@checkoutpage/sdk 0.1.31 → 0.1.32
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 +196 -2
- package/dist/index.d.mts +5728 -327
- package/dist/index.d.ts +5728 -327
- package/dist/index.js +292 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +292 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -241,6 +241,67 @@ const pageBookings = await checkoutpage.bookings.list({
|
|
|
241
241
|
});
|
|
242
242
|
```
|
|
243
243
|
|
|
244
|
+
#### Create a booking
|
|
245
|
+
|
|
246
|
+
`bookings.create` issues a real booking without collecting card payment: tickets
|
|
247
|
+
are issued, the customer gets a confirmation email with the ticket PDF, and
|
|
248
|
+
booking webhooks fire. Field values are addressed by `fieldId`, and every field
|
|
249
|
+
the event marks as required must be supplied.
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
const { data: booking } = await checkoutpage.bookings.create({
|
|
253
|
+
eventId: '67fcbdac6a91c25ef2d3534a',
|
|
254
|
+
tickets: { '65f4a1c2e4a9f3d2b1c0a9e8': 2 },
|
|
255
|
+
fields: [
|
|
256
|
+
{ fieldId: '507f1f77bcf86cd799439030', value: 'ada@example.com' },
|
|
257
|
+
{ fieldId: '507f1f77bcf86cd799439031', value: 'Ada Lovelace' },
|
|
258
|
+
],
|
|
259
|
+
paymentOption: { manualType: 'invoice' },
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
console.log(booking.status); // 'unpaid'
|
|
263
|
+
console.log(booking.amountDue); // 5000, settled outside checkout
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### Create a complimentary booking
|
|
267
|
+
|
|
268
|
+
There are two ways to settle a booking, and exactly one of them is required.
|
|
269
|
+
Pass `paymentOption`, as above, and the booking is recorded as `unpaid` with the
|
|
270
|
+
amount as its balance due, settled outside checkout. Pass `complimentary: true`
|
|
271
|
+
instead and the tickets are issued at no charge: the booking is recorded as
|
|
272
|
+
`paid` with `amount`, `amountPaid` and `amountDue` of 0 and
|
|
273
|
+
`isComplimentary: true`, while the ticket lines keep their face value and
|
|
274
|
+
`complimentaryDiscountAmount` records what they would have cost. `complimentary`
|
|
275
|
+
cannot be combined with `paymentOption` or `couponId`.
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
const { data: booking } = await checkoutpage.bookings.create({
|
|
279
|
+
eventId: '67fcbdac6a91c25ef2d3534a',
|
|
280
|
+
tickets: { '65f4a1c2e4a9f3d2b1c0a9e8': 2 },
|
|
281
|
+
fields: [
|
|
282
|
+
{ fieldId: '507f1f77bcf86cd799439030', value: 'ada@example.com' },
|
|
283
|
+
{ fieldId: '507f1f77bcf86cd799439031', value: 'Ada Lovelace' },
|
|
284
|
+
],
|
|
285
|
+
complimentary: true,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
console.log(booking.status); // 'paid'
|
|
289
|
+
console.log(booking.amount); // 0
|
|
290
|
+
console.log(booking.complimentaryDiscountAmount); // 5000 (2 x 2500 face value)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### Filter complimentary bookings
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
const complimentary = await checkoutpage.bookings.list({
|
|
297
|
+
isComplimentary: 'true',
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
const paidFor = await checkoutpage.bookings.list({
|
|
301
|
+
isComplimentary: 'false',
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
244
305
|
### Products
|
|
245
306
|
|
|
246
307
|
#### Get a product
|
|
@@ -249,6 +310,15 @@ const pageBookings = await checkoutpage.bookings.list({
|
|
|
249
310
|
const product = await checkoutpage.products.get('product_id');
|
|
250
311
|
```
|
|
251
312
|
|
|
313
|
+
#### List products
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
const products = await checkoutpage.products.list({
|
|
317
|
+
search: 'shirt',
|
|
318
|
+
limit: 20,
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
252
322
|
#### Update a product
|
|
253
323
|
|
|
254
324
|
```typescript
|
|
@@ -327,6 +397,69 @@ const result = await checkoutpage.files.upload({
|
|
|
327
397
|
console.log('File uploaded:', result.data.id);
|
|
328
398
|
```
|
|
329
399
|
|
|
400
|
+
### Themes
|
|
401
|
+
|
|
402
|
+
A theme is a page design you can reuse across checkout pages, events and forms. `list()` returns
|
|
403
|
+
your own themes (`scope: 'seller'`) and the built-in ones (`scope: 'global'`), which are read-only.
|
|
404
|
+
|
|
405
|
+
#### List themes
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
const { data: themes, has_more } = await checkoutpage.themes.list();
|
|
409
|
+
|
|
410
|
+
const builtIn = await checkoutpage.themes.list({ scope: 'global' });
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
#### Create a theme
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
const { data: theme } = await checkoutpage.themes.create({
|
|
417
|
+
name: 'Brand',
|
|
418
|
+
// Optional: start from a copy of a built-in theme or one of yours
|
|
419
|
+
baseThemeId: builtIn.data[0].id,
|
|
420
|
+
variables: { tokens: { colorPrimary: { light: '#4f46e5' } } },
|
|
421
|
+
});
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
`variables` takes the same shape as a page's `themeOverrides`. A copy of a built-in theme does not
|
|
425
|
+
follow your store's brand colour, so set `tokens.colorPrimary` if you want it. A name another of
|
|
426
|
+
your themes already uses is rejected with a `ConflictError`.
|
|
427
|
+
|
|
428
|
+
#### Get and update a theme
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
const { data: theme } = await checkoutpage.themes.get(themeId);
|
|
432
|
+
|
|
433
|
+
const { data: updated } = await checkoutpage.themes.update(themeId, {
|
|
434
|
+
name: 'Brand v2',
|
|
435
|
+
variables: { tokens: { colorPrimary: { light: '#0f766e' }, radius: null } },
|
|
436
|
+
});
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
Every page that uses the theme changes too. Keys you leave out keep their value, and `null` resets a
|
|
440
|
+
property, or everything under a key. Built-in themes can't be changed: copy one with `baseThemeId`.
|
|
441
|
+
|
|
442
|
+
#### Use a theme on a page
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
await checkoutpage.checkoutPages.update(pageId, { themeId: theme.id });
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
`events` and `forms` take `themeId` on `create` and `update` too, and page responses include it.
|
|
449
|
+
Changing a page's theme replaces the page's own theme settings, including ones set in the
|
|
450
|
+
dashboard such as custom CSS, so the page looks like the theme. `themeOverrides` sent in the same
|
|
451
|
+
request apply on top, and the page's locale is kept.
|
|
452
|
+
|
|
453
|
+
#### Delete a theme
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
const { data: deleted } = await checkoutpage.themes.delete(themeId);
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
A theme that any of your pages uses, archived ones included, or that is your store's default theme,
|
|
460
|
+
can't be deleted and throws a `ConflictError`. Move those pages to another theme with `themeId`
|
|
461
|
+
first.
|
|
462
|
+
|
|
330
463
|
### Webhooks
|
|
331
464
|
|
|
332
465
|
#### List webhook endpoints
|
|
@@ -362,8 +495,36 @@ saveSecret(webhook.secret);
|
|
|
362
495
|
> and a URL already registered on the account is rejected with a `ConflictError`.
|
|
363
496
|
|
|
364
497
|
> The create response is the **only** place the signing `secret` is ever returned.
|
|
365
|
-
> It is not included in `list()` responses and cannot be retrieved later
|
|
366
|
-
> when you create the endpoint. Omit `secret` to have one generated for you.
|
|
498
|
+
> It is not included in `list()` or `get()` responses and cannot be retrieved later, so store
|
|
499
|
+
> it when you create the endpoint. Omit `secret` to have one generated for you.
|
|
500
|
+
|
|
501
|
+
#### Get a webhook endpoint
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
const { data: webhook } = await checkoutpage.webhooks.get(webhookId);
|
|
505
|
+
|
|
506
|
+
console.log(webhook.status, webhook.deliveryCount, webhook.lastFailureAt);
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
The signing `secret` is not included.
|
|
510
|
+
|
|
511
|
+
#### Update a webhook endpoint
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
const { data: updated } = await checkoutpage.webhooks.update(webhookId, {
|
|
515
|
+
url: 'https://example.com/hooks/checkoutpage-v2',
|
|
516
|
+
events: ['payment.paid', 'checkout_page.updated', 'product.updated'],
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
// Pause deliveries without deleting the endpoint, then resume them
|
|
520
|
+
await checkoutpage.webhooks.update(webhookId, { status: 'inactive' });
|
|
521
|
+
await checkoutpage.webhooks.update(webhookId, { status: 'active' });
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
Only the fields you send change. `events` and `customHeaders` replace the existing values rather
|
|
525
|
+
than merging with them. A new `url` must use https and must not already be registered on another of
|
|
526
|
+
your webhooks (`ValidationError` / `ConflictError`). The signing secret cannot be changed through
|
|
527
|
+
the API.
|
|
367
528
|
|
|
368
529
|
#### Delete a webhook endpoint
|
|
369
530
|
|
|
@@ -373,6 +534,39 @@ const { data: deleted } = await checkoutpage.webhooks.delete(webhook.id);
|
|
|
373
534
|
|
|
374
535
|
Deliveries stop immediately and the endpoint no longer appears in `list()`.
|
|
375
536
|
|
|
537
|
+
### Test mode
|
|
538
|
+
|
|
539
|
+
Switch a checkout page, event or form into test mode with `testmode: true`. While it is on, every
|
|
540
|
+
purchase on that page is a test purchase: no money is taken, the buyer gets the product for free,
|
|
541
|
+
and the records are created with `livemode: false`.
|
|
542
|
+
|
|
543
|
+
```typescript
|
|
544
|
+
await checkoutpage.checkoutPages.update(pageId, { testmode: true });
|
|
545
|
+
|
|
546
|
+
const { data: pagesInTestMode } = await checkoutpage.checkoutPages.list({ testmode: true });
|
|
547
|
+
|
|
548
|
+
// Turn it off to take real payments again
|
|
549
|
+
await checkoutpage.checkoutPages.update(pageId, { testmode: false });
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
`events` and `forms` take the same field on `create`, `update` and `list`. Page responses carry
|
|
553
|
+
`testmode` and `testmodeEnabledAt` (when test mode was switched on, `null` while it is off).
|
|
554
|
+
|
|
555
|
+
#### Read test records
|
|
556
|
+
|
|
557
|
+
Pass `livemode: false` to read test records from payments, bookings, subscriptions, subscription
|
|
558
|
+
payments, invoices, submissions and tickets:
|
|
559
|
+
|
|
560
|
+
```typescript
|
|
561
|
+
const { data: testPayments } = await checkoutpage.payments.list({ pageId, livemode: false });
|
|
562
|
+
const { data: testPayment } = await checkoutpage.payments.get(paymentId, { livemode: false });
|
|
563
|
+
const pdf = await checkoutpage.bookings.downloadTicketPdf(bookingId, { livemode: false });
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
Without `livemode`, reads return records in the mode of your API key. A live key (`sk_live_`)
|
|
567
|
+
reads live data by default and test data with `livemode: false`. A test key (`sk_test_`) only
|
|
568
|
+
reads test data: `livemode: true` with a test key throws an `AuthenticationError` (403).
|
|
569
|
+
|
|
376
570
|
## Error Handling
|
|
377
571
|
|
|
378
572
|
The SDK provides typed error classes for different error scenarios:
|