@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @usebillow/sdk
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f9db27d: `credits.accounts.freeze(customer)` and `credits.accounts.unfreeze(customer)` freeze and unfreeze a customer's Credit Account (by external id), answering the new `CreditAccount` type: `{ customerId, status, changed }`, where `changed` says whether this call moved the account (false for a repeat; of two racing calls exactly one is true). A frozen account takes no new reservations - a reserve throws `account_frozen` (423) - while holds already made still commit and release, and grants, top-ups, reversals and included credits still fund it. Both are safe to retry (a repeat changes nothing) and take no idempotency key; an erased customer's account throws `account_closed` (409). A credit top-up (`CreditTopUp`) now also carries `packName`, the pack's name when it was bought, and `consumed`, the microcredits of its credits the customer has spent (consumed, net of reversals) - what a refund can never take back, and what refunding the whole payment leaves as its `shortfall`. A ledger entry (`CreditLedgerEntry`) now carries `grantKind`, the kind of the grant it names (null when it names no one grant), so a promotional grant and an adjustment - both `reason: "api_grant"` - read apart.
|
|
8
|
+
|
|
9
|
+
## 0.10.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 935c12d: Included credits now follow plan changes and early endings. A plan upgrade inside the period raises its current and later Included Credit Windows to the new plan's rule (a high-water mark, never lowered), and the difference is issued at once as an `included` grant with ledger reason `subscription_upgrade`; `CreditIncludedWindow` gains `raisedAt`, when an upgrade last raised the window. An immediate cancellation, or a lost chargeback of the payment for the period, ends the period's unspent included credits and its later refills: the window reads `ended` with its `endedAt` and `endCause` (`canceled` or `charged_back`), and the grant's unheld credits expire with ledger reason `subscription_canceled` or `subscription_charged_back`. The `credit_grant.expired` webhook data's `reason` is now `grant_expired`, `subscription_canceled` or `subscription_charged_back`.
|
|
14
|
+
- a41c39f: `BillowApiError.retryAfterSeconds` says how many seconds to wait before trying again, read from the response's `Retry-After` header: whole seconds, or an HTTP date (`Sun, 06 Nov 1994 08:49:37 GMT`) counted from now, at most an hour. billow sends it with a `429 rate_limited`; it is undefined when the response did not say, or said something that is neither. With `maxRetries` set, the SDK already waited between attempts (now at most an hour, however long the header asks); a caller that does not retry can now tell its user when to try again.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- a41c39f: Usage line descriptions count their units in words: `Usage - 1 unit over allowance` or `Usage - 7 units over allowance` (and `Usage - api: 7 units over allowance (2026-03-01 - 2026-04-01)` for a reset window) instead of `unit(s)`. This is the text of an invoice's usage `lineItems` from `invoices.get`, and of an invoice's `reason` (its first line) from `invoices.list` and the portal's `invoices.list` and `invoices.get` when that line is a usage line. Invoices issued before keep the descriptions they were issued with. No SDK code changed.
|
|
19
|
+
|
|
3
20
|
## 0.9.0
|
|
4
21
|
|
|
5
22
|
### Minor Changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { A as ActivatedSubscriptionResponse, C as CreateSubscriptionResponse, P as PendingSubscriptionCheckoutResponse, a as ProductResponse, b as ProductEntitlementResponse, c as ProductPriceResponse, S as SubscriptionResponse, d as SubscriptionDetailResponse, e as SubscriptionItemResponse } from './index.d-DSEYhV2c.cjs';
|
|
2
|
-
import { C as ChargeStatus } from './billing-status-
|
|
2
|
+
import { C as ChargeStatus } from './billing-status-DZkB0VPK.cjs';
|
|
3
3
|
|
|
4
4
|
/** Public SDK types for this domain. Re-exported by ../types.ts. */
|
|
5
5
|
interface BillowOptions {
|
|
@@ -16,14 +16,14 @@ interface BillowOptions {
|
|
|
16
16
|
*/
|
|
17
17
|
timeoutMs?: number;
|
|
18
18
|
/**
|
|
19
|
-
* How many times to retry a transient failure. Retries are **opt-in**
|
|
19
|
+
* How many times to retry a transient failure. Retries are **opt-in** - the default is
|
|
20
20
|
* `0`. Only requests that are safe to repeat are retried: every `GET`, plus **any** method
|
|
21
21
|
* on a `429` (a rate-limited request never executed). A write (`POST`/`PATCH`/`DELETE`) is
|
|
22
22
|
* never retried on a `5xx`/network error, since it may have already applied.
|
|
23
23
|
*/
|
|
24
24
|
maxRetries?: number;
|
|
25
25
|
/**
|
|
26
|
-
* Base backoff in milliseconds between retries
|
|
26
|
+
* Base backoff in milliseconds between retries - exponential (`base × 2^attempt`), and a
|
|
27
27
|
* `Retry-After` response header takes precedence when present. Defaults to 500.
|
|
28
28
|
*/
|
|
29
29
|
retryBackoffMs?: number;
|
|
@@ -32,7 +32,7 @@ interface BillowOptions {
|
|
|
32
32
|
* Per-call overrides passed as the last argument to a resource method.
|
|
33
33
|
* - `signal` cancels the request (a caller abort is surfaced immediately and never retried).
|
|
34
34
|
* - `timeoutMs` overrides the client's default timeout for this call (applied per attempt).
|
|
35
|
-
* - `idempotencyKey` sends an `Idempotency-Key` and makes the write **safe to retry**
|
|
35
|
+
* - `idempotencyKey` sends an `Idempotency-Key` and makes the write **safe to retry** - reused
|
|
36
36
|
* verbatim on every attempt. Only exposed on writes the server replays (create/attach/track/refund).
|
|
37
37
|
*/
|
|
38
38
|
interface RequestOptions {
|
|
@@ -44,7 +44,7 @@ interface RequestOptions {
|
|
|
44
44
|
type IdempotentRequestOptions = RequestOptions & {
|
|
45
45
|
idempotencyKey: string;
|
|
46
46
|
};
|
|
47
|
-
/** Per-call overrides for reads and non-replayable writes
|
|
47
|
+
/** Per-call overrides for reads and non-replayable writes - cancellation + timeout, no idempotency key. */
|
|
48
48
|
type CallOptions = Omit<RequestOptions, "idempotencyKey">;
|
|
49
49
|
interface Customer {
|
|
50
50
|
id: string;
|
|
@@ -77,7 +77,7 @@ interface MeterFilter {
|
|
|
77
77
|
key: string;
|
|
78
78
|
values: string[];
|
|
79
79
|
}
|
|
80
|
-
/** A meter's measurement config (ADR-0011)
|
|
80
|
+
/** A meter's measurement config (ADR-0011) - how a metered feature's usage aggregates. */
|
|
81
81
|
interface MeterConfig {
|
|
82
82
|
aggregation: MeterAggregation;
|
|
83
83
|
eventProperty?: string | null;
|
|
@@ -186,7 +186,7 @@ interface Feature {
|
|
|
186
186
|
}
|
|
187
187
|
/**
|
|
188
188
|
* An in-place edit to a feature. `name` is always allowed; `meter` re-configures a
|
|
189
|
-
* metered feature's aggregation
|
|
189
|
+
* metered feature's aggregation - but the server refuses a meter change once usage has
|
|
190
190
|
* been recorded (it would rewrite billed history). At least one field must be present.
|
|
191
191
|
*/
|
|
192
192
|
interface UpdateFeatureInput {
|
|
@@ -221,7 +221,7 @@ interface CreateUsageAlertInput {
|
|
|
221
221
|
}
|
|
222
222
|
interface TrackResult {
|
|
223
223
|
ok: true;
|
|
224
|
-
/** True when the idempotency key was already seen
|
|
224
|
+
/** True when the idempotency key was already seen - the call was a no-op. */
|
|
225
225
|
deduplicated: boolean;
|
|
226
226
|
/** Remaining balance for the feature; `null` if unlimited. */
|
|
227
227
|
balance: number | null;
|
|
@@ -238,7 +238,7 @@ type Product = ProductResponse;
|
|
|
238
238
|
type Subscription = SubscriptionResponse;
|
|
239
239
|
/** A single fetched subscription (`subscriptions.get`) - {@link Subscription} plus the stable `customerExternalId` + `productSlug`. */
|
|
240
240
|
type SubscriptionDetail = SubscriptionDetailResponse;
|
|
241
|
-
/** A subscription line item
|
|
241
|
+
/** A subscription line item - the base plan or an attached add-on (Phase D2). */
|
|
242
242
|
type SubscriptionItem = SubscriptionItemResponse;
|
|
243
243
|
interface CreateSubscriptionInput {
|
|
244
244
|
customerId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { A as ActivatedSubscriptionResponse, C as CreateSubscriptionResponse, P as PendingSubscriptionCheckoutResponse, a as ProductResponse, b as ProductEntitlementResponse, c as ProductPriceResponse, S as SubscriptionResponse, d as SubscriptionDetailResponse, e as SubscriptionItemResponse } from './index.d-DSEYhV2c.js';
|
|
2
|
-
import { C as ChargeStatus } from './billing-status-
|
|
2
|
+
import { C as ChargeStatus } from './billing-status-DZkB0VPK.js';
|
|
3
3
|
|
|
4
4
|
/** Public SDK types for this domain. Re-exported by ../types.ts. */
|
|
5
5
|
interface BillowOptions {
|
|
@@ -16,14 +16,14 @@ interface BillowOptions {
|
|
|
16
16
|
*/
|
|
17
17
|
timeoutMs?: number;
|
|
18
18
|
/**
|
|
19
|
-
* How many times to retry a transient failure. Retries are **opt-in**
|
|
19
|
+
* How many times to retry a transient failure. Retries are **opt-in** - the default is
|
|
20
20
|
* `0`. Only requests that are safe to repeat are retried: every `GET`, plus **any** method
|
|
21
21
|
* on a `429` (a rate-limited request never executed). A write (`POST`/`PATCH`/`DELETE`) is
|
|
22
22
|
* never retried on a `5xx`/network error, since it may have already applied.
|
|
23
23
|
*/
|
|
24
24
|
maxRetries?: number;
|
|
25
25
|
/**
|
|
26
|
-
* Base backoff in milliseconds between retries
|
|
26
|
+
* Base backoff in milliseconds between retries - exponential (`base × 2^attempt`), and a
|
|
27
27
|
* `Retry-After` response header takes precedence when present. Defaults to 500.
|
|
28
28
|
*/
|
|
29
29
|
retryBackoffMs?: number;
|
|
@@ -32,7 +32,7 @@ interface BillowOptions {
|
|
|
32
32
|
* Per-call overrides passed as the last argument to a resource method.
|
|
33
33
|
* - `signal` cancels the request (a caller abort is surfaced immediately and never retried).
|
|
34
34
|
* - `timeoutMs` overrides the client's default timeout for this call (applied per attempt).
|
|
35
|
-
* - `idempotencyKey` sends an `Idempotency-Key` and makes the write **safe to retry**
|
|
35
|
+
* - `idempotencyKey` sends an `Idempotency-Key` and makes the write **safe to retry** - reused
|
|
36
36
|
* verbatim on every attempt. Only exposed on writes the server replays (create/attach/track/refund).
|
|
37
37
|
*/
|
|
38
38
|
interface RequestOptions {
|
|
@@ -44,7 +44,7 @@ interface RequestOptions {
|
|
|
44
44
|
type IdempotentRequestOptions = RequestOptions & {
|
|
45
45
|
idempotencyKey: string;
|
|
46
46
|
};
|
|
47
|
-
/** Per-call overrides for reads and non-replayable writes
|
|
47
|
+
/** Per-call overrides for reads and non-replayable writes - cancellation + timeout, no idempotency key. */
|
|
48
48
|
type CallOptions = Omit<RequestOptions, "idempotencyKey">;
|
|
49
49
|
interface Customer {
|
|
50
50
|
id: string;
|
|
@@ -77,7 +77,7 @@ interface MeterFilter {
|
|
|
77
77
|
key: string;
|
|
78
78
|
values: string[];
|
|
79
79
|
}
|
|
80
|
-
/** A meter's measurement config (ADR-0011)
|
|
80
|
+
/** A meter's measurement config (ADR-0011) - how a metered feature's usage aggregates. */
|
|
81
81
|
interface MeterConfig {
|
|
82
82
|
aggregation: MeterAggregation;
|
|
83
83
|
eventProperty?: string | null;
|
|
@@ -186,7 +186,7 @@ interface Feature {
|
|
|
186
186
|
}
|
|
187
187
|
/**
|
|
188
188
|
* An in-place edit to a feature. `name` is always allowed; `meter` re-configures a
|
|
189
|
-
* metered feature's aggregation
|
|
189
|
+
* metered feature's aggregation - but the server refuses a meter change once usage has
|
|
190
190
|
* been recorded (it would rewrite billed history). At least one field must be present.
|
|
191
191
|
*/
|
|
192
192
|
interface UpdateFeatureInput {
|
|
@@ -221,7 +221,7 @@ interface CreateUsageAlertInput {
|
|
|
221
221
|
}
|
|
222
222
|
interface TrackResult {
|
|
223
223
|
ok: true;
|
|
224
|
-
/** True when the idempotency key was already seen
|
|
224
|
+
/** True when the idempotency key was already seen - the call was a no-op. */
|
|
225
225
|
deduplicated: boolean;
|
|
226
226
|
/** Remaining balance for the feature; `null` if unlimited. */
|
|
227
227
|
balance: number | null;
|
|
@@ -238,7 +238,7 @@ type Product = ProductResponse;
|
|
|
238
238
|
type Subscription = SubscriptionResponse;
|
|
239
239
|
/** A single fetched subscription (`subscriptions.get`) - {@link Subscription} plus the stable `customerExternalId` + `productSlug`. */
|
|
240
240
|
type SubscriptionDetail = SubscriptionDetailResponse;
|
|
241
|
-
/** A subscription line item
|
|
241
|
+
/** A subscription line item - the base plan or an attached add-on (Phase D2). */
|
|
242
242
|
type SubscriptionItem = SubscriptionItemResponse;
|
|
243
243
|
interface CreateSubscriptionInput {
|
|
244
244
|
customerId: string;
|
|
@@ -5,21 +5,21 @@
|
|
|
5
5
|
* against it (see billing-status.test.ts); webhook-delivery status is a free-text column
|
|
6
6
|
* server-side with a fixed vocabulary, documented here.
|
|
7
7
|
*/
|
|
8
|
-
/** A charge's lifecycle status
|
|
8
|
+
/** A charge's lifecycle status - mirrors `@billow/core` `CHARGE_STATUSES`. */
|
|
9
9
|
declare const CHARGE_STATUSES: readonly ["pending", "processing", "succeeded", "failed", "requires_reconciliation", "disputed"];
|
|
10
10
|
type ChargeStatus = (typeof CHARGE_STATUSES)[number];
|
|
11
|
-
/** An invoice's lifecycle status
|
|
11
|
+
/** An invoice's lifecycle status - mirrors `@billow/core` `INVOICE_STATUSES`. */
|
|
12
12
|
declare const INVOICE_STATUSES: readonly ["draft", "open", "paid", "uncollectible", "void"];
|
|
13
13
|
type InvoiceStatus = (typeof INVOICE_STATUSES)[number];
|
|
14
|
-
/** A refund's lifecycle status
|
|
14
|
+
/** A refund's lifecycle status - mirrors `@billow/core` `REFUND_STATUSES`. */
|
|
15
15
|
declare const REFUND_STATUSES: readonly ["pending", "succeeded", "failed"];
|
|
16
16
|
type RefundStatus = (typeof REFUND_STATUSES)[number];
|
|
17
|
-
/** A saved payment method's status
|
|
17
|
+
/** A saved payment method's status - mirrors `@billow/core` `PAYMENT_METHOD_STATUSES`. */
|
|
18
18
|
declare const PAYMENT_METHOD_STATUSES: readonly ["active", "expired", "removed"];
|
|
19
19
|
type PaymentMethodStatus = (typeof PAYMENT_METHOD_STATUSES)[number];
|
|
20
20
|
/**
|
|
21
21
|
* A webhook delivery attempt's status. Not a DB enum (a free-text column); the dispatcher
|
|
22
|
-
* inserts one row per attempt with exactly `delivered` (a 2xx) or `failed` (anything else)
|
|
22
|
+
* inserts one row per attempt with exactly `delivered` (a 2xx) or `failed` (anything else) -
|
|
23
23
|
* see `packages/server/src/jobs/outbox.ts`. (Retry/backoff state lives on the outbox event,
|
|
24
24
|
* a separate table, not on the delivery record.)
|
|
25
25
|
*/
|
|
@@ -5,21 +5,21 @@
|
|
|
5
5
|
* against it (see billing-status.test.ts); webhook-delivery status is a free-text column
|
|
6
6
|
* server-side with a fixed vocabulary, documented here.
|
|
7
7
|
*/
|
|
8
|
-
/** A charge's lifecycle status
|
|
8
|
+
/** A charge's lifecycle status - mirrors `@billow/core` `CHARGE_STATUSES`. */
|
|
9
9
|
declare const CHARGE_STATUSES: readonly ["pending", "processing", "succeeded", "failed", "requires_reconciliation", "disputed"];
|
|
10
10
|
type ChargeStatus = (typeof CHARGE_STATUSES)[number];
|
|
11
|
-
/** An invoice's lifecycle status
|
|
11
|
+
/** An invoice's lifecycle status - mirrors `@billow/core` `INVOICE_STATUSES`. */
|
|
12
12
|
declare const INVOICE_STATUSES: readonly ["draft", "open", "paid", "uncollectible", "void"];
|
|
13
13
|
type InvoiceStatus = (typeof INVOICE_STATUSES)[number];
|
|
14
|
-
/** A refund's lifecycle status
|
|
14
|
+
/** A refund's lifecycle status - mirrors `@billow/core` `REFUND_STATUSES`. */
|
|
15
15
|
declare const REFUND_STATUSES: readonly ["pending", "succeeded", "failed"];
|
|
16
16
|
type RefundStatus = (typeof REFUND_STATUSES)[number];
|
|
17
|
-
/** A saved payment method's status
|
|
17
|
+
/** A saved payment method's status - mirrors `@billow/core` `PAYMENT_METHOD_STATUSES`. */
|
|
18
18
|
declare const PAYMENT_METHOD_STATUSES: readonly ["active", "expired", "removed"];
|
|
19
19
|
type PaymentMethodStatus = (typeof PAYMENT_METHOD_STATUSES)[number];
|
|
20
20
|
/**
|
|
21
21
|
* A webhook delivery attempt's status. Not a DB enum (a free-text column); the dispatcher
|
|
22
|
-
* inserts one row per attempt with exactly `delivered` (a 2xx) or `failed` (anything else)
|
|
22
|
+
* inserts one row per attempt with exactly `delivered` (a 2xx) or `failed` (anything else) -
|
|
23
23
|
* see `packages/server/src/jobs/outbox.ts`. (Retry/backoff state lives on the outbox event,
|
|
24
24
|
* a separate table, not on the delivery record.)
|
|
25
25
|
*/
|
|
@@ -44,5 +44,5 @@ function isTerminal(status) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export { ACTIVE_SUBSCRIPTION_STATUSES, CHARGE_STATUSES, INVOICE_STATUSES, NEVER_ACTIVATED_SUBSCRIPTION_STATUSES, PAYMENT_METHOD_STATUSES, REFUND_STATUSES, SUBSCRIPTION_STATUSES, TERMINAL_SUBSCRIPTION_STATUSES, WEBHOOK_DELIVERY_STATUSES, grantsAccess, isTerminal };
|
|
47
|
-
//# sourceMappingURL=chunk-
|
|
48
|
-
//# sourceMappingURL=chunk-
|
|
47
|
+
//# sourceMappingURL=chunk-47J7FYM5.js.map
|
|
48
|
+
//# sourceMappingURL=chunk-47J7FYM5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/billing-status.ts","../src/subscription-status.ts"],"names":[],"mappings":";AASO,IAAM,eAAA,GAAkB;AAAA,EAC7B,SAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,yBAAA;AAAA,EACA;AACF;AAIO,IAAM,mBAAmB,CAAC,OAAA,EAAS,MAAA,EAAQ,MAAA,EAAQ,iBAAiB,MAAM;AAI1E,IAAM,eAAA,GAAkB,CAAC,SAAA,EAAW,WAAA,EAAa,QAAQ;AAIzD,IAAM,uBAAA,GAA0B,CAAC,QAAA,EAAU,SAAA,EAAW,SAAS;AAS/D,IAAM,yBAAA,GAA4B,CAAC,WAAA,EAAa,QAAQ;;;ACxBxD,IAAM,qBAAA,GAAwB;AAAA,EACnC,YAAA;AAAA,EACA,oBAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF;AAQO,IAAM,4BAAA,GAA8D;AAAA,EACzE,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF;AAGO,IAAM,8BAAA,GAAgE;AAAA,EAC3E,oBAAA;AAAA,EACA;AACF;AAGO,IAAM,qCAAA,GAAuE;AAAA,EAClF,YAAA;AAAA,EACA;AACF;AAGO,SAAS,aAAa,MAAA,EAAqC;AAChE,EAAA,OAAO,4BAAA,CAA6B,SAAS,MAAM,CAAA;AACrD;AAGO,SAAS,WAAW,MAAA,EAAqC;AAC9D,EAAA,OAAO,8BAAA,CAA+B,SAAS,MAAM,CAAA;AACvD","file":"chunk-47J7FYM5.js","sourcesContent":["/**\n * Charge / invoice / refund / payment-method / webhook-delivery status vocabularies,\n * mirrored for the SDK (which cannot import the server-side `@billow/core`). The DB-enum\n * ones (charge, invoice, refund, payment method) mirror core enums and are parity-tested\n * against it (see billing-status.test.ts); webhook-delivery status is a free-text column\n * server-side with a fixed vocabulary, documented here.\n */\n\n/** A charge's lifecycle status - mirrors `@billow/core` `CHARGE_STATUSES`. */\nexport const CHARGE_STATUSES = [\n \"pending\",\n \"processing\",\n \"succeeded\",\n \"failed\",\n \"requires_reconciliation\",\n \"disputed\",\n] as const;\nexport type ChargeStatus = (typeof CHARGE_STATUSES)[number];\n\n/** An invoice's lifecycle status - mirrors `@billow/core` `INVOICE_STATUSES`. */\nexport const INVOICE_STATUSES = [\"draft\", \"open\", \"paid\", \"uncollectible\", \"void\"] as const;\nexport type InvoiceStatus = (typeof INVOICE_STATUSES)[number];\n\n/** A refund's lifecycle status - mirrors `@billow/core` `REFUND_STATUSES`. */\nexport const REFUND_STATUSES = [\"pending\", \"succeeded\", \"failed\"] as const;\nexport type RefundStatus = (typeof REFUND_STATUSES)[number];\n\n/** A saved payment method's status - mirrors `@billow/core` `PAYMENT_METHOD_STATUSES`. */\nexport const PAYMENT_METHOD_STATUSES = [\"active\", \"expired\", \"removed\"] as const;\nexport type PaymentMethodStatus = (typeof PAYMENT_METHOD_STATUSES)[number];\n\n/**\n * A webhook delivery attempt's status. Not a DB enum (a free-text column); the dispatcher\n * inserts one row per attempt with exactly `delivered` (a 2xx) or `failed` (anything else) -\n * see `packages/server/src/jobs/outbox.ts`. (Retry/backoff state lives on the outbox event,\n * a separate table, not on the delivery record.)\n */\nexport const WEBHOOK_DELIVERY_STATUSES = [\"delivered\", \"failed\"] as const;\nexport type WebhookDeliveryStatus = (typeof WEBHOOK_DELIVERY_STATUSES)[number];\n","/**\n * The subscription status vocabulary + access predicate, mirrored from @billow/core\n * (`enums.ts` + `billing/subscription-state.ts`) so SDK consumers can type and branch on\n * billow's own model instead of hand-maintaining a union that drifts (a real bug: an app\n * copy once carried a non-existent `ended` status - that string is a webhook event type,\n * not a subscription status).\n *\n * Mirrored, not imported: @billow/core is a server package the published SDK cannot depend\n * on (the same reason @billow/contracts mirrors core's pure logic). The parity test\n * `subscription-status.test.ts` imports @billow/core and fails CI on any drift.\n */\n\n/** The 8 canonical subscription statuses, in lifecycle order. */\nexport const SUBSCRIPTION_STATUSES = [\n \"incomplete\",\n \"incomplete_expired\",\n \"trialing\",\n \"active\",\n \"past_due\",\n \"paused\",\n \"canceled\",\n \"unpaid\",\n] as const;\n\nexport type SubscriptionStatus = (typeof SUBSCRIPTION_STATUSES)[number];\n\n/**\n * Statuses that currently grant access (a live commitment): `trialing`, `active`, and\n * `past_due` (access is retained through dunning). Note `paused` does NOT grant access.\n */\nexport const ACTIVE_SUBSCRIPTION_STATUSES: readonly SubscriptionStatus[] = [\n \"trialing\",\n \"active\",\n \"past_due\",\n];\n\n/** Statuses a subscription can never leave: `incomplete_expired` and `canceled`. */\nexport const TERMINAL_SUBSCRIPTION_STATUSES: readonly SubscriptionStatus[] = [\n \"incomplete_expired\",\n \"canceled\",\n];\n\n/** Statuses in which a subscription never activated (no access was ever granted). */\nexport const NEVER_ACTIVATED_SUBSCRIPTION_STATUSES: readonly SubscriptionStatus[] = [\n \"incomplete\",\n \"incomplete_expired\",\n];\n\n/** Whether access should currently be granted for a subscription in this state. */\nexport function grantsAccess(status: SubscriptionStatus): boolean {\n return ACTIVE_SUBSCRIPTION_STATUSES.includes(status);\n}\n\n/** Whether this is a terminal status the subscription can never leave. */\nexport function isTerminal(status: SubscriptionStatus): boolean {\n return TERMINAL_SUBSCRIPTION_STATUSES.includes(status);\n}\n"]}
|
|
@@ -20,19 +20,26 @@ var BillowApiError = class extends Error {
|
|
|
20
20
|
code;
|
|
21
21
|
/** Structured error context from the server (e.g. per-field validation issues), when present. */
|
|
22
22
|
details;
|
|
23
|
-
/** billow's per-request id (`x-request-id`)
|
|
23
|
+
/** billow's per-request id (`x-request-id`) - quote it in a bug report to trace the server log. */
|
|
24
24
|
requestId;
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* How many seconds to wait before trying again, from the response's `Retry-After` header (sent
|
|
27
|
+
* with a `429 rate_limited`); undefined when the response did not say.
|
|
28
|
+
*/
|
|
29
|
+
retryAfterSeconds;
|
|
30
|
+
constructor(status, code, message, details, requestId, retryAfterSeconds) {
|
|
26
31
|
super(message);
|
|
27
32
|
this.name = "BillowApiError";
|
|
28
33
|
this.status = status;
|
|
29
34
|
this.code = code;
|
|
30
35
|
this.details = details;
|
|
31
36
|
this.requestId = requestId;
|
|
37
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
32
38
|
}
|
|
33
39
|
};
|
|
34
40
|
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
35
41
|
var DEFAULT_RETRY_BACKOFF_MS = 500;
|
|
42
|
+
var MAX_RETRY_AFTER_SECONDS = 3600;
|
|
36
43
|
function makeContext(bearer, opts) {
|
|
37
44
|
return {
|
|
38
45
|
fetch: opts.fetch ?? fetch,
|
|
@@ -51,7 +58,7 @@ function isRetryable(status, safeToRepeat2) {
|
|
|
51
58
|
function backoffMs(base, attempt, retryAfter) {
|
|
52
59
|
if (retryAfter) {
|
|
53
60
|
const secs = Number(retryAfter);
|
|
54
|
-
if (Number.isFinite(secs) && secs >= 0) return secs * 1e3;
|
|
61
|
+
if (Number.isFinite(secs) && secs >= 0) return Math.min(secs, MAX_RETRY_AFTER_SECONDS) * 1e3;
|
|
55
62
|
}
|
|
56
63
|
return base * 2 ** attempt;
|
|
57
64
|
}
|
|
@@ -173,9 +180,25 @@ function errorFrom(res, data) {
|
|
|
173
180
|
err.code ?? "error",
|
|
174
181
|
err.message ?? String(res.status),
|
|
175
182
|
err.details,
|
|
176
|
-
requestIdOf(res)
|
|
183
|
+
requestIdOf(res),
|
|
184
|
+
retryAfterOf(res)
|
|
177
185
|
);
|
|
178
186
|
}
|
|
187
|
+
var IMF_FIXDATE = /^[A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4} \d{2}:\d{2}:\d{2} GMT$/;
|
|
188
|
+
function retryAfterOf(res) {
|
|
189
|
+
const value = res.headers.get("retry-after")?.trim();
|
|
190
|
+
if (!value) return void 0;
|
|
191
|
+
let seconds;
|
|
192
|
+
if (/^\d+$/.test(value)) {
|
|
193
|
+
seconds = Number(value);
|
|
194
|
+
} else if (IMF_FIXDATE.test(value)) {
|
|
195
|
+
seconds = Math.ceil((Date.parse(value) - Date.now()) / 1e3);
|
|
196
|
+
} else {
|
|
197
|
+
return void 0;
|
|
198
|
+
}
|
|
199
|
+
if (!Number.isFinite(seconds)) return void 0;
|
|
200
|
+
return Math.min(Math.max(0, seconds), MAX_RETRY_AFTER_SECONDS);
|
|
201
|
+
}
|
|
179
202
|
async function apiRequestBinary(ctx, method, path2, options) {
|
|
180
203
|
const res = await sendWithResilience(
|
|
181
204
|
ctx,
|
|
@@ -449,6 +472,35 @@ function createCreditsResource(ctx) {
|
|
|
449
472
|
return { ...data, replayed: status === 200 };
|
|
450
473
|
}
|
|
451
474
|
},
|
|
475
|
+
accounts: {
|
|
476
|
+
/**
|
|
477
|
+
* Freeze a customer's Credit Account (by external id): it takes no new reservations - a
|
|
478
|
+
* reserve throws `account_frozen` (423) - until unfrozen, while holds already made still
|
|
479
|
+
* commit and release, and grants, top-ups, reversals and included credits still fund it.
|
|
480
|
+
* Safe to retry: freezing a frozen account changes nothing and answers `changed: false`. A
|
|
481
|
+
* customer with no account yet gets one, frozen. Throws `account_closed` (409) for an erased
|
|
482
|
+
* customer.
|
|
483
|
+
*/
|
|
484
|
+
freeze: (customer, options) => apiRequest(
|
|
485
|
+
ctx,
|
|
486
|
+
"POST",
|
|
487
|
+
"/v1/credits/accounts/freeze",
|
|
488
|
+
{ customerId: customer },
|
|
489
|
+
options
|
|
490
|
+
),
|
|
491
|
+
/**
|
|
492
|
+
* Unfreeze a customer's Credit Account (by external id): it takes reservations again. Safe to
|
|
493
|
+
* retry: unfreezing an account that is not frozen changes nothing and answers
|
|
494
|
+
* `changed: false`.
|
|
495
|
+
*/
|
|
496
|
+
unfreeze: (customer, options) => apiRequest(
|
|
497
|
+
ctx,
|
|
498
|
+
"POST",
|
|
499
|
+
"/v1/credits/accounts/unfreeze",
|
|
500
|
+
{ customerId: customer },
|
|
501
|
+
options
|
|
502
|
+
)
|
|
503
|
+
},
|
|
452
504
|
packs: {
|
|
453
505
|
/**
|
|
454
506
|
* The Credit Packs a customer can buy in `currency` (ISO 4217), cheapest first: credits and
|
|
@@ -1161,7 +1213,7 @@ function createSettingsResource(ctx) {
|
|
|
1161
1213
|
},
|
|
1162
1214
|
/**
|
|
1163
1215
|
* Usage settlement grace (hours): defers *collection* of a boundary-adjacent priced
|
|
1164
|
-
* calendar-meter renewal past the tz month boundary until late usage settles
|
|
1216
|
+
* calendar-meter renewal past the tz month boundary until late usage settles - the billed
|
|
1165
1217
|
* windows/amount are unchanged, only the invoice timing shifts. `0` disables it (the default);
|
|
1166
1218
|
* a no-op for any subscription without a priced calendar meter. Cap 72h.
|
|
1167
1219
|
*/
|
|
@@ -1288,7 +1340,7 @@ function createSubscriptionsResource(ctx) {
|
|
|
1288
1340
|
void 0,
|
|
1289
1341
|
options
|
|
1290
1342
|
),
|
|
1291
|
-
/** Cancel
|
|
1343
|
+
/** Cancel - immediately, or at period end with `{ atPeriodEnd: true }`. */
|
|
1292
1344
|
cancel: (id, opts) => apiRequest(
|
|
1293
1345
|
ctx,
|
|
1294
1346
|
"POST",
|
|
@@ -1321,7 +1373,7 @@ function createSubscriptionsResource(ctx) {
|
|
|
1321
1373
|
`/v1/subscriptions/${encodeURIComponent(id)}/coupon`,
|
|
1322
1374
|
{ code }
|
|
1323
1375
|
),
|
|
1324
|
-
/** Change plan
|
|
1376
|
+
/** Change plan - immediate prorated upgrade, or downgrade scheduled for period end. `productId` accepts the product's id or slug. */
|
|
1325
1377
|
changePlan: (id, productId) => apiRequest(ctx, "POST", `/v1/subscriptions/${encodeURIComponent(id)}/change-plan`, { productId }),
|
|
1326
1378
|
/** Clear a pending downgrade. Duplicate calls are safe. */
|
|
1327
1379
|
clearScheduledPlanChange: (id) => apiRequest(
|
|
@@ -1395,7 +1447,7 @@ function createWebhookEndpointsResource(ctx) {
|
|
|
1395
1447
|
),
|
|
1396
1448
|
/** Delete an endpoint and its delivery history. */
|
|
1397
1449
|
delete: (id) => apiRequest(ctx, "DELETE", `/v1/webhook-endpoints/${encodeURIComponent(id)}`),
|
|
1398
|
-
/** Rotate the signing secret
|
|
1450
|
+
/** Rotate the signing secret - the new plaintext is returned once. */
|
|
1399
1451
|
rotateSecret: (id) => apiRequest(
|
|
1400
1452
|
ctx,
|
|
1401
1453
|
"POST",
|
|
@@ -1434,7 +1486,7 @@ var Billow = class {
|
|
|
1434
1486
|
/** Custom domains for the hosted customer portal (live keys, behind a rollout flag). */
|
|
1435
1487
|
hostedDomains;
|
|
1436
1488
|
/**
|
|
1437
|
-
* Organization settings (Phase D3, F)
|
|
1489
|
+
* Organization settings (Phase D3, F) - the configurable dunning schedule, usage settlement grace,
|
|
1438
1490
|
* and the cross-currency reporting currency + FX-rate registry (ADR-0013).
|
|
1439
1491
|
*/
|
|
1440
1492
|
settings;
|
|
@@ -1462,7 +1514,7 @@ var Billow = class {
|
|
|
1462
1514
|
coupons = {
|
|
1463
1515
|
/** Define a coupon (a reusable discount template). */
|
|
1464
1516
|
create: (input) => this.#request("POST", "/v1/coupons", input),
|
|
1465
|
-
/** List coupons (secret key only
|
|
1517
|
+
/** List coupons (secret key only - enumerates live promo codes). Auto-paginating. */
|
|
1466
1518
|
list: (params = {}, options) => makeListPromise(
|
|
1467
1519
|
(p) => this.#request("GET", `/v1/coupons${toQuery(p)}`, void 0, options),
|
|
1468
1520
|
params
|
|
@@ -1470,13 +1522,13 @@ var Billow = class {
|
|
|
1470
1522
|
/** Deactivate a coupon (existing discounts keep running). */
|
|
1471
1523
|
deactivate: (id) => this.#request("POST", `/v1/coupons/${encodeURIComponent(id)}/deactivate`)
|
|
1472
1524
|
};
|
|
1473
|
-
/** Manage developer webhook endpoints
|
|
1525
|
+
/** Manage developer webhook endpoints - register, rotate secrets, inspect deliveries.
|
|
1474
1526
|
* (To VERIFY incoming deliveries, import `constructEvent` from `@usebillow/sdk/webhooks`.) */
|
|
1475
1527
|
features = {
|
|
1476
1528
|
/** Define a feature (a boolean access gate, or a metered feature with a meter). */
|
|
1477
1529
|
create: (input) => this.#request("POST", "/v1/features", input),
|
|
1478
1530
|
/**
|
|
1479
|
-
* Edit a feature in place: its `name`, and
|
|
1531
|
+
* Edit a feature in place: its `name`, and - for a metered feature - its `meter`
|
|
1480
1532
|
* aggregation. The server refuses a meter change once usage has been recorded (it
|
|
1481
1533
|
* would rewrite billed history), so set the meter right at create time or before you
|
|
1482
1534
|
* start tracking. Returns the updated feature.
|
|
@@ -1533,7 +1585,7 @@ var Billow = class {
|
|
|
1533
1585
|
* choose a credential set and `target` to probe one verify target (Paymob: a
|
|
1534
1586
|
* method); pass `sampleToken` (SANDBOX ONLY) to run a functional sub-test.
|
|
1535
1587
|
* This probe hits the provider's live API (mutates nothing here), so it takes a
|
|
1536
|
-
* per-call {@link CallOptions} for a timeout / cancellation
|
|
1588
|
+
* per-call {@link CallOptions} for a timeout / cancellation - `opts` is spread into
|
|
1537
1589
|
* the body, so `options` stays a separate trailing arg (never merged in).
|
|
1538
1590
|
*/
|
|
1539
1591
|
verify: (provider, opts, options) => this.#request(
|
|
@@ -1560,7 +1612,7 @@ var Billow = class {
|
|
|
1560
1612
|
)
|
|
1561
1613
|
}
|
|
1562
1614
|
};
|
|
1563
|
-
/** The merchant's business identity
|
|
1615
|
+
/** The merchant's business identity - the seller block on documents and email from-name. */
|
|
1564
1616
|
businessProfile = {
|
|
1565
1617
|
/** The stored profile, or null if one was never saved. */
|
|
1566
1618
|
get: (options) => this.#request(
|
|
@@ -1576,11 +1628,11 @@ var Billow = class {
|
|
|
1576
1628
|
};
|
|
1577
1629
|
/**
|
|
1578
1630
|
* Hosted customer surfaces (Phase G, ADR-0014). Mint a portal session for one of
|
|
1579
|
-
* your signed-in users and redirect them to the returned `url`
|
|
1631
|
+
* your signed-in users and redirect them to the returned `url` - the self-serve
|
|
1580
1632
|
* portal, or a `checkout` hand-off for `productId`. The Customer's own calls go
|
|
1581
1633
|
* through {@link BillowPortal}, constructed with the session token.
|
|
1582
1634
|
*/
|
|
1583
|
-
/** Identity of this key's tenant
|
|
1635
|
+
/** Identity of this key's tenant - org, environment, configured currencies. */
|
|
1584
1636
|
me(options) {
|
|
1585
1637
|
return this.#request("GET", "/v1/me", void 0, options);
|
|
1586
1638
|
}
|
|
@@ -1600,14 +1652,14 @@ var Billow = class {
|
|
|
1600
1652
|
// ── The headline verbs ──────────────────────────────────────────────
|
|
1601
1653
|
/**
|
|
1602
1654
|
* Gate access to a feature. `featureId` is the feature slug. Returns
|
|
1603
|
-
* `{ allowed, balance }`
|
|
1655
|
+
* `{ allowed, balance }` - `balance` is `null` for unlimited/boolean features.
|
|
1604
1656
|
*/
|
|
1605
1657
|
check(input, options) {
|
|
1606
1658
|
return this.#request("POST", "/v1/check", input, options);
|
|
1607
1659
|
}
|
|
1608
1660
|
/**
|
|
1609
1661
|
* Record usage of a metered feature (`value` defaults to 1; negative credits
|
|
1610
|
-
* back). Pass `idempotencyKey` to make a retried call a no-op
|
|
1662
|
+
* back). Pass `idempotencyKey` to make a retried call a no-op - which also makes the call
|
|
1611
1663
|
* safe to retry automatically when `maxRetries` is set.
|
|
1612
1664
|
*/
|
|
1613
1665
|
track(input, options) {
|
|
@@ -1644,7 +1696,7 @@ var BillowPublishable = class {
|
|
|
1644
1696
|
this.#ctx = makeContext(publishableKey, opts);
|
|
1645
1697
|
}
|
|
1646
1698
|
products = {
|
|
1647
|
-
/** The active catalog
|
|
1699
|
+
/** The active catalog - products and their prices, for a pricing table. */
|
|
1648
1700
|
list: (options) => apiRequest(
|
|
1649
1701
|
this.#ctx,
|
|
1650
1702
|
"GET",
|
|
@@ -1668,7 +1720,7 @@ var BillowPortal = class {
|
|
|
1668
1720
|
if (!sessionToken) throw new Error("billow: a portal session token is required");
|
|
1669
1721
|
this.#ctx = makeContext(sessionToken, opts);
|
|
1670
1722
|
}
|
|
1671
|
-
/** The portal shell: flow, return URL, merchant brand, and customer identity
|
|
1723
|
+
/** The portal shell: flow, return URL, merchant brand, and customer identity -
|
|
1672
1724
|
* the lightweight payload the hosting app frames every page with, and the
|
|
1673
1725
|
* validate-and-route check at login. */
|
|
1674
1726
|
session(options) {
|
|
@@ -1796,5 +1848,5 @@ var BillowPortal = class {
|
|
|
1796
1848
|
};
|
|
1797
1849
|
|
|
1798
1850
|
export { BILLOW_ERROR_CODES, Billow, BillowApiError, BillowPortal, BillowPublishable, currencyExponent, formatMoney, isSecretField, toMajorUnits, toMinorUnits };
|
|
1799
|
-
//# sourceMappingURL=chunk-
|
|
1800
|
-
//# sourceMappingURL=chunk-
|
|
1851
|
+
//# sourceMappingURL=chunk-XUFQG6EA.js.map
|
|
1852
|
+
//# sourceMappingURL=chunk-XUFQG6EA.js.map
|