@checkoutpage/sdk 0.1.32 → 0.1.33

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
@@ -127,6 +127,40 @@ const results = await checkoutpage.coupons.create({
127
127
  });
128
128
  ```
129
129
 
130
+ Without `rules` a coupon discounts the whole order on every checkout page and event. `rules`
131
+ limits it, one rule per checkout page or event, combined with OR:
132
+
133
+ - Checkout pages: `wholeOrder`, `prices` (only when the customer buys one of `priceIds`, and
134
+ only that price is discounted) or `pricesAndBumps` (only when the customer buys one of
135
+ `priceIds` **and** one of `bumpProductIds`, and both are discounted).
136
+ - Events: `wholeOrder`, `tickets` or `ticketsAndAddOns`, the same with `ticketTypeIds` and
137
+ add-ons.
138
+ - An empty or missing `priceIds`, `ticketTypeIds` or `bumpProductIds` means all of them,
139
+ including ones added later. `priceIds` are the `id`s of the page's main product `prices`, not
140
+ Stripe price ids.
141
+
142
+ ```typescript
143
+ const results = await checkoutpage.coupons.create({
144
+ type: 'percent',
145
+ label: 'Monthly plus workbook',
146
+ code: 'BUNDLE20',
147
+ percentOff: 20,
148
+ duration: 'once',
149
+ rules: [
150
+ {
151
+ pageId,
152
+ appliesTo: 'pricesAndBumps',
153
+ priceIds: [monthlyPriceId],
154
+ bumpProductIds: [workbookProductId],
155
+ },
156
+ { pageId: eventId, appliesTo: 'tickets', ticketTypeIds: [vipTicketTypeId] },
157
+ ],
158
+ });
159
+ ```
160
+
161
+ `pageIds` and `ticketTypeIds` are deprecated in favour of `rules`. They still work, but only
162
+ without `rules`, and responses derive them from the rules.
163
+
130
164
  ### Subscriptions
131
165
 
132
166
  #### List subscriptions
@@ -369,6 +403,64 @@ await checkoutpage.checkoutPages.create({
369
403
  > report them by mirroring the product — but new integrations should set them
370
404
  > under `productData` or via `products.update()`.
371
405
 
406
+ ### Order bumps
407
+
408
+ An order bump is an extra product offered on a checkout page or event (shown as
409
+ an add-on on an event). Create the order bump product once, then offer it on as
410
+ many pages as you like.
411
+
412
+ #### Create an order bump product
413
+
414
+ Order bump products use a single one-time price, which can have a setup fee or be
415
+ pay what you want. Recurring prices and payment plans are refused with a
416
+ `ValidationError`.
417
+
418
+ ```typescript
419
+ const { data: bump } = await checkoutpage.products.create({
420
+ role: 'orderbump',
421
+ title: 'Gift wrapping',
422
+ price: { amount: 500, currency: 'usd' },
423
+ callToActionText: 'Yes! Add gift wrapping',
424
+ shortDescription: 'Wrapped in recycled paper with a handwritten note.',
425
+ });
426
+
427
+ const bumps = await checkoutpage.products.list({ role: 'orderbump' });
428
+ ```
429
+
430
+ #### Offer it on a page
431
+
432
+ The same methods are on `checkoutpage.events.orderBumps` for events.
433
+
434
+ ```typescript
435
+ await checkoutpage.checkoutPages.orderBumps.create('page_id', {
436
+ productId: bump.id,
437
+ preselected: true,
438
+ });
439
+
440
+ const { data: placed } = await checkoutpage.checkoutPages.orderBumps.list('page_id');
441
+
442
+ await checkoutpage.checkoutPages.orderBumps.update('page_id', bump.id, {
443
+ allowQuantity: true,
444
+ });
445
+
446
+ // List every order bump on the page, once, in the new order
447
+ await checkoutpage.checkoutPages.orderBumps.reorder('page_id', {
448
+ productIds: ['other_bump_id', bump.id],
449
+ });
450
+
451
+ // Stops offering it on this page; the product is kept
452
+ await checkoutpage.checkoutPages.orderBumps.delete('page_id', bump.id);
453
+ ```
454
+
455
+ #### Delete an order bump product
456
+
457
+ Only order bump products that have never been bought can be deleted. A product
458
+ still offered on a page is refused unless you pass `fromAllPages: true`.
459
+
460
+ ```typescript
461
+ await checkoutpage.products.delete(bump.id, { fromAllPages: true });
462
+ ```
463
+
372
464
  ### Files
373
465
 
374
466
  #### Upload an image
@@ -460,6 +552,52 @@ A theme that any of your pages uses, archived ones included, or that is your sto
460
552
  can't be deleted and throws a `ConflictError`. Move those pages to another theme with `themeId`
461
553
  first.
462
554
 
555
+ ### Form layout
556
+
557
+ `formLayout` arranges a page's form, top to bottom: fields, headings, dividers, the discount code
558
+ box and groups that put up to 4 items side by side. Checkout pages, events and forms take it on
559
+ `create` and `update`, and page responses always include it. On `create`, reference a field by
560
+ `fieldKey`, the `key` you gave it in `fields` in the same request.
561
+
562
+ ```typescript
563
+ import type { CreateFormLayout } from '@checkoutpage/sdk';
564
+
565
+ const formLayout: CreateFormLayout = [
566
+ { type: 'heading', id: 'your-details', text: 'Your details', level: 'heading' },
567
+ {
568
+ type: 'group',
569
+ id: 'name-row',
570
+ columns: 2,
571
+ items: [
572
+ { type: 'field', fieldKey: 'first-name' },
573
+ { type: 'field', fieldKey: 'last-name' },
574
+ ],
575
+ },
576
+ { type: 'divider', id: 'divider-1' },
577
+ { type: 'discount-code' },
578
+ ];
579
+
580
+ const { data: page } = await checkoutpage.checkoutPages.create({
581
+ name: 'Workshop',
582
+ productData: { title: 'Workshop', price: { amount: 4900, currency: 'usd' } },
583
+ fields: [
584
+ { label: 'Email', element: 'email', type: 'email', required: true },
585
+ { key: 'first-name', element: 'text', label: 'First name' },
586
+ { key: 'last-name', element: 'text', label: 'Last name' },
587
+ ],
588
+ showCouponCodeField: true,
589
+ formLayout,
590
+ });
591
+ ```
592
+
593
+ Responses and `update` reference fields by `fieldId` (the `FormLayout` type). `update` replaces the
594
+ whole layout, so read `page.formLayout`, change it and send it back. Fields the layout leaves out
595
+ are added after it. A `fieldKey` that matches no field, a field id that is not on the page, or a
596
+ `discount-code` item on a form, throws a `ValidationError`. The `discount-code` item only places
597
+ the box: `showCouponCodeField` switches it on, and a saved placement is returned while the box is
598
+ off too. More item types may be added later: skip any type you do not recognise when reading, and
599
+ send it back as you received it when updating.
600
+
463
601
  ### Webhooks
464
602
 
465
603
  #### List webhook endpoints