@billkit-eu/sdk 0.7.1 → 0.8.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 +14 -1
- package/README.md +6 -2
- package/dist/index.cjs +25 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -9
- package/dist/index.d.ts +49 -9
- package/dist/index.js +25 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/resources.ts +55 -7
- package/src/version.ts +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pagination.ts","../src/resources.ts","../src/errors.ts","../src/logging.ts","../src/retry.ts","../src/version.ts","../src/transport.ts","../src/client.ts","../src/webhooks.ts"],"names":["delayMs"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Auto-pagination helper for list endpoints.\n *\n * The BillKit API returns Stripe-shape envelopes:\n *\n * { \"object\": \"list\", \"data\": [...], \"has_more\": bool }\n *\n * Cursor pagination is forward-only via the last item's `id` as\n * `starting_after`. `paginate` walks every page and yields each row.\n * Callers consume it via `for await`:\n *\n * for await (const customer of client.customers.iter()) {\n * ...\n * }\n */\n\nimport type { QueryValue } from \"./transport.js\";\n\nexport interface ListResponseEnvelope<T = unknown> {\n readonly data?: readonly T[];\n readonly has_more?: boolean;\n}\n\nexport interface PaginateOptions {\n /** Maps to the API's `limit` parameter. `undefined` lets the\n * server pick its default (10 today). */\n pageSize?: number | undefined;\n /** Extra filters forwarded on every page (e.g. `type` on events,\n * `action` on audit logs). Values are pruned of `undefined` so\n * callers can spread their full options object in. */\n filters?: Readonly<Record<string, QueryValue>>;\n}\n\ntype ListFn<T> = (params: {\n limit?: number | undefined;\n starting_after?: string | undefined;\n [key: string]: QueryValue;\n}) => Promise<ListResponseEnvelope<T>>;\n\n/**\n * Walk every page of `listFn` and yield each row.\n *\n * Three terminators, in priority order:\n * 1. `has_more=false`: the server's authoritative signal (common case).\n * 2. Empty `data` with `has_more=true`: shouldn't happen per the API\n * contract, but if a future server bug or proxy misbehaviour\n * produced it the iterator would loop forever. Belt-and-suspenders.\n * 3. The last row has no `id`, so there is no cursor to advance with. The schema\n * doesn't allow it today, but same defensive reasoning.\n */\nexport async function* paginate<T>(\n listFn: ListFn<T>,\n options: PaginateOptions = {},\n): AsyncIterableIterator<T> {\n const { pageSize, filters } = options;\n const cleanFilters: Record<string, QueryValue> = {};\n if (filters) {\n for (const [k, v] of Object.entries(filters)) {\n if (v !== undefined) cleanFilters[k] = v;\n }\n }\n\n let cursor: string | undefined;\n for (;;) {\n const page = await listFn({\n ...cleanFilters,\n limit: pageSize,\n starting_after: cursor,\n });\n const items = page.data ?? [];\n for (const item of items) yield item;\n if (!page.has_more || items.length === 0) return;\n const last = items[items.length - 1] as { id?: string } | undefined;\n cursor = last?.id;\n if (cursor === undefined) return;\n }\n}\n","/**\n * Resource accessors mirroring the BillKit API surface.\n *\n * Each resource exposes the public verbs from `/v1/<resource>`. The\n * return type defaults to `unknown`; the SDK doesn't ship runtime\n * schemas (zod / valibot) because the API is Stripe-shape and tenants\n * typically forward the JSON through their own data layer unchanged.\n * Callers who want strong types parameterise each call with their\n * own generic:\n *\n * interface Customer { id: string; email: string }\n * const c = await client.customers.create<Customer>({ email: \"...\" });\n *\n * Every list-returning resource also exposes an `iter()` method that\n * walks every page via the Stripe-shape `has_more` + `starting_after`\n * cursor protocol. Iterate with `for await`:\n *\n * for await (const customer of client.customers.iter()) { ... }\n */\n\nimport { paginate, type ListResponseEnvelope } from \"./pagination.js\";\nimport type { Transport } from \"./transport.js\";\n\n// ─── Shared parameter shapes ───────────────────────────────────────\n\n/**\n * Cursor-pagination knobs shared by every `list()` method.\n *\n * Closed on purpose: there is no index signature, so a misspelled filter\n * (`provisonal`) is a compile error instead of a query parameter the\n * server ignores. The Transport takes `query` as a plain `object` and\n * prunes/stringifies it, which is what lets these interfaces through\n * without a cast.\n */\nexport interface BaseListParams {\n limit?: number;\n starting_after?: string;\n // Deliberately no `ending_before`: BillKit's cursor pagination binds\n // `limit` + `starting_after` only (see `api/billkit/api/pagination.py`).\n // Advertising a backwards cursor the server ignores is worse than not\n // having one — the request succeeds and silently re-serves page 1.\n}\n\n/**\n * `?expand=` on a single-object GET. The relations a route accepts differ\n * per resource and are listed on each `retrieve()`; an unknown one is a\n * `400` naming the ones that work.\n */\nexport interface ExpandOptions {\n expand?: string[];\n}\n\n/**\n * `prices.list` params. Adds the server-side `product_id` filter on top of\n * the usual cursor knobs. `GET /v1/prices?product_id=...` narrows to one\n * product's prices, which beats listing everything and filtering client-side\n * once a tenant has more than a page of prices.\n */\nexport interface PricesListParams extends BaseListParams {\n product_id?: string;\n}\n\n/**\n * `payments.list` params. `customer_id` narrows to one customer's\n * charges. Mandate verifications are never listed, so every row is a\n * real purchase attempt; check `status` before treating one as revenue.\n */\nexport interface PaymentsListParams extends BaseListParams {\n customer_id?: string;\n /** Expandable here: `customer`, `subscription`. */\n expand?: string[];\n}\n\n/**\n * `invoices.list` params. The three id filters each narrow to one row's\n * worth of invoices: `payment_id` answers \"which invoice did this charge\n * produce\".\n */\nexport interface InvoicesListParams extends BaseListParams {\n customer_id?: string;\n subscription_id?: string;\n payment_id?: string;\n /** One of `draft`, `open`, `paid`, `void`, `uncollectible`. */\n status?: string;\n /** Expandable here: `customer`. */\n expand?: string[];\n}\n\n/**\n * `disputes.list` params. `status` takes a comma-separated list of `open`\n * / `won`. There is no `lost`, because the provider gives no signal for\n * one. `payment_id` matches subscription payments only, not one-off\n * charges.\n */\nexport interface DisputesListParams extends BaseListParams {\n status?: string;\n payment_id?: string;\n}\n\n/**\n * `subscriptions.list` params. Both filters take a comma-separated\n * list (`\"active,past_due\"`); an unrecognised value is rejected with\n * `400 parameter_invalid` rather than silently ignored.\n *\n * The two answer different questions, and mixing them up is the most\n * common mistake against this route. `status` is where the subscription\n * stands with its payments. `renewal_state` is what happens at the end\n * of the current period. A paused subscription keeps `status: \"active\"`,\n * because the customer has paid for the period they are in, so\n * `renewal_state: \"paused\"` is the only way to find paused ones —\n * `status: \"paused\"` is not an accepted value and is rejected.\n */\nexport interface SubscriptionsListParams extends BaseListParams {\n customer_id?: string;\n /** `incomplete` | `trialing` | `active` | `past_due` | `canceled`, CSV. */\n status?: string;\n /** `auto_renew` | `paused` | `canceling` | `stopped`, CSV. */\n renewal_state?: string;\n /** Expandable here: `customer`, `price`, `refund_eligibility`. */\n expand?: string[];\n}\n\n/** Optional idempotency knob carried by every mutating call. */\nexport interface IdempotencyOptions {\n /** Coalesces retries across process restarts. The SDK generates\n * a random `sdk-<uuid>` key for every mutating call if you don't\n * supply one. Pass your own when you want retries from a different\n * process to converge on the same server-side result. */\n idempotencyKey?: string;\n}\n\n/**\n * @deprecated Alias of {@link BaseListParams}, kept for callers that\n * imported the older name. Reach for the resource-specific `*ListParams`\n * (e.g. `EventsListParams`) instead.\n */\nexport type ListParams = BaseListParams;\n\n// ─── Per-resource parameter shapes ─────────────────────────────────\n//\n// We keep one exported interface per public surface so callers can\n// import the shape, build it ahead of time, and pass it in. Inlined\n// shapes were inconsistent across resources; the named-interface\n// form is greppable and survives editor \"go to definition\".\n\nexport interface CreateCustomerParams extends IdempotencyOptions {\n email?: string;\n name?: string;\n country_code?: string;\n metadata?: Record<string, string>;\n}\n\nexport interface UpdateCustomerParams extends IdempotencyOptions {\n email?: string;\n name?: string;\n country_code?: string;\n metadata?: Record<string, string>;\n}\n\n/** Query parameters accepted by `GET /v1/customers`. */\nexport interface CustomerListParams extends BaseListParams {\n /**\n * `false` for customers who have paid, `true` for abandoned checkouts,\n * omitted for both.\n */\n provisional?: boolean;\n /** Expandable here: `stats`. Sent as `expand=a,b`. */\n expand?: string[];\n}\n\n/** Query parameters accepted by `GET /v1/products`. */\nexport interface ProductsListParams extends BaseListParams {\n /** Expandable here: `prices`, `stats`, `default_price`. */\n expand?: string[];\n}\n\n/**\n * Body for `POST /v1/customers/{id}/vat_number`. The VAT number is\n * sent through VIES server-side; the response carries\n * `vat_number_validated` reflecting the outcome.\n *\n * `vat_number: null` **clears** the registration, and is sent as an\n * explicit null rather than pruned: only `undefined` is dropped.\n */\nexport interface SetCustomerVatNumberParams extends IdempotencyOptions {\n vat_number: string | null;\n /** VIES needs a country; send it when the customer has none yet. */\n country_code?: string;\n}\n\n/**\n * Body for `POST /v1/customers/{id}/purge`. The server requires\n * `confirmed: true` as a fat-finger guard against accidental purges\n * fired from a DELETE that meant to soft-delete. The SDK defaults\n * `confirmed` to `true` so the caller doesn't have to opt in twice.\n */\nexport interface PurgeCustomerParams extends IdempotencyOptions {\n confirmed?: boolean;\n}\n\nexport interface CreateProductParams extends IdempotencyOptions {\n /** Customer-facing name, for example \"Pro\" or \"Enterprise\". */\n name: string;\n /** Optional long-form description shown in your own catalog UI. */\n description?: string;\n /** Ordered bullets suitable for pricing tables and checkout pages. */\n marketing_features?: string[];\n /** Small string metadata map echoed back on the Product object. */\n metadata?: Record<string, string>;\n /**\n * Let a *buyer* type a coupon code at the embedded checkout for this\n * product. Defaults to `false`. A coupon you apply yourself by passing\n * `coupon_code` when you create a Checkout Session is unaffected — that\n * is you discounting your own sale, and it has never needed this flag.\n *\n * The code is redeemed only once the payment settles, so a shopper who\n * tries a single-use code and abandons the checkout does not use it up.\n */\n allow_promotion_codes?: boolean;\n}\n\nexport interface UpdateProductParams extends IdempotencyOptions {\n name?: string;\n description?: string;\n marketing_features?: string[];\n metadata?: Record<string, string>;\n /** Set false to stop selling a product without deleting history. */\n active?: boolean;\n /** See {@link CreateProductParams.allow_promotion_codes}. */\n allow_promotion_codes?: boolean;\n /**\n * The price the billing portal offers on that price's interval. Must be\n * an active price of this product; anything else is a 400 on\n * `default_price_id`. An explicit `null` **clears** the default and is\n * sent as a JSON null rather than pruned (only `undefined` is dropped);\n * omit the field to leave the default alone.\n */\n default_price_id?: string | null;\n}\n\n/**\n * Body for `POST /v1/prices/{id}`. Every field is optional; omitted ones\n * are left alone.\n *\n * The dividing line is what a field decides. `amount_cents`, `currency`,\n * `interval` and `usage_type` decide **what a past charge was**, so they\n * are fixed at creation and absent here, because subscriptions renew\n * against a price by id and editing one would re-price live customers.\n * Everything\n * below decides **what happens next**, which is why it is editable:\n * setting `refund_on_cancel` covers the customers already on the price.\n *\n * `tax_behavior` is the exception and moves one way. It can be set while\n * the price is still `\"unspecified\"` and never changed again, because\n * flipping it would restate whether tax was inside or on top of an amount\n * somebody has already paid.\n */\nexport interface UpdatePriceParams extends IdempotencyOptions {\n /** `false` withdraws the price from sale, `true` puts it back. */\n active?: boolean;\n metadata?: Record<string, string>;\n /** Settable once, while the price is still `\"unspecified\"`. */\n tax_behavior?: \"inclusive\" | \"exclusive\";\n /** Read when a checkout opens. At least one entry. */\n payment_methods?: Array<\n \"creditcard\" | \"directdebit\" | \"ideal\" | \"eps\" | \"applepay\" | \"paypal\" | (string & {})\n >;\n refund_on_cancel?: \"none\" | \"full\" | \"prorated\";\n /** `0` disables refunds for that charge type; `N > 0` is an N-day window. */\n refund_window_initial_days?: number;\n refund_window_renewal_days?: number;\n}\n\n/**\n * One band of a tiered price.\n *\n * `up_to` is inclusive, and the **last band must be `\"inf\"`** because a\n * bounded top band cannot price the usage above it. Bands must strictly\n * increase.\n *\n * A band names a unit rate (`unit_amount` in whole minor units, or\n * `unit_amount_decimal` for a finer one), a `flat_amount` charged once for\n * reaching the band, or both. Write a free band as `unit_amount: 0` rather\n * than by omitting the rate, so \"free\" is something the price says instead\n * of something it forgot.\n */\nexport interface PriceTier {\n up_to: number | \"inf\";\n /** Whole minor units per unit in this band. */\n unit_amount?: number;\n /**\n * A rate finer than one minor unit, **as a string** — see\n * {@link CreatePriceParams.unit_amount_decimal} for why it is never a\n * `number`.\n */\n unit_amount_decimal?: string;\n /** Charged once when the usage reaches this band. Whole minor units. */\n flat_amount?: number;\n}\n\nexport interface CreatePriceParams extends IdempotencyOptions {\n /** Existing Product id returned from `client.products.create`. */\n product_id: string;\n /**\n * Whole minor units per period (licensed) or per unit (metered).\n *\n * Optional because a metered price can be priced by\n * {@link CreatePriceParams.unit_amount_decimal} or by\n * {@link CreatePriceParams.tiers} instead. Exactly one of the three; a\n * price with none of them is refused server-side.\n */\n amount_cents?: number;\n /**\n * A per-unit rate smaller than one minor unit, in **minor units**, to 12\n * decimal places. `\"0.02\"` is 0.02 cents, i.e. EUR 0.0002 per unit, which\n * is the canonical per-API-call price and not expressible as an integer.\n * Metered prices only.\n *\n * **It is a `string`, and that is load-bearing.** A JS `number` is an\n * IEEE-754 double and cannot hold 0.0002 exactly, so the rate would be\n * corrupted before it was ever multiplied by a quantity. The type forbids\n * a number at compile time, and the SDK throws a `TypeError` if an\n * untyped JavaScript caller passes one anyway.\n *\n * The period's whole quantity is multiplied by the rate and rounded\n * **once**, at the invoice.\n */\n unit_amount_decimal?: string;\n /**\n * `\"per_unit\"` (the default) multiplies one rate by the quantity.\n * `\"tiered\"` prices by bands and requires\n * {@link CreatePriceParams.tiers} and\n * {@link CreatePriceParams.tiers_mode}. Metered prices only.\n */\n billing_scheme?: \"per_unit\" | \"tiered\";\n /**\n * How a tier table is read, and there is **no default** because the same\n * table means two different bills. `\"graduated\"` prices the units inside\n * each band; `\"volume\"` lets the period total pick one band which then\n * prices every unit. 1,500 units against \"first 1,000 at EUR 0.01, then\n * EUR 0.005\" is EUR 12.50 graduated and EUR 7.50 by volume.\n */\n tiers_mode?: \"graduated\" | \"volume\";\n /** The band table. Required when `billing_scheme` is `\"tiered\"`, refused otherwise. */\n tiers?: PriceTier[];\n currency: string;\n interval: \"month\" | \"year\" | (string & {});\n metadata?: Record<string, string>;\n trial_days?: number;\n trial_verification_cents?: number;\n payment_methods?: Array<\n \"creditcard\" | \"directdebit\" | \"ideal\" | \"eps\" | \"applepay\" | \"paypal\" | (string & {})\n >;\n /**\n * What a cancellation refunds without being asked. `\"none\"` (the default)\n * nothing; `\"full\"` the whole last charge; `\"prorated\"` the unused part\n * of the current period. Both non-none modes also end access\n * immediately, and both stay bounded by the refund window below.\n *\n * Metered prices must leave this at `\"none\"`: ending access mid-period\n * would strand usage that has not been billed yet.\n */\n refund_on_cancel?: \"none\" | \"full\" | \"prorated\";\n /**\n * Per-Price refund-window override (`POST /v1/prices`). `undefined`\n * inherits the default policy table (7d / 30d initial, 3d renewal);\n * `0` disables refunds for that charge type; `N > 0` is an N-day\n * window (capped server-side at 365). Useful for \"Pro Bundle has a\n * 14-day money back\" or \"Lifetime: no refunds\" product decisions.\n */\n refund_window_initial_days?: number;\n refund_window_renewal_days?: number;\n /**\n * Whether `amount_cents` is quoted gross (`\"inclusive\"`, VAT is\n * backed out of it) or net (`\"exclusive\"`, VAT is added on top at\n * charge time). `undefined` inherits `\"unspecified\"`, which defers to\n * the tax rate configured for the buyer's country. Set it explicitly\n * when the amount you advertise has to be the amount charged,\n * regardless of what tax rates exist now or later.\n */\n tax_behavior?: \"inclusive\" | \"exclusive\" | \"unspecified\";\n /**\n * `\"licensed\"` (the default when omitted) bills `amount_cents` per\n * period regardless of consumption. `\"metered\"` bills **per reported\n * unit**: post consumption with `subscriptions.createUsageRecord`, and\n * at each period close BillKit invoices the period's total and charges\n * the stored mandate.\n *\n * A metered unit is priced by `amount_cents`, by `unit_amount_decimal`,\n * or by `tiers` — exactly one. Metered prices must be\n * `interval: \"month\"`, cannot have `trial_days`, and cannot set\n * `refund_on_cancel`.\n */\n usage_type?: \"licensed\" | \"metered\";\n}\n\n/**\n * Body for `POST /v1/subscriptions/{id}/usage_records`. Only valid\n * against a subscription whose price is `usage_type: \"metered\"`; the\n * server rejects a licensed subscription with `400 parameter_invalid`.\n */\nexport interface CreateUsageRecordParams extends IdempotencyOptions {\n /** Units consumed, `1..1_000_000`. Post multiple records to accumulate. */\n quantity: number;\n /**\n * Epoch seconds when the consumption happened. Omit to let the\n * server stamp receipt time. Useful when reporting is batched and\n * the record must land in the period the usage occurred.\n */\n occurred_at?: number;\n /**\n * Your own id for the event being metered, unique within this\n * subscription. This is the dedupe an `Idempotency-Key` cannot do.\n *\n * The key covers a retry of *one HTTP request*, including the SDK's own\n * internal retries. `identifier` covers a retry of *your* call — a job\n * runner replaying a task, a queue delivering twice, your code\n * re-invoking after its own timeout — which arrives at the API as a\n * genuinely new request with a new key. A second report of the same\n * identifier returns the first record unchanged instead of billing\n * twice.\n *\n * If your reporting pipeline is at-least-once, this is the one that\n * matters.\n */\n identifier?: string;\n /** Small string metadata map echoed back on the record. */\n metadata?: Record<string, string>;\n}\n\n/**\n * `subscriptions.listUsageRecords` params. `invoice_id` filters by\n * billing state: `\"pending\"` selects records not yet rolled into an\n * invoice, and a concrete `inv_...` id selects the records that\n * invoice billed. Omit it to list everything.\n */\nexport interface UsageRecordsListParams extends BaseListParams {\n invoice_id?: \"pending\" | (string & {});\n}\n\nexport interface CreateCheckoutSessionParams extends IdempotencyOptions {\n /**\n * Existing Customer to attach the session to. Mutually exclusive\n * with `customer_email`; exactly one of the two must be set.\n */\n customer_id?: string;\n /**\n * Stripe-compatible shortcut: BillKit creates a fresh Customer row\n * in the same transaction as the checkout. Never dedupes by email\n * (emails are not unique identifiers in BillKit). Mutually exclusive\n * with `customer_id`.\n */\n customer_email?: string;\n /**\n * Optional friendly name carried onto the auto-created Customer when\n * using `customer_email`. Rejected with `422` if supplied alongside\n * `customer_id` (rename existing customers via `customers.update`).\n */\n customer_name?: string;\n price_id: string;\n success_url: string;\n cancel_url: string;\n /**\n * The buyer's ISO-3166-1 alpha-2 country, when you already know it.\n * Stored on the customer if they do not have one yet, which is what\n * lets VAT apply to the very first charge. On the hosted flow the buyer\n * only reaches a country-collecting page after the charge exists.\n * Never overwrites a country the customer already has.\n */\n country?: string;\n /**\n * Pin the Mollie payment method. `undefined` lets Mollie pick from\n * the customer's available methods; when set, must be in the price's\n * `payment_methods` allowlist.\n *\n * Subscription-starting only, so this is deliberately NARROWER than the\n * one-shot union: `bancontact` and `banktransfer` are absent because\n * neither can mint the mandate a renewal needs. Mollie refuses the\n * latter outright with \"The payment method does not support sequence\n * type\".\n */\n method?:\n | \"creditcard\"\n | \"directdebit\"\n | \"ideal\"\n | \"eps\"\n | \"applepay\"\n | \"paypal\"\n | (string & {});\n /** Optional coupon code applied at checkout; atomically claimed. */\n coupon_code?: string;\n /**\n * Per-session trial override. Replaces the price's `trial_days`\n * for this checkout. Capped server-side at `2 × max(price.trial_days, 14)`.\n * `0` disables a trial that the price would otherwise grant.\n */\n trial_days_override?: number;\n /**\n * `\"hosted\"` (the default) returns a `url` you redirect the buyer to.\n * `\"embedded\"` returns a `client_secret` instead, for\n * `mountCheckoutElement()` / `<CheckoutElement/>` from\n * `@billkit-eu/js` — the card fields then render in a cross-origin\n * iframe on your own page.\n */\n ui_mode?: \"hosted\" | \"embedded\";\n /**\n * Small string map carried onto the session. Up to 50 keys, key ≤ 40\n * chars, value ≤ 500 chars.\n */\n metadata?: Record<string, string>;\n}\n\nexport interface CreateRefundParams extends IdempotencyOptions {\n payment_id?: string;\n subscription_id?: string;\n /**\n * Refund a mandate-less one-shot payment (`oneShotPayments.create`).\n * Mutually exclusive with `payment_id` / `subscription_id`; pass\n * exactly one target or the server rejects with `400`.\n */\n one_shot_payment_id?: string;\n /**\n * Partial-refund amount in minor units. Omit to refund the whole remaining\n * balance (the full charge when nothing has been refunded yet). A payment\n * may carry several partial refunds up to the charged amount; the one that\n * brings the cumulative total to the full charge cancels the bound\n * subscription (or flips a one-shot to `refunded`).\n */\n amount_cents?: number;\n reason?: string;\n}\n\n/**\n * Body for `POST /v1/checkout/one_shot`, a single mandate-less charge\n * (the Stripe PaymentIntent shape, mapped onto Mollie). No subscription,\n * no mandate, no renewals: it settles once against your `success_url`.\n */\nexport interface CreateOneShotPaymentParams extends IdempotencyOptions {\n /** Existing Customer to charge. */\n customer_id: string;\n amount_cents: number;\n /** ISO-4217, e.g. `\"EUR\"`. Validated against the tenant allowlist. */\n currency: string;\n /**\n * Concrete Mollie method to charge with. Required, because a one-shot commits\n * up front). Validated against the tenant's capability allowlist for\n * `currency`; one-off methods like `bancontact` and `banktransfer` are\n * allowed here even though they can't back a subscription.\n *\n * `banktransfer` settles in DAYS, not seconds: the payer is handed bank\n * details and Mollie holds the payment `open` for about a fortnight. Expect\n * `one_shot_payment.paid` long after the call returns.\n *\n * `giropay` was removed: the scheme shut down at the end of 2024 and the\n * server now 422s it. The `(string & {})` tail keeps this open on\n * purpose: unlike the console's read-side `PaymentMethodKind`, this is a\n * *request* type the server validates, so an SDK that lags a newly-added\n * method should not be the thing that blocks the call.\n */\n method:\n | \"creditcard\"\n | \"directdebit\"\n | \"ideal\"\n | \"bancontact\"\n | \"eps\"\n | \"applepay\"\n | \"paypal\"\n | \"banktransfer\"\n | (string & {});\n /** Where Mollie returns the payer after the hosted checkout. */\n success_url: string;\n /** Optional page for an abandoned/cancelled payment. */\n cancel_url?: string;\n /** Shown on the Mollie page + the payer's bank statement. */\n description?: string;\n /**\n * Per-payment refund-window override in days. `undefined` inherits the\n * one-shot default (30 days); `0` disables refunds for this payment;\n * `N > 0` is an N-day window (capped server-side at 365).\n */\n refund_window_days?: number;\n /**\n * Whether `amount_cents` is quoted gross or net.\n *\n * `\"inclusive\"` (the default when omitted) charges `amount_cents` and\n * backs the VAT out of it. `\"exclusive\"` reads it as a net figure and\n * charges the payer `amount_cents + tax`, so the response's\n * `amount_cents` comes back *larger* than the one you sent, because it\n * is always what was actually charged. Reconcile against `net_cents` /\n * `tax_cents` on the response.\n *\n * Omit to inherit the country default from your configured tax rate.\n */\n tax_behavior?: \"inclusive\" | \"exclusive\";\n metadata?: Record<string, string>;\n}\n\nexport interface CreateWebhookEndpointParams extends IdempotencyOptions {\n url: string;\n enabled_events?: string[];\n description?: string;\n}\n\nexport interface UpdateWebhookEndpointParams extends IdempotencyOptions {\n url?: string;\n enabled_events?: string[];\n description?: string;\n status?: string;\n}\n\nexport interface EventsListParams extends BaseListParams {\n /** Server-side filter, e.g. `customer.created`. */\n type?: string;\n /** Expandable here: `customer`. `events.retrieve` accepts none. */\n expand?: string[];\n}\n\nexport interface SetPortalBrandingParams extends IdempotencyOptions {\n business_name?: string;\n support_email?: string;\n logo_url?: string;\n theme?: Record<string, unknown>;\n capabilities?: Record<string, unknown>;\n}\n\nexport interface RotateProviderCredentialParams extends IdempotencyOptions {\n /** New raw provider API key. Encrypted server-side; never logged. */\n api_key: string;\n /** Defaults to the calling key's mode. */\n mode?: \"test\" | \"live\" | (string & {});\n /** Currently only `\"mollie\"`. */\n provider?: \"mollie\" | (string & {});\n}\n\nexport interface CreateCouponParams extends IdempotencyOptions {\n code: string;\n /**\n * `\"percent\"` reads `discount_value` as whole percent; `\"fixed_cents\"`\n * reads it as minor units off the charge. Those are the only two the\n * API accepts (`schemas/coupon.py`); anything else is a `422`.\n */\n discount_type: \"percent\" | \"fixed_cents\" | (string & {});\n discount_value: number;\n duration: \"once\" | \"repeating\" | \"forever\" | (string & {});\n duration_in_months?: number;\n max_redemptions?: number;\n redeem_by?: number;\n applies_to_price_ids?: string[];\n min_amount_cents?: number;\n}\n\nexport interface UpdateCouponParams extends IdempotencyOptions {\n active?: boolean;\n max_redemptions?: number;\n redeem_by?: number;\n applies_to_price_ids?: string[];\n min_amount_cents?: number;\n}\n\nexport interface ValidateCouponParams {\n code: string;\n /**\n * Scope the dry-run to one price. Optional: omit to validate the code\n * on its own (existence, active, not exhausted, not expired). Supply it\n * to also check the coupon's `applies_to_price_ids` restriction.\n */\n price_id?: string;\n /**\n * Base amount the discount is computed against, in minor units.\n * Optional: omit to skip the discount math and the `min_amount_cents`\n * check. `POST /v1/coupons/validate` treats both fields as nullable.\n */\n amount_cents?: number;\n}\n\nexport interface CreateTaxRateParams extends IdempotencyOptions {\n country_code: string;\n rate_basis_points: number;\n display_name?: string;\n inclusive?: boolean;\n}\n\nexport interface UpdateTaxRateParams extends IdempotencyOptions {\n rate_basis_points?: number;\n display_name?: string;\n inclusive?: boolean;\n active?: boolean;\n}\n\n/**\n * `auditLogs.list` params. All four filters match exactly and combine.\n *\n * `resource_type` narrows to a kind (`\"customer\"`, `\"price\"`);\n * `resource_id` narrows to one row, which is the \"everything that ever\n * happened to this customer\" question an audit log mostly exists for.\n * Pair them or use `resource_id` alone — ids are already unique.\n */\nexport interface AuditLogsListParams extends BaseListParams {\n action?: string;\n resource_type?: string;\n resource_id?: string;\n actor_id?: string;\n}\n\n/**\n * `creditNotes.list` params.\n *\n * `invoice_id` answers \"was this sale credited, and by how much\", which is\n * the question when reconciling one invoice; `customer_id` answers it for\n * everything credited back to one buyer.\n */\nexport interface CreditNotesListParams extends BaseListParams {\n invoice_id?: string;\n customer_id?: string;\n}\n\n/**\n * Body for `POST /v1/tenant/billing_profile`: the seller identity that\n * VAT is decided against and that an invoice prints.\n *\n * `country_code` is required on every call: there is nothing to leave\n * alone about a jurisdiction. The address fields and\n * `registration_number` are partial-update: omit one to leave the stored\n * value alone, or pass an explicit `null` to clear it, because moving\n * office is a real event.\n *\n * `vat_id` can be set once. After that, a different value or `null` is\n * refused with a 400 (`param: \"vat_id\"`, reason `vat_id_locked`) and the\n * call writes nothing; re-sending the stored number is accepted. BillKit\n * invoices you reverse-charged against it, so support changes it.\n */\nexport interface SetTenantBillingProfileParams extends IdempotencyOptions {\n /** ISO-3166-1 alpha-2, e.g. `\"NL\"`. */\n country_code: string;\n /** Your own EU VAT registration. Set once; support changes or clears it. */\n vat_id?: string | null;\n address_line1?: string | null;\n address_line2?: string | null;\n postal_code?: string | null;\n city?: string | null;\n registration_number?: string | null;\n}\n\n/**\n * Body for `POST /v1/api_keys`. The full key is returned **once**, on the\n * create response, and is never retrievable again.\n */\nexport interface CreateApiKeyParams extends IdempotencyOptions {\n /** Human label, so a key can be identified before it is revoked. */\n label?: string;\n /**\n * Narrow what the key may do. Omit to inherit the calling key's own\n * scopes; a key can never grant more than it holds.\n */\n scopes?: string[];\n}\n\n/** `invoices.void` params. `reason` is recorded on the audit row only. */\nexport interface VoidInvoiceParams extends IdempotencyOptions {\n reason?: string;\n}\n\nexport interface CreateBillingPortalSessionParams extends IdempotencyOptions {\n subscription_id: string;\n return_url: string;\n /**\n * Also email the portal link to the subscription's customer, at the\n * address on their record, as a tenant-branded message. Defaults to\n * `false`: without it you distribute the returned `url` yourself.\n */\n deliver_email?: boolean;\n}\n\n// ─── Internals ─────────────────────────────────────────────────────\n\n/**\n * Percent-encode a caller-supplied id before it becomes a path segment.\n *\n * Ids reach the SDK from the caller's own storage, and one carrying `/`,\n * `?` or `#` would otherwise rewrite the request: `#` truncates the path,\n * `?` turns the tail into a query string, and `/` walks to a different\n * route entirely. Encoding keeps the request on the route the method\n * names, so a bad id is a clean `404` rather than a call somewhere else.\n */\nfunction p(id: string): string {\n return encodeURIComponent(id);\n}\n\nfunction dropUndefined<T extends Record<string, unknown>>(obj: T): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) out[k] = v;\n }\n return out;\n}\n\n/**\n * Strips the `idempotencyKey` carrier from a mutating-call body and\n * returns `{ body, idempotencyKey }`. Pulled out so the per-resource\n * methods read as \"describe the verb\" instead of \"shuffle keys\".\n */\nfunction splitIdempotency<P extends IdempotencyOptions>(\n params: P,\n): { body: Record<string, unknown>; idempotencyKey: string | undefined } {\n const { idempotencyKey, ...rest } = params;\n return { body: dropUndefined(rest as Record<string, unknown>), idempotencyKey };\n}\n\n/**\n * Refuse a sub-minor-unit rate that arrived as a `number`.\n *\n * The type already forbids it, so this exists for the callers the type\n * system cannot reach: plain JavaScript, a value that came through `any`,\n * a body parsed from JSON. A double cannot hold 0.0002 exactly, so\n * accepting one would work for the rates that happen to round-trip and\n * silently mis-price the ones that do not — the worst of the three\n * available behaviours, and the reason the field is a string in the first\n * place.\n */\nfunction assertDecimalRateIsString(value: unknown, field: string): void {\n if (value === undefined || value === null || typeof value === \"string\") return;\n throw new TypeError(\n `${field} must be a string, not a ${typeof value}. A JavaScript number cannot ` +\n \"hold a rate like 0.0002 exactly, so it would be corrupted before it was ever \" +\n `multiplied by a quantity. Pass it as a string: \"${String(value)}\".`,\n );\n}\n\n/** Same check at the price level and inside every band of a tier table. */\nfunction assertPriceRatesAreStrings(params: CreatePriceParams): CreatePriceParams {\n assertDecimalRateIsString(params.unit_amount_decimal, \"unit_amount_decimal\");\n // Inside a tier is where a rate is most likely to be typed as a bare\n // literal, so the guard has to reach in there too.\n (params.tiers ?? []).forEach((tier, index) => {\n assertDecimalRateIsString(\n (tier as PriceTier | undefined)?.unit_amount_decimal,\n `tiers[${index}].unit_amount_decimal`,\n );\n });\n return params;\n}\n\n/**\n * Shared transport wrapper. Resources subclass this so each method\n * reads as a single line, \"verb to path with params\", instead of\n * the four-line `this.t.request({ ... })` boilerplate the previous\n * draft repeated everywhere.\n */\nabstract class BaseResource {\n constructor(protected readonly t: Transport) {}\n\n /**\n * `query` is a plain object rather than an index-signature type: TypeScript\n * only gives an implicit index signature to type *aliases*, so a closed\n * `*ListParams` interface would otherwise need a cast at every call site.\n * The transport prunes `undefined`/`null` and joins arrays with commas.\n */\n protected get<T>(path: string, query?: object): Promise<T> {\n return this.t.request<T>({ method: \"GET\", path, query });\n }\n\n protected post<T, P extends IdempotencyOptions>(path: string, params: P): Promise<T> {\n const { body, idempotencyKey } = splitIdempotency(params);\n return this.t.request<T>({ method: \"POST\", path, body, idempotencyKey });\n }\n\n /** POST with no body, used by lifecycle verbs (cancel, resume, revoke ...). */\n protected postEmpty<T>(path: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.t.request<T>({\n method: \"POST\",\n path,\n idempotencyKey: params.idempotencyKey,\n });\n }\n\n /** POST with a fixed body and no idempotency stripping (used by\n * endpoints whose body is fully specified by the caller's args\n * and not optional, e.g. `preview_update`). */\n protected postFixed<T>(\n path: string,\n body: Record<string, unknown>,\n params: IdempotencyOptions = {},\n ): Promise<T> {\n return this.t.request<T>({\n method: \"POST\",\n path,\n body,\n idempotencyKey: params.idempotencyKey,\n });\n }\n\n protected del<T>(path: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.t.request<T>({\n method: \"DELETE\",\n path,\n idempotencyKey: params.idempotencyKey,\n });\n }\n}\n\n// ─── Resources ─────────────────────────────────────────────────────\n\nexport class Customers extends BaseResource {\n /** Create a tenant-scoped buyer record. */\n create<T = unknown>(params: CreateCustomerParams = {}): Promise<T> {\n return this.post<T, CreateCustomerParams>(\"/v1/customers\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/customers/${p(id)}`);\n }\n\n update<T = unknown>(id: string, params: UpdateCustomerParams = {}): Promise<T> {\n return this.post<T, UpdateCustomerParams>(`/v1/customers/${p(id)}`, params);\n }\n\n /**\n * Delete a customer. Resolves to `{ id, object: \"customer\", deleted:\n * true }`, not the customer.\n *\n * The customer leaves the API: `retrieve()` 404s and they drop out of\n * `list()`. Their payments, invoices and refunds are untouched, and so\n * is their personal data — use {@link Customers.purge} for a GDPR\n * erasure. Refused while they hold a subscription that can still\n * charge them.\n */\n delete<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.del<T>(`/v1/customers/${p(id)}`, params);\n }\n\n /**\n * List customers, newest first.\n *\n * `provisional` filters on whether the customer ever completed a\n * payment. A checkout that captures an email commits its Customer\n * before the charge, so a checkout nobody finished leaves a row behind:\n * pass `false` for real customers only, `true` for the abandoned ones\n * (the cart-recovery worklist), or omit for both. Abandoned rows are\n * swept after the tenant's retention window.\n */\n list<T = unknown>(params: CustomerListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/customers\", params);\n }\n\n /** Walk every page of `list()` and yield each customer. */\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/customers\", page), { pageSize: options.pageSize });\n }\n\n /**\n * Attach or replace the customer's VAT number; triggers server-side\n * VIES validation. The response carries `vat_number_validated`\n * reflecting whether VIES confirmed the number.\n */\n setVatNumber<T = unknown>(id: string, params: SetCustomerVatNumberParams): Promise<T> {\n return this.post<T, SetCustomerVatNumberParams>(`/v1/customers/${p(id)}/vat_number`, params);\n }\n\n /**\n * Hard-purge a customer's PII for GDPR erasure. Distinct from\n * `delete()` (soft delete): purge nulls email/name/country/VAT/\n * metadata, sets `purged_at`, and is irreversible.\n *\n * The server requires `confirmed: true` as a fat-finger guard; the\n * SDK defaults it to `true` so callers don't have to opt in twice.\n */\n purge<T = unknown>(id: string, params: PurgeCustomerParams = {}): Promise<T> {\n const { confirmed = true, idempotencyKey } = params;\n return this.postFixed<T>(`/v1/customers/${p(id)}/purge`, { confirmed }, { idempotencyKey });\n }\n}\n\nexport class Products extends BaseResource {\n /** Create a catalog Product, then attach one or more Prices to it. */\n create<T = unknown>(params: CreateProductParams): Promise<T> {\n return this.post<T, CreateProductParams>(\"/v1/products\", params);\n }\n\n /**\n * Expandable: `prices` (every price on the product), `stats`, and\n * `default_price` (the price `default_price_id` names).\n */\n retrieve<T = unknown>(id: string, options: ExpandOptions = {}): Promise<T> {\n return this.get<T>(`/v1/products/${p(id)}`, options);\n }\n\n /**\n * Patch mutable Product fields, or archive it with `active: false`.\n *\n * Archiving is how you stop offering something. The product keeps its\n * id and still comes back from `retrieve()` and `list()`, because what\n * was sold under it has to stay readable, so there is no `delete()`.\n * A checkout against any of its prices is refused from then on, and\n * `active: true` un-archives.\n */\n update<T = unknown>(id: string, params: UpdateProductParams): Promise<T> {\n return this.post<T, UpdateProductParams>(`/v1/products/${p(id)}`, params);\n }\n\n list<T = unknown>(params: ProductsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/products\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/products\", page), { pageSize: options.pageSize });\n }\n}\n\nexport class Prices extends BaseResource {\n /**\n * Create immutable billing terms for an existing Product.\n *\n * A licensed price sends `amount_cents`. A metered price sends one of\n * `amount_cents`, `unit_amount_decimal` (a rate finer than one minor\n * unit, as a string) or `billing_scheme: \"tiered\"` with `tiers` and\n * `tiers_mode`. Throws `TypeError` before any HTTP call if a decimal\n * rate arrives as a number — see\n * {@link CreatePriceParams.unit_amount_decimal}.\n */\n // `async` on purpose. The rate guard throws, and a synchronous throw out\n // of a method typed `Promise<T>` escapes `.catch()` entirely — the caller\n // would have to wrap the call site in try/catch as well, which nobody\n // does for a promise-returning API. Marking it async turns the throw into\n // a rejection, so one error path handles both.\n async create<T = unknown>(params: CreatePriceParams): Promise<T> {\n return this.post<T, CreatePriceParams>(\"/v1/prices\", assertPriceRatesAreStrings(params));\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/prices/${p(id)}`);\n }\n\n /**\n * Archive a Price so it stops selling, or put it back on sale.\n *\n * `update(id, { active: false })` archives. The price keeps its id and\n * is still returned by `retrieve()` and by `list()`, because\n * subscriptions renew against it by id and what they are charged has to\n * stay readable. Subscriptions already on it keep renewing at it. What\n * stops is new business: a checkout session against the price is\n * refused and it is no longer offered as a plan change.\n *\n * `{ active: true }` undoes that. `active` is the only field because\n * `amount_cents`, `currency` and `interval` are fixed at creation, and\n * since none of them move here neither direction can change what a past\n * charge was made under. To charge something different, create a new\n * price.\n *\n * Sending the value a price already has returns it unchanged and emits\n * no second event, so a retry is safe. Archiving emits\n * `price.archived`; putting one back emits `price.updated`.\n */\n update<T = unknown>(id: string, params: UpdatePriceParams): Promise<T> {\n return this.post<T, UpdatePriceParams>(`/v1/prices/${p(id)}`, params);\n }\n\n list<T = unknown>(params: PricesListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/prices\", params);\n }\n\n iter<T = unknown>(\n options: { pageSize?: number; product_id?: string } = {},\n ): AsyncIterableIterator<T> {\n const filter = options.product_id === undefined ? {} : { product_id: options.product_id };\n return paginate<T>((page) => this.get(\"/v1/prices\", { ...filter, ...page }), {\n pageSize: options.pageSize,\n });\n }\n}\n\nexport class CheckoutSessions extends BaseResource {\n create<T = unknown>(params: CreateCheckoutSessionParams): Promise<T> {\n return this.post<T, CreateCheckoutSessionParams>(\"/v1/checkout/sessions\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/checkout/sessions/${p(id)}`);\n }\n}\n\n/**\n * Mandate-less one-shot payments (`/v1/checkout/one_shot`).\n *\n * A one-shot is the Stripe PaymentIntent shape mapped onto Mollie: a\n * single `sequenceType=oneoff` charge that provisions nothing: no\n * subscription, no mandate, no renewals. Drive terminal state via the\n * `one_shot_payment.succeeded` / `.failed` webhook events; refund one\n * with `client.refunds.create({ one_shot_payment_id })`.\n */\nexport class OneShotPayments extends BaseResource {\n /** Create a one-off charge; returns the object with a `redirect_url`. */\n create<T = unknown>(params: CreateOneShotPaymentParams): Promise<T> {\n return this.post<T, CreateOneShotPaymentParams>(\"/v1/checkout/one_shot\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/checkout/one_shot/${p(id)}`);\n }\n}\n\nexport class Subscriptions extends BaseResource {\n /** Expandable: `customer`, `price`, `refund_eligibility`. */\n retrieve<T = unknown>(id: string, options: ExpandOptions = {}): Promise<T> {\n return this.get<T>(`/v1/subscriptions/${p(id)}`, options);\n }\n\n /**\n * List subscriptions, newest first, optionally filtered.\n *\n * Reach for `renewal_state: \"paused\"` rather than `status: \"paused\"`\n * to find paused subscriptions; see `SubscriptionsListParams`.\n */\n list<T = unknown>(params: SubscriptionsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/subscriptions\", params);\n }\n\n /**\n * Walk every page of `list()`. Filters are carried onto each page\n * request, so a filtered walk narrows server-side instead of paging\n * the whole history and discarding rows client-side.\n */\n iter<T = unknown>(\n options: {\n pageSize?: number;\n customer_id?: string;\n status?: string;\n renewal_state?: string;\n } = {},\n ): AsyncIterableIterator<T> {\n // `undefined` query values are pruned by the transport, so the\n // filter can be spread as-is without a conditional per key.\n const { pageSize, ...filter } = options;\n return paginate<T>((page) => this.get(\"/v1/subscriptions\", { ...filter, ...page }), { pageSize });\n }\n\n cancel<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/subscriptions/${p(id)}/cancel`, params);\n }\n\n pause<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/subscriptions/${p(id)}/pause`, params);\n }\n\n resume<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/subscriptions/${p(id)}/resume`, params);\n }\n\n /**\n * Reactivate a canceled-but-still-in-period subscription.\n *\n * Distinct from `resume()` (paused → active): `reactivate()` flips\n * `canceled` back to `active` for the remainder of the current\n * period, so the customer keeps service without a new checkout.\n * Returns `409` if the period has already elapsed.\n */\n reactivate<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/subscriptions/${p(id)}/reactivate`, params);\n }\n\n previewUpdate<T = unknown>(id: string, params: { target_price_id: string }): Promise<T> {\n return this.postFixed<T>(`/v1/subscriptions/${p(id)}/preview_update`, {\n target_price_id: params.target_price_id,\n });\n }\n\n update<T = unknown>(\n id: string,\n params: { target_price_id: string } & IdempotencyOptions,\n ): Promise<T> {\n return this.postFixed<T>(\n `/v1/subscriptions/${p(id)}/update`,\n { target_price_id: params.target_price_id },\n { idempotencyKey: params.idempotencyKey },\n );\n }\n\n reauthorizePaymentMethod<T = unknown>(\n id: string,\n params: { return_url: string } & IdempotencyOptions,\n ): Promise<T> {\n return this.postFixed<T>(\n `/v1/subscriptions/${p(id)}/reauthorize_payment_method`,\n { return_url: params.return_url },\n { idempotencyKey: params.idempotencyKey },\n );\n }\n\n /**\n * Report consumption against a metered subscription.\n *\n * Only valid when the subscription's price is `usage_type:\n * \"metered\"`; a licensed subscription is rejected with `400\n * parameter_invalid`. Records accumulate until the next period close\n * rolls them into one invoice line; the record's `invoice_id` stays\n * `null` until then. Records are immutable once written — they are the\n * audit trail behind that line — so there is no update or delete.\n *\n * Two dedupe mechanisms, covering different failures. The\n * `Idempotency-Key` the SDK sends covers a retry of this HTTP request,\n * including its own internal retries. `params.identifier` covers a\n * retry of *your* call, which arrives as a new request with a new key.\n * See {@link CreateUsageRecordParams.identifier}.\n */\n createUsageRecord<T = unknown>(id: string, params: CreateUsageRecordParams): Promise<T> {\n return this.post<T, CreateUsageRecordParams>(`/v1/subscriptions/${p(id)}/usage_records`, params);\n }\n\n /**\n * List usage records for one subscription.\n *\n * Pass `invoice_id: \"pending\"` to reconcile what has been reported\n * but not yet billed, or a concrete invoice id to see what that\n * invoice charged for.\n */\n listUsageRecords<T = unknown>(\n id: string,\n params: UsageRecordsListParams = {},\n ): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(`/v1/subscriptions/${p(id)}/usage_records`, params);\n }\n\n /** Walk every page of `listUsageRecords()` for one subscription. */\n iterUsageRecords<T = unknown>(\n id: string,\n options: { pageSize?: number; invoice_id?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(`/v1/subscriptions/${p(id)}/usage_records`, page), {\n pageSize: options.pageSize,\n filters: { invoice_id: options.invoice_id },\n });\n }\n\n /**\n * Price the pending usage, before the period close bills it.\n *\n * `listUsageRecords({ invoice_id: \"pending\" })` gives the quantity; this\n * gives the money. `net_cents` / `tax_cents` / `gross_cents` are\n * computed through the same rate or tier table and the same VAT\n * resolution the close itself uses, so it is a forecast of the real\n * invoice rather than an estimate.\n *\n * **Read `will_charge` before promising a customer an amount.** A period\n * whose total is under `minimum_charge_cents` (EUR 1.00) is not charged,\n * because the payment provider would refuse it. The usage is not lost:\n * it stays pending and rolls into the next period, which is then billed\n * for both.\n *\n * `open_invoice_id` names an earlier cycle that is invoiced and still\n * unsettled; while one is open, this period cannot be charged.\n */\n retrieveUsageSummary<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/subscriptions/${p(id)}/usage_summary`);\n }\n}\n\nexport class Refunds extends BaseResource {\n create<T = unknown>(params: CreateRefundParams): Promise<T> {\n return this.post<T, CreateRefundParams>(\"/v1/refunds\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/refunds/${p(id)}`);\n }\n\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/refunds\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/refunds\", page), { pageSize: options.pageSize });\n }\n}\n\n/**\n * Chargebacks / disputes (`/v1/disputes`).\n *\n * Read-only. Disputes are provider-originated (opened by the cardholder's\n * bank) and surfaced via the `dispute.created` / `dispute.closed` webhook\n * events. There is no create/update. A dispute's `status` is `open` or `won`\n * (chargeback reversed); Mollie exposes no \"lost\" signal, so an upheld\n * chargeback stays `open` (treat any non-`won` dispute as unresolved).\n */\nexport class Disputes extends BaseResource {\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/disputes/${p(id)}`);\n }\n\n list<T = unknown>(params: DisputesListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/disputes\", params);\n }\n\n iter<T = unknown>(\n options: { pageSize?: number; status?: string; payment_id?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/disputes\", page), {\n pageSize: options.pageSize,\n filters: { status: options.status, payment_id: options.payment_id },\n });\n }\n}\n\nexport class WebhookEndpoints extends BaseResource {\n /**\n * Every event type this deployment can deliver, plus the wildcard.\n *\n * `enabled_events` rejects anything not on this list, so read it rather\n * than hard-coding a set: a name that is not on it fails at\n * registration and leaves you with an endpoint that never fires.\n */\n listEventTypes<T = unknown>(): Promise<T> {\n return this.get<T>(\"/v1/webhook_endpoints/event_types\");\n }\n\n create<T = unknown>(params: CreateWebhookEndpointParams): Promise<T> {\n return this.post<T, CreateWebhookEndpointParams>(\"/v1/webhook_endpoints\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/webhook_endpoints/${p(id)}`);\n }\n\n /**\n * Update an endpoint, or stop delivery with `status: \"disabled\"`.\n *\n * Disabling keeps the endpoint, its signing secret and its delivery\n * history, and `status: \"enabled\"` resumes. Use {@link\n * WebhookEndpoints.delete} when the endpoint should not exist at all:\n * disabling is reversible and deleting is not.\n */\n update<T = unknown>(id: string, params: UpdateWebhookEndpointParams): Promise<T> {\n return this.post<T, UpdateWebhookEndpointParams>(`/v1/webhook_endpoints/${p(id)}`, params);\n }\n\n /**\n * Delete an endpoint. Resolves to `{ id, object: \"webhook_endpoint\",\n * deleted: true }`, not the endpoint.\n *\n * A URL registered by mistake should not be a permanent fixture of the\n * account, so this removes it: `retrieve()` 404s afterwards and it is\n * gone from `list()`. Its delivery attempts go with it, because they\n * are readable only through the endpoint that owns them. The events\n * themselves are untouched and still in `client.events`, so what you\n * were sent stays on record.\n */\n delete<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.del<T>(`/v1/webhook_endpoints/${p(id)}`, params);\n }\n\n /** Rotate the signing secret. The new `bkwhsec_...` is returned once. */\n rotateSecret<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/webhook_endpoints/${p(id)}/rotate_secret`, params);\n }\n\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/webhook_endpoints\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/webhook_endpoints\", page), {\n pageSize: options.pageSize,\n });\n }\n\n /**\n * List per-attempt delivery records for one endpoint.\n *\n * Useful when a tenant's receiver is failing. Surfaces the status\n * code, response body excerpt, error, and next-attempt timestamp\n * for each event × endpoint pair.\n */\n listDeliveries<T = unknown>(\n endpointId: string,\n params: BaseListParams = {},\n ): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\n `/v1/webhook_endpoints/${p(endpointId)}/deliveries`,\n params,\n );\n }\n\n /** Walk every page of `listDeliveries()` for one endpoint. */\n iterDeliveries<T = unknown>(\n endpointId: string,\n options: { pageSize?: number } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>(\n (page) => this.get(`/v1/webhook_endpoints/${p(endpointId)}/deliveries`, page),\n { pageSize: options.pageSize },\n );\n }\n\n /** Fetch one delivery row for inspection before deciding to redeliver. */\n retrieveDelivery<T = unknown>(endpointId: string, deliveryId: string): Promise<T> {\n return this.get<T>(`/v1/webhook_endpoints/${p(endpointId)}/deliveries/${p(deliveryId)}`);\n }\n\n /**\n * @deprecated Renamed to {@link WebhookEndpoints.retrieveDelivery}.\n *\n * Every other single-row fetch in every BillKit SDK is `retrieve`; this\n * one method was `get`, which meant reaching for the obvious name and\n * getting a type error. The python and php clients already spell it\n * `retrieve_delivery` / `retrieveDelivery`, so node was the outlier.\n *\n * Kept as an alias because removing it would break callers for a naming\n * preference. It will go in the next major.\n */\n getDelivery<T = unknown>(endpointId: string, deliveryId: string): Promise<T> {\n return this.retrieveDelivery<T>(endpointId, deliveryId);\n }\n\n /**\n * Re-enqueue a delivery row for the dispatcher.\n *\n * Idempotent: a row already in `delivered` returns unchanged. A\n * `pending` / `failed` row flips to `pending` with\n * `next_attempt_at = now()`; `attempt_count` is preserved.\n */\n redeliver<T = unknown>(\n endpointId: string,\n deliveryId: string,\n params: IdempotencyOptions = {},\n ): Promise<T> {\n return this.postEmpty<T>(\n `/v1/webhook_endpoints/${p(endpointId)}/deliveries/${p(deliveryId)}/redeliver`,\n params,\n );\n }\n}\n\nexport class Events extends BaseResource {\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/events/${p(id)}`);\n }\n\n list<T = unknown>(params: EventsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/events\", params);\n }\n\n /** Walk every page of `list()`. Pass `type` to filter at the server. */\n iter<T = unknown>(\n options: { pageSize?: number; type?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/events\", page), {\n pageSize: options.pageSize,\n filters: { type: options.type },\n });\n }\n}\n\n/**\n * Read + mutate tenant-level configuration.\n *\n * Exposes the Mollie capability cache, the portal-branding row, and\n * the encrypted Mollie API key. None of these are per-resource;\n * they're tenant-wide knobs.\n */\nexport class Tenant extends BaseResource {\n /** Cached Mollie profile shape (enabled methods, country, currency). */\n capabilities<T = unknown>(): Promise<T> {\n return this.get<T>(\"/v1/tenant/capabilities\");\n }\n\n /**\n * Your registered country and VAT number: what your customers' VAT is\n * decided against.\n *\n * `country_code` is what you have stored and can be `null`;\n * `effective_country_code` is what the next charge will really use.\n * The two differ only when you have stored nothing, which is exactly\n * the case worth spotting before a first live payment.\n */\n billingProfile<T = unknown>(): Promise<T> {\n return this.get<T>(\"/v1/tenant/billing_profile\");\n }\n\n /**\n * Set the seller identity. `country_code` is required on every call;\n * every other field is partial-update, with an explicit `null` to\n * clear. Changes take effect on the next charge only. Tax is written\n * onto a payment and its invoice before money moves, and nothing goes\n * back and recalculates it.\n */\n setBillingProfile<T = unknown>(params: SetTenantBillingProfileParams): Promise<T> {\n return this.post<T, SetTenantBillingProfileParams>(\"/v1/tenant/billing_profile\", params);\n }\n\n /**\n * Download everything in the account as one JSON document, as raw bytes.\n *\n * ```ts\n * await writeFile(\"export.json\", Buffer.from(await client.tenant.export()));\n * ```\n *\n * The GDPR Article 20 portability route, and the way to take a backup.\n * It is `application/json` streamed inline, with no redirect, and each\n * record has the same shape its `GET` route returns, with\n * `billkit_export_version` naming the shape. It can be large, so write\n * it to a file rather than holding it in memory. Test and live data\n * export separately: you get whichever mode the key belongs to. The\n * access is recorded in your audit log.\n */\n export(): Promise<ArrayBuffer> {\n return this.t.requestBinary({ method: \"GET\", path: \"/v1/tenant/export\" });\n }\n\n /** Current portal branding row (business name, theme, capability flags). */\n portalBranding<T = unknown>(): Promise<T> {\n return this.get<T>(\"/v1/tenant/portal_branding\");\n }\n\n /**\n * Partial-update the portal branding row.\n *\n * Only fields you set are sent. Pass `undefined` to leave a field\n * untouched; sending an empty string explicitly clears it.\n */\n setPortalBranding<T = unknown>(params: SetPortalBrandingParams = {}): Promise<T> {\n return this.post<T, SetPortalBrandingParams>(\"/v1/tenant/portal_branding\", params);\n }\n\n /**\n * Rotate the encrypted provider credential for this tenant.\n *\n * The new `api_key` is encrypted server-side; nothing is logged.\n * `mode` defaults to the calling key's mode; prefix-mismatch\n * (`test_...` under live, `live_...` under test) is rejected at the\n * API boundary.\n */\n rotateProviderCredential<T = unknown>(params: RotateProviderCredentialParams): Promise<T> {\n return this.post<T, RotateProviderCredentialParams>(\n \"/v1/tenant/provider_credential\",\n params,\n );\n }\n}\n\nexport class Coupons extends BaseResource {\n create<T = unknown>(params: CreateCouponParams): Promise<T> {\n return this.post<T, CreateCouponParams>(\"/v1/coupons\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/coupons/${p(id)}`);\n }\n\n /**\n * Update a coupon's limits, or withdraw it with `active: false`.\n *\n * A withdrawn code is refused at checkout while the coupon stays\n * readable and discounts already applied keep working out, so there is\n * no `delete()`: a coupon that has been redeemed is part of what a\n * customer was charged. `active: true` brings the campaign back.\n */\n update<T = unknown>(id: string, params: UpdateCouponParams): Promise<T> {\n return this.post<T, UpdateCouponParams>(`/v1/coupons/${p(id)}`, params);\n }\n\n /**\n * Server-side dry-run of a coupon redemption.\n *\n * Returns the discount math without atomically claiming the coupon,\n * which is useful for \"preview before checkout\" UX.\n */\n validate<T = unknown>(params: ValidateCouponParams): Promise<T> {\n // Omit the optional fields rather than sending explicit nulls, so the\n // request body matches what a caller who only has a code would hand\n // written by hand, and so `extra=\"forbid\"` schemas stay happy.\n const body: Record<string, unknown> = { code: params.code };\n if (params.price_id !== undefined) body[\"price_id\"] = params.price_id;\n if (params.amount_cents !== undefined) body[\"amount_cents\"] = params.amount_cents;\n return this.postFixed<T>(\"/v1/coupons/validate\", body);\n }\n\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/coupons\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/coupons\", page), { pageSize: options.pageSize });\n }\n}\n\nexport class TaxRates extends BaseResource {\n create<T = unknown>(params: CreateTaxRateParams): Promise<T> {\n return this.post<T, CreateTaxRateParams>(\"/v1/tax_rates\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/tax_rates/${p(id)}`);\n }\n\n /**\n * Correct a rate, retire it with `active: false`, or bring one back.\n *\n * Retiring is how you stop charging VAT in a country. The rate stays\n * readable, because an invoice records the percentage it charged and\n * you have to be able to point at the rate that produced it, so there\n * is no `delete()`.\n */\n update<T = unknown>(id: string, params: UpdateTaxRateParams): Promise<T> {\n return this.post<T, UpdateTaxRateParams>(`/v1/tax_rates/${p(id)}`, params);\n }\n\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/tax_rates\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/tax_rates\", page), { pageSize: options.pageSize });\n }\n}\n\n/**\n * Read-only access to generated invoices.\n *\n * Invoices are produced by the billing pipeline; tenants don't create\n * them directly. Fetch the rendered document with\n * {@link Invoices.retrievePdf}.\n */\nexport class Invoices extends BaseResource {\n /** Expandable: `customer`. */\n retrieve<T = unknown>(id: string, options: ExpandOptions = {}): Promise<T> {\n return this.get<T>(`/v1/invoices/${p(id)}`, options);\n }\n\n /**\n * Download the rendered invoice PDF as raw bytes.\n *\n * ```ts\n * const pdf = await client.invoices.retrievePdf(\"inv_123\");\n * await writeFile(\"invoice.pdf\", Buffer.from(pdf));\n * ```\n *\n * Blob-backed deployments stream the bytes inline; S3-backed ones\n * answer `302` to a presigned URL, which `fetch` follows for us under\n * the SDK's own timeout and retry policy — so both storage adapters\n * look identical from here.\n *\n * Deployments with `INVOICE_PDF_ENABLED=false` never render one and\n * answer `501 rendering_pending`, which surfaces as a `ServerError`\n * whose `code` is `\"rendering_pending\"`; `retrieve()` still returns the\n * structured invoice for tenants who render their own.\n */\n retrievePdf(id: string): Promise<ArrayBuffer> {\n return this.t.requestBinary({ method: \"GET\", path: `/v1/invoices/${p(id)}/pdf` });\n }\n\n /**\n * Send the customer their invoice again.\n *\n * The same tenant-branded \"your invoice is ready\" email, with a fresh\n * portal link, because the one in the original may have expired. It\n * goes to the address captured **on the invoice**, not the customer's\n * current one: this is a copy of a document that was issued to\n * somebody. An invoice with no address on file is a\n * `InvalidRequestError` rather than a send that did not happen.\n */\n sendEmail<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/invoices/${p(id)}/email`, params);\n }\n\n list<T = unknown>(params: InvoicesListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/invoices\", params);\n }\n\n iter<T = unknown>(\n options: {\n pageSize?: number;\n customer_id?: string;\n subscription_id?: string;\n payment_id?: string;\n status?: string;\n } = {},\n ): AsyncIterableIterator<T> {\n const { pageSize, ...filters } = options;\n return paginate<T>((page) => this.get(\"/v1/invoices\", page), { pageSize, filters });\n }\n\n /**\n * Void an invoice: state that the sale was never owed.\n *\n * The invoice keeps its number and stays readable — a gapless series\n * cannot lose a row — and stops being a receivable. Use it for an\n * invoice that should not have been issued.\n *\n * A **paid** invoice is refused with a `ConflictError` whose `code` is\n * `\"invoice_not_voidable\"`. That is deliberate rather than a\n * limitation: once the money has moved, \"never owed\" is false, and the\n * document that reverses a real sale is a credit note — refund the\n * payment and one is issued when the refund settles.\n *\n * Idempotent: re-voiding an already-void invoice returns it unchanged.\n */\n void<T = unknown>(id: string, params: VoidInvoiceParams = {}): Promise<T> {\n return this.post<T, VoidInvoiceParams>(`/v1/invoices/${p(id)}/void`, params);\n }\n}\n\n/**\n * Read-only access to credit notes — the documents that reverse an\n * issued invoice.\n *\n * There is no create: a credit note is issued for you when a refund\n * settles, never on request, so that a numbered legal record is only\n * minted once the money has actually moved. A refund that is still\n * pending, one that fails, and a refund of a one-off charge that was\n * never invoiced all produce none.\n */\nexport class CreditNotes extends BaseResource {\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/credit_notes/${p(id)}`);\n }\n\n /**\n * Download the rendered credit note PDF as raw bytes. Same storage\n * split as {@link Invoices.retrievePdf}: bytes inline or a followed\n * `302`, and `501 rendering_pending` on a deployment with no renderer.\n */\n retrievePdf(id: string): Promise<ArrayBuffer> {\n return this.t.requestBinary({ method: \"GET\", path: `/v1/credit_notes/${p(id)}/pdf` });\n }\n\n list<T = unknown>(params: CreditNotesListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/credit_notes\", params);\n }\n\n iter<T = unknown>(\n options: { pageSize?: number; invoice_id?: string; customer_id?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/credit_notes\", page), {\n pageSize: options.pageSize,\n filters: { invoice_id: options.invoice_id, customer_id: options.customer_id },\n });\n }\n}\n\n/**\n * Read-only access to the per-tenant audit log.\n *\n * Supports server-side filters: `action`, `resource_type`, `actor_id`.\n * The filters are forwarded through to `iter()` so an audit walk can\n * scope to a single actor or action without client-side filtering.\n */\nexport class AuditLogs extends BaseResource {\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/audit_logs/${p(id)}`);\n }\n\n list<T = unknown>(params: AuditLogsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/audit_logs\", params);\n }\n\n iter<T = unknown>(\n options: {\n pageSize?: number;\n action?: string;\n resource_type?: string;\n resource_id?: string;\n actor_id?: string;\n } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/audit_logs\", page), {\n pageSize: options.pageSize,\n filters: {\n action: options.action,\n resource_type: options.resource_type,\n resource_id: options.resource_id,\n actor_id: options.actor_id,\n },\n });\n }\n}\n\n/**\n * Read-only access to the payment ledger.\n *\n * Payments are written by the billing pipeline (checkout, renewal,\n * reauthorize). Inspect attempts and their Mollie-side metadata here;\n * refunds and disputes are separate flows.\n */\nexport class Payments extends BaseResource {\n /** Expandable: `customer`, `subscription`. */\n retrieve<T = unknown>(id: string, options: ExpandOptions = {}): Promise<T> {\n return this.get<T>(`/v1/payments/${p(id)}`, options);\n }\n\n /**\n * Fetch the provider's own record of this charge, live.\n *\n * Reads Mollie at request time rather than a stored copy, so it carries\n * what BillKit deliberately does not keep: the card BIN, the iDEAL\n * bank, the provider's own status string. Reading live means it can\n * fail: a provider outage or a charge old enough to have aged out\n * answers `200` with `available: false` and a short reason, so render\n * the rest of the page regardless.\n */\n retrieveProvider<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/payments/${p(id)}/provider`);\n }\n\n list<T = unknown>(params: PaymentsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/payments\", params);\n }\n\n iter<T = unknown>(\n options: { pageSize?: number; customer_id?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/payments\", page), {\n pageSize: options.pageSize,\n filters: { customer_id: options.customer_id },\n });\n }\n}\n\n/**\n * Mint and revoke customer-facing billing-portal sessions.\n *\n * Each session token is scoped to a single subscription with a\n * sliding 30-minute idle window and a 2-hour hard cap. The raw token\n * is returned **once** on mint; the response also includes the URL\n * the tenant embeds in their app.\n */\nexport class BillingPortalSessions extends BaseResource {\n create<T = unknown>(params: CreateBillingPortalSessionParams): Promise<T> {\n return this.post<T, CreateBillingPortalSessionParams>(\"/v1/billing_portal/sessions\", params);\n }\n\n /** Kill an in-the-wild portal session. Idempotent. */\n revoke<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/billing_portal/sessions/${p(id)}/revoke`, params);\n }\n}\n\n/**\n * Issue, inspect and revoke API keys.\n *\n * A key is issued in the same mode as the key that created it, so a test\n * key can only mint test keys, and it can never grant scopes it does not\n * hold itself. The secret is returned **once**, on\n * {@link ApiKeys.create}; every later read carries only the prefix.\n */\nexport class ApiKeys extends BaseResource {\n /**\n * Issue a new key. The response's `secret` is the only time the full\n * key exists outside the caller's own storage, so record it now.\n */\n create<T = unknown>(params: CreateApiKeyParams = {}): Promise<T> {\n return this.post<T, CreateApiKeyParams>(\"/v1/api_keys\", params);\n }\n\n /**\n * One key's metadata: prefix, label, scopes, `revoked_at`, and\n * `last_used_at`, which is the field to read before revoking one.\n */\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/api_keys/${p(id)}`);\n }\n\n /**\n * Revoke a key so it stops working. Immediate and irreversible; issue a\n * new key instead. Revoking an already-revoked key returns it\n * unchanged, so a retry is safe, and a key may revoke itself, which is\n * what you want when the leaked key is the one you are calling with.\n */\n revoke<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/api_keys/${p(id)}/revoke`, params);\n }\n\n /** List keys, newest first. Revoked ones are included; check `revoked_at`. */\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/api_keys\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/api_keys\", page), { pageSize: options.pageSize });\n }\n}\n","/**\n * Typed exception hierarchy mirroring the BillKit API error envelope.\n *\n * The API returns errors in the Stripe-shape:\n *\n * { \"error\": { \"type\": \"...\", \"code\": \"...\", \"message\": \"...\", \"param\": \"...\" } }\n *\n * The HTTP **status** picks the class so callers can `catch` on the\n * subclass they care about rather than branching on status codes; the\n * envelope's `type`/`code`/`param` ride along on the thrown object.\n * See {@link classForStatus} for why the status, not `type`, is the\n * authority.\n */\n\nexport interface ErrorEnvelope {\n type?: string;\n code?: string;\n message?: string;\n param?: string;\n}\n\nexport interface BillKitErrorOptions {\n type?: string | undefined;\n code?: string | undefined;\n param?: string | undefined;\n statusCode?: number | undefined;\n requestId?: string | undefined;\n rawBody?: unknown;\n /**\n * The underlying error, forwarded to `Error`'s own `cause`. Set on\n * `APIConnectionError` so the runtime's reason for a failed fetch\n * (`ECONNREFUSED`, a TLS failure, an abort) survives the mapping.\n */\n cause?: unknown;\n}\n\n// TS treats `name = \"Foo\"` as a literal-type property, which then conflicts\n// when subclasses override it. We widen to `string` everywhere so the\n// hierarchy can re-set ``name`` cleanly.\nexport class BillKitError extends Error {\n override name: string = \"BillKitError\";\n readonly type: string | undefined;\n readonly code: string | undefined;\n readonly param: string | undefined;\n readonly statusCode: number | undefined;\n readonly requestId: string | undefined;\n readonly rawBody: unknown;\n\n constructor(message: string, options: BillKitErrorOptions = {}) {\n // Only pass the options bag when there is a cause: `{ cause: undefined }`\n // still installs an own `cause` property, which would show up on every\n // error that never had one.\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.type = options.type;\n this.code = options.code;\n this.param = options.param;\n this.statusCode = options.statusCode;\n this.requestId = options.requestId;\n this.rawBody = options.rawBody;\n // Restore the prototype chain, required when targeting ES5 transpilers\n // (some bundlers still emit them) so `instanceof BillKitError` works.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class APIConnectionError extends BillKitError {\n override name = \"APIConnectionError\";\n}\n\nexport class APIError extends BillKitError {\n override name = \"APIError\";\n}\n\nexport class ServerError extends APIError {\n override name = \"ServerError\";\n}\n\nexport class AuthenticationError extends BillKitError {\n override name = \"AuthenticationError\";\n}\n\nexport class PermissionError extends BillKitError {\n override name = \"PermissionError\";\n}\n\nexport class ResourceMissingError extends BillKitError {\n override name = \"ResourceMissingError\";\n}\n\nexport class InvalidRequestError extends BillKitError {\n override name = \"InvalidRequestError\";\n}\n\nexport class ConflictError extends BillKitError {\n override name = \"ConflictError\";\n}\n\nexport class RateLimitError extends BillKitError {\n override name = \"RateLimitError\";\n readonly retryAfter: number | undefined;\n\n constructor(\n message: string,\n options: BillKitErrorOptions & { retryAfter?: number | undefined } = {},\n ) {\n super(message, options);\n this.retryAfter = options.retryAfter;\n }\n}\n\nfunction fallbackType(status: number): string {\n if (status === 401) return \"authentication_error\";\n if (status === 403) return \"permission_error\";\n if (status === 404) return \"invalid_request_error\";\n if (status === 409) return \"conflict\";\n if (status === 429) return \"rate_limit_error\";\n if (status >= 500) return \"api_error\";\n return \"invalid_request_error\";\n}\n\n/**\n * Pick the exception class from the HTTP **status**, not the envelope\n * `type`.\n *\n * The status is the field the API cannot get wrong. The `type` is\n * accurate for errors BillKit raises itself, but a request that never\n * reaches a route handler — an unmatched path, a method the route does\n * not allow — is serialised by the framework-level handler as\n * `{\"type\": \"api_error\", \"code\": \"unhandled\"}` *with a 4xx status*.\n * Trusting `type` there mapped a plain `404 Not Found` (a typo in a\n * resource id, or an SDK/API version skew) onto `ServerError`, telling\n * the caller BillKit had broken when their own request was at fault —\n * and `ServerError` is the class retry/alerting policies key on.\n *\n * The envelope `type` is still preserved verbatim on\n * {@link BillKitError.type} for callers that want it; only the class is\n * status-driven.\n */\nfunction classForStatus(\n status: number,\n): new (msg: string, opts: BillKitErrorOptions) => BillKitError {\n if (status >= 500) return ServerError;\n if (status === 401) return AuthenticationError;\n if (status === 403) return PermissionError;\n if (status === 404) return ResourceMissingError;\n if (status === 409) return ConflictError;\n if (status === 429) return RateLimitError;\n // Everything else below 500 (400, 405, 422, 451 …) is a request the\n // caller has to change.\n return InvalidRequestError;\n}\n\nexport function errorFromResponse(args: {\n status: number;\n body: unknown;\n requestId?: string | undefined;\n retryAfter?: number | undefined;\n}): BillKitError {\n const { status, body, requestId, retryAfter } = args;\n const envelope: ErrorEnvelope =\n typeof body === \"object\" && body !== null && \"error\" in body\n ? ((body as { error?: ErrorEnvelope }).error ?? {})\n : {};\n\n const type = envelope.type ?? fallbackType(status);\n const message =\n envelope.message ?? `BillKit API returned HTTP ${status} with no error body.`;\n\n const cls = classForStatus(status);\n\n const options: BillKitErrorOptions & { retryAfter?: number | undefined } = {\n type,\n code: envelope.code,\n param: envelope.param,\n statusCode: status,\n requestId,\n rawBody: typeof body === \"object\" && body !== null ? body : undefined,\n };\n if (cls === RateLimitError) {\n options.retryAfter = retryAfter;\n }\n return new cls(message, options);\n}\n","/**\n * Opt-in logging for the BillKit SDK.\n *\n * A library has no business deciding where its host application's logs\n * go, so this SDK ships no logger, no transport, and no destination. It\n * accepts one from you and writes to a no-op until you do:\n *\n * ```ts\n * const client = new BillKit({ logger: console });\n * ```\n *\n * `console` satisfies {@link BillKitLogger} structurally, so that line\n * works with no adapter. So does a pino/winston/bunyan child logger:\n * their `debug(msg, ctx)` / `warn(msg, ctx)` signatures line up. If yours\n * takes its arguments the other way round, wrap it:\n *\n * ```ts\n * const logger = {\n * debug: (m, c) => myLogger.debug(c, m),\n * warn: (m, c) => myLogger.warn(c, m),\n * };\n * ```\n *\n * ## What gets logged\n *\n * - **debug**: one call per HTTP attempt and one per response, with\n * `method`, `url`, `attempt`, `status`, `durationMs`, and `requestId`\n * (quote that id to BillKit support).\n * - **warn**: one call per retry, naming the reason and the delay before\n * the next attempt. A retry is a real anomaly worth surfacing without\n * being an error.\n *\n * ## What is deliberately never logged\n *\n * - The `Authorization` header or the API key, in any form.\n * - Request and response **bodies**. They carry customer PII (emails,\n * names, addresses) and billing detail; a payments SDK that quietly\n * copies those into its user's log sink has manufactured a compliance\n * problem on their behalf.\n * - The **query string**. List filters routinely carry values like\n * `email=ada@example.com`, so only the path is logged.\n * - The **final failure**. Every exhausted call throws a typed\n * `BillKitError` carrying the status, request id and retry-after;\n * logging it here as well would produce a duplicate the caller never\n * asked for and cannot suppress from their own sink.\n */\n\n/** Structured context attached to a log line. Never contains secrets. */\nexport type LogContext = Record<string, unknown>;\n\n/**\n * The minimum a logger must do for the SDK to use it. Deliberately two\n * methods: the SDK has exactly two things to say, and a narrow interface\n * is one almost every logger already satisfies without an adapter.\n */\nexport interface BillKitLogger {\n debug(message: string, context?: LogContext): void;\n warn(message: string, context?: LogContext): void;\n}\n\n/**\n * The default. Discards everything, so the SDK is silent until a logger\n * is supplied, and costs nothing when it isn't.\n */\nexport const NOOP_LOGGER: BillKitLogger = {\n debug(): void {\n /* intentionally empty */\n },\n warn(): void {\n /* intentionally empty */\n },\n};\n","/**\n * Retry policy for transient failures.\n *\n * Retries 5xx + network errors with jittered exponential backoff.\n * 4xx are caller-fault and never retried, with one deliberate\n * exception: `409 idempotency_in_progress`. See\n * {@link IN_PROGRESS_CODE}.\n *\n * The SDK auto-generates an `Idempotency-Key` for every mutating call\n * and reuses it across attempts, so retrying never double-charges.\n */\n\nexport interface RetryPolicy {\n readonly maxAttempts: number;\n readonly initialBackoffMs: number;\n readonly backoffMultiplier: number;\n readonly maxBackoffMs: number;\n readonly maxRetryAfterMs?: number;\n readonly jitter: number;\n}\n\nexport const DEFAULT_RETRY_POLICY: RetryPolicy = {\n maxAttempts: 4,\n initialBackoffMs: 500,\n backoffMultiplier: 2.0,\n maxBackoffMs: 8000,\n maxRetryAfterMs: 30_000,\n jitter: 0.25,\n};\n\n/**\n * Backoff before attempt `attempt` (1-indexed: attempt 2 is the first\n * retry). Caller never asks for attempt=1.\n */\nexport function backoffForMs(attempt: number, policy: RetryPolicy): number {\n const base = policy.initialBackoffMs * policy.backoffMultiplier ** (attempt - 2);\n const capped = Math.min(base, policy.maxBackoffMs);\n const jitterRange = capped * policy.jitter;\n const jittered = capped + (Math.random() * 2 - 1) * jitterRange;\n return Math.max(0, jittered);\n}\n\n/**\n * The one 409 error code that is transient rather than caller-fault.\n *\n * The server returns it when a request carrying the *same*\n * `Idempotency-Key` is still in flight (\"Retry after a short delay\",\n * `Retry-After: 1`). It is the only 4xx where doing nothing is the\n * dangerous option: the call may well have charged the customer, the\n * caller cannot see the outcome, and the obvious workaround — retry\n * with a *fresh* key — is precisely what turns one charge into two.\n *\n * Retrying is safe because the transport reuses the original\n * `Idempotency-Key` on every attempt, so the retry either loses the\n * race again or replays the first call's recorded response.\n */\nexport const IN_PROGRESS_CODE = \"idempotency_in_progress\";\n\nexport function shouldRetry(\n status: number | null,\n attempt: number,\n policy: RetryPolicy,\n retryAfterMs?: number,\n /**\n * `error.code` from the parsed response envelope, when there was one.\n * Only consulted for 409s; every other decision is status-driven.\n */\n errorCode?: string,\n): boolean {\n if (attempt >= policy.maxAttempts) return false;\n if (status === null) return true; // network error\n // A 409 from a *different* code (`idempotency_key_in_use`, a\n // conflicting subscription state) is a genuine caller-fault conflict\n // that retrying can only repeat, so it still fails fast.\n if (status === 409) return errorCode === IN_PROGRESS_CODE;\n if (status === 429) {\n // 429 is retried only when the server supplies a short, parseable\n // Retry-After value; otherwise we surface the exception so the\n // caller can decide. ``maxRetryAfterMs`` may be left ``undefined``\n // to allow any Retry-After value within budget.\n if (retryAfterMs === undefined || retryAfterMs < 0) return false;\n return policy.maxRetryAfterMs === undefined || retryAfterMs <= policy.maxRetryAfterMs;\n }\n return status >= 500;\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","export const VERSION = \"0.7.1\";\n","/**\n * Fetch-backed transport with retry + error mapping.\n *\n * Uses the runtime's native `fetch` (Node 20+, Bun, Deno, Cloudflare\n * Workers, browsers). The transport is the only place that touches HTTP;\n * everything else in the SDK speaks to a `Transport` interface so a\n * caller can inject a mock or replay layer for testing.\n */\n\nimport { APIConnectionError, errorFromResponse, type BillKitError } from \"./errors.js\";\nimport { NOOP_LOGGER, type BillKitLogger } from \"./logging.js\";\nimport {\n DEFAULT_RETRY_POLICY,\n type RetryPolicy,\n backoffForMs,\n shouldRetry,\n sleep,\n} from \"./retry.js\";\nimport { VERSION } from \"./version.js\";\n\nexport const DEFAULT_BASE_URL = \"https://api.billkit.eu\";\nexport const DEFAULT_TIMEOUT_MS = 30_000;\n\nexport type QueryValue = string | number | boolean | null | undefined;\n\nexport interface RequestOptions {\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n path: string;\n /**\n * Query parameters, as a plain object. Typed this way rather than with\n * an index signature because TypeScript only gives an implicit index\n * signature to type aliases, so a closed `*ListParams` interface would\n * need a cast at every call site. {@link buildUrl} does the pruning:\n * `undefined` and `null` are dropped, an array is joined with commas\n * (the API's `expand=a,b` shape), everything else is stringified.\n */\n query?: object;\n body?: Record<string, unknown> | undefined;\n idempotencyKey?: string | undefined;\n extraHeaders?: Record<string, string>;\n /**\n * How to read a **successful** response body. `\"json\"` (the default)\n * parses it; `\"binary\"` hands back the raw `ArrayBuffer`, for\n * endpoints that serve a document rather than a resource (the invoice\n * PDF). Error responses are always read as JSON either way, so the\n * typed error hierarchy behaves identically on both paths.\n */\n responseType?: \"json\" | \"binary\";\n}\n\nexport interface TransportConfig {\n apiKey: string;\n baseUrl?: string;\n timeoutMs?: number;\n retryPolicy?: RetryPolicy;\n fetch?: typeof fetch;\n /**\n * Where to send the SDK's request/retry lifecycle. Omitted (the\n * default) means a no-op: the SDK stays silent and never picks a\n * destination for you. `console` works as-is; see\n * {@link BillKitLogger}. Secrets, bodies and query strings are never\n * passed to it.\n */\n logger?: BillKitLogger;\n}\n\nfunction userAgent(): string {\n return `billkit-node/${VERSION}`;\n}\n\nfunction autoIdempotencyKey(method: string, supplied?: string): string | undefined {\n if (method === \"GET\") return undefined;\n if (supplied !== undefined) return supplied;\n const uuid = globalThis.crypto?.randomUUID?.();\n if (uuid === undefined) {\n // Deliberately fail loudly rather than fall back to\n // `Date.now()-Math.random()`. This key is what makes a retried\n // mutating call safe: two processes that generate the *same* key send\n // different requests the server treats as replays of each other, so it\n // returns the first call's response for the second, silently wrong on\n // a charge. `Math.random()` is not collision-resistant and is seeded\n // per-process, so a fleet starting together is exactly the case where\n // it collides. Every runtime this SDK supports (Node 20+, Bun, Deno,\n // Workers, modern browsers) has `crypto.randomUUID`.\n throw new Error(\n \"BillKit: crypto.randomUUID() is unavailable, so a safe Idempotency-Key \" +\n \"cannot be generated. Use Node 20+, Bun, Deno, or Cloudflare Workers, \" +\n \"or pass your own `idempotencyKey` on this call.\",\n );\n }\n return `sdk-${uuid}`;\n}\n\n/**\n * The URL with the **query string stripped**, for logging only.\n *\n * Never log the value {@link buildUrl} returns: list filters routinely\n * carry `?email=ada@example.com`, and copying customer PII into the\n * caller's log sink is exactly what this SDK must not do. Keeping the\n * two builders separate makes that a visible choice rather than an\n * accident waiting for someone to \"simplify\" it.\n */\nfunction logSafeUrl(baseUrl: string, path: string): string {\n const normalised = path.startsWith(\"/\") ? path : `/${path}`;\n return baseUrl.replace(/\\/$/, \"\") + normalised;\n}\n\nfunction buildUrl(baseUrl: string, path: string, query: RequestOptions[\"query\"]): string {\n const normalised = path.startsWith(\"/\") ? path : `/${path}`;\n const url = new URL(baseUrl.replace(/\\/$/, \"\") + normalised);\n if (query) {\n for (const [k, v] of Object.entries(query as Record<string, unknown>)) {\n if (v === null || v === undefined) continue;\n url.searchParams.set(k, Array.isArray(v) ? v.join(\",\") : String(v));\n }\n }\n return url.toString();\n}\n\nfunction buildHeaders(\n apiKey: string,\n hasBody: boolean,\n idempotencyKey: string | undefined,\n extra: Record<string, string> | undefined,\n): Headers {\n const headers = new Headers({\n Authorization: `Bearer ${apiKey}`,\n \"User-Agent\": userAgent(),\n Accept: \"application/json\",\n });\n if (hasBody) headers.set(\"Content-Type\", \"application/json\");\n if (idempotencyKey) headers.set(\"Idempotency-Key\", idempotencyKey);\n if (extra) {\n for (const [k, v] of Object.entries(extra)) {\n headers.set(k, v);\n }\n }\n return headers;\n}\n\nfunction parseJsonText(text: string): unknown {\n if (!text) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nasync function parseJson(response: Response): Promise<unknown> {\n return parseJsonText(await response.text());\n}\n\n/**\n * Read the body once, as the caller asked for it.\n *\n * A `Response` body can only be consumed once, so the choice has to be\n * made here rather than after the status check. On the binary path a\n * *failed* response is still decoded as UTF-8 JSON: an error is an error\n * envelope no matter which endpoint produced it, and losing that would\n * mean the PDF call throwing a shapeless error where every other call\n * throws a typed one.\n */\nasync function readBody(\n response: Response,\n responseType: \"json\" | \"binary\",\n): Promise<{ parsed: unknown; binary: ArrayBuffer | undefined }> {\n if (responseType !== \"binary\") {\n return { parsed: await parseJson(response), binary: undefined };\n }\n const buffer = await response.arrayBuffer();\n if (response.ok) return { parsed: null, binary: buffer };\n return { parsed: parseJsonText(new TextDecoder().decode(buffer)), binary: undefined };\n}\n\nfunction parseRetryAfterMs(header: string | null): number | undefined {\n if (!header) return undefined;\n const n = Number.parseFloat(header);\n if (Number.isFinite(n) && n >= 0) return n * 1000;\n\n const retryAt = Date.parse(header);\n if (Number.isNaN(retryAt)) return undefined;\n return Math.max(0, retryAt - Date.now());\n}\n\nfunction retryDelayMs(\n status: number | null,\n attempt: number,\n policy: RetryPolicy,\n retryAfterMs?: number,\n): number {\n if (status === 429 && retryAfterMs !== undefined) return retryAfterMs;\n return backoffForMs(attempt + 1, policy);\n}\n\n/**\n * Map a thrown fetch/read error to an {@link APIConnectionError}.\n *\n * ``AbortSignal.timeout`` aborts with a ``TimeoutError`` (some runtimes\n * surface ``AbortError``); we translate that into an explicit, greppable\n * timeout message instead of the runtime's terse default.\n *\n * The original error is attached as ``cause`` either way. Node's fetch\n * reports every transport failure as the same \"fetch failed\" message and\n * puts the real reason (``ECONNREFUSED``, ``ENOTFOUND``, a TLS error) in\n * its own cause, so dropping it left the caller with nothing to diagnose.\n */\nfunction connectionError(err: unknown, timeoutMs: number): APIConnectionError {\n const e = err as { name?: string; message?: string } | undefined;\n if (e?.name === \"TimeoutError\" || e?.name === \"AbortError\") {\n return new APIConnectionError(`BillKit request timed out after ${timeoutMs}ms.`, {\n cause: err,\n });\n }\n return new APIConnectionError(e?.message ?? \"Network request failed.\", { cause: err });\n}\n\nexport class Transport {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n private readonly retryPolicy: RetryPolicy;\n private readonly fetchFn: typeof fetch;\n private readonly logger: BillKitLogger;\n\n constructor(config: TransportConfig) {\n if (!config.apiKey) {\n throw new Error(\"BillKit: an API key is required (config.apiKey or BILLKIT_API_KEY env).\");\n }\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;\n this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.retryPolicy = config.retryPolicy ?? DEFAULT_RETRY_POLICY;\n this.logger = config.logger ?? NOOP_LOGGER;\n const fetchFn = config.fetch ?? globalThis.fetch;\n if (!fetchFn) {\n throw new Error(\n \"BillKit: no global fetch implementation found. Use Node 20+, Bun, Deno, \" +\n \"Cloudflare Workers, or pass { fetch } in the client options.\",\n );\n }\n this.fetchFn = fetchFn.bind(globalThis);\n }\n\n /**\n * Fetch a binary document (currently only the invoice PDF).\n *\n * Same retry policy, same timeout, same typed errors as\n * {@link Transport.request}; only the success-path decoding differs.\n * `fetch` follows the storage adapter's `302` to the signed URL by\n * itself, and the WHATWG spec drops the `Authorization` header on that\n * cross-origin hop — which is correct, since a presigned URL carries\n * its own credential and must not be handed BillKit's API key.\n */\n requestBinary(options: Omit<RequestOptions, \"responseType\">): Promise<ArrayBuffer> {\n return this.request<ArrayBuffer>({ ...options, responseType: \"binary\" });\n }\n\n async request<T = unknown>(options: RequestOptions): Promise<T> {\n const responseType = options.responseType ?? \"json\";\n const idempotencyKey = autoIdempotencyKey(options.method, options.idempotencyKey);\n const url = buildUrl(this.baseUrl, options.path, options.query);\n const headers = buildHeaders(\n this.apiKey,\n options.body !== undefined,\n idempotencyKey,\n options.extraHeaders,\n );\n const body = options.body !== undefined ? JSON.stringify(options.body) : undefined;\n // Query-free; see `logSafeUrl`. Never swap this for `url`.\n const loggedUrl = logSafeUrl(this.baseUrl, options.path);\n\n let lastError: BillKitError | null = null;\n for (let attempt = 1; attempt <= this.retryPolicy.maxAttempts; attempt++) {\n this.logger.debug(\"BillKit request\", {\n method: options.method,\n url: loggedUrl,\n attempt,\n maxAttempts: this.retryPolicy.maxAttempts,\n });\n const startedAt = Date.now();\n let response: Response;\n let parsedBody: unknown;\n let binaryBody: ArrayBuffer | undefined;\n try {\n // ``body`` is only spread when present so a GET request goes\n // out without a body field. Some hosts (Cloudflare Workers'\n // outgoing fetch) refuse ``body: null`` on GET; omitting it\n // is the portable shape.\n //\n // ``AbortSignal.timeout`` stays armed through the *body read*\n // below, not just until the headers arrive, so a server that\n // streams headers and then stalls the body is still bounded by\n // ``timeoutMs`` instead of hanging forever. A fresh signal is\n // created per attempt because a timed-out signal can't be reused.\n const init: RequestInit = {\n method: options.method,\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n };\n if (body !== undefined) init.body = body;\n response = await this.fetchFn(url, init);\n ({ parsed: parsedBody, binary: binaryBody } = await readBody(response, responseType));\n } catch (err) {\n lastError = connectionError(err, this.timeoutMs);\n if (!shouldRetry(null, attempt, this.retryPolicy)) throw lastError;\n const delayMs = retryDelayMs(null, attempt, this.retryPolicy);\n this.logger.warn(\"BillKit retrying\", {\n method: options.method,\n url: loggedUrl,\n reason: (err as { name?: string } | undefined)?.name ?? \"network error\",\n attempt,\n delayMs,\n });\n await sleep(delayMs);\n continue;\n }\n\n const requestId =\n response.headers.get(\"x-request-id\") ?? response.headers.get(\"request-id\") ?? undefined;\n this.logger.debug(\"BillKit response\", {\n method: options.method,\n url: loggedUrl,\n status: response.status,\n durationMs: Date.now() - startedAt,\n requestId: requestId ?? null,\n });\n\n if (response.ok) {\n if (responseType === \"binary\") return binaryBody as T;\n return (parsedBody ?? undefined) as T;\n }\n\n const retryAfterMs = parseRetryAfterMs(response.headers.get(\"retry-after\"));\n const error = errorFromResponse({\n status: response.status,\n body: parsedBody,\n requestId,\n retryAfter: retryAfterMs === undefined ? undefined : retryAfterMs / 1000,\n });\n\n // `error.code` is what separates a transient\n // `409 idempotency_in_progress` from every other (permanent) 409;\n // see `IN_PROGRESS_CODE`. The key on the wire is unchanged across\n // attempts, so the retry replays rather than re-charges.\n if (!shouldRetry(response.status, attempt, this.retryPolicy, retryAfterMs, error.code)) {\n throw error;\n }\n lastError = error;\n const delayMs = retryDelayMs(response.status, attempt, this.retryPolicy, retryAfterMs);\n this.logger.warn(\"BillKit retrying\", {\n method: options.method,\n url: loggedUrl,\n reason: `HTTP ${response.status}`,\n attempt,\n delayMs,\n });\n await sleep(delayMs);\n }\n\n // Loop exhausted; surface the last seen error.\n if (lastError) throw lastError;\n throw new APIConnectionError(\"Retry budget exhausted with no recorded error.\");\n }\n}\n","/**\n * Top-level BillKit client.\n *\n * Wraps a single Transport and exposes every resource family as a\n * field. The Transport is configured once at construction; every\n * resource reuses it, so a runtime-injected `fetch` impl (Cloudflare\n * Workers, MSW for tests, a debug proxy) flows through automatically.\n */\n\nimport {\n ApiKeys,\n AuditLogs,\n BillingPortalSessions,\n CheckoutSessions,\n Coupons,\n CreditNotes,\n Customers,\n Disputes,\n Events,\n Invoices,\n OneShotPayments,\n Payments,\n Prices,\n Products,\n Refunds,\n Subscriptions,\n TaxRates,\n Tenant,\n WebhookEndpoints,\n} from \"./resources.js\";\nimport { Transport, type TransportConfig } from \"./transport.js\";\n\nexport interface BillKitOptions extends Omit<TransportConfig, \"apiKey\"> {\n /** Falls back to `process.env.BILLKIT_API_KEY` when omitted. */\n apiKey?: string;\n}\n\nfunction resolveApiKey(supplied: string | undefined): string {\n if (supplied) return supplied;\n const env = (globalThis.process as { env?: Record<string, string> } | undefined)?.env\n ?.[\"BILLKIT_API_KEY\"];\n if (env) return env;\n throw new Error(\n \"BillKit: missing API key. Pass { apiKey } or set BILLKIT_API_KEY in the environment.\",\n );\n}\n\nexport class BillKit {\n readonly apiKeys: ApiKeys;\n readonly customers: Customers;\n readonly products: Products;\n readonly prices: Prices;\n readonly checkoutSessions: CheckoutSessions;\n readonly oneShotPayments: OneShotPayments;\n readonly subscriptions: Subscriptions;\n readonly refunds: Refunds;\n readonly disputes: Disputes;\n readonly webhookEndpoints: WebhookEndpoints;\n readonly events: Events;\n readonly tenant: Tenant;\n readonly coupons: Coupons;\n readonly taxRates: TaxRates;\n readonly invoices: Invoices;\n readonly creditNotes: CreditNotes;\n readonly auditLogs: AuditLogs;\n readonly payments: Payments;\n readonly billingPortalSessions: BillingPortalSessions;\n\n constructor(options: BillKitOptions = {}) {\n const transport = new Transport({\n ...options,\n apiKey: resolveApiKey(options.apiKey),\n });\n this.apiKeys = new ApiKeys(transport);\n this.customers = new Customers(transport);\n this.products = new Products(transport);\n this.prices = new Prices(transport);\n this.checkoutSessions = new CheckoutSessions(transport);\n this.oneShotPayments = new OneShotPayments(transport);\n this.subscriptions = new Subscriptions(transport);\n this.refunds = new Refunds(transport);\n this.disputes = new Disputes(transport);\n this.webhookEndpoints = new WebhookEndpoints(transport);\n this.events = new Events(transport);\n this.tenant = new Tenant(transport);\n this.coupons = new Coupons(transport);\n this.taxRates = new TaxRates(transport);\n this.invoices = new Invoices(transport);\n this.creditNotes = new CreditNotes(transport);\n this.auditLogs = new AuditLogs(transport);\n this.payments = new Payments(transport);\n this.billingPortalSessions = new BillingPortalSessions(transport);\n }\n}\n","/**\n * Verify `BillKit-Signature: t=<unix>,v1=<hex>` headers.\n *\n * Works in Node 20+, Bun, Deno, Cloudflare Workers and the browser:\n * we use the Web Crypto API (`globalThis.crypto.subtle`) which is\n * available in all modern runtimes. The verifier:\n *\n * 1. Parses the header (rejects malformed shapes). A header may carry\n * more than one `v1=` value, because the server emits both the old and new\n * signature during a signing-secret rotation, and verification passes\n * if any of them matches.\n * 2. Confirms the timestamp is within `toleranceSeconds` of now\n * (replay protection).\n * 3. Computes the expected HMAC and compares against each candidate in\n * constant time.\n */\n\nexport const DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;\n\nexport class WebhookVerificationError extends Error {\n override name = \"WebhookVerificationError\";\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport interface VerifyWebhookOptions {\n payload: string | Uint8Array;\n signatureHeader: string | null | undefined;\n secret: string;\n toleranceSeconds?: number;\n nowMs?: number; // injectable for tests\n}\n\nconst textEncoder = new TextEncoder();\nconst V1_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\nfunction toBytes(payload: string | Uint8Array): Uint8Array {\n return typeof payload === \"string\" ? textEncoder.encode(payload) : payload;\n}\n\nfunction constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) {\n diff |= (a[i] ?? 0) ^ (b[i] ?? 0);\n }\n return diff === 0;\n}\n\nfunction hexToBytes(hex: string): Uint8Array | null {\n if (!V1_HEX_RE.test(hex)) return null;\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n const byte = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n if (Number.isNaN(byte)) return null;\n out[i] = byte;\n }\n return out;\n}\n\nfunction parseSignatureHeader(header: string): { ts: number; v1List: string[] } {\n let tsRaw: string | undefined;\n const v1List: string[] = [];\n for (const chunk of header.split(\",\")) {\n const idx = chunk.indexOf(\"=\");\n if (idx < 0) continue;\n const key = chunk.slice(0, idx).trim();\n const value = chunk.slice(idx + 1).trim();\n // A rotation can carry more than one ``v1=`` (old + new secret);\n // collect them all and let the verifier accept any match.\n if (key === \"t\") tsRaw = value;\n else if (key === \"v1\") v1List.push(value);\n }\n if (!tsRaw || v1List.length === 0) {\n throw new WebhookVerificationError(`Malformed BillKit-Signature header: ${header}`);\n }\n const ts = Number.parseInt(tsRaw, 10);\n if (Number.isNaN(ts) || ts <= 0) {\n throw new WebhookVerificationError(`Malformed timestamp in BillKit-Signature: ${tsRaw}`);\n }\n return { ts, v1List };\n}\n\nfunction toArrayBuffer(view: Uint8Array): ArrayBuffer {\n // ``Uint8Array.buffer`` is ``ArrayBufferLike`` (could be\n // ``SharedArrayBuffer``); SubtleCrypto wants a concrete\n // ``ArrayBuffer``. We copy into a fresh ArrayBuffer to bridge.\n const out = new ArrayBuffer(view.byteLength);\n new Uint8Array(out).set(view);\n return out;\n}\n\nasync function computeHmac(secret: string, signed: Uint8Array): Promise<Uint8Array> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new WebhookVerificationError(\n \"No SubtleCrypto available. The BillKit SDK requires Node 20+, Bun, Deno, \" +\n \"Cloudflare Workers, or any runtime that exposes globalThis.crypto.subtle.\",\n );\n }\n const key = await subtle.importKey(\n \"raw\",\n toArrayBuffer(textEncoder.encode(secret)),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const signature = await subtle.sign(\"HMAC\", key, toArrayBuffer(signed));\n return new Uint8Array(signature);\n}\n\nexport async function verifyWebhookSignature<T = unknown>(\n options: VerifyWebhookOptions,\n): Promise<T> {\n const {\n payload,\n signatureHeader,\n secret,\n toleranceSeconds = DEFAULT_WEBHOOK_TOLERANCE_SECONDS,\n nowMs = Date.now(),\n } = options;\n\n if (signatureHeader === null || signatureHeader === undefined) {\n throw new WebhookVerificationError(\"Missing BillKit-Signature header.\");\n }\n\n const { ts, v1List } = parseSignatureHeader(signatureHeader);\n if (Math.abs(nowMs / 1000 - ts) > toleranceSeconds) {\n throw new WebhookVerificationError(\n `Signature timestamp outside ±${toleranceSeconds}s tolerance.`,\n );\n }\n\n const payloadBytes = toBytes(payload);\n const signed = new Uint8Array(payloadBytes.length + textEncoder.encode(`${ts}.`).length);\n const prefix = textEncoder.encode(`${ts}.`);\n signed.set(prefix, 0);\n signed.set(payloadBytes, prefix.length);\n\n const expected = await computeHmac(secret, signed);\n // Compare against every candidate; don't break on the first match so\n // the loop's timing doesn't reveal which signature matched.\n let sawValidHex = false;\n let matched = false;\n for (const v1 of v1List) {\n const received = hexToBytes(v1);\n if (!received) continue;\n sawValidHex = true;\n if (constantTimeEqual(expected, received)) matched = true;\n }\n if (!sawValidHex) {\n throw new WebhookVerificationError(\n `Malformed v1 hex in BillKit-Signature: ${v1List.join(\",\")}`,\n );\n }\n if (!matched) {\n throw new WebhookVerificationError(\"Signature mismatch.\");\n }\n\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(payloadBytes);\n try {\n return JSON.parse(text) as T;\n } catch (err) {\n throw new WebhookVerificationError(\n `Webhook body is not valid JSON: ${(err as Error).message}`,\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/pagination.ts","../src/resources.ts","../src/errors.ts","../src/logging.ts","../src/retry.ts","../src/version.ts","../src/transport.ts","../src/client.ts","../src/webhooks.ts"],"names":["delayMs"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Auto-pagination helper for list endpoints.\n *\n * The BillKit API returns Stripe-shape envelopes:\n *\n * { \"object\": \"list\", \"data\": [...], \"has_more\": bool }\n *\n * Cursor pagination is forward-only via the last item's `id` as\n * `starting_after`. `paginate` walks every page and yields each row.\n * Callers consume it via `for await`:\n *\n * for await (const customer of client.customers.iter()) {\n * ...\n * }\n */\n\nimport type { QueryValue } from \"./transport.js\";\n\nexport interface ListResponseEnvelope<T = unknown> {\n readonly data?: readonly T[];\n readonly has_more?: boolean;\n}\n\nexport interface PaginateOptions {\n /** Maps to the API's `limit` parameter. `undefined` lets the\n * server pick its default (10 today). */\n pageSize?: number | undefined;\n /** Extra filters forwarded on every page (e.g. `type` on events,\n * `action` on audit logs). Values are pruned of `undefined` so\n * callers can spread their full options object in. */\n filters?: Readonly<Record<string, QueryValue>>;\n}\n\ntype ListFn<T> = (params: {\n limit?: number | undefined;\n starting_after?: string | undefined;\n [key: string]: QueryValue;\n}) => Promise<ListResponseEnvelope<T>>;\n\n/**\n * Walk every page of `listFn` and yield each row.\n *\n * Three terminators, in priority order:\n * 1. `has_more=false`: the server's authoritative signal (common case).\n * 2. Empty `data` with `has_more=true`: shouldn't happen per the API\n * contract, but if a future server bug or proxy misbehaviour\n * produced it the iterator would loop forever. Belt-and-suspenders.\n * 3. The last row has no `id`, so there is no cursor to advance with. The schema\n * doesn't allow it today, but same defensive reasoning.\n */\nexport async function* paginate<T>(\n listFn: ListFn<T>,\n options: PaginateOptions = {},\n): AsyncIterableIterator<T> {\n const { pageSize, filters } = options;\n const cleanFilters: Record<string, QueryValue> = {};\n if (filters) {\n for (const [k, v] of Object.entries(filters)) {\n if (v !== undefined) cleanFilters[k] = v;\n }\n }\n\n let cursor: string | undefined;\n for (;;) {\n const page = await listFn({\n ...cleanFilters,\n limit: pageSize,\n starting_after: cursor,\n });\n const items = page.data ?? [];\n for (const item of items) yield item;\n if (!page.has_more || items.length === 0) return;\n const last = items[items.length - 1] as { id?: string } | undefined;\n cursor = last?.id;\n if (cursor === undefined) return;\n }\n}\n","/**\n * Resource accessors mirroring the BillKit API surface.\n *\n * Each resource exposes the public verbs from `/v1/<resource>`. The\n * return type defaults to `unknown`; the SDK doesn't ship runtime\n * schemas (zod / valibot) because the API is Stripe-shape and tenants\n * typically forward the JSON through their own data layer unchanged.\n * Callers who want strong types parameterise each call with their\n * own generic:\n *\n * interface Customer { id: string; email: string }\n * const c = await client.customers.create<Customer>({ email: \"...\" });\n *\n * Every list-returning resource also exposes an `iter()` method that\n * walks every page via the Stripe-shape `has_more` + `starting_after`\n * cursor protocol. Iterate with `for await`:\n *\n * for await (const customer of client.customers.iter()) { ... }\n */\n\nimport { paginate, type ListResponseEnvelope } from \"./pagination.js\";\nimport type { Transport } from \"./transport.js\";\n\n// ─── Shared parameter shapes ───────────────────────────────────────\n\n/**\n * Cursor-pagination knobs shared by every `list()` method.\n *\n * Closed on purpose: there is no index signature, so a misspelled filter\n * (`provisonal`) is a compile error instead of a query parameter the\n * server ignores. The Transport takes `query` as a plain `object` and\n * prunes/stringifies it, which is what lets these interfaces through\n * without a cast.\n */\nexport interface BaseListParams {\n limit?: number;\n starting_after?: string;\n // Deliberately no `ending_before`: BillKit's cursor pagination binds\n // `limit` + `starting_after` only (see `api/billkit/api/pagination.py`).\n // Advertising a backwards cursor the server ignores is worse than not\n // having one — the request succeeds and silently re-serves page 1.\n}\n\n/**\n * `?expand=` on a single-object GET. The relations a route accepts differ\n * per resource and are listed on each `retrieve()`; an unknown one is a\n * `400` naming the ones that work.\n */\nexport interface ExpandOptions {\n expand?: string[];\n}\n\n/**\n * `prices.list` params. Adds the server-side `product_id` filter on top of\n * the usual cursor knobs. `GET /v1/prices?product_id=...` narrows to one\n * product's prices, which beats listing everything and filtering client-side\n * once a tenant has more than a page of prices.\n */\nexport interface PricesListParams extends BaseListParams {\n product_id?: string;\n}\n\n/**\n * `payments.list` params. `customer_id` narrows to one customer's\n * charges. Mandate verifications are never listed, so every row is a\n * real purchase attempt; check `status` before treating one as revenue.\n */\nexport interface PaymentsListParams extends BaseListParams {\n customer_id?: string;\n /** Expandable here: `customer`, `subscription`. */\n expand?: string[];\n}\n\n/**\n * `oneShotPayments.list` params. `payments.list` lists subscription\n * payments only; one-off charges are listed here, newest first.\n * Failed, expired and still-open charges are included, so check `status`\n * before counting a row as revenue.\n */\nexport interface OneShotPaymentsListParams extends BaseListParams {\n customer_id?: string;\n /**\n * One of `open`, `pending`, `authorized`, `paid`, `failed`, `expired`,\n * `canceled`, `refunded`. Anything else is a `400` on `status`.\n */\n status?: string;\n}\n\n/**\n * `invoices.list` params. The three id filters each narrow to one row's\n * worth of invoices: `payment_id` answers \"which invoice did this charge\n * produce\".\n */\nexport interface InvoicesListParams extends BaseListParams {\n customer_id?: string;\n subscription_id?: string;\n payment_id?: string;\n /** One of `draft`, `open`, `paid`, `void`, `uncollectible`. */\n status?: string;\n /** Expandable here: `customer`. */\n expand?: string[];\n}\n\n/**\n * `disputes.list` params. `status` takes a comma-separated list of `open`\n * / `won`. There is no `lost`, because the provider gives no signal for\n * one. `payment_id` matches subscription payments only, not one-off\n * charges.\n */\nexport interface DisputesListParams extends BaseListParams {\n status?: string;\n payment_id?: string;\n}\n\n/**\n * `subscriptions.list` params. Both filters take a comma-separated\n * list (`\"active,past_due\"`); an unrecognised value is rejected with\n * `400 parameter_invalid` rather than silently ignored.\n *\n * The two answer different questions, and mixing them up is the most\n * common mistake against this route. `status` is where the subscription\n * stands with its payments. `renewal_state` is what happens at the end\n * of the current period. A paused subscription keeps `status: \"active\"`,\n * because the customer has paid for the period they are in, so\n * `renewal_state: \"paused\"` is the only way to find paused ones —\n * `status: \"paused\"` is not an accepted value and is rejected.\n */\nexport interface SubscriptionsListParams extends BaseListParams {\n customer_id?: string;\n /** `incomplete` | `trialing` | `active` | `past_due` | `canceled`, CSV. */\n status?: string;\n /** `auto_renew` | `paused` | `canceling` | `stopped`, CSV. */\n renewal_state?: string;\n /** Expandable here: `customer`, `price`, `refund_eligibility`. */\n expand?: string[];\n}\n\n/** Optional idempotency knob carried by every mutating call. */\nexport interface IdempotencyOptions {\n /** Coalesces retries across process restarts. The SDK generates\n * a random `sdk-<uuid>` key for every mutating call if you don't\n * supply one. Pass your own when you want retries from a different\n * process to converge on the same server-side result. */\n idempotencyKey?: string;\n}\n\n/**\n * @deprecated Alias of {@link BaseListParams}, kept for callers that\n * imported the older name. Reach for the resource-specific `*ListParams`\n * (e.g. `EventsListParams`) instead.\n */\nexport type ListParams = BaseListParams;\n\n// ─── Per-resource parameter shapes ─────────────────────────────────\n//\n// We keep one exported interface per public surface so callers can\n// import the shape, build it ahead of time, and pass it in. Inlined\n// shapes were inconsistent across resources; the named-interface\n// form is greppable and survives editor \"go to definition\".\n\nexport interface CreateCustomerParams extends IdempotencyOptions {\n email?: string;\n name?: string;\n country_code?: string;\n metadata?: Record<string, string>;\n}\n\nexport interface UpdateCustomerParams extends IdempotencyOptions {\n email?: string;\n /** An explicit `null` **clears** it and is sent as a JSON null rather than pruned (only `undefined` is dropped); omit the field to leave it alone. */\n name?: string | null;\n country_code?: string;\n metadata?: Record<string, string>;\n}\n\n/** Query parameters accepted by `GET /v1/customers`. */\nexport interface CustomerListParams extends BaseListParams {\n /**\n * `false` for customers who have paid, `true` for abandoned checkouts,\n * omitted for both.\n */\n provisional?: boolean;\n /** Expandable here: `stats`. Sent as `expand=a,b`. */\n expand?: string[];\n}\n\n/** Query parameters accepted by `GET /v1/products`. */\nexport interface ProductsListParams extends BaseListParams {\n /** Expandable here: `prices`, `stats`, `default_price`. */\n expand?: string[];\n}\n\n/**\n * Body for `POST /v1/customers/{id}/vat_number`. The VAT number is\n * sent through VIES server-side; the response carries\n * `vat_number_validated` reflecting the outcome.\n *\n * `vat_number: null` **clears** the registration, and is sent as an\n * explicit null rather than pruned: only `undefined` is dropped.\n */\nexport interface SetCustomerVatNumberParams extends IdempotencyOptions {\n vat_number: string | null;\n /** VIES needs a country; send it when the customer has none yet. */\n country_code?: string;\n}\n\n/**\n * Body for `POST /v1/customers/{id}/purge`. The server requires\n * `confirmed: true` as a fat-finger guard against accidental purges\n * fired from a DELETE that meant to soft-delete. The SDK defaults\n * `confirmed` to `true` so the caller doesn't have to opt in twice.\n */\nexport interface PurgeCustomerParams extends IdempotencyOptions {\n confirmed?: boolean;\n}\n\nexport interface CreateProductParams extends IdempotencyOptions {\n /** Customer-facing name, for example \"Pro\" or \"Enterprise\". */\n name: string;\n /** Optional long-form description shown in your own catalog UI. */\n description?: string;\n /** Ordered bullets suitable for pricing tables and checkout pages. */\n marketing_features?: string[];\n /** Small string metadata map echoed back on the Product object. */\n metadata?: Record<string, string>;\n /**\n * Let a *buyer* type a coupon code at the embedded checkout for this\n * product. Defaults to `false`. A coupon you apply yourself by passing\n * `coupon_code` when you create a Checkout Session is unaffected — that\n * is you discounting your own sale, and it has never needed this flag.\n *\n * The code is redeemed only once the payment settles, so a shopper who\n * tries a single-use code and abandons the checkout does not use it up.\n */\n allow_promotion_codes?: boolean;\n}\n\nexport interface UpdateProductParams extends IdempotencyOptions {\n name?: string;\n /** An explicit `null` **clears** it and is sent as a JSON null rather than pruned (only `undefined` is dropped); omit the field to leave it alone. */\n description?: string | null;\n marketing_features?: string[];\n metadata?: Record<string, string>;\n /** Set false to stop selling a product without deleting history. */\n active?: boolean;\n /** See {@link CreateProductParams.allow_promotion_codes}. */\n allow_promotion_codes?: boolean;\n /**\n * The price the billing portal offers on that price's interval. Must be\n * an active price of this product; anything else is a 400 on\n * `default_price_id`. An explicit `null` **clears** the default and is\n * sent as a JSON null rather than pruned (only `undefined` is dropped);\n * omit the field to leave the default alone.\n */\n default_price_id?: string | null;\n}\n\n/**\n * Body for `POST /v1/prices/{id}`. Every field is optional; omitted ones\n * are left alone.\n *\n * The dividing line is what a field decides. `amount_cents`, `currency`,\n * `interval` and `usage_type` decide **what a past charge was**, so they\n * are fixed at creation and absent here, because subscriptions renew\n * against a price by id and editing one would re-price live customers.\n * Everything\n * below decides **what happens next**, which is why it is editable:\n * setting `refund_on_cancel` covers the customers already on the price.\n *\n * `tax_behavior` is the exception and moves one way. It can be set while\n * the price is still `\"unspecified\"` and never changed again, because\n * flipping it would restate whether tax was inside or on top of an amount\n * somebody has already paid.\n */\nexport interface UpdatePriceParams extends IdempotencyOptions {\n /** `false` withdraws the price from sale, `true` puts it back. */\n active?: boolean;\n metadata?: Record<string, string>;\n /** Settable once, while the price is still `\"unspecified\"`. */\n tax_behavior?: \"inclusive\" | \"exclusive\";\n /** Read when a checkout opens. At least one entry. */\n payment_methods?: Array<\n \"creditcard\" | \"directdebit\" | \"ideal\" | \"eps\" | \"applepay\" | \"paypal\" | (string & {})\n >;\n refund_on_cancel?: \"none\" | \"full\" | \"prorated\";\n /** `0` disables refunds for that charge type; `N > 0` is an N-day window. */\n refund_window_initial_days?: number;\n refund_window_renewal_days?: number;\n}\n\n/**\n * One band of a tiered price.\n *\n * `up_to` is inclusive, and the **last band must be `\"inf\"`** because a\n * bounded top band cannot price the usage above it. Bands must strictly\n * increase.\n *\n * A band names a unit rate (`unit_amount` in whole minor units, or\n * `unit_amount_decimal` for a finer one), a `flat_amount` charged once for\n * reaching the band, or both. Write a free band as `unit_amount: 0` rather\n * than by omitting the rate, so \"free\" is something the price says instead\n * of something it forgot.\n */\nexport interface PriceTier {\n up_to: number | \"inf\";\n /** Whole minor units per unit in this band. */\n unit_amount?: number;\n /**\n * A rate finer than one minor unit, **as a string** — see\n * {@link CreatePriceParams.unit_amount_decimal} for why it is never a\n * `number`.\n */\n unit_amount_decimal?: string;\n /** Charged once when the usage reaches this band. Whole minor units. */\n flat_amount?: number;\n}\n\nexport interface CreatePriceParams extends IdempotencyOptions {\n /** Existing Product id returned from `client.products.create`. */\n product_id: string;\n /**\n * Whole minor units per period (licensed) or per unit (metered).\n *\n * Optional because a metered price can be priced by\n * {@link CreatePriceParams.unit_amount_decimal} or by\n * {@link CreatePriceParams.tiers} instead. Exactly one of the three; a\n * price with none of them is refused server-side.\n */\n amount_cents?: number;\n /**\n * A per-unit rate smaller than one minor unit, in **minor units**, to 12\n * decimal places. `\"0.02\"` is 0.02 cents, i.e. EUR 0.0002 per unit, which\n * is the canonical per-API-call price and not expressible as an integer.\n * Metered prices only.\n *\n * **It is a `string`, and that is load-bearing.** A JS `number` is an\n * IEEE-754 double and cannot hold 0.0002 exactly, so the rate would be\n * corrupted before it was ever multiplied by a quantity. The type forbids\n * a number at compile time, and the SDK throws a `TypeError` if an\n * untyped JavaScript caller passes one anyway.\n *\n * The period's whole quantity is multiplied by the rate and rounded\n * **once**, at the invoice.\n */\n unit_amount_decimal?: string;\n /**\n * `\"per_unit\"` (the default) multiplies one rate by the quantity.\n * `\"tiered\"` prices by bands and requires\n * {@link CreatePriceParams.tiers} and\n * {@link CreatePriceParams.tiers_mode}. Metered prices only.\n */\n billing_scheme?: \"per_unit\" | \"tiered\";\n /**\n * How a tier table is read, and there is **no default** because the same\n * table means two different bills. `\"graduated\"` prices the units inside\n * each band; `\"volume\"` lets the period total pick one band which then\n * prices every unit. 1,500 units against \"first 1,000 at EUR 0.01, then\n * EUR 0.005\" is EUR 12.50 graduated and EUR 7.50 by volume.\n */\n tiers_mode?: \"graduated\" | \"volume\";\n /** The band table. Required when `billing_scheme` is `\"tiered\"`, refused otherwise. */\n tiers?: PriceTier[];\n currency: string;\n interval: \"month\" | \"year\" | (string & {});\n metadata?: Record<string, string>;\n trial_days?: number;\n trial_verification_cents?: number;\n payment_methods?: Array<\n \"creditcard\" | \"directdebit\" | \"ideal\" | \"eps\" | \"applepay\" | \"paypal\" | (string & {})\n >;\n /**\n * What a cancellation refunds without being asked. `\"none\"` (the default)\n * nothing; `\"full\"` the whole last charge; `\"prorated\"` the unused part\n * of the current period. Both non-none modes also end access\n * immediately, and both stay bounded by the refund window below.\n *\n * Metered prices must leave this at `\"none\"`: ending access mid-period\n * would strand usage that has not been billed yet.\n */\n refund_on_cancel?: \"none\" | \"full\" | \"prorated\";\n /**\n * Per-Price refund-window override (`POST /v1/prices`). `undefined`\n * inherits the default policy table (7d / 30d initial, 3d renewal);\n * `0` disables refunds for that charge type; `N > 0` is an N-day\n * window (capped server-side at 365). Useful for \"Pro Bundle has a\n * 14-day money back\" or \"Lifetime: no refunds\" product decisions.\n */\n refund_window_initial_days?: number;\n refund_window_renewal_days?: number;\n /**\n * Whether `amount_cents` is quoted gross (`\"inclusive\"`, VAT is\n * backed out of it) or net (`\"exclusive\"`, VAT is added on top at\n * charge time). `undefined` inherits `\"unspecified\"`, which defers to\n * the tax rate configured for the buyer's country. Set it explicitly\n * when the amount you advertise has to be the amount charged,\n * regardless of what tax rates exist now or later.\n */\n tax_behavior?: \"inclusive\" | \"exclusive\" | \"unspecified\";\n /**\n * `\"licensed\"` (the default when omitted) bills `amount_cents` per\n * period regardless of consumption. `\"metered\"` bills **per reported\n * unit**: post consumption with `subscriptions.createUsageRecord`, and\n * at each period close BillKit invoices the period's total and charges\n * the stored mandate.\n *\n * A metered unit is priced by `amount_cents`, by `unit_amount_decimal`,\n * or by `tiers` — exactly one. Metered prices must be\n * `interval: \"month\"`, cannot have `trial_days`, and cannot set\n * `refund_on_cancel`.\n */\n usage_type?: \"licensed\" | \"metered\";\n}\n\n/**\n * Body for `POST /v1/subscriptions/{id}/usage_records`. Only valid\n * against a subscription whose price is `usage_type: \"metered\"`; the\n * server rejects a licensed subscription with `400 parameter_invalid`.\n */\nexport interface CreateUsageRecordParams extends IdempotencyOptions {\n /** Units consumed, `1..1_000_000`. Post multiple records to accumulate. */\n quantity: number;\n /**\n * Epoch seconds when the consumption happened. Omit to let the\n * server stamp receipt time. Useful when reporting is batched and\n * the record must land in the period the usage occurred.\n */\n occurred_at?: number;\n /**\n * Your own id for the event being metered, unique within this\n * subscription. This is the dedupe an `Idempotency-Key` cannot do.\n *\n * The key covers a retry of *one HTTP request*, including the SDK's own\n * internal retries. `identifier` covers a retry of *your* call — a job\n * runner replaying a task, a queue delivering twice, your code\n * re-invoking after its own timeout — which arrives at the API as a\n * genuinely new request with a new key. A second report of the same\n * identifier returns the first record unchanged instead of billing\n * twice.\n *\n * If your reporting pipeline is at-least-once, this is the one that\n * matters.\n */\n identifier?: string;\n /** Small string metadata map echoed back on the record. */\n metadata?: Record<string, string>;\n}\n\n/**\n * `subscriptions.listUsageRecords` params. `invoice_id` filters by\n * billing state: `\"pending\"` selects records not yet rolled into an\n * invoice, and a concrete `inv_...` id selects the records that\n * invoice billed. Omit it to list everything.\n */\nexport interface UsageRecordsListParams extends BaseListParams {\n invoice_id?: \"pending\" | (string & {});\n}\n\nexport interface CreateCheckoutSessionParams extends IdempotencyOptions {\n /**\n * Existing Customer to attach the session to. Mutually exclusive\n * with `customer_email`; exactly one of the two must be set.\n */\n customer_id?: string;\n /**\n * Stripe-compatible shortcut: BillKit creates a fresh Customer row\n * in the same transaction as the checkout. Never dedupes by email\n * (emails are not unique identifiers in BillKit). Mutually exclusive\n * with `customer_id`.\n */\n customer_email?: string;\n /**\n * Optional friendly name carried onto the auto-created Customer when\n * using `customer_email`. Rejected with `422` if supplied alongside\n * `customer_id` (rename existing customers via `customers.update`).\n */\n customer_name?: string;\n price_id: string;\n success_url: string;\n cancel_url: string;\n /**\n * The buyer's ISO-3166-1 alpha-2 country, when you already know it.\n * Stored on the customer if they do not have one yet, which is what\n * lets VAT apply to the very first charge. On the hosted flow the buyer\n * only reaches a country-collecting page after the charge exists.\n * Never overwrites a country the customer already has.\n */\n country?: string;\n /**\n * Pin the Mollie payment method. `undefined` lets Mollie pick from\n * the customer's available methods; when set, must be in the price's\n * `payment_methods` allowlist.\n *\n * Subscription-starting only, so this is deliberately NARROWER than the\n * one-shot union: `bancontact` and `banktransfer` are absent because\n * neither can mint the mandate a renewal needs. Mollie refuses the\n * latter outright with \"The payment method does not support sequence\n * type\".\n */\n method?:\n | \"creditcard\"\n | \"directdebit\"\n | \"ideal\"\n | \"eps\"\n | \"applepay\"\n | \"paypal\"\n | (string & {});\n /** Optional coupon code applied at checkout; atomically claimed. */\n coupon_code?: string;\n /**\n * Per-session trial override. Replaces the price's `trial_days`\n * for this checkout. Capped server-side at `2 × max(price.trial_days, 14)`.\n * `0` disables a trial that the price would otherwise grant.\n */\n trial_days_override?: number;\n /**\n * `\"hosted\"` (the default) returns a `url` you redirect the buyer to.\n * `\"embedded\"` returns a `client_secret` instead, for\n * `mountCheckoutElement()` / `<CheckoutElement/>` from\n * `@billkit-eu/js` — the card fields then render in a cross-origin\n * iframe on your own page.\n */\n ui_mode?: \"hosted\" | \"embedded\";\n /**\n * Small string map carried onto the session. Up to 50 keys, key ≤ 40\n * chars, value ≤ 500 chars.\n */\n metadata?: Record<string, string>;\n}\n\nexport interface CreateRefundParams extends IdempotencyOptions {\n payment_id?: string;\n subscription_id?: string;\n /**\n * Refund a mandate-less one-shot payment (`oneShotPayments.create`).\n * Mutually exclusive with `payment_id` / `subscription_id`; pass\n * exactly one target or the server rejects with `400`.\n */\n one_shot_payment_id?: string;\n /**\n * Partial-refund amount in minor units. Omit to refund the whole remaining\n * balance (the full charge when nothing has been refunded yet). A payment\n * may carry several partial refunds up to the charged amount; the one that\n * brings the cumulative total to the full charge cancels the bound\n * subscription (or flips a one-shot to `refunded`).\n */\n amount_cents?: number;\n reason?: string;\n}\n\n/**\n * Body for `POST /v1/checkout/one_shot`, a single mandate-less charge\n * (the Stripe PaymentIntent shape, mapped onto Mollie). No subscription,\n * no mandate, no renewals: it settles once against your `success_url`.\n */\nexport interface CreateOneShotPaymentParams extends IdempotencyOptions {\n /** Existing Customer to charge. */\n customer_id: string;\n amount_cents: number;\n /** ISO-4217, e.g. `\"EUR\"`. Validated against the tenant allowlist. */\n currency: string;\n /**\n * Concrete Mollie method to charge with. Required, because a one-shot commits\n * up front). Validated against the tenant's capability allowlist for\n * `currency`; one-off methods like `bancontact` and `banktransfer` are\n * allowed here even though they can't back a subscription.\n *\n * `banktransfer` settles in DAYS, not seconds: the payer is handed bank\n * details and Mollie holds the payment `open` for about a fortnight. Expect\n * `one_shot_payment.paid` long after the call returns.\n *\n * `giropay` was removed: the scheme shut down at the end of 2024 and the\n * server now 422s it. The `(string & {})` tail keeps this open on\n * purpose: unlike the console's read-side `PaymentMethodKind`, this is a\n * *request* type the server validates, so an SDK that lags a newly-added\n * method should not be the thing that blocks the call.\n */\n method:\n | \"creditcard\"\n | \"directdebit\"\n | \"ideal\"\n | \"bancontact\"\n | \"eps\"\n | \"applepay\"\n | \"paypal\"\n | \"banktransfer\"\n | (string & {});\n /** Where Mollie returns the payer after the hosted checkout. */\n success_url: string;\n /** Optional page for an abandoned/cancelled payment. */\n cancel_url?: string;\n /** Shown on the Mollie page + the payer's bank statement. */\n description?: string;\n /**\n * Per-payment refund-window override in days. `undefined` inherits the\n * one-shot default (30 days); `0` disables refunds for this payment;\n * `N > 0` is an N-day window (capped server-side at 365).\n */\n refund_window_days?: number;\n /**\n * Whether `amount_cents` is quoted gross or net.\n *\n * `\"inclusive\"` (the default when omitted) charges `amount_cents` and\n * backs the VAT out of it. `\"exclusive\"` reads it as a net figure and\n * charges the payer `amount_cents + tax`, so the response's\n * `amount_cents` comes back *larger* than the one you sent, because it\n * is always what was actually charged. Reconcile against `net_cents` /\n * `tax_cents` on the response.\n *\n * Omit to inherit the country default from your configured tax rate.\n */\n tax_behavior?: \"inclusive\" | \"exclusive\";\n metadata?: Record<string, string>;\n}\n\nexport interface CreateWebhookEndpointParams extends IdempotencyOptions {\n url: string;\n enabled_events?: string[];\n description?: string;\n}\n\nexport interface UpdateWebhookEndpointParams extends IdempotencyOptions {\n url?: string;\n enabled_events?: string[];\n /** An explicit `null` **clears** it and is sent as a JSON null rather than pruned (only `undefined` is dropped); omit the field to leave it alone. */\n description?: string | null;\n status?: string;\n}\n\nexport interface EventsListParams extends BaseListParams {\n /** Server-side filter, e.g. `customer.created`. */\n type?: string;\n /** Expandable here: `customer`. `events.retrieve` accepts none. */\n expand?: string[];\n}\n\nexport interface SetPortalBrandingParams extends IdempotencyOptions {\n business_name?: string;\n support_email?: string;\n logo_url?: string;\n theme?: Record<string, unknown>;\n capabilities?: Record<string, unknown>;\n}\n\nexport interface RotateProviderCredentialParams extends IdempotencyOptions {\n /** New raw provider API key. Encrypted server-side; never logged. */\n api_key: string;\n /** Defaults to the calling key's mode. */\n mode?: \"test\" | \"live\" | (string & {});\n /** Currently only `\"mollie\"`. */\n provider?: \"mollie\" | (string & {});\n}\n\nexport interface CreateCouponParams extends IdempotencyOptions {\n code: string;\n /**\n * `\"percent\"` reads `discount_value` as whole percent; `\"fixed_cents\"`\n * reads it as minor units off the charge. Those are the only two the\n * API accepts (`schemas/coupon.py`); anything else is a `422`.\n */\n discount_type: \"percent\" | \"fixed_cents\" | (string & {});\n discount_value: number;\n duration: \"once\" | \"repeating\" | \"forever\" | (string & {});\n duration_in_months?: number;\n max_redemptions?: number;\n redeem_by?: number;\n applies_to_price_ids?: string[];\n min_amount_cents?: number;\n}\n\nexport interface UpdateCouponParams extends IdempotencyOptions {\n active?: boolean;\n /** `null` removes the redemption cap. An explicit `null` **clears** it and is sent as a JSON null rather than pruned (only `undefined` is dropped); omit the field to leave it alone. */\n max_redemptions?: number | null;\n /** Epoch seconds. `null` removes the expiry. An explicit `null` **clears** it and is sent as a JSON null rather than pruned (only `undefined` is dropped); omit the field to leave it alone. */\n redeem_by?: number | null;\n applies_to_price_ids?: string[];\n min_amount_cents?: number;\n}\n\nexport interface ValidateCouponParams {\n code: string;\n /**\n * Scope the dry-run to one price. Optional: omit to validate the code\n * on its own (existence, active, not exhausted, not expired). Supply it\n * to also check the coupon's `applies_to_price_ids` restriction.\n */\n price_id?: string;\n /**\n * Base amount the discount is computed against, in minor units.\n * Optional: omit to skip the discount math and the `min_amount_cents`\n * check. `POST /v1/coupons/validate` treats both fields as nullable.\n */\n amount_cents?: number;\n}\n\nexport interface CreateTaxRateParams extends IdempotencyOptions {\n country_code: string;\n rate_basis_points: number;\n display_name?: string;\n inclusive?: boolean;\n}\n\nexport interface UpdateTaxRateParams extends IdempotencyOptions {\n rate_basis_points?: number;\n /** An explicit `null` **clears** it and is sent as a JSON null rather than pruned (only `undefined` is dropped); omit the field to leave it alone. */\n display_name?: string | null;\n inclusive?: boolean;\n active?: boolean;\n}\n\n/**\n * `auditLogs.list` params. All four filters match exactly and combine.\n *\n * `resource_type` narrows to a kind (`\"customer\"`, `\"price\"`);\n * `resource_id` narrows to one row, which is the \"everything that ever\n * happened to this customer\" question an audit log mostly exists for.\n * Pair them or use `resource_id` alone — ids are already unique.\n */\nexport interface AuditLogsListParams extends BaseListParams {\n action?: string;\n resource_type?: string;\n resource_id?: string;\n actor_id?: string;\n}\n\n/**\n * `creditNotes.list` params.\n *\n * `invoice_id` answers \"was this sale credited, and by how much\", which is\n * the question when reconciling one invoice; `customer_id` answers it for\n * everything credited back to one buyer.\n */\nexport interface CreditNotesListParams extends BaseListParams {\n invoice_id?: string;\n customer_id?: string;\n}\n\n/**\n * Body for `POST /v1/tenant/billing_profile`: the seller identity that\n * VAT is decided against and that an invoice prints.\n *\n * `country_code` is required on every call: there is nothing to leave\n * alone about a jurisdiction. The address fields and\n * `registration_number` are partial-update: omit one to leave the stored\n * value alone, or pass an explicit `null` to clear it, because moving\n * office is a real event.\n *\n * `vat_id` can be set once. After that, a different value or `null` is\n * refused with a 400 (`param: \"vat_id\"`, reason `vat_id_locked`) and the\n * call writes nothing; re-sending the stored number is accepted. BillKit\n * invoices you reverse-charged against it, so support changes it.\n */\nexport interface SetTenantBillingProfileParams extends IdempotencyOptions {\n /** ISO-3166-1 alpha-2, e.g. `\"NL\"`. */\n country_code: string;\n /** Your own EU VAT registration. Set once; support changes or clears it. */\n vat_id?: string | null;\n address_line1?: string | null;\n address_line2?: string | null;\n postal_code?: string | null;\n city?: string | null;\n registration_number?: string | null;\n}\n\n/**\n * Body for `POST /v1/api_keys`. The full key is returned **once**, on the\n * create response, and is never retrievable again.\n */\nexport interface CreateApiKeyParams extends IdempotencyOptions {\n /** Human label, so a key can be identified before it is revoked. */\n label?: string;\n /**\n * Narrow what the key may do. Omit to inherit the calling key's own\n * scopes; a key can never grant more than it holds.\n */\n scopes?: string[];\n}\n\n/** `invoices.void` params. `reason` is recorded on the audit row only. */\nexport interface VoidInvoiceParams extends IdempotencyOptions {\n reason?: string;\n}\n\nexport interface CreateBillingPortalSessionParams extends IdempotencyOptions {\n subscription_id: string;\n return_url: string;\n /**\n * Also email the portal link to the subscription's customer, at the\n * address on their record, as a tenant-branded message. Defaults to\n * `false`: without it you distribute the returned `url` yourself.\n */\n deliver_email?: boolean;\n}\n\n// ─── Internals ─────────────────────────────────────────────────────\n\n/**\n * Percent-encode a caller-supplied id before it becomes a path segment.\n *\n * Ids reach the SDK from the caller's own storage, and one carrying `/`,\n * `?` or `#` would otherwise rewrite the request: `#` truncates the path,\n * `?` turns the tail into a query string, and `/` walks to a different\n * route entirely. Encoding keeps the request on the route the method\n * names, so a bad id is a clean `404` rather than a call somewhere else.\n */\nfunction p(id: string): string {\n return encodeURIComponent(id);\n}\n\nfunction dropUndefined<T extends Record<string, unknown>>(obj: T): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) out[k] = v;\n }\n return out;\n}\n\n/**\n * Strips the `idempotencyKey` carrier from a mutating-call body and\n * returns `{ body, idempotencyKey }`. Pulled out so the per-resource\n * methods read as \"describe the verb\" instead of \"shuffle keys\".\n */\nfunction splitIdempotency<P extends IdempotencyOptions>(\n params: P,\n): { body: Record<string, unknown>; idempotencyKey: string | undefined } {\n const { idempotencyKey, ...rest } = params;\n return { body: dropUndefined(rest as Record<string, unknown>), idempotencyKey };\n}\n\n/**\n * Refuse a sub-minor-unit rate that arrived as a `number`.\n *\n * The type already forbids it, so this exists for the callers the type\n * system cannot reach: plain JavaScript, a value that came through `any`,\n * a body parsed from JSON. A double cannot hold 0.0002 exactly, so\n * accepting one would work for the rates that happen to round-trip and\n * silently mis-price the ones that do not — the worst of the three\n * available behaviours, and the reason the field is a string in the first\n * place.\n */\nfunction assertDecimalRateIsString(value: unknown, field: string): void {\n if (value === undefined || value === null || typeof value === \"string\") return;\n throw new TypeError(\n `${field} must be a string, not a ${typeof value}. A JavaScript number cannot ` +\n \"hold a rate like 0.0002 exactly, so it would be corrupted before it was ever \" +\n `multiplied by a quantity. Pass it as a string: \"${String(value)}\".`,\n );\n}\n\n/** Same check at the price level and inside every band of a tier table. */\nfunction assertPriceRatesAreStrings(params: CreatePriceParams): CreatePriceParams {\n assertDecimalRateIsString(params.unit_amount_decimal, \"unit_amount_decimal\");\n // Inside a tier is where a rate is most likely to be typed as a bare\n // literal, so the guard has to reach in there too.\n (params.tiers ?? []).forEach((tier, index) => {\n assertDecimalRateIsString(\n (tier as PriceTier | undefined)?.unit_amount_decimal,\n `tiers[${index}].unit_amount_decimal`,\n );\n });\n return params;\n}\n\n/**\n * Shared transport wrapper. Resources subclass this so each method\n * reads as a single line, \"verb to path with params\", instead of\n * the four-line `this.t.request({ ... })` boilerplate the previous\n * draft repeated everywhere.\n */\nabstract class BaseResource {\n constructor(protected readonly t: Transport) {}\n\n /**\n * `query` is a plain object rather than an index-signature type: TypeScript\n * only gives an implicit index signature to type *aliases*, so a closed\n * `*ListParams` interface would otherwise need a cast at every call site.\n * The transport prunes `undefined`/`null` and joins arrays with commas.\n */\n protected get<T>(path: string, query?: object): Promise<T> {\n return this.t.request<T>({ method: \"GET\", path, query });\n }\n\n protected post<T, P extends IdempotencyOptions>(path: string, params: P): Promise<T> {\n const { body, idempotencyKey } = splitIdempotency(params);\n return this.t.request<T>({ method: \"POST\", path, body, idempotencyKey });\n }\n\n /** POST with no body, used by lifecycle verbs (cancel, resume, revoke ...). */\n protected postEmpty<T>(path: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.t.request<T>({\n method: \"POST\",\n path,\n idempotencyKey: params.idempotencyKey,\n });\n }\n\n /** POST with a fixed body and no idempotency stripping (used by\n * endpoints whose body is fully specified by the caller's args\n * and not optional, e.g. `preview_update`). */\n protected postFixed<T>(\n path: string,\n body: Record<string, unknown>,\n params: IdempotencyOptions = {},\n ): Promise<T> {\n return this.t.request<T>({\n method: \"POST\",\n path,\n body,\n idempotencyKey: params.idempotencyKey,\n });\n }\n\n protected del<T>(path: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.t.request<T>({\n method: \"DELETE\",\n path,\n idempotencyKey: params.idempotencyKey,\n });\n }\n}\n\n// ─── Resources ─────────────────────────────────────────────────────\n\nexport class Customers extends BaseResource {\n /** Create a tenant-scoped buyer record. */\n create<T = unknown>(params: CreateCustomerParams = {}): Promise<T> {\n return this.post<T, CreateCustomerParams>(\"/v1/customers\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/customers/${p(id)}`);\n }\n\n update<T = unknown>(id: string, params: UpdateCustomerParams = {}): Promise<T> {\n return this.post<T, UpdateCustomerParams>(`/v1/customers/${p(id)}`, params);\n }\n\n /**\n * Delete a customer. Resolves to `{ id, object: \"customer\", deleted:\n * true }`, not the customer.\n *\n * The customer leaves the API: `retrieve()` 404s and they drop out of\n * `list()`. Their payments, invoices and refunds are untouched, and so\n * is their personal data — use {@link Customers.purge} for a GDPR\n * erasure. Refused while they hold a subscription that can still\n * charge them.\n */\n delete<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.del<T>(`/v1/customers/${p(id)}`, params);\n }\n\n /**\n * List customers, newest first.\n *\n * `provisional` filters on whether the customer ever completed a\n * payment. A checkout that captures an email commits its Customer\n * before the charge, so a checkout nobody finished leaves a row behind:\n * pass `false` for real customers only, `true` for the abandoned ones\n * (the cart-recovery worklist), or omit for both. Abandoned rows are\n * swept after the tenant's retention window.\n */\n list<T = unknown>(params: CustomerListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/customers\", params);\n }\n\n /** Walk every page of `list()` and yield each customer. */\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/customers\", page), { pageSize: options.pageSize });\n }\n\n /**\n * Attach or replace the customer's VAT number; triggers server-side\n * VIES validation. The response carries `vat_number_validated`\n * reflecting whether VIES confirmed the number.\n */\n setVatNumber<T = unknown>(id: string, params: SetCustomerVatNumberParams): Promise<T> {\n return this.post<T, SetCustomerVatNumberParams>(`/v1/customers/${p(id)}/vat_number`, params);\n }\n\n /**\n * Hard-purge a customer's PII for GDPR erasure. Distinct from\n * `delete()` (soft delete): purge nulls email/name/country/VAT/\n * metadata, sets `purged_at`, and is irreversible.\n *\n * The server requires `confirmed: true` as a fat-finger guard; the\n * SDK defaults it to `true` so callers don't have to opt in twice.\n */\n purge<T = unknown>(id: string, params: PurgeCustomerParams = {}): Promise<T> {\n const { confirmed = true, idempotencyKey } = params;\n return this.postFixed<T>(`/v1/customers/${p(id)}/purge`, { confirmed }, { idempotencyKey });\n }\n}\n\nexport class Products extends BaseResource {\n /** Create a catalog Product, then attach one or more Prices to it. */\n create<T = unknown>(params: CreateProductParams): Promise<T> {\n return this.post<T, CreateProductParams>(\"/v1/products\", params);\n }\n\n /**\n * Expandable: `prices` (every price on the product), `stats`, and\n * `default_price` (the price `default_price_id` names).\n */\n retrieve<T = unknown>(id: string, options: ExpandOptions = {}): Promise<T> {\n return this.get<T>(`/v1/products/${p(id)}`, options);\n }\n\n /**\n * Patch mutable Product fields, or archive it with `active: false`.\n *\n * Archiving is how you stop offering something. The product keeps its\n * id and still comes back from `retrieve()` and `list()`, because what\n * was sold under it has to stay readable, so there is no `delete()`.\n * A checkout against any of its prices is refused from then on, and\n * `active: true` un-archives.\n */\n update<T = unknown>(id: string, params: UpdateProductParams): Promise<T> {\n return this.post<T, UpdateProductParams>(`/v1/products/${p(id)}`, params);\n }\n\n list<T = unknown>(params: ProductsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/products\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/products\", page), { pageSize: options.pageSize });\n }\n}\n\nexport class Prices extends BaseResource {\n /**\n * Create immutable billing terms for an existing Product.\n *\n * A licensed price sends `amount_cents`. A metered price sends one of\n * `amount_cents`, `unit_amount_decimal` (a rate finer than one minor\n * unit, as a string) or `billing_scheme: \"tiered\"` with `tiers` and\n * `tiers_mode`. Throws `TypeError` before any HTTP call if a decimal\n * rate arrives as a number — see\n * {@link CreatePriceParams.unit_amount_decimal}.\n */\n // `async` on purpose. The rate guard throws, and a synchronous throw out\n // of a method typed `Promise<T>` escapes `.catch()` entirely — the caller\n // would have to wrap the call site in try/catch as well, which nobody\n // does for a promise-returning API. Marking it async turns the throw into\n // a rejection, so one error path handles both.\n async create<T = unknown>(params: CreatePriceParams): Promise<T> {\n return this.post<T, CreatePriceParams>(\"/v1/prices\", assertPriceRatesAreStrings(params));\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/prices/${p(id)}`);\n }\n\n /**\n * Archive a Price so it stops selling, or put it back on sale.\n *\n * `update(id, { active: false })` archives. The price keeps its id and\n * is still returned by `retrieve()` and by `list()`, because\n * subscriptions renew against it by id and what they are charged has to\n * stay readable. Subscriptions already on it keep renewing at it. What\n * stops is new business: a checkout session against the price is\n * refused and it is no longer offered as a plan change.\n *\n * `{ active: true }` undoes that. `active` is the only field because\n * `amount_cents`, `currency` and `interval` are fixed at creation, and\n * since none of them move here neither direction can change what a past\n * charge was made under. To charge something different, create a new\n * price.\n *\n * Sending the value a price already has returns it unchanged and emits\n * no second event, so a retry is safe. Archiving emits\n * `price.archived`; putting one back emits `price.updated`.\n */\n update<T = unknown>(id: string, params: UpdatePriceParams): Promise<T> {\n return this.post<T, UpdatePriceParams>(`/v1/prices/${p(id)}`, params);\n }\n\n list<T = unknown>(params: PricesListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/prices\", params);\n }\n\n iter<T = unknown>(\n options: { pageSize?: number; product_id?: string } = {},\n ): AsyncIterableIterator<T> {\n const filter = options.product_id === undefined ? {} : { product_id: options.product_id };\n return paginate<T>((page) => this.get(\"/v1/prices\", { ...filter, ...page }), {\n pageSize: options.pageSize,\n });\n }\n}\n\nexport class CheckoutSessions extends BaseResource {\n create<T = unknown>(params: CreateCheckoutSessionParams): Promise<T> {\n return this.post<T, CreateCheckoutSessionParams>(\"/v1/checkout/sessions\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/checkout/sessions/${p(id)}`);\n }\n}\n\n/**\n * Mandate-less one-shot payments (`/v1/checkout/one_shot`).\n *\n * A one-shot is the Stripe PaymentIntent shape mapped onto Mollie: a\n * single `sequenceType=oneoff` charge that provisions nothing: no\n * subscription, no mandate, no renewals. Drive terminal state via the\n * `one_shot_payment.succeeded` / `.failed` webhook events; refund one\n * with `client.refunds.create({ one_shot_payment_id })`.\n */\nexport class OneShotPayments extends BaseResource {\n /** Create a one-off charge; returns the object with a `redirect_url`. */\n create<T = unknown>(params: CreateOneShotPaymentParams): Promise<T> {\n return this.post<T, CreateOneShotPaymentParams>(\"/v1/checkout/one_shot\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/checkout/one_shot/${p(id)}`);\n }\n\n /** List one-off charges, newest first. Filter by `customer_id` and `status`. */\n list<T = unknown>(params: OneShotPaymentsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/checkout/one_shot\", params);\n }\n\n iter<T = unknown>(\n options: { pageSize?: number; customer_id?: string; status?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/checkout/one_shot\", page), {\n pageSize: options.pageSize,\n filters: { customer_id: options.customer_id, status: options.status },\n });\n }\n}\n\nexport class Subscriptions extends BaseResource {\n /** Expandable: `customer`, `price`, `refund_eligibility`. */\n retrieve<T = unknown>(id: string, options: ExpandOptions = {}): Promise<T> {\n return this.get<T>(`/v1/subscriptions/${p(id)}`, options);\n }\n\n /**\n * List subscriptions, newest first, optionally filtered.\n *\n * Reach for `renewal_state: \"paused\"` rather than `status: \"paused\"`\n * to find paused subscriptions; see `SubscriptionsListParams`.\n */\n list<T = unknown>(params: SubscriptionsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/subscriptions\", params);\n }\n\n /**\n * Walk every page of `list()`. Filters are carried onto each page\n * request, so a filtered walk narrows server-side instead of paging\n * the whole history and discarding rows client-side.\n */\n iter<T = unknown>(\n options: {\n pageSize?: number;\n customer_id?: string;\n status?: string;\n renewal_state?: string;\n } = {},\n ): AsyncIterableIterator<T> {\n // `undefined` query values are pruned by the transport, so the\n // filter can be spread as-is without a conditional per key.\n const { pageSize, ...filter } = options;\n return paginate<T>((page) => this.get(\"/v1/subscriptions\", { ...filter, ...page }), { pageSize });\n }\n\n cancel<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/subscriptions/${p(id)}/cancel`, params);\n }\n\n pause<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/subscriptions/${p(id)}/pause`, params);\n }\n\n resume<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/subscriptions/${p(id)}/resume`, params);\n }\n\n /**\n * Reactivate a canceled-but-still-in-period subscription.\n *\n * Distinct from `resume()` (paused → active): `reactivate()` flips\n * `canceled` back to `active` for the remainder of the current\n * period, so the customer keeps service without a new checkout.\n * Returns `409` if the period has already elapsed.\n */\n reactivate<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/subscriptions/${p(id)}/reactivate`, params);\n }\n\n previewUpdate<T = unknown>(id: string, params: { target_price_id: string }): Promise<T> {\n return this.postFixed<T>(`/v1/subscriptions/${p(id)}/preview_update`, {\n target_price_id: params.target_price_id,\n });\n }\n\n update<T = unknown>(\n id: string,\n params: { target_price_id: string } & IdempotencyOptions,\n ): Promise<T> {\n return this.postFixed<T>(\n `/v1/subscriptions/${p(id)}/update`,\n { target_price_id: params.target_price_id },\n { idempotencyKey: params.idempotencyKey },\n );\n }\n\n reauthorizePaymentMethod<T = unknown>(\n id: string,\n params: { return_url: string } & IdempotencyOptions,\n ): Promise<T> {\n return this.postFixed<T>(\n `/v1/subscriptions/${p(id)}/reauthorize_payment_method`,\n { return_url: params.return_url },\n { idempotencyKey: params.idempotencyKey },\n );\n }\n\n /**\n * Report consumption against a metered subscription.\n *\n * Only valid when the subscription's price is `usage_type:\n * \"metered\"`; a licensed subscription is rejected with `400\n * parameter_invalid`. Records accumulate until the next period close\n * rolls them into one invoice line; the record's `invoice_id` stays\n * `null` until then. Records are immutable once written — they are the\n * audit trail behind that line — so there is no update or delete.\n *\n * Two dedupe mechanisms, covering different failures. The\n * `Idempotency-Key` the SDK sends covers a retry of this HTTP request,\n * including its own internal retries. `params.identifier` covers a\n * retry of *your* call, which arrives as a new request with a new key.\n * See {@link CreateUsageRecordParams.identifier}.\n */\n createUsageRecord<T = unknown>(id: string, params: CreateUsageRecordParams): Promise<T> {\n return this.post<T, CreateUsageRecordParams>(`/v1/subscriptions/${p(id)}/usage_records`, params);\n }\n\n /**\n * List usage records for one subscription.\n *\n * Pass `invoice_id: \"pending\"` to reconcile what has been reported\n * but not yet billed, or a concrete invoice id to see what that\n * invoice charged for.\n */\n listUsageRecords<T = unknown>(\n id: string,\n params: UsageRecordsListParams = {},\n ): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(`/v1/subscriptions/${p(id)}/usage_records`, params);\n }\n\n /** Walk every page of `listUsageRecords()` for one subscription. */\n iterUsageRecords<T = unknown>(\n id: string,\n options: { pageSize?: number; invoice_id?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(`/v1/subscriptions/${p(id)}/usage_records`, page), {\n pageSize: options.pageSize,\n filters: { invoice_id: options.invoice_id },\n });\n }\n\n /**\n * Price the pending usage, before the period close bills it.\n *\n * `listUsageRecords({ invoice_id: \"pending\" })` gives the quantity; this\n * gives the money. `net_cents` / `tax_cents` / `gross_cents` are\n * computed through the same rate or tier table and the same VAT\n * resolution the close itself uses, so it is a forecast of the real\n * invoice rather than an estimate.\n *\n * **Read `will_charge` before promising a customer an amount.** A period\n * whose total is under `minimum_charge_cents` (EUR 1.00) is not charged,\n * because the payment provider would refuse it. The usage is not lost:\n * it stays pending and rolls into the next period, which is then billed\n * for both.\n *\n * `open_invoice_id` names an earlier cycle that is invoiced and still\n * unsettled; while one is open, this period cannot be charged.\n */\n retrieveUsageSummary<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/subscriptions/${p(id)}/usage_summary`);\n }\n}\n\nexport class Refunds extends BaseResource {\n create<T = unknown>(params: CreateRefundParams): Promise<T> {\n return this.post<T, CreateRefundParams>(\"/v1/refunds\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/refunds/${p(id)}`);\n }\n\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/refunds\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/refunds\", page), { pageSize: options.pageSize });\n }\n}\n\n/**\n * Chargebacks / disputes (`/v1/disputes`).\n *\n * Read-only. Disputes are provider-originated (opened by the cardholder's\n * bank) and surfaced via the `dispute.created` / `dispute.closed` webhook\n * events. There is no create/update. A dispute's `status` is `open` or `won`\n * (chargeback reversed); Mollie exposes no \"lost\" signal, so an upheld\n * chargeback stays `open` (treat any non-`won` dispute as unresolved).\n */\nexport class Disputes extends BaseResource {\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/disputes/${p(id)}`);\n }\n\n list<T = unknown>(params: DisputesListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/disputes\", params);\n }\n\n iter<T = unknown>(\n options: { pageSize?: number; status?: string; payment_id?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/disputes\", page), {\n pageSize: options.pageSize,\n filters: { status: options.status, payment_id: options.payment_id },\n });\n }\n}\n\nexport class WebhookEndpoints extends BaseResource {\n /**\n * Every event type this deployment can deliver, plus the wildcard.\n *\n * `enabled_events` rejects anything not on this list, so read it rather\n * than hard-coding a set: a name that is not on it fails at\n * registration and leaves you with an endpoint that never fires.\n */\n listEventTypes<T = unknown>(): Promise<T> {\n return this.get<T>(\"/v1/webhook_endpoints/event_types\");\n }\n\n create<T = unknown>(params: CreateWebhookEndpointParams): Promise<T> {\n return this.post<T, CreateWebhookEndpointParams>(\"/v1/webhook_endpoints\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/webhook_endpoints/${p(id)}`);\n }\n\n /**\n * Update an endpoint, or stop delivery with `status: \"disabled\"`.\n *\n * Disabling keeps the endpoint, its signing secret and its delivery\n * history, and `status: \"enabled\"` resumes. Use {@link\n * WebhookEndpoints.delete} when the endpoint should not exist at all:\n * disabling is reversible and deleting is not.\n */\n update<T = unknown>(id: string, params: UpdateWebhookEndpointParams): Promise<T> {\n return this.post<T, UpdateWebhookEndpointParams>(`/v1/webhook_endpoints/${p(id)}`, params);\n }\n\n /**\n * Delete an endpoint. Resolves to `{ id, object: \"webhook_endpoint\",\n * deleted: true }`, not the endpoint.\n *\n * A URL registered by mistake should not be a permanent fixture of the\n * account, so this removes it: `retrieve()` 404s afterwards and it is\n * gone from `list()`. Its delivery attempts go with it, because they\n * are readable only through the endpoint that owns them. The events\n * themselves are untouched and still in `client.events`, so what you\n * were sent stays on record.\n */\n delete<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.del<T>(`/v1/webhook_endpoints/${p(id)}`, params);\n }\n\n /** Rotate the signing secret. The new `bkwhsec_...` is returned once. */\n rotateSecret<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/webhook_endpoints/${p(id)}/rotate_secret`, params);\n }\n\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/webhook_endpoints\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/webhook_endpoints\", page), {\n pageSize: options.pageSize,\n });\n }\n\n /**\n * List per-attempt delivery records for one endpoint.\n *\n * Useful when a tenant's receiver is failing. Surfaces the status\n * code, response body excerpt, error, and next-attempt timestamp\n * for each event × endpoint pair.\n */\n listDeliveries<T = unknown>(\n endpointId: string,\n params: BaseListParams = {},\n ): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\n `/v1/webhook_endpoints/${p(endpointId)}/deliveries`,\n params,\n );\n }\n\n /** Walk every page of `listDeliveries()` for one endpoint. */\n iterDeliveries<T = unknown>(\n endpointId: string,\n options: { pageSize?: number } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>(\n (page) => this.get(`/v1/webhook_endpoints/${p(endpointId)}/deliveries`, page),\n { pageSize: options.pageSize },\n );\n }\n\n /** Fetch one delivery row for inspection before deciding to redeliver. */\n retrieveDelivery<T = unknown>(endpointId: string, deliveryId: string): Promise<T> {\n return this.get<T>(`/v1/webhook_endpoints/${p(endpointId)}/deliveries/${p(deliveryId)}`);\n }\n\n /**\n * @deprecated Renamed to {@link WebhookEndpoints.retrieveDelivery}.\n *\n * Every other single-row fetch in every BillKit SDK is `retrieve`; this\n * one method was `get`, which meant reaching for the obvious name and\n * getting a type error. The python and php clients already spell it\n * `retrieve_delivery` / `retrieveDelivery`, so node was the outlier.\n *\n * Kept as an alias because removing it would break callers for a naming\n * preference. It will go in the next major.\n */\n getDelivery<T = unknown>(endpointId: string, deliveryId: string): Promise<T> {\n return this.retrieveDelivery<T>(endpointId, deliveryId);\n }\n\n /**\n * Re-enqueue a delivery row for the dispatcher.\n *\n * Idempotent: a row already in `delivered` returns unchanged. A\n * `pending` / `failed` row flips to `pending` with\n * `next_attempt_at = now()`; `attempt_count` is preserved.\n */\n redeliver<T = unknown>(\n endpointId: string,\n deliveryId: string,\n params: IdempotencyOptions = {},\n ): Promise<T> {\n return this.postEmpty<T>(\n `/v1/webhook_endpoints/${p(endpointId)}/deliveries/${p(deliveryId)}/redeliver`,\n params,\n );\n }\n}\n\nexport class Events extends BaseResource {\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/events/${p(id)}`);\n }\n\n list<T = unknown>(params: EventsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/events\", params);\n }\n\n /** Walk every page of `list()`. Pass `type` to filter at the server. */\n iter<T = unknown>(\n options: { pageSize?: number; type?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/events\", page), {\n pageSize: options.pageSize,\n filters: { type: options.type },\n });\n }\n}\n\n/**\n * Read + mutate tenant-level configuration.\n *\n * Exposes the Mollie capability cache, the portal-branding row, and\n * the encrypted Mollie API key. None of these are per-resource;\n * they're tenant-wide knobs.\n */\nexport class Tenant extends BaseResource {\n /** Cached Mollie profile shape (enabled methods, country, currency). */\n capabilities<T = unknown>(): Promise<T> {\n return this.get<T>(\"/v1/tenant/capabilities\");\n }\n\n /**\n * Your registered country and VAT number: what your customers' VAT is\n * decided against.\n *\n * `country_code` is what you have stored and can be `null`;\n * `effective_country_code` is what the next charge will really use.\n * The two differ only when you have stored nothing, which is exactly\n * the case worth spotting before a first live payment.\n */\n billingProfile<T = unknown>(): Promise<T> {\n return this.get<T>(\"/v1/tenant/billing_profile\");\n }\n\n /**\n * Set the seller identity. `country_code` is required on every call;\n * every other field is partial-update, with an explicit `null` to\n * clear. Changes take effect on the next charge only. Tax is written\n * onto a payment and its invoice before money moves, and nothing goes\n * back and recalculates it.\n */\n setBillingProfile<T = unknown>(params: SetTenantBillingProfileParams): Promise<T> {\n return this.post<T, SetTenantBillingProfileParams>(\"/v1/tenant/billing_profile\", params);\n }\n\n /**\n * Download everything in the account as one JSON document, as raw bytes.\n *\n * ```ts\n * await writeFile(\"export.json\", Buffer.from(await client.tenant.export()));\n * ```\n *\n * The GDPR Article 20 portability route, and the way to take a backup.\n * It is `application/json` streamed inline, with no redirect, and each\n * record has the same shape its `GET` route returns, with\n * `billkit_export_version` naming the shape. It can be large, so write\n * it to a file rather than holding it in memory. Test and live data\n * export separately: you get whichever mode the key belongs to. The\n * access is recorded in your audit log.\n */\n export(): Promise<ArrayBuffer> {\n return this.t.requestBinary({ method: \"GET\", path: \"/v1/tenant/export\" });\n }\n\n /** Current portal branding row (business name, theme, capability flags). */\n portalBranding<T = unknown>(): Promise<T> {\n return this.get<T>(\"/v1/tenant/portal_branding\");\n }\n\n /**\n * Partial-update the portal branding row.\n *\n * Only fields you set are sent. Pass `undefined` to leave a field\n * untouched; sending an empty string explicitly clears it.\n */\n setPortalBranding<T = unknown>(params: SetPortalBrandingParams = {}): Promise<T> {\n return this.post<T, SetPortalBrandingParams>(\"/v1/tenant/portal_branding\", params);\n }\n\n /**\n * Rotate the encrypted provider credential for this tenant.\n *\n * The new `api_key` is encrypted server-side; nothing is logged.\n * `mode` defaults to the calling key's mode; prefix-mismatch\n * (`test_...` under live, `live_...` under test) is rejected at the\n * API boundary.\n */\n rotateProviderCredential<T = unknown>(params: RotateProviderCredentialParams): Promise<T> {\n return this.post<T, RotateProviderCredentialParams>(\n \"/v1/tenant/provider_credential\",\n params,\n );\n }\n}\n\nexport class Coupons extends BaseResource {\n create<T = unknown>(params: CreateCouponParams): Promise<T> {\n return this.post<T, CreateCouponParams>(\"/v1/coupons\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/coupons/${p(id)}`);\n }\n\n /**\n * Update a coupon's limits, or withdraw it with `active: false`.\n *\n * A withdrawn code is refused at checkout while the coupon stays\n * readable and discounts already applied keep working out, so there is\n * no `delete()`: a coupon that has been redeemed is part of what a\n * customer was charged. `active: true` brings the campaign back.\n */\n update<T = unknown>(id: string, params: UpdateCouponParams): Promise<T> {\n return this.post<T, UpdateCouponParams>(`/v1/coupons/${p(id)}`, params);\n }\n\n /**\n * Server-side dry-run of a coupon redemption.\n *\n * Returns the discount math without atomically claiming the coupon,\n * which is useful for \"preview before checkout\" UX.\n */\n validate<T = unknown>(params: ValidateCouponParams): Promise<T> {\n // Omit the optional fields rather than sending explicit nulls, so the\n // request body matches what a caller who only has a code would hand\n // written by hand, and so `extra=\"forbid\"` schemas stay happy.\n const body: Record<string, unknown> = { code: params.code };\n if (params.price_id !== undefined) body[\"price_id\"] = params.price_id;\n if (params.amount_cents !== undefined) body[\"amount_cents\"] = params.amount_cents;\n return this.postFixed<T>(\"/v1/coupons/validate\", body);\n }\n\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/coupons\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/coupons\", page), { pageSize: options.pageSize });\n }\n}\n\nexport class TaxRates extends BaseResource {\n create<T = unknown>(params: CreateTaxRateParams): Promise<T> {\n return this.post<T, CreateTaxRateParams>(\"/v1/tax_rates\", params);\n }\n\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/tax_rates/${p(id)}`);\n }\n\n /**\n * Correct a rate, retire it with `active: false`, or bring one back.\n *\n * Retiring is how you stop charging VAT in a country. The rate stays\n * readable, because an invoice records the percentage it charged and\n * you have to be able to point at the rate that produced it, so there\n * is no `delete()`.\n */\n update<T = unknown>(id: string, params: UpdateTaxRateParams): Promise<T> {\n return this.post<T, UpdateTaxRateParams>(`/v1/tax_rates/${p(id)}`, params);\n }\n\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/tax_rates\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/tax_rates\", page), { pageSize: options.pageSize });\n }\n}\n\n/**\n * Read-only access to generated invoices.\n *\n * Invoices are produced by the billing pipeline; tenants don't create\n * them directly. Fetch the rendered document with\n * {@link Invoices.retrievePdf}.\n */\nexport class Invoices extends BaseResource {\n /** Expandable: `customer`. */\n retrieve<T = unknown>(id: string, options: ExpandOptions = {}): Promise<T> {\n return this.get<T>(`/v1/invoices/${p(id)}`, options);\n }\n\n /**\n * Download the rendered invoice PDF as raw bytes.\n *\n * ```ts\n * const pdf = await client.invoices.retrievePdf(\"inv_123\");\n * await writeFile(\"invoice.pdf\", Buffer.from(pdf));\n * ```\n *\n * Blob-backed deployments stream the bytes inline; S3-backed ones\n * answer `302` to a presigned URL, which `fetch` follows for us under\n * the SDK's own timeout and retry policy — so both storage adapters\n * look identical from here.\n *\n * Deployments with `INVOICE_PDF_ENABLED=false` never render one and\n * answer `501 rendering_pending`, which surfaces as a `ServerError`\n * whose `code` is `\"rendering_pending\"`; `retrieve()` still returns the\n * structured invoice for tenants who render their own.\n */\n retrievePdf(id: string): Promise<ArrayBuffer> {\n return this.t.requestBinary({ method: \"GET\", path: `/v1/invoices/${p(id)}/pdf` });\n }\n\n /**\n * Send the customer their invoice again.\n *\n * The same tenant-branded \"your invoice is ready\" email, with a fresh\n * portal link, because the one in the original may have expired. It\n * goes to the address captured **on the invoice**, not the customer's\n * current one: this is a copy of a document that was issued to\n * somebody. An invoice with no address on file is a\n * `InvalidRequestError` rather than a send that did not happen.\n */\n sendEmail<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/invoices/${p(id)}/email`, params);\n }\n\n list<T = unknown>(params: InvoicesListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/invoices\", params);\n }\n\n iter<T = unknown>(\n options: {\n pageSize?: number;\n customer_id?: string;\n subscription_id?: string;\n payment_id?: string;\n status?: string;\n } = {},\n ): AsyncIterableIterator<T> {\n const { pageSize, ...filters } = options;\n return paginate<T>((page) => this.get(\"/v1/invoices\", page), { pageSize, filters });\n }\n\n /**\n * Void an invoice: state that the sale was never owed.\n *\n * The invoice keeps its number and stays readable — a gapless series\n * cannot lose a row — and stops being a receivable. Use it for an\n * invoice that should not have been issued.\n *\n * A **paid** invoice is refused with a `ConflictError` whose `code` is\n * `\"invoice_not_voidable\"`. That is deliberate rather than a\n * limitation: once the money has moved, \"never owed\" is false, and the\n * document that reverses a real sale is a credit note — refund the\n * payment and one is issued when the refund settles.\n *\n * Idempotent: re-voiding an already-void invoice returns it unchanged.\n */\n void<T = unknown>(id: string, params: VoidInvoiceParams = {}): Promise<T> {\n return this.post<T, VoidInvoiceParams>(`/v1/invoices/${p(id)}/void`, params);\n }\n}\n\n/**\n * Read-only access to credit notes — the documents that reverse an\n * issued invoice.\n *\n * There is no create: a credit note is issued for you when a refund\n * settles, never on request, so that a numbered legal record is only\n * minted once the money has actually moved. A refund that is still\n * pending, one that fails, and a refund of a one-off charge that was\n * never invoiced all produce none.\n */\nexport class CreditNotes extends BaseResource {\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/credit_notes/${p(id)}`);\n }\n\n /**\n * Download the rendered credit note PDF as raw bytes. Same storage\n * split as {@link Invoices.retrievePdf}: bytes inline or a followed\n * `302`, and `501 rendering_pending` on a deployment with no renderer.\n */\n retrievePdf(id: string): Promise<ArrayBuffer> {\n return this.t.requestBinary({ method: \"GET\", path: `/v1/credit_notes/${p(id)}/pdf` });\n }\n\n list<T = unknown>(params: CreditNotesListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/credit_notes\", params);\n }\n\n iter<T = unknown>(\n options: { pageSize?: number; invoice_id?: string; customer_id?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/credit_notes\", page), {\n pageSize: options.pageSize,\n filters: { invoice_id: options.invoice_id, customer_id: options.customer_id },\n });\n }\n}\n\n/**\n * Read-only access to the per-tenant audit log.\n *\n * Supports server-side filters: `action`, `resource_type`, `actor_id`.\n * The filters are forwarded through to `iter()` so an audit walk can\n * scope to a single actor or action without client-side filtering.\n */\nexport class AuditLogs extends BaseResource {\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/audit_logs/${p(id)}`);\n }\n\n list<T = unknown>(params: AuditLogsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/audit_logs\", params);\n }\n\n iter<T = unknown>(\n options: {\n pageSize?: number;\n action?: string;\n resource_type?: string;\n resource_id?: string;\n actor_id?: string;\n } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/audit_logs\", page), {\n pageSize: options.pageSize,\n filters: {\n action: options.action,\n resource_type: options.resource_type,\n resource_id: options.resource_id,\n actor_id: options.actor_id,\n },\n });\n }\n}\n\n/**\n * Read-only access to the payment ledger.\n *\n * Payments are written by the billing pipeline (checkout, renewal,\n * reauthorize). Inspect attempts and their Mollie-side metadata here;\n * refunds and disputes are separate flows.\n */\nexport class Payments extends BaseResource {\n /**\n * Expandable: `customer`, `subscription`, `refund_eligibility`. The last\n * is retrieve-only (`list` refuses it with a `400`) and attaches\n * `refund_eligibility: { object: \"refund_eligibility\", eligible,\n * amount_cents, currency, days_remaining, window_ends_at, reason }`:\n * whether `refunds.create` for the remaining balance would succeed now,\n * applying the refund window and the price's refund policy, which\n * `amount_refundable_cents` does not. When `eligible` is false, `reason`\n * is one of `not_paid`, `unrefundable_type`, `window_expired`,\n * `fully_refunded`, `disputed`, `operation_pending` or\n * `plan_change_pending` (a plan change is settling: the full balance\n * cannot be refunded yet, a partial refund still can); treat any other\n * value as \"not refundable\".\n */\n retrieve<T = unknown>(id: string, options: ExpandOptions = {}): Promise<T> {\n return this.get<T>(`/v1/payments/${p(id)}`, options);\n }\n\n /**\n * Fetch the provider's own record of this charge, live.\n *\n * Reads Mollie at request time rather than a stored copy, so it carries\n * what BillKit deliberately does not keep: the card BIN, the iDEAL\n * bank, the provider's own status string. Reading live means it can\n * fail: a provider outage or a charge old enough to have aged out\n * answers `200` with `available: false` and a short reason, so render\n * the rest of the page regardless.\n */\n retrieveProvider<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/payments/${p(id)}/provider`);\n }\n\n list<T = unknown>(params: PaymentsListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/payments\", params);\n }\n\n iter<T = unknown>(\n options: { pageSize?: number; customer_id?: string } = {},\n ): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/payments\", page), {\n pageSize: options.pageSize,\n filters: { customer_id: options.customer_id },\n });\n }\n}\n\n/**\n * Mint and revoke customer-facing billing-portal sessions.\n *\n * Each session token is scoped to a single subscription with a\n * sliding 30-minute idle window and a 2-hour hard cap. The raw token\n * is returned **once** on mint; the response also includes the URL\n * the tenant embeds in their app.\n */\nexport class BillingPortalSessions extends BaseResource {\n create<T = unknown>(params: CreateBillingPortalSessionParams): Promise<T> {\n return this.post<T, CreateBillingPortalSessionParams>(\"/v1/billing_portal/sessions\", params);\n }\n\n /** Kill an in-the-wild portal session. Idempotent. */\n revoke<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/billing_portal/sessions/${p(id)}/revoke`, params);\n }\n}\n\n/**\n * Issue, inspect and revoke API keys.\n *\n * A key is issued in the same mode as the key that created it, so a test\n * key can only mint test keys, and it can never grant scopes it does not\n * hold itself. The secret is returned **once**, on\n * {@link ApiKeys.create}; every later read carries only the prefix.\n */\nexport class ApiKeys extends BaseResource {\n /**\n * Issue a new key. The response's `secret` is the only time the full\n * key exists outside the caller's own storage, so record it now.\n */\n create<T = unknown>(params: CreateApiKeyParams = {}): Promise<T> {\n return this.post<T, CreateApiKeyParams>(\"/v1/api_keys\", params);\n }\n\n /**\n * One key's metadata: prefix, label, scopes, `revoked_at`, and\n * `last_used_at`, which is the field to read before revoking one.\n */\n retrieve<T = unknown>(id: string): Promise<T> {\n return this.get<T>(`/v1/api_keys/${p(id)}`);\n }\n\n /**\n * Revoke a key so it stops working. Immediate and irreversible; issue a\n * new key instead. Revoking an already-revoked key returns it\n * unchanged, so a retry is safe, and a key may revoke itself, which is\n * what you want when the leaked key is the one you are calling with.\n */\n revoke<T = unknown>(id: string, params: IdempotencyOptions = {}): Promise<T> {\n return this.postEmpty<T>(`/v1/api_keys/${p(id)}/revoke`, params);\n }\n\n /** List keys, newest first. Revoked ones are included; check `revoked_at`. */\n list<T = unknown>(params: BaseListParams = {}): Promise<ListResponseEnvelope<T>> {\n return this.get<ListResponseEnvelope<T>>(\"/v1/api_keys\", params);\n }\n\n iter<T = unknown>(options: { pageSize?: number } = {}): AsyncIterableIterator<T> {\n return paginate<T>((page) => this.get(\"/v1/api_keys\", page), { pageSize: options.pageSize });\n }\n}\n","/**\n * Typed exception hierarchy mirroring the BillKit API error envelope.\n *\n * The API returns errors in the Stripe-shape:\n *\n * { \"error\": { \"type\": \"...\", \"code\": \"...\", \"message\": \"...\", \"param\": \"...\" } }\n *\n * The HTTP **status** picks the class so callers can `catch` on the\n * subclass they care about rather than branching on status codes; the\n * envelope's `type`/`code`/`param` ride along on the thrown object.\n * See {@link classForStatus} for why the status, not `type`, is the\n * authority.\n */\n\nexport interface ErrorEnvelope {\n type?: string;\n code?: string;\n message?: string;\n param?: string;\n}\n\nexport interface BillKitErrorOptions {\n type?: string | undefined;\n code?: string | undefined;\n param?: string | undefined;\n statusCode?: number | undefined;\n requestId?: string | undefined;\n rawBody?: unknown;\n /**\n * The underlying error, forwarded to `Error`'s own `cause`. Set on\n * `APIConnectionError` so the runtime's reason for a failed fetch\n * (`ECONNREFUSED`, a TLS failure, an abort) survives the mapping.\n */\n cause?: unknown;\n}\n\n// TS treats `name = \"Foo\"` as a literal-type property, which then conflicts\n// when subclasses override it. We widen to `string` everywhere so the\n// hierarchy can re-set ``name`` cleanly.\nexport class BillKitError extends Error {\n override name: string = \"BillKitError\";\n readonly type: string | undefined;\n readonly code: string | undefined;\n readonly param: string | undefined;\n readonly statusCode: number | undefined;\n readonly requestId: string | undefined;\n readonly rawBody: unknown;\n\n constructor(message: string, options: BillKitErrorOptions = {}) {\n // Only pass the options bag when there is a cause: `{ cause: undefined }`\n // still installs an own `cause` property, which would show up on every\n // error that never had one.\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.type = options.type;\n this.code = options.code;\n this.param = options.param;\n this.statusCode = options.statusCode;\n this.requestId = options.requestId;\n this.rawBody = options.rawBody;\n // Restore the prototype chain, required when targeting ES5 transpilers\n // (some bundlers still emit them) so `instanceof BillKitError` works.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class APIConnectionError extends BillKitError {\n override name = \"APIConnectionError\";\n}\n\nexport class APIError extends BillKitError {\n override name = \"APIError\";\n}\n\nexport class ServerError extends APIError {\n override name = \"ServerError\";\n}\n\nexport class AuthenticationError extends BillKitError {\n override name = \"AuthenticationError\";\n}\n\nexport class PermissionError extends BillKitError {\n override name = \"PermissionError\";\n}\n\nexport class ResourceMissingError extends BillKitError {\n override name = \"ResourceMissingError\";\n}\n\nexport class InvalidRequestError extends BillKitError {\n override name = \"InvalidRequestError\";\n}\n\nexport class ConflictError extends BillKitError {\n override name = \"ConflictError\";\n}\n\nexport class RateLimitError extends BillKitError {\n override name = \"RateLimitError\";\n readonly retryAfter: number | undefined;\n\n constructor(\n message: string,\n options: BillKitErrorOptions & { retryAfter?: number | undefined } = {},\n ) {\n super(message, options);\n this.retryAfter = options.retryAfter;\n }\n}\n\nfunction fallbackType(status: number): string {\n if (status === 401) return \"authentication_error\";\n if (status === 403) return \"permission_error\";\n if (status === 404) return \"invalid_request_error\";\n if (status === 409) return \"conflict\";\n if (status === 429) return \"rate_limit_error\";\n if (status >= 500) return \"api_error\";\n return \"invalid_request_error\";\n}\n\n/**\n * Pick the exception class from the HTTP **status**, not the envelope\n * `type`.\n *\n * The status is the field the API cannot get wrong. The `type` is\n * accurate for errors BillKit raises itself, but a request that never\n * reaches a route handler — an unmatched path, a method the route does\n * not allow — is serialised by the framework-level handler as\n * `{\"type\": \"api_error\", \"code\": \"unhandled\"}` *with a 4xx status*.\n * Trusting `type` there mapped a plain `404 Not Found` (a typo in a\n * resource id, or an SDK/API version skew) onto `ServerError`, telling\n * the caller BillKit had broken when their own request was at fault —\n * and `ServerError` is the class retry/alerting policies key on.\n *\n * The envelope `type` is still preserved verbatim on\n * {@link BillKitError.type} for callers that want it; only the class is\n * status-driven.\n */\nfunction classForStatus(\n status: number,\n): new (msg: string, opts: BillKitErrorOptions) => BillKitError {\n if (status >= 500) return ServerError;\n if (status === 401) return AuthenticationError;\n if (status === 403) return PermissionError;\n if (status === 404) return ResourceMissingError;\n if (status === 409) return ConflictError;\n if (status === 429) return RateLimitError;\n // Everything else below 500 (400, 405, 422, 451 …) is a request the\n // caller has to change.\n return InvalidRequestError;\n}\n\nexport function errorFromResponse(args: {\n status: number;\n body: unknown;\n requestId?: string | undefined;\n retryAfter?: number | undefined;\n}): BillKitError {\n const { status, body, requestId, retryAfter } = args;\n const envelope: ErrorEnvelope =\n typeof body === \"object\" && body !== null && \"error\" in body\n ? ((body as { error?: ErrorEnvelope }).error ?? {})\n : {};\n\n const type = envelope.type ?? fallbackType(status);\n const message =\n envelope.message ?? `BillKit API returned HTTP ${status} with no error body.`;\n\n const cls = classForStatus(status);\n\n const options: BillKitErrorOptions & { retryAfter?: number | undefined } = {\n type,\n code: envelope.code,\n param: envelope.param,\n statusCode: status,\n requestId,\n rawBody: typeof body === \"object\" && body !== null ? body : undefined,\n };\n if (cls === RateLimitError) {\n options.retryAfter = retryAfter;\n }\n return new cls(message, options);\n}\n","/**\n * Opt-in logging for the BillKit SDK.\n *\n * A library has no business deciding where its host application's logs\n * go, so this SDK ships no logger, no transport, and no destination. It\n * accepts one from you and writes to a no-op until you do:\n *\n * ```ts\n * const client = new BillKit({ logger: console });\n * ```\n *\n * `console` satisfies {@link BillKitLogger} structurally, so that line\n * works with no adapter. So does a pino/winston/bunyan child logger:\n * their `debug(msg, ctx)` / `warn(msg, ctx)` signatures line up. If yours\n * takes its arguments the other way round, wrap it:\n *\n * ```ts\n * const logger = {\n * debug: (m, c) => myLogger.debug(c, m),\n * warn: (m, c) => myLogger.warn(c, m),\n * };\n * ```\n *\n * ## What gets logged\n *\n * - **debug**: one call per HTTP attempt and one per response, with\n * `method`, `url`, `attempt`, `status`, `durationMs`, and `requestId`\n * (quote that id to BillKit support).\n * - **warn**: one call per retry, naming the reason and the delay before\n * the next attempt. A retry is a real anomaly worth surfacing without\n * being an error.\n *\n * ## What is deliberately never logged\n *\n * - The `Authorization` header or the API key, in any form.\n * - Request and response **bodies**. They carry customer PII (emails,\n * names, addresses) and billing detail; a payments SDK that quietly\n * copies those into its user's log sink has manufactured a compliance\n * problem on their behalf.\n * - The **query string**. List filters routinely carry values like\n * `email=ada@example.com`, so only the path is logged.\n * - The **final failure**. Every exhausted call throws a typed\n * `BillKitError` carrying the status, request id and retry-after;\n * logging it here as well would produce a duplicate the caller never\n * asked for and cannot suppress from their own sink.\n */\n\n/** Structured context attached to a log line. Never contains secrets. */\nexport type LogContext = Record<string, unknown>;\n\n/**\n * The minimum a logger must do for the SDK to use it. Deliberately two\n * methods: the SDK has exactly two things to say, and a narrow interface\n * is one almost every logger already satisfies without an adapter.\n */\nexport interface BillKitLogger {\n debug(message: string, context?: LogContext): void;\n warn(message: string, context?: LogContext): void;\n}\n\n/**\n * The default. Discards everything, so the SDK is silent until a logger\n * is supplied, and costs nothing when it isn't.\n */\nexport const NOOP_LOGGER: BillKitLogger = {\n debug(): void {\n /* intentionally empty */\n },\n warn(): void {\n /* intentionally empty */\n },\n};\n","/**\n * Retry policy for transient failures.\n *\n * Retries 5xx + network errors with jittered exponential backoff.\n * 4xx are caller-fault and never retried, with one deliberate\n * exception: `409 idempotency_in_progress`. See\n * {@link IN_PROGRESS_CODE}.\n *\n * The SDK auto-generates an `Idempotency-Key` for every mutating call\n * and reuses it across attempts, so retrying never double-charges.\n */\n\nexport interface RetryPolicy {\n readonly maxAttempts: number;\n readonly initialBackoffMs: number;\n readonly backoffMultiplier: number;\n readonly maxBackoffMs: number;\n readonly maxRetryAfterMs?: number;\n readonly jitter: number;\n}\n\nexport const DEFAULT_RETRY_POLICY: RetryPolicy = {\n maxAttempts: 4,\n initialBackoffMs: 500,\n backoffMultiplier: 2.0,\n maxBackoffMs: 8000,\n maxRetryAfterMs: 30_000,\n jitter: 0.25,\n};\n\n/**\n * Backoff before attempt `attempt` (1-indexed: attempt 2 is the first\n * retry). Caller never asks for attempt=1.\n */\nexport function backoffForMs(attempt: number, policy: RetryPolicy): number {\n const base = policy.initialBackoffMs * policy.backoffMultiplier ** (attempt - 2);\n const capped = Math.min(base, policy.maxBackoffMs);\n const jitterRange = capped * policy.jitter;\n const jittered = capped + (Math.random() * 2 - 1) * jitterRange;\n return Math.max(0, jittered);\n}\n\n/**\n * The one 409 error code that is transient rather than caller-fault.\n *\n * The server returns it when a request carrying the *same*\n * `Idempotency-Key` is still in flight (\"Retry after a short delay\",\n * `Retry-After: 1`). It is the only 4xx where doing nothing is the\n * dangerous option: the call may well have charged the customer, the\n * caller cannot see the outcome, and the obvious workaround — retry\n * with a *fresh* key — is precisely what turns one charge into two.\n *\n * Retrying is safe because the transport reuses the original\n * `Idempotency-Key` on every attempt, so the retry either loses the\n * race again or replays the first call's recorded response.\n */\nexport const IN_PROGRESS_CODE = \"idempotency_in_progress\";\n\nexport function shouldRetry(\n status: number | null,\n attempt: number,\n policy: RetryPolicy,\n retryAfterMs?: number,\n /**\n * `error.code` from the parsed response envelope, when there was one.\n * Only consulted for 409s; every other decision is status-driven.\n */\n errorCode?: string,\n): boolean {\n if (attempt >= policy.maxAttempts) return false;\n if (status === null) return true; // network error\n // A 409 from a *different* code (`idempotency_key_in_use`, a\n // conflicting subscription state) is a genuine caller-fault conflict\n // that retrying can only repeat, so it still fails fast.\n if (status === 409) return errorCode === IN_PROGRESS_CODE;\n if (status === 429) {\n // 429 is retried only when the server supplies a short, parseable\n // Retry-After value; otherwise we surface the exception so the\n // caller can decide. ``maxRetryAfterMs`` may be left ``undefined``\n // to allow any Retry-After value within budget.\n if (retryAfterMs === undefined || retryAfterMs < 0) return false;\n return policy.maxRetryAfterMs === undefined || retryAfterMs <= policy.maxRetryAfterMs;\n }\n return status >= 500;\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","export const VERSION = \"0.8.0\";\n","/**\n * Fetch-backed transport with retry + error mapping.\n *\n * Uses the runtime's native `fetch` (Node 20+, Bun, Deno, Cloudflare\n * Workers, browsers). The transport is the only place that touches HTTP;\n * everything else in the SDK speaks to a `Transport` interface so a\n * caller can inject a mock or replay layer for testing.\n */\n\nimport { APIConnectionError, errorFromResponse, type BillKitError } from \"./errors.js\";\nimport { NOOP_LOGGER, type BillKitLogger } from \"./logging.js\";\nimport {\n DEFAULT_RETRY_POLICY,\n type RetryPolicy,\n backoffForMs,\n shouldRetry,\n sleep,\n} from \"./retry.js\";\nimport { VERSION } from \"./version.js\";\n\nexport const DEFAULT_BASE_URL = \"https://api.billkit.eu\";\nexport const DEFAULT_TIMEOUT_MS = 30_000;\n\nexport type QueryValue = string | number | boolean | null | undefined;\n\nexport interface RequestOptions {\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n path: string;\n /**\n * Query parameters, as a plain object. Typed this way rather than with\n * an index signature because TypeScript only gives an implicit index\n * signature to type aliases, so a closed `*ListParams` interface would\n * need a cast at every call site. {@link buildUrl} does the pruning:\n * `undefined` and `null` are dropped, an array is joined with commas\n * (the API's `expand=a,b` shape), everything else is stringified.\n */\n query?: object;\n body?: Record<string, unknown> | undefined;\n idempotencyKey?: string | undefined;\n extraHeaders?: Record<string, string>;\n /**\n * How to read a **successful** response body. `\"json\"` (the default)\n * parses it; `\"binary\"` hands back the raw `ArrayBuffer`, for\n * endpoints that serve a document rather than a resource (the invoice\n * PDF). Error responses are always read as JSON either way, so the\n * typed error hierarchy behaves identically on both paths.\n */\n responseType?: \"json\" | \"binary\";\n}\n\nexport interface TransportConfig {\n apiKey: string;\n baseUrl?: string;\n timeoutMs?: number;\n retryPolicy?: RetryPolicy;\n fetch?: typeof fetch;\n /**\n * Where to send the SDK's request/retry lifecycle. Omitted (the\n * default) means a no-op: the SDK stays silent and never picks a\n * destination for you. `console` works as-is; see\n * {@link BillKitLogger}. Secrets, bodies and query strings are never\n * passed to it.\n */\n logger?: BillKitLogger;\n}\n\nfunction userAgent(): string {\n return `billkit-node/${VERSION}`;\n}\n\nfunction autoIdempotencyKey(method: string, supplied?: string): string | undefined {\n if (method === \"GET\") return undefined;\n if (supplied !== undefined) return supplied;\n const uuid = globalThis.crypto?.randomUUID?.();\n if (uuid === undefined) {\n // Deliberately fail loudly rather than fall back to\n // `Date.now()-Math.random()`. This key is what makes a retried\n // mutating call safe: two processes that generate the *same* key send\n // different requests the server treats as replays of each other, so it\n // returns the first call's response for the second, silently wrong on\n // a charge. `Math.random()` is not collision-resistant and is seeded\n // per-process, so a fleet starting together is exactly the case where\n // it collides. Every runtime this SDK supports (Node 20+, Bun, Deno,\n // Workers, modern browsers) has `crypto.randomUUID`.\n throw new Error(\n \"BillKit: crypto.randomUUID() is unavailable, so a safe Idempotency-Key \" +\n \"cannot be generated. Use Node 20+, Bun, Deno, or Cloudflare Workers, \" +\n \"or pass your own `idempotencyKey` on this call.\",\n );\n }\n return `sdk-${uuid}`;\n}\n\n/**\n * The URL with the **query string stripped**, for logging only.\n *\n * Never log the value {@link buildUrl} returns: list filters routinely\n * carry `?email=ada@example.com`, and copying customer PII into the\n * caller's log sink is exactly what this SDK must not do. Keeping the\n * two builders separate makes that a visible choice rather than an\n * accident waiting for someone to \"simplify\" it.\n */\nfunction logSafeUrl(baseUrl: string, path: string): string {\n const normalised = path.startsWith(\"/\") ? path : `/${path}`;\n return baseUrl.replace(/\\/$/, \"\") + normalised;\n}\n\nfunction buildUrl(baseUrl: string, path: string, query: RequestOptions[\"query\"]): string {\n const normalised = path.startsWith(\"/\") ? path : `/${path}`;\n const url = new URL(baseUrl.replace(/\\/$/, \"\") + normalised);\n if (query) {\n for (const [k, v] of Object.entries(query as Record<string, unknown>)) {\n if (v === null || v === undefined) continue;\n url.searchParams.set(k, Array.isArray(v) ? v.join(\",\") : String(v));\n }\n }\n return url.toString();\n}\n\nfunction buildHeaders(\n apiKey: string,\n hasBody: boolean,\n idempotencyKey: string | undefined,\n extra: Record<string, string> | undefined,\n): Headers {\n const headers = new Headers({\n Authorization: `Bearer ${apiKey}`,\n \"User-Agent\": userAgent(),\n Accept: \"application/json\",\n });\n if (hasBody) headers.set(\"Content-Type\", \"application/json\");\n if (idempotencyKey) headers.set(\"Idempotency-Key\", idempotencyKey);\n if (extra) {\n for (const [k, v] of Object.entries(extra)) {\n headers.set(k, v);\n }\n }\n return headers;\n}\n\nfunction parseJsonText(text: string): unknown {\n if (!text) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nasync function parseJson(response: Response): Promise<unknown> {\n return parseJsonText(await response.text());\n}\n\n/**\n * Read the body once, as the caller asked for it.\n *\n * A `Response` body can only be consumed once, so the choice has to be\n * made here rather than after the status check. On the binary path a\n * *failed* response is still decoded as UTF-8 JSON: an error is an error\n * envelope no matter which endpoint produced it, and losing that would\n * mean the PDF call throwing a shapeless error where every other call\n * throws a typed one.\n */\nasync function readBody(\n response: Response,\n responseType: \"json\" | \"binary\",\n): Promise<{ parsed: unknown; binary: ArrayBuffer | undefined }> {\n if (responseType !== \"binary\") {\n return { parsed: await parseJson(response), binary: undefined };\n }\n const buffer = await response.arrayBuffer();\n if (response.ok) return { parsed: null, binary: buffer };\n return { parsed: parseJsonText(new TextDecoder().decode(buffer)), binary: undefined };\n}\n\nfunction parseRetryAfterMs(header: string | null): number | undefined {\n if (!header) return undefined;\n const n = Number.parseFloat(header);\n if (Number.isFinite(n) && n >= 0) return n * 1000;\n\n const retryAt = Date.parse(header);\n if (Number.isNaN(retryAt)) return undefined;\n return Math.max(0, retryAt - Date.now());\n}\n\nfunction retryDelayMs(\n status: number | null,\n attempt: number,\n policy: RetryPolicy,\n retryAfterMs?: number,\n): number {\n if (status === 429 && retryAfterMs !== undefined) return retryAfterMs;\n return backoffForMs(attempt + 1, policy);\n}\n\n/**\n * Map a thrown fetch/read error to an {@link APIConnectionError}.\n *\n * ``AbortSignal.timeout`` aborts with a ``TimeoutError`` (some runtimes\n * surface ``AbortError``); we translate that into an explicit, greppable\n * timeout message instead of the runtime's terse default.\n *\n * The original error is attached as ``cause`` either way. Node's fetch\n * reports every transport failure as the same \"fetch failed\" message and\n * puts the real reason (``ECONNREFUSED``, ``ENOTFOUND``, a TLS error) in\n * its own cause, so dropping it left the caller with nothing to diagnose.\n */\nfunction connectionError(err: unknown, timeoutMs: number): APIConnectionError {\n const e = err as { name?: string; message?: string } | undefined;\n if (e?.name === \"TimeoutError\" || e?.name === \"AbortError\") {\n return new APIConnectionError(`BillKit request timed out after ${timeoutMs}ms.`, {\n cause: err,\n });\n }\n return new APIConnectionError(e?.message ?? \"Network request failed.\", { cause: err });\n}\n\nexport class Transport {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n private readonly retryPolicy: RetryPolicy;\n private readonly fetchFn: typeof fetch;\n private readonly logger: BillKitLogger;\n\n constructor(config: TransportConfig) {\n if (!config.apiKey) {\n throw new Error(\"BillKit: an API key is required (config.apiKey or BILLKIT_API_KEY env).\");\n }\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;\n this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.retryPolicy = config.retryPolicy ?? DEFAULT_RETRY_POLICY;\n this.logger = config.logger ?? NOOP_LOGGER;\n const fetchFn = config.fetch ?? globalThis.fetch;\n if (!fetchFn) {\n throw new Error(\n \"BillKit: no global fetch implementation found. Use Node 20+, Bun, Deno, \" +\n \"Cloudflare Workers, or pass { fetch } in the client options.\",\n );\n }\n this.fetchFn = fetchFn.bind(globalThis);\n }\n\n /**\n * Fetch a binary document (currently only the invoice PDF).\n *\n * Same retry policy, same timeout, same typed errors as\n * {@link Transport.request}; only the success-path decoding differs.\n * `fetch` follows the storage adapter's `302` to the signed URL by\n * itself, and the WHATWG spec drops the `Authorization` header on that\n * cross-origin hop — which is correct, since a presigned URL carries\n * its own credential and must not be handed BillKit's API key.\n */\n requestBinary(options: Omit<RequestOptions, \"responseType\">): Promise<ArrayBuffer> {\n return this.request<ArrayBuffer>({ ...options, responseType: \"binary\" });\n }\n\n async request<T = unknown>(options: RequestOptions): Promise<T> {\n const responseType = options.responseType ?? \"json\";\n const idempotencyKey = autoIdempotencyKey(options.method, options.idempotencyKey);\n const url = buildUrl(this.baseUrl, options.path, options.query);\n const headers = buildHeaders(\n this.apiKey,\n options.body !== undefined,\n idempotencyKey,\n options.extraHeaders,\n );\n const body = options.body !== undefined ? JSON.stringify(options.body) : undefined;\n // Query-free; see `logSafeUrl`. Never swap this for `url`.\n const loggedUrl = logSafeUrl(this.baseUrl, options.path);\n\n let lastError: BillKitError | null = null;\n for (let attempt = 1; attempt <= this.retryPolicy.maxAttempts; attempt++) {\n this.logger.debug(\"BillKit request\", {\n method: options.method,\n url: loggedUrl,\n attempt,\n maxAttempts: this.retryPolicy.maxAttempts,\n });\n const startedAt = Date.now();\n let response: Response;\n let parsedBody: unknown;\n let binaryBody: ArrayBuffer | undefined;\n try {\n // ``body`` is only spread when present so a GET request goes\n // out without a body field. Some hosts (Cloudflare Workers'\n // outgoing fetch) refuse ``body: null`` on GET; omitting it\n // is the portable shape.\n //\n // ``AbortSignal.timeout`` stays armed through the *body read*\n // below, not just until the headers arrive, so a server that\n // streams headers and then stalls the body is still bounded by\n // ``timeoutMs`` instead of hanging forever. A fresh signal is\n // created per attempt because a timed-out signal can't be reused.\n const init: RequestInit = {\n method: options.method,\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n };\n if (body !== undefined) init.body = body;\n response = await this.fetchFn(url, init);\n ({ parsed: parsedBody, binary: binaryBody } = await readBody(response, responseType));\n } catch (err) {\n lastError = connectionError(err, this.timeoutMs);\n if (!shouldRetry(null, attempt, this.retryPolicy)) throw lastError;\n const delayMs = retryDelayMs(null, attempt, this.retryPolicy);\n this.logger.warn(\"BillKit retrying\", {\n method: options.method,\n url: loggedUrl,\n reason: (err as { name?: string } | undefined)?.name ?? \"network error\",\n attempt,\n delayMs,\n });\n await sleep(delayMs);\n continue;\n }\n\n const requestId =\n response.headers.get(\"x-request-id\") ?? response.headers.get(\"request-id\") ?? undefined;\n this.logger.debug(\"BillKit response\", {\n method: options.method,\n url: loggedUrl,\n status: response.status,\n durationMs: Date.now() - startedAt,\n requestId: requestId ?? null,\n });\n\n if (response.ok) {\n if (responseType === \"binary\") return binaryBody as T;\n return (parsedBody ?? undefined) as T;\n }\n\n const retryAfterMs = parseRetryAfterMs(response.headers.get(\"retry-after\"));\n const error = errorFromResponse({\n status: response.status,\n body: parsedBody,\n requestId,\n retryAfter: retryAfterMs === undefined ? undefined : retryAfterMs / 1000,\n });\n\n // `error.code` is what separates a transient\n // `409 idempotency_in_progress` from every other (permanent) 409;\n // see `IN_PROGRESS_CODE`. The key on the wire is unchanged across\n // attempts, so the retry replays rather than re-charges.\n if (!shouldRetry(response.status, attempt, this.retryPolicy, retryAfterMs, error.code)) {\n throw error;\n }\n lastError = error;\n const delayMs = retryDelayMs(response.status, attempt, this.retryPolicy, retryAfterMs);\n this.logger.warn(\"BillKit retrying\", {\n method: options.method,\n url: loggedUrl,\n reason: `HTTP ${response.status}`,\n attempt,\n delayMs,\n });\n await sleep(delayMs);\n }\n\n // Loop exhausted; surface the last seen error.\n if (lastError) throw lastError;\n throw new APIConnectionError(\"Retry budget exhausted with no recorded error.\");\n }\n}\n","/**\n * Top-level BillKit client.\n *\n * Wraps a single Transport and exposes every resource family as a\n * field. The Transport is configured once at construction; every\n * resource reuses it, so a runtime-injected `fetch` impl (Cloudflare\n * Workers, MSW for tests, a debug proxy) flows through automatically.\n */\n\nimport {\n ApiKeys,\n AuditLogs,\n BillingPortalSessions,\n CheckoutSessions,\n Coupons,\n CreditNotes,\n Customers,\n Disputes,\n Events,\n Invoices,\n OneShotPayments,\n Payments,\n Prices,\n Products,\n Refunds,\n Subscriptions,\n TaxRates,\n Tenant,\n WebhookEndpoints,\n} from \"./resources.js\";\nimport { Transport, type TransportConfig } from \"./transport.js\";\n\nexport interface BillKitOptions extends Omit<TransportConfig, \"apiKey\"> {\n /** Falls back to `process.env.BILLKIT_API_KEY` when omitted. */\n apiKey?: string;\n}\n\nfunction resolveApiKey(supplied: string | undefined): string {\n if (supplied) return supplied;\n const env = (globalThis.process as { env?: Record<string, string> } | undefined)?.env\n ?.[\"BILLKIT_API_KEY\"];\n if (env) return env;\n throw new Error(\n \"BillKit: missing API key. Pass { apiKey } or set BILLKIT_API_KEY in the environment.\",\n );\n}\n\nexport class BillKit {\n readonly apiKeys: ApiKeys;\n readonly customers: Customers;\n readonly products: Products;\n readonly prices: Prices;\n readonly checkoutSessions: CheckoutSessions;\n readonly oneShotPayments: OneShotPayments;\n readonly subscriptions: Subscriptions;\n readonly refunds: Refunds;\n readonly disputes: Disputes;\n readonly webhookEndpoints: WebhookEndpoints;\n readonly events: Events;\n readonly tenant: Tenant;\n readonly coupons: Coupons;\n readonly taxRates: TaxRates;\n readonly invoices: Invoices;\n readonly creditNotes: CreditNotes;\n readonly auditLogs: AuditLogs;\n readonly payments: Payments;\n readonly billingPortalSessions: BillingPortalSessions;\n\n constructor(options: BillKitOptions = {}) {\n const transport = new Transport({\n ...options,\n apiKey: resolveApiKey(options.apiKey),\n });\n this.apiKeys = new ApiKeys(transport);\n this.customers = new Customers(transport);\n this.products = new Products(transport);\n this.prices = new Prices(transport);\n this.checkoutSessions = new CheckoutSessions(transport);\n this.oneShotPayments = new OneShotPayments(transport);\n this.subscriptions = new Subscriptions(transport);\n this.refunds = new Refunds(transport);\n this.disputes = new Disputes(transport);\n this.webhookEndpoints = new WebhookEndpoints(transport);\n this.events = new Events(transport);\n this.tenant = new Tenant(transport);\n this.coupons = new Coupons(transport);\n this.taxRates = new TaxRates(transport);\n this.invoices = new Invoices(transport);\n this.creditNotes = new CreditNotes(transport);\n this.auditLogs = new AuditLogs(transport);\n this.payments = new Payments(transport);\n this.billingPortalSessions = new BillingPortalSessions(transport);\n }\n}\n","/**\n * Verify `BillKit-Signature: t=<unix>,v1=<hex>` headers.\n *\n * Works in Node 20+, Bun, Deno, Cloudflare Workers and the browser:\n * we use the Web Crypto API (`globalThis.crypto.subtle`) which is\n * available in all modern runtimes. The verifier:\n *\n * 1. Parses the header (rejects malformed shapes). A header may carry\n * more than one `v1=` value, because the server emits both the old and new\n * signature during a signing-secret rotation, and verification passes\n * if any of them matches.\n * 2. Confirms the timestamp is within `toleranceSeconds` of now\n * (replay protection).\n * 3. Computes the expected HMAC and compares against each candidate in\n * constant time.\n */\n\nexport const DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;\n\nexport class WebhookVerificationError extends Error {\n override name = \"WebhookVerificationError\";\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport interface VerifyWebhookOptions {\n payload: string | Uint8Array;\n signatureHeader: string | null | undefined;\n secret: string;\n toleranceSeconds?: number;\n nowMs?: number; // injectable for tests\n}\n\nconst textEncoder = new TextEncoder();\nconst V1_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\nfunction toBytes(payload: string | Uint8Array): Uint8Array {\n return typeof payload === \"string\" ? textEncoder.encode(payload) : payload;\n}\n\nfunction constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) {\n diff |= (a[i] ?? 0) ^ (b[i] ?? 0);\n }\n return diff === 0;\n}\n\nfunction hexToBytes(hex: string): Uint8Array | null {\n if (!V1_HEX_RE.test(hex)) return null;\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n const byte = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n if (Number.isNaN(byte)) return null;\n out[i] = byte;\n }\n return out;\n}\n\nfunction parseSignatureHeader(header: string): { ts: number; v1List: string[] } {\n let tsRaw: string | undefined;\n const v1List: string[] = [];\n for (const chunk of header.split(\",\")) {\n const idx = chunk.indexOf(\"=\");\n if (idx < 0) continue;\n const key = chunk.slice(0, idx).trim();\n const value = chunk.slice(idx + 1).trim();\n // A rotation can carry more than one ``v1=`` (old + new secret);\n // collect them all and let the verifier accept any match.\n if (key === \"t\") tsRaw = value;\n else if (key === \"v1\") v1List.push(value);\n }\n if (!tsRaw || v1List.length === 0) {\n throw new WebhookVerificationError(`Malformed BillKit-Signature header: ${header}`);\n }\n const ts = Number.parseInt(tsRaw, 10);\n if (Number.isNaN(ts) || ts <= 0) {\n throw new WebhookVerificationError(`Malformed timestamp in BillKit-Signature: ${tsRaw}`);\n }\n return { ts, v1List };\n}\n\nfunction toArrayBuffer(view: Uint8Array): ArrayBuffer {\n // ``Uint8Array.buffer`` is ``ArrayBufferLike`` (could be\n // ``SharedArrayBuffer``); SubtleCrypto wants a concrete\n // ``ArrayBuffer``. We copy into a fresh ArrayBuffer to bridge.\n const out = new ArrayBuffer(view.byteLength);\n new Uint8Array(out).set(view);\n return out;\n}\n\nasync function computeHmac(secret: string, signed: Uint8Array): Promise<Uint8Array> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new WebhookVerificationError(\n \"No SubtleCrypto available. The BillKit SDK requires Node 20+, Bun, Deno, \" +\n \"Cloudflare Workers, or any runtime that exposes globalThis.crypto.subtle.\",\n );\n }\n const key = await subtle.importKey(\n \"raw\",\n toArrayBuffer(textEncoder.encode(secret)),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const signature = await subtle.sign(\"HMAC\", key, toArrayBuffer(signed));\n return new Uint8Array(signature);\n}\n\nexport async function verifyWebhookSignature<T = unknown>(\n options: VerifyWebhookOptions,\n): Promise<T> {\n const {\n payload,\n signatureHeader,\n secret,\n toleranceSeconds = DEFAULT_WEBHOOK_TOLERANCE_SECONDS,\n nowMs = Date.now(),\n } = options;\n\n if (signatureHeader === null || signatureHeader === undefined) {\n throw new WebhookVerificationError(\"Missing BillKit-Signature header.\");\n }\n\n const { ts, v1List } = parseSignatureHeader(signatureHeader);\n if (Math.abs(nowMs / 1000 - ts) > toleranceSeconds) {\n throw new WebhookVerificationError(\n `Signature timestamp outside ±${toleranceSeconds}s tolerance.`,\n );\n }\n\n const payloadBytes = toBytes(payload);\n const signed = new Uint8Array(payloadBytes.length + textEncoder.encode(`${ts}.`).length);\n const prefix = textEncoder.encode(`${ts}.`);\n signed.set(prefix, 0);\n signed.set(payloadBytes, prefix.length);\n\n const expected = await computeHmac(secret, signed);\n // Compare against every candidate; don't break on the first match so\n // the loop's timing doesn't reveal which signature matched.\n let sawValidHex = false;\n let matched = false;\n for (const v1 of v1List) {\n const received = hexToBytes(v1);\n if (!received) continue;\n sawValidHex = true;\n if (constantTimeEqual(expected, received)) matched = true;\n }\n if (!sawValidHex) {\n throw new WebhookVerificationError(\n `Malformed v1 hex in BillKit-Signature: ${v1List.join(\",\")}`,\n );\n }\n if (!matched) {\n throw new WebhookVerificationError(\"Signature mismatch.\");\n }\n\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(payloadBytes);\n try {\n return JSON.parse(text) as T;\n } catch (err) {\n throw new WebhookVerificationError(\n `Webhook body is not valid JSON: ${(err as Error).message}`,\n );\n }\n}\n"]}
|