azirid-react 0.10.0 → 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 +13 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +13 -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
|
@@ -604,6 +604,7 @@ function useAuthMutations(deps) {
|
|
|
604
604
|
updateAccessToken(normalizeToken(data));
|
|
605
605
|
saveSessionTokens(data);
|
|
606
606
|
setError(null);
|
|
607
|
+
props.onAuthStateChange?.();
|
|
607
608
|
props.onLoginSuccess?.(data);
|
|
608
609
|
},
|
|
609
610
|
onError: (err) => {
|
|
@@ -621,6 +622,7 @@ function useAuthMutations(deps) {
|
|
|
621
622
|
updateAccessToken(normalizeToken(data));
|
|
622
623
|
saveSessionTokens(data);
|
|
623
624
|
setError(null);
|
|
625
|
+
props.onAuthStateChange?.();
|
|
624
626
|
props.onSignupSuccess?.(data);
|
|
625
627
|
},
|
|
626
628
|
onError: (err) => {
|
|
@@ -634,6 +636,7 @@ function useAuthMutations(deps) {
|
|
|
634
636
|
clearSession();
|
|
635
637
|
setError(null);
|
|
636
638
|
queryClient.clear();
|
|
639
|
+
props.onAuthStateChange?.();
|
|
637
640
|
props.onLogoutSuccess?.();
|
|
638
641
|
}
|
|
639
642
|
});
|
|
@@ -3008,6 +3011,7 @@ function usePayButton({
|
|
|
3008
3011
|
const [payphoneConfig, setPayphoneConfig] = react.useState(null);
|
|
3009
3012
|
const [currentError, setCurrentError] = react.useState(null);
|
|
3010
3013
|
const payphoneConfirmTriggered = react.useRef(false);
|
|
3014
|
+
const { isBootstrapping } = useAzirid();
|
|
3011
3015
|
const params = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : new URLSearchParams();
|
|
3012
3016
|
const callbackId = params.get("id");
|
|
3013
3017
|
const callbackClientTxId = params.get("clientTransactionId");
|
|
@@ -3090,12 +3094,12 @@ function usePayButton({
|
|
|
3090
3094
|
}
|
|
3091
3095
|
});
|
|
3092
3096
|
react.useEffect(() => {
|
|
3093
|
-
if (!isPayphoneCallback || payphoneConfirmTriggered.current) return;
|
|
3097
|
+
if (!isPayphoneCallback || payphoneConfirmTriggered.current || isBootstrapping) return;
|
|
3094
3098
|
payphoneConfirmTriggered.current = true;
|
|
3095
3099
|
setSelectedProvider("PAYPHONE");
|
|
3096
3100
|
setStatus("processing");
|
|
3097
3101
|
confirmPayphone({ id: Number(callbackId), clientTransactionId: callbackClientTxId });
|
|
3098
|
-
}, [isPayphoneCallback, callbackId, callbackClientTxId, confirmPayphone]);
|
|
3102
|
+
}, [isPayphoneCallback, isBootstrapping, callbackId, callbackClientTxId, confirmPayphone]);
|
|
3099
3103
|
const handleSdkError = react.useCallback(
|
|
3100
3104
|
(err) => {
|
|
3101
3105
|
setCurrentError(err);
|
|
@@ -3529,16 +3533,17 @@ function PayphoneCallback({ onSuccess, onError, className, style }) {
|
|
|
3529
3533
|
onSuccess,
|
|
3530
3534
|
onError
|
|
3531
3535
|
});
|
|
3536
|
+
const { isBootstrapping } = useAzirid();
|
|
3532
3537
|
const called = react.useRef(false);
|
|
3533
3538
|
react.useEffect(() => {
|
|
3534
|
-
if (called.current) return;
|
|
3539
|
+
if (called.current || isBootstrapping) return;
|
|
3535
3540
|
called.current = true;
|
|
3536
3541
|
const params = new URLSearchParams(window.location.search);
|
|
3537
3542
|
const id = params.get("id");
|
|
3538
3543
|
const clientTransactionId = params.get("clientTransactionId");
|
|
3539
3544
|
if (!id || !clientTransactionId) return;
|
|
3540
3545
|
mutate({ id: Number(id), clientTransactionId });
|
|
3541
|
-
}, [mutate]);
|
|
3546
|
+
}, [mutate, isBootstrapping]);
|
|
3542
3547
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { textAlign: "center", padding: "32px", ...style }, children: [
|
|
3543
3548
|
isPending && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3544
3549
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: textStyle, children: "Confirming your payment..." }),
|
|
@@ -4040,6 +4045,7 @@ function usePayphoneCheckout({
|
|
|
4040
4045
|
const [currentError, setCurrentError] = react.useState(null);
|
|
4041
4046
|
const checkoutTriggered = react.useRef(false);
|
|
4042
4047
|
const confirmTriggered = react.useRef(false);
|
|
4048
|
+
const { isBootstrapping } = useAzirid();
|
|
4043
4049
|
const params = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : new URLSearchParams();
|
|
4044
4050
|
const callbackId = params.get("id");
|
|
4045
4051
|
const callbackClientTxId = params.get("clientTransactionId");
|
|
@@ -4081,11 +4087,11 @@ function usePayphoneCheckout({
|
|
|
4081
4087
|
}
|
|
4082
4088
|
});
|
|
4083
4089
|
react.useEffect(() => {
|
|
4084
|
-
if (!isCallback || confirmTriggered.current) return;
|
|
4090
|
+
if (!isCallback || confirmTriggered.current || isBootstrapping) return;
|
|
4085
4091
|
confirmTriggered.current = true;
|
|
4086
4092
|
setStatus("confirming");
|
|
4087
4093
|
confirm({ id: Number(callbackId), clientTransactionId: callbackClientTxId });
|
|
4088
|
-
}, [isCallback, callbackId, callbackClientTxId, confirm]);
|
|
4094
|
+
}, [isCallback, isBootstrapping, callbackId, callbackClientTxId, confirm]);
|
|
4089
4095
|
const handleSdkError = react.useCallback(
|
|
4090
4096
|
(err) => {
|
|
4091
4097
|
setCurrentError(err);
|
|
@@ -4343,7 +4349,7 @@ function usePasswordToggle() {
|
|
|
4343
4349
|
}
|
|
4344
4350
|
|
|
4345
4351
|
// src/index.ts
|
|
4346
|
-
var SDK_VERSION = "0.10.
|
|
4352
|
+
var SDK_VERSION = "0.10.2";
|
|
4347
4353
|
|
|
4348
4354
|
exports.AuthForm = AuthForm;
|
|
4349
4355
|
exports.AziridProvider = AziridProvider;
|