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 +34 -3
- package/dist/index.cjs +10 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +10 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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.
|
|
4352
|
+
var SDK_VERSION = "0.10.2";
|
|
4350
4353
|
|
|
4351
4354
|
exports.AuthForm = AuthForm;
|
|
4352
4355
|
exports.AziridProvider = AziridProvider;
|