azirid-react 0.10.1 → 0.10.2

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
@@ -81,11 +81,12 @@ AZIRID_API_URL=http://localhost:3000
81
81
  import { AziridProvider } from 'azirid-react'
82
82
 
83
83
  export default function RootLayout({ children }: { children: React.ReactNode }) {
84
+ const router = useRouter()
85
+
84
86
  return (
85
87
  <AziridProvider
86
88
  publishableKey={process.env.NEXT_PUBLIC_AZIRID_PK!}
87
- onLoginSuccess={(data) => console.log('Logged in:', data.user)}
88
- onLogoutSuccess={() => console.log('Logged out')}
89
+ onAuthStateChange={() => router.refresh()}
89
90
  onSessionExpired={() => (window.location.href = '/login')}
90
91
  >
91
92
  {children}
@@ -717,6 +718,8 @@ The hook handles both phases automatically:
717
718
 
718
719
  > **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.
719
720
 
721
+ > **Session safety:** The confirmation request waits for the session bootstrap to complete before firing. This prevents 401 errors when Payphone redirects back and the page reloads — the SDK restores the session first, then confirms the payment.
722
+
720
723
  ### `usePayButton`
721
724
 
722
725
  Hook that returns **renderable components** and **state** for a complete payment flow. Supports all providers (Stripe, PayPal, Payphone, Manual Transfer, Nuvei). You control the layout.
@@ -926,7 +929,7 @@ import { InvoiceList } from 'azirid-react'
926
929
 
927
930
  #### `PayphoneCallback`
928
931
 
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.
932
+ 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. The component waits for the session bootstrap to complete before confirming, preventing 401 errors on page reload.
930
933
 
931
934
  ```tsx
932
935
  // app/payphone/callback/page.tsx
@@ -1297,6 +1300,7 @@ function createAccessClient(
1297
1300
  | `autoBootstrap` | `boolean` | `true` | Auto-restore session on mount |
1298
1301
  | `refreshInterval` | `number` | `50000` | Token refresh interval in ms. `0` to disable |
1299
1302
  | `sessionSyncUrl` | `string \| false` | auto | URL for session cookie sync. Auto-activates in dev mode. Pass `false` to disable |
1303
+ | `onAuthStateChange`| `() => void` | — | Called after login, signup, or logout. **In Next.js, pass `router.refresh()`** to sync server actions with updated cookies |
1300
1304
  | `onLoginSuccess` | `(data) => void` | — | Called after successful login |
1301
1305
  | `onSignupSuccess` | `(data) => void` | — | Called after successful signup |
1302
1306
  | `onLogoutSuccess` | `() => void` | — | Called after logout |
@@ -1311,6 +1315,33 @@ function createAccessClient(
1311
1315
 
1312
1316
  `azirid-react` supports **Next.js 14, 15, and 16+** with full compatibility for each version's API conventions.
1313
1317
 
1318
+ ### Server Actions & `onAuthStateChange`
1319
+
1320
+ If you use **server actions** or **server components** that read the session token (via `createServerAccess`), you **must** pass `onAuthStateChange` to keep server-side cookies in sync:
1321
+
1322
+ ```tsx
1323
+ 'use client'
1324
+ import { useRouter } from 'next/navigation'
1325
+ import { AziridProvider } from 'azirid-react'
1326
+
1327
+ export function Providers({ children }: { children: React.ReactNode }) {
1328
+ const router = useRouter()
1329
+
1330
+ return (
1331
+ <AziridProvider
1332
+ publishableKey={process.env.NEXT_PUBLIC_AZIRID_PK!}
1333
+ onAuthStateChange={() => router.refresh()}
1334
+ >
1335
+ {children}
1336
+ </AziridProvider>
1337
+ )
1338
+ }
1339
+ ```
1340
+
1341
+ **Why?** After login/signup/logout, azirid-react updates the `__session` cookie in the browser. But Next.js server actions keep using the old cookies until `router.refresh()` forces a new server request. Without this, server actions may return 401 after login.
1342
+
1343
+ > **Not using server actions?** (e.g. pure client-side SPA with Vite) — you can skip `onAuthStateChange`.
1344
+
1314
1345
  ### Proxy Route Handler (all versions)
1315
1346
 
1316
1347
  Create the file `app/api/auth/[...path]/route.ts` — one line is all you need:
package/dist/index.cjs CHANGED
@@ -3011,6 +3011,7 @@ function usePayButton({
3011
3011
  const [payphoneConfig, setPayphoneConfig] = react.useState(null);
3012
3012
  const [currentError, setCurrentError] = react.useState(null);
3013
3013
  const payphoneConfirmTriggered = react.useRef(false);
3014
+ const { isBootstrapping } = useAzirid();
3014
3015
  const params = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : new URLSearchParams();
3015
3016
  const callbackId = params.get("id");
3016
3017
  const callbackClientTxId = params.get("clientTransactionId");
@@ -3093,12 +3094,12 @@ function usePayButton({
3093
3094
  }
3094
3095
  });
3095
3096
  react.useEffect(() => {
3096
- if (!isPayphoneCallback || payphoneConfirmTriggered.current) return;
3097
+ if (!isPayphoneCallback || payphoneConfirmTriggered.current || isBootstrapping) return;
3097
3098
  payphoneConfirmTriggered.current = true;
3098
3099
  setSelectedProvider("PAYPHONE");
3099
3100
  setStatus("processing");
3100
3101
  confirmPayphone({ id: Number(callbackId), clientTransactionId: callbackClientTxId });
3101
- }, [isPayphoneCallback, callbackId, callbackClientTxId, confirmPayphone]);
3102
+ }, [isPayphoneCallback, isBootstrapping, callbackId, callbackClientTxId, confirmPayphone]);
3102
3103
  const handleSdkError = react.useCallback(
3103
3104
  (err) => {
3104
3105
  setCurrentError(err);
@@ -3532,16 +3533,17 @@ function PayphoneCallback({ onSuccess, onError, className, style }) {
3532
3533
  onSuccess,
3533
3534
  onError
3534
3535
  });
3536
+ const { isBootstrapping } = useAzirid();
3535
3537
  const called = react.useRef(false);
3536
3538
  react.useEffect(() => {
3537
- if (called.current) return;
3539
+ if (called.current || isBootstrapping) return;
3538
3540
  called.current = true;
3539
3541
  const params = new URLSearchParams(window.location.search);
3540
3542
  const id = params.get("id");
3541
3543
  const clientTransactionId = params.get("clientTransactionId");
3542
3544
  if (!id || !clientTransactionId) return;
3543
3545
  mutate({ id: Number(id), clientTransactionId });
3544
- }, [mutate]);
3546
+ }, [mutate, isBootstrapping]);
3545
3547
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { textAlign: "center", padding: "32px", ...style }, children: [
3546
3548
  isPending && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3547
3549
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: textStyle, children: "Confirming your payment..." }),
@@ -4043,6 +4045,7 @@ function usePayphoneCheckout({
4043
4045
  const [currentError, setCurrentError] = react.useState(null);
4044
4046
  const checkoutTriggered = react.useRef(false);
4045
4047
  const confirmTriggered = react.useRef(false);
4048
+ const { isBootstrapping } = useAzirid();
4046
4049
  const params = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : new URLSearchParams();
4047
4050
  const callbackId = params.get("id");
4048
4051
  const callbackClientTxId = params.get("clientTransactionId");
@@ -4084,11 +4087,11 @@ function usePayphoneCheckout({
4084
4087
  }
4085
4088
  });
4086
4089
  react.useEffect(() => {
4087
- if (!isCallback || confirmTriggered.current) return;
4090
+ if (!isCallback || confirmTriggered.current || isBootstrapping) return;
4088
4091
  confirmTriggered.current = true;
4089
4092
  setStatus("confirming");
4090
4093
  confirm({ id: Number(callbackId), clientTransactionId: callbackClientTxId });
4091
- }, [isCallback, callbackId, callbackClientTxId, confirm]);
4094
+ }, [isCallback, isBootstrapping, callbackId, callbackClientTxId, confirm]);
4092
4095
  const handleSdkError = react.useCallback(
4093
4096
  (err) => {
4094
4097
  setCurrentError(err);
@@ -4346,7 +4349,7 @@ function usePasswordToggle() {
4346
4349
  }
4347
4350
 
4348
4351
  // src/index.ts
4349
- var SDK_VERSION = "0.10.1";
4352
+ var SDK_VERSION = "0.10.2";
4350
4353
 
4351
4354
  exports.AuthForm = AuthForm;
4352
4355
  exports.AziridProvider = AziridProvider;