@openrails/billing-ui 0.248.0 → 0.249.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 +20 -0
- package/README.md +32 -27
- package/dist/buy-button.d.ts +9 -15
- package/dist/client/client.d.ts +12 -20
- package/dist/client/generated/error-codes.d.ts +1 -1
- package/dist/client/generated/routes.d.ts +8 -22
- package/dist/client/generated/wire.d.ts +42 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/types.d.ts +7 -3
- package/dist/{client-DoRYitD3.js → client-rFrCMrkn.js} +211 -226
- package/dist/client-rFrCMrkn.js.map +1 -0
- package/dist/client.js +1 -1
- package/dist/embedded-checkout.d.ts +5 -2
- package/dist/{hooks-DCSelDIZ.js → hooks-B1TffejB.js} +7 -20
- package/dist/hooks-B1TffejB.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +247 -235
- package/dist/index.js.map +1 -1
- package/dist/modal.d.ts +10 -1
- package/dist/product-list.d.ts +7 -13
- package/dist/react/hooks.d.ts +2 -15
- package/dist/react/index.d.ts +1 -1
- package/dist/react.js +2 -2
- package/package.json +1 -1
- package/dist/client-DoRYitD3.js.map +0 -1
- package/dist/hooks-DCSelDIZ.js.map +0 -1
package/dist/modal.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import { CheckoutAppearance } from './appearance';
|
|
2
|
+
import { EmbeddedCheckoutProps } from './embedded-checkout';
|
|
1
3
|
import { OrderCheckoutProps } from './order-checkout';
|
|
2
|
-
|
|
4
|
+
interface DialogProps {
|
|
3
5
|
open: boolean;
|
|
4
6
|
onOpenChange: (open: boolean) => void;
|
|
5
7
|
}
|
|
8
|
+
export interface OrderModalProps extends OrderCheckoutProps, DialogProps {
|
|
9
|
+
}
|
|
6
10
|
export declare function OrderModal({ open, onOpenChange, ...checkout }: OrderModalProps): import("react").JSX.Element;
|
|
11
|
+
export interface EmbeddedModalProps extends EmbeddedCheckoutProps, DialogProps {
|
|
12
|
+
appearance?: CheckoutAppearance;
|
|
13
|
+
}
|
|
14
|
+
export declare function EmbeddedModal({ open, onOpenChange, appearance, ...checkout }: EmbeddedModalProps): import("react").JSX.Element;
|
|
15
|
+
export {};
|
package/dist/product-list.d.ts
CHANGED
|
@@ -2,20 +2,12 @@ import { CheckoutAppearance } from './appearance';
|
|
|
2
2
|
import { Order, Product } from './client/types';
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
export interface ProductListProps {
|
|
5
|
-
/** The id of the merchant whose catalog `keys` are looked up in. */
|
|
6
|
-
merchant?: string;
|
|
7
5
|
/**
|
|
8
|
-
* What to sell
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* ListProducts finds the products granting an entitlement).
|
|
6
|
+
* What to sell, from the host's own server: the Go Client's ListProducts
|
|
7
|
+
* (by product key or entitlement), their prices as a buyer sees them
|
|
8
|
+
* (`billing.BuyerPrices`).
|
|
12
9
|
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* The products to display instead, from the host's own server (the Go
|
|
16
|
-
* Client's ListProducts): nothing is fetched.
|
|
17
|
-
*/
|
|
18
|
-
products?: Product[];
|
|
10
|
+
products: Product[];
|
|
19
11
|
/**
|
|
20
12
|
* The order is paid. A hint: the host's own gate decides access, so send
|
|
21
13
|
* the buyer back to the content it guards.
|
|
@@ -28,7 +20,9 @@ export interface ProductListProps {
|
|
|
28
20
|
onSignInRequired: () => void;
|
|
29
21
|
/** false when the host knows the visitor is signed out. */
|
|
30
22
|
signedIn?: boolean;
|
|
23
|
+
/** Where a redirect PSP (Stripe's hosted page) returns the buyer: one of the app's return origins. */
|
|
24
|
+
returnUrl?: string;
|
|
31
25
|
appearance?: CheckoutAppearance;
|
|
32
26
|
className?: string;
|
|
33
27
|
}
|
|
34
|
-
export declare function ProductList({ products,
|
|
28
|
+
export declare function ProductList({ products: given, onPaid, onSignInRequired, signedIn, returnUrl, appearance, className, }: ProductListProps): React.JSX.Element;
|
package/dist/react/hooks.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SendSolanaTransaction, SubscriptionChangeInput } from '../client/client';
|
|
2
2
|
import { BillingError } from '../client/errors';
|
|
3
|
-
import { NewCard, Order, Payment, PaymentMethod,
|
|
3
|
+
import { NewCard, Order, Payment, PaymentMethod, Subscription, SubscriptionChange } from '../client/types';
|
|
4
4
|
export type ActionResult = Promise<BillingError | null>;
|
|
5
5
|
/** `signing` and `confirming` are a wallet step's stages. */
|
|
6
6
|
export type SubscriptionAction = "cancel" | "resume" | "payment_method" | "change" | "signing" | "confirming";
|
|
@@ -37,19 +37,6 @@ export interface SubscriptionsState {
|
|
|
37
37
|
}, sendTransaction?: SendSolanaTransaction) => Promise<SubscriptionChange | BillingError>;
|
|
38
38
|
}
|
|
39
39
|
export declare function useSubscriptions(options?: SubscriptionsOptions): SubscriptionsState;
|
|
40
|
-
export interface ProductsState {
|
|
41
|
-
products: Product[] | null;
|
|
42
|
-
loading: boolean;
|
|
43
|
-
error: BillingError | null;
|
|
44
|
-
refetch: () => void;
|
|
45
|
-
}
|
|
46
|
-
/** The merchant and its product keys to look up: `ProductListOptions`. */
|
|
47
|
-
export type ProductsOptions = Pick<ProductListOptions, "merchant" | "keys">;
|
|
48
|
-
/**
|
|
49
|
-
* The products `merchant` has on sale named by `keys`, each with its active
|
|
50
|
-
* prices: a public catalog lookup.
|
|
51
|
-
*/
|
|
52
|
-
export declare function useProducts({ merchant, keys, }: ProductsOptions): ProductsState;
|
|
53
40
|
export type PaymentMethodAction = "remove" | "default";
|
|
54
41
|
export interface PaymentMethodsState {
|
|
55
42
|
methods: PaymentMethod[] | null;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { BillingProvider, type BillingProviderProps } from './provider';
|
|
2
2
|
export { useBillingClient, useBillingRefresh, useOptionalBillingContext, type BillingChange, type BillingContextValue, } from './context';
|
|
3
3
|
export { useConfig, useCurrencyScales, useCustomerConfig, type ConfigState, type ConfigStore, } from './config';
|
|
4
|
-
export { usePaymentMethods, usePayments,
|
|
4
|
+
export { usePaymentMethods, usePayments, useSubscriptions, type ActionResult, type PaymentMethodAction, type PaymentMethodsState, type PaymentsOptions, type PaymentsState, type SubscriptionAction, type SubscriptionsOptions, type SubscriptionsState, } from './hooks';
|
package/dist/react.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, c as t, d as n,
|
|
2
|
-
export {
|
|
1
|
+
import { a as e, c as t, d as n, i as r, n as i, o as a, r as o, s, t as c, u as l } from "./hooks-B1TffejB.js";
|
|
2
|
+
export { r as BillingProvider, t as useBillingClient, l as useBillingRefresh, e as useConfig, a as useCurrencyScales, s as useCustomerConfig, n as useOptionalBillingContext, c as usePaymentMethods, i as usePayments, o as useSubscriptions };
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client-DoRYitD3.js","names":[],"sources":["../src/client/errors.ts","../src/client/generated/currencies.ts","../src/client/token-source.ts","../src/psp.ts","../src/lib/money.ts","../src/client/types.ts","../src/client/client.ts"],"sourcesContent":["// Mirrors OpenRails internal/api.ErrorResponse:\n// {\"error\":{\"type\",\"code\",\"message\",\"request_id?\",\"param?\",\"metadata?\"}}.\nexport interface BillingErrorBody {\n type: string\n code: string\n message: string\n request_id?: string\n param?: string\n metadata?: Record<string, unknown>\n /** The order a failed payment left open (402 card_error). */\n order?: unknown\n}\n\n// Local codes: network_error, invalid_response, unknown_error, and the wallet\n// codes a wallet next action raises (wallet_rejected, wallet_no_signature,\n// wallet_required).\nexport class BillingError extends Error {\n readonly status: number\n readonly type: string\n readonly code: string\n readonly param?: string\n readonly requestId?: string\n readonly metadata: Record<string, unknown>\n /** The order a failed payment left open, unvalidated. */\n readonly order?: unknown\n\n constructor(status: number, body: BillingErrorBody) {\n super(body.message)\n this.name = \"BillingError\"\n this.status = status\n this.type = body.type\n this.code = body.code\n this.param = body.param\n this.requestId = body.request_id\n this.metadata = body.metadata ?? {}\n this.order = body.order\n }\n}\n\nexport const isBillingError = (value: unknown): value is BillingError =>\n value instanceof BillingError\n\n/** A server failure (HTTP 5xx) from any client or host source that carries a numeric `status`. */\nexport const isServerError = (value: unknown): boolean => {\n const status = (value as { status?: unknown } | null)?.status\n return typeof status === \"number\" && status >= 500 && status < 600\n}\n\nexport function localError(code: string, message: string): BillingError {\n return new BillingError(0, { type: \"local\", code, message })\n}\n\nexport async function readBillingError(res: Response): Promise<BillingError> {\n let body: unknown\n try {\n body = await res.json()\n } catch {\n body = undefined\n }\n const err = (body as { error?: unknown } | undefined)?.error\n if (err && typeof err === \"object\") {\n const e = err as Partial<BillingErrorBody>\n if (typeof e.code === \"string\" && e.code) {\n return new BillingError(res.status, {\n type: typeof e.type === \"string\" ? e.type : \"\",\n code: e.code,\n message: typeof e.message === \"string\" ? e.message : e.code,\n request_id:\n typeof e.request_id === \"string\"\n ? e.request_id\n : (res.headers.get(\"X-Request-ID\") ?? undefined),\n param: typeof e.param === \"string\" ? e.param : undefined,\n metadata:\n e.metadata && typeof e.metadata === \"object\" ? e.metadata : undefined,\n order: e.order,\n })\n }\n }\n return new BillingError(res.status, {\n type: res.status >= 500 ? \"api_error\" : \"\",\n code:\n typeof err === \"string\" && err\n ? err\n : res.status >= 500\n ? \"server_error\"\n : \"unknown_error\",\n message: `HTTP ${res.status}`,\n })\n}\n\n// Normalizes anything a client call can throw into a BillingError.\nexport function toBillingError(error: unknown): BillingError {\n if (error instanceof BillingError) return error\n if (error instanceof TypeError)\n return localError(\"network_error\", error.message)\n return localError(\n \"unknown_error\",\n error instanceof Error ? error.message : String(error)\n )\n}\n","// Generated by `go run ./scripts/contracts -write` from the currency registry (billing.Currencies). Do not edit.\n\n// Currency code to native-unit decimals.\nexport const OPENRAILS_CURRENCY_SCALES: Readonly<Record<string, number>> = {\n AED: 6,\n AUD: 6,\n BRL: 6,\n CAD: 6,\n CHF: 6,\n CNY: 6,\n CZK: 6,\n DKK: 6,\n EUR: 6,\n GBP: 6,\n HKD: 6,\n ILS: 6,\n INR: 6,\n JPY: 4,\n KRW: 4,\n MXN: 6,\n MYR: 6,\n NOK: 6,\n NZD: 6,\n PHP: 6,\n PLN: 6,\n PYUSD: 6,\n SAR: 6,\n SEK: 6,\n SGD: 6,\n SOL: 9,\n THB: 6,\n TRY: 6,\n USD: 6,\n USD1: 6,\n USDC: 6,\n USDG: 6,\n USDT: 6,\n ZAR: 6,\n}\n","import { localError, readBillingError } from \"./errors\"\n\n/** A token endpoint's answer (RFC 6749 §5.1). */\nexport interface TokenResponse {\n access_token: string\n /** Seconds until the token expires. */\n expires_in: number\n}\n\nexport interface TokenSourceOptions {\n /**\n * Asks the host for the customer's access token: one bound to the\n * merchant, from the host's own backend or `redeemAssertion`.\n */\n fetchToken: () => Promise<TokenResponse>\n /** Seconds before its expiry at which a token is replaced. Default 60. */\n skew?: number\n}\n\n/**\n * A `getToken` for `createBillingClient`: the current token, fetched when\n * there is none or the cached one is about to expire.\n */\nexport interface TokenSource {\n (): Promise<string>\n /**\n * Drops the cached token, so the next call fetches a new one. With\n * `token`, only when that is the one cached.\n */\n invalidate(token?: string): void\n}\n\n/**\n * Keeps the customer's access token for a billing client: it caches the\n * token until `skew` seconds before it expires and fetches the next one with\n * a single request, however many calls are waiting. A failed fetch is not\n * cached. Tokens stay in memory, never in browser storage, so a reload\n * fetches again. The client retries a call answered 401 `credential_expired`\n * once with a new token.\n */\nexport function tokenSource({\n fetchToken,\n skew = 60,\n}: TokenSourceOptions): TokenSource {\n let cached: { token: string; staleAt: number } | undefined\n let pending: Promise<string> | undefined\n\n const source = (): Promise<string> => {\n if (cached && Date.now() < cached.staleAt)\n return Promise.resolve(cached.token)\n pending ??= fetchToken()\n .then((answer) => {\n if (\n typeof answer?.access_token !== \"string\" ||\n !answer.access_token ||\n !Number.isFinite(answer.expires_in)\n )\n throw localError(\n \"invalid_response\",\n \"fetchToken answered no access_token and expires_in\"\n )\n cached = {\n token: answer.access_token,\n staleAt: Date.now() + (answer.expires_in - skew) * 1000,\n }\n return answer.access_token\n })\n .finally(() => {\n pending = undefined\n })\n return pending\n }\n source.invalidate = (token?: string) => {\n if (token === undefined || cached?.token === token) cached = undefined\n }\n return source\n}\n\n/** Whether `getToken` is a `tokenSource`, whose token the client can replace. */\nexport const isTokenSource = (getToken: unknown): getToken is TokenSource =>\n typeof getToken === \"function\" &&\n typeof (getToken as Partial<TokenSource>).invalidate === \"function\"\n\nexport interface RedeemAssertionOptions {\n /** The authorization server's token endpoint, such as `https://billing.example/oauth2/token`. */\n tokenEndpoint: string\n /**\n * The assertion the merchant's backend signed for this customer (RFC\n * 7523): single use and minutes long, so redeem each one once.\n */\n assertion: string\n /**\n * Transport. Pass a fetch that adds a DPoP proof (auth-ui's `dpopFetch`)\n * to bind the token to the browser's key.\n */\n fetch?: (input: string, init: RequestInit) => Promise<Response>\n}\n\n/**\n * Redeems a customer assertion for an access token to OpenRails\n * (`scope=openrails:self`): a `fetchToken` for `tokenSource`, after the\n * host's backend signed the assertion.\n */\nexport async function redeemAssertion(\n options: RedeemAssertionOptions\n): Promise<TokenResponse & { token_type: string }> {\n const doFetch =\n options.fetch ?? ((input: string, init: RequestInit) => fetch(input, init))\n const res = await doFetch(options.tokenEndpoint, {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n grant_type: \"urn:ietf:params:oauth:grant-type:jwt-bearer\",\n assertion: options.assertion,\n scope: \"openrails:self\",\n }).toString(),\n })\n if (!res.ok) throw await readBillingError(res)\n const answer = (await res.json().catch(() => null)) as Record<\n string,\n unknown\n > | null\n if (\n typeof answer?.access_token !== \"string\" ||\n typeof answer.expires_in !== \"number\"\n )\n throw localError(\n \"invalid_response\",\n \"the token endpoint answered no access_token and expires_in\"\n )\n return {\n access_token: answer.access_token,\n expires_in: answer.expires_in,\n token_type:\n typeof answer.token_type === \"string\" ? answer.token_type : \"Bearer\",\n }\n}\n","// OpenRails's browser-safe PSP projection (GET /config's payment). Which\n// browser flow a PSP needs is decided here, never by the host.\nimport { z } from \"zod\"\n\nexport const pspConfigSchema = z.object({\n psp_id: z.string().min(1),\n /** The PSP's key. */\n key: z.string().min(1),\n rail: z.string(),\n /** Who holds the card: \"psp\" or a third-party custodian. */\n custodian: z.string(),\n display_name: z.string(),\n /** `tokenize | card | elements | redirect | wallet` */\n flow: z.string(),\n config: z.record(z.string(), z.string()).nullish(),\n /**\n * New purchases and new cards use this PSP (the operator's checkout PSP).\n * Other PSPs stay listed so existing cards and subscriptions keep working.\n */\n checkout: z.boolean().nullish(),\n /**\n * `temporarily_unavailable`: the PSP could not be checked just now and is\n * listed without `config`; ask again after `retry_after` seconds.\n */\n status: z.string().nullish(),\n retry_after: z.number().int().nullish(),\n})\nexport type PspConfig = z.infer<typeof pspConfigSchema>\n\n/** PSPs that take new purchases and new cards. */\nexport const checkoutPsps = (psps: readonly PspConfig[]): PspConfig[] =>\n psps.filter((psp) => psp.checkout !== false)\n\nconst cardFlows = new Set([\"tokenize\", \"card\", \"elements\"])\n\n/**\n * Seconds until a card PSP listed as temporarily unavailable is worth asking\n * for again; null when none is.\n */\nexport function cardRetryAfter(psps: readonly PspConfig[]): number | null {\n const waits = psps\n .filter(\n (psp) =>\n !!psp.status && psp.custodian === \"psp\" && cardFlows.has(psp.flow)\n )\n .map((psp) => psp.retry_after ?? 30)\n return waits.length > 0 ? Math.min(...waits) : null\n}\n\nexport type CardSetupDriver = \"collect_js\" | \"card\" | \"stripe_elements\"\n\nconst usable = (value?: string) => !!value && !value.startsWith(\"preview_\")\n\nconst stripeKey = (psp: PspConfig) =>\n psp.rail === \"stripe\" && !!psp.config?.publishable_key?.startsWith(\"pk_\")\n\n/** How a card is saved with this PSP in the page, or null when it cannot be. */\nexport function cardSetupDriver(psp: PspConfig): CardSetupDriver | null {\n if (psp.custodian !== \"psp\" || psp.status) return null\n // The PSP takes cards on OpenRails itself (card_entry: server).\n if (psp.flow === \"card\" && psp.rail === \"nmi\") return \"card\"\n if (\n psp.flow === \"tokenize\" &&\n usable(psp.config?.tokenization_key) &&\n !!psp.config?.tokenization_url\n )\n return \"collect_js\"\n if (stripeKey(psp)) return \"stripe_elements\"\n return null\n}\n\nexport const canSavePaymentMethod = (psp: PspConfig): boolean =>\n cardSetupDriver(psp) !== null\n\n/** Whether a pending payment on this PSP can be authenticated in the page. */\nexport const canAuthenticatePayment = (psp: PspConfig): boolean =>\n cardSetupDriver(psp) === \"stripe_elements\"\n","// Exact money. Every amount OpenRails serves is a signed int64 decimal string\n// of the plan currency's native unit, at plan.unit_decimals (the currency\n// registry's scale). Amounts are scaled with BigInt, never a JS number; only\n// the exact major-unit decimal reaches Intl.\n\n// Amount is an int64 decimal string, e.g. \"99000000\" (99 USD at 6 decimals).\nexport type Amount = string\n\nconst INT64_MIN = -(1n << 63n)\nconst INT64_MAX = (1n << 63n) - 1n\nexport const MAX_UNIT_DECIMALS = 18\n\n// amountUnits parses an exact int64 decimal string, or null.\nexport function amountUnits(amount: unknown): bigint | null {\n if (typeof amount !== \"string\" || !/^-?\\d{1,19}$/.test(amount)) return null\n const value = BigInt(amount)\n return value < INT64_MIN || value > INT64_MAX ? null : value\n}\n\nexport function isAmount(value: unknown): value is Amount {\n return amountUnits(value) !== null\n}\n\nexport function isUnitDecimals(value: unknown): value is number {\n return (\n typeof value === \"number\" &&\n Number.isInteger(value) &&\n value >= 0 &&\n value <= MAX_UNIT_DECIMALS\n )\n}\n\n// addAmounts sums exact amounts; null when an input or the sum leaves int64.\nexport function addAmounts(...amounts: Amount[]): Amount | null {\n let total = 0n\n for (const amount of amounts) {\n const units = amountUnits(amount)\n if (units === null) return null\n total += units\n }\n return total < INT64_MIN || total > INT64_MAX ? null : total.toString()\n}\n\n// Intl.NumberFormat formats a decimal string exactly only since ECMA-402 2023\n// (Chrome/Edge 106, Firefox 116, Safari 15.4); older engines coerce it through\n// Number. Probed once with 2^53 + 1, which a Number cannot hold.\nexport const intlFormatsDecimalStringsExactly: boolean = (() => {\n try {\n return (\n new Intl.NumberFormat(\"en\", { useGrouping: false }).format(\n \"9007199254740993\" as `${number}`\n ) === \"9007199254740993\"\n )\n } catch {\n return false\n }\n})()\n\n// Below 10^15 native units a Number-coerced decimal still rounds back to the\n// exact digits at every registry scale; from 10^15 the coerced value can differ\n// in the last digit, so a legacy engine refuses instead of misformatting.\nconst LEGACY_EXACT_UNITS = 10n ** 15n\n\nfunction decimalFromUnits(value: bigint, decimals: number): string {\n const absolute = value < 0n ? -value : value\n const scale = 10n ** BigInt(decimals)\n const fraction = (absolute % scale)\n .toString()\n .padStart(decimals, \"0\")\n .replace(/0+$/, \"\")\n return `${value < 0n ? \"-\" : \"\"}${absolute / scale}${fraction ? `.${fraction}` : \"\"}`\n}\n\n// amountToDecimal renders native units as the exact major-unit decimal with\n// trailing zeros trimmed (\"99000000\" at 6 -> \"99\", \"1234567\" -> \"1.234567\"),\n// or null when the amount or scale is invalid.\nexport function amountToDecimal(\n amount: Amount,\n decimals: number\n): string | null {\n const units = amountUnits(amount)\n if (units === null || !isUnitDecimals(decimals)) return null\n return decimalFromUnits(units, decimals)\n}\n\n// amountToMinorUnits is an amount in the provider's minor units (Stripe's\n// `amount`: \"12500000\" USD at 6 and 2 -> 1250), or null when the amount is not\n// a whole number of them or leaves the exact range of a JS number.\nexport function amountToMinorUnits(\n amount: Amount,\n decimals: number,\n minorDecimals: number\n): number | null {\n const units = amountUnits(amount)\n if (\n units === null ||\n !isUnitDecimals(decimals) ||\n !isUnitDecimals(minorDecimals) ||\n minorDecimals > decimals\n )\n return null\n const scale = 10n ** BigInt(decimals - minorDecimals)\n if (units % scale !== 0n) return null\n const minor = units / scale\n return minor > BigInt(Number.MAX_SAFE_INTEGER) ||\n minor < -BigInt(Number.MAX_SAFE_INTEGER)\n ? null\n : Number(minor)\n}\n\n// decimalToAmount parses a major-unit decimal exactly (\"100.25\" at 6 ->\n// \"100250000\"). Excess precision, scientific notation and int64 overflow\n// are refused; input is never rounded or converted through a JS number.\nexport function decimalToAmount(\n decimal: string,\n decimals: number\n): Amount | null {\n if (!isUnitDecimals(decimals) || decimal.length > 40) return null\n const match = /^(-?)(\\d+)(?:\\.(\\d+))?$/.exec(decimal)\n if (!match) return null\n const fraction = match[3] ?? \"\"\n if (fraction.length > decimals) return null\n const units =\n BigInt(match[2]) * 10n ** BigInt(decimals) +\n BigInt(fraction.padEnd(decimals, \"0\") || \"0\")\n const signed = match[1] ? -units : units\n return signed < INT64_MIN || signed > INT64_MAX ? null : signed.toString()\n}\n\n// formatAmount renders an exact amount in its currency for the buyer. It never\n// passes money through a JS number; an amount it cannot show exactly is\n// refused with a visible notice rather than a rounded figure.\nexport function formatAmount(\n amount: Amount | null | undefined,\n currency: string,\n decimals: number,\n locale?: string\n): string {\n const code = currency.trim().toUpperCase()\n const units = amountUnits(amount)\n if (units === null || !isUnitDecimals(decimals))\n return `${code} amount exceeds the exact display range`\n if (\n !intlFormatsDecimalStringsExactly &&\n (units >= LEGACY_EXACT_UNITS || units <= -LEGACY_EXACT_UNITS)\n )\n return `${code} amount exceeds this browser's exact display range`\n const decimal = decimalFromUnits(units, decimals) as `${number}`\n try {\n return new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency: code,\n maximumFractionDigits: decimals,\n }).format(decimal)\n } catch {\n return `${decimal} ${code}`\n }\n}\n","// Wire types of the OpenRails customer surface (`/billing/v1/me/*`) and public\n// catalog, validated at the boundary. Money is an int64 string in the\n// currency's native unit; its scale comes from GET /config's currencies.\n// Fixtures: the repository's canonical testdata/wire.\nimport { z } from \"zod\"\n\nimport { pspConfigSchema } from \"../psp\"\n\nimport type { CardEntry } from \"../lib/card-entry\"\nimport { isAmount } from \"../lib/money\"\n\nimport type * as wire from \"./generated/wire\"\n\nconst amount = z.string().refine(isAmount, \"amount must be an int64 string\")\nconst time = z.string()\n\nexport const pageSchema = <T extends z.ZodType>(item: T) =>\n z.object({\n data: z\n .array(item)\n .nullish()\n .transform((v) => v ?? []),\n total: z.number().nullish(),\n limit: z.number().nullish(),\n offset: z.number().nullish(),\n has_more: z.boolean().nullish(),\n next_cursor: z.string().nullish(),\n })\n\nexport interface Page<T> {\n data: T[]\n total?: number | null\n limit?: number | null\n offset?: number | null\n has_more?: boolean | null\n /** The next page's cursor; null on the last page of a cursor list. */\n next_cursor?: string | null\n}\n\n/** One page of a cursor list; `next_cursor` is null on the last page. */\nexport const listPageSchema = <T extends z.ZodType>(item: T) =>\n z.object({\n data: z\n .array(item)\n .nullish()\n .transform((v) => v ?? []),\n next_cursor: z\n .string()\n .nullish()\n .transform((v) => v ?? null),\n })\n\nexport interface ListPage<T> {\n data: T[]\n next_cursor: string | null\n}\n\nexport const subscriptionStatusSchema = z.string()\n/** `pending | active | past_due | awaiting_method | unverified | canceled`; kept open for new values. */\nexport type SubscriptionStatus =\n | \"pending\"\n | \"active\"\n | \"past_due\"\n | \"awaiting_method\"\n | \"unverified\"\n | \"canceled\"\n | (string & {})\n\nexport const pspLinkStateSchema = z.object({\n /** `linked | pending_manual_link | sync_disabled | error` */\n status: z.string(),\n ids: z.record(z.string(), z.string()).nullish(),\n sync_status: z.string().nullish(),\n})\n\n/**\n * A catalog price, embedded in a product (`GET /products`): `unit_amount` of\n * `currency` for `access_duration_hours` of access (null: for good),\n * charging every `billing_interval_hours` (null: one-time).\n */\nexport const priceSchema = z.object({\n id: z.string(),\n key: z.string(),\n /** The price key's revision: every change to any of its versions; absent on older servers. */\n revision: z.number().int().nonnegative().optional(),\n /** This price's terms within its key, from zero; absent on older servers. */\n version: z.number().int().nonnegative().optional(),\n product_id: z.string(),\n archived: z.boolean(),\n unit_amount: amount,\n /** Optional bounds for a deposit whose amount is selected before checkout. */\n customer_amount: z\n .object({ min_amount: amount, max_amount: amount })\n .nullish(),\n currency: z.string(),\n access_duration_hours: z.number().nullable(),\n billing_interval_hours: z.number().nullable(),\n trial_unit_amount: amount.nullable(),\n trial_duration_hours: z.number().nullable(),\n /** Keyed by PSP key. */\n psps: z.record(z.string(), pspLinkStateSchema).nullish(),\n created_at: time,\n updated_at: time,\n})\nexport type Price = z.infer<typeof priceSchema>\n\nexport const subscriptionProductSchema = z.object({\n id: z.string(),\n key: z.string().nullish(),\n revision: z.number().int().nonnegative().optional(),\n display_name: z.string().nullish(),\n description: z.string().nullish(),\n tier_group: z.string().nullish(),\n tier_rank: z.number().nullish(),\n})\nexport type SubscriptionProduct = z.infer<typeof subscriptionProductSchema>\n\nexport const cardSummarySchema = z.object({\n brand: z.string().nullish(),\n last4: z.string().nullish(),\n exp_month: z.number().nullish(),\n exp_year: z.number().nullish(),\n})\nexport type CardSummary = z.infer<typeof cardSummarySchema>\n\nexport const paymentRecoverySchema = z.object({\n last_failure_reason: z.string().nullish(),\n retryable: z.boolean(),\n blocked_reason: z.string().nullish(),\n /** An engine-owned subscription's unpaid renewal: the order to pay. */\n order_id: z.string().nullish(),\n})\nexport type PaymentRecovery = z.infer<typeof paymentRecoverySchema>\n\n/**\n * What the customer completes before an action or payment can finish:\n * `authenticate` runs the PSP's own script with `payload` (Stripe.js\n * `handleNextAction` with `client_secret`), then the payable is confirmed;\n * `redirect_to_url` leaves for `url`; with `solana_sign_transactions` the\n * wallet signs and sends `transactions` in order and the action is repeated\n * with the last signature. `capture` initializes vendor-owned card fields\n * from the scoped payload, then confirms the pending payment method with\n * the vendor session token. Capturing never charges the card.\n */\nexport const nextActionSchema = z.object({\n type: z.string(),\n url: z.string().nullish(),\n psp_id: z.string().nullish(),\n transactions: z.array(z.string()).nullish(),\n payload: z.record(z.string(), z.string()).nullish(),\n})\nexport type NextAction = z.infer<typeof nextActionSchema>\n\n/**\n * A declined renewal being collected. `retries_left` and `final_retry_at`\n * follow the merchant's dunning policy; both are null when the provider runs\n * the retries. While `waiting_for_new_card`, nothing is charged until the card\n * is replaced, and the subscription ends at `final_retry_at`.\n */\nexport const subscriptionDunningSchema = z.object({\n attempts: z.number(),\n retries_left: z.number().nullish(),\n next_retry_at: time.nullish(),\n final_retry_at: time.nullish(),\n waiting_for_new_card: z.boolean(),\n last_failure_reason: z.string().nullish(),\n})\nexport type SubscriptionDunning = z.infer<typeof subscriptionDunningSchema>\n\nexport const subscriptionSchema = z.object({\n id: z.string(),\n status: subscriptionStatusSchema,\n rail: z.string().nullish(),\n product_id: z.string().nullish(),\n price_id: z.string().nullish(),\n /** Seats of a per-seat price; null otherwise. */\n quantity: z.number().nullish(),\n psp_id: z.string().nullish(),\n /** `engine | nmi_schedule | provider` */\n collection_policy: z.string().nullish(),\n /** The subscription's own card; null follows the default card. */\n payment_method_id: z.string().nullish(),\n started_at: time.nullish(),\n ended_at: time.nullish(),\n current_period_starts_at: time.nullish(),\n current_period_ends_at: time.nullish(),\n canceled_at: time.nullish(),\n cancel_type: z.string().nullish(),\n resumable: z.boolean().nullish(),\n cancel_scheduled: z.boolean().nullish(),\n /** `reversible | destructive | external_portal` */\n cancel_mode: z.string().nullish(),\n cancel_portal_url: z.string().nullish(),\n access: z.object({ starts_at: time, ends_at: time.nullish() }).nullish(),\n /** Null unless the subscription is `past_due` or `awaiting_method`. */\n dunning: subscriptionDunningSchema.nullish(),\n price: priceSchema.nullish(),\n product: subscriptionProductSchema.nullish(),\n /** The change waiting for the next renewal, with its price and product. */\n scheduled_change: z\n .object({\n price_id: z.string(),\n quantity: z.number().nullish(),\n effective_at: time,\n /** `change | migration` */\n source: z.string(),\n price: priceSchema.nullish(),\n product: subscriptionProductSchema.nullish(),\n })\n .nullish(),\n card: cardSummarySchema.nullish(),\n recovery: paymentRecoverySchema.nullish(),\n /** Set on an action's answer when the rail needs the customer's step. */\n next_action: nextActionSchema.nullish(),\n created_at: time.nullish(),\n updated_at: time.nullish(),\n})\nexport type Subscription = z.infer<typeof subscriptionSchema> & {\n status: SubscriptionStatus\n}\n\nexport const billingDetailsSchema = z.object({\n name: z.string().nullish(),\n email: z.string().nullish(),\n phone: z.string().nullish(),\n address: z\n .object({\n line1: z.string().nullish(),\n line2: z.string().nullish(),\n city: z.string().nullish(),\n state: z.string().nullish(),\n postal_code: z.string().nullish(),\n country: z.string().nullish(),\n })\n .nullish(),\n})\nexport type BillingDetails = z.infer<typeof billingDetailsSchema>\n\nexport const paymentMethodSchema = z.object({\n id: z.string(),\n /** `requires_action` while vendor card entry or bank authentication waits. */\n status: z.string().nullish(),\n /** Vendor card capture or the bank's authentication of a card being saved. */\n next_action: z\n .object({\n type: z.string(),\n psp_id: z.string().nullish(),\n payload: z.record(z.string(), z.string()).nullish(),\n })\n .nullish(),\n rail: z.string().nullish(),\n /** The PSP holding the card; null for a card a custodian holds. */\n psp_id: z.string().nullish(),\n card: cardSummarySchema.nullish(),\n billing_details: billingDetailsSchema.nullish(),\n /** Kept for one-click buys; a card stored only for a subscription is not. */\n reusable: z.boolean().nullish(),\n health: z\n .object({\n /** `valid | expiring_soon | expired` */\n expiry_status: z.string().nullish(),\n last_charged_at: time.nullish(),\n last_charge_outcome: z.string().nullish(),\n active: z.boolean().nullish(),\n })\n .nullish(),\n subscriptions: z\n .array(\n z.object({\n id: z.string(),\n display_name: z.string().nullish(),\n })\n )\n .nullish(),\n /** Currencies whose usage orders this card pays. */\n default_currencies: z.array(z.string()).nullish(),\n created_at: time.nullish(),\n})\nexport type PaymentMethod = z.infer<typeof paymentMethodSchema>\n\n/** Why the latest payment attempt failed, in the customer's words. */\nexport const paymentFailureSchema = z.object({\n reason: z.string(),\n message: z.string(),\n field: z.string().nullish(),\n})\nexport type PaymentFailure = z.infer<typeof paymentFailureSchema>\n\n/**\n * One line of an order. A purchased line names its price and product; a\n * usage order's line names its accrual source (`metered:<meter>`) instead.\n */\nexport const orderLineSchema = z.object({\n id: z.string(),\n price_id: z.string().nullish(),\n product_id: z.string().nullish(),\n source: z.string().nullish(),\n description: z.string(),\n quantity: z.number().nullish(),\n unit_amount: amount,\n amount: amount,\n billing_interval_hours: z.number().nullish(),\n access_duration_hours: z.number().nullish(),\n subscription_id: z.string().nullish(),\n product_access_id: z.string().nullish(),\n})\nexport type OrderLine = z.infer<typeof orderLineSchema>\n\n/**\n * A purchase, a subscription's renewal (`origin: subscription`) or usage\n * billed in arrears (`origin: usage`): frozen lines and total, read and paid\n * by its own customer. `status` is the order's (`open | processing |\n * complete | canceled | expired | void | uncollectible`); `payment.status`\n * its payment's (`requires_payment_method | requires_action | processing |\n * succeeded`).\n */\nexport const orderSchema = z.object({\n id: z.string(),\n customer_id: z.string(),\n origin: z.string(),\n /** Only `engine` orders accept generic payment commands. */\n collection_owner: z.string().nullish(),\n collection_psp_id: z.string().nullish(),\n provider_bills: z.array(z.object({\n psp_id: z.string(),\n kind: z.string(),\n reference: z.string(),\n settlement_source: z.string().nullish(),\n non_cash_amount: amount,\n settled_at: time.nullish(),\n })).nullish().transform((bills) => bills ?? []),\n status: z.string(),\n number: z.string().nullish(),\n currency: z.string(),\n total: amount,\n lines: z.array(orderLineSchema),\n payment: z.object({\n status: z.string(),\n next_action: nextActionSchema.nullish(),\n last_payment_error: paymentFailureSchema.nullish(),\n payment_method_id: z.string().nullish(),\n payment_id: z.string().nullish(),\n }),\n payment_options: z\n .array(\n z.object({\n psp_id: z.string(),\n rail: z.string(),\n accepts: z.array(z.string()),\n })\n )\n .nullish()\n .transform((v) => v ?? []),\n /** The order's hosted checkout; `url` only on the answer that made it. */\n checkout: z\n .object({\n url: z.string().nullish(),\n /** `hosted`, or `embedded` in the merchant's registered origins. */\n ui_mode: z.enum([\"hosted\", \"embedded\"]).catch(\"hosted\"),\n expires_at: time,\n success_url: z.string(),\n cancel_url: z.string().nullish(),\n saved_payment_methods: z.boolean(),\n })\n .nullish(),\n renewal: z\n .object({\n subscription_id: z.string(),\n period_starts_at: time,\n period_ends_at: time,\n due_at: time,\n })\n .nullish(),\n /**\n * A usage order's period, when it is due and how much of it is paid (a\n * funded balance and remittances pay part of it). `delinquent`: overdue\n * past grace, so new usage in its currency is refused until it is paid.\n */\n usage: z\n .object({\n period_starts_at: time,\n period_ends_at: time,\n due_at: time,\n amount_paid: amount,\n amount_due: amount,\n collection_method: z.string(),\n next_collection_attempt_at: time.nullish(),\n po_number: z.string().nullish(),\n memo: z.string().nullish(),\n delinquent: z.boolean(),\n })\n .nullish(),\n expires_at: time.nullish(),\n completed_at: time.nullish(),\n canceled_at: time.nullish(),\n expired_at: time.nullish(),\n voided_at: time.nullish(),\n uncollectible_at: time.nullish(),\n created_at: time,\n})\nexport type Order = z.infer<typeof orderSchema>\n\n/** Why a line cannot be bought: `already_owned`, `unavailable`, ... */\nexport const orderLineRefusalSchema = z.object({\n code: z.string(),\n message: z.string(),\n owned_by: z.string().nullish(),\n hint: z.string().nullish(),\n})\nexport type OrderLineRefusal = z.infer<typeof orderLineRefusalSchema>\n\n/** One line priced as an order would freeze it, or why it cannot be bought. */\nexport const orderPreviewLineSchema = z.object({\n price_id: z.string(),\n product_id: z.string(),\n description: z.string(),\n quantity: z.number().nullish(),\n unit_amount: amount,\n amount: amount,\n ownership: z.string(),\n billing_interval_hours: z.number().nullish(),\n access_duration_hours: z.number().nullish(),\n refusal: orderLineRefusalSchema.nullish(),\n})\nexport type OrderPreviewLine = z.infer<typeof orderPreviewLineSchema>\n\n/**\n * The customer's cart, priced live: one per customer of a merchant, shared by\n * the merchant's sites. `last_changed_at` and `expires_at` are null while it\n * is empty.\n */\nexport const cartSchema = z.object({\n currency: z.string(),\n total: amount,\n lines: z.array(orderPreviewLineSchema),\n payment_options: orderSchema.shape.payment_options,\n last_changed_at: time.nullish(),\n expires_at: time.nullish(),\n})\nexport type Cart = z.infer<typeof cartSchema>\n\n/**\n * How to pay an order: a saved card, a card just entered (the token of the\n * PSP's own fields, its `psp_id`), a Solana wallet (`token_symbol`, the\n * token it pays in) or the PSP's hosted page (`return_url`).\n */\nexport type OrderPaymentInput =\n | { payment_method_id: string }\n | {\n token: string\n psp_id?: string\n billing_details?: NewCard[\"billing_details\"]\n }\n | { token_symbol: string; psp_id?: string }\n | { return_url: string; psp_id?: string }\n\n/** A price's state on one PSP; public routes carry the status only. */\nexport const productSchema = z.object({\n id: z.string(),\n key: z.string(),\n /** Current mutation counter; absent on older servers. */\n revision: z.number().int().nonnegative().optional(),\n display_name: z.string(),\n description: z.string(),\n /** Opaque entitlement keys granted by the product. */\n entitlements: z.array(z.string()),\n /** Prepaid balance fulfilled once for each qualifying successful payment. */\n credit_grant: z\n .object({\n currency: z.string(),\n amount: amount.nullish(),\n from_payment: z.boolean().optional(),\n expires_after_days: z.number().int().positive().nullish(),\n })\n .nullish(),\n /** Products sharing a group are tiers a subscription can change between. */\n tier_group: z.string().nullable(),\n tier_rank: z.number(),\n archived: z.boolean(),\n prices: z\n .array(priceSchema)\n .nullish()\n .transform((v) => v ?? []),\n created_at: time,\n updated_at: time,\n})\nexport type Product = z.infer<typeof productSchema>\n\nexport const paymentSchema = z.object({\n id: z.string(),\n /** `charge | refund | chargeback | dispute_reversal` */\n kind: z.string(),\n /** `succeeded | pending | failed | refunded | partially_refunded` */\n status: z.string(),\n /** Negative for a refund or chargeback. */\n amount: amount,\n amount_refunded: amount.nullish(),\n currency: z.string(),\n subscription_id: z.string().nullish(),\n /** The bill this money movement settles or reverses. */\n order_id: z.string().nullish(),\n /** `rail | manual | admin` */\n channel: z.string().nullish(),\n rail: z.string().nullish(),\n created_at: time,\n card: cardSummarySchema.nullish(),\n /** Normalized decline of a failed payment. */\n failure: z\n .object({\n reason: z.string(),\n message: z.string(),\n field: z.string().nullish(),\n })\n .nullish(),\n})\nexport type Payment = z.infer<typeof paymentSchema>\n\n/**\n * An entitlement key the customer holds through a product. `quantity` is the\n * most seats a held per-seat product grants it; null when none is per seat.\n */\nexport const customerEntitlementSchema: z.ZodType<wire.CustomerEntitlement> =\n z.object({\n customer_id: z.string(),\n entitlement: z.string(),\n quantity: z.number().int().nullable(),\n })\nexport type CustomerEntitlement = wire.CustomerEntitlement\n\n/**\n * A customer's money in one currency, as of `as_of`. `accrued_amount` is what\n * its running charges have charged and the ledger does not hold yet, already\n * taken off `available_amount`; until `depletes_at` (null with no running\n * charge) show `available_amount - accrual_rate_per_hour x hours since as_of`.\n */\nexport const balanceSchema = z.object({\n currency: z.string(),\n billing_mode: z.string(),\n balance_amount: amount,\n held_amount: amount,\n accrued_amount: amount,\n available_amount: amount,\n owed_amount: amount,\n accrual_rate_per_hour: amount,\n as_of: z.string(),\n depletes_at: z.string().nullable(),\n})\nexport type Balance = z.infer<typeof balanceSchema>\n\n/**\n * The low-balance line a balance is judged at: the customer is told when what\n * it may spend is under the larger of `amount` and its burn rate times\n * `runway_hours`. `source` is `customer`, `merchant` or `default`.\n */\nexport const lowBalanceLineSchema = z.object({\n currency: z.string(),\n amount: amount,\n runway_hours: z.number().int(),\n source: z.enum([\"customer\", \"merchant\", \"default\"]),\n})\nexport type LowBalanceLine = z.infer<typeof lowBalanceLineSchema>\n\n/**\n * The signed-in customer's summary (`GET /me`): money per currency, the\n * default card of each currency, and the low-balance line of each balance.\n */\nexport const accountSchema = z.object({\n id: z.string(),\n balances: z.array(balanceSchema),\n default_payment_methods: z.array(\n z.object({ currency: z.string(), payment_method_id: z.string() })\n ),\n low_balance_lines: z.array(lowBalanceLineSchema),\n})\nexport type Account = z.infer<typeof accountSchema>\n\n/**\n * One group of a usage report: its events and their total `amount`.\n * `dimensions` are the summed event dimensions when grouped by event type.\n * Grouped by meter, `key` is the meter, `cell` its matrix cell and\n * `quantity` what it priced.\n */\nexport const usageRowSchema = z.object({\n key: z.string(),\n cell: z.string().nullish(),\n event_count: z.number(),\n amount,\n quantity: z.number().nullish(),\n dimensions: z.record(z.string(), z.number()).nullish(),\n})\nexport type UsageRow = z.infer<typeof usageRowSchema>\n\n/**\n * One page of the customer's usage in `currency` over [`from`, `to`): its\n * groups by total amount, largest first, then by key. `next_cursor` reads the\n * next page; null on the last.\n */\nexport const usageSchema = z.object({\n customer_id: z.string(),\n currency: z.string(),\n from: time,\n to: time,\n /** `event_type | resource | invoker`; kept open for new values. */\n group_by: z.string(),\n rows: z.array(usageRowSchema),\n next_cursor: z\n .string()\n .nullish()\n .transform((v) => v ?? null),\n})\nexport type Usage = z.infer<typeof usageSchema>\n\n/** Currency code (upper case) to its native-unit scale. */\nexport type CurrencyScales = Readonly<Record<string, number>>\n\nexport const currencySchema = z.object({\n code: z.string(),\n /** Native-unit decimals of every amount on the wire. */\n decimals: z.number(),\n /** Decimals the provider settles in. */\n minor_decimals: z.number().nullish(),\n})\nexport type Currency = z.infer<typeof currencySchema>\n\nexport const subscriptionChangePreviewSchema = z.object({\n price_id: z.string(),\n /** Seats of a per-seat price; null otherwise. */\n quantity: z.number().nullish(),\n rail: z.string().nullish(),\n currency: z.string(),\n /** Charged immediately; `\"0\"` for a change at period end. */\n amount_due_now: amount,\n /** The new price, charged at the next renewal. */\n next_charge_amount: amount,\n next_charge_date: time.nullish(),\n /** `now | period_end` */\n effective: z.string(),\n /** The rail finalizes the exact amount (Stripe provider changes). */\n is_estimate: z.boolean().nullish(),\n message: z.string().nullish(),\n})\nexport type SubscriptionChangePreview = z.infer<\n typeof subscriptionChangePreviewSchema\n>\n\nexport const subscriptionChangeSchema = z.object({\n /** `succeeded | processing | requires_action | blocked` */\n status: z.string(),\n /** `now | period_end` */\n effective: z.string().nullish(),\n price_id: z.string().nullish(),\n quantity: z.number().nullish(),\n /** The subscription now carrying the plan (an upgrade may open a successor). */\n subscription_id: z.string().nullish(),\n /** On `requires_action`: complete it, then `confirmSubscriptionChange`. */\n next_action: nextActionSchema.nullish(),\n /** When a change at period end takes effect. */\n delayed_start: time.nullish(),\n currency: z.string().nullish(),\n amount_due_now: amount.nullish(),\n next_charge_amount: amount.nullish(),\n next_charge_date: time.nullish(),\n message: z.string().nullish(),\n})\nexport type SubscriptionChange = z.infer<typeof subscriptionChangeSchema>\n\n/**\n * The merchant's browser payment setup: its armed PSPs with their public\n * values and, with a Solana PSP, the network and accepted tokens a wallet\n * adapter is configured with.\n */\nexport const paymentConfigSchema = z.object({\n psps: z\n .array(pspConfigSchema)\n .nullish()\n .transform((v) => v ?? []),\n solana: z\n .object({\n /** `mainnet | devnet | testnet` */\n network: z.string(),\n /** `solana:<network>` */\n chain: z.string(),\n preferred_token: z.string().nullish(),\n tokens: z\n .array(\n z.object({\n symbol: z.string(),\n name: z.string().nullish(),\n mint: z.string(),\n decimals: z.number().int(),\n preferred: z.boolean().nullish(),\n recurring_eligible: z.boolean().nullish(),\n })\n )\n .nullish()\n .transform((v) => v ?? []),\n })\n .nullish(),\n})\nexport type PaymentConfig = z.infer<typeof paymentConfigSchema>\n\n/**\n * The challenge to solve when a request answers 403 `captcha_required`: load\n * `script_url`, solve with `site_key` and `action`, and resend the request\n * with the token in the `token_header` header.\n */\nexport const captchaConfigSchema = z.object({\n provider: z.string(),\n site_key: z.string(),\n script_url: z.string(),\n action: z.string(),\n token_header: z.string(),\n})\nexport type CaptchaConfig = z.infer<typeof captchaConfigSchema>\n\n/** The merchant as its customers see it; logo and support are https. */\nexport const publicMerchantSchema = z.object({\n display_name: z.string(),\n logo_url: z.string().nullish(),\n support_url: z.string().nullish(),\n /** The origins that may frame its embedded checkouts. */\n embed_origins: z\n .array(z.string())\n .nullish()\n .transform((v) => v ?? []),\n})\nexport type PublicMerchant = z.infer<typeof publicMerchantSchema>\n\n/**\n * What any browser needs to know about the deployment (`GET /config`, no\n * credential): the mount's capabilities, the currency registry and the\n * captcha (null when the deployment challenges nobody).\n */\nexport const publicConfigSchema = z.object({\n capabilities: z.object({\n route_groups: z.record(z.string(), z.boolean()),\n features: z.record(z.string(), z.boolean()),\n }),\n currencies: z\n .array(currencySchema)\n .nullish()\n .transform((v) => v ?? []),\n captcha: captchaConfigSchema.nullish(),\n /**\n * The checkout page's sign-in to the customer network (OpenID Connect,\n * code and PKCE); null without the network or a hosted checkout.\n */\n network: z.object({ issuer: z.string(), client_id: z.string() }).nullish(),\n})\nexport type PublicConfig = z.infer<typeof publicConfigSchema>\n\n/**\n * What a customer's browser needs to know about the merchant it pays\n * (`GET /me/config`): its payment setup and how it presents itself.\n */\nexport const customerConfigSchema = z.object({\n payment: paymentConfigSchema,\n merchant: publicMerchantSchema,\n})\nexport type CustomerConfig = z.infer<typeof customerConfigSchema>\n\nexport const networkLinkChallengeSchema = z.object({\n id: z.string(),\n nonce: z.string(),\n expires_at: time,\n})\nexport type NetworkLinkChallenge = z.infer<typeof networkLinkChallengeSchema>\n\nexport const customerLinkSchema = z.object({\n id: z.string(),\n merchant_id: z.string(),\n customer_id: z.string(),\n account_id: z.string(),\n method: z.string(),\n status: z.string(),\n linked_at: time,\n revoked_at: time.nullish(),\n revoked_by: z.string().nullish(),\n})\nexport type CustomerLink = z.infer<typeof customerLinkSchema>\n\n/**\n * What a card setup hands the server: tokenized data only, never a PAN.\n * OpenRails reads the saved card's brand, last four and expiry from the PSP.\n */\ninterface NewCardFields {\n /** The PSP the card is saved with (`psp_id` of a rail option); required. */\n psp_id: string\n billing_details?: {\n name?: string\n email?: string\n address?: { postal_code?: string; country?: string }\n }\n}\n\n/**\n * A card to save: the single-use token of the PSP's own fields (a Collect.js\n * token, a Stripe `pm_`), or, for a PSP whose card_entry is server\n * (`cardSetupDriver` \"card\"), the card itself, posted to OpenRails and never\n * kept by this package. A HyperSwitch capture starts without either; reuse an\n * Idempotency-Key and confirm the pending method with its vendor session token.\n */\nexport type NewCard = NewCardFields &\n (\n | { token: string; card?: never }\n | { card: CardEntry; token?: never }\n | { token?: never; card?: never }\n )\n\n/** A token issued by the vendor session of an owned pending payment method. */\nexport interface CardCaptureReference {\n custodian_id: string\n session_id: string\n token: string\n}\n","import type { z } from \"zod\"\n\nimport {\n BillingError,\n isBillingError,\n localError,\n readBillingError,\n} from \"./errors\"\nimport { OPENRAILS_CURRENCY_SCALES } from \"./generated/currencies\"\nimport type * as wire from \"./generated/wire\"\nimport { isTokenSource } from \"./token-source\"\nimport {\n accountSchema,\n customerConfigSchema,\n customerEntitlementSchema,\n customerLinkSchema,\n lowBalanceLineSchema,\n networkLinkChallengeSchema,\n publicConfigSchema,\n listPageSchema,\n orderSchema,\n cartSchema,\n pageSchema,\n paymentMethodSchema,\n paymentSchema,\n productSchema,\n subscriptionSchema,\n subscriptionChangePreviewSchema,\n subscriptionChangeSchema,\n usageSchema,\n type Account,\n type CustomerConfig,\n type CustomerEntitlement,\n type CustomerLink,\n type LowBalanceLine,\n type NetworkLinkChallenge,\n type PublicConfig,\n type CurrencyScales,\n type ListPage,\n type NewCard,\n type CardCaptureReference,\n type NextAction,\n type Cart,\n type Order,\n type OrderPaymentInput,\n type Page,\n type Payment,\n type PaymentMethod,\n type Product,\n type Subscription,\n type SubscriptionChange,\n type SubscriptionChangePreview,\n type Usage,\n} from \"./types\"\n\nexport interface BillingClientOptions {\n /** OpenRails embedded mount. Default \"/billing/v1\". */\n baseUrl?: string\n /**\n * Transport. Pass an authenticating fetch (auth-ui's `client.authFetch`)\n * or combine the default with `getToken`.\n */\n fetch?: (input: string, init: RequestInit) => Promise<Response>\n /**\n * The customer's access token, sent as the bearer of every request but\n * the two public reads (`getConfig`, `listProducts`); omit when `fetch`\n * authenticates. A `tokenSource` keeps it fresh: a call answered 401\n * `credential_expired` is then retried once with a new token.\n */\n getToken?: () =>\n string | null | undefined | Promise<string | null | undefined>\n /** Sent as Accept-Language. */\n language?: () => string | null | undefined\n /**\n * Extra or overriding currency scales (code -> native-unit decimals). The\n * pinned OpenRails registry is built in; `/me` amounts carry no scale.\n */\n currencies?: CurrencyScales\n}\n\n/**\n * A public catalog lookup: the products of `merchant` (its id) named by\n * `keys` (at most 100 product keys), in one page.\n */\nexport interface ProductListOptions {\n merchant: string\n keys: string[]\n signal?: AbortSignal\n}\n\nexport interface ListOptions {\n limit?: number\n offset?: number\n /** A cursor list's next page: the previous page's `next_cursor`. */\n cursor?: string\n signal?: AbortSignal\n}\n\n/**\n * A subscription change: another price of its tier group, other seats of a\n * per-seat price, or both. A quantity for a price that is not per seat is\n * refused (`quantity_not_allowed`).\n */\nexport interface SubscriptionChangeInput {\n priceId?: string\n quantity?: number\n}\n\nexport interface CursorOptions {\n limit?: number\n cursor?: string | null\n signal?: AbortSignal\n}\n\n/**\n * A page of the customer's usage report in `currency`, grouped by `groupBy`\n * (event type by default). `from` and `to` are RFC 3339 or a date; left out,\n * the month before now, or with `cursor` the window of the page it came from.\n * `limit` is at most 1,000 groups (default 100).\n */\nexport interface UsageOptions extends CursorOptions {\n currency: string\n groupBy?: \"event_type\" | \"resource\" | \"invoker\" | \"meter\"\n from?: string\n to?: string\n}\n\n/**\n * Signs and submits a base64 transaction with the customer's wallet and\n * returns its signature. Throw `WalletRejectedError` when the user declines.\n */\nexport type SendSolanaTransaction = (\n transactionBase64: string\n) => Promise<string>\n\nexport class WalletRejectedError extends Error {\n constructor(message = \"The wallet request was declined.\") {\n super(message)\n this.name = \"WalletRejectedError\"\n }\n}\n\nexport const CANCEL_REASON_MIN = 4\nexport const CANCEL_REASON_MAX = 500\n\n/** A next action the customer's wallet completes. */\nexport const isWalletAction = (next: NextAction | null | undefined): boolean =>\n next?.type === \"solana_sign_transactions\" && !!next.transactions?.length\n\n/**\n * Signs and sends a `solana_sign_transactions` next action's transactions in\n * order and returns the last signature, the value the action is repeated\n * with. A declined prompt is a local `wallet_rejected` error.\n */\nexport async function signWalletAction(\n next: NextAction,\n sendTransaction: SendSolanaTransaction\n): Promise<string> {\n let signature = \"\"\n for (const transaction of next.transactions ?? []) {\n try {\n signature = await sendTransaction(transaction)\n } catch (err) {\n if (isWalletRejection(err))\n throw localError(\"wallet_rejected\", \"The wallet request was declined.\")\n throw err\n }\n if (!signature)\n throw localError(\n \"wallet_no_signature\",\n \"The wallet returned no signature.\"\n )\n }\n if (!signature)\n throw localError(\"wallet_no_signature\", \"The wallet returned no signature.\")\n return signature\n}\n\ntype Query = Record<string, string | number | boolean | string[] | undefined>\n\ninterface RequestOptions {\n method?: string\n query?: Query\n body?: unknown\n signal?: AbortSignal\n headers?: Record<string, string>\n /** A public route: it reads no credential, so none is sent. */\n public?: boolean\n}\n\n/** Total wait a GET may spend on its one retry. */\nexport const RETRY_BUDGET_MS = 2_000\nconst RETRY_DELAY_MS = 300\n\n// The wait before retrying a GET answered with res, or null if it is final.\nfunction retryDelay(res: Response): number | null {\n const retryAfter = parseRetryAfter(res.headers.get(\"Retry-After\"))\n switch (res.status) {\n case 429:\n return retryAfter\n case 503:\n return retryAfter ?? RETRY_DELAY_MS\n case 502:\n case 504:\n return RETRY_DELAY_MS\n default:\n return null\n }\n}\n\nfunction parseRetryAfter(value: string | null): number | null {\n if (!value) return null\n if (/^\\d+$/.test(value.trim())) return Number(value.trim()) * 1000\n const at = Date.parse(value)\n return Number.isNaN(at) ? null : Math.max(0, at - Date.now())\n}\n\nfunction pause(ms: number, signal?: AbortSignal): Promise<number> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) return reject(signal.reason)\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", abort)\n resolve(ms)\n }, ms)\n const abort = () => {\n clearTimeout(timer)\n reject(signal?.reason)\n }\n signal?.addEventListener(\"abort\", abort, { once: true })\n })\n}\n\n/**\n * An order request's answer. `error` is set when the payment failed: the\n * order is open again and its `payment.last_payment_error` says why.\n */\nexport interface OrderResult {\n order: Order\n error?: BillingError\n}\n\nexport function createBillingClient(options: BillingClientOptions = {}) {\n const base = (options.baseUrl ?? \"/billing/v1\").replace(/\\/+$/, \"\")\n const doFetch =\n options.fetch ?? ((input: string, init: RequestInit) => fetch(input, init))\n const currencies = normalizeScales({\n ...OPENRAILS_CURRENCY_SCALES,\n ...options.currencies,\n })\n\n function url(path: string, query?: Query): string {\n const qs = new URLSearchParams()\n for (const [k, v] of Object.entries(query ?? {}))\n if (Array.isArray(v)) for (const item of v) qs.append(k, item)\n else if (v !== undefined && v !== \"\") qs.set(k, String(v))\n const q = qs.toString()\n return `${base}${path}${q ? `?${q}` : \"\"}`\n }\n\n async function send(\n path: string,\n opts: RequestOptions = {}\n ): Promise<Response> {\n const headers = new Headers({ Accept: \"application/json\", ...opts.headers })\n if (opts.body !== undefined) headers.set(\"Content-Type\", \"application/json\")\n let token = opts.public ? undefined : await options.getToken?.()\n if (token) headers.set(\"Authorization\", `Bearer ${token}`)\n const lang = options.language?.()\n if (lang) headers.set(\"Accept-Language\", lang)\n const method = opts.method ?? \"GET\"\n const init = {\n method,\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n signal: opts.signal,\n }\n // Only a GET is retried: once, on a network error or 502/503/504 (and a\n // 429 that names its wait), within RETRY_BUDGET_MS. Writes never are.\n const retries = method === \"GET\" ? 1 : 0\n let waited = 0\n let renewed = false\n for (let attempt = 0; ; attempt++) {\n let res: Response\n try {\n res = await doFetch(url(path, opts.query), init)\n } catch (cause) {\n const delay = RETRY_DELAY_MS\n if (\n attempt >= retries ||\n opts.signal?.aborted ||\n !(cause instanceof TypeError) ||\n waited + delay > RETRY_BUDGET_MS\n )\n throw cause\n waited += await pause(delay, opts.signal)\n continue\n }\n if (res.ok) return res\n // The gate refused an expired token before the route ran: any call,\n // a write too, is sent once more with the source's next token.\n if (\n res.status === 401 &&\n token &&\n !renewed &&\n isTokenSource(options.getToken)\n ) {\n const refusal = await readBillingError(res)\n if (refusal.code !== \"credential_expired\") throw refusal\n options.getToken.invalidate(token)\n token = await options.getToken()\n headers.set(\"Authorization\", `Bearer ${token}`)\n renewed = true\n attempt--\n continue\n }\n const delay = retryDelay(res)\n if (\n attempt >= retries ||\n delay === null ||\n waited + delay > RETRY_BUDGET_MS\n )\n throw await readBillingError(res)\n await res.body?.cancel().catch(() => undefined)\n waited += await pause(delay, opts.signal)\n }\n }\n\n async function json<S extends z.ZodType>(\n schema: S,\n path: string,\n opts?: RequestOptions\n ): Promise<z.output<S>> {\n const res = await send(path, opts)\n let body: unknown\n try {\n body = await res.json()\n } catch {\n throw localError(\"invalid_response\", `${path}: body is not JSON`)\n }\n const parsed = schema.safeParse(body)\n if (!parsed.success)\n throw localError(\n \"invalid_response\",\n `${path}: ${parsed.error.issues[0]?.path.join(\".\")} ${parsed.error.issues[0]?.message}`\n )\n return parsed.data\n }\n\n const id = (value: string) => encodeURIComponent(value)\n const subscriptionPage = listPageSchema(subscriptionSchema)\n const methodPage = listPageSchema(paymentMethodSchema)\n const paymentPage = listPageSchema(paymentSchema)\n const orderPage = listPageSchema(orderSchema)\n const entitlementPage = listPageSchema(customerEntitlementSchema)\n const cursorQuery = (opts: CursorOptions, limit: number) => ({\n limit: opts.limit ?? limit,\n cursor: opts.cursor ?? undefined,\n })\n const productPage = pageSchema(productSchema)\n\n // An order answer: the order, or a failed payment's 402 with it.\n async function orderResult(\n path: string,\n opts: RequestOptions\n ): Promise<OrderResult> {\n try {\n return { order: await json(orderSchema, path, opts) }\n } catch (cause) {\n if (isBillingError(cause) && cause.status === 402 && cause.order) {\n const order = orderSchema.safeParse(cause.order)\n if (order.success) return { order: order.data, error: cause }\n }\n throw cause\n }\n }\n\n const client = {\n baseUrl: base,\n\n /** One page of the customer's subscriptions, newest first. */\n listSubscriptions(\n opts: CursorOptions & { status?: string } = {}\n ): Promise<ListPage<Subscription>> {\n return json(subscriptionPage, \"/me/subscriptions\", {\n query: { status: opts.status ?? \"all\", ...cursorQuery(opts, 100) },\n signal: opts.signal,\n })\n },\n\n /** Includes `recovery` (list rows do not). */\n getSubscription(\n subscriptionId: string,\n signal?: AbortSignal\n ): Promise<Subscription> {\n return json(\n subscriptionSchema,\n `/me/subscriptions/${id(subscriptionId)}`,\n {\n signal,\n }\n )\n },\n\n /**\n * Cancels at period end and answers the subscription. When the rail needs\n * the customer's step (`next_action`, a Solana wallet signature), the\n * subscription is unchanged: complete it with `signWalletAction` and\n * repeat with `signature`.\n */\n cancelSubscription(\n subscriptionId: string,\n input: { reason: string; signature?: string }\n ): Promise<Subscription> {\n return json(\n subscriptionSchema,\n `/me/subscriptions/${id(subscriptionId)}/cancel`,\n {\n method: \"POST\",\n body: {\n reason: input.reason.trim(),\n signature: input.signature,\n } satisfies wire.CustomerCancelSubscriptionParams,\n }\n )\n },\n\n /** Undoes a scheduled cancel before the period ends. */\n resumeSubscription(subscriptionId: string): Promise<Subscription> {\n return json(\n subscriptionSchema,\n `/me/subscriptions/${id(subscriptionId)}/resume`,\n { method: \"POST\", body: {} }\n )\n },\n\n /** Gives the subscription its own card; `null` makes it follow the default. */\n setSubscriptionPaymentMethod(\n subscriptionId: string,\n paymentMethodId: string | null\n ): Promise<Subscription> {\n return json(\n subscriptionSchema,\n `/me/subscriptions/${id(subscriptionId)}/payment-method`,\n {\n method: \"PUT\",\n body: {\n payment_method_id: paymentMethodId,\n } satisfies wire.SetSubscriptionPaymentMethodParams,\n }\n )\n },\n\n /** What `changeSubscription` would charge now and at the next renewal. */\n previewSubscriptionChange(\n subscriptionId: string,\n change: SubscriptionChangeInput,\n signal?: AbortSignal\n ): Promise<SubscriptionChangePreview> {\n return json(\n subscriptionChangePreviewSchema,\n `/me/subscriptions/${id(subscriptionId)}/change/preview`,\n {\n method: \"POST\",\n body: {\n price_id: change.priceId,\n quantity: change.quantity,\n } satisfies wire.PreviewSubscriptionChangeParams,\n signal,\n }\n )\n },\n\n /**\n * Reads the provider for a change awaiting the customer, after they\n * completed its `next_action` (the issuer's authentication), and answers\n * the change as it now stands.\n */\n confirmSubscriptionChange(\n subscriptionId: string\n ): Promise<SubscriptionChange> {\n return json(\n subscriptionChangeSchema,\n `/me/subscriptions/${id(subscriptionId)}/confirm`,\n { method: \"POST\", body: {} }\n )\n },\n\n /**\n * Moves the subscription to another price of its tier group, to other\n * seats of a per-seat price, or both. An upgrade and more seats charge\n * the saved card now; a downgrade and fewer seats apply at period end.\n * Reuse `idempotencyKey` until the change resolves (`processing`, a\n * `subscription_change_in_flight` refusal or a lost response) so the\n * stored result replays instead of charging twice. A Solana wallet next\n * action is completed with `signWalletAction`, then repeated with\n * `signature`; an `authenticate` one with `authenticateChange`.\n */\n changeSubscription(\n subscriptionId: string,\n input: SubscriptionChangeInput & {\n idempotencyKey: string\n signature?: string\n }\n ): Promise<SubscriptionChange> {\n return json(\n subscriptionChangeSchema,\n `/me/subscriptions/${id(subscriptionId)}/change`,\n {\n method: \"POST\",\n body: {\n price_id: input.priceId,\n quantity: input.quantity,\n signature: input.signature,\n } satisfies wire.CustomerChangeSubscriptionParams,\n headers: { \"Idempotency-Key\": input.idempotencyKey },\n }\n )\n },\n\n listPaymentMethods(\n opts: CursorOptions = {}\n ): Promise<ListPage<PaymentMethod>> {\n return json(methodPage, \"/me/payment-methods\", {\n query: cursorQuery(opts, 100),\n signal: opts.signal,\n })\n },\n\n /**\n * Saves a card entered in the page with the PSP `psp_id` in one call: the\n * token of its own fields, or the card itself (\"card\"). A Stripe card the\n * bank wants authenticated answers `requires_action`. HyperSwitch capture\n * starts without token/card and requires a stable `idempotencyKey`.\n */\n addPaymentMethod(\n card: NewCard,\n idempotencyKey?: string\n ): Promise<PaymentMethod> {\n return json(paymentMethodSchema, \"/me/payment-methods\", {\n method: \"POST\",\n body: card,\n headers: idempotencyKey\n ? { \"Idempotency-Key\": idempotencyKey }\n : undefined,\n })\n },\n\n /** The customer's cart, priced now. */\n getCart(signal?: AbortSignal): Promise<Cart> {\n return json(cartSchema, \"/me/cart\", { signal })\n },\n\n /**\n * Puts a price in the cart or changes its line, and answers the cart.\n * `quantity` 0 removes the line; omitted, the price's default. `amount`\n * is the customer's choice on a price that takes one.\n */\n setCartLine(\n priceId: string,\n input: { quantity?: number; amount?: string } = {}\n ): Promise<Cart> {\n return json(cartSchema, `/me/cart/lines/${id(priceId)}`, {\n method: \"PUT\",\n body: input satisfies wire.SetCartLineParams,\n })\n },\n\n /** Empties the cart. */\n async clearCart(): Promise<void> {\n await send(\"/me/cart\", { method: \"DELETE\" })\n },\n\n /**\n * Creates an order from `lines` or the cart (`cart: true`), and with\n * `payment` pays it in the same call; `expectedTotal` is the total the\n * customer saw. A failed payment resolves as payOrder's does.\n */\n createOrder(input: {\n lines?: { price_id: string; quantity?: number; amount?: string }[]\n cart?: boolean\n expectedTotal?: string\n payment?: OrderPaymentInput\n reusable?: boolean\n idempotencyKey: string\n }): Promise<OrderResult> {\n return orderResult(\"/me/orders\", {\n method: \"POST\",\n body: {\n ...(input.cart ? { cart: true } : { lines: input.lines ?? [] }),\n ...(input.expectedTotal === undefined\n ? {}\n : { expected_total: input.expectedTotal }),\n ...(input.payment === undefined ? {} : { payment: input.payment }),\n ...(input.reusable === undefined ? {} : { reusable: input.reusable }),\n },\n headers: { \"Idempotency-Key\": input.idempotencyKey },\n })\n },\n\n /**\n * The customer's orders, newest first: `origin: \"usage\"` their usage\n * orders, `overdue` those still owed past their due date.\n */\n listOrders(\n opts: CursorOptions & {\n /** Read exactly these orders (at most 100), e.g. a page of payments'. */\n ids?: string[]\n origin?: string\n status?: string\n subscriptionId?: string\n overdue?: boolean\n } = {}\n ): Promise<ListPage<Order>> {\n // A set of ids is the whole query: it takes no paging or filter.\n if (opts.ids?.length)\n return json(orderPage, \"/me/orders\", {\n query: { ids: opts.ids.join(\",\") },\n signal: opts.signal,\n })\n return json(orderPage, \"/me/orders\", {\n query: {\n ...cursorQuery(opts, 20),\n origin: opts.origin,\n status: opts.status,\n subscription_id: opts.subscriptionId,\n overdue: opts.overdue ? \"true\" : undefined,\n },\n signal: opts.signal,\n })\n },\n\n /** One of the customer's orders: the resumable handle of a purchase. */\n getOrder(orderId: string, signal?: AbortSignal): Promise<Order> {\n return json(orderSchema, `/me/orders/${id(orderId)}`, { signal })\n },\n\n /**\n * Pays an open order. A failed payment resolves with the order (open,\n * `payment.last_payment_error` saying why) and `error`, the 402.\n * `idempotencyKey` is minted when the pay button renders: a retry with it\n * answers what the first request answered.\n */\n payOrder(\n orderId: string,\n input: {\n payment: OrderPaymentInput\n expectedTotal: string\n reusable?: boolean\n idempotencyKey: string\n }\n ): Promise<OrderResult> {\n return orderResult(`/me/orders/${id(orderId)}/pay`, {\n method: \"POST\",\n body: {\n payment: input.payment,\n expected_total: input.expectedTotal,\n ...(input.reusable === undefined ? {} : { reusable: input.reusable }),\n },\n headers: { \"Idempotency-Key\": input.idempotencyKey },\n })\n },\n\n /**\n * Reads the provider after the customer completed `next_action`. A Solana\n * wallet's `signature` names the transaction it sent: a subscription's\n * first payment enrolls from it at once.\n */\n confirmOrder(\n orderId: string,\n input?: { signature?: string }\n ): Promise<OrderResult> {\n return orderResult(`/me/orders/${id(orderId)}/confirm`, {\n method: \"POST\",\n body: input?.signature ? { signature: input.signature } : {},\n })\n },\n\n /**\n * Finishes saving a card the bank asked to authenticate, after the PSP's\n * script answered its `next_action`.\n */\n confirmPaymentMethod(\n paymentMethodId: string,\n capture?: CardCaptureReference\n ): Promise<PaymentMethod> {\n return json(\n paymentMethodSchema,\n `/me/payment-methods/${id(paymentMethodId)}/confirm`,\n { method: \"POST\", body: capture ? { capture } : {} }\n )\n },\n\n /** `pending` when the provider is still converging (202). */\n async removePaymentMethod(\n paymentMethodId: string\n ): Promise<\"removed\" | \"pending\"> {\n const res = await send(`/me/payment-methods/${id(paymentMethodId)}`, {\n method: \"DELETE\",\n })\n return res.status === 202 ? \"pending\" : \"removed\"\n },\n\n /**\n * Makes the card the default for one currency: it pays the currency's\n * usage orders and every subscription in it without its own card.\n */\n async setDefaultPaymentMethod(input: {\n currency: string\n paymentMethodId: string\n }): Promise<void> {\n await send(\n `/me/default-payment-methods/${id(input.currency.toUpperCase())}`,\n {\n method: \"PUT\",\n body: {\n payment_method_id: input.paymentMethodId,\n } satisfies wire.SetDefaultPaymentMethodParams,\n }\n )\n },\n\n /** Charges and refunds, newest first. `rail` filters by rail. */\n listPayments(\n opts: CursorOptions & { rail?: string } = {}\n ): Promise<ListPage<Payment>> {\n return json(paymentPage, \"/me/payments\", {\n query: { ...cursorQuery(opts, 20), rail: opts.rail },\n signal: opts.signal,\n })\n },\n\n /**\n * One page of the entitlement keys the customer holds (up to 500 by\n * default), by key. `at` reads them as of an RFC 3339 instant; `prefix`\n * keeps the keys that start with it.\n */\n getEntitlements(\n opts: CursorOptions & { at?: string; prefix?: string } = {}\n ): Promise<ListPage<CustomerEntitlement>> {\n return json(entitlementPage, \"/me/entitlements\", {\n query: { ...cursorQuery(opts, 500), at: opts.at, prefix: opts.prefix },\n signal: opts.signal,\n })\n },\n\n /**\n * The customer's summary: balance and amount owed per currency, the card\n * that pays each currency, and the low-balance line of each balance.\n */\n getAccount(signal?: AbortSignal): Promise<Account> {\n return json(accountSchema, \"/me\", { signal })\n },\n\n /**\n * Sets the customer's own low-balance line in one currency and answers\n * the line its balance is judged at. `null` inherits the merchant's; 0\n * turns that part off.\n */\n setLowBalanceLine(input: {\n currency: string\n amount: string | null\n runwayHours: number | null\n }): Promise<LowBalanceLine> {\n return json(\n lowBalanceLineSchema,\n `/me/low-balance-lines/${id(input.currency.toUpperCase())}`,\n {\n method: \"PUT\",\n body: {\n amount: input.amount,\n runway_hours: input.runwayHours,\n } satisfies wire.SetLowBalanceLineParams,\n }\n )\n },\n\n /**\n * A page of the customer's usage: its groups by total amount, largest\n * first. Pass the answer's `next_cursor` as `cursor` for the next page.\n */\n getUsage(opts: UsageOptions): Promise<Usage> {\n return json(usageSchema, \"/me/usage\", {\n query: {\n currency: opts.currency,\n group_by: opts.groupBy,\n from: opts.from,\n to: opts.to,\n limit: opts.limit,\n cursor: opts.cursor ?? undefined,\n },\n signal: opts.signal,\n })\n },\n\n /**\n * The products `merchant` has on sale named by `keys`, each with its\n * current prices: a public read, the same signed in or out. No keys\n * name no products: nothing is fetched.\n */\n async listProducts(opts: ProductListOptions): Promise<Page<Product>> {\n if (opts.keys.length === 0) return { data: [], next_cursor: null }\n return json(productPage, \"/products\", {\n query: { merchant: opts.merchant, keys: opts.keys },\n signal: opts.signal,\n public: true,\n })\n },\n\n /**\n * A challenge to link the customer to an openrails.dev account: its\n * `nonce` goes in the network sign-in's authorization request.\n */\n createNetworkLinkChallenge(): Promise<NetworkLinkChallenge> {\n return json(networkLinkChallengeSchema, \"/me/network-link/challenges\", {\n method: \"POST\",\n body: {},\n })\n },\n\n /**\n * Links the customer to the openrails.dev account whose fresh sign-in\n * answered the challenge (its ID token).\n */\n createNetworkLink(params: {\n challengeId: string\n idToken: string\n }): Promise<CustomerLink> {\n return json(customerLinkSchema, \"/me/network-link\", {\n method: \"POST\",\n body: { challenge_id: params.challengeId, id_token: params.idToken },\n })\n },\n\n /**\n * The deployment's configuration, a public read: what the mount serves,\n * the currency registry and the captcha. React components share one\n * copy through `useConfig()`.\n */\n getConfig(signal?: AbortSignal): Promise<PublicConfig> {\n return json(publicConfigSchema, \"/config\", { signal, public: true })\n },\n\n /**\n * The customer's merchant: its payment setup (PSPs, Solana network and\n * tokens) and how it presents itself. React components share one copy\n * through `useCustomerConfig()`.\n */\n getCustomerConfig(signal?: AbortSignal): Promise<CustomerConfig> {\n return json(customerConfigSchema, \"/me/config\", { signal })\n },\n\n /** Currency code (upper case) to native-unit decimals. */\n currencies,\n }\n return client\n}\n\nfunction normalizeScales(scales: CurrencyScales): CurrencyScales {\n return Object.fromEntries(\n Object.entries(scales).map(([code, decimals]) => [\n code.toUpperCase(),\n decimals,\n ])\n )\n}\n\nexport type BillingClient = ReturnType<typeof createBillingClient>\n\nexport const isWalletRejection = (error: unknown): boolean =>\n error instanceof WalletRejectedError ||\n (error instanceof Error && error.name === \"WalletRejectedError\") ||\n (error instanceof BillingError && error.code === \"wallet_rejected\")\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-DCSelDIZ.js","names":[],"sources":["../src/i18n/messages.ts","../src/i18n/context.ts","../src/appearance.ts","../src/scope-context.ts","../src/react/context.ts","../src/react/config.ts","../src/react/provider.tsx","../src/react/remote.ts","../src/react/hooks.ts"],"sourcesContent":["import { en } from \"../locales/en.ts\"\n\n/**\n * A count-dependent message: CLDR plural categories for the locale, with\n * `other` required. An exact-count key (`\"1\"`) wins over the category, like\n * ICU's `=1`, for locales whose single form differs from `{count}` (毎日).\n */\nexport type PluralMessage = {\n [K in Intl.LDMLPluralRule | \"1\"]?: string\n} & { other: string }\n\ntype Widen<T> = {\n [K in keyof T]: T[K] extends string\n ? string\n : T[K] extends PluralMessage\n ? PluralMessage\n : Widen<T[K]>\n}\n\n/** The complete message tree; English is the reference shape. */\nexport type BillingUiMessages = Widen<typeof en>\n\ntype DeepPartial<T> = {\n [K in keyof T]?: T[K] extends string\n ? string\n : T[K] extends PluralMessage\n ? Partial<PluralMessage>\n : DeepPartial<T[K]>\n}\n\n/** A locale bundle or host override: any subset of the tree. */\nexport type BillingUiMessageBundle = DeepPartial<BillingUiMessages>\n\ntype Paths<T, P extends string = \"\"> = {\n [K in keyof T & string]: T[K] extends string\n ? `${P}${K}`\n : T[K] extends PluralMessage\n ? never\n : Paths<T[K], `${P}${K}.`>\n}[keyof T & string]\n\ntype PluralPaths<T, P extends string = \"\"> = {\n [K in keyof T & string]: T[K] extends string\n ? never\n : T[K] extends PluralMessage\n ? `${P}${K}`\n : PluralPaths<T[K], `${P}${K}.`>\n}[keyof T & string]\n\n/** Dotted key of any message, e.g. `subscriptions.title`. */\nexport type MessageKey = Paths<BillingUiMessages>\n\n/** Dotted key of a count-dependent message, e.g. `interval.every.day`. */\nexport type PluralKey = PluralPaths<BillingUiMessages>\n\nexport type MessageVars = Record<string, string | number>\n\n/**\n * Host translation hook. Receives the bare key (`subscriptions.title`,\n * `errors.not_found`); return nothing or the key itself to use ours.\n */\nexport type BillingUiTranslate = (\n key: string,\n vars?: MessageVars\n) => string | null | undefined\n\n/** Types a locale bundle or override against the message tree. */\nexport function defineMessages(\n bundle: BillingUiMessageBundle\n): BillingUiMessageBundle {\n return bundle\n}\n\nexport const defaultMessages: BillingUiMessages = en\n\ntype Tree = { [key: string]: string | Tree }\n\nfunction mergeInto(target: Tree, source: Tree): Tree {\n const out: Tree = { ...target }\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined || value === null) continue\n const current = out[key]\n if (typeof value === \"string\") {\n if (value !== \"\") out[key] = value\n } else if (typeof current === \"object\") {\n out[key] = mergeInto(current, value)\n } else {\n out[key] = mergeInto({}, value)\n }\n }\n return out\n}\n\n/** Layers bundles over English; later bundles win, missing keys fall back. */\nexport function resolveMessages(\n bundles?: BillingUiMessageBundle | readonly BillingUiMessageBundle[]\n): BillingUiMessages {\n const list = bundles ? (Array.isArray(bundles) ? bundles : [bundles]) : []\n let tree = en as unknown as Tree\n for (const bundle of list) tree = mergeInto(tree, bundle as Tree)\n return tree as unknown as BillingUiMessages\n}\n\nexport function interpolate(template: string, vars?: MessageVars): string {\n if (!vars) return template\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) =>\n name in vars ? String(vars[name]) : match\n )\n}\n\nfunction lookup(messages: BillingUiMessages, key: string): string | undefined {\n let node: unknown = messages\n for (const part of key.split(\".\")) {\n if (!node || typeof node !== \"object\") return undefined\n node = (node as Tree)[part]\n }\n return typeof node === \"string\" ? node : undefined\n}\n\nexport interface Translator {\n messages: BillingUiMessages\n /** BCP 47 tag used for plural rules and numbers; the runtime's when unset. */\n locale?: string\n t(key: MessageKey, vars?: MessageVars): string\n /**\n * Count-dependent message: tries `<key>.<count>`, then the locale's plural\n * category, then `<key>.other`. `{count}` is locale-formatted.\n */\n plural(key: PluralKey, count: number, vars?: MessageVars): string\n /** Message for a billing error, error code, or thrown value. */\n error(error: unknown, vars?: MessageVars): string\n}\n\nfunction errorCode(error: unknown): string | undefined {\n if (typeof error === \"string\") return error\n if (error && typeof error === \"object\" && \"code\" in error) {\n const code = (error as { code: unknown }).code\n if (typeof code === \"string\") return code\n }\n return undefined\n}\n\nfunction isNetworkError(error: unknown): boolean {\n return error instanceof TypeError && /fetch|network/i.test(error.message)\n}\n\nfunction pluralRules(locale?: string): Intl.PluralRules {\n try {\n return new Intl.PluralRules(locale)\n } catch {\n return new Intl.PluralRules(\"en\")\n }\n}\n\nfunction formatCount(count: number, locale?: string): string {\n try {\n return new Intl.NumberFormat(locale).format(count)\n } catch {\n return String(count)\n }\n}\n\nexport function createTranslator(\n messages: BillingUiMessages,\n hostT?: BillingUiTranslate,\n locale?: string\n): Translator {\n const rules = pluralRules(locale)\n const translate = (key: string, vars?: MessageVars): string | undefined => {\n const hosted = hostT?.(key, vars)\n if (hosted && hosted !== key) return hosted\n const own = lookup(messages, key)\n return own === undefined ? undefined : interpolate(own, vars)\n }\n return {\n messages,\n locale,\n t: (key, vars) => translate(key, vars) ?? key,\n plural(key, count, vars) {\n const all = { ...vars, count: formatCount(count, locale) }\n return (\n translate(`${key}.${count}`, all) ??\n translate(`${key}.${rules.select(count)}`, all) ??\n translate(`${key}.other`, all) ??\n key\n )\n },\n error(error, vars) {\n const code = errorCode(error)\n if (code && code !== \"generic\" && code !== \"network\") {\n const metadata =\n error && typeof error === \"object\" && \"metadata\" in error\n ? (error as { metadata?: MessageVars }).metadata\n : undefined\n const message = translate(`errors.${code}`, { ...metadata, ...vars })\n if (message) return message\n }\n const fallback = isNetworkError(error)\n ? \"errors.network\"\n : \"errors.generic\"\n return translate(fallback, vars) ?? messages.errors.generic\n },\n }\n}\n","import { createContext, useContext } from \"react\"\n\nimport {\n createTranslator,\n defaultMessages,\n type Translator,\n} from \"./messages.ts\"\n\nexport const MessagesContext = createContext<Translator>(\n createTranslator(defaultMessages)\n)\n\n/** English defaults when rendered outside a `BillingProvider`. */\nexport function useMessages(): Translator {\n return useContext(MessagesContext)\n}\n","// Integrator theming. The component scopes the standard shadcn token set\n// under its root, so `theme` flips the whole palette and `variables` override\n// individual tokens without the integrator touching our CSS.\nimport type { CSSProperties } from \"react\"\n\n// `inherit` uses the host page's shadcn tokens (`--background`, ...) and its\n// `.dark` class instead of the bundled zinc palette.\nexport type CheckoutTheme = \"light\" | \"dark\" | \"auto\" | \"inherit\"\n\n// The tokens integrators may override. Values are raw CSS color/length\n// strings; they land as custom properties on the checkout root.\nexport interface CheckoutVariables {\n background?: string\n foreground?: string\n card?: string\n mutedForeground?: string\n faintForeground?: string\n border?: string\n input?: string\n primary?: string\n primaryForeground?: string\n destructive?: string\n ring?: string\n radius?: string\n fontFamily?: string\n}\n\nexport interface CheckoutAppearance {\n theme?: CheckoutTheme\n variables?: CheckoutVariables\n}\n\nconst VARIABLE_TO_CSS: Record<keyof CheckoutVariables, string> = {\n background: \"--background\",\n foreground: \"--foreground\",\n card: \"--card\",\n mutedForeground: \"--muted-foreground\",\n faintForeground: \"--orck-faint\",\n border: \"--border\",\n input: \"--input\",\n primary: \"--primary\",\n primaryForeground: \"--primary-foreground\",\n destructive: \"--destructive\",\n ring: \"--ring\",\n radius: \"--radius\",\n fontFamily: \"--orck-font\",\n}\n\nexport function appearanceStyle(\n appearance: CheckoutAppearance | undefined,\n namespace: \"orck\" | \"orba\" = \"orck\"\n): CSSProperties | undefined {\n const variables = appearance?.variables\n if (!variables) return undefined\n const style: Record<string, string> = {}\n for (const [key, value] of Object.entries(variables)) {\n if (!value) continue\n style[\n VARIABLE_TO_CSS[key as keyof CheckoutVariables].replace(\n \"--orck-\",\n `--${namespace}-`\n )\n ] = value\n }\n return style as CSSProperties\n}\n\nexport function appearanceTheme(\n appearance: CheckoutAppearance | undefined\n): CheckoutTheme {\n return appearance?.theme ?? \"auto\"\n}\n","import { createContext, useContext, type CSSProperties } from \"react\"\n\nimport {\n appearanceStyle,\n appearanceTheme,\n type CheckoutAppearance,\n type CheckoutTheme,\n} from \"./appearance\"\n\nexport type Navigate = (to: string) => void\n\nexport interface UiSettings {\n appearance?: CheckoutAppearance\n locale?: string\n navigate?: Navigate\n}\n\nexport const UiContext = createContext<UiSettings>({})\n\nexport const useUiSettings = (): UiSettings => useContext(UiContext)\n\nexport interface ScopeProps {\n className: string\n \"data-orck-theme\": CheckoutTheme\n style?: CSSProperties\n}\n\n/** Props that make an element a styling root; portals carry them too. */\nexport function useScopeProps(appearance?: CheckoutAppearance): ScopeProps {\n const settings = useUiSettings()\n const resolved = appearance ?? settings.appearance\n return {\n className: \"orck\",\n \"data-orck-theme\": appearanceTheme(resolved),\n style: appearanceStyle(resolved),\n }\n}\n","import { createContext, useContext } from \"react\"\n\nimport type { BillingClient } from \"../client/client\"\nimport type { CustomerConfig, SubscriptionChange } from \"../client/types\"\nimport type { ConfigStore } from \"./config\"\n\nexport type BillingChange =\n | {\n type: \"subscription.canceled\" | \"subscription.resumed\"\n subscriptionId: string\n }\n | {\n type: \"subscription.payment_method_changed\"\n subscriptionId: string\n /** null: the subscription follows the default card. */\n paymentMethodId: string | null\n }\n | {\n type: \"subscription.changed\"\n subscriptionId: string\n /** `status` may still be `processing` or `requires_action`. */\n change: SubscriptionChange\n }\n | {\n type:\n | \"payment_method.added\"\n | \"payment_method.removed\"\n | \"payment_method.default_changed\"\n paymentMethodId: string\n }\n\nexport interface BillingContextValue {\n client: BillingClient\n /** Bumped after every mutation; hooks refetch on change. */\n version: number\n notify(change: BillingChange): void\n /** Refetch every hook after a host-side change such as a plan switch. */\n refresh(): void\n /** The shared `GET /config`; read it with `useConfig()`. */\n config: ConfigStore\n /** The shared `GET /me/config`; read it with `useCustomerConfig()`. */\n customerConfig: ConfigStore<CustomerConfig>\n}\n\nexport const BillingContext = createContext<BillingContextValue | null>(null)\n\nexport function useBillingContext(): BillingContextValue {\n const ctx = useContext(BillingContext)\n if (!ctx) throw new Error(\"billing-ui: wrap the tree in <BillingProvider>\")\n return ctx\n}\n\nexport const useBillingClient = (): BillingClient => useBillingContext().client\n\nexport const useBillingRefresh = (): (() => void) => useBillingContext().refresh\n\n/** The billing context when a BillingProvider is present, else null. */\nexport const useOptionalBillingContext = (): BillingContextValue | null =>\n useContext(BillingContext)\n","import { useEffect, useMemo, useSyncExternalStore } from \"react\"\n\nimport { toBillingError, type BillingError } from \"../client/errors\"\nimport type {\n CurrencyScales,\n CustomerConfig,\n PublicConfig,\n} from \"../client/types\"\nimport { useBillingContext } from \"./context\"\n\nexport interface ConfigState<T = PublicConfig> {\n config: T | null\n loading: boolean\n error: BillingError | null\n refetch: () => void\n}\n\ninterface Snapshot<T> {\n config: T | null\n loading: boolean\n error: BillingError | null\n}\n\n/** One shared copy of a configuration read per client, fetched on first use. */\nexport interface ConfigStore<T = PublicConfig> {\n subscribe(listener: () => void): () => void\n snapshot(): Snapshot<T>\n /** Fetches the document unless it is loaded or loading. */\n ensure(): void\n refetch(): void\n}\n\nexport function createConfigStore<T>(read: () => Promise<T>): ConfigStore<T> {\n let snapshot: Snapshot<T> = { config: null, loading: true, error: null }\n let started = false\n let latest = 0\n const listeners = new Set<() => void>()\n const set = (next: Snapshot<T>) => {\n snapshot = next\n for (const listener of listeners) listener()\n }\n const load = () => {\n started = true\n const request = ++latest\n if (!snapshot.loading) set({ ...snapshot, loading: true })\n read().then(\n (config) => {\n if (request === latest) set({ config, loading: false, error: null })\n },\n (err: unknown) => {\n if (request === latest)\n set({\n config: snapshot.config,\n loading: false,\n error: toBillingError(err),\n })\n }\n )\n }\n return {\n subscribe(listener) {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n snapshot: () => snapshot,\n // A read that failed with nothing loaded is tried again by the next\n // component: the customer may have signed in since.\n ensure() {\n if (!started || (snapshot.error && !snapshot.config && !snapshot.loading))\n load()\n },\n refetch: load,\n }\n}\n\nfunction useStore<T>(store: ConfigStore<T>): ConfigState<T> {\n const snapshot = useSyncExternalStore(\n store.subscribe,\n store.snapshot,\n store.snapshot\n )\n useEffect(() => store.ensure(), [store])\n return { ...snapshot, refetch: store.refetch }\n}\n\n/**\n * The deployment's configuration (`GET /config`), fetched once per\n * `BillingProvider` and shared by every component that reads it.\n */\nexport function useConfig(): ConfigState {\n return useStore(useBillingContext().config)\n}\n\n/**\n * The customer's merchant (`GET /me/config`): its payment setup and how it\n * presents itself, fetched once per `BillingProvider` for the signed-in\n * customer and shared by every component that reads it.\n */\nexport function useCustomerConfig(): ConfigState<CustomerConfig> {\n return useStore(useBillingContext().customerConfig)\n}\n\n/**\n * Currency scales: the server's registry, under the client's pinned copy and\n * host overrides, which stand alone until the registry loads.\n */\nexport function useCurrencyScales(): CurrencyScales {\n const { client } = useBillingContext()\n const { config } = useConfig()\n return useMemo(() => {\n const served = Object.fromEntries(\n (config?.currencies ?? []).map((c) => [c.code.toUpperCase(), c.decimals])\n )\n return { ...served, ...client.currencies }\n }, [config, client])\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\"\n\nimport type { CheckoutAppearance } from \"../appearance\"\nimport type { BillingClient } from \"../client/client\"\nimport { MessagesContext } from \"../i18n/context\"\nimport {\n createTranslator,\n resolveMessages,\n type BillingUiMessageBundle,\n type BillingUiTranslate,\n} from \"../i18n/messages\"\nimport { UiContext, type Navigate } from \"../scope-context\"\nimport { createConfigStore } from \"./config\"\nimport { BillingContext, type BillingChange } from \"./context\"\n\nexport interface BillingProviderProps {\n /**\n * The customer's client: hooks and the account panels read it, and a\n * checkout saves a new card to the customer first. Leave it out where no\n * customer is signed in, such as the shared payment page.\n */\n client?: BillingClient\n /** Fires after each successful mutation: the host's cache-invalidation hook. */\n onChange?: (change: BillingChange) => void\n appearance?: CheckoutAppearance\n /** Locale bundle(s) layered over English; later entries win. */\n messages?: BillingUiMessageBundle | readonly BillingUiMessageBundle[]\n /** Host translation hook, consulted before the bundles. */\n t?: BillingUiTranslate\n /** BCP 47 tag for dates, money and plurals; defaults to the browser's. */\n locale?: string\n /** Host router for in-app links (e.g. the plans page). */\n navigate?: Navigate\n children?: ReactNode\n}\n\n/**\n * The one billing-ui provider: the client, and the appearance and words of\n * the styled components. Renders no DOM; surfaces create their own styling\n * roots, and no stylesheet loads until a styled component is imported.\n */\nexport function BillingProvider({\n client,\n onChange,\n appearance,\n messages,\n t,\n locale,\n navigate,\n children,\n}: BillingProviderProps) {\n const translator = useMemo(\n () => createTranslator(resolveMessages(messages), t, locale),\n [messages, t, locale]\n )\n const ui = useMemo(\n () => ({ appearance, locale, navigate }),\n [appearance, locale, navigate]\n )\n return (\n <UiContext.Provider value={ui}>\n <MessagesContext.Provider value={translator}>\n {client ? (\n <ClientProvider client={client} onChange={onChange}>\n {children}\n </ClientProvider>\n ) : (\n children\n )}\n </MessagesContext.Provider>\n </UiContext.Provider>\n )\n}\n\nfunction ClientProvider({\n client,\n onChange,\n children,\n}: {\n client: BillingClient\n onChange?: (change: BillingChange) => void\n children?: ReactNode\n}) {\n const [version, setVersion] = useState(0)\n const onChangeRef = useRef(onChange)\n useEffect(() => {\n onChangeRef.current = onChange\n })\n const notify = useCallback((change: BillingChange) => {\n setVersion((v) => v + 1)\n onChangeRef.current?.(change)\n }, [])\n const refresh = useCallback(() => setVersion((v) => v + 1), [])\n const config = useMemo(\n () => createConfigStore(() => client.getConfig()),\n [client]\n )\n const customerConfig = useMemo(\n () => createConfigStore(() => client.getCustomerConfig()),\n [client]\n )\n const value = useMemo(\n () => ({ client, version, notify, refresh, config, customerConfig }),\n [client, version, notify, refresh, config, customerConfig]\n )\n return (\n <BillingContext.Provider value={value}>{children}</BillingContext.Provider>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\n\nimport { toBillingError, type BillingError } from \"../client/errors\"\n\nexport interface RemoteState<T> {\n data: T | null\n loading: boolean\n error: BillingError | null\n refetch: () => void\n}\n\n// Keyed fetch that keeps the previous data while a newer key loads, so a\n// refetch after a mutation never flashes an empty list.\nexport function useRemote<T>(\n key: string,\n load: (signal: AbortSignal) => Promise<T>\n): RemoteState<T> & { replace: (update: (data: T) => T) => void } {\n const [nonce, setNonce] = useState(0)\n const request = `${key}|${nonce}`\n const [state, setState] = useState<{\n request: string | null\n data: T | null\n error: BillingError | null\n }>({ request: null, data: null, error: null })\n const loadRef = useRef(load)\n useEffect(() => {\n loadRef.current = load\n })\n\n useEffect(() => {\n const ctl = new AbortController()\n loadRef.current(ctl.signal).then(\n (data) => setState({ request, data, error: null }),\n (err: unknown) => {\n if (!ctl.signal.aborted)\n setState((s) => ({\n request,\n data: s.data,\n error: toBillingError(err),\n }))\n }\n )\n return () => ctl.abort()\n }, [request])\n\n const refetch = useCallback(() => setNonce((n) => n + 1), [])\n const replace = useCallback(\n (update: (data: T) => T) =>\n setState((s) => (s.data === null ? s : { ...s, data: update(s.data) })),\n []\n )\n return {\n data: state.data,\n loading: state.request !== request,\n error: state.request === request ? state.error : null,\n refetch,\n replace,\n }\n}\n","import { useCallback, useMemo, useState } from \"react\"\n\nimport {\n isWalletAction,\n signWalletAction,\n type ProductListOptions,\n type SendSolanaTransaction,\n type SubscriptionChangeInput,\n} from \"../client/client\"\nimport { localError, toBillingError, type BillingError } from \"../client/errors\"\nimport type {\n NewCard,\n Order,\n Payment,\n PaymentMethod,\n Product,\n Subscription,\n SubscriptionChange,\n} from \"../client/types\"\nimport { useBillingContext } from \"./context\"\nimport { useRemote } from \"./remote\"\n\n// Actions never throw: they resolve to null on success or the error.\nexport type ActionResult = Promise<BillingError | null>\n\n/** `signing` and `confirming` are a wallet step's stages. */\nexport type SubscriptionAction =\n | \"cancel\"\n | \"resume\"\n | \"payment_method\"\n | \"change\"\n | \"signing\"\n | \"confirming\"\n\nexport interface SubscriptionsOptions {\n /** Server filter; default `all`. */\n status?: string\n limit?: number\n}\n\nexport interface SubscriptionsState {\n subscriptions: Subscription[] | null\n /** The next page's cursor; null on the last page. */\n nextCursor: string | null\n loading: boolean\n error: BillingError | null\n refetch: () => void\n /** In-flight action per subscription id. */\n pending: Readonly<Record<string, SubscriptionAction>>\n /**\n * Cancels at period end. A Solana subscription is canceled by the wallet:\n * pass `sendTransaction`; without it the cancel resolves to a\n * `wallet_required` error.\n */\n cancel: (\n subscriptionId: string,\n reason: string,\n sendTransaction?: SendSolanaTransaction\n ) => ActionResult\n resume: (subscriptionId: string) => ActionResult\n /** `null` makes the subscription follow the default card. */\n setPaymentMethod: (\n subscriptionId: string,\n paymentMethodId: string | null\n ) => ActionResult\n /**\n * Resolves to the change, whose `status` may still be `processing` or\n * `requires_action`, or to the error. A Solana change is signed with\n * `sendTransaction` and resolves once the chain confirms it.\n */\n changeSubscription: (\n subscriptionId: string,\n input: SubscriptionChangeInput & { idempotencyKey: string },\n sendTransaction?: SendSolanaTransaction\n ) => Promise<SubscriptionChange | BillingError>\n}\n\nfunction usePending<A extends string>() {\n const [pending, setPending] = useState<Readonly<Record<string, A>>>({})\n const mark = useCallback((id: string, action: A | null) => {\n setPending((p) => {\n const next = { ...p }\n if (action) next[id] = action\n else delete next[id]\n return next\n })\n }, [])\n return [pending, mark] as const\n}\n\nconst walletRequired = () =>\n localError(\"wallet_required\", \"A wallet must sign this action.\")\n\nexport function useSubscriptions(\n options: SubscriptionsOptions = {}\n): SubscriptionsState {\n const { client, version, notify } = useBillingContext()\n const status = options.status ?? \"all\"\n const limit = options.limit ?? 100\n const remote = useRemote(`${status}|${limit}|${version}`, (signal) =>\n client.listSubscriptions({ status, limit, signal })\n )\n const [pending, mark] = usePending<SubscriptionAction>()\n const { replace } = remote\n\n const patchRow = useCallback(\n (next: Subscription) =>\n replace((page) => ({\n ...page,\n data: page.data.map((s) => (s.id === next.id ? next : s)),\n })),\n [replace]\n )\n\n const act = useCallback(\n async (\n id: string,\n action: SubscriptionAction,\n run: () => Promise<Subscription>,\n done: (subscription: Subscription) => void\n ): ActionResult => {\n mark(id, action)\n try {\n const next = await run()\n patchRow(next)\n done(next)\n return null\n } catch (err) {\n return toBillingError(err)\n } finally {\n mark(id, null)\n }\n },\n [mark, patchRow]\n )\n\n // A declined wallet prompt resolves to a `wallet_rejected` error.\n const cancel = useCallback(\n (id: string, reason: string, sendTransaction?: SendSolanaTransaction) =>\n act(\n id,\n \"cancel\",\n async () => {\n const sub = await client.cancelSubscription(id, { reason })\n if (!sub.next_action) return sub\n if (!isWalletAction(sub.next_action) || !sendTransaction)\n throw walletRequired()\n mark(id, \"signing\")\n const signature = await signWalletAction(\n sub.next_action,\n sendTransaction\n )\n mark(id, \"confirming\")\n return client.cancelSubscription(id, { reason, signature })\n },\n () => notify({ type: \"subscription.canceled\", subscriptionId: id })\n ),\n [act, client, mark, notify]\n )\n\n const resume = useCallback(\n (id: string) =>\n act(\n id,\n \"resume\",\n () => client.resumeSubscription(id),\n () => notify({ type: \"subscription.resumed\", subscriptionId: id })\n ),\n [act, client, notify]\n )\n\n const setPaymentMethod = useCallback(\n (id: string, paymentMethodId: string | null) =>\n act(\n id,\n \"payment_method\",\n () => client.setSubscriptionPaymentMethod(id, paymentMethodId),\n () =>\n notify({\n type: \"subscription.payment_method_changed\",\n subscriptionId: id,\n paymentMethodId,\n })\n ),\n [act, client, notify]\n )\n\n // An upgrade may open a successor subscription: notify refetches the list.\n const changeSubscription = useCallback(\n async (\n id: string,\n input: SubscriptionChangeInput & { idempotencyKey: string },\n sendTransaction?: SendSolanaTransaction\n ) => {\n mark(id, \"change\")\n try {\n let change = await client.changeSubscription(id, input)\n if (\n change.status === \"requires_action\" &&\n isWalletAction(change.next_action) &&\n sendTransaction\n ) {\n mark(id, \"signing\")\n const signature = await signWalletAction(\n change.next_action!,\n sendTransaction\n )\n mark(id, \"confirming\")\n change = await client.changeSubscription(id, { ...input, signature })\n }\n notify({\n type: \"subscription.changed\",\n subscriptionId: id,\n change,\n })\n return change\n } catch (err) {\n return toBillingError(err)\n } finally {\n mark(id, null)\n }\n },\n [client, mark, notify]\n )\n\n return {\n subscriptions: remote.data?.data ?? null,\n nextCursor: remote.data?.next_cursor ?? null,\n loading: remote.loading,\n error: remote.error,\n refetch: remote.refetch,\n pending,\n cancel,\n resume,\n setPaymentMethod,\n changeSubscription,\n }\n}\n\nexport interface ProductsState {\n products: Product[] | null\n loading: boolean\n error: BillingError | null\n refetch: () => void\n}\n\n/** The merchant and its product keys to look up: `ProductListOptions`. */\nexport type ProductsOptions = Pick<ProductListOptions, \"merchant\" | \"keys\">\n\n/**\n * The products `merchant` has on sale named by `keys`, each with its active\n * prices: a public catalog lookup.\n */\nexport function useProducts({\n merchant,\n keys,\n}: ProductsOptions): ProductsState {\n const { client } = useBillingContext()\n const remote = useRemote(JSON.stringify([merchant, keys]), (signal) =>\n client.listProducts({ merchant, keys, signal })\n )\n return {\n products: remote.data?.data ?? null,\n loading: remote.loading,\n error: remote.error,\n refetch: remote.refetch,\n }\n}\n\nexport type PaymentMethodAction = \"remove\" | \"default\"\n\nexport interface PaymentMethodsState {\n methods: PaymentMethod[] | null\n loading: boolean\n error: BillingError | null\n refetch: () => void\n pending: Readonly<Record<string, PaymentMethodAction>>\n adding: boolean\n add: (card: NewCard) => ActionResult\n remove: (paymentMethodId: string) => ActionResult\n /** Makes the card the default for the currency. */\n setDefault: (paymentMethodId: string, currency: string) => ActionResult\n}\n\nexport function usePaymentMethods(): PaymentMethodsState {\n const { client, version, notify } = useBillingContext()\n const remote = useRemote(`${version}`, (signal) =>\n client.listPaymentMethods({ signal })\n )\n const [pending, mark] = usePending<PaymentMethodAction>()\n const [adding, setAdding] = useState(false)\n const { replace } = remote\n\n const add = useCallback(\n async (card: NewCard): ActionResult => {\n setAdding(true)\n try {\n const method = await client.addPaymentMethod(card)\n replace((page) => ({ ...page, data: [...page.data, method] }))\n notify({ type: \"payment_method.added\", paymentMethodId: method.id })\n return null\n } catch (err) {\n return toBillingError(err)\n } finally {\n setAdding(false)\n }\n },\n [client, notify, replace]\n )\n\n const remove = useCallback(\n async (id: string): ActionResult => {\n mark(id, \"remove\")\n try {\n await client.removePaymentMethod(id)\n replace((page) => ({\n ...page,\n data: page.data.filter((m) => m.id !== id),\n }))\n notify({ type: \"payment_method.removed\", paymentMethodId: id })\n return null\n } catch (err) {\n return toBillingError(err)\n } finally {\n mark(id, null)\n }\n },\n [client, mark, notify, replace]\n )\n\n const setDefault = useCallback(\n async (id: string, currency: string): ActionResult => {\n mark(id, \"default\")\n try {\n await client.setDefaultPaymentMethod({\n currency,\n paymentMethodId: id,\n })\n const code = currency.toUpperCase()\n replace((page) => ({\n ...page,\n data: page.data.map((m) => {\n const others = (m.default_currencies ?? []).filter(\n (c) => c !== code\n )\n return {\n ...m,\n default_currencies: m.id === id ? [...others, code] : others,\n }\n }),\n }))\n notify({\n type: \"payment_method.default_changed\",\n paymentMethodId: id,\n })\n return null\n } catch (err) {\n return toBillingError(err)\n } finally {\n mark(id, null)\n }\n },\n [client, mark, notify, replace]\n )\n\n return {\n methods: remote.data?.data ?? null,\n loading: remote.loading,\n error: remote.error,\n refetch: remote.refetch,\n pending,\n adding,\n add,\n remove,\n setDefault,\n }\n}\n\nexport interface PaymentsOptions {\n pageSize?: number\n /** Filter by rail. */\n rail?: string\n}\n\nexport interface PaymentsState {\n payments: Payment[] | null\n /** The bills these payments settle, by order id: what each one bought. */\n orders: Record<string, Order>\n /** Zero-based. */\n page: number\n hasMore: boolean\n loading: boolean\n error: BillingError | null\n next: () => void\n previous: () => void\n refetch: () => void\n}\n\nconst noOrders: Record<string, Order> = {}\n\nexport function usePayments(options: PaymentsOptions = {}): PaymentsState {\n const { client, version } = useBillingContext()\n const pageSize = options.pageSize ?? 20\n // cursors[i] reads page i of this filter; page 0 is the newest payments.\n const filter = `${pageSize}|${options.rail ?? \"\"}`\n const [state, setState] = useState({\n filter,\n cursors: [null] as (string | null)[],\n })\n const cursors = useMemo(\n () => (state.filter === filter ? state.cursors : [null]),\n [state, filter]\n )\n const page = cursors.length - 1\n const cursor = cursors[page]\n const remote = useRemote(\n `${filter}|${cursor ?? \"\"}|${version}`,\n async (signal) => {\n const page = await client.listPayments({\n limit: pageSize,\n cursor,\n rail: options.rail,\n signal,\n })\n // One read names every payment on the page by the order it settles.\n const ids = [\n ...new Set(page.data.flatMap((p) => (p.order_id ? [p.order_id] : []))),\n ]\n const orders: Record<string, Order> = {}\n if (ids.length) {\n const bills = await client.listOrders({ ids, signal })\n for (const o of bills.data) orders[o.id] = o\n }\n return { ...page, orders }\n }\n )\n const data = remote.data\n const nextCursor = data?.next_cursor ?? null\n return {\n payments: data?.data ?? null,\n orders: data?.orders ?? noOrders,\n page,\n hasMore: nextCursor !== null,\n loading: remote.loading,\n error: remote.error,\n next: useCallback(() => {\n if (nextCursor !== null)\n setState({ filter, cursors: [...cursors, nextCursor] })\n }, [filter, cursors, nextCursor]),\n previous: useCallback(() => {\n if (cursors.length > 1)\n setState({ filter, cursors: cursors.slice(0, -1) })\n }, [filter, cursors]),\n refetch: remote.refetch,\n }\n}\n"],"mappings":"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"}
|