@checkoutpage/sdk 0.1.21 → 0.1.31

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/dist/index.mjs CHANGED
@@ -53,16 +53,68 @@ var APIError = class _APIError extends CheckoutPageError {
53
53
  }
54
54
  };
55
55
 
56
+ // src/resources/invoices/invoices.ts
57
+ var InvoiceResource = class {
58
+ constructor(client) {
59
+ this.client = client;
60
+ }
61
+ /**
62
+ * Retrieve a single invoice by ID. The returned `invoiceUrl` is a freshly
63
+ * signed link to the hosted PDF and expires an hour later — re-fetch to
64
+ * mint a new one.
65
+ *
66
+ * @example
67
+ * const { data: invoice } = await client.invoices.get(invoiceId);
68
+ */
69
+ async get(id) {
70
+ if (!id) {
71
+ throw new Error("Invoice ID is required");
72
+ }
73
+ return this.client.request({
74
+ method: "GET",
75
+ path: `/v1/invoices/${id}`
76
+ });
77
+ }
78
+ async list(args = {}) {
79
+ const query = {
80
+ limit: args.limit?.toString(),
81
+ starting_after: args.starting_after,
82
+ ending_before: args.ending_before,
83
+ search: args.search,
84
+ status: args.status,
85
+ customerId: args.customerId,
86
+ chargeId: args.chargeId,
87
+ poNumber: args.poNumber,
88
+ createdAfter: args.createdAfter,
89
+ createdBefore: args.createdBefore
90
+ };
91
+ return this.client.request({
92
+ method: "GET",
93
+ path: "/v1/invoices/",
94
+ query
95
+ });
96
+ }
97
+ async regenerate(id) {
98
+ const response = await this.client.request({
99
+ method: "POST",
100
+ path: `/v1/invoices/${id}/regenerate`
101
+ });
102
+ return response.data;
103
+ }
104
+ };
105
+
56
106
  // src/client.ts
57
107
  var CheckoutPageApiClient = class {
58
108
  apiKey;
59
109
  baseUrl;
110
+ invoices;
60
111
  constructor(options) {
61
112
  if (!options.apiKey) {
62
113
  throw new Error("API key is required");
63
114
  }
64
115
  this.apiKey = options.apiKey;
65
116
  this.baseUrl = options.baseUrl || "https://api.checkoutpage.com";
117
+ this.invoices = new InvoiceResource(this);
66
118
  }
67
119
  async request(options) {
68
120
  const url = this.buildUrl(options.path, options.query);
@@ -85,6 +137,25 @@ var CheckoutPageApiClient = class {
85
137
  const response = await fetch(url, fetchOptions);
86
138
  return await this.handleResponse(response);
87
139
  }
140
+ /**
141
+ * Perform a request whose successful response is a binary file rather than
142
+ * JSON (e.g. a ticket PDF). Errors are parsed and thrown the same way as
143
+ * request().
144
+ */
145
+ async requestRaw(options) {
146
+ const url = this.buildUrl(options.path, options.query);
147
+ const response = await fetch(url, {
148
+ method: options.method,
149
+ headers: {
150
+ Authorization: `Bearer ${this.apiKey}`,
151
+ "User-Agent": "@checkoutpage/sdk/0.1.0"
152
+ }
153
+ });
154
+ if (!response.ok) {
155
+ await this.handleResponse(response);
156
+ }
157
+ return await response.arrayBuffer();
158
+ }
88
159
  buildUrl(path, query) {
89
160
  const url = new URL(path, this.baseUrl);
90
161
  if (query) {
@@ -139,6 +210,27 @@ var CheckoutPageApiClient = class {
139
210
  }
140
211
  };
141
212
 
213
+ // src/resources/accounts/accounts.ts
214
+ var AccountResource = class {
215
+ constructor(client) {
216
+ this.client = client;
217
+ }
218
+ /**
219
+ * Retrieve the seller account the API key belongs to: store slug, display
220
+ * name and logo.
221
+ *
222
+ * The endpoint wraps the account in a `data` envelope (the OpenAPI spec
223
+ * documents the bare object); this unwraps it so callers get the account.
224
+ */
225
+ async get() {
226
+ const response = await this.client.request({
227
+ method: "GET",
228
+ path: "/v1/account/"
229
+ });
230
+ return response.data;
231
+ }
232
+ };
233
+
142
234
  // src/resources/customers/customers.ts
143
235
  var CustomerResource = class {
144
236
  constructor(client) {
@@ -166,6 +258,38 @@ var CustomerResource = class {
166
258
  path: "/v1/customers/"
167
259
  });
168
260
  }
261
+ async update(customerId, params) {
262
+ if (!customerId) {
263
+ throw new Error("Customer ID is required");
264
+ }
265
+ const body = {};
266
+ if (params.name !== void 0) {
267
+ body.name = params.name;
268
+ }
269
+ if (params.companyName !== void 0) {
270
+ body.companyName = params.companyName;
271
+ }
272
+ if (params.email !== void 0) {
273
+ body.email = params.email;
274
+ }
275
+ if (params.phone !== void 0) {
276
+ body.phone = params.phone;
277
+ }
278
+ if (params.billingEmail !== void 0) {
279
+ body.billingEmail = params.billingEmail;
280
+ }
281
+ if (params.address !== void 0) {
282
+ body.address = params.address;
283
+ }
284
+ if (params.shipping !== void 0) {
285
+ body.shipping = params.shipping;
286
+ }
287
+ return this.client.request({
288
+ method: "PATCH",
289
+ path: `/v1/customers/${customerId}`,
290
+ body
291
+ });
292
+ }
169
293
  };
170
294
 
171
295
  // src/resources/coupons/coupons.ts
@@ -186,6 +310,29 @@ var CouponResource = class {
186
310
  path: "/v1/coupons/"
187
311
  });
188
312
  }
313
+ /**
314
+ * Update an existing coupon. Only the fields you supply are changed.
315
+ *
316
+ * `pageIds` and `ticketTypeIds` replace the existing lists rather than
317
+ * merging — pass an empty array to clear one.
318
+ *
319
+ * The discount itself (`code`, `amountOff`, `percentOff`, `currency`,
320
+ * `duration`) is fixed once the coupon is mirrored into Stripe. To change a
321
+ * discount, soft delete this coupon and create a replacement.
322
+ *
323
+ * @example
324
+ * const { data: coupon } = await client.coupons.update(couponId, { deleted: true });
325
+ */
326
+ async update(couponId, params) {
327
+ if (!couponId) {
328
+ throw new Error("Coupon ID is required");
329
+ }
330
+ return this.client.request({
331
+ method: "PATCH",
332
+ path: `/v1/coupons/${couponId}`,
333
+ body: params
334
+ });
335
+ }
189
336
  async create(params) {
190
337
  const body = {
191
338
  label: params.label,
@@ -229,6 +376,22 @@ var PaymentResource = class {
229
376
  constructor(client) {
230
377
  this.client = client;
231
378
  }
379
+ /**
380
+ * Retrieve a single payment by ID. Only checkout payments are returned —
381
+ * an event charge is a booking, and 404s here.
382
+ *
383
+ * @example
384
+ * const { data: payment } = await client.payments.get(paymentId);
385
+ */
386
+ async get(paymentId) {
387
+ if (!paymentId) {
388
+ throw new Error("Payment ID is required");
389
+ }
390
+ return this.client.request({
391
+ method: "GET",
392
+ path: `/v1/payments/${paymentId}`
393
+ });
394
+ }
232
395
  async list(args = {}) {
233
396
  const query = {
234
397
  search: args.search,
@@ -258,6 +421,21 @@ var SubscriptionResource = class {
258
421
  constructor(client) {
259
422
  this.client = client;
260
423
  }
424
+ /**
425
+ * Retrieve a single subscription by ID.
426
+ *
427
+ * @example
428
+ * const { data: subscription } = await client.subscriptions.get(subscriptionId);
429
+ */
430
+ async get(subscriptionId) {
431
+ if (!subscriptionId) {
432
+ throw new Error("Subscription ID is required");
433
+ }
434
+ return this.client.request({
435
+ method: "GET",
436
+ path: `/v1/subscriptions/${subscriptionId}`
437
+ });
438
+ }
261
439
  async list(args = {}) {
262
440
  const query = {
263
441
  search: args.search,
@@ -273,6 +451,71 @@ var SubscriptionResource = class {
273
451
  path: "/v1/subscriptions/"
274
452
  });
275
453
  }
454
+ /**
455
+ * Cancel a subscription. Provide exactly one of `cancelImmediately`,
456
+ * `cancelAtPeriodEnd`, or `cancelAt` — timing is explicit at the API
457
+ * boundary. Enforced both at the type level via the
458
+ * {@link SubscriptionCancelParams} discriminated union and at the server
459
+ * via zod. Cancellation is one-way; a canceled Stripe subscription cannot
460
+ * be un-canceled.
461
+ *
462
+ * @example
463
+ * await client.subscriptions.cancel(id, { cancelImmediately: true });
464
+ * await client.subscriptions.cancel(id, { cancelAtPeriodEnd: true, sendCancellationEmail: true });
465
+ * await client.subscriptions.cancel(id, { cancelAt: '2026-12-31T23:59:59.000Z' });
466
+ */
467
+ async cancel(subscriptionId, params) {
468
+ return this.client.request({
469
+ method: "POST",
470
+ path: `/v1/subscriptions/${subscriptionId}/cancel`,
471
+ body: params
472
+ });
473
+ }
474
+ };
475
+
476
+ // src/resources/subscription-payments/subscription-payments.ts
477
+ var SubscriptionPaymentResource = class {
478
+ constructor(client) {
479
+ this.client = client;
480
+ }
481
+ /**
482
+ * Retrieve a single subscription payment by ID — one charge within a
483
+ * subscription's billing cycle, not the subscription itself. For every
484
+ * payment on a subscription, use `list({ subscriptionId })`.
485
+ *
486
+ * @example
487
+ * const { data: payment } = await client.subscriptionPayments.get(paymentId);
488
+ */
489
+ async get(subscriptionPaymentId) {
490
+ if (!subscriptionPaymentId) {
491
+ throw new Error("Subscription payment ID is required");
492
+ }
493
+ return this.client.request({
494
+ method: "GET",
495
+ path: `/v1/subscription-payments/${subscriptionPaymentId}`
496
+ });
497
+ }
498
+ async list(args = {}) {
499
+ const query = {
500
+ limit: args.limit?.toString(),
501
+ starting_after: args.starting_after,
502
+ ending_before: args.ending_before,
503
+ subscriptionId: args.subscriptionId,
504
+ customerId: args.customerId,
505
+ pageId: args.pageId,
506
+ paymentStatus: args.paymentStatus,
507
+ paid: args.paid,
508
+ refunded: args.refunded,
509
+ billingReason: args.billingReason,
510
+ createdAfter: args.createdAfter,
511
+ createdBefore: args.createdBefore
512
+ };
513
+ return this.client.request({
514
+ method: "GET",
515
+ query,
516
+ path: "/v1/subscription-payments/"
517
+ });
518
+ }
276
519
  };
277
520
 
278
521
  // src/resources/bookings/bookings.ts
@@ -280,6 +523,41 @@ var BookingResource = class {
280
523
  constructor(client) {
281
524
  this.client = client;
282
525
  }
526
+ /**
527
+ * Retrieve a single booking by ID. Only event bookings are returned —
528
+ * a checkout charge is a payment, and 404s here.
529
+ *
530
+ * @example
531
+ * const { data: booking } = await client.bookings.get(bookingId);
532
+ */
533
+ async get(bookingId) {
534
+ if (!bookingId) {
535
+ throw new Error("Booking ID is required");
536
+ }
537
+ return this.client.request({
538
+ method: "GET",
539
+ path: `/v1/bookings/${bookingId}`
540
+ });
541
+ }
542
+ /**
543
+ * Download the booking's ticket PDF (every ticket in the booking) as raw
544
+ * bytes. The response reflects the current tickets, so attendee updates
545
+ * appear on the next download. Throws NotFoundError when no PDF exists,
546
+ * e.g. for unpaid or abandoned bookings.
547
+ *
548
+ * @example
549
+ * const pdf = await client.bookings.downloadTicketPdf(bookingId);
550
+ * fs.writeFileSync('tickets.pdf', Buffer.from(pdf));
551
+ */
552
+ async downloadTicketPdf(bookingId) {
553
+ if (!bookingId) {
554
+ throw new Error("Booking ID is required");
555
+ }
556
+ return this.client.requestRaw({
557
+ method: "GET",
558
+ path: `/v1/bookings/${bookingId}/ticket-pdf`
559
+ });
560
+ }
283
561
  async list(args = {}) {
284
562
  const query = {
285
563
  search: args.search,
@@ -308,6 +586,48 @@ var TicketResource = class {
308
586
  constructor(client) {
309
587
  this.client = client;
310
588
  }
589
+ async list(args = {}) {
590
+ const query = {
591
+ pageId: args.pageId,
592
+ bookingId: args.bookingId,
593
+ orderId: args.orderId,
594
+ customerId: args.customerId,
595
+ ticketTypeId: args.ticketTypeId,
596
+ status: args.status,
597
+ checkInStatus: args.checkInStatus,
598
+ createdAfter: args.createdAfter,
599
+ createdBefore: args.createdBefore,
600
+ search: args.search,
601
+ limit: args.limit?.toString(),
602
+ starting_after: args.starting_after,
603
+ ending_before: args.ending_before
604
+ };
605
+ return this.client.request({
606
+ method: "GET",
607
+ query,
608
+ path: "/v1/tickets/"
609
+ });
610
+ }
611
+ async update(ticketId, params) {
612
+ if (!ticketId) {
613
+ throw new Error("Ticket ID is required");
614
+ }
615
+ const body = {};
616
+ if (params.attendeeName !== void 0) {
617
+ body.attendeeName = params.attendeeName;
618
+ }
619
+ if (params.attendeeEmail !== void 0) {
620
+ body.attendeeEmail = params.attendeeEmail;
621
+ }
622
+ if (params.metadata !== void 0) {
623
+ body.metadata = params.metadata;
624
+ }
625
+ return this.client.request({
626
+ method: "PATCH",
627
+ path: `/v1/tickets/${ticketId}`,
628
+ body
629
+ });
630
+ }
311
631
  async validate(qrCode, params) {
312
632
  const body = params || {};
313
633
  const response = await this.client.request({
@@ -380,9 +700,21 @@ var ProductResource = class {
380
700
  if (params.limitSubscriptions !== void 0) {
381
701
  body.limitSubscriptions = params.limitSubscriptions;
382
702
  }
703
+ if (params.enableFileAccessForInactiveSubscriptions !== void 0) {
704
+ body.enableFileAccessForInactiveSubscriptions = params.enableFileAccessForInactiveSubscriptions;
705
+ }
383
706
  if (params.generateLicenseKeys !== void 0) {
384
707
  body.generateLicenseKeys = params.generateLicenseKeys;
385
708
  }
709
+ if (params.fixedTaxRateIds !== void 0) {
710
+ body.fixedTaxRateIds = params.fixedTaxRateIds;
711
+ }
712
+ if (params.prices !== void 0) {
713
+ body.prices = params.prices;
714
+ }
715
+ if (params.defaultPriceId !== void 0) {
716
+ body.defaultPriceId = params.defaultPriceId;
717
+ }
386
718
  return this.client.request({
387
719
  method: "PATCH",
388
720
  path: `/v1/products/${productId}`,
@@ -488,11 +820,10 @@ var CheckoutPageFieldsResource = class {
488
820
  if (!fieldId) {
489
821
  throw new Error("Field ID is required");
490
822
  }
491
- const response = await this.client.request({
823
+ return this.client.request({
492
824
  method: "DELETE",
493
825
  path: `/v1/checkout-pages/${pageId}/fields/${fieldId}`
494
826
  });
495
- return response;
496
827
  }
497
828
  };
498
829
  var CheckoutPagesResource = class {
@@ -1011,12 +1342,76 @@ var TaxRateResource = class {
1011
1342
  }
1012
1343
  };
1013
1344
 
1345
+ // src/resources/webhooks/webhooks.ts
1346
+ var WebhookResource = class {
1347
+ constructor(client) {
1348
+ this.client = client;
1349
+ }
1350
+ /**
1351
+ * List webhook endpoints, newest first. Secrets are never returned.
1352
+ *
1353
+ * @example
1354
+ * const { data, has_more } = await client.webhooks.list({ event: 'payment.paid' });
1355
+ */
1356
+ async list(args = {}) {
1357
+ const query = {
1358
+ status: args.status,
1359
+ event: args.event,
1360
+ limit: args.limit?.toString(),
1361
+ starting_after: args.starting_after,
1362
+ ending_before: args.ending_before
1363
+ };
1364
+ return this.client.request({
1365
+ method: "GET",
1366
+ path: "/v1/webhooks/",
1367
+ query
1368
+ });
1369
+ }
1370
+ /**
1371
+ * Create a webhook endpoint. The `url` must use https.
1372
+ *
1373
+ * The response is the only place the signing `secret` is ever returned —
1374
+ * store it immediately. Omit `secret` to have one generated.
1375
+ *
1376
+ * @example
1377
+ * const { data: webhook } = await client.webhooks.create({
1378
+ * name: 'CRM sync',
1379
+ * url: 'https://example.com/hooks/checkoutpage',
1380
+ * events: ['payment.paid', 'subscription.created'],
1381
+ * });
1382
+ * saveSecret(webhook.secret);
1383
+ */
1384
+ async create(params) {
1385
+ return this.client.request({
1386
+ method: "POST",
1387
+ path: "/v1/webhooks/",
1388
+ body: params
1389
+ });
1390
+ }
1391
+ /**
1392
+ * Delete a webhook endpoint. Deliveries stop immediately; the returned
1393
+ * object is its final state. The webhook no longer appears in `list()`,
1394
+ * and deleting the same id again returns 404.
1395
+ */
1396
+ async delete(webhookId) {
1397
+ if (!webhookId) {
1398
+ throw new Error("Webhook ID is required");
1399
+ }
1400
+ return this.client.request({
1401
+ method: "DELETE",
1402
+ path: `/v1/webhooks/${encodeURIComponent(webhookId)}`
1403
+ });
1404
+ }
1405
+ };
1406
+
1014
1407
  // src/index.ts
1015
1408
  var CheckoutPageClient = class {
1409
+ accounts;
1016
1410
  customers;
1017
1411
  coupons;
1018
1412
  payments;
1019
1413
  subscriptions;
1414
+ subscriptionPayments;
1020
1415
  bookings;
1021
1416
  tickets;
1022
1417
  products;
@@ -1026,13 +1421,17 @@ var CheckoutPageClient = class {
1026
1421
  forms;
1027
1422
  submissions;
1028
1423
  taxRates;
1424
+ invoices;
1425
+ webhooks;
1029
1426
  client;
1030
1427
  constructor(options) {
1031
1428
  this.client = new CheckoutPageApiClient(options);
1429
+ this.accounts = new AccountResource(this.client);
1032
1430
  this.customers = new CustomerResource(this.client);
1033
1431
  this.coupons = new CouponResource(this.client);
1034
1432
  this.payments = new PaymentResource(this.client);
1035
1433
  this.subscriptions = new SubscriptionResource(this.client);
1434
+ this.subscriptionPayments = new SubscriptionPaymentResource(this.client);
1036
1435
  this.bookings = new BookingResource(this.client);
1037
1436
  this.tickets = new TicketResource(this.client);
1038
1437
  this.products = new ProductResource(this.client);
@@ -1042,6 +1441,8 @@ var CheckoutPageClient = class {
1042
1441
  this.forms = new FormsResource(this.client);
1043
1442
  this.submissions = new SubmissionResource(this.client);
1044
1443
  this.taxRates = new TaxRateResource(this.client);
1444
+ this.invoices = new InvoiceResource(this.client);
1445
+ this.webhooks = new WebhookResource(this.client);
1045
1446
  }
1046
1447
  };
1047
1448
  var createCheckoutPageClient = (options) => {