@waffo/pancake-ts 0.1.7 → 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.
@@ -0,0 +1,877 @@
1
+ # API Reference
2
+
3
+ Complete reference for all `@waffo/pancake-ts` resources, parameters, and return types.
4
+
5
+ > **Conventions**:
6
+ > - All amounts are in the **smallest currency unit** (e.g. 999 = $9.99 USD, 4500 = ¥4500 JPY)
7
+ > - All timestamps are **ISO 8601 UTC** strings
8
+ > - Product updates follow **immutable versioning** — each update creates a new version, skipped if content is unchanged
9
+ > - The **publish** flow promotes a test version to production
10
+
11
+ ---
12
+
13
+ ## Auth
14
+
15
+ ### `client.auth.issueSessionToken(params)`
16
+
17
+ Issue a buyer session token (JWT) for storefront authentication.
18
+
19
+ ```typescript
20
+ const { token, expiresAt } = await client.auth.issueSessionToken({
21
+ storeId: "STO_xxx",
22
+ buyerIdentity: "customer@example.com",
23
+ });
24
+ ```
25
+
26
+ **Parameters `IssueSessionTokenParams`**:
27
+
28
+ | Field | Type | Required | Description |
29
+ |-------|------|----------|-------------|
30
+ | `storeId` | `string` | Yes | Store ID |
31
+ | `buyerIdentity` | `string` | Yes | Buyer identity (email or merchant-defined identifier) |
32
+
33
+ **Returns `SessionToken`**:
34
+
35
+ | Field | Type | Description |
36
+ |-------|------|-------------|
37
+ | `token` | `string` | JWT token string |
38
+ | `expiresAt` | `string` | Token expiration time |
39
+
40
+ ---
41
+
42
+ ## Stores
43
+
44
+ ### `client.stores.create(params)`
45
+
46
+ Create a store. The URL slug is auto-generated from the name.
47
+
48
+ ```typescript
49
+ const { store } = await client.stores.create({ name: "My Store" });
50
+ ```
51
+
52
+ **Parameters `CreateStoreParams`**:
53
+
54
+ | Field | Type | Required | Description |
55
+ |-------|------|----------|-------------|
56
+ | `name` | `string` | Yes | Store name (1–48 characters, trimmed automatically) |
57
+
58
+ **Returns `{ store: Store }`**
59
+
60
+ ### `client.stores.update(params)`
61
+
62
+ Update store settings including webhook endpoints, notification preferences, and checkout page styling.
63
+
64
+ ```typescript
65
+ const { store } = await client.stores.update({
66
+ id: "STO_xxx",
67
+ name: "Updated Name",
68
+ supportEmail: "help@example.com",
69
+ webhookSettings: {
70
+ testWebhookUrl: "https://example.com/webhooks",
71
+ prodWebhookUrl: null,
72
+ testEvents: ["order.completed", "subscription.created"],
73
+ prodEvents: [],
74
+ },
75
+ notificationSettings: {
76
+ emailOrderConfirmation: true,
77
+ emailSubscriptionConfirmation: true,
78
+ emailSubscriptionCycled: true,
79
+ emailSubscriptionCanceled: true,
80
+ emailSubscriptionRevoked: true,
81
+ emailSubscriptionPastDue: true,
82
+ notifyNewOrders: true,
83
+ notifyNewSubscriptions: true,
84
+ },
85
+ checkoutSettings: {
86
+ light: {
87
+ checkoutLogo: null,
88
+ checkoutColorPrimary: "#000000",
89
+ checkoutColorBackground: "#ffffff",
90
+ checkoutColorCard: "#f5f5f5",
91
+ checkoutColorText: "#000000",
92
+ checkoutBorderRadius: "8px",
93
+ },
94
+ dark: {
95
+ checkoutLogo: null,
96
+ checkoutColorPrimary: "#ffffff",
97
+ checkoutColorBackground: "#1a1a1a",
98
+ checkoutColorCard: "#2a2a2a",
99
+ checkoutColorText: "#ffffff",
100
+ checkoutBorderRadius: "8px",
101
+ },
102
+ },
103
+ });
104
+ ```
105
+
106
+ **Parameters `UpdateStoreParams`**:
107
+
108
+ | Field | Type | Required | Description |
109
+ |-------|------|----------|-------------|
110
+ | `id` | `string` | Yes | Store ID |
111
+ | `name` | `string` | No | Store name (1–100 characters) |
112
+ | `status` | `EntityStatus` | No | Store status |
113
+ | `logo` | `string \| null` | No | Logo (Base64 encoded image) |
114
+ | `supportEmail` | `string \| null` | No | Support email address |
115
+ | `website` | `string \| null` | No | Store website URL |
116
+ | `webhookSettings` | `WebhookSettings \| null` | No | Webhook endpoint configuration (test/prod URLs and subscribed event types) |
117
+ | `notificationSettings` | `NotificationSettings \| null` | No | Email notification preferences |
118
+ | `checkoutSettings` | `CheckoutSettings \| null` | No | Checkout page theme (light/dark) |
119
+
120
+ **Returns `{ store: Store }`**
121
+
122
+ ### `client.stores.delete(params)`
123
+
124
+ Soft-delete a store. Only the store owner can perform this operation.
125
+
126
+ ```typescript
127
+ const { store } = await client.stores.delete({ id: "STO_xxx" });
128
+ ```
129
+
130
+ **Parameters `DeleteStoreParams`**:
131
+
132
+ | Field | Type | Required | Description |
133
+ |-------|------|----------|-------------|
134
+ | `id` | `string` | Yes | Store ID |
135
+
136
+ **Returns `{ store: Store }`**
137
+
138
+ ---
139
+
140
+ ## Store Merchants
141
+
142
+ > Coming soon — endpoints currently return 501.
143
+
144
+ ### `client.storeMerchants.add(params)`
145
+
146
+ Add a merchant to a store with a specified role.
147
+
148
+ ```typescript
149
+ const result = await client.storeMerchants.add({
150
+ storeId: "STO_xxx",
151
+ email: "member@example.com",
152
+ role: "admin",
153
+ });
154
+ ```
155
+
156
+ **Parameters `AddMerchantParams`**:
157
+
158
+ | Field | Type | Required | Description |
159
+ |-------|------|----------|-------------|
160
+ | `storeId` | `string` | Yes | Store ID |
161
+ | `email` | `string` | Yes | Merchant email |
162
+ | `role` | `"admin" \| "member"` | Yes | Role to assign |
163
+
164
+ **Returns `AddMerchantResult`**:
165
+
166
+ | Field | Type | Description |
167
+ |-------|------|-------------|
168
+ | `storeId` | `string` | Store ID |
169
+ | `merchantId` | `string` | Merchant ID |
170
+ | `email` | `string` | Merchant email |
171
+ | `role` | `string` | Assigned role |
172
+ | `status` | `string` | Membership status |
173
+ | `addedAt` | `string` | Timestamp when added |
174
+
175
+ ### `client.storeMerchants.remove(params)`
176
+
177
+ Remove a merchant from a store.
178
+
179
+ ```typescript
180
+ const result = await client.storeMerchants.remove({
181
+ storeId: "STO_xxx",
182
+ merchantId: "MER_xxx",
183
+ });
184
+ ```
185
+
186
+ **Parameters `RemoveMerchantParams`**:
187
+
188
+ | Field | Type | Required | Description |
189
+ |-------|------|----------|-------------|
190
+ | `storeId` | `string` | Yes | Store ID |
191
+ | `merchantId` | `string` | Yes | Merchant ID |
192
+
193
+ **Returns `RemoveMerchantResult`**:
194
+
195
+ | Field | Type | Description |
196
+ |-------|------|-------------|
197
+ | `message` | `string` | Operation message |
198
+ | `removedAt` | `string` | Timestamp when removed |
199
+
200
+ ### `client.storeMerchants.updateRole(params)`
201
+
202
+ Update a merchant's role within a store.
203
+
204
+ ```typescript
205
+ const result = await client.storeMerchants.updateRole({
206
+ storeId: "STO_xxx",
207
+ merchantId: "MER_xxx",
208
+ role: "member",
209
+ });
210
+ ```
211
+
212
+ **Parameters `UpdateRoleParams`**:
213
+
214
+ | Field | Type | Required | Description |
215
+ |-------|------|----------|-------------|
216
+ | `storeId` | `string` | Yes | Store ID |
217
+ | `merchantId` | `string` | Yes | Merchant ID |
218
+ | `role` | `"admin" \| "member"` | Yes | New role |
219
+
220
+ **Returns `UpdateRoleResult`**:
221
+
222
+ | Field | Type | Description |
223
+ |-------|------|-------------|
224
+ | `storeId` | `string` | Store ID |
225
+ | `merchantId` | `string` | Merchant ID |
226
+ | `role` | `string` | Updated role |
227
+ | `updatedAt` | `string` | Timestamp when updated |
228
+
229
+ ---
230
+
231
+ ## Onetime Products
232
+
233
+ ### `client.onetimeProducts.create(params)`
234
+
235
+ Create a one-time product with multi-currency pricing.
236
+
237
+ ```typescript
238
+ import { TaxCategory } from "@waffo/pancake-ts";
239
+
240
+ const { product } = await client.onetimeProducts.create({
241
+ storeId: "STO_xxx",
242
+ name: "E-Book: TypeScript Handbook",
243
+ description: "Complete TypeScript guide for developers",
244
+ prices: {
245
+ USD: { amount: "29.00", taxCategory: TaxCategory.DigitalGoods },
246
+ EUR: { amount: "27.00", taxCategory: TaxCategory.DigitalGoods },
247
+ JPY: { amount: "4500", taxCategory: TaxCategory.DigitalGoods },
248
+ },
249
+ media: [{ type: "image", url: "https://example.com/cover.jpg", alt: "Book cover" }],
250
+ successUrl: "https://example.com/thank-you",
251
+ metadata: { sku: "ebook-ts-001" },
252
+ });
253
+ ```
254
+
255
+ **Parameters `CreateOnetimeProductParams`**:
256
+
257
+ | Field | Type | Required | Description |
258
+ |-------|------|----------|-------------|
259
+ | `storeId` | `string` | Yes | Store ID |
260
+ | `name` | `string` | Yes | Product name |
261
+ | `prices` | `Prices` | Yes | Multi-currency prices (`Record<string, PriceInfo>`) |
262
+ | `description` | `string` | No | Product description |
263
+ | `media` | `MediaItem[]` | No | Media assets (images, videos) |
264
+ | `successUrl` | `string` | No | Redirect URL after successful payment |
265
+ | `metadata` | `Record<string, unknown>` | No | Custom metadata |
266
+
267
+ **Returns `{ product: OnetimeProductDetail }`**
268
+
269
+ ### `client.onetimeProducts.update(params)`
270
+
271
+ Update a one-time product. Creates a new immutable version; skips if content is unchanged.
272
+
273
+ ```typescript
274
+ const { product } = await client.onetimeProducts.update({
275
+ id: "PROD_xxx",
276
+ name: "E-Book: TypeScript Handbook v2",
277
+ prices: { USD: { amount: "39.00", taxCategory: "digital_goods" } },
278
+ });
279
+ ```
280
+
281
+ **Parameters `UpdateOnetimeProductParams`**:
282
+
283
+ | Field | Type | Required | Description |
284
+ |-------|------|----------|-------------|
285
+ | `id` | `string` | Yes | Product ID |
286
+ | `name` | `string` | Yes | Product name |
287
+ | `prices` | `Prices` | Yes | Multi-currency prices |
288
+ | `description` | `string` | No | Product description |
289
+ | `media` | `MediaItem[]` | No | Media assets |
290
+ | `successUrl` | `string` | No | Redirect URL after successful payment |
291
+ | `metadata` | `Record<string, unknown>` | No | Custom metadata |
292
+
293
+ **Returns `{ product: OnetimeProductDetail }`**
294
+
295
+ ### `client.onetimeProducts.publish(params)`
296
+
297
+ Publish the test version to production.
298
+
299
+ ```typescript
300
+ const { product } = await client.onetimeProducts.publish({ id: "PROD_xxx" });
301
+ ```
302
+
303
+ **Parameters `PublishOnetimeProductParams`**:
304
+
305
+ | Field | Type | Required | Description |
306
+ |-------|------|----------|-------------|
307
+ | `id` | `string` | Yes | Product ID |
308
+
309
+ **Returns `{ product: OnetimeProductDetail }`**
310
+
311
+ ### `client.onetimeProducts.updateStatus(params)`
312
+
313
+ Activate or deactivate a product.
314
+
315
+ ```typescript
316
+ import { ProductVersionStatus } from "@waffo/pancake-ts";
317
+
318
+ const { product } = await client.onetimeProducts.updateStatus({
319
+ id: "PROD_xxx",
320
+ status: ProductVersionStatus.Inactive,
321
+ });
322
+ ```
323
+
324
+ **Parameters `UpdateOnetimeStatusParams`**:
325
+
326
+ | Field | Type | Required | Description |
327
+ |-------|------|----------|-------------|
328
+ | `id` | `string` | Yes | Product ID |
329
+ | `status` | `ProductVersionStatus` | Yes | `Active` or `Inactive` |
330
+
331
+ **Returns `{ product: OnetimeProductDetail }`**
332
+
333
+ ---
334
+
335
+ ## Subscription Products
336
+
337
+ ### `client.subscriptionProducts.create(params)`
338
+
339
+ Create a subscription product with a billing period and multi-currency pricing.
340
+
341
+ ```typescript
342
+ import { BillingPeriod, TaxCategory } from "@waffo/pancake-ts";
343
+
344
+ const { product } = await client.subscriptionProducts.create({
345
+ storeId: "STO_xxx",
346
+ name: "Pro Plan",
347
+ billingPeriod: BillingPeriod.Monthly,
348
+ prices: { USD: { amount: "9.99", taxCategory: TaxCategory.SaaS } },
349
+ description: "Unlimited access to all features",
350
+ });
351
+ ```
352
+
353
+ **Parameters `CreateSubscriptionProductParams`**:
354
+
355
+ | Field | Type | Required | Description |
356
+ |-------|------|----------|-------------|
357
+ | `storeId` | `string` | Yes | Store ID |
358
+ | `name` | `string` | Yes | Product name |
359
+ | `billingPeriod` | `BillingPeriod` | Yes | Billing period (`Weekly` / `Monthly` / `Quarterly` / `Yearly`) |
360
+ | `prices` | `Prices` | Yes | Multi-currency prices |
361
+ | `description` | `string` | No | Product description |
362
+ | `media` | `MediaItem[]` | No | Media assets |
363
+ | `successUrl` | `string` | No | Redirect URL after successful payment |
364
+ | `metadata` | `Record<string, unknown>` | No | Custom metadata |
365
+
366
+ **Returns `{ product: SubscriptionProductDetail }`**
367
+
368
+ ### `client.subscriptionProducts.update(params)`
369
+
370
+ Update a subscription product. Creates a new immutable version; skips if unchanged.
371
+
372
+ ```typescript
373
+ const { product } = await client.subscriptionProducts.update({
374
+ id: "PROD_xxx",
375
+ name: "Pro Plan v2",
376
+ billingPeriod: BillingPeriod.Monthly,
377
+ prices: { USD: { amount: "14.99", taxCategory: "saas" } },
378
+ });
379
+ ```
380
+
381
+ **Parameters `UpdateSubscriptionProductParams`**: Same as create, but `id` replaces `storeId`.
382
+
383
+ **Returns `{ product: SubscriptionProductDetail }`**
384
+
385
+ ### `client.subscriptionProducts.publish(params)`
386
+
387
+ Publish the test version to production.
388
+
389
+ ```typescript
390
+ const { product } = await client.subscriptionProducts.publish({ id: "PROD_xxx" });
391
+ ```
392
+
393
+ **Returns `{ product: SubscriptionProductDetail }`**
394
+
395
+ ### `client.subscriptionProducts.updateStatus(params)`
396
+
397
+ Activate or deactivate a subscription product.
398
+
399
+ ```typescript
400
+ const { product } = await client.subscriptionProducts.updateStatus({
401
+ id: "PROD_xxx",
402
+ status: ProductVersionStatus.Active,
403
+ });
404
+ ```
405
+
406
+ **Returns `{ product: SubscriptionProductDetail }`**
407
+
408
+ ---
409
+
410
+ ## Subscription Product Groups
411
+
412
+ Groups enable **shared trial periods** and **plan switching** across related subscription products (e.g. Free / Pro / Enterprise tiers).
413
+
414
+ > **Note**: Group IDs are UUIDs (not Short IDs). The `id` field in responses and the `id` parameter in requests use raw UUID format.
415
+
416
+ ### `client.subscriptionProductGroups.create(params)`
417
+
418
+ ```typescript
419
+ const { group } = await client.subscriptionProductGroups.create({
420
+ storeId: "STO_xxx",
421
+ name: "Pro Plans",
422
+ description: "All Pro tier plans",
423
+ rules: { sharedTrial: true },
424
+ productIds: ["PROD_aaa", "PROD_bbb"],
425
+ });
426
+ ```
427
+
428
+ **Parameters `CreateSubscriptionProductGroupParams`**:
429
+
430
+ | Field | Type | Required | Description |
431
+ |-------|------|----------|-------------|
432
+ | `storeId` | `string` | Yes | Store ID |
433
+ | `name` | `string` | Yes | Group name |
434
+ | `description` | `string` | No | Group description |
435
+ | `rules` | `GroupRules` | No | Group rules (e.g. `{ sharedTrial: true }`) |
436
+ | `productIds` | `string[]` | No | Subscription product IDs to include |
437
+
438
+ **Returns `{ group: SubscriptionProductGroup }`**
439
+
440
+ ### `client.subscriptionProductGroups.update(params)`
441
+
442
+ Update a group. `productIds` is a **full replacement** (not a merge).
443
+
444
+ ```typescript
445
+ const { group } = await client.subscriptionProductGroups.update({
446
+ id: "spg_xxx",
447
+ productIds: ["PROD_aaa", "PROD_bbb", "PROD_ccc"],
448
+ });
449
+ ```
450
+
451
+ **Returns `{ group: SubscriptionProductGroup }`**
452
+
453
+ ### `client.subscriptionProductGroups.delete(params)`
454
+
455
+ Hard-delete a group.
456
+
457
+ ```typescript
458
+ const { group } = await client.subscriptionProductGroups.delete({ id: "spg_xxx" });
459
+ ```
460
+
461
+ **Returns `{ group: SubscriptionProductGroup }`**
462
+
463
+ ### `client.subscriptionProductGroups.publish(params)`
464
+
465
+ Publish a test-environment group to production (upsert).
466
+
467
+ ```typescript
468
+ const { group } = await client.subscriptionProductGroups.publish({ id: "spg_xxx" });
469
+ ```
470
+
471
+ **Returns `{ group: SubscriptionProductGroup }`**
472
+
473
+ ---
474
+
475
+ ## Orders
476
+
477
+ ### `client.orders.cancelSubscription(params)`
478
+
479
+ Cancel a subscription order. The resulting status depends on the current order state:
480
+
481
+ | Current Status | Result | Behavior |
482
+ |---------------|--------|----------|
483
+ | `pending` | `canceled` | Immediate cancellation |
484
+ | `active` / `trialing` | `canceling` | PSP cancellation initiated; webhook updates status later |
485
+
486
+ ```typescript
487
+ const { orderId, status } = await client.orders.cancelSubscription({
488
+ orderId: "ORD_xxx",
489
+ });
490
+ // status: "canceled" or "canceling"
491
+ ```
492
+
493
+ **Parameters `CancelSubscriptionParams`**:
494
+
495
+ | Field | Type | Required | Description |
496
+ |-------|------|----------|-------------|
497
+ | `orderId` | `string` | Yes | Order ID |
498
+
499
+ **Returns `CancelSubscriptionResult`**:
500
+
501
+ | Field | Type | Description |
502
+ |-------|------|-------------|
503
+ | `orderId` | `string` | Order ID |
504
+ | `status` | `string` | Resulting status (`"canceled"` or `"canceling"`) |
505
+
506
+ ---
507
+
508
+ ## Buyer Self-Service
509
+
510
+ Issue a session token and create a buyer session to let buyers manage their own orders.
511
+
512
+ ### `client.buyer(token)`
513
+
514
+ Create a buyer session from a session token issued by `client.auth.issueSessionToken()`.
515
+
516
+ ```typescript
517
+ const { token } = await client.auth.issueSessionToken({
518
+ storeId: "STO_xxx",
519
+ buyerIdentity: "customer@example.com",
520
+ });
521
+ const buyer = client.buyer(token);
522
+ ```
523
+
524
+ ### `buyer.cancelSubscription(params)`
525
+
526
+ | Field | Type | Required | Description |
527
+ |-------|------|----------|-------------|
528
+ | `orderId` | `string` | Yes | Subscription order ID |
529
+
530
+ **Returns `CancelSubscriptionResult`**: `{ orderId, status }` — status is `"canceling"` (active) or `"canceled"` (pending)
531
+
532
+ ### `buyer.cancelOnetimeOrder(params)`
533
+
534
+ | Field | Type | Required | Description |
535
+ |-------|------|----------|-------------|
536
+ | `orderId` | `string` | Yes | One-time order ID |
537
+
538
+ **Returns `CancelOnetimeOrderResult`**: `{ orderId, status }` — status is `"canceled"`
539
+
540
+ ### `buyer.reactivateSubscription(params)`
541
+
542
+ | Field | Type | Required | Description |
543
+ |-------|------|----------|-------------|
544
+ | `orderId` | `string` | Yes | Subscription order ID (must be in `canceling` status) |
545
+
546
+ **Returns `ReactivateSubscriptionResult`**: `{ orderId, status }` — status is `"active"`
547
+
548
+ ### `buyer.createRefundTicket(params)`
549
+
550
+ | Field | Type | Required | Description |
551
+ |-------|------|----------|-------------|
552
+ | `paymentId` | `string` | Yes | Payment ID to refund |
553
+ | `reason` | `string` | Yes | Reason for the refund request |
554
+ | `requestedAmount` | `RequestedAmount` | Yes | Refund amount (`{ amount, currency }`) |
555
+ | `metadata` | `Record<string, unknown>` | No | Custom metadata |
556
+
557
+ **`RequestedAmount`**:
558
+
559
+ | Field | Type | Description |
560
+ |-------|------|-------------|
561
+ | `amount` | `string` | Amount in display format (e.g., `"29.00"`) |
562
+ | `currency` | `string` | Currency code (ISO 4217) |
563
+
564
+ **Returns `{ ticket: RefundTicket }`**
565
+
566
+ ### `buyer.resubmitRefundTicket(params)`
567
+
568
+ | Field | Type | Required | Description |
569
+ |-------|------|----------|-------------|
570
+ | `ticketId` | `string` | Yes | Existing ticket ID |
571
+ | `paymentId` | `string` | Yes | Payment ID |
572
+ | `reason` | `string` | Yes | Updated reason |
573
+ | `requestedAmount` | `RequestedAmount` | Yes | Updated refund amount |
574
+
575
+ **Returns `{ ticket: RefundTicket }`**
576
+
577
+ ### `buyer.graphql.query<T>(params)`
578
+
579
+ Same parameters as `client.graphql.query<T>()` but scoped to the buyer's own data via session token.
580
+
581
+ | Field | Type | Required | Description |
582
+ |-------|------|----------|-------------|
583
+ | `query` | `string` | Yes | GraphQL query string |
584
+ | `variables` | `Record<string, unknown>` | No | Query variables |
585
+
586
+ **Returns `GraphQLResponse<T>`**: `{ data, errors? }`
587
+
588
+ ---
589
+
590
+ ## Checkout
591
+
592
+ Waffo supports two checkout modes based on whether the merchant knows the buyer's identity at checkout time:
593
+
594
+ - **Authenticated** — the merchant has a user system or collects buyer info before checkout. The buyer's identity is provided upfront, the checkout form is pre-filled, and a session token is automatically issued.
595
+ - **Anonymous** — the buyer arrives via a template store or shared link with no prior context. They fill in billing details manually on the checkout page.
596
+
597
+ > **Authenticated checkout is recommended.** The key advantage: the order is bound to the `buyerIdentity` you provide — a **merchant-controlled stable identifier**. Even if the buyer changes the email on the checkout form, the order stays tied to your identifier. In anonymous mode, the buyer self-reports their email, and a different address means a different user — **previous orders become unlinked** and **subscription trial periods can be exploited** (new email = new user = fresh trial). Additionally, anonymous checkout only supports creating orders — buyers cannot cancel orders, manage subscriptions, or submit refund tickets afterward.
598
+
599
+ For advanced use cases, the low-level `createSession()` is also available.
600
+
601
+ ### `client.checkout.authenticated.create(params)`
602
+
603
+ Authenticated checkout — the merchant provides buyer identity. The SDK issues a session token, creates a checkout session, and returns a checkout URL with the token appended as a URL fragment (`#token=...`). The checkout page pre-fills buyer information from the token.
604
+
605
+ Internally calls `POST /v1/actions/auth/issue-session-token` and `POST /v1/actions/checkout/create-session` in parallel.
606
+
607
+ ```typescript
608
+ // One-time product with buyer identity
609
+ const result = await client.checkout.authenticated.create({
610
+ storeId: "STO_xxx",
611
+ productId: "PROD_xxx",
612
+ productType: "onetime",
613
+ currency: "USD",
614
+ buyerIdentity: "customer@example.com",
615
+ successUrl: "https://example.com/thank-you",
616
+ });
617
+ // => redirect buyer to result.checkoutUrl (includes #token=...)
618
+
619
+ // Subscription with trial and billing detail
620
+ const subResult = await client.checkout.authenticated.create({
621
+ storeId: "STO_xxx",
622
+ productId: "PROD_yyy",
623
+ productType: "subscription",
624
+ currency: "USD",
625
+ buyerIdentity: "customer@example.com",
626
+ withTrial: true,
627
+ billingDetail: { country: "US", isBusiness: false, state: "CA", postcode: "94105" },
628
+ });
629
+ ```
630
+
631
+ **Parameters `AuthenticatedCheckoutParams`**:
632
+
633
+ | Field | Type | Required | Description |
634
+ |-------|------|----------|-------------|
635
+ | `storeId` | `string` | Yes | Store ID |
636
+ | `productId` | `string` | Yes | Product ID |
637
+ | `productType` | `CheckoutSessionProductType` | Yes | `"onetime"` or `"subscription"` |
638
+ | `currency` | `string` | Yes | Currency code (ISO 4217) |
639
+ | `buyerIdentity` | `string` | Yes | Buyer identity (email or merchant-defined identifier) |
640
+ | `buyerEmail` | `string` | No | Pre-filled buyer email (defaults to `buyerIdentity`) |
641
+ | `billingDetail` | `BillingDetail` | No | Pre-filled billing details (country, tax ID, etc.) |
642
+ | `priceSnapshot` | `PriceInfo` | No | Price snapshot override (reads from DB if omitted) |
643
+ | `withTrial` | `boolean` | No | Enable trial period (subscription only) |
644
+ | `successUrl` | `string` | No | Redirect URL after successful payment |
645
+ | `expiresInSeconds` | `number` | No | Session expiry in seconds (default: 45 minutes) |
646
+ | `darkMode` | `boolean` | No | Dark mode override (true=dark, false=light, omit=store default) |
647
+ | `metadata` | `Record<string, string>` | No | Custom metadata |
648
+
649
+ **Returns `AuthenticatedCheckoutResult`**:
650
+
651
+ | Field | Type | Description |
652
+ |-------|------|-------------|
653
+ | `sessionId` | `string` | Session ID |
654
+ | `checkoutUrl` | `string` | Checkout URL with `#token=...` appended |
655
+ | `expiresAt` | `string` | Session expiration time |
656
+ | `token` | `string` | Issued JWT token |
657
+ | `tokenExpiresAt` | `string` | Token expiration time |
658
+
659
+ ### `client.checkout.anonymous.create(params)`
660
+
661
+ Anonymous checkout — visitor enters without a session token. The buyer fills in billing details manually on the checkout page.
662
+
663
+ Internally calls `POST /v1/actions/checkout/create-session`.
664
+
665
+ ```typescript
666
+ const result = await client.checkout.anonymous.create({
667
+ storeId: "STO_xxx",
668
+ productId: "PROD_xxx",
669
+ productType: "onetime",
670
+ currency: "USD",
671
+ });
672
+ // => redirect buyer to result.checkoutUrl (buyer fills form manually)
673
+
674
+ // With price snapshot override
675
+ const snapshotResult = await client.checkout.anonymous.create({
676
+ storeId: "STO_xxx",
677
+ productId: "PROD_xxx",
678
+ productType: "onetime",
679
+ currency: "USD",
680
+ priceSnapshot: { amount: "19.99", taxCategory: "digital_goods" },
681
+ });
682
+ ```
683
+
684
+ **Parameters `AnonymousCheckoutParams`**:
685
+
686
+ | Field | Type | Required | Description |
687
+ |-------|------|----------|-------------|
688
+ | `storeId` | `string` | Yes | Store ID |
689
+ | `productId` | `string` | Yes | Product ID |
690
+ | `productType` | `CheckoutSessionProductType` | Yes | `"onetime"` or `"subscription"` |
691
+ | `currency` | `string` | Yes | Currency code (ISO 4217) |
692
+ | `priceSnapshot` | `PriceInfo` | No | Price snapshot override (reads from DB if omitted) |
693
+ | `withTrial` | `boolean` | No | Enable trial period (subscription only) |
694
+ | `successUrl` | `string` | No | Redirect URL after successful payment |
695
+ | `expiresInSeconds` | `number` | No | Session expiry in seconds (default: 45 minutes) |
696
+ | `darkMode` | `boolean` | No | Dark mode override (true=dark, false=light, omit=store default) |
697
+ | `metadata` | `Record<string, string>` | No | Custom metadata |
698
+
699
+ **Returns `CheckoutSessionResult`**:
700
+
701
+ | Field | Type | Description |
702
+ |-------|------|-------------|
703
+ | `sessionId` | `string` | Session ID |
704
+ | `checkoutUrl` | `string` | Hosted checkout page URL |
705
+ | `expiresAt` | `string` | Session expiration time |
706
+
707
+ ### `client.checkout.createSession(params)` (low-level)
708
+
709
+ Create a checkout session directly. For most use cases, prefer `checkout.authenticated.create()` or `checkout.anonymous.create()`.
710
+
711
+ ```typescript
712
+ const session = await client.checkout.createSession({
713
+ storeId: "STO_xxx",
714
+ productId: "PROD_xxx",
715
+ productType: "onetime",
716
+ currency: "USD",
717
+ buyerEmail: "customer@example.com",
718
+ });
719
+ ```
720
+
721
+ **Parameters `CreateCheckoutSessionParams`**:
722
+
723
+ | Field | Type | Required | Description |
724
+ |-------|------|----------|-------------|
725
+ | `storeId` | `string` | Yes | Store ID |
726
+ | `productId` | `string` | Yes | Product ID |
727
+ | `productType` | `CheckoutSessionProductType` | Yes | `"onetime"` or `"subscription"` |
728
+ | `currency` | `string` | Yes | Currency code (ISO 4217) |
729
+ | `priceSnapshot` | `PriceInfo` | No | Price snapshot override (reads from DB if omitted) |
730
+ | `withTrial` | `boolean` | No | Enable trial period (subscription only) |
731
+ | `buyerEmail` | `string` | No | Pre-filled buyer email |
732
+ | `billingDetail` | `BillingDetail` | No | Pre-filled billing details (country, tax ID, etc.) |
733
+ | `successUrl` | `string` | No | Redirect URL after successful payment |
734
+ | `expiresInSeconds` | `number` | No | Session expiry in seconds (default: 45 minutes) |
735
+ | `darkMode` | `boolean` | No | Dark mode override |
736
+ | `metadata` | `Record<string, string>` | No | Custom metadata |
737
+
738
+ **`BillingDetail` fields**:
739
+
740
+ | Field | Type | Required | Description |
741
+ |-------|------|----------|-------------|
742
+ | `country` | `string` | Yes | Country code (ISO 3166-1 alpha-2) |
743
+ | `isBusiness` | `boolean` | Yes | Whether this is a business purchase |
744
+ | `postcode` | `string` | No | Postal / ZIP code |
745
+ | `state` | `string` | Conditional | State / province code (required when `country` is `US` or `CA`) |
746
+ | `businessName` | `string` | Conditional | Business name (required when `isBusiness` is `true`) |
747
+ | `taxId` | `string` | Conditional | Tax ID / VAT number (required for EU countries when `isBusiness` is `true`; triggers reverse charge 0%) |
748
+
749
+ **Returns `CheckoutSessionResult`**:
750
+
751
+ | Field | Type | Description |
752
+ |-------|------|-------------|
753
+ | `sessionId` | `string` | Session ID |
754
+ | `checkoutUrl` | `string` | Hosted checkout page URL |
755
+ | `expiresAt` | `string` | Session expiration time |
756
+
757
+ ---
758
+
759
+ ## GraphQL
760
+
761
+ ### `client.graphql.query<T>(params)`
762
+
763
+ Execute a typed GraphQL query. Only Query operations are supported — Mutations return a 403 error.
764
+
765
+ ```typescript
766
+ interface StoresQuery {
767
+ stores: Array<{ id: string; name: string; status: string }>;
768
+ }
769
+ const result = await client.graphql.query<StoresQuery>({
770
+ query: `query { stores { id name status } }`,
771
+ });
772
+
773
+ const productResult = await client.graphql.query({
774
+ query: `query ($id: ID!) { onetimeProduct(id: $id) { id name prices } }`,
775
+ variables: { id: "PROD_xxx" },
776
+ });
777
+ ```
778
+
779
+ **Parameters `GraphQLParams`**:
780
+
781
+ | Field | Type | Required | Description |
782
+ |-------|------|----------|-------------|
783
+ | `query` | `string` | Yes | GraphQL query string |
784
+ | `variables` | `Record<string, unknown>` | No | Query variables |
785
+
786
+ **Returns `GraphQLResponse<T>`**:
787
+
788
+ | Field | Type | Description |
789
+ |-------|------|-------------|
790
+ | `data` | `T \| null` | Query result |
791
+ | `errors` | `Array<{ message, locations?, path? }>` | GraphQL errors (if any) |
792
+
793
+ See [GraphQL Guide](graphql-guide.md) for introspection, filters, pagination, and practical examples.
794
+
795
+ ---
796
+
797
+ ## Types
798
+
799
+ All exported type interfaces:
800
+
801
+ | Export | Description |
802
+ |--------|-------------|
803
+ | **Config** | |
804
+ | `WaffoPancakeConfig` | Client configuration |
805
+ | **Response Envelope** | |
806
+ | `ApiError` | Error object (`{ message, layer }`) |
807
+ | `ApiErrorResponse` | Error response (`{ data: null, errors }`) |
808
+ | `ApiResponse<T>` | Union of success and error responses |
809
+ | `ApiSuccessResponse<T>` | Success response (`{ data: T }`) |
810
+ | **Auth** | |
811
+ | `IssueSessionTokenParams` | Issue token request |
812
+ | `SessionToken` | Token response |
813
+ | **Store** | |
814
+ | `Store` | Store entity |
815
+ | `CreateStoreParams` | Create store request |
816
+ | `UpdateStoreParams` | Update store request |
817
+ | `DeleteStoreParams` | Delete store request |
818
+ | `WebhookSettings` | Webhook endpoint configuration (test/prod) |
819
+ | `NotificationSettings` | Email notification preferences |
820
+ | `CheckoutSettings` | Checkout page theme (light/dark) |
821
+ | `CheckoutThemeSettings` | Single-theme checkout styling |
822
+ | **Store Merchant** | |
823
+ | `AddMerchantParams` | Add merchant request |
824
+ | `AddMerchantResult` | Add merchant response |
825
+ | `RemoveMerchantParams` | Remove merchant request |
826
+ | `RemoveMerchantResult` | Remove merchant response |
827
+ | `UpdateRoleParams` | Update role request |
828
+ | `UpdateRoleResult` | Update role response |
829
+ | **Product (shared)** | |
830
+ | `PriceInfo` | Single-currency price (amount in smallest unit) |
831
+ | `Prices` | Multi-currency prices (`Record<currencyCode, PriceInfo>`) |
832
+ | `MediaItem` | Media asset (image or video) |
833
+ | **Onetime Product** | |
834
+ | `OnetimeProductDetail` | One-time product entity |
835
+ | `CreateOnetimeProductParams` | Create request |
836
+ | `UpdateOnetimeProductParams` | Update request (creates new version) |
837
+ | `PublishOnetimeProductParams` | Publish test → prod |
838
+ | `UpdateOnetimeStatusParams` | Activate / deactivate |
839
+ | **Subscription Product** | |
840
+ | `SubscriptionProductDetail` | Subscription product entity |
841
+ | `CreateSubscriptionProductParams` | Create request |
842
+ | `UpdateSubscriptionProductParams` | Update request (creates new version) |
843
+ | `PublishSubscriptionProductParams` | Publish test → prod |
844
+ | `UpdateSubscriptionStatusParams` | Activate / deactivate |
845
+ | **Subscription Product Group** | |
846
+ | `SubscriptionProductGroup` | Product group entity |
847
+ | `GroupRules` | Group rules (shared trial, etc.) |
848
+ | `CreateSubscriptionProductGroupParams` | Create request |
849
+ | `UpdateSubscriptionProductGroupParams` | Update request (`productIds` = full replacement) |
850
+ | `DeleteSubscriptionProductGroupParams` | Delete request |
851
+ | `PublishSubscriptionProductGroupParams` | Publish test → prod |
852
+ | **Order** | |
853
+ | `CancelSubscriptionParams` | Cancel subscription request |
854
+ | `CancelSubscriptionResult` | Cancel subscription response |
855
+ | `BillingDetail` | Buyer billing details (country, tax ID, etc.) |
856
+ | **Buyer Self-Service** | |
857
+ | `CancelOnetimeOrderParams` | Cancel one-time order request |
858
+ | `CancelOnetimeOrderResult` | Cancel one-time order response |
859
+ | `ReactivateSubscriptionParams` | Reactivate subscription request |
860
+ | `ReactivateSubscriptionResult` | Reactivate subscription response |
861
+ | `CreateRefundTicketParams` | Create refund ticket request |
862
+ | `ResubmitRefundTicketParams` | Resubmit refund ticket request |
863
+ | `RefundTicket` | Refund ticket entity |
864
+ | `RequestedAmount` | Refund amount (`{ amount, currency }`) |
865
+ | **Checkout** | |
866
+ | `AuthenticatedCheckoutParams` | Authenticated checkout request (with buyer identity) |
867
+ | `AuthenticatedCheckoutResult` | Authenticated checkout response (URL with token + expiry) |
868
+ | `AnonymousCheckoutParams` | Anonymous checkout request (no identity) |
869
+ | `CreateCheckoutSessionParams` | Low-level checkout session request |
870
+ | `CheckoutSessionResult` | Checkout session response (URL + expiry) |
871
+ | **GraphQL** | |
872
+ | `GraphQLParams` | GraphQL query parameters |
873
+ | `GraphQLResponse<T>` | GraphQL response envelope |
874
+ | **Webhook** | |
875
+ | `WebhookEvent<T>` | Webhook event payload |
876
+ | `WebhookEventData` | Common event data fields |
877
+ | `VerifyWebhookOptions` | Verification options (environment, tolerance) |