azirid-react 0.9.8 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -713,7 +713,9 @@ function CheckoutPage({ intentId }: { intentId: string }) {
713
713
 
714
714
  The hook handles both phases automatically:
715
715
  1. **Widget phase**: Calls checkout API, loads Payphone SDK, widget renders via `<PayphoneWidget />`.
716
- 2. **Confirmation phase**: After Payphone redirects back (same page), detects URL params and confirms the payment.
716
+ 2. **Confirmation phase**: After Payphone redirects back to your configured **Response URL** (set in Payphone Developer dashboard), detects `?id=X&clientTransactionId=Y` params and confirms the payment.
717
+
718
+ > **Important:** The redirect URL after payment is configured in the **Payphone Developer dashboard** (not passed via code). Make sure your Response URL points to the page where `usePayphoneCheckout` or `<PayphoneCallback>` is rendered.
717
719
 
718
720
  ### `usePayButton`
719
721
 
@@ -924,7 +926,7 @@ import { InvoiceList } from 'azirid-react'
924
926
 
925
927
  #### `PayphoneCallback`
926
928
 
927
- Page component for handling Payphone payment callbacks. Reads `id` and `clientTransactionId` from URL query params automatically.
929
+ Page component for handling Payphone payment callbacks. Reads `id` and `clientTransactionId` from URL query params automatically. Deploy this page at the **Response URL** configured in your Payphone Developer dashboard.
928
930
 
929
931
  ```tsx
930
932
  // app/payphone/callback/page.tsx
package/dist/index.cjs CHANGED
@@ -165,6 +165,31 @@ function createAccessClient(config, appContext) {
165
165
  let refreshToken = ssGet(storageKeyRt);
166
166
  let csrfToken = ssGet(storageKeyCsrf);
167
167
  let refreshPromise = null;
168
+ let channel = null;
169
+ try {
170
+ if (typeof BroadcastChannel !== "undefined") {
171
+ channel = new BroadcastChannel("azirid-auth");
172
+ channel.onmessage = (event) => {
173
+ if (event.data?.type === "token-refreshed") {
174
+ accessToken = event.data.accessToken;
175
+ if (event.data.refreshToken) setRefreshToken(event.data.refreshToken);
176
+ if (event.data.csrfToken) setCsrfToken(event.data.csrfToken);
177
+ }
178
+ };
179
+ }
180
+ } catch {
181
+ }
182
+ function broadcastTokens() {
183
+ try {
184
+ channel?.postMessage({
185
+ type: "token-refreshed",
186
+ accessToken,
187
+ refreshToken,
188
+ csrfToken
189
+ });
190
+ } catch {
191
+ }
192
+ }
168
193
  function setAccessToken(token) {
169
194
  accessToken = token;
170
195
  }
@@ -226,6 +251,7 @@ function createAccessClient(config, appContext) {
226
251
  const xc = json.xc ?? json.csrfToken;
227
252
  if (rt) setRefreshToken(rt);
228
253
  if (xc) setCsrfToken(xc);
254
+ broadcastTokens();
229
255
  }
230
256
  function refreshTokens(opts) {
231
257
  if (opts?.tenantId) {
@@ -775,6 +801,27 @@ function AziridProviderInner({
775
801
  }, [client, props.autoBootstrap, updateAccessToken, saveSessionTokens]);
776
802
  const silentRefresh = react.useCallback(async () => {
777
803
  if (!client.getAccessToken()) return;
804
+ if (typeof navigator !== "undefined" && "locks" in navigator) {
805
+ let acquired = false;
806
+ try {
807
+ await navigator.locks.request(
808
+ "azirid-token-refresh",
809
+ { ifAvailable: true },
810
+ async (lock) => {
811
+ if (!lock) return;
812
+ acquired = true;
813
+ await client.refreshSession();
814
+ updateAccessToken(client.getAccessToken());
815
+ }
816
+ );
817
+ } catch (err) {
818
+ if (acquired && isAuthError(err)) {
819
+ clearSession();
820
+ props.onSessionExpired?.();
821
+ }
822
+ }
823
+ return;
824
+ }
778
825
  try {
779
826
  await client.refreshSession();
780
827
  updateAccessToken(client.getAccessToken());
@@ -785,6 +832,27 @@ function AziridProviderInner({
785
832
  }
786
833
  }
787
834
  }, [client, updateAccessToken, clearSession, props]);
835
+ react.useEffect(() => {
836
+ let channel = null;
837
+ try {
838
+ if (typeof BroadcastChannel !== "undefined") {
839
+ channel = new BroadcastChannel("azirid-auth");
840
+ channel.onmessage = (event) => {
841
+ if (event.data?.type === "token-refreshed" && event.data.accessToken) {
842
+ client.setAccessToken(event.data.accessToken);
843
+ updateAccessToken(event.data.accessToken);
844
+ }
845
+ };
846
+ }
847
+ } catch {
848
+ }
849
+ return () => {
850
+ try {
851
+ channel?.close();
852
+ } catch {
853
+ }
854
+ };
855
+ }, [client, updateAccessToken]);
788
856
  react.useEffect(() => {
789
857
  const intervalMs = props.refreshInterval ?? 5e4;
790
858
  if (intervalMs <= 0) return;
@@ -2297,7 +2365,6 @@ function loadPayphoneSdk() {
2297
2365
  }
2298
2366
  function PayphoneWidgetRenderer({
2299
2367
  config,
2300
- responseUrl,
2301
2368
  containerId,
2302
2369
  onReady,
2303
2370
  onError
@@ -2319,18 +2386,17 @@ function PayphoneWidgetRenderer({
2319
2386
  amountWithoutTax: config.amountWithoutTax,
2320
2387
  currency: config.currency,
2321
2388
  storeId: config.storeId,
2322
- reference: config.reference,
2323
- responseUrl
2389
+ reference: config.reference
2324
2390
  }).render(containerId);
2325
2391
  onReady?.();
2326
2392
  });
2327
2393
  }).catch((err) => {
2328
2394
  onError?.(new Error(err instanceof Error ? err.message : "Failed to load Payphone SDK"));
2329
2395
  });
2330
- }, [config, responseUrl, containerId, onReady, onError]);
2396
+ }, [config, containerId, onReady, onError]);
2331
2397
  return /* @__PURE__ */ jsxRuntime.jsx("div", { id: containerId });
2332
2398
  }
2333
- function PayphoneModal({ config, successUrl, onClose }) {
2399
+ function PayphoneModal({ config, onClose }) {
2334
2400
  const [error, setError] = react.useState(null);
2335
2401
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: cardStyle, onClick: (e) => e.stopPropagation(), children: [
2336
2402
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyle, children: "Payphone" }),
@@ -2339,7 +2405,6 @@ function PayphoneModal({ config, successUrl, onClose }) {
2339
2405
  PayphoneWidgetRenderer,
2340
2406
  {
2341
2407
  config,
2342
- responseUrl: successUrl,
2343
2408
  containerId: "pp-button-azirid",
2344
2409
  onError: (err) => setError(err.message)
2345
2410
  }
@@ -2864,7 +2929,6 @@ function PricingTable({
2864
2929
  PayphoneModal,
2865
2930
  {
2866
2931
  config: payphoneData.widgetConfig,
2867
- successUrl,
2868
2932
  onClose: () => setPayphoneData(null)
2869
2933
  }
2870
2934
  )
@@ -2944,7 +3008,6 @@ function usePayButton({
2944
3008
  const [payphoneConfig, setPayphoneConfig] = react.useState(null);
2945
3009
  const [currentError, setCurrentError] = react.useState(null);
2946
3010
  const payphoneConfirmTriggered = react.useRef(false);
2947
- const responseUrl = typeof window !== "undefined" ? window.location.href.split("?")[0] : "";
2948
3011
  const params = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : new URLSearchParams();
2949
3012
  const callbackId = params.get("id");
2950
3013
  const callbackClientTxId = params.get("clientTransactionId");
@@ -2995,15 +3058,16 @@ function usePayButton({
2995
3058
  setSelectedProvider(provider);
2996
3059
  setStatus("processing");
2997
3060
  setCurrentError(null);
3061
+ const currentUrl = typeof window !== "undefined" ? window.location.href.split("?")[0] : "";
2998
3062
  doCheckout({
2999
3063
  intentId,
3000
3064
  planId,
3001
3065
  provider,
3002
- successUrl: responseUrl,
3003
- cancelUrl: responseUrl
3066
+ successUrl: currentUrl,
3067
+ cancelUrl: currentUrl
3004
3068
  });
3005
3069
  },
3006
- [doCheckout, intentId, planId, responseUrl]
3070
+ [doCheckout, intentId, planId]
3007
3071
  );
3008
3072
  const { mutate: confirmPayphone } = usePayphoneConfirm({
3009
3073
  onSuccess: (data) => {
@@ -3150,12 +3214,11 @@ function usePayButton({
3150
3214
  if (!payphoneConfig || isPayphoneCallback) return null;
3151
3215
  return PayphoneWidgetRenderer({
3152
3216
  config: payphoneConfig,
3153
- responseUrl,
3154
3217
  containerId: PP_CONTAINER_ID,
3155
3218
  onError: handleSdkError
3156
3219
  });
3157
3220
  };
3158
- }, [payphoneConfig, responseUrl, isPayphoneCallback, handleSdkError]);
3221
+ }, [payphoneConfig, isPayphoneCallback, handleSdkError]);
3159
3222
  return {
3160
3223
  providers,
3161
3224
  checkout,
@@ -3454,7 +3517,6 @@ function PayButton({
3454
3517
  PayphoneModal,
3455
3518
  {
3456
3519
  config: checkoutData.widgetConfig,
3457
- successUrl,
3458
3520
  onClose: () => {
3459
3521
  onSuccess?.(checkoutData);
3460
3522
  }
@@ -3978,7 +4040,6 @@ function usePayphoneCheckout({
3978
4040
  const [currentError, setCurrentError] = react.useState(null);
3979
4041
  const checkoutTriggered = react.useRef(false);
3980
4042
  const confirmTriggered = react.useRef(false);
3981
- const responseUrl = typeof window !== "undefined" ? window.location.href.split("?")[0] : "";
3982
4043
  const params = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : new URLSearchParams();
3983
4044
  const callbackId = params.get("id");
3984
4045
  const callbackClientTxId = params.get("clientTransactionId");
@@ -4004,10 +4065,10 @@ function usePayphoneCheckout({
4004
4065
  checkout({
4005
4066
  intentId,
4006
4067
  provider: "PAYPHONE",
4007
- successUrl: responseUrl,
4008
- cancelUrl: responseUrl
4068
+ successUrl: window.location.href,
4069
+ cancelUrl: window.location.href
4009
4070
  });
4010
- }, [checkout, intentId, responseUrl, isCallback]);
4071
+ }, [checkout, intentId, isCallback]);
4011
4072
  const { mutate: confirm } = usePayphoneConfirm({
4012
4073
  onSuccess: (data) => {
4013
4074
  setStatus(data.status === "confirmed" || data.status === "already_confirmed" ? "confirmed" : "cancelled");
@@ -4038,12 +4099,11 @@ function usePayphoneCheckout({
4038
4099
  if (!widgetConfig || isCallback) return null;
4039
4100
  return PayphoneWidgetRenderer({
4040
4101
  config: widgetConfig,
4041
- responseUrl,
4042
4102
  containerId: CONTAINER_ID,
4043
4103
  onError: handleSdkError
4044
4104
  });
4045
4105
  };
4046
- }, [widgetConfig, responseUrl, isCallback, handleSdkError]);
4106
+ }, [widgetConfig, isCallback, handleSdkError]);
4047
4107
  return { PayphoneWidget, status, intentId, error: currentError };
4048
4108
  }
4049
4109
  function useTransferPayment({
@@ -4283,7 +4343,7 @@ function usePasswordToggle() {
4283
4343
  }
4284
4344
 
4285
4345
  // src/index.ts
4286
- var SDK_VERSION = "0.9.8";
4346
+ var SDK_VERSION = "0.10.0";
4287
4347
 
4288
4348
  exports.AuthForm = AuthForm;
4289
4349
  exports.AziridProvider = AziridProvider;