@billkit-eu/sdk 0.6.0 → 0.7.1
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 +38 -1
- package/README.md +3 -1
- package/dist/index.cjs +206 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +305 -29
- package/dist/index.d.ts +305 -29
- package/dist/index.js +206 -79
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +3 -0
- package/src/errors.ts +10 -1
- package/src/index.ts +9 -0
- package/src/resources.ts +417 -99
- package/src/transport.ts +21 -10
- package/src/version.ts +1 -1
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,9 @@ async function* paginate(listFn, options = {}) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// src/resources.ts
|
|
29
|
+
function p(id) {
|
|
30
|
+
return encodeURIComponent(id);
|
|
31
|
+
}
|
|
29
32
|
function dropUndefined(obj) {
|
|
30
33
|
const out = {};
|
|
31
34
|
for (const [k, v] of Object.entries(obj)) {
|
|
@@ -58,6 +61,12 @@ var BaseResource = class {
|
|
|
58
61
|
this.t = t;
|
|
59
62
|
}
|
|
60
63
|
t;
|
|
64
|
+
/**
|
|
65
|
+
* `query` is a plain object rather than an index-signature type: TypeScript
|
|
66
|
+
* only gives an implicit index signature to type *aliases*, so a closed
|
|
67
|
+
* `*ListParams` interface would otherwise need a cast at every call site.
|
|
68
|
+
* The transport prunes `undefined`/`null` and joins arrays with commas.
|
|
69
|
+
*/
|
|
61
70
|
get(path, query) {
|
|
62
71
|
return this.t.request({ method: "GET", path, query });
|
|
63
72
|
}
|
|
@@ -98,10 +107,10 @@ var Customers = class extends BaseResource {
|
|
|
98
107
|
return this.post("/v1/customers", params);
|
|
99
108
|
}
|
|
100
109
|
retrieve(id) {
|
|
101
|
-
return this.get(`/v1/customers/${id}`);
|
|
110
|
+
return this.get(`/v1/customers/${p(id)}`);
|
|
102
111
|
}
|
|
103
112
|
update(id, params = {}) {
|
|
104
|
-
return this.post(`/v1/customers/${id}`, params);
|
|
113
|
+
return this.post(`/v1/customers/${p(id)}`, params);
|
|
105
114
|
}
|
|
106
115
|
/**
|
|
107
116
|
* Delete a customer. Resolves to `{ id, object: "customer", deleted:
|
|
@@ -114,7 +123,7 @@ var Customers = class extends BaseResource {
|
|
|
114
123
|
* charge them.
|
|
115
124
|
*/
|
|
116
125
|
delete(id, params = {}) {
|
|
117
|
-
return this.del(`/v1/customers/${id}`, params);
|
|
126
|
+
return this.del(`/v1/customers/${p(id)}`, params);
|
|
118
127
|
}
|
|
119
128
|
/**
|
|
120
129
|
* List customers, newest first.
|
|
@@ -131,7 +140,7 @@ var Customers = class extends BaseResource {
|
|
|
131
140
|
}
|
|
132
141
|
/** Walk every page of `list()` and yield each customer. */
|
|
133
142
|
iter(options = {}) {
|
|
134
|
-
return paginate((
|
|
143
|
+
return paginate((page) => this.get("/v1/customers", page), { pageSize: options.pageSize });
|
|
135
144
|
}
|
|
136
145
|
/**
|
|
137
146
|
* Attach or replace the customer's VAT number; triggers server-side
|
|
@@ -139,7 +148,7 @@ var Customers = class extends BaseResource {
|
|
|
139
148
|
* reflecting whether VIES confirmed the number.
|
|
140
149
|
*/
|
|
141
150
|
setVatNumber(id, params) {
|
|
142
|
-
return this.post(`/v1/customers/${id}/vat_number`, params);
|
|
151
|
+
return this.post(`/v1/customers/${p(id)}/vat_number`, params);
|
|
143
152
|
}
|
|
144
153
|
/**
|
|
145
154
|
* Hard-purge a customer's PII for GDPR erasure. Distinct from
|
|
@@ -151,7 +160,7 @@ var Customers = class extends BaseResource {
|
|
|
151
160
|
*/
|
|
152
161
|
purge(id, params = {}) {
|
|
153
162
|
const { confirmed = true, idempotencyKey } = params;
|
|
154
|
-
return this.postFixed(`/v1/customers/${id}/purge`, { confirmed }, { idempotencyKey });
|
|
163
|
+
return this.postFixed(`/v1/customers/${p(id)}/purge`, { confirmed }, { idempotencyKey });
|
|
155
164
|
}
|
|
156
165
|
};
|
|
157
166
|
var Products = class extends BaseResource {
|
|
@@ -159,8 +168,12 @@ var Products = class extends BaseResource {
|
|
|
159
168
|
create(params) {
|
|
160
169
|
return this.post("/v1/products", params);
|
|
161
170
|
}
|
|
162
|
-
|
|
163
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Expandable: `prices` (every price on the product), `stats`, and
|
|
173
|
+
* `default_price` (the price `default_price_id` names).
|
|
174
|
+
*/
|
|
175
|
+
retrieve(id, options = {}) {
|
|
176
|
+
return this.get(`/v1/products/${p(id)}`, options);
|
|
164
177
|
}
|
|
165
178
|
/**
|
|
166
179
|
* Patch mutable Product fields, or archive it with `active: false`.
|
|
@@ -172,13 +185,13 @@ var Products = class extends BaseResource {
|
|
|
172
185
|
* `active: true` un-archives.
|
|
173
186
|
*/
|
|
174
187
|
update(id, params) {
|
|
175
|
-
return this.post(`/v1/products/${id}`, params);
|
|
188
|
+
return this.post(`/v1/products/${p(id)}`, params);
|
|
176
189
|
}
|
|
177
190
|
list(params = {}) {
|
|
178
191
|
return this.get("/v1/products", params);
|
|
179
192
|
}
|
|
180
193
|
iter(options = {}) {
|
|
181
|
-
return paginate((
|
|
194
|
+
return paginate((page) => this.get("/v1/products", page), { pageSize: options.pageSize });
|
|
182
195
|
}
|
|
183
196
|
};
|
|
184
197
|
var Prices = class extends BaseResource {
|
|
@@ -201,7 +214,7 @@ var Prices = class extends BaseResource {
|
|
|
201
214
|
return this.post("/v1/prices", assertPriceRatesAreStrings(params));
|
|
202
215
|
}
|
|
203
216
|
retrieve(id) {
|
|
204
|
-
return this.get(`/v1/prices/${id}`);
|
|
217
|
+
return this.get(`/v1/prices/${p(id)}`);
|
|
205
218
|
}
|
|
206
219
|
/**
|
|
207
220
|
* Archive a Price so it stops selling, or put it back on sale.
|
|
@@ -224,14 +237,14 @@ var Prices = class extends BaseResource {
|
|
|
224
237
|
* `price.archived`; putting one back emits `price.updated`.
|
|
225
238
|
*/
|
|
226
239
|
update(id, params) {
|
|
227
|
-
return this.post(`/v1/prices/${id}`, params);
|
|
240
|
+
return this.post(`/v1/prices/${p(id)}`, params);
|
|
228
241
|
}
|
|
229
242
|
list(params = {}) {
|
|
230
243
|
return this.get("/v1/prices", params);
|
|
231
244
|
}
|
|
232
245
|
iter(options = {}) {
|
|
233
246
|
const filter = options.product_id === void 0 ? {} : { product_id: options.product_id };
|
|
234
|
-
return paginate((
|
|
247
|
+
return paginate((page) => this.get("/v1/prices", { ...filter, ...page }), {
|
|
235
248
|
pageSize: options.pageSize
|
|
236
249
|
});
|
|
237
250
|
}
|
|
@@ -241,7 +254,7 @@ var CheckoutSessions = class extends BaseResource {
|
|
|
241
254
|
return this.post("/v1/checkout/sessions", params);
|
|
242
255
|
}
|
|
243
256
|
retrieve(id) {
|
|
244
|
-
return this.get(`/v1/checkout/sessions/${id}`);
|
|
257
|
+
return this.get(`/v1/checkout/sessions/${p(id)}`);
|
|
245
258
|
}
|
|
246
259
|
};
|
|
247
260
|
var OneShotPayments = class extends BaseResource {
|
|
@@ -250,12 +263,13 @@ var OneShotPayments = class extends BaseResource {
|
|
|
250
263
|
return this.post("/v1/checkout/one_shot", params);
|
|
251
264
|
}
|
|
252
265
|
retrieve(id) {
|
|
253
|
-
return this.get(`/v1/checkout/one_shot/${id}`);
|
|
266
|
+
return this.get(`/v1/checkout/one_shot/${p(id)}`);
|
|
254
267
|
}
|
|
255
268
|
};
|
|
256
269
|
var Subscriptions = class extends BaseResource {
|
|
257
|
-
|
|
258
|
-
|
|
270
|
+
/** Expandable: `customer`, `price`, `refund_eligibility`. */
|
|
271
|
+
retrieve(id, options = {}) {
|
|
272
|
+
return this.get(`/v1/subscriptions/${p(id)}`, options);
|
|
259
273
|
}
|
|
260
274
|
/**
|
|
261
275
|
* List subscriptions, newest first, optionally filtered.
|
|
@@ -273,16 +287,16 @@ var Subscriptions = class extends BaseResource {
|
|
|
273
287
|
*/
|
|
274
288
|
iter(options = {}) {
|
|
275
289
|
const { pageSize, ...filter } = options;
|
|
276
|
-
return paginate((
|
|
290
|
+
return paginate((page) => this.get("/v1/subscriptions", { ...filter, ...page }), { pageSize });
|
|
277
291
|
}
|
|
278
292
|
cancel(id, params = {}) {
|
|
279
|
-
return this.postEmpty(`/v1/subscriptions/${id}/cancel`, params);
|
|
293
|
+
return this.postEmpty(`/v1/subscriptions/${p(id)}/cancel`, params);
|
|
280
294
|
}
|
|
281
295
|
pause(id, params = {}) {
|
|
282
|
-
return this.postEmpty(`/v1/subscriptions/${id}/pause`, params);
|
|
296
|
+
return this.postEmpty(`/v1/subscriptions/${p(id)}/pause`, params);
|
|
283
297
|
}
|
|
284
298
|
resume(id, params = {}) {
|
|
285
|
-
return this.postEmpty(`/v1/subscriptions/${id}/resume`, params);
|
|
299
|
+
return this.postEmpty(`/v1/subscriptions/${p(id)}/resume`, params);
|
|
286
300
|
}
|
|
287
301
|
/**
|
|
288
302
|
* Reactivate a canceled-but-still-in-period subscription.
|
|
@@ -293,23 +307,23 @@ var Subscriptions = class extends BaseResource {
|
|
|
293
307
|
* Returns `409` if the period has already elapsed.
|
|
294
308
|
*/
|
|
295
309
|
reactivate(id, params = {}) {
|
|
296
|
-
return this.postEmpty(`/v1/subscriptions/${id}/reactivate`, params);
|
|
310
|
+
return this.postEmpty(`/v1/subscriptions/${p(id)}/reactivate`, params);
|
|
297
311
|
}
|
|
298
312
|
previewUpdate(id, params) {
|
|
299
|
-
return this.postFixed(`/v1/subscriptions/${id}/preview_update`, {
|
|
313
|
+
return this.postFixed(`/v1/subscriptions/${p(id)}/preview_update`, {
|
|
300
314
|
target_price_id: params.target_price_id
|
|
301
315
|
});
|
|
302
316
|
}
|
|
303
317
|
update(id, params) {
|
|
304
318
|
return this.postFixed(
|
|
305
|
-
`/v1/subscriptions/${id}/update`,
|
|
319
|
+
`/v1/subscriptions/${p(id)}/update`,
|
|
306
320
|
{ target_price_id: params.target_price_id },
|
|
307
321
|
{ idempotencyKey: params.idempotencyKey }
|
|
308
322
|
);
|
|
309
323
|
}
|
|
310
324
|
reauthorizePaymentMethod(id, params) {
|
|
311
325
|
return this.postFixed(
|
|
312
|
-
`/v1/subscriptions/${id}/reauthorize_payment_method`,
|
|
326
|
+
`/v1/subscriptions/${p(id)}/reauthorize_payment_method`,
|
|
313
327
|
{ return_url: params.return_url },
|
|
314
328
|
{ idempotencyKey: params.idempotencyKey }
|
|
315
329
|
);
|
|
@@ -331,7 +345,7 @@ var Subscriptions = class extends BaseResource {
|
|
|
331
345
|
* See {@link CreateUsageRecordParams.identifier}.
|
|
332
346
|
*/
|
|
333
347
|
createUsageRecord(id, params) {
|
|
334
|
-
return this.post(`/v1/subscriptions/${id}/usage_records`, params);
|
|
348
|
+
return this.post(`/v1/subscriptions/${p(id)}/usage_records`, params);
|
|
335
349
|
}
|
|
336
350
|
/**
|
|
337
351
|
* List usage records for one subscription.
|
|
@@ -341,11 +355,11 @@ var Subscriptions = class extends BaseResource {
|
|
|
341
355
|
* invoice charged for.
|
|
342
356
|
*/
|
|
343
357
|
listUsageRecords(id, params = {}) {
|
|
344
|
-
return this.get(`/v1/subscriptions/${id}/usage_records`, params);
|
|
358
|
+
return this.get(`/v1/subscriptions/${p(id)}/usage_records`, params);
|
|
345
359
|
}
|
|
346
360
|
/** Walk every page of `listUsageRecords()` for one subscription. */
|
|
347
361
|
iterUsageRecords(id, options = {}) {
|
|
348
|
-
return paginate((
|
|
362
|
+
return paginate((page) => this.get(`/v1/subscriptions/${p(id)}/usage_records`, page), {
|
|
349
363
|
pageSize: options.pageSize,
|
|
350
364
|
filters: { invoice_id: options.invoice_id }
|
|
351
365
|
});
|
|
@@ -369,7 +383,7 @@ var Subscriptions = class extends BaseResource {
|
|
|
369
383
|
* unsettled; while one is open, this period cannot be charged.
|
|
370
384
|
*/
|
|
371
385
|
retrieveUsageSummary(id) {
|
|
372
|
-
return this.get(`/v1/subscriptions/${id}/usage_summary`);
|
|
386
|
+
return this.get(`/v1/subscriptions/${p(id)}/usage_summary`);
|
|
373
387
|
}
|
|
374
388
|
};
|
|
375
389
|
var Refunds = class extends BaseResource {
|
|
@@ -377,32 +391,45 @@ var Refunds = class extends BaseResource {
|
|
|
377
391
|
return this.post("/v1/refunds", params);
|
|
378
392
|
}
|
|
379
393
|
retrieve(id) {
|
|
380
|
-
return this.get(`/v1/refunds/${id}`);
|
|
394
|
+
return this.get(`/v1/refunds/${p(id)}`);
|
|
381
395
|
}
|
|
382
396
|
list(params = {}) {
|
|
383
397
|
return this.get("/v1/refunds", params);
|
|
384
398
|
}
|
|
385
399
|
iter(options = {}) {
|
|
386
|
-
return paginate((
|
|
400
|
+
return paginate((page) => this.get("/v1/refunds", page), { pageSize: options.pageSize });
|
|
387
401
|
}
|
|
388
402
|
};
|
|
389
403
|
var Disputes = class extends BaseResource {
|
|
390
404
|
retrieve(id) {
|
|
391
|
-
return this.get(`/v1/disputes/${id}`);
|
|
405
|
+
return this.get(`/v1/disputes/${p(id)}`);
|
|
392
406
|
}
|
|
393
407
|
list(params = {}) {
|
|
394
408
|
return this.get("/v1/disputes", params);
|
|
395
409
|
}
|
|
396
410
|
iter(options = {}) {
|
|
397
|
-
return paginate((
|
|
411
|
+
return paginate((page) => this.get("/v1/disputes", page), {
|
|
412
|
+
pageSize: options.pageSize,
|
|
413
|
+
filters: { status: options.status, payment_id: options.payment_id }
|
|
414
|
+
});
|
|
398
415
|
}
|
|
399
416
|
};
|
|
400
417
|
var WebhookEndpoints = class extends BaseResource {
|
|
418
|
+
/**
|
|
419
|
+
* Every event type this deployment can deliver, plus the wildcard.
|
|
420
|
+
*
|
|
421
|
+
* `enabled_events` rejects anything not on this list, so read it rather
|
|
422
|
+
* than hard-coding a set: a name that is not on it fails at
|
|
423
|
+
* registration and leaves you with an endpoint that never fires.
|
|
424
|
+
*/
|
|
425
|
+
listEventTypes() {
|
|
426
|
+
return this.get("/v1/webhook_endpoints/event_types");
|
|
427
|
+
}
|
|
401
428
|
create(params) {
|
|
402
429
|
return this.post("/v1/webhook_endpoints", params);
|
|
403
430
|
}
|
|
404
431
|
retrieve(id) {
|
|
405
|
-
return this.get(`/v1/webhook_endpoints/${id}`);
|
|
432
|
+
return this.get(`/v1/webhook_endpoints/${p(id)}`);
|
|
406
433
|
}
|
|
407
434
|
/**
|
|
408
435
|
* Update an endpoint, or stop delivery with `status: "disabled"`.
|
|
@@ -413,7 +440,7 @@ var WebhookEndpoints = class extends BaseResource {
|
|
|
413
440
|
* disabling is reversible and deleting is not.
|
|
414
441
|
*/
|
|
415
442
|
update(id, params) {
|
|
416
|
-
return this.post(`/v1/webhook_endpoints/${id}`, params);
|
|
443
|
+
return this.post(`/v1/webhook_endpoints/${p(id)}`, params);
|
|
417
444
|
}
|
|
418
445
|
/**
|
|
419
446
|
* Delete an endpoint. Resolves to `{ id, object: "webhook_endpoint",
|
|
@@ -427,17 +454,17 @@ var WebhookEndpoints = class extends BaseResource {
|
|
|
427
454
|
* were sent stays on record.
|
|
428
455
|
*/
|
|
429
456
|
delete(id, params = {}) {
|
|
430
|
-
return this.del(`/v1/webhook_endpoints/${id}`, params);
|
|
457
|
+
return this.del(`/v1/webhook_endpoints/${p(id)}`, params);
|
|
431
458
|
}
|
|
432
459
|
/** Rotate the signing secret. The new `bkwhsec_...` is returned once. */
|
|
433
460
|
rotateSecret(id, params = {}) {
|
|
434
|
-
return this.postEmpty(`/v1/webhook_endpoints/${id}/rotate_secret`, params);
|
|
461
|
+
return this.postEmpty(`/v1/webhook_endpoints/${p(id)}/rotate_secret`, params);
|
|
435
462
|
}
|
|
436
463
|
list(params = {}) {
|
|
437
464
|
return this.get("/v1/webhook_endpoints", params);
|
|
438
465
|
}
|
|
439
466
|
iter(options = {}) {
|
|
440
|
-
return paginate((
|
|
467
|
+
return paginate((page) => this.get("/v1/webhook_endpoints", page), {
|
|
441
468
|
pageSize: options.pageSize
|
|
442
469
|
});
|
|
443
470
|
}
|
|
@@ -450,20 +477,20 @@ var WebhookEndpoints = class extends BaseResource {
|
|
|
450
477
|
*/
|
|
451
478
|
listDeliveries(endpointId, params = {}) {
|
|
452
479
|
return this.get(
|
|
453
|
-
`/v1/webhook_endpoints/${endpointId}/deliveries`,
|
|
480
|
+
`/v1/webhook_endpoints/${p(endpointId)}/deliveries`,
|
|
454
481
|
params
|
|
455
482
|
);
|
|
456
483
|
}
|
|
457
484
|
/** Walk every page of `listDeliveries()` for one endpoint. */
|
|
458
485
|
iterDeliveries(endpointId, options = {}) {
|
|
459
486
|
return paginate(
|
|
460
|
-
(
|
|
487
|
+
(page) => this.get(`/v1/webhook_endpoints/${p(endpointId)}/deliveries`, page),
|
|
461
488
|
{ pageSize: options.pageSize }
|
|
462
489
|
);
|
|
463
490
|
}
|
|
464
491
|
/** Fetch one delivery row for inspection before deciding to redeliver. */
|
|
465
492
|
retrieveDelivery(endpointId, deliveryId) {
|
|
466
|
-
return this.get(`/v1/webhook_endpoints/${endpointId}/deliveries/${deliveryId}`);
|
|
493
|
+
return this.get(`/v1/webhook_endpoints/${p(endpointId)}/deliveries/${p(deliveryId)}`);
|
|
467
494
|
}
|
|
468
495
|
/**
|
|
469
496
|
* @deprecated Renamed to {@link WebhookEndpoints.retrieveDelivery}.
|
|
@@ -488,21 +515,21 @@ var WebhookEndpoints = class extends BaseResource {
|
|
|
488
515
|
*/
|
|
489
516
|
redeliver(endpointId, deliveryId, params = {}) {
|
|
490
517
|
return this.postEmpty(
|
|
491
|
-
`/v1/webhook_endpoints/${endpointId}/deliveries/${deliveryId}/redeliver`,
|
|
518
|
+
`/v1/webhook_endpoints/${p(endpointId)}/deliveries/${p(deliveryId)}/redeliver`,
|
|
492
519
|
params
|
|
493
520
|
);
|
|
494
521
|
}
|
|
495
522
|
};
|
|
496
523
|
var Events = class extends BaseResource {
|
|
497
524
|
retrieve(id) {
|
|
498
|
-
return this.get(`/v1/events/${id}`);
|
|
525
|
+
return this.get(`/v1/events/${p(id)}`);
|
|
499
526
|
}
|
|
500
527
|
list(params = {}) {
|
|
501
528
|
return this.get("/v1/events", params);
|
|
502
529
|
}
|
|
503
530
|
/** Walk every page of `list()`. Pass `type` to filter at the server. */
|
|
504
531
|
iter(options = {}) {
|
|
505
|
-
return paginate((
|
|
532
|
+
return paginate((page) => this.get("/v1/events", page), {
|
|
506
533
|
pageSize: options.pageSize,
|
|
507
534
|
filters: { type: options.type }
|
|
508
535
|
});
|
|
@@ -513,6 +540,46 @@ var Tenant = class extends BaseResource {
|
|
|
513
540
|
capabilities() {
|
|
514
541
|
return this.get("/v1/tenant/capabilities");
|
|
515
542
|
}
|
|
543
|
+
/**
|
|
544
|
+
* Your registered country and VAT number: what your customers' VAT is
|
|
545
|
+
* decided against.
|
|
546
|
+
*
|
|
547
|
+
* `country_code` is what you have stored and can be `null`;
|
|
548
|
+
* `effective_country_code` is what the next charge will really use.
|
|
549
|
+
* The two differ only when you have stored nothing, which is exactly
|
|
550
|
+
* the case worth spotting before a first live payment.
|
|
551
|
+
*/
|
|
552
|
+
billingProfile() {
|
|
553
|
+
return this.get("/v1/tenant/billing_profile");
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Set the seller identity. `country_code` is required on every call;
|
|
557
|
+
* every other field is partial-update, with an explicit `null` to
|
|
558
|
+
* clear. Changes take effect on the next charge only. Tax is written
|
|
559
|
+
* onto a payment and its invoice before money moves, and nothing goes
|
|
560
|
+
* back and recalculates it.
|
|
561
|
+
*/
|
|
562
|
+
setBillingProfile(params) {
|
|
563
|
+
return this.post("/v1/tenant/billing_profile", params);
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Download everything in the account as one JSON document, as raw bytes.
|
|
567
|
+
*
|
|
568
|
+
* ```ts
|
|
569
|
+
* await writeFile("export.json", Buffer.from(await client.tenant.export()));
|
|
570
|
+
* ```
|
|
571
|
+
*
|
|
572
|
+
* The GDPR Article 20 portability route, and the way to take a backup.
|
|
573
|
+
* It is `application/json` streamed inline, with no redirect, and each
|
|
574
|
+
* record has the same shape its `GET` route returns, with
|
|
575
|
+
* `billkit_export_version` naming the shape. It can be large, so write
|
|
576
|
+
* it to a file rather than holding it in memory. Test and live data
|
|
577
|
+
* export separately: you get whichever mode the key belongs to. The
|
|
578
|
+
* access is recorded in your audit log.
|
|
579
|
+
*/
|
|
580
|
+
export() {
|
|
581
|
+
return this.t.requestBinary({ method: "GET", path: "/v1/tenant/export" });
|
|
582
|
+
}
|
|
516
583
|
/** Current portal branding row (business name, theme, capability flags). */
|
|
517
584
|
portalBranding() {
|
|
518
585
|
return this.get("/v1/tenant/portal_branding");
|
|
@@ -546,7 +613,7 @@ var Coupons = class extends BaseResource {
|
|
|
546
613
|
return this.post("/v1/coupons", params);
|
|
547
614
|
}
|
|
548
615
|
retrieve(id) {
|
|
549
|
-
return this.get(`/v1/coupons/${id}`);
|
|
616
|
+
return this.get(`/v1/coupons/${p(id)}`);
|
|
550
617
|
}
|
|
551
618
|
/**
|
|
552
619
|
* Update a coupon's limits, or withdraw it with `active: false`.
|
|
@@ -557,7 +624,7 @@ var Coupons = class extends BaseResource {
|
|
|
557
624
|
* customer was charged. `active: true` brings the campaign back.
|
|
558
625
|
*/
|
|
559
626
|
update(id, params) {
|
|
560
|
-
return this.post(`/v1/coupons/${id}`, params);
|
|
627
|
+
return this.post(`/v1/coupons/${p(id)}`, params);
|
|
561
628
|
}
|
|
562
629
|
/**
|
|
563
630
|
* Server-side dry-run of a coupon redemption.
|
|
@@ -575,7 +642,7 @@ var Coupons = class extends BaseResource {
|
|
|
575
642
|
return this.get("/v1/coupons", params);
|
|
576
643
|
}
|
|
577
644
|
iter(options = {}) {
|
|
578
|
-
return paginate((
|
|
645
|
+
return paginate((page) => this.get("/v1/coupons", page), { pageSize: options.pageSize });
|
|
579
646
|
}
|
|
580
647
|
};
|
|
581
648
|
var TaxRates = class extends BaseResource {
|
|
@@ -583,7 +650,7 @@ var TaxRates = class extends BaseResource {
|
|
|
583
650
|
return this.post("/v1/tax_rates", params);
|
|
584
651
|
}
|
|
585
652
|
retrieve(id) {
|
|
586
|
-
return this.get(`/v1/tax_rates/${id}`);
|
|
653
|
+
return this.get(`/v1/tax_rates/${p(id)}`);
|
|
587
654
|
}
|
|
588
655
|
/**
|
|
589
656
|
* Correct a rate, retire it with `active: false`, or bring one back.
|
|
@@ -594,18 +661,19 @@ var TaxRates = class extends BaseResource {
|
|
|
594
661
|
* is no `delete()`.
|
|
595
662
|
*/
|
|
596
663
|
update(id, params) {
|
|
597
|
-
return this.post(`/v1/tax_rates/${id}`, params);
|
|
664
|
+
return this.post(`/v1/tax_rates/${p(id)}`, params);
|
|
598
665
|
}
|
|
599
666
|
list(params = {}) {
|
|
600
667
|
return this.get("/v1/tax_rates", params);
|
|
601
668
|
}
|
|
602
669
|
iter(options = {}) {
|
|
603
|
-
return paginate((
|
|
670
|
+
return paginate((page) => this.get("/v1/tax_rates", page), { pageSize: options.pageSize });
|
|
604
671
|
}
|
|
605
672
|
};
|
|
606
673
|
var Invoices = class extends BaseResource {
|
|
607
|
-
|
|
608
|
-
|
|
674
|
+
/** Expandable: `customer`. */
|
|
675
|
+
retrieve(id, options = {}) {
|
|
676
|
+
return this.get(`/v1/invoices/${p(id)}`, options);
|
|
609
677
|
}
|
|
610
678
|
/**
|
|
611
679
|
* Download the rendered invoice PDF as raw bytes.
|
|
@@ -626,13 +694,27 @@ var Invoices = class extends BaseResource {
|
|
|
626
694
|
* structured invoice for tenants who render their own.
|
|
627
695
|
*/
|
|
628
696
|
retrievePdf(id) {
|
|
629
|
-
return this.t.requestBinary({ method: "GET", path: `/v1/invoices/${id}/pdf` });
|
|
697
|
+
return this.t.requestBinary({ method: "GET", path: `/v1/invoices/${p(id)}/pdf` });
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Send the customer their invoice again.
|
|
701
|
+
*
|
|
702
|
+
* The same tenant-branded "your invoice is ready" email, with a fresh
|
|
703
|
+
* portal link, because the one in the original may have expired. It
|
|
704
|
+
* goes to the address captured **on the invoice**, not the customer's
|
|
705
|
+
* current one: this is a copy of a document that was issued to
|
|
706
|
+
* somebody. An invoice with no address on file is a
|
|
707
|
+
* `InvalidRequestError` rather than a send that did not happen.
|
|
708
|
+
*/
|
|
709
|
+
sendEmail(id, params = {}) {
|
|
710
|
+
return this.postEmpty(`/v1/invoices/${p(id)}/email`, params);
|
|
630
711
|
}
|
|
631
712
|
list(params = {}) {
|
|
632
713
|
return this.get("/v1/invoices", params);
|
|
633
714
|
}
|
|
634
715
|
iter(options = {}) {
|
|
635
|
-
|
|
716
|
+
const { pageSize, ...filters } = options;
|
|
717
|
+
return paginate((page) => this.get("/v1/invoices", page), { pageSize, filters });
|
|
636
718
|
}
|
|
637
719
|
/**
|
|
638
720
|
* Void an invoice: state that the sale was never owed.
|
|
@@ -650,12 +732,12 @@ var Invoices = class extends BaseResource {
|
|
|
650
732
|
* Idempotent: re-voiding an already-void invoice returns it unchanged.
|
|
651
733
|
*/
|
|
652
734
|
void(id, params = {}) {
|
|
653
|
-
return this.post(`/v1/invoices/${id}/void`, params);
|
|
735
|
+
return this.post(`/v1/invoices/${p(id)}/void`, params);
|
|
654
736
|
}
|
|
655
737
|
};
|
|
656
738
|
var CreditNotes = class extends BaseResource {
|
|
657
739
|
retrieve(id) {
|
|
658
|
-
return this.get(`/v1/credit_notes/${id}`);
|
|
740
|
+
return this.get(`/v1/credit_notes/${p(id)}`);
|
|
659
741
|
}
|
|
660
742
|
/**
|
|
661
743
|
* Download the rendered credit note PDF as raw bytes. Same storage
|
|
@@ -663,13 +745,13 @@ var CreditNotes = class extends BaseResource {
|
|
|
663
745
|
* `302`, and `501 rendering_pending` on a deployment with no renderer.
|
|
664
746
|
*/
|
|
665
747
|
retrievePdf(id) {
|
|
666
|
-
return this.t.requestBinary({ method: "GET", path: `/v1/credit_notes/${id}/pdf` });
|
|
748
|
+
return this.t.requestBinary({ method: "GET", path: `/v1/credit_notes/${p(id)}/pdf` });
|
|
667
749
|
}
|
|
668
750
|
list(params = {}) {
|
|
669
751
|
return this.get("/v1/credit_notes", params);
|
|
670
752
|
}
|
|
671
753
|
iter(options = {}) {
|
|
672
|
-
return paginate((
|
|
754
|
+
return paginate((page) => this.get("/v1/credit_notes", page), {
|
|
673
755
|
pageSize: options.pageSize,
|
|
674
756
|
filters: { invoice_id: options.invoice_id, customer_id: options.customer_id }
|
|
675
757
|
});
|
|
@@ -677,13 +759,13 @@ var CreditNotes = class extends BaseResource {
|
|
|
677
759
|
};
|
|
678
760
|
var AuditLogs = class extends BaseResource {
|
|
679
761
|
retrieve(id) {
|
|
680
|
-
return this.get(`/v1/audit_logs/${id}`);
|
|
762
|
+
return this.get(`/v1/audit_logs/${p(id)}`);
|
|
681
763
|
}
|
|
682
764
|
list(params = {}) {
|
|
683
765
|
return this.get("/v1/audit_logs", params);
|
|
684
766
|
}
|
|
685
767
|
iter(options = {}) {
|
|
686
|
-
return paginate((
|
|
768
|
+
return paginate((page) => this.get("/v1/audit_logs", page), {
|
|
687
769
|
pageSize: options.pageSize,
|
|
688
770
|
filters: {
|
|
689
771
|
action: options.action,
|
|
@@ -695,30 +777,72 @@ var AuditLogs = class extends BaseResource {
|
|
|
695
777
|
}
|
|
696
778
|
};
|
|
697
779
|
var Payments = class extends BaseResource {
|
|
698
|
-
|
|
699
|
-
|
|
780
|
+
/** Expandable: `customer`, `subscription`. */
|
|
781
|
+
retrieve(id, options = {}) {
|
|
782
|
+
return this.get(`/v1/payments/${p(id)}`, options);
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Fetch the provider's own record of this charge, live.
|
|
786
|
+
*
|
|
787
|
+
* Reads Mollie at request time rather than a stored copy, so it carries
|
|
788
|
+
* what BillKit deliberately does not keep: the card BIN, the iDEAL
|
|
789
|
+
* bank, the provider's own status string. Reading live means it can
|
|
790
|
+
* fail: a provider outage or a charge old enough to have aged out
|
|
791
|
+
* answers `200` with `available: false` and a short reason, so render
|
|
792
|
+
* the rest of the page regardless.
|
|
793
|
+
*/
|
|
794
|
+
retrieveProvider(id) {
|
|
795
|
+
return this.get(`/v1/payments/${p(id)}/provider`);
|
|
700
796
|
}
|
|
701
797
|
list(params = {}) {
|
|
702
798
|
return this.get("/v1/payments", params);
|
|
703
799
|
}
|
|
704
800
|
iter(options = {}) {
|
|
705
|
-
return paginate((
|
|
801
|
+
return paginate((page) => this.get("/v1/payments", page), {
|
|
802
|
+
pageSize: options.pageSize,
|
|
803
|
+
filters: { customer_id: options.customer_id }
|
|
804
|
+
});
|
|
706
805
|
}
|
|
707
806
|
};
|
|
708
807
|
var BillingPortalSessions = class extends BaseResource {
|
|
709
808
|
create(params) {
|
|
710
|
-
return this.
|
|
711
|
-
"/v1/billing_portal/sessions",
|
|
712
|
-
{
|
|
713
|
-
subscription_id: params.subscription_id,
|
|
714
|
-
return_url: params.return_url
|
|
715
|
-
},
|
|
716
|
-
{ idempotencyKey: params.idempotencyKey }
|
|
717
|
-
);
|
|
809
|
+
return this.post("/v1/billing_portal/sessions", params);
|
|
718
810
|
}
|
|
719
811
|
/** Kill an in-the-wild portal session. Idempotent. */
|
|
720
812
|
revoke(id, params = {}) {
|
|
721
|
-
return this.postEmpty(`/v1/billing_portal/sessions/${id}/revoke`, params);
|
|
813
|
+
return this.postEmpty(`/v1/billing_portal/sessions/${p(id)}/revoke`, params);
|
|
814
|
+
}
|
|
815
|
+
};
|
|
816
|
+
var ApiKeys = class extends BaseResource {
|
|
817
|
+
/**
|
|
818
|
+
* Issue a new key. The response's `secret` is the only time the full
|
|
819
|
+
* key exists outside the caller's own storage, so record it now.
|
|
820
|
+
*/
|
|
821
|
+
create(params = {}) {
|
|
822
|
+
return this.post("/v1/api_keys", params);
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* One key's metadata: prefix, label, scopes, `revoked_at`, and
|
|
826
|
+
* `last_used_at`, which is the field to read before revoking one.
|
|
827
|
+
*/
|
|
828
|
+
retrieve(id) {
|
|
829
|
+
return this.get(`/v1/api_keys/${p(id)}`);
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Revoke a key so it stops working. Immediate and irreversible; issue a
|
|
833
|
+
* new key instead. Revoking an already-revoked key returns it
|
|
834
|
+
* unchanged, so a retry is safe, and a key may revoke itself, which is
|
|
835
|
+
* what you want when the leaked key is the one you are calling with.
|
|
836
|
+
*/
|
|
837
|
+
revoke(id, params = {}) {
|
|
838
|
+
return this.postEmpty(`/v1/api_keys/${p(id)}/revoke`, params);
|
|
839
|
+
}
|
|
840
|
+
/** List keys, newest first. Revoked ones are included; check `revoked_at`. */
|
|
841
|
+
list(params = {}) {
|
|
842
|
+
return this.get("/v1/api_keys", params);
|
|
843
|
+
}
|
|
844
|
+
iter(options = {}) {
|
|
845
|
+
return paginate((page) => this.get("/v1/api_keys", page), { pageSize: options.pageSize });
|
|
722
846
|
}
|
|
723
847
|
};
|
|
724
848
|
|
|
@@ -732,7 +856,7 @@ var BillKitError = class extends Error {
|
|
|
732
856
|
requestId;
|
|
733
857
|
rawBody;
|
|
734
858
|
constructor(message, options = {}) {
|
|
735
|
-
super(message);
|
|
859
|
+
super(message, options.cause === void 0 ? void 0 : { cause: options.cause });
|
|
736
860
|
this.type = options.type;
|
|
737
861
|
this.code = options.code;
|
|
738
862
|
this.param = options.param;
|
|
@@ -852,7 +976,7 @@ function sleep(ms) {
|
|
|
852
976
|
}
|
|
853
977
|
|
|
854
978
|
// src/version.ts
|
|
855
|
-
var VERSION = "0.
|
|
979
|
+
var VERSION = "0.7.1";
|
|
856
980
|
|
|
857
981
|
// src/transport.ts
|
|
858
982
|
var DEFAULT_BASE_URL = "https://api.billkit.eu";
|
|
@@ -880,9 +1004,8 @@ function buildUrl(baseUrl, path, query) {
|
|
|
880
1004
|
const url = new URL(baseUrl.replace(/\/$/, "") + normalised);
|
|
881
1005
|
if (query) {
|
|
882
1006
|
for (const [k, v] of Object.entries(query)) {
|
|
883
|
-
if (v
|
|
884
|
-
|
|
885
|
-
}
|
|
1007
|
+
if (v === null || v === void 0) continue;
|
|
1008
|
+
url.searchParams.set(k, Array.isArray(v) ? v.join(",") : String(v));
|
|
886
1009
|
}
|
|
887
1010
|
}
|
|
888
1011
|
return url.toString();
|
|
@@ -936,9 +1059,11 @@ function retryDelayMs(status, attempt, policy, retryAfterMs) {
|
|
|
936
1059
|
function connectionError(err, timeoutMs) {
|
|
937
1060
|
const e = err;
|
|
938
1061
|
if (e?.name === "TimeoutError" || e?.name === "AbortError") {
|
|
939
|
-
return new APIConnectionError(`BillKit request timed out after ${timeoutMs}ms
|
|
1062
|
+
return new APIConnectionError(`BillKit request timed out after ${timeoutMs}ms.`, {
|
|
1063
|
+
cause: err
|
|
1064
|
+
});
|
|
940
1065
|
}
|
|
941
|
-
return new APIConnectionError(e?.message ?? "Network request failed.");
|
|
1066
|
+
return new APIConnectionError(e?.message ?? "Network request failed.", { cause: err });
|
|
942
1067
|
}
|
|
943
1068
|
var Transport = class {
|
|
944
1069
|
apiKey;
|
|
@@ -1072,6 +1197,7 @@ function resolveApiKey(supplied) {
|
|
|
1072
1197
|
);
|
|
1073
1198
|
}
|
|
1074
1199
|
var BillKit = class {
|
|
1200
|
+
apiKeys;
|
|
1075
1201
|
customers;
|
|
1076
1202
|
products;
|
|
1077
1203
|
prices;
|
|
@@ -1095,6 +1221,7 @@ var BillKit = class {
|
|
|
1095
1221
|
...options,
|
|
1096
1222
|
apiKey: resolveApiKey(options.apiKey)
|
|
1097
1223
|
});
|
|
1224
|
+
this.apiKeys = new ApiKeys(transport);
|
|
1098
1225
|
this.customers = new Customers(transport);
|
|
1099
1226
|
this.products = new Products(transport);
|
|
1100
1227
|
this.prices = new Prices(transport);
|