@usebillow/sdk 0.5.0 → 0.6.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 +11 -0
- package/README.md +9 -0
- package/dist/billing-B-VyZCXV.d.cts +371 -0
- package/dist/billing-CgjcWmvb.d.ts +371 -0
- package/dist/{chunk-Z6VXPONT.js → chunk-DYWGZRE2.js} +197 -15
- package/dist/chunk-DYWGZRE2.js.map +1 -0
- package/dist/config.d.cts +4 -3
- package/dist/config.d.ts +4 -3
- package/dist/{credits-C3Fe3TO0.d.ts → hosted-domains-BtCd-Rur.d.cts} +43 -1
- package/dist/{credits-C3Fe3TO0.d.cts → hosted-domains-CrVDsk2i.d.ts} +43 -1
- package/dist/index.cjs +195 -13
- package/dist/index.cjs.map +1 -1
- package/dist/{billing-C4RIMgH_.d.ts → index.d-CKQAhQfJ.d.cts} +180 -374
- package/dist/{billing-DZ4rIyg7.d.cts → index.d-CKQAhQfJ.d.ts} +180 -374
- package/dist/index.d.cts +547 -42
- package/dist/index.d.ts +547 -42
- package/dist/index.js +1 -1
- package/dist/ingestion.d.cts +3 -2
- package/dist/ingestion.d.ts +3 -2
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -1
- package/dist/react.d.ts +2 -1
- package/dist/react.js +1 -1
- package/dist/server.d.cts +3 -2
- package/dist/server.d.ts +3 -2
- package/dist/webhooks.cjs +10 -2
- package/dist/webhooks.cjs.map +1 -1
- package/dist/webhooks.d.cts +37 -21
- package/dist/webhooks.d.ts +37 -21
- package/dist/webhooks.js +10 -3
- package/dist/webhooks.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-Z6VXPONT.js.map +0 -1
|
@@ -0,0 +1,371 @@
|
|
|
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-CKQAhQfJ.js';
|
|
2
|
+
import { C as ChargeStatus } from './billing-status-BZQN_gm7.js';
|
|
3
|
+
|
|
4
|
+
/** Public SDK types for this domain. Re-exported by ../types.ts. */
|
|
5
|
+
interface BillowOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Base URL of the Billow API. Falls back to the `BILLOW_URL` env var, then to the hosted
|
|
8
|
+
* API at `https://api.usebillow.com`. Set it for local development (for example
|
|
9
|
+
* `http://localhost:4001`) or a self-hosted server.
|
|
10
|
+
*/
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
fetch?: typeof fetch;
|
|
13
|
+
/**
|
|
14
|
+
* Hard per-request timeout in milliseconds; the request is aborted once it elapses.
|
|
15
|
+
* Defaults to 60_000. Set `0` to disable the timeout.
|
|
16
|
+
*/
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
/**
|
|
19
|
+
* How many times to retry a transient failure. Retries are **opt-in** — the default is
|
|
20
|
+
* `0`. Only requests that are safe to repeat are retried: every `GET`, plus **any** method
|
|
21
|
+
* on a `429` (a rate-limited request never executed). A write (`POST`/`PATCH`/`DELETE`) is
|
|
22
|
+
* never retried on a `5xx`/network error, since it may have already applied.
|
|
23
|
+
*/
|
|
24
|
+
maxRetries?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Base backoff in milliseconds between retries — exponential (`base × 2^attempt`), and a
|
|
27
|
+
* `Retry-After` response header takes precedence when present. Defaults to 500.
|
|
28
|
+
*/
|
|
29
|
+
retryBackoffMs?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Per-call overrides passed as the last argument to a resource method.
|
|
33
|
+
* - `signal` cancels the request (a caller abort is surfaced immediately and never retried).
|
|
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** — reused
|
|
36
|
+
* verbatim on every attempt. Only exposed on writes the server replays (create/attach/track/refund).
|
|
37
|
+
*/
|
|
38
|
+
interface RequestOptions {
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
timeoutMs?: number;
|
|
41
|
+
idempotencyKey?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Options for writes that require a stable idempotency key. */
|
|
44
|
+
type IdempotentRequestOptions = RequestOptions & {
|
|
45
|
+
idempotencyKey: string;
|
|
46
|
+
};
|
|
47
|
+
/** Per-call overrides for reads and non-replayable writes — cancellation + timeout, no idempotency key. */
|
|
48
|
+
type CallOptions = Omit<RequestOptions, "idempotencyKey">;
|
|
49
|
+
interface Customer {
|
|
50
|
+
id: string;
|
|
51
|
+
externalId: string;
|
|
52
|
+
name?: string | null;
|
|
53
|
+
email?: string | null;
|
|
54
|
+
phone?: string | null;
|
|
55
|
+
/** The customer's tax / VAT registration number, recorded on their invoices. */
|
|
56
|
+
taxId?: string | null;
|
|
57
|
+
}
|
|
58
|
+
/** How a price's tax relates to its amount: added on top (`exclusive`) or contained (`inclusive`). */
|
|
59
|
+
type TaxBehavior = "exclusive" | "inclusive";
|
|
60
|
+
interface CheckResult {
|
|
61
|
+
feature: string;
|
|
62
|
+
allowed: boolean;
|
|
63
|
+
balance: number | null;
|
|
64
|
+
}
|
|
65
|
+
interface AttachResult {
|
|
66
|
+
/** Hosted checkout URL to redirect the customer to (null if none was minted). */
|
|
67
|
+
url: string | null;
|
|
68
|
+
/** Null until a paid first-cycle checkout succeeds and creates the subscription. */
|
|
69
|
+
subscriptionId: string | null;
|
|
70
|
+
checkoutSessionId: string | null;
|
|
71
|
+
}
|
|
72
|
+
type BillingInterval = "day" | "week" | "month" | "year";
|
|
73
|
+
type FeatureKind = "boolean" | "metered";
|
|
74
|
+
type MeterAggregation = "count" | "sum" | "max" | "latest" | "count_unique";
|
|
75
|
+
type MeterRoundingMode = "none" | "round" | "ceil" | "floor";
|
|
76
|
+
interface MeterFilter {
|
|
77
|
+
key: string;
|
|
78
|
+
values: string[];
|
|
79
|
+
}
|
|
80
|
+
/** A meter's measurement config (ADR-0011) — how a metered feature's usage aggregates. */
|
|
81
|
+
interface MeterConfig {
|
|
82
|
+
aggregation: MeterAggregation;
|
|
83
|
+
eventProperty?: string | null;
|
|
84
|
+
filters?: MeterFilter[];
|
|
85
|
+
roundingMode?: MeterRoundingMode;
|
|
86
|
+
roundingScale?: number | null;
|
|
87
|
+
/**
|
|
88
|
+
* Reset window anchoring (plan 07). Omitted/`cycle` = subscription anniversary in UTC
|
|
89
|
+
* (default). `calendar` tiles windows on calendar months in `resetTz` and REQUIRES a
|
|
90
|
+
* canonical IANA `resetTz` (e.g. `"Africa/Cairo"`, `"UTC"`).
|
|
91
|
+
*/
|
|
92
|
+
resetAnchor?: "cycle" | "calendar";
|
|
93
|
+
resetTz?: string | null;
|
|
94
|
+
}
|
|
95
|
+
/** How a usage price turns billable quantity into money. */
|
|
96
|
+
type UsageModel = "graduated" | "volume" | "package" | "percentage" | "stairstep";
|
|
97
|
+
/** A usage-pricing tier (`upTo: null` = the unbounded last tier). */
|
|
98
|
+
interface UsageTier {
|
|
99
|
+
upTo: number | null;
|
|
100
|
+
unitAmount: number;
|
|
101
|
+
flatAmount?: number;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Public SDK types for this domain. Re-exported by ../types.ts. */
|
|
105
|
+
|
|
106
|
+
interface PriceInput {
|
|
107
|
+
/** `licensed` = per-unit recurring, billed × the subscription item's quantity (seats). */
|
|
108
|
+
kind: "fixed_recurring" | "licensed" | "one_time" | "usage";
|
|
109
|
+
interval?: BillingInterval;
|
|
110
|
+
intervalCount?: number;
|
|
111
|
+
/** Amount in minor units (per unit for `usage` prices without tiers). */
|
|
112
|
+
amount: number;
|
|
113
|
+
currency: string;
|
|
114
|
+
/** For `usage` prices: the metered feature's slug. */
|
|
115
|
+
meterFeature?: string;
|
|
116
|
+
/** For `usage` prices: the pricing model (default graduated). */
|
|
117
|
+
usageModel?: UsageModel;
|
|
118
|
+
/** For `usage` prices: tiers for graduated/volume/stairstep (overrides flat `amount`). */
|
|
119
|
+
usageTiers?: UsageTier[];
|
|
120
|
+
/** For `package` pricing: units per package (each priced at `amount`). */
|
|
121
|
+
packageSize?: number;
|
|
122
|
+
/** For `percentage` pricing: basis points of the metered amount. */
|
|
123
|
+
rateBps?: number;
|
|
124
|
+
/** Tax rate override in basis points; omit to inherit the org default, 0 = zero-rated. */
|
|
125
|
+
taxRateBps?: number | null;
|
|
126
|
+
/** Tax behavior override; omit to inherit the org default. */
|
|
127
|
+
taxBehavior?: TaxBehavior | null;
|
|
128
|
+
}
|
|
129
|
+
interface EntitlementInput {
|
|
130
|
+
/** The feature's slug (must already exist). */
|
|
131
|
+
feature: string;
|
|
132
|
+
/** Included units; `null`/omitted = unlimited. */
|
|
133
|
+
allowance?: number | null;
|
|
134
|
+
/** How often the balance refills; omitted = only on renewal. */
|
|
135
|
+
resetInterval?: BillingInterval;
|
|
136
|
+
rollover?: boolean;
|
|
137
|
+
}
|
|
138
|
+
interface CreateProductInput {
|
|
139
|
+
slug: string;
|
|
140
|
+
name: string;
|
|
141
|
+
type: "recurring" | "one_time";
|
|
142
|
+
isAddOn?: boolean;
|
|
143
|
+
/** Free-form string map that round-trips on the product + on subscription.* webhooks. */
|
|
144
|
+
metadata?: Record<string, string>;
|
|
145
|
+
prices: PriceInput[];
|
|
146
|
+
entitlements?: EntitlementInput[];
|
|
147
|
+
}
|
|
148
|
+
/** A price in a product edit: carry `id` to update that row in place, omit it to add. */
|
|
149
|
+
type UpdatePriceInput = PriceInput & {
|
|
150
|
+
id?: string;
|
|
151
|
+
};
|
|
152
|
+
/** The result of migrating a plan's subscribers to another plan (ADR-0015). */
|
|
153
|
+
interface MigrationResult {
|
|
154
|
+
/** How many subscriptions were moved to the target plan. */
|
|
155
|
+
migrated: number;
|
|
156
|
+
/** Subscriptions that couldn't be moved, with the reason (wrong currency, not active, …). */
|
|
157
|
+
skipped: Array<{
|
|
158
|
+
subscriptionId: string;
|
|
159
|
+
reason: string;
|
|
160
|
+
}>;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Edit a product (ADR-0015): rename, archive, and/or replace its prices/entitlements
|
|
164
|
+
* in place. `prices`/`entitlements`, when given, reconcile the latest version's rows
|
|
165
|
+
* (existing subscribers re-price at their next renewal).
|
|
166
|
+
*/
|
|
167
|
+
interface UpdateProductInput {
|
|
168
|
+
name?: string;
|
|
169
|
+
archived?: boolean;
|
|
170
|
+
/** Replace the product's metadata map. */
|
|
171
|
+
metadata?: Record<string, string>;
|
|
172
|
+
prices?: UpdatePriceInput[];
|
|
173
|
+
entitlements?: EntitlementInput[];
|
|
174
|
+
}
|
|
175
|
+
interface Feature {
|
|
176
|
+
id: string;
|
|
177
|
+
slug: string;
|
|
178
|
+
name: string;
|
|
179
|
+
kind: FeatureKind;
|
|
180
|
+
/** Meter config for metered features (ADR-0011); null/absent for boolean. */
|
|
181
|
+
meter?: MeterConfig | null;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* An in-place edit to a feature. `name` is always allowed; `meter` re-configures a
|
|
185
|
+
* metered feature's aggregation — but the server refuses a meter change once usage has
|
|
186
|
+
* been recorded (it would rewrite billed history). At least one field must be present.
|
|
187
|
+
*/
|
|
188
|
+
interface UpdateFeatureInput {
|
|
189
|
+
name?: string;
|
|
190
|
+
meter?: MeterConfig;
|
|
191
|
+
}
|
|
192
|
+
/** A usage-monitoring rule: a `threshold` Alert (notifies) or a `cap` (blocks). */
|
|
193
|
+
type UsageAlertKind = "threshold" | "cap";
|
|
194
|
+
/** How an alert threshold figure reads: absolute usage, percent used, or percent remaining. */
|
|
195
|
+
type UsageAlertMetric = "absolute" | "percent_used" | "percent_remaining";
|
|
196
|
+
/** A configured Alert / Spend cap on a metered feature (Phase C). */
|
|
197
|
+
interface UsageAlert {
|
|
198
|
+
id: string;
|
|
199
|
+
kind: UsageAlertKind;
|
|
200
|
+
metric: UsageAlertMetric;
|
|
201
|
+
/** Threshold figures (units, or a percentage). One for a cap; one+ for an Alert. */
|
|
202
|
+
thresholds: number[];
|
|
203
|
+
/** Threshold Alerts: re-fire every N past the highest threshold; else null. */
|
|
204
|
+
recurringStep: number | null;
|
|
205
|
+
/** Threshold Alerts: also email the Customer (webhook always fires). */
|
|
206
|
+
notifyCustomer: boolean;
|
|
207
|
+
enabled: boolean;
|
|
208
|
+
}
|
|
209
|
+
interface CreateUsageAlertInput {
|
|
210
|
+
kind: UsageAlertKind;
|
|
211
|
+
metric: UsageAlertMetric;
|
|
212
|
+
thresholds: number[];
|
|
213
|
+
/** Threshold Alerts only: re-fire every N past the highest threshold. */
|
|
214
|
+
recurringStep?: number;
|
|
215
|
+
/** Threshold Alerts only: also email the Customer. */
|
|
216
|
+
notifyCustomer?: boolean;
|
|
217
|
+
}
|
|
218
|
+
interface TrackResult {
|
|
219
|
+
ok: true;
|
|
220
|
+
/** True when the idempotency key was already seen — the call was a no-op. */
|
|
221
|
+
deduplicated: boolean;
|
|
222
|
+
/** Remaining balance for the feature; `null` if unlimited. */
|
|
223
|
+
balance: number | null;
|
|
224
|
+
}
|
|
225
|
+
interface EntitlementView {
|
|
226
|
+
feature: string;
|
|
227
|
+
kind: FeatureKind;
|
|
228
|
+
allowed: boolean;
|
|
229
|
+
balance: number | null;
|
|
230
|
+
}
|
|
231
|
+
type ProductPrice = ProductPriceResponse;
|
|
232
|
+
type ProductEntitlement = ProductEntitlementResponse;
|
|
233
|
+
type Product = ProductResponse;
|
|
234
|
+
type Subscription = SubscriptionResponse;
|
|
235
|
+
/** A single fetched subscription (`subscriptions.get`) - {@link Subscription} plus the stable `customerExternalId` + `productSlug`. */
|
|
236
|
+
type SubscriptionDetail = SubscriptionDetailResponse;
|
|
237
|
+
/** A subscription line item — the base plan or an attached add-on (Phase D2). */
|
|
238
|
+
type SubscriptionItem = SubscriptionItemResponse;
|
|
239
|
+
interface CreateSubscriptionInput {
|
|
240
|
+
customerId: string;
|
|
241
|
+
/** The product slug to subscribe to. */
|
|
242
|
+
productId: string;
|
|
243
|
+
redirectionUrl?: string;
|
|
244
|
+
/** Optional coupon code to apply to the subscription. */
|
|
245
|
+
couponCode?: string;
|
|
246
|
+
/** Free-trial length in days (starts `trialing`, no charge until trial end). */
|
|
247
|
+
trialDays?: number;
|
|
248
|
+
/** For a trial, collect a card up front via tokenization (default true). */
|
|
249
|
+
collectCard?: boolean;
|
|
250
|
+
/** Units of the base price to bill (e.g. seats for a `licensed` plan); default 1. */
|
|
251
|
+
quantity?: number;
|
|
252
|
+
/** Limited term: total billing cycles before the subscription ends; omit = open-ended. */
|
|
253
|
+
cycles?: number;
|
|
254
|
+
/**
|
|
255
|
+
* The billing currency (Phase F, ADR-0013). Required only when the product has
|
|
256
|
+
* recurring prices in more than one currency; inferred when there's a single one.
|
|
257
|
+
*/
|
|
258
|
+
currency?: string;
|
|
259
|
+
}
|
|
260
|
+
type CouponKind = "percent" | "fixed";
|
|
261
|
+
type CouponDuration = "once" | "repeating" | "forever";
|
|
262
|
+
interface CreateCouponInput {
|
|
263
|
+
code?: string;
|
|
264
|
+
kind: CouponKind;
|
|
265
|
+
/** percent: basis points (1% = 100 bps). fixed: minor units. */
|
|
266
|
+
value: number;
|
|
267
|
+
currency?: string;
|
|
268
|
+
duration: CouponDuration;
|
|
269
|
+
durationCycles?: number;
|
|
270
|
+
maxRedemptions?: number;
|
|
271
|
+
/** ISO-8601 timestamp. */
|
|
272
|
+
expiresAt?: string;
|
|
273
|
+
/** Product slugs the coupon is restricted to. */
|
|
274
|
+
productRestrictions?: string[];
|
|
275
|
+
}
|
|
276
|
+
interface Coupon {
|
|
277
|
+
id: string;
|
|
278
|
+
code: string | null;
|
|
279
|
+
kind: CouponKind;
|
|
280
|
+
value: number;
|
|
281
|
+
currency: string | null;
|
|
282
|
+
duration: CouponDuration;
|
|
283
|
+
durationCycles: number | null;
|
|
284
|
+
maxRedemptions: number | null;
|
|
285
|
+
redeemedCount: number;
|
|
286
|
+
expiresAt: string | null;
|
|
287
|
+
/** Set when an operator deactivated the coupon (it can no longer be applied). */
|
|
288
|
+
deactivatedAt?: string | null;
|
|
289
|
+
productRestrictions?: string[] | null;
|
|
290
|
+
}
|
|
291
|
+
type ActivatedSubscriptionResult = ActivatedSubscriptionResponse;
|
|
292
|
+
type PendingSubscriptionCheckoutResult = PendingSubscriptionCheckoutResponse;
|
|
293
|
+
type CreateSubscriptionResult = CreateSubscriptionResponse;
|
|
294
|
+
/**
|
|
295
|
+
* Why a succeeded charge could not be applied to the invoice it paid, so its money awaits an
|
|
296
|
+
* Operator refund: `duplicate_payment` - another payment had already paid the invoice;
|
|
297
|
+
* `invoice_closed` - the invoice was voided or written off before this payment arrived.
|
|
298
|
+
*/
|
|
299
|
+
type UnappliedPaymentReason = "duplicate_payment" | "invoice_closed";
|
|
300
|
+
interface Charge {
|
|
301
|
+
id: string;
|
|
302
|
+
status: ChargeStatus;
|
|
303
|
+
customerId: string;
|
|
304
|
+
customerExternalId: string;
|
|
305
|
+
invoiceId: string | null;
|
|
306
|
+
kind: "customer_present" | "mit";
|
|
307
|
+
subtotal: number;
|
|
308
|
+
tax: number;
|
|
309
|
+
total: number;
|
|
310
|
+
taxRateBps: number | null;
|
|
311
|
+
taxBehavior: "exclusive" | "inclusive" | null;
|
|
312
|
+
items: {
|
|
313
|
+
name: string;
|
|
314
|
+
amount: number;
|
|
315
|
+
quantity: number;
|
|
316
|
+
description?: string;
|
|
317
|
+
}[];
|
|
318
|
+
/** Backward-compatible alias of `total`, the amount sent to the provider. */
|
|
319
|
+
amount: number;
|
|
320
|
+
currency: string;
|
|
321
|
+
checkoutUrl: string | null;
|
|
322
|
+
specialReference: string;
|
|
323
|
+
providerTransactionId: string | null;
|
|
324
|
+
errorMessage: string | null;
|
|
325
|
+
/** Provider-reported dispute/chargeback (PRD-08), read-only. Null unless disputed. */
|
|
326
|
+
disputedAt: string | null;
|
|
327
|
+
disputeReason: string | null;
|
|
328
|
+
disputeId: string | null;
|
|
329
|
+
disputeAmount: number | null;
|
|
330
|
+
disputeState: "open" | "won" | "lost" | null;
|
|
331
|
+
/** Set when this payment could not be applied to its invoice; null otherwise. */
|
|
332
|
+
unappliedReason: UnappliedPaymentReason | null;
|
|
333
|
+
createdAt: string;
|
|
334
|
+
}
|
|
335
|
+
interface CreateChargeInput {
|
|
336
|
+
customerId: string;
|
|
337
|
+
/** Amount in minor units (e.g. piasters). */
|
|
338
|
+
amount: number;
|
|
339
|
+
currency: string;
|
|
340
|
+
/** Tax rate in basis points. When set, `taxBehavior` defaults to `exclusive`. */
|
|
341
|
+
taxRateBps?: number;
|
|
342
|
+
/** Whether `amount` excludes or includes tax. Requires `taxRateBps`. */
|
|
343
|
+
taxBehavior?: "exclusive" | "inclusive";
|
|
344
|
+
items?: {
|
|
345
|
+
name: string;
|
|
346
|
+
amount: number;
|
|
347
|
+
quantity: number;
|
|
348
|
+
description?: string;
|
|
349
|
+
}[];
|
|
350
|
+
/** Restrict the offered methods; omit to offer every method the merchant has configured. */
|
|
351
|
+
methods?: ("card" | "wallet" | "sympl" | "applepay")[];
|
|
352
|
+
saveCard?: boolean;
|
|
353
|
+
redirectionUrl?: string;
|
|
354
|
+
}
|
|
355
|
+
/** A standalone off-session charge against the customer's current saved card. */
|
|
356
|
+
interface CreateMerchantInitiatedChargeInput {
|
|
357
|
+
customerId: string;
|
|
358
|
+
paymentMethodId: string;
|
|
359
|
+
amount: number;
|
|
360
|
+
currency: string;
|
|
361
|
+
items: {
|
|
362
|
+
name: string;
|
|
363
|
+
amount: number;
|
|
364
|
+
quantity: number;
|
|
365
|
+
description?: string;
|
|
366
|
+
}[];
|
|
367
|
+
taxRateBps?: number;
|
|
368
|
+
taxBehavior?: "exclusive" | "inclusive";
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export type { AttachResult as A, BillowOptions as B, CreateProductInput as C, PriceInput as D, EntitlementView as E, FeatureKind as F, ProductEntitlement as G, ProductPrice as H, IdempotentRequestOptions as I, SubscriptionDetail as J, SubscriptionItem as K, UpdatePriceInput as L, MeterConfig as M, UsageAlertKind as N, UsageAlertMetric as O, Product as P, UsageModel as Q, RequestOptions as R, Subscription as S, TrackResult as T, UnappliedPaymentReason as U, UsageTier as V, CreateCouponInput as a, CheckResult as b, TaxBehavior as c, Customer as d, CreateChargeInput as e, Charge as f, CreateMerchantInitiatedChargeInput as g, CallOptions as h, UpdateProductInput as i, MigrationResult as j, CreateSubscriptionInput as k, Coupon as l, Feature as m, UpdateFeatureInput as n, UsageAlert as o, CreateUsageAlertInput as p, ActivatedSubscriptionResult as q, BillingInterval as r, CouponDuration as s, CouponKind as t, CreateSubscriptionResult as u, EntitlementInput as v, MeterAggregation as w, MeterFilter as x, MeterRoundingMode as y, PendingSubscriptionCheckoutResult as z };
|
|
@@ -117,10 +117,10 @@ function resolveBaseUrl(explicit) {
|
|
|
117
117
|
const fromEnv = typeof process !== "undefined" ? process.env?.["BILLOW_URL"] : void 0;
|
|
118
118
|
return (explicit || fromEnv || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
119
119
|
}
|
|
120
|
-
async function apiRequest(ctx, method,
|
|
121
|
-
return (await apiRequestWithStatus(ctx, method,
|
|
120
|
+
async function apiRequest(ctx, method, path2, body, options) {
|
|
121
|
+
return (await apiRequestWithStatus(ctx, method, path2, body, options)).data;
|
|
122
122
|
}
|
|
123
|
-
async function apiRequestWithStatus(ctx, method,
|
|
123
|
+
async function apiRequestWithStatus(ctx, method, path2, body, options) {
|
|
124
124
|
const init = {
|
|
125
125
|
method,
|
|
126
126
|
headers: {
|
|
@@ -130,7 +130,7 @@ async function apiRequestWithStatus(ctx, method, path, body, options) {
|
|
|
130
130
|
}
|
|
131
131
|
};
|
|
132
132
|
if (body) init.body = JSON.stringify(body);
|
|
133
|
-
const res = await sendWithResilience(ctx, `${ctx.baseUrl}${
|
|
133
|
+
const res = await sendWithResilience(ctx, `${ctx.baseUrl}${path2}`, init, {
|
|
134
134
|
timeoutMs: options?.timeoutMs ?? ctx.timeoutMs,
|
|
135
135
|
safeToRepeat: safeToRepeat(method, !!options?.idempotencyKey),
|
|
136
136
|
callerSignal: options?.signal
|
|
@@ -176,10 +176,10 @@ function errorFrom(res, data) {
|
|
|
176
176
|
requestIdOf(res)
|
|
177
177
|
);
|
|
178
178
|
}
|
|
179
|
-
async function apiRequestBinary(ctx, method,
|
|
179
|
+
async function apiRequestBinary(ctx, method, path2, options) {
|
|
180
180
|
const res = await sendWithResilience(
|
|
181
181
|
ctx,
|
|
182
|
-
`${ctx.baseUrl}${
|
|
182
|
+
`${ctx.baseUrl}${path2}`,
|
|
183
183
|
{ method, headers: { authorization: `Bearer ${ctx.bearer}` } },
|
|
184
184
|
{
|
|
185
185
|
timeoutMs: options?.timeoutMs ?? ctx.timeoutMs,
|
|
@@ -487,11 +487,14 @@ function createCreditsResource(ctx) {
|
|
|
487
487
|
* checkout to send the buyer to. Credits are granted when the payment succeeds (listen for
|
|
488
488
|
* `credit_top_up.succeeded`). The `idempotencyKey` is required and must identify this one
|
|
489
489
|
* purchase: a retry under it answers the same top-up as it now stands (`replayed: true`) and
|
|
490
|
-
* buys nothing again
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
494
|
-
*
|
|
490
|
+
* buys nothing again - asking the payment provider again for a checkout the first attempt
|
|
491
|
+
* could not open, within its page's 40 minutes (Stripe only in the first 10, while 30
|
|
492
|
+
* remain: it answers a timed-out first attempt with the checkout it made, or makes one never
|
|
493
|
+
* made; Paymob only if the first attempt never made one); reusing it for another purchase
|
|
494
|
+
* throws `idempotency_conflict` (409). A retry can also throw `conflict` (409), with
|
|
495
|
+
* `details.reason`: `checkout_in_progress` - another request is still opening the
|
|
496
|
+
* checkout, so retry the same key shortly - or `checkout_unavailable` - its checkout could
|
|
497
|
+
* not be opened and never will be, so buy again under a new key.
|
|
495
498
|
*/
|
|
496
499
|
create: async (input, options) => {
|
|
497
500
|
const { status, data } = await apiRequestWithStatus(
|
|
@@ -573,6 +576,155 @@ function createCreditsResource(ctx) {
|
|
|
573
576
|
void 0,
|
|
574
577
|
options
|
|
575
578
|
)
|
|
579
|
+
},
|
|
580
|
+
rateCards: {
|
|
581
|
+
/**
|
|
582
|
+
* Publish a new Rate Card version: what each Credit Action costs, as
|
|
583
|
+
* `ceil(units * unitPrice / perUnits)` microcredits a line. Versions are immutable - a price
|
|
584
|
+
* change is a new version - and take effect in order, at `effectiveAt` (now when omitted).
|
|
585
|
+
*/
|
|
586
|
+
publish: (input, options) => apiRequest(ctx, "POST", "/v1/credits/rate-cards", input, options),
|
|
587
|
+
/** The version in effect now (`not_found` before the first takes effect). */
|
|
588
|
+
current: (options) => apiRequest(
|
|
589
|
+
ctx,
|
|
590
|
+
"GET",
|
|
591
|
+
"/v1/credits/rate-cards/current",
|
|
592
|
+
void 0,
|
|
593
|
+
options
|
|
594
|
+
),
|
|
595
|
+
/** One version, by its number. */
|
|
596
|
+
get: (version, options) => apiRequest(
|
|
597
|
+
ctx,
|
|
598
|
+
"GET",
|
|
599
|
+
`/v1/credits/rate-cards/${encodeURIComponent(String(version))}`,
|
|
600
|
+
void 0,
|
|
601
|
+
options
|
|
602
|
+
),
|
|
603
|
+
/**
|
|
604
|
+
* The published versions, newest first. Auto-paginating by cursor: `await` the first page,
|
|
605
|
+
* `for await (…)` every version, or `.listAll()` to collect them.
|
|
606
|
+
*/
|
|
607
|
+
list: (params = {}, options) => makeCursorListPromise(
|
|
608
|
+
(p) => apiRequest(
|
|
609
|
+
ctx,
|
|
610
|
+
"GET",
|
|
611
|
+
`/v1/credits/rate-cards${toQuery(p)}`,
|
|
612
|
+
void 0,
|
|
613
|
+
options
|
|
614
|
+
),
|
|
615
|
+
params
|
|
616
|
+
)
|
|
617
|
+
},
|
|
618
|
+
quotes: {
|
|
619
|
+
/**
|
|
620
|
+
* Price a customer's Credit Actions (all of one category) at the current Rate Card version
|
|
621
|
+
* and keep the price for 15 minutes: a reservation over the quote holds exactly its
|
|
622
|
+
* `amount`, and its commit prices at the version the quote pinned. A quote holds nothing.
|
|
623
|
+
*/
|
|
624
|
+
create: (input, options) => apiRequest(ctx, "POST", "/v1/credits/quotes", input, options),
|
|
625
|
+
/** A quote as it was made. */
|
|
626
|
+
get: (quoteId, options) => apiRequest(
|
|
627
|
+
ctx,
|
|
628
|
+
"GET",
|
|
629
|
+
`/v1/credits/quotes/${encodeURIComponent(quoteId)}`,
|
|
630
|
+
void 0,
|
|
631
|
+
options
|
|
632
|
+
)
|
|
633
|
+
},
|
|
634
|
+
reservations: {
|
|
635
|
+
/**
|
|
636
|
+
* Hold credits for one operation: over a `quoteId`, or over `items` priced at the current
|
|
637
|
+
* Rate Card version. The `idempotencyKey` is required: a retry under it - after a lost
|
|
638
|
+
* reply, even once the quote expired - answers the same reservation (`replayed: true`) and
|
|
639
|
+
* holds nothing again. Reusing it for another request, or a new key with an `operationKey`
|
|
640
|
+
* the customer already used (`details.reason: "operation_key_used"`), throws
|
|
641
|
+
* `idempotency_conflict` (409). Throws `insufficient_credits` (402), `account_frozen`
|
|
642
|
+
* (423), `account_closed` (409), `conflict` (409, `details.reason: "quote_expired"`), or
|
|
643
|
+
* `validation_error` (422) - e.g. `details.reason: "zero_amount"` when the items cost nothing.
|
|
644
|
+
* The `operationKey` is an operation id, never personal data: erasure replaces it.
|
|
645
|
+
*/
|
|
646
|
+
create: async (input, options) => {
|
|
647
|
+
const { status, data } = await apiRequestWithStatus(
|
|
648
|
+
ctx,
|
|
649
|
+
"POST",
|
|
650
|
+
"/v1/credits/reservations",
|
|
651
|
+
input,
|
|
652
|
+
options
|
|
653
|
+
);
|
|
654
|
+
return { ...data, replayed: status === 200 };
|
|
655
|
+
},
|
|
656
|
+
/** A reservation as it now stands. */
|
|
657
|
+
get: (reservationId, options) => apiRequest(
|
|
658
|
+
ctx,
|
|
659
|
+
"GET",
|
|
660
|
+
`/v1/credits/reservations/${encodeURIComponent(reservationId)}`,
|
|
661
|
+
void 0,
|
|
662
|
+
options
|
|
663
|
+
),
|
|
664
|
+
/**
|
|
665
|
+
* A customer's reservation (by external id) made with `operationKey` - how to find one whose
|
|
666
|
+
* reply was lost. Throws `not_found` (404) when there is none.
|
|
667
|
+
*/
|
|
668
|
+
findByOperationKey: (customer, operationKey, options) => apiRequest(
|
|
669
|
+
ctx,
|
|
670
|
+
"GET",
|
|
671
|
+
`/v1/credits/reservations${toQuery({ customer, operationKey })}`,
|
|
672
|
+
void 0,
|
|
673
|
+
options
|
|
674
|
+
),
|
|
675
|
+
/**
|
|
676
|
+
* Commit what the operation used: lines priced at the reservation's Rate Card version,
|
|
677
|
+
* consuming at most what it holds (`commit_exceeds_hold`, 409) and releasing the rest; lines
|
|
678
|
+
* that cost nothing in all consume nothing (`consumed: "0"`, `consumptionId: null`). The
|
|
679
|
+
* same commit again answers it again, so it is safe to retry; anything else after it throws
|
|
680
|
+
* `invalid_state_transition` (409) with the reservation in `details` - with
|
|
681
|
+
* `details.reason: "reservation_expired"` once the hold is past its `expiresAt`.
|
|
682
|
+
*/
|
|
683
|
+
commit: (reservationId, items, options) => apiRequest(
|
|
684
|
+
ctx,
|
|
685
|
+
"POST",
|
|
686
|
+
`/v1/credits/reservations/${encodeURIComponent(reservationId)}/commit`,
|
|
687
|
+
{ items },
|
|
688
|
+
options
|
|
689
|
+
),
|
|
690
|
+
/** Release the whole hold. Safe to retry; after a commit it throws (409). */
|
|
691
|
+
release: (reservationId, options) => apiRequest(
|
|
692
|
+
ctx,
|
|
693
|
+
"POST",
|
|
694
|
+
`/v1/credits/reservations/${encodeURIComponent(reservationId)}/release`,
|
|
695
|
+
void 0,
|
|
696
|
+
options
|
|
697
|
+
),
|
|
698
|
+
/**
|
|
699
|
+
* Protect a held reservation whose operation was paid for and is still being fulfilled: it
|
|
700
|
+
* never expires (commit or release it when done). Safe to retry. A hold already past its
|
|
701
|
+
* `expiresAt` throws `invalid_state_transition` (409, `details.reason: "reservation_expired"`).
|
|
702
|
+
*/
|
|
703
|
+
protect: (reservationId, options) => apiRequest(
|
|
704
|
+
ctx,
|
|
705
|
+
"POST",
|
|
706
|
+
`/v1/credits/reservations/${encodeURIComponent(reservationId)}/protect`,
|
|
707
|
+
void 0,
|
|
708
|
+
options
|
|
709
|
+
)
|
|
710
|
+
},
|
|
711
|
+
consumptions: {
|
|
712
|
+
/**
|
|
713
|
+
* Give back part or all of a commit's consumption (`consumptionId` on the committed
|
|
714
|
+
* reservation), never more than is left (`reversal_exceeds_consumption`, 409). The
|
|
715
|
+
* `idempotencyKey` is required: a retry under it answers the same reversal
|
|
716
|
+
* (`replayed: true`) and gives nothing back again.
|
|
717
|
+
*/
|
|
718
|
+
reverse: async (consumptionId, input, options) => {
|
|
719
|
+
const { status, data } = await apiRequestWithStatus(
|
|
720
|
+
ctx,
|
|
721
|
+
"POST",
|
|
722
|
+
`/v1/credits/consumptions/${encodeURIComponent(consumptionId)}/reverse`,
|
|
723
|
+
input,
|
|
724
|
+
options
|
|
725
|
+
);
|
|
726
|
+
return { ...data, replayed: status === 200 };
|
|
727
|
+
}
|
|
576
728
|
}
|
|
577
729
|
};
|
|
578
730
|
}
|
|
@@ -685,6 +837,33 @@ function createDeliverabilityResource(ctx) {
|
|
|
685
837
|
};
|
|
686
838
|
}
|
|
687
839
|
|
|
840
|
+
// src/resources/hosted-domains.ts
|
|
841
|
+
var path = (id, action = "") => `/v1/hosted-domains/${encodeURIComponent(id)}${action}`;
|
|
842
|
+
function createHostedDomainsResource(ctx) {
|
|
843
|
+
return {
|
|
844
|
+
/** The Project's domains, and whether its plan allows adding more (`whiteLabel`). */
|
|
845
|
+
list: (options) => apiRequest(ctx, "GET", "/v1/hosted-domains", void 0, options),
|
|
846
|
+
/**
|
|
847
|
+
* Add a subdomain such as `billing.example.com`. Answers the domain with the TXT and CNAME
|
|
848
|
+
* `records` to create. Needs a plan with white-label branding (`permission_denied` otherwise).
|
|
849
|
+
*/
|
|
850
|
+
create: (input, options) => apiRequest(ctx, "POST", "/v1/hosted-domains", input, options),
|
|
851
|
+
get: (id, options) => apiRequest(ctx, "GET", path(id), void 0, options),
|
|
852
|
+
/** Check the DNS records now (2 per minute per domain); answers the refreshed domain. */
|
|
853
|
+
verify: (id, options) => apiRequest(ctx, "POST", path(id, "/verify"), void 0, options),
|
|
854
|
+
/** Make an active domain the default host for new portal sessions. */
|
|
855
|
+
makePrimary: (id, options) => apiRequest(ctx, "POST", path(id, "/primary"), void 0, options),
|
|
856
|
+
/** Remove a domain; the portal sessions on it end immediately. */
|
|
857
|
+
remove: (id, options) => apiRequest(
|
|
858
|
+
ctx,
|
|
859
|
+
"DELETE",
|
|
860
|
+
path(id),
|
|
861
|
+
void 0,
|
|
862
|
+
options
|
|
863
|
+
)
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
|
|
688
867
|
// src/resources/invoices.ts
|
|
689
868
|
function createInvoicesResource(ctx) {
|
|
690
869
|
return {
|
|
@@ -1150,6 +1329,8 @@ var Billow = class {
|
|
|
1150
1329
|
portalSessions;
|
|
1151
1330
|
deliverability;
|
|
1152
1331
|
marketplace;
|
|
1332
|
+
/** Custom domains for the hosted customer portal (live keys, behind a rollout flag). */
|
|
1333
|
+
hostedDomains;
|
|
1153
1334
|
/**
|
|
1154
1335
|
* Organization settings (Phase D3, F) — the configurable dunning schedule, usage settlement grace,
|
|
1155
1336
|
* and the cross-currency reporting currency + FX-rate registry (ADR-0013).
|
|
@@ -1170,10 +1351,11 @@ var Billow = class {
|
|
|
1170
1351
|
this.portalSessions = createPortalSessionsResource(this.#ctx);
|
|
1171
1352
|
this.deliverability = createDeliverabilityResource(this.#ctx);
|
|
1172
1353
|
this.marketplace = createMarketplaceResource(this.#ctx);
|
|
1354
|
+
this.hostedDomains = createHostedDomainsResource(this.#ctx);
|
|
1173
1355
|
this.settings = createSettingsResource(this.#ctx);
|
|
1174
1356
|
}
|
|
1175
|
-
#request(method,
|
|
1176
|
-
return apiRequest(this.#ctx, method,
|
|
1357
|
+
#request(method, path2, body, options) {
|
|
1358
|
+
return apiRequest(this.#ctx, method, path2, body, options);
|
|
1177
1359
|
}
|
|
1178
1360
|
coupons = {
|
|
1179
1361
|
/** Define a coupon (a reusable discount template). */
|
|
@@ -1489,5 +1671,5 @@ var BillowPortal = class {
|
|
|
1489
1671
|
};
|
|
1490
1672
|
|
|
1491
1673
|
export { BILLOW_ERROR_CODES, Billow, BillowApiError, BillowPortal, BillowPublishable, currencyExponent, formatMoney, isSecretField, toMajorUnits, toMinorUnits };
|
|
1492
|
-
//# sourceMappingURL=chunk-
|
|
1493
|
-
//# sourceMappingURL=chunk-
|
|
1674
|
+
//# sourceMappingURL=chunk-DYWGZRE2.js.map
|
|
1675
|
+
//# sourceMappingURL=chunk-DYWGZRE2.js.map
|