@usebillow/sdk 0.9.0 → 0.11.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.
- package/CHANGELOG.md +17 -0
- package/dist/{billing-B16zL5xU.d.cts → billing-8ug1Gw05.d.cts} +9 -9
- package/dist/{billing-BF4OGaLI.d.ts → billing-Bs10EcjR.d.ts} +9 -9
- package/dist/{billing-status-BZQN_gm7.d.cts → billing-status-DZkB0VPK.d.cts} +5 -5
- package/dist/{billing-status-BZQN_gm7.d.ts → billing-status-DZkB0VPK.d.ts} +5 -5
- package/dist/{chunk-CCG4F5FK.js → chunk-47J7FYM5.js} +2 -2
- package/dist/chunk-47J7FYM5.js.map +1 -0
- package/dist/{chunk-GT5VBLN5.js → chunk-XUFQG6EA.js} +74 -22
- package/dist/chunk-XUFQG6EA.js.map +1 -0
- package/dist/config.cjs +3 -3
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +9 -9
- package/dist/config.d.ts +9 -9
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/{hosted-domains-DSTQ1GZz.d.ts → hosted-domains-BrnwkHqq.d.ts} +40 -2
- package/dist/{hosted-domains-DwakPG4J.d.cts → hosted-domains-zWm2srOk.d.cts} +40 -2
- package/dist/index.cjs +72 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -48
- package/dist/index.d.ts +70 -48
- package/dist/index.js +2 -2
- package/dist/ingestion.cjs.map +1 -1
- package/dist/ingestion.d.cts +18 -18
- package/dist/ingestion.d.ts +18 -18
- package/dist/ingestion.js.map +1 -1
- package/dist/react.cjs +28 -5
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +6 -6
- package/dist/react.d.ts +6 -6
- package/dist/react.js +2 -2
- package/dist/react.js.map +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +11 -11
- package/dist/server.d.ts +11 -11
- package/dist/server.js.map +1 -1
- package/dist/status.cjs.map +1 -1
- package/dist/status.d.cts +1 -1
- package/dist/status.d.ts +1 -1
- package/dist/status.js +1 -1
- package/dist/webhooks.cjs.map +1 -1
- package/dist/webhooks.d.cts +20 -15
- package/dist/webhooks.d.ts +20 -15
- package/dist/webhooks.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-CCG4F5FK.js.map +0 -1
- package/dist/chunk-GT5VBLN5.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -36,19 +36,26 @@ var BillowApiError = class extends Error {
|
|
|
36
36
|
code;
|
|
37
37
|
/** Structured error context from the server (e.g. per-field validation issues), when present. */
|
|
38
38
|
details;
|
|
39
|
-
/** billow's per-request id (`x-request-id`)
|
|
39
|
+
/** billow's per-request id (`x-request-id`) - quote it in a bug report to trace the server log. */
|
|
40
40
|
requestId;
|
|
41
|
-
|
|
41
|
+
/**
|
|
42
|
+
* How many seconds to wait before trying again, from the response's `Retry-After` header (sent
|
|
43
|
+
* with a `429 rate_limited`); undefined when the response did not say.
|
|
44
|
+
*/
|
|
45
|
+
retryAfterSeconds;
|
|
46
|
+
constructor(status, code, message, details, requestId, retryAfterSeconds) {
|
|
42
47
|
super(message);
|
|
43
48
|
this.name = "BillowApiError";
|
|
44
49
|
this.status = status;
|
|
45
50
|
this.code = code;
|
|
46
51
|
this.details = details;
|
|
47
52
|
this.requestId = requestId;
|
|
53
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
48
54
|
}
|
|
49
55
|
};
|
|
50
56
|
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
51
57
|
var DEFAULT_RETRY_BACKOFF_MS = 500;
|
|
58
|
+
var MAX_RETRY_AFTER_SECONDS = 3600;
|
|
52
59
|
function makeContext(bearer, opts) {
|
|
53
60
|
return {
|
|
54
61
|
fetch: opts.fetch ?? fetch,
|
|
@@ -67,7 +74,7 @@ function isRetryable(status, safeToRepeat2) {
|
|
|
67
74
|
function backoffMs(base, attempt, retryAfter) {
|
|
68
75
|
if (retryAfter) {
|
|
69
76
|
const secs = Number(retryAfter);
|
|
70
|
-
if (Number.isFinite(secs) && secs >= 0) return secs * 1e3;
|
|
77
|
+
if (Number.isFinite(secs) && secs >= 0) return Math.min(secs, MAX_RETRY_AFTER_SECONDS) * 1e3;
|
|
71
78
|
}
|
|
72
79
|
return base * 2 ** attempt;
|
|
73
80
|
}
|
|
@@ -189,9 +196,25 @@ function errorFrom(res, data) {
|
|
|
189
196
|
err.code ?? "error",
|
|
190
197
|
err.message ?? String(res.status),
|
|
191
198
|
err.details,
|
|
192
|
-
requestIdOf(res)
|
|
199
|
+
requestIdOf(res),
|
|
200
|
+
retryAfterOf(res)
|
|
193
201
|
);
|
|
194
202
|
}
|
|
203
|
+
var IMF_FIXDATE = /^[A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4} \d{2}:\d{2}:\d{2} GMT$/;
|
|
204
|
+
function retryAfterOf(res) {
|
|
205
|
+
const value = res.headers.get("retry-after")?.trim();
|
|
206
|
+
if (!value) return void 0;
|
|
207
|
+
let seconds;
|
|
208
|
+
if (/^\d+$/.test(value)) {
|
|
209
|
+
seconds = Number(value);
|
|
210
|
+
} else if (IMF_FIXDATE.test(value)) {
|
|
211
|
+
seconds = Math.ceil((Date.parse(value) - Date.now()) / 1e3);
|
|
212
|
+
} else {
|
|
213
|
+
return void 0;
|
|
214
|
+
}
|
|
215
|
+
if (!Number.isFinite(seconds)) return void 0;
|
|
216
|
+
return Math.min(Math.max(0, seconds), MAX_RETRY_AFTER_SECONDS);
|
|
217
|
+
}
|
|
195
218
|
async function apiRequestBinary(ctx, method, path2, options) {
|
|
196
219
|
const res = await sendWithResilience(
|
|
197
220
|
ctx,
|
|
@@ -496,6 +519,35 @@ function createCreditsResource(ctx) {
|
|
|
496
519
|
return { ...data, replayed: status === 200 };
|
|
497
520
|
}
|
|
498
521
|
},
|
|
522
|
+
accounts: {
|
|
523
|
+
/**
|
|
524
|
+
* Freeze a customer's Credit Account (by external id): it takes no new reservations - a
|
|
525
|
+
* reserve throws `account_frozen` (423) - until unfrozen, while holds already made still
|
|
526
|
+
* commit and release, and grants, top-ups, reversals and included credits still fund it.
|
|
527
|
+
* Safe to retry: freezing a frozen account changes nothing and answers `changed: false`. A
|
|
528
|
+
* customer with no account yet gets one, frozen. Throws `account_closed` (409) for an erased
|
|
529
|
+
* customer.
|
|
530
|
+
*/
|
|
531
|
+
freeze: (customer, options) => apiRequest(
|
|
532
|
+
ctx,
|
|
533
|
+
"POST",
|
|
534
|
+
"/v1/credits/accounts/freeze",
|
|
535
|
+
{ customerId: customer },
|
|
536
|
+
options
|
|
537
|
+
),
|
|
538
|
+
/**
|
|
539
|
+
* Unfreeze a customer's Credit Account (by external id): it takes reservations again. Safe to
|
|
540
|
+
* retry: unfreezing an account that is not frozen changes nothing and answers
|
|
541
|
+
* `changed: false`.
|
|
542
|
+
*/
|
|
543
|
+
unfreeze: (customer, options) => apiRequest(
|
|
544
|
+
ctx,
|
|
545
|
+
"POST",
|
|
546
|
+
"/v1/credits/accounts/unfreeze",
|
|
547
|
+
{ customerId: customer },
|
|
548
|
+
options
|
|
549
|
+
)
|
|
550
|
+
},
|
|
499
551
|
packs: {
|
|
500
552
|
/**
|
|
501
553
|
* The Credit Packs a customer can buy in `currency` (ISO 4217), cheapest first: credits and
|
|
@@ -1208,7 +1260,7 @@ function createSettingsResource(ctx) {
|
|
|
1208
1260
|
},
|
|
1209
1261
|
/**
|
|
1210
1262
|
* Usage settlement grace (hours): defers *collection* of a boundary-adjacent priced
|
|
1211
|
-
* calendar-meter renewal past the tz month boundary until late usage settles
|
|
1263
|
+
* calendar-meter renewal past the tz month boundary until late usage settles - the billed
|
|
1212
1264
|
* windows/amount are unchanged, only the invoice timing shifts. `0` disables it (the default);
|
|
1213
1265
|
* a no-op for any subscription without a priced calendar meter. Cap 72h.
|
|
1214
1266
|
*/
|
|
@@ -1335,7 +1387,7 @@ function createSubscriptionsResource(ctx) {
|
|
|
1335
1387
|
void 0,
|
|
1336
1388
|
options
|
|
1337
1389
|
),
|
|
1338
|
-
/** Cancel
|
|
1390
|
+
/** Cancel - immediately, or at period end with `{ atPeriodEnd: true }`. */
|
|
1339
1391
|
cancel: (id, opts) => apiRequest(
|
|
1340
1392
|
ctx,
|
|
1341
1393
|
"POST",
|
|
@@ -1368,7 +1420,7 @@ function createSubscriptionsResource(ctx) {
|
|
|
1368
1420
|
`/v1/subscriptions/${encodeURIComponent(id)}/coupon`,
|
|
1369
1421
|
{ code }
|
|
1370
1422
|
),
|
|
1371
|
-
/** Change plan
|
|
1423
|
+
/** Change plan - immediate prorated upgrade, or downgrade scheduled for period end. `productId` accepts the product's id or slug. */
|
|
1372
1424
|
changePlan: (id, productId) => apiRequest(ctx, "POST", `/v1/subscriptions/${encodeURIComponent(id)}/change-plan`, { productId }),
|
|
1373
1425
|
/** Clear a pending downgrade. Duplicate calls are safe. */
|
|
1374
1426
|
clearScheduledPlanChange: (id) => apiRequest(
|
|
@@ -1442,7 +1494,7 @@ function createWebhookEndpointsResource(ctx) {
|
|
|
1442
1494
|
),
|
|
1443
1495
|
/** Delete an endpoint and its delivery history. */
|
|
1444
1496
|
delete: (id) => apiRequest(ctx, "DELETE", `/v1/webhook-endpoints/${encodeURIComponent(id)}`),
|
|
1445
|
-
/** Rotate the signing secret
|
|
1497
|
+
/** Rotate the signing secret - the new plaintext is returned once. */
|
|
1446
1498
|
rotateSecret: (id) => apiRequest(
|
|
1447
1499
|
ctx,
|
|
1448
1500
|
"POST",
|
|
@@ -1481,7 +1533,7 @@ var Billow = class {
|
|
|
1481
1533
|
/** Custom domains for the hosted customer portal (live keys, behind a rollout flag). */
|
|
1482
1534
|
hostedDomains;
|
|
1483
1535
|
/**
|
|
1484
|
-
* Organization settings (Phase D3, F)
|
|
1536
|
+
* Organization settings (Phase D3, F) - the configurable dunning schedule, usage settlement grace,
|
|
1485
1537
|
* and the cross-currency reporting currency + FX-rate registry (ADR-0013).
|
|
1486
1538
|
*/
|
|
1487
1539
|
settings;
|
|
@@ -1509,7 +1561,7 @@ var Billow = class {
|
|
|
1509
1561
|
coupons = {
|
|
1510
1562
|
/** Define a coupon (a reusable discount template). */
|
|
1511
1563
|
create: (input) => this.#request("POST", "/v1/coupons", input),
|
|
1512
|
-
/** List coupons (secret key only
|
|
1564
|
+
/** List coupons (secret key only - enumerates live promo codes). Auto-paginating. */
|
|
1513
1565
|
list: (params = {}, options) => makeListPromise(
|
|
1514
1566
|
(p) => this.#request("GET", `/v1/coupons${toQuery(p)}`, void 0, options),
|
|
1515
1567
|
params
|
|
@@ -1517,13 +1569,13 @@ var Billow = class {
|
|
|
1517
1569
|
/** Deactivate a coupon (existing discounts keep running). */
|
|
1518
1570
|
deactivate: (id) => this.#request("POST", `/v1/coupons/${encodeURIComponent(id)}/deactivate`)
|
|
1519
1571
|
};
|
|
1520
|
-
/** Manage developer webhook endpoints
|
|
1572
|
+
/** Manage developer webhook endpoints - register, rotate secrets, inspect deliveries.
|
|
1521
1573
|
* (To VERIFY incoming deliveries, import `constructEvent` from `@usebillow/sdk/webhooks`.) */
|
|
1522
1574
|
features = {
|
|
1523
1575
|
/** Define a feature (a boolean access gate, or a metered feature with a meter). */
|
|
1524
1576
|
create: (input) => this.#request("POST", "/v1/features", input),
|
|
1525
1577
|
/**
|
|
1526
|
-
* Edit a feature in place: its `name`, and
|
|
1578
|
+
* Edit a feature in place: its `name`, and - for a metered feature - its `meter`
|
|
1527
1579
|
* aggregation. The server refuses a meter change once usage has been recorded (it
|
|
1528
1580
|
* would rewrite billed history), so set the meter right at create time or before you
|
|
1529
1581
|
* start tracking. Returns the updated feature.
|
|
@@ -1580,7 +1632,7 @@ var Billow = class {
|
|
|
1580
1632
|
* choose a credential set and `target` to probe one verify target (Paymob: a
|
|
1581
1633
|
* method); pass `sampleToken` (SANDBOX ONLY) to run a functional sub-test.
|
|
1582
1634
|
* This probe hits the provider's live API (mutates nothing here), so it takes a
|
|
1583
|
-
* per-call {@link CallOptions} for a timeout / cancellation
|
|
1635
|
+
* per-call {@link CallOptions} for a timeout / cancellation - `opts` is spread into
|
|
1584
1636
|
* the body, so `options` stays a separate trailing arg (never merged in).
|
|
1585
1637
|
*/
|
|
1586
1638
|
verify: (provider, opts, options) => this.#request(
|
|
@@ -1607,7 +1659,7 @@ var Billow = class {
|
|
|
1607
1659
|
)
|
|
1608
1660
|
}
|
|
1609
1661
|
};
|
|
1610
|
-
/** The merchant's business identity
|
|
1662
|
+
/** The merchant's business identity - the seller block on documents and email from-name. */
|
|
1611
1663
|
businessProfile = {
|
|
1612
1664
|
/** The stored profile, or null if one was never saved. */
|
|
1613
1665
|
get: (options) => this.#request(
|
|
@@ -1623,11 +1675,11 @@ var Billow = class {
|
|
|
1623
1675
|
};
|
|
1624
1676
|
/**
|
|
1625
1677
|
* Hosted customer surfaces (Phase G, ADR-0014). Mint a portal session for one of
|
|
1626
|
-
* your signed-in users and redirect them to the returned `url`
|
|
1678
|
+
* your signed-in users and redirect them to the returned `url` - the self-serve
|
|
1627
1679
|
* portal, or a `checkout` hand-off for `productId`. The Customer's own calls go
|
|
1628
1680
|
* through {@link BillowPortal}, constructed with the session token.
|
|
1629
1681
|
*/
|
|
1630
|
-
/** Identity of this key's tenant
|
|
1682
|
+
/** Identity of this key's tenant - org, environment, configured currencies. */
|
|
1631
1683
|
me(options) {
|
|
1632
1684
|
return this.#request("GET", "/v1/me", void 0, options);
|
|
1633
1685
|
}
|
|
@@ -1647,14 +1699,14 @@ var Billow = class {
|
|
|
1647
1699
|
// ── The headline verbs ──────────────────────────────────────────────
|
|
1648
1700
|
/**
|
|
1649
1701
|
* Gate access to a feature. `featureId` is the feature slug. Returns
|
|
1650
|
-
* `{ allowed, balance }`
|
|
1702
|
+
* `{ allowed, balance }` - `balance` is `null` for unlimited/boolean features.
|
|
1651
1703
|
*/
|
|
1652
1704
|
check(input, options) {
|
|
1653
1705
|
return this.#request("POST", "/v1/check", input, options);
|
|
1654
1706
|
}
|
|
1655
1707
|
/**
|
|
1656
1708
|
* Record usage of a metered feature (`value` defaults to 1; negative credits
|
|
1657
|
-
* back). Pass `idempotencyKey` to make a retried call a no-op
|
|
1709
|
+
* back). Pass `idempotencyKey` to make a retried call a no-op - which also makes the call
|
|
1658
1710
|
* safe to retry automatically when `maxRetries` is set.
|
|
1659
1711
|
*/
|
|
1660
1712
|
track(input, options) {
|
|
@@ -1691,7 +1743,7 @@ var BillowPublishable = class {
|
|
|
1691
1743
|
this.#ctx = makeContext(publishableKey, opts);
|
|
1692
1744
|
}
|
|
1693
1745
|
products = {
|
|
1694
|
-
/** The active catalog
|
|
1746
|
+
/** The active catalog - products and their prices, for a pricing table. */
|
|
1695
1747
|
list: (options) => apiRequest(
|
|
1696
1748
|
this.#ctx,
|
|
1697
1749
|
"GET",
|
|
@@ -1715,7 +1767,7 @@ var BillowPortal = class {
|
|
|
1715
1767
|
if (!sessionToken) throw new Error("billow: a portal session token is required");
|
|
1716
1768
|
this.#ctx = makeContext(sessionToken, opts);
|
|
1717
1769
|
}
|
|
1718
|
-
/** The portal shell: flow, return URL, merchant brand, and customer identity
|
|
1770
|
+
/** The portal shell: flow, return URL, merchant brand, and customer identity -
|
|
1719
1771
|
* the lightweight payload the hosting app frames every page with, and the
|
|
1720
1772
|
* validate-and-route check at login. */
|
|
1721
1773
|
session(options) {
|