@waffo/pancake-nextjs 0.1.9 → 0.2.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/CHANGELOG.md +15 -0
- package/README.md +56 -54
- package/dist/index.cjs +62 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -63
- package/dist/index.d.ts +92 -63
- package/dist/index.js +58 -48
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +16 -10
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +25 -15
- package/dist/server.d.ts +25 -15
- package/dist/server.js +14 -10
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ All notable changes to `@waffo/pancake-nextjs` will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.2.0] - 2026-07-14
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **Public API renamed from "buyer" to "customer"** — the merchant's end consumer is called a customer across the SDK (matching the session-token JWT role). New primary names:
|
|
12
|
+
- Hooks: `useBuyer` → `useCustomer` · `useBuyerOrders` → `useCustomerOrders` · `useBuyerPayments` → `useCustomerPayments` · `useBuyerRefundTickets` → `useCustomerRefundTickets`
|
|
13
|
+
- Server action factories (`@waffo/pancake-nextjs/server`): `createBuyerTokenAction` → `createCustomerTokenAction` · `createBuyerSessionAction` → `createCustomerSessionAction`
|
|
14
|
+
- Types: `BuyerConfig` → `CustomerConfig` · `BuyerActionState` → `CustomerActionState` · `UseBuyerReturn` → `UseCustomerReturn` · `BuyerOnetimeOrder` → `CustomerOnetimeOrder` · `BuyerSubscriptionOrder` → `CustomerSubscriptionOrder` · `BuyerPayment` → `CustomerPayment` · `BuyerRefundTicket` → `CustomerRefundTicket` · `BuyerTokenAction` → `CustomerTokenAction` · `BuyerSessionAction` → `CustomerSessionAction` · `BuyerSessionActionType` → `CustomerSessionActionType`
|
|
15
|
+
- `<WaffoPancakeProvider>`: the config prop is now `customer` (the `buyer` prop is still accepted; `customer` wins when both are set)
|
|
16
|
+
- **Wire contract unchanged** — request/payload field names stay as-is: `buyerIdentity` (checkout params, `issueSessionToken` params), `buyerEmail` (webhook event data, GraphQL fields), HTTP paths, and header names. No server-side changes required.
|
|
17
|
+
|
|
18
|
+
### Deprecated
|
|
19
|
+
|
|
20
|
+
- All previous "buyer" names remain exported as working aliases of the new "customer" names (marked `@deprecated`) and will be removed in the next release: `useBuyer`, `useBuyerOrders`, `useBuyerPayments`, `useBuyerRefundTickets`, `createBuyerTokenAction`, `createBuyerSessionAction`, the `Buyer*` types listed above, and the `buyer` prop on `<WaffoPancakeProvider>`.
|
|
21
|
+
|
|
7
22
|
## [0.1.9] - 2026-06-05
|
|
8
23
|
|
|
9
24
|
### Changed
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Next.js SDK for the [Waffo Pancake](https://waffo.ai) Merchant of Record (MoR) p
|
|
|
5
5
|
- Three checkout modes: link (instant redirect), anonymous (API), authenticated (API + token)
|
|
6
6
|
- Popup blocker avoidance — synchronous `window.open` in click handler
|
|
7
7
|
- Webhook route handler with automatic signature verification and event dispatch
|
|
8
|
-
-
|
|
8
|
+
- Customer self-service hooks with automatic token lifecycle management
|
|
9
9
|
- Server action architecture — private keys never leave the server
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
@@ -16,7 +16,7 @@ npm install @waffo/pancake-nextjs
|
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
19
|
-
> Most merchants create stores and products in the [Dashboard](https://pancake.waffo.ai/dashboard). This SDK is primarily used for **embedding checkout, webhooks, and
|
|
19
|
+
> Most merchants create stores and products in the [Dashboard](https://pancake.waffo.ai/dashboard). This SDK is primarily used for **embedding checkout, webhooks, and customer self-service** into your Next.js app.
|
|
20
20
|
|
|
21
21
|
The fastest integration — a link checkout button, no API keys needed:
|
|
22
22
|
|
|
@@ -29,15 +29,15 @@ import { CheckoutButton } from "@waffo/pancake-nextjs";
|
|
|
29
29
|
</CheckoutButton>;
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
For API-level control (dynamic pricing,
|
|
32
|
+
For API-level control (dynamic pricing, customer identity, trial overrides), set up server actions first:
|
|
33
33
|
|
|
34
34
|
```ts
|
|
35
35
|
// app/lib/waffo.ts — define once, import everywhere
|
|
36
36
|
"use server";
|
|
37
37
|
import {
|
|
38
38
|
createCheckoutAction,
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
createCustomerTokenAction,
|
|
40
|
+
createCustomerSessionAction,
|
|
41
41
|
createMerchantQueryAction,
|
|
42
42
|
} from "@waffo/pancake-nextjs/server";
|
|
43
43
|
|
|
@@ -48,8 +48,8 @@ const config = {
|
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
export const checkout = createCheckoutAction(config);
|
|
51
|
-
export const
|
|
52
|
-
export const
|
|
51
|
+
export const issueCustomerToken = createCustomerTokenAction(config);
|
|
52
|
+
export const customerAction = createCustomerSessionAction(config);
|
|
53
53
|
export const merchantQuery = createMerchantQueryAction(config);
|
|
54
54
|
```
|
|
55
55
|
|
|
@@ -59,13 +59,13 @@ Private keys are captured in server action closures — they never reach the bro
|
|
|
59
59
|
|
|
60
60
|
Waffo supports three checkout modes based on how much control the merchant needs:
|
|
61
61
|
|
|
62
|
-
| Mode | `type` | Needs Server Action? | Use Case
|
|
63
|
-
| ----------------- | ----------------- | :------------------: |
|
|
64
|
-
| **Link** | `"link"` | No | Landing pages, email campaigns. Redirects to product page which auto-creates a session.
|
|
65
|
-
| **Anonymous** | omit | Yes | API-level control without
|
|
66
|
-
| **Authenticated** | `"authenticated"` | Yes | Merchant provides
|
|
62
|
+
| Mode | `type` | Needs Server Action? | Use Case |
|
|
63
|
+
| ----------------- | ----------------- | :------------------: | ---------------------------------------------------------------------------------------- |
|
|
64
|
+
| **Link** | `"link"` | No | Landing pages, email campaigns. Redirects to product page which auto-creates a session. |
|
|
65
|
+
| **Anonymous** | omit | Yes | API-level control without customer identity. Customer fills in details on checkout page. |
|
|
66
|
+
| **Authenticated** | `"authenticated"` | Yes | Merchant provides customer identity. Form pre-filled. Enables customer self-service. |
|
|
67
67
|
|
|
68
|
-
> **We recommend authenticated checkout whenever possible.** It binds orders to a stable merchant-controlled identifier. In anonymous mode, the
|
|
68
|
+
> **We recommend authenticated checkout whenever possible.** It binds orders to a stable merchant-controlled identifier. In anonymous mode, the customer self-reports their email — if they enter a different address, previous orders become unlinked and subscription trial periods can be exploited.
|
|
69
69
|
|
|
70
70
|
### Link Checkout
|
|
71
71
|
|
|
@@ -85,7 +85,7 @@ import { CheckoutButton } from "@waffo/pancake-nextjs";
|
|
|
85
85
|
storeSlug="my-store"
|
|
86
86
|
productId="PROD_xxx"
|
|
87
87
|
currency="USD"
|
|
88
|
-
email="
|
|
88
|
+
email="customer@example.com"
|
|
89
89
|
successUrl="https://example.com/thank-you"
|
|
90
90
|
country="US"
|
|
91
91
|
test={false}
|
|
@@ -122,13 +122,13 @@ Pass an optional `orderMerchantExternalId` to attach your internal order referen
|
|
|
122
122
|
|
|
123
123
|
### Authenticated Checkout (Recommended)
|
|
124
124
|
|
|
125
|
-
Creates a session **and** a token bound to the
|
|
125
|
+
Creates a session **and** a token bound to the customer you provide. `buyerIdentity` is for order attribution and trial tracking — it is not rendered on the checkout page. To pre-fill the email field on the checkout form, pass `buyerEmail` explicitly.
|
|
126
126
|
|
|
127
127
|
```tsx
|
|
128
128
|
import { CheckoutButton } from "@waffo/pancake-nextjs";
|
|
129
129
|
import { checkout } from "./lib/waffo";
|
|
130
130
|
|
|
131
|
-
// Basic —
|
|
131
|
+
// Basic — customer identity only (checkout page email field stays empty)
|
|
132
132
|
<CheckoutButton type="authenticated" action={checkout} productId="PROD_xxx" currency="USD" buyerIdentity={user.id}>
|
|
133
133
|
Upgrade to Pro
|
|
134
134
|
</CheckoutButton>
|
|
@@ -191,12 +191,12 @@ const { checkout, isLoading, error } = useCheckout({
|
|
|
191
191
|
|
|
192
192
|
Both `CheckoutButton` and `useCheckout` support two navigation modes via the `mode` prop:
|
|
193
193
|
|
|
194
|
-
- `"redirect"` (default) — navigates the current page.
|
|
194
|
+
- `"redirect"` (default) — navigates the current page. Customer returns via `successUrl`.
|
|
195
195
|
- `"popup"` — opens a new tab. Link mode opens the URL directly; API modes show a loading page first, then redirect once the session is ready.
|
|
196
196
|
|
|
197
197
|
## Webhook Verification
|
|
198
198
|
|
|
199
|
-
After a
|
|
199
|
+
After a customer completes payment, Waffo sends webhook events to your server. The `Webhook` factory creates a Next.js route handler that verifies signatures and dispatches events:
|
|
200
200
|
|
|
201
201
|
```ts
|
|
202
202
|
// app/api/webhooks/waffo/route.ts
|
|
@@ -237,18 +237,20 @@ export const POST = Webhook({
|
|
|
237
237
|
|
|
238
238
|
Returns `200` on success, `401` on invalid signature, `500` if a handler throws. Full event list: `onOrderCompleted`, `onSubscriptionActivated`, `onSubscriptionPaymentSucceeded`, `onSubscriptionCanceling`, `onSubscriptionUncanceled`, `onSubscriptionUpdated`, `onSubscriptionCanceled`, `onSubscriptionPastDue`, `onRefundSucceeded`, `onRefundFailed`.
|
|
239
239
|
|
|
240
|
-
##
|
|
240
|
+
## Customer Self-Service
|
|
241
241
|
|
|
242
|
-
Beyond checkout, you can let
|
|
242
|
+
Beyond checkout, you can let customers manage their own orders and subscriptions. Wrap with `WaffoPancakeProvider` — it auto-issues tokens and refreshes them before expiry:
|
|
243
243
|
|
|
244
244
|
```tsx
|
|
245
|
-
import { WaffoPancakeProvider,
|
|
246
|
-
import {
|
|
245
|
+
import { WaffoPancakeProvider, useCustomer, useCustomerOrders, useCustomerPayments, useCustomerRefundTickets } from "@waffo/pancake-nextjs";
|
|
246
|
+
import { issueCustomerToken, customerAction } from "./lib/waffo";
|
|
247
247
|
|
|
248
248
|
// Wrap once — provider manages token lifecycle
|
|
249
249
|
export default function AccountLayout({ user }: { user: { email: string } }) {
|
|
250
250
|
return (
|
|
251
|
-
<WaffoPancakeProvider
|
|
251
|
+
<WaffoPancakeProvider
|
|
252
|
+
customer={{ identity: user.email, storeId: "STO_xxx", issueToken: issueCustomerToken, sessionAction: customerAction }}
|
|
253
|
+
>
|
|
252
254
|
<AccountPage />
|
|
253
255
|
</WaffoPancakeProvider>
|
|
254
256
|
);
|
|
@@ -256,10 +258,10 @@ export default function AccountLayout({ user }: { user: { email: string } }) {
|
|
|
256
258
|
|
|
257
259
|
// All hooks work without passing token or client
|
|
258
260
|
function AccountPage() {
|
|
259
|
-
const { data: orders, isLoading, refetch } =
|
|
260
|
-
const { data: payments } =
|
|
261
|
-
const { data: tickets } =
|
|
262
|
-
const
|
|
261
|
+
const { data: orders, isLoading, refetch } = useCustomerOrders();
|
|
262
|
+
const { data: payments } = useCustomerPayments();
|
|
263
|
+
const { data: tickets } = useCustomerRefundTickets();
|
|
264
|
+
const customer = useCustomer();
|
|
263
265
|
|
|
264
266
|
if (isLoading) return <p>Loading...</p>;
|
|
265
267
|
|
|
@@ -271,9 +273,9 @@ function AccountPage() {
|
|
|
271
273
|
<p>
|
|
272
274
|
{sub.product?.name} — {sub.status}
|
|
273
275
|
</p>
|
|
274
|
-
{sub.status === "active" && <button onClick={() =>
|
|
276
|
+
{sub.status === "active" && <button onClick={() => customer.cancelSubscription.execute({ orderId: sub.id })}>Cancel</button>}
|
|
275
277
|
{sub.status === "canceling" && (
|
|
276
|
-
<button onClick={() =>
|
|
278
|
+
<button onClick={() => customer.reactivateSubscription.execute({ orderId: sub.id })}>Undo Cancellation</button>
|
|
277
279
|
)}
|
|
278
280
|
</div>
|
|
279
281
|
))}
|
|
@@ -287,7 +289,7 @@ function AccountPage() {
|
|
|
287
289
|
|
|
288
290
|
<button
|
|
289
291
|
onClick={() =>
|
|
290
|
-
|
|
292
|
+
customer.createRefundTicket.execute({
|
|
291
293
|
paymentId: "PAY_xxx",
|
|
292
294
|
reason: "Product not as described",
|
|
293
295
|
requestedAmount: { amount: "29.00", currency: "USD" },
|
|
@@ -302,14 +304,14 @@ function AccountPage() {
|
|
|
302
304
|
}
|
|
303
305
|
```
|
|
304
306
|
|
|
305
|
-
###
|
|
307
|
+
### Customer Hooks
|
|
306
308
|
|
|
307
|
-
| Hook
|
|
308
|
-
|
|
|
309
|
-
| `
|
|
310
|
-
| `
|
|
311
|
-
| `
|
|
312
|
-
| `
|
|
309
|
+
| Hook | Returns | Auto-fetches? |
|
|
310
|
+
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------- | :--------------------: |
|
|
311
|
+
| `useCustomer()` | `cancelSubscription`, `cancelOnetimeOrder`, `reactivateSubscription`, `createRefundTicket`, `resubmitRefundTicket`, `query` | No — call `.execute()` |
|
|
312
|
+
| `useCustomerOrders()` | `{ onetimeOrders, subscriptionOrders }` with product, payments, billing cycle | Yes |
|
|
313
|
+
| `useCustomerPayments()` | Payment records — amount, status, failure reason | Yes |
|
|
314
|
+
| `useCustomerRefundTickets()` | Refund tickets — status, reason, amount | Yes |
|
|
313
315
|
|
|
314
316
|
Action hooks return `{ execute, isLoading, error, data }`. Data hooks return `{ data, isLoading, error, refetch }`.
|
|
315
317
|
|
|
@@ -317,10 +319,10 @@ Action hooks return `{ execute, isLoading, error, data }`. Data hooks return `{
|
|
|
317
319
|
|
|
318
320
|
Attach your own internal references to a checkout or a refund ticket so cross-system reconciliation does not require Waffo IDs. Two flat keys, both optional (max 128 chars):
|
|
319
321
|
|
|
320
|
-
| Field | Attach via
|
|
321
|
-
| -------------------------------- |
|
|
322
|
-
| `orderMerchantExternalId` | `CheckoutButton` / `useCheckout`
|
|
323
|
-
| `refundTicketMerchantExternalId` | `
|
|
322
|
+
| Field | Attach via | Inherited by |
|
|
323
|
+
| -------------------------------- | ---------------------------------- | --------------------------------------------- |
|
|
324
|
+
| `orderMerchantExternalId` | `CheckoutButton` / `useCheckout` | `Order`, `Payment` (incl. renewals), `Refund` |
|
|
325
|
+
| `refundTicketMerchantExternalId` | `useCustomer().createRefundTicket` | `RefundTicket`, `Refund` |
|
|
324
326
|
|
|
325
327
|
The same field name appears at every layer: prop / hook param, webhook payload (`event.data.orderMerchantExternalId` / `event.data.refundTicketMerchantExternalId`), and GraphQL types. A `refund.*` webhook event carries **both** keys (order key inherited from the originating order).
|
|
326
328
|
|
|
@@ -333,8 +335,8 @@ The same field name appears at every layer: prop / hook param, webhook payload (
|
|
|
333
335
|
|
|
334
336
|
// 2. Attach at refund-ticket creation — value is bound to the ticket and the
|
|
335
337
|
// refund record once the PSP confirms.
|
|
336
|
-
const
|
|
337
|
-
await
|
|
338
|
+
const customer = useCustomer();
|
|
339
|
+
await customer.createRefundTicket.execute({
|
|
338
340
|
paymentId: "PAY_xxx",
|
|
339
341
|
reason: "Product not as described",
|
|
340
342
|
requestedAmount: { amount: "29.00", currency: "USD" },
|
|
@@ -351,8 +353,8 @@ export const POST = Webhook({
|
|
|
351
353
|
},
|
|
352
354
|
});
|
|
353
355
|
|
|
354
|
-
// 4. Query by reference via the
|
|
355
|
-
const result = await
|
|
356
|
+
// 4. Query by reference via the customer's GraphQL surface — same field name on every type.
|
|
357
|
+
const result = await customer.query({
|
|
356
358
|
query: `query ($ref: String!) {
|
|
357
359
|
onetimeOrders(filter: { orderMerchantExternalId: { eq: $ref } }) {
|
|
358
360
|
id status orderMerchantExternalId
|
|
@@ -386,12 +388,12 @@ All merchant hooks return `{ data, isLoading, error, refetch }`.
|
|
|
386
388
|
|
|
387
389
|
## Server Actions
|
|
388
390
|
|
|
389
|
-
| Factory
|
|
390
|
-
|
|
|
391
|
-
| `createCheckoutAction(config)`
|
|
392
|
-
| `
|
|
393
|
-
| `
|
|
394
|
-
| `createMerchantQueryAction(config)`
|
|
391
|
+
| Factory | Returns | Description |
|
|
392
|
+
| ------------------------------------- | ----------------------- | ----------------------------------------------------- |
|
|
393
|
+
| `createCheckoutAction(config)` | `CheckoutAction` | Checkout session creation (anonymous + authenticated) |
|
|
394
|
+
| `createCustomerTokenAction(config)` | `CustomerTokenAction` | Customer session token issuance |
|
|
395
|
+
| `createCustomerSessionAction(config)` | `CustomerSessionAction` | Customer self-service operations |
|
|
396
|
+
| `createMerchantQueryAction(config)` | `MerchantQueryAction` | Merchant GraphQL queries |
|
|
395
397
|
|
|
396
398
|
Import from `@waffo/pancake-nextjs/server`. Config requires `merchantId` and `privateKey`.
|
|
397
399
|
|
|
@@ -407,7 +409,7 @@ Import from `@waffo/pancake-nextjs/server`. Config requires `merchantId` and `pr
|
|
|
407
409
|
|
|
408
410
|
### Types
|
|
409
411
|
|
|
410
|
-
Key types: `PriceInfo`, `BillingDetail`, `WebhookEvent`, `CheckoutAction`, `
|
|
412
|
+
Key types: `PriceInfo`, `BillingDetail`, `WebhookEvent`, `CheckoutAction`, `CustomerTokenAction`, `CustomerSessionAction`, `MerchantQueryAction`, `CustomerConfig`, `CheckoutButtonProps`, `CheckoutMode`, `UseCheckoutReturn`, `UseCustomerReturn`, `CustomerActionState<T>`, `QueryState<T>`, `SalesOverview`, `SubscriptionOverview`, `WebhookConfig`.
|
|
411
413
|
|
|
412
414
|
## Development
|
|
413
415
|
|
|
@@ -429,8 +431,8 @@ src/
|
|
|
429
431
|
├── provider.tsx # <WaffoPancakeProvider> — token lifecycle
|
|
430
432
|
├── checkout-button.tsx # <CheckoutButton> component
|
|
431
433
|
├── use-checkout.ts # useCheckout() — link + anonymous + authenticated
|
|
432
|
-
├── use-
|
|
433
|
-
├── use-
|
|
434
|
+
├── use-customer.ts # useCustomer() — customer actions
|
|
435
|
+
├── use-customer-data.ts # useCustomerOrders / useCustomerPayments / useCustomerRefundTickets
|
|
434
436
|
├── use-merchant-data.ts # useMerchantOrders / useMerchantSales / useMerchantSubscriptions
|
|
435
437
|
├── use-query.ts # Shared useQuery helper
|
|
436
438
|
├── webhook.ts # Webhook() route handler factory
|
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,10 @@ __export(src_exports, {
|
|
|
32
32
|
useBuyerPayments: () => useBuyerPayments,
|
|
33
33
|
useBuyerRefundTickets: () => useBuyerRefundTickets,
|
|
34
34
|
useCheckout: () => useCheckout,
|
|
35
|
+
useCustomer: () => useCustomer,
|
|
36
|
+
useCustomerOrders: () => useCustomerOrders,
|
|
37
|
+
useCustomerPayments: () => useCustomerPayments,
|
|
38
|
+
useCustomerRefundTickets: () => useCustomerRefundTickets,
|
|
35
39
|
useMerchantOrders: () => useMerchantOrders,
|
|
36
40
|
useMerchantSales: () => useMerchantSales,
|
|
37
41
|
useMerchantSubscriptions: () => useMerchantSubscriptions
|
|
@@ -43,23 +47,25 @@ var import_react = require("react");
|
|
|
43
47
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
44
48
|
var PancakeContext = (0, import_react.createContext)(null);
|
|
45
49
|
var REFRESH_BUFFER_MS = 3e4;
|
|
46
|
-
function WaffoPancakeProvider({ buyer, children }) {
|
|
50
|
+
function WaffoPancakeProvider({ customer, buyer, children }) {
|
|
51
|
+
const config = customer ?? buyer;
|
|
52
|
+
if (!config) throw new Error("WaffoPancakeProvider: the `customer` prop is required");
|
|
47
53
|
const tokenRef = (0, import_react.useRef)(null);
|
|
48
54
|
const refreshPromiseRef = (0, import_react.useRef)(null);
|
|
49
|
-
const [
|
|
55
|
+
const [isCustomerReady, setIsCustomerReady] = (0, import_react.useState)(false);
|
|
50
56
|
const refreshToken = (0, import_react.useCallback)(async () => {
|
|
51
|
-
const result = await
|
|
52
|
-
buyerIdentity:
|
|
53
|
-
storeId:
|
|
54
|
-
productId:
|
|
57
|
+
const result = await config.issueToken({
|
|
58
|
+
buyerIdentity: config.identity,
|
|
59
|
+
storeId: config.storeId,
|
|
60
|
+
productId: config.productId
|
|
55
61
|
});
|
|
56
62
|
tokenRef.current = {
|
|
57
63
|
token: result.token,
|
|
58
64
|
expiresAt: new Date(result.expiresAt).getTime()
|
|
59
65
|
};
|
|
60
66
|
return result.token;
|
|
61
|
-
}, [
|
|
62
|
-
const
|
|
67
|
+
}, [config]);
|
|
68
|
+
const getCustomerToken = (0, import_react.useCallback)(async () => {
|
|
63
69
|
const current = tokenRef.current;
|
|
64
70
|
if (current && Date.now() < current.expiresAt - REFRESH_BUFFER_MS) {
|
|
65
71
|
return current.token;
|
|
@@ -72,16 +78,16 @@ function WaffoPancakeProvider({ buyer, children }) {
|
|
|
72
78
|
return refreshPromiseRef.current;
|
|
73
79
|
}, [refreshToken]);
|
|
74
80
|
(0, import_react.useEffect)(() => {
|
|
75
|
-
refreshToken().then(() =>
|
|
81
|
+
refreshToken().then(() => setIsCustomerReady(true)).catch(() => setIsCustomerReady(true));
|
|
76
82
|
}, [refreshToken]);
|
|
77
83
|
const value = (0, import_react.useMemo)(
|
|
78
84
|
() => ({
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
getCustomerToken,
|
|
86
|
+
customerSessionAction: config.sessionAction,
|
|
87
|
+
hasCustomer: true,
|
|
88
|
+
isCustomerReady
|
|
83
89
|
}),
|
|
84
|
-
[
|
|
90
|
+
[getCustomerToken, config.sessionAction, isCustomerReady]
|
|
85
91
|
);
|
|
86
92
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PancakeContext.Provider, { value, children });
|
|
87
93
|
}
|
|
@@ -165,9 +171,9 @@ function CheckoutButton(props) {
|
|
|
165
171
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", onClick: checkout, disabled: disabled || isLoading, className, style, children: isLoading ? loadingChildren ?? children : children });
|
|
166
172
|
}
|
|
167
173
|
|
|
168
|
-
// src/use-
|
|
174
|
+
// src/use-customer.ts
|
|
169
175
|
var import_react3 = require("react");
|
|
170
|
-
function
|
|
176
|
+
function useCustomerAction(actionFn) {
|
|
171
177
|
const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
|
|
172
178
|
const [error, setError] = (0, import_react3.useState)(null);
|
|
173
179
|
const [data, setData] = (0, import_react3.useState)(null);
|
|
@@ -189,34 +195,34 @@ function useBuyerAction(actionFn) {
|
|
|
189
195
|
);
|
|
190
196
|
return { execute, isLoading, error, data };
|
|
191
197
|
}
|
|
192
|
-
function
|
|
198
|
+
function useCustomer() {
|
|
193
199
|
const ctx = (0, import_react3.useContext)(PancakeContext);
|
|
194
|
-
if (!ctx) throw new Error("
|
|
195
|
-
const {
|
|
200
|
+
if (!ctx) throw new Error("useCustomer: must be used within <WaffoPancakeProvider>");
|
|
201
|
+
const { getCustomerToken, customerSessionAction } = ctx;
|
|
196
202
|
const callAction = (0, import_react3.useCallback)(
|
|
197
203
|
async (actionType, params) => {
|
|
198
|
-
const token = await
|
|
199
|
-
return
|
|
204
|
+
const token = await getCustomerToken();
|
|
205
|
+
return customerSessionAction(token, actionType, params);
|
|
200
206
|
},
|
|
201
|
-
[
|
|
207
|
+
[getCustomerToken, customerSessionAction]
|
|
202
208
|
);
|
|
203
|
-
const cancelSubscription =
|
|
209
|
+
const cancelSubscription = useCustomerAction(
|
|
204
210
|
(0, import_react3.useCallback)((params) => callAction("cancelSubscription", params), [callAction])
|
|
205
211
|
);
|
|
206
|
-
const cancelOnetimeOrder =
|
|
212
|
+
const cancelOnetimeOrder = useCustomerAction(
|
|
207
213
|
(0, import_react3.useCallback)((params) => callAction("cancelOnetimeOrder", params), [callAction])
|
|
208
214
|
);
|
|
209
|
-
const reactivateSubscription =
|
|
215
|
+
const reactivateSubscription = useCustomerAction(
|
|
210
216
|
(0, import_react3.useCallback)((params) => callAction("reactivateSubscription", params), [callAction])
|
|
211
217
|
);
|
|
212
|
-
const createRefundTicket =
|
|
218
|
+
const createRefundTicket = useCustomerAction(
|
|
213
219
|
(0, import_react3.useCallback)((params) => callAction("createRefundTicket", params), [callAction])
|
|
214
220
|
);
|
|
215
221
|
const createRefundTicketMapped = (0, import_react3.useMemo)(
|
|
216
222
|
() => ({ ...createRefundTicket, data: createRefundTicket.data?.ticket ?? null }),
|
|
217
223
|
[createRefundTicket]
|
|
218
224
|
);
|
|
219
|
-
const resubmitRefundTicket =
|
|
225
|
+
const resubmitRefundTicket = useCustomerAction(
|
|
220
226
|
(0, import_react3.useCallback)((params) => callAction("resubmitRefundTicket", params), [callAction])
|
|
221
227
|
);
|
|
222
228
|
const resubmitRefundTicketMapped = (0, import_react3.useMemo)(
|
|
@@ -225,10 +231,10 @@ function useBuyer() {
|
|
|
225
231
|
);
|
|
226
232
|
const query = (0, import_react3.useCallback)(
|
|
227
233
|
async (params) => {
|
|
228
|
-
const token = await
|
|
229
|
-
return
|
|
234
|
+
const token = await getCustomerToken();
|
|
235
|
+
return customerSessionAction(token, "query", params);
|
|
230
236
|
},
|
|
231
|
-
[
|
|
237
|
+
[getCustomerToken, customerSessionAction]
|
|
232
238
|
);
|
|
233
239
|
return {
|
|
234
240
|
cancelSubscription,
|
|
@@ -239,8 +245,9 @@ function useBuyer() {
|
|
|
239
245
|
query
|
|
240
246
|
};
|
|
241
247
|
}
|
|
248
|
+
var useBuyer = useCustomer;
|
|
242
249
|
|
|
243
|
-
// src/use-
|
|
250
|
+
// src/use-customer-data.ts
|
|
244
251
|
var import_react5 = require("react");
|
|
245
252
|
|
|
246
253
|
// src/use-query.ts
|
|
@@ -261,8 +268,8 @@ function useQuery(queryFn, ready) {
|
|
|
261
268
|
return { data, isLoading, error, refetch: fetch };
|
|
262
269
|
}
|
|
263
270
|
|
|
264
|
-
// src/use-
|
|
265
|
-
var
|
|
271
|
+
// src/use-customer-data.ts
|
|
272
|
+
var CUSTOMER_ORDERS_QUERY = `query {
|
|
266
273
|
onetimeOrders(limit: 50) {
|
|
267
274
|
id status currency buyerEmail createdAt
|
|
268
275
|
product { id name }
|
|
@@ -274,12 +281,12 @@ var BUYER_ORDERS_QUERY = `query {
|
|
|
274
281
|
payments { id status snapshotDisplayAmount snapshotDisplayCurrency createdAt }
|
|
275
282
|
}
|
|
276
283
|
}`;
|
|
277
|
-
var
|
|
284
|
+
var CUSTOMER_PAYMENTS_QUERY = `query {
|
|
278
285
|
payments(limit: 50) {
|
|
279
286
|
id orderId status snapshotDisplayAmount snapshotDisplayCurrency failureReason createdAt
|
|
280
287
|
}
|
|
281
288
|
}`;
|
|
282
|
-
var
|
|
289
|
+
var CUSTOMER_REFUND_TICKETS_QUERY = `query {
|
|
283
290
|
refundTickets(limit: 50) {
|
|
284
291
|
id status versionNumber
|
|
285
292
|
versionData {
|
|
@@ -289,28 +296,31 @@ var BUYER_REFUND_TICKETS_QUERY = `query {
|
|
|
289
296
|
createdAt
|
|
290
297
|
}
|
|
291
298
|
}`;
|
|
292
|
-
function
|
|
299
|
+
function useCustomerQuery(query) {
|
|
293
300
|
const ctx = (0, import_react5.useContext)(PancakeContext);
|
|
294
|
-
if (!ctx) throw new Error("
|
|
295
|
-
const {
|
|
301
|
+
if (!ctx) throw new Error("Customer data hook: must be used within <WaffoPancakeProvider>");
|
|
302
|
+
const { getCustomerToken, customerSessionAction, isCustomerReady } = ctx;
|
|
296
303
|
const queryFn = (0, import_react5.useCallback)(async () => {
|
|
297
|
-
const token = await
|
|
298
|
-
const result = await
|
|
304
|
+
const token = await getCustomerToken();
|
|
305
|
+
const result = await customerSessionAction(token, "query", { query });
|
|
299
306
|
return result.data;
|
|
300
|
-
}, [
|
|
301
|
-
return useQuery(queryFn,
|
|
307
|
+
}, [getCustomerToken, customerSessionAction, query]);
|
|
308
|
+
return useQuery(queryFn, isCustomerReady);
|
|
302
309
|
}
|
|
303
|
-
function
|
|
304
|
-
return
|
|
310
|
+
function useCustomerOrders() {
|
|
311
|
+
return useCustomerQuery(CUSTOMER_ORDERS_QUERY);
|
|
305
312
|
}
|
|
306
|
-
function
|
|
307
|
-
const result =
|
|
313
|
+
function useCustomerPayments() {
|
|
314
|
+
const result = useCustomerQuery(CUSTOMER_PAYMENTS_QUERY);
|
|
308
315
|
return { ...result, data: result.data?.payments ?? null };
|
|
309
316
|
}
|
|
310
|
-
function
|
|
311
|
-
const result =
|
|
317
|
+
function useCustomerRefundTickets() {
|
|
318
|
+
const result = useCustomerQuery(CUSTOMER_REFUND_TICKETS_QUERY);
|
|
312
319
|
return { ...result, data: result.data?.refundTickets ?? null };
|
|
313
320
|
}
|
|
321
|
+
var useBuyerOrders = useCustomerOrders;
|
|
322
|
+
var useBuyerPayments = useCustomerPayments;
|
|
323
|
+
var useBuyerRefundTickets = useCustomerRefundTickets;
|
|
314
324
|
|
|
315
325
|
// src/use-merchant-data.ts
|
|
316
326
|
var import_react6 = require("react");
|
|
@@ -464,6 +474,10 @@ var import_pancake_ts2 = require("@waffo/pancake-ts");
|
|
|
464
474
|
useBuyerPayments,
|
|
465
475
|
useBuyerRefundTickets,
|
|
466
476
|
useCheckout,
|
|
477
|
+
useCustomer,
|
|
478
|
+
useCustomerOrders,
|
|
479
|
+
useCustomerPayments,
|
|
480
|
+
useCustomerRefundTickets,
|
|
467
481
|
useMerchantOrders,
|
|
468
482
|
useMerchantSales,
|
|
469
483
|
useMerchantSubscriptions
|