@delopay/sdk 0.117.0 → 0.119.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/dist/{chunk-RN4LGMQM.js → chunk-IQIUYV2B.js} +72 -4
- package/dist/chunk-IQIUYV2B.js.map +1 -0
- package/dist/index.cjs +71 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +285 -11
- package/dist/index.d.ts +285 -11
- package/dist/index.js +1 -1
- package/dist/internal.cjs +84 -3
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +42 -3
- package/dist/internal.d.ts +42 -3
- package/dist/internal.js +14 -1
- package/dist/internal.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-RN4LGMQM.js.map +0 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/error.ts","../src/resources/apiKeys.ts","../src/resources/authentication.ts","../src/resources/billing.ts","../src/resources/blocklist.ts","../src/resources/connectors.ts","../src/resources/customers.ts","../src/resources/disputes.ts","../src/resources/ephemeralKeys.ts","../src/resources/events.ts","../src/resources/fees.ts","../src/resources/mandates.ts","../src/resources/merchantAccounts.ts","../src/resources/paymentLinks.ts","../src/resources/paymentMethods.ts","../src/resources/payments.ts","../src/resources/payouts.ts","../src/resources/poll.ts","../src/resources/profileAcquirers.ts","../src/resources/profiles.ts","../src/resources/projects.ts","../src/resources/refunds.ts","../src/resources/relay.ts","../src/resources/routing.ts","../src/resources/search.ts","../src/resources/shops.ts","../src/resources/stripeConnect.ts","../src/resources/threeDsRules.ts","../src/resources/users.ts","../src/resources/verification.ts","../src/resources/webhooks.ts","../src/resources/analytics.ts","../src/resources/analyticsDashboard.ts","../src/resources/cards.ts","../src/resources/export.ts","../src/resources/featureMatrix.ts","../src/resources/files.ts","../src/resources/forex.ts","../src/resources/regions.ts","../src/resources/availabilityOverrides.ts","../src/resources/subscriptions.ts","../src/resources/audit.ts","../src/resources/settlement.ts","../src/resources/operationLimits.ts","../src/resources/risk.ts","../src/client.ts","../src/feeProgram.ts","../src/branding.ts","../src/checkoutSession.ts","../src/panes.ts"],"sourcesContent":["export { Delopay } from './client';\nexport type {\n DelopayOptions,\n RequestOptions,\n RequestExtras,\n RequestFn,\n DelopayLogger,\n} from './client';\nexport { DelopayError, DelopayAuthenticationError } from './error';\nexport type * from './types';\nexport { Webhooks } from './resources/webhooks';\nexport type { WebhookEvent } from './resources/webhooks';\n\n// Platform fee-rule engine: builder for the Euclid fee program consumed by\n// `delopay.fees.rules.upsert(...)` (and the admin `platformFees.rules`).\nexport {\n feeProgram,\n FeeProgramBuilder,\n leaf,\n allOf,\n anyOf,\n programToTree,\n ruleMatchToTree,\n} from './feeProgram';\nexport type {\n FeeSpecInput,\n FeeRuleInput,\n FeeRuleConditions,\n ConditionNode,\n LeafNode,\n GroupNode,\n} from './feeProgram';\n\n// Checkout branding — shared between the buyer-facing checkout\n// (delopay-checkout) and the merchant control-center's branding form so\n// the form saves what the checkout can read back, and vice versa.\nexport {\n fontStack,\n radiusValue,\n fontWeightValue,\n surfacePadValue,\n verticalGapValue,\n inputPadValue,\n buttonPadValue,\n logoDimensions,\n isHexColor,\n isDarkSurface,\n contrastRatio,\n WCAG_AA_TEXT,\n SURCHARGE_POSITIONS,\n SURCHARGE_STYLES,\n SURCHARGE_SIZES,\n SURCHARGE_SHAPES,\n SURCHARGE_BORDER_WIDTHS,\n SURCHARGE_BORDER_STYLES,\n SURCHARGE_WEIGHTS,\n SURCHARGE_SIGNS,\n SURCHARGE_LABEL_MODES,\n readableInkOn,\n surchargeShowsLabel,\n surchargeFigurePlan,\n surchargeWordFor,\n checkoutCopy,\n copyTranslationsKey,\n CHECKOUT_LOCALES,\n LOCALIZABLE_COPY_FIELDS,\n SURCHARGE_FIGURE_MODES,\n surchargeStyleDrawsAShape,\n WCAG_AA_UI,\n shadowFor,\n sanitizeCustomCss,\n applyBrandingVariables,\n decodeBadges,\n encodeBadges,\n decodeCustomFields,\n encodeCustomFields,\n parseCustomFieldsLoose,\n customFieldText,\n customFieldOptionLabel,\n cloneCustomField,\n defaultCustomFieldVisibility,\n defaultOperatorForSource,\n customFieldOperatorTakesValue,\n customFieldIsTextLike,\n isCheckboxChecked,\n customFieldContextFromMetadata,\n evaluateCustomFieldCondition,\n evaluateCustomFieldVisibility,\n visibleCustomFields,\n decodeBranding,\n encodeBranding,\n cloneBranding,\n defaultBranding,\n buildBrandingExport,\n parseImportedBranding,\n DEFAULT_BRANDING,\n DEFAULT_BRANDING_DARK,\n DEFAULT_BADGES,\n DEFAULT_BADGES_DARK,\n CUSTOM_CSS_MAX_LENGTH,\n CUSTOM_FIELDS_MAX,\n CUSTOM_FIELD_KEY_PATTERN,\n ALL_CUSTOM_FIELD_TYPES,\n CHECKBOX_CHECKED,\n CHECKBOX_UNCHECKED,\n CUSTOM_FIELD_CONDITIONS_MAX,\n ALL_CUSTOM_FIELD_CONDITION_SOURCES,\n ALL_CUSTOM_FIELD_OPERATORS,\n CUSTOM_FIELD_OPERATORS_BY_SOURCE,\n CUSTOM_FIELD_VALUELESS_OPERATORS,\n BRANDING_EXPORT_FORMAT,\n BRANDING_EXPORT_VERSION,\n} from './branding';\nexport type {\n CheckoutBranding,\n TrustBadge,\n CheckoutCustomField,\n CustomFieldType,\n CustomFieldOption,\n CustomFieldTranslations,\n CustomFieldCondition,\n CustomFieldConditionSource,\n CustomFieldOperator,\n CustomFieldVisibility,\n CustomFieldContext,\n CornerRadius,\n NonPillRadius,\n SpacingScale,\n SizeScale,\n SurfaceStyle,\n FontFamily,\n FontWeight,\n LayoutStyle,\n SummaryPosition,\n SurchargePosition,\n SurchargeStyle,\n SurchargeSize,\n SurchargeShape,\n SurchargeBorderWidth,\n SurchargeBorderStyle,\n SurchargeWeight,\n SurchargeSign,\n SurchargeLabelMode,\n SurchargeFigureMode,\n SurchargeFigurePart,\n SurchargeFigurePlan,\n CheckoutLocale,\n LocalizableCopyField,\n LabelStyle,\n PaymentLayout,\n LogoShape,\n LogoSize,\n BrandingSource,\n EncodedBranding,\n BrandingExport,\n} from './branding';\n\n// New resources (Phases 3-4)\nexport { Analytics } from './resources/analytics';\nexport { AnalyticsDashboard } from './resources/analyticsDashboard';\nexport { Cards } from './resources/cards';\nexport { Export } from './resources/export';\nexport { FeatureMatrix } from './resources/featureMatrix';\nexport { Files } from './resources/files';\nexport { Forex } from './resources/forex';\nexport { Regions } from './resources/regions';\nexport { AvailabilityOverrides } from './resources/availabilityOverrides';\nexport { Subscriptions } from './resources/subscriptions';\nexport { Audit } from './resources/audit';\nexport { Settlement } from './resources/settlement';\nexport { OperationLimits } from './resources/operationLimits';\nexport { Risk } from './resources/risk';\nexport { Search } from './resources/search';\n\n// Buyer-side client for a single hosted-checkout payment: binds the\n// publishable key + client secret once and gives each route exactly the\n// credential it expects.\nexport { CheckoutSession } from './checkoutSession';\nexport type { CheckoutSessionOptions, PublishableKey } from './checkoutSession';\nexport type {\n SearchIndex,\n SearchStatus,\n SearchGroupResponse,\n GlobalSearchRequest,\n SearchTimeRange,\n} from './resources/search';\n\n// Payment panes — merchant-configured payment methods promoted out of a\n// connector's own embedded form into DeloPay-drawn tiles, plus the focused\n// single-method checkout link those tiles (and a merchant's own button) open.\nexport {\n STRIPE_FALLBACK_PANE_METHODS,\n STRIPE_FALLBACK_PANE_CATALOG,\n PANE_ICON_KEYS,\n PANE_CATEGORY_KEYS,\n PANES_MAX,\n CHECKOUT_EVENT_KINDS,\n emptyPaneCatalog,\n paneCatalogFor,\n paneMethodInfo,\n paneRailAllowed,\n offerablePaneMethods,\n paneDisplayDefaults,\n paneViewVisibility,\n validatePanes,\n defaultPane,\n clonePane,\n decodePanes,\n encodePanes,\n focusedCheckoutUrl,\n} from './panes';\nexport type {\n Pane,\n PaneView,\n PaneVisibility,\n PaneOpenTarget,\n PaneMethodInfo,\n PaneDisplayDefaults,\n PaneIssue,\n PaneIssueCode,\n PaneSurcharge,\n FocusedCheckoutUrlParams,\n CheckoutEventKind,\n} from './panes';\n\n// Pre-0.109.0 pane names. Removed in 0.112.0 — see CHANGELOG.md.\n// The catalogue's own deprecated names (`NativePaneRail`, `NativePaneCapability`,\n// `NativePanesConnectorCatalog`, `NativePanesCatalogResponse`) come through the\n// `export type * from './types'` above.\nexport {\n STRIPE_NATIVE_PANE_METHODS,\n NATIVE_PANE_ICON_KEYS,\n NATIVE_PANE_CATEGORY_KEYS,\n NATIVE_PANES_MAX,\n nativePaneMethodInfo,\n defaultNativePane,\n cloneNativePane,\n decodeNativePanes,\n encodeNativePanes,\n} from './panes';\nexport type {\n NativePaneVisibility,\n NativePaneOpenTarget,\n NativePaneView,\n NativePaneMethodInfo,\n StripeNativePane,\n} from './panes';\n","/**\n * Error thrown when the Delopay API returns a non-2xx response, or when a\n * timeout or network error occurs.\n *\n * @example\n * ```typescript\n * try {\n * await delopay.payments.create({ amount: 5000, currency: 'EUR' });\n * } catch (e) {\n * if (e instanceof DelopayError) {\n * console.error(e.status, e.code, e.requestId, e.message);\n * }\n * }\n * ```\n */\nexport class DelopayError extends Error {\n /** HTTP status code returned by the API, or `0` for timeout/network errors. */\n readonly status: number;\n /** Machine-readable error code returned by the API (e.g. `'HE_00'`). */\n readonly code: string;\n /** Error category (e.g. `'invalid_request'`, `'timeout_error'`). */\n readonly type: string;\n /** Value of the `x-request-id` response header, when present. Include this when contacting support. */\n readonly requestId?: string;\n /**\n * Raw response body (truncated to ~2 KB). Populated when the server returns a\n * non-JSON error body (e.g. an HTML 502 from an upstream proxy) so debugging\n * still has something to go on.\n */\n readonly rawBody?: string;\n /**\n * Structured error context the API attaches under `error.data` for select\n * codes — e.g. `{ retry_after_secs: 248 }` on rate-limit / max-attempt\n * lockouts. Schema is per-code; consult the API reference for the shape.\n */\n readonly data?: Record<string, unknown>;\n\n constructor(\n message: string,\n options: {\n status: number;\n code: string;\n type: string;\n requestId?: string;\n rawBody?: string;\n data?: Record<string, unknown>;\n },\n ) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'DelopayError';\n this.status = options.status;\n this.code = options.code;\n this.type = options.type;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.rawBody !== undefined) this.rawBody = options.rawBody;\n if (options.data !== undefined) this.data = options.data;\n }\n}\n\n/**\n * Thrown when the API key is missing, invalid, or revoked (HTTP 401).\n *\n * @example\n * ```typescript\n * if (e instanceof DelopayAuthenticationError) {\n * // Prompt user to re-enter their API key.\n * }\n * ```\n */\nexport class DelopayAuthenticationError extends DelopayError {\n constructor(\n message = 'Invalid API key',\n options?: {\n code?: string;\n type?: string;\n requestId?: string;\n rawBody?: string;\n data?: Record<string, unknown>;\n },\n ) {\n super(message, {\n status: 401,\n // Default to the generic \"invalid API key\" code, but let callers pass\n // through the server-reported code (e.g. `UR_05` for unverified-email\n // 401s) so they can differentiate between auth failure reasons.\n code: options?.code || 'AUTH_01',\n type: options?.type || 'authentication_error',\n requestId: options?.requestId,\n rawBody: options?.rawBody,\n data: options?.data,\n });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'DelopayAuthenticationError';\n }\n}\n","import type {\n ApiKeyCreateRequest,\n ApiKeyCreateResponse,\n ApiKeyListConstraints,\n ApiKeyResponse,\n ApiKeyUpdateRequest,\n ApiKeyRevokeResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage API keys for a merchant account. */\nexport class ApiKeys {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new API key for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Key creation parameters (name, expiry, etc.).\n * @returns The newly created key including the plaintext secret (shown once only).\n *\n * @example\n * ```typescript\n * const { key_value } = await delopay.apiKeys.create('merch_123', { name: 'Production key' });\n * ```\n */\n async create(merchantId: string, params: ApiKeyCreateRequest): Promise<ApiKeyCreateResponse> {\n return this.request('POST', `/api-keys/${encodeURIComponent(merchantId)}`, { body: params });\n }\n\n /**\n * Retrieve metadata about an API key (does not return the plaintext secret).\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID.\n * @returns The API key metadata.\n */\n async retrieve(merchantId: string, keyId: string): Promise<ApiKeyResponse> {\n return this.request(\n 'GET',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * Update an API key's name or expiry.\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to update.\n * @param params - Fields to update.\n * @returns The updated API key metadata.\n */\n async update(\n merchantId: string,\n keyId: string,\n params: ApiKeyUpdateRequest,\n ): Promise<ApiKeyResponse> {\n return this.request(\n 'POST',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,\n { body: params },\n );\n }\n\n /**\n * Revoke an API key, immediately invalidating it.\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to revoke.\n * @returns Revocation confirmation.\n */\n async revoke(merchantId: string, keyId: string): Promise<ApiKeyRevokeResponse> {\n return this.request(\n 'DELETE',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * List all API keys for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns Array of API key metadata objects.\n */\n async list(merchantId: string): Promise<ApiKeyResponse[]> {\n return this.request('GET', `/api-keys/${encodeURIComponent(merchantId)}/list`);\n }\n\n // --- Profile-scoped (shop-level) API keys ---------------------------------\n //\n // JWT-authenticated routes under `/account/{merchantId}/profile/api-keys`.\n // The caller's shop (business profile) comes from the JWT, never from the\n // request, so a shop-scoped user can only mint/list/manage keys pinned to\n // their own shop. Requires a backend with profile-scoped API key support.\n\n /**\n * Create a new API key pinned to the caller's shop (business profile).\n * `POST /account/{merchantId}/profile/api-keys`\n *\n * @param merchantId - The merchant account ID.\n * @param params - Key creation parameters (name, expiry, etc.).\n * @returns The newly created key including the plaintext secret (shown once\n * only) and the `profile_id` it is pinned to.\n *\n * @example\n * ```typescript\n * const { api_key } = await delopay.apiKeys.createByProfile('merch_123', {\n * name: 'Shop key',\n * expiration: 'never',\n * });\n * ```\n */\n async createByProfile(\n merchantId: string,\n params: ApiKeyCreateRequest,\n ): Promise<ApiKeyCreateResponse> {\n return this.request('POST', `/account/${encodeURIComponent(merchantId)}/profile/api-keys`, {\n body: params,\n });\n }\n\n /**\n * List API keys pinned to the caller's shop (business profile) only.\n * `GET /account/{merchantId}/profile/api-keys`\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional pagination constraints (`limit`, `skip`).\n * @returns Array of API key metadata objects belonging to the caller's shop.\n */\n async listByProfile(\n merchantId: string,\n params?: ApiKeyListConstraints,\n ): Promise<ApiKeyResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(merchantId)}/profile/api-keys`, {\n query: params as Record<string, number | null | undefined>,\n });\n }\n\n /**\n * Retrieve metadata about a shop-pinned API key (does not return the\n * plaintext secret). `GET /account/{merchantId}/profile/api-keys/{keyId}`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID.\n * @returns The API key metadata.\n */\n async retrieveByProfile(merchantId: string, keyId: string): Promise<ApiKeyResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * Update a shop-pinned API key's name, description, or expiry.\n * `POST /account/{merchantId}/profile/api-keys/{keyId}`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to update.\n * @param params - Fields to update.\n * @returns The updated API key metadata.\n */\n async updateByProfile(\n merchantId: string,\n keyId: string,\n params: ApiKeyUpdateRequest,\n ): Promise<ApiKeyResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}`,\n { body: params },\n );\n }\n\n /**\n * Revoke a shop-pinned API key, immediately invalidating it.\n * `DELETE /account/{merchantId}/profile/api-keys/{keyId}`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to revoke.\n * @returns Revocation confirmation.\n */\n async revokeByProfile(merchantId: string, keyId: string): Promise<ApiKeyRevokeResponse> {\n return this.request(\n 'DELETE',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}`,\n );\n }\n}\n","import type { AuthenticationCreateRequest, AuthenticationResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Authentication {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: AuthenticationCreateRequest): Promise<AuthenticationResponse> {\n return this.request('POST', '/authentication', { body: params });\n }\n\n async checkEligibility(authId: string): Promise<AuthenticationResponse> {\n return this.request('POST', `/authentication/${encodeURIComponent(authId)}/eligibility`);\n }\n\n async authenticate(\n authId: string,\n params: Record<string, unknown>,\n ): Promise<AuthenticationResponse> {\n return this.request('POST', `/authentication/${encodeURIComponent(authId)}/authenticate`, {\n body: params,\n });\n }\n\n /** Sync authentication status. `POST /authentication/{merchantId}/{authId}/sync` */\n async sync(\n merchantId: string,\n authId: string,\n params?: Record<string, unknown>,\n ): Promise<AuthenticationResponse> {\n return this.request(\n 'POST',\n `/authentication/${encodeURIComponent(merchantId)}/${encodeURIComponent(authId)}/sync`,\n { body: params },\n );\n }\n\n /** Redirect after authentication. `POST /authentication/{merchantId}/{authId}/redirect` */\n async redirect(\n merchantId: string,\n authId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request(\n 'POST',\n `/authentication/${encodeURIComponent(merchantId)}/${encodeURIComponent(authId)}/redirect`,\n { body: params },\n );\n }\n\n /** Enable authn methods token. `POST /authentication/{authId}/enabled-authn-methods-token` */\n async enabledAuthnMethodsToken(\n authId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request(\n 'POST',\n `/authentication/${encodeURIComponent(authId)}/enabled-authn-methods-token`,\n {\n body: params,\n },\n );\n }\n\n /** Submit eligibility check. `POST /authentication/{authId}/eligibility-check` */\n async eligibilityCheck(\n authId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/authentication/${encodeURIComponent(authId)}/eligibility-check`, {\n body: params,\n });\n }\n}\n","import type {\n BillingProfileResponse,\n BillingSetupRequest,\n BillingSetupResponse,\n BillingCompleteSetupRequest,\n TopupRequest,\n TopupResponse,\n LedgerResponse,\n LedgerListParams,\n BlockedAttemptListResponse,\n BlockedAttemptListParams,\n AutoRechargeUpdateRequest,\n AllocationTransferRequest,\n AllocationTransferResponse,\n AllocationListResponse,\n AllocationResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Manage per-shop prepaid balance allocations transferred from the host merchant treasury. */\nclass BillingAllocations {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Transfer funds from the host merchant treasury into a shop's allocation.\n *\n * @param merchantId - The host merchant account ID.\n * @param params - Transfer details (amount, target profile/shop ID).\n * @returns The allocation transfer result.\n */\n async transferIn(\n merchantId: string,\n params: AllocationTransferRequest,\n ): Promise<AllocationTransferResponse> {\n return this.request(\n 'POST',\n `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-in`,\n { body: params },\n );\n }\n\n /**\n * Transfer funds from a shop's allocation back to the host merchant treasury.\n *\n * @param merchantId - The host merchant account ID.\n * @param params - Transfer details (amount, source profile/shop ID).\n * @returns The allocation transfer result.\n */\n async transferOut(\n merchantId: string,\n params: AllocationTransferRequest,\n ): Promise<AllocationTransferResponse> {\n return this.request(\n 'POST',\n `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-out`,\n {\n body: params,\n },\n );\n }\n\n /**\n * List all shop balance allocations for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns List of shop allocations.\n */\n async list(merchantId: string): Promise<AllocationListResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}/allocations`);\n }\n\n /**\n * Get the balance allocation for a specific shop.\n *\n * @param merchantId - The merchant account ID.\n * @param profileId - The shop (business profile) ID.\n * @returns The shop's balance allocation.\n */\n async get(merchantId: string, profileId: string): Promise<AllocationResponse> {\n return this.request(\n 'GET',\n `/billing/${encodeURIComponent(merchantId)}/allocations/${encodeURIComponent(profileId)}`,\n );\n }\n}\n\n/**\n * Manage prepaid billing balances — top-ups, card setup, auto-recharge, and the balance ledger.\n *\n * Delopay deducts a platform fee from the merchant's prepaid balance on every successful payment.\n * Use these endpoints to fund and monitor that balance.\n */\nexport class Billing {\n /** Per-shop balance allocation management for host merchants. */\n readonly allocations: BillingAllocations;\n\n constructor(private readonly request: RequestFn) {\n this.allocations = new BillingAllocations(request);\n }\n\n /**\n * Retrieve a merchant's billing profile (balance, status, auto-recharge config).\n *\n * @param merchantId - The merchant account ID.\n * @returns The billing profile.\n *\n * @example\n * ```typescript\n * const profile = await delopay.billing.getProfile('merch_123');\n * console.log(profile.balance, profile.status);\n * ```\n */\n async getProfile(merchantId: string): Promise<BillingProfileResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}`);\n }\n\n /**\n * Start a Stripe SetupIntent flow to collect a payment card for auto-recharge.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional setup parameters.\n * @returns The Stripe client secret needed to render the card element.\n */\n async setup(merchantId: string, params?: BillingSetupRequest): Promise<BillingSetupResponse> {\n return this.request('POST', `/billing/${encodeURIComponent(merchantId)}/setup`, {\n body: params,\n });\n }\n\n /**\n * Confirm card setup after the Stripe SetupIntent completes on the frontend.\n *\n * @param merchantId - The merchant account ID.\n * @param params - The Stripe SetupIntent ID to confirm.\n * @returns The updated billing profile.\n */\n async completeSetup(\n merchantId: string,\n params: BillingCompleteSetupRequest,\n ): Promise<BillingProfileResponse> {\n return this.request('POST', `/billing/${encodeURIComponent(merchantId)}/setup/complete`, {\n body: params,\n });\n }\n\n /**\n * Manually top up a merchant's prepaid balance by charging their saved card.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Top-up amount and currency.\n * @returns The top-up result.\n */\n async topup(merchantId: string, params: TopupRequest): Promise<TopupResponse> {\n return this.request('POST', `/billing/${encodeURIComponent(merchantId)}/topup`, {\n body: params,\n });\n }\n\n /**\n * List the balance ledger (credits and debits) for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional pagination parameters.\n * @returns The ledger entries.\n */\n async listLedger(merchantId: string, params?: LedgerListParams): Promise<LedgerResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}/ledger`, {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * List payment attempts that were blocked by the billing suspension gate\n * (account suspended, setup incomplete, or shop allocation suspended).\n *\n * These attempts never created a payment, so they do not appear in the\n * payments list — this is the only way to retrieve them.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional filters (profile, reason, date range) and pagination.\n * @returns The blocked-attempt entries with a total count.\n */\n async listBlockedAttempts(\n merchantId: string,\n params?: BlockedAttemptListParams,\n ): Promise<BlockedAttemptListResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}/blocked-attempts`, {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * Update auto-recharge configuration (threshold, top-up amount, enabled flag).\n *\n * @param merchantId - The merchant account ID.\n * @param params - Auto-recharge settings to update.\n * @returns The updated billing profile.\n */\n async updateAutoRecharge(\n merchantId: string,\n params: AutoRechargeUpdateRequest,\n ): Promise<BillingProfileResponse> {\n return this.request('PATCH', `/billing/${encodeURIComponent(merchantId)}/auto-recharge`, {\n body: params,\n });\n }\n}\n","import type { BlocklistAddRequest, BlocklistResponse, BlocklistDataKind } from '../types';\nimport type { RequestFn } from '../client';\n\nexport interface BlocklistListParams {\n data_kind?: BlocklistDataKind | null;\n limit?: number | null;\n offset?: number | null;\n}\n\nexport interface BlocklistToggleParams {\n status: boolean;\n}\n\nexport class Blocklist {\n constructor(private readonly request: RequestFn) {}\n\n async add(params: BlocklistAddRequest): Promise<BlocklistResponse> {\n return this.request('POST', '/blocklist', { body: params });\n }\n\n async remove(params: BlocklistAddRequest): Promise<BlocklistResponse> {\n return this.request('DELETE', '/blocklist', { body: params });\n }\n\n async list(params?: BlocklistListParams): Promise<BlocklistResponse[]> {\n return this.request('GET', '/blocklist', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n async toggle(params: BlocklistToggleParams): Promise<Record<string, unknown>> {\n return this.request('POST', '/blocklist/toggle', { body: params });\n }\n}\n","import type {\n ConnectorCloneRequest,\n EpayoutsCatalogResponse,\n PanesCatalogResponse,\n VaultRoutesApplyRequest,\n VaultRoutesApplyResponse,\n VaultRoutesPreviewRequest,\n VaultRoutesPreviewResponse,\n VaultVerificationResponse,\n VaultVerifyRequest,\n ConnectorCreateRequest,\n ConnectorResponse,\n ConnectorUpdateRequest,\n ConnectorWebhookListResponse,\n ConnectorWebhookRegisterRequest,\n ConnectorWebhookRegisterResponse,\n ConnectorWebhookSyncResponse,\n StripePaymentMethodDomainsRegisterRequest,\n StripePaymentMethodDomainsRegisterResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Connectors {\n constructor(private readonly request: RequestFn) {}\n\n async create(accountId: string, params: ConnectorCreateRequest): Promise<ConnectorResponse> {\n return this.request('POST', `/account/${encodeURIComponent(accountId)}/connectors`, {\n body: params,\n });\n }\n\n /**\n * One connector account.\n *\n * The credential-bearing fields come back `null` here, whatever is stored:\n * `connector_webhook_details`, `connector_wallets_details`,\n * `pm_auth_config` and `additional_merchant_data`. They are dropped rather\n * than masked, because an editor that prefills from this response and\n * PATCHes the field back would otherwise save a mask over a live signing\n * secret. Send those fields only when the operator has typed a new value,\n * and omit them entirely otherwise — an omitted field leaves the stored one\n * alone.\n *\n * This is the retrieve path alone. `create` and `update` echo back what the\n * caller sent, and `clone` returns the *copied* secrets — see that method.\n *\n * Because the value is gone, `has_live_webhook_secret` and\n * `has_sandbox_webhook_secret` are what tell a stored webhook signing secret\n * from an unconfigured one. Render those; never infer configuration from the\n * `null` block.\n *\n * `GET /account/{accountId}/connectors/{connectorId}`\n */\n async retrieve(accountId: string, connectorId: string): Promise<ConnectorResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,\n );\n }\n\n /**\n * The merchant's connector accounts.\n *\n * Never wider than the caller: an API key pinned to one shop lists that\n * shop's connectors only, not every sibling shop's.\n *\n * `GET /account/{accountId}/connectors`\n */\n async list(accountId: string): Promise<ConnectorResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/connectors`);\n }\n\n /**\n * The profile-scoped connector list. The merchant-wide `list()` is\n * merchant-gated and 403s for a profile-entity (shop user) JWT; this\n * variant is scoped server-side to the caller's own profile.\n *\n * `GET /account/{accountId}/profile/connectors`\n */\n async listByProfile(accountId: string): Promise<ConnectorResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/profile/connectors`);\n }\n\n /**\n * The built-in e-Payouts reference catalog — the \"Restore defaults\" source.\n * `GET /account/{accountId}/connectors/epayouts/catalog/defaults`\n */\n async getEpayoutsCatalogDefaults(accountId: string): Promise<EpayoutsCatalogResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/connectors/epayouts/catalog/defaults`,\n );\n }\n\n /**\n * Every connector's pane capabilities, as the router itself knows them —\n * which rails a connector supports, and which methods it can publish as a\n * pane with the confirm routing keys each one carries.\n *\n * Capability facts only: no label, sublabel or category comes back. A\n * designer renders a method's copy from its own locale files, keyed by\n * `key`, and takes `payment_method` / `payment_method_type` from here\n * verbatim rather than deriving them client-side.\n *\n * This is what the pane helpers in `src/panes.ts` should be driven from —\n * `paneMethodInfo`, `defaultPane` and `validatePanes` all take a\n * {@link PanesConnectorCatalog} out of this response, so a connector the\n * router starts publishing panes for needs no SDK release.\n *\n * `GET /account/{accountId}/connectors/native-panes/catalog`\n *\n * The path keeps the `native-panes` spelling deliberately. The identifiers\n * were renamed off \"native pane\"; the route was not, and pointing at the\n * backend's new name before it is deployed everywhere would both 404 against\n * un-upgraded replicas mid-rollout and fail `scripts/parity-check.mjs`,\n * which blocks publishing.\n */\n async getPanesCatalog(accountId: string): Promise<PanesCatalogResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/connectors/native-panes/catalog`,\n );\n }\n\n /** @deprecated Renamed to {@link getPanesCatalog}. Removed in 0.112.0. */\n async getNativePanesCatalog(accountId: string): Promise<PanesCatalogResponse> {\n return this.getPanesCatalog(accountId);\n }\n\n /**\n * Sweep the merchant's own e-Payouts module and return the rails it\n * actually has enabled. Server-side this makes many upstream calls, so it\n * can take several seconds — show progress.\n *\n * `POST /account/{accountId}/connectors/{connectorId}/epayouts/catalog/sync`\n */\n async syncEpayoutsCatalog(\n accountId: string,\n connectorId: string,\n ): Promise<EpayoutsCatalogResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/epayouts/catalog/sync`,\n );\n }\n\n /**\n * Update a connector account.\n *\n * `connector_webhook_details` **merges** into the stored block key by key:\n * an absent key keeps its stored secret, an explicit value is written, and\n * an explicit empty string clears that secret. Send only the\n * keys the operator typed — padding the other environment's keys with `''`\n * clears a live signing secret and inbound webhooks stop verifying.\n *\n * The other credential-bearing fields — `connector_wallets_details`,\n * `pm_auth_config`, `additional_merchant_data` — are still whole-value\n * replacements: omit them unless you are writing a complete new value.\n *\n * `POST /account/{accountId}/connectors/{connectorId}`\n */\n async update(\n accountId: string,\n connectorId: string,\n params: ConnectorUpdateRequest,\n ): Promise<ConnectorResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,\n {\n body: params,\n },\n );\n }\n\n /**\n * Remove a connector account.\n *\n * A shop-scoped role may remove a connector of its own shop — the shop is\n * re-checked server-side — so creating processors and removing them are the\n * same rung of access rather than two.\n *\n * `DELETE /account/{accountId}/connectors/{connectorId}`\n */\n async delete(accountId: string, connectorId: string): Promise<ConnectorResponse> {\n return this.request(\n 'DELETE',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,\n );\n }\n\n /**\n * Clone a connector into another shop (business profile) of the same\n * merchant. `POST /account/{accountId}/connectors/{connectorId}/clone`\n *\n * Credentials are copied server-side, re-encrypted under the same merchant\n * key, so the caller never has to *supply* them — `retrieve` returns `null`\n * for the credential fields, which is what makes a client-side copy\n * impossible in the first place.\n *\n * The response, however, is the unredacted connector: `connector_account_details`\n * is masked, but `connector_webhook_details`, `connector_wallets_details`,\n * `pm_auth_config` and `additional_merchant_data` come back with the copied\n * secrets in them — values this caller never sent. Do not log or echo the\n * response; read `merchant_connector_id` and discard the rest.\n */\n async clone(\n accountId: string,\n connectorId: string,\n params: ConnectorCloneRequest,\n ): Promise<ConnectorResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/clone`,\n { body: params },\n );\n }\n\n // --- Advanced operations (Task 4.8) ---\n\n /**\n * Run the configuration checks for a vault (VGS) connector account:\n * credential validity, write-only Collect scope, reachability, environment\n * coherence, route coverage. Read-only but not cheap — it decrypts the\n * vault's management credential and talks to VGS.\n *\n * `POST /account/{accountId}/connectors/{connectorId}/vault/verify`\n */\n async verifyVault(\n accountId: string,\n connectorId: string,\n params: VaultVerifyRequest,\n ): Promise<VaultVerificationResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/vault/verify`,\n { body: params },\n );\n }\n\n /**\n * Compute the route document the vault SHOULD have and diff it against\n * what exists, without writing anything. The returned fingerprints must be\n * echoed byte for byte on {@link Connectors.applyVaultRoutes}.\n *\n * A router without these endpoints answers 404 — render that as \"this\n * build cannot configure routes\", never as \"there is nothing to change\".\n *\n * `POST /account/{accountId}/connectors/{connectorId}/vault/routes/preview`\n */\n async previewVaultRoutes(\n accountId: string,\n connectorId: string,\n params: VaultRoutesPreviewRequest,\n ): Promise<VaultRoutesPreviewResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/vault/routes/preview`,\n { body: params },\n );\n }\n\n /**\n * Write the routes the merchant just previewed. Both fingerprints come\n * from the preview and are opaque: `expected_current_fingerprint` says the\n * vault has not moved (`null` = \"the preview found no routes\" and is sent\n * as `null`, never omitted), `expected_desired_fingerprint` says the\n * document is still the one on screen. A 409 (`DE_04`) means the vault\n * changed since the preview — nothing was written; preview again.\n *\n * `POST /account/{accountId}/connectors/{connectorId}/vault/routes/apply`\n */\n async applyVaultRoutes(\n accountId: string,\n connectorId: string,\n params: VaultRoutesApplyRequest,\n ): Promise<VaultRoutesApplyResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/vault/routes/apply`,\n { body: params },\n );\n }\n\n /** Verify connector credentials. `POST /account/connectors/verify` */\n async verify(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/account/connectors/verify', { body: params });\n }\n\n /**\n * Register a webhook for a connector.\n * `POST /account/{merchantId}/connectors/webhooks/{connectorId}`\n *\n * @param params - Optional event scope. Defaults to `{ event_type: 'all_events' }`\n * when omitted; pass `{ event_type: { specific_event: '…' } }` to scope\n * to a single event.\n */\n async registerWebhook(\n merchantId: string,\n connectorId: string,\n params?: ConnectorWebhookRegisterRequest,\n ): Promise<ConnectorWebhookRegisterResponse> {\n const path = `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`;\n if (params === undefined) return this.request('POST', path);\n return this.request('POST', path, { body: params });\n }\n\n /**\n * Register checkout/shop domains as Stripe payment method domains, so Apple\n * Pay renders on those pages.\n * `POST /account/{merchantId}/connectors/{connectorId}/stripe/payment-method-domains`\n *\n * Stripe connectors only. One call registers against a single credential set\n * (`environment`, default `'live'`) — call twice to cover live and sandbox.\n * Per-URL outcomes come back in `results`; a missing sandbox credential set\n * is a request-level 400.\n */\n async registerStripePaymentMethodDomains(\n merchantId: string,\n connectorId: string,\n params: StripePaymentMethodDomainsRegisterRequest,\n ): Promise<StripePaymentMethodDomainsRegisterResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/connectors/${encodeURIComponent(connectorId)}/stripe/payment-method-domains`,\n { body: params },\n );\n }\n\n /** Get registered webhooks for a connector. `GET /account/{merchantId}/connectors/webhooks/{connectorId}` */\n async getWebhook(merchantId: string, connectorId: string): Promise<ConnectorWebhookListResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`,\n );\n }\n\n /**\n * Bring an already-registered webhook's event subscription up to date with\n * the events Delopay handles.\n * `POST /account/{merchantId}/connectors/webhooks/{connectorId}/sync-events`\n *\n * A PSP freezes an endpoint's event list at registration time, so an endpoint\n * created before an event type was added never receives it — silently, with\n * no error anywhere. {@link getWebhook} reports the gap as `missing_events`;\n * this repairs it.\n *\n * Unlike re-registering, the endpoints are updated in place: the endpoint id\n * and its signing secret are preserved, so signature verification keeps\n * working across the change. Stripe connectors only; idempotent, so it is\n * safe to call on a schedule or after every deploy.\n *\n * @example\n * ```typescript\n * const sync = await delopay.connectors.syncWebhookEvents('mer_abc', 'mca_xyz');\n * for (const endpoint of sync.endpoints) {\n * if (endpoint.error_message) console.warn(endpoint.connector_webhook_id, endpoint.error_message);\n * else if (endpoint.updated) console.log('subscribed', endpoint.added_events);\n * }\n * ```\n */\n async syncWebhookEvents(\n merchantId: string,\n connectorId: string,\n ): Promise<ConnectorWebhookSyncResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}/sync-events`,\n );\n }\n\n /** List available payment methods. `GET /account/payment-methods` */\n async listPaymentMethods(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/account/payment-methods');\n }\n}\n","import type {\n CustomerCreateRequest,\n CustomerResponse,\n CustomerUpdateRequest,\n CustomerListParams,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Flatten list params for the query string.\n *\n * `profile_ids` must go out as ONE comma-separated value. The client\n * serializes arrays as repeated keys (`?profile_ids=a&profile_ids=b`), and the\n * customers endpoints cannot parse that — the whole request fails, rather than\n * the second id being ignored. So the join happens here, once, instead of at\n * four call sites.\n */\nfunction toQuery(\n params?: CustomerListParams,\n): Record<string, string | number | boolean | undefined> | undefined {\n if (!params) return undefined;\n const { profile_ids, ...rest } = params;\n const query = rest as Record<string, string | number | boolean | undefined>;\n // An empty array means \"no shop filter\", which is the absent key — sending\n // `profile_ids=` would work too, but omitting it keeps the URL honest.\n if (profile_ids && profile_ids.length > 0) {\n query.profile_ids = profile_ids.join(',');\n }\n return query;\n}\n\n/** Create and manage customer profiles. */\nexport class Customers {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new customer.\n *\n * @param params - Customer creation parameters (name, email, phone, address, etc.).\n * @returns The created customer.\n *\n * @example\n * ```typescript\n * const customer = await delopay.customers.create({\n * email: 'alice@example.com',\n * name: 'Alice Smith',\n * });\n * ```\n */\n async create(params: CustomerCreateRequest): Promise<CustomerResponse> {\n return this.request('POST', '/customers', { body: params });\n }\n\n /**\n * Retrieve a customer by their ID.\n *\n * @param customerId - The unique customer ID.\n * @returns The customer.\n *\n * @example\n * ```typescript\n * const customer = await delopay.customers.retrieve('cus_abc123');\n * ```\n */\n async retrieve(customerId: string): Promise<CustomerResponse> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}`);\n }\n\n /**\n * Update an existing customer's details.\n *\n * @param customerId - The customer ID to update.\n * @param params - Fields to update (name, email, address, metadata, etc.).\n * @returns The updated customer.\n */\n async update(customerId: string, params: CustomerUpdateRequest): Promise<CustomerResponse> {\n return this.request('POST', `/customers/${encodeURIComponent(customerId)}`, { body: params });\n }\n\n /**\n * Delete a customer and all their saved payment methods.\n *\n * @param customerId - The customer ID to delete.\n * @returns The deleted customer object.\n */\n async delete(customerId: string): Promise<CustomerResponse> {\n return this.request('DELETE', `/customers/${encodeURIComponent(customerId)}`);\n }\n\n /**\n * List customers, optionally filtered by email, shop (`profile_id`), or\n * project (`project_id`).\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of customer objects.\n *\n * @example\n * ```typescript\n * // Customers who have transacted in a specific shop.\n * const customers = await delopay.customers.list({ profile_id: 'pro_abc123' });\n *\n * // Several shops at once (unions with profile_id / project_id).\n * const many = await delopay.customers.list({\n * profile_ids: ['pro_abc123', 'pro_def456'],\n * });\n * ```\n */\n async list(params?: CustomerListParams): Promise<CustomerResponse[]> {\n return this.request('GET', '/customers/list', {\n query: toQuery(params),\n });\n }\n\n // --- OLAP extensions (Task 4.6) ---\n\n /**\n * List customers with count. Supports the same `profile_id` / `project_id`\n * shop filters as {@link list}. `GET /customers/list-with-count`\n */\n async listWithCount(\n params?: CustomerListParams,\n ): Promise<{ count: number; total_count: number; data: CustomerResponse[] }> {\n return this.request('GET', '/customers/list-with-count', {\n query: toQuery(params),\n });\n }\n\n /**\n * List customers scoped to the authenticated dashboard user's shop\n * (business profile). The JWT auto-scopes to its own `profile`; an explicit\n * `profile_id` / `project_id` outside that scope is rejected with\n * `AccessForbidden`. `GET /customers/profile/list`\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of customer objects.\n */\n async listByProfile(params?: CustomerListParams): Promise<CustomerResponse[]> {\n return this.request('GET', '/customers/profile/list', {\n query: toQuery(params),\n });\n }\n\n /**\n * Profile-scoped variant of {@link listWithCount}.\n * `GET /customers/profile/list-with-count`\n */\n async listByProfileWithCount(\n params?: CustomerListParams,\n ): Promise<{ count: number; total_count: number; data: CustomerResponse[] }> {\n return this.request('GET', '/customers/profile/list-with-count', {\n query: toQuery(params),\n });\n }\n\n /** List mandates for a customer. `GET /customers/{customerId}/mandates` */\n async listMandates(customerId: string): Promise<Record<string, unknown>[]> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}/mandates`);\n }\n}\n","import type {\n DisputeResponse,\n DisputeListParams,\n DisputeEvidenceRequest,\n DeleteEvidenceRequest,\n DisputeEvidenceBlock,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** View and respond to payment disputes and chargebacks. */\nexport class Disputes {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Retrieve a dispute by its ID.\n *\n * @param disputeId - The unique dispute ID.\n * @returns The dispute.\n */\n async retrieve(disputeId: string): Promise<DisputeResponse> {\n return this.request('GET', `/disputes/${encodeURIComponent(disputeId)}`);\n }\n\n /**\n * List disputes, optionally filtered by status, stage, or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of disputes.\n */\n async list(params?: DisputeListParams): Promise<DisputeResponse[]> {\n return this.request('GET', '/disputes/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * Accept a dispute, conceding the chargeback to the customer.\n *\n * @param disputeId - The dispute ID to accept.\n * @returns The updated dispute.\n */\n async accept(disputeId: string): Promise<DisputeResponse> {\n return this.request('POST', `/disputes/accept/${encodeURIComponent(disputeId)}`);\n }\n\n /**\n * Submit evidence to challenge a dispute.\n *\n * @param params - Evidence details and the dispute ID to contest.\n * @returns The updated dispute.\n */\n async submitEvidence(params: DisputeEvidenceRequest): Promise<DisputeResponse> {\n return this.request('POST', '/disputes/evidence', { body: params });\n }\n\n /**\n * Attach evidence (e.g. file upload metadata) to a dispute.\n *\n * Uses `PUT /disputes/evidence`.\n */\n async attachEvidence(params: DisputeEvidenceRequest): Promise<DisputeResponse> {\n return this.request('PUT', '/disputes/evidence', { body: params });\n }\n\n /**\n * Retrieve previously stored evidence for a dispute.\n *\n * Returns an ARRAY of file-evidence blocks (this was previously mistyped\n * as the flat submit-request shape). Only file evidence is reported —\n * text evidence is not retrievable once submitted.\n *\n * @param disputeId - The dispute ID.\n * @returns The stored file-evidence blocks.\n */\n async retrieveEvidence(disputeId: string): Promise<DisputeEvidenceBlock[]> {\n return this.request('GET', `/disputes/evidence/${encodeURIComponent(disputeId)}`);\n }\n\n /**\n * Delete submitted evidence for a dispute.\n *\n * @param params - Evidence request body identifying what to delete.\n * @returns The updated dispute.\n */\n async deleteEvidence(params: DeleteEvidenceRequest): Promise<DisputeResponse> {\n return this.request('DELETE', '/disputes/evidence', { body: params });\n }\n\n // --- OLAP extensions (Task 4.4) ---\n\n /** List disputes (profile-scoped). `GET /disputes/profile/list` */\n async listByProfile(params?: DisputeListParams): Promise<DisputeResponse[]> {\n return this.request('GET', '/disputes/profile/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** Get dispute filter options. `GET /disputes/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/filter', { query: params });\n }\n\n /** Get dispute filters (profile-scoped). `GET /disputes/profile/filter` */\n async getFiltersByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/profile/filter', { query: params });\n }\n\n /** Get dispute aggregates. `GET /disputes/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/aggregate', { query: params });\n }\n\n /** Get dispute aggregates (profile-scoped). `GET /disputes/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/profile/aggregate', { query: params });\n }\n\n /**\n * Fetch the latest dispute state from the connector (gateway) and persist it.\n * `GET /disputes/{disputeId}?force_sync=true`\n *\n * The path parameter is the **Delopay dispute id** (`dp_…`). Force-sync asks the\n * backend to pull the dispute from the connector (supported where the connector\n * implements the dispute-sync flow, e.g. Stripe) and update the stored record\n * before returning it.\n *\n * Note: this method previously called `GET /disputes/{id}/fetch`, which is a\n * different backend route — a bulk import keyed by **merchant connector account\n * id** with a required date range — so every call with a dispute id failed.\n */\n async fetchFromConnector(disputeId: string): Promise<DisputeResponse> {\n return this.request('GET', `/disputes/${encodeURIComponent(disputeId)}`, {\n query: { force_sync: 'true' },\n });\n }\n}\n","import type { EphemeralKeyCreateRequest, EphemeralKeyCreateResponse } from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Create short-lived ephemeral keys for secure client-side operations.\n *\n * Ephemeral keys grant a mobile or browser client temporary access to a\n * specific customer's data (e.g. to display saved payment methods) without\n * exposing your secret API key.\n *\n * The key is confined to the customer it was minted for, and that is\n * enforced on every customer and payment-method route: a request for another\n * customer — or for a payment method belonging to one — is refused rather\n * than served. Mint one key per customer; do not reuse a key across them.\n */\nexport class EphemeralKeys {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create an ephemeral key scoped to a specific customer.\n *\n * @param params - Customer ID and optional expiry.\n * @returns The ephemeral key with its plaintext secret and expiry timestamp.\n *\n * @example\n * ```typescript\n * const ephKey = await delopay.ephemeralKeys.create({ customer_id: 'cus_123' });\n * // Pass ephKey.secret to your mobile app.\n * ```\n */\n async create(params: EphemeralKeyCreateRequest): Promise<EphemeralKeyCreateResponse> {\n return this.request('POST', '/ephemeral-keys', { body: params });\n }\n\n /**\n * Invalidate an ephemeral key before it expires.\n *\n * @param keyId - The ephemeral key ID to delete.\n * @returns The deleted key object.\n */\n async delete(keyId: string): Promise<EphemeralKeyCreateResponse> {\n return this.request('DELETE', `/ephemeral-keys/${encodeURIComponent(keyId)}`);\n }\n}\n","import type {\n EventListParams,\n EventListResponse,\n EventDeliveryAttemptResponse,\n EventDetailResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Events {\n constructor(private readonly request: RequestFn) {}\n\n async list(merchantId: string, params?: EventListParams): Promise<EventListResponse> {\n return this.request('POST', `/events/${encodeURIComponent(merchantId)}`, { body: params });\n }\n\n async listDeliveryAttempts(\n merchantId: string,\n eventId: string,\n ): Promise<EventDeliveryAttemptResponse[]> {\n return this.request(\n 'GET',\n `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/attempts`,\n );\n }\n\n async retryDelivery(merchantId: string, eventId: string): Promise<EventDetailResponse> {\n return this.request(\n 'POST',\n `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/retry`,\n );\n }\n\n // --- Profile-scoped listing (Task 4.12) ---\n\n /** List events (profile-scoped). `POST /events/profile/list` */\n async listByProfile(params?: Record<string, unknown>): Promise<EventListResponse> {\n return this.request('POST', '/events/profile/list', { body: params });\n }\n}\n","import type {\n FeeRulePreviewRequest,\n FeeRulePreviewResponse,\n FeeScheduleCreateRequest,\n FeeScheduleResponse,\n FeeScheduleUpdateRequest,\n PlatformFeeRuleInput,\n PlatformFeeRuleRecord,\n PlatformFeeRuleRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Merchant-scoped fee schedules. Each schedule optionally targets a\n * specific shop (via `shop_id`). Merchants can CRUD their own fee\n * overrides; platform-wide fee programs are administered by Delopay and\n * not exposed here.\n *\n * `fees.rules` manages the merchant-owned Euclid fee-rule program, which takes\n * precedence over the flat schedules above. A program is scoped either to one\n * shop (`profile_id`) or merchant-wide; a shop-scoped program wins for that\n * shop, otherwise the merchant-wide one applies. Build the program with the\n * `feeProgram()` helper.\n */\nexport class Fees {\n /** Merchant-owned Euclid fee-rule program (`/merchant-fees/rules`). */\n readonly rules: FeeRulesManager;\n\n constructor(private readonly request: RequestFn) {\n this.rules = new FeeRulesManager(request);\n }\n\n /**\n * Create a merchant-scoped fee schedule (optionally per-shop).\n *\n * @param params - Fee schedule parameters.\n * @param merchantId - The merchant account ID.\n */\n async create(params: FeeScheduleCreateRequest, merchantId: string): Promise<FeeScheduleResponse> {\n return this.request('POST', '/merchant-fees', {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * List the merchant's own fee schedules.\n *\n * @param merchantId - The merchant account ID.\n */\n async list(merchantId: string): Promise<FeeScheduleResponse[]> {\n return this.request('GET', '/merchant-fees/list', {\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Update a merchant-scoped fee schedule.\n *\n * @param feeId - The fee schedule ID.\n * @param params - Fields to update.\n */\n async update(feeId: string, params: FeeScheduleUpdateRequest): Promise<FeeScheduleResponse> {\n return this.request('PUT', `/merchant-fees/${encodeURIComponent(feeId)}`, { body: params });\n }\n\n /**\n * Delete a merchant-scoped fee schedule.\n *\n * @param feeId - The fee schedule ID.\n */\n async delete(feeId: string): Promise<FeeScheduleResponse> {\n return this.request('DELETE', `/merchant-fees/${encodeURIComponent(feeId)}`);\n }\n}\n\n/**\n * Manages a merchant's Euclid fee-rule programs (merchant-wide or per-shop, one\n * active program per scope). Build the `algorithm` with `feeProgram()`. The SDK\n * injects `fee_owner: 'merchant'`; set `profile_id` on the input to scope a\n * program to a shop.\n */\nexport class FeeRulesManager {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create or replace the merchant's fee-rule program (a new active version;\n * the previous version is deactivated server-side).\n *\n * @param params - The program plus optional name / shop scope / validity window.\n * @param merchantId - The merchant account ID.\n */\n async upsert(params: PlatformFeeRuleInput, merchantId: string): Promise<PlatformFeeRuleRecord> {\n const body: PlatformFeeRuleRequest = { ...params, fee_owner: 'merchant' };\n return this.request('PUT', '/merchant-fees/rules', {\n body,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Retrieve the active fee-rule program for a scope, or `null` if none.\n *\n * @param merchantId - The merchant account ID.\n * @param profileId - Optional shop (`profile_id`) scope. Omit for the\n * merchant-wide program; pass a shop id to get that shop's program.\n */\n async retrieve(merchantId: string, profileId?: string): Promise<PlatformFeeRuleRecord | null> {\n return this.request('GET', '/merchant-fees/rules', {\n query: { merchant_id: merchantId, profile_id: profileId },\n });\n }\n\n /**\n * Deactivate a fee-rule program (falls back to the flat fee schedules /\n * volume tier). Idempotent.\n *\n * @param merchantId - The merchant account ID.\n * @param profileId - Optional shop (`profile_id`) scope. Omit to target the\n * merchant-wide program; pass a shop id to delete only that shop's program\n * (other shops' programs are left intact).\n */\n async delete(merchantId: string, profileId?: string): Promise<void> {\n await this.request('DELETE', '/merchant-fees/rules', {\n query: { merchant_id: merchantId, profile_id: profileId },\n });\n }\n\n /**\n * Dry-run a candidate fee-rule program against a sample transaction.\n * Returns the matched rule name, whether it fell through, and the computed fee.\n * Does not persist anything.\n *\n * @param input - Candidate program + sample transaction fields.\n * @param merchantId - The merchant account ID.\n */\n async preview(input: FeeRulePreviewRequest, merchantId: string): Promise<FeeRulePreviewResponse> {\n return this.request('POST', '/merchant-fees/rules/preview', {\n body: input,\n query: { merchant_id: merchantId },\n });\n }\n}\n","import type { MandateResponse, MandateRevokedResponse, MandateListParams } from '../types';\nimport type { RequestFn } from '../client';\n\n/** View and revoke recurring payment mandates. */\nexport class Mandates {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Retrieve a mandate by its ID.\n *\n * @param mandateId - The unique mandate ID.\n * @returns The mandate.\n */\n async retrieve(mandateId: string): Promise<MandateResponse> {\n return this.request('GET', `/mandates/${encodeURIComponent(mandateId)}`);\n }\n\n /**\n * Revoke an active mandate, preventing future charges.\n *\n * @param mandateId - The mandate ID to revoke.\n * @returns Revocation confirmation.\n */\n async revoke(mandateId: string): Promise<MandateRevokedResponse> {\n return this.request('POST', `/mandates/revoke/${encodeURIComponent(mandateId)}`);\n }\n\n /**\n * List mandates, optionally filtered by customer or status.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of mandates.\n */\n async list(params?: MandateListParams): Promise<MandateResponse[]> {\n return this.request('GET', '/mandates/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n}\n","import type {\n MerchantAccountCreateRequest,\n MerchantAccountResponse,\n MerchantAccountUpdateRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class MerchantAccounts {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: MerchantAccountCreateRequest): Promise<MerchantAccountResponse> {\n return this.request('POST', '/accounts', { body: params });\n }\n\n async retrieve(accountId: string): Promise<MerchantAccountResponse> {\n return this.request('GET', `/accounts/${encodeURIComponent(accountId)}`);\n }\n\n async update(\n accountId: string,\n params: MerchantAccountUpdateRequest,\n ): Promise<MerchantAccountResponse> {\n return this.request('POST', `/accounts/${encodeURIComponent(accountId)}`, { body: params });\n }\n\n async delete(accountId: string): Promise<MerchantAccountResponse> {\n return this.request('DELETE', `/accounts/${encodeURIComponent(accountId)}`);\n }\n\n // --- Advanced operations (Task 4.9) ---\n\n /** List all merchant accounts. `GET /accounts/list` */\n async list(): Promise<MerchantAccountResponse[]> {\n return this.request('GET', '/accounts/list');\n }\n\n /** Toggle key-value store for a merchant. `POST /accounts/{accountId}/kv` */\n async toggleKv(accountId: string): Promise<Record<string, unknown>> {\n return this.request('POST', `/accounts/${encodeURIComponent(accountId)}/kv`);\n }\n\n /** Get KV status for a merchant. `GET /accounts/{accountId}/kv` */\n async getKvStatus(accountId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/accounts/${encodeURIComponent(accountId)}/kv`);\n }\n\n /** Transfer keys between merchants. `POST /accounts/transfer` */\n async transferKeys(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/accounts/transfer', { body: params });\n }\n}\n","import type { PaymentLinkResponse, PaymentLinkListParams, PaymentLinkListResponse } from '../types';\nimport type { RequestFn } from '../client';\n\n/** Retrieve and list hosted payment links. */\nexport class PaymentLinks {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Retrieve a payment link by its ID.\n *\n * @param linkId - The unique payment link ID.\n * @returns The payment link details.\n */\n async retrieve(linkId: string): Promise<PaymentLinkResponse> {\n return this.request('GET', `/payment-link/${encodeURIComponent(linkId)}`);\n }\n\n /**\n * List payment links, optionally filtered by status or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Paginated list of payment links.\n */\n async list(params?: PaymentLinkListParams): Promise<PaymentLinkListResponse> {\n return this.request('POST', '/payment-link/list', { body: params });\n }\n\n /** Initiate (render) a payment link page. `GET /payment-link/{merchantId}/{paymentId}` */\n async initiate(merchantId: string, paymentId: string): Promise<Record<string, unknown>> {\n return this.request(\n 'GET',\n `/payment-link/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`,\n );\n }\n\n /** Get payment link status. `GET /payment-link/status/{merchantId}/{paymentId}` */\n async status(merchantId: string, paymentId: string): Promise<Record<string, unknown>> {\n return this.request(\n 'GET',\n `/payment-link/status/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`,\n );\n }\n}\n","import type {\n PaymentMethodCreateRequest,\n PaymentMethodResponse,\n PaymentMethodUpdateRequest,\n PaymentMethodListParams,\n PaymentMethodListResponse,\n PaymentMethodDeleteResponse,\n CustomerPaymentMethodsListParams,\n CustomerPaymentMethodsListResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage saved payment methods for customers. */\nexport class PaymentMethods {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Save a new payment method (card, bank account, wallet, etc.).\n *\n * @param params - Payment method data including type and card/bank details.\n * @returns The saved payment method.\n *\n * @example\n * ```typescript\n * const pm = await delopay.paymentMethods.create({\n * payment_method: 'card',\n * customer_id: 'cus_123',\n * client_secret: 'cs_...',\n * });\n * ```\n */\n async create(params: PaymentMethodCreateRequest): Promise<PaymentMethodResponse> {\n return this.request('POST', '/payment-methods', { body: params });\n }\n\n /**\n * Retrieve a saved payment method by its ID.\n *\n * @param methodId - The payment method ID.\n * @returns The payment method.\n */\n async retrieve(methodId: string): Promise<PaymentMethodResponse> {\n return this.request('GET', `/payment-methods/${encodeURIComponent(methodId)}`);\n }\n\n /**\n * Update an existing payment method (e.g. update card expiry).\n *\n * @param methodId - The payment method ID to update.\n * @param params - Fields to update (card expiry, holder name, etc.).\n * @returns The updated payment method.\n */\n async update(\n methodId: string,\n params: PaymentMethodUpdateRequest,\n ): Promise<PaymentMethodResponse> {\n return this.request('POST', `/payment-methods/${encodeURIComponent(methodId)}/update`, {\n body: params,\n });\n }\n\n /**\n * Delete a saved payment method.\n *\n * @param methodId - The payment method ID to delete.\n * @returns Deletion confirmation.\n */\n async delete(methodId: string): Promise<PaymentMethodDeleteResponse> {\n return this.request('DELETE', `/payment-methods/${encodeURIComponent(methodId)}`);\n }\n\n /**\n * List the payment methods available for a payment — the discovery endpoint a\n * custom checkout renders its tiles from.\n *\n * Callable with a publishable key plus the payment's `client_secret`, so it\n * runs from the browser. The returned set is already filtered by country,\n * order value and the merchant's availability rules, and each entry carries\n * `display` (name + icon slug) and `amount_limits` (the order values it stays\n * available for) so you do not have to maintain either alongside.\n *\n * This is *not* the customer's saved methods — see {@link listForCustomer}.\n *\n * @param params - `client_secret`, plus optional `country`, `amount` and filters.\n * @returns The methods available for the payment, grouped by payment method.\n *\n * @example\n * ```typescript\n * const { payment_methods } = await delopay.paymentMethods.list({\n * client_secret: 'pay_abc_secret_xyz',\n * country: 'DE',\n * amount: 25000,\n * });\n *\n * for (const group of payment_methods) {\n * for (const method of group.payment_method_types) {\n * // Re-check availability yourself as the cart total changes, instead of\n * // re-listing on every keystroke.\n * const limits = method.amount_limits;\n * const available =\n * !limits ||\n * ((limits.min_amount == null || cartTotal >= limits.min_amount) &&\n * (limits.max_amount == null || cartTotal <= limits.max_amount) &&\n * !limits.excluded_ranges.some(\n * (band) => cartTotal >= band.min_amount && cartTotal <= band.max_amount,\n * ));\n *\n * if (available) render(method.display?.display_name, method.display?.icon_slug);\n * }\n * }\n * ```\n */\n async list(params?: PaymentMethodListParams): Promise<PaymentMethodListResponse> {\n return this.request('GET', '/payment-methods', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * List all saved payment methods for a customer, optionally filtered.\n *\n * @param customerId - The customer ID.\n * @param params - Optional filters: `client_secret`, `accepted_countries`, `accepted_currencies`,\n * `amount`, `recurring_enabled`, `installment_payment_enabled`, `limit`, `card_networks`.\n * @returns Customer's saved payment methods.\n *\n * @example\n * ```typescript\n * const { customer_payment_methods } = await delopay.paymentMethods.listForCustomer(\n * 'cus_123',\n * { accepted_currencies: ['EUR'], amount: 5000 },\n * );\n * ```\n */\n async listForCustomer(\n customerId: string,\n params?: CustomerPaymentMethodsListParams,\n ): Promise<CustomerPaymentMethodsListResponse> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}/payment-methods`, {\n query: params as Record<\n string,\n string | number | boolean | (string | number | boolean)[] | null | undefined\n >,\n });\n }\n\n /**\n * Set a payment method as the default for a customer.\n *\n * @param customerId - The customer ID.\n * @param methodId - The payment method ID to set as default.\n * @returns The updated payment method.\n */\n async setDefault(customerId: string, methodId: string): Promise<PaymentMethodResponse> {\n return this.request(\n 'POST',\n `/customers/${encodeURIComponent(customerId)}/payment-methods/${encodeURIComponent(methodId)}/default`,\n );\n }\n\n // --- Advanced operations (Task 3.3) ---\n\n /** Migrate a payment method. `POST /payment-methods/migrate` */\n async migrate(params: Record<string, unknown>): Promise<PaymentMethodResponse> {\n return this.request('POST', '/payment-methods/migrate', { body: params });\n }\n\n /** Batch migrate payment methods. `POST /payment-methods/migrate-batch` */\n async migrateBatch(params: Record<string, unknown>[]): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/migrate-batch', { body: params });\n }\n\n /** Batch update payment methods. `POST /payment-methods/update-batch` */\n async updateBatch(params: Record<string, unknown>[]): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/update-batch', { body: params });\n }\n\n /** Batch retrieve payment methods. `GET /payment-methods/batch` */\n async batchRetrieve(\n params?: Record<string, string | number | undefined>,\n ): Promise<PaymentMethodResponse[]> {\n return this.request('GET', '/payment-methods/batch', { query: params });\n }\n\n /** Tokenize a card. `POST /payment-methods/tokenize-card` */\n async tokenizeCard(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/tokenize-card', { body: params });\n }\n\n /** Batch tokenize cards. `POST /payment-methods/tokenize-card-batch` */\n async tokenizeCardBatch(params: Record<string, unknown>[]): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/tokenize-card-batch', { body: params });\n }\n\n /** Initiate payment method collect link flow. `POST /payment-methods/collect` */\n async collect(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/collect', { body: params });\n }\n\n /** Save a payment method. `POST /payment-methods/{methodId}/save` */\n async save(methodId: string, params?: Record<string, unknown>): Promise<PaymentMethodResponse> {\n return this.request('POST', `/payment-methods/${encodeURIComponent(methodId)}/save`, {\n body: params,\n });\n }\n\n /** Create payment method auth link token. `POST /payment-methods/auth/link` */\n async createAuthLink(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/auth/link', { body: params });\n }\n\n /** Exchange payment method auth token. `POST /payment-methods/auth/exchange` */\n async exchangeAuthToken(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/auth/exchange', { body: params });\n }\n\n /** Tokenize card using existing PM. `POST /payment-methods/{methodId}/tokenize-card` */\n async tokenizeCardForMethod(\n methodId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/payment-methods/${encodeURIComponent(methodId)}/tokenize-card`, {\n body: params,\n });\n }\n}\n","import type {\n PaymentClientContextListResponse,\n PaymentCreateRequest,\n PaymentListFilterConstraints,\n PaymentListFilteredResponse,\n PaymentListResponse,\n PaymentResponse,\n PaymentRetrieveOptions,\n PaymentUpdateRequest,\n PaymentConfirmRequest,\n PaymentCaptureRequest,\n PaymentCancelRequest,\n PaymentListParams,\n PaymentAttemptsListResponse,\n PaymentsDeletePolicyResponse,\n PaymentsDeleteResponse,\n PaymentStatusHistoryResponse,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/** Manage payment intents — create, confirm, capture, cancel, and list payments. */\nexport class Payments {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new payment intent.\n *\n * @param params - Payment creation parameters including amount and currency.\n * @param options - Optional per-call extras: extra `headers` (e.g. an\n * `Idempotency-Key` to make the create safe to retry), a `timeout` override,\n * and an `AbortSignal`.\n * @returns The created payment intent.\n *\n * @example\n * ```typescript\n * const payment = await delopay.payments.create(\n * { amount: 5000, currency: 'EUR', customer_id: 'cus_123' },\n * { headers: { 'Idempotency-Key': 'order_1001' } },\n * );\n * ```\n *\n * @example Send `test_mode` to pick the environment per payment, so a staging\n * deploy cannot charge real cards and a forgotten processor toggle cannot\n * swallow production traffic:\n * ```typescript\n * const payment = await delopay.payments.create({\n * amount: 5000,\n * currency: 'EUR',\n * test_mode: process.env.NODE_ENV !== 'production',\n * });\n * ```\n *\n * A payment that pins one connector through `routing` (the `single` form)\n * is now checked against `test_mode` here rather than at confirm: if that\n * connector has no credentials for the environment asked for, create fails\n * instead of handing back a payment whose checkout the buyer cannot\n * complete. `priority` and `volume_split` name several accounts and are\n * still resolved at confirm.\n */\n async create(params: PaymentCreateRequest, options?: RequestExtras): Promise<PaymentResponse> {\n return this.request('POST', '/payments', { body: params, ...options });\n }\n\n /**\n * Retrieve a payment by its ID.\n *\n * @param paymentId - The unique payment intent ID.\n * @param options - Optional query flags. `force_sync` reconciles the\n * intent's state with the connector before returning (useful to recover\n * a stuck intent when a webhook was lost). `all_keys_required` forces a\n * connector sync even for intents in early states like\n * `requires_payment_method` that would otherwise return the local\n * snapshot. Both flags work with JWT and API-key authentication.\n * @returns The payment intent.\n *\n * @example\n * ```typescript\n * const payment = await delopay.payments.retrieve('pay_abc123');\n * const synced = await delopay.payments.retrieve('pay_abc123', {\n * force_sync: true,\n * all_keys_required: true,\n * });\n * ```\n */\n async retrieve(paymentId: string, options?: PaymentRetrieveOptions): Promise<PaymentResponse> {\n const path = `/payments/${encodeURIComponent(paymentId)}`;\n if (options === undefined) return this.request('GET', path);\n const query: Record<string, boolean> = {};\n if (options.force_sync !== undefined) query['force_sync'] = options.force_sync;\n if (options.all_keys_required !== undefined) {\n query['all_keys_required'] = options.all_keys_required;\n }\n if (Object.keys(query).length === 0) return this.request('GET', path);\n return this.request('GET', path, { query });\n }\n\n /**\n * List every attempt made on a payment, each with its full failure detail\n * (`error_code` / `error_message`, the Delopay-unified `unified_code` and\n * `unified_message`, and structured `error_details`).\n *\n * Useful for surfacing retries across connectors — e.g. \"attempt 1 stripe →\n * insufficient_funds, attempt 2 adyen → success\".\n *\n * `GET /payments/{paymentId}/attempts`\n *\n * @param paymentId - The payment intent ID whose attempts to list.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal`.\n * @returns The attempt list — `size` plus a `data` array of attempts.\n * @throws If the payment does not exist or belongs to another merchant (404).\n *\n * @example\n * ```typescript\n * const { size, data } = await delopay.payments.listAttempts('pay_abc123');\n * for (const attempt of data) {\n * console.log(attempt.status, attempt.unified_message ?? attempt.error_message);\n * }\n * ```\n */\n async listAttempts(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentAttemptsListResponse> {\n return this.request('GET', `/payments/${encodeURIComponent(paymentId)}/attempts`, options);\n }\n\n /**\n * The status timeline of a payment: every recorded creation / status\n * transition of the intent and its attempts, refunds and disputes, oldest\n * first. `complete: false` marks timelines partially reconstructed from\n * current records (payments created before the status log existed).\n *\n * @param paymentId - The payment intent ID.\n * @returns The ordered status-history events.\n *\n * @example\n * ```typescript\n * const { events, complete } = await delopay.payments.listStatusHistory('pay_abc123');\n * for (const event of events) {\n * console.log(event.timestamp, event.entity_type, event.status);\n * }\n * ```\n */\n async listStatusHistory(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentStatusHistoryResponse> {\n return this.request(\n 'GET',\n `/payments/${encodeURIComponent(paymentId)}/status-history`,\n options,\n );\n }\n\n /**\n * Update an existing payment intent before it is confirmed.\n *\n * @param paymentId - The payment intent ID to update.\n * @param params - Fields to update (amount, currency, metadata, etc.).\n * @returns The updated payment intent.\n */\n async update(paymentId: string, params: PaymentUpdateRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}`, { body: params });\n }\n\n /**\n * Confirm a payment intent, triggering authorisation with the selected gateway.\n *\n * @param paymentId - The payment intent ID to confirm.\n * @param params - Confirmation parameters (payment method data, return URL, etc.).\n * @returns The updated payment intent.\n */\n async confirm(paymentId: string, params: PaymentConfirmRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/confirm`, {\n body: params,\n });\n }\n\n /**\n * Capture a previously authorised payment.\n *\n * @param paymentId - The payment intent ID to capture.\n * @param params - Optional capture parameters (partial capture amount, etc.).\n * @returns The updated payment intent.\n */\n async capture(paymentId: string, params?: PaymentCaptureRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/capture`, {\n body: params,\n });\n }\n\n /**\n * Cancel a payment intent that has not yet been captured.\n *\n * @param paymentId - The payment intent ID to cancel.\n * @param params - Optional cancellation reason.\n * @returns The updated payment intent.\n */\n async cancel(paymentId: string, params?: PaymentCancelRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/cancel`, {\n body: params,\n });\n }\n\n /**\n * List payment intents, optionally filtered by customer or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal` for cancellation.\n * @returns Paginated list of payment intents.\n *\n * @example\n * ```typescript\n * const { data } = await delopay.payments.list({ customer_id: 'cus_123', limit: 25 });\n * ```\n */\n async list(params?: PaymentListParams, options?: RequestExtras): Promise<PaymentListResponse> {\n return this.request('GET', '/payments/list', {\n query: params as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /**\n * The status timeline of client/device observations captured while the\n * buyer interacted with the payment (checkout opens, confirms, redirect\n * legs, reported client signals), oldest first.\n *\n * `GET /payments/{paymentId}/client-context`\n */\n async listClientContext(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentClientContextListResponse> {\n return this.request(\n 'GET',\n `/payments/${encodeURIComponent(paymentId)}/client-context`,\n options,\n );\n }\n\n /**\n * Soft-delete a payment. Only payments whose status is in the merchant's\n * delete policy (see {@link Payments.getDeletePolicy}) can be deleted;\n * anything else fails with a precondition error.\n *\n * `DELETE /payments/{paymentId}`\n */\n async delete(paymentId: string, options?: RequestExtras): Promise<PaymentsDeleteResponse> {\n return this.request('DELETE', `/payments/${encodeURIComponent(paymentId)}`, options);\n }\n\n /**\n * The effective deletable-status set for the calling merchant — lets a\n * dashboard show the delete action only where it is allowed.\n *\n * `GET /payments/delete-policy`\n */\n async getDeletePolicy(options?: RequestExtras): Promise<PaymentsDeletePolicyResponse> {\n return this.request('GET', '/payments/delete-policy', options);\n }\n\n // --- Advanced operations (Task 3.2) ---\n\n /** Generate session tokens. `POST /payments/session-tokens` */\n async sessionTokens(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payments/session-tokens', { body: params });\n }\n\n /** Retrieve payment with gateway credentials. `POST /payments/sync` */\n async sync(params: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('POST', '/payments/sync', { body: params });\n }\n\n /** Cancel after partial capture. `POST /payments/{paymentId}/cancel-post-capture` */\n async cancelPostCapture(\n paymentId: string,\n params?: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/cancel-post-capture`, {\n body: params,\n });\n }\n\n /** Incrementally authorize more funds. `POST /payments/{paymentId}/incremental-authorization` */\n async incrementalAuthorization(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request(\n 'POST',\n `/payments/${encodeURIComponent(paymentId)}/incremental-authorization`,\n {\n body: params,\n },\n );\n }\n\n /** Extend authorization window. `POST /payments/{paymentId}/extend-authorization` */\n async extendAuthorization(\n paymentId: string,\n params?: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/extend-authorization`, {\n body: params,\n });\n }\n\n /** Complete authorization. `POST /payments/{paymentId}/complete-authorize` */\n async completeAuthorize(\n paymentId: string,\n params?: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/complete-authorize`, {\n body: params,\n });\n }\n\n /** Dynamic tax calculation. `POST /payments/{paymentId}/calculate-tax` */\n async calculateTax(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/calculate-tax`, {\n body: params,\n });\n }\n\n /** Update payment metadata. `POST /payments/{paymentId}/update-metadata` */\n async updateMetadata(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/update-metadata`, {\n body: params,\n });\n }\n\n /** Retrieve extended card info. `GET /payments/{paymentId}/extended-card-info` */\n async extendedCardInfo(paymentId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/payments/${encodeURIComponent(paymentId)}/extended-card-info`);\n }\n\n // --- OLAP extensions (Task 4.2) ---\n\n /** List payments (profile-scoped). `GET /payments/profile/list` */\n async listByProfile(params?: PaymentListParams): Promise<PaymentListResponse> {\n return this.request('GET', '/payments/profile/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** List payments across all shops. `GET /payments/list-all-shops` */\n async listAllShops(params?: PaymentListParams): Promise<PaymentListResponse> {\n return this.request('GET', '/payments/list-all-shops', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** List payments by filter (POST body). `POST /payments/list` */\n async listByFilter(params: Record<string, unknown>): Promise<PaymentListResponse> {\n return this.request('POST', '/payments/list', { body: params });\n }\n\n /**\n * List payments by filter, scoped to the caller's profile (the shop-user\n * twin of `listByFilter`). The backend narrows to the profile from the\n * auth context, so `profile_id` / `project_id` must not be sent.\n *\n * Not to be confused with {@link Payments.listByProfile}, which is the GET\n * cursor variant and rejects this body.\n *\n * `POST /payments/profile/list`\n */\n async listByProfileFilter(\n params: PaymentListFilterConstraints,\n options?: RequestExtras,\n ): Promise<PaymentListFilteredResponse> {\n return this.request('POST', '/payments/profile/list', { body: params, ...options });\n }\n\n /** Get payment filter options. `GET /payments/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/filter', { query: params });\n }\n\n /**\n * Get payment filter options, scoped to the caller's profile.\n * `GET /payments/profile/filter`\n */\n async getFiltersByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/profile/filter', { query: params });\n }\n\n /** Get payment aggregates. `GET /payments/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/aggregate', { query: params });\n }\n\n /** Get payment aggregates (profile-scoped). `GET /payments/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/profile/aggregate', { query: params });\n }\n\n /** Manually update payment status. `PUT /payments/{paymentId}/manual-update` */\n async manualUpdate(paymentId: string, params: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('PUT', `/payments/${encodeURIComponent(paymentId)}/manual-update`, {\n body: params,\n });\n }\n\n /** Approve a payment waiting for review. `POST /payments/{paymentId}/approve` */\n async approve(paymentId: string, params?: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/approve`, {\n body: params,\n });\n }\n\n /** Reject a payment waiting for review. `POST /payments/{paymentId}/reject` */\n async reject(paymentId: string, params?: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/reject`, {\n body: params,\n });\n }\n\n /** Initiate external 3DS authentication. `POST /payments/{paymentId}/3ds/authentication` */\n async threeDsAuthentication(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/3ds/authentication`, {\n body: params,\n });\n }\n}\n","import type {\n PayoutCreateRequest,\n PayoutResponse,\n PayoutUpdateRequest,\n PayoutListParams,\n PayoutListResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage payouts — fund transfers from merchant to a recipient bank account. */\nexport class Payouts {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new payout.\n *\n * @param params - Payout parameters including amount, currency, and destination.\n * @returns The created payout.\n *\n * @example\n * ```typescript\n * const payout = await delopay.payouts.create({\n * amount: 10000,\n * currency: 'EUR',\n * customer_id: 'cus_123',\n * });\n * ```\n */\n async create(params: PayoutCreateRequest): Promise<PayoutResponse> {\n return this.request('POST', '/payouts/create', { body: params });\n }\n\n /**\n * Retrieve a payout by its ID.\n *\n * @param payoutId - The unique payout ID.\n * @returns The payout.\n */\n async retrieve(payoutId: string): Promise<PayoutResponse> {\n return this.request('GET', `/payouts/${encodeURIComponent(payoutId)}`);\n }\n\n /**\n * Update a payout before it is confirmed.\n *\n * @param payoutId - The payout ID to update.\n * @param params - Fields to update.\n * @returns The updated payout.\n */\n async update(payoutId: string, params: PayoutUpdateRequest): Promise<PayoutResponse> {\n return this.request('PUT', `/payouts/${encodeURIComponent(payoutId)}`, { body: params });\n }\n\n /**\n * Confirm a payout, triggering the actual transfer.\n *\n * @param payoutId - The payout ID to confirm.\n * @param params - Optional confirmation parameters.\n * @returns The updated payout.\n */\n async confirm(payoutId: string, params?: PayoutUpdateRequest): Promise<PayoutResponse> {\n return this.request('POST', `/payouts/${encodeURIComponent(payoutId)}/confirm`, {\n body: params,\n });\n }\n\n /**\n * Cancel a payout before it is fulfilled.\n *\n * @param payoutId - The payout ID to cancel.\n * @returns The cancelled payout.\n */\n async cancel(payoutId: string): Promise<PayoutResponse> {\n return this.request('POST', `/payouts/${encodeURIComponent(payoutId)}/cancel`);\n }\n\n /**\n * Mark a payout as fulfilled (manual confirmation of successful transfer).\n *\n * @param payoutId - The payout ID to fulfil.\n * @returns The fulfilled payout.\n */\n async fulfill(payoutId: string): Promise<PayoutResponse> {\n return this.request('POST', `/payouts/${encodeURIComponent(payoutId)}/fulfill`);\n }\n\n /**\n * List payouts, optionally filtered by status or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Paginated list of payouts.\n */\n async list(params?: PayoutListParams): Promise<PayoutListResponse> {\n return this.request('GET', '/payouts/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n // --- OLAP extensions (Task 4.5) ---\n\n /** List payouts (profile-scoped). `GET /payouts/profile/list` */\n async listByProfile(params?: PayoutListParams): Promise<PayoutListResponse> {\n return this.request('GET', '/payouts/profile/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** List payouts by filter (POST body). `POST /payouts/list` */\n async listByFilter(params: Record<string, unknown>): Promise<PayoutListResponse> {\n return this.request('POST', '/payouts/list', { body: params });\n }\n\n /** Get payout filter options. `GET /payouts/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/filter', { query: params });\n }\n\n /** Get payout filters (profile-scoped). `GET /payouts/profile/filter` */\n async getFiltersByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/profile/filter', { query: params });\n }\n\n /** Get payout aggregates. `GET /payouts/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/aggregate', { query: params });\n }\n\n /** Get payout aggregates (profile-scoped). `GET /payouts/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/profile/aggregate', { query: params });\n }\n\n /** Manually update payout status. `PUT /payouts/{payoutId}/manual-update` */\n async manualUpdate(payoutId: string, params: Record<string, unknown>): Promise<PayoutResponse> {\n return this.request('PUT', `/payouts/${encodeURIComponent(payoutId)}/manual-update`, {\n body: params,\n });\n }\n}\n","import type { PollStatusResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Poll {\n constructor(private readonly request: RequestFn) {}\n\n async getStatus(pollId: string): Promise<PollStatusResponse> {\n return this.request('GET', `/poll/status/${encodeURIComponent(pollId)}`);\n }\n}\n","import type {\n ProfileAcquirerCreateRequest,\n ProfileAcquirerResponse,\n ProfileAcquirerUpdateRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class ProfileAcquirers {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: ProfileAcquirerCreateRequest): Promise<ProfileAcquirerResponse> {\n return this.request('POST', '/profile-acquirer', { body: params });\n }\n\n async update(\n profileId: string,\n profileAcquirerId: string,\n params: ProfileAcquirerUpdateRequest,\n ): Promise<ProfileAcquirerResponse> {\n return this.request(\n 'POST',\n `/profile-acquirer/${encodeURIComponent(profileId)}/${encodeURIComponent(profileAcquirerId)}`,\n {\n body: params,\n },\n );\n }\n}\n","import type { ProfileCreateRequest, ProfileResponse, ProfileUpdateRequest } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Profiles {\n constructor(private readonly request: RequestFn) {}\n\n async create(accountId: string, params: ProfileCreateRequest): Promise<ProfileResponse> {\n return this.request('POST', `/account/${encodeURIComponent(accountId)}/business-profile`, {\n body: params,\n });\n }\n\n async retrieve(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}`,\n );\n }\n\n async list(accountId: string): Promise<ProfileResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/business-profile`);\n }\n\n /**\n * List the business profiles the caller can see at profile scope — the\n * `ProfileAccountRead` twin of `list()` (which needs merchant-level read).\n * A shop-scoped user gets exactly their own shop back.\n *\n * `GET /account/{accountId}/profile`\n */\n async listByProfile(accountId: string): Promise<ProfileResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/profile`);\n }\n\n async update(\n accountId: string,\n profileId: string,\n params: ProfileUpdateRequest,\n ): Promise<ProfileResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}`,\n {\n body: params,\n },\n );\n }\n\n async delete(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'DELETE',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}`,\n );\n }\n\n // --- Advanced operations (Task 4.8) ---\n\n /** Toggle extended card info for a profile. `POST /account/{accountId}/business-profile/{profileId}/toggle-extended-card-info` */\n async toggleExtendedCardInfo(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}/toggle-extended-card-info`,\n );\n }\n\n /** Toggle connector agnostic MIT. `POST /account/{accountId}/business-profile/{profileId}/toggle-connector-agnostic-mit` */\n async toggleConnectorAgnosticMit(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}/toggle-connector-agnostic-mit`,\n );\n }\n}\n","import type {\n ProjectCreateRequest,\n ProjectResponse,\n ProjectUpdateRequest,\n ProjectStatsResponse,\n MerchantOverviewResponse,\n StatsPeriod,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage projects — optional grouping layers that contain one or more shops. */\nexport class Projects {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new project under a merchant account.\n *\n * @param params - Project creation parameters (name, description, etc.).\n * @param merchantId - The merchant account ID that owns this project.\n * @returns The created project.\n *\n * @example\n * ```typescript\n * const project = await delopay.projects.create({ name: 'EU Stores' }, 'merch_123');\n * ```\n */\n async create(params: ProjectCreateRequest, merchantId: string): Promise<ProjectResponse> {\n return this.request('POST', '/projects', {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Retrieve a project by its ID.\n *\n * @param projectId - The unique project ID.\n * @param merchantId - Optional merchant scope. When provided, sent as\n * `?merchant_id=…` — required by dashboards that authenticate with a JWT\n * spanning multiple merchants and need to disambiguate which one this\n * call applies to. API-key callers can omit it.\n * @returns The project.\n */\n async retrieve(projectId: string, merchantId?: string): Promise<ProjectResponse> {\n const path = `/projects/${encodeURIComponent(projectId)}`;\n if (merchantId === undefined) return this.request('GET', path);\n return this.request('GET', path, { query: { merchant_id: merchantId } });\n }\n\n /**\n * Update a project's details.\n *\n * @param projectId - The project ID to update.\n * @param params - Fields to update.\n * @param merchantId - Optional merchant scope. See {@link Projects.retrieve}.\n * @returns The updated project.\n */\n async update(\n projectId: string,\n params: ProjectUpdateRequest,\n merchantId?: string,\n ): Promise<ProjectResponse> {\n const path = `/projects/${encodeURIComponent(projectId)}`;\n if (merchantId === undefined) return this.request('PUT', path, { body: params });\n return this.request('PUT', path, { body: params, query: { merchant_id: merchantId } });\n }\n\n /**\n * Delete a project.\n *\n * @param projectId - The project ID to delete.\n * @param merchantId - Optional merchant scope. See {@link Projects.retrieve}.\n * @returns The deleted project object.\n */\n async delete(projectId: string, merchantId?: string): Promise<ProjectResponse> {\n const path = `/projects/${encodeURIComponent(projectId)}`;\n if (merchantId === undefined) return this.request('DELETE', path);\n return this.request('DELETE', path, { query: { merchant_id: merchantId } });\n }\n\n /**\n * List all projects for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns Array of projects.\n */\n async list(merchantId: string): Promise<ProjectResponse[]> {\n return this.request('GET', '/projects/list', {\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Get aggregate payment statistics across all projects for a merchant.\n *\n * The response's flat `shops[]` array holds every shop, including shops that\n * belong to no project — those are absent from `projects[].shops[]`, so look\n * a single shop up in `shops[]`. Requires `MerchantAccountRead`; a\n * shop-scoped user should call {@link Shops.stats} instead.\n *\n * @param merchantId - The merchant account ID.\n * @param period - Window in days, or `'all'` for an all-time total.\n * Omitted means the server default of 30 days.\n * @returns Project statistics.\n *\n * @example\n * ```typescript\n * const stats = await delopay.projects.stats('merch_123', 'all');\n * const shop = stats.shops.find((s) => s.shop_id === 'pro_1');\n * ```\n */\n async stats(merchantId: string, period?: StatsPeriod): Promise<ProjectStatsResponse> {\n const query: Record<string, string> = { merchant_id: merchantId };\n if (period !== undefined) query['period'] = String(period);\n return this.request('GET', '/projects/stats', { query });\n }\n\n /**\n * Get a high-level overview (volume, counts, top connectors) for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns Merchant overview data.\n */\n async overview(merchantId: string): Promise<MerchantOverviewResponse> {\n return this.request('GET', '/projects/overview', {\n query: { merchant_id: merchantId },\n });\n }\n}\n","import type {\n RefundCreateRequest,\n RefundResponse,\n RefundUpdateRequest,\n RefundListParams,\n RefundListResponse,\n RefundAggregateResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage refunds for completed payments. */\nexport class Refunds {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a refund for a payment.\n *\n * Dashboard-initiated refunds are subject to the caller's operation-limit\n * rule, resolved against the role the request authenticated with. An\n * over-limit refund either fails with `DE_01` (the rule blocks) or with\n * HTTP 409 `DE_06` — the rule requires approval, and `DelopayError.data`\n * carries `PendingApprovalErrorDetails`. No refund exists in either case;\n * `DE_06` names one that a second approver can still let through, via\n * `operationLimits.approve()`.\n *\n * @param params - Refund parameters, including the required `payment_id` and optional amount.\n * @returns The created refund.\n *\n * @example\n * ```typescript\n * const refund = await delopay.refunds.create({\n * payment_id: 'pay_abc123',\n * amount: 2500, // partial refund of 25.00 EUR\n * });\n * ```\n */\n async create(params: RefundCreateRequest): Promise<RefundResponse> {\n return this.request('POST', '/refunds', { body: params });\n }\n\n /**\n * Retrieve a refund by its ID.\n *\n * @param refundId - The unique refund ID.\n * @returns The refund.\n *\n * @example\n * ```typescript\n * const refund = await delopay.refunds.retrieve('ref_abc123');\n * ```\n */\n async retrieve(refundId: string): Promise<RefundResponse> {\n return this.request('GET', `/refunds/${encodeURIComponent(refundId)}`);\n }\n\n /**\n * Update the reason or metadata on an existing refund.\n *\n * @param refundId - The refund ID to update.\n * @param params - Fields to update (reason, metadata).\n * @returns The updated refund.\n */\n async update(refundId: string, params: RefundUpdateRequest): Promise<RefundResponse> {\n return this.request('POST', `/refunds/${encodeURIComponent(refundId)}`, { body: params });\n }\n\n /**\n * List refunds, optionally filtered by payment, status, or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Paginated list of refunds.\n */\n async list(params?: RefundListParams): Promise<RefundListResponse> {\n return this.request('POST', '/refunds/list', { body: params });\n }\n\n // --- OLAP extensions (Task 4.3) ---\n\n /** List refunds (profile-scoped). `POST /refunds/profile/list` */\n async listByProfile(params?: RefundListParams): Promise<RefundListResponse> {\n return this.request('POST', '/refunds/profile/list', { body: params });\n }\n\n /** Get refund filter options. `GET /refunds/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/refunds/filter', { query: params });\n }\n\n /** Get refund aggregates. `GET /refunds/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<RefundAggregateResponse> {\n return this.request('GET', '/refunds/aggregate', { query: params });\n }\n\n /** Get refund aggregates (profile-scoped). `GET /refunds/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<RefundAggregateResponse> {\n return this.request('GET', '/refunds/profile/aggregate', { query: params });\n }\n\n /** Manually update refund status. `PUT /refunds/{refundId}/manual-update` */\n async manualUpdate(refundId: string, params: Record<string, unknown>): Promise<RefundResponse> {\n return this.request('PUT', `/refunds/${encodeURIComponent(refundId)}/manual-update`, {\n body: params,\n });\n }\n}\n","import type { RelayRequest, RelayResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Relay {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: RelayRequest): Promise<RelayResponse> {\n return this.request('POST', '/relay', { body: params });\n }\n\n async retrieve(relayId: string): Promise<RelayResponse> {\n return this.request('GET', `/relay/${encodeURIComponent(relayId)}`);\n }\n}\n","import type {\n CheckoutThemeConversionQuery,\n CheckoutThemeConversionResponse,\n CheckoutThemeProgramRequest,\n CheckoutThemeProgramResponse,\n LinkedRoutingConfigRetrieveResponse,\n MerchantRoutingAlgorithm,\n ProfileDefaultRoutingConfig,\n ProfileDeniedConnectorsResponse,\n RoutableConnectorChoice,\n RoutingActivatePayload,\n RoutingConfigCreateRequest,\n RoutingConfigHistoryResponse,\n RoutingConfigUpdateRequest,\n RoutingConnectorCaps,\n RoutingDeactivateRequest,\n RoutingDictionary,\n RoutingDictionaryRecord,\n RoutingHistoryParams,\n SurchargeRuleRequest,\n SurchargeRuleResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Create and manage payment routing algorithms.\n *\n * Routing rules determine which gateway connector handles each payment based on\n * card type, currency, amount, or custom conditions.\n */\nexport class Routing {\n readonly decision: RoutingDecisionManager;\n /** Merchant-friendly, per-payment-method surcharge rules (no Euclid DSL). */\n readonly surchargeRules: SurchargeRules;\n /** Which stored appearance variant a buyer is shown. Decides a look, never a payment. */\n readonly checkoutThemeRules: CheckoutThemeRules;\n /** Rendered-to-paid conversion per appearance variant and segment. */\n readonly checkoutThemeConversion: CheckoutThemeConversion;\n\n constructor(private readonly request: RequestFn) {\n this.decision = new RoutingDecisionManager(request);\n this.surchargeRules = new SurchargeRules(request);\n this.checkoutThemeRules = new CheckoutThemeRules(request);\n this.checkoutThemeConversion = new CheckoutThemeConversion(request);\n }\n\n /**\n * Create a new routing algorithm.\n *\n * @param params - Routing algorithm definition (rule-based, priority, or volume-based).\n * @returns Metadata record for the created routing configuration. The full\n * algorithm body is not echoed back — use `retrieve(id)` if you need it.\n *\n * @example\n * ```typescript\n * const config = await delopay.routing.create({\n * name: 'EU Priority',\n * algorithm: { type: 'priority', data: [{ connector: 'stripe' }] },\n * });\n * ```\n *\n * @example Conditional volume split (advanced): cards → 90% epayouts / 10% stripe.\n * Rules run top-down (first match wins); `defaultSelection` is the fallback.\n * Splits must sum to 100; `amount` conditions are in minor units.\n * ```typescript\n * const config = await delopay.routing.create({\n * name: 'Card split 90/10',\n * profile_id: 'pro_...',\n * algorithm: {\n * type: 'advanced',\n * data: {\n * defaultSelection: { type: 'priority', data: [{ connector: 'stripe' }] },\n * rules: [\n * {\n * name: 'cards',\n * connectorSelection: {\n * type: 'volume_split',\n * data: [\n * { connector: { connector: 'epayouts' }, split: 90 },\n * { connector: { connector: 'stripe' }, split: 10 },\n * ],\n * },\n * statements: [\n * {\n * condition: [\n * {\n * lhs: 'payment_method',\n * comparison: 'equal',\n * value: { type: 'enum_variant', value: 'card' },\n * metadata: {},\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * metadata: {},\n * },\n * },\n * });\n * await delopay.routing.activate(config.id);\n * ```\n */\n async create(params: RoutingConfigCreateRequest): Promise<RoutingDictionaryRecord> {\n return this.request('POST', '/routing', { body: params });\n }\n\n /**\n * Retrieve a routing algorithm by its ID.\n *\n * @param algorithmId - The routing algorithm ID.\n * @returns The full routing configuration including the algorithm body.\n */\n async retrieve(algorithmId: string): Promise<MerchantRoutingAlgorithm> {\n return this.request('GET', `/routing/${encodeURIComponent(algorithmId)}`);\n }\n\n /**\n * Activate a routing algorithm, making it the active routing strategy.\n *\n * Always sends a JSON body (default `{}`) so the request carries the\n * `Content-Type: application/json` header that the server requires.\n *\n * @param algorithmId - The routing algorithm ID to activate.\n * @param params - Optional activation payload (e.g. `transaction_type`).\n */\n async activate(\n algorithmId: string,\n params: RoutingActivatePayload = {},\n ): Promise<RoutingDictionaryRecord> {\n return this.request('POST', `/routing/${encodeURIComponent(algorithmId)}/activate`, {\n body: params,\n });\n }\n\n /**\n * Deactivate the currently active routing algorithm (falls back to default routing).\n *\n * Always sends a JSON body (default `{}`) so the request carries the\n * `Content-Type: application/json` header that the server requires.\n *\n * @param params - Optional deactivation payload.\n */\n async deactivate(params: RoutingDeactivateRequest = {}): Promise<RoutingDictionaryRecord> {\n return this.request('POST', '/routing/deactivate', { body: params });\n }\n\n /**\n * Edit a static routing configuration.\n *\n * Partial: send only the fields to change. `name`/`description` are\n * metadata-only; `algorithm` is a wholesale rule replacement, validated\n * against the shop exactly as at create. `modified_at` is bumped either way.\n *\n * `PUT /routing/{algorithmId}`\n *\n * @param algorithmId - The routing algorithm ID to edit.\n * @param params - The fields to change (at least one required).\n * @returns The updated routing configuration including the algorithm body.\n */\n async update(\n algorithmId: string,\n params: RoutingConfigUpdateRequest,\n ): Promise<MerchantRoutingAlgorithm> {\n return this.request('PUT', `/routing/${encodeURIComponent(algorithmId)}`, { body: params });\n }\n\n /**\n * Every content window a routing configuration has had, oldest first.\n *\n * A configuration's rule can be edited in place, so this is what makes \"which\n * rule decided this payment\" answerable after the fact. Each entry is the rule\n * as it stood between `valid_from` and `valid_until`; the windows of one\n * config abut exactly, with no gap.\n *\n * Paging covers the whole timeline including the live window, so a page never\n * holds more than `limit` entries and the live one — the only entry without a\n * `valid_until` — comes back on exactly one page. Advance `offset` by `limit`;\n * a page past the end is empty, and `total_count` says where that end is\n * without probing for it.\n *\n * `GET /routing/{algorithmId}/history`\n *\n * @param algorithmId - The routing algorithm to read the history of.\n * @param params - Optional paging.\n */\n async history(\n algorithmId: string,\n params: RoutingHistoryParams = {},\n ): Promise<RoutingConfigHistoryResponse> {\n return this.request('GET', `/routing/${encodeURIComponent(algorithmId)}/history`, {\n query: params as Record<string, number | null | undefined>,\n });\n }\n\n /**\n * A shop's lifetime per-connector payment caps, each with how much of it is\n * already spent.\n *\n * `GET /routing/connector-caps/{profileId}`\n */\n async connectorCaps(profileId: string): Promise<RoutingConnectorCaps> {\n return this.request('GET', `/routing/connector-caps/${encodeURIComponent(profileId)}`);\n }\n\n /**\n * Replace a shop's per-connector payment caps.\n *\n * Whole-set replacement, not a patch: the list sent becomes the complete set\n * of capped connectors, and an empty list clears them all — which is how\n * acquirer onboarding finishes, the new account ceasing to be a special case.\n *\n * Every account named must belong to this shop; one that does not is refused.\n *\n * `PUT /routing/connector-caps/{profileId}`\n */\n async setConnectorCaps(\n profileId: string,\n params: RoutingConnectorCaps,\n ): Promise<RoutingConnectorCaps> {\n return this.request('PUT', `/routing/connector-caps/${encodeURIComponent(profileId)}`, {\n body: params,\n });\n }\n\n /**\n * List all routing algorithms for the current merchant.\n *\n * @returns The routing dictionary (records + currently active id).\n */\n async list(): Promise<RoutingDictionary> {\n return this.request('GET', '/routing');\n }\n\n /**\n * Connector names denied at routing for a shop (explicit denies plus\n * whitelist-implied exclusions). Read-only; surfaced in the routing builder.\n *\n * `GET /routing/connector-restrictions/{profileId}`\n */\n async connectorRestrictions(profileId: string): Promise<ProfileDeniedConnectorsResponse> {\n return this.request('GET', `/routing/connector-restrictions/${encodeURIComponent(profileId)}`);\n }\n\n // --- Advanced operations (Task 3.4) ---\n\n /** Get active routing config. `GET /routing/active` */\n async getActive(): Promise<LinkedRoutingConfigRetrieveResponse> {\n return this.request('GET', '/routing/active');\n }\n\n /** Update default routing config. `POST /routing/default` */\n async updateDefault(params: Record<string, unknown>): Promise<RoutableConnectorChoice[]> {\n return this.request('POST', '/routing/default', { body: params });\n }\n\n /** Retrieve default config for profiles. `GET /routing/default/profile` */\n async getDefaultProfile(): Promise<RoutableConnectorChoice[] | ProfileDefaultRoutingConfig[]> {\n return this.request('GET', '/routing/default/profile');\n }\n\n /**\n * Retrieve one profile's default config. `GET /routing/default/profile/{profileId}`\n *\n * The narrow counterpart of `getDefaultProfile()`: that one returns every\n * profile of the merchant and needs merchant-level routing read, so a\n * profile-scoped (shop) role could write its own default through\n * `updateDefaultProfile()` but never read it back. This read is gated on\n * profile-level routing read and pinned to the caller's own profile — a shop\n * role asking for a sibling profile is refused.\n */\n async getDefaultForProfile(profileId: string): Promise<ProfileDefaultRoutingConfig> {\n return this.request('GET', `/routing/default/profile/${encodeURIComponent(profileId)}`);\n }\n\n /** Update default config for a profile. `POST /routing/default/profile/{profileId}` */\n async updateDefaultProfile(\n profileId: string,\n params: Record<string, unknown>,\n ): Promise<ProfileDefaultRoutingConfig> {\n return this.request('POST', `/routing/default/profile/${encodeURIComponent(profileId)}`, {\n body: params,\n });\n }\n\n /** List routing configs for profile. `GET /routing/list/profile` */\n async listForProfile(): Promise<RoutingDictionary> {\n return this.request('GET', '/routing/list/profile');\n }\n\n /** Evaluate a routing rule. `POST /routing/rule/evaluate` */\n async evaluateRule(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/rule/evaluate', { body: params });\n }\n\n /** Migrate routing rules for profile. `POST /routing/rule/migrate` */\n async migrateRule(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/rule/migrate', { body: params });\n }\n\n /** Evaluate routing for a payment. `POST /routing/evaluate` */\n async evaluate(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/evaluate', { body: params });\n }\n\n /** Update gateway scores for dynamic routing. `POST /routing/feedback` */\n async feedback(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/feedback', { body: params });\n }\n}\n\nclass RoutingDecisionManager {\n constructor(private readonly request: RequestFn) {}\n\n /** Upsert decision manager config. `PUT /routing/decision` */\n async upsert(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PUT', '/routing/decision', { body: params });\n }\n\n /** Retrieve decision manager config. `GET /routing/decision` */\n async retrieve(): Promise<Record<string, unknown>> {\n return this.request('GET', '/routing/decision');\n }\n\n /** Delete decision manager config. `DELETE /routing/decision` */\n async delete(): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/routing/decision');\n }\n\n /** Upsert surcharge decision config. `PUT /routing/decision/surcharge` */\n async upsertSurcharge(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PUT', '/routing/decision/surcharge', { body: params });\n }\n\n /** Retrieve surcharge decision config. `GET /routing/decision/surcharge` */\n async retrieveSurcharge(): Promise<Record<string, unknown>> {\n return this.request('GET', '/routing/decision/surcharge');\n }\n\n /** Delete surcharge decision config. `DELETE /routing/decision/surcharge` */\n async deleteSurcharge(): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/routing/decision/surcharge');\n }\n}\n\n/**\n * Merchant-friendly surcharge rules: configure a per-payment-method surcharge\n * (fixed or %) added to the amount the buyer pays — without hand-writing the\n * Euclid DSL. Scope to a shop via `profile_id` (omit for merchant-wide).\n *\n * Distinct from the platform fee (a balance deduction): a surcharge changes what\n * the buyer is charged.\n */\nclass SurchargeRules {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create or replace the surcharge program for a scope.\n *\n * `PUT /routing/surcharge/rules`\n *\n * @example\n * ```typescript\n * await delopay.routing.surchargeRules.upsert({\n * surcharges: [\n * { payment_method: 'crypto', surcharge: { rate: { percent: 1.0 } } },\n * { payment_method: 'card', surcharge: { fixed: { amount: 35 } } },\n * ],\n * });\n * ```\n */\n async upsert(params: SurchargeRuleRequest): Promise<SurchargeRuleResponse> {\n return this.request('PUT', '/routing/surcharge/rules', { body: params });\n }\n\n /**\n * Retrieve the active surcharge program for a scope, or `null` when none is set.\n *\n * `GET /routing/surcharge/rules?profile_id={profileId}`\n *\n * @param profileId - Shop scope. Omit for the merchant-wide rule.\n */\n async retrieve(profileId?: string): Promise<SurchargeRuleResponse | null> {\n return this.request('GET', '/routing/surcharge/rules', {\n query: { profile_id: profileId },\n });\n }\n\n /**\n * Deactivate the active surcharge program for a scope.\n *\n * `DELETE /routing/surcharge/rules?profile_id={profileId}`\n *\n * @param profileId - Shop scope. Omit for the merchant-wide rule.\n */\n async delete(profileId?: string): Promise<void> {\n return this.request('DELETE', '/routing/surcharge/rules', {\n query: { profile_id: profileId },\n });\n }\n}\n\n/**\n * Checkout theme programs: which of a shop's stored appearance variants a buyer\n * is shown.\n *\n * Same engine and same wire format as the advanced routing rules above — a\n * Euclid program whose rules run top-down, first match wins, with\n * `defaultSelection` as the fallback — with the output swapped for a variant\n * name. That is deliberate: the dashboard's routing rule builder can author\n * these without learning a second condition language.\n *\n * **A theme program decides a look and nothing else.** It cannot express which\n * payment methods are offered, what is charged, which provider processes the\n * payment, or whether it succeeds. The allowed dimensions are fixed server-side\n * by the output type — see {@link CheckoutThemeDimension} — so that is a\n * property of the API rather than a convention.\n *\n * Naming a variant the shop has not defined is **not** an error: the checkout\n * falls back to the shop default, exactly as it does for an unknown `?theme=`,\n * because a buyer who cannot pay is worse than a buyer who sees the default\n * look. Such names come back in `warnings` instead, recomputed on every read.\n */\nclass CheckoutThemeRules {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create or replace the theme program for a scope.\n *\n * `PUT /routing/checkout-theme/rules`\n *\n * Supersedes rather than overwrites: the previous active version is retired\n * and a new one stored, so the record of which look was live when survives.\n * Pass `active: false` to store a revision **without** retiring the live one —\n * that is where a program drafted against a variant you have not built yet\n * belongs.\n *\n * @example A phone in Germany gets the compact look; everyone else the house style.\n * ```typescript\n * await delopay.routing.checkoutThemeRules.upsert({\n * name: 'Autumn targeting',\n * profile_id: 'pro_...',\n * algorithm: {\n * rules: [\n * {\n * name: 'German phones',\n * connectorSelection: { theme: { variant: 'compact' } },\n * statements: [\n * {\n * condition: [\n * {\n * lhs: 'device_class',\n * comparison: 'equal',\n * value: { type: 'enum_variant', value: 'phone' },\n * metadata: {},\n * },\n * {\n * lhs: 'browser_language',\n * comparison: 'equal',\n * value: { type: 'enum_variant', value: 'de' },\n * metadata: {},\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * defaultSelection: { theme: { variant: 'house' } },\n * metadata: {},\n * },\n * });\n * ```\n */\n async upsert(params: CheckoutThemeProgramRequest): Promise<CheckoutThemeProgramResponse> {\n return this.request('PUT', '/routing/checkout-theme/rules', { body: params });\n }\n\n /**\n * Retrieve the active theme program for a scope, or `null` when none is set.\n *\n * `GET /routing/checkout-theme/rules?profile_id={profileId}`\n *\n * @param profileId - Shop scope. Omit for the merchant-wide program. A\n * shop-scoped caller that omits it gets its own shop's program.\n */\n async retrieve(profileId?: string): Promise<CheckoutThemeProgramResponse | null> {\n return this.request('GET', '/routing/checkout-theme/rules', {\n query: { profile_id: profileId },\n });\n }\n\n /**\n * Deactivate the active theme program for a scope. Idempotent.\n *\n * `DELETE /routing/checkout-theme/rules?profile_id={profileId}`\n *\n * Deactivation, not deletion — the stored row is what says which look was\n * live when, and that history cannot be reconstructed after the fact. Shops\n * go back to their default appearance immediately.\n *\n * @param profileId - Shop scope. Omit for the merchant-wide program.\n */\n async delete(profileId?: string): Promise<void> {\n return this.request('DELETE', '/routing/checkout-theme/rules', {\n query: { profile_id: profileId },\n });\n }\n}\n\n/**\n * Rendered-to-paid conversion, per appearance variant and segment.\n *\n * Answers the one question theme targeting exists for: *does variant B convert\n * better than the house style, on phones, in Germany?*\n *\n * **What a rate here means.** The denominator is backend-observed checkout page\n * opens, deduplicated by device within the hosted checkout's cache window, with\n * automated traffic excluded from both sides. It is narrower than \"paints\", and\n * that is deliberate - counting one buyer's refresh as a second render would\n * understate conversion. The exact basis travels with every response in\n * `denominator`, and the ways it is not the whole truth travel in `caveats`.\n *\n * **The server decides what may be concluded, not you.** Rate, Wilson interval,\n * per-cell `verdict` and the variant-vs-default `separates` test are computed\n * once, server-side, and shipped as values. Do not recompute them: the first\n * client that rounds differently tells a merchant a difference is real when the\n * server says it is not.\n */\nclass CheckoutThemeConversion {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Rendered-to-paid conversion for a shop over a window.\n *\n * `GET /routing/checkout-theme/conversion`\n *\n * Requires `CheckoutBranding` read at profile scope - the same permission\n * that governs seeing how a checkout looks.\n *\n * @param params - Window (RFC3339, `start` inclusive / `end` exclusive), the\n * shop, and the dimension to group by.\n *\n * @example Which variant wins on which device, over the last 30 days.\n * ```typescript\n * const report = await delopay.routing.checkoutThemeConversion.retrieve({\n * profile_id: 'pro_...',\n * start: '2026-07-21T00:00:00Z',\n * end: '2026-08-20T00:00:00Z',\n * segment: 'device',\n * });\n *\n * for (const c of report.comparisons) {\n * if (!c.separates) continue; // \"not shown to differ\" - say nothing\n * console.log(`${c.variant} on ${c.segment}: ${c.higher} converts better`);\n * }\n * ```\n */\n async retrieve(params: CheckoutThemeConversionQuery): Promise<CheckoutThemeConversionResponse> {\n return this.request('GET', '/routing/checkout-theme/conversion', {\n query: {\n profile_id: params.profile_id,\n start: params.start,\n end: params.end,\n segment: params.segment,\n },\n });\n }\n}\n","import type { RequestFn } from '../client';\n\n/** Index discriminator returned for each search result group. */\nexport type SearchIndex =\n | 'payment_attempts'\n | 'payment_intents'\n | 'refunds'\n | 'disputes'\n | 'payouts'\n | 'sessionizer_payment_attempts'\n | 'sessionizer_payment_intents'\n | 'sessionizer_refunds'\n | 'sessionizer_disputes'\n | 'routing_rules'\n | 'webhook_events'\n | 'audit_logs'\n | 'subscriptions';\n\nexport type SearchStatus = 'Success' | 'Failure';\n\n/** One result group (per index) in the response array. */\nexport interface SearchGroupResponse {\n count: number;\n index: SearchIndex;\n hits: Record<string, unknown>[];\n status: SearchStatus;\n}\n\n/**\n * The window a global search covers. The documented wire fields are\n * `start_time` (required) and `end_time` (optional — omit it for \"up to\n * now\"); the server also accepts the camelCase spellings as aliases, which\n * earlier SDK versions sent, so both are declared and either compiles.\n * Prefer the snake_case pair: it is what the operation documents.\n */\nexport type SearchTimeRange =\n | { start_time: string; end_time?: string | null }\n /** @deprecated Use `start_time` / `end_time` — the documented wire names. */\n | { startTime: string; endTime?: string | null };\n\nexport interface GlobalSearchRequest {\n query: string;\n filters?: Record<string, unknown>;\n /** Naive ISO 8601 bounds; `end_time` may be omitted. */\n timeRange?: SearchTimeRange;\n /** Wire alias for `timeRange` — the server reads either. */\n time_range?: SearchTimeRange;\n}\n\n/** Global cross-index search. */\nexport class Search {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Search every supported index for `query`.\n * `POST /analytics/search`\n *\n * @example\n * ```typescript\n * const groups = await delopay.search.global({ query: 'pay_abc' });\n * for (const g of groups) console.log(g.index, g.count);\n * ```\n */\n async global(\n params: GlobalSearchRequest,\n options?: { signal?: AbortSignal },\n ): Promise<SearchGroupResponse[]> {\n return this.request('POST', '/analytics/search', {\n body: params,\n ...(options?.signal ? { signal: options.signal } : {}),\n });\n }\n}\n","import type {\n CheckoutBrandingResponse,\n CheckoutBrandingUpdate,\n ShopCreateRequest,\n ShopResponse,\n ShopUpdateRequest,\n GatewayConnectRequest,\n GatewayResponse,\n ProfileLogoUploadResponse,\n ShopStatsResponse,\n StatsPeriod,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/** Manage gateway connections for a specific shop. */\nclass ShopGateways {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Connect a payment gateway to a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID.\n * @param params - Gateway connector credentials and configuration.\n * @returns The created gateway connection.\n */\n async connect(\n merchantId: string,\n shopId: string,\n params: GatewayConnectRequest,\n ): Promise<GatewayResponse> {\n return this.request(\n 'POST',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`,\n { body: params },\n );\n }\n\n /**\n * List all gateway connections for a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID.\n * @returns Array of gateway connections.\n */\n async list(merchantId: string, shopId: string): Promise<GatewayResponse[]> {\n return this.request(\n 'GET',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`,\n );\n }\n\n /**\n * Disconnect a gateway from a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID.\n * @param gatewayId - The gateway connector ID to remove.\n * @returns The removed gateway connection.\n */\n async disconnect(\n merchantId: string,\n shopId: string,\n gatewayId: string,\n ): Promise<GatewayResponse> {\n return this.request(\n 'DELETE',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways/${encodeURIComponent(gatewayId)}`,\n );\n }\n}\n\n/**\n * Create and manage shops (business profiles) within a merchant account.\n *\n * Each shop can have its own gateway connections, routing rules, and fee schedules.\n */\nexport class Shops {\n /** Gateway connection management for shops. */\n readonly gateways: ShopGateways;\n\n constructor(private readonly request: RequestFn) {\n this.gateways = new ShopGateways(request);\n }\n\n /**\n * Create a new shop under a merchant account.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Shop creation parameters (name, etc.).\n * @returns The created shop.\n *\n * @example\n * ```typescript\n * const shop = await delopay.shops.create('merch_123', { shop_name: 'EU Store' });\n * ```\n */\n async create(merchantId: string, params: ShopCreateRequest): Promise<ShopResponse> {\n return this.request('POST', `/shops/${encodeURIComponent(merchantId)}`, { body: params });\n }\n\n /**\n * Retrieve a shop by its ID.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID.\n * @returns The shop.\n */\n async retrieve(merchantId: string, shopId: string): Promise<ShopResponse> {\n return this.request(\n 'GET',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,\n );\n }\n\n /**\n * Update a shop's configuration.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID to update.\n * @param params - Fields to update.\n * @returns The updated shop.\n */\n async update(\n merchantId: string,\n shopId: string,\n params: ShopUpdateRequest,\n ): Promise<ShopResponse> {\n return this.request(\n 'PUT',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,\n { body: params },\n );\n }\n\n /**\n * Delete a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID to delete.\n * @returns The deleted shop object.\n */\n async delete(merchantId: string, shopId: string): Promise<ShopResponse> {\n return this.request(\n 'DELETE',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,\n );\n }\n\n /**\n * List all shops under a merchant account.\n *\n * @param merchantId - The merchant account ID.\n * @returns Array of shops.\n */\n async list(merchantId: string): Promise<ShopResponse[]> {\n return this.request('GET', `/shops/${encodeURIComponent(merchantId)}`);\n }\n\n /**\n * Successful-order count and revenue for one shop.\n *\n * Unlike `projects.stats()` this needs only `ProfileAccountRead`, so a\n * shop-scoped user can load it for their own shop; merchant-level users can\n * load any shop of their merchant.\n *\n * Revenue comes back FX-converted as `revenue_usd` (USD major units) plus a\n * `revenue_by_currency` breakdown. The legacy `revenue` field is a raw\n * cross-currency minor-unit sum and should not be displayed.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID.\n * @param period - Window in days, or `'all'` for an all-time total.\n * Omitted means the server default of 30 days.\n * @returns The shop's stats over the requested window.\n *\n * @example\n * ```typescript\n * const stats = await delopay.shops.stats('merch_123', 'pro_1', 'all');\n * console.log(stats.orders, stats.revenue_usd);\n * ```\n */\n async stats(\n merchantId: string,\n shopId: string,\n period?: StatsPeriod,\n ): Promise<ShopStatsResponse> {\n const path = `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/stats`;\n if (period === undefined) return this.request('GET', path);\n return this.request('GET', path, { query: { period: String(period) } });\n }\n\n /**\n * Upload a logo file for a shop. The file is stored in Delopay's configured\n * object store and a public HTTPS URL is returned. This method does NOT write\n * the URL into the shop's `payment_link_config.logo` — call\n * `shops.update` afterwards with the returned `logo_url` to persist the change.\n *\n * Accepts PNG, JPEG, WebP or SVG. The file must be ≤ 1 MiB.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID.\n * @param file - The logo file (Blob / File in browsers).\n * @returns The publicly-reachable URL of the uploaded logo.\n *\n * @example\n * ```typescript\n * const { logo_url } = await delopay.shops.uploadLogo('merch_1', 'pro_1', file);\n * await delopay.shops.update('merch_1', 'pro_1', {\n * payment_link_config: { logo: logo_url },\n * });\n * ```\n */\n async uploadLogo(\n merchantId: string,\n shopId: string,\n file: Blob,\n ): Promise<ProfileLogoUploadResponse> {\n const form = new FormData();\n form.append('file', file);\n return this.request(\n 'POST',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/logo`,\n { body: form },\n );\n }\n\n /**\n * Update only the checkout appearance (the `payment_link_config` blob:\n * theme, logo, colours, seller name, SDK layout/rules, DeloPay-branding\n * toggle) of a shop. Applied as a whole-object replace of\n * `payment_link_config`, mirroring the shop-update semantics.\n *\n * Gated on the dedicated `CheckoutBranding` permission, so \"may restyle\n * the checkout\" can be granted without full account/shop write.\n *\n * `POST /shops/{merchantId}/{shopId}/checkout-branding`\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID to restyle.\n * @param params - The new `payment_link_config` blob (full replacement).\n * @returns The saved branding — the same shape `retrieveCheckoutBranding`\n * returns, not the whole shop. A role whose only power is restyling a\n * checkout must not receive the webhook signing key or the card-vault\n * configuration back from a save.\n */\n async updateCheckoutBranding(\n merchantId: string,\n shopId: string,\n params: CheckoutBrandingUpdate,\n options?: RequestExtras,\n ): Promise<CheckoutBrandingResponse> {\n return this.request(\n 'POST',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/checkout-branding`,\n { body: params, ...options },\n );\n }\n\n /**\n * Read only the checkout appearance of a shop, so the role that may restyle a\n * checkout can load the checkout it may restyle.\n *\n * Gated on `ProfileCheckoutBrandingRead` — the read twin of the\n * `ProfileCheckoutBrandingEdit` guard on `updateCheckoutBranding` above.\n * Prefer this over `shops.retrieve` for the branding editor: `retrieve`\n * returns the whole profile, including the webhook signing key and the\n * card-vault configuration, and needs the shop-read permission for exactly\n * that reason.\n *\n * `GET /shops/{merchantId}/{shopId}/checkout-branding`\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID whose branding to read.\n * @returns The shop's id, name and stored `payment_link_config`. That config\n * is `null` when the shop has never been styled — the untouched default, not\n * an error, and distinct from a stored-but-empty style.\n */\n async retrieveCheckoutBranding(\n merchantId: string,\n shopId: string,\n options?: RequestExtras,\n ): Promise<CheckoutBrandingResponse> {\n return this.request(\n 'GET',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/checkout-branding`,\n options,\n );\n }\n}\n","import type {\n StripeConnectAccountRequest,\n StripeConnectAccountResponse,\n StripeConnectLinkRequest,\n StripeConnectLinkResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class StripeConnect {\n constructor(private readonly request: RequestFn) {}\n\n async createAccount(params: StripeConnectAccountRequest): Promise<StripeConnectAccountResponse> {\n return this.request('POST', '/connector-onboarding/stripe/accounts', { body: params });\n }\n\n async createAccountLink(params: StripeConnectLinkRequest): Promise<StripeConnectLinkResponse> {\n return this.request('POST', '/connector-onboarding/stripe/account-links', { body: params });\n }\n\n // --- Generic connector onboarding (Task 4.11) ---\n\n /** Get onboarding action URL. `POST /connector-onboarding/action-url` */\n async getActionUrl(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/connector-onboarding/action-url', { body: params });\n }\n\n /** Sync onboarding status. `POST /connector-onboarding/sync` */\n async syncOnboarding(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/connector-onboarding/sync', { body: params });\n }\n\n /** Reset tracking ID. `POST /connector-onboarding/reset-tracking-id` */\n async resetTrackingId(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/connector-onboarding/reset-tracking-id', { body: params });\n }\n}\n","import type { ThreeDsRuleExecuteRequest, ThreeDsRuleResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class ThreeDsRules {\n constructor(private readonly request: RequestFn) {}\n\n async execute(params: ThreeDsRuleExecuteRequest): Promise<ThreeDsRuleResponse> {\n return this.request('POST', '/three-ds-decision/execute', { body: params });\n }\n}\n","import type {\n SignUpRequest,\n SignUpWithMerchantRequest,\n SignInRequest,\n AuthResponse,\n UserResponse,\n ChangePasswordRequest,\n DeleteAccountRequest,\n ForgotPasswordRequest,\n ResetPasswordRequest,\n SwitchMerchantRequest,\n SwitchProfileRequest,\n ImpersonateEmployeeRequest,\n InviteUsersRequest,\n InviteUsersResponse,\n AddUserRequest,\n AddUserResponse,\n UpdateUserRoleRequest,\n DeleteUserRoleRequest,\n TotpResponse,\n RecoveryCodesResponse,\n PhoneOtpRequest,\n PhoneOtpResponse,\n PhoneOtpVerifyRequest,\n PhoneOtpVerifyResponse,\n UpdateMetadataRequest,\n UpdateUserDetailsRequest,\n FromEmailRequest,\n TokenResponse,\n VerifyTotpRequest,\n Terminate2faQueryParams,\n ListInvitableRolesParams,\n ListUsersInLineageParams,\n UserInLineage,\n LoginHistoryParams,\n LoginHistoryResponse,\n UserSessionListResponse,\n UserSessionRevokeResponse,\n ParentGroupInfo,\n RoleConnectorGrant,\n UpdateRoleConnectorGrantParams,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Users {\n constructor(private readonly request: RequestFn) {}\n\n async signUp(params: SignUpRequest | SignUpWithMerchantRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/signup', { body: params });\n }\n\n async signIn(params: SignInRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/signin', { body: params });\n }\n\n async signOut(): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/signout');\n }\n\n /**\n * Sliding-session refresh: exchange the current (still-valid) login JWT\n * for a fresh one with the same claims and a full lifetime. The backend\n * keeps the session's identity (`jti`), slides `user_session.expires_at`\n * forward and re-sets the `login_token` cookie.\n *\n * Requires a token backed by a revocable session (a `jti` claim). Signin\n * and switch-merchant/-profile tokens have one; **session-less tokens do\n * not and are rejected with 400** — team-impersonation tokens are the\n * case in practice, and they are deliberately tab-scoped and\n * time-bounded rather than renewable. A 400 here is not a dead session:\n * the token remains valid for ordinary calls, it simply cannot slide.\n *\n * Rejected (401) for expired, blacklisted or revoked tokens — refresh can\n * only extend a session that is still alive. Rate-limited server-side\n * (429) to one mint per session per minute; treat a 429 as \"still fresh\n * enough\", not as an error.\n *\n * The returned token is NOT applied to this client automatically — pass\n * it to `setJwtToken()`, or use {@link Delopay.refreshSession} which does\n * both.\n *\n * `POST /user/token/refresh`. Requires a logged-in JWT.\n */\n async refreshToken(): Promise<TokenResponse> {\n return this.request('POST', '/user/token/refresh');\n }\n\n /**\n * Paginated login history for the authenticated user -- IP, User-Agent,\n * country / city / lat-lon (when GeoIP is enabled), success and failure\n * events with their reasons. Strictly scoped to the JWT subject; a user\n * can only see their own activity.\n *\n * `GET /user/me/login-activity`. Requires a logged-in JWT.\n *\n * Returns an empty page when a Delopay admin is impersonating a merchant,\n * so the admin's metadata is not exposed inside the merchant dashboard.\n */\n async listLoginActivity(params?: LoginHistoryParams): Promise<LoginHistoryResponse> {\n if (params === undefined) {\n return this.request('GET', '/user/me/login-activity');\n }\n return this.request('GET', '/user/me/login-activity', {\n query: params as Record<string, number | undefined>,\n });\n }\n\n /**\n * List the authenticated user's currently-active dashboard sessions\n * (one row per minted login JWT that hasn't been revoked or expired).\n *\n * The row matching the JWT making this call has `is_current: true`,\n * which is what lets the dashboard render a \"This device\" tag.\n *\n * `GET /user/me/sessions`. Requires a logged-in JWT. Returns an empty\n * list when a Delopay admin is impersonating a non-admin merchant\n * (same guard as `listLoginActivity`).\n */\n async listActiveSessions(): Promise<UserSessionListResponse> {\n return this.request('GET', '/user/me/sessions');\n }\n\n /**\n * Disconnect one of the authenticated user's sessions. The matching\n * JWT is rejected on its next request — fast-path via Redis, fall back\n * to the persistent `revoked_at` column.\n *\n * Idempotent: revoking an already-revoked or unknown id returns 404,\n * which the caller can treat as success for retry purposes. Revoking\n * a session id that belongs to a different user also returns 404 —\n * the response intentionally doesn't leak whether the id exists.\n *\n * `POST /user/me/sessions/{sessionId}/revoke`.\n */\n async revokeSession(sessionId: string): Promise<UserSessionRevokeResponse> {\n return this.request('POST', `/user/me/sessions/${encodeURIComponent(sessionId)}/revoke`);\n }\n\n async getDetails(): Promise<UserResponse> {\n return this.request('GET', '/user');\n }\n\n async update(params: UpdateUserDetailsRequest): Promise<UserResponse> {\n return this.request('POST', '/user/update', { body: params });\n }\n\n /**\n * RFC 7396 merge-patch the caller's own user-scoped metadata bucket.\n * Returns the full user details, so callers can refresh their context\n * without a second fetch.\n *\n * `PATCH /user/metadata`\n */\n async updateMetadata(params: UpdateMetadataRequest): Promise<UserResponse> {\n return this.request('PATCH', '/user/metadata', { body: params });\n }\n\n /**\n * RFC 7396 merge-patch the merchant-scoped metadata bucket shared by\n * every dashboard user of the merchant. Same response contract as\n * {@link Users.updateMetadata}.\n *\n * `PATCH /user/merchant/metadata`\n */\n async updateMerchantMetadata(params: UpdateMetadataRequest): Promise<UserResponse> {\n return this.request('PATCH', '/user/merchant/metadata', { body: params });\n }\n\n /**\n * Permanently delete the caller's account. Requires a fresh password\n * (and a current 6-digit TOTP code if the user has TOTP enrolled). On\n * success all role assignments are removed, the user record is\n * deactivated, and all in-flight sessions are invalidated. The caller\n * should clear local credentials and route to the login page.\n *\n * Returns `InvalidDeleteOperation` when the caller is the sole\n * owner-level admin of an org / merchant / profile -- they must\n * transfer ownership first.\n */\n async deleteAccount(params: DeleteAccountRequest): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/user/account', { body: params });\n }\n\n async changePassword(params: ChangePasswordRequest): Promise<UserResponse> {\n return this.request('POST', '/user/change-password', { body: params });\n }\n\n async rotatePassword(params: ResetPasswordRequest): Promise<UserResponse> {\n return this.request('POST', '/user/rotate-password', { body: params });\n }\n\n async forgotPassword(params: ForgotPasswordRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/forgot-password', { body: params });\n }\n\n /**\n * Commit a password reset.\n *\n * The caller is responsible for obtaining a `SinglePurposeToken` with\n * `purpose: reset_password` via the email-token exchange + TOTP flow\n * (see `fromEmail`, `beginTotp`, `updateTotp`/`verifyTotp`,\n * `generateRecoveryCodes`, `terminate2fa`) and setting it on the client\n * via `setJwtToken` before calling this method. `body.token` must still\n * be the original `EmailToken` from the reset-link URL — the handler\n * decodes it a second time to find the user.\n */\n async resetPassword(params: ResetPasswordRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/reset-password', { body: params });\n }\n\n /**\n * Exchange an email-link token (`EmailToken`) for a single-purpose JWT\n * that drives the next step of the flow (TOTP, verify email, accept\n * invitation, etc.). No authentication required.\n *\n * The `token_type` in the response tells you which step to run next.\n */\n async fromEmail(params: FromEmailRequest): Promise<TokenResponse> {\n return this.request('POST', '/user/from-email', { body: params });\n }\n\n async verifyEmail(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/verify-email', { body: params });\n }\n\n async sendVerificationEmail(params: ForgotPasswordRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/verify-email-request', { body: params });\n }\n\n async createMerchant(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/create-merchant', { body: params });\n }\n\n async switchMerchant(params: SwitchMerchantRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/switch/merchant', { body: params });\n }\n\n async switchProfile(params: SwitchProfileRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/switch/profile', { body: params });\n }\n\n async listMerchants(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/list/merchant');\n }\n\n async listProfiles(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/list/profile');\n }\n\n async inviteUsers(params: InviteUsersRequest[]): Promise<InviteUsersResponse[]> {\n return this.request('POST', '/user/employees/invite', { body: params });\n }\n\n /**\n * Add a team member directly, without sending an invite email.\n * `POST /user/employees/add`\n *\n * Unlike `inviteUsers`, the account is active immediately and you hand over\n * the credentials yourself. Omit `password` to have the server generate one\n * and return it once in `password` on the response; supply your own and it is\n * not echoed back. Either way the member must change it on first sign-in.\n *\n * Same role rules as invite: you cannot grant a role above your own, and a\n * shop-scoped caller can only target their own shop.\n */\n async addUser(params: AddUserRequest): Promise<AddUserResponse> {\n return this.request('POST', '/user/employees/add', { body: params });\n }\n\n /**\n * Impersonate one of your own team members — `POST /user/employees/impersonate`.\n *\n * Mints a session token **as** the given member, so the dashboard renders\n * exactly what they see (useful for support and role verification). The\n * caller needs the *Impersonation* permission, and the member's role must\n * rank **strictly below** the caller's (`Profile < Merchant < Organization`);\n * the server rejects self-impersonation, cross-merchant targets, and\n * equal/higher roles.\n *\n * The returned token is tab-scoped by design: open it in a fresh tab (e.g.\n * `/auth/impersonate?token=…`) rather than replacing the caller's own\n * session. No auth cookie is set on the response.\n */\n async impersonateEmployee(params: ImpersonateEmployeeRequest): Promise<TokenResponse> {\n return this.request('POST', '/user/employees/impersonate', { body: params });\n }\n\n async acceptInvitation(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/employees/invite/accept', { body: params });\n }\n\n /**\n * Accept an invitation via the email-link flow.\n *\n * Caller must already hold a `SinglePurposeToken` with\n * `purpose: accept_invitation_from_email` (obtained via `fromEmail` + any\n * required TOTP step) and have set it on the client via `setJwtToken`.\n * `body.token` must still be the original `EmailToken` from the\n * invite-link URL — the handler decodes it a second time to find the\n * invitee and the entity lineage.\n */\n async acceptInviteFromEmail(params: FromEmailRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/accept-invite-from-email', { body: params });\n }\n\n /**\n * Start TOTP setup (or no-op if already set).\n *\n * Returns the QR-code payload when the user has no TOTP configured yet;\n * returns `{ secret: null }` when the user is already set up (caller\n * should then prompt for a 6-digit code and call `verifyTotp`).\n *\n * Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async beginTotp(): Promise<TotpResponse> {\n return this.request('GET', '/user/2fa/totp/begin');\n }\n\n /**\n * Verify a 6-digit TOTP code for a user whose TOTP is already set up.\n * Marks the code as used in Redis so subsequent flow steps can advance.\n *\n * Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async verifyTotp(params: VerifyTotpRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/2fa/totp/verify', { body: params });\n }\n\n async resetTotp(): Promise<Record<string, unknown>> {\n return this.request('GET', '/user/2fa/totp/reset');\n }\n\n async generateRecoveryCodes(): Promise<RecoveryCodesResponse> {\n return this.request('GET', '/user/2fa/recovery-code/generate');\n }\n\n async verifyRecoveryCode(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/2fa/recovery-code/verify', { body: params });\n }\n\n async sendPhoneOtp(params: PhoneOtpRequest): Promise<PhoneOtpResponse> {\n return this.request('POST', '/user/phone/send-otp', { body: params });\n }\n\n async verifyPhoneOtp(params: PhoneOtpVerifyRequest): Promise<PhoneOtpVerifyResponse> {\n return this.request('POST', '/user/phone/verify-otp', { body: params });\n }\n\n /**\n * List all roles visible to the caller (predefined + custom).\n *\n * `GET /user/role/list`. With `groups: true` the response is the\n * parent-groups shape: `[{role_id, role_name, entity_type, role_scope,\n * parent_groups: [{name, description, scopes}]}]`; without it, the\n * deprecated flat `groups` shape.\n */\n async listRoles(params?: {\n groups?: boolean;\n entity_type?: string;\n }): Promise<Record<string, unknown>[]> {\n if (params === undefined) {\n return this.request('GET', '/user/role/list');\n }\n return this.request('GET', '/user/role/list', {\n query: { groups: params.groups, entity_type: params.entity_type },\n });\n }\n\n async listUserRoles(params?: Record<string, unknown>): Promise<Record<string, unknown>[]> {\n return this.request('POST', '/user/employees', { body: params });\n }\n\n /**\n * Change a team member's role. `POST /user/employees/update-role`\n *\n * Pass `profile_id` to name the shop when managing a shop's team as a\n * merchant-scoped admin — see {@link UpdateUserRoleRequest.profile_id}.\n */\n async updateUserRole(params: UpdateUserRoleRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/employees/update-role', { body: params });\n }\n\n /**\n * Remove a team member. `DELETE /user/employees/delete`\n *\n * Pass `profile_id` to name the shop when managing a shop's team as a\n * merchant-scoped admin — see {@link DeleteUserRoleRequest.profile_id}.\n */\n async deleteUserRole(params: DeleteUserRoleRequest): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/user/employees/delete', { body: params });\n }\n\n /** Sign in via OIDC. `POST /user/oidc` */\n async signInOidc(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/oidc', { body: params });\n }\n\n /** Transfer key. `POST /user/key/transfer` */\n async transferKey(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/key/transfer', { body: params });\n }\n\n /** List invitations. `GET /user/list/invitation` */\n async listInvitations(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/list/invitation');\n }\n\n /** Check 2FA status. `GET /user/2fa` */\n async check2faStatus(): Promise<Record<string, unknown>> {\n return this.request('GET', '/user/2fa');\n }\n\n /**\n * Finish first-time TOTP setup: commit the secret generated by `beginTotp`\n * against a 6-digit code from the user's authenticator app.\n *\n * `PUT /user/2fa/totp/verify`. Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async updateTotp(params: VerifyTotpRequest): Promise<Record<string, unknown>> {\n return this.request('PUT', '/user/2fa/totp/verify', { body: params });\n }\n\n /**\n * Complete the TOTP step and advance to the next flow stage (e.g.\n * `reset_password`). Returns a fresh single-purpose token with the\n * next `token_type`.\n *\n * `GET /user/2fa/terminate`. Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async terminate2fa(query?: Terminate2faQueryParams): Promise<TokenResponse> {\n if (query === undefined) {\n return this.request('GET', '/user/2fa/terminate');\n }\n return this.request('GET', '/user/2fa/terminate', {\n query: query as Record<string, boolean | undefined>,\n });\n }\n\n /** Create auth method. `POST /user/auth` */\n async createAuthMethod(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/auth', { body: params });\n }\n\n /** Update auth method. `PUT /user/auth` */\n async updateAuthMethod(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PUT', '/user/auth', { body: params });\n }\n\n /** List auth methods. `GET /user/auth/list` */\n async listAuthMethods(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/auth/list');\n }\n\n /** Get auth URL. `GET /user/auth/url` */\n async getAuthUrl(): Promise<Record<string, unknown>> {\n return this.request('GET', '/user/auth/url');\n }\n\n /** Select auth method. `POST /user/auth/select` */\n async selectAuth(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/auth/select', { body: params });\n }\n\n /**\n * List users in lineage.\n *\n * Needs the Users *view* grant now — the response carries colleagues' email\n * addresses, so a role without it is refused rather than handed a roster.\n * A shop-scoped role keeps reading its own shop's members.\n *\n * `GET /user/employees/list`\n */\n async listUsersInLineage(params?: ListUsersInLineageParams): Promise<UserInLineage[]> {\n return this.request('GET', '/user/employees/list', {\n query: params as Record<string, string | undefined> | undefined,\n });\n }\n\n /** Resend invite. `POST /user/resend-invite` */\n async resendInvite(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/resend-invite', { body: params });\n }\n\n /**\n * Get the caller's parent permission groups + scopes.\n *\n * `GET /user/role`\n */\n async getRolePermissions(): Promise<ParentGroupInfo[]> {\n return this.request('GET', '/user/role');\n }\n\n /**\n * List invitable roles. `GET /user/role/list/invite`\n *\n * @param params - Optional query. `entity_type` scopes the role list to a\n * particular entity (e.g. `'merchant'` to list only merchant-scoped roles\n * when inviting employees from the merchant dashboard).\n */\n async listInvitableRoles(params?: ListInvitableRolesParams): Promise<Record<string, unknown>[]> {\n if (params === undefined || params.entity_type === undefined) {\n return this.request('GET', '/user/role/list/invite');\n }\n return this.request('GET', '/user/role/list/invite', {\n query: { entity_type: params.entity_type },\n });\n }\n\n /** List updatable roles. `GET /user/role/list/update` */\n async listUpdatableRoles(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/role/list/update');\n }\n\n /** Get parent list. `GET /user/parent/list` */\n async getParentList(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/parent/list');\n }\n\n /** Create a role. `POST /user/role` */\n async createRole(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/role', { body: params });\n }\n\n /** Get role by ID. `GET /user/role/{roleId}` */\n async getRoleById(roleId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/user/role/${encodeURIComponent(roleId)}`);\n }\n\n /** Update role by ID. `PUT /user/role/{roleId}` */\n async updateRole(\n roleId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('PUT', `/user/role/${encodeURIComponent(roleId)}`, { body: params });\n }\n\n /**\n * Delete a custom role. Predefined roles and roles still assigned to\n * team members are rejected by the backend with a 400.\n *\n * `DELETE /user/role/{roleId}`\n */\n async deleteRole(roleId: string): Promise<Record<string, unknown>> {\n return this.request('DELETE', `/user/role/${encodeURIComponent(roleId)}`);\n }\n\n /**\n * Read which individual connector accounts a role may see.\n *\n * `GET /user/role/{roleId}/connectors`\n *\n * **Check `restricted` before reading `connectors`.** An empty list is\n * ambiguous by itself, so the backend states which case it is: `false` means\n * the role holds no grant and sees whatever its entity and profile scope\n * already allowed. Rendering an empty `connectors` array as \"this role sees\n * nothing\" inverts the meaning.\n *\n * Requires the permission that *edits a role*, not a connector permission.\n */\n async getRoleConnectors(roleId: string): Promise<RoleConnectorGrant> {\n return this.request('GET', `/user/role/${encodeURIComponent(roleId)}/connectors`);\n }\n\n /**\n * Replace the set of connector accounts a role may see.\n *\n * `PUT /user/role/{roleId}/connectors`\n *\n * The call **replaces** the whole set rather than adding to it, so send the\n * complete list every time. An empty `merchant_connector_ids` clears the\n * grant and returns the role to unrestricted.\n *\n * The backend refuses an id that is not a connector account of the caller's\n * own merchant, an `Organization`-scoped role (a connector account belongs to\n * exactly one merchant, so an org-spanning role cannot hold one coherently),\n * and any predefined role (one static entry shared by every tenant).\n *\n * Editing a grant invalidates the role cache and blacklists tokens minted\n * before the edit, so **users holding this role must sign in again**. Worth\n * saying in the UI before the save, not after.\n */\n async updateRoleConnectors(\n roleId: string,\n params: UpdateRoleConnectorGrantParams,\n ): Promise<RoleConnectorGrant> {\n return this.request('PUT', `/user/role/${encodeURIComponent(roleId)}/connectors`, {\n body: params,\n });\n }\n}\n","import type {\n ApplePayVerificationRequest,\n ApplePayVerificationResponse,\n ApplePayVerifiedDomainsResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Verification {\n constructor(private readonly request: RequestFn) {}\n\n async registerApplePayDomains(\n merchantId: string,\n params: ApplePayVerificationRequest,\n ): Promise<ApplePayVerificationResponse> {\n return this.request('POST', `/verify/apple-pay/${encodeURIComponent(merchantId)}`, {\n body: params,\n });\n }\n\n async getApplePayVerifiedDomains(\n params: Record<string, string>,\n ): Promise<ApplePayVerifiedDomainsResponse> {\n return this.request('GET', '/verify/applepay-verified-domains', {\n query: params,\n });\n }\n}\n","import type {\n EventType,\n PaymentResponse,\n RefundResponse,\n DisputeResponse,\n MandateResponse,\n PayoutResponse,\n ConfirmSubscriptionResponse,\n} from '../types';\n\n/**\n * The payload of a webhook event, tagged by kind.\n *\n * Mirrors the backend's `{ \"type\": …, \"object\": … }` envelope: `type` names the\n * payload shape and `object` carries it. Narrow on `content.type` to get a\n * fully-typed `object`:\n *\n * ```typescript\n * if (event.content.type === 'payment_details') {\n * event.content.object.payment_id; // typed as PaymentResponse\n * }\n * ```\n */\nexport type WebhookContent =\n | { type: 'payment_details'; object: PaymentResponse }\n | { type: 'refund_details'; object: RefundResponse }\n | { type: 'dispute_details'; object: DisputeResponse }\n | { type: 'mandate_details'; object: MandateResponse }\n | { type: 'payout_details'; object: PayoutResponse }\n | { type: 'subscription_details'; object: ConfirmSubscriptionResponse };\n\n/**\n * A parsed and verified Delopay webhook event.\n *\n * Matches the signed wire body exactly:\n * `{ merchant_id, event_id, event_type, content: { type, object }, timestamp }`.\n *\n * - `event_type` identifies the event, e.g. `'payment_succeeded'`.\n * - `content.type` tags the payload kind, e.g. `'payment_details'`.\n * - `content.object` is the payload; narrow on `content.type` to type it.\n */\nexport interface WebhookEvent {\n /** ID of the merchant that owns this event. */\n merchant_id: string;\n /** Unique ID for this event (stable across delivery retries). */\n event_id: string;\n /** Event type identifier, e.g. `'payment_succeeded'` or `'refund_succeeded'`. */\n event_type: EventType;\n /** The event payload, tagged by kind. Narrow on `content.type` to type `object`. */\n content: WebhookContent;\n /** ISO 8601 timestamp at which the webhook was sent. */\n timestamp: string;\n}\n\nfunction hexToBytes(hex: string): Uint8Array | null {\n if (hex.length === 0 || hex.length % 2 !== 0) return null;\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n const byte = Number.parseInt(hex.slice(i, i + 2), 16);\n if (Number.isNaN(byte)) return null;\n bytes[i / 2] = byte;\n }\n return bytes;\n}\n\nexport const Webhooks = {\n /**\n * Verify the signature of an incoming Delopay webhook and return the parsed event.\n *\n * Delopay signs each outgoing webhook with HMAC-SHA512 over the raw request body,\n * using your shop's webhook secret (the *payment response hash key* configured on\n * the shop). The hex-encoded digest is delivered in the `X-Webhook-Signature-512`\n * HTTP header.\n *\n * Uses the Web Crypto API (`globalThis.crypto.subtle`), so it runs unchanged in\n * Node 18+, modern browsers, Deno, Bun, and edge runtimes (Cloudflare Workers, Vercel Edge).\n *\n * Available as a static property on the `Delopay` class\n * (`Delopay.webhooks.verify`) and does not require a client instance.\n *\n * @param rawBody - The raw request body. Pass the original bytes (`Uint8Array` /\n * `Buffer`) when possible; if you pass a string, it must be the unmodified UTF-8\n * text of the request body. Do **not** parse it before passing.\n * @param signatureHeader - The value of the `X-Webhook-Signature-512` HTTP header.\n * @param secret - Your shop's webhook signing secret.\n * @returns Promise that resolves to the parsed webhook event.\n * @throws {Error} When the signature header is malformed or does not match the body.\n *\n * @example\n * ```typescript\n * // Express example\n * app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {\n * try {\n * const event = await Delopay.webhooks.verify(\n * req.body, // Buffer from express.raw()\n * req.header('x-webhook-signature-512') ?? '',\n * process.env.DELOPAY_WEBHOOK_SECRET!,\n * );\n * console.log(event.event_type, event.content.object);\n * res.sendStatus(200);\n * } catch {\n * res.status(400).send('Invalid signature');\n * }\n * });\n * ```\n */\n async verify(\n rawBody: string | Uint8Array,\n signatureHeader: string,\n secret: string,\n ): Promise<WebhookEvent> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new Error(\n 'Web Crypto unavailable: Delopay.webhooks.verify requires globalThis.crypto.subtle (Node 18+, modern browsers, Workers, Deno)',\n );\n }\n\n const signatureBytes = hexToBytes(signatureHeader.trim());\n if (!signatureBytes) {\n throw new Error('Invalid webhook signature format');\n }\n\n const encoder = new TextEncoder();\n const bodyBytes = typeof rawBody === 'string' ? encoder.encode(rawBody) : rawBody;\n\n // `TextEncoder.encode` returns `Uint8Array<ArrayBufferLike>` in current lib.dom.d.ts,\n // but `crypto.subtle.*` wants `BufferSource` (backed by `ArrayBuffer`). At runtime the\n // underlying buffer is always an `ArrayBuffer` — cast to quiet the type checker.\n const asBufferSource = (bytes: Uint8Array): BufferSource => bytes as unknown as BufferSource;\n const key = await subtle.importKey(\n 'raw',\n asBufferSource(encoder.encode(secret)),\n { name: 'HMAC', hash: 'SHA-512' },\n false,\n ['verify'],\n );\n\n const valid = await subtle.verify(\n 'HMAC',\n key,\n asBufferSource(signatureBytes),\n asBufferSource(bodyBytes),\n );\n\n if (!valid) {\n throw new Error('Invalid webhook signature');\n }\n\n const bodyText =\n typeof rawBody === 'string' ? rawBody : new TextDecoder('utf-8').decode(rawBody);\n return JSON.parse(bodyText) as WebhookEvent;\n },\n};\n","import type { RequestFn } from '../client';\nimport type {\n AnalyticsScopeRequest,\n AnalyticsScopeResponse,\n ClientAnalyticsRequest,\n DevicesAnalyticsResponse,\n GeoAnalyticsResponse,\n DeviceDrillRequest,\n GeoDrillRequest,\n DrillResponse,\n SubscriptionAnalyticsRequest,\n SubscriptionAnalyticsResponse,\n SubscriptionDrillRequest,\n ScopeDrillRequest,\n} from '../types';\n\nexport class Analytics {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Scoped, drill-level analytics dashboard for the authenticated merchant\n * (the same engine as the admin portal, pinned server-side to your own\n * merchant). The server ignores `merchant_id` — it always scopes to your\n * merchant, and to your single shop for profile-scoped users — so pass only\n * `project_id` / `shop_id` to drill and the window / `sections` fields.\n * Returns one drill level: the scope's daily series + previous window,\n * processor mix and direct children. `GET /analytics/scope`\n */\n async scope(params?: AnalyticsScopeRequest): Promise<AnalyticsScopeResponse> {\n return this.request('GET', '/analytics/scope', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Device analytics over the canonical client-context observation per\n * payment (browser/platform families, device classes and models, checkout\n * channel mix, time-to-pay), pinned server-side to your own merchant and\n * drillable via `project_id` / `shop_id` exactly like `scope`. Gated on the\n * client-context optimisation-use switch: when it is off the server answers\n * 200 with `enabled: false` and a caveat naming the switch.\n * `GET /analytics/devices`\n */\n async devices(params?: ClientAnalyticsRequest): Promise<DevicesAnalyticsResponse> {\n return this.request('GET', '/analytics/devices', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Geo analytics over the canonical client-context observation per payment:\n * country totals, city bubbles (IP mode), buyer languages, buyer-local\n * purchase hours and the IP-vs-billing mismatch share. `mode` selects the\n * location claim (`ip` default, `billing`); the two are never coalesced.\n * Same drill, window and gating contract as `devices`.\n * `GET /analytics/geo`\n */\n async geo(params?: ClientAnalyticsRequest): Promise<GeoAnalyticsResponse> {\n return this.request('GET', '/analytics/geo', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The recent payments behind one clicked geo target: a map country (in the\n * active claim mode), optionally narrowed to an IP-resolved city, or one\n * buyer-local heatmap cell (`dow` + `hour`, paid sessions only). Same\n * window/scope/filter and gating contract as `geo`; capped at 50 rows,\n * newest first, with the full match count alongside.\n * `GET /analytics/geo/transactions`\n */\n async geoTransactions(params: GeoDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/geo/transactions', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The recent payments behind one clicked device target: exactly one of a\n * browser family, a platform family, an identified device-model label, or\n * a device class. Family/model targets are resolved server-side with the\n * same classifiers the cards use. Same window/scope/filter and gating\n * contract as `devices`; 50 rows per page (`offset` for the next page),\n * newest first, with the full match count alongside.\n * `GET /analytics/devices/transactions`\n */\n async deviceTransactions(params: DeviceDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/devices/transactions', {\n // A discriminated union carries no index signature, so the widening\n // goes via `unknown` — the union is the point.\n query: params as unknown as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The payments behind one clicked element of the payments dashboard: a\n * processor-donut slice, a payment-method slice, an outcome segment of a\n * series bar, a series bucket, or a breakdown row — combinable, with\n * `target_bucket` narrowing every other target. The outcome mapping is the\n * one the series and donuts are folded with, expanded server-side, so the\n * list is what the clicked number was made of. Rows and the whole-match\n * `summary` carry USD figures converted with the dashboard's own rates.\n * Same window/scope/chip contract as `scope`; sorted per `sort_on` /\n * `sort_by`, `limit` rows (default 50) per page, `offset` for the next.\n * `GET /analytics/scope/transactions`\n */\n async scopeTransactions(params: ScopeDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/scope/transactions', {\n // A discriminated union carries no index signature, so the widening\n // goes via `unknown` — the union is the point, and the query builder\n // only ever reads own enumerable keys.\n query: params as unknown as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Subscription analytics over `subscription` and `invoice`: estimated\n * recurring volume, the invoice funnel, movement (new / expansion /\n * contraction / churn), both processor axes, plan mix and the breakdown one\n * level below the scope. Pinned server-side to your own merchant and\n * drillable via `project_id` / `shop_id` exactly like `scope`.\n *\n * Half the figures are **stocks** — a snapshot at the window's end rather\n * than a sum over it — so `est_monthly_volume_usd` and `active` can match\n * across a 7-day and a 30-day window while `billed_volume_usd` does not.\n * Day granularity only. `GET /analytics/subscriptions`\n */\n async subscriptions(\n params?: SubscriptionAnalyticsRequest,\n ): Promise<SubscriptionAnalyticsResponse> {\n return this.request('GET', '/analytics/subscriptions', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The billing cycles behind one clicked element of the subscription\n * dashboard: an invoice outcome, a processor slice on either axis, a plan\n * row, a subscription status, a movement component, a series bucket or a\n * breakdown row. Same window/scope/filter contract as `subscriptions`; 50\n * rows per page (`offset` for the next), newest first, with the full match\n * count alongside.\n *\n * A cycle that never reached a payment is listed too — that is what \"still\n * unpaid\" means — and carries its invoice id as `payment_id` with\n * `invoice_id` set to the same value, so you can always tell which you got.\n * `GET /analytics/subscriptions/list`\n */\n async subscriptionsList(params: SubscriptionDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/subscriptions/list', {\n // A discriminated union carries no index signature, so the widening\n // goes via `unknown` — the union is the point, and the query builder\n // only ever reads own enumerable keys.\n query: params as unknown as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /** Global search. `POST /analytics/search` */\n async search(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/analytics/search', { body: params });\n }\n\n /** Domain-specific search. `POST /analytics/search/{domain}` */\n async searchDomain(\n domain: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/analytics/search/${encodeURIComponent(domain)}`, {\n body: params,\n });\n }\n\n /** Get analytics info. `GET /analytics/{domain}/info` */\n async getInfo(domain: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/analytics/${encodeURIComponent(domain)}/info`);\n }\n\n /** Get API event logs. `GET /analytics/api-event-logs` */\n async apiEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/api-event-logs', { query: params });\n }\n\n /** Get SDK event logs. `POST /analytics/sdk-event-logs` */\n async sdkEventLogs(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/analytics/sdk-event-logs', { body: params });\n }\n\n /** Get connector event logs. `GET /analytics/connector-event-logs` */\n async connectorEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/connector-event-logs', { query: params });\n }\n\n /** Get routing event logs. `GET /analytics/routing-event-logs` */\n async routingEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/routing-event-logs', { query: params });\n }\n\n /** Get outgoing webhook event logs. `GET /analytics/outgoing-webhook-event-logs` */\n async outgoingWebhookEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/outgoing-webhook-event-logs', { query: params });\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class AnalyticsDashboard {\n constructor(private readonly request: RequestFn) {}\n\n /** Get analytics dashboard data. `GET /analytics-dashboard` */\n async retrieve(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics-dashboard', { query: params });\n }\n\n /** Generate analytics dashboard report. `POST /analytics-dashboard` */\n async generate(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/analytics-dashboard', { body: params });\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Cards {\n constructor(private readonly request: RequestFn) {}\n\n /** Create a card. `POST /cards/create` */\n async create(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/cards/create', { body: params });\n }\n\n /** Update a card. `POST /cards/update` */\n async update(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/cards/update', { body: params });\n }\n\n /** Retrieve card info by BIN. `GET /cards/{bin}` */\n async retrieve(bin: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/cards/${encodeURIComponent(bin)}`);\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Export {\n constructor(private readonly request: RequestFn) {}\n\n /** Export transactions. `POST /export/transactions` */\n async transactions(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/export/transactions', { body: params });\n }\n}\n","import type { FeatureMatrixResponse } from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * What each connector can do: payment methods, capture methods, webhook\n * flows, and whether an unverified webhook is acted on.\n */\nexport class FeatureMatrix {\n constructor(private readonly request: RequestFn) {}\n\n /** Retrieve the feature matrix. `GET /feature-matrix` */\n async retrieve(): Promise<FeatureMatrixResponse> {\n return this.request('GET', '/feature-matrix');\n }\n\n /**\n * Retrieve the feature matrix scoped to a merchant. Beta connectors\n * are filtered against the merchant's allowlist so the dashboard only\n * surfaces connectors the merchant can actually attach.\n * `GET /feature-matrix/{merchantId}`\n */\n async retrieveForMerchant(merchantId: string): Promise<FeatureMatrixResponse> {\n return this.request('GET', `/feature-matrix/${encodeURIComponent(merchantId)}`);\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Files {\n constructor(private readonly request: RequestFn) {}\n\n /** Upload a file. `POST /files` */\n async create(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/files', { body: params });\n }\n\n /** Retrieve/download a file. `GET /files/{fileId}` */\n async retrieve(fileId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/files/${encodeURIComponent(fileId)}`);\n }\n\n /** Delete a file. `DELETE /files/{fileId}` */\n async delete(fileId: string): Promise<Record<string, unknown>> {\n return this.request('DELETE', `/files/${encodeURIComponent(fileId)}`);\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Forex {\n constructor(private readonly request: RequestFn) {}\n\n /** Retrieve forex rates. `GET /forex/rates` */\n async getRates(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/forex/rates', { query: params });\n }\n\n /** Convert from minor currency. `GET /forex/convert-from-minor` */\n async convertFromMinor(\n params: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/forex/convert-from-minor', { query: params });\n }\n}\n","import type {\n RegionCreateRequest,\n RegionUpdateRequest,\n RegionResponse,\n RegionSetCountriesRequest,\n RegionCountriesResponse,\n BuiltInRegionGroupResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Custom regions (named country groups) scoped to a shop/profile, used by the\n * geo-aware payment-method availability overrides. Every endpoint is scoped by\n * `profileId`. Admin (`sk_*`) access required.\n */\nexport class Regions {\n constructor(private readonly request: RequestFn) {}\n\n /** Create a region. `POST /regions?profile_id=` */\n async create(profileId: string, params: RegionCreateRequest): Promise<RegionResponse> {\n return this.request('POST', '/regions', {\n body: params,\n query: { profile_id: profileId },\n });\n }\n\n /** List all regions for a profile. `GET /regions/list?profile_id=` */\n async list(profileId: string): Promise<RegionResponse[]> {\n return this.request('GET', '/regions/list', { query: { profile_id: profileId } });\n }\n\n /** List the built-in (global) region groups (EU/EEA/SEPA/LATAM/APAC). `GET /regions/groups` */\n async groups(): Promise<BuiltInRegionGroupResponse[]> {\n return this.request('GET', '/regions/groups');\n }\n\n /** Retrieve a region by id. `GET /regions/{regionId}?profile_id=` */\n async retrieve(regionId: string, profileId: string): Promise<RegionResponse> {\n return this.request('GET', `/regions/${encodeURIComponent(regionId)}`, {\n query: { profile_id: profileId },\n });\n }\n\n /** Update a region. `PUT /regions/{regionId}?profile_id=` */\n async update(\n regionId: string,\n profileId: string,\n params: RegionUpdateRequest,\n ): Promise<RegionResponse> {\n return this.request('PUT', `/regions/${encodeURIComponent(regionId)}`, {\n body: params,\n query: { profile_id: profileId },\n });\n }\n\n /** Delete a region. `DELETE /regions/{regionId}?profile_id=` */\n async delete(regionId: string, profileId: string): Promise<boolean> {\n return this.request('DELETE', `/regions/${encodeURIComponent(regionId)}`, {\n query: { profile_id: profileId },\n });\n }\n\n /** Get the countries that belong to a region. `GET /regions/{regionId}/countries?profile_id=` */\n async getCountries(regionId: string, profileId: string): Promise<RegionCountriesResponse> {\n return this.request('GET', `/regions/${encodeURIComponent(regionId)}/countries`, {\n query: { profile_id: profileId },\n });\n }\n\n /** Replace the full country membership of a region. `PUT /regions/{regionId}/countries?profile_id=` */\n async setCountries(\n regionId: string,\n profileId: string,\n params: RegionSetCountriesRequest,\n ): Promise<RegionCountriesResponse> {\n return this.request('PUT', `/regions/${encodeURIComponent(regionId)}/countries`, {\n body: params,\n query: { profile_id: profileId },\n });\n }\n}\n","import type {\n AvailabilityOverrideCreateRequest,\n AvailabilityOverrideResponse,\n AvailabilityPreviewParams,\n AvailabilityPreviewResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Merchant payment-method availability overrides. Force-show or force-hide a\n * payment method per country/region at global, project, or shop scope, on top\n * of the curated country defaults. Admin (`sk_*`) access required.\n */\nexport class AvailabilityOverrides {\n constructor(private readonly request: RequestFn) {}\n\n /** Create an availability override. `POST /availability-overrides` */\n async create(params: AvailabilityOverrideCreateRequest): Promise<AvailabilityOverrideResponse> {\n return this.request('POST', '/availability-overrides', { body: params });\n }\n\n /** List a merchant's availability overrides. `GET /availability-overrides` */\n async list(merchantId: string): Promise<AvailabilityOverrideResponse[]> {\n return this.request('GET', '/availability-overrides', {\n query: { merchant_id: merchantId },\n });\n }\n\n /** Delete an availability override by id. `DELETE /availability-overrides/{id}` */\n async delete(id: string): Promise<boolean> {\n return this.request('DELETE', `/availability-overrides/${encodeURIComponent(id)}`);\n }\n\n /**\n * Preview the methods a customer in `country` would be shown for a shop —\n * the connector ceiling narrowed by the smart country defaults and the\n * merchant overrides, without an active payment. Pass `amount` + `currency`\n * to also evaluate order-value rules.\n * `GET /availability-overrides/preview`\n */\n async preview(params: AvailabilityPreviewParams): Promise<AvailabilityPreviewResponse> {\n return this.request('GET', '/availability-overrides/preview', {\n query: {\n merchant_id: params.merchant_id,\n profile_id: params.profile_id,\n ...(params.country ? { country: params.country } : {}),\n // `0` is a legitimate order value, so test for presence, not truthiness.\n ...(params.amount !== undefined ? { amount: params.amount } : {}),\n ...(params.currency ? { currency: params.currency } : {}),\n },\n });\n }\n}\n","import type {\n CreateSubscriptionRequest,\n CreateAndConfirmSubscriptionRequest,\n ConfirmSubscriptionRequest,\n UpdateSubscriptionRequest,\n PauseSubscriptionRequest,\n ResumeSubscriptionRequest,\n CancelSubscriptionRequest,\n SubscriptionResponse,\n ConfirmSubscriptionResponse,\n PauseSubscriptionResponse,\n ResumeSubscriptionResponse,\n CancelSubscriptionResponse,\n GetSubscriptionItemsResponse,\n GetSubscriptionItemsParams,\n SubscriptionEstimateResponse,\n SubscriptionEstimateParams,\n SubscriptionListParams,\n SubscriptionPaymentLookupRequest,\n SubscriptionPaymentLookupResponse,\n SubscriptionInvoiceListParams,\n SubscriptionInvoiceListResponse,\n SubscriptionBillingProcessorResponse,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Subscription endpoints are profile-scoped: the backend requires an\n * `X-Profile-Id` header to resolve the shop / billing processor (`IR_04`\n * otherwise). Pass it through the per-call `options.headers`, e.g.\n * `subscriptions.list(params, { headers: { 'X-Profile-Id': profileId } })`.\n */\nexport class Subscriptions {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create and immediately confirm a subscription. `POST /subscriptions`\n *\n * For billing processors that require buyer approval (e.g. PayPal), the\n * response carries a `redirect_url` the customer must be sent to.\n */\n async createAndConfirm(\n params: CreateAndConfirmSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<ConfirmSubscriptionResponse> {\n return this.request('POST', '/subscriptions', { body: params, ...options });\n }\n\n /** Create a subscription without confirming it. `POST /subscriptions/create` */\n async create(\n params: CreateSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionResponse> {\n return this.request('POST', '/subscriptions/create', { body: params, ...options });\n }\n\n /** Retrieve a subscription by ID. `GET /subscriptions/{subscriptionId}` */\n async retrieve(subscriptionId: string, options?: RequestExtras): Promise<SubscriptionResponse> {\n return this.request('GET', `/subscriptions/${encodeURIComponent(subscriptionId)}`, {\n ...options,\n });\n }\n\n /**\n * Confirm a previously created subscription. `POST /subscriptions/{subscriptionId}/confirm`\n *\n * Like {@link createAndConfirm}, the response may carry a `redirect_url` for\n * processors that require buyer approval.\n */\n async confirm(\n subscriptionId: string,\n params: ConfirmSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<ConfirmSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/confirm`, {\n body: params,\n ...options,\n });\n }\n\n /** Update a subscription's plan/price. `PUT /subscriptions/{subscriptionId}/update` */\n async update(\n subscriptionId: string,\n params: UpdateSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionResponse> {\n return this.request('PUT', `/subscriptions/${encodeURIComponent(subscriptionId)}/update`, {\n body: params,\n ...options,\n });\n }\n\n /** List subscriptions for the profile. `GET /subscriptions/list` */\n async list(\n params?: SubscriptionListParams,\n options?: RequestExtras,\n ): Promise<SubscriptionResponse[]> {\n return this.request('GET', '/subscriptions/list', {\n query: params as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /** Estimate the cost of a subscription before creating it. `GET /subscriptions/estimate` */\n async getEstimate(\n params: SubscriptionEstimateParams,\n options?: RequestExtras,\n ): Promise<SubscriptionEstimateResponse> {\n return this.request('GET', '/subscriptions/estimate', {\n query: params as unknown as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /** List purchasable subscription items (plans/addons). `GET /subscriptions/items` */\n async getItems(\n params: GetSubscriptionItemsParams,\n options?: RequestExtras,\n ): Promise<GetSubscriptionItemsResponse[]> {\n return this.request('GET', '/subscriptions/items', {\n query: params as unknown as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /**\n * Pause a subscription. `POST /subscriptions/{subscriptionId}/pause`\n *\n * The body defaults to `{}` so the request still carries\n * `Content-Type: application/json` even when no params are passed — the\n * backend rejects the POST otherwise (\"Unsupported content type\").\n */\n async pause(\n subscriptionId: string,\n params?: PauseSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<PauseSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/pause`, {\n body: params ?? {},\n ...options,\n });\n }\n\n /** Resume a paused subscription. `POST /subscriptions/{subscriptionId}/resume` */\n async resume(\n subscriptionId: string,\n params?: ResumeSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<ResumeSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/resume`, {\n body: params ?? {},\n ...options,\n });\n }\n\n /** Cancel a subscription. `POST /subscriptions/{subscriptionId}/cancel` */\n async cancel(\n subscriptionId: string,\n params?: CancelSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<CancelSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/cancel`, {\n body: params ?? {},\n ...options,\n });\n }\n\n /**\n * Resolve which of the given payments were raised by a subscription.\n * `POST /subscriptions/payments/lookup`\n *\n * The linkage exists in one direction only — an invoice points at the payment\n * it settled, and nothing is stamped on the payment — so this is the only way\n * to tell a subscription charge from a one-off one when you are holding a\n * page of payments. In particular, do not use `off_session` or the presence\n * of a mandate: an ordinary saved-card charge sets those identically.\n *\n * Ids that belong to no subscription are **absent** from `links` rather than\n * returned as an error, so match on presence:\n *\n * ```ts\n * const { links } = await subscriptions.lookupPayments(\n * { payment_ids: page.map((p) => p.payment_id) },\n * { headers: { 'X-Profile-Id': profileId } },\n * );\n * const bySubscription = new Map(links.map((l) => [l.payment_id, l]));\n * ```\n *\n * Profile-scoped like every other subscription route, and that matters more\n * here than elsewhere: a `payment_id` is merchant-supplied and only unique\n * within a merchant, so the shop is part of the question, not an\n * optimisation. Pass the profile that owns **the payments** — for a list\n * spanning several shops, group the ids by shop and call once per group.\n *\n * At most 200 ids per call.\n */\n async lookupPayments(\n params: SubscriptionPaymentLookupRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionPaymentLookupResponse> {\n return this.request('POST', '/subscriptions/payments/lookup', { body: params, ...options });\n }\n\n /**\n * One subscription's billing history, newest cycle first.\n * `GET /subscriptions/{subscriptionId}/invoices`\n *\n * {@link retrieve} carries only the *latest* invoice, which is the current\n * cycle — a subscription that has renewed monthly for a year has one of those\n * and twelve of these. Use this wherever a merchant needs to see what a\n * subscription has actually billed, in particular on self-charging processors\n * (Creem, PayPal) where each renewal is charged by the processor and mirrored\n * here rather than raised as a DeloPay payment.\n *\n * Two things to render honestly, both decided rather than incidental:\n *\n * - `amount` is **gross** and `refunded_amount` sits beside it. Do not net\n * them: the difference between the two is not a smaller charge.\n * - A `refunded_amount` of `null` is \"not reported\" and must not render as\n * `0`. Likewise a processor-hosted origination records a bootstrap invoice\n * at `0` before the buyer has paid anything, so a zero amount on such a\n * subscription is a placeholder rather than a free cycle.\n *\n * Profile-scoped like every other subscription route.\n */\n async listInvoices(\n subscriptionId: string,\n params?: SubscriptionInvoiceListParams,\n options?: RequestExtras,\n ): Promise<SubscriptionInvoiceListResponse> {\n return this.request('GET', `/subscriptions/${encodeURIComponent(subscriptionId)}/invoices`, {\n query: params as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /**\n * Which billing processor this shop's subscriptions run on.\n * `GET /subscriptions/billing_processor`\n *\n * The same mapping is derivable from the connector inventory\n * (`GET /account/{merchant_id}/connectors`), but that route is gated by a\n * connector-read permission granted independently of subscriptions — so a\n * role authorised to create subscriptions could be unable to learn which\n * processor it was creating them on. This answers under the same\n * authorization as the rest of the subscription API.\n *\n * Reach for it when the client must branch on the processor *before* calling\n * — origination differs by processor, and guessing is destructive. Resolve\n * the shop's `billing_processor_id` first: a shop that runs no subscriptions\n * has none assigned, and this route has no identity to report for it.\n */\n async getBillingProcessor(\n options?: RequestExtras,\n ): Promise<SubscriptionBillingProcessorResponse> {\n return this.request('GET', '/subscriptions/billing_processor', { ...options });\n }\n}\n","import type {\n MerchantAuditLogListParams,\n MerchantAuditLogListResponse,\n MerchantAuditLogEntry,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * A merchant's own audit log — everything changed on their account and their\n * shops, grouped by the sign-in it happened in.\n *\n * Requires a dashboard JWT (`setJwtToken`) whose role holds the `AuditLog`\n * permission; an API key cannot read it. This is deliberate: the log names\n * people, and an API key names no one.\n *\n * There is no `merchant_id` parameter. The scope comes from the token, so this\n * resource cannot be pointed at another merchant — see\n * {@link MerchantAuditLogListParams}.\n */\nexport class Audit {\n constructor(private readonly request: RequestFn) {}\n\n async list(params?: MerchantAuditLogListParams): Promise<MerchantAuditLogListResponse> {\n return this.request('GET', '/audit', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * One entry. An id belonging to another merchant answers 404, not 403 — the\n * endpoint does not confirm that an entry it will not serve exists.\n */\n async retrieve(logId: string): Promise<MerchantAuditLogEntry> {\n return this.request('GET', `/audit/${encodeURIComponent(logId)}`);\n }\n}\n","import type {\n FeeStatementDetail,\n SettlementBackfillRequest,\n SettlementBackfillResponse,\n SettlementCostParams,\n SettlementCostResponse,\n SettlementCurrentParams,\n SettlementCurrentResponse,\n SettlementLineListParams,\n SettlementLineListResponse,\n SettlementOverviewParams,\n SettlementOverviewResponse,\n SettlementStatementListParams,\n SettlementStatementListResponse,\n ShopFeeConfigParams,\n ShopFeeConfigResponse,\n ShopVisibilityResponse,\n ShopVisibilityUpdateRequest,\n StatementAdjustment,\n StatementAdjustmentCreateRequest,\n StatementAdjustmentListResponse,\n StatementGenerateRequest,\n StatementPayoutUpdateRequest,\n StatementPdfParams,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Hosted-shop settlement: monthly statements, the live current-period\n * rollup, per-line detail, fee schedules and backfills.\n *\n * Every read takes an explicit `test_mode` — test and live figures must\n * never blend, so the environment lives in the signature rather than in a\n * default. `false` is transmitted, not dropped.\n *\n * Shop-owner responses are redacted server-side: absent platform-fee fields\n * are a permission boundary, not a gap — never re-derive them client-side.\n */\nexport class Settlement {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Per-shop settlement rollup for the host merchant: unpaid totals and the\n * running current period, one row per shop.\n *\n * `GET /settlement/overview`\n */\n async overview(\n params: SettlementOverviewParams,\n options?: RequestExtras,\n ): Promise<SettlementOverviewResponse> {\n return this.request('GET', '/settlement/overview', {\n query: { test_mode: params.test_mode },\n ...options,\n });\n }\n\n /**\n * Live rollup of the current (not yet statemented) period.\n *\n * `GET /settlement/current`\n */\n async current(\n params: SettlementCurrentParams,\n options?: RequestExtras,\n ): Promise<SettlementCurrentResponse> {\n return this.request('GET', '/settlement/current', {\n query: { test_mode: params.test_mode, profile_id: params.profile_id },\n ...options,\n });\n }\n\n /**\n * What a period's payments cost, and what was left over: gross, the\n * platform fee, hosting fees, what the rails took, and the margin, with a\n * per-connector breakdown.\n *\n * Send `year` and `month` together to report one UTC calendar month, or\n * neither for the running month so far.\n *\n * **Host-only.** The response is the host's cost base, which a shop owner\n * must never see, so a profile-scoped caller is refused with a 403 rather\n * than given a redacted shell. Gate the surface on the caller's scope\n * instead of calling it and handling the failure.\n *\n * Two things not to flatten when rendering the result:\n * `margin_usd` is absent — not zero — whenever `margin_quality` is\n * `'unknown'`, and `unlined_captured_attempt_count` (cost definitely\n * missing) means something different from `unlined_unresolved_attempt_count`\n * (mostly ordinary abandonment).\n *\n * `GET /settlement/cost`\n *\n * @example\n * ```typescript\n * const cost = await delopay.settlement.cost({ test_mode: false, year: 2026, month: 7 });\n * if (cost.margin_quality === 'unknown') {\n * // cost.margin_usd is absent — say so, do not render 0.00\n * }\n * ```\n */\n async cost(\n params?: SettlementCostParams,\n options?: RequestExtras,\n ): Promise<SettlementCostResponse> {\n return this.request('GET', '/settlement/cost', {\n query: {\n profile_id: params?.profile_id,\n test_mode: params?.test_mode,\n year: params?.year,\n month: params?.month,\n },\n ...options,\n });\n }\n\n /**\n * List generated settlement statements, newest first.\n *\n * `GET /settlement/statements`\n */\n async listStatements(\n params: SettlementStatementListParams,\n options?: RequestExtras,\n ): Promise<SettlementStatementListResponse> {\n return this.request('GET', '/settlement/statements', {\n query: {\n test_mode: params.test_mode,\n profile_id: params.profile_id,\n limit: params.limit,\n offset: params.offset,\n },\n ...options,\n });\n }\n\n /**\n * One statement with its per-connector/currency breakdown.\n *\n * `GET /settlement/statements/{statementId}`\n */\n async retrieveStatement(\n statementId: string,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request(\n 'GET',\n `/settlement/statements/${encodeURIComponent(statementId)}`,\n options,\n );\n }\n\n /**\n * Generate (or regenerate) the statement for one shop and calendar month.\n *\n * `POST /settlement/statements/generate`\n */\n async generateStatement(\n params: StatementGenerateRequest,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request('POST', '/settlement/statements/generate', {\n body: params,\n ...options,\n });\n }\n\n /**\n * Record payout progress on a statement (`unpaid` / `partial` / `paid`).\n *\n * Subject to the caller's `settlement_payout` operation limit — a\n * per-operation ceiling, a windowed total, a windowed count, or any\n * combination: an over-limit call fails with `DE_01` and nothing is\n * recorded. There is no approval route out of it — four-eyes needs an\n * executor that can run the operation once somebody says yes, and only\n * refunds have one, so a settlement rule can only block.\n *\n * `POST /settlement/statements/{statementId}/payout`\n */\n async updateStatementPayout(\n statementId: string,\n params: StatementPayoutUpdateRequest,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request(\n 'POST',\n `/settlement/statements/${encodeURIComponent(statementId)}/payout`,\n { body: params, ...options },\n );\n }\n\n /**\n * Export a statement as PDF. Returns the raw PDF bytes as a `Blob`, with\n * the same auth, retries and error handling as every other call — persist\n * or object-URL it caller-side.\n *\n * `GET /settlement/statements/{statementId}/pdf`\n *\n * @example\n * ```typescript\n * const pdf = await delopay.settlement.downloadStatementPdf('stmt_1', {\n * currency: 'EUR',\n * include_transactions: true,\n * });\n * const url = URL.createObjectURL(pdf);\n * ```\n */\n async downloadStatementPdf(\n statementId: string,\n params?: StatementPdfParams,\n options?: RequestExtras,\n ): Promise<Blob> {\n return this.request('GET', `/settlement/statements/${encodeURIComponent(statementId)}/pdf`, {\n query: {\n currency: params?.currency,\n include_transactions: params?.include_transactions,\n },\n responseType: 'blob',\n ...options,\n });\n }\n\n /**\n * The individual settled attempts of one shop's calendar month.\n *\n * `GET /settlement/lines`\n */\n async listLines(\n params: SettlementLineListParams,\n options?: RequestExtras,\n ): Promise<SettlementLineListResponse> {\n return this.request('GET', '/settlement/lines', {\n query: {\n profile_id: params.profile_id,\n year: params.year,\n month: params.month,\n test_mode: params.test_mode,\n limit: params.limit,\n offset: params.offset,\n },\n ...options,\n });\n }\n\n /**\n * The fee schedules that currently apply to a shop.\n *\n * `GET /settlement/fee-config`\n */\n async feeConfig(\n params: ShopFeeConfigParams,\n options?: RequestExtras,\n ): Promise<ShopFeeConfigResponse> {\n return this.request('GET', '/settlement/fee-config', {\n query: { profile_id: params.profile_id },\n ...options,\n });\n }\n\n /**\n * Enqueue a settlement-line backfill over historical attempts. Attempts\n * already covered by a line are always skipped.\n *\n * `POST /settlement/backfill`\n */\n async backfill(\n params?: SettlementBackfillRequest,\n options?: RequestExtras,\n ): Promise<SettlementBackfillResponse> {\n return this.request('POST', '/settlement/backfill', { body: params, ...options });\n }\n\n /**\n * Toggle whether a shop's owner can see their own settlement figures.\n *\n * `POST /settlement/shops/visibility`\n */\n async setShopVisibility(\n params: ShopVisibilityUpdateRequest,\n options?: RequestExtras,\n ): Promise<ShopVisibilityResponse> {\n return this.request('POST', '/settlement/shops/visibility', {\n body: params,\n ...options,\n });\n }\n\n /**\n * Manual adjustments recorded on a statement.\n *\n * `GET /settlement/statements/{statementId}/adjustments`\n */\n async listStatementAdjustments(\n statementId: string,\n options?: RequestExtras,\n ): Promise<StatementAdjustmentListResponse> {\n return this.request(\n 'GET',\n `/settlement/statements/${encodeURIComponent(statementId)}/adjustments`,\n options,\n );\n }\n\n /**\n * Add a manual adjustment to a statement. Positive `amount_usd` charges\n * the shop (reducing their payout); negative credits them.\n *\n * Subject to the caller's `settlement_adjustment` operation limit (amount\n * dimensions only): an over-limit call fails with `DE_01` and no adjustment\n * is added. A settlement rule can only block — approval is refund-only, for\n * the reason given on `updateStatementPayout()`.\n *\n * `POST /settlement/statements/{statementId}/adjustments`\n */\n async createStatementAdjustment(\n statementId: string,\n params: StatementAdjustmentCreateRequest,\n options?: RequestExtras,\n ): Promise<StatementAdjustment> {\n return this.request(\n 'POST',\n `/settlement/statements/${encodeURIComponent(statementId)}/adjustments`,\n { body: params, ...options },\n );\n }\n\n /**\n * Remove a manual adjustment from a statement.\n *\n * `DELETE /settlement/statements/{statementId}/adjustments/{adjustmentId}`\n */\n async deleteStatementAdjustment(\n statementId: string,\n adjustmentId: string,\n options?: RequestExtras,\n ): Promise<void> {\n return this.request(\n 'DELETE',\n `/settlement/statements/${encodeURIComponent(statementId)}/adjustments/${encodeURIComponent(adjustmentId)}`,\n options,\n );\n }\n}\n","import type {\n DecidePendingOperationRequest,\n OperationLimitRule,\n OperationLimitRuleDeleteResponse,\n OperationLimitRuleListParams,\n OperationLimitSettings,\n PendingOperation,\n PendingOperationListParams,\n PendingOperationListResponse,\n UpdateOperationLimitSettingsRequest,\n UpsertOperationLimitRuleRequest,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Per-operation spending limits: rules scoped to the merchant, a role or a\n * user, the merchant-level enforcement settings, and the approvals inbox.\n * Enforcement resolves the most specific rule: user > role > merchant.\n *\n * A rule set to `require_approval` does not refuse an over-limit operation —\n * it parks it. The original call fails with HTTP 409 `DE_06` carrying\n * `PendingApprovalErrorDetails`, and the operation runs only once a second\n * person approves the request through this inbox.\n *\n * **Refunds only.** Approval needs an executor that can run the operation\n * after the decision, and only refunds have one; the settlement operations\n * take `block` alone, which the request type enforces. So every request in\n * this inbox is a refund, and `DE_06` never comes back from a settlement\n * call — an over-limit settlement adjustment or payout fails with `DE_01`.\n */\nexport class OperationLimits {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * List the merchant's limit rules, optionally for one operation.\n *\n * `GET /operation-limits/rules`\n */\n async listRules(\n params?: OperationLimitRuleListParams,\n options?: RequestExtras,\n ): Promise<OperationLimitRule[]> {\n return this.request('GET', '/operation-limits/rules', {\n query: { operation: params?.operation },\n ...options,\n });\n }\n\n /**\n * Create or replace the limit rule for one target. Full-replace upsert:\n * absent limit fields clear that dimension.\n *\n * `PUT /operation-limits/rules`\n */\n async upsertRule(\n params: UpsertOperationLimitRuleRequest,\n options?: RequestExtras,\n ): Promise<OperationLimitRule> {\n return this.request('PUT', '/operation-limits/rules', { body: params, ...options });\n }\n\n /**\n * Delete a limit rule.\n *\n * `DELETE /operation-limits/rules/{ruleId}`\n */\n async deleteRule(\n ruleId: string,\n options?: RequestExtras,\n ): Promise<OperationLimitRuleDeleteResponse> {\n return this.request('DELETE', `/operation-limits/rules/${encodeURIComponent(ruleId)}`, options);\n }\n\n /**\n * The merchant-level enforcement settings. An untouched merchant gets the\n * defaults: rolling window, admins not exempt.\n *\n * `GET /operation-limits/settings`\n */\n async retrieveSettings(options?: RequestExtras): Promise<OperationLimitSettings> {\n return this.request('GET', '/operation-limits/settings', options);\n }\n\n /**\n * Update the enforcement settings. Only provided fields change.\n *\n * `PUT /operation-limits/settings`\n */\n async updateSettings(\n params: UpdateOperationLimitSettingsRequest,\n options?: RequestExtras,\n ): Promise<OperationLimitSettings> {\n return this.request('PUT', '/operation-limits/settings', { body: params, ...options });\n }\n\n /**\n * The approvals inbox: over-limit operations waiting on a second person.\n *\n * Both filters default rather than widen. With no `status` the list holds\n * **pending requests only** — approved, rejected and expired ones are\n * reachable only by asking for that status, so a history view must pass one\n * per status. With no `operation` it lists **refunds only**; the list is one\n * operation at a time. `limit` defaults to 100 and is clamped to 1–500.\n *\n * Requests past their `expires_at` are expired before the list is read, so\n * nothing here is shown as actionable when it is not.\n *\n * `GET /operation-limits/approvals`\n */\n async listApprovals(\n params?: PendingOperationListParams,\n options?: RequestExtras,\n ): Promise<PendingOperationListResponse> {\n return this.request('GET', '/operation-limits/approvals', {\n query: {\n operation: params?.operation,\n status: params?.status,\n limit: params?.limit,\n },\n ...options,\n });\n }\n\n /**\n * Approve a parked operation and execute it.\n *\n * Refused for the user who requested it, and for an approver whose own\n * limit would not have covered the operation — the permission is necessary\n * and not sufficient.\n *\n * Approval and execution are two facts. A request that was approved but\n * whose operation then failed comes back `approved` with `execution_error`\n * set and no `result_entity_id`; that is a real outcome, not a partial read.\n *\n * `POST /operation-limits/approvals/{id}/approve`\n */\n async approve(\n id: string,\n params: DecidePendingOperationRequest = {},\n options?: RequestExtras,\n ): Promise<PendingOperation> {\n return this.request('POST', `/operation-limits/approvals/${encodeURIComponent(id)}/approve`, {\n body: params,\n ...options,\n });\n }\n\n /**\n * Reject a parked operation. Nothing is executed and the request is closed.\n *\n * `POST /operation-limits/approvals/{id}/reject`\n */\n async reject(\n id: string,\n params: DecidePendingOperationRequest = {},\n options?: RequestExtras,\n ): Promise<PendingOperation> {\n return this.request('POST', `/operation-limits/approvals/${encodeURIComponent(id)}/reject`, {\n body: params,\n ...options,\n });\n }\n}\n","import type { MerchantRisk, ShopRisk } from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Stored shop risk indexes, per connector.\n *\n * Both reads return snapshots and never score on demand, so `computed_at` is\n * the age of the answer rather than the time of the call.\n *\n * The caller's own scope is what bounds the answer, and it is enforced\n * server-side: a profile-scoped role, or an API key pinned to one shop, gets\n * that shop from both endpoints and cannot read or enumerate a sibling's.\n */\nexport class Risk {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Every shop's stored risk for the caller's merchant, with the worst band\n * across them.\n *\n * `GET /risk`\n */\n async retrieve(options?: RequestExtras): Promise<MerchantRisk> {\n return this.request('GET', '/risk', options);\n }\n\n /**\n * One shop's stored risk index per connector.\n *\n * `GET /risk/shops/{profileId}`\n */\n async retrieveShop(profileId: string, options?: RequestExtras): Promise<ShopRisk> {\n return this.request('GET', `/risk/shops/${encodeURIComponent(profileId)}`, options);\n }\n}\n","import { DelopayError, DelopayAuthenticationError } from './error';\nimport { ApiKeys } from './resources/apiKeys';\nimport { Authentication } from './resources/authentication';\nimport { Billing } from './resources/billing';\nimport { Blocklist } from './resources/blocklist';\nimport { Connectors } from './resources/connectors';\nimport { Customers } from './resources/customers';\nimport { Disputes } from './resources/disputes';\nimport { EphemeralKeys } from './resources/ephemeralKeys';\nimport { Events } from './resources/events';\nimport { Fees } from './resources/fees';\nimport { Mandates } from './resources/mandates';\nimport { MerchantAccounts } from './resources/merchantAccounts';\nimport { PaymentLinks } from './resources/paymentLinks';\nimport { PaymentMethods } from './resources/paymentMethods';\nimport { Payments } from './resources/payments';\nimport { Payouts } from './resources/payouts';\nimport { Poll } from './resources/poll';\nimport { ProfileAcquirers } from './resources/profileAcquirers';\nimport { Profiles } from './resources/profiles';\nimport { Projects } from './resources/projects';\nimport { Refunds } from './resources/refunds';\nimport { Relay } from './resources/relay';\nimport { Routing } from './resources/routing';\nimport { Search } from './resources/search';\nimport { Shops } from './resources/shops';\nimport { StripeConnect } from './resources/stripeConnect';\nimport { ThreeDsRules } from './resources/threeDsRules';\nimport { Users } from './resources/users';\nimport { Verification } from './resources/verification';\nimport { Webhooks } from './resources/webhooks';\nimport type { TokenResponse } from './types';\nimport { Analytics } from './resources/analytics';\nimport { AnalyticsDashboard } from './resources/analyticsDashboard';\nimport { Cards } from './resources/cards';\nimport { Export } from './resources/export';\nimport { FeatureMatrix } from './resources/featureMatrix';\nimport { Files } from './resources/files';\nimport { Forex } from './resources/forex';\nimport { Regions } from './resources/regions';\nimport { AvailabilityOverrides } from './resources/availabilityOverrides';\nimport { Subscriptions } from './resources/subscriptions';\nimport { Audit } from './resources/audit';\nimport { Settlement } from './resources/settlement';\nimport { OperationLimits } from './resources/operationLimits';\nimport { Risk } from './resources/risk';\n\nconst PRODUCTION_URL = 'https://api.delopay.net';\nconst SANDBOX_URL = 'https://sandbox.delopay.net';\n\nconst MAX_RAW_BODY_BYTES = 2048;\nconst MAX_RETRY_AFTER_MS = 30_000;\n\nfunction parseRetryAfter(header: string | null): number | null {\n if (!header) return null;\n const trimmed = header.trim();\n const seconds = Number(trimmed);\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.min(seconds * 1000, MAX_RETRY_AFTER_MS);\n }\n const date = Date.parse(trimmed);\n if (Number.isFinite(date)) {\n const delta = date - Date.now();\n return delta > 0 ? Math.min(delta, MAX_RETRY_AFTER_MS) : 0;\n }\n return null;\n}\n\nfunction truncateRawBody(raw: string): string | undefined {\n if (!raw) return undefined;\n return raw.length > MAX_RAW_BODY_BYTES ? raw.slice(0, MAX_RAW_BODY_BYTES) + '…' : raw;\n}\n\nfunction findIdempotencyKey(headers: Record<string, string>): string | undefined {\n for (const [k, v] of Object.entries(headers)) {\n if (k.toLowerCase() === 'idempotency-key') return v;\n }\n return undefined;\n}\n\ninterface CombinedSignal {\n signal: AbortSignal;\n dispose: () => void;\n}\n\nfunction noop(): void {\n // Intentionally empty: no listeners registered, nothing to clean up.\n}\n\nfunction combineSignals(signals: AbortSignal[]): CombinedSignal {\n const controller = new AbortController();\n const listeners: { signal: AbortSignal; handler: () => void }[] = [];\n const dispose = () => {\n for (const { signal, handler } of listeners) {\n signal.removeEventListener('abort', handler);\n }\n listeners.length = 0;\n };\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n dispose();\n return { signal: controller.signal, dispose: noop };\n }\n const handler = () => {\n controller.abort(signal.reason);\n dispose();\n };\n signal.addEventListener('abort', handler, { once: true });\n listeners.push({ signal, handler });\n }\n return { signal: controller.signal, dispose };\n}\n\n/**\n * Events emitted by the debug logger.\n * - `request` — about to send a request (`method`, `url`, `path`)\n * - `response` — response received (`status`, `method`, `path`, `requestId?`)\n * - `retry` — about to retry after a transient failure (`attempt`, `maxRetries`, `method`, `path`)\n */\nexport type DelopayLogger = (\n event: 'request' | 'response' | 'retry',\n data: Record<string, unknown>,\n) => void;\n\n/**\n * Configuration options for the Delopay client.\n */\nexport interface DelopayOptions {\n /** Use the sandbox environment (`https://sandbox.delopay.net`). Defaults to `false` (production). */\n sandbox?: boolean;\n /** Override the base URL entirely. Takes precedence over `sandbox`. */\n baseUrl?: string;\n /** Request timeout in milliseconds. Defaults to `30000` (30 seconds). */\n timeout?: number;\n /**\n * Maximum number of automatic retries for transient failures (5xx, timeout, network errors).\n * Retries use exponential backoff. Set to `0` to disable. Defaults to `2`.\n * Only idempotent-safe requests (GET, DELETE, and requests with an `Idempotency-Key` header) are retried.\n */\n maxRetries?: number;\n /** Enable debug logging of requests and responses. Defaults to `false`. */\n debug?: boolean;\n /**\n * Custom logger for debug events (`request`, `response`, `retry`). When omitted,\n * debug output is written to `console.log`. Has no effect unless `debug` is `true`.\n * Useful for routing SDK logs through pino, winston, or similar structured loggers.\n */\n logger?: DelopayLogger;\n}\n\nconst SENSITIVE_QUERY_KEYS = new Set([\n 'client_secret',\n 'ephemeral_key',\n 'api_key',\n 'publishable_key',\n]);\n\n/**\n * Return a copy of `url` with the values of known-sensitive query parameters\n * replaced by `REDACTED`, leaving the rest of the query string intact.\n * Used only to sanitize URLs before they hit debug logs.\n */\nfunction redactUrlForLogging(url: string): string {\n const qIdx = url.indexOf('?');\n if (qIdx === -1) return url;\n const base = url.slice(0, qIdx);\n const query = url.slice(qIdx + 1);\n const parts = query.split('&').map((pair) => {\n const eqIdx = pair.indexOf('=');\n if (eqIdx === -1) return pair;\n const key = pair.slice(0, eqIdx);\n if (SENSITIVE_QUERY_KEYS.has(decodeURIComponent(key).toLowerCase())) {\n return `${key}=REDACTED`;\n }\n return pair;\n });\n return `${base}?${parts.join('&')}`;\n}\n\n/**\n * Low-level options forwarded to a single HTTP request.\n */\nexport interface RequestOptions {\n /** Request body, serialised as JSON. */\n body?: unknown;\n /**\n * Query-string parameters. `undefined` and `null` values are omitted.\n * Array values are emitted as repeated keys (`?tag=a&tag=b`) — not comma-joined.\n */\n query?: Record<\n string,\n string | number | boolean | null | undefined | (string | number | boolean)[]\n >;\n /** Additional HTTP headers merged with the default `api-key` header. */\n headers?: Record<string, string>;\n /** Override the client-level timeout for this request, in milliseconds. */\n timeout?: number;\n /**\n * Caller-provided `AbortSignal`. Aborting it cancels the in-flight request and rejects\n * with a `DelopayError` carrying code `'ABORTED'`. Combined with the per-request timeout.\n */\n signal?: AbortSignal;\n /**\n * How to decode a 2xx response body. `'json'` (the default) parses JSON;\n * `'blob'` / `'arraybuffer'` return the raw bytes for binary endpoints\n * such as PDF exports. Error responses are always decoded as JSON and\n * thrown as `DelopayError` regardless of this setting.\n */\n responseType?: 'json' | 'blob' | 'arraybuffer';\n /**\n * Pass `keepalive: true` to let the request outlive its page — e.g.\n * telemetry sent while the document is navigating away. Browsers cap\n * keepalive request bodies at ~64 KiB and reject larger ones.\n */\n keepalive?: boolean;\n}\n\nexport type RequestFn = <T>(method: string, path: string, options?: RequestOptions) => Promise<T>;\n\n/**\n * Per-call options that resource methods accept as an optional final argument:\n * extra HTTP headers (e.g. `Idempotency-Key`), a per-request timeout override,\n * and an `AbortSignal` for cancellation.\n */\nexport type RequestExtras = Pick<RequestOptions, 'headers' | 'timeout' | 'signal'>;\n\n/**\n * Delopay API client.\n *\n * Instantiate once with your API key and reuse across your application.\n * All resource sub-clients (payments, refunds, customers, …) are exposed\n * as properties on the instance.\n *\n * @example\n * ```typescript\n * const delopay = new Delopay('prd_...', { sandbox: false });\n * const payment = await delopay.payments.create({ amount: 5000, currency: 'EUR' });\n * ```\n */\nexport class Delopay {\n /** Utility for verifying incoming webhook signatures (static, no instance needed). */\n static webhooks = Webhooks;\n\n /** The resolved base URL used for all API requests. */\n readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly debug: boolean;\n private readonly logger?: DelopayLogger;\n private jwtToken?: string;\n\n // Merchant-facing\n readonly payments: Payments;\n readonly refunds: Refunds;\n readonly customers: Customers;\n readonly paymentMethods: PaymentMethods;\n readonly paymentLinks: PaymentLinks;\n readonly mandates: Mandates;\n readonly disputes: Disputes;\n readonly payouts: Payouts;\n readonly ephemeralKeys: EphemeralKeys;\n readonly events: Events;\n readonly poll: Poll;\n\n // Connector / routing\n readonly connectors: Connectors;\n readonly routing: Routing;\n readonly profiles: Profiles;\n readonly shops: Shops;\n readonly profileAcquirers: ProfileAcquirers;\n\n // Authentication & verification\n readonly authentication: Authentication;\n readonly verification: Verification;\n\n // Dashboard / internal\n readonly users: Users;\n readonly apiKeys: ApiKeys;\n readonly billing: Billing;\n readonly blocklist: Blocklist;\n readonly fees: Fees;\n readonly merchantAccounts: MerchantAccounts;\n readonly projects: Projects;\n readonly relay: Relay;\n readonly stripeConnect: StripeConnect;\n readonly threeDsRules: ThreeDsRules;\n /**\n * A merchant's own audit log. Needs a dashboard JWT, not an API key —\n * see {@link Audit}.\n */\n readonly audit: Audit;\n readonly settlement: Settlement;\n readonly operationLimits: OperationLimits;\n readonly risk: Risk;\n\n // New resources (Phases 3-4)\n readonly subscriptions: Subscriptions;\n readonly files: Files;\n readonly export: Export;\n readonly forex: Forex;\n readonly regions: Regions;\n readonly availabilityOverrides: AvailabilityOverrides;\n readonly analytics: Analytics;\n readonly analyticsDashboard: AnalyticsDashboard;\n readonly featureMatrix: FeatureMatrix;\n readonly cards: Cards;\n readonly search: Search;\n\n /**\n * Create a new Delopay client.\n *\n * @param apiKey - Your Delopay API key (e.g. `prd_...` or `snd_...`).\n * Pass an empty string or omit for JWT-only usage (e.g. dashboard apps).\n * @param options - Optional configuration (sandbox mode, base URL override, timeout).\n */\n constructor(apiKey?: string, options?: DelopayOptions) {\n this.apiKey = apiKey ?? '';\n this.timeout = options?.timeout ?? 30_000;\n this.maxRetries = options?.maxRetries ?? 2;\n this.debug = options?.debug ?? false;\n if (options?.logger !== undefined) this.logger = options.logger;\n\n if (options?.baseUrl !== undefined) {\n this.baseUrl = options.baseUrl;\n } else if (options?.sandbox) {\n this.baseUrl = SANDBOX_URL;\n } else {\n this.baseUrl = PRODUCTION_URL;\n }\n\n const request = this.request.bind(this) as RequestFn;\n\n // JWT auth methods are defined below (setJwtToken / clearJwtToken)\n\n // Merchant-facing\n this.payments = new Payments(request);\n this.refunds = new Refunds(request);\n this.customers = new Customers(request);\n this.paymentMethods = new PaymentMethods(request);\n this.paymentLinks = new PaymentLinks(request);\n this.mandates = new Mandates(request);\n this.disputes = new Disputes(request);\n this.payouts = new Payouts(request);\n this.ephemeralKeys = new EphemeralKeys(request);\n this.events = new Events(request);\n this.poll = new Poll(request);\n\n // Connector / routing\n this.connectors = new Connectors(request);\n this.routing = new Routing(request);\n this.profiles = new Profiles(request);\n this.shops = new Shops(request);\n this.profileAcquirers = new ProfileAcquirers(request);\n\n // Authentication & verification\n this.authentication = new Authentication(request);\n this.verification = new Verification(request);\n\n // Dashboard / internal\n this.users = new Users(request);\n this.apiKeys = new ApiKeys(request);\n this.billing = new Billing(request);\n this.blocklist = new Blocklist(request);\n this.fees = new Fees(request);\n this.merchantAccounts = new MerchantAccounts(request);\n this.projects = new Projects(request);\n this.relay = new Relay(request);\n this.stripeConnect = new StripeConnect(request);\n this.threeDsRules = new ThreeDsRules(request);\n this.audit = new Audit(request);\n this.settlement = new Settlement(request);\n this.operationLimits = new OperationLimits(request);\n this.risk = new Risk(request);\n\n // New resources (Phases 3-4)\n this.subscriptions = new Subscriptions(request);\n this.files = new Files(request);\n this.export = new Export(request);\n this.forex = new Forex(request);\n this.regions = new Regions(request);\n this.availabilityOverrides = new AvailabilityOverrides(request);\n this.analytics = new Analytics(request);\n this.analyticsDashboard = new AnalyticsDashboard(request);\n this.featureMatrix = new FeatureMatrix(request);\n this.cards = new Cards(request);\n this.search = new Search(request);\n }\n\n /**\n * Set a JWT token for subsequent requests.\n * When set, requests use `Authorization: Bearer <token>` instead of `api-key`.\n * Useful after `users.signIn()` returns a JWT for dashboard operations.\n */\n setJwtToken(token: string): void {\n this.jwtToken = token;\n }\n\n /**\n * Clear the JWT token, reverting to API key authentication.\n */\n clearJwtToken(): void {\n this.jwtToken = undefined;\n }\n\n /**\n * Refresh the current login JWT (see {@link Users.refreshToken}) and\n * apply the fresh token to this client, so subsequent requests use it.\n * Returns the fresh token for the caller to persist (e.g. session\n * storage) — the backend has already re-set the `login_token` cookie.\n *\n * If the client's auth state changes while the refresh is pending —\n * `clearJwtToken()` on sign-out, or `setJwtToken()` switching to another\n * session — the stale completion is discarded and this rejects with a\n * `session_changed` `DelopayError` (status 0), so the explicit change\n * wins and the caller never persists a token for a session that is gone.\n *\n * Otherwise throws like any other request; in particular a 401 means the\n * session is dead (expired/blacklisted/revoked), a 429 means a refresh\n * was already minted for this session within the last minute, and a 400\n * means this token has no revocable session to slide (no `jti` — team\n * impersonation is the case in practice) and can never be refreshed,\n * though it stays valid for ordinary calls.\n */\n async refreshSession(): Promise<TokenResponse> {\n const originatingToken = this.jwtToken;\n const response = await this.users.refreshToken();\n if (this.jwtToken !== originatingToken) {\n throw new DelopayError(\n 'Auth state changed while the refresh was pending; refreshed token discarded',\n {\n status: 0,\n code: 'session_changed',\n type: 'session_changed',\n },\n );\n }\n this.setJwtToken(response.token);\n return response;\n }\n\n /**\n * Make a raw HTTP request to the Delopay API.\n *\n * You rarely need to call this directly — prefer the typed resource methods.\n * Use it only for endpoints not yet covered by a resource class.\n *\n * @param method - HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`).\n * @param path - API path starting with `/` (e.g. `/payments`).\n * @param options - Optional body, query parameters, and headers.\n * @returns Parsed JSON response body typed as `T`.\n * @throws {DelopayAuthenticationError} On 401 responses.\n * @throws {DelopayError} On all other non-2xx responses, timeouts, and network errors.\n */\n async request<T>(method: string, path: string, options?: RequestOptions): Promise<T> {\n let url = `${this.baseUrl}${path}`;\n\n if (options?.query) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(options.query)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n if (v !== undefined && v !== null) params.append(key, String(v));\n }\n } else {\n params.set(key, String(value));\n }\n }\n const qs = params.toString();\n if (qs) {\n url += `?${qs}`;\n }\n }\n\n const headers: Record<string, string> = {\n ...(this.jwtToken\n ? { Authorization: `Bearer ${this.jwtToken}` }\n : this.apiKey\n ? { 'api-key': this.apiKey }\n : {}),\n ...options?.headers,\n };\n\n // FormData / Blob / ArrayBuffer / URLSearchParams pass through unchanged so callers\n // can send multipart uploads. The runtime (browser or Node 18+ fetch) sets the\n // appropriate Content-Type including the multipart boundary, so we don't touch it.\n const isRawBody =\n options?.body !== undefined &&\n options?.body !== null &&\n (options.body instanceof FormData ||\n options.body instanceof Blob ||\n options.body instanceof ArrayBuffer ||\n options.body instanceof URLSearchParams);\n\n if (options?.body && !isRawBody) {\n headers['Content-Type'] = 'application/json';\n }\n\n const idempotencyKey = findIdempotencyKey(headers)?.trim();\n const isRetryable =\n method === 'GET' ||\n method === 'DELETE' ||\n (idempotencyKey !== undefined && idempotencyKey !== '');\n\n // Serialize body once so circular-reference errors surface immediately and big payloads\n // aren't re-stringified on every retry attempt. Raw bodies pass through untouched.\n let serializedBody: BodyInit | undefined;\n if (isRawBody) {\n serializedBody = options?.body as BodyInit;\n } else if (options?.body) {\n serializedBody = JSON.stringify(options.body);\n }\n\n const callerSignal = options?.signal;\n if (callerSignal?.aborted) {\n throw new DelopayError('Request aborted', {\n status: 0,\n code: 'ABORTED',\n type: 'abort_error',\n });\n }\n\n const timeoutMs = options?.timeout ?? this.timeout;\n\n let lastError: unknown;\n let retryAfterOverrideMs: number | null = null;\n\n const safeUrl = () => redactUrlForLogging(url);\n const emit = (event: 'request' | 'response' | 'retry', data: Record<string, unknown>) => {\n if (!this.debug) return;\n if (this.logger) {\n this.logger(event, data);\n return;\n }\n if (event === 'request')\n console.log(`[delopay] ${data.method as string} ${data.url as string}`);\n else if (event === 'response')\n console.log(\n `[delopay] ${data.status as number} ${data.method as string} ${data.path as string}`,\n );\n else\n console.log(\n `[delopay] retry ${data.attempt as number}/${data.maxRetries as number} ${data.method as string} ${data.path as string}`,\n );\n };\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n const base = Math.min(500 * 2 ** (attempt - 1), 5000);\n // Full jitter: pick uniformly in [0, base) to avoid synchronized retry storms.\n const jittered = Math.random() * base;\n const delay = Math.max(retryAfterOverrideMs ?? 0, jittered);\n retryAfterOverrideMs = null;\n await new Promise((resolve) => setTimeout(resolve, delay));\n emit('retry', { attempt, maxRetries: this.maxRetries, method, path });\n }\n\n const timeoutCtrl = new AbortController();\n const timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);\n const combined = combineSignals(\n callerSignal ? [timeoutCtrl.signal, callerSignal] : [timeoutCtrl.signal],\n );\n\n try {\n emit('request', { method, url: safeUrl(), path });\n\n const response = await fetch(url, {\n method,\n headers,\n body: serializedBody,\n signal: combined.signal,\n ...(options?.keepalive !== undefined ? { keepalive: options.keepalive } : {}),\n });\n\n const requestId =\n response.headers?.get('x-request-id') ?? response.headers?.get('x-trace-id') ?? undefined;\n\n emit('response', { status: response.status, method, path, requestId });\n\n if (!response.ok) {\n const rawBody = await response.text().catch(() => '');\n let parsed: Record<string, unknown> = {};\n if (rawBody) {\n try {\n parsed = JSON.parse(rawBody) as Record<string, unknown>;\n } catch {\n // non-JSON error body (HTML from a proxy, truncated stream, etc.) — keep raw\n }\n }\n // API wraps errors as { error: { message, code, type, data? } } — unwrap if present\n const err = (parsed.error as Record<string, unknown>) ?? parsed;\n const message =\n (err.message as string) ?? `Request failed with status ${response.status}`;\n const code = (err.code as string) ?? '';\n const type = (err.error_type as string) ?? (err.type as string) ?? '';\n const data =\n err.data && typeof err.data === 'object' && !Array.isArray(err.data)\n ? (err.data as Record<string, unknown>)\n : undefined;\n const truncatedRaw = truncateRawBody(rawBody);\n\n // A 401 usually means OUR credential (API key / JWT) was rejected —\n // but connector-passthrough errors (`CE_*` / type \"connector\", e.g.\n // a PSP rejecting the merchant's stored Stripe key) propagate the\n // upstream status and are NOT a Delopay authentication failure, so\n // they stay a plain DelopayError instead of triggering the\n // \"re-authenticate\" handling dashboards attach to auth errors.\n const isConnectorPassthrough = type === 'connector' || code.startsWith('CE_');\n if (response.status === 401 && !isConnectorPassthrough) {\n throw new DelopayAuthenticationError(message, {\n code,\n type,\n requestId,\n rawBody: truncatedRaw,\n data,\n });\n }\n\n const error = new DelopayError(message, {\n status: response.status,\n code,\n type,\n requestId,\n rawBody: truncatedRaw,\n data,\n });\n\n // Retry on 5xx and 429 (rate limit). 4xx other than 429 are not transient.\n const isTransientStatus = response.status >= 500 || response.status === 429;\n if (isTransientStatus && isRetryable && attempt < this.maxRetries) {\n if (response.status === 429) {\n retryAfterOverrideMs = parseRetryAfter(response.headers?.get('retry-after') ?? null);\n }\n lastError = error;\n continue;\n }\n\n throw error;\n }\n\n if (options?.responseType === 'blob') {\n return (await response.blob()) as T;\n }\n if (options?.responseType === 'arraybuffer') {\n return (await response.arrayBuffer()) as T;\n }\n const text = await response.text();\n return (text ? JSON.parse(text) : undefined) as T;\n } catch (err) {\n if (err instanceof DelopayError || err instanceof DelopayAuthenticationError) {\n throw err;\n }\n if (err instanceof Error && err.name === 'AbortError') {\n if (callerSignal?.aborted) {\n throw new DelopayError('Request aborted', {\n status: 0,\n code: 'ABORTED',\n type: 'abort_error',\n });\n }\n lastError = new DelopayError('Request timed out', {\n status: 0,\n code: 'TIMEOUT',\n type: 'timeout_error',\n });\n if (isRetryable && attempt < this.maxRetries) continue;\n throw lastError;\n }\n if (err instanceof TypeError) {\n lastError = new DelopayError(`Network error: ${err.message}`, {\n status: 0,\n code: 'NETWORK',\n type: 'network_error',\n });\n if (isRetryable && attempt < this.maxRetries) continue;\n throw lastError;\n }\n throw err;\n } finally {\n clearTimeout(timeoutId);\n combined.dispose();\n }\n }\n\n throw lastError;\n }\n\n /**\n * Auto-paginate a list endpoint. Yields items one by one, fetching\n * the next page automatically when the current one is exhausted.\n *\n * Delopay list endpoints use one of two pagination styles, so this helper\n * supports both:\n * - **Offset** (default) — for endpoints like `customers.list` that accept\n * `offset`/`limit`. Each page advances `offset` by the number of items returned.\n * - **Cursor** — for endpoints like `payments.list` and `payouts.list` that page\n * with `starting_after`/`limit` (they ignore `offset`). Pass a `cursor` extractor\n * that returns the id of an item; the next page is requested with\n * `starting_after` set to the last item's id.\n *\n * @param listFn - A function that takes the paging params and returns `{ data: T[] }` or `T[]`.\n * @param params - Additional parameters to pass to every page request.\n * @param options - Page size (number) for offset mode, or `{ pageSize?, cursor? }`.\n * Provide `cursor` to switch to cursor pagination.\n *\n * @example\n * ```typescript\n * // Offset endpoint (customers):\n * for await (const c of delopay.paginate((p) => delopay.customers.list(p))) {\n * console.log(c.customer_id);\n * }\n *\n * // Cursor endpoint (payments): extract the id used as the next cursor.\n * for await (const payment of delopay.paginate(\n * (p) => delopay.payments.list(p),\n * undefined,\n * { cursor: (p) => p.payment_id },\n * )) {\n * console.log(payment.payment_id);\n * }\n * ```\n */\n async *paginate<T, P extends Record<string, unknown>>(\n listFn: (\n params: P & { limit: number; offset?: number; starting_after?: string },\n ) => Promise<{ data: T[] } | T[]>,\n params?: P,\n options?: number | { pageSize?: number; cursor?: (item: T) => string | undefined },\n ): AsyncGenerator<T> {\n const pageSize = typeof options === 'number' ? options : (options?.pageSize ?? 50);\n const cursorOf = typeof options === 'object' ? options.cursor : undefined;\n let offset = 0;\n let after: string | undefined;\n while (true) {\n const page = { ...((params ?? {}) as P), limit: pageSize } as P & {\n limit: number;\n offset?: number;\n starting_after?: string;\n };\n if (cursorOf) {\n if (after !== undefined) page.starting_after = after;\n } else {\n page.offset = offset;\n }\n const result = await listFn(page);\n const items = Array.isArray(result) ? result : result.data;\n if (items.length === 0) break;\n for (const item of items) {\n yield item;\n }\n if (items.length < pageSize) break;\n if (cursorOf) {\n const last = items[items.length - 1];\n if (last === undefined) break;\n after = cursorOf(last);\n if (after === undefined) break;\n } else {\n offset += items.length;\n }\n }\n }\n}\n","import type {\n Connector,\n Currency,\n EuclidComparison,\n EuclidComparisonType,\n EuclidIfStatement,\n EuclidValue,\n PaymentMethod,\n PlatformFeeKind,\n PlatformFeeOutput,\n PlatformFeeProgram,\n PlatformFeeRule,\n} from './types';\n\n/** A single condition leaf in the builder's condition tree. */\nexport interface LeafNode {\n kind: 'leaf';\n lhs: string;\n comparison: EuclidComparisonType;\n value: EuclidValue;\n}\n\n/** An AND (`all`) or OR (`any`) group of condition nodes. */\nexport interface GroupNode {\n kind: 'all' | 'any';\n children: ConditionNode[];\n}\n\nexport type ConditionNode = LeafNode | GroupNode;\n\n/**\n * A condition leaf. Numeric values (amount, merchant_volume) tag as `number`;\n * string values (payment_method, connector, currency, card_network) tag as\n * `enum_variant`.\n */\nexport function leaf(\n lhs: string,\n comparison: EuclidComparisonType,\n value: string | number,\n): LeafNode {\n const tagged: EuclidValue =\n typeof value === 'number' ? { type: 'number', value } : { type: 'enum_variant', value };\n return { kind: 'leaf', lhs, comparison, value: tagged };\n}\n\n/** AND group — all children must match. */\nexport function allOf(...children: ConditionNode[]): GroupNode {\n return { kind: 'all', children };\n}\n\n/** OR group — any child matching is enough. */\nexport function anyOf(...children: ConditionNode[]): GroupNode {\n return { kind: 'any', children };\n}\n\n/**\n * How a rule (or the default) prices a transaction. `fee_type` is inferred:\n * percentage-only → `percentage`, flat-only → `flat`, both → `combined`.\n */\nexport interface FeeSpecInput {\n /** Percentage fee, e.g. `2.5` means 2.5%. */\n percentage?: number;\n /** Flat fee in minor units. */\n flat?: number;\n /** ISO 4217 currency for the flat fee. */\n flatCurrency?: string;\n /** Clamp floor in minor units. */\n min?: number;\n /** Clamp ceiling in minor units. */\n max?: number;\n}\n\n/**\n * Friendly conditions for a rule. Every provided key becomes one condition and\n * they are ANDed together. For dimensions not covered here (payment-method-type\n * keys like `crypto`/`wallet`, metadata, value arrays) use `rawConditions`.\n */\nexport interface FeeRuleConditions {\n paymentMethod?: PaymentMethod;\n connector?: Connector;\n currency?: Currency;\n cardNetwork?: string;\n /**\n * Customer billing-address country. Must be the exact backend `Country` enum\n * variant (PascalCase full name, e.g. `Germany`/`UnitedStatesOfAmerica`), not\n * an ISO code — the engine lowers `billing_country` via case-sensitive\n * `from_str`.\n */\n billingCountry?: string;\n /** `amount == n` (minor units). */\n amountEquals?: number;\n /** `amount > n` (minor units). */\n amountGreaterThan?: number;\n /** `amount < n` (minor units). */\n amountLessThan?: number;\n /**\n * `merchant_volume == n` — the merchant's previous-month volume snapshot\n * (USD minor units). Combine with any other condition, e.g.\n * `{ paymentMethod: 'crypto', merchantVolumeGreaterThan: 1_000_000 }`.\n */\n merchantVolumeEquals?: number;\n /** `merchant_volume > n` (USD minor units). */\n merchantVolumeGreaterThan?: number;\n /** `merchant_volume < n` (USD minor units). */\n merchantVolumeLessThan?: number;\n}\n\nexport interface FeeRuleInput {\n name: string;\n /** Friendly conditions (ANDed). Omit for an always-matching rule (prefer `otherwise`). */\n when?: FeeRuleConditions;\n /** Extra raw conditions ANDed in, for dimensions `when` does not cover. */\n rawConditions?: EuclidComparison[];\n /** Nested AND/OR condition tree. Mutually exclusive with `when`/`rawConditions`. */\n match?: ConditionNode;\n fee: FeeSpecInput;\n}\n\nfunction toFeeOutput(spec: FeeSpecInput): PlatformFeeOutput {\n const hasPct = spec.percentage != null;\n const hasFlat = spec.flat != null;\n const feeType: PlatformFeeKind = hasPct && hasFlat ? 'combined' : hasFlat ? 'flat' : 'percentage';\n return {\n fee_type: feeType,\n percentage_fee: spec.percentage ?? null,\n flat_fee_amount: spec.flat ?? null,\n flat_fee_currency: spec.flatCurrency ?? null,\n min_fee_amount: spec.min ?? null,\n max_fee_amount: spec.max ?? null,\n };\n}\n\nfunction enumCondition(lhs: string, value: string): EuclidComparison {\n return { lhs, comparison: 'equal', value: { type: 'enum_variant', value }, metadata: {} };\n}\n\nfunction numberCondition(\n lhs: string,\n comparison: EuclidComparisonType,\n value: number,\n): EuclidComparison {\n return { lhs, comparison, value: { type: 'number', value }, metadata: {} };\n}\n\nfunction buildConditions(\n when: FeeRuleConditions = {},\n raw: EuclidComparison[] = [],\n): EuclidComparison[] {\n const out: EuclidComparison[] = [];\n if (when.paymentMethod != null) out.push(enumCondition('payment_method', when.paymentMethod));\n if (when.connector != null) out.push(enumCondition('connector', when.connector));\n if (when.currency != null) out.push(enumCondition('currency', when.currency));\n if (when.cardNetwork != null) out.push(enumCondition('card_network', when.cardNetwork));\n if (when.billingCountry != null) out.push(enumCondition('billing_country', when.billingCountry));\n if (when.amountEquals != null) out.push(numberCondition('amount', 'equal', when.amountEquals));\n if (when.amountGreaterThan != null) {\n out.push(numberCondition('amount', 'greater_than', when.amountGreaterThan));\n }\n if (when.amountLessThan != null) {\n out.push(numberCondition('amount', 'less_than', when.amountLessThan));\n }\n if (when.merchantVolumeEquals != null) {\n out.push(numberCondition('merchant_volume', 'equal', when.merchantVolumeEquals));\n }\n if (when.merchantVolumeGreaterThan != null) {\n out.push(numberCondition('merchant_volume', 'greater_than', when.merchantVolumeGreaterThan));\n }\n if (when.merchantVolumeLessThan != null) {\n out.push(numberCondition('merchant_volume', 'less_than', when.merchantVolumeLessThan));\n }\n out.push(...raw);\n return out;\n}\n\nfunction leafToComparison(node: LeafNode): EuclidComparison {\n return { lhs: node.lhs, comparison: node.comparison, value: node.value, metadata: {} };\n}\n\n/**\n * Flatten associativity (nested all-in-all / any-in-any) and collapse\n * single-child groups, so every group child of an `all` is an `any`.\n * @internal\n */\nexport function normalizeNode(node: ConditionNode): ConditionNode {\n if (node.kind === 'leaf') return node;\n const children = node.children.map(normalizeNode);\n const flat: ConditionNode[] = [];\n for (const c of children) {\n if (c.kind === node.kind) flat.push(...c.children);\n else flat.push(c);\n }\n if (flat.length === 1) return flat[0];\n return { kind: node.kind, children: flat };\n}\n\nfunction toStatement(node: ConditionNode): EuclidIfStatement {\n if (node.kind === 'leaf') return { condition: [leafToComparison(node)], nested: null };\n // Unreachable via current callers (encodeStatements strips top-level any); kept for totality.\n if (node.kind === 'any') {\n return { condition: [], nested: node.children.map(toStatement) };\n }\n // 'all': after normalize, group children are all 'any'.\n const leaves = node.children.filter((c): c is LeafNode => c.kind === 'leaf');\n const groups = node.children.filter((c): c is GroupNode => c.kind !== 'leaf');\n const condition = leaves.map(leafToComparison);\n if (groups.length === 0) return { condition, nested: null };\n const [first, ...rest] = groups;\n // `first` is an OR; AND each of its branches with the remaining OR groups.\n const nested = first.children.map((branch) => toStatement(normalizeNode(allOf(branch, ...rest))));\n return { condition, nested };\n}\n\nfunction assertNoEmptyAnyOf(node: ConditionNode): void {\n if (node.kind === 'leaf') return;\n if (node.kind === 'any' && node.children.length === 0) {\n throw new Error('feeProgram: an anyOf() group must have at least one condition');\n }\n node.children.forEach(assertNoEmptyAnyOf);\n}\n\n/**\n * Encode a rule's match (a condition tree) into the engine's `statements[]`.\n * A top-level OR spreads across statements; anything else is a single statement.\n * @internal\n */\nexport function encodeStatements(match: ConditionNode): EuclidIfStatement[] {\n const m = normalizeNode(match);\n if (m.kind === 'any') return m.children.map(toStatement);\n return [toStatement(m)];\n}\n\nfunction comparisonToLeaf(c: EuclidComparison): LeafNode {\n return { kind: 'leaf', lhs: c.lhs, comparison: c.comparison, value: c.value };\n}\n\nfunction statementToNode(stmt: EuclidIfStatement): ConditionNode {\n const leaves = stmt.condition.map(comparisonToLeaf);\n if (stmt.nested && stmt.nested.length > 0) {\n const orNode = anyOf(...stmt.nested.map(statementToNode));\n if (leaves.length === 0) return orNode;\n return allOf(...leaves, orNode);\n }\n return leaves.length === 1 ? leaves[0] : allOf(...leaves);\n}\n\n/**\n * Decode a rule's `statements[]` back into a condition tree.\n *\n * Returns a tree that is **logically equivalent** to the source. It is\n * deep-equal to `normalizeNode(input)` only when no `all` group contains two\n * or more `any` groups; where the encoder distributed AND over OR, the decoded\n * shape differs (still equivalent).\n */\nexport function ruleMatchToTree(statements: EuclidIfStatement[]): ConditionNode {\n if (statements.length === 1) return normalizeNode(statementToNode(statements[0]));\n return normalizeNode(anyOf(...statements.map(statementToNode)));\n}\n\n/**\n * Decode a stored program into the builder's editable model.\n *\n * Returns a tree that is **logically equivalent** to the source. It is\n * deep-equal to `normalizeNode(input)` only when no `all` group contains two\n * or more `any` groups; where the encoder distributed AND over OR, the decoded\n * shape differs (still equivalent).\n */\nexport function programToTree(program: PlatformFeeProgram): {\n rules: { name: string; match: ConditionNode; fee: PlatformFeeOutput | null }[];\n otherwise: PlatformFeeOutput | null;\n} {\n return {\n rules: program.rules.map((r) => ({\n name: r.name,\n match: ruleMatchToTree(r.statements),\n fee: r.connectorSelection.fee ?? null,\n })),\n otherwise: program.defaultSelection.fee ?? null,\n };\n}\n\n/**\n * Fluent builder for a platform fee-rule program. Emits the exact Euclid wire\n * shape (camelCase tree, tagged values, `metadata: {}` everywhere) so callers\n * never hand-write the AST. Rules are evaluated in order; the first match wins,\n * else `otherwise` (the default selection).\n *\n * @example\n * ```ts\n * const algorithm = feeProgram()\n * .rule({ name: 'crypto', when: { paymentMethod: 'crypto' }, fee: { percentage: 1.0 } })\n * .rule({\n * name: 'card_on_cryptomus',\n * when: { paymentMethod: 'card', connector: 'cryptomus' },\n * fee: { percentage: 2.0 },\n * })\n * .otherwise({ percentage: 3.0 })\n * .build();\n *\n * await delopay.fees.rules.upsert({ algorithm }, merchantId);\n * ```\n */\nexport class FeeProgramBuilder {\n private readonly rules: PlatformFeeRule[] = [];\n private defaultFee: PlatformFeeOutput | null = null;\n\n /** Append a rule. Provided `when`/`rawConditions` are ANDed. */\n rule(input: FeeRuleInput): this {\n if (input.match) assertNoEmptyAnyOf(input.match);\n const statements: PlatformFeeRule['statements'] = input.match\n ? encodeStatements(input.match)\n : [{ condition: buildConditions(input.when, input.rawConditions) }];\n this.rules.push({\n name: input.name,\n connectorSelection: { fee: toFeeOutput(input.fee) },\n statements,\n });\n return this;\n }\n\n /** Set the default selection (applied when no rule matches). */\n otherwise(fee: FeeSpecInput): this {\n this.defaultFee = toFeeOutput(fee);\n return this;\n }\n\n /** Produce the wire-ready program. */\n build(): PlatformFeeProgram {\n return {\n defaultSelection: { fee: this.defaultFee },\n rules: this.rules,\n metadata: {},\n };\n }\n}\n\n/** Start building a platform fee-rule program. See {@link FeeProgramBuilder}. */\nexport function feeProgram(): FeeProgramBuilder {\n return new FeeProgramBuilder();\n}\n","// Checkout branding — typed shape, design tokens, palettes, persistence\n// codec, CSS sanitizer, and DOM helpers for `--dp-*` CSS variables.\n//\n// Both delopay-checkout and delopay-control-center consume this module.\n//\n// Persistence: top-level fields own the \"loud\" tokens (logo, theme,\n// payment_button_*, background_colour, etc.). Everything else lives in\n// `sdk_ui_rules.branding` as a nested string-keyed map — booleans and\n// numbers round-trip as strings, the trust-badge list is JSON-stringified.\n\n// --- Types --------------------------------------------------------------\n\nexport type CornerRadius = 'square' | 'small' | 'medium' | 'large' | 'pill';\n\n// Surfaces and inputs never make sense pill-shaped (a pill input ends up with\n// half-circle ends crammed against text). The form picker only exposes these\n// four; if a stale 'pill' value lands here from older saved data, decode\n// drops it back to 'medium'. Buttons and badges still allow 'pill'.\nexport type NonPillRadius = Exclude<CornerRadius, 'pill'>;\n\n// Spacing scales — split apart so the merchant can independently tune\n// surface padding, vertical rhythm, input height and pay-button height. Used\n// to live as a single `density` enum but that conflated four dimensions.\nexport type SpacingScale = 'compact' | 'comfortable' | 'spacious';\nexport type SizeScale = 'sm' | 'md' | 'lg';\nexport type SurfaceStyle = 'flat' | 'outlined' | 'elevated';\n\nexport type FontFamily =\n | 'inter'\n | 'system'\n | 'serif'\n | 'mono'\n | 'roboto'\n | 'poppins'\n | 'manrope'\n | 'dm-sans'\n | 'space-grotesk'\n | 'plex-sans'\n | 'work-sans'\n | 'open-sans'\n | 'lora'\n | 'playfair'\n | 'plex-mono'\n | 'jetbrains-mono';\n\nexport type FontWeight = 'regular' | 'medium' | 'semibold' | 'bold';\nexport type LayoutStyle = 'compact' | 'split';\nexport type SummaryPosition = 'left' | 'right';\n\n// Stripe Elements only supports two label modes (\"above\" or hidden via the\n// .Label-collapse hack); a \"floating\" label is not a Stripe concept and\n// would only render in our own mock — preview was lying about it. Persisted\n// `'floating'` is silently decoded to `'above'` for back-compat.\nexport type LabelStyle = 'above' | 'hidden';\n\n// Stripe Elements layout. Honored inside the StripeCardPane only — other\n// connector panes stack vertically regardless of this setting.\nexport type PaymentLayout = 'tabs' | 'accordion' | 'spaced_accordion';\n\nexport type LogoShape = 'square' | 'rounded' | 'circle';\nexport type LogoSize = 'sm' | 'md' | 'lg';\n\n// --- Provider surcharge / discount disclosure ---------------------------\n//\n// With surcharges scoped to the provider rather than to the payment method,\n// two tiles on one checkout can cost the buyer different amounts — so the\n// figure has to be legible on the tile, before the choice, not only in the\n// breakdown after it. These control how that figure is painted; whether there\n// is one at all is the router's answer, per pane.\n//\n// Nothing here can invent a figure or change one. A merchant who would rather\n// not disclose per-tile turns it off with `showSurcharge` and keeps the\n// breakdown inside the pane, which is where the disclosure lived before.\n\n// Where the figure sits relative to the tile's label.\n//\n// `inline` follows the label text immediately, so the price reads as part of\n// the name — good for short labels.\n// `trailing` pushes it to the tile's trailing edge on the label's own line: the\n// price reads as a property of the tile, and the tile's height does not change,\n// which matters because most tiles carry no figure at all and a row that grows\n// only for some of them makes the list look ragged.\n// `below` puts it under the sublabel, for merchants whose labels are long\n// enough that a trailing figure would crowd them.\n// `above` puts it over the label as an eyebrow, which is the one position that\n// reads before the method name rather than after it.\nexport type SurchargePosition =\n | 'inline'\n | 'trailing'\n | 'below'\n | 'above'\n | 'cornerStart'\n | 'cornerEnd';\n\n// How the figure is painted.\n//\n// `plain` is text in the configured colour. `badge` fills the shape with a tint\n// of it. `outline` draws the border only — the middle weight, for a checkout\n// whose tiles are already busy. `solid` fills with the colour itself and writes\n// on it in whichever of black or white reads better, which is the loudest\n// option and the one to reach for when the figure must not be missed.\n// `underline` keeps the text weight of `plain` and adds a rule beneath it.\n// `ribbon` runs the figure diagonally across a corner of the tile — the one\n// treatment that reads before the label rather than beside it, for a merchant\n// steering hard toward a cheaper provider.\nexport type SurchargeStyle = 'plain' | 'badge' | 'outline' | 'solid' | 'underline' | 'ribbon';\n\n// The border drawn around the shapes `badge`, `outline`, `solid` and `ribbon`\n// paint. `outline` draws nothing BUT its border, so `none` there would erase\n// the style rather than restyle it and reads as `thin` instead.\nexport type SurchargeBorderWidth = 'none' | 'thin' | 'medium' | 'thick';\n\n// How that border is drawn. `dashed` and `dotted` read as provisional, which\n// suits a promotional discount; `solid` is the neutral default.\nexport type SurchargeBorderStyle = 'solid' | 'dashed' | 'dotted';\n\n// The figure's type size, relative to the tile's own text.\nexport type SurchargeSize = 'sm' | 'md' | 'lg';\n\n// The corner treatment of the shapes `badge`, `outline` and `solid` draw.\n// Ignored by `plain` and `underline`, which draw no shape.\nexport type SurchargeShape = 'pill' | 'rounded' | 'square';\n\n// How heavily the figure is set.\nexport type SurchargeWeight = 'regular' | 'medium' | 'bold';\n\n// Whether the figure carries an explicit sign.\n//\n// `always` writes `+` on a surcharge and `−` on a discount (U+2212, not a\n// hyphen, so it aligns with the digits). `minusOnly` writes the minus and\n// leaves a surcharge unsigned, which reads as a price rather than as an\n// adjustment. `none` writes neither and leans entirely on the two colours —\n// legible only when a merchant configures one direction, and offered because a\n// merchant who only ever discounts should not have to explain a plus sign.\nexport type SurchargeSign = 'always' | 'minusOnly' | 'none';\n\n// Whether the figure names itself.\n//\n// `amount` is the figure alone. `labelled` prefixes the localized word for the\n// direction (\"Surcharge\" / \"Discount\"), which costs horizontal room and buys a\n// tile nobody has to interpret.\nexport type SurchargeLabelMode = 'amount' | 'labelled';\n\n// WHICH figure the tile prints, and in which order when it prints both.\n//\n// A discount and a surcharge are the same mechanism pointed in opposite\n// directions, but they are not the same message: a saving is something a\n// merchant advertises and a percentage is the persuasive half of it (\"20%\n// off\"), while a fee is something a merchant discloses and the money is the\n// half the buyer actually cares about. So the two directions carry this\n// setting separately — `discountFigure` and `surchargeFigure` — rather than\n// sharing one.\n//\n// The two figures always describe the same money. The router derives the\n// percentage from the charge rather than from the merchant's rule, so a fixed\n// rule states its share of this cart and a taxed rate states the share the\n// buyer actually pays. That is what makes showing either — or both — safe.\nexport type SurchargeFigureMode = 'amount' | 'percent' | 'amountThenPercent' | 'percentThenAmount';\n\n/**\n * Whether the tile has room to print the wording alongside the figure.\n *\n * One pairing says no: the diagonal ribbon at either corner. That band is\n * clipped by the tile it crosses, and the readable length is set by how far the\n * corner is inset — roughly 75px on a standard payment tile, against roughly\n * 107px for a labelled figure at the default size. Printing the word there\n * clips the *figure*, and a half-shown price is worse than a plain one, so the\n * word is what gives way.\n *\n * Exported, and shared by the buyer-facing checkout and the dashboard's live\n * preview, because the two must reach the same answer. A preview that promises\n * a word the checkout will not print is the one failure a preview cannot have.\n */\nexport function surchargeShowsLabel(\n labelMode: SurchargeLabelMode,\n style: SurchargeStyle,\n position: SurchargePosition,\n): boolean {\n if (labelMode !== 'labelled') return false;\n return !(style === 'ribbon' && (position === 'cornerStart' || position === 'cornerEnd'));\n}\n\n/** One of the two things a tile can print. */\nexport type SurchargeFigurePart = 'amount' | 'percent';\n\n/** Exactly what one tile prints, in order. See {@link surchargeFigurePlan}. */\nexport interface SurchargeFigurePlan {\n /** The leading figure. Always present — a tile with nothing to say renders nothing at all. */\n first: SurchargeFigurePart;\n /** The trailing figure, parenthesised by the renderer, or `null` for one figure. */\n second: SurchargeFigurePart | null;\n /** Whether the localized direction word prefixes the whole thing. */\n label: boolean;\n}\n\n/**\n * What one tile prints: which figures, in which order, and whether the word\n * comes with them.\n *\n * One function rather than a rule per surface, because the buyer-facing tile\n * and the dashboard's live preview must reach the same answer. A preview that\n * shows a percentage the checkout will not print — or prints in the other\n * order — is the one failure a preview cannot have.\n *\n * Three things it decides, in order of how much they cost to get wrong:\n *\n * * **No percentage available, no percentage printed.** `percentAvailable` is\n * false when the router sent none, which happens on an order of zero. A\n * merchant who asked for `percent` gets the amount instead — never a blank\n * tile, and never `0%`. This is the fallback the whole design leans on: the\n * amount is exact in every case, so it is what every degradation lands on.\n * * **A corner ribbon prints one figure.** The band crossing a tile's corner\n * is clipped to roughly 75px of readable length; two figures and a word do\n * not fit, and clipping a *price* is worse than showing less of one. It\n * keeps the merchant's leading figure — their own statement of which half\n * matters — and drops the trailing one along with the word.\n * * **Direction picks the setting.** `discountFigure` for a credit,\n * `surchargeFigure` for a charge, because a saving and a fee are not the\n * same message even though they are the same mechanism.\n */\nexport function surchargeFigurePlan(\n branding: Pick<\n CheckoutBranding,\n 'surchargeFigure' | 'discountFigure' | 'surchargeLabel' | 'surchargeStyle' | 'surchargePosition'\n >,\n isDiscount: boolean,\n percentAvailable: boolean,\n): SurchargeFigurePlan {\n const mode = isDiscount ? branding.discountFigure : branding.surchargeFigure;\n const label = surchargeShowsLabel(\n branding.surchargeLabel,\n branding.surchargeStyle,\n branding.surchargePosition,\n );\n\n // Money only, whatever was asked for: there is no second figure to state.\n if (!percentAvailable) return { first: 'amount', second: null, label };\n\n const ordered: Record<SurchargeFigureMode, [SurchargeFigurePart, SurchargeFigurePart | null]> = {\n amount: ['amount', null],\n percent: ['percent', null],\n amountThenPercent: ['amount', 'percent'],\n percentThenAmount: ['percent', 'amount'],\n };\n const [first, second] = ordered[mode];\n\n // The corner ribbon keeps the merchant's leading figure and nothing else.\n // `surchargeShowsLabel` has already dropped the word for the same reason, so\n // this is the same rule applied to the second figure.\n const cornerRibbon =\n branding.surchargeStyle === 'ribbon' &&\n (branding.surchargePosition === 'cornerStart' || branding.surchargePosition === 'cornerEnd');\n\n return { first, second: cornerRibbon ? null : second, label };\n}\n\n/**\n * Black or white, whichever reads better on `color` — for the `solid` style,\n * which writes on the configured colour itself.\n *\n * Picked by contrast rather than by a luminance threshold so the answer is the\n * one WCAG would give, and falls back to white on an unparseable colour, which\n * is what the rest of this module does with a colour it cannot read.\n */\nexport function readableInkOn(color: string): string {\n const onBlack = contrastRatio(color, '#000000');\n const onWhite = contrastRatio(color, '#ffffff');\n if (onBlack === null || onWhite === null) return '#ffffff';\n return onBlack >= onWhite ? '#000000' : '#ffffff';\n}\n\n/** Type size per {@link SurchargeSize}, relative to the tile's own text. */\nconst SURCHARGE_FONT_SIZE: Record<SurchargeSize, string> = {\n sm: '0.6875rem',\n md: '0.8125rem',\n lg: '0.9375rem',\n};\n\n/** Shape padding per {@link SurchargeSize}. Grows with the type. */\nconst SURCHARGE_PAD: Record<SurchargeSize, string> = {\n sm: '1px 6px',\n md: '2px 8px',\n lg: '3px 10px',\n};\n\n/** Corner radius per {@link SurchargeShape}. */\nconst SURCHARGE_RADIUS: Record<SurchargeShape, string> = {\n pill: '999px',\n rounded: '6px',\n square: '0px',\n};\n\n/** Border thickness per {@link SurchargeBorderWidth}. */\nconst SURCHARGE_BORDER_WIDTH: Record<SurchargeBorderWidth, string> = {\n none: '0px',\n thin: '1px',\n medium: '2px',\n thick: '3px',\n};\n\n/** Font weight per {@link SurchargeWeight}. */\nconst SURCHARGE_FONT_WEIGHT: Record<SurchargeWeight, string> = {\n regular: '400',\n medium: '600',\n bold: '700',\n};\n\n/**\n * The values each disclosure axis accepts, in the order a picker should offer\n * them: quietest first, so a merchant scrolling down is turning the figure up.\n *\n * Exported because both the dashboard's picker and this module's decoder need\n * the same list, and a picker offering a value the decoder rejects is a control\n * that silently does nothing.\n */\nexport const SURCHARGE_POSITIONS: readonly SurchargePosition[] = [\n 'trailing',\n 'inline',\n 'below',\n 'above',\n 'cornerStart',\n 'cornerEnd',\n];\nexport const SURCHARGE_STYLES: readonly SurchargeStyle[] = [\n 'plain',\n 'underline',\n 'outline',\n 'badge',\n 'solid',\n 'ribbon',\n];\nexport const SURCHARGE_BORDER_WIDTHS: readonly SurchargeBorderWidth[] = [\n 'none',\n 'thin',\n 'medium',\n 'thick',\n];\nexport const SURCHARGE_BORDER_STYLES: readonly SurchargeBorderStyle[] = [\n 'solid',\n 'dashed',\n 'dotted',\n];\nexport const SURCHARGE_SIZES: readonly SurchargeSize[] = ['sm', 'md', 'lg'];\n\n/**\n * Whether a style draws a shape behind the figure, and therefore whether\n * {@link SurchargeShape} means anything for it.\n *\n * `plain` and `underline` paint text. A dashboard that leaves the corner picker\n * live under them offers a control that changes nothing on screen, which is how\n * a merchant decides the whole panel is broken; one that hides it loses their\n * choice when they switch back. Disabled is the answer, and this is the\n * predicate it needs.\n */\nexport function surchargeStyleDrawsAShape(style: SurchargeStyle): boolean {\n return style === 'badge' || style === 'outline' || style === 'solid';\n}\nexport const SURCHARGE_SHAPES: readonly SurchargeShape[] = ['pill', 'rounded', 'square'];\nexport const SURCHARGE_WEIGHTS: readonly SurchargeWeight[] = ['regular', 'medium', 'bold'];\nexport const SURCHARGE_SIGNS: readonly SurchargeSign[] = ['always', 'minusOnly', 'none'];\nexport const SURCHARGE_LABEL_MODES: readonly SurchargeLabelMode[] = ['amount', 'labelled'];\nexport const SURCHARGE_FIGURE_MODES: readonly SurchargeFigureMode[] = [\n 'amount',\n 'percent',\n 'amountThenPercent',\n 'percentThenAmount',\n];\n\n/**\n * The buyer locales the checkout ships copy for, and therefore the ones a\n * merchant can override.\n *\n * Driven from here rather than restated in the dashboard, so a locale added to\n * the checkout cannot leave the dashboard offering one fewer box than the\n * buyer-facing render reads.\n */\nexport const CHECKOUT_LOCALES = ['en', 'de'] as const;\nexport type CheckoutLocale = (typeof CHECKOUT_LOCALES)[number];\n\n/**\n * The copy fields a merchant may write once per locale.\n *\n * Each has a flat `<field>` and a `<field>Translations` map beside it. The flat\n * value is what every existing merchant already has and stays authoritative\n * wherever no override is set — which is what makes this additive: a profile\n * saved before translations existed renders exactly as it did, in every locale.\n */\nexport const LOCALIZABLE_COPY_FIELDS = [\n 'headerText',\n 'payButtonLabel',\n 'cardTermsMessage',\n 'footerText',\n] as const;\nexport type LocalizableCopyField = (typeof LOCALIZABLE_COPY_FIELDS)[number];\n\n/** The translations key that belongs to a copy field. */\nexport function copyTranslationsKey(\n field: LocalizableCopyField,\n): `${LocalizableCopyField}Translations` {\n return `${field}Translations`;\n}\n\n/**\n * One piece of merchant copy, in the buyer's locale.\n *\n * Exact locale wins (`de-AT`), then its base language (`de`), then the flat\n * field — the same order `customFieldText` resolves in, because a merchant who\n * has learnt one of these should not have to learn the other.\n *\n * Returning the flat value rather than `''` is the backward-compatibility\n * guarantee: an override is an addition to what a merchant already wrote, never\n * a replacement for it, so an empty or missing map changes nothing.\n */\nexport function checkoutCopy(\n branding: CheckoutBranding,\n field: LocalizableCopyField,\n locale?: string,\n): string {\n const translated = translationFor(branding[copyTranslationsKey(field)], locale);\n return translated ?? branding[field];\n}\n\n/**\n * The merchant's own word for one direction, or `null` to use the checkout's\n * built-in one.\n *\n * `null` rather than a default string because the fallback is *localized* and\n * lives in the buyer-facing bundle — this module has no i18n of its own, and\n * inventing an English default here would print \"Discount\" to a German buyer.\n *\n * A merchant who sets nothing therefore keeps the shipped wording in both\n * languages, which is the intended default and already reads well.\n */\nexport function surchargeWordFor(\n branding: Pick<CheckoutBranding, 'surchargeWordTranslations' | 'discountWordTranslations'>,\n isDiscount: boolean,\n locale?: string,\n): string | null {\n return translationFor(\n isDiscount ? branding.discountWordTranslations : branding.surchargeWordTranslations,\n locale,\n );\n}\n\nexport interface TrustBadge {\n id: string;\n label: string;\n textColor: string;\n backgroundColor: string;\n borderColor: string | null;\n}\n\n// Merchant-defined checkout inputs. Rendered by the buyer-facing checkout\n// above the payment surface; submitted values land in the payment's\n// `metadata` under each field's `key`. Persisted JSON-stringified under\n// `sdk_ui_rules.branding.customFields` (same transport as trustBadges).\n// `checkbox` is a single opt-in box (terms acceptance, marketing consent),\n// not a multi-select. Its submitted value is always the string `'true'` or\n// `'false'` — never absent — so a merchant can tell \"declined\" from \"never\n// asked\" in the payment's metadata, which is what makes it usable as a\n// consent record. See `CHECKBOX_CHECKED` / `isCheckboxChecked`.\nexport type CustomFieldType = 'text' | 'textarea' | 'password' | 'email' | 'select' | 'checkbox';\n\n// Per-locale overrides ('de', 'en', …). Missing locale falls back to the\n// default-language string on the field itself — see `customFieldText`.\nexport type CustomFieldTranslations = Record<string, string>;\n\nexport interface CustomFieldOption {\n value: string;\n label: string;\n labelTranslations: CustomFieldTranslations;\n}\n\n// --- Conditional visibility ---------------------------------------------\n//\n// A field can be gated on facts the payment already carries when the\n// checkout renders: the intent's `metadata` (which a shop integration fills\n// per product/category — see the WordPress plugin's product metadata), its\n// `currency`, or its `amount`. This is what lets one profile serve a\n// \"Windows key\" order (no fields) and a \"Spotify account\" order (login\n// fields) without two shops.\n//\n// Evaluation is authoritative on the **backend**: `form_payment_link_data`\n// drops non-matching fields from the payload the buyer's browser receives,\n// so merchant metadata never leaves the server and the rules can't be\n// tampered with client-side. The implementation here is the shared\n// specification (and drives the control-center's builder); the Rust mirror\n// in `crates/router/src/core/payment_link/custom_fields.rs` must stay\n// behaviorally identical.\nexport type CustomFieldConditionSource = 'metadata' | 'currency' | 'amount';\n\n// String operators apply to metadata + currency; numeric ones (`gt`…`lte`)\n// apply to amount and to metadata values that parse as numbers.\nexport type CustomFieldOperator =\n | 'equals'\n | 'not_equals'\n | 'contains'\n | 'not_contains'\n | 'starts_with'\n | 'ends_with'\n | 'in'\n | 'not_in'\n | 'exists'\n | 'not_exists'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte';\n\nexport interface CustomFieldCondition {\n // Stable identity for editor list operations (reorder/remove). Not part\n // of the semantics.\n id: string;\n source: CustomFieldConditionSource;\n // Metadata key to read. Ignored (and persisted empty) for currency/amount.\n key: string;\n operator: CustomFieldOperator;\n // Right-hand operand. `in`/`not_in` read it as a comma-separated list;\n // `exists`/`not_exists` ignore it; amount comparisons parse it as an\n // integer in the currency's minor unit (1000 = 10.00).\n value: string;\n}\n\nexport interface CustomFieldVisibility {\n // `always` — unconditional (the default, and what every pre-feature field\n // decodes to). `match` — evaluate `conditions`.\n mode: 'always' | 'match';\n // How to combine multiple conditions.\n match: 'all' | 'any';\n conditions: CustomFieldCondition[];\n}\n\nexport interface CheckoutCustomField {\n // Stable identity for editor list operations (reorder/remove).\n id: string;\n // Metadata key the submitted value is stored under. Must be unique per\n // profile; the editor enforces `CUSTOM_FIELD_KEY_PATTERN`.\n key: string;\n type: CustomFieldType;\n // Default-language copy; `*Translations` maps override per locale.\n label: string;\n labelTranslations: CustomFieldTranslations;\n placeholder: string;\n placeholderTranslations: CustomFieldTranslations;\n helpText: string;\n helpTextTranslations: CustomFieldTranslations;\n required: boolean;\n // Disabled fields stay configured but are neither rendered nor submitted.\n enabled: boolean;\n // Length bounds apply to text/textarea/password/email; null = unbounded.\n minLength: number | null;\n maxLength: number | null;\n // Prefill for text-like fields; for selects, the option `value` selected\n // initially (empty = placeholder \"choose\" state).\n defaultValue: string;\n // Select choices; ignored for other types.\n options: CustomFieldOption[];\n // Conditional display. Always populated by the decoder — fields without a\n // persisted rule decode to `{ mode: 'always', … }`.\n visibility: CustomFieldVisibility;\n}\n\nexport interface CheckoutBranding {\n // Brand identity\n displayName: string;\n logoUrl: string;\n tagline: string;\n showLogo: boolean;\n logoShape: LogoShape;\n logoSize: LogoSize;\n\n // Color tokens\n primary: string;\n background: string;\n surface: string;\n text: string;\n heading: string;\n muted: string;\n border: string;\n accentText: string;\n buttonBackground: string;\n buttonText: string;\n\n // Typography\n fontFamily: FontFamily;\n headingWeight: FontWeight;\n\n // Shape — granular per-element. Surfaces & inputs use a narrower union\n // (no pill) because pill cards/inputs are always wrong; button and badge\n // keep the full `CornerRadius` since pill is a legitimate look there.\n radiusSurface: NonPillRadius;\n radiusInput: NonPillRadius;\n radiusButton: CornerRadius;\n radiusBadge: CornerRadius;\n surfaceStyle: SurfaceStyle;\n\n // Spacing — four independent dimensions.\n surfacePadding: SpacingScale;\n verticalGap: SpacingScale;\n inputSize: SizeScale;\n buttonSize: SizeScale;\n\n // Layout\n layout: LayoutStyle;\n summaryPosition: SummaryPosition;\n showOrderSummary: boolean;\n summaryGradient: boolean;\n showTotal: boolean;\n totalLabel: string;\n showCurrencyCode: boolean;\n showOrderItems: boolean;\n\n // Provider surcharge / discount disclosure. `showSurcharge` false hides the\n // per-tile figure entirely; the in-pane breakdown is unaffected, since that\n // one is the merchant's existing legal disclosure rather than a steering\n // signal. The two colours are separate on purpose: a surcharge and a discount\n // are opposite news for the buyer and reading them in one colour is exactly\n // the mistake a minus sign is easy to miss in.\n showSurcharge: boolean;\n surchargePosition: SurchargePosition;\n surchargeStyle: SurchargeStyle;\n surchargeSize: SurchargeSize;\n surchargeShape: SurchargeShape;\n surchargeBorderWidth: SurchargeBorderWidth;\n surchargeBorderStyle: SurchargeBorderStyle;\n surchargeWeight: SurchargeWeight;\n surchargeSign: SurchargeSign;\n surchargeUppercase: boolean;\n surchargeLabel: SurchargeLabelMode;\n surchargeFigure: SurchargeFigureMode;\n discountFigure: SurchargeFigureMode;\n surchargeWordTranslations: CustomFieldTranslations;\n discountWordTranslations: CustomFieldTranslations;\n surchargeColor: string;\n discountColor: string;\n\n // Trust badges (fully customizable; empty = hide row).\n trustBadges: TrustBadge[];\n\n // Merchant-defined checkout inputs (empty = no custom fields section).\n customFields: CheckoutCustomField[];\n\n // Copy. All of these are optional in the persisted form: empty string\n // means \"unset\" and consumers should fall back (e.g. payButtonLabel falls\n // back to a localized \"Pay $X\" string).\n headerText: string;\n headerTextTranslations: CustomFieldTranslations;\n payButtonLabel: string;\n payButtonLabelTranslations: CustomFieldTranslations;\n cardTermsMessage: string;\n cardTermsMessageTranslations: CustomFieldTranslations;\n footerText: string;\n footerTextTranslations: CustomFieldTranslations;\n supportEmail: string;\n\n // Stripe Elements behavior. `paymentLayout` only affects what's painted\n // inside Stripe's iframe; non-Stripe connector panes stack vertically\n // regardless. `labelStyle` is also Stripe-iframe scope.\n paymentLayout: PaymentLayout;\n labelStyle: LabelStyle;\n\n // Footer\n showPoweredBy: boolean;\n\n // Advanced — raw CSS appended after brand-token CSS variables are\n // applied, so its declarations win cascade order. Sanitized at render\n // time (see `sanitizeCustomCss`); persisted as-typed under\n // `sdk_ui_rules.branding.customCss`.\n customCss: string;\n}\n\n// --- Token maps ---------------------------------------------------------\n\n// Self-hostable font stacks. The buyer-facing checkout bundles these via\n// @fontsource* packages; the variable-font names ('Inter Variable', …) are\n// listed first so the smaller variable file is preferred when bundled.\nconst FONT_STACKS: Record<FontFamily, string> = {\n inter: \"'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif\",\n system:\n \"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif\",\n serif: \"Georgia, 'Times New Roman', serif\",\n mono: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',\n roboto: \"'Roboto', system-ui, sans-serif\",\n poppins: \"'Poppins', system-ui, sans-serif\",\n manrope: \"'Manrope Variable', 'Manrope', system-ui, sans-serif\",\n 'dm-sans': \"'DM Sans Variable', 'DM Sans', system-ui, sans-serif\",\n 'space-grotesk': \"'Space Grotesk Variable', 'Space Grotesk', system-ui, sans-serif\",\n 'plex-sans': \"'IBM Plex Sans', system-ui, sans-serif\",\n 'work-sans': \"'Work Sans Variable', 'Work Sans', system-ui, sans-serif\",\n 'open-sans': \"'Open Sans Variable', 'Open Sans', system-ui, sans-serif\",\n lora: \"'Lora Variable', 'Lora', Georgia, serif\",\n playfair: \"'Playfair Display Variable', 'Playfair Display', Georgia, serif\",\n 'plex-mono': \"'IBM Plex Mono', ui-monospace, monospace\",\n 'jetbrains-mono': \"'JetBrains Mono Variable', 'JetBrains Mono', ui-monospace, monospace\",\n};\n\nconst RADIUS_PX: Record<CornerRadius, string> = {\n square: '0px',\n small: '6px',\n medium: '12px',\n large: '20px',\n pill: '999px',\n};\n\nconst FONT_WEIGHT_NUMERIC: Record<FontWeight, string> = {\n regular: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n};\n\nconst SURFACE_PAD: Record<SpacingScale, string> = {\n compact: '1rem',\n comfortable: '1.5rem',\n spacious: '2rem',\n};\n\nconst VERTICAL_GAP: Record<SpacingScale, string> = {\n compact: '0.75rem',\n comfortable: '1rem',\n spacious: '1.5rem',\n};\n\nconst INPUT_PAD: Record<SizeScale, string> = {\n sm: '0.5rem 0.75rem',\n md: '0.625rem 0.75rem',\n lg: '0.875rem 0.875rem',\n};\n\nconst BUTTON_PAD: Record<SizeScale, string> = {\n sm: '0.625rem 1rem',\n md: '0.875rem 1.25rem',\n lg: '1.125rem 1.5rem',\n};\n\nexport function fontStack(family: FontFamily): string {\n return FONT_STACKS[family] ?? FONT_STACKS.inter;\n}\n\nexport function radiusValue(radius: CornerRadius): string {\n return RADIUS_PX[radius] ?? RADIUS_PX.medium;\n}\n\nexport function fontWeightValue(weight: FontWeight): string {\n return FONT_WEIGHT_NUMERIC[weight] ?? '600';\n}\n\nexport function surfacePadValue(scale: SpacingScale): string {\n return SURFACE_PAD[scale] ?? SURFACE_PAD.comfortable;\n}\n\nexport function verticalGapValue(scale: SpacingScale): string {\n return VERTICAL_GAP[scale] ?? VERTICAL_GAP.comfortable;\n}\n\nexport function inputPadValue(size: SizeScale): string {\n return INPUT_PAD[size] ?? INPUT_PAD.md;\n}\n\nexport function buttonPadValue(size: SizeScale): string {\n return BUTTON_PAD[size] ?? BUTTON_PAD.md;\n}\n\nexport function logoDimensions(size: LogoSize): { px: number; radius: number } {\n switch (size) {\n case 'sm':\n return { px: 36, radius: 8 };\n case 'lg':\n return { px: 64, radius: 16 };\n case 'md':\n default:\n return { px: 48, radius: 12 };\n }\n}\n\nconst HEX_RE = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/;\n\nexport function isHexColor(value: string): boolean {\n return HEX_RE.test(value.trim());\n}\n\n/**\n * A CSS `<hex-color>`: whole token, leading `#` REQUIRED.\n *\n * ⚠️ The `#` is not pedantry here. `applyBrandingVariables` writes branding\n * values into custom properties unchanged (`el.style.setProperty(k, v)`), and\n * a custom property accepts any token stream — it is only interpreted when\n * substituted into a typed property, where `000` is not a colour and the\n * declaration is dropped. So a contrast API that accepted `'000'` would hand\n * back `21` for a pair that renders as nothing at all: approving a palette\n * that never reaches the screen is worse than refusing to judge it.\n */\nconst CSS_HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\n/**\n * The same shape with the `#` optional, for {@link isDarkSurface} ONLY.\n *\n * That function has stripped an optional hash since it was written, and\n * `'5a5a5a'` is a real colour whose answer is correct — tightening it onto the\n * CSS form would answer correct input wrongly. New API does not inherit the\n * tolerance; the existing caller keeps it.\n */\nconst LENIENT_HEX_RE = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\n/** `[r, g, b]` in 0–255, or `null` when the token is not a colour. */\nfunction parseHexChannels(value: string, pattern: RegExp): [number, number, number] | null {\n const match = pattern.exec(value.trim());\n if (!match) return null;\n const digits = match[1] as string;\n const full =\n digits.length === 3\n ? digits\n .split('')\n .map((c) => c + c)\n .join('')\n : digits;\n return [\n parseInt(full.slice(0, 2), 16),\n parseInt(full.slice(2, 4), 16),\n parseInt(full.slice(4, 6), 16),\n ];\n}\n\n/** WCAG 2.1 relative luminance (1.4.3), with the sRGB linearisation. */\nfunction relativeLuminance([r, g, b]: [number, number, number]): number {\n const [lr, lg, lb] = [r, g, b].map((channel) => {\n const c = channel / 255;\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n }) as [number, number, number];\n return 0.2126 * lr + 0.7152 * lg + 0.0722 * lb;\n}\n\n/** Minimum contrast for body text — WCAG 2.1 success criterion 1.4.3. */\nexport const WCAG_AA_TEXT = 4.5;\n\n/**\n * Minimum contrast for non-text UI — WCAG 2.1 success criterion 1.4.11.\n * Focus rings, borders, icons carrying meaning.\n */\nexport const WCAG_AA_UI = 3;\n\n/**\n * WCAG 2.1 contrast ratio between two colours, 1–21. Order does not matter.\n *\n * Compare against {@link WCAG_AA_TEXT} or {@link WCAG_AA_UI}:\n *\n * ```ts\n * const ratio = contrastRatio(branding.surface, branding.text);\n * if (ratio === null || ratio < WCAG_AA_TEXT) useDefaultPalette();\n * ```\n *\n * ⚠️ Returns `null` — never a number — when either colour cannot be parsed.\n * That is the load-bearing part of this signature. Every colour bug this API\n * exists to prevent came from a helper answering with a plausible value for\n * something it could not read, and a `0` or a `21` here would be silently\n * believed by exactly the branch that is deciding whether text is legible.\n *\n * Accepts `#rgb` and `#rrggbb` — a CSS `<hex-color>`. ⚠️ A hash-less token is\n * `null`, not a ratio: `applyBrandingVariables` writes branding values into\n * custom properties verbatim, so `'000'` reaches CSS as something that is not a\n * colour. Returning `21` for it would approve a palette that never renders.\n * ({@link isDarkSurface} keeps its historical hash-less tolerance; this is new\n * API and does not inherit it.)\n */\nexport function contrastRatio(a: string, b: string): number | null {\n const first = parseHexChannels(a, CSS_HEX_RE);\n const second = parseHexChannels(b, CSS_HEX_RE);\n if (!first || !second) return null;\n const [x, y] = [relativeLuminance(first), relativeLuminance(second)];\n const lighter = Math.max(x, y);\n const darker = Math.min(x, y);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Crude perceived-luminance check — picks the right Stripe Elements preset\n * (`'night'` vs `'stripe'`) when the merchant has a dark surface.\n *\n * ⚠️ **This is not a readability test. Use {@link contrastRatio} for that.**\n * It is a YIQ luma split at 128, and on real brand colours its verdict and\n * actual legibility are not merely imprecise relative to each other — they can\n * be anti-correlated:\n *\n * | colour | `isDarkSurface` | vs white | |\n * | --- | --- | --- | --- |\n * | `#ff00ff` | `true` | 3.14:1 | fails AA text |\n * | `#00ff00` | `false` | 1.37:1 | fails AA text |\n * | `#0000ff` | `true` | 8.59:1 | passes |\n *\n * A caller picking text colour from this gets the wrong answer on both failing\n * cases. It is kept because choosing a Stripe preset is a legitimate and\n * different question.\n *\n * Inputs that are not a 3-/6-digit hex fall through to \"light\", the safer\n * assumption for the default palette.\n */\nexport function isDarkSurface(color: string): boolean {\n // ⚠️ Was a length check plus `parseInt` plus `Number.isNaN`, which let six\n // values the package's own validator rejects through as \"dark\" — `parseInt`\n // accepts a valid prefix, so `parseInt('0g', 16)` is `0`, not `NaN`. The\n // comment above already promised these fall through to \"light\"; now they do.\n const channels = parseHexChannels(color, LENIENT_HEX_RE);\n if (!channels) return false;\n const [r, g, b] = channels;\n const luma = (r * 299 + g * 587 + b * 114) / 1000;\n return luma < 128;\n}\n\n// --- Defaults -----------------------------------------------------------\n\n// Light-mode DeloPay-branded baseline. Hex values come straight from\n// `design-guidelines/colors.md`:\n// - #1E4FEB is `--color-dp-blue`, the wordmark/icon brand blue\n// - #0A1130 is `--color-dp-blue-dark`, the wordmark navy\n// - the rest are slate-50 / slate-200 / slate-500 / slate-800 from the\n// design system's neutral ramp.\n// Picked for: high contrast, neutral surroundings, brand-blue accents,\n// confident navy CTA. Reads \"fintech\" without feeling cold.\nconst LIGHT_PALETTE = {\n primary: '#1E4FEB',\n background: '#f8fafc',\n surface: '#ffffff',\n text: '#1e293b',\n heading: '#0A1130',\n muted: '#64748b',\n border: '#e2e8f0',\n accentText: '#1E4FEB',\n buttonBackground: '#0A1130',\n buttonText: '#ffffff',\n} as const;\n\nexport const DEFAULT_BADGES: TrustBadge[] = [\n {\n id: 'secure',\n label: 'Secure',\n textColor: '#047857',\n backgroundColor: '#ecfdf5',\n borderColor: '#a7f3d0',\n },\n {\n id: 'ssl',\n label: '256-bit SSL',\n textColor: '#1E4FEB',\n backgroundColor: '#eff6ff',\n borderColor: '#bfdbfe',\n },\n];\n\n// Dark-mode equivalents of DEFAULT_BADGES. Dark trust chips need solid hex\n// (the form's color picker only accepts hex), so we pick the design system's\n// success-900 / info-900 backdrops paired with their *-400 foreground tokens.\nexport const DEFAULT_BADGES_DARK: TrustBadge[] = [\n {\n id: 'secure',\n label: 'Secure',\n textColor: '#34d399',\n backgroundColor: '#064e3b',\n borderColor: '#065f46',\n },\n {\n id: 'ssl',\n label: '256-bit SSL',\n textColor: '#60a5fa',\n backgroundColor: '#172554',\n borderColor: '#1e40af',\n },\n];\n\nconst DEFAULT_BRANDING_BASE: Omit<\n CheckoutBranding,\n keyof typeof LIGHT_PALETTE | 'trustBadges' | 'customFields'\n> = {\n displayName: '',\n logoUrl: '',\n tagline: '',\n // Logo + summary gradient OFF by default — an unconfigured DeloPay\n // checkout reads cleaner without a placeholder logo block, and the\n // gradient implies a primary tint the merchant hasn't yet picked.\n showLogo: false,\n logoShape: 'rounded',\n logoSize: 'md',\n\n fontFamily: 'inter',\n headingWeight: 'semibold',\n\n radiusSurface: 'medium',\n radiusInput: 'medium',\n radiusButton: 'medium',\n radiusBadge: 'pill',\n surfaceStyle: 'elevated',\n surfacePadding: 'comfortable',\n verticalGap: 'comfortable',\n inputSize: 'md',\n buttonSize: 'md',\n\n // Disclosure on by default: with provider-scoped pricing the tile is where\n // the buyer chooses between prices, and a price they cannot see is one they\n // find out about on the statement.\n showSurcharge: true,\n surchargePosition: 'trailing',\n surchargeStyle: 'badge',\n surchargeSize: 'sm',\n surchargeShape: 'pill',\n surchargeBorderWidth: 'thin',\n surchargeBorderStyle: 'solid',\n surchargeWeight: 'medium',\n surchargeSign: 'always',\n surchargeUppercase: false,\n // Named, not bare. A tile that reads \"-EUR 2.50\" beside a brand name is a\n // number with no subject — buyers read it as the price, not as a change to\n // it. \"Discount -EUR 2.50\" needs no interpreting, and the word is what makes\n // the default configuration legible without the merchant touching anything.\n surchargeLabel: 'labelled',\n // The two directions default differently on purpose, which is the whole\n // reason they are two settings. A fee is something a buyer acts on in money,\n // so it leads with money and says nothing else. A saving is something worth\n // advertising, and the share is the persuasive half of it — \"-5.1% (EUR\n // 2.50)\" sells what \"-EUR 2.50\" merely states, and the amount is still right\n // there beside it.\n surchargeFigure: 'amount',\n discountFigure: 'percentThenAmount',\n // Empty: the checkout's own localized words are the default, in every\n // language it ships. A merchant fills these in only to say it differently.\n surchargeWordTranslations: {},\n discountWordTranslations: {},\n // amber-700 / emerald-700, not the 600s: the `plain` style renders the\n // disclosure as coloured TEXT, so it is bound by `WCAG_AA_TEXT` (4.5) rather\n // than by the 3:1 a coloured shape would be, and the 600s come to 3.19 and\n // 3.77 against the default white surface. These are 5.02 and 5.48, pinned by\n // tests. Far enough apart to read as opposite news at a glance rather than as\n // two shades of \"extra\".\n surchargeColor: '#b45309',\n discountColor: '#047857',\n\n layout: 'split',\n summaryPosition: 'left',\n showOrderSummary: true,\n summaryGradient: false,\n showTotal: true,\n totalLabel: 'Total',\n showCurrencyCode: false,\n showOrderItems: true,\n\n // Each flat field keeps its meaning: what the merchant wrote, used in every\n // locale that carries no override. Empty maps therefore change nothing for a\n // profile saved before translations existed.\n headerText: '',\n headerTextTranslations: {},\n payButtonLabel: '',\n payButtonLabelTranslations: {},\n cardTermsMessage: '',\n cardTermsMessageTranslations: {},\n footerText: '',\n footerTextTranslations: {},\n supportEmail: '',\n\n paymentLayout: 'tabs',\n labelStyle: 'above',\n showPoweredBy: true,\n\n customCss: '',\n};\n\nexport const DEFAULT_BRANDING: CheckoutBranding = {\n ...DEFAULT_BRANDING_BASE,\n ...LIGHT_PALETTE,\n trustBadges: DEFAULT_BADGES.map((b) => ({ ...b })),\n customFields: [],\n};\n\n// Dark counterpart to DEFAULT_BRANDING. Same form-only fields stay empty\n// (logo / display name / tagline / copy) — only visual tokens diverge.\n// Palette mirrors the design-guidelines dark ramp:\n// - background = slate-950, surface = slate-900 → soft contrast.\n// - text = slate-200, heading = slate-50 → AA+ contrast on the surface.\n// - muted = slate-400, border = slate-800 → chrome that fades into the bg.\n// - accentText = primary-400, button bg = brand blue → brand pops on dark\n// where the light theme's near-black navy CTA would disappear.\n// - surfaceStyle = 'flat' because soft drop-shadows don't read on dark\n// surfaces; the existing 'elevated' shadow tokens are tuned for light.\nexport const DEFAULT_BRANDING_DARK: CheckoutBranding = {\n ...DEFAULT_BRANDING_BASE,\n primary: '#1E4FEB',\n background: '#020617',\n surface: '#0f172a',\n text: '#e2e8f0',\n heading: '#f8fafc',\n muted: '#94a3b8',\n border: '#1e293b',\n accentText: '#60a5fa',\n buttonBackground: '#1E4FEB',\n buttonText: '#ffffff',\n surfaceStyle: 'flat',\n // amber-400 / emerald-400: the 700s above are far too dark to read on\n // slate-900, and this pair is the same news in the same order at the light\n // end of the ramp — 10.69 and 9.29 against the dark surface, also pinned.\n surchargeColor: '#fbbf24',\n discountColor: '#34d399',\n trustBadges: DEFAULT_BADGES_DARK.map((b) => ({ ...b })),\n customFields: [],\n};\n\n// Back-compat alias. Prefer `DEFAULT_BRANDING` directly.\nexport function defaultBranding(): CheckoutBranding {\n return cloneBranding(DEFAULT_BRANDING);\n}\n\n// Deep-ish clone — needed because the form mutates state reactively and we\n// don't want shared TrustBadge / CheckoutCustomField object refs across the\n// loaded/edit/default snapshots. Spread is shallow; array elements would\n// otherwise be shared between snapshots, breaking reset.\nexport function cloneBranding(b: CheckoutBranding): CheckoutBranding {\n return {\n ...b,\n trustBadges: b.trustBadges.map((badge) => ({ ...badge })),\n customFields: b.customFields.map(cloneCustomField),\n // Copied, not shared. A spread alone would leave the clone pointing at the\n // original's maps, and the dashboard edits a clone precisely so the form\n // can be abandoned without touching what is saved.\n surchargeWordTranslations: { ...b.surchargeWordTranslations },\n discountWordTranslations: { ...b.discountWordTranslations },\n headerTextTranslations: { ...b.headerTextTranslations },\n payButtonLabelTranslations: { ...b.payButtonLabelTranslations },\n cardTermsMessageTranslations: { ...b.cardTermsMessageTranslations },\n footerTextTranslations: { ...b.footerTextTranslations },\n };\n}\n\nexport function cloneCustomField(f: CheckoutCustomField): CheckoutCustomField {\n return {\n ...f,\n labelTranslations: { ...f.labelTranslations },\n placeholderTranslations: { ...f.placeholderTranslations },\n helpTextTranslations: { ...f.helpTextTranslations },\n options: f.options.map((o) => ({ ...o, labelTranslations: { ...o.labelTranslations } })),\n visibility: {\n ...f.visibility,\n conditions: f.visibility.conditions.map((c) => ({ ...c })),\n },\n };\n}\n\n// --- Sanitizer ----------------------------------------------------------\n\n// Hard cap on the persisted custom CSS payload. Mirrors the editor's\n// validation; oversized input is dropped to null rather than truncated,\n// since a half-truncated rule is worse than no rule.\nexport const CUSTOM_CSS_MAX_LENGTH = 50_000;\n\n// Strip CSS tokens that turn a stylesheet into a delivery vector before\n// handing the merchant's input to the renderer. The list isn't exhaustive\n// — it's the everyday surface area:\n//\n// - `</style` would let injected text break out of the <style> block and\n// parse as HTML/JS. Replaced with a benign token (not removed) so\n// `</styled-tag` (unlikely but possible inside a content: string)\n// doesn't silently merge into surrounding text.\n// - `@import` would let the merchant pull in a remote stylesheet on\n// every buyer page-load (analytics by side-channel; possible buyer-IP\n// leak).\n// - `expression(…)` was a legacy IE construct that ran JS from CSS.\n// - `behavior:` and `-moz-binding:` ditto for IE/old-Gecko.\n// - `javascript:` URLs in url(...) execute on resource load in some\n// browsers/contexts.\n//\n// Anything else passes through. The merchant can still write whatever\n// declarations they like (background images, gradients, transforms,\n// keyframes, container queries, …).\nexport function sanitizeCustomCss(raw: string | null | undefined): string | null {\n if (typeof raw !== 'string') return null;\n const trimmed = raw.trim();\n if (trimmed.length === 0) return null;\n if (trimmed.length > CUSTOM_CSS_MAX_LENGTH) return null;\n\n let out = trimmed;\n out = out.replace(/<\\/style/gi, '<\\\\/style');\n out = out.replace(/@import\\b[^;]*;?/gi, '');\n out = out.replace(/expression\\s*\\(/gi, '/* expression( */');\n out = out.replace(/(^|[^a-z-])behavior\\s*:/gi, '$1/* behavior: */');\n out = out.replace(/-moz-binding\\s*:/gi, '/* -moz-binding: */');\n out = out.replace(/url\\s*\\(\\s*[\"']?\\s*javascript:/gi, 'url(invalid:');\n return out;\n}\n\n// --- Codec --------------------------------------------------------------\n\n// Structural shape the decoder reads. Both `CheckoutDetails` (public buyer\n// payload) and `BusinessPaymentLinkConfig` (merchant config request shape)\n// satisfy this via duck typing — they each fill some of these and leave the\n// rest undefined. `merchant_*` and `seller_*`/`logo` are aliases for the\n// same API field, surfaced under different names by the two payloads.\nexport interface BrandingSource {\n // Identity (one or the other, depending on payload shape)\n merchant_name?: string | null;\n seller_name?: string | null;\n merchant_logo?: string | null;\n logo?: string | null;\n merchant_description?: string | null;\n\n // Visual\n theme?: string | null;\n background_colour?: string | null;\n payment_button_colour?: string | null;\n payment_button_text_colour?: string | null;\n\n // Copy\n payment_form_header_text?: string | null;\n payment_button_text?: string | null;\n custom_message_for_card_terms?: string | null;\n\n // Footer\n branding_visibility?: boolean | null;\n\n // Stripe\n sdk_layout?: string | null;\n payment_form_label_type?: string | null;\n\n // The bag for everything else\n sdk_ui_rules?: Record<string, Record<string, string> | null | undefined> | null;\n}\n\nconst BRANDING_GROUP_KEY = 'branding';\n\nconst ALL_FONT_FAMILIES: readonly FontFamily[] = [\n 'inter',\n 'system',\n 'serif',\n 'mono',\n 'roboto',\n 'poppins',\n 'manrope',\n 'dm-sans',\n 'space-grotesk',\n 'plex-sans',\n 'work-sans',\n 'open-sans',\n 'lora',\n 'playfair',\n 'plex-mono',\n 'jetbrains-mono',\n];\n\nconst ALL_RADII: readonly CornerRadius[] = ['square', 'small', 'medium', 'large', 'pill'];\nconst NON_PILL_RADII: readonly NonPillRadius[] = ['square', 'small', 'medium', 'large'];\n\nfunction pickEnum<T extends string>(value: unknown, allowed: readonly T[], fallback: T): T {\n if (typeof value !== 'string') return fallback;\n return (allowed as readonly string[]).includes(value) ? (value as T) : fallback;\n}\n\nfunction parseBool(value: unknown, fallback: boolean): boolean {\n if (typeof value === 'boolean') return value;\n if (value === 'true') return true;\n if (value === 'false') return false;\n return fallback;\n}\n\nfunction s(value: string | null | undefined): string {\n return typeof value === 'string' ? value : '';\n}\n\n// Decode the JSON-encoded trust badges stored under\n// `sdk_ui_rules.branding.trustBadges`. Tolerant: a malformed payload,\n// missing fields, or wrong types fall through to null so the caller can\n// substitute the default badge set. An explicit empty array means \"no\n// badges\" (we honor it — merchants who hide the row need a way to express\n// that).\nexport function decodeBadges(raw: string | undefined): TrustBadge[] | null {\n if (raw === undefined) return null;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return null;\n return parsed\n .filter((b): b is Record<string, unknown> => !!b && typeof b === 'object')\n .map((b, i) => ({\n id: typeof b['id'] === 'string' && b['id'] ? (b['id'] as string) : `badge-${i}`,\n label: typeof b['label'] === 'string' ? (b['label'] as string) : '',\n textColor: typeof b['textColor'] === 'string' ? (b['textColor'] as string) : '#0f172a',\n backgroundColor:\n typeof b['backgroundColor'] === 'string' ? (b['backgroundColor'] as string) : '#f1f5f9',\n borderColor:\n typeof b['borderColor'] === 'string' && b['borderColor']\n ? (b['borderColor'] as string)\n : null,\n }))\n .filter((b) => b.label.length > 0);\n } catch {\n return null;\n }\n}\n\nexport function encodeBadges(badges: TrustBadge[]): string {\n return JSON.stringify(\n badges.map((b) => ({\n id: b.id,\n label: b.label,\n textColor: b.textColor,\n backgroundColor: b.backgroundColor,\n ...(b.borderColor ? { borderColor: b.borderColor } : {}),\n })),\n );\n}\n\n// --- Custom checkout fields codec ---------------------------------------\n\nexport const CUSTOM_FIELDS_MAX = 20;\n// Metadata keys: start with a letter, then letters/digits/underscore/dash.\n// Keeps keys safe for every downstream metadata consumer (dashboards,\n// exports, PSP forwarding).\nexport const CUSTOM_FIELD_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9_-]{0,39}$/;\n\nexport const ALL_CUSTOM_FIELD_TYPES: readonly CustomFieldType[] = [\n 'text',\n 'textarea',\n 'password',\n 'email',\n 'select',\n 'checkbox',\n];\n\n// The two values a checkbox field ever submits. Kept as strings because the\n// whole metadata bag is `Record<string, string>` on the wire.\nexport const CHECKBOX_CHECKED = 'true';\nexport const CHECKBOX_UNCHECKED = 'false';\n\n/** Whether a stored/submitted checkbox value counts as ticked. Tolerant of\n * case and padding so a value round-tripped through a shop integration\n * ('True', ' true ') still reads correctly. */\nexport function isCheckboxChecked(value: string | null | undefined): boolean {\n return typeof value === 'string' && value.trim().toLowerCase() === CHECKBOX_CHECKED;\n}\n\n/** Types whose value is free text, so length bounds and a placeholder apply.\n * `select` and `checkbox` are choice controls and have neither. */\nexport function customFieldIsTextLike(type: CustomFieldType): boolean {\n return type !== 'select' && type !== 'checkbox';\n}\n\n// Rule-builder vocabulary. Kept next to the codec so the editor, the\n// evaluator and the Rust mirror all read from one list.\nexport const CUSTOM_FIELD_CONDITIONS_MAX = 10;\n\nexport const ALL_CUSTOM_FIELD_CONDITION_SOURCES: readonly CustomFieldConditionSource[] = [\n 'metadata',\n 'currency',\n 'amount',\n];\n\nexport const ALL_CUSTOM_FIELD_OPERATORS: readonly CustomFieldOperator[] = [\n 'equals',\n 'not_equals',\n 'contains',\n 'not_contains',\n 'starts_with',\n 'ends_with',\n 'in',\n 'not_in',\n 'exists',\n 'not_exists',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n];\n\n// Which operators make sense per source. Currency is a closed 3-letter set,\n// so substring/numeric operators would only ever confuse; amount is numeric,\n// so string operators don't apply. Metadata is free-form and gets all of them.\nexport const CUSTOM_FIELD_OPERATORS_BY_SOURCE: Record<\n CustomFieldConditionSource,\n readonly CustomFieldOperator[]\n> = {\n metadata: ALL_CUSTOM_FIELD_OPERATORS,\n currency: ['equals', 'not_equals', 'in', 'not_in'],\n amount: ['equals', 'not_equals', 'gt', 'gte', 'lt', 'lte'],\n};\n\n// Operators that ignore the right-hand operand — the editor hides the value\n// input for these, and validation must not demand a value.\nexport const CUSTOM_FIELD_VALUELESS_OPERATORS: readonly CustomFieldOperator[] = [\n 'exists',\n 'not_exists',\n];\n\nexport function customFieldOperatorTakesValue(operator: CustomFieldOperator): boolean {\n return !CUSTOM_FIELD_VALUELESS_OPERATORS.includes(operator);\n}\n\n// The operator a condition falls back to when its source changes and the\n// current operator isn't valid for the new source.\nexport function defaultOperatorForSource(source: CustomFieldConditionSource): CustomFieldOperator {\n return CUSTOM_FIELD_OPERATORS_BY_SOURCE[source][0] ?? 'equals';\n}\n\nexport function defaultCustomFieldVisibility(): CustomFieldVisibility {\n return { mode: 'always', match: 'all', conditions: [] };\n}\n\nfunction parseTranslations(raw: unknown): CustomFieldTranslations {\n // The branding bag stores every value as a string, so a map persisted there\n // arrives as JSON; an import file and a custom field carry it inline. Both\n // reach this, and a string that is not JSON is simply not a map.\n let value = raw;\n if (typeof value === 'string') {\n try {\n value = JSON.parse(value) as unknown;\n } catch {\n return {};\n }\n }\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {};\n const out: CustomFieldTranslations = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n // Own properties only: a persisted key of `__proto__` or `constructor`\n // must not reach the object being built, and `Object.entries` already\n // gives own enumerable keys only — the length check is what drops a blank\n // override, which means \"no override\" rather than \"render nothing\".\n if (typeof v === 'string' && v.trim().length > 0) out[k] = v;\n }\n return out;\n}\n\n/**\n * A translations map for the branding bag, or `undefined` when there is\n * nothing to store.\n *\n * Omitting the key rather than writing `{}` keeps the bag of a merchant who\n * never opened the translations strip byte-identical to what it was before\n * these fields existed.\n */\nfunction encodeTranslations(map: CustomFieldTranslations): string | undefined {\n const entries = Object.entries(map).filter(([, v]) => v.trim().length > 0);\n return entries.length > 0 ? JSON.stringify(Object.fromEntries(entries)) : undefined;\n}\n\n// Normalize one persisted condition. Total: an unusable source/operator\n// falls back rather than dropping the row, so a rule authored by a newer\n// control-center never silently becomes \"always visible\" on an older\n// decoder — it becomes a stricter, still-evaluable rule.\nfunction normalizeCondition(raw: unknown, index: number): CustomFieldCondition | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const c = raw as Record<string, unknown>;\n const source = pickEnum<CustomFieldConditionSource>(\n c['source'],\n ALL_CUSTOM_FIELD_CONDITION_SOURCES,\n 'metadata',\n );\n const allowed = CUSTOM_FIELD_OPERATORS_BY_SOURCE[source];\n const operator = pickEnum<CustomFieldOperator>(\n c['operator'],\n allowed,\n defaultOperatorForSource(source),\n );\n const rawValue = c['value'];\n return {\n id: typeof c['id'] === 'string' && c['id'] ? (c['id'] as string) : `cond-${index}`,\n source,\n // Only metadata conditions carry a key; drop anything else so the\n // encoded form stays canonical.\n key: source === 'metadata' && typeof c['key'] === 'string' ? c['key'].trim() : '',\n operator,\n value:\n typeof rawValue === 'string'\n ? rawValue\n : typeof rawValue === 'number' || typeof rawValue === 'boolean'\n ? String(rawValue)\n : '',\n };\n}\n\nfunction normalizeVisibility(raw: unknown): CustomFieldVisibility {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return defaultCustomFieldVisibility();\n const v = raw as Record<string, unknown>;\n const conditions: CustomFieldCondition[] = Array.isArray(v['conditions'])\n ? (v['conditions'] as unknown[])\n .slice(0, CUSTOM_FIELD_CONDITIONS_MAX)\n .map(normalizeCondition)\n .filter((c): c is CustomFieldCondition => c !== null)\n : [];\n return {\n mode: pickEnum<'always' | 'match'>(v['mode'], ['always', 'match'], 'always'),\n match: pickEnum<'all' | 'any'>(v['match'], ['all', 'any'], 'all'),\n conditions,\n };\n}\n\nfunction parseBoundedInt(raw: unknown): number | null {\n const n = typeof raw === 'number' ? raw : typeof raw === 'string' ? Number(raw) : NaN;\n if (!Number.isInteger(n) || n < 0) return null;\n return Math.min(n, 5000);\n}\n\n// Normalize one persisted/imported field object. Total: anything malformed\n// falls back per-property; returns null only when there is no usable key.\nfunction normalizeCustomField(raw: unknown, index: number): CheckoutCustomField | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const f = raw as Record<string, unknown>;\n const key = typeof f['key'] === 'string' ? f['key'].trim() : '';\n if (!CUSTOM_FIELD_KEY_PATTERN.test(key)) return null;\n\n const type = pickEnum<CustomFieldType>(f['type'], ALL_CUSTOM_FIELD_TYPES, 'text');\n\n const options: CustomFieldOption[] =\n type === 'select' && Array.isArray(f['options'])\n ? (f['options'] as unknown[])\n .filter((o): o is Record<string, unknown> => !!o && typeof o === 'object')\n .map((o) => {\n const value = typeof o['value'] === 'string' ? o['value'] : '';\n return {\n value,\n label: typeof o['label'] === 'string' && o['label'] ? (o['label'] as string) : value,\n labelTranslations: parseTranslations(o['labelTranslations']),\n };\n })\n .filter((o) => o.value.length > 0)\n : [];\n\n // Length bounds are meaningless for choice controls; drop them at decode\n // so a field switched to checkbox/select can't carry stale bounds that\n // would then be validated against 'true'/'false'.\n const textLike = customFieldIsTextLike(type);\n const minLength = textLike ? parseBoundedInt(f['minLength']) : null;\n const maxLength = textLike ? parseBoundedInt(f['maxLength']) : null;\n\n // A checkbox default is a tick state, not free text: anything that isn't\n // truthy normalizes to unchecked, so the control can never start in a\n // third state.\n const rawDefault = typeof f['defaultValue'] === 'string' ? f['defaultValue'] : '';\n const defaultValue =\n type === 'checkbox'\n ? isCheckboxChecked(rawDefault)\n ? CHECKBOX_CHECKED\n : CHECKBOX_UNCHECKED\n : rawDefault;\n\n return {\n id: typeof f['id'] === 'string' && f['id'] ? (f['id'] as string) : `field-${index}`,\n key,\n type,\n label: typeof f['label'] === 'string' && f['label'] ? (f['label'] as string) : key,\n labelTranslations: parseTranslations(f['labelTranslations']),\n placeholder: typeof f['placeholder'] === 'string' ? (f['placeholder'] as string) : '',\n placeholderTranslations: parseTranslations(f['placeholderTranslations']),\n helpText: typeof f['helpText'] === 'string' ? (f['helpText'] as string) : '',\n helpTextTranslations: parseTranslations(f['helpTextTranslations']),\n required: parseBool(f['required'], false),\n enabled: parseBool(f['enabled'], true),\n minLength,\n // Guard inverted bounds at decode so consumers never see min > max.\n maxLength: maxLength !== null && minLength !== null && maxLength < minLength ? null : maxLength,\n defaultValue,\n options,\n visibility: normalizeVisibility(f['visibility']),\n };\n}\n\n// Parse an array of field objects (already JSON-parsed). Null when the\n// input isn't an array — callers fall back to \"no custom fields\". Duplicate\n// keys keep the first occurrence; the list is capped at CUSTOM_FIELDS_MAX.\nexport function parseCustomFieldsLoose(raw: unknown): CheckoutCustomField[] | null {\n if (!Array.isArray(raw)) return null;\n const seen = new Set<string>();\n const out: CheckoutCustomField[] = [];\n for (let i = 0; i < raw.length && out.length < CUSTOM_FIELDS_MAX; i++) {\n const field = normalizeCustomField(raw[i], i);\n if (!field || seen.has(field.key)) continue;\n seen.add(field.key);\n out.push(field);\n }\n return out;\n}\n\n// Decode the JSON-encoded custom fields stored under\n// `sdk_ui_rules.branding.customFields`. Tolerant like `decodeBadges`:\n// malformed payloads fall through to null.\nexport function decodeCustomFields(raw: string | undefined): CheckoutCustomField[] | null {\n if (raw === undefined) return null;\n try {\n return parseCustomFieldsLoose(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\nexport function encodeCustomFields(fields: CheckoutCustomField[]): string {\n const nonEmpty = (m: CustomFieldTranslations): CustomFieldTranslations | undefined => {\n const entries = Object.entries(m).filter(([, v]) => v.trim().length > 0);\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n };\n return JSON.stringify(\n fields.map((f) => ({\n id: f.id,\n key: f.key,\n type: f.type,\n label: f.label,\n ...(nonEmpty(f.labelTranslations)\n ? { labelTranslations: nonEmpty(f.labelTranslations) }\n : {}),\n ...(f.placeholder ? { placeholder: f.placeholder } : {}),\n ...(nonEmpty(f.placeholderTranslations)\n ? { placeholderTranslations: nonEmpty(f.placeholderTranslations) }\n : {}),\n ...(f.helpText ? { helpText: f.helpText } : {}),\n ...(nonEmpty(f.helpTextTranslations)\n ? { helpTextTranslations: nonEmpty(f.helpTextTranslations) }\n : {}),\n ...(f.required ? { required: true } : {}),\n ...(f.enabled ? {} : { enabled: false }),\n // Length bounds only exist for free-text types; a choice control that\n // still carries them is stale state the decoder would drop anyway.\n ...(customFieldIsTextLike(f.type) && f.minLength !== null ? { minLength: f.minLength } : {}),\n ...(customFieldIsTextLike(f.type) && f.maxLength !== null ? { maxLength: f.maxLength } : {}),\n // A checkbox persists only \"starts ticked\"; unticked is the decoder's\n // default, so writing 'false' would be noise on every such field.\n ...(f.type === 'checkbox'\n ? isCheckboxChecked(f.defaultValue)\n ? { defaultValue: CHECKBOX_CHECKED }\n : {}\n : f.defaultValue\n ? { defaultValue: f.defaultValue }\n : {}),\n ...(f.type === 'select' ? { options: f.options } : {}),\n // Omitted for unconditional fields so the stored blob (and every\n // pre-feature payload) stays byte-identical to what it was.\n ...(f.visibility.mode === 'match' ? { visibility: encodeVisibility(f.visibility) } : {}),\n })),\n );\n}\n\nfunction encodeVisibility(v: CustomFieldVisibility): Record<string, unknown> {\n return {\n mode: v.mode,\n match: v.match,\n conditions: v.conditions.map((c) => ({\n id: c.id,\n source: c.source,\n ...(c.source === 'metadata' && c.key ? { key: c.key } : {}),\n operator: c.operator,\n ...(customFieldOperatorTakesValue(c.operator) && c.value ? { value: c.value } : {}),\n })),\n };\n}\n\n// --- Conditional-visibility evaluator -----------------------------------\n\n/** Facts a rule can read. `amount` is in the currency's minor unit (what\n * the payment intent stores); `metadata` values are already flattened to\n * strings by `customFieldContextFromMetadata`. */\nexport interface CustomFieldContext {\n amount: number;\n currency: string;\n metadata: Record<string, string>;\n}\n\n/** Flatten a payment's raw `metadata` object into the string map a rule\n * compares against. Arrays join on `,` so a list-shaped value stays usable\n * with `contains` / `in`; objects fall back to JSON. Mirrors the Rust\n * side's `flatten_metadata`. */\nexport function customFieldContextFromMetadata(raw: unknown): Record<string, string> {\n const out: Record<string, string> = {};\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return out;\n for (const [key, value] of Object.entries(raw as Record<string, unknown>)) {\n const flat = flattenMetadataValue(value);\n if (flat !== null) out[key] = flat;\n }\n return out;\n}\n\nfunction flattenMetadataValue(value: unknown): string | null {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (value === null || value === undefined) return null;\n if (Array.isArray(value)) {\n return value\n .map((v) => flattenMetadataValue(v))\n .filter((v): v is string => v !== null)\n .join(',');\n }\n try {\n return JSON.stringify(value);\n } catch {\n return null;\n }\n}\n\n// Case- and whitespace-insensitive: merchants type `Windows` in the builder\n// and the shop sends `windows`. Exact-case matching would be a support\n// ticket generator.\nfunction norm(value: string): string {\n return value.trim().toLowerCase();\n}\n\n// Decimal-float grammar, deliberately narrower than `Number()`.\n//\n// `Number()` accepts radix-prefixed literals — `Number('0x10') === 16` — while\n// the router's Rust mirror uses `f64::from_str`, which rejects them. Left\n// unconstrained, a metadata value of `0x10` would satisfy `gte 5` in the\n// control-center's builder and fail it on the backend: the merchant sees one\n// rule, buyers get another. This regex is `f64::from_str`'s number grammar\n// (sign, digits with optional point, optional exponent); `inf`/`nan` are\n// excluded here rather than by the finiteness check below, which matches\n// Rust filtering them out too.\nconst DECIMAL_NUMBER_PATTERN = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?$/;\n\n// Both implementations compare as f64, so they round identically. Payment\n// amounts in minor units are far below 2^53, where that is lossless.\nfunction numeric(value: string): number | null {\n const trimmed = value.trim();\n if (!DECIMAL_NUMBER_PATTERN.test(trimmed)) return null;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : null;\n}\n\nfunction splitList(value: string): string[] {\n return value\n .split(',')\n .map((part) => norm(part))\n .filter((part) => part.length > 0);\n}\n\n/** Resolve the left-hand operand. `undefined` means \"the metadata key is\n * absent\" — which only `exists`/`not_exists` distinguish from empty. */\nfunction operandFor(condition: CustomFieldCondition, ctx: CustomFieldContext): string | undefined {\n switch (condition.source) {\n case 'currency':\n return ctx.currency;\n case 'amount':\n return String(ctx.amount);\n case 'metadata':\n return Object.prototype.hasOwnProperty.call(ctx.metadata, condition.key)\n ? ctx.metadata[condition.key]\n : undefined;\n }\n}\n\nexport function evaluateCustomFieldCondition(\n condition: CustomFieldCondition,\n ctx: CustomFieldContext,\n): boolean {\n const raw = operandFor(condition, ctx);\n const actual = raw ?? '';\n const expected = condition.value;\n\n switch (condition.operator) {\n case 'exists':\n return raw !== undefined && raw.trim().length > 0;\n case 'not_exists':\n return raw === undefined || raw.trim().length === 0;\n case 'equals':\n return norm(actual) === norm(expected);\n case 'not_equals':\n return norm(actual) !== norm(expected);\n case 'contains':\n return norm(actual).includes(norm(expected));\n case 'not_contains':\n return !norm(actual).includes(norm(expected));\n case 'starts_with':\n return norm(actual).startsWith(norm(expected));\n case 'ends_with':\n return norm(actual).endsWith(norm(expected));\n case 'in':\n return splitList(expected).includes(norm(actual));\n case 'not_in':\n return !splitList(expected).includes(norm(actual));\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n // Both sides must be numbers. A non-numeric metadata value never\n // matches a numeric comparison (rather than coercing to 0).\n const a = numeric(actual);\n const b = numeric(expected);\n if (a === null || b === null) return false;\n if (condition.operator === 'gt') return a > b;\n if (condition.operator === 'gte') return a >= b;\n if (condition.operator === 'lt') return a < b;\n return a <= b;\n }\n }\n}\n\n/**\n * Whether a field's rule matches the payment.\n *\n * Fail-open in two spots, deliberately: `mode: 'always'` and a `match` rule\n * with no conditions both resolve to visible. A half-authored rule should\n * never silently swallow a field the merchant needs collected — the\n * control-center flags the empty rule as a validation issue instead.\n */\nexport function evaluateCustomFieldVisibility(\n field: CheckoutCustomField,\n ctx: CustomFieldContext,\n): boolean {\n const { mode, match, conditions } = field.visibility;\n if (mode !== 'match' || conditions.length === 0) return true;\n return match === 'any'\n ? conditions.some((c) => evaluateCustomFieldCondition(c, ctx))\n : conditions.every((c) => evaluateCustomFieldCondition(c, ctx));\n}\n\n/** Filter a field list to what the buyer should see for this payment.\n * Disabled fields are dropped here too — the two reasons a field doesn't\n * render are the same to every consumer. */\nexport function visibleCustomFields(\n fields: CheckoutCustomField[],\n ctx: CustomFieldContext,\n): CheckoutCustomField[] {\n return fields.filter((f) => f.enabled && evaluateCustomFieldVisibility(f, ctx));\n}\n\n// Exact-locale-then-base-language lookup. Own-property + string checks so\n// a hostile or odd locale string ('constructor', '__proto__') can never\n// surface a prototype-chain member as a \"translation\".\nfunction translationFor(map: CustomFieldTranslations, locale?: string): string | null {\n if (!locale) return null;\n const own = (k: string): string | null => {\n const v = Object.prototype.hasOwnProperty.call(map, k) ? map[k] : undefined;\n return typeof v === 'string' && v.length > 0 ? v : null;\n };\n const exact = own(locale);\n if (exact) return exact;\n const base = locale.split('-')[0];\n return base && base !== locale ? own(base) : null;\n}\n\n// Resolve the display string for a field part in a buyer locale.\n// Exact locale wins ('de-AT'), then its base language ('de'), then the\n// field's default-language string; labels finally fall back to the key so\n// a field is never rendered nameless.\nexport function customFieldText(\n field: CheckoutCustomField,\n part: 'label' | 'placeholder' | 'helpText',\n locale?: string,\n): string {\n const map =\n part === 'label'\n ? field.labelTranslations\n : part === 'placeholder'\n ? field.placeholderTranslations\n : field.helpTextTranslations;\n const translated = translationFor(map, locale);\n if (translated) return translated;\n const fallback = field[part];\n if (fallback) return fallback;\n return part === 'label' ? field.key : '';\n}\n\nexport function customFieldOptionLabel(option: CustomFieldOption, locale?: string): string {\n return translationFor(option.labelTranslations, locale) ?? (option.label || option.value);\n}\n\n// Read a branding source into a fully-resolved CheckoutBranding.\n// Flat fields are authoritative when set; the bag fills in everything not\n// reachable via flat columns. Persisted `labelStyle: 'floating'` (legacy\n// \"floating\" mock) decodes to `'above'`.\nexport function decodeBranding(source: BrandingSource | null | undefined): CheckoutBranding {\n if (!source) return cloneBranding(DEFAULT_BRANDING);\n\n const extras: Record<string, string> = (source.sdk_ui_rules?.[BRANDING_GROUP_KEY] ??\n {}) as Record<string, string>;\n\n const decodedBadges = decodeBadges(extras['trustBadges']);\n const decodedCustomFields = decodeCustomFields(extras['customFields']);\n\n // Identity name: public payloads call it `merchant_name`, request payloads\n // call it `seller_name`. Same API field; pick whichever is present.\n const displayName = s(source.merchant_name) || s(source.seller_name);\n const logoUrl = s(source.merchant_logo) || s(source.logo);\n\n // Tagline lives in the bag, but `merchant_description` is its public\n // surface. Either may fill it; bag wins if both are set.\n const tagline = s(extras['tagline']) || s(source.merchant_description);\n\n // Stripe label style: the bag's `labelStyle` is the new source of truth;\n // the legacy flat `payment_form_label_type` is consulted only when the\n // bag is empty. `'floating'` (a legacy preview-only value that Stripe\n // Elements never honored) decodes to `'above'`. `'never'` (legacy API\n // wording) decodes to `'hidden'`.\n const labelStyle: LabelStyle = (() => {\n const fromBag = extras['labelStyle'];\n if (fromBag === 'above' || fromBag === 'hidden') return fromBag;\n if (fromBag === 'floating') return 'above';\n const legacy = source.payment_form_label_type;\n if (legacy === 'above' || legacy === 'floating') return 'above';\n if (legacy === 'hidden' || legacy === 'never') return 'hidden';\n return DEFAULT_BRANDING.labelStyle;\n })();\n\n return {\n displayName,\n logoUrl,\n tagline,\n showLogo: parseBool(extras['showLogo'], DEFAULT_BRANDING.showLogo),\n logoShape: pickEnum<LogoShape>(\n extras['logoShape'],\n ['square', 'rounded', 'circle'],\n DEFAULT_BRANDING.logoShape,\n ),\n logoSize: pickEnum<LogoSize>(extras['logoSize'], ['sm', 'md', 'lg'], DEFAULT_BRANDING.logoSize),\n\n primary: s(source.theme) || DEFAULT_BRANDING.primary,\n background: s(source.background_colour) || DEFAULT_BRANDING.background,\n surface: s(extras['surface']) || DEFAULT_BRANDING.surface,\n text: s(extras['text']) || DEFAULT_BRANDING.text,\n heading: s(extras['heading']) || s(extras['text']) || DEFAULT_BRANDING.heading,\n muted: s(extras['muted']) || DEFAULT_BRANDING.muted,\n border: s(extras['border']) || DEFAULT_BRANDING.border,\n accentText: s(extras['accentText']) || s(source.theme) || DEFAULT_BRANDING.accentText,\n buttonBackground:\n s(source.payment_button_colour) || s(source.theme) || DEFAULT_BRANDING.buttonBackground,\n buttonText: s(source.payment_button_text_colour) || DEFAULT_BRANDING.buttonText,\n\n fontFamily: pickEnum<FontFamily>(\n extras['fontFamily'],\n ALL_FONT_FAMILIES,\n DEFAULT_BRANDING.fontFamily,\n ),\n headingWeight: pickEnum<FontWeight>(\n extras['headingWeight'],\n ['regular', 'medium', 'semibold', 'bold'],\n DEFAULT_BRANDING.headingWeight,\n ),\n\n radiusSurface: pickEnum<NonPillRadius>(\n extras['radiusSurface'],\n NON_PILL_RADII,\n DEFAULT_BRANDING.radiusSurface,\n ),\n radiusInput: pickEnum<NonPillRadius>(\n extras['radiusInput'],\n NON_PILL_RADII,\n DEFAULT_BRANDING.radiusInput,\n ),\n radiusButton: pickEnum<CornerRadius>(\n extras['radiusButton'],\n ALL_RADII,\n DEFAULT_BRANDING.radiusButton,\n ),\n radiusBadge: pickEnum<CornerRadius>(\n extras['radiusBadge'],\n ALL_RADII,\n DEFAULT_BRANDING.radiusBadge,\n ),\n surfaceStyle: pickEnum<SurfaceStyle>(\n extras['surfaceStyle'],\n ['flat', 'outlined', 'elevated'],\n DEFAULT_BRANDING.surfaceStyle,\n ),\n surfacePadding: pickEnum<SpacingScale>(\n extras['surfacePadding'],\n ['compact', 'comfortable', 'spacious'],\n DEFAULT_BRANDING.surfacePadding,\n ),\n verticalGap: pickEnum<SpacingScale>(\n extras['verticalGap'],\n ['compact', 'comfortable', 'spacious'],\n DEFAULT_BRANDING.verticalGap,\n ),\n inputSize: pickEnum<SizeScale>(\n extras['inputSize'],\n ['sm', 'md', 'lg'],\n DEFAULT_BRANDING.inputSize,\n ),\n buttonSize: pickEnum<SizeScale>(\n extras['buttonSize'],\n ['sm', 'md', 'lg'],\n DEFAULT_BRANDING.buttonSize,\n ),\n\n showSurcharge: parseBool(extras['showSurcharge'], DEFAULT_BRANDING.showSurcharge),\n surchargePosition: pickEnum<SurchargePosition>(\n extras['surchargePosition'],\n SURCHARGE_POSITIONS,\n DEFAULT_BRANDING.surchargePosition,\n ),\n surchargeStyle: pickEnum<SurchargeStyle>(\n extras['surchargeStyle'],\n SURCHARGE_STYLES,\n DEFAULT_BRANDING.surchargeStyle,\n ),\n surchargeSize: pickEnum<SurchargeSize>(\n extras['surchargeSize'],\n SURCHARGE_SIZES,\n DEFAULT_BRANDING.surchargeSize,\n ),\n surchargeShape: pickEnum<SurchargeShape>(\n extras['surchargeShape'],\n SURCHARGE_SHAPES,\n DEFAULT_BRANDING.surchargeShape,\n ),\n surchargeBorderWidth: pickEnum<SurchargeBorderWidth>(\n extras['surchargeBorderWidth'],\n SURCHARGE_BORDER_WIDTHS,\n DEFAULT_BRANDING.surchargeBorderWidth,\n ),\n surchargeBorderStyle: pickEnum<SurchargeBorderStyle>(\n extras['surchargeBorderStyle'],\n SURCHARGE_BORDER_STYLES,\n DEFAULT_BRANDING.surchargeBorderStyle,\n ),\n surchargeWeight: pickEnum<SurchargeWeight>(\n extras['surchargeWeight'],\n SURCHARGE_WEIGHTS,\n DEFAULT_BRANDING.surchargeWeight,\n ),\n surchargeSign: pickEnum<SurchargeSign>(\n extras['surchargeSign'],\n SURCHARGE_SIGNS,\n DEFAULT_BRANDING.surchargeSign,\n ),\n surchargeUppercase: parseBool(\n extras['surchargeUppercase'],\n DEFAULT_BRANDING.surchargeUppercase,\n ),\n surchargeLabel: pickEnum<SurchargeLabelMode>(\n extras['surchargeLabel'],\n SURCHARGE_LABEL_MODES,\n DEFAULT_BRANDING.surchargeLabel,\n ),\n surchargeFigure: pickEnum<SurchargeFigureMode>(\n extras['surchargeFigure'],\n SURCHARGE_FIGURE_MODES,\n DEFAULT_BRANDING.surchargeFigure,\n ),\n discountFigure: pickEnum<SurchargeFigureMode>(\n extras['discountFigure'],\n SURCHARGE_FIGURE_MODES,\n DEFAULT_BRANDING.discountFigure,\n ),\n surchargeWordTranslations: parseTranslations(extras['surchargeWordTranslations']),\n discountWordTranslations: parseTranslations(extras['discountWordTranslations']),\n headerTextTranslations: parseTranslations(extras['headerTextTranslations']),\n payButtonLabelTranslations: parseTranslations(extras['payButtonLabelTranslations']),\n cardTermsMessageTranslations: parseTranslations(extras['cardTermsMessageTranslations']),\n footerTextTranslations: parseTranslations(extras['footerTextTranslations']),\n surchargeColor: s(extras['surchargeColor']) || DEFAULT_BRANDING.surchargeColor,\n discountColor: s(extras['discountColor']) || DEFAULT_BRANDING.discountColor,\n\n layout: pickEnum<LayoutStyle>(extras['layout'], ['compact', 'split'], DEFAULT_BRANDING.layout),\n summaryPosition: pickEnum<SummaryPosition>(\n extras['summaryPosition'],\n ['left', 'right'],\n DEFAULT_BRANDING.summaryPosition,\n ),\n showOrderSummary: parseBool(extras['showOrderSummary'], DEFAULT_BRANDING.showOrderSummary),\n summaryGradient: parseBool(extras['summaryGradient'], DEFAULT_BRANDING.summaryGradient),\n showTotal: parseBool(extras['showTotal'], DEFAULT_BRANDING.showTotal),\n totalLabel: s(extras['totalLabel']) || DEFAULT_BRANDING.totalLabel,\n showCurrencyCode: parseBool(extras['showCurrencyCode'], DEFAULT_BRANDING.showCurrencyCode),\n showOrderItems: parseBool(extras['showOrderItems'], DEFAULT_BRANDING.showOrderItems),\n\n trustBadges: decodedBadges ?? DEFAULT_BRANDING.trustBadges.map((b) => ({ ...b })),\n customFields: decodedCustomFields ?? [],\n\n headerText: s(source.payment_form_header_text),\n payButtonLabel: s(source.payment_button_text),\n cardTermsMessage: s(source.custom_message_for_card_terms),\n footerText: s(extras['footerText']),\n supportEmail: s(extras['supportEmail']),\n\n paymentLayout: pickEnum<PaymentLayout>(\n source.sdk_layout,\n ['tabs', 'accordion', 'spaced_accordion'],\n DEFAULT_BRANDING.paymentLayout,\n ),\n labelStyle,\n showPoweredBy: source.branding_visibility !== false,\n\n customCss: s(extras['customCss']),\n };\n}\n\n// Encoded request shape — the union of fields the encoder fills. Compatible\n// with `BusinessPaymentLinkConfig` / `PaymentLinkConfigRequest` via\n// structural typing on the consumer side.\nexport interface EncodedBranding {\n theme: string;\n logo: string | null;\n seller_name: string | null;\n sdk_layout: PaymentLayout;\n payment_button_text: string | null;\n payment_button_colour: string;\n payment_button_text_colour: string;\n background_colour: string;\n payment_form_header_text: string | null;\n payment_form_label_type: 'above' | 'never';\n custom_message_for_card_terms: string | null;\n sdk_ui_rules: Record<string, Record<string, string>>;\n branding_visibility: boolean;\n}\n\n// Encode a CheckoutBranding into the API request shape. `base` is the\n// existing config (if any) -- preserves bag entries the form doesn't surface\n// (other sdk_ui_rules groups, business_specific_configs, etc.) by spreading\n// it through.\n//\n// `TBase` is constrained to `object | null | undefined` (not\n// `Record<string, unknown>`) so consumers can pass interface-typed values\n// directly. TS interfaces don't get an implicit string index signature, so\n// they don't structurally satisfy `Record<string, unknown>` even when their\n// property values would all unify to `unknown` — `object` admits them\n// without forcing a cast at every call site. We only spread the value, so\n// no index-signature semantics are needed at runtime.\nexport function encodeBranding<TBase extends object | null | undefined>(\n branding: CheckoutBranding,\n base?: TBase,\n): EncodedBranding & (TBase extends object ? TBase : Record<string, never>) {\n const trim = (v: string): string | null => {\n const t = v.trim();\n return t.length > 0 ? t : null;\n };\n\n // We only read one property off `base` and structural typing on `object`\n // doesn't permit index access, so go through `unknown` here.\n const existingRules = ((base as unknown as Record<string, unknown> | undefined)?.[\n 'sdk_ui_rules'\n ] ?? {}) as Record<string, Record<string, string>>;\n const extras: Record<string, string> = {\n surface: branding.surface,\n text: branding.text,\n heading: branding.heading,\n muted: branding.muted,\n border: branding.border,\n accentText: branding.accentText,\n fontFamily: branding.fontFamily,\n headingWeight: branding.headingWeight,\n radiusSurface: branding.radiusSurface,\n radiusInput: branding.radiusInput,\n radiusButton: branding.radiusButton,\n radiusBadge: branding.radiusBadge,\n surfaceStyle: branding.surfaceStyle,\n surfacePadding: branding.surfacePadding,\n verticalGap: branding.verticalGap,\n inputSize: branding.inputSize,\n buttonSize: branding.buttonSize,\n showSurcharge: String(branding.showSurcharge),\n surchargePosition: branding.surchargePosition,\n surchargeStyle: branding.surchargeStyle,\n surchargeSize: branding.surchargeSize,\n surchargeShape: branding.surchargeShape,\n surchargeBorderWidth: branding.surchargeBorderWidth,\n surchargeBorderStyle: branding.surchargeBorderStyle,\n surchargeWeight: branding.surchargeWeight,\n surchargeSign: branding.surchargeSign,\n surchargeUppercase: String(branding.surchargeUppercase),\n surchargeLabel: branding.surchargeLabel,\n surchargeFigure: branding.surchargeFigure,\n discountFigure: branding.discountFigure,\n surchargeColor: branding.surchargeColor,\n discountColor: branding.discountColor,\n layout: branding.layout,\n summaryPosition: branding.summaryPosition,\n showOrderSummary: String(branding.showOrderSummary),\n summaryGradient: String(branding.summaryGradient),\n showTotal: String(branding.showTotal),\n totalLabel: branding.totalLabel,\n showCurrencyCode: String(branding.showCurrencyCode),\n showOrderItems: String(branding.showOrderItems),\n showLogo: String(branding.showLogo),\n logoShape: branding.logoShape,\n logoSize: branding.logoSize,\n labelStyle: branding.labelStyle,\n trustBadges: encodeBadges(branding.trustBadges),\n };\n // Omit the key entirely when there are no fields — decode treats a\n // missing entry the same as an empty list, and the bag stays clean for\n // merchants who never touch the feature.\n if (branding.customFields.length > 0) {\n extras['customFields'] = encodeCustomFields(branding.customFields);\n }\n // Localized copy, each written only when the merchant actually set one, so\n // an untouched profile's bag is unchanged by this feature existing.\n for (const key of [\n 'surchargeWordTranslations',\n 'discountWordTranslations',\n 'headerTextTranslations',\n 'payButtonLabelTranslations',\n 'cardTermsMessageTranslations',\n 'footerTextTranslations',\n ] as const) {\n const encoded = encodeTranslations(branding[key]);\n if (encoded) extras[key] = encoded;\n }\n const tagline = trim(branding.tagline);\n if (tagline) extras['tagline'] = tagline;\n const footer = trim(branding.footerText);\n if (footer) extras['footerText'] = footer;\n const support = trim(branding.supportEmail);\n if (support) extras['supportEmail'] = support;\n // Persist raw — sanitization runs at render time so we keep the merchant's\n // input as-typed (preserves comments, whitespace) and let the checkout\n // strip dangerous tokens consistently across all readers.\n const css = trim(branding.customCss);\n if (css) extras['customCss'] = css;\n\n const nextRules: Record<string, Record<string, string>> = {\n ...existingRules,\n [BRANDING_GROUP_KEY]: extras,\n };\n\n // Map `hidden` back to the legacy `never` token the API's label type\n // enum understands. `floating` no longer exists.\n const legacyLabel: 'above' | 'never' = branding.labelStyle === 'hidden' ? 'never' : 'above';\n\n const flatFields: EncodedBranding = {\n theme: branding.primary,\n logo: trim(branding.logoUrl),\n seller_name: trim(branding.displayName),\n sdk_layout: branding.paymentLayout,\n payment_button_text: trim(branding.payButtonLabel),\n payment_button_colour: branding.buttonBackground,\n payment_button_text_colour: branding.buttonText,\n background_colour: branding.background,\n payment_form_header_text: trim(branding.headerText),\n payment_form_label_type: legacyLabel,\n custom_message_for_card_terms: trim(branding.cardTermsMessage),\n sdk_ui_rules: nextRules,\n branding_visibility: branding.showPoweredBy,\n };\n\n // Spread `base` first to preserve fields the encoder doesn't surface\n // (show_card_terms, show_card_form_by_default, hide_card_nickname_field,\n // enable_button_only_on_form_ready, skip_status_screen,\n // transaction_details, background_image, details_layout,\n // custom_message_for_payment_method_types, payment_link_ui_rules,\n // color_icon_card_cvc_error, is_setup_mandate_flow,\n // enabled_saved_payment_method, display_sdk_only,\n // business_specific_configs, domain_name, allowed_domains).\n return {\n ...base,\n ...flatFields,\n } as EncodedBranding & (TBase extends object ? TBase : Record<string, never>);\n}\n\n// --- Import / Export envelope ------------------------------------------\n\n// Versioned envelope used by the merchant control-center's \"Import /\n// Export\" buttons. Bumping `version` is informational; the importer is\n// graceful and accepts any version (or no envelope at all).\nexport const BRANDING_EXPORT_FORMAT = 'delopay-checkout-branding';\nexport const BRANDING_EXPORT_VERSION = 1;\n\nexport interface BrandingExport {\n format: typeof BRANDING_EXPORT_FORMAT;\n version: number;\n exported_at: string;\n branding: CheckoutBranding;\n}\n\nexport function buildBrandingExport(branding: CheckoutBranding): BrandingExport {\n return {\n format: BRANDING_EXPORT_FORMAT,\n version: BRANDING_EXPORT_VERSION,\n exported_at: new Date().toISOString(),\n branding: cloneBranding(branding),\n };\n}\n\n// Resolve arbitrary JSON into a fully-typed CheckoutBranding. Designed to\n// never throw — every field is independently validated against its type\n// and silently falls back to the light-mode default if missing or\n// malformed:\n// - extra fields the form doesn't know about are ignored,\n// - missing fields inherit defaults,\n// - hex colors that fail the regex stay at the default,\n// - enums outside the allowed set fall back,\n// - a payload with no recognizable shape produces DEFAULT_BRANDING.\n//\n// Accepts either a bare CheckoutBranding object or an envelope produced by\n// `buildBrandingExport()`. The caller (the import handler) only needs to\n// catch JSON.parse errors; everything past that point is total.\nexport function parseImportedBranding(raw: unknown): CheckoutBranding {\n // Unwrap the envelope if present. Don't gate on version — bumping it is\n // informational; this function is the migration layer.\n const root: Record<string, unknown> | null =\n isObject(raw) && isObject(raw['branding'])\n ? (raw['branding'] as Record<string, unknown>)\n : isObject(raw)\n ? raw\n : null;\n\n if (!root) return cloneBranding(DEFAULT_BRANDING);\n\n const dflt = DEFAULT_BRANDING;\n const sStr = (v: unknown, fallback: string): string => (typeof v === 'string' ? v : fallback);\n const sHex = (v: unknown, fallback: string): string =>\n typeof v === 'string' && isHexColor(v) ? v : fallback;\n\n const trustBadges =\n parseTrustBadgesLoose(root['trustBadges']) ?? dflt.trustBadges.map((b) => ({ ...b }));\n const customFields = parseCustomFieldsLoose(root['customFields']) ?? [];\n\n // `floating` from older exports normalizes to `above`; see decodeBranding.\n const labelStyle: LabelStyle = (() => {\n const v = root['labelStyle'];\n if (v === 'above' || v === 'hidden') return v;\n return dflt.labelStyle;\n })();\n\n return {\n displayName: sStr(root['displayName'], dflt.displayName),\n logoUrl: sStr(root['logoUrl'], dflt.logoUrl),\n tagline: sStr(root['tagline'], dflt.tagline),\n showLogo: parseBool(root['showLogo'], dflt.showLogo),\n logoShape: pickEnum<LogoShape>(\n root['logoShape'],\n ['square', 'rounded', 'circle'],\n dflt.logoShape,\n ),\n logoSize: pickEnum<LogoSize>(root['logoSize'], ['sm', 'md', 'lg'], dflt.logoSize),\n\n primary: sHex(root['primary'], dflt.primary),\n background: sHex(root['background'], dflt.background),\n surface: sHex(root['surface'], dflt.surface),\n text: sHex(root['text'], dflt.text),\n heading: sHex(root['heading'], dflt.heading),\n muted: sHex(root['muted'], dflt.muted),\n border: sHex(root['border'], dflt.border),\n accentText: sHex(root['accentText'], dflt.accentText),\n buttonBackground: sHex(root['buttonBackground'], dflt.buttonBackground),\n buttonText: sHex(root['buttonText'], dflt.buttonText),\n\n fontFamily: pickEnum<FontFamily>(root['fontFamily'], ALL_FONT_FAMILIES, dflt.fontFamily),\n headingWeight: pickEnum<FontWeight>(\n root['headingWeight'],\n ['regular', 'medium', 'semibold', 'bold'],\n dflt.headingWeight,\n ),\n\n radiusSurface: pickEnum<NonPillRadius>(\n root['radiusSurface'],\n NON_PILL_RADII,\n dflt.radiusSurface,\n ),\n radiusInput: pickEnum<NonPillRadius>(root['radiusInput'], NON_PILL_RADII, dflt.radiusInput),\n radiusButton: pickEnum<CornerRadius>(root['radiusButton'], ALL_RADII, dflt.radiusButton),\n radiusBadge: pickEnum<CornerRadius>(root['radiusBadge'], ALL_RADII, dflt.radiusBadge),\n surfaceStyle: pickEnum<SurfaceStyle>(\n root['surfaceStyle'],\n ['flat', 'outlined', 'elevated'],\n dflt.surfaceStyle,\n ),\n surfacePadding: pickEnum<SpacingScale>(\n root['surfacePadding'],\n ['compact', 'comfortable', 'spacious'],\n dflt.surfacePadding,\n ),\n verticalGap: pickEnum<SpacingScale>(\n root['verticalGap'],\n ['compact', 'comfortable', 'spacious'],\n dflt.verticalGap,\n ),\n inputSize: pickEnum<SizeScale>(root['inputSize'], ['sm', 'md', 'lg'], dflt.inputSize),\n buttonSize: pickEnum<SizeScale>(root['buttonSize'], ['sm', 'md', 'lg'], dflt.buttonSize),\n\n showSurcharge: parseBool(root['showSurcharge'], dflt.showSurcharge),\n surchargePosition: pickEnum<SurchargePosition>(\n root['surchargePosition'],\n SURCHARGE_POSITIONS,\n dflt.surchargePosition,\n ),\n surchargeStyle: pickEnum<SurchargeStyle>(\n root['surchargeStyle'],\n SURCHARGE_STYLES,\n dflt.surchargeStyle,\n ),\n surchargeSize: pickEnum<SurchargeSize>(\n root['surchargeSize'],\n SURCHARGE_SIZES,\n dflt.surchargeSize,\n ),\n surchargeShape: pickEnum<SurchargeShape>(\n root['surchargeShape'],\n SURCHARGE_SHAPES,\n dflt.surchargeShape,\n ),\n surchargeBorderWidth: pickEnum<SurchargeBorderWidth>(\n root['surchargeBorderWidth'],\n SURCHARGE_BORDER_WIDTHS,\n dflt.surchargeBorderWidth,\n ),\n surchargeBorderStyle: pickEnum<SurchargeBorderStyle>(\n root['surchargeBorderStyle'],\n SURCHARGE_BORDER_STYLES,\n dflt.surchargeBorderStyle,\n ),\n surchargeWeight: pickEnum<SurchargeWeight>(\n root['surchargeWeight'],\n SURCHARGE_WEIGHTS,\n dflt.surchargeWeight,\n ),\n surchargeSign: pickEnum<SurchargeSign>(\n root['surchargeSign'],\n SURCHARGE_SIGNS,\n dflt.surchargeSign,\n ),\n surchargeUppercase: parseBool(root['surchargeUppercase'], dflt.surchargeUppercase),\n surchargeLabel: pickEnum<SurchargeLabelMode>(\n root['surchargeLabel'],\n SURCHARGE_LABEL_MODES,\n dflt.surchargeLabel,\n ),\n surchargeFigure: pickEnum<SurchargeFigureMode>(\n root['surchargeFigure'],\n SURCHARGE_FIGURE_MODES,\n dflt.surchargeFigure,\n ),\n discountFigure: pickEnum<SurchargeFigureMode>(\n root['discountFigure'],\n SURCHARGE_FIGURE_MODES,\n dflt.discountFigure,\n ),\n surchargeWordTranslations: parseTranslations(root['surchargeWordTranslations']),\n discountWordTranslations: parseTranslations(root['discountWordTranslations']),\n headerTextTranslations: parseTranslations(root['headerTextTranslations']),\n payButtonLabelTranslations: parseTranslations(root['payButtonLabelTranslations']),\n cardTermsMessageTranslations: parseTranslations(root['cardTermsMessageTranslations']),\n footerTextTranslations: parseTranslations(root['footerTextTranslations']),\n surchargeColor: sHex(root['surchargeColor'], dflt.surchargeColor),\n discountColor: sHex(root['discountColor'], dflt.discountColor),\n\n layout: pickEnum<LayoutStyle>(root['layout'], ['compact', 'split'], dflt.layout),\n summaryPosition: pickEnum<SummaryPosition>(\n root['summaryPosition'],\n ['left', 'right'],\n dflt.summaryPosition,\n ),\n showOrderSummary: parseBool(root['showOrderSummary'], dflt.showOrderSummary),\n summaryGradient: parseBool(root['summaryGradient'], dflt.summaryGradient),\n showTotal: parseBool(root['showTotal'], dflt.showTotal),\n totalLabel: sStr(root['totalLabel'], dflt.totalLabel),\n showCurrencyCode: parseBool(root['showCurrencyCode'], dflt.showCurrencyCode),\n showOrderItems: parseBool(root['showOrderItems'], dflt.showOrderItems),\n\n trustBadges,\n customFields,\n\n headerText: sStr(root['headerText'], dflt.headerText),\n payButtonLabel: sStr(root['payButtonLabel'], dflt.payButtonLabel),\n cardTermsMessage: sStr(root['cardTermsMessage'], dflt.cardTermsMessage),\n footerText: sStr(root['footerText'], dflt.footerText),\n supportEmail: sStr(root['supportEmail'], dflt.supportEmail),\n\n paymentLayout: pickEnum<PaymentLayout>(\n root['paymentLayout'],\n ['tabs', 'accordion', 'spaced_accordion'],\n dflt.paymentLayout,\n ),\n labelStyle,\n showPoweredBy: parseBool(root['showPoweredBy'], dflt.showPoweredBy),\n\n customCss: sStr(root['customCss'], dflt.customCss).slice(0, CUSTOM_CSS_MAX_LENGTH),\n };\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\n// Loose trust-badge parser used by the importer. Unlike `decodeBadges`\n// (which reads the JSON-stringified API bag), this accepts an array of\n// objects directly. Returns null when the input isn't an array — the\n// caller falls back to the default badge set; an explicit empty array is\n// honored.\nfunction parseTrustBadgesLoose(raw: unknown): TrustBadge[] | null {\n if (!Array.isArray(raw)) return null;\n return raw\n .filter(isObject)\n .map((b, i) => ({\n id: typeof b['id'] === 'string' && b['id'] ? (b['id'] as string) : `badge-${i}`,\n label: typeof b['label'] === 'string' ? (b['label'] as string) : '',\n textColor:\n typeof b['textColor'] === 'string' && isHexColor(b['textColor'] as string)\n ? (b['textColor'] as string)\n : '#0f172a',\n backgroundColor:\n typeof b['backgroundColor'] === 'string' && isHexColor(b['backgroundColor'] as string)\n ? (b['backgroundColor'] as string)\n : '#f1f5f9',\n borderColor:\n typeof b['borderColor'] === 'string' && isHexColor(b['borderColor'] as string)\n ? (b['borderColor'] as string)\n : null,\n }))\n .filter((b) => b.label.length > 0);\n}\n\n// --- DOM helpers --------------------------------------------------------\n\n// Write branding tokens onto a target element as CSS custom properties.\n// The buyer-facing checkout sets these on `<html>` so every component sees\n// the same set, including Stripe Elements (indirectly via\n// appearance.variables). The merchant control-center's preview component\n// uses an analogous `--p-*` set with `var(--dp-*, fallback)` indirection so\n// a custom-CSS rule like `:root{--dp-primary:red}` overrides the preview\n// without re-typing the whole brand.\nexport function applyBrandingVariables(el: HTMLElement, b: CheckoutBranding): void {\n const set = (k: string, v: string) => {\n el.style.setProperty(k, v);\n };\n\n set('--dp-primary', b.primary);\n set('--dp-bg', b.background);\n set('--dp-surface', b.surface);\n set('--dp-text', b.text);\n set('--dp-heading', b.heading);\n set('--dp-muted', b.muted);\n set('--dp-border', b.border);\n set('--dp-accent-text', b.accentText);\n set('--dp-btn-bg', b.buttonBackground);\n set('--dp-btn-fg', b.buttonText);\n\n set('--dp-radius-surface', radiusValue(b.radiusSurface));\n set('--dp-radius-input', radiusValue(b.radiusInput));\n set('--dp-radius-button', radiusValue(b.radiusButton));\n set('--dp-radius-badge', radiusValue(b.radiusBadge));\n\n set('--dp-font', fontStack(b.fontFamily));\n set('--dp-heading-weight', fontWeightValue(b.headingWeight));\n\n set('--dp-pad-surface', SURFACE_PAD[b.surfacePadding]);\n set('--dp-gap-vertical', VERTICAL_GAP[b.verticalGap]);\n set('--dp-input-pad', INPUT_PAD[b.inputSize]);\n set('--dp-button-pad', BUTTON_PAD[b.buttonSize]);\n\n // Published whatever `showSurcharge` says: the flag decides whether a figure\n // renders, not what colour it would be, and a stylesheet that reads the\n // variable must not get an empty string when the merchant has one configured.\n set('--dp-surcharge', b.surchargeColor);\n set('--dp-discount', b.discountColor);\n // What `solid` writes ON the fill. Computed here rather than in a stylesheet\n // because CSS cannot ask a colour how light it is, and picking one fixed ink\n // would make either a pale amber or a deep emerald unreadable.\n set('--dp-surcharge-ink', readableInkOn(b.surchargeColor));\n set('--dp-discount-ink', readableInkOn(b.discountColor));\n set('--dp-surcharge-size', SURCHARGE_FONT_SIZE[b.surchargeSize]);\n set('--dp-surcharge-pad', SURCHARGE_PAD[b.surchargeSize]);\n set('--dp-surcharge-radius', SURCHARGE_RADIUS[b.surchargeShape]);\n set('--dp-surcharge-weight', SURCHARGE_FONT_WEIGHT[b.surchargeWeight]);\n // `outline` draws nothing BUT its border, so `none` there would erase the\n // style rather than restyle it — it reads as `thin` instead.\n set(\n '--dp-surcharge-border-width',\n SURCHARGE_BORDER_WIDTH[\n b.surchargeStyle === 'outline' && b.surchargeBorderWidth === 'none'\n ? 'thin'\n : b.surchargeBorderWidth\n ],\n );\n set('--dp-surcharge-border-style', b.surchargeBorderStyle);\n\n set('--dp-shadow', shadowFor(b.surfaceStyle));\n set(\n '--dp-surface-border',\n b.surfaceStyle === 'outlined' ? `1px solid ${b.border}` : '1px solid transparent',\n );\n}\n\nexport function shadowFor(style: SurfaceStyle): string {\n switch (style) {\n case 'elevated':\n return '0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 32px -12px rgba(15, 23, 42, 0.08)';\n case 'outlined':\n case 'flat':\n default:\n return 'none';\n }\n}\n","import { Delopay } from './client';\nimport type { DelopayLogger, RequestExtras } from './client';\nimport { DelopayError } from './error';\nimport type {\n ConfirmSubscriptionRequest,\n ConfirmSubscriptionResponse,\n EpayoutsMethodsResponse,\n PaymentConfirmRequest,\n PaymentMethodListResponse,\n PaymentResponse,\n PaymentUpdateRequest,\n PayseproMethodsResponse,\n RecordCheckoutEventRequest,\n RecordCheckoutEventResponse,\n VaultCollectSessionResponse,\n VaultPaymentMethodRequest,\n VaultPaymentMethodResponse,\n} from './types';\n\n/**\n * A publishable (browser-safe) API key. The template type rejects secret\n * keys (`prd_…` / `snd_…`) at compile time, so a checkout cannot be handed\n * a credential that would reach secret-key routes.\n */\nexport type PublishableKey = `pk_${string}`;\n\n/**\n * Drop any caller-supplied credential headers (case-insensitively), so a\n * route can only ever carry the one credential its family requires — the\n * class's isolation guarantee must hold against per-call `headers` too.\n * Non-credential extras (`Idempotency-Key`, `X-Dp-*`, …) pass through.\n */\nfunction withoutCredentialHeaders(extra?: Record<string, string>): Record<string, string> {\n if (!extra) return {};\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(extra)) {\n const lower = key.toLowerCase();\n if (lower === 'api-key' || lower === 'authorization') continue;\n out[key] = value;\n }\n return out;\n}\n\n/** Drop one header (case-insensitively) from a caller-supplied extras map. */\nfunction withoutHeader(headers: Record<string, string>, name: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === name) continue;\n out[key] = value;\n }\n return out;\n}\n\n/** Configuration for a {@link CheckoutSession}. */\nexport interface CheckoutSessionOptions {\n /** The merchant the payment belongs to. */\n merchantId: string;\n /** The payment this session is about. */\n paymentId: string;\n /**\n * The merchant's publishable key (`pk_prd_…` / `pk_snd_…`), from the\n * checkout payload's `pub_key`. Required for the `/payments/*` and\n * `/payment-methods` calls.\n */\n publishableKey?: PublishableKey;\n /**\n * The payment's client secret, from the checkout payload. Required for\n * every `/payment-link/*` call, and rides along on the payment calls.\n */\n clientSecret?: string;\n /** Override the API base URL (e.g. `/api` behind a same-origin proxy). */\n baseUrl?: string;\n /** Use the sandbox environment. Ignored when `baseUrl` is set. */\n sandbox?: boolean;\n /** Per-request timeout in milliseconds. */\n timeout?: number;\n /** Maximum automatic retries for retryable requests. */\n maxRetries?: number;\n debug?: boolean;\n logger?: DelopayLogger;\n}\n\n/**\n * Buyer-side client for a single hosted-checkout payment.\n *\n * Binds the two browser-safe credentials once — the merchant's publishable\n * key and the payment's client secret — and sends each request with exactly\n * the credential its route expects:\n *\n * - `/payment-link/*` side-channel routes authenticate with\n * `Authorization: Bearer <client_secret>`.\n * - `/payments/*` and `/payment-methods` authenticate with the publishable\n * key in the `api-key` header, with the client secret as query parameter\n * or body field.\n *\n * Neither credential can reach a secret-key route: the publishable key is\n * typed to the `pk_` prefix and the client secret only ever leaves as a\n * bearer token / parameter, never as an `api-key`.\n *\n * @example\n * ```typescript\n * const session = new CheckoutSession({\n * merchantId: checkout.merchant_id,\n * paymentId: checkout.payment_id,\n * publishableKey: checkout.pub_key,\n * clientSecret: checkout.client_secret,\n * });\n * const catalog = await session.payseproMethods('de');\n * ```\n */\nexport class CheckoutSession {\n private readonly client: Delopay;\n private readonly merchantId: string;\n private readonly paymentId: string;\n private readonly publishableKey?: PublishableKey;\n private readonly clientSecret?: string;\n\n constructor(options: CheckoutSessionOptions) {\n this.merchantId = options.merchantId;\n this.paymentId = options.paymentId;\n this.publishableKey = options.publishableKey;\n this.clientSecret = options.clientSecret;\n // Constructed WITHOUT a key: every call attaches its own credential\n // explicitly, so a bearer-authenticated route never carries an api-key\n // header and vice versa.\n this.client = new Delopay('', {\n baseUrl: options.baseUrl,\n sandbox: options.sandbox,\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n debug: options.debug,\n logger: options.logger,\n });\n }\n\n private get linkBase(): string {\n return `/payment-link/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`;\n }\n\n /** Headers for the client-secret bearer routes (`/payment-link/*`). */\n private bearerHeaders(extra?: Record<string, string>): Record<string, string> {\n return {\n ...withoutCredentialHeaders(extra),\n Authorization: `Bearer ${this.requireClientSecret()}`,\n };\n }\n\n /** Headers for the publishable-key routes (`/payments/*`, `/payment-methods`). */\n private pkHeaders(extra?: Record<string, string>): Record<string, string> {\n if (!this.publishableKey) {\n throw new DelopayError('This call requires the publishable key', {\n status: 0,\n code: 'MISSING_CREDENTIAL',\n type: 'invalid_request',\n });\n }\n return { ...withoutCredentialHeaders(extra), 'api-key': this.publishableKey };\n }\n\n private requireClientSecret(): string {\n if (!this.clientSecret) {\n throw new DelopayError('This call requires the payment client secret', {\n status: 0,\n code: 'MISSING_CREDENTIAL',\n type: 'invalid_request',\n });\n }\n return this.clientSecret;\n }\n\n /**\n * The hosted checkout's bootstrap payload for a one-time payment —\n * `CheckoutDetails` while payable, a status view once settled.\n *\n * Deliberately unauthenticated: a `pay_` link bootstraps before any\n * credential exists, so no credential header is ever attached (caller\n * extras are still stripped of credentials). The response is a large\n * discriminated union owned by the consuming checkout, which keeps its\n * own types and runtime gates — hence the loose return type.\n *\n * `theme` is the route's one declared query parameter (a named checkout\n * variant). `locale` travels as `Accept-Language` — the only\n * channel the backend's locale resolution reads; a `?locale=` query is\n * silently ignored by this route.\n *\n * `GET /payment-link/data/{merchantId}/{paymentId}`\n */\n async fetchCheckoutData(\n params?: { locale?: string; theme?: string },\n options?: RequestExtras,\n ): Promise<Record<string, unknown>> {\n return this.client.request(\n 'GET',\n `/payment-link/data/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n query: { theme: params?.theme },\n ...options,\n headers: {\n ...(params?.locale\n ? {\n ...withoutHeader(withoutCredentialHeaders(options?.headers), 'accept-language'),\n 'Accept-Language': params.locale,\n }\n : withoutCredentialHeaders(options?.headers)),\n },\n },\n );\n }\n\n /**\n * The subscription twin of {@link CheckoutSession.fetchCheckoutData}: the\n * bootstrap payload for a `sub_` checkout. Authenticated with the\n * subscription's client secret (construct the session with the `sub_…` id\n * in the `paymentId` slot). `locale` travels as `Accept-Language`, same\n * as {@link CheckoutSession.fetchCheckoutData}.\n *\n * `GET /subscriptions/data/{merchantId}/{subscriptionId}`\n */\n async fetchSubscriptionData(\n params?: { locale?: string },\n options?: RequestExtras,\n ): Promise<Record<string, unknown>> {\n return this.client.request(\n 'GET',\n `/subscriptions/data/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n ...options,\n headers: {\n ...(params?.locale\n ? {\n ...withoutHeader(this.bearerHeaders(options?.headers), 'accept-language'),\n 'Accept-Language': params.locale,\n }\n : this.bearerHeaders(options?.headers)),\n },\n },\n );\n }\n\n /**\n * Report buyer/device signals for rails that never reach\n * `/payments/{id}/confirm` (the Stripe SAQ-A rail: raw cards, Apple Pay,\n * Google Pay). Same telemetry contract as\n * {@link CheckoutSession.recordEvent}: sent with `keepalive: true`, and\n * failures resolve instead of rejecting — signals must never block or\n * break a checkout. Unauthenticated by design.\n *\n * `POST /payment-link/client-signals/{merchantId}/{paymentId}`\n */\n async reportClientSignals(\n params: {\n browser_info?: Record<string, unknown>;\n signals: Record<string, unknown>;\n },\n options?: RequestExtras,\n ): Promise<void> {\n try {\n await this.client.request(\n 'POST',\n `/payment-link/client-signals/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n body: params,\n keepalive: true,\n ...options,\n headers: withoutCredentialHeaders(options?.headers),\n },\n );\n } catch {\n // Telemetry: swallowing is the contract, not an oversight.\n }\n }\n\n /**\n * Confirm a subscription (PayPal approval rail). The client secret is\n * attached automatically; the shop's profile id travels as the\n * `X-Profile-Id` header the subscription routes require.\n *\n * `POST /subscriptions/{subscriptionId}/confirm` (publishable key)\n */\n async confirmSubscription(\n subscriptionId: string,\n profileId: string,\n params: Omit<ConfirmSubscriptionRequest, 'client_secret'>,\n options?: RequestExtras,\n ): Promise<ConfirmSubscriptionResponse> {\n return this.client.request(\n 'POST',\n `/subscriptions/${encodeURIComponent(subscriptionId)}/confirm`,\n {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n // Strip any caller-supplied x-profile-id first (case-insensitively):\n // Fetch folds duplicate headers into `caller, pro_x`, and the\n // subscription routes must see exactly one profile scope.\n headers: {\n ...withoutHeader(this.pkHeaders(options?.headers), 'x-profile-id'),\n 'X-Profile-Id': profileId,\n },\n },\n );\n }\n\n /**\n * The Paysepro rail catalog for the buyer's country.\n *\n * `GET /payment-link/{merchantId}/{paymentId}/paysepro/methods`\n *\n * @param country - Lowercase ISO 3166-1 alpha-2 country code.\n */\n async payseproMethods(\n country: string,\n options?: RequestExtras,\n ): Promise<PayseproMethodsResponse> {\n return this.client.request('GET', `${this.linkBase}/paysepro/methods`, {\n query: { cc: country },\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * The e-Payouts rail catalog for the buyer's country, plus the set of\n * countries that have at least one vendor.\n *\n * `GET /payment-link/{merchantId}/{paymentId}/epayouts/methods`\n *\n * @param country - Lowercase ISO 3166-1 alpha-2 country code.\n */\n async epayoutsMethods(\n country: string,\n options?: RequestExtras,\n ): Promise<EpayoutsMethodsResponse> {\n return this.client.request('GET', `${this.linkBase}/epayouts/methods`, {\n query: { cc: country },\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Record a buyer-side checkout event on the payment's status timeline.\n *\n * Telemetry semantics, built in so callers can genuinely fire-and-forget:\n * the request is sent with `keepalive: true` (it survives the document\n * navigating away, e.g. right before a `window.open`), and transport or\n * server failures resolve to `undefined` instead of rejecting — telemetry\n * must never break a checkout or surface an unhandled rejection. Do not\n * `await` this in a click handler that must stay synchronous.\n *\n * A missing client secret still throws `MISSING_CREDENTIAL`: that is a\n * wiring bug, not a telemetry failure.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/checkout-events`\n */\n async recordEvent(\n params: RecordCheckoutEventRequest,\n options?: RequestExtras,\n ): Promise<RecordCheckoutEventResponse | undefined> {\n const headers = this.bearerHeaders(options?.headers);\n try {\n return await this.client.request('POST', `${this.linkBase}/checkout-events`, {\n body: params,\n keepalive: true,\n ...options,\n headers,\n });\n } catch {\n return undefined;\n }\n }\n\n /**\n * A short-lived VGS Collect session for browser-side card capture.\n *\n * **Exactly one refusal means \"this shop has no vault\": a 400 carrying\n * `IR_19`.** Every other refusal means a vault exists and could not be used,\n * and answering it by falling back to the processor's own card pane sends an\n * unprotected card number to the very processor the shop pays to hide it\n * from — the bug this endpoint's error contract exists to prevent.\n *\n * A **404 is not benign.** The router answers it when the shop's vault\n * account cannot be found — the state a shop is left in when its vault\n * connector is deleted while the profile keeps naming the id: it still\n * reports the vault as enabled and still expects its cards cloaked. The same\n * status also covers a payment that does not exist.\n *\n * `GET /payment-link/{merchantId}/{paymentId}/vault/collect-session`\n */\n async vaultCollectSession(options?: RequestExtras): Promise<VaultCollectSessionResponse> {\n return this.client.request('GET', `${this.linkBase}/vault/collect-session`, {\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Register the aliased card as a payment method and mint the one-shot\n * `payment_token` the confirm call spends.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/vault/payment-method`\n */\n async registerVaultPaymentMethod(\n params: VaultPaymentMethodRequest,\n options?: RequestExtras,\n ): Promise<VaultPaymentMethodResponse> {\n return this.client.request('POST', `${this.linkBase}/vault/payment-method`, {\n body: params,\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * The payment's current state — status polling for redirect/popup rails.\n *\n * `GET /payments/{paymentId}` (publishable key + client secret)\n */\n async retrievePayment(options?: RequestExtras): Promise<PaymentResponse> {\n return this.client.request('GET', `/payments/${encodeURIComponent(this.paymentId)}`, {\n query: { client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n\n /**\n * Update the payment before confirmation (e.g. persist custom-field\n * answers as `metadata` on rails that never hit `/confirm`). The client\n * secret is attached automatically.\n *\n * `POST /payments/{paymentId}` (publishable key)\n */\n async updatePayment(\n params: PaymentUpdateRequest,\n options?: RequestExtras,\n ): Promise<PaymentResponse> {\n return this.client.request('POST', `/payments/${encodeURIComponent(this.paymentId)}`, {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n\n /**\n * Confirm the payment. The client secret is attached automatically; pass\n * an `Idempotency-Key` header via `options` to make retries safe.\n *\n * `POST /payments/{paymentId}/confirm` (publishable key)\n */\n async confirmPayment(\n params: PaymentConfirmRequest,\n options?: RequestExtras,\n ): Promise<PaymentResponse> {\n return this.client.request('POST', `/payments/${encodeURIComponent(this.paymentId)}/confirm`, {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n\n /**\n * Payment methods available for this payment.\n *\n * `GET /payment-methods` (publishable key + client secret)\n *\n * @param params - Optional filters; `country` is the highest-precedence\n * geo hint, ahead of billing address and IP geolocation.\n */\n async listPaymentMethods(\n params?: { country?: string },\n options?: RequestExtras,\n ): Promise<PaymentMethodListResponse> {\n return this.client.request('GET', '/payment-methods', {\n query: { client_secret: this.requireClientSecret(), country: params?.country },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n}\n","// **Payment panes** — merchant-configured payment methods that render as\n// DeloPay-drawn tiles in the embedded checkout instead of inside a connector's\n// own embedded form.\n//\n// Why they exist: Stripe only offers Apple Pay / Google Pay / Link when the\n// *top-level* document's domain is registered as a payment method domain on the\n// merchant's Stripe account. In an embedded iframe that domain is the\n// merchant's shop, not the DeloPay checkout — so the wallet silently\n// disappears. A pane replaces it with our own tile that opens the DeloPay\n// hosted checkout at the top level, in a focused single-method view.\n//\n// Nothing here is Apple-Pay-specific, and since the router published a\n// per-connector capability catalogue nothing here is Stripe-specific either:\n// the feature is \"which of a connector's payment methods render as a pane, and\n// how they look\".\n//\n// This module serves SDK consumers: merchants configuring\n// `metadata.native_panes` on a merchant connector account programmatically\n// (codec), reading the resolved `native_panes` off a checkout payload\n// ({@link PaneView}), or building the focused single-method link that goes\n// behind their own button ({@link focusedCheckoutUrl}).\n//\n// The wire shapes are owned by the router (delopay-backend\n// `crates/router/src/core/payment_link/native_panes.rs`) — `native_panes` in\n// the metadata key, the field names and the enum values are contracts with it\n// and with links already in buyers' hands, so the identifiers here were renamed\n// off \"native pane\" and the wire was not.\n//\n// Capability (which connector may publish which method, on which rail) comes\n// from the router at runtime through `connectors.getPanesCatalog()`, not from a\n// table here.\n\n// Type-only, so this module still emits no imports and can be executed\n// standalone. `types.ts` owns the catalogue's wire shapes because they are\n// generated-spec-paired (`scripts/validate-types.ts`); it imports nothing from\n// here, so the dependency runs one way.\nimport type {\n PaneCapability,\n PaneRail,\n PanesCatalogResponse,\n PanesConnectorCatalog,\n PaneSurcharge,\n PaneView,\n PaneVisibility,\n PaneOpenTarget,\n SurchargeDirection,\n} from './types';\n\nexport type {\n PaneCapability,\n PaneRail,\n PanesCatalogResponse,\n PanesConnectorCatalog,\n PaneSurcharge,\n PaneView,\n PaneVisibility,\n PaneOpenTarget,\n SurchargeDirection,\n};\n\n// --- Wire types ---------------------------------------------------------\n\n/**\n * The values {@link decodePanes} recognises. Anything else — a value written by\n * a dashboard newer than this SDK — degrades to `always` rather than throwing\n * or dropping the row: an older SDK reading a newer blob is a normal state\n * during a rollout, and a hard failure there takes out a merchant's whole\n * connector config rather than one tile.\n */\nconst PANE_VISIBILITIES: readonly PaneVisibility[] = ['always', 'embedded_only', 'external_only'];\n\nfunction parseVisibility(raw: unknown): PaneVisibility {\n return PANE_VISIBILITIES.find((value) => value === raw) ?? 'always';\n}\n\n/**\n * One pane exactly as the merchant configures it. Persisted (JSON) under\n * `metadata.native_panes` on the merchant connector account.\n *\n * Field names are the wire contract — renaming one is a migration. The router\n * decodes strictly row by row: a row that fails strict decoding (e.g. a\n * wrong-typed field like `display_order: \"3\"`) is dropped whole with a server\n * log, and the remaining rows still render. This SDK's {@link decodePanes} is\n * additionally per-property tolerant — including clamping `display_order` into\n * the router's `i32` range — so a decode→encode round-trip through the SDK\n * repairs a blob the router would partially drop.\n */\nexport interface Pane {\n /** Catalogue key of the promoted method — see {@link paneMethodInfo}. */\n method: string;\n /** Disabled rows keep their tuning but never reach a buyer. */\n enabled: boolean;\n /** Default-language tile label. Empty falls back to the catalogue name. */\n label: string;\n /** Per-locale overrides of `label`, keyed by checkout locale (`de`, `de-AT`). */\n labelTranslations: Record<string, string>;\n /**\n * Secondary line under the label. `null` means \"use the catalogue default\";\n * an empty string means the merchant deliberately hid the line. That\n * distinction is the whole reason this is nullable and `label` is not.\n */\n sublabel: string | null;\n /** Per-locale overrides of `sublabel`. */\n sublabelTranslations: Record<string, string>;\n /** Section the tile groups under. Empty falls back to the catalogue category. */\n category: string;\n /** Built-in icon key — see {@link PANE_ICON_KEYS}. */\n icon: string;\n /** Custom inline SVG. Sanitized server-side before it reaches a buyer; a\n * rejected payload falls back to the built-in `icon`. */\n iconSvg: string;\n /** Lower renders first; ties break on catalogue order. */\n displayOrder: number;\n /** Where the tile is offered — see {@link PaneVisibility}. */\n visibility: PaneVisibility;\n /** How the embedded checkout opens the focused view — see {@link PaneOpenTarget}. */\n openIn: PaneOpenTarget;\n}\n\n/**\n * Read a resolved tile's placement rule, across every payload version.\n *\n * Prefer this to touching either field. They are independent on the wire — a\n * payload may carry either, both or neither — and each alone loses a placement\n * rule: `embedded_only` cannot express `external_only`, so an `external_only`\n * tile read through it renders inside the merchant iframe the merchant asked\n * to keep it out of; `visibility` is absent on a router that predates it, so\n * an `embedded_only` tile read through it alone renders at top level too,\n * duplicating a method Stripe's own form already offers there.\n *\n * A recognised `visibility` wins. Otherwise the legacy boolean answers: absent\n * (old router) it carries the only placement that router could express, and\n * unrecognised (newer router) the router still sets it under its own fixed\n * rule. Neither path throws, and both degrade toward showing a tile — losing a\n * placement rule, never stranding a method.\n */\nexport function paneViewVisibility(\n view: Pick<PaneView, 'visibility' | 'embedded_only'>,\n): PaneVisibility {\n const declared = PANE_VISIBILITIES.find((value) => value === view.visibility);\n if (declared) return declared;\n return view.embedded_only === true ? 'embedded_only' : 'always';\n}\n\n// --- Catalogue ----------------------------------------------------------\n\n/**\n * A method the frozen Stripe fallback table knows, with the compiled copy the\n * router shipped for it at the time.\n *\n * Only {@link STRIPE_FALLBACK_PANE_METHODS} is typed with this. The live\n * catalogue (`connectors.getPanesCatalog()`) carries capability facts and no\n * copy at all, by design — see {@link PaneCapability}.\n */\nexport interface PaneMethodInfo {\n key: string;\n rail: PaneRail;\n /** Confirm routing key. Pass through verbatim; never derive it. */\n paymentMethod: string;\n /** Confirm routing key. Pass through verbatim; never derive it. */\n paymentMethodType: string;\n /** The focused checkout has to collect a billing country to confirm this. */\n requiresBillingCountry: boolean;\n /** Catalogue default label, shown as the editor's placeholder. */\n defaultLabel: string;\n /** Catalogue default sub-text. */\n defaultSublabel: string;\n /** Catalogue default section. */\n defaultCategory: string;\n /** Catalogue default icon key. */\n defaultIcon: string;\n}\n\n/**\n * What this SDK assumes when the router cannot answer.\n *\n * The capability endpoint does not exist on an older router, which answers\n * `connectors.getPanesCatalog()` with a 404.\n * Rather than leaving a caller with nothing, the pane helpers default to\n * exactly the behaviour they had before that endpoint existed: panes on the\n * Stripe connector only, with the method set the router's Stripe catalogue had\n * at the time.\n *\n * **This is a degradation path, not a mirror. Do not keep it in sync by hand,\n * and do not add a connector or a method to it** — that is what this table was\n * before this ticket, and adding to it would quietly rebuild the mirror. A\n * connector the router serves panes for arrives through the endpoint and needs\n * no entry here; a connector that needs an entry here to appear is a connector\n * the router will not deliver panes for anyway.\n *\n * The only reason to touch this list is to correct what Stripe's catalogue\n * looked like *before* the endpoint existed, and that is history, so there is\n * no such reason. Once the endpoint is reachable it is never consulted for a\n * connector the router answered for.\n *\n * The redirect-rail set is deliberately narrow — every entry is a variant the\n * Stripe connector accepts and that needs no extra buyer input beyond a\n * billing country. `eps` / `p24` / `bancontact` are absent because Stripe\n * hard-requires billing fields the focused checkout never collects (a full\n * name for EPS and Bancontact, an email for Przelewy24), so their tiles could\n * never succeed.\n *\n * `defaultLabel` / `defaultSublabel` are the copy the router compiled at that\n * time and are frozen with the rest of the table. Copy for a method the live\n * catalogue reports belongs to the consumer's own locale files, keyed by\n * `key` — the router ships none.\n */\nexport const STRIPE_FALLBACK_PANE_METHODS: readonly PaneMethodInfo[] = [\n {\n key: 'apple_pay',\n rail: 'wallet',\n paymentMethod: 'wallet',\n paymentMethodType: 'apple_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Apple Pay',\n defaultSublabel: 'Pay with Apple Pay',\n defaultCategory: 'wallet',\n defaultIcon: 'apple',\n },\n {\n key: 'google_pay',\n rail: 'wallet',\n paymentMethod: 'wallet',\n paymentMethodType: 'google_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Google Pay',\n defaultSublabel: 'Pay with Google Pay',\n defaultCategory: 'wallet',\n defaultIcon: 'google',\n },\n {\n key: 'link',\n rail: 'wallet',\n paymentMethod: 'wallet',\n paymentMethodType: 'link',\n requiresBillingCountry: false,\n defaultLabel: 'Link',\n defaultSublabel: 'Pay with saved details',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n {\n key: 'klarna',\n rail: 'redirect',\n paymentMethod: 'pay_later',\n paymentMethodType: 'klarna',\n // Stripe's Klarna needs the buyer's country echoed into the confirm body.\n requiresBillingCountry: true,\n defaultLabel: 'Klarna',\n // NOT the router's current \"Pay later or in 3 instalments\". This table is\n // what a router predating the capability endpoint renders, and that copy\n // only gained the \"3\" in the same release that added the endpoint.\n // Restating the new string here\n // would put copy no reachable router emits in front of a merchant, and\n // would change what the deprecated `nativePaneMethodInfo` has returned\n // since 0.106.0.\n defaultSublabel: 'Pay later or in instalments',\n defaultCategory: 'bnpl',\n defaultIcon: 'bnpl',\n },\n {\n key: 'affirm',\n rail: 'redirect',\n paymentMethod: 'pay_later',\n paymentMethodType: 'affirm',\n requiresBillingCountry: false,\n defaultLabel: 'Affirm',\n defaultSublabel: 'Pay over time',\n defaultCategory: 'bnpl',\n defaultIcon: 'bnpl',\n },\n {\n key: 'ideal',\n rail: 'redirect',\n paymentMethod: 'bank_redirect',\n paymentMethodType: 'ideal',\n requiresBillingCountry: false,\n defaultLabel: 'iDEAL',\n defaultSublabel: 'Pay from your bank',\n defaultCategory: 'bank_redirect',\n defaultIcon: 'bank',\n },\n {\n key: 'alipay',\n rail: 'redirect',\n paymentMethod: 'wallet',\n paymentMethodType: 'ali_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Alipay',\n defaultSublabel: 'Pay with Alipay',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n {\n key: 'revolut_pay',\n rail: 'redirect',\n paymentMethod: 'wallet',\n paymentMethodType: 'revolut_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Revolut Pay',\n defaultSublabel: 'Pay with Revolut',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n {\n key: 'amazon_pay',\n rail: 'redirect',\n paymentMethod: 'wallet',\n paymentMethodType: 'amazon_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Amazon Pay',\n defaultSublabel: 'Pay with Amazon',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n];\n\n/**\n * {@link STRIPE_FALLBACK_PANE_METHODS} in the shape the live endpoint returns,\n * so every helper below takes one type of catalogue and the degradation path\n * is not a second code path. Derived, not written out: two spellings of one\n * table is exactly the drift this ticket removed.\n */\nexport const STRIPE_FALLBACK_PANE_CATALOG: PanesConnectorCatalog = {\n connector: 'stripe',\n allowed_rails: ['wallet', 'redirect'],\n methods: STRIPE_FALLBACK_PANE_METHODS.map((info) => ({\n key: info.key,\n rail: info.rail,\n payment_method: info.paymentMethod,\n payment_method_type: info.paymentMethodType,\n requires_billing_country: info.requiresBillingCountry,\n })),\n};\n\n/**\n * An empty catalogue — a connector the router does not offer panes for.\n * Exported so callers can express \"asked, and the answer was no\" without\n * reaching for `null` in the middle of a computation.\n */\nexport function emptyPaneCatalog(connector: string): PanesConnectorCatalog {\n return { connector, allowed_rails: [], methods: [] };\n}\n\n/**\n * Pull one connector's entry out of a `connectors.getPanesCatalog()` response.\n *\n * Returns {@link emptyPaneCatalog} for a connector the response does not name:\n * \"the router knows this connector and publishes no panes for it\" and \"the\n * router has never heard of it\" are the same answer to a caller building an\n * editor, and both mean \"offer nothing\".\n */\nexport function paneCatalogFor(\n response: PanesCatalogResponse,\n connector: string,\n): PanesConnectorCatalog {\n return (\n response.connectors.find((entry) => entry.connector === connector) ??\n emptyPaneCatalog(connector)\n );\n}\n\n/**\n * Built-in tile icon keys the buyer-facing checkout ships a glyph for.\n *\n * Reconciled against both ends: every key here has a branch in the checkout's\n * `NativePaneIcon.svelte`, and every `default_icon` the router's catalogue\n * publishes is in this list. An icon key the checkout does not ship falls\n * through to `wallet` there, so a key that drifts in renders as the wrong\n * glyph rather than as nothing.\n */\nexport const PANE_ICON_KEYS: readonly string[] = [\n 'wallet',\n 'card',\n 'bank',\n 'apple',\n 'google',\n 'bnpl',\n 'cash',\n // Brand marks, not category glyphs: the checkout draws PayPal's monogram,\n // Klarna's squircle-K and the Bitcoin mark for these, the same logos the\n // bespoke panes they replace already drew. Listed here so a merchant's own\n // dashboard can offer them; the router decides which one a tile *defaults*\n // to, and a router predating them simply keeps sending the old default.\n 'paypal',\n 'klarna',\n 'crypto',\n];\n\n/**\n * Section keys a pane's tile may group under.\n *\n * Reconciled against the router's actual `default_category` values rather than\n * against what the Stripe table happened to need. `crypto` and `game_items`\n * are router defaults (the Cryptomus/NowPayments and Skinsback catalogues) and\n * were missing here, so a merchant configuring one of those panes was shown a\n * category their editor did not recognise.\n *\n * A custom value is allowed and renders as its own section under that literal\n * text. The buyer-facing checkout translates a subset of these into a section\n * header and falls through to the raw key for the rest — `crypto` and\n * `game_items` are the two it has yet to add, tracked in delopay-checkout#70.\n */\nexport const PANE_CATEGORY_KEYS: readonly string[] = [\n 'wallet',\n 'card',\n 'bnpl',\n 'bank_redirect',\n 'bank_transfer',\n 'crypto',\n 'game_items',\n 'cash',\n];\n\n/**\n * Mirror of the router's per-connector cap. Counted differently on each side:\n * {@link decodePanes} stops after 12 *decoded* rows (entries with a usable,\n * non-duplicate `method` — junk and duplicate entries don't consume a slot),\n * while the router caps *accepted* panes (enabled, known, deduplicated) at 12\n * — so an oversized hand-written blob may render a pane this decoder drops.\n * Blobs the SDK itself encodes never exceed the cap.\n */\nexport const PANES_MAX = 12;\n\n/**\n * Look a method up in one connector's catalogue.\n *\n * Pass the entry for the connector being configured, from\n * `connectors.getPanesCatalog()` via {@link paneCatalogFor}. The default is\n * the degradation path and only correct for Stripe on a router that predates\n * the endpoint — see {@link STRIPE_FALLBACK_PANE_CATALOG}.\n */\nexport function paneMethodInfo(\n method: string,\n catalog: PanesConnectorCatalog = STRIPE_FALLBACK_PANE_CATALOG,\n): PaneCapability | undefined {\n return catalog.methods.find((info) => info.key === method);\n}\n\n/** Whether this connector may declare a pane on `rail` at all. A wallet pane\n * on a connector outside its `allowed_rails` is refused at save time — the\n * wallet rail rides on Stripe's Express Checkout Element charging the *same*\n * payment intent the embedded checkout holds, which does not generalise. */\nexport function paneRailAllowed(rail: PaneRail, catalog: PanesConnectorCatalog): boolean {\n return catalog.allowed_rails.includes(rail);\n}\n\n/**\n * The methods a caller may actually offer for this connector: the catalogue's\n * own list, minus anything on a rail the connector does not allow.\n *\n * The router should not report such a pair in the first place, but the two\n * fields are independent in the response and a save that crosses them is\n * refused at the API with an error naming the connector and the method. Filter\n * rather than trust, so a merchant never configures a tile the save will\n * bounce.\n */\nexport function offerablePaneMethods(catalog: PanesConnectorCatalog): PaneCapability[] {\n return catalog.methods.filter((info) => paneRailAllowed(info.rail, catalog));\n}\n\n/** Non-copy display defaults for a tile: which built-in glyph and which\n * section heading a new pane starts on. */\nexport interface PaneDisplayDefaults {\n icon: string;\n category: string;\n}\n\n/**\n * Per-method overrides, for the handful whose brand glyph is not what their\n * payment method would suggest. Everything else is derived from the catalogue\n * entry's `payment_method` below, so a connector the SDK has never heard of\n * still gets a sensible tile rather than a blank one.\n *\n * These have to be keyed by method and not by `payment_method`: `wallet` also\n * routes Link, Alipay, Revolut Pay and Amazon Pay, and `pay_later` also routes\n * Affirm — none of which the SDK has a mark for. Getting this wrong is not a\n * cosmetic slip that the next release fixes, because {@link defaultPane}\n * materialises the value and {@link encodePanes} writes it to\n * `metadata.native_panes`, where a stored `icon` outranks the router's\n * `default_icon` for the life of the pane.\n */\nconst DISPLAY_DEFAULTS_BY_KEY: Readonly<Record<string, PaneDisplayDefaults>> = {\n apple_pay: { icon: 'apple', category: 'wallet' },\n google_pay: { icon: 'google', category: 'wallet' },\n paypal: { icon: 'paypal', category: 'wallet' },\n // Both the Klarna connector's own tile and Stripe's Klarna. Affirm stays on\n // the generic `bnpl` glyph — same rail, no mark of its own.\n klarna: { icon: 'klarna', category: 'bnpl' },\n};\n\n/**\n * Derived from the `payment_method` half of the catalogue's routing pair.\n * Every value here reproduces the router's own `default_icon` /\n * `default_category` for the methods it publishes today, so a tile the SDK\n * lays out and a tile the router lays out agree.\n */\nconst DISPLAY_DEFAULTS_BY_PAYMENT_METHOD: Readonly<Record<string, PaneDisplayDefaults>> = {\n wallet: { icon: 'wallet', category: 'wallet' },\n card: { icon: 'card', category: 'card' },\n card_redirect: { icon: 'card', category: 'card' },\n pay_later: { icon: 'bnpl', category: 'bnpl' },\n bank_redirect: { icon: 'bank', category: 'bank_redirect' },\n bank_transfer: { icon: 'bank', category: 'bank_transfer' },\n bank_debit: { icon: 'bank', category: 'bank_transfer' },\n // Cryptomus and NowPayments publish the same `crypto` key on this rail, and\n // the router defaults both to the Bitcoin mark.\n crypto: { icon: 'crypto', category: 'crypto' },\n // Skinsback, which has no mark: the router defaults it to `wallet` too.\n game_items: { icon: 'wallet', category: 'game_items' },\n cash: { icon: 'cash', category: 'cash' },\n voucher: { icon: 'cash', category: 'cash' },\n};\n\nconst DISPLAY_DEFAULTS_FALLBACK: PaneDisplayDefaults = { icon: 'wallet', category: 'wallet' };\n\n/**\n * What a new tile looks like before the merchant designs it.\n *\n * The router serves capability, not presentation, so the glyph and the section\n * come from here and the accompanying text comes from the caller's own locale\n * files. A method with no entry at all still resolves — that is the point of\n * deriving from `payment_method`: a connector added to the router's catalogue\n * tomorrow needs no SDK release to be designable today.\n */\nexport function paneDisplayDefaults(info: PaneCapability | undefined): PaneDisplayDefaults {\n if (!info) return DISPLAY_DEFAULTS_FALLBACK;\n return (\n DISPLAY_DEFAULTS_BY_KEY[info.key] ??\n DISPLAY_DEFAULTS_BY_PAYMENT_METHOD[info.payment_method] ??\n DISPLAY_DEFAULTS_FALLBACK\n );\n}\n\n// --- Validation ---------------------------------------------------------\n\n/**\n * Why a configured pane would not survive a save or a render.\n *\n * - `method_unknown` — the connector's catalogue does not publish this key, so\n * the router drops the row at render.\n * - `rail_not_allowed` — the method's rail is not in the connector's\n * `allowed_rails`; the API refuses this at save time.\n * - `over_cap` — past the router's per-connector cap of {@link PANES_MAX}; the\n * row is stored but never rendered.\n * - `duplicate_method` — an earlier enabled row already claims this method.\n * The router skips disabled rows and then dedupes, so the first *enabled*\n * row renders and every later one is dropped in silence. Reported on the\n * losing rows, never on the one that survives.\n */\nexport type PaneIssueCode = 'method_unknown' | 'rail_not_allowed' | 'over_cap' | 'duplicate_method';\n\nexport interface PaneIssue {\n /** Index into the list handed to {@link validatePanes}. */\n index: number;\n method: string;\n code: PaneIssueCode;\n}\n\n/**\n * Check a configured list against one connector's catalogue, before writing it\n * to `metadata.native_panes`.\n *\n * The API applies the same rules at save time, so this changes where the\n * merchant finds out, not whether they do — and an SDK caller building an\n * editor would otherwise learn it from a bounced request with no row to point\n * at. An empty result means nothing here will be refused or silently dropped.\n */\nexport function validatePanes(\n panes: readonly Pane[],\n catalog: PanesConnectorCatalog = STRIPE_FALLBACK_PANE_CATALOG,\n): PaneIssue[] {\n const issues: PaneIssue[] = [];\n // Keyed on the catalogue's own key rather than the raw string, because that\n // is what the router dedupes on. Only enabled rows are recorded: a disabled\n // row never reaches the router's `seen` set, so it neither claims a method\n // nor loses to one.\n const claimedBy = new Set<string>();\n panes.forEach((pane, index) => {\n const info = paneMethodInfo(pane.method, catalog);\n if (!info) {\n issues.push({ index, method: pane.method, code: 'method_unknown' });\n } else if (!paneRailAllowed(info.rail, catalog)) {\n issues.push({ index, method: pane.method, code: 'rail_not_allowed' });\n } else if (pane.enabled) {\n // Unknown and rail-refused rows are dropped before the router dedupes,\n // so they cannot claim a key — and reporting two codes for one row would\n // point the merchant at the wrong repair.\n if (claimedBy.has(info.key)) {\n issues.push({ index, method: pane.method, code: 'duplicate_method' });\n } else {\n claimedBy.add(info.key);\n }\n }\n if (index >= PANES_MAX) issues.push({ index, method: pane.method, code: 'over_cap' });\n });\n return issues;\n}\n\n// --- Codec --------------------------------------------------------------\n\n/**\n * A new pane for `method`, with its glyph and section resolved from the\n * connector's catalogue entry rather than from a Stripe-keyed table — so\n * `defaultPane('creem_checkout', catalog)` is a designed tile and not a blank\n * one.\n *\n * Pass the catalogue entry for the connector being configured; the default is\n * the degradation path (see {@link STRIPE_FALLBACK_PANE_CATALOG}). Labels are\n * deliberately left empty: empty means \"use the catalogue default\", which the\n * router resolves at render, and the router ships no copy for a caller to\n * mirror.\n */\nexport function defaultPane(\n method: string,\n catalog: PanesConnectorCatalog = STRIPE_FALLBACK_PANE_CATALOG,\n): Pane {\n const defaults = paneDisplayDefaults(paneMethodInfo(method, catalog));\n return {\n method,\n enabled: true,\n label: '',\n labelTranslations: {},\n sublabel: null,\n sublabelTranslations: {},\n category: defaults.category,\n icon: defaults.icon,\n iconSvg: '',\n displayOrder: 0,\n visibility: 'always',\n openIn: 'tab',\n };\n}\n\nexport function clonePane(pane: Pane): Pane {\n return {\n ...pane,\n labelTranslations: { ...pane.labelTranslations },\n sublabelTranslations: { ...pane.sublabelTranslations },\n };\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseTranslations(raw: unknown): Record<string, string> {\n if (!isObject(raw)) return {};\n const out: Record<string, string> = {};\n for (const [locale, value] of Object.entries(raw)) {\n if (typeof value === 'string' && value.length > 0) out[locale] = value;\n }\n return out;\n}\n\nfunction str(raw: unknown): string {\n return typeof raw === 'string' ? raw : '';\n}\n\n// The router's wire type is an `i32` (`api_models` `display_order`), and a\n// fractional or out-of-range value fails its strict row decode — dropping the\n// whole row server-side while an SDK round-trip would keep the blob looking\n// healthy. Clamped on BOTH decode and encode so this codec never emits a\n// value the router rejects, regardless of where the number came from.\nconst DISPLAY_ORDER_MIN = -2147483648;\nconst DISPLAY_ORDER_MAX = 2147483647;\n\nfunction clampDisplayOrder(raw: number): number {\n if (!Number.isFinite(raw)) return 0;\n return Math.min(DISPLAY_ORDER_MAX, Math.max(DISPLAY_ORDER_MIN, Math.trunc(raw)));\n}\n\n/**\n * Decode the stored `metadata.native_panes` blob into editor rows.\n *\n * Tolerant like the branding codecs: anything malformed falls back per\n * property, rows without a usable `method` are dropped, duplicates keep the\n * first occurrence — except that an enabled row wins over an earlier disabled\n * one for the same method, because that is the row the router renders — and\n * decoding stops after {@link PANES_MAX} decoded rows (dropped junk/duplicate\n * entries don't consume a slot). That is more forgiving than the router, which\n * drops a strict-decode-failing row whole (keeping the rest) and caps accepted\n * panes rather than decoded rows — see {@link Pane} and {@link PANES_MAX}.\n * Returns `null` when the input is not an array so the caller can distinguish\n * \"never configured\" from \"cleared\".\n */\nexport function decodePanes(raw: unknown): Pane[] | null {\n if (!Array.isArray(raw)) return null;\n const decodeRow = (entry: Record<string, unknown>, method: string): Pane => ({\n method,\n enabled: entry['enabled'] !== false,\n label: str(entry['label']),\n labelTranslations: parseTranslations(entry['label_translations']),\n sublabel: typeof entry['sublabel'] === 'string' ? entry['sublabel'] : null,\n sublabelTranslations: parseTranslations(entry['sublabel_translations']),\n category: str(entry['category']),\n icon: str(entry['icon']),\n iconSvg: str(entry['icon_svg']),\n displayOrder: clampDisplayOrder(Number(entry['display_order'])),\n // Anything unrecognised degrades to `always` rather than dropping the row.\n visibility: parseVisibility(entry['visibility']),\n // Same tolerance: an unknown value degrades to the default `tab`.\n openIn: entry['open_in'] === 'popup' ? 'popup' : 'tab',\n });\n\n const indexByMethod = new Map<string, number>();\n const out: Pane[] = [];\n for (const entry of raw) {\n if (out.length >= PANES_MAX) break;\n if (!isObject(entry)) continue;\n const method = str(entry['method']).trim();\n if (!method) continue;\n const kept = indexByMethod.get(method);\n if (kept !== undefined) {\n // Duplicate method. Keep the row the ROUTER would render: it skips\n // disabled rows BEFORE deduping (`native_panes.rs`), so where a blob\n // holds both a disabled and an enabled row for one method, buyers see\n // the enabled one. Keeping the disabled row here would show the merchant\n // a pane that is off while it is live, and persist that on the next save.\n const enabled = entry['enabled'] !== false;\n const existing = out[kept];\n if (enabled && existing && !existing.enabled) out[kept] = decodeRow(entry, method);\n continue;\n }\n indexByMethod.set(method, out.length);\n out.push(decodeRow(entry, method));\n }\n return out;\n}\n\n/**\n * Encode editor rows back into the snake_case blob the connector account\n * stores. Empty optional strings are omitted so the metadata stays small and a\n * merchant who typed nothing round-trips as \"use the catalogue default\" rather\n * than as an explicit empty override.\n *\n * `sublabel` is the exception: an explicitly-empty value is preserved (as `\"\"`)\n * because that is how a merchant hides the second line.\n */\nexport function encodePanes(panes: Pane[]): Record<string, unknown>[] {\n const nonEmpty = (map: Record<string, string>): Record<string, string> | undefined => {\n const entries = Object.entries(map).filter(([, v]) => v.trim().length > 0);\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n };\n return panes.slice(0, PANES_MAX).map((pane) => {\n const labelTranslations = nonEmpty(pane.labelTranslations);\n const sublabelTranslations = nonEmpty(pane.sublabelTranslations);\n return {\n method: pane.method,\n enabled: pane.enabled,\n ...(pane.label.trim() ? { label: pane.label.trim() } : {}),\n ...(labelTranslations ? { label_translations: labelTranslations } : {}),\n // `null` omits the key entirely (catalogue default wins); `''` is sent\n // as-is because that is how the merchant hides the second line.\n ...(pane.sublabel !== null ? { sublabel: pane.sublabel } : {}),\n ...(sublabelTranslations ? { sublabel_translations: sublabelTranslations } : {}),\n ...(pane.category.trim() ? { category: pane.category.trim() } : {}),\n ...(pane.icon.trim() ? { icon: pane.icon.trim() } : {}),\n ...(pane.iconSvg.trim() ? { icon_svg: pane.iconSvg.trim() } : {}),\n // Clamped on encode too, not only decode: the router's strict i32 row\n // decode drops a row whole for a fractional or out-of-range value, so\n // writing e.g. 3.5 or Date.now() verbatim would silently delete the\n // pane at render while every read surface shows it healthy.\n display_order: clampDisplayOrder(pane.displayOrder),\n // Normalised on encode for the same reason `display_order` is clamped:\n // the router's strict row decode drops a row whole on a value outside\n // its enum, and a caller who built a `Pane` by hand (or in plain JS)\n // never went through `decodePanes`. A decoded pane always holds a valid\n // value, so this is a no-op on the round-trip path.\n visibility: parseVisibility(pane.visibility),\n open_in: pane.openIn === 'popup' ? 'popup' : 'tab',\n };\n });\n}\n\n// --- Focused checkout URL ----------------------------------------------\n\nexport interface FocusedCheckoutUrlParams {\n /** Base URL of the DeloPay hosted checkout, e.g. `https://checkout.delopay.net`. */\n checkoutBaseUrl: string;\n merchantId: string;\n paymentId: string;\n /** Pane method key to focus on (`apple_pay`, `klarna`, …). */\n method: string;\n /**\n * Connector that owns the tile, forwarded as `connector=`.\n *\n * A bare `pane=` resolves to the **first payable match in server-sorted\n * order**, which is unambiguous only while one connector publishes a given\n * key. Stripe publishes `klarna` and so does the Klarna connector, so a deep\n * link that names neither charges through whichever tile happens to sort\n * first. Name the connector whenever you know it.\n *\n * Optional because links minted before this parameter existed are already in\n * merchants' pages and still have to resolve.\n */\n connector?: string;\n /**\n * Merchant connector ACCOUNT that owns the tile, forwarded as `mca=`.\n *\n * Needed for the same reason `connector` is, one level down: a profile may\n * hold two enabled accounts of one connector, each publishing its own tile,\n * and the two links would otherwise be identical. Only meaningful alongside\n * `connector`.\n */\n merchantConnectorId?: string;\n /** Optional buyer locale, forwarded as `?locale=`. */\n locale?: string;\n /**\n * Set when the merchant's checkout-custom-field answers are already\n * persisted on the payment — forwarded as `cf=1` so the focused view skips\n * asking a second time. Purely a UI hint: the values live on the intent\n * either way, and the backend only accepts the merchant's configured field\n * keys from a client, so a wrongly-set flag can at worst skip an\n * informational prompt. This is the same hint the embedded pane sets when\n * it opens the focused view.\n */\n customFieldsCollected?: boolean;\n}\n\n/**\n * Build the link to the **focused single-method checkout**: the DeloPay hosted\n * checkout rendered with one payment method, one button, no picker.\n *\n * Two callers:\n * - the embedded checkout, which opens this in a new tab when a buyer clicks\n * a pane tile, and\n * - a merchant running their own checkout, who puts it behind their own\n * button — the same mechanism without an iframe.\n *\n * `method` is not limited to configured panes. A configured pane gets the\n * focused one-button view; `card`, `paypal`, `crypto_currency` and the\n * local-methods catalogs (by method key or vendor code) open the checkout\n * pinned to that method. Methods that exist only as a tab inside a connector's\n * own embedded form — iDEAL, Bancontact, P24 and the like, unless promoted to\n * a pane — cannot be isolated, because the connector owns that surface. An\n * unknown or unavailable method is never a dead end: the checkout shows a\n * notice with a visible \"show all payment methods\" action.\n *\n * Pass {@link FocusedCheckoutUrlParams.connector} (and\n * {@link FocusedCheckoutUrlParams.merchantConnectorId}) whenever you know\n * them. Without them the method key alone picks the first payable match, and\n * more than one connector can publish the same key. Omitting them produces\n * exactly the URL this function has always produced, so links already minted\n * are unaffected.\n *\n * Open it **at the top level** (a new tab or a full-page navigation). The whole\n * point is that the top-level domain is the registered payment method domain;\n * rendering it in an iframe puts you back where you started.\n *\n * If you open it with `window.open`, call that **synchronously inside the click\n * handler** or the popup blocker will eat it, and make sure any iframe you\n * render DeloPay in permits popups (`allow-popups`, plus\n * `allow-popups-to-escape-sandbox` under a restrictive `sandbox`).\n */\nexport function focusedCheckoutUrl(params: FocusedCheckoutUrlParams): string {\n const base = params.checkoutBaseUrl.replace(/\\/+$/, '');\n const path = `${base}/pay/${encodeURIComponent(params.merchantId)}/${encodeURIComponent(\n params.paymentId,\n )}`;\n const query = new URLSearchParams({ pane: params.method });\n // Parameter order matches the embedded checkout's own `focusedUrl`\n // (`NativePanesPane.svelte`), so a merchant's deep link and a tile click\n // produce the same string for the same tile. A blank value is treated as\n // absent rather than emitted empty: `connector=` would otherwise read as a\n // connector named \"\" instead of as \"not specified\".\n const connector = params.connector?.trim();\n if (connector) query.set('connector', connector);\n const merchantConnectorId = params.merchantConnectorId?.trim();\n if (merchantConnectorId) query.set('mca', merchantConnectorId);\n if (params.locale) query.set('locale', params.locale);\n if (params.customFieldsCollected) query.set('cf', '1');\n return `${path}?${query.toString()}`;\n}\n\n// --- Buyer-side checkout events ----------------------------------------\n\n/**\n * The closed vocabulary of buyer-side checkout events recorded on the payment's\n * status timeline. Written through\n * `POST /payment-link/{merchant_id}/{payment_id}/checkout-events`, authorized\n * with the payment's `client_secret` as a bearer token.\n *\n * The `native_pane_` prefix is the router's enum on the wire and does not move\n * with the rename — see the module header.\n */\nexport const CHECKOUT_EVENT_KINDS = [\n 'native_pane_selected',\n 'native_pane_tab_opened',\n 'native_pane_tab_blocked',\n 'native_pane_abandoned',\n 'native_pane_returned',\n] as const;\n\nexport type CheckoutEventKind = (typeof CHECKOUT_EVENT_KINDS)[number];\n\n// --- Deprecated aliases -------------------------------------------------\n//\n// The pre-0.109.0 names, kept so an external `@delopay/sdk` consumer upgrades\n// on their own schedule rather than on ours. **Scheduled for removal in\n// 0.112.0** — see CHANGELOG.md. Nothing in this repo uses them.\n\n/** @deprecated Renamed to {@link Pane}. Removed in 0.112.0. */\nexport type StripeNativePane = Pane;\n/** @deprecated Renamed to {@link PaneView}. Removed in 0.112.0. */\nexport type NativePaneView = PaneView;\n/** @deprecated Renamed to {@link PaneVisibility}. Removed in 0.112.0. */\nexport type NativePaneVisibility = PaneVisibility;\n/** @deprecated Renamed to {@link PaneOpenTarget}. Removed in 0.112.0. */\nexport type NativePaneOpenTarget = PaneOpenTarget;\n/**\n * @deprecated Superseded by {@link PaneMethodInfo}. Removed in 0.112.0.\n *\n * Deliberately **not** an alias of `PaneMethodInfo`: that type gained three\n * required routing fields (`paymentMethod`, `paymentMethodType`,\n * `requiresBillingCountry`), and a consumer who wrote an object literal or a\n * function return against the 0.108 shape would stop compiling on a deprecated\n * name that promises the opposite. This stays the six fields that shape had.\n *\n * `PaneMethodInfo` is structurally assignable to it, so everything this SDK\n * hands back — including {@link nativePaneMethodInfo} — still satisfies it.\n */\nexport interface NativePaneMethodInfo {\n key: string;\n rail: PaneRail;\n /** Catalogue default label, shown as the editor's placeholder. */\n defaultLabel: string;\n /** Catalogue default sub-text. */\n defaultSublabel: string;\n /** Catalogue default section. */\n defaultCategory: string;\n /** Catalogue default icon key. */\n defaultIcon: string;\n}\n\n/**\n * @deprecated Renamed to {@link STRIPE_FALLBACK_PANE_METHODS}, which is a\n * degradation path and not a catalogue mirror. Removed in 0.112.0.\n */\nexport const STRIPE_NATIVE_PANE_METHODS = STRIPE_FALLBACK_PANE_METHODS;\n/** @deprecated Renamed to {@link PANE_ICON_KEYS}. Removed in 0.112.0. */\nexport const NATIVE_PANE_ICON_KEYS = PANE_ICON_KEYS;\n/** @deprecated Renamed to {@link PANE_CATEGORY_KEYS}. Removed in 0.112.0. */\nexport const NATIVE_PANE_CATEGORY_KEYS = PANE_CATEGORY_KEYS;\n/** @deprecated Renamed to {@link PANES_MAX}. Removed in 0.112.0. */\nexport const NATIVE_PANES_MAX = PANES_MAX;\n\n/**\n * @deprecated Superseded by {@link paneMethodInfo}, which takes the connector's\n * catalogue and answers for every connector rather than only for Stripe.\n * Removed in 0.112.0.\n *\n * Kept as its own function rather than as an alias because it must keep its\n * old return type: it answers out of the frozen Stripe table and carries that\n * table's compiled copy, which the live catalogue deliberately does not have.\n */\nexport function nativePaneMethodInfo(method: string): PaneMethodInfo | undefined {\n return STRIPE_FALLBACK_PANE_METHODS.find((info) => info.key === method);\n}\n\n/**\n * @deprecated Superseded by {@link defaultPane}. Removed in 0.112.0.\n *\n * Kept as its own function rather than as an alias because it must keep its\n * old behaviour: it leaves `category` empty and resolves `icon` out of the\n * frozen Stripe table only. `defaultPane` fills both from the connector's\n * catalogue, which is the fix — but a caller on the old name encodes whatever\n * it is handed, and quietly turning a blank field into a stored override is\n * not something a deprecated alias should do to a merchant's saved config.\n */\nexport function defaultNativePane(method: string): Pane {\n const info = nativePaneMethodInfo(method);\n return {\n ...defaultPane(method),\n category: '',\n icon: info?.defaultIcon ?? '',\n };\n}\n\n/** @deprecated Renamed to {@link clonePane}. Removed in 0.112.0. */\nexport const cloneNativePane = clonePane;\n/** @deprecated Renamed to {@link decodePanes}. Removed in 0.112.0. */\nexport const decodeNativePanes = decodePanes;\n/** @deprecated Renamed to {@link encodePanes}. Removed in 0.112.0. */\nexport const encodeNativePanes = encodePanes;\n"],"mappings":"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","names":["isObject","parseTranslations"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/error.ts","../src/resources/apiKeys.ts","../src/resources/authentication.ts","../src/resources/billing.ts","../src/resources/blocklist.ts","../src/resources/connectors.ts","../src/resources/customers.ts","../src/resources/disputes.ts","../src/resources/ephemeralKeys.ts","../src/resources/events.ts","../src/resources/fees.ts","../src/resources/mandates.ts","../src/resources/merchantAccounts.ts","../src/resources/paymentLinks.ts","../src/resources/paymentMethods.ts","../src/resources/payments.ts","../src/resources/payouts.ts","../src/resources/poll.ts","../src/resources/profileAcquirers.ts","../src/resources/profiles.ts","../src/resources/projects.ts","../src/resources/refunds.ts","../src/resources/relay.ts","../src/resources/routing.ts","../src/resources/search.ts","../src/resources/shops.ts","../src/resources/stripeConnect.ts","../src/resources/threeDsRules.ts","../src/resources/users.ts","../src/resources/verification.ts","../src/resources/webhooks.ts","../src/resources/analytics.ts","../src/resources/analyticsDashboard.ts","../src/resources/cards.ts","../src/resources/export.ts","../src/resources/featureMatrix.ts","../src/resources/files.ts","../src/resources/forex.ts","../src/resources/regions.ts","../src/resources/availabilityOverrides.ts","../src/resources/subscriptions.ts","../src/resources/audit.ts","../src/resources/settlement.ts","../src/resources/operationLimits.ts","../src/resources/risk.ts","../src/client.ts","../src/feeProgram.ts","../src/branding.ts","../src/checkoutSession.ts","../src/panes.ts"],"sourcesContent":["export { Delopay } from './client';\nexport type {\n DelopayOptions,\n RequestOptions,\n RequestExtras,\n RequestFn,\n DelopayLogger,\n} from './client';\nexport { DelopayError, DelopayAuthenticationError } from './error';\nexport type * from './types';\nexport { Webhooks } from './resources/webhooks';\nexport type { WebhookEvent } from './resources/webhooks';\n\n// Platform fee-rule engine: builder for the Euclid fee program consumed by\n// `delopay.fees.rules.upsert(...)` (and the admin `platformFees.rules`).\nexport {\n feeProgram,\n FeeProgramBuilder,\n leaf,\n allOf,\n anyOf,\n programToTree,\n ruleMatchToTree,\n} from './feeProgram';\nexport type {\n FeeSpecInput,\n FeeRuleInput,\n FeeRuleConditions,\n ConditionNode,\n LeafNode,\n GroupNode,\n} from './feeProgram';\n\n// Checkout branding — shared between the buyer-facing checkout\n// (delopay-checkout) and the merchant control-center's branding form so\n// the form saves what the checkout can read back, and vice versa.\nexport {\n fontStack,\n radiusValue,\n fontWeightValue,\n surfacePadValue,\n verticalGapValue,\n inputPadValue,\n buttonPadValue,\n logoDimensions,\n isHexColor,\n isDarkSurface,\n contrastRatio,\n WCAG_AA_TEXT,\n SURCHARGE_POSITIONS,\n SURCHARGE_STYLES,\n SURCHARGE_SIZES,\n SURCHARGE_SHAPES,\n SURCHARGE_BORDER_WIDTHS,\n SURCHARGE_BORDER_STYLES,\n SURCHARGE_WEIGHTS,\n SURCHARGE_SIGNS,\n SURCHARGE_LABEL_MODES,\n readableInkOn,\n surchargeShowsLabel,\n surchargeFigurePlan,\n surchargeWordFor,\n checkoutCopy,\n copyTranslationsKey,\n CHECKOUT_LOCALES,\n LOCALIZABLE_COPY_FIELDS,\n SURCHARGE_FIGURE_MODES,\n surchargeStyleDrawsAShape,\n WCAG_AA_UI,\n shadowFor,\n sanitizeCustomCss,\n applyBrandingVariables,\n decodeBadges,\n encodeBadges,\n decodeCustomFields,\n encodeCustomFields,\n parseCustomFieldsLoose,\n customFieldText,\n customFieldOptionLabel,\n cloneCustomField,\n defaultCustomFieldVisibility,\n defaultOperatorForSource,\n customFieldOperatorTakesValue,\n customFieldIsTextLike,\n isCheckboxChecked,\n customFieldContextFromMetadata,\n evaluateCustomFieldCondition,\n evaluateCustomFieldVisibility,\n visibleCustomFields,\n decodeBranding,\n encodeBranding,\n cloneBranding,\n defaultBranding,\n buildBrandingExport,\n parseImportedBranding,\n DEFAULT_BRANDING,\n DEFAULT_BRANDING_DARK,\n DEFAULT_BADGES,\n DEFAULT_BADGES_DARK,\n CUSTOM_CSS_MAX_LENGTH,\n CUSTOM_FIELDS_MAX,\n CUSTOM_FIELD_KEY_PATTERN,\n ALL_CUSTOM_FIELD_TYPES,\n CHECKBOX_CHECKED,\n CHECKBOX_UNCHECKED,\n CUSTOM_FIELD_CONDITIONS_MAX,\n ALL_CUSTOM_FIELD_CONDITION_SOURCES,\n ALL_CUSTOM_FIELD_OPERATORS,\n CUSTOM_FIELD_OPERATORS_BY_SOURCE,\n CUSTOM_FIELD_VALUELESS_OPERATORS,\n BRANDING_EXPORT_FORMAT,\n BRANDING_EXPORT_VERSION,\n} from './branding';\nexport type {\n CheckoutBranding,\n TrustBadge,\n CheckoutCustomField,\n CustomFieldType,\n CustomFieldOption,\n CustomFieldTranslations,\n CustomFieldCondition,\n CustomFieldConditionSource,\n CustomFieldOperator,\n CustomFieldVisibility,\n CustomFieldContext,\n CornerRadius,\n NonPillRadius,\n SpacingScale,\n SizeScale,\n SurfaceStyle,\n FontFamily,\n FontWeight,\n LayoutStyle,\n SummaryPosition,\n SurchargePosition,\n SurchargeStyle,\n SurchargeSize,\n SurchargeShape,\n SurchargeBorderWidth,\n SurchargeBorderStyle,\n SurchargeWeight,\n SurchargeSign,\n SurchargeLabelMode,\n SurchargeFigureMode,\n SurchargeFigurePart,\n SurchargeFigurePlan,\n CheckoutLocale,\n LocalizableCopyField,\n LabelStyle,\n PaymentLayout,\n LogoShape,\n LogoSize,\n BrandingSource,\n EncodedBranding,\n BrandingExport,\n} from './branding';\n\n// New resources (Phases 3-4)\nexport { Analytics } from './resources/analytics';\nexport { AnalyticsDashboard } from './resources/analyticsDashboard';\nexport { Cards } from './resources/cards';\nexport { Export } from './resources/export';\nexport { FeatureMatrix } from './resources/featureMatrix';\nexport { Files } from './resources/files';\nexport { Forex } from './resources/forex';\nexport { Regions } from './resources/regions';\nexport { AvailabilityOverrides } from './resources/availabilityOverrides';\nexport { Subscriptions } from './resources/subscriptions';\nexport { Audit } from './resources/audit';\nexport { Settlement } from './resources/settlement';\nexport { OperationLimits } from './resources/operationLimits';\nexport { Risk } from './resources/risk';\nexport { Search } from './resources/search';\n\n// Buyer-side client for a single hosted-checkout payment: binds the\n// publishable key + client secret once and gives each route exactly the\n// credential it expects.\nexport { CheckoutSession } from './checkoutSession';\nexport type { CheckoutSessionOptions, PublishableKey } from './checkoutSession';\nexport type {\n SearchIndex,\n SearchStatus,\n SearchGroupResponse,\n GlobalSearchRequest,\n SearchTimeRange,\n} from './resources/search';\n\n// Payment panes — merchant-configured payment methods promoted out of a\n// connector's own embedded form into DeloPay-drawn tiles, plus the focused\n// single-method checkout link those tiles (and a merchant's own button) open.\nexport {\n STRIPE_FALLBACK_PANE_METHODS,\n STRIPE_FALLBACK_PANE_CATALOG,\n PANE_ICON_KEYS,\n PANE_CATEGORY_KEYS,\n PANES_MAX,\n CHECKOUT_EVENT_KINDS,\n emptyPaneCatalog,\n paneCatalogFor,\n paneMethodInfo,\n paneRailAllowed,\n offerablePaneMethods,\n paneDisplayDefaults,\n paneViewVisibility,\n validatePanes,\n defaultPane,\n clonePane,\n decodePanes,\n encodePanes,\n focusedCheckoutUrl,\n} from './panes';\nexport type {\n Pane,\n PaneView,\n PaneVisibility,\n PaneOpenTarget,\n PaneMethodInfo,\n PaneDisplayDefaults,\n PaneIssue,\n PaneIssueCode,\n PaneSurcharge,\n FocusedCheckoutUrlParams,\n CheckoutEventKind,\n} from './panes';\n\n// Pre-0.109.0 pane names. Removed in 0.112.0 — see CHANGELOG.md.\n// The catalogue's own deprecated names (`NativePaneRail`, `NativePaneCapability`,\n// `NativePanesConnectorCatalog`, `NativePanesCatalogResponse`) come through the\n// `export type * from './types'` above.\nexport {\n STRIPE_NATIVE_PANE_METHODS,\n NATIVE_PANE_ICON_KEYS,\n NATIVE_PANE_CATEGORY_KEYS,\n NATIVE_PANES_MAX,\n nativePaneMethodInfo,\n defaultNativePane,\n cloneNativePane,\n decodeNativePanes,\n encodeNativePanes,\n} from './panes';\nexport type {\n NativePaneVisibility,\n NativePaneOpenTarget,\n NativePaneView,\n NativePaneMethodInfo,\n StripeNativePane,\n} from './panes';\n","/**\n * Error thrown when the Delopay API returns a non-2xx response, or when a\n * timeout or network error occurs.\n *\n * @example\n * ```typescript\n * try {\n * await delopay.payments.create({ amount: 5000, currency: 'EUR' });\n * } catch (e) {\n * if (e instanceof DelopayError) {\n * console.error(e.status, e.code, e.requestId, e.message);\n * }\n * }\n * ```\n */\nexport class DelopayError extends Error {\n /** HTTP status code returned by the API, or `0` for timeout/network errors. */\n readonly status: number;\n /** Machine-readable error code returned by the API (e.g. `'HE_00'`). */\n readonly code: string;\n /** Error category (e.g. `'invalid_request'`, `'timeout_error'`). */\n readonly type: string;\n /** Value of the `x-request-id` response header, when present. Include this when contacting support. */\n readonly requestId?: string;\n /**\n * Raw response body (truncated to ~2 KB). Populated when the server returns a\n * non-JSON error body (e.g. an HTML 502 from an upstream proxy) so debugging\n * still has something to go on.\n */\n readonly rawBody?: string;\n /**\n * Structured error context the API attaches under `error.data` for select\n * codes — e.g. `{ retry_after_secs: 248 }` on rate-limit / max-attempt\n * lockouts. Schema is per-code; consult the API reference for the shape.\n */\n readonly data?: Record<string, unknown>;\n\n constructor(\n message: string,\n options: {\n status: number;\n code: string;\n type: string;\n requestId?: string;\n rawBody?: string;\n data?: Record<string, unknown>;\n },\n ) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'DelopayError';\n this.status = options.status;\n this.code = options.code;\n this.type = options.type;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.rawBody !== undefined) this.rawBody = options.rawBody;\n if (options.data !== undefined) this.data = options.data;\n }\n}\n\n/**\n * Thrown when the API key is missing, invalid, or revoked (HTTP 401).\n *\n * @example\n * ```typescript\n * if (e instanceof DelopayAuthenticationError) {\n * // Prompt user to re-enter their API key.\n * }\n * ```\n */\nexport class DelopayAuthenticationError extends DelopayError {\n constructor(\n message = 'Invalid API key',\n options?: {\n code?: string;\n type?: string;\n requestId?: string;\n rawBody?: string;\n data?: Record<string, unknown>;\n },\n ) {\n super(message, {\n status: 401,\n // Default to the generic \"invalid API key\" code, but let callers pass\n // through the server-reported code (e.g. `UR_05` for unverified-email\n // 401s) so they can differentiate between auth failure reasons.\n code: options?.code || 'AUTH_01',\n type: options?.type || 'authentication_error',\n requestId: options?.requestId,\n rawBody: options?.rawBody,\n data: options?.data,\n });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'DelopayAuthenticationError';\n }\n}\n","import type {\n ApiKeyCreateRequest,\n ApiKeyCreateResponse,\n ApiKeyListConstraints,\n ApiKeyResponse,\n ApiKeyUpdateRequest,\n ApiKeyRevokeResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage API keys for a merchant account. */\nexport class ApiKeys {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new API key for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Key creation parameters (name, expiry, etc.).\n * @returns The newly created key including the plaintext secret (shown once only).\n *\n * @example\n * ```typescript\n * const { key_value } = await delopay.apiKeys.create('merch_123', { name: 'Production key' });\n * ```\n */\n async create(merchantId: string, params: ApiKeyCreateRequest): Promise<ApiKeyCreateResponse> {\n return this.request('POST', `/api-keys/${encodeURIComponent(merchantId)}`, { body: params });\n }\n\n /**\n * Retrieve metadata about an API key (does not return the plaintext secret).\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID.\n * @returns The API key metadata.\n */\n async retrieve(merchantId: string, keyId: string): Promise<ApiKeyResponse> {\n return this.request(\n 'GET',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * Update an API key's name or expiry.\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to update.\n * @param params - Fields to update.\n * @returns The updated API key metadata.\n */\n async update(\n merchantId: string,\n keyId: string,\n params: ApiKeyUpdateRequest,\n ): Promise<ApiKeyResponse> {\n return this.request(\n 'POST',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,\n { body: params },\n );\n }\n\n /**\n * Revoke an API key, immediately invalidating it.\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to revoke.\n * @returns Revocation confirmation.\n */\n async revoke(merchantId: string, keyId: string): Promise<ApiKeyRevokeResponse> {\n return this.request(\n 'DELETE',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * List all API keys for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns Array of API key metadata objects.\n */\n async list(merchantId: string): Promise<ApiKeyResponse[]> {\n return this.request('GET', `/api-keys/${encodeURIComponent(merchantId)}/list`);\n }\n\n // --- Profile-scoped (shop-level) API keys ---------------------------------\n //\n // JWT-authenticated routes under `/account/{merchantId}/profile/api-keys`.\n // The caller's shop (business profile) comes from the JWT, never from the\n // request, so a shop-scoped user can only mint/list/manage keys pinned to\n // their own shop. Requires a backend with profile-scoped API key support.\n\n /**\n * Create a new API key pinned to the caller's shop (business profile).\n * `POST /account/{merchantId}/profile/api-keys`\n *\n * @param merchantId - The merchant account ID.\n * @param params - Key creation parameters (name, expiry, etc.).\n * @returns The newly created key including the plaintext secret (shown once\n * only) and the `profile_id` it is pinned to.\n *\n * @example\n * ```typescript\n * const { api_key } = await delopay.apiKeys.createByProfile('merch_123', {\n * name: 'Shop key',\n * expiration: 'never',\n * });\n * ```\n */\n async createByProfile(\n merchantId: string,\n params: ApiKeyCreateRequest,\n ): Promise<ApiKeyCreateResponse> {\n return this.request('POST', `/account/${encodeURIComponent(merchantId)}/profile/api-keys`, {\n body: params,\n });\n }\n\n /**\n * List API keys pinned to the caller's shop (business profile) only.\n * `GET /account/{merchantId}/profile/api-keys`\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional pagination constraints (`limit`, `skip`).\n * @returns Array of API key metadata objects belonging to the caller's shop.\n */\n async listByProfile(\n merchantId: string,\n params?: ApiKeyListConstraints,\n ): Promise<ApiKeyResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(merchantId)}/profile/api-keys`, {\n query: params as Record<string, number | null | undefined>,\n });\n }\n\n /**\n * Retrieve metadata about a shop-pinned API key (does not return the\n * plaintext secret). `GET /account/{merchantId}/profile/api-keys/{keyId}`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID.\n * @returns The API key metadata.\n */\n async retrieveByProfile(merchantId: string, keyId: string): Promise<ApiKeyResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * Update a shop-pinned API key's name, description, or expiry.\n * `POST /account/{merchantId}/profile/api-keys/{keyId}`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to update.\n * @param params - Fields to update.\n * @returns The updated API key metadata.\n */\n async updateByProfile(\n merchantId: string,\n keyId: string,\n params: ApiKeyUpdateRequest,\n ): Promise<ApiKeyResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}`,\n { body: params },\n );\n }\n\n /**\n * Revoke a shop-pinned API key, immediately invalidating it.\n * `DELETE /account/{merchantId}/profile/api-keys/{keyId}`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to revoke.\n * @returns Revocation confirmation.\n */\n async revokeByProfile(merchantId: string, keyId: string): Promise<ApiKeyRevokeResponse> {\n return this.request(\n 'DELETE',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}`,\n );\n }\n}\n","import type { AuthenticationCreateRequest, AuthenticationResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Authentication {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: AuthenticationCreateRequest): Promise<AuthenticationResponse> {\n return this.request('POST', '/authentication', { body: params });\n }\n\n async checkEligibility(authId: string): Promise<AuthenticationResponse> {\n return this.request('POST', `/authentication/${encodeURIComponent(authId)}/eligibility`);\n }\n\n async authenticate(\n authId: string,\n params: Record<string, unknown>,\n ): Promise<AuthenticationResponse> {\n return this.request('POST', `/authentication/${encodeURIComponent(authId)}/authenticate`, {\n body: params,\n });\n }\n\n /** Sync authentication status. `POST /authentication/{merchantId}/{authId}/sync` */\n async sync(\n merchantId: string,\n authId: string,\n params?: Record<string, unknown>,\n ): Promise<AuthenticationResponse> {\n return this.request(\n 'POST',\n `/authentication/${encodeURIComponent(merchantId)}/${encodeURIComponent(authId)}/sync`,\n { body: params },\n );\n }\n\n /** Redirect after authentication. `POST /authentication/{merchantId}/{authId}/redirect` */\n async redirect(\n merchantId: string,\n authId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request(\n 'POST',\n `/authentication/${encodeURIComponent(merchantId)}/${encodeURIComponent(authId)}/redirect`,\n { body: params },\n );\n }\n\n /** Enable authn methods token. `POST /authentication/{authId}/enabled-authn-methods-token` */\n async enabledAuthnMethodsToken(\n authId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request(\n 'POST',\n `/authentication/${encodeURIComponent(authId)}/enabled-authn-methods-token`,\n {\n body: params,\n },\n );\n }\n\n /** Submit eligibility check. `POST /authentication/{authId}/eligibility-check` */\n async eligibilityCheck(\n authId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/authentication/${encodeURIComponent(authId)}/eligibility-check`, {\n body: params,\n });\n }\n}\n","import type {\n BillingProfileResponse,\n BillingSetupRequest,\n BillingSetupResponse,\n BillingCompleteSetupRequest,\n TopupRequest,\n TopupResponse,\n LedgerResponse,\n LedgerListParams,\n BlockedAttemptListResponse,\n BlockedAttemptListParams,\n AutoRechargeUpdateRequest,\n AllocationTransferRequest,\n AllocationTransferResponse,\n AllocationListResponse,\n AllocationResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Manage per-shop prepaid balance allocations transferred from the host merchant treasury. */\nclass BillingAllocations {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Transfer funds from the host merchant treasury into a shop's allocation.\n *\n * @param merchantId - The host merchant account ID.\n * @param params - Transfer details (amount, target profile/shop ID).\n * @returns The allocation transfer result.\n */\n async transferIn(\n merchantId: string,\n params: AllocationTransferRequest,\n ): Promise<AllocationTransferResponse> {\n return this.request(\n 'POST',\n `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-in`,\n { body: params },\n );\n }\n\n /**\n * Transfer funds from a shop's allocation back to the host merchant treasury.\n *\n * @param merchantId - The host merchant account ID.\n * @param params - Transfer details (amount, source profile/shop ID).\n * @returns The allocation transfer result.\n */\n async transferOut(\n merchantId: string,\n params: AllocationTransferRequest,\n ): Promise<AllocationTransferResponse> {\n return this.request(\n 'POST',\n `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-out`,\n {\n body: params,\n },\n );\n }\n\n /**\n * List all shop balance allocations for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns List of shop allocations.\n */\n async list(merchantId: string): Promise<AllocationListResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}/allocations`);\n }\n\n /**\n * Get the balance allocation for a specific shop.\n *\n * @param merchantId - The merchant account ID.\n * @param profileId - The shop (business profile) ID.\n * @returns The shop's balance allocation.\n */\n async get(merchantId: string, profileId: string): Promise<AllocationResponse> {\n return this.request(\n 'GET',\n `/billing/${encodeURIComponent(merchantId)}/allocations/${encodeURIComponent(profileId)}`,\n );\n }\n}\n\n/**\n * Manage prepaid billing balances — top-ups, card setup, auto-recharge, and the balance ledger.\n *\n * Delopay deducts a platform fee from the merchant's prepaid balance on every successful payment.\n * Use these endpoints to fund and monitor that balance.\n */\nexport class Billing {\n /** Per-shop balance allocation management for host merchants. */\n readonly allocations: BillingAllocations;\n\n constructor(private readonly request: RequestFn) {\n this.allocations = new BillingAllocations(request);\n }\n\n /**\n * Retrieve a merchant's billing profile (balance, status, auto-recharge config).\n *\n * @param merchantId - The merchant account ID.\n * @returns The billing profile.\n *\n * @example\n * ```typescript\n * const profile = await delopay.billing.getProfile('merch_123');\n * console.log(profile.balance, profile.status);\n * ```\n */\n async getProfile(merchantId: string): Promise<BillingProfileResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}`);\n }\n\n /**\n * Start a Stripe SetupIntent flow to collect a payment card for auto-recharge.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional setup parameters.\n * @returns The Stripe client secret needed to render the card element.\n */\n async setup(merchantId: string, params?: BillingSetupRequest): Promise<BillingSetupResponse> {\n return this.request('POST', `/billing/${encodeURIComponent(merchantId)}/setup`, {\n body: params,\n });\n }\n\n /**\n * Confirm card setup after the Stripe SetupIntent completes on the frontend.\n *\n * @param merchantId - The merchant account ID.\n * @param params - The Stripe SetupIntent ID to confirm.\n * @returns The updated billing profile.\n */\n async completeSetup(\n merchantId: string,\n params: BillingCompleteSetupRequest,\n ): Promise<BillingProfileResponse> {\n return this.request('POST', `/billing/${encodeURIComponent(merchantId)}/setup/complete`, {\n body: params,\n });\n }\n\n /**\n * Manually top up a merchant's prepaid balance by charging their saved card.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Top-up amount and currency.\n * @returns The top-up result.\n */\n async topup(merchantId: string, params: TopupRequest): Promise<TopupResponse> {\n return this.request('POST', `/billing/${encodeURIComponent(merchantId)}/topup`, {\n body: params,\n });\n }\n\n /**\n * List the balance ledger (credits and debits) for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional pagination parameters.\n * @returns The ledger entries.\n */\n async listLedger(merchantId: string, params?: LedgerListParams): Promise<LedgerResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}/ledger`, {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * List payment attempts that were blocked by the billing suspension gate\n * (account suspended, setup incomplete, or shop allocation suspended).\n *\n * These attempts never created a payment, so they do not appear in the\n * payments list — this is the only way to retrieve them.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional filters (profile, reason, date range) and pagination.\n * @returns The blocked-attempt entries with a total count.\n */\n async listBlockedAttempts(\n merchantId: string,\n params?: BlockedAttemptListParams,\n ): Promise<BlockedAttemptListResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}/blocked-attempts`, {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * Update auto-recharge configuration (threshold, top-up amount, enabled flag).\n *\n * @param merchantId - The merchant account ID.\n * @param params - Auto-recharge settings to update.\n * @returns The updated billing profile.\n */\n async updateAutoRecharge(\n merchantId: string,\n params: AutoRechargeUpdateRequest,\n ): Promise<BillingProfileResponse> {\n return this.request('PATCH', `/billing/${encodeURIComponent(merchantId)}/auto-recharge`, {\n body: params,\n });\n }\n}\n","import type { BlocklistAddRequest, BlocklistResponse, BlocklistDataKind } from '../types';\nimport type { RequestFn } from '../client';\n\nexport interface BlocklistListParams {\n data_kind?: BlocklistDataKind | null;\n limit?: number | null;\n offset?: number | null;\n}\n\nexport interface BlocklistToggleParams {\n status: boolean;\n}\n\nexport class Blocklist {\n constructor(private readonly request: RequestFn) {}\n\n async add(params: BlocklistAddRequest): Promise<BlocklistResponse> {\n return this.request('POST', '/blocklist', { body: params });\n }\n\n async remove(params: BlocklistAddRequest): Promise<BlocklistResponse> {\n return this.request('DELETE', '/blocklist', { body: params });\n }\n\n async list(params?: BlocklistListParams): Promise<BlocklistResponse[]> {\n return this.request('GET', '/blocklist', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n async toggle(params: BlocklistToggleParams): Promise<Record<string, unknown>> {\n return this.request('POST', '/blocklist/toggle', { body: params });\n }\n}\n","import type {\n ConnectorCloneRequest,\n EpayoutsCatalogResponse,\n PanesCatalogResponse,\n VaultRoutesApplyRequest,\n VaultRoutesApplyResponse,\n VaultRoutesPreviewRequest,\n VaultRoutesPreviewResponse,\n VaultVerificationResponse,\n VaultVerifyRequest,\n ConnectorCreateRequest,\n ConnectorResponse,\n ConnectorUpdateRequest,\n ConnectorWebhookListResponse,\n ConnectorWebhookRegisterRequest,\n ConnectorWebhookRegisterResponse,\n ConnectorWebhookSyncResponse,\n StripePaymentMethodDomainsRegisterRequest,\n StripePaymentMethodDomainsRegisterResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Connectors {\n constructor(private readonly request: RequestFn) {}\n\n async create(accountId: string, params: ConnectorCreateRequest): Promise<ConnectorResponse> {\n return this.request('POST', `/account/${encodeURIComponent(accountId)}/connectors`, {\n body: params,\n });\n }\n\n /**\n * One connector account.\n *\n * The credential-bearing fields come back `null` here, whatever is stored:\n * `connector_webhook_details`, `connector_wallets_details`,\n * `pm_auth_config` and `additional_merchant_data`. They are dropped rather\n * than masked, because an editor that prefills from this response and\n * PATCHes the field back would otherwise save a mask over a live signing\n * secret. Send those fields only when the operator has typed a new value,\n * and omit them entirely otherwise — an omitted field leaves the stored one\n * alone.\n *\n * This is the retrieve path alone. `create` and `update` echo back what the\n * caller sent, and `clone` returns the *copied* secrets — see that method.\n *\n * Because the value is gone, `has_live_webhook_secret` and\n * `has_sandbox_webhook_secret` are what tell a stored webhook signing secret\n * from an unconfigured one. Render those; never infer configuration from the\n * `null` block.\n *\n * `GET /account/{accountId}/connectors/{connectorId}`\n */\n async retrieve(accountId: string, connectorId: string): Promise<ConnectorResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,\n );\n }\n\n /**\n * The merchant's connector accounts.\n *\n * Never wider than the caller: an API key pinned to one shop lists that\n * shop's connectors only, not every sibling shop's.\n *\n * `GET /account/{accountId}/connectors`\n */\n async list(accountId: string): Promise<ConnectorResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/connectors`);\n }\n\n /**\n * The profile-scoped connector list. The merchant-wide `list()` is\n * merchant-gated and 403s for a profile-entity (shop user) JWT; this\n * variant is scoped server-side to the caller's own profile.\n *\n * `GET /account/{accountId}/profile/connectors`\n */\n async listByProfile(accountId: string): Promise<ConnectorResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/profile/connectors`);\n }\n\n /**\n * The built-in e-Payouts reference catalog — the \"Restore defaults\" source.\n * `GET /account/{accountId}/connectors/epayouts/catalog/defaults`\n */\n async getEpayoutsCatalogDefaults(accountId: string): Promise<EpayoutsCatalogResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/connectors/epayouts/catalog/defaults`,\n );\n }\n\n /**\n * Every connector's pane capabilities, as the router itself knows them —\n * which rails a connector supports, and which methods it can publish as a\n * pane with the confirm routing keys each one carries.\n *\n * Capability facts only: no label, sublabel or category comes back. A\n * designer renders a method's copy from its own locale files, keyed by\n * `key`, and takes `payment_method` / `payment_method_type` from here\n * verbatim rather than deriving them client-side.\n *\n * This is what the pane helpers in `src/panes.ts` should be driven from —\n * `paneMethodInfo`, `defaultPane` and `validatePanes` all take a\n * {@link PanesConnectorCatalog} out of this response, so a connector the\n * router starts publishing panes for needs no SDK release.\n *\n * `GET /account/{accountId}/connectors/native-panes/catalog`\n *\n * The path keeps the `native-panes` spelling deliberately. The identifiers\n * were renamed off \"native pane\"; the route was not, and pointing at the\n * backend's new name before it is deployed everywhere would both 404 against\n * un-upgraded replicas mid-rollout and fail `scripts/parity-check.mjs`,\n * which blocks publishing.\n */\n async getPanesCatalog(accountId: string): Promise<PanesCatalogResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/connectors/native-panes/catalog`,\n );\n }\n\n /** @deprecated Renamed to {@link getPanesCatalog}. Removed in 0.112.0. */\n async getNativePanesCatalog(accountId: string): Promise<PanesCatalogResponse> {\n return this.getPanesCatalog(accountId);\n }\n\n /**\n * Sweep the merchant's own e-Payouts module and return the rails it\n * actually has enabled. Server-side this makes many upstream calls, so it\n * can take several seconds — show progress.\n *\n * `POST /account/{accountId}/connectors/{connectorId}/epayouts/catalog/sync`\n */\n async syncEpayoutsCatalog(\n accountId: string,\n connectorId: string,\n ): Promise<EpayoutsCatalogResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/epayouts/catalog/sync`,\n );\n }\n\n /**\n * Update a connector account.\n *\n * `connector_webhook_details` **merges** into the stored block key by key:\n * an absent key keeps its stored secret, an explicit value is written, and\n * an explicit empty string clears that secret. Send only the\n * keys the operator typed — padding the other environment's keys with `''`\n * clears a live signing secret and inbound webhooks stop verifying.\n *\n * The other credential-bearing fields — `connector_wallets_details`,\n * `pm_auth_config`, `additional_merchant_data` — are still whole-value\n * replacements: omit them unless you are writing a complete new value.\n *\n * `POST /account/{accountId}/connectors/{connectorId}`\n */\n async update(\n accountId: string,\n connectorId: string,\n params: ConnectorUpdateRequest,\n ): Promise<ConnectorResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,\n {\n body: params,\n },\n );\n }\n\n /**\n * Remove a connector account.\n *\n * A shop-scoped role may remove a connector of its own shop — the shop is\n * re-checked server-side — so creating processors and removing them are the\n * same rung of access rather than two.\n *\n * `DELETE /account/{accountId}/connectors/{connectorId}`\n */\n async delete(accountId: string, connectorId: string): Promise<ConnectorResponse> {\n return this.request(\n 'DELETE',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,\n );\n }\n\n /**\n * Clone a connector into another shop (business profile) of the same\n * merchant. `POST /account/{accountId}/connectors/{connectorId}/clone`\n *\n * Credentials are copied server-side, re-encrypted under the same merchant\n * key, so the caller never has to *supply* them — `retrieve` returns `null`\n * for the credential fields, which is what makes a client-side copy\n * impossible in the first place.\n *\n * The response, however, is the unredacted connector: `connector_account_details`\n * is masked, but `connector_webhook_details`, `connector_wallets_details`,\n * `pm_auth_config` and `additional_merchant_data` come back with the copied\n * secrets in them — values this caller never sent. Do not log or echo the\n * response; read `merchant_connector_id` and discard the rest.\n */\n async clone(\n accountId: string,\n connectorId: string,\n params: ConnectorCloneRequest,\n ): Promise<ConnectorResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/clone`,\n { body: params },\n );\n }\n\n // --- Advanced operations (Task 4.8) ---\n\n /**\n * Run the configuration checks for a vault (VGS) connector account:\n * credential validity, write-only Collect scope, reachability, environment\n * coherence, route coverage. Read-only but not cheap — it decrypts the\n * vault's management credential and talks to VGS.\n *\n * `POST /account/{accountId}/connectors/{connectorId}/vault/verify`\n */\n async verifyVault(\n accountId: string,\n connectorId: string,\n params: VaultVerifyRequest,\n ): Promise<VaultVerificationResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/vault/verify`,\n { body: params },\n );\n }\n\n /**\n * Compute the route document the vault SHOULD have and diff it against\n * what exists, without writing anything. The returned fingerprints must be\n * echoed byte for byte on {@link Connectors.applyVaultRoutes}.\n *\n * A router without these endpoints answers 404 — render that as \"this\n * build cannot configure routes\", never as \"there is nothing to change\".\n *\n * `POST /account/{accountId}/connectors/{connectorId}/vault/routes/preview`\n */\n async previewVaultRoutes(\n accountId: string,\n connectorId: string,\n params: VaultRoutesPreviewRequest,\n ): Promise<VaultRoutesPreviewResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/vault/routes/preview`,\n { body: params },\n );\n }\n\n /**\n * Write the routes the merchant just previewed. Both fingerprints come\n * from the preview and are opaque: `expected_current_fingerprint` says the\n * vault has not moved (`null` = \"the preview found no routes\" and is sent\n * as `null`, never omitted), `expected_desired_fingerprint` says the\n * document is still the one on screen. A 409 (`DE_04`) means the vault\n * changed since the preview — nothing was written; preview again.\n *\n * `POST /account/{accountId}/connectors/{connectorId}/vault/routes/apply`\n */\n async applyVaultRoutes(\n accountId: string,\n connectorId: string,\n params: VaultRoutesApplyRequest,\n ): Promise<VaultRoutesApplyResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/vault/routes/apply`,\n { body: params },\n );\n }\n\n /** Verify connector credentials. `POST /account/connectors/verify` */\n async verify(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/account/connectors/verify', { body: params });\n }\n\n /**\n * Register a webhook for a connector.\n * `POST /account/{merchantId}/connectors/webhooks/{connectorId}`\n *\n * @param params - Optional event scope. Defaults to `{ event_type: 'all_events' }`\n * when omitted; pass `{ event_type: { specific_event: '…' } }` to scope\n * to a single event.\n */\n async registerWebhook(\n merchantId: string,\n connectorId: string,\n params?: ConnectorWebhookRegisterRequest,\n ): Promise<ConnectorWebhookRegisterResponse> {\n const path = `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`;\n if (params === undefined) return this.request('POST', path);\n return this.request('POST', path, { body: params });\n }\n\n /**\n * Register checkout/shop domains as Stripe payment method domains, so Apple\n * Pay renders on those pages.\n * `POST /account/{merchantId}/connectors/{connectorId}/stripe/payment-method-domains`\n *\n * Stripe connectors only. One call registers against a single credential set\n * (`environment`, default `'live'`) — call twice to cover live and sandbox.\n * Per-URL outcomes come back in `results`; a missing sandbox credential set\n * is a request-level 400.\n */\n async registerStripePaymentMethodDomains(\n merchantId: string,\n connectorId: string,\n params: StripePaymentMethodDomainsRegisterRequest,\n ): Promise<StripePaymentMethodDomainsRegisterResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/connectors/${encodeURIComponent(connectorId)}/stripe/payment-method-domains`,\n { body: params },\n );\n }\n\n /** Get registered webhooks for a connector. `GET /account/{merchantId}/connectors/webhooks/{connectorId}` */\n async getWebhook(merchantId: string, connectorId: string): Promise<ConnectorWebhookListResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`,\n );\n }\n\n /**\n * Bring an already-registered webhook's event subscription up to date with\n * the events Delopay handles.\n * `POST /account/{merchantId}/connectors/webhooks/{connectorId}/sync-events`\n *\n * A PSP freezes an endpoint's event list at registration time, so an endpoint\n * created before an event type was added never receives it — silently, with\n * no error anywhere. {@link getWebhook} reports the gap as `missing_events`;\n * this repairs it.\n *\n * Unlike re-registering, the endpoints are updated in place: the endpoint id\n * and its signing secret are preserved, so signature verification keeps\n * working across the change. Stripe connectors only; idempotent, so it is\n * safe to call on a schedule or after every deploy.\n *\n * @example\n * ```typescript\n * const sync = await delopay.connectors.syncWebhookEvents('mer_abc', 'mca_xyz');\n * for (const endpoint of sync.endpoints) {\n * if (endpoint.error_message) console.warn(endpoint.connector_webhook_id, endpoint.error_message);\n * else if (endpoint.updated) console.log('subscribed', endpoint.added_events);\n * }\n * ```\n */\n async syncWebhookEvents(\n merchantId: string,\n connectorId: string,\n ): Promise<ConnectorWebhookSyncResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}/sync-events`,\n );\n }\n\n /** List available payment methods. `GET /account/payment-methods` */\n async listPaymentMethods(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/account/payment-methods');\n }\n}\n","import type {\n CustomerCreateRequest,\n CustomerResponse,\n CustomerUpdateRequest,\n CustomerListParams,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Flatten list params for the query string.\n *\n * `profile_ids` must go out as ONE comma-separated value. The client\n * serializes arrays as repeated keys (`?profile_ids=a&profile_ids=b`), and the\n * customers endpoints cannot parse that — the whole request fails, rather than\n * the second id being ignored. So the join happens here, once, instead of at\n * four call sites.\n */\nfunction toQuery(\n params?: CustomerListParams,\n): Record<string, string | number | boolean | undefined> | undefined {\n if (!params) return undefined;\n const { profile_ids, ...rest } = params;\n const query = rest as Record<string, string | number | boolean | undefined>;\n // An empty array means \"no shop filter\", which is the absent key — sending\n // `profile_ids=` would work too, but omitting it keeps the URL honest.\n if (profile_ids && profile_ids.length > 0) {\n query.profile_ids = profile_ids.join(',');\n }\n return query;\n}\n\n/** Create and manage customer profiles. */\nexport class Customers {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new customer.\n *\n * @param params - Customer creation parameters (name, email, phone, address, etc.).\n * @returns The created customer.\n *\n * @example\n * ```typescript\n * const customer = await delopay.customers.create({\n * email: 'alice@example.com',\n * name: 'Alice Smith',\n * });\n * ```\n */\n async create(params: CustomerCreateRequest): Promise<CustomerResponse> {\n return this.request('POST', '/customers', { body: params });\n }\n\n /**\n * Retrieve a customer by their ID.\n *\n * @param customerId - The unique customer ID.\n * @returns The customer.\n *\n * @example\n * ```typescript\n * const customer = await delopay.customers.retrieve('cus_abc123');\n * ```\n */\n async retrieve(customerId: string): Promise<CustomerResponse> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}`);\n }\n\n /**\n * Update an existing customer's details.\n *\n * @param customerId - The customer ID to update.\n * @param params - Fields to update (name, email, address, metadata, etc.).\n * @returns The updated customer.\n */\n async update(customerId: string, params: CustomerUpdateRequest): Promise<CustomerResponse> {\n return this.request('POST', `/customers/${encodeURIComponent(customerId)}`, { body: params });\n }\n\n /**\n * Delete a customer and all their saved payment methods.\n *\n * @param customerId - The customer ID to delete.\n * @returns The deleted customer object.\n */\n async delete(customerId: string): Promise<CustomerResponse> {\n return this.request('DELETE', `/customers/${encodeURIComponent(customerId)}`);\n }\n\n /**\n * List customers, optionally filtered by email, shop (`profile_id`), or\n * project (`project_id`).\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of customer objects.\n *\n * @example\n * ```typescript\n * // Customers who have transacted in a specific shop.\n * const customers = await delopay.customers.list({ profile_id: 'pro_abc123' });\n *\n * // Several shops at once (unions with profile_id / project_id).\n * const many = await delopay.customers.list({\n * profile_ids: ['pro_abc123', 'pro_def456'],\n * });\n * ```\n */\n async list(params?: CustomerListParams): Promise<CustomerResponse[]> {\n return this.request('GET', '/customers/list', {\n query: toQuery(params),\n });\n }\n\n // --- OLAP extensions (Task 4.6) ---\n\n /**\n * List customers with count. Supports the same `profile_id` / `project_id`\n * shop filters as {@link list}. `GET /customers/list-with-count`\n */\n async listWithCount(\n params?: CustomerListParams,\n ): Promise<{ count: number; total_count: number; data: CustomerResponse[] }> {\n return this.request('GET', '/customers/list-with-count', {\n query: toQuery(params),\n });\n }\n\n /**\n * List customers scoped to the authenticated dashboard user's shop\n * (business profile). The JWT auto-scopes to its own `profile`; an explicit\n * `profile_id` / `project_id` outside that scope is rejected with\n * `AccessForbidden`. `GET /customers/profile/list`\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of customer objects.\n */\n async listByProfile(params?: CustomerListParams): Promise<CustomerResponse[]> {\n return this.request('GET', '/customers/profile/list', {\n query: toQuery(params),\n });\n }\n\n /**\n * Profile-scoped variant of {@link listWithCount}.\n * `GET /customers/profile/list-with-count`\n */\n async listByProfileWithCount(\n params?: CustomerListParams,\n ): Promise<{ count: number; total_count: number; data: CustomerResponse[] }> {\n return this.request('GET', '/customers/profile/list-with-count', {\n query: toQuery(params),\n });\n }\n\n /** List mandates for a customer. `GET /customers/{customerId}/mandates` */\n async listMandates(customerId: string): Promise<Record<string, unknown>[]> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}/mandates`);\n }\n}\n","import type {\n DisputeResponse,\n DisputeListParams,\n DisputeEvidenceRequest,\n DeleteEvidenceRequest,\n DisputeEvidenceBlock,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** View and respond to payment disputes and chargebacks. */\nexport class Disputes {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Retrieve a dispute by its ID.\n *\n * @param disputeId - The unique dispute ID.\n * @returns The dispute.\n */\n async retrieve(disputeId: string): Promise<DisputeResponse> {\n return this.request('GET', `/disputes/${encodeURIComponent(disputeId)}`);\n }\n\n /**\n * List disputes, optionally filtered by status, stage, or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of disputes.\n */\n async list(params?: DisputeListParams): Promise<DisputeResponse[]> {\n return this.request('GET', '/disputes/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * Accept a dispute, conceding the chargeback to the customer.\n *\n * @param disputeId - The dispute ID to accept.\n * @returns The updated dispute.\n */\n async accept(disputeId: string): Promise<DisputeResponse> {\n return this.request('POST', `/disputes/accept/${encodeURIComponent(disputeId)}`);\n }\n\n /**\n * Submit evidence to challenge a dispute.\n *\n * @param params - Evidence details and the dispute ID to contest.\n * @returns The updated dispute.\n */\n async submitEvidence(params: DisputeEvidenceRequest): Promise<DisputeResponse> {\n return this.request('POST', '/disputes/evidence', { body: params });\n }\n\n /**\n * Attach evidence (e.g. file upload metadata) to a dispute.\n *\n * Uses `PUT /disputes/evidence`.\n */\n async attachEvidence(params: DisputeEvidenceRequest): Promise<DisputeResponse> {\n return this.request('PUT', '/disputes/evidence', { body: params });\n }\n\n /**\n * Retrieve previously stored evidence for a dispute.\n *\n * Returns an ARRAY of file-evidence blocks (this was previously mistyped\n * as the flat submit-request shape). Only file evidence is reported —\n * text evidence is not retrievable once submitted.\n *\n * @param disputeId - The dispute ID.\n * @returns The stored file-evidence blocks.\n */\n async retrieveEvidence(disputeId: string): Promise<DisputeEvidenceBlock[]> {\n return this.request('GET', `/disputes/evidence/${encodeURIComponent(disputeId)}`);\n }\n\n /**\n * Delete submitted evidence for a dispute.\n *\n * @param params - Evidence request body identifying what to delete.\n * @returns The updated dispute.\n */\n async deleteEvidence(params: DeleteEvidenceRequest): Promise<DisputeResponse> {\n return this.request('DELETE', '/disputes/evidence', { body: params });\n }\n\n // --- OLAP extensions (Task 4.4) ---\n\n /** List disputes (profile-scoped). `GET /disputes/profile/list` */\n async listByProfile(params?: DisputeListParams): Promise<DisputeResponse[]> {\n return this.request('GET', '/disputes/profile/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** Get dispute filter options. `GET /disputes/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/filter', { query: params });\n }\n\n /** Get dispute filters (profile-scoped). `GET /disputes/profile/filter` */\n async getFiltersByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/profile/filter', { query: params });\n }\n\n /** Get dispute aggregates. `GET /disputes/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/aggregate', { query: params });\n }\n\n /** Get dispute aggregates (profile-scoped). `GET /disputes/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/profile/aggregate', { query: params });\n }\n\n /**\n * Fetch the latest dispute state from the connector (gateway) and persist it.\n * `GET /disputes/{disputeId}?force_sync=true`\n *\n * The path parameter is the **Delopay dispute id** (`dp_…`). Force-sync asks the\n * backend to pull the dispute from the connector (supported where the connector\n * implements the dispute-sync flow, e.g. Stripe) and update the stored record\n * before returning it.\n *\n * Note: this method previously called `GET /disputes/{id}/fetch`, which is a\n * different backend route — a bulk import keyed by **merchant connector account\n * id** with a required date range — so every call with a dispute id failed.\n */\n async fetchFromConnector(disputeId: string): Promise<DisputeResponse> {\n return this.request('GET', `/disputes/${encodeURIComponent(disputeId)}`, {\n query: { force_sync: 'true' },\n });\n }\n}\n","import type { EphemeralKeyCreateRequest, EphemeralKeyCreateResponse } from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Create short-lived ephemeral keys for secure client-side operations.\n *\n * Ephemeral keys grant a mobile or browser client temporary access to a\n * specific customer's data (e.g. to display saved payment methods) without\n * exposing your secret API key.\n *\n * The key is confined to the customer it was minted for, and that is\n * enforced on every customer and payment-method route: a request for another\n * customer — or for a payment method belonging to one — is refused rather\n * than served. Mint one key per customer; do not reuse a key across them.\n */\nexport class EphemeralKeys {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create an ephemeral key scoped to a specific customer.\n *\n * @param params - Customer ID and optional expiry.\n * @returns The ephemeral key with its plaintext secret and expiry timestamp.\n *\n * @example\n * ```typescript\n * const ephKey = await delopay.ephemeralKeys.create({ customer_id: 'cus_123' });\n * // Pass ephKey.secret to your mobile app.\n * ```\n */\n async create(params: EphemeralKeyCreateRequest): Promise<EphemeralKeyCreateResponse> {\n return this.request('POST', '/ephemeral-keys', { body: params });\n }\n\n /**\n * Invalidate an ephemeral key before it expires.\n *\n * @param keyId - The ephemeral key ID to delete.\n * @returns The deleted key object.\n */\n async delete(keyId: string): Promise<EphemeralKeyCreateResponse> {\n return this.request('DELETE', `/ephemeral-keys/${encodeURIComponent(keyId)}`);\n }\n}\n","import type {\n EventListParams,\n EventListResponse,\n EventDeliveryAttemptResponse,\n EventDetailResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Events {\n constructor(private readonly request: RequestFn) {}\n\n async list(merchantId: string, params?: EventListParams): Promise<EventListResponse> {\n return this.request('POST', `/events/${encodeURIComponent(merchantId)}`, { body: params });\n }\n\n async listDeliveryAttempts(\n merchantId: string,\n eventId: string,\n ): Promise<EventDeliveryAttemptResponse[]> {\n return this.request(\n 'GET',\n `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/attempts`,\n );\n }\n\n async retryDelivery(merchantId: string, eventId: string): Promise<EventDetailResponse> {\n return this.request(\n 'POST',\n `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/retry`,\n );\n }\n\n // --- Profile-scoped listing (Task 4.12) ---\n\n /** List events (profile-scoped). `POST /events/profile/list` */\n async listByProfile(params?: Record<string, unknown>): Promise<EventListResponse> {\n return this.request('POST', '/events/profile/list', { body: params });\n }\n}\n","import type {\n FeeRulePreviewRequest,\n FeeRulePreviewResponse,\n FeeScheduleCreateRequest,\n FeeScheduleResponse,\n FeeScheduleUpdateRequest,\n PlatformFeeRuleInput,\n PlatformFeeRuleRecord,\n PlatformFeeRuleRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Merchant-scoped fee schedules. Each schedule optionally targets a\n * specific shop (via `shop_id`). Merchants can CRUD their own fee\n * overrides; platform-wide fee programs are administered by Delopay and\n * not exposed here.\n *\n * `fees.rules` manages the merchant-owned Euclid fee-rule program, which takes\n * precedence over the flat schedules above. A program is scoped either to one\n * shop (`profile_id`) or merchant-wide; a shop-scoped program wins for that\n * shop, otherwise the merchant-wide one applies. Build the program with the\n * `feeProgram()` helper.\n */\nexport class Fees {\n /** Merchant-owned Euclid fee-rule program (`/merchant-fees/rules`). */\n readonly rules: FeeRulesManager;\n\n constructor(private readonly request: RequestFn) {\n this.rules = new FeeRulesManager(request);\n }\n\n /**\n * Create a merchant-scoped fee schedule (optionally per-shop).\n *\n * @param params - Fee schedule parameters.\n * @param merchantId - The merchant account ID.\n */\n async create(params: FeeScheduleCreateRequest, merchantId: string): Promise<FeeScheduleResponse> {\n return this.request('POST', '/merchant-fees', {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * List the merchant's own fee schedules.\n *\n * @param merchantId - The merchant account ID.\n */\n async list(merchantId: string): Promise<FeeScheduleResponse[]> {\n return this.request('GET', '/merchant-fees/list', {\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Update a merchant-scoped fee schedule.\n *\n * @param feeId - The fee schedule ID.\n * @param params - Fields to update.\n */\n async update(feeId: string, params: FeeScheduleUpdateRequest): Promise<FeeScheduleResponse> {\n return this.request('PUT', `/merchant-fees/${encodeURIComponent(feeId)}`, { body: params });\n }\n\n /**\n * Delete a merchant-scoped fee schedule.\n *\n * @param feeId - The fee schedule ID.\n */\n async delete(feeId: string): Promise<FeeScheduleResponse> {\n return this.request('DELETE', `/merchant-fees/${encodeURIComponent(feeId)}`);\n }\n}\n\n/**\n * Manages a merchant's Euclid fee-rule programs (merchant-wide or per-shop, one\n * active program per scope). Build the `algorithm` with `feeProgram()`. The SDK\n * injects `fee_owner: 'merchant'`; set `profile_id` on the input to scope a\n * program to a shop.\n */\nexport class FeeRulesManager {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create or replace the merchant's fee-rule program (a new active version;\n * the previous version is deactivated server-side).\n *\n * @param params - The program plus optional name / shop scope / validity window.\n * @param merchantId - The merchant account ID.\n */\n async upsert(params: PlatformFeeRuleInput, merchantId: string): Promise<PlatformFeeRuleRecord> {\n const body: PlatformFeeRuleRequest = { ...params, fee_owner: 'merchant' };\n return this.request('PUT', '/merchant-fees/rules', {\n body,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Retrieve the active fee-rule program for a scope, or `null` if none.\n *\n * @param merchantId - The merchant account ID.\n * @param profileId - Optional shop (`profile_id`) scope. Omit for the\n * merchant-wide program; pass a shop id to get that shop's program.\n */\n async retrieve(merchantId: string, profileId?: string): Promise<PlatformFeeRuleRecord | null> {\n return this.request('GET', '/merchant-fees/rules', {\n query: { merchant_id: merchantId, profile_id: profileId },\n });\n }\n\n /**\n * Deactivate a fee-rule program (falls back to the flat fee schedules /\n * volume tier). Idempotent.\n *\n * @param merchantId - The merchant account ID.\n * @param profileId - Optional shop (`profile_id`) scope. Omit to target the\n * merchant-wide program; pass a shop id to delete only that shop's program\n * (other shops' programs are left intact).\n */\n async delete(merchantId: string, profileId?: string): Promise<void> {\n await this.request('DELETE', '/merchant-fees/rules', {\n query: { merchant_id: merchantId, profile_id: profileId },\n });\n }\n\n /**\n * Dry-run a candidate fee-rule program against a sample transaction.\n * Returns the matched rule name, whether it fell through, and the computed fee.\n * Does not persist anything.\n *\n * @param input - Candidate program + sample transaction fields.\n * @param merchantId - The merchant account ID.\n */\n async preview(input: FeeRulePreviewRequest, merchantId: string): Promise<FeeRulePreviewResponse> {\n return this.request('POST', '/merchant-fees/rules/preview', {\n body: input,\n query: { merchant_id: merchantId },\n });\n }\n}\n","import type { MandateResponse, MandateRevokedResponse, MandateListParams } from '../types';\nimport type { RequestFn } from '../client';\n\n/** View and revoke recurring payment mandates. */\nexport class Mandates {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Retrieve a mandate by its ID.\n *\n * @param mandateId - The unique mandate ID.\n * @returns The mandate.\n */\n async retrieve(mandateId: string): Promise<MandateResponse> {\n return this.request('GET', `/mandates/${encodeURIComponent(mandateId)}`);\n }\n\n /**\n * Revoke an active mandate, preventing future charges.\n *\n * @param mandateId - The mandate ID to revoke.\n * @returns Revocation confirmation.\n */\n async revoke(mandateId: string): Promise<MandateRevokedResponse> {\n return this.request('POST', `/mandates/revoke/${encodeURIComponent(mandateId)}`);\n }\n\n /**\n * List mandates, optionally filtered by customer or status.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of mandates.\n */\n async list(params?: MandateListParams): Promise<MandateResponse[]> {\n return this.request('GET', '/mandates/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n}\n","import type {\n MerchantAccountCreateRequest,\n MerchantAccountResponse,\n MerchantAccountUpdateRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class MerchantAccounts {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: MerchantAccountCreateRequest): Promise<MerchantAccountResponse> {\n return this.request('POST', '/accounts', { body: params });\n }\n\n async retrieve(accountId: string): Promise<MerchantAccountResponse> {\n return this.request('GET', `/accounts/${encodeURIComponent(accountId)}`);\n }\n\n async update(\n accountId: string,\n params: MerchantAccountUpdateRequest,\n ): Promise<MerchantAccountResponse> {\n return this.request('POST', `/accounts/${encodeURIComponent(accountId)}`, { body: params });\n }\n\n async delete(accountId: string): Promise<MerchantAccountResponse> {\n return this.request('DELETE', `/accounts/${encodeURIComponent(accountId)}`);\n }\n\n // --- Advanced operations (Task 4.9) ---\n\n /** List all merchant accounts. `GET /accounts/list` */\n async list(): Promise<MerchantAccountResponse[]> {\n return this.request('GET', '/accounts/list');\n }\n\n /** Toggle key-value store for a merchant. `POST /accounts/{accountId}/kv` */\n async toggleKv(accountId: string): Promise<Record<string, unknown>> {\n return this.request('POST', `/accounts/${encodeURIComponent(accountId)}/kv`);\n }\n\n /** Get KV status for a merchant. `GET /accounts/{accountId}/kv` */\n async getKvStatus(accountId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/accounts/${encodeURIComponent(accountId)}/kv`);\n }\n\n /** Transfer keys between merchants. `POST /accounts/transfer` */\n async transferKeys(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/accounts/transfer', { body: params });\n }\n}\n","import type { PaymentLinkResponse, PaymentLinkListParams, PaymentLinkListResponse } from '../types';\nimport type { RequestFn } from '../client';\n\n/** Retrieve and list hosted payment links. */\nexport class PaymentLinks {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Retrieve a payment link by its ID.\n *\n * @param linkId - The unique payment link ID.\n * @returns The payment link details.\n */\n async retrieve(linkId: string): Promise<PaymentLinkResponse> {\n return this.request('GET', `/payment-link/${encodeURIComponent(linkId)}`);\n }\n\n /**\n * List payment links, optionally filtered by status or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Paginated list of payment links.\n */\n async list(params?: PaymentLinkListParams): Promise<PaymentLinkListResponse> {\n return this.request('POST', '/payment-link/list', { body: params });\n }\n\n /** Initiate (render) a payment link page. `GET /payment-link/{merchantId}/{paymentId}` */\n async initiate(merchantId: string, paymentId: string): Promise<Record<string, unknown>> {\n return this.request(\n 'GET',\n `/payment-link/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`,\n );\n }\n\n /** Get payment link status. `GET /payment-link/status/{merchantId}/{paymentId}` */\n async status(merchantId: string, paymentId: string): Promise<Record<string, unknown>> {\n return this.request(\n 'GET',\n `/payment-link/status/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`,\n );\n }\n}\n","import type {\n PaymentMethodCreateRequest,\n PaymentMethodResponse,\n PaymentMethodUpdateRequest,\n PaymentMethodListParams,\n PaymentMethodListResponse,\n PaymentMethodDeleteResponse,\n CustomerPaymentMethodsListParams,\n CustomerPaymentMethodsListResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage saved payment methods for customers. */\nexport class PaymentMethods {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Save a new payment method (card, bank account, wallet, etc.).\n *\n * @param params - Payment method data including type and card/bank details.\n * @returns The saved payment method.\n *\n * @example\n * ```typescript\n * const pm = await delopay.paymentMethods.create({\n * payment_method: 'card',\n * customer_id: 'cus_123',\n * client_secret: 'cs_...',\n * });\n * ```\n */\n async create(params: PaymentMethodCreateRequest): Promise<PaymentMethodResponse> {\n return this.request('POST', '/payment-methods', { body: params });\n }\n\n /**\n * Retrieve a saved payment method by its ID.\n *\n * @param methodId - The payment method ID.\n * @returns The payment method.\n */\n async retrieve(methodId: string): Promise<PaymentMethodResponse> {\n return this.request('GET', `/payment-methods/${encodeURIComponent(methodId)}`);\n }\n\n /**\n * Update an existing payment method (e.g. update card expiry).\n *\n * @param methodId - The payment method ID to update.\n * @param params - Fields to update (card expiry, holder name, etc.).\n * @returns The updated payment method.\n */\n async update(\n methodId: string,\n params: PaymentMethodUpdateRequest,\n ): Promise<PaymentMethodResponse> {\n return this.request('POST', `/payment-methods/${encodeURIComponent(methodId)}/update`, {\n body: params,\n });\n }\n\n /**\n * Delete a saved payment method.\n *\n * @param methodId - The payment method ID to delete.\n * @returns Deletion confirmation.\n */\n async delete(methodId: string): Promise<PaymentMethodDeleteResponse> {\n return this.request('DELETE', `/payment-methods/${encodeURIComponent(methodId)}`);\n }\n\n /**\n * List the payment methods available for a payment — the discovery endpoint a\n * custom checkout renders its tiles from.\n *\n * Callable with a publishable key plus the payment's `client_secret`, so it\n * runs from the browser. The returned set is already filtered by country,\n * order value and the merchant's availability rules, and each entry carries\n * `display` (name + icon slug) and `amount_limits` (the order values it stays\n * available for) so you do not have to maintain either alongside.\n *\n * This is *not* the customer's saved methods — see {@link listForCustomer}.\n *\n * @param params - `client_secret`, plus optional `country`, `amount` and filters.\n * @returns The methods available for the payment, grouped by payment method.\n *\n * @example\n * ```typescript\n * const { payment_methods } = await delopay.paymentMethods.list({\n * client_secret: 'pay_abc_secret_xyz',\n * country: 'DE',\n * amount: 25000,\n * });\n *\n * for (const group of payment_methods) {\n * for (const method of group.payment_method_types) {\n * // Re-check availability yourself as the cart total changes, instead of\n * // re-listing on every keystroke.\n * const limits = method.amount_limits;\n * const available =\n * !limits ||\n * ((limits.min_amount == null || cartTotal >= limits.min_amount) &&\n * (limits.max_amount == null || cartTotal <= limits.max_amount) &&\n * !limits.excluded_ranges.some(\n * (band) => cartTotal >= band.min_amount && cartTotal <= band.max_amount,\n * ));\n *\n * if (available) render(method.display?.display_name, method.display?.icon_slug);\n * }\n * }\n * ```\n */\n async list(params?: PaymentMethodListParams): Promise<PaymentMethodListResponse> {\n return this.request('GET', '/payment-methods', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * List all saved payment methods for a customer, optionally filtered.\n *\n * @param customerId - The customer ID.\n * @param params - Optional filters: `client_secret`, `accepted_countries`, `accepted_currencies`,\n * `amount`, `recurring_enabled`, `installment_payment_enabled`, `limit`, `card_networks`.\n * @returns Customer's saved payment methods.\n *\n * @example\n * ```typescript\n * const { customer_payment_methods } = await delopay.paymentMethods.listForCustomer(\n * 'cus_123',\n * { accepted_currencies: ['EUR'], amount: 5000 },\n * );\n * ```\n */\n async listForCustomer(\n customerId: string,\n params?: CustomerPaymentMethodsListParams,\n ): Promise<CustomerPaymentMethodsListResponse> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}/payment-methods`, {\n query: params as Record<\n string,\n string | number | boolean | (string | number | boolean)[] | null | undefined\n >,\n });\n }\n\n /**\n * Set a payment method as the default for a customer.\n *\n * @param customerId - The customer ID.\n * @param methodId - The payment method ID to set as default.\n * @returns The updated payment method.\n */\n async setDefault(customerId: string, methodId: string): Promise<PaymentMethodResponse> {\n return this.request(\n 'POST',\n `/customers/${encodeURIComponent(customerId)}/payment-methods/${encodeURIComponent(methodId)}/default`,\n );\n }\n\n // --- Advanced operations (Task 3.3) ---\n\n /** Migrate a payment method. `POST /payment-methods/migrate` */\n async migrate(params: Record<string, unknown>): Promise<PaymentMethodResponse> {\n return this.request('POST', '/payment-methods/migrate', { body: params });\n }\n\n /** Batch migrate payment methods. `POST /payment-methods/migrate-batch` */\n async migrateBatch(params: Record<string, unknown>[]): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/migrate-batch', { body: params });\n }\n\n /** Batch update payment methods. `POST /payment-methods/update-batch` */\n async updateBatch(params: Record<string, unknown>[]): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/update-batch', { body: params });\n }\n\n /** Batch retrieve payment methods. `GET /payment-methods/batch` */\n async batchRetrieve(\n params?: Record<string, string | number | undefined>,\n ): Promise<PaymentMethodResponse[]> {\n return this.request('GET', '/payment-methods/batch', { query: params });\n }\n\n /** Tokenize a card. `POST /payment-methods/tokenize-card` */\n async tokenizeCard(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/tokenize-card', { body: params });\n }\n\n /** Batch tokenize cards. `POST /payment-methods/tokenize-card-batch` */\n async tokenizeCardBatch(params: Record<string, unknown>[]): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/tokenize-card-batch', { body: params });\n }\n\n /** Initiate payment method collect link flow. `POST /payment-methods/collect` */\n async collect(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/collect', { body: params });\n }\n\n /** Save a payment method. `POST /payment-methods/{methodId}/save` */\n async save(methodId: string, params?: Record<string, unknown>): Promise<PaymentMethodResponse> {\n return this.request('POST', `/payment-methods/${encodeURIComponent(methodId)}/save`, {\n body: params,\n });\n }\n\n /** Create payment method auth link token. `POST /payment-methods/auth/link` */\n async createAuthLink(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/auth/link', { body: params });\n }\n\n /** Exchange payment method auth token. `POST /payment-methods/auth/exchange` */\n async exchangeAuthToken(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/auth/exchange', { body: params });\n }\n\n /** Tokenize card using existing PM. `POST /payment-methods/{methodId}/tokenize-card` */\n async tokenizeCardForMethod(\n methodId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/payment-methods/${encodeURIComponent(methodId)}/tokenize-card`, {\n body: params,\n });\n }\n}\n","import type {\n PaymentClientContextListResponse,\n PaymentCreateRequest,\n PaymentListFilterConstraints,\n PaymentListFilteredResponse,\n PaymentListResponse,\n PaymentResponse,\n PaymentRetrieveOptions,\n PaymentUpdateRequest,\n PaymentConfirmRequest,\n PaymentCaptureRequest,\n PaymentCancelRequest,\n PaymentListParams,\n PaymentAttemptsListResponse,\n PaymentsDeletePolicyResponse,\n PaymentsDeleteResponse,\n PaymentStatusHistoryResponse,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/** Manage payment intents — create, confirm, capture, cancel, and list payments. */\nexport class Payments {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new payment intent.\n *\n * @param params - Payment creation parameters including amount and currency.\n * @param options - Optional per-call extras: extra `headers` (e.g. an\n * `Idempotency-Key` to make the create safe to retry), a `timeout` override,\n * and an `AbortSignal`.\n * @returns The created payment intent.\n *\n * @example\n * ```typescript\n * const payment = await delopay.payments.create(\n * { amount: 5000, currency: 'EUR', customer_id: 'cus_123' },\n * { headers: { 'Idempotency-Key': 'order_1001' } },\n * );\n * ```\n *\n * @example Send `test_mode` to pick the environment per payment, so a staging\n * deploy cannot charge real cards and a forgotten processor toggle cannot\n * swallow production traffic:\n * ```typescript\n * const payment = await delopay.payments.create({\n * amount: 5000,\n * currency: 'EUR',\n * test_mode: process.env.NODE_ENV !== 'production',\n * });\n * ```\n *\n * A payment that pins one connector through `routing` (the `single` form)\n * is now checked against `test_mode` here rather than at confirm: if that\n * connector has no credentials for the environment asked for, create fails\n * instead of handing back a payment whose checkout the buyer cannot\n * complete. `priority` and `volume_split` name several accounts and are\n * still resolved at confirm.\n */\n async create(params: PaymentCreateRequest, options?: RequestExtras): Promise<PaymentResponse> {\n return this.request('POST', '/payments', { body: params, ...options });\n }\n\n /**\n * Retrieve a payment by its ID.\n *\n * @param paymentId - The unique payment intent ID.\n * @param options - Optional query flags. `force_sync` reconciles the\n * intent's state with the connector before returning (useful to recover\n * a stuck intent when a webhook was lost). `all_keys_required` forces a\n * connector sync even for intents in early states like\n * `requires_payment_method` that would otherwise return the local\n * snapshot. Both flags work with JWT and API-key authentication.\n * @returns The payment intent.\n *\n * @example\n * ```typescript\n * const payment = await delopay.payments.retrieve('pay_abc123');\n * const synced = await delopay.payments.retrieve('pay_abc123', {\n * force_sync: true,\n * all_keys_required: true,\n * });\n * ```\n */\n async retrieve(paymentId: string, options?: PaymentRetrieveOptions): Promise<PaymentResponse> {\n const path = `/payments/${encodeURIComponent(paymentId)}`;\n if (options === undefined) return this.request('GET', path);\n const query: Record<string, boolean> = {};\n if (options.force_sync !== undefined) query['force_sync'] = options.force_sync;\n if (options.all_keys_required !== undefined) {\n query['all_keys_required'] = options.all_keys_required;\n }\n if (Object.keys(query).length === 0) return this.request('GET', path);\n return this.request('GET', path, { query });\n }\n\n /**\n * List every attempt made on a payment, each with its full failure detail\n * (`error_code` / `error_message`, the Delopay-unified `unified_code` and\n * `unified_message`, and structured `error_details`).\n *\n * Useful for surfacing retries across connectors — e.g. \"attempt 1 stripe →\n * insufficient_funds, attempt 2 adyen → success\".\n *\n * `GET /payments/{paymentId}/attempts`\n *\n * @param paymentId - The payment intent ID whose attempts to list.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal`.\n * @returns The attempt list — `size` plus a `data` array of attempts.\n * @throws If the payment does not exist or belongs to another merchant (404).\n *\n * @example\n * ```typescript\n * const { size, data } = await delopay.payments.listAttempts('pay_abc123');\n * for (const attempt of data) {\n * console.log(attempt.status, attempt.unified_message ?? attempt.error_message);\n * }\n * ```\n */\n async listAttempts(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentAttemptsListResponse> {\n return this.request('GET', `/payments/${encodeURIComponent(paymentId)}/attempts`, options);\n }\n\n /**\n * The status timeline of a payment: every recorded creation / status\n * transition of the intent and its attempts, refunds and disputes, oldest\n * first. `complete: false` marks timelines partially reconstructed from\n * current records (payments created before the status log existed).\n *\n * @param paymentId - The payment intent ID.\n * @returns The ordered status-history events.\n *\n * @example\n * ```typescript\n * const { events, complete } = await delopay.payments.listStatusHistory('pay_abc123');\n * for (const event of events) {\n * console.log(event.timestamp, event.entity_type, event.status);\n * }\n * ```\n */\n async listStatusHistory(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentStatusHistoryResponse> {\n return this.request(\n 'GET',\n `/payments/${encodeURIComponent(paymentId)}/status-history`,\n options,\n );\n }\n\n /**\n * Update an existing payment intent before it is confirmed.\n *\n * @param paymentId - The payment intent ID to update.\n * @param params - Fields to update (amount, currency, metadata, etc.).\n * @returns The updated payment intent.\n */\n async update(paymentId: string, params: PaymentUpdateRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}`, { body: params });\n }\n\n /**\n * Confirm a payment intent, triggering authorisation with the selected gateway.\n *\n * @param paymentId - The payment intent ID to confirm.\n * @param params - Confirmation parameters (payment method data, return URL, etc.).\n * @returns The updated payment intent.\n */\n async confirm(paymentId: string, params: PaymentConfirmRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/confirm`, {\n body: params,\n });\n }\n\n /**\n * Capture a previously authorised payment.\n *\n * @param paymentId - The payment intent ID to capture.\n * @param params - Optional capture parameters (partial capture amount, etc.).\n * @returns The updated payment intent.\n */\n async capture(paymentId: string, params?: PaymentCaptureRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/capture`, {\n body: params,\n });\n }\n\n /**\n * Cancel a payment intent that has not yet been captured.\n *\n * @param paymentId - The payment intent ID to cancel.\n * @param params - Optional cancellation reason.\n * @returns The updated payment intent.\n */\n async cancel(paymentId: string, params?: PaymentCancelRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/cancel`, {\n body: params,\n });\n }\n\n /**\n * List payment intents, optionally filtered by customer or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal` for cancellation.\n * @returns Paginated list of payment intents.\n *\n * @example\n * ```typescript\n * const { data } = await delopay.payments.list({ customer_id: 'cus_123', limit: 25 });\n * ```\n */\n async list(params?: PaymentListParams, options?: RequestExtras): Promise<PaymentListResponse> {\n return this.request('GET', '/payments/list', {\n query: params as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /**\n * The status timeline of client/device observations captured while the\n * buyer interacted with the payment (checkout opens, confirms, redirect\n * legs, reported client signals), oldest first.\n *\n * `GET /payments/{paymentId}/client-context`\n */\n async listClientContext(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentClientContextListResponse> {\n return this.request(\n 'GET',\n `/payments/${encodeURIComponent(paymentId)}/client-context`,\n options,\n );\n }\n\n /**\n * Soft-delete a payment. Only payments whose status is in the merchant's\n * delete policy (see {@link Payments.getDeletePolicy}) can be deleted;\n * anything else fails with a precondition error.\n *\n * `DELETE /payments/{paymentId}`\n */\n async delete(paymentId: string, options?: RequestExtras): Promise<PaymentsDeleteResponse> {\n return this.request('DELETE', `/payments/${encodeURIComponent(paymentId)}`, options);\n }\n\n /**\n * The effective deletable-status set for the calling merchant — lets a\n * dashboard show the delete action only where it is allowed.\n *\n * `GET /payments/delete-policy`\n */\n async getDeletePolicy(options?: RequestExtras): Promise<PaymentsDeletePolicyResponse> {\n return this.request('GET', '/payments/delete-policy', options);\n }\n\n // --- Advanced operations (Task 3.2) ---\n\n /** Generate session tokens. `POST /payments/session-tokens` */\n async sessionTokens(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payments/session-tokens', { body: params });\n }\n\n /** Retrieve payment with gateway credentials. `POST /payments/sync` */\n async sync(params: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('POST', '/payments/sync', { body: params });\n }\n\n /** Cancel after partial capture. `POST /payments/{paymentId}/cancel-post-capture` */\n async cancelPostCapture(\n paymentId: string,\n params?: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/cancel-post-capture`, {\n body: params,\n });\n }\n\n /** Incrementally authorize more funds. `POST /payments/{paymentId}/incremental-authorization` */\n async incrementalAuthorization(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request(\n 'POST',\n `/payments/${encodeURIComponent(paymentId)}/incremental-authorization`,\n {\n body: params,\n },\n );\n }\n\n /** Extend authorization window. `POST /payments/{paymentId}/extend-authorization` */\n async extendAuthorization(\n paymentId: string,\n params?: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/extend-authorization`, {\n body: params,\n });\n }\n\n /** Complete authorization. `POST /payments/{paymentId}/complete-authorize` */\n async completeAuthorize(\n paymentId: string,\n params?: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/complete-authorize`, {\n body: params,\n });\n }\n\n /** Dynamic tax calculation. `POST /payments/{paymentId}/calculate-tax` */\n async calculateTax(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/calculate-tax`, {\n body: params,\n });\n }\n\n /** Update payment metadata. `POST /payments/{paymentId}/update-metadata` */\n async updateMetadata(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/update-metadata`, {\n body: params,\n });\n }\n\n /** Retrieve extended card info. `GET /payments/{paymentId}/extended-card-info` */\n async extendedCardInfo(paymentId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/payments/${encodeURIComponent(paymentId)}/extended-card-info`);\n }\n\n // --- OLAP extensions (Task 4.2) ---\n\n /** List payments (profile-scoped). `GET /payments/profile/list` */\n async listByProfile(params?: PaymentListParams): Promise<PaymentListResponse> {\n return this.request('GET', '/payments/profile/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** List payments across all shops. `GET /payments/list-all-shops` */\n async listAllShops(params?: PaymentListParams): Promise<PaymentListResponse> {\n return this.request('GET', '/payments/list-all-shops', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** List payments by filter (POST body). `POST /payments/list` */\n async listByFilter(params: Record<string, unknown>): Promise<PaymentListResponse> {\n return this.request('POST', '/payments/list', { body: params });\n }\n\n /**\n * List payments by filter, scoped to the caller's profile (the shop-user\n * twin of `listByFilter`). The backend narrows to the profile from the\n * auth context, so `profile_id` / `project_id` must not be sent.\n *\n * Not to be confused with {@link Payments.listByProfile}, which is the GET\n * cursor variant and rejects this body.\n *\n * `POST /payments/profile/list`\n */\n async listByProfileFilter(\n params: PaymentListFilterConstraints,\n options?: RequestExtras,\n ): Promise<PaymentListFilteredResponse> {\n return this.request('POST', '/payments/profile/list', { body: params, ...options });\n }\n\n /** Get payment filter options. `GET /payments/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/filter', { query: params });\n }\n\n /**\n * Get payment filter options, scoped to the caller's profile.\n * `GET /payments/profile/filter`\n */\n async getFiltersByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/profile/filter', { query: params });\n }\n\n /** Get payment aggregates. `GET /payments/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/aggregate', { query: params });\n }\n\n /** Get payment aggregates (profile-scoped). `GET /payments/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/profile/aggregate', { query: params });\n }\n\n /** Manually update payment status. `PUT /payments/{paymentId}/manual-update` */\n async manualUpdate(paymentId: string, params: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('PUT', `/payments/${encodeURIComponent(paymentId)}/manual-update`, {\n body: params,\n });\n }\n\n /** Approve a payment waiting for review. `POST /payments/{paymentId}/approve` */\n async approve(paymentId: string, params?: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/approve`, {\n body: params,\n });\n }\n\n /** Reject a payment waiting for review. `POST /payments/{paymentId}/reject` */\n async reject(paymentId: string, params?: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/reject`, {\n body: params,\n });\n }\n\n /** Initiate external 3DS authentication. `POST /payments/{paymentId}/3ds/authentication` */\n async threeDsAuthentication(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/3ds/authentication`, {\n body: params,\n });\n }\n}\n","import type {\n PayoutCreateRequest,\n PayoutResponse,\n PayoutUpdateRequest,\n PayoutListParams,\n PayoutListResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage payouts — fund transfers from merchant to a recipient bank account. */\nexport class Payouts {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new payout.\n *\n * @param params - Payout parameters including amount, currency, and destination.\n * @returns The created payout.\n *\n * @example\n * ```typescript\n * const payout = await delopay.payouts.create({\n * amount: 10000,\n * currency: 'EUR',\n * customer_id: 'cus_123',\n * });\n * ```\n */\n async create(params: PayoutCreateRequest): Promise<PayoutResponse> {\n return this.request('POST', '/payouts/create', { body: params });\n }\n\n /**\n * Retrieve a payout by its ID.\n *\n * @param payoutId - The unique payout ID.\n * @returns The payout.\n */\n async retrieve(payoutId: string): Promise<PayoutResponse> {\n return this.request('GET', `/payouts/${encodeURIComponent(payoutId)}`);\n }\n\n /**\n * Update a payout before it is confirmed.\n *\n * @param payoutId - The payout ID to update.\n * @param params - Fields to update.\n * @returns The updated payout.\n */\n async update(payoutId: string, params: PayoutUpdateRequest): Promise<PayoutResponse> {\n return this.request('PUT', `/payouts/${encodeURIComponent(payoutId)}`, { body: params });\n }\n\n /**\n * Confirm a payout, triggering the actual transfer.\n *\n * @param payoutId - The payout ID to confirm.\n * @param params - Optional confirmation parameters.\n * @returns The updated payout.\n */\n async confirm(payoutId: string, params?: PayoutUpdateRequest): Promise<PayoutResponse> {\n return this.request('POST', `/payouts/${encodeURIComponent(payoutId)}/confirm`, {\n body: params,\n });\n }\n\n /**\n * Cancel a payout before it is fulfilled.\n *\n * @param payoutId - The payout ID to cancel.\n * @returns The cancelled payout.\n */\n async cancel(payoutId: string): Promise<PayoutResponse> {\n return this.request('POST', `/payouts/${encodeURIComponent(payoutId)}/cancel`);\n }\n\n /**\n * Mark a payout as fulfilled (manual confirmation of successful transfer).\n *\n * @param payoutId - The payout ID to fulfil.\n * @returns The fulfilled payout.\n */\n async fulfill(payoutId: string): Promise<PayoutResponse> {\n return this.request('POST', `/payouts/${encodeURIComponent(payoutId)}/fulfill`);\n }\n\n /**\n * List payouts, optionally filtered by status or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Paginated list of payouts.\n */\n async list(params?: PayoutListParams): Promise<PayoutListResponse> {\n return this.request('GET', '/payouts/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n // --- OLAP extensions (Task 4.5) ---\n\n /** List payouts (profile-scoped). `GET /payouts/profile/list` */\n async listByProfile(params?: PayoutListParams): Promise<PayoutListResponse> {\n return this.request('GET', '/payouts/profile/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** List payouts by filter (POST body). `POST /payouts/list` */\n async listByFilter(params: Record<string, unknown>): Promise<PayoutListResponse> {\n return this.request('POST', '/payouts/list', { body: params });\n }\n\n /** Get payout filter options. `GET /payouts/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/filter', { query: params });\n }\n\n /** Get payout filters (profile-scoped). `GET /payouts/profile/filter` */\n async getFiltersByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/profile/filter', { query: params });\n }\n\n /** Get payout aggregates. `GET /payouts/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/aggregate', { query: params });\n }\n\n /** Get payout aggregates (profile-scoped). `GET /payouts/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/profile/aggregate', { query: params });\n }\n\n /** Manually update payout status. `PUT /payouts/{payoutId}/manual-update` */\n async manualUpdate(payoutId: string, params: Record<string, unknown>): Promise<PayoutResponse> {\n return this.request('PUT', `/payouts/${encodeURIComponent(payoutId)}/manual-update`, {\n body: params,\n });\n }\n}\n","import type { PollStatusResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Poll {\n constructor(private readonly request: RequestFn) {}\n\n async getStatus(pollId: string): Promise<PollStatusResponse> {\n return this.request('GET', `/poll/status/${encodeURIComponent(pollId)}`);\n }\n}\n","import type {\n ProfileAcquirerCreateRequest,\n ProfileAcquirerResponse,\n ProfileAcquirerUpdateRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class ProfileAcquirers {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: ProfileAcquirerCreateRequest): Promise<ProfileAcquirerResponse> {\n return this.request('POST', '/profile-acquirer', { body: params });\n }\n\n async update(\n profileId: string,\n profileAcquirerId: string,\n params: ProfileAcquirerUpdateRequest,\n ): Promise<ProfileAcquirerResponse> {\n return this.request(\n 'POST',\n `/profile-acquirer/${encodeURIComponent(profileId)}/${encodeURIComponent(profileAcquirerId)}`,\n {\n body: params,\n },\n );\n }\n}\n","import type { ProfileCreateRequest, ProfileResponse, ProfileUpdateRequest } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Profiles {\n constructor(private readonly request: RequestFn) {}\n\n async create(accountId: string, params: ProfileCreateRequest): Promise<ProfileResponse> {\n return this.request('POST', `/account/${encodeURIComponent(accountId)}/business-profile`, {\n body: params,\n });\n }\n\n async retrieve(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}`,\n );\n }\n\n async list(accountId: string): Promise<ProfileResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/business-profile`);\n }\n\n /**\n * List the business profiles the caller can see at profile scope — the\n * `ProfileAccountRead` twin of `list()` (which needs merchant-level read).\n * A shop-scoped user gets exactly their own shop back.\n *\n * `GET /account/{accountId}/profile`\n */\n async listByProfile(accountId: string): Promise<ProfileResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/profile`);\n }\n\n async update(\n accountId: string,\n profileId: string,\n params: ProfileUpdateRequest,\n ): Promise<ProfileResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}`,\n {\n body: params,\n },\n );\n }\n\n async delete(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'DELETE',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}`,\n );\n }\n\n // --- Advanced operations (Task 4.8) ---\n\n /** Toggle extended card info for a profile. `POST /account/{accountId}/business-profile/{profileId}/toggle-extended-card-info` */\n async toggleExtendedCardInfo(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}/toggle-extended-card-info`,\n );\n }\n\n /** Toggle connector agnostic MIT. `POST /account/{accountId}/business-profile/{profileId}/toggle-connector-agnostic-mit` */\n async toggleConnectorAgnosticMit(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}/toggle-connector-agnostic-mit`,\n );\n }\n}\n","import type {\n ProjectCreateRequest,\n ProjectResponse,\n ProjectUpdateRequest,\n ProjectStatsResponse,\n MerchantOverviewResponse,\n StatsPeriod,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage projects — optional grouping layers that contain one or more shops. */\nexport class Projects {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new project under a merchant account.\n *\n * @param params - Project creation parameters (name, description, etc.).\n * @param merchantId - The merchant account ID that owns this project.\n * @returns The created project.\n *\n * @example\n * ```typescript\n * const project = await delopay.projects.create({ name: 'EU Stores' }, 'merch_123');\n * ```\n */\n async create(params: ProjectCreateRequest, merchantId: string): Promise<ProjectResponse> {\n return this.request('POST', '/projects', {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Retrieve a project by its ID.\n *\n * @param projectId - The unique project ID.\n * @param merchantId - Optional merchant scope. When provided, sent as\n * `?merchant_id=…` — required by dashboards that authenticate with a JWT\n * spanning multiple merchants and need to disambiguate which one this\n * call applies to. API-key callers can omit it.\n * @returns The project.\n */\n async retrieve(projectId: string, merchantId?: string): Promise<ProjectResponse> {\n const path = `/projects/${encodeURIComponent(projectId)}`;\n if (merchantId === undefined) return this.request('GET', path);\n return this.request('GET', path, { query: { merchant_id: merchantId } });\n }\n\n /**\n * Update a project's details.\n *\n * @param projectId - The project ID to update.\n * @param params - Fields to update.\n * @param merchantId - Optional merchant scope. See {@link Projects.retrieve}.\n * @returns The updated project.\n */\n async update(\n projectId: string,\n params: ProjectUpdateRequest,\n merchantId?: string,\n ): Promise<ProjectResponse> {\n const path = `/projects/${encodeURIComponent(projectId)}`;\n if (merchantId === undefined) return this.request('PUT', path, { body: params });\n return this.request('PUT', path, { body: params, query: { merchant_id: merchantId } });\n }\n\n /**\n * Delete a project.\n *\n * @param projectId - The project ID to delete.\n * @param merchantId - Optional merchant scope. See {@link Projects.retrieve}.\n * @returns The deleted project object.\n */\n async delete(projectId: string, merchantId?: string): Promise<ProjectResponse> {\n const path = `/projects/${encodeURIComponent(projectId)}`;\n if (merchantId === undefined) return this.request('DELETE', path);\n return this.request('DELETE', path, { query: { merchant_id: merchantId } });\n }\n\n /**\n * List all projects for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns Array of projects.\n */\n async list(merchantId: string): Promise<ProjectResponse[]> {\n return this.request('GET', '/projects/list', {\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Get aggregate payment statistics across all projects for a merchant.\n *\n * The response's flat `shops[]` array holds every shop, including shops that\n * belong to no project — those are absent from `projects[].shops[]`, so look\n * a single shop up in `shops[]`. Requires `MerchantAccountRead`; a\n * shop-scoped user should call {@link Shops.stats} instead.\n *\n * @param merchantId - The merchant account ID.\n * @param period - Window in days, or `'all'` for an all-time total.\n * Omitted means the server default of 30 days.\n * @returns Project statistics.\n *\n * @example\n * ```typescript\n * const stats = await delopay.projects.stats('merch_123', 'all');\n * const shop = stats.shops.find((s) => s.shop_id === 'pro_1');\n * ```\n */\n async stats(merchantId: string, period?: StatsPeriod): Promise<ProjectStatsResponse> {\n const query: Record<string, string> = { merchant_id: merchantId };\n if (period !== undefined) query['period'] = String(period);\n return this.request('GET', '/projects/stats', { query });\n }\n\n /**\n * Get a high-level overview (volume, counts, top connectors) for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns Merchant overview data.\n */\n async overview(merchantId: string): Promise<MerchantOverviewResponse> {\n return this.request('GET', '/projects/overview', {\n query: { merchant_id: merchantId },\n });\n }\n}\n","import type {\n RefundCreateRequest,\n RefundResponse,\n RefundUpdateRequest,\n RefundListParams,\n RefundListResponse,\n RefundAggregateResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage refunds for completed payments. */\nexport class Refunds {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a refund for a payment.\n *\n * Dashboard-initiated refunds are subject to the caller's operation-limit\n * rule, resolved against the role the request authenticated with. An\n * over-limit refund either fails with `DE_01` (the rule blocks) or with\n * HTTP 409 `DE_06` — the rule requires approval, and `DelopayError.data`\n * carries `PendingApprovalErrorDetails`. No refund exists in either case;\n * `DE_06` names one that a second approver can still let through, via\n * `operationLimits.approve()`.\n *\n * @param params - Refund parameters, including the required `payment_id` and optional amount.\n * @returns The created refund.\n *\n * @example\n * ```typescript\n * const refund = await delopay.refunds.create({\n * payment_id: 'pay_abc123',\n * amount: 2500, // partial refund of 25.00 EUR\n * });\n * ```\n */\n async create(params: RefundCreateRequest): Promise<RefundResponse> {\n return this.request('POST', '/refunds', { body: params });\n }\n\n /**\n * Retrieve a refund by its ID.\n *\n * @param refundId - The unique refund ID.\n * @returns The refund.\n *\n * @example\n * ```typescript\n * const refund = await delopay.refunds.retrieve('ref_abc123');\n * ```\n */\n async retrieve(refundId: string): Promise<RefundResponse> {\n return this.request('GET', `/refunds/${encodeURIComponent(refundId)}`);\n }\n\n /**\n * Update the reason or metadata on an existing refund.\n *\n * @param refundId - The refund ID to update.\n * @param params - Fields to update (reason, metadata).\n * @returns The updated refund.\n */\n async update(refundId: string, params: RefundUpdateRequest): Promise<RefundResponse> {\n return this.request('POST', `/refunds/${encodeURIComponent(refundId)}`, { body: params });\n }\n\n /**\n * List refunds, optionally filtered by payment, status, or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Paginated list of refunds.\n */\n async list(params?: RefundListParams): Promise<RefundListResponse> {\n return this.request('POST', '/refunds/list', { body: params });\n }\n\n // --- OLAP extensions (Task 4.3) ---\n\n /** List refunds (profile-scoped). `POST /refunds/profile/list` */\n async listByProfile(params?: RefundListParams): Promise<RefundListResponse> {\n return this.request('POST', '/refunds/profile/list', { body: params });\n }\n\n /** Get refund filter options. `GET /refunds/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/refunds/filter', { query: params });\n }\n\n /** Get refund aggregates. `GET /refunds/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<RefundAggregateResponse> {\n return this.request('GET', '/refunds/aggregate', { query: params });\n }\n\n /** Get refund aggregates (profile-scoped). `GET /refunds/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<RefundAggregateResponse> {\n return this.request('GET', '/refunds/profile/aggregate', { query: params });\n }\n\n /** Manually update refund status. `PUT /refunds/{refundId}/manual-update` */\n async manualUpdate(refundId: string, params: Record<string, unknown>): Promise<RefundResponse> {\n return this.request('PUT', `/refunds/${encodeURIComponent(refundId)}/manual-update`, {\n body: params,\n });\n }\n}\n","import type { RelayRequest, RelayResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Relay {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: RelayRequest): Promise<RelayResponse> {\n return this.request('POST', '/relay', { body: params });\n }\n\n async retrieve(relayId: string): Promise<RelayResponse> {\n return this.request('GET', `/relay/${encodeURIComponent(relayId)}`);\n }\n}\n","import type {\n CheckoutThemeConversionQuery,\n CheckoutThemeConversionResponse,\n CheckoutThemeProgramRequest,\n CheckoutThemeProgramResponse,\n LinkedRoutingConfigRetrieveResponse,\n MerchantRoutingAlgorithm,\n ProfileDefaultRoutingConfig,\n ProfileDeniedConnectorsResponse,\n RoutableConnectorChoice,\n RoutingActivatePayload,\n RoutingConfigCreateRequest,\n RoutingConfigHistoryResponse,\n RoutingConfigUpdateRequest,\n RoutingConnectorCaps,\n RoutingDeactivateRequest,\n RoutingDictionary,\n RoutingDictionaryRecord,\n RoutingHistoryParams,\n SurchargeRuleRequest,\n SurchargeRuleResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Create and manage payment routing algorithms.\n *\n * Routing rules determine which gateway connector handles each payment based on\n * card type, currency, amount, or custom conditions.\n */\nexport class Routing {\n readonly decision: RoutingDecisionManager;\n /** Merchant-friendly, per-payment-method surcharge rules (no Euclid DSL). */\n readonly surchargeRules: SurchargeRules;\n /** Which stored appearance variant a buyer is shown. Decides a look, never a payment. */\n readonly checkoutThemeRules: CheckoutThemeRules;\n /** Rendered-to-paid conversion per appearance variant and segment. */\n readonly checkoutThemeConversion: CheckoutThemeConversion;\n\n constructor(private readonly request: RequestFn) {\n this.decision = new RoutingDecisionManager(request);\n this.surchargeRules = new SurchargeRules(request);\n this.checkoutThemeRules = new CheckoutThemeRules(request);\n this.checkoutThemeConversion = new CheckoutThemeConversion(request);\n }\n\n /**\n * Create a new routing algorithm.\n *\n * @param params - Routing algorithm definition (rule-based, priority, or volume-based).\n * @returns Metadata record for the created routing configuration. The full\n * algorithm body is not echoed back — use `retrieve(id)` if you need it.\n *\n * @example\n * ```typescript\n * const config = await delopay.routing.create({\n * name: 'EU Priority',\n * algorithm: { type: 'priority', data: [{ connector: 'stripe' }] },\n * });\n * ```\n *\n * @example Conditional volume split (advanced): cards → 90% epayouts / 10% stripe.\n * Rules run top-down (first match wins); `defaultSelection` is the fallback.\n * Splits must sum to 100; `amount` conditions are in minor units.\n * ```typescript\n * const config = await delopay.routing.create({\n * name: 'Card split 90/10',\n * profile_id: 'pro_...',\n * algorithm: {\n * type: 'advanced',\n * data: {\n * defaultSelection: { type: 'priority', data: [{ connector: 'stripe' }] },\n * rules: [\n * {\n * name: 'cards',\n * connectorSelection: {\n * type: 'volume_split',\n * data: [\n * { connector: { connector: 'epayouts' }, split: 90 },\n * { connector: { connector: 'stripe' }, split: 10 },\n * ],\n * },\n * statements: [\n * {\n * condition: [\n * {\n * lhs: 'payment_method',\n * comparison: 'equal',\n * value: { type: 'enum_variant', value: 'card' },\n * metadata: {},\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * metadata: {},\n * },\n * },\n * });\n * await delopay.routing.activate(config.id);\n * ```\n */\n async create(params: RoutingConfigCreateRequest): Promise<RoutingDictionaryRecord> {\n return this.request('POST', '/routing', { body: params });\n }\n\n /**\n * Retrieve a routing algorithm by its ID.\n *\n * @param algorithmId - The routing algorithm ID.\n * @returns The full routing configuration including the algorithm body.\n */\n async retrieve(algorithmId: string): Promise<MerchantRoutingAlgorithm> {\n return this.request('GET', `/routing/${encodeURIComponent(algorithmId)}`);\n }\n\n /**\n * Activate a routing algorithm, making it the active routing strategy.\n *\n * Always sends a JSON body (default `{}`) so the request carries the\n * `Content-Type: application/json` header that the server requires.\n *\n * @param algorithmId - The routing algorithm ID to activate.\n * @param params - Optional activation payload (e.g. `transaction_type`).\n */\n async activate(\n algorithmId: string,\n params: RoutingActivatePayload = {},\n ): Promise<RoutingDictionaryRecord> {\n return this.request('POST', `/routing/${encodeURIComponent(algorithmId)}/activate`, {\n body: params,\n });\n }\n\n /**\n * Deactivate the currently active routing algorithm (falls back to default routing).\n *\n * Always sends a JSON body (default `{}`) so the request carries the\n * `Content-Type: application/json` header that the server requires.\n *\n * @param params - Optional deactivation payload.\n */\n async deactivate(params: RoutingDeactivateRequest = {}): Promise<RoutingDictionaryRecord> {\n return this.request('POST', '/routing/deactivate', { body: params });\n }\n\n /**\n * Edit a static routing configuration.\n *\n * Partial: send only the fields to change. `name`/`description` are\n * metadata-only; `algorithm` is a wholesale rule replacement, validated\n * against the shop exactly as at create. `modified_at` is bumped either way.\n *\n * `PUT /routing/{algorithmId}`\n *\n * @param algorithmId - The routing algorithm ID to edit.\n * @param params - The fields to change (at least one required).\n * @returns The updated routing configuration including the algorithm body.\n */\n async update(\n algorithmId: string,\n params: RoutingConfigUpdateRequest,\n ): Promise<MerchantRoutingAlgorithm> {\n return this.request('PUT', `/routing/${encodeURIComponent(algorithmId)}`, { body: params });\n }\n\n /**\n * Every content window a routing configuration has had, oldest first.\n *\n * A configuration's rule can be edited in place, so this is what makes \"which\n * rule decided this payment\" answerable after the fact. Each entry is the rule\n * as it stood between `valid_from` and `valid_until`; the windows of one\n * config abut exactly, with no gap.\n *\n * Paging covers the whole timeline including the live window, so a page never\n * holds more than `limit` entries and the live one — the only entry without a\n * `valid_until` — comes back on exactly one page. Advance `offset` by `limit`;\n * a page past the end is empty, and `total_count` says where that end is\n * without probing for it.\n *\n * `GET /routing/{algorithmId}/history`\n *\n * @param algorithmId - The routing algorithm to read the history of.\n * @param params - Optional paging.\n */\n async history(\n algorithmId: string,\n params: RoutingHistoryParams = {},\n ): Promise<RoutingConfigHistoryResponse> {\n return this.request('GET', `/routing/${encodeURIComponent(algorithmId)}/history`, {\n query: params as Record<string, number | null | undefined>,\n });\n }\n\n /**\n * A shop's lifetime per-connector payment caps, each with how much of it is\n * already spent.\n *\n * `GET /routing/connector-caps/{profileId}`\n */\n async connectorCaps(profileId: string): Promise<RoutingConnectorCaps> {\n return this.request('GET', `/routing/connector-caps/${encodeURIComponent(profileId)}`);\n }\n\n /**\n * Replace a shop's per-connector payment caps.\n *\n * Whole-set replacement, not a patch: the list sent becomes the complete set\n * of capped connectors, and an empty list clears them all — which is how\n * acquirer onboarding finishes, the new account ceasing to be a special case.\n *\n * Every account named must belong to this shop; one that does not is refused.\n *\n * `PUT /routing/connector-caps/{profileId}`\n */\n async setConnectorCaps(\n profileId: string,\n params: RoutingConnectorCaps,\n ): Promise<RoutingConnectorCaps> {\n return this.request('PUT', `/routing/connector-caps/${encodeURIComponent(profileId)}`, {\n body: params,\n });\n }\n\n /**\n * List all routing algorithms for the current merchant.\n *\n * @returns The routing dictionary (records + currently active id).\n */\n async list(): Promise<RoutingDictionary> {\n return this.request('GET', '/routing');\n }\n\n /**\n * Connector names denied at routing for a shop (explicit denies plus\n * whitelist-implied exclusions). Read-only; surfaced in the routing builder.\n *\n * `GET /routing/connector-restrictions/{profileId}`\n */\n async connectorRestrictions(profileId: string): Promise<ProfileDeniedConnectorsResponse> {\n return this.request('GET', `/routing/connector-restrictions/${encodeURIComponent(profileId)}`);\n }\n\n // --- Advanced operations (Task 3.4) ---\n\n /** Get active routing config. `GET /routing/active` */\n async getActive(): Promise<LinkedRoutingConfigRetrieveResponse> {\n return this.request('GET', '/routing/active');\n }\n\n /** Update default routing config. `POST /routing/default` */\n async updateDefault(params: Record<string, unknown>): Promise<RoutableConnectorChoice[]> {\n return this.request('POST', '/routing/default', { body: params });\n }\n\n /** Retrieve default config for profiles. `GET /routing/default/profile` */\n async getDefaultProfile(): Promise<RoutableConnectorChoice[] | ProfileDefaultRoutingConfig[]> {\n return this.request('GET', '/routing/default/profile');\n }\n\n /**\n * Retrieve one profile's default config. `GET /routing/default/profile/{profileId}`\n *\n * The narrow counterpart of `getDefaultProfile()`: that one returns every\n * profile of the merchant and needs merchant-level routing read, so a\n * profile-scoped (shop) role could write its own default through\n * `updateDefaultProfile()` but never read it back. This read is gated on\n * profile-level routing read and pinned to the caller's own profile — a shop\n * role asking for a sibling profile is refused.\n */\n async getDefaultForProfile(profileId: string): Promise<ProfileDefaultRoutingConfig> {\n return this.request('GET', `/routing/default/profile/${encodeURIComponent(profileId)}`);\n }\n\n /** Update default config for a profile. `POST /routing/default/profile/{profileId}` */\n async updateDefaultProfile(\n profileId: string,\n params: Record<string, unknown>,\n ): Promise<ProfileDefaultRoutingConfig> {\n return this.request('POST', `/routing/default/profile/${encodeURIComponent(profileId)}`, {\n body: params,\n });\n }\n\n /** List routing configs for profile. `GET /routing/list/profile` */\n async listForProfile(): Promise<RoutingDictionary> {\n return this.request('GET', '/routing/list/profile');\n }\n\n /** Evaluate a routing rule. `POST /routing/rule/evaluate` */\n async evaluateRule(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/rule/evaluate', { body: params });\n }\n\n /** Migrate routing rules for profile. `POST /routing/rule/migrate` */\n async migrateRule(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/rule/migrate', { body: params });\n }\n\n /** Evaluate routing for a payment. `POST /routing/evaluate` */\n async evaluate(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/evaluate', { body: params });\n }\n\n /** Update gateway scores for dynamic routing. `POST /routing/feedback` */\n async feedback(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/feedback', { body: params });\n }\n}\n\nclass RoutingDecisionManager {\n constructor(private readonly request: RequestFn) {}\n\n /** Upsert decision manager config. `PUT /routing/decision` */\n async upsert(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PUT', '/routing/decision', { body: params });\n }\n\n /** Retrieve decision manager config. `GET /routing/decision` */\n async retrieve(): Promise<Record<string, unknown>> {\n return this.request('GET', '/routing/decision');\n }\n\n /** Delete decision manager config. `DELETE /routing/decision` */\n async delete(): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/routing/decision');\n }\n\n /** Upsert surcharge decision config. `PUT /routing/decision/surcharge` */\n async upsertSurcharge(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PUT', '/routing/decision/surcharge', { body: params });\n }\n\n /** Retrieve surcharge decision config. `GET /routing/decision/surcharge` */\n async retrieveSurcharge(): Promise<Record<string, unknown>> {\n return this.request('GET', '/routing/decision/surcharge');\n }\n\n /** Delete surcharge decision config. `DELETE /routing/decision/surcharge` */\n async deleteSurcharge(): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/routing/decision/surcharge');\n }\n}\n\n/**\n * Merchant-friendly surcharge rules: configure a per-payment-method surcharge\n * (fixed or %) added to the amount the buyer pays — without hand-writing the\n * Euclid DSL. Scope to a shop via `profile_id` (omit for merchant-wide).\n *\n * Distinct from the platform fee (a balance deduction): a surcharge changes what\n * the buyer is charged.\n */\nclass SurchargeRules {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create or replace the surcharge program for a scope.\n *\n * `PUT /routing/surcharge/rules`\n *\n * @example\n * ```typescript\n * await delopay.routing.surchargeRules.upsert({\n * surcharges: [\n * { payment_method: 'crypto', surcharge: { rate: { percent: 1.0 } } },\n * { payment_method: 'card', surcharge: { fixed: { amount: 35 } } },\n * ],\n * });\n * ```\n */\n async upsert(params: SurchargeRuleRequest): Promise<SurchargeRuleResponse> {\n return this.request('PUT', '/routing/surcharge/rules', { body: params });\n }\n\n /**\n * Retrieve the active surcharge program for a scope, or `null` when none is set.\n *\n * `GET /routing/surcharge/rules?profile_id={profileId}`\n *\n * @param profileId - Shop scope. Omit for the merchant-wide rule.\n */\n async retrieve(profileId?: string): Promise<SurchargeRuleResponse | null> {\n return this.request('GET', '/routing/surcharge/rules', {\n query: { profile_id: profileId },\n });\n }\n\n /**\n * Deactivate the active surcharge program for a scope.\n *\n * `DELETE /routing/surcharge/rules?profile_id={profileId}`\n *\n * @param profileId - Shop scope. Omit for the merchant-wide rule.\n */\n async delete(profileId?: string): Promise<void> {\n return this.request('DELETE', '/routing/surcharge/rules', {\n query: { profile_id: profileId },\n });\n }\n}\n\n/**\n * Checkout theme programs: which of a shop's stored appearance variants a buyer\n * is shown.\n *\n * Same engine and same wire format as the advanced routing rules above — a\n * Euclid program whose rules run top-down, first match wins, with\n * `defaultSelection` as the fallback — with the output swapped for a variant\n * name. That is deliberate: the dashboard's routing rule builder can author\n * these without learning a second condition language.\n *\n * **A theme program decides a look and nothing else.** It cannot express which\n * payment methods are offered, what is charged, which provider processes the\n * payment, or whether it succeeds. The allowed dimensions are fixed server-side\n * by the output type — see {@link CheckoutThemeDimension} — so that is a\n * property of the API rather than a convention.\n *\n * Naming a variant the shop has not defined is **not** an error: the checkout\n * falls back to the shop default, exactly as it does for an unknown `?theme=`,\n * because a buyer who cannot pay is worse than a buyer who sees the default\n * look. Such names come back in `warnings` instead, recomputed on every read.\n */\nclass CheckoutThemeRules {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create or replace the theme program for a scope.\n *\n * `PUT /routing/checkout-theme/rules`\n *\n * Supersedes rather than overwrites: the previous active version is retired\n * and a new one stored, so the record of which look was live when survives.\n * Pass `active: false` to store a revision **without** retiring the live one —\n * that is where a program drafted against a variant you have not built yet\n * belongs.\n *\n * @example A phone in Germany gets the compact look; everyone else the house style.\n * ```typescript\n * await delopay.routing.checkoutThemeRules.upsert({\n * name: 'Autumn targeting',\n * profile_id: 'pro_...',\n * algorithm: {\n * rules: [\n * {\n * name: 'German phones',\n * connectorSelection: { theme: { variant: 'compact' } },\n * statements: [\n * {\n * condition: [\n * {\n * lhs: 'device_class',\n * comparison: 'equal',\n * value: { type: 'enum_variant', value: 'phone' },\n * metadata: {},\n * },\n * {\n * lhs: 'browser_language',\n * comparison: 'equal',\n * value: { type: 'enum_variant', value: 'de' },\n * metadata: {},\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * defaultSelection: { theme: { variant: 'house' } },\n * metadata: {},\n * },\n * });\n * ```\n */\n async upsert(params: CheckoutThemeProgramRequest): Promise<CheckoutThemeProgramResponse> {\n return this.request('PUT', '/routing/checkout-theme/rules', { body: params });\n }\n\n /**\n * Retrieve the active theme program for a scope, or `null` when none is set.\n *\n * `GET /routing/checkout-theme/rules?profile_id={profileId}`\n *\n * @param profileId - Shop scope. Omit for the merchant-wide program. A\n * shop-scoped caller that omits it gets its own shop's program.\n */\n async retrieve(profileId?: string): Promise<CheckoutThemeProgramResponse | null> {\n return this.request('GET', '/routing/checkout-theme/rules', {\n query: { profile_id: profileId },\n });\n }\n\n /**\n * Deactivate the active theme program for a scope. Idempotent.\n *\n * `DELETE /routing/checkout-theme/rules?profile_id={profileId}`\n *\n * Deactivation, not deletion — the stored row is what says which look was\n * live when, and that history cannot be reconstructed after the fact. Shops\n * go back to their default appearance immediately.\n *\n * @param profileId - Shop scope. Omit for the merchant-wide program.\n */\n async delete(profileId?: string): Promise<void> {\n return this.request('DELETE', '/routing/checkout-theme/rules', {\n query: { profile_id: profileId },\n });\n }\n}\n\n/**\n * Rendered-to-paid conversion, per appearance variant and segment.\n *\n * Answers the one question theme targeting exists for: *does variant B convert\n * better than the house style, on phones, in Germany?*\n *\n * **What a rate here means.** The denominator is backend-observed checkout page\n * opens, deduplicated by device within the hosted checkout's cache window, with\n * automated traffic excluded from both sides. It is narrower than \"paints\", and\n * that is deliberate - counting one buyer's refresh as a second render would\n * understate conversion. The exact basis travels with every response in\n * `denominator`, and the ways it is not the whole truth travel in `caveats`.\n *\n * **The server decides what may be concluded, not you.** Rate, Wilson interval,\n * per-cell `verdict` and the variant-vs-default `separates` test are computed\n * once, server-side, and shipped as values. Do not recompute them: the first\n * client that rounds differently tells a merchant a difference is real when the\n * server says it is not.\n */\nclass CheckoutThemeConversion {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Rendered-to-paid conversion for a shop over a window.\n *\n * `GET /routing/checkout-theme/conversion`\n *\n * Requires `CheckoutBranding` read at profile scope - the same permission\n * that governs seeing how a checkout looks.\n *\n * @param params - Window (RFC3339, `start` inclusive / `end` exclusive), the\n * shop, and the dimension to group by.\n *\n * @example Which variant wins on which device, over the last 30 days.\n * ```typescript\n * const report = await delopay.routing.checkoutThemeConversion.retrieve({\n * profile_id: 'pro_...',\n * start: '2026-07-21T00:00:00Z',\n * end: '2026-08-20T00:00:00Z',\n * segment: 'device',\n * });\n *\n * for (const c of report.comparisons) {\n * if (!c.separates) continue; // \"not shown to differ\" - say nothing\n * console.log(`${c.variant} on ${c.segment}: ${c.higher} converts better`);\n * }\n * ```\n */\n async retrieve(params: CheckoutThemeConversionQuery): Promise<CheckoutThemeConversionResponse> {\n return this.request('GET', '/routing/checkout-theme/conversion', {\n query: {\n profile_id: params.profile_id,\n start: params.start,\n end: params.end,\n segment: params.segment,\n },\n });\n }\n}\n","import type { RequestFn } from '../client';\n\n/** Index discriminator returned for each search result group. */\nexport type SearchIndex =\n | 'payment_attempts'\n | 'payment_intents'\n | 'refunds'\n | 'disputes'\n | 'payouts'\n | 'sessionizer_payment_attempts'\n | 'sessionizer_payment_intents'\n | 'sessionizer_refunds'\n | 'sessionizer_disputes'\n | 'routing_rules'\n | 'webhook_events'\n | 'audit_logs'\n | 'subscriptions';\n\nexport type SearchStatus = 'Success' | 'Failure';\n\n/** One result group (per index) in the response array. */\nexport interface SearchGroupResponse {\n count: number;\n index: SearchIndex;\n hits: Record<string, unknown>[];\n status: SearchStatus;\n}\n\n/**\n * The window a global search covers. The documented wire fields are\n * `start_time` (required) and `end_time` (optional — omit it for \"up to\n * now\"); the server also accepts the camelCase spellings as aliases, which\n * earlier SDK versions sent, so both are declared and either compiles.\n * Prefer the snake_case pair: it is what the operation documents.\n */\nexport type SearchTimeRange =\n | { start_time: string; end_time?: string | null }\n /** @deprecated Use `start_time` / `end_time` — the documented wire names. */\n | { startTime: string; endTime?: string | null };\n\nexport interface GlobalSearchRequest {\n query: string;\n filters?: Record<string, unknown>;\n /** Naive ISO 8601 bounds; `end_time` may be omitted. */\n timeRange?: SearchTimeRange;\n /** Wire alias for `timeRange` — the server reads either. */\n time_range?: SearchTimeRange;\n}\n\n/** Global cross-index search. */\nexport class Search {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Search every supported index for `query`.\n * `POST /analytics/search`\n *\n * @example\n * ```typescript\n * const groups = await delopay.search.global({ query: 'pay_abc' });\n * for (const g of groups) console.log(g.index, g.count);\n * ```\n */\n async global(\n params: GlobalSearchRequest,\n options?: { signal?: AbortSignal },\n ): Promise<SearchGroupResponse[]> {\n return this.request('POST', '/analytics/search', {\n body: params,\n ...(options?.signal ? { signal: options.signal } : {}),\n });\n }\n}\n","import type {\n CheckoutBrandingResponse,\n CheckoutBrandingUpdate,\n ShopCreateRequest,\n ShopResponse,\n ShopUpdateRequest,\n GatewayConnectRequest,\n GatewayResponse,\n ProfileLogoUploadResponse,\n ShopStatsResponse,\n StatsPeriod,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/** Manage gateway connections for a specific shop. */\nclass ShopGateways {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Connect a payment gateway to a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID.\n * @param params - Gateway connector credentials and configuration.\n * @returns The created gateway connection.\n */\n async connect(\n merchantId: string,\n shopId: string,\n params: GatewayConnectRequest,\n ): Promise<GatewayResponse> {\n return this.request(\n 'POST',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`,\n { body: params },\n );\n }\n\n /**\n * List all gateway connections for a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID.\n * @returns Array of gateway connections.\n */\n async list(merchantId: string, shopId: string): Promise<GatewayResponse[]> {\n return this.request(\n 'GET',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`,\n );\n }\n\n /**\n * Disconnect a gateway from a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID.\n * @param gatewayId - The gateway connector ID to remove.\n * @returns The removed gateway connection.\n */\n async disconnect(\n merchantId: string,\n shopId: string,\n gatewayId: string,\n ): Promise<GatewayResponse> {\n return this.request(\n 'DELETE',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways/${encodeURIComponent(gatewayId)}`,\n );\n }\n}\n\n/**\n * Create and manage shops (business profiles) within a merchant account.\n *\n * Each shop can have its own gateway connections, routing rules, and fee schedules.\n */\nexport class Shops {\n /** Gateway connection management for shops. */\n readonly gateways: ShopGateways;\n\n constructor(private readonly request: RequestFn) {\n this.gateways = new ShopGateways(request);\n }\n\n /**\n * Create a new shop under a merchant account.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Shop creation parameters (name, etc.).\n * @returns The created shop.\n *\n * @example\n * ```typescript\n * const shop = await delopay.shops.create('merch_123', { shop_name: 'EU Store' });\n * ```\n */\n async create(merchantId: string, params: ShopCreateRequest): Promise<ShopResponse> {\n return this.request('POST', `/shops/${encodeURIComponent(merchantId)}`, { body: params });\n }\n\n /**\n * Retrieve a shop by its ID.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID.\n * @returns The shop.\n */\n async retrieve(merchantId: string, shopId: string): Promise<ShopResponse> {\n return this.request(\n 'GET',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,\n );\n }\n\n /**\n * Update a shop's configuration.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID to update.\n * @param params - Fields to update.\n * @returns The updated shop.\n */\n async update(\n merchantId: string,\n shopId: string,\n params: ShopUpdateRequest,\n ): Promise<ShopResponse> {\n return this.request(\n 'PUT',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,\n { body: params },\n );\n }\n\n /**\n * Delete a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID to delete.\n * @returns The deleted shop object.\n */\n async delete(merchantId: string, shopId: string): Promise<ShopResponse> {\n return this.request(\n 'DELETE',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,\n );\n }\n\n /**\n * List all shops under a merchant account.\n *\n * @param merchantId - The merchant account ID.\n * @returns Array of shops.\n */\n async list(merchantId: string): Promise<ShopResponse[]> {\n return this.request('GET', `/shops/${encodeURIComponent(merchantId)}`);\n }\n\n /**\n * Successful-order count and revenue for one shop.\n *\n * Unlike `projects.stats()` this needs only `ProfileAccountRead`, so a\n * shop-scoped user can load it for their own shop; merchant-level users can\n * load any shop of their merchant.\n *\n * Revenue comes back FX-converted as `revenue_usd` (USD major units) plus a\n * `revenue_by_currency` breakdown. The legacy `revenue` field is a raw\n * cross-currency minor-unit sum and should not be displayed.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID.\n * @param period - Window in days, or `'all'` for an all-time total.\n * Omitted means the server default of 30 days.\n * @returns The shop's stats over the requested window.\n *\n * @example\n * ```typescript\n * const stats = await delopay.shops.stats('merch_123', 'pro_1', 'all');\n * console.log(stats.orders, stats.revenue_usd);\n * ```\n */\n async stats(\n merchantId: string,\n shopId: string,\n period?: StatsPeriod,\n ): Promise<ShopStatsResponse> {\n const path = `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/stats`;\n if (period === undefined) return this.request('GET', path);\n return this.request('GET', path, { query: { period: String(period) } });\n }\n\n /**\n * Upload a logo file for a shop. The file is stored in Delopay's configured\n * object store and a public HTTPS URL is returned. This method does NOT write\n * the URL into the shop's `payment_link_config.logo` — call\n * `shops.update` afterwards with the returned `logo_url` to persist the change.\n *\n * Accepts PNG, JPEG, WebP or SVG. The file must be ≤ 1 MiB.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID.\n * @param file - The logo file (Blob / File in browsers).\n * @returns The publicly-reachable URL of the uploaded logo.\n *\n * @example\n * ```typescript\n * const { logo_url } = await delopay.shops.uploadLogo('merch_1', 'pro_1', file);\n * await delopay.shops.update('merch_1', 'pro_1', {\n * payment_link_config: { logo: logo_url },\n * });\n * ```\n */\n async uploadLogo(\n merchantId: string,\n shopId: string,\n file: Blob,\n ): Promise<ProfileLogoUploadResponse> {\n const form = new FormData();\n form.append('file', file);\n return this.request(\n 'POST',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/logo`,\n { body: form },\n );\n }\n\n /**\n * Update only the checkout appearance (the `payment_link_config` blob:\n * theme, logo, colours, seller name, SDK layout/rules, DeloPay-branding\n * toggle) of a shop. Applied as a whole-object replace of\n * `payment_link_config`, mirroring the shop-update semantics.\n *\n * Gated on the dedicated `CheckoutBranding` permission, so \"may restyle\n * the checkout\" can be granted without full account/shop write.\n *\n * `POST /shops/{merchantId}/{shopId}/checkout-branding`\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID to restyle.\n * @param params - The new `payment_link_config` blob (full replacement).\n * @returns The saved branding — the same shape `retrieveCheckoutBranding`\n * returns, not the whole shop. A role whose only power is restyling a\n * checkout must not receive the webhook signing key or the card-vault\n * configuration back from a save.\n */\n async updateCheckoutBranding(\n merchantId: string,\n shopId: string,\n params: CheckoutBrandingUpdate,\n options?: RequestExtras,\n ): Promise<CheckoutBrandingResponse> {\n return this.request(\n 'POST',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/checkout-branding`,\n { body: params, ...options },\n );\n }\n\n /**\n * Read only the checkout appearance of a shop, so the role that may restyle a\n * checkout can load the checkout it may restyle.\n *\n * Gated on `ProfileCheckoutBrandingRead` — the read twin of the\n * `ProfileCheckoutBrandingEdit` guard on `updateCheckoutBranding` above.\n * Prefer this over `shops.retrieve` for the branding editor: `retrieve`\n * returns the whole profile, including the webhook signing key and the\n * card-vault configuration, and needs the shop-read permission for exactly\n * that reason.\n *\n * `GET /shops/{merchantId}/{shopId}/checkout-branding`\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID whose branding to read.\n * @returns The shop's id, name and stored `payment_link_config`. That config\n * is `null` when the shop has never been styled — the untouched default, not\n * an error, and distinct from a stored-but-empty style.\n */\n async retrieveCheckoutBranding(\n merchantId: string,\n shopId: string,\n options?: RequestExtras,\n ): Promise<CheckoutBrandingResponse> {\n return this.request(\n 'GET',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/checkout-branding`,\n options,\n );\n }\n}\n","import type {\n StripeConnectAccountRequest,\n StripeConnectAccountResponse,\n StripeConnectLinkRequest,\n StripeConnectLinkResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class StripeConnect {\n constructor(private readonly request: RequestFn) {}\n\n async createAccount(params: StripeConnectAccountRequest): Promise<StripeConnectAccountResponse> {\n return this.request('POST', '/connector-onboarding/stripe/accounts', { body: params });\n }\n\n async createAccountLink(params: StripeConnectLinkRequest): Promise<StripeConnectLinkResponse> {\n return this.request('POST', '/connector-onboarding/stripe/account-links', { body: params });\n }\n\n // --- Generic connector onboarding (Task 4.11) ---\n\n /** Get onboarding action URL. `POST /connector-onboarding/action-url` */\n async getActionUrl(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/connector-onboarding/action-url', { body: params });\n }\n\n /** Sync onboarding status. `POST /connector-onboarding/sync` */\n async syncOnboarding(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/connector-onboarding/sync', { body: params });\n }\n\n /** Reset tracking ID. `POST /connector-onboarding/reset-tracking-id` */\n async resetTrackingId(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/connector-onboarding/reset-tracking-id', { body: params });\n }\n}\n","import type { ThreeDsRuleExecuteRequest, ThreeDsRuleResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class ThreeDsRules {\n constructor(private readonly request: RequestFn) {}\n\n async execute(params: ThreeDsRuleExecuteRequest): Promise<ThreeDsRuleResponse> {\n return this.request('POST', '/three-ds-decision/execute', { body: params });\n }\n}\n","import type {\n SignUpRequest,\n SignUpWithMerchantRequest,\n SignInRequest,\n AuthResponse,\n UserResponse,\n ChangePasswordRequest,\n DeleteAccountRequest,\n ForgotPasswordRequest,\n ResetPasswordRequest,\n SwitchMerchantRequest,\n SwitchProfileRequest,\n ImpersonateEmployeeRequest,\n InviteUsersRequest,\n InviteUsersResponse,\n AddUserRequest,\n AddUserResponse,\n UpdateUserRoleRequest,\n DeleteUserRoleRequest,\n TotpResponse,\n RecoveryCodesResponse,\n PhoneOtpRequest,\n PhoneOtpResponse,\n PhoneOtpVerifyRequest,\n PhoneOtpVerifyResponse,\n UpdateMetadataRequest,\n UpdateUserDetailsRequest,\n FromEmailRequest,\n TokenResponse,\n VerifyTotpRequest,\n Terminate2faQueryParams,\n ListInvitableRolesParams,\n ListUsersInLineageParams,\n UserInLineage,\n LoginHistoryParams,\n LoginHistoryResponse,\n UserSessionListResponse,\n UserSessionRevokeResponse,\n ParentGroupInfo,\n RoleConnectorGrant,\n UpdateRoleConnectorGrantParams,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Users {\n constructor(private readonly request: RequestFn) {}\n\n async signUp(params: SignUpRequest | SignUpWithMerchantRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/signup', { body: params });\n }\n\n async signIn(params: SignInRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/signin', { body: params });\n }\n\n async signOut(): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/signout');\n }\n\n /**\n * Sliding-session refresh: exchange the current (still-valid) login JWT\n * for a fresh one with the same claims and a full lifetime. The backend\n * keeps the session's identity (`jti`), slides `user_session.expires_at`\n * forward and re-sets the `login_token` cookie.\n *\n * Requires a token backed by a revocable session (a `jti` claim). Signin\n * and switch-merchant/-profile tokens have one; **session-less tokens do\n * not and are rejected with 400** — team-impersonation tokens are the\n * case in practice, and they are deliberately tab-scoped and\n * time-bounded rather than renewable. A 400 here is not a dead session:\n * the token remains valid for ordinary calls, it simply cannot slide.\n *\n * Rejected (401) for expired, blacklisted or revoked tokens — refresh can\n * only extend a session that is still alive. Rate-limited server-side\n * (429) to one mint per session per minute; treat a 429 as \"still fresh\n * enough\", not as an error.\n *\n * The returned token is NOT applied to this client automatically — pass\n * it to `setJwtToken()`, or use {@link Delopay.refreshSession} which does\n * both.\n *\n * `POST /user/token/refresh`. Requires a logged-in JWT.\n */\n async refreshToken(): Promise<TokenResponse> {\n return this.request('POST', '/user/token/refresh');\n }\n\n /**\n * Paginated login history for the authenticated user -- IP, User-Agent,\n * country / city / lat-lon (when GeoIP is enabled), success and failure\n * events with their reasons. Strictly scoped to the JWT subject; a user\n * can only see their own activity.\n *\n * `GET /user/me/login-activity`. Requires a logged-in JWT.\n *\n * Returns an empty page when a Delopay admin is impersonating a merchant,\n * so the admin's metadata is not exposed inside the merchant dashboard.\n */\n async listLoginActivity(params?: LoginHistoryParams): Promise<LoginHistoryResponse> {\n if (params === undefined) {\n return this.request('GET', '/user/me/login-activity');\n }\n return this.request('GET', '/user/me/login-activity', {\n query: params as Record<string, number | undefined>,\n });\n }\n\n /**\n * List the authenticated user's currently-active dashboard sessions\n * (one row per minted login JWT that hasn't been revoked or expired).\n *\n * The row matching the JWT making this call has `is_current: true`,\n * which is what lets the dashboard render a \"This device\" tag.\n *\n * `GET /user/me/sessions`. Requires a logged-in JWT. Returns an empty\n * list when a Delopay admin is impersonating a non-admin merchant\n * (same guard as `listLoginActivity`).\n */\n async listActiveSessions(): Promise<UserSessionListResponse> {\n return this.request('GET', '/user/me/sessions');\n }\n\n /**\n * Disconnect one of the authenticated user's sessions. The matching\n * JWT is rejected on its next request — fast-path via Redis, fall back\n * to the persistent `revoked_at` column.\n *\n * Idempotent: revoking an already-revoked or unknown id returns 404,\n * which the caller can treat as success for retry purposes. Revoking\n * a session id that belongs to a different user also returns 404 —\n * the response intentionally doesn't leak whether the id exists.\n *\n * `POST /user/me/sessions/{sessionId}/revoke`.\n */\n async revokeSession(sessionId: string): Promise<UserSessionRevokeResponse> {\n return this.request('POST', `/user/me/sessions/${encodeURIComponent(sessionId)}/revoke`);\n }\n\n async getDetails(): Promise<UserResponse> {\n return this.request('GET', '/user');\n }\n\n async update(params: UpdateUserDetailsRequest): Promise<UserResponse> {\n return this.request('POST', '/user/update', { body: params });\n }\n\n /**\n * RFC 7396 merge-patch the caller's own user-scoped metadata bucket.\n * Returns the full user details, so callers can refresh their context\n * without a second fetch.\n *\n * `PATCH /user/metadata`\n */\n async updateMetadata(params: UpdateMetadataRequest): Promise<UserResponse> {\n return this.request('PATCH', '/user/metadata', { body: params });\n }\n\n /**\n * RFC 7396 merge-patch the merchant-scoped metadata bucket shared by\n * every dashboard user of the merchant. Same response contract as\n * {@link Users.updateMetadata}.\n *\n * `PATCH /user/merchant/metadata`\n */\n async updateMerchantMetadata(params: UpdateMetadataRequest): Promise<UserResponse> {\n return this.request('PATCH', '/user/merchant/metadata', { body: params });\n }\n\n /**\n * Permanently delete the caller's account. Requires a fresh password\n * (and a current 6-digit TOTP code if the user has TOTP enrolled). On\n * success all role assignments are removed, the user record is\n * deactivated, and all in-flight sessions are invalidated. The caller\n * should clear local credentials and route to the login page.\n *\n * Returns `InvalidDeleteOperation` when the caller is the sole\n * owner-level admin of an org / merchant / profile -- they must\n * transfer ownership first.\n */\n async deleteAccount(params: DeleteAccountRequest): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/user/account', { body: params });\n }\n\n async changePassword(params: ChangePasswordRequest): Promise<UserResponse> {\n return this.request('POST', '/user/change-password', { body: params });\n }\n\n async rotatePassword(params: ResetPasswordRequest): Promise<UserResponse> {\n return this.request('POST', '/user/rotate-password', { body: params });\n }\n\n async forgotPassword(params: ForgotPasswordRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/forgot-password', { body: params });\n }\n\n /**\n * Commit a password reset.\n *\n * The caller is responsible for obtaining a `SinglePurposeToken` with\n * `purpose: reset_password` via the email-token exchange + TOTP flow\n * (see `fromEmail`, `beginTotp`, `updateTotp`/`verifyTotp`,\n * `generateRecoveryCodes`, `terminate2fa`) and setting it on the client\n * via `setJwtToken` before calling this method. `body.token` must still\n * be the original `EmailToken` from the reset-link URL — the handler\n * decodes it a second time to find the user.\n */\n async resetPassword(params: ResetPasswordRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/reset-password', { body: params });\n }\n\n /**\n * Exchange an email-link token (`EmailToken`) for a single-purpose JWT\n * that drives the next step of the flow (TOTP, verify email, accept\n * invitation, etc.). No authentication required.\n *\n * The `token_type` in the response tells you which step to run next.\n */\n async fromEmail(params: FromEmailRequest): Promise<TokenResponse> {\n return this.request('POST', '/user/from-email', { body: params });\n }\n\n async verifyEmail(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/verify-email', { body: params });\n }\n\n async sendVerificationEmail(params: ForgotPasswordRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/verify-email-request', { body: params });\n }\n\n async createMerchant(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/create-merchant', { body: params });\n }\n\n async switchMerchant(params: SwitchMerchantRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/switch/merchant', { body: params });\n }\n\n async switchProfile(params: SwitchProfileRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/switch/profile', { body: params });\n }\n\n async listMerchants(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/list/merchant');\n }\n\n async listProfiles(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/list/profile');\n }\n\n async inviteUsers(params: InviteUsersRequest[]): Promise<InviteUsersResponse[]> {\n return this.request('POST', '/user/employees/invite', { body: params });\n }\n\n /**\n * Add a team member directly, without sending an invite email.\n * `POST /user/employees/add`\n *\n * Unlike `inviteUsers`, the account is active immediately and you hand over\n * the credentials yourself. Omit `password` to have the server generate one\n * and return it once in `password` on the response; supply your own and it is\n * not echoed back. Either way the member must change it on first sign-in.\n *\n * Same role rules as invite: you cannot grant a role above your own, and a\n * shop-scoped caller can only target their own shop.\n */\n async addUser(params: AddUserRequest): Promise<AddUserResponse> {\n return this.request('POST', '/user/employees/add', { body: params });\n }\n\n /**\n * Impersonate one of your own team members — `POST /user/employees/impersonate`.\n *\n * Mints a session token **as** the given member, so the dashboard renders\n * exactly what they see (useful for support and role verification). The\n * caller needs the *Impersonation* permission, and the member's role must\n * rank **strictly below** the caller's (`Profile < Merchant < Organization`);\n * the server rejects self-impersonation, cross-merchant targets, and\n * equal/higher roles.\n *\n * The returned token is tab-scoped by design: open it in a fresh tab (e.g.\n * `/auth/impersonate?token=…`) rather than replacing the caller's own\n * session. No auth cookie is set on the response.\n */\n async impersonateEmployee(params: ImpersonateEmployeeRequest): Promise<TokenResponse> {\n return this.request('POST', '/user/employees/impersonate', { body: params });\n }\n\n async acceptInvitation(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/employees/invite/accept', { body: params });\n }\n\n /**\n * Accept an invitation via the email-link flow.\n *\n * Caller must already hold a `SinglePurposeToken` with\n * `purpose: accept_invitation_from_email` (obtained via `fromEmail` + any\n * required TOTP step) and have set it on the client via `setJwtToken`.\n * `body.token` must still be the original `EmailToken` from the\n * invite-link URL — the handler decodes it a second time to find the\n * invitee and the entity lineage.\n */\n async acceptInviteFromEmail(params: FromEmailRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/accept-invite-from-email', { body: params });\n }\n\n /**\n * Start TOTP setup (or no-op if already set).\n *\n * Returns the QR-code payload when the user has no TOTP configured yet;\n * returns `{ secret: null }` when the user is already set up (caller\n * should then prompt for a 6-digit code and call `verifyTotp`).\n *\n * Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async beginTotp(): Promise<TotpResponse> {\n return this.request('GET', '/user/2fa/totp/begin');\n }\n\n /**\n * Verify a 6-digit TOTP code for a user whose TOTP is already set up.\n * Marks the code as used in Redis so subsequent flow steps can advance.\n *\n * Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async verifyTotp(params: VerifyTotpRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/2fa/totp/verify', { body: params });\n }\n\n async resetTotp(): Promise<Record<string, unknown>> {\n return this.request('GET', '/user/2fa/totp/reset');\n }\n\n async generateRecoveryCodes(): Promise<RecoveryCodesResponse> {\n return this.request('GET', '/user/2fa/recovery-code/generate');\n }\n\n async verifyRecoveryCode(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/2fa/recovery-code/verify', { body: params });\n }\n\n async sendPhoneOtp(params: PhoneOtpRequest): Promise<PhoneOtpResponse> {\n return this.request('POST', '/user/phone/send-otp', { body: params });\n }\n\n async verifyPhoneOtp(params: PhoneOtpVerifyRequest): Promise<PhoneOtpVerifyResponse> {\n return this.request('POST', '/user/phone/verify-otp', { body: params });\n }\n\n /**\n * List all roles visible to the caller (predefined + custom).\n *\n * `GET /user/role/list`. With `groups: true` the response is the\n * parent-groups shape: `[{role_id, role_name, entity_type, role_scope,\n * parent_groups: [{name, description, scopes}]}]`; without it, the\n * deprecated flat `groups` shape.\n */\n async listRoles(params?: {\n groups?: boolean;\n entity_type?: string;\n }): Promise<Record<string, unknown>[]> {\n if (params === undefined) {\n return this.request('GET', '/user/role/list');\n }\n return this.request('GET', '/user/role/list', {\n query: { groups: params.groups, entity_type: params.entity_type },\n });\n }\n\n async listUserRoles(params?: Record<string, unknown>): Promise<Record<string, unknown>[]> {\n return this.request('POST', '/user/employees', { body: params });\n }\n\n /**\n * Change a team member's role. `POST /user/employees/update-role`\n *\n * Pass `profile_id` to name the shop when managing a shop's team as a\n * merchant-scoped admin — see {@link UpdateUserRoleRequest.profile_id}.\n */\n async updateUserRole(params: UpdateUserRoleRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/employees/update-role', { body: params });\n }\n\n /**\n * Remove a team member. `DELETE /user/employees/delete`\n *\n * Pass `profile_id` to name the shop when managing a shop's team as a\n * merchant-scoped admin — see {@link DeleteUserRoleRequest.profile_id}.\n */\n async deleteUserRole(params: DeleteUserRoleRequest): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/user/employees/delete', { body: params });\n }\n\n /** Sign in via OIDC. `POST /user/oidc` */\n async signInOidc(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/oidc', { body: params });\n }\n\n /** Transfer key. `POST /user/key/transfer` */\n async transferKey(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/key/transfer', { body: params });\n }\n\n /** List invitations. `GET /user/list/invitation` */\n async listInvitations(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/list/invitation');\n }\n\n /** Check 2FA status. `GET /user/2fa` */\n async check2faStatus(): Promise<Record<string, unknown>> {\n return this.request('GET', '/user/2fa');\n }\n\n /**\n * Finish first-time TOTP setup: commit the secret generated by `beginTotp`\n * against a 6-digit code from the user's authenticator app.\n *\n * `PUT /user/2fa/totp/verify`. Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async updateTotp(params: VerifyTotpRequest): Promise<Record<string, unknown>> {\n return this.request('PUT', '/user/2fa/totp/verify', { body: params });\n }\n\n /**\n * Complete the TOTP step and advance to the next flow stage (e.g.\n * `reset_password`). Returns a fresh single-purpose token with the\n * next `token_type`.\n *\n * `GET /user/2fa/terminate`. Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async terminate2fa(query?: Terminate2faQueryParams): Promise<TokenResponse> {\n if (query === undefined) {\n return this.request('GET', '/user/2fa/terminate');\n }\n return this.request('GET', '/user/2fa/terminate', {\n query: query as Record<string, boolean | undefined>,\n });\n }\n\n /** Create auth method. `POST /user/auth` */\n async createAuthMethod(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/auth', { body: params });\n }\n\n /** Update auth method. `PUT /user/auth` */\n async updateAuthMethod(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PUT', '/user/auth', { body: params });\n }\n\n /** List auth methods. `GET /user/auth/list` */\n async listAuthMethods(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/auth/list');\n }\n\n /** Get auth URL. `GET /user/auth/url` */\n async getAuthUrl(): Promise<Record<string, unknown>> {\n return this.request('GET', '/user/auth/url');\n }\n\n /** Select auth method. `POST /user/auth/select` */\n async selectAuth(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/auth/select', { body: params });\n }\n\n /**\n * List users in lineage.\n *\n * Needs the Users *view* grant now — the response carries colleagues' email\n * addresses, so a role without it is refused rather than handed a roster.\n * A shop-scoped role keeps reading its own shop's members.\n *\n * `GET /user/employees/list`\n */\n async listUsersInLineage(params?: ListUsersInLineageParams): Promise<UserInLineage[]> {\n return this.request('GET', '/user/employees/list', {\n query: params as Record<string, string | undefined> | undefined,\n });\n }\n\n /** Resend invite. `POST /user/resend-invite` */\n async resendInvite(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/resend-invite', { body: params });\n }\n\n /**\n * Get the caller's parent permission groups + scopes.\n *\n * `GET /user/role`\n */\n async getRolePermissions(): Promise<ParentGroupInfo[]> {\n return this.request('GET', '/user/role');\n }\n\n /**\n * List invitable roles. `GET /user/role/list/invite`\n *\n * @param params - Optional query. `entity_type` scopes the role list to a\n * particular entity (e.g. `'merchant'` to list only merchant-scoped roles\n * when inviting employees from the merchant dashboard).\n */\n async listInvitableRoles(params?: ListInvitableRolesParams): Promise<Record<string, unknown>[]> {\n if (params === undefined || params.entity_type === undefined) {\n return this.request('GET', '/user/role/list/invite');\n }\n return this.request('GET', '/user/role/list/invite', {\n query: { entity_type: params.entity_type },\n });\n }\n\n /** List updatable roles. `GET /user/role/list/update` */\n async listUpdatableRoles(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/role/list/update');\n }\n\n /** Get parent list. `GET /user/parent/list` */\n async getParentList(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/parent/list');\n }\n\n /** Create a role. `POST /user/role` */\n async createRole(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/role', { body: params });\n }\n\n /** Get role by ID. `GET /user/role/{roleId}` */\n async getRoleById(roleId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/user/role/${encodeURIComponent(roleId)}`);\n }\n\n /** Update role by ID. `PUT /user/role/{roleId}` */\n async updateRole(\n roleId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('PUT', `/user/role/${encodeURIComponent(roleId)}`, { body: params });\n }\n\n /**\n * Delete a custom role. Predefined roles and roles still assigned to\n * team members are rejected by the backend with a 400.\n *\n * `DELETE /user/role/{roleId}`\n */\n async deleteRole(roleId: string): Promise<Record<string, unknown>> {\n return this.request('DELETE', `/user/role/${encodeURIComponent(roleId)}`);\n }\n\n /**\n * Read which individual connector accounts a role may see.\n *\n * `GET /user/role/{roleId}/connectors`\n *\n * **Check `restricted` before reading `connectors`.** An empty list is\n * ambiguous by itself, so the backend states which case it is: `false` means\n * the role holds no grant and sees whatever its entity and profile scope\n * already allowed. Rendering an empty `connectors` array as \"this role sees\n * nothing\" inverts the meaning.\n *\n * Requires the permission that *edits a role*, not a connector permission.\n */\n async getRoleConnectors(roleId: string): Promise<RoleConnectorGrant> {\n return this.request('GET', `/user/role/${encodeURIComponent(roleId)}/connectors`);\n }\n\n /**\n * Replace the set of connector accounts a role may see.\n *\n * `PUT /user/role/{roleId}/connectors`\n *\n * The call **replaces** the whole set rather than adding to it, so send the\n * complete list every time. An empty `merchant_connector_ids` clears the\n * grant and returns the role to unrestricted.\n *\n * The backend refuses an id that is not a connector account of the caller's\n * own merchant, an `Organization`-scoped role (a connector account belongs to\n * exactly one merchant, so an org-spanning role cannot hold one coherently),\n * and any predefined role (one static entry shared by every tenant).\n *\n * Editing a grant invalidates the role cache and blacklists tokens minted\n * before the edit, so **users holding this role must sign in again**. Worth\n * saying in the UI before the save, not after.\n */\n async updateRoleConnectors(\n roleId: string,\n params: UpdateRoleConnectorGrantParams,\n ): Promise<RoleConnectorGrant> {\n return this.request('PUT', `/user/role/${encodeURIComponent(roleId)}/connectors`, {\n body: params,\n });\n }\n}\n","import type {\n ApplePayVerificationRequest,\n ApplePayVerificationResponse,\n ApplePayVerifiedDomainsResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Verification {\n constructor(private readonly request: RequestFn) {}\n\n async registerApplePayDomains(\n merchantId: string,\n params: ApplePayVerificationRequest,\n ): Promise<ApplePayVerificationResponse> {\n return this.request('POST', `/verify/apple-pay/${encodeURIComponent(merchantId)}`, {\n body: params,\n });\n }\n\n async getApplePayVerifiedDomains(\n params: Record<string, string>,\n ): Promise<ApplePayVerifiedDomainsResponse> {\n return this.request('GET', '/verify/applepay-verified-domains', {\n query: params,\n });\n }\n}\n","import type {\n EventType,\n PaymentResponse,\n RefundResponse,\n DisputeResponse,\n MandateResponse,\n PayoutResponse,\n ConfirmSubscriptionResponse,\n} from '../types';\n\n/**\n * The payload of a webhook event, tagged by kind.\n *\n * Mirrors the backend's `{ \"type\": …, \"object\": … }` envelope: `type` names the\n * payload shape and `object` carries it. Narrow on `content.type` to get a\n * fully-typed `object`:\n *\n * ```typescript\n * if (event.content.type === 'payment_details') {\n * event.content.object.payment_id; // typed as PaymentResponse\n * }\n * ```\n */\nexport type WebhookContent =\n | { type: 'payment_details'; object: PaymentResponse }\n | { type: 'refund_details'; object: RefundResponse }\n | { type: 'dispute_details'; object: DisputeResponse }\n | { type: 'mandate_details'; object: MandateResponse }\n | { type: 'payout_details'; object: PayoutResponse }\n | { type: 'subscription_details'; object: ConfirmSubscriptionResponse };\n\n/**\n * A parsed and verified Delopay webhook event.\n *\n * Matches the signed wire body exactly:\n * `{ merchant_id, event_id, event_type, content: { type, object }, timestamp }`.\n *\n * - `event_type` identifies the event, e.g. `'payment_succeeded'`.\n * - `content.type` tags the payload kind, e.g. `'payment_details'`.\n * - `content.object` is the payload; narrow on `content.type` to type it.\n */\nexport interface WebhookEvent {\n /** ID of the merchant that owns this event. */\n merchant_id: string;\n /** Unique ID for this event (stable across delivery retries). */\n event_id: string;\n /** Event type identifier, e.g. `'payment_succeeded'` or `'refund_succeeded'`. */\n event_type: EventType;\n /** The event payload, tagged by kind. Narrow on `content.type` to type `object`. */\n content: WebhookContent;\n /** ISO 8601 timestamp at which the webhook was sent. */\n timestamp: string;\n}\n\nfunction hexToBytes(hex: string): Uint8Array | null {\n if (hex.length === 0 || hex.length % 2 !== 0) return null;\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n const byte = Number.parseInt(hex.slice(i, i + 2), 16);\n if (Number.isNaN(byte)) return null;\n bytes[i / 2] = byte;\n }\n return bytes;\n}\n\nexport const Webhooks = {\n /**\n * Verify the signature of an incoming Delopay webhook and return the parsed event.\n *\n * Delopay signs each outgoing webhook with HMAC-SHA512 over the raw request body,\n * using your shop's webhook secret (the *payment response hash key* configured on\n * the shop). The hex-encoded digest is delivered in the `X-Webhook-Signature-512`\n * HTTP header.\n *\n * Uses the Web Crypto API (`globalThis.crypto.subtle`), so it runs unchanged in\n * Node 18+, modern browsers, Deno, Bun, and edge runtimes (Cloudflare Workers, Vercel Edge).\n *\n * Available as a static property on the `Delopay` class\n * (`Delopay.webhooks.verify`) and does not require a client instance.\n *\n * @param rawBody - The raw request body. Pass the original bytes (`Uint8Array` /\n * `Buffer`) when possible; if you pass a string, it must be the unmodified UTF-8\n * text of the request body. Do **not** parse it before passing.\n * @param signatureHeader - The value of the `X-Webhook-Signature-512` HTTP header.\n * @param secret - Your shop's webhook signing secret.\n * @returns Promise that resolves to the parsed webhook event.\n * @throws {Error} When the signature header is malformed or does not match the body.\n *\n * @example\n * ```typescript\n * // Express example\n * app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {\n * try {\n * const event = await Delopay.webhooks.verify(\n * req.body, // Buffer from express.raw()\n * req.header('x-webhook-signature-512') ?? '',\n * process.env.DELOPAY_WEBHOOK_SECRET!,\n * );\n * console.log(event.event_type, event.content.object);\n * res.sendStatus(200);\n * } catch {\n * res.status(400).send('Invalid signature');\n * }\n * });\n * ```\n */\n async verify(\n rawBody: string | Uint8Array,\n signatureHeader: string,\n secret: string,\n ): Promise<WebhookEvent> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new Error(\n 'Web Crypto unavailable: Delopay.webhooks.verify requires globalThis.crypto.subtle (Node 18+, modern browsers, Workers, Deno)',\n );\n }\n\n const signatureBytes = hexToBytes(signatureHeader.trim());\n if (!signatureBytes) {\n throw new Error('Invalid webhook signature format');\n }\n\n const encoder = new TextEncoder();\n const bodyBytes = typeof rawBody === 'string' ? encoder.encode(rawBody) : rawBody;\n\n // `TextEncoder.encode` returns `Uint8Array<ArrayBufferLike>` in current lib.dom.d.ts,\n // but `crypto.subtle.*` wants `BufferSource` (backed by `ArrayBuffer`). At runtime the\n // underlying buffer is always an `ArrayBuffer` — cast to quiet the type checker.\n const asBufferSource = (bytes: Uint8Array): BufferSource => bytes as unknown as BufferSource;\n const key = await subtle.importKey(\n 'raw',\n asBufferSource(encoder.encode(secret)),\n { name: 'HMAC', hash: 'SHA-512' },\n false,\n ['verify'],\n );\n\n const valid = await subtle.verify(\n 'HMAC',\n key,\n asBufferSource(signatureBytes),\n asBufferSource(bodyBytes),\n );\n\n if (!valid) {\n throw new Error('Invalid webhook signature');\n }\n\n const bodyText =\n typeof rawBody === 'string' ? rawBody : new TextDecoder('utf-8').decode(rawBody);\n return JSON.parse(bodyText) as WebhookEvent;\n },\n};\n","import type { RequestFn } from '../client';\nimport type {\n AnalyticsScopeRequest,\n AnalyticsScopeResponse,\n ClientAnalyticsRequest,\n DevicesAnalyticsResponse,\n GeoAnalyticsResponse,\n DeviceDrillRequest,\n GeoDrillRequest,\n DrillResponse,\n SubscriptionAnalyticsRequest,\n SubscriptionAnalyticsResponse,\n SubscriptionDrillRequest,\n ScopeDrillRequest,\n} from '../types';\n\nexport class Analytics {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Scoped, drill-level analytics dashboard for the authenticated merchant\n * (the same engine as the admin portal, pinned server-side to your own\n * merchant). The server ignores `merchant_id` — it always scopes to your\n * merchant, and to your single shop for profile-scoped users — so pass only\n * `project_id` / `shop_id` to drill and the window / `sections` fields.\n * Returns one drill level: the scope's daily series + previous window,\n * processor mix and direct children. `GET /analytics/scope`\n */\n async scope(params?: AnalyticsScopeRequest): Promise<AnalyticsScopeResponse> {\n return this.request('GET', '/analytics/scope', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Device analytics over the canonical client-context observation per\n * payment (browser/platform families, device classes and models, checkout\n * channel mix, time-to-pay), pinned server-side to your own merchant and\n * drillable via `project_id` / `shop_id` exactly like `scope`. Gated on the\n * client-context optimisation-use switch: when it is off the server answers\n * 200 with `enabled: false` and a caveat naming the switch.\n * `GET /analytics/devices`\n */\n async devices(params?: ClientAnalyticsRequest): Promise<DevicesAnalyticsResponse> {\n return this.request('GET', '/analytics/devices', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Geo analytics over the canonical client-context observation per payment:\n * country totals, city bubbles (IP mode), buyer languages, buyer-local\n * purchase hours and the IP-vs-billing mismatch share. `mode` selects the\n * location claim (`ip` default, `billing`); the two are never coalesced.\n * Same drill, window and gating contract as `devices`.\n * `GET /analytics/geo`\n */\n async geo(params?: ClientAnalyticsRequest): Promise<GeoAnalyticsResponse> {\n return this.request('GET', '/analytics/geo', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The recent payments behind one clicked geo target: a map country (in the\n * active claim mode), optionally narrowed to an IP-resolved city, or one\n * buyer-local heatmap cell (`dow` + `hour`, paid sessions only). Same\n * window/scope/filter and gating contract as `geo`; capped at 50 rows,\n * newest first, with the full match count alongside.\n * `GET /analytics/geo/transactions`\n */\n async geoTransactions(params: GeoDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/geo/transactions', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The recent payments behind one clicked device target: exactly one of a\n * browser family, a platform family, an identified device-model label, or\n * a device class. Family/model targets are resolved server-side with the\n * same classifiers the cards use. Same window/scope/filter and gating\n * contract as `devices`; 50 rows per page (`offset` for the next page),\n * newest first, with the full match count alongside.\n * `GET /analytics/devices/transactions`\n */\n async deviceTransactions(params: DeviceDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/devices/transactions', {\n // A discriminated union carries no index signature, so the widening\n // goes via `unknown` — the union is the point.\n query: params as unknown as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The payments behind one clicked element of the payments dashboard: a\n * processor-donut slice, a payment-method slice, an outcome segment of a\n * series bar, a series bucket, or a breakdown row — combinable, with\n * `target_bucket` narrowing every other target. The outcome mapping is the\n * one the series and donuts are folded with, expanded server-side, so the\n * list is what the clicked number was made of. Rows and the whole-match\n * `summary` carry USD figures converted with the dashboard's own rates.\n * Same window/scope/chip contract as `scope`; sorted per `sort_on` /\n * `sort_by`, `limit` rows (default 50) per page, `offset` for the next.\n * `GET /analytics/scope/transactions`\n */\n async scopeTransactions(params: ScopeDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/scope/transactions', {\n // A discriminated union carries no index signature, so the widening\n // goes via `unknown` — the union is the point, and the query builder\n // only ever reads own enumerable keys.\n query: params as unknown as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Subscription analytics over `subscription` and `invoice`: estimated\n * recurring volume, the invoice funnel, movement (new / expansion /\n * contraction / churn), both processor axes, plan mix and the breakdown one\n * level below the scope. Pinned server-side to your own merchant and\n * drillable via `project_id` / `shop_id` exactly like `scope`.\n *\n * Half the figures are **stocks** — a snapshot at the window's end rather\n * than a sum over it — so `est_monthly_volume_usd` and `active` can match\n * across a 7-day and a 30-day window while `billed_volume_usd` does not.\n * Day granularity only. `GET /analytics/subscriptions`\n */\n async subscriptions(\n params?: SubscriptionAnalyticsRequest,\n ): Promise<SubscriptionAnalyticsResponse> {\n return this.request('GET', '/analytics/subscriptions', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The billing cycles behind one clicked element of the subscription\n * dashboard: an invoice outcome, a processor slice on either axis, a plan\n * row, a subscription status, a movement component, a series bucket or a\n * breakdown row. Same window/scope/filter contract as `subscriptions`; 50\n * rows per page (`offset` for the next), newest first, with the full match\n * count alongside.\n *\n * A cycle that never reached a payment is listed too — that is what \"still\n * unpaid\" means — and carries its invoice id as `payment_id` with\n * `invoice_id` set to the same value, so you can always tell which you got.\n * `GET /analytics/subscriptions/list`\n */\n async subscriptionsList(params: SubscriptionDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/subscriptions/list', {\n // A discriminated union carries no index signature, so the widening\n // goes via `unknown` — the union is the point, and the query builder\n // only ever reads own enumerable keys.\n query: params as unknown as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /** Global search. `POST /analytics/search` */\n async search(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/analytics/search', { body: params });\n }\n\n /** Domain-specific search. `POST /analytics/search/{domain}` */\n async searchDomain(\n domain: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/analytics/search/${encodeURIComponent(domain)}`, {\n body: params,\n });\n }\n\n /** Get analytics info. `GET /analytics/{domain}/info` */\n async getInfo(domain: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/analytics/${encodeURIComponent(domain)}/info`);\n }\n\n /** Get API event logs. `GET /analytics/api-event-logs` */\n async apiEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/api-event-logs', { query: params });\n }\n\n /** Get SDK event logs. `POST /analytics/sdk-event-logs` */\n async sdkEventLogs(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/analytics/sdk-event-logs', { body: params });\n }\n\n /** Get connector event logs. `GET /analytics/connector-event-logs` */\n async connectorEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/connector-event-logs', { query: params });\n }\n\n /** Get routing event logs. `GET /analytics/routing-event-logs` */\n async routingEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/routing-event-logs', { query: params });\n }\n\n /** Get outgoing webhook event logs. `GET /analytics/outgoing-webhook-event-logs` */\n async outgoingWebhookEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/outgoing-webhook-event-logs', { query: params });\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class AnalyticsDashboard {\n constructor(private readonly request: RequestFn) {}\n\n /** Get analytics dashboard data. `GET /analytics-dashboard` */\n async retrieve(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics-dashboard', { query: params });\n }\n\n /** Generate analytics dashboard report. `POST /analytics-dashboard` */\n async generate(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/analytics-dashboard', { body: params });\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Cards {\n constructor(private readonly request: RequestFn) {}\n\n /** Create a card. `POST /cards/create` */\n async create(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/cards/create', { body: params });\n }\n\n /** Update a card. `POST /cards/update` */\n async update(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/cards/update', { body: params });\n }\n\n /** Retrieve card info by BIN. `GET /cards/{bin}` */\n async retrieve(bin: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/cards/${encodeURIComponent(bin)}`);\n }\n}\n","import type {\n DisputeExportRecord,\n DisputeListParams,\n ExportEnvelope,\n ExportFormat,\n BinaryExportOptions,\n ExportOptions,\n JsonExportOptions,\n MerchantAuditLogExportRecord,\n MerchantAuditLogListParams,\n PayoutExportRecord,\n PayoutListParams,\n RefundExportRecord,\n RefundListParams,\n SubscriptionExportRecord,\n SubscriptionListParams,\n TransactionExportParams,\n TransactionExportRecord,\n} from '../types';\nimport type { RequestFn, RequestOptions } from '../client';\n\n/** Query value shape `RequestOptions.query` accepts. */\ntype Query = NonNullable<RequestOptions['query']>;\n\n/**\n * Emit a list as a file.\n *\n * Every method here mirrors one list endpoint and takes **that list's own\n * filters**, unchanged — there is no second filter vocabulary for exports. The\n * shop scope is resolved the same way too, so an export cannot show a shop its\n * list would not: a shop-scoped token exports its own shop, and naming another\n * is refused rather than ignored.\n *\n * Every export is **one read**, not a paged walk, and is bounded at 25,000\n * rows (500 for `pdf`, which is a document rather than a data feed). Over the\n * bound the request is refused with `DE_07 export_row_limit_exceeded` carrying\n * `{entity, max_rows}` — a truncated finance file that reports success is the\n * thing these endpoints exist not to produce.\n *\n * `format` selects an `Accept` header, never a request field: an export reuses\n * its list's filter model as literally the same type, and several of those are\n * `deny_unknown_fields`, so a `format` key would be a 400. It defaults to\n * `json`, which resolves to a typed {@link ExportEnvelope}; `csv` and `pdf`\n * resolve to a `Blob`.\n */\nexport class Export {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Transactions. `POST /export/transactions`\n *\n * Merchant-level: every shop under the merchant unless `shop_id` narrows it.\n * A `shop_id` that is not one of the merchant's own shops is an error, not an\n * empty file.\n */\n async transactions(\n params: TransactionExportParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord>>;\n async transactions(params: TransactionExportParams, options: BinaryExportOptions): Promise<Blob>;\n async transactions(\n params: TransactionExportParams,\n options: ExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord> | Blob>;\n async transactions(\n params: TransactionExportParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord> | Blob> {\n return this.request(\n 'POST',\n '/export/transactions',\n transactionBody(params, options),\n ) as Promise<ExportEnvelope<TransactionExportRecord> | Blob>;\n }\n\n /**\n * The caller's own shop's transactions.\n * `POST /export/profile/transactions`\n *\n * Gated on the profile-level payment permission, which a shop-scoped role can\n * hold where the merchant-level one it replaces cannot — without this route a\n * shop user had no export at all.\n */\n async transactionsForProfile(\n params: TransactionExportParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord>>;\n async transactionsForProfile(\n params: TransactionExportParams,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async transactionsForProfile(\n params: TransactionExportParams,\n options: ExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord> | Blob>;\n async transactionsForProfile(\n params: TransactionExportParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord> | Blob> {\n return this.request(\n 'POST',\n '/export/profile/transactions',\n transactionBody(params, options),\n ) as Promise<ExportEnvelope<TransactionExportRecord> | Blob>;\n }\n\n /** Refunds. `POST /refunds/list/export` */\n async refunds(\n params?: RefundListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord>>;\n async refunds(params: RefundListParams | undefined, options: BinaryExportOptions): Promise<Blob>;\n async refunds(\n params: RefundListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord> | Blob>;\n async refunds(\n params?: RefundListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord> | Blob> {\n return this.request('POST', '/refunds/list/export', bodied(params ?? {}, options)) as Promise<\n ExportEnvelope<RefundExportRecord> | Blob\n >;\n }\n\n /** The caller's own shop's refunds. `POST /refunds/profile/list/export` */\n async refundsForProfile(\n params?: RefundListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord>>;\n async refundsForProfile(\n params: RefundListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async refundsForProfile(\n params: RefundListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord> | Blob>;\n async refundsForProfile(\n params?: RefundListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord> | Blob> {\n return this.request(\n 'POST',\n '/refunds/profile/list/export',\n bodied(params ?? {}, options),\n ) as Promise<ExportEnvelope<RefundExportRecord> | Blob>;\n }\n\n /** Disputes. `GET /disputes/list/export` */\n async disputes(\n params?: DisputeListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord>>;\n async disputes(\n params: DisputeListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async disputes(\n params: DisputeListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord> | Blob>;\n async disputes(\n params?: DisputeListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord> | Blob> {\n return this.request('GET', '/disputes/list/export', queried(params, options)) as Promise<\n ExportEnvelope<DisputeExportRecord> | Blob\n >;\n }\n\n /** The caller's own shop's disputes. `GET /disputes/profile/list/export` */\n async disputesForProfile(\n params?: DisputeListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord>>;\n async disputesForProfile(\n params: DisputeListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async disputesForProfile(\n params: DisputeListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord> | Blob>;\n async disputesForProfile(\n params?: DisputeListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord> | Blob> {\n return this.request(\n 'GET',\n '/disputes/profile/list/export',\n queried(params, options),\n ) as Promise<ExportEnvelope<DisputeExportRecord> | Blob>;\n }\n\n /** Payouts. `POST /payouts/list/export` */\n async payouts(\n params: PayoutListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord>>;\n async payouts(params: PayoutListParams, options: BinaryExportOptions): Promise<Blob>;\n async payouts(\n params: PayoutListParams,\n options: ExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord> | Blob>;\n async payouts(\n params: PayoutListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord> | Blob> {\n return this.request('POST', '/payouts/list/export', bodied(params, options)) as Promise<\n ExportEnvelope<PayoutExportRecord> | Blob\n >;\n }\n\n /** The caller's own shop's payouts. `POST /payouts/profile/list/export` */\n async payoutsForProfile(\n params: PayoutListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord>>;\n async payoutsForProfile(params: PayoutListParams, options: BinaryExportOptions): Promise<Blob>;\n async payoutsForProfile(\n params: PayoutListParams,\n options: ExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord> | Blob>;\n async payoutsForProfile(\n params: PayoutListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord> | Blob> {\n return this.request('POST', '/payouts/profile/list/export', bodied(params, options)) as Promise<\n ExportEnvelope<PayoutExportRecord> | Blob\n >;\n }\n\n /**\n * Subscriptions. `GET /subscriptions/list/export`\n *\n * `profileId` becomes the `X-Profile-Id` header, exactly as on the list. A\n * shop-scoped token exports its own shop whatever this says.\n */\n async subscriptions(\n profileId: string,\n params?: SubscriptionListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<SubscriptionExportRecord>>;\n async subscriptions(\n profileId: string,\n params: SubscriptionListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async subscriptions(\n profileId: string,\n params: SubscriptionListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<SubscriptionExportRecord> | Blob>;\n async subscriptions(\n profileId: string,\n params?: SubscriptionListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<SubscriptionExportRecord> | Blob> {\n return this.request(\n 'GET',\n '/subscriptions/list/export',\n queried(params, options, { 'X-Profile-Id': profileId }),\n ) as Promise<ExportEnvelope<SubscriptionExportRecord> | Blob>;\n }\n\n /** Settlement statements. `GET /settlement/statements/export` */\n\n /** One period's settlement lines. `GET /settlement/lines/export` */\n\n /**\n * The merchant's own audit log. `GET /audit/export`\n *\n * Requires a dashboard JWT whose role holds the merchant-level `AuditLog`\n * permission — a shop-scoped role cannot hold it. There is no `merchant_id`\n * parameter: the scope comes from the token.\n */\n async auditLog(\n params?: MerchantAuditLogListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<MerchantAuditLogExportRecord>>;\n async auditLog(\n params: MerchantAuditLogListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async auditLog(\n params: MerchantAuditLogListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<MerchantAuditLogExportRecord> | Blob>;\n async auditLog(\n params?: MerchantAuditLogListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<MerchantAuditLogExportRecord> | Blob> {\n return this.request('GET', '/audit/export', queried(params, options)) as Promise<\n ExportEnvelope<MerchantAuditLogExportRecord> | Blob\n >;\n }\n}\n\n/** The media type each format is asked for by name. */\nconst ACCEPT: Record<ExportFormat, string> = {\n csv: 'text/csv',\n json: 'application/json',\n pdf: 'application/pdf',\n};\n\n/**\n * Headers and response handling for one export.\n *\n * The format is negotiated with `Accept`, never a request field. The API's\n * reason is that an export reuses its list's filter model as literally the same\n * type, and several of those are `deny_unknown_fields` — so a `format` key in\n * the query or body is a 400, not an option.\n *\n * `csv` and `pdf` are not JSON, and the client parses a body as JSON unless it\n * is told otherwise, so a missing `responseType` would be a `SyntaxError` on\n * the first comma rather than a wrong type.\n */\nfunction negotiated(options: RequestOptions, format: ExportFormat): RequestOptions {\n const headers = { ...options.headers, Accept: ACCEPT[format] };\n return format === 'json'\n ? { ...options, headers }\n : { ...options, headers, responseType: 'blob' };\n}\n\n/**\n * The transactions export, which is the one endpoint that keeps a `format`\n * field on its body.\n *\n * Its body is the export's own request type rather than a list's filter model,\n * so the field has been there since it was written and removing it would break\n * every caller for no gain. `Accept` is sent as well, and the API lets the\n * field win when both are present — so the two can never disagree about what\n * this client asked for.\n */\nfunction transactionBody(\n params: TransactionExportParams,\n options: ExportOptions | undefined,\n): RequestOptions {\n const format = options?.format ?? 'json';\n return negotiated({ body: { ...params, format } }, format);\n}\n\n/** Request options for an export whose filters travel in the body. */\nfunction bodied(body: unknown, options: ExportOptions | undefined): RequestOptions {\n return negotiated({ body }, options?.format ?? 'json');\n}\n\n/** Request options for an export whose filters travel in the query. */\nfunction queried(\n params: unknown,\n options: ExportOptions | undefined,\n headers?: Record<string, string>,\n): RequestOptions {\n return negotiated(\n { query: (params ?? {}) as Query, ...(headers ? { headers } : {}) },\n options?.format ?? 'json',\n );\n}\n","import type { FeatureMatrixResponse } from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * What each connector can do: payment methods, capture methods, webhook\n * flows, and whether an unverified webhook is acted on.\n */\nexport class FeatureMatrix {\n constructor(private readonly request: RequestFn) {}\n\n /** Retrieve the feature matrix. `GET /feature-matrix` */\n async retrieve(): Promise<FeatureMatrixResponse> {\n return this.request('GET', '/feature-matrix');\n }\n\n /**\n * Retrieve the feature matrix scoped to a merchant. Beta connectors\n * are filtered against the merchant's allowlist so the dashboard only\n * surfaces connectors the merchant can actually attach.\n * `GET /feature-matrix/{merchantId}`\n */\n async retrieveForMerchant(merchantId: string): Promise<FeatureMatrixResponse> {\n return this.request('GET', `/feature-matrix/${encodeURIComponent(merchantId)}`);\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Files {\n constructor(private readonly request: RequestFn) {}\n\n /** Upload a file. `POST /files` */\n async create(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/files', { body: params });\n }\n\n /** Retrieve/download a file. `GET /files/{fileId}` */\n async retrieve(fileId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/files/${encodeURIComponent(fileId)}`);\n }\n\n /** Delete a file. `DELETE /files/{fileId}` */\n async delete(fileId: string): Promise<Record<string, unknown>> {\n return this.request('DELETE', `/files/${encodeURIComponent(fileId)}`);\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Forex {\n constructor(private readonly request: RequestFn) {}\n\n /** Retrieve forex rates. `GET /forex/rates` */\n async getRates(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/forex/rates', { query: params });\n }\n\n /** Convert from minor currency. `GET /forex/convert-from-minor` */\n async convertFromMinor(\n params: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/forex/convert-from-minor', { query: params });\n }\n}\n","import type {\n RegionCreateRequest,\n RegionUpdateRequest,\n RegionResponse,\n RegionSetCountriesRequest,\n RegionCountriesResponse,\n BuiltInRegionGroupResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Custom regions (named country groups) scoped to a shop/profile, used by the\n * geo-aware payment-method availability overrides. Every endpoint is scoped by\n * `profileId`. Admin (`sk_*`) access required.\n */\nexport class Regions {\n constructor(private readonly request: RequestFn) {}\n\n /** Create a region. `POST /regions?profile_id=` */\n async create(profileId: string, params: RegionCreateRequest): Promise<RegionResponse> {\n return this.request('POST', '/regions', {\n body: params,\n query: { profile_id: profileId },\n });\n }\n\n /** List all regions for a profile. `GET /regions/list?profile_id=` */\n async list(profileId: string): Promise<RegionResponse[]> {\n return this.request('GET', '/regions/list', { query: { profile_id: profileId } });\n }\n\n /** List the built-in (global) region groups (EU/EEA/SEPA/LATAM/APAC). `GET /regions/groups` */\n async groups(): Promise<BuiltInRegionGroupResponse[]> {\n return this.request('GET', '/regions/groups');\n }\n\n /** Retrieve a region by id. `GET /regions/{regionId}?profile_id=` */\n async retrieve(regionId: string, profileId: string): Promise<RegionResponse> {\n return this.request('GET', `/regions/${encodeURIComponent(regionId)}`, {\n query: { profile_id: profileId },\n });\n }\n\n /** Update a region. `PUT /regions/{regionId}?profile_id=` */\n async update(\n regionId: string,\n profileId: string,\n params: RegionUpdateRequest,\n ): Promise<RegionResponse> {\n return this.request('PUT', `/regions/${encodeURIComponent(regionId)}`, {\n body: params,\n query: { profile_id: profileId },\n });\n }\n\n /** Delete a region. `DELETE /regions/{regionId}?profile_id=` */\n async delete(regionId: string, profileId: string): Promise<boolean> {\n return this.request('DELETE', `/regions/${encodeURIComponent(regionId)}`, {\n query: { profile_id: profileId },\n });\n }\n\n /** Get the countries that belong to a region. `GET /regions/{regionId}/countries?profile_id=` */\n async getCountries(regionId: string, profileId: string): Promise<RegionCountriesResponse> {\n return this.request('GET', `/regions/${encodeURIComponent(regionId)}/countries`, {\n query: { profile_id: profileId },\n });\n }\n\n /** Replace the full country membership of a region. `PUT /regions/{regionId}/countries?profile_id=` */\n async setCountries(\n regionId: string,\n profileId: string,\n params: RegionSetCountriesRequest,\n ): Promise<RegionCountriesResponse> {\n return this.request('PUT', `/regions/${encodeURIComponent(regionId)}/countries`, {\n body: params,\n query: { profile_id: profileId },\n });\n }\n}\n","import type {\n AvailabilityOverrideCreateRequest,\n AvailabilityOverrideResponse,\n AvailabilityPreviewParams,\n AvailabilityPreviewResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Merchant payment-method availability overrides. Force-show or force-hide a\n * payment method per country/region at global, project, or shop scope, on top\n * of the curated country defaults. Admin (`sk_*`) access required.\n */\nexport class AvailabilityOverrides {\n constructor(private readonly request: RequestFn) {}\n\n /** Create an availability override. `POST /availability-overrides` */\n async create(params: AvailabilityOverrideCreateRequest): Promise<AvailabilityOverrideResponse> {\n return this.request('POST', '/availability-overrides', { body: params });\n }\n\n /** List a merchant's availability overrides. `GET /availability-overrides` */\n async list(merchantId: string): Promise<AvailabilityOverrideResponse[]> {\n return this.request('GET', '/availability-overrides', {\n query: { merchant_id: merchantId },\n });\n }\n\n /** Delete an availability override by id. `DELETE /availability-overrides/{id}` */\n async delete(id: string): Promise<boolean> {\n return this.request('DELETE', `/availability-overrides/${encodeURIComponent(id)}`);\n }\n\n /**\n * Preview the methods a customer in `country` would be shown for a shop —\n * the connector ceiling narrowed by the smart country defaults and the\n * merchant overrides, without an active payment. Pass `amount` + `currency`\n * to also evaluate order-value rules.\n * `GET /availability-overrides/preview`\n */\n async preview(params: AvailabilityPreviewParams): Promise<AvailabilityPreviewResponse> {\n return this.request('GET', '/availability-overrides/preview', {\n query: {\n merchant_id: params.merchant_id,\n profile_id: params.profile_id,\n ...(params.country ? { country: params.country } : {}),\n // `0` is a legitimate order value, so test for presence, not truthiness.\n ...(params.amount !== undefined ? { amount: params.amount } : {}),\n ...(params.currency ? { currency: params.currency } : {}),\n },\n });\n }\n}\n","import type {\n CreateSubscriptionRequest,\n CreateAndConfirmSubscriptionRequest,\n ConfirmSubscriptionRequest,\n UpdateSubscriptionRequest,\n PauseSubscriptionRequest,\n ResumeSubscriptionRequest,\n CancelSubscriptionRequest,\n SubscriptionResponse,\n ConfirmSubscriptionResponse,\n PauseSubscriptionResponse,\n ResumeSubscriptionResponse,\n CancelSubscriptionResponse,\n GetSubscriptionItemsResponse,\n GetSubscriptionItemsParams,\n SubscriptionEstimateResponse,\n SubscriptionEstimateParams,\n SubscriptionListParams,\n SubscriptionPaymentLookupRequest,\n SubscriptionPaymentLookupResponse,\n SubscriptionInvoiceListParams,\n SubscriptionInvoiceListResponse,\n SubscriptionBillingProcessorResponse,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Subscription endpoints are profile-scoped: the backend requires an\n * `X-Profile-Id` header to resolve the shop / billing processor (`IR_04`\n * otherwise). Pass it through the per-call `options.headers`, e.g.\n * `subscriptions.list(params, { headers: { 'X-Profile-Id': profileId } })`.\n */\nexport class Subscriptions {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create and immediately confirm a subscription. `POST /subscriptions`\n *\n * For billing processors that require buyer approval (e.g. PayPal), the\n * response carries a `redirect_url` the customer must be sent to.\n */\n async createAndConfirm(\n params: CreateAndConfirmSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<ConfirmSubscriptionResponse> {\n return this.request('POST', '/subscriptions', { body: params, ...options });\n }\n\n /** Create a subscription without confirming it. `POST /subscriptions/create` */\n async create(\n params: CreateSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionResponse> {\n return this.request('POST', '/subscriptions/create', { body: params, ...options });\n }\n\n /** Retrieve a subscription by ID. `GET /subscriptions/{subscriptionId}` */\n async retrieve(subscriptionId: string, options?: RequestExtras): Promise<SubscriptionResponse> {\n return this.request('GET', `/subscriptions/${encodeURIComponent(subscriptionId)}`, {\n ...options,\n });\n }\n\n /**\n * Confirm a previously created subscription. `POST /subscriptions/{subscriptionId}/confirm`\n *\n * Like {@link createAndConfirm}, the response may carry a `redirect_url` for\n * processors that require buyer approval.\n */\n async confirm(\n subscriptionId: string,\n params: ConfirmSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<ConfirmSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/confirm`, {\n body: params,\n ...options,\n });\n }\n\n /** Update a subscription's plan/price. `PUT /subscriptions/{subscriptionId}/update` */\n async update(\n subscriptionId: string,\n params: UpdateSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionResponse> {\n return this.request('PUT', `/subscriptions/${encodeURIComponent(subscriptionId)}/update`, {\n body: params,\n ...options,\n });\n }\n\n /** List subscriptions for the profile. `GET /subscriptions/list` */\n async list(\n params?: SubscriptionListParams,\n options?: RequestExtras,\n ): Promise<SubscriptionResponse[]> {\n return this.request('GET', '/subscriptions/list', {\n query: params as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /** Estimate the cost of a subscription before creating it. `GET /subscriptions/estimate` */\n async getEstimate(\n params: SubscriptionEstimateParams,\n options?: RequestExtras,\n ): Promise<SubscriptionEstimateResponse> {\n return this.request('GET', '/subscriptions/estimate', {\n query: params as unknown as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /** List purchasable subscription items (plans/addons). `GET /subscriptions/items` */\n async getItems(\n params: GetSubscriptionItemsParams,\n options?: RequestExtras,\n ): Promise<GetSubscriptionItemsResponse[]> {\n return this.request('GET', '/subscriptions/items', {\n query: params as unknown as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /**\n * Pause a subscription. `POST /subscriptions/{subscriptionId}/pause`\n *\n * The body defaults to `{}` so the request still carries\n * `Content-Type: application/json` even when no params are passed — the\n * backend rejects the POST otherwise (\"Unsupported content type\").\n */\n async pause(\n subscriptionId: string,\n params?: PauseSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<PauseSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/pause`, {\n body: params ?? {},\n ...options,\n });\n }\n\n /** Resume a paused subscription. `POST /subscriptions/{subscriptionId}/resume` */\n async resume(\n subscriptionId: string,\n params?: ResumeSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<ResumeSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/resume`, {\n body: params ?? {},\n ...options,\n });\n }\n\n /** Cancel a subscription. `POST /subscriptions/{subscriptionId}/cancel` */\n async cancel(\n subscriptionId: string,\n params?: CancelSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<CancelSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/cancel`, {\n body: params ?? {},\n ...options,\n });\n }\n\n /**\n * Resolve which of the given payments were raised by a subscription.\n * `POST /subscriptions/payments/lookup`\n *\n * The linkage exists in one direction only — an invoice points at the payment\n * it settled, and nothing is stamped on the payment — so this is the only way\n * to tell a subscription charge from a one-off one when you are holding a\n * page of payments. In particular, do not use `off_session` or the presence\n * of a mandate: an ordinary saved-card charge sets those identically.\n *\n * Ids that belong to no subscription are **absent** from `links` rather than\n * returned as an error, so match on presence:\n *\n * ```ts\n * const { links } = await subscriptions.lookupPayments(\n * { payment_ids: page.map((p) => p.payment_id) },\n * { headers: { 'X-Profile-Id': profileId } },\n * );\n * const bySubscription = new Map(links.map((l) => [l.payment_id, l]));\n * ```\n *\n * Profile-scoped like every other subscription route, and that matters more\n * here than elsewhere: a `payment_id` is merchant-supplied and only unique\n * within a merchant, so the shop is part of the question, not an\n * optimisation. Pass the profile that owns **the payments** — for a list\n * spanning several shops, group the ids by shop and call once per group.\n *\n * At most 200 ids per call.\n */\n async lookupPayments(\n params: SubscriptionPaymentLookupRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionPaymentLookupResponse> {\n return this.request('POST', '/subscriptions/payments/lookup', { body: params, ...options });\n }\n\n /**\n * One subscription's billing history, newest cycle first.\n * `GET /subscriptions/{subscriptionId}/invoices`\n *\n * {@link retrieve} carries only the *latest* invoice, which is the current\n * cycle — a subscription that has renewed monthly for a year has one of those\n * and twelve of these. Use this wherever a merchant needs to see what a\n * subscription has actually billed, in particular on self-charging processors\n * (Creem, PayPal) where each renewal is charged by the processor and mirrored\n * here rather than raised as a DeloPay payment.\n *\n * Two things to render honestly, both decided rather than incidental:\n *\n * - `amount` is **gross** and `refunded_amount` sits beside it. Do not net\n * them: the difference between the two is not a smaller charge.\n * - A `refunded_amount` of `null` is \"not reported\" and must not render as\n * `0`. Likewise a processor-hosted origination records a bootstrap invoice\n * at `0` before the buyer has paid anything, so a zero amount on such a\n * subscription is a placeholder rather than a free cycle.\n *\n * Profile-scoped like every other subscription route.\n */\n async listInvoices(\n subscriptionId: string,\n params?: SubscriptionInvoiceListParams,\n options?: RequestExtras,\n ): Promise<SubscriptionInvoiceListResponse> {\n return this.request('GET', `/subscriptions/${encodeURIComponent(subscriptionId)}/invoices`, {\n query: params as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /**\n * Which billing processor this shop's subscriptions run on.\n * `GET /subscriptions/billing_processor`\n *\n * The same mapping is derivable from the connector inventory\n * (`GET /account/{merchant_id}/connectors`), but that route is gated by a\n * connector-read permission granted independently of subscriptions — so a\n * role authorised to create subscriptions could be unable to learn which\n * processor it was creating them on. This answers under the same\n * authorization as the rest of the subscription API.\n *\n * Reach for it when the client must branch on the processor *before* calling\n * — origination differs by processor, and guessing is destructive. Resolve\n * the shop's `billing_processor_id` first: a shop that runs no subscriptions\n * has none assigned, and this route has no identity to report for it.\n */\n async getBillingProcessor(\n options?: RequestExtras,\n ): Promise<SubscriptionBillingProcessorResponse> {\n return this.request('GET', '/subscriptions/billing_processor', { ...options });\n }\n}\n","import type {\n MerchantAuditLogListParams,\n MerchantAuditLogListResponse,\n MerchantAuditLogEntry,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * A merchant's own audit log — everything changed on their account and their\n * shops, grouped by the sign-in it happened in.\n *\n * Requires a dashboard JWT (`setJwtToken`) whose role holds the `AuditLog`\n * permission; an API key cannot read it. This is deliberate: the log names\n * people, and an API key names no one.\n *\n * There is no `merchant_id` parameter. The scope comes from the token, so this\n * resource cannot be pointed at another merchant — see\n * {@link MerchantAuditLogListParams}.\n */\nexport class Audit {\n constructor(private readonly request: RequestFn) {}\n\n async list(params?: MerchantAuditLogListParams): Promise<MerchantAuditLogListResponse> {\n return this.request('GET', '/audit', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * One entry. An id belonging to another merchant answers 404, not 403 — the\n * endpoint does not confirm that an entry it will not serve exists.\n */\n async retrieve(logId: string): Promise<MerchantAuditLogEntry> {\n return this.request('GET', `/audit/${encodeURIComponent(logId)}`);\n }\n}\n","import type {\n FeeStatementDetail,\n SettlementBackfillRequest,\n SettlementBackfillResponse,\n SettlementCostParams,\n SettlementCostResponse,\n SettlementCurrentParams,\n SettlementCurrentResponse,\n SettlementLineListParams,\n SettlementLineListResponse,\n SettlementOverviewParams,\n SettlementOverviewResponse,\n SettlementStatementListParams,\n SettlementStatementListResponse,\n ShopFeeConfigParams,\n ShopFeeConfigResponse,\n ShopVisibilityResponse,\n ShopVisibilityUpdateRequest,\n StatementAdjustment,\n StatementAdjustmentCreateRequest,\n StatementAdjustmentListResponse,\n StatementGenerateRequest,\n StatementPayoutUpdateRequest,\n StatementPdfParams,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Hosted-shop settlement: monthly statements, the live current-period\n * rollup, per-line detail, fee schedules and backfills.\n *\n * Every read takes an explicit `test_mode` — test and live figures must\n * never blend, so the environment lives in the signature rather than in a\n * default. `false` is transmitted, not dropped.\n *\n * Shop-owner responses are redacted server-side: absent platform-fee fields\n * are a permission boundary, not a gap — never re-derive them client-side.\n */\nexport class Settlement {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Per-shop settlement rollup for the host merchant: unpaid totals and the\n * running current period, one row per shop.\n *\n * `GET /settlement/overview`\n */\n async overview(\n params: SettlementOverviewParams,\n options?: RequestExtras,\n ): Promise<SettlementOverviewResponse> {\n return this.request('GET', '/settlement/overview', {\n query: { test_mode: params.test_mode },\n ...options,\n });\n }\n\n /**\n * Live rollup of the current (not yet statemented) period.\n *\n * `GET /settlement/current`\n */\n async current(\n params: SettlementCurrentParams,\n options?: RequestExtras,\n ): Promise<SettlementCurrentResponse> {\n return this.request('GET', '/settlement/current', {\n query: { test_mode: params.test_mode, profile_id: params.profile_id },\n ...options,\n });\n }\n\n /**\n * What a period's payments cost, and what was left over: gross, the\n * platform fee, hosting fees, what the rails took, and the margin, with a\n * per-connector breakdown.\n *\n * Send `year` and `month` together to report one UTC calendar month, or\n * neither for the running month so far.\n *\n * **Host-only.** The response is the host's cost base, which a shop owner\n * must never see, so a profile-scoped caller is refused with a 403 rather\n * than given a redacted shell. Gate the surface on the caller's scope\n * instead of calling it and handling the failure.\n *\n * Two things not to flatten when rendering the result:\n * `margin_usd` is absent — not zero — whenever `margin_quality` is\n * `'unknown'`, and `unlined_captured_attempt_count` (cost definitely\n * missing) means something different from `unlined_unresolved_attempt_count`\n * (mostly ordinary abandonment).\n *\n * `GET /settlement/cost`\n *\n * @example\n * ```typescript\n * const cost = await delopay.settlement.cost({ test_mode: false, year: 2026, month: 7 });\n * if (cost.margin_quality === 'unknown') {\n * // cost.margin_usd is absent — say so, do not render 0.00\n * }\n * ```\n */\n async cost(\n params?: SettlementCostParams,\n options?: RequestExtras,\n ): Promise<SettlementCostResponse> {\n return this.request('GET', '/settlement/cost', {\n query: {\n profile_id: params?.profile_id,\n test_mode: params?.test_mode,\n year: params?.year,\n month: params?.month,\n },\n ...options,\n });\n }\n\n /**\n * List generated settlement statements, newest first.\n *\n * `GET /settlement/statements`\n */\n async listStatements(\n params: SettlementStatementListParams,\n options?: RequestExtras,\n ): Promise<SettlementStatementListResponse> {\n return this.request('GET', '/settlement/statements', {\n query: {\n test_mode: params.test_mode,\n profile_id: params.profile_id,\n limit: params.limit,\n offset: params.offset,\n },\n ...options,\n });\n }\n\n /**\n * One statement with its per-connector/currency breakdown.\n *\n * `GET /settlement/statements/{statementId}`\n */\n async retrieveStatement(\n statementId: string,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request(\n 'GET',\n `/settlement/statements/${encodeURIComponent(statementId)}`,\n options,\n );\n }\n\n /**\n * Generate (or regenerate) the statement for one shop and calendar month.\n *\n * `POST /settlement/statements/generate`\n */\n async generateStatement(\n params: StatementGenerateRequest,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request('POST', '/settlement/statements/generate', {\n body: params,\n ...options,\n });\n }\n\n /**\n * Record payout progress on a statement (`unpaid` / `partial` / `paid`).\n *\n * Subject to the caller's `settlement_payout` operation limit — a\n * per-operation ceiling, a windowed total, a windowed count, or any\n * combination: an over-limit call fails with `DE_01` and nothing is\n * recorded. There is no approval route out of it — four-eyes needs an\n * executor that can run the operation once somebody says yes, and only\n * refunds have one, so a settlement rule can only block.\n *\n * `POST /settlement/statements/{statementId}/payout`\n */\n async updateStatementPayout(\n statementId: string,\n params: StatementPayoutUpdateRequest,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request(\n 'POST',\n `/settlement/statements/${encodeURIComponent(statementId)}/payout`,\n { body: params, ...options },\n );\n }\n\n /**\n * Export a statement as PDF. Returns the raw PDF bytes as a `Blob`, with\n * the same auth, retries and error handling as every other call — persist\n * or object-URL it caller-side.\n *\n * `GET /settlement/statements/{statementId}/pdf`\n *\n * @example\n * ```typescript\n * const pdf = await delopay.settlement.downloadStatementPdf('stmt_1', {\n * currency: 'EUR',\n * include_transactions: true,\n * });\n * const url = URL.createObjectURL(pdf);\n * ```\n */\n async downloadStatementPdf(\n statementId: string,\n params?: StatementPdfParams,\n options?: RequestExtras,\n ): Promise<Blob> {\n return this.request('GET', `/settlement/statements/${encodeURIComponent(statementId)}/pdf`, {\n query: {\n currency: params?.currency,\n include_transactions: params?.include_transactions,\n },\n responseType: 'blob',\n ...options,\n });\n }\n\n /**\n * The individual settled attempts of one shop's calendar month.\n *\n * `GET /settlement/lines`\n */\n async listLines(\n params: SettlementLineListParams,\n options?: RequestExtras,\n ): Promise<SettlementLineListResponse> {\n return this.request('GET', '/settlement/lines', {\n query: {\n profile_id: params.profile_id,\n year: params.year,\n month: params.month,\n test_mode: params.test_mode,\n limit: params.limit,\n offset: params.offset,\n },\n ...options,\n });\n }\n\n /**\n * The fee schedules that currently apply to a shop.\n *\n * `GET /settlement/fee-config`\n */\n async feeConfig(\n params: ShopFeeConfigParams,\n options?: RequestExtras,\n ): Promise<ShopFeeConfigResponse> {\n return this.request('GET', '/settlement/fee-config', {\n query: { profile_id: params.profile_id },\n ...options,\n });\n }\n\n /**\n * Enqueue a settlement-line backfill over historical attempts. Attempts\n * already covered by a line are always skipped.\n *\n * `POST /settlement/backfill`\n */\n async backfill(\n params?: SettlementBackfillRequest,\n options?: RequestExtras,\n ): Promise<SettlementBackfillResponse> {\n return this.request('POST', '/settlement/backfill', { body: params, ...options });\n }\n\n /**\n * Toggle whether a shop's owner can see their own settlement figures.\n *\n * `POST /settlement/shops/visibility`\n */\n async setShopVisibility(\n params: ShopVisibilityUpdateRequest,\n options?: RequestExtras,\n ): Promise<ShopVisibilityResponse> {\n return this.request('POST', '/settlement/shops/visibility', {\n body: params,\n ...options,\n });\n }\n\n /**\n * Manual adjustments recorded on a statement.\n *\n * `GET /settlement/statements/{statementId}/adjustments`\n */\n async listStatementAdjustments(\n statementId: string,\n options?: RequestExtras,\n ): Promise<StatementAdjustmentListResponse> {\n return this.request(\n 'GET',\n `/settlement/statements/${encodeURIComponent(statementId)}/adjustments`,\n options,\n );\n }\n\n /**\n * Add a manual adjustment to a statement. Positive `amount_usd` charges\n * the shop (reducing their payout); negative credits them.\n *\n * Subject to the caller's `settlement_adjustment` operation limit (amount\n * dimensions only): an over-limit call fails with `DE_01` and no adjustment\n * is added. A settlement rule can only block — approval is refund-only, for\n * the reason given on `updateStatementPayout()`.\n *\n * `POST /settlement/statements/{statementId}/adjustments`\n */\n async createStatementAdjustment(\n statementId: string,\n params: StatementAdjustmentCreateRequest,\n options?: RequestExtras,\n ): Promise<StatementAdjustment> {\n return this.request(\n 'POST',\n `/settlement/statements/${encodeURIComponent(statementId)}/adjustments`,\n { body: params, ...options },\n );\n }\n\n /**\n * Remove a manual adjustment from a statement.\n *\n * `DELETE /settlement/statements/{statementId}/adjustments/{adjustmentId}`\n */\n async deleteStatementAdjustment(\n statementId: string,\n adjustmentId: string,\n options?: RequestExtras,\n ): Promise<void> {\n return this.request(\n 'DELETE',\n `/settlement/statements/${encodeURIComponent(statementId)}/adjustments/${encodeURIComponent(adjustmentId)}`,\n options,\n );\n }\n}\n","import type {\n DecidePendingOperationRequest,\n OperationLimitRule,\n OperationLimitRuleDeleteResponse,\n OperationLimitRuleListParams,\n OperationLimitSettings,\n PendingOperation,\n PendingOperationListParams,\n PendingOperationListResponse,\n UpdateOperationLimitSettingsRequest,\n UpsertOperationLimitRuleRequest,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Per-operation spending limits: rules scoped to the merchant, a role or a\n * user, the merchant-level enforcement settings, and the approvals inbox.\n * Enforcement resolves the most specific rule: user > role > merchant.\n *\n * A rule set to `require_approval` does not refuse an over-limit operation —\n * it parks it. The original call fails with HTTP 409 `DE_06` carrying\n * `PendingApprovalErrorDetails`, and the operation runs only once a second\n * person approves the request through this inbox.\n *\n * **Refunds only.** Approval needs an executor that can run the operation\n * after the decision, and only refunds have one; the settlement operations\n * take `block` alone, which the request type enforces. So every request in\n * this inbox is a refund, and `DE_06` never comes back from a settlement\n * call — an over-limit settlement adjustment or payout fails with `DE_01`.\n */\nexport class OperationLimits {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * List the merchant's limit rules, optionally for one operation.\n *\n * `GET /operation-limits/rules`\n */\n async listRules(\n params?: OperationLimitRuleListParams,\n options?: RequestExtras,\n ): Promise<OperationLimitRule[]> {\n return this.request('GET', '/operation-limits/rules', {\n query: { operation: params?.operation },\n ...options,\n });\n }\n\n /**\n * Create or replace the limit rule for one target. Full-replace upsert:\n * absent limit fields clear that dimension.\n *\n * `PUT /operation-limits/rules`\n */\n async upsertRule(\n params: UpsertOperationLimitRuleRequest,\n options?: RequestExtras,\n ): Promise<OperationLimitRule> {\n return this.request('PUT', '/operation-limits/rules', { body: params, ...options });\n }\n\n /**\n * Delete a limit rule.\n *\n * `DELETE /operation-limits/rules/{ruleId}`\n */\n async deleteRule(\n ruleId: string,\n options?: RequestExtras,\n ): Promise<OperationLimitRuleDeleteResponse> {\n return this.request('DELETE', `/operation-limits/rules/${encodeURIComponent(ruleId)}`, options);\n }\n\n /**\n * The merchant-level enforcement settings. An untouched merchant gets the\n * defaults: rolling window, admins not exempt.\n *\n * `GET /operation-limits/settings`\n */\n async retrieveSettings(options?: RequestExtras): Promise<OperationLimitSettings> {\n return this.request('GET', '/operation-limits/settings', options);\n }\n\n /**\n * Update the enforcement settings. Only provided fields change.\n *\n * `PUT /operation-limits/settings`\n */\n async updateSettings(\n params: UpdateOperationLimitSettingsRequest,\n options?: RequestExtras,\n ): Promise<OperationLimitSettings> {\n return this.request('PUT', '/operation-limits/settings', { body: params, ...options });\n }\n\n /**\n * The approvals inbox: over-limit operations waiting on a second person.\n *\n * Both filters default rather than widen. With no `status` the list holds\n * **pending requests only** — approved, rejected and expired ones are\n * reachable only by asking for that status, so a history view must pass one\n * per status. With no `operation` it lists **refunds only**; the list is one\n * operation at a time. `limit` defaults to 100 and is clamped to 1–500.\n *\n * Requests past their `expires_at` are expired before the list is read, so\n * nothing here is shown as actionable when it is not.\n *\n * `GET /operation-limits/approvals`\n */\n async listApprovals(\n params?: PendingOperationListParams,\n options?: RequestExtras,\n ): Promise<PendingOperationListResponse> {\n return this.request('GET', '/operation-limits/approvals', {\n query: {\n operation: params?.operation,\n status: params?.status,\n limit: params?.limit,\n },\n ...options,\n });\n }\n\n /**\n * Approve a parked operation and execute it.\n *\n * Refused for the user who requested it, and for an approver whose own\n * limit would not have covered the operation — the permission is necessary\n * and not sufficient.\n *\n * Approval and execution are two facts. A request that was approved but\n * whose operation then failed comes back `approved` with `execution_error`\n * set and no `result_entity_id`; that is a real outcome, not a partial read.\n *\n * `POST /operation-limits/approvals/{id}/approve`\n */\n async approve(\n id: string,\n params: DecidePendingOperationRequest = {},\n options?: RequestExtras,\n ): Promise<PendingOperation> {\n return this.request('POST', `/operation-limits/approvals/${encodeURIComponent(id)}/approve`, {\n body: params,\n ...options,\n });\n }\n\n /**\n * Reject a parked operation. Nothing is executed and the request is closed.\n *\n * `POST /operation-limits/approvals/{id}/reject`\n */\n async reject(\n id: string,\n params: DecidePendingOperationRequest = {},\n options?: RequestExtras,\n ): Promise<PendingOperation> {\n return this.request('POST', `/operation-limits/approvals/${encodeURIComponent(id)}/reject`, {\n body: params,\n ...options,\n });\n }\n}\n","import type { MerchantRisk, ShopRisk } from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Stored shop risk indexes, per connector.\n *\n * Both reads return snapshots and never score on demand, so `computed_at` is\n * the age of the answer rather than the time of the call.\n *\n * The caller's own scope is what bounds the answer, and it is enforced\n * server-side: a profile-scoped role, or an API key pinned to one shop, gets\n * that shop from both endpoints and cannot read or enumerate a sibling's.\n */\nexport class Risk {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Every shop's stored risk for the caller's merchant, with the worst band\n * across them.\n *\n * `GET /risk`\n */\n async retrieve(options?: RequestExtras): Promise<MerchantRisk> {\n return this.request('GET', '/risk', options);\n }\n\n /**\n * One shop's stored risk index per connector.\n *\n * `GET /risk/shops/{profileId}`\n */\n async retrieveShop(profileId: string, options?: RequestExtras): Promise<ShopRisk> {\n return this.request('GET', `/risk/shops/${encodeURIComponent(profileId)}`, options);\n }\n}\n","import { DelopayError, DelopayAuthenticationError } from './error';\nimport { ApiKeys } from './resources/apiKeys';\nimport { Authentication } from './resources/authentication';\nimport { Billing } from './resources/billing';\nimport { Blocklist } from './resources/blocklist';\nimport { Connectors } from './resources/connectors';\nimport { Customers } from './resources/customers';\nimport { Disputes } from './resources/disputes';\nimport { EphemeralKeys } from './resources/ephemeralKeys';\nimport { Events } from './resources/events';\nimport { Fees } from './resources/fees';\nimport { Mandates } from './resources/mandates';\nimport { MerchantAccounts } from './resources/merchantAccounts';\nimport { PaymentLinks } from './resources/paymentLinks';\nimport { PaymentMethods } from './resources/paymentMethods';\nimport { Payments } from './resources/payments';\nimport { Payouts } from './resources/payouts';\nimport { Poll } from './resources/poll';\nimport { ProfileAcquirers } from './resources/profileAcquirers';\nimport { Profiles } from './resources/profiles';\nimport { Projects } from './resources/projects';\nimport { Refunds } from './resources/refunds';\nimport { Relay } from './resources/relay';\nimport { Routing } from './resources/routing';\nimport { Search } from './resources/search';\nimport { Shops } from './resources/shops';\nimport { StripeConnect } from './resources/stripeConnect';\nimport { ThreeDsRules } from './resources/threeDsRules';\nimport { Users } from './resources/users';\nimport { Verification } from './resources/verification';\nimport { Webhooks } from './resources/webhooks';\nimport type { TokenResponse } from './types';\nimport { Analytics } from './resources/analytics';\nimport { AnalyticsDashboard } from './resources/analyticsDashboard';\nimport { Cards } from './resources/cards';\nimport { Export } from './resources/export';\nimport { FeatureMatrix } from './resources/featureMatrix';\nimport { Files } from './resources/files';\nimport { Forex } from './resources/forex';\nimport { Regions } from './resources/regions';\nimport { AvailabilityOverrides } from './resources/availabilityOverrides';\nimport { Subscriptions } from './resources/subscriptions';\nimport { Audit } from './resources/audit';\nimport { Settlement } from './resources/settlement';\nimport { OperationLimits } from './resources/operationLimits';\nimport { Risk } from './resources/risk';\n\nconst PRODUCTION_URL = 'https://api.delopay.net';\nconst SANDBOX_URL = 'https://sandbox.delopay.net';\n\nconst MAX_RAW_BODY_BYTES = 2048;\nconst MAX_RETRY_AFTER_MS = 30_000;\n\nfunction parseRetryAfter(header: string | null): number | null {\n if (!header) return null;\n const trimmed = header.trim();\n const seconds = Number(trimmed);\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.min(seconds * 1000, MAX_RETRY_AFTER_MS);\n }\n const date = Date.parse(trimmed);\n if (Number.isFinite(date)) {\n const delta = date - Date.now();\n return delta > 0 ? Math.min(delta, MAX_RETRY_AFTER_MS) : 0;\n }\n return null;\n}\n\nfunction truncateRawBody(raw: string): string | undefined {\n if (!raw) return undefined;\n return raw.length > MAX_RAW_BODY_BYTES ? raw.slice(0, MAX_RAW_BODY_BYTES) + '…' : raw;\n}\n\nfunction findIdempotencyKey(headers: Record<string, string>): string | undefined {\n for (const [k, v] of Object.entries(headers)) {\n if (k.toLowerCase() === 'idempotency-key') return v;\n }\n return undefined;\n}\n\ninterface CombinedSignal {\n signal: AbortSignal;\n dispose: () => void;\n}\n\nfunction noop(): void {\n // Intentionally empty: no listeners registered, nothing to clean up.\n}\n\nfunction combineSignals(signals: AbortSignal[]): CombinedSignal {\n const controller = new AbortController();\n const listeners: { signal: AbortSignal; handler: () => void }[] = [];\n const dispose = () => {\n for (const { signal, handler } of listeners) {\n signal.removeEventListener('abort', handler);\n }\n listeners.length = 0;\n };\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n dispose();\n return { signal: controller.signal, dispose: noop };\n }\n const handler = () => {\n controller.abort(signal.reason);\n dispose();\n };\n signal.addEventListener('abort', handler, { once: true });\n listeners.push({ signal, handler });\n }\n return { signal: controller.signal, dispose };\n}\n\n/**\n * Events emitted by the debug logger.\n * - `request` — about to send a request (`method`, `url`, `path`)\n * - `response` — response received (`status`, `method`, `path`, `requestId?`)\n * - `retry` — about to retry after a transient failure (`attempt`, `maxRetries`, `method`, `path`)\n */\nexport type DelopayLogger = (\n event: 'request' | 'response' | 'retry',\n data: Record<string, unknown>,\n) => void;\n\n/**\n * Configuration options for the Delopay client.\n */\nexport interface DelopayOptions {\n /** Use the sandbox environment (`https://sandbox.delopay.net`). Defaults to `false` (production). */\n sandbox?: boolean;\n /** Override the base URL entirely. Takes precedence over `sandbox`. */\n baseUrl?: string;\n /** Request timeout in milliseconds. Defaults to `30000` (30 seconds). */\n timeout?: number;\n /**\n * Maximum number of automatic retries for transient failures (5xx, timeout, network errors).\n * Retries use exponential backoff. Set to `0` to disable. Defaults to `2`.\n * Only idempotent-safe requests (GET, DELETE, and requests with an `Idempotency-Key` header) are retried.\n */\n maxRetries?: number;\n /** Enable debug logging of requests and responses. Defaults to `false`. */\n debug?: boolean;\n /**\n * Custom logger for debug events (`request`, `response`, `retry`). When omitted,\n * debug output is written to `console.log`. Has no effect unless `debug` is `true`.\n * Useful for routing SDK logs through pino, winston, or similar structured loggers.\n */\n logger?: DelopayLogger;\n}\n\nconst SENSITIVE_QUERY_KEYS = new Set([\n 'client_secret',\n 'ephemeral_key',\n 'api_key',\n 'publishable_key',\n]);\n\n/**\n * Return a copy of `url` with the values of known-sensitive query parameters\n * replaced by `REDACTED`, leaving the rest of the query string intact.\n * Used only to sanitize URLs before they hit debug logs.\n */\nfunction redactUrlForLogging(url: string): string {\n const qIdx = url.indexOf('?');\n if (qIdx === -1) return url;\n const base = url.slice(0, qIdx);\n const query = url.slice(qIdx + 1);\n const parts = query.split('&').map((pair) => {\n const eqIdx = pair.indexOf('=');\n if (eqIdx === -1) return pair;\n const key = pair.slice(0, eqIdx);\n if (SENSITIVE_QUERY_KEYS.has(decodeURIComponent(key).toLowerCase())) {\n return `${key}=REDACTED`;\n }\n return pair;\n });\n return `${base}?${parts.join('&')}`;\n}\n\n/**\n * Low-level options forwarded to a single HTTP request.\n */\nexport interface RequestOptions {\n /** Request body, serialised as JSON. */\n body?: unknown;\n /**\n * Query-string parameters. `undefined` and `null` values are omitted.\n * Array values are emitted as repeated keys (`?tag=a&tag=b`) — not comma-joined.\n */\n query?: Record<\n string,\n string | number | boolean | null | undefined | (string | number | boolean)[]\n >;\n /** Additional HTTP headers merged with the default `api-key` header. */\n headers?: Record<string, string>;\n /** Override the client-level timeout for this request, in milliseconds. */\n timeout?: number;\n /**\n * Caller-provided `AbortSignal`. Aborting it cancels the in-flight request and rejects\n * with a `DelopayError` carrying code `'ABORTED'`. Combined with the per-request timeout.\n */\n signal?: AbortSignal;\n /**\n * How to decode a 2xx response body. `'json'` (the default) parses JSON;\n * `'blob'` / `'arraybuffer'` return the raw bytes for binary endpoints\n * such as PDF exports. Error responses are always decoded as JSON and\n * thrown as `DelopayError` regardless of this setting.\n */\n responseType?: 'json' | 'blob' | 'arraybuffer';\n /**\n * Pass `keepalive: true` to let the request outlive its page — e.g.\n * telemetry sent while the document is navigating away. Browsers cap\n * keepalive request bodies at ~64 KiB and reject larger ones.\n */\n keepalive?: boolean;\n}\n\nexport type RequestFn = <T>(method: string, path: string, options?: RequestOptions) => Promise<T>;\n\n/**\n * Per-call options that resource methods accept as an optional final argument:\n * extra HTTP headers (e.g. `Idempotency-Key`), a per-request timeout override,\n * and an `AbortSignal` for cancellation.\n */\nexport type RequestExtras = Pick<RequestOptions, 'headers' | 'timeout' | 'signal'>;\n\n/**\n * Delopay API client.\n *\n * Instantiate once with your API key and reuse across your application.\n * All resource sub-clients (payments, refunds, customers, …) are exposed\n * as properties on the instance.\n *\n * @example\n * ```typescript\n * const delopay = new Delopay('prd_...', { sandbox: false });\n * const payment = await delopay.payments.create({ amount: 5000, currency: 'EUR' });\n * ```\n */\nexport class Delopay {\n /** Utility for verifying incoming webhook signatures (static, no instance needed). */\n static webhooks = Webhooks;\n\n /** The resolved base URL used for all API requests. */\n readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly debug: boolean;\n private readonly logger?: DelopayLogger;\n private jwtToken?: string;\n\n // Merchant-facing\n readonly payments: Payments;\n readonly refunds: Refunds;\n readonly customers: Customers;\n readonly paymentMethods: PaymentMethods;\n readonly paymentLinks: PaymentLinks;\n readonly mandates: Mandates;\n readonly disputes: Disputes;\n readonly payouts: Payouts;\n readonly ephemeralKeys: EphemeralKeys;\n readonly events: Events;\n readonly poll: Poll;\n\n // Connector / routing\n readonly connectors: Connectors;\n readonly routing: Routing;\n readonly profiles: Profiles;\n readonly shops: Shops;\n readonly profileAcquirers: ProfileAcquirers;\n\n // Authentication & verification\n readonly authentication: Authentication;\n readonly verification: Verification;\n\n // Dashboard / internal\n readonly users: Users;\n readonly apiKeys: ApiKeys;\n readonly billing: Billing;\n readonly blocklist: Blocklist;\n readonly fees: Fees;\n readonly merchantAccounts: MerchantAccounts;\n readonly projects: Projects;\n readonly relay: Relay;\n readonly stripeConnect: StripeConnect;\n readonly threeDsRules: ThreeDsRules;\n /**\n * A merchant's own audit log. Needs a dashboard JWT, not an API key —\n * see {@link Audit}.\n */\n readonly audit: Audit;\n readonly settlement: Settlement;\n readonly operationLimits: OperationLimits;\n readonly risk: Risk;\n\n // New resources (Phases 3-4)\n readonly subscriptions: Subscriptions;\n readonly files: Files;\n readonly export: Export;\n readonly forex: Forex;\n readonly regions: Regions;\n readonly availabilityOverrides: AvailabilityOverrides;\n readonly analytics: Analytics;\n readonly analyticsDashboard: AnalyticsDashboard;\n readonly featureMatrix: FeatureMatrix;\n readonly cards: Cards;\n readonly search: Search;\n\n /**\n * Create a new Delopay client.\n *\n * @param apiKey - Your Delopay API key (e.g. `prd_...` or `snd_...`).\n * Pass an empty string or omit for JWT-only usage (e.g. dashboard apps).\n * @param options - Optional configuration (sandbox mode, base URL override, timeout).\n */\n constructor(apiKey?: string, options?: DelopayOptions) {\n this.apiKey = apiKey ?? '';\n this.timeout = options?.timeout ?? 30_000;\n this.maxRetries = options?.maxRetries ?? 2;\n this.debug = options?.debug ?? false;\n if (options?.logger !== undefined) this.logger = options.logger;\n\n if (options?.baseUrl !== undefined) {\n this.baseUrl = options.baseUrl;\n } else if (options?.sandbox) {\n this.baseUrl = SANDBOX_URL;\n } else {\n this.baseUrl = PRODUCTION_URL;\n }\n\n const request = this.request.bind(this) as RequestFn;\n\n // JWT auth methods are defined below (setJwtToken / clearJwtToken)\n\n // Merchant-facing\n this.payments = new Payments(request);\n this.refunds = new Refunds(request);\n this.customers = new Customers(request);\n this.paymentMethods = new PaymentMethods(request);\n this.paymentLinks = new PaymentLinks(request);\n this.mandates = new Mandates(request);\n this.disputes = new Disputes(request);\n this.payouts = new Payouts(request);\n this.ephemeralKeys = new EphemeralKeys(request);\n this.events = new Events(request);\n this.poll = new Poll(request);\n\n // Connector / routing\n this.connectors = new Connectors(request);\n this.routing = new Routing(request);\n this.profiles = new Profiles(request);\n this.shops = new Shops(request);\n this.profileAcquirers = new ProfileAcquirers(request);\n\n // Authentication & verification\n this.authentication = new Authentication(request);\n this.verification = new Verification(request);\n\n // Dashboard / internal\n this.users = new Users(request);\n this.apiKeys = new ApiKeys(request);\n this.billing = new Billing(request);\n this.blocklist = new Blocklist(request);\n this.fees = new Fees(request);\n this.merchantAccounts = new MerchantAccounts(request);\n this.projects = new Projects(request);\n this.relay = new Relay(request);\n this.stripeConnect = new StripeConnect(request);\n this.threeDsRules = new ThreeDsRules(request);\n this.audit = new Audit(request);\n this.settlement = new Settlement(request);\n this.operationLimits = new OperationLimits(request);\n this.risk = new Risk(request);\n\n // New resources (Phases 3-4)\n this.subscriptions = new Subscriptions(request);\n this.files = new Files(request);\n this.export = new Export(request);\n this.forex = new Forex(request);\n this.regions = new Regions(request);\n this.availabilityOverrides = new AvailabilityOverrides(request);\n this.analytics = new Analytics(request);\n this.analyticsDashboard = new AnalyticsDashboard(request);\n this.featureMatrix = new FeatureMatrix(request);\n this.cards = new Cards(request);\n this.search = new Search(request);\n }\n\n /**\n * Set a JWT token for subsequent requests.\n * When set, requests use `Authorization: Bearer <token>` instead of `api-key`.\n * Useful after `users.signIn()` returns a JWT for dashboard operations.\n */\n setJwtToken(token: string): void {\n this.jwtToken = token;\n }\n\n /**\n * Clear the JWT token, reverting to API key authentication.\n */\n clearJwtToken(): void {\n this.jwtToken = undefined;\n }\n\n /**\n * Refresh the current login JWT (see {@link Users.refreshToken}) and\n * apply the fresh token to this client, so subsequent requests use it.\n * Returns the fresh token for the caller to persist (e.g. session\n * storage) — the backend has already re-set the `login_token` cookie.\n *\n * If the client's auth state changes while the refresh is pending —\n * `clearJwtToken()` on sign-out, or `setJwtToken()` switching to another\n * session — the stale completion is discarded and this rejects with a\n * `session_changed` `DelopayError` (status 0), so the explicit change\n * wins and the caller never persists a token for a session that is gone.\n *\n * Otherwise throws like any other request; in particular a 401 means the\n * session is dead (expired/blacklisted/revoked), a 429 means a refresh\n * was already minted for this session within the last minute, and a 400\n * means this token has no revocable session to slide (no `jti` — team\n * impersonation is the case in practice) and can never be refreshed,\n * though it stays valid for ordinary calls.\n */\n async refreshSession(): Promise<TokenResponse> {\n const originatingToken = this.jwtToken;\n const response = await this.users.refreshToken();\n if (this.jwtToken !== originatingToken) {\n throw new DelopayError(\n 'Auth state changed while the refresh was pending; refreshed token discarded',\n {\n status: 0,\n code: 'session_changed',\n type: 'session_changed',\n },\n );\n }\n this.setJwtToken(response.token);\n return response;\n }\n\n /**\n * Make a raw HTTP request to the Delopay API.\n *\n * You rarely need to call this directly — prefer the typed resource methods.\n * Use it only for endpoints not yet covered by a resource class.\n *\n * @param method - HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`).\n * @param path - API path starting with `/` (e.g. `/payments`).\n * @param options - Optional body, query parameters, and headers.\n * @returns Parsed JSON response body typed as `T`.\n * @throws {DelopayAuthenticationError} On 401 responses.\n * @throws {DelopayError} On all other non-2xx responses, timeouts, and network errors.\n */\n async request<T>(method: string, path: string, options?: RequestOptions): Promise<T> {\n let url = `${this.baseUrl}${path}`;\n\n if (options?.query) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(options.query)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n if (v !== undefined && v !== null) params.append(key, String(v));\n }\n } else {\n params.set(key, String(value));\n }\n }\n const qs = params.toString();\n if (qs) {\n url += `?${qs}`;\n }\n }\n\n const headers: Record<string, string> = {\n ...(this.jwtToken\n ? { Authorization: `Bearer ${this.jwtToken}` }\n : this.apiKey\n ? { 'api-key': this.apiKey }\n : {}),\n ...options?.headers,\n };\n\n // FormData / Blob / ArrayBuffer / URLSearchParams pass through unchanged so callers\n // can send multipart uploads. The runtime (browser or Node 18+ fetch) sets the\n // appropriate Content-Type including the multipart boundary, so we don't touch it.\n const isRawBody =\n options?.body !== undefined &&\n options?.body !== null &&\n (options.body instanceof FormData ||\n options.body instanceof Blob ||\n options.body instanceof ArrayBuffer ||\n options.body instanceof URLSearchParams);\n\n if (options?.body && !isRawBody) {\n headers['Content-Type'] = 'application/json';\n }\n\n const idempotencyKey = findIdempotencyKey(headers)?.trim();\n const isRetryable =\n method === 'GET' ||\n method === 'DELETE' ||\n (idempotencyKey !== undefined && idempotencyKey !== '');\n\n // Serialize body once so circular-reference errors surface immediately and big payloads\n // aren't re-stringified on every retry attempt. Raw bodies pass through untouched.\n let serializedBody: BodyInit | undefined;\n if (isRawBody) {\n serializedBody = options?.body as BodyInit;\n } else if (options?.body) {\n serializedBody = JSON.stringify(options.body);\n }\n\n const callerSignal = options?.signal;\n if (callerSignal?.aborted) {\n throw new DelopayError('Request aborted', {\n status: 0,\n code: 'ABORTED',\n type: 'abort_error',\n });\n }\n\n const timeoutMs = options?.timeout ?? this.timeout;\n\n let lastError: unknown;\n let retryAfterOverrideMs: number | null = null;\n\n const safeUrl = () => redactUrlForLogging(url);\n const emit = (event: 'request' | 'response' | 'retry', data: Record<string, unknown>) => {\n if (!this.debug) return;\n if (this.logger) {\n this.logger(event, data);\n return;\n }\n if (event === 'request')\n console.log(`[delopay] ${data.method as string} ${data.url as string}`);\n else if (event === 'response')\n console.log(\n `[delopay] ${data.status as number} ${data.method as string} ${data.path as string}`,\n );\n else\n console.log(\n `[delopay] retry ${data.attempt as number}/${data.maxRetries as number} ${data.method as string} ${data.path as string}`,\n );\n };\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n const base = Math.min(500 * 2 ** (attempt - 1), 5000);\n // Full jitter: pick uniformly in [0, base) to avoid synchronized retry storms.\n const jittered = Math.random() * base;\n const delay = Math.max(retryAfterOverrideMs ?? 0, jittered);\n retryAfterOverrideMs = null;\n await new Promise((resolve) => setTimeout(resolve, delay));\n emit('retry', { attempt, maxRetries: this.maxRetries, method, path });\n }\n\n const timeoutCtrl = new AbortController();\n const timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);\n const combined = combineSignals(\n callerSignal ? [timeoutCtrl.signal, callerSignal] : [timeoutCtrl.signal],\n );\n\n try {\n emit('request', { method, url: safeUrl(), path });\n\n const response = await fetch(url, {\n method,\n headers,\n body: serializedBody,\n signal: combined.signal,\n ...(options?.keepalive !== undefined ? { keepalive: options.keepalive } : {}),\n });\n\n const requestId =\n response.headers?.get('x-request-id') ?? response.headers?.get('x-trace-id') ?? undefined;\n\n emit('response', { status: response.status, method, path, requestId });\n\n if (!response.ok) {\n const rawBody = await response.text().catch(() => '');\n let parsed: Record<string, unknown> = {};\n if (rawBody) {\n try {\n parsed = JSON.parse(rawBody) as Record<string, unknown>;\n } catch {\n // non-JSON error body (HTML from a proxy, truncated stream, etc.) — keep raw\n }\n }\n // API wraps errors as { error: { message, code, type, data? } } — unwrap if present\n const err = (parsed.error as Record<string, unknown>) ?? parsed;\n const message =\n (err.message as string) ?? `Request failed with status ${response.status}`;\n const code = (err.code as string) ?? '';\n const type = (err.error_type as string) ?? (err.type as string) ?? '';\n const data =\n err.data && typeof err.data === 'object' && !Array.isArray(err.data)\n ? (err.data as Record<string, unknown>)\n : undefined;\n const truncatedRaw = truncateRawBody(rawBody);\n\n // A 401 usually means OUR credential (API key / JWT) was rejected —\n // but connector-passthrough errors (`CE_*` / type \"connector\", e.g.\n // a PSP rejecting the merchant's stored Stripe key) propagate the\n // upstream status and are NOT a Delopay authentication failure, so\n // they stay a plain DelopayError instead of triggering the\n // \"re-authenticate\" handling dashboards attach to auth errors.\n const isConnectorPassthrough = type === 'connector' || code.startsWith('CE_');\n if (response.status === 401 && !isConnectorPassthrough) {\n throw new DelopayAuthenticationError(message, {\n code,\n type,\n requestId,\n rawBody: truncatedRaw,\n data,\n });\n }\n\n const error = new DelopayError(message, {\n status: response.status,\n code,\n type,\n requestId,\n rawBody: truncatedRaw,\n data,\n });\n\n // Retry on 5xx and 429 (rate limit). 4xx other than 429 are not transient.\n const isTransientStatus = response.status >= 500 || response.status === 429;\n if (isTransientStatus && isRetryable && attempt < this.maxRetries) {\n if (response.status === 429) {\n retryAfterOverrideMs = parseRetryAfter(response.headers?.get('retry-after') ?? null);\n }\n lastError = error;\n continue;\n }\n\n throw error;\n }\n\n if (options?.responseType === 'blob') {\n return (await response.blob()) as T;\n }\n if (options?.responseType === 'arraybuffer') {\n return (await response.arrayBuffer()) as T;\n }\n const text = await response.text();\n return (text ? JSON.parse(text) : undefined) as T;\n } catch (err) {\n if (err instanceof DelopayError || err instanceof DelopayAuthenticationError) {\n throw err;\n }\n if (err instanceof Error && err.name === 'AbortError') {\n if (callerSignal?.aborted) {\n throw new DelopayError('Request aborted', {\n status: 0,\n code: 'ABORTED',\n type: 'abort_error',\n });\n }\n lastError = new DelopayError('Request timed out', {\n status: 0,\n code: 'TIMEOUT',\n type: 'timeout_error',\n });\n if (isRetryable && attempt < this.maxRetries) continue;\n throw lastError;\n }\n if (err instanceof TypeError) {\n lastError = new DelopayError(`Network error: ${err.message}`, {\n status: 0,\n code: 'NETWORK',\n type: 'network_error',\n });\n if (isRetryable && attempt < this.maxRetries) continue;\n throw lastError;\n }\n throw err;\n } finally {\n clearTimeout(timeoutId);\n combined.dispose();\n }\n }\n\n throw lastError;\n }\n\n /**\n * Auto-paginate a list endpoint. Yields items one by one, fetching\n * the next page automatically when the current one is exhausted.\n *\n * Delopay list endpoints use one of two pagination styles, so this helper\n * supports both:\n * - **Offset** (default) — for endpoints like `customers.list` that accept\n * `offset`/`limit`. Each page advances `offset` by the number of items returned.\n * - **Cursor** — for endpoints like `payments.list` and `payouts.list` that page\n * with `starting_after`/`limit` (they ignore `offset`). Pass a `cursor` extractor\n * that returns the id of an item; the next page is requested with\n * `starting_after` set to the last item's id.\n *\n * @param listFn - A function that takes the paging params and returns `{ data: T[] }` or `T[]`.\n * @param params - Additional parameters to pass to every page request.\n * @param options - Page size (number) for offset mode, or `{ pageSize?, cursor? }`.\n * Provide `cursor` to switch to cursor pagination.\n *\n * @example\n * ```typescript\n * // Offset endpoint (customers):\n * for await (const c of delopay.paginate((p) => delopay.customers.list(p))) {\n * console.log(c.customer_id);\n * }\n *\n * // Cursor endpoint (payments): extract the id used as the next cursor.\n * for await (const payment of delopay.paginate(\n * (p) => delopay.payments.list(p),\n * undefined,\n * { cursor: (p) => p.payment_id },\n * )) {\n * console.log(payment.payment_id);\n * }\n * ```\n */\n async *paginate<T, P extends Record<string, unknown>>(\n listFn: (\n params: P & { limit: number; offset?: number; starting_after?: string },\n ) => Promise<{ data: T[] } | T[]>,\n params?: P,\n options?: number | { pageSize?: number; cursor?: (item: T) => string | undefined },\n ): AsyncGenerator<T> {\n const pageSize = typeof options === 'number' ? options : (options?.pageSize ?? 50);\n const cursorOf = typeof options === 'object' ? options.cursor : undefined;\n let offset = 0;\n let after: string | undefined;\n while (true) {\n const page = { ...((params ?? {}) as P), limit: pageSize } as P & {\n limit: number;\n offset?: number;\n starting_after?: string;\n };\n if (cursorOf) {\n if (after !== undefined) page.starting_after = after;\n } else {\n page.offset = offset;\n }\n const result = await listFn(page);\n const items = Array.isArray(result) ? result : result.data;\n if (items.length === 0) break;\n for (const item of items) {\n yield item;\n }\n if (items.length < pageSize) break;\n if (cursorOf) {\n const last = items[items.length - 1];\n if (last === undefined) break;\n after = cursorOf(last);\n if (after === undefined) break;\n } else {\n offset += items.length;\n }\n }\n }\n}\n","import type {\n Connector,\n Currency,\n EuclidComparison,\n EuclidComparisonType,\n EuclidIfStatement,\n EuclidValue,\n PaymentMethod,\n PlatformFeeKind,\n PlatformFeeOutput,\n PlatformFeeProgram,\n PlatformFeeRule,\n} from './types';\n\n/** A single condition leaf in the builder's condition tree. */\nexport interface LeafNode {\n kind: 'leaf';\n lhs: string;\n comparison: EuclidComparisonType;\n value: EuclidValue;\n}\n\n/** An AND (`all`) or OR (`any`) group of condition nodes. */\nexport interface GroupNode {\n kind: 'all' | 'any';\n children: ConditionNode[];\n}\n\nexport type ConditionNode = LeafNode | GroupNode;\n\n/**\n * A condition leaf. Numeric values (amount, merchant_volume) tag as `number`;\n * string values (payment_method, connector, currency, card_network) tag as\n * `enum_variant`.\n */\nexport function leaf(\n lhs: string,\n comparison: EuclidComparisonType,\n value: string | number,\n): LeafNode {\n const tagged: EuclidValue =\n typeof value === 'number' ? { type: 'number', value } : { type: 'enum_variant', value };\n return { kind: 'leaf', lhs, comparison, value: tagged };\n}\n\n/** AND group — all children must match. */\nexport function allOf(...children: ConditionNode[]): GroupNode {\n return { kind: 'all', children };\n}\n\n/** OR group — any child matching is enough. */\nexport function anyOf(...children: ConditionNode[]): GroupNode {\n return { kind: 'any', children };\n}\n\n/**\n * How a rule (or the default) prices a transaction. `fee_type` is inferred:\n * percentage-only → `percentage`, flat-only → `flat`, both → `combined`.\n */\nexport interface FeeSpecInput {\n /** Percentage fee, e.g. `2.5` means 2.5%. */\n percentage?: number;\n /** Flat fee in minor units. */\n flat?: number;\n /** ISO 4217 currency for the flat fee. */\n flatCurrency?: string;\n /** Clamp floor in minor units. */\n min?: number;\n /** Clamp ceiling in minor units. */\n max?: number;\n}\n\n/**\n * Friendly conditions for a rule. Every provided key becomes one condition and\n * they are ANDed together. For dimensions not covered here (payment-method-type\n * keys like `crypto`/`wallet`, metadata, value arrays) use `rawConditions`.\n */\nexport interface FeeRuleConditions {\n paymentMethod?: PaymentMethod;\n connector?: Connector;\n currency?: Currency;\n cardNetwork?: string;\n /**\n * Customer billing-address country. Must be the exact backend `Country` enum\n * variant (PascalCase full name, e.g. `Germany`/`UnitedStatesOfAmerica`), not\n * an ISO code — the engine lowers `billing_country` via case-sensitive\n * `from_str`.\n */\n billingCountry?: string;\n /** `amount == n` (minor units). */\n amountEquals?: number;\n /** `amount > n` (minor units). */\n amountGreaterThan?: number;\n /** `amount < n` (minor units). */\n amountLessThan?: number;\n /**\n * `merchant_volume == n` — the merchant's previous-month volume snapshot\n * (USD minor units). Combine with any other condition, e.g.\n * `{ paymentMethod: 'crypto', merchantVolumeGreaterThan: 1_000_000 }`.\n */\n merchantVolumeEquals?: number;\n /** `merchant_volume > n` (USD minor units). */\n merchantVolumeGreaterThan?: number;\n /** `merchant_volume < n` (USD minor units). */\n merchantVolumeLessThan?: number;\n}\n\nexport interface FeeRuleInput {\n name: string;\n /** Friendly conditions (ANDed). Omit for an always-matching rule (prefer `otherwise`). */\n when?: FeeRuleConditions;\n /** Extra raw conditions ANDed in, for dimensions `when` does not cover. */\n rawConditions?: EuclidComparison[];\n /** Nested AND/OR condition tree. Mutually exclusive with `when`/`rawConditions`. */\n match?: ConditionNode;\n fee: FeeSpecInput;\n}\n\nfunction toFeeOutput(spec: FeeSpecInput): PlatformFeeOutput {\n const hasPct = spec.percentage != null;\n const hasFlat = spec.flat != null;\n const feeType: PlatformFeeKind = hasPct && hasFlat ? 'combined' : hasFlat ? 'flat' : 'percentage';\n return {\n fee_type: feeType,\n percentage_fee: spec.percentage ?? null,\n flat_fee_amount: spec.flat ?? null,\n flat_fee_currency: spec.flatCurrency ?? null,\n min_fee_amount: spec.min ?? null,\n max_fee_amount: spec.max ?? null,\n };\n}\n\nfunction enumCondition(lhs: string, value: string): EuclidComparison {\n return { lhs, comparison: 'equal', value: { type: 'enum_variant', value }, metadata: {} };\n}\n\nfunction numberCondition(\n lhs: string,\n comparison: EuclidComparisonType,\n value: number,\n): EuclidComparison {\n return { lhs, comparison, value: { type: 'number', value }, metadata: {} };\n}\n\nfunction buildConditions(\n when: FeeRuleConditions = {},\n raw: EuclidComparison[] = [],\n): EuclidComparison[] {\n const out: EuclidComparison[] = [];\n if (when.paymentMethod != null) out.push(enumCondition('payment_method', when.paymentMethod));\n if (when.connector != null) out.push(enumCondition('connector', when.connector));\n if (when.currency != null) out.push(enumCondition('currency', when.currency));\n if (when.cardNetwork != null) out.push(enumCondition('card_network', when.cardNetwork));\n if (when.billingCountry != null) out.push(enumCondition('billing_country', when.billingCountry));\n if (when.amountEquals != null) out.push(numberCondition('amount', 'equal', when.amountEquals));\n if (when.amountGreaterThan != null) {\n out.push(numberCondition('amount', 'greater_than', when.amountGreaterThan));\n }\n if (when.amountLessThan != null) {\n out.push(numberCondition('amount', 'less_than', when.amountLessThan));\n }\n if (when.merchantVolumeEquals != null) {\n out.push(numberCondition('merchant_volume', 'equal', when.merchantVolumeEquals));\n }\n if (when.merchantVolumeGreaterThan != null) {\n out.push(numberCondition('merchant_volume', 'greater_than', when.merchantVolumeGreaterThan));\n }\n if (when.merchantVolumeLessThan != null) {\n out.push(numberCondition('merchant_volume', 'less_than', when.merchantVolumeLessThan));\n }\n out.push(...raw);\n return out;\n}\n\nfunction leafToComparison(node: LeafNode): EuclidComparison {\n return { lhs: node.lhs, comparison: node.comparison, value: node.value, metadata: {} };\n}\n\n/**\n * Flatten associativity (nested all-in-all / any-in-any) and collapse\n * single-child groups, so every group child of an `all` is an `any`.\n * @internal\n */\nexport function normalizeNode(node: ConditionNode): ConditionNode {\n if (node.kind === 'leaf') return node;\n const children = node.children.map(normalizeNode);\n const flat: ConditionNode[] = [];\n for (const c of children) {\n if (c.kind === node.kind) flat.push(...c.children);\n else flat.push(c);\n }\n if (flat.length === 1) return flat[0];\n return { kind: node.kind, children: flat };\n}\n\nfunction toStatement(node: ConditionNode): EuclidIfStatement {\n if (node.kind === 'leaf') return { condition: [leafToComparison(node)], nested: null };\n // Unreachable via current callers (encodeStatements strips top-level any); kept for totality.\n if (node.kind === 'any') {\n return { condition: [], nested: node.children.map(toStatement) };\n }\n // 'all': after normalize, group children are all 'any'.\n const leaves = node.children.filter((c): c is LeafNode => c.kind === 'leaf');\n const groups = node.children.filter((c): c is GroupNode => c.kind !== 'leaf');\n const condition = leaves.map(leafToComparison);\n if (groups.length === 0) return { condition, nested: null };\n const [first, ...rest] = groups;\n // `first` is an OR; AND each of its branches with the remaining OR groups.\n const nested = first.children.map((branch) => toStatement(normalizeNode(allOf(branch, ...rest))));\n return { condition, nested };\n}\n\nfunction assertNoEmptyAnyOf(node: ConditionNode): void {\n if (node.kind === 'leaf') return;\n if (node.kind === 'any' && node.children.length === 0) {\n throw new Error('feeProgram: an anyOf() group must have at least one condition');\n }\n node.children.forEach(assertNoEmptyAnyOf);\n}\n\n/**\n * Encode a rule's match (a condition tree) into the engine's `statements[]`.\n * A top-level OR spreads across statements; anything else is a single statement.\n * @internal\n */\nexport function encodeStatements(match: ConditionNode): EuclidIfStatement[] {\n const m = normalizeNode(match);\n if (m.kind === 'any') return m.children.map(toStatement);\n return [toStatement(m)];\n}\n\nfunction comparisonToLeaf(c: EuclidComparison): LeafNode {\n return { kind: 'leaf', lhs: c.lhs, comparison: c.comparison, value: c.value };\n}\n\nfunction statementToNode(stmt: EuclidIfStatement): ConditionNode {\n const leaves = stmt.condition.map(comparisonToLeaf);\n if (stmt.nested && stmt.nested.length > 0) {\n const orNode = anyOf(...stmt.nested.map(statementToNode));\n if (leaves.length === 0) return orNode;\n return allOf(...leaves, orNode);\n }\n return leaves.length === 1 ? leaves[0] : allOf(...leaves);\n}\n\n/**\n * Decode a rule's `statements[]` back into a condition tree.\n *\n * Returns a tree that is **logically equivalent** to the source. It is\n * deep-equal to `normalizeNode(input)` only when no `all` group contains two\n * or more `any` groups; where the encoder distributed AND over OR, the decoded\n * shape differs (still equivalent).\n */\nexport function ruleMatchToTree(statements: EuclidIfStatement[]): ConditionNode {\n if (statements.length === 1) return normalizeNode(statementToNode(statements[0]));\n return normalizeNode(anyOf(...statements.map(statementToNode)));\n}\n\n/**\n * Decode a stored program into the builder's editable model.\n *\n * Returns a tree that is **logically equivalent** to the source. It is\n * deep-equal to `normalizeNode(input)` only when no `all` group contains two\n * or more `any` groups; where the encoder distributed AND over OR, the decoded\n * shape differs (still equivalent).\n */\nexport function programToTree(program: PlatformFeeProgram): {\n rules: { name: string; match: ConditionNode; fee: PlatformFeeOutput | null }[];\n otherwise: PlatformFeeOutput | null;\n} {\n return {\n rules: program.rules.map((r) => ({\n name: r.name,\n match: ruleMatchToTree(r.statements),\n fee: r.connectorSelection.fee ?? null,\n })),\n otherwise: program.defaultSelection.fee ?? null,\n };\n}\n\n/**\n * Fluent builder for a platform fee-rule program. Emits the exact Euclid wire\n * shape (camelCase tree, tagged values, `metadata: {}` everywhere) so callers\n * never hand-write the AST. Rules are evaluated in order; the first match wins,\n * else `otherwise` (the default selection).\n *\n * @example\n * ```ts\n * const algorithm = feeProgram()\n * .rule({ name: 'crypto', when: { paymentMethod: 'crypto' }, fee: { percentage: 1.0 } })\n * .rule({\n * name: 'card_on_cryptomus',\n * when: { paymentMethod: 'card', connector: 'cryptomus' },\n * fee: { percentage: 2.0 },\n * })\n * .otherwise({ percentage: 3.0 })\n * .build();\n *\n * await delopay.fees.rules.upsert({ algorithm }, merchantId);\n * ```\n */\nexport class FeeProgramBuilder {\n private readonly rules: PlatformFeeRule[] = [];\n private defaultFee: PlatformFeeOutput | null = null;\n\n /** Append a rule. Provided `when`/`rawConditions` are ANDed. */\n rule(input: FeeRuleInput): this {\n if (input.match) assertNoEmptyAnyOf(input.match);\n const statements: PlatformFeeRule['statements'] = input.match\n ? encodeStatements(input.match)\n : [{ condition: buildConditions(input.when, input.rawConditions) }];\n this.rules.push({\n name: input.name,\n connectorSelection: { fee: toFeeOutput(input.fee) },\n statements,\n });\n return this;\n }\n\n /** Set the default selection (applied when no rule matches). */\n otherwise(fee: FeeSpecInput): this {\n this.defaultFee = toFeeOutput(fee);\n return this;\n }\n\n /** Produce the wire-ready program. */\n build(): PlatformFeeProgram {\n return {\n defaultSelection: { fee: this.defaultFee },\n rules: this.rules,\n metadata: {},\n };\n }\n}\n\n/** Start building a platform fee-rule program. See {@link FeeProgramBuilder}. */\nexport function feeProgram(): FeeProgramBuilder {\n return new FeeProgramBuilder();\n}\n","// Checkout branding — typed shape, design tokens, palettes, persistence\n// codec, CSS sanitizer, and DOM helpers for `--dp-*` CSS variables.\n//\n// Both delopay-checkout and delopay-control-center consume this module.\n//\n// Persistence: top-level fields own the \"loud\" tokens (logo, theme,\n// payment_button_*, background_colour, etc.). Everything else lives in\n// `sdk_ui_rules.branding` as a nested string-keyed map — booleans and\n// numbers round-trip as strings, the trust-badge list is JSON-stringified.\n\n// --- Types --------------------------------------------------------------\n\nexport type CornerRadius = 'square' | 'small' | 'medium' | 'large' | 'pill';\n\n// Surfaces and inputs never make sense pill-shaped (a pill input ends up with\n// half-circle ends crammed against text). The form picker only exposes these\n// four; if a stale 'pill' value lands here from older saved data, decode\n// drops it back to 'medium'. Buttons and badges still allow 'pill'.\nexport type NonPillRadius = Exclude<CornerRadius, 'pill'>;\n\n// Spacing scales — split apart so the merchant can independently tune\n// surface padding, vertical rhythm, input height and pay-button height. Used\n// to live as a single `density` enum but that conflated four dimensions.\nexport type SpacingScale = 'compact' | 'comfortable' | 'spacious';\nexport type SizeScale = 'sm' | 'md' | 'lg';\nexport type SurfaceStyle = 'flat' | 'outlined' | 'elevated';\n\nexport type FontFamily =\n | 'inter'\n | 'system'\n | 'serif'\n | 'mono'\n | 'roboto'\n | 'poppins'\n | 'manrope'\n | 'dm-sans'\n | 'space-grotesk'\n | 'plex-sans'\n | 'work-sans'\n | 'open-sans'\n | 'lora'\n | 'playfair'\n | 'plex-mono'\n | 'jetbrains-mono';\n\nexport type FontWeight = 'regular' | 'medium' | 'semibold' | 'bold';\nexport type LayoutStyle = 'compact' | 'split';\nexport type SummaryPosition = 'left' | 'right';\n\n// Stripe Elements only supports two label modes (\"above\" or hidden via the\n// .Label-collapse hack); a \"floating\" label is not a Stripe concept and\n// would only render in our own mock — preview was lying about it. Persisted\n// `'floating'` is silently decoded to `'above'` for back-compat.\nexport type LabelStyle = 'above' | 'hidden';\n\n// Stripe Elements layout. Honored inside the StripeCardPane only — other\n// connector panes stack vertically regardless of this setting.\nexport type PaymentLayout = 'tabs' | 'accordion' | 'spaced_accordion';\n\nexport type LogoShape = 'square' | 'rounded' | 'circle';\nexport type LogoSize = 'sm' | 'md' | 'lg';\n\n// --- Provider surcharge / discount disclosure ---------------------------\n//\n// With surcharges scoped to the provider rather than to the payment method,\n// two tiles on one checkout can cost the buyer different amounts — so the\n// figure has to be legible on the tile, before the choice, not only in the\n// breakdown after it. These control how that figure is painted; whether there\n// is one at all is the router's answer, per pane.\n//\n// Nothing here can invent a figure or change one. A merchant who would rather\n// not disclose per-tile turns it off with `showSurcharge` and keeps the\n// breakdown inside the pane, which is where the disclosure lived before.\n\n// Where the figure sits relative to the tile's label.\n//\n// `inline` follows the label text immediately, so the price reads as part of\n// the name — good for short labels.\n// `trailing` pushes it to the tile's trailing edge on the label's own line: the\n// price reads as a property of the tile, and the tile's height does not change,\n// which matters because most tiles carry no figure at all and a row that grows\n// only for some of them makes the list look ragged.\n// `below` puts it under the sublabel, for merchants whose labels are long\n// enough that a trailing figure would crowd them.\n// `above` puts it over the label as an eyebrow, which is the one position that\n// reads before the method name rather than after it.\nexport type SurchargePosition =\n | 'inline'\n | 'trailing'\n | 'below'\n | 'above'\n | 'cornerStart'\n | 'cornerEnd';\n\n// How the figure is painted.\n//\n// `plain` is text in the configured colour. `badge` fills the shape with a tint\n// of it. `outline` draws the border only — the middle weight, for a checkout\n// whose tiles are already busy. `solid` fills with the colour itself and writes\n// on it in whichever of black or white reads better, which is the loudest\n// option and the one to reach for when the figure must not be missed.\n// `underline` keeps the text weight of `plain` and adds a rule beneath it.\n// `ribbon` runs the figure diagonally across a corner of the tile — the one\n// treatment that reads before the label rather than beside it, for a merchant\n// steering hard toward a cheaper provider.\nexport type SurchargeStyle = 'plain' | 'badge' | 'outline' | 'solid' | 'underline' | 'ribbon';\n\n// The border drawn around the shapes `badge`, `outline`, `solid` and `ribbon`\n// paint. `outline` draws nothing BUT its border, so `none` there would erase\n// the style rather than restyle it and reads as `thin` instead.\nexport type SurchargeBorderWidth = 'none' | 'thin' | 'medium' | 'thick';\n\n// How that border is drawn. `dashed` and `dotted` read as provisional, which\n// suits a promotional discount; `solid` is the neutral default.\nexport type SurchargeBorderStyle = 'solid' | 'dashed' | 'dotted';\n\n// The figure's type size, relative to the tile's own text.\nexport type SurchargeSize = 'sm' | 'md' | 'lg';\n\n// The corner treatment of the shapes `badge`, `outline` and `solid` draw.\n// Ignored by `plain` and `underline`, which draw no shape.\nexport type SurchargeShape = 'pill' | 'rounded' | 'square';\n\n// How heavily the figure is set.\nexport type SurchargeWeight = 'regular' | 'medium' | 'bold';\n\n// Whether the figure carries an explicit sign.\n//\n// `always` writes `+` on a surcharge and `−` on a discount (U+2212, not a\n// hyphen, so it aligns with the digits). `minusOnly` writes the minus and\n// leaves a surcharge unsigned, which reads as a price rather than as an\n// adjustment. `none` writes neither and leans entirely on the two colours —\n// legible only when a merchant configures one direction, and offered because a\n// merchant who only ever discounts should not have to explain a plus sign.\nexport type SurchargeSign = 'always' | 'minusOnly' | 'none';\n\n// Whether the figure names itself.\n//\n// `amount` is the figure alone. `labelled` prefixes the localized word for the\n// direction (\"Surcharge\" / \"Discount\"), which costs horizontal room and buys a\n// tile nobody has to interpret.\nexport type SurchargeLabelMode = 'amount' | 'labelled';\n\n// WHICH figure the tile prints, and in which order when it prints both.\n//\n// A discount and a surcharge are the same mechanism pointed in opposite\n// directions, but they are not the same message: a saving is something a\n// merchant advertises and a percentage is the persuasive half of it (\"20%\n// off\"), while a fee is something a merchant discloses and the money is the\n// half the buyer actually cares about. So the two directions carry this\n// setting separately — `discountFigure` and `surchargeFigure` — rather than\n// sharing one.\n//\n// The two figures always describe the same money. The router derives the\n// percentage from the charge rather than from the merchant's rule, so a fixed\n// rule states its share of this cart and a taxed rate states the share the\n// buyer actually pays. That is what makes showing either — or both — safe.\nexport type SurchargeFigureMode = 'amount' | 'percent' | 'amountThenPercent' | 'percentThenAmount';\n\n/**\n * Whether the tile has room to print the wording alongside the figure.\n *\n * One pairing says no: the diagonal ribbon at either corner. That band is\n * clipped by the tile it crosses, and the readable length is set by how far the\n * corner is inset — roughly 75px on a standard payment tile, against roughly\n * 107px for a labelled figure at the default size. Printing the word there\n * clips the *figure*, and a half-shown price is worse than a plain one, so the\n * word is what gives way.\n *\n * Exported, and shared by the buyer-facing checkout and the dashboard's live\n * preview, because the two must reach the same answer. A preview that promises\n * a word the checkout will not print is the one failure a preview cannot have.\n */\nexport function surchargeShowsLabel(\n labelMode: SurchargeLabelMode,\n style: SurchargeStyle,\n position: SurchargePosition,\n): boolean {\n if (labelMode !== 'labelled') return false;\n return !(style === 'ribbon' && (position === 'cornerStart' || position === 'cornerEnd'));\n}\n\n/** One of the two things a tile can print. */\nexport type SurchargeFigurePart = 'amount' | 'percent';\n\n/** Exactly what one tile prints, in order. See {@link surchargeFigurePlan}. */\nexport interface SurchargeFigurePlan {\n /** The leading figure. Always present — a tile with nothing to say renders nothing at all. */\n first: SurchargeFigurePart;\n /** The trailing figure, parenthesised by the renderer, or `null` for one figure. */\n second: SurchargeFigurePart | null;\n /** Whether the localized direction word prefixes the whole thing. */\n label: boolean;\n}\n\n/**\n * What one tile prints: which figures, in which order, and whether the word\n * comes with them.\n *\n * One function rather than a rule per surface, because the buyer-facing tile\n * and the dashboard's live preview must reach the same answer. A preview that\n * shows a percentage the checkout will not print — or prints in the other\n * order — is the one failure a preview cannot have.\n *\n * Three things it decides, in order of how much they cost to get wrong:\n *\n * * **No percentage available, no percentage printed.** `percentAvailable` is\n * false when the router sent none, which happens on an order of zero. A\n * merchant who asked for `percent` gets the amount instead — never a blank\n * tile, and never `0%`. This is the fallback the whole design leans on: the\n * amount is exact in every case, so it is what every degradation lands on.\n * * **A corner ribbon prints one figure.** The band crossing a tile's corner\n * is clipped to roughly 75px of readable length; two figures and a word do\n * not fit, and clipping a *price* is worse than showing less of one. It\n * keeps the merchant's leading figure — their own statement of which half\n * matters — and drops the trailing one along with the word.\n * * **Direction picks the setting.** `discountFigure` for a credit,\n * `surchargeFigure` for a charge, because a saving and a fee are not the\n * same message even though they are the same mechanism.\n */\nexport function surchargeFigurePlan(\n branding: Pick<\n CheckoutBranding,\n 'surchargeFigure' | 'discountFigure' | 'surchargeLabel' | 'surchargeStyle' | 'surchargePosition'\n >,\n isDiscount: boolean,\n percentAvailable: boolean,\n): SurchargeFigurePlan {\n const mode = isDiscount ? branding.discountFigure : branding.surchargeFigure;\n const label = surchargeShowsLabel(\n branding.surchargeLabel,\n branding.surchargeStyle,\n branding.surchargePosition,\n );\n\n // Money only, whatever was asked for: there is no second figure to state.\n if (!percentAvailable) return { first: 'amount', second: null, label };\n\n const ordered: Record<SurchargeFigureMode, [SurchargeFigurePart, SurchargeFigurePart | null]> = {\n amount: ['amount', null],\n percent: ['percent', null],\n amountThenPercent: ['amount', 'percent'],\n percentThenAmount: ['percent', 'amount'],\n };\n const [first, second] = ordered[mode];\n\n // The corner ribbon keeps the merchant's leading figure and nothing else.\n // `surchargeShowsLabel` has already dropped the word for the same reason, so\n // this is the same rule applied to the second figure.\n const cornerRibbon =\n branding.surchargeStyle === 'ribbon' &&\n (branding.surchargePosition === 'cornerStart' || branding.surchargePosition === 'cornerEnd');\n\n return { first, second: cornerRibbon ? null : second, label };\n}\n\n/**\n * Black or white, whichever reads better on `color` — for the `solid` style,\n * which writes on the configured colour itself.\n *\n * Picked by contrast rather than by a luminance threshold so the answer is the\n * one WCAG would give, and falls back to white on an unparseable colour, which\n * is what the rest of this module does with a colour it cannot read.\n */\nexport function readableInkOn(color: string): string {\n const onBlack = contrastRatio(color, '#000000');\n const onWhite = contrastRatio(color, '#ffffff');\n if (onBlack === null || onWhite === null) return '#ffffff';\n return onBlack >= onWhite ? '#000000' : '#ffffff';\n}\n\n/** Type size per {@link SurchargeSize}, relative to the tile's own text. */\nconst SURCHARGE_FONT_SIZE: Record<SurchargeSize, string> = {\n sm: '0.6875rem',\n md: '0.8125rem',\n lg: '0.9375rem',\n};\n\n/** Shape padding per {@link SurchargeSize}. Grows with the type. */\nconst SURCHARGE_PAD: Record<SurchargeSize, string> = {\n sm: '1px 6px',\n md: '2px 8px',\n lg: '3px 10px',\n};\n\n/** Corner radius per {@link SurchargeShape}. */\nconst SURCHARGE_RADIUS: Record<SurchargeShape, string> = {\n pill: '999px',\n rounded: '6px',\n square: '0px',\n};\n\n/** Border thickness per {@link SurchargeBorderWidth}. */\nconst SURCHARGE_BORDER_WIDTH: Record<SurchargeBorderWidth, string> = {\n none: '0px',\n thin: '1px',\n medium: '2px',\n thick: '3px',\n};\n\n/** Font weight per {@link SurchargeWeight}. */\nconst SURCHARGE_FONT_WEIGHT: Record<SurchargeWeight, string> = {\n regular: '400',\n medium: '600',\n bold: '700',\n};\n\n/**\n * The values each disclosure axis accepts, in the order a picker should offer\n * them: quietest first, so a merchant scrolling down is turning the figure up.\n *\n * Exported because both the dashboard's picker and this module's decoder need\n * the same list, and a picker offering a value the decoder rejects is a control\n * that silently does nothing.\n */\nexport const SURCHARGE_POSITIONS: readonly SurchargePosition[] = [\n 'trailing',\n 'inline',\n 'below',\n 'above',\n 'cornerStart',\n 'cornerEnd',\n];\nexport const SURCHARGE_STYLES: readonly SurchargeStyle[] = [\n 'plain',\n 'underline',\n 'outline',\n 'badge',\n 'solid',\n 'ribbon',\n];\nexport const SURCHARGE_BORDER_WIDTHS: readonly SurchargeBorderWidth[] = [\n 'none',\n 'thin',\n 'medium',\n 'thick',\n];\nexport const SURCHARGE_BORDER_STYLES: readonly SurchargeBorderStyle[] = [\n 'solid',\n 'dashed',\n 'dotted',\n];\nexport const SURCHARGE_SIZES: readonly SurchargeSize[] = ['sm', 'md', 'lg'];\n\n/**\n * Whether a style draws a shape behind the figure, and therefore whether\n * {@link SurchargeShape} means anything for it.\n *\n * `plain` and `underline` paint text. A dashboard that leaves the corner picker\n * live under them offers a control that changes nothing on screen, which is how\n * a merchant decides the whole panel is broken; one that hides it loses their\n * choice when they switch back. Disabled is the answer, and this is the\n * predicate it needs.\n */\nexport function surchargeStyleDrawsAShape(style: SurchargeStyle): boolean {\n return style === 'badge' || style === 'outline' || style === 'solid';\n}\nexport const SURCHARGE_SHAPES: readonly SurchargeShape[] = ['pill', 'rounded', 'square'];\nexport const SURCHARGE_WEIGHTS: readonly SurchargeWeight[] = ['regular', 'medium', 'bold'];\nexport const SURCHARGE_SIGNS: readonly SurchargeSign[] = ['always', 'minusOnly', 'none'];\nexport const SURCHARGE_LABEL_MODES: readonly SurchargeLabelMode[] = ['amount', 'labelled'];\nexport const SURCHARGE_FIGURE_MODES: readonly SurchargeFigureMode[] = [\n 'amount',\n 'percent',\n 'amountThenPercent',\n 'percentThenAmount',\n];\n\n/**\n * The buyer locales the checkout ships copy for, and therefore the ones a\n * merchant can override.\n *\n * Driven from here rather than restated in the dashboard, so a locale added to\n * the checkout cannot leave the dashboard offering one fewer box than the\n * buyer-facing render reads.\n */\nexport const CHECKOUT_LOCALES = ['en', 'de'] as const;\nexport type CheckoutLocale = (typeof CHECKOUT_LOCALES)[number];\n\n/**\n * The copy fields a merchant may write once per locale.\n *\n * Each has a flat `<field>` and a `<field>Translations` map beside it. The flat\n * value is what every existing merchant already has and stays authoritative\n * wherever no override is set — which is what makes this additive: a profile\n * saved before translations existed renders exactly as it did, in every locale.\n */\nexport const LOCALIZABLE_COPY_FIELDS = [\n 'headerText',\n 'payButtonLabel',\n 'cardTermsMessage',\n 'footerText',\n] as const;\nexport type LocalizableCopyField = (typeof LOCALIZABLE_COPY_FIELDS)[number];\n\n/** The translations key that belongs to a copy field. */\nexport function copyTranslationsKey(\n field: LocalizableCopyField,\n): `${LocalizableCopyField}Translations` {\n return `${field}Translations`;\n}\n\n/**\n * One piece of merchant copy, in the buyer's locale.\n *\n * Exact locale wins (`de-AT`), then its base language (`de`), then the flat\n * field — the same order `customFieldText` resolves in, because a merchant who\n * has learnt one of these should not have to learn the other.\n *\n * Returning the flat value rather than `''` is the backward-compatibility\n * guarantee: an override is an addition to what a merchant already wrote, never\n * a replacement for it, so an empty or missing map changes nothing.\n */\nexport function checkoutCopy(\n branding: CheckoutBranding,\n field: LocalizableCopyField,\n locale?: string,\n): string {\n const translated = translationFor(branding[copyTranslationsKey(field)], locale);\n return translated ?? branding[field];\n}\n\n/**\n * The merchant's own word for one direction, or `null` to use the checkout's\n * built-in one.\n *\n * `null` rather than a default string because the fallback is *localized* and\n * lives in the buyer-facing bundle — this module has no i18n of its own, and\n * inventing an English default here would print \"Discount\" to a German buyer.\n *\n * A merchant who sets nothing therefore keeps the shipped wording in both\n * languages, which is the intended default and already reads well.\n */\nexport function surchargeWordFor(\n branding: Pick<CheckoutBranding, 'surchargeWordTranslations' | 'discountWordTranslations'>,\n isDiscount: boolean,\n locale?: string,\n): string | null {\n return translationFor(\n isDiscount ? branding.discountWordTranslations : branding.surchargeWordTranslations,\n locale,\n );\n}\n\nexport interface TrustBadge {\n id: string;\n label: string;\n textColor: string;\n backgroundColor: string;\n borderColor: string | null;\n}\n\n// Merchant-defined checkout inputs. Rendered by the buyer-facing checkout\n// above the payment surface; submitted values land in the payment's\n// `metadata` under each field's `key`. Persisted JSON-stringified under\n// `sdk_ui_rules.branding.customFields` (same transport as trustBadges).\n// `checkbox` is a single opt-in box (terms acceptance, marketing consent),\n// not a multi-select. Its submitted value is always the string `'true'` or\n// `'false'` — never absent — so a merchant can tell \"declined\" from \"never\n// asked\" in the payment's metadata, which is what makes it usable as a\n// consent record. See `CHECKBOX_CHECKED` / `isCheckboxChecked`.\nexport type CustomFieldType = 'text' | 'textarea' | 'password' | 'email' | 'select' | 'checkbox';\n\n// Per-locale overrides ('de', 'en', …). Missing locale falls back to the\n// default-language string on the field itself — see `customFieldText`.\nexport type CustomFieldTranslations = Record<string, string>;\n\nexport interface CustomFieldOption {\n value: string;\n label: string;\n labelTranslations: CustomFieldTranslations;\n}\n\n// --- Conditional visibility ---------------------------------------------\n//\n// A field can be gated on facts the payment already carries when the\n// checkout renders: the intent's `metadata` (which a shop integration fills\n// per product/category — see the WordPress plugin's product metadata), its\n// `currency`, or its `amount`. This is what lets one profile serve a\n// \"Windows key\" order (no fields) and a \"Spotify account\" order (login\n// fields) without two shops.\n//\n// Evaluation is authoritative on the **backend**: `form_payment_link_data`\n// drops non-matching fields from the payload the buyer's browser receives,\n// so merchant metadata never leaves the server and the rules can't be\n// tampered with client-side. The implementation here is the shared\n// specification (and drives the control-center's builder); the Rust mirror\n// in `crates/router/src/core/payment_link/custom_fields.rs` must stay\n// behaviorally identical.\nexport type CustomFieldConditionSource = 'metadata' | 'currency' | 'amount';\n\n// String operators apply to metadata + currency; numeric ones (`gt`…`lte`)\n// apply to amount and to metadata values that parse as numbers.\nexport type CustomFieldOperator =\n | 'equals'\n | 'not_equals'\n | 'contains'\n | 'not_contains'\n | 'starts_with'\n | 'ends_with'\n | 'in'\n | 'not_in'\n | 'exists'\n | 'not_exists'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte';\n\nexport interface CustomFieldCondition {\n // Stable identity for editor list operations (reorder/remove). Not part\n // of the semantics.\n id: string;\n source: CustomFieldConditionSource;\n // Metadata key to read. Ignored (and persisted empty) for currency/amount.\n key: string;\n operator: CustomFieldOperator;\n // Right-hand operand. `in`/`not_in` read it as a comma-separated list;\n // `exists`/`not_exists` ignore it; amount comparisons parse it as an\n // integer in the currency's minor unit (1000 = 10.00).\n value: string;\n}\n\nexport interface CustomFieldVisibility {\n // `always` — unconditional (the default, and what every pre-feature field\n // decodes to). `match` — evaluate `conditions`.\n mode: 'always' | 'match';\n // How to combine multiple conditions.\n match: 'all' | 'any';\n conditions: CustomFieldCondition[];\n}\n\nexport interface CheckoutCustomField {\n // Stable identity for editor list operations (reorder/remove).\n id: string;\n // Metadata key the submitted value is stored under. Must be unique per\n // profile; the editor enforces `CUSTOM_FIELD_KEY_PATTERN`.\n key: string;\n type: CustomFieldType;\n // Default-language copy; `*Translations` maps override per locale.\n label: string;\n labelTranslations: CustomFieldTranslations;\n placeholder: string;\n placeholderTranslations: CustomFieldTranslations;\n helpText: string;\n helpTextTranslations: CustomFieldTranslations;\n required: boolean;\n // Disabled fields stay configured but are neither rendered nor submitted.\n enabled: boolean;\n // Length bounds apply to text/textarea/password/email; null = unbounded.\n minLength: number | null;\n maxLength: number | null;\n // Prefill for text-like fields; for selects, the option `value` selected\n // initially (empty = placeholder \"choose\" state).\n defaultValue: string;\n // Select choices; ignored for other types.\n options: CustomFieldOption[];\n // Conditional display. Always populated by the decoder — fields without a\n // persisted rule decode to `{ mode: 'always', … }`.\n visibility: CustomFieldVisibility;\n}\n\nexport interface CheckoutBranding {\n // Brand identity\n displayName: string;\n logoUrl: string;\n tagline: string;\n showLogo: boolean;\n logoShape: LogoShape;\n logoSize: LogoSize;\n\n // Color tokens\n primary: string;\n background: string;\n surface: string;\n text: string;\n heading: string;\n muted: string;\n border: string;\n accentText: string;\n buttonBackground: string;\n buttonText: string;\n\n // Typography\n fontFamily: FontFamily;\n headingWeight: FontWeight;\n\n // Shape — granular per-element. Surfaces & inputs use a narrower union\n // (no pill) because pill cards/inputs are always wrong; button and badge\n // keep the full `CornerRadius` since pill is a legitimate look there.\n radiusSurface: NonPillRadius;\n radiusInput: NonPillRadius;\n radiusButton: CornerRadius;\n radiusBadge: CornerRadius;\n surfaceStyle: SurfaceStyle;\n\n // Spacing — four independent dimensions.\n surfacePadding: SpacingScale;\n verticalGap: SpacingScale;\n inputSize: SizeScale;\n buttonSize: SizeScale;\n\n // Layout\n layout: LayoutStyle;\n summaryPosition: SummaryPosition;\n showOrderSummary: boolean;\n summaryGradient: boolean;\n showTotal: boolean;\n totalLabel: string;\n showCurrencyCode: boolean;\n showOrderItems: boolean;\n\n // Provider surcharge / discount disclosure. `showSurcharge` false hides the\n // per-tile figure entirely; the in-pane breakdown is unaffected, since that\n // one is the merchant's existing legal disclosure rather than a steering\n // signal. The two colours are separate on purpose: a surcharge and a discount\n // are opposite news for the buyer and reading them in one colour is exactly\n // the mistake a minus sign is easy to miss in.\n showSurcharge: boolean;\n surchargePosition: SurchargePosition;\n surchargeStyle: SurchargeStyle;\n surchargeSize: SurchargeSize;\n surchargeShape: SurchargeShape;\n surchargeBorderWidth: SurchargeBorderWidth;\n surchargeBorderStyle: SurchargeBorderStyle;\n surchargeWeight: SurchargeWeight;\n surchargeSign: SurchargeSign;\n surchargeUppercase: boolean;\n surchargeLabel: SurchargeLabelMode;\n surchargeFigure: SurchargeFigureMode;\n discountFigure: SurchargeFigureMode;\n surchargeWordTranslations: CustomFieldTranslations;\n discountWordTranslations: CustomFieldTranslations;\n surchargeColor: string;\n discountColor: string;\n\n // Trust badges (fully customizable; empty = hide row).\n trustBadges: TrustBadge[];\n\n // Merchant-defined checkout inputs (empty = no custom fields section).\n customFields: CheckoutCustomField[];\n\n // Copy. All of these are optional in the persisted form: empty string\n // means \"unset\" and consumers should fall back (e.g. payButtonLabel falls\n // back to a localized \"Pay $X\" string).\n headerText: string;\n headerTextTranslations: CustomFieldTranslations;\n payButtonLabel: string;\n payButtonLabelTranslations: CustomFieldTranslations;\n cardTermsMessage: string;\n cardTermsMessageTranslations: CustomFieldTranslations;\n footerText: string;\n footerTextTranslations: CustomFieldTranslations;\n supportEmail: string;\n\n // Stripe Elements behavior. `paymentLayout` only affects what's painted\n // inside Stripe's iframe; non-Stripe connector panes stack vertically\n // regardless. `labelStyle` is also Stripe-iframe scope.\n paymentLayout: PaymentLayout;\n labelStyle: LabelStyle;\n\n // Footer\n showPoweredBy: boolean;\n\n // Advanced — raw CSS appended after brand-token CSS variables are\n // applied, so its declarations win cascade order. Sanitized at render\n // time (see `sanitizeCustomCss`); persisted as-typed under\n // `sdk_ui_rules.branding.customCss`.\n customCss: string;\n}\n\n// --- Token maps ---------------------------------------------------------\n\n// Self-hostable font stacks. The buyer-facing checkout bundles these via\n// @fontsource* packages; the variable-font names ('Inter Variable', …) are\n// listed first so the smaller variable file is preferred when bundled.\nconst FONT_STACKS: Record<FontFamily, string> = {\n inter: \"'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif\",\n system:\n \"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif\",\n serif: \"Georgia, 'Times New Roman', serif\",\n mono: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',\n roboto: \"'Roboto', system-ui, sans-serif\",\n poppins: \"'Poppins', system-ui, sans-serif\",\n manrope: \"'Manrope Variable', 'Manrope', system-ui, sans-serif\",\n 'dm-sans': \"'DM Sans Variable', 'DM Sans', system-ui, sans-serif\",\n 'space-grotesk': \"'Space Grotesk Variable', 'Space Grotesk', system-ui, sans-serif\",\n 'plex-sans': \"'IBM Plex Sans', system-ui, sans-serif\",\n 'work-sans': \"'Work Sans Variable', 'Work Sans', system-ui, sans-serif\",\n 'open-sans': \"'Open Sans Variable', 'Open Sans', system-ui, sans-serif\",\n lora: \"'Lora Variable', 'Lora', Georgia, serif\",\n playfair: \"'Playfair Display Variable', 'Playfair Display', Georgia, serif\",\n 'plex-mono': \"'IBM Plex Mono', ui-monospace, monospace\",\n 'jetbrains-mono': \"'JetBrains Mono Variable', 'JetBrains Mono', ui-monospace, monospace\",\n};\n\nconst RADIUS_PX: Record<CornerRadius, string> = {\n square: '0px',\n small: '6px',\n medium: '12px',\n large: '20px',\n pill: '999px',\n};\n\nconst FONT_WEIGHT_NUMERIC: Record<FontWeight, string> = {\n regular: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n};\n\nconst SURFACE_PAD: Record<SpacingScale, string> = {\n compact: '1rem',\n comfortable: '1.5rem',\n spacious: '2rem',\n};\n\nconst VERTICAL_GAP: Record<SpacingScale, string> = {\n compact: '0.75rem',\n comfortable: '1rem',\n spacious: '1.5rem',\n};\n\nconst INPUT_PAD: Record<SizeScale, string> = {\n sm: '0.5rem 0.75rem',\n md: '0.625rem 0.75rem',\n lg: '0.875rem 0.875rem',\n};\n\nconst BUTTON_PAD: Record<SizeScale, string> = {\n sm: '0.625rem 1rem',\n md: '0.875rem 1.25rem',\n lg: '1.125rem 1.5rem',\n};\n\nexport function fontStack(family: FontFamily): string {\n return FONT_STACKS[family] ?? FONT_STACKS.inter;\n}\n\nexport function radiusValue(radius: CornerRadius): string {\n return RADIUS_PX[radius] ?? RADIUS_PX.medium;\n}\n\nexport function fontWeightValue(weight: FontWeight): string {\n return FONT_WEIGHT_NUMERIC[weight] ?? '600';\n}\n\nexport function surfacePadValue(scale: SpacingScale): string {\n return SURFACE_PAD[scale] ?? SURFACE_PAD.comfortable;\n}\n\nexport function verticalGapValue(scale: SpacingScale): string {\n return VERTICAL_GAP[scale] ?? VERTICAL_GAP.comfortable;\n}\n\nexport function inputPadValue(size: SizeScale): string {\n return INPUT_PAD[size] ?? INPUT_PAD.md;\n}\n\nexport function buttonPadValue(size: SizeScale): string {\n return BUTTON_PAD[size] ?? BUTTON_PAD.md;\n}\n\nexport function logoDimensions(size: LogoSize): { px: number; radius: number } {\n switch (size) {\n case 'sm':\n return { px: 36, radius: 8 };\n case 'lg':\n return { px: 64, radius: 16 };\n case 'md':\n default:\n return { px: 48, radius: 12 };\n }\n}\n\nconst HEX_RE = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/;\n\nexport function isHexColor(value: string): boolean {\n return HEX_RE.test(value.trim());\n}\n\n/**\n * A CSS `<hex-color>`: whole token, leading `#` REQUIRED.\n *\n * ⚠️ The `#` is not pedantry here. `applyBrandingVariables` writes branding\n * values into custom properties unchanged (`el.style.setProperty(k, v)`), and\n * a custom property accepts any token stream — it is only interpreted when\n * substituted into a typed property, where `000` is not a colour and the\n * declaration is dropped. So a contrast API that accepted `'000'` would hand\n * back `21` for a pair that renders as nothing at all: approving a palette\n * that never reaches the screen is worse than refusing to judge it.\n */\nconst CSS_HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\n/**\n * The same shape with the `#` optional, for {@link isDarkSurface} ONLY.\n *\n * That function has stripped an optional hash since it was written, and\n * `'5a5a5a'` is a real colour whose answer is correct — tightening it onto the\n * CSS form would answer correct input wrongly. New API does not inherit the\n * tolerance; the existing caller keeps it.\n */\nconst LENIENT_HEX_RE = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\n/** `[r, g, b]` in 0–255, or `null` when the token is not a colour. */\nfunction parseHexChannels(value: string, pattern: RegExp): [number, number, number] | null {\n const match = pattern.exec(value.trim());\n if (!match) return null;\n const digits = match[1] as string;\n const full =\n digits.length === 3\n ? digits\n .split('')\n .map((c) => c + c)\n .join('')\n : digits;\n return [\n parseInt(full.slice(0, 2), 16),\n parseInt(full.slice(2, 4), 16),\n parseInt(full.slice(4, 6), 16),\n ];\n}\n\n/** WCAG 2.1 relative luminance (1.4.3), with the sRGB linearisation. */\nfunction relativeLuminance([r, g, b]: [number, number, number]): number {\n const [lr, lg, lb] = [r, g, b].map((channel) => {\n const c = channel / 255;\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n }) as [number, number, number];\n return 0.2126 * lr + 0.7152 * lg + 0.0722 * lb;\n}\n\n/** Minimum contrast for body text — WCAG 2.1 success criterion 1.4.3. */\nexport const WCAG_AA_TEXT = 4.5;\n\n/**\n * Minimum contrast for non-text UI — WCAG 2.1 success criterion 1.4.11.\n * Focus rings, borders, icons carrying meaning.\n */\nexport const WCAG_AA_UI = 3;\n\n/**\n * WCAG 2.1 contrast ratio between two colours, 1–21. Order does not matter.\n *\n * Compare against {@link WCAG_AA_TEXT} or {@link WCAG_AA_UI}:\n *\n * ```ts\n * const ratio = contrastRatio(branding.surface, branding.text);\n * if (ratio === null || ratio < WCAG_AA_TEXT) useDefaultPalette();\n * ```\n *\n * ⚠️ Returns `null` — never a number — when either colour cannot be parsed.\n * That is the load-bearing part of this signature. Every colour bug this API\n * exists to prevent came from a helper answering with a plausible value for\n * something it could not read, and a `0` or a `21` here would be silently\n * believed by exactly the branch that is deciding whether text is legible.\n *\n * Accepts `#rgb` and `#rrggbb` — a CSS `<hex-color>`. ⚠️ A hash-less token is\n * `null`, not a ratio: `applyBrandingVariables` writes branding values into\n * custom properties verbatim, so `'000'` reaches CSS as something that is not a\n * colour. Returning `21` for it would approve a palette that never renders.\n * ({@link isDarkSurface} keeps its historical hash-less tolerance; this is new\n * API and does not inherit it.)\n */\nexport function contrastRatio(a: string, b: string): number | null {\n const first = parseHexChannels(a, CSS_HEX_RE);\n const second = parseHexChannels(b, CSS_HEX_RE);\n if (!first || !second) return null;\n const [x, y] = [relativeLuminance(first), relativeLuminance(second)];\n const lighter = Math.max(x, y);\n const darker = Math.min(x, y);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Crude perceived-luminance check — picks the right Stripe Elements preset\n * (`'night'` vs `'stripe'`) when the merchant has a dark surface.\n *\n * ⚠️ **This is not a readability test. Use {@link contrastRatio} for that.**\n * It is a YIQ luma split at 128, and on real brand colours its verdict and\n * actual legibility are not merely imprecise relative to each other — they can\n * be anti-correlated:\n *\n * | colour | `isDarkSurface` | vs white | |\n * | --- | --- | --- | --- |\n * | `#ff00ff` | `true` | 3.14:1 | fails AA text |\n * | `#00ff00` | `false` | 1.37:1 | fails AA text |\n * | `#0000ff` | `true` | 8.59:1 | passes |\n *\n * A caller picking text colour from this gets the wrong answer on both failing\n * cases. It is kept because choosing a Stripe preset is a legitimate and\n * different question.\n *\n * Inputs that are not a 3-/6-digit hex fall through to \"light\", the safer\n * assumption for the default palette.\n */\nexport function isDarkSurface(color: string): boolean {\n // ⚠️ Was a length check plus `parseInt` plus `Number.isNaN`, which let six\n // values the package's own validator rejects through as \"dark\" — `parseInt`\n // accepts a valid prefix, so `parseInt('0g', 16)` is `0`, not `NaN`. The\n // comment above already promised these fall through to \"light\"; now they do.\n const channels = parseHexChannels(color, LENIENT_HEX_RE);\n if (!channels) return false;\n const [r, g, b] = channels;\n const luma = (r * 299 + g * 587 + b * 114) / 1000;\n return luma < 128;\n}\n\n// --- Defaults -----------------------------------------------------------\n\n// Light-mode DeloPay-branded baseline. Hex values come straight from\n// `design-guidelines/colors.md`:\n// - #1E4FEB is `--color-dp-blue`, the wordmark/icon brand blue\n// - #0A1130 is `--color-dp-blue-dark`, the wordmark navy\n// - the rest are slate-50 / slate-200 / slate-500 / slate-800 from the\n// design system's neutral ramp.\n// Picked for: high contrast, neutral surroundings, brand-blue accents,\n// confident navy CTA. Reads \"fintech\" without feeling cold.\nconst LIGHT_PALETTE = {\n primary: '#1E4FEB',\n background: '#f8fafc',\n surface: '#ffffff',\n text: '#1e293b',\n heading: '#0A1130',\n muted: '#64748b',\n border: '#e2e8f0',\n accentText: '#1E4FEB',\n buttonBackground: '#0A1130',\n buttonText: '#ffffff',\n} as const;\n\nexport const DEFAULT_BADGES: TrustBadge[] = [\n {\n id: 'secure',\n label: 'Secure',\n textColor: '#047857',\n backgroundColor: '#ecfdf5',\n borderColor: '#a7f3d0',\n },\n {\n id: 'ssl',\n label: '256-bit SSL',\n textColor: '#1E4FEB',\n backgroundColor: '#eff6ff',\n borderColor: '#bfdbfe',\n },\n];\n\n// Dark-mode equivalents of DEFAULT_BADGES. Dark trust chips need solid hex\n// (the form's color picker only accepts hex), so we pick the design system's\n// success-900 / info-900 backdrops paired with their *-400 foreground tokens.\nexport const DEFAULT_BADGES_DARK: TrustBadge[] = [\n {\n id: 'secure',\n label: 'Secure',\n textColor: '#34d399',\n backgroundColor: '#064e3b',\n borderColor: '#065f46',\n },\n {\n id: 'ssl',\n label: '256-bit SSL',\n textColor: '#60a5fa',\n backgroundColor: '#172554',\n borderColor: '#1e40af',\n },\n];\n\nconst DEFAULT_BRANDING_BASE: Omit<\n CheckoutBranding,\n keyof typeof LIGHT_PALETTE | 'trustBadges' | 'customFields'\n> = {\n displayName: '',\n logoUrl: '',\n tagline: '',\n // Logo + summary gradient OFF by default — an unconfigured DeloPay\n // checkout reads cleaner without a placeholder logo block, and the\n // gradient implies a primary tint the merchant hasn't yet picked.\n showLogo: false,\n logoShape: 'rounded',\n logoSize: 'md',\n\n fontFamily: 'inter',\n headingWeight: 'semibold',\n\n radiusSurface: 'medium',\n radiusInput: 'medium',\n radiusButton: 'medium',\n radiusBadge: 'pill',\n surfaceStyle: 'elevated',\n surfacePadding: 'comfortable',\n verticalGap: 'comfortable',\n inputSize: 'md',\n buttonSize: 'md',\n\n // Disclosure on by default: with provider-scoped pricing the tile is where\n // the buyer chooses between prices, and a price they cannot see is one they\n // find out about on the statement.\n showSurcharge: true,\n surchargePosition: 'trailing',\n surchargeStyle: 'badge',\n surchargeSize: 'sm',\n surchargeShape: 'pill',\n surchargeBorderWidth: 'thin',\n surchargeBorderStyle: 'solid',\n surchargeWeight: 'medium',\n surchargeSign: 'always',\n surchargeUppercase: false,\n // Named, not bare. A tile that reads \"-EUR 2.50\" beside a brand name is a\n // number with no subject — buyers read it as the price, not as a change to\n // it. \"Discount -EUR 2.50\" needs no interpreting, and the word is what makes\n // the default configuration legible without the merchant touching anything.\n surchargeLabel: 'labelled',\n // The two directions default differently on purpose, which is the whole\n // reason they are two settings. A fee is something a buyer acts on in money,\n // so it leads with money and says nothing else. A saving is something worth\n // advertising, and the share is the persuasive half of it — \"-5.1% (EUR\n // 2.50)\" sells what \"-EUR 2.50\" merely states, and the amount is still right\n // there beside it.\n surchargeFigure: 'amount',\n discountFigure: 'percentThenAmount',\n // Empty: the checkout's own localized words are the default, in every\n // language it ships. A merchant fills these in only to say it differently.\n surchargeWordTranslations: {},\n discountWordTranslations: {},\n // amber-700 / emerald-700, not the 600s: the `plain` style renders the\n // disclosure as coloured TEXT, so it is bound by `WCAG_AA_TEXT` (4.5) rather\n // than by the 3:1 a coloured shape would be, and the 600s come to 3.19 and\n // 3.77 against the default white surface. These are 5.02 and 5.48, pinned by\n // tests. Far enough apart to read as opposite news at a glance rather than as\n // two shades of \"extra\".\n surchargeColor: '#b45309',\n discountColor: '#047857',\n\n layout: 'split',\n summaryPosition: 'left',\n showOrderSummary: true,\n summaryGradient: false,\n showTotal: true,\n totalLabel: 'Total',\n showCurrencyCode: false,\n showOrderItems: true,\n\n // Each flat field keeps its meaning: what the merchant wrote, used in every\n // locale that carries no override. Empty maps therefore change nothing for a\n // profile saved before translations existed.\n headerText: '',\n headerTextTranslations: {},\n payButtonLabel: '',\n payButtonLabelTranslations: {},\n cardTermsMessage: '',\n cardTermsMessageTranslations: {},\n footerText: '',\n footerTextTranslations: {},\n supportEmail: '',\n\n paymentLayout: 'tabs',\n labelStyle: 'above',\n showPoweredBy: true,\n\n customCss: '',\n};\n\nexport const DEFAULT_BRANDING: CheckoutBranding = {\n ...DEFAULT_BRANDING_BASE,\n ...LIGHT_PALETTE,\n trustBadges: DEFAULT_BADGES.map((b) => ({ ...b })),\n customFields: [],\n};\n\n// Dark counterpart to DEFAULT_BRANDING. Same form-only fields stay empty\n// (logo / display name / tagline / copy) — only visual tokens diverge.\n// Palette mirrors the design-guidelines dark ramp:\n// - background = slate-950, surface = slate-900 → soft contrast.\n// - text = slate-200, heading = slate-50 → AA+ contrast on the surface.\n// - muted = slate-400, border = slate-800 → chrome that fades into the bg.\n// - accentText = primary-400, button bg = brand blue → brand pops on dark\n// where the light theme's near-black navy CTA would disappear.\n// - surfaceStyle = 'flat' because soft drop-shadows don't read on dark\n// surfaces; the existing 'elevated' shadow tokens are tuned for light.\nexport const DEFAULT_BRANDING_DARK: CheckoutBranding = {\n ...DEFAULT_BRANDING_BASE,\n primary: '#1E4FEB',\n background: '#020617',\n surface: '#0f172a',\n text: '#e2e8f0',\n heading: '#f8fafc',\n muted: '#94a3b8',\n border: '#1e293b',\n accentText: '#60a5fa',\n buttonBackground: '#1E4FEB',\n buttonText: '#ffffff',\n surfaceStyle: 'flat',\n // amber-400 / emerald-400: the 700s above are far too dark to read on\n // slate-900, and this pair is the same news in the same order at the light\n // end of the ramp — 10.69 and 9.29 against the dark surface, also pinned.\n surchargeColor: '#fbbf24',\n discountColor: '#34d399',\n trustBadges: DEFAULT_BADGES_DARK.map((b) => ({ ...b })),\n customFields: [],\n};\n\n// Back-compat alias. Prefer `DEFAULT_BRANDING` directly.\nexport function defaultBranding(): CheckoutBranding {\n return cloneBranding(DEFAULT_BRANDING);\n}\n\n// Deep-ish clone — needed because the form mutates state reactively and we\n// don't want shared TrustBadge / CheckoutCustomField object refs across the\n// loaded/edit/default snapshots. Spread is shallow; array elements would\n// otherwise be shared between snapshots, breaking reset.\nexport function cloneBranding(b: CheckoutBranding): CheckoutBranding {\n return {\n ...b,\n trustBadges: b.trustBadges.map((badge) => ({ ...badge })),\n customFields: b.customFields.map(cloneCustomField),\n // Copied, not shared. A spread alone would leave the clone pointing at the\n // original's maps, and the dashboard edits a clone precisely so the form\n // can be abandoned without touching what is saved.\n surchargeWordTranslations: { ...b.surchargeWordTranslations },\n discountWordTranslations: { ...b.discountWordTranslations },\n headerTextTranslations: { ...b.headerTextTranslations },\n payButtonLabelTranslations: { ...b.payButtonLabelTranslations },\n cardTermsMessageTranslations: { ...b.cardTermsMessageTranslations },\n footerTextTranslations: { ...b.footerTextTranslations },\n };\n}\n\nexport function cloneCustomField(f: CheckoutCustomField): CheckoutCustomField {\n return {\n ...f,\n labelTranslations: { ...f.labelTranslations },\n placeholderTranslations: { ...f.placeholderTranslations },\n helpTextTranslations: { ...f.helpTextTranslations },\n options: f.options.map((o) => ({ ...o, labelTranslations: { ...o.labelTranslations } })),\n visibility: {\n ...f.visibility,\n conditions: f.visibility.conditions.map((c) => ({ ...c })),\n },\n };\n}\n\n// --- Sanitizer ----------------------------------------------------------\n\n// Hard cap on the persisted custom CSS payload. Mirrors the editor's\n// validation; oversized input is dropped to null rather than truncated,\n// since a half-truncated rule is worse than no rule.\nexport const CUSTOM_CSS_MAX_LENGTH = 50_000;\n\n// Strip CSS tokens that turn a stylesheet into a delivery vector before\n// handing the merchant's input to the renderer. The list isn't exhaustive\n// — it's the everyday surface area:\n//\n// - `</style` would let injected text break out of the <style> block and\n// parse as HTML/JS. Replaced with a benign token (not removed) so\n// `</styled-tag` (unlikely but possible inside a content: string)\n// doesn't silently merge into surrounding text.\n// - `@import` would let the merchant pull in a remote stylesheet on\n// every buyer page-load (analytics by side-channel; possible buyer-IP\n// leak).\n// - `expression(…)` was a legacy IE construct that ran JS from CSS.\n// - `behavior:` and `-moz-binding:` ditto for IE/old-Gecko.\n// - `javascript:` URLs in url(...) execute on resource load in some\n// browsers/contexts.\n//\n// Anything else passes through. The merchant can still write whatever\n// declarations they like (background images, gradients, transforms,\n// keyframes, container queries, …).\nexport function sanitizeCustomCss(raw: string | null | undefined): string | null {\n if (typeof raw !== 'string') return null;\n const trimmed = raw.trim();\n if (trimmed.length === 0) return null;\n if (trimmed.length > CUSTOM_CSS_MAX_LENGTH) return null;\n\n let out = trimmed;\n out = out.replace(/<\\/style/gi, '<\\\\/style');\n out = out.replace(/@import\\b[^;]*;?/gi, '');\n out = out.replace(/expression\\s*\\(/gi, '/* expression( */');\n out = out.replace(/(^|[^a-z-])behavior\\s*:/gi, '$1/* behavior: */');\n out = out.replace(/-moz-binding\\s*:/gi, '/* -moz-binding: */');\n out = out.replace(/url\\s*\\(\\s*[\"']?\\s*javascript:/gi, 'url(invalid:');\n return out;\n}\n\n// --- Codec --------------------------------------------------------------\n\n// Structural shape the decoder reads. Both `CheckoutDetails` (public buyer\n// payload) and `BusinessPaymentLinkConfig` (merchant config request shape)\n// satisfy this via duck typing — they each fill some of these and leave the\n// rest undefined. `merchant_*` and `seller_*`/`logo` are aliases for the\n// same API field, surfaced under different names by the two payloads.\nexport interface BrandingSource {\n // Identity (one or the other, depending on payload shape)\n merchant_name?: string | null;\n seller_name?: string | null;\n merchant_logo?: string | null;\n logo?: string | null;\n merchant_description?: string | null;\n\n // Visual\n theme?: string | null;\n background_colour?: string | null;\n payment_button_colour?: string | null;\n payment_button_text_colour?: string | null;\n\n // Copy\n payment_form_header_text?: string | null;\n payment_button_text?: string | null;\n custom_message_for_card_terms?: string | null;\n\n // Footer\n branding_visibility?: boolean | null;\n\n // Stripe\n sdk_layout?: string | null;\n payment_form_label_type?: string | null;\n\n // The bag for everything else\n sdk_ui_rules?: Record<string, Record<string, string> | null | undefined> | null;\n}\n\nconst BRANDING_GROUP_KEY = 'branding';\n\nconst ALL_FONT_FAMILIES: readonly FontFamily[] = [\n 'inter',\n 'system',\n 'serif',\n 'mono',\n 'roboto',\n 'poppins',\n 'manrope',\n 'dm-sans',\n 'space-grotesk',\n 'plex-sans',\n 'work-sans',\n 'open-sans',\n 'lora',\n 'playfair',\n 'plex-mono',\n 'jetbrains-mono',\n];\n\nconst ALL_RADII: readonly CornerRadius[] = ['square', 'small', 'medium', 'large', 'pill'];\nconst NON_PILL_RADII: readonly NonPillRadius[] = ['square', 'small', 'medium', 'large'];\n\nfunction pickEnum<T extends string>(value: unknown, allowed: readonly T[], fallback: T): T {\n if (typeof value !== 'string') return fallback;\n return (allowed as readonly string[]).includes(value) ? (value as T) : fallback;\n}\n\nfunction parseBool(value: unknown, fallback: boolean): boolean {\n if (typeof value === 'boolean') return value;\n if (value === 'true') return true;\n if (value === 'false') return false;\n return fallback;\n}\n\nfunction s(value: string | null | undefined): string {\n return typeof value === 'string' ? value : '';\n}\n\n// Decode the JSON-encoded trust badges stored under\n// `sdk_ui_rules.branding.trustBadges`. Tolerant: a malformed payload,\n// missing fields, or wrong types fall through to null so the caller can\n// substitute the default badge set. An explicit empty array means \"no\n// badges\" (we honor it — merchants who hide the row need a way to express\n// that).\nexport function decodeBadges(raw: string | undefined): TrustBadge[] | null {\n if (raw === undefined) return null;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return null;\n return parsed\n .filter((b): b is Record<string, unknown> => !!b && typeof b === 'object')\n .map((b, i) => ({\n id: typeof b['id'] === 'string' && b['id'] ? (b['id'] as string) : `badge-${i}`,\n label: typeof b['label'] === 'string' ? (b['label'] as string) : '',\n textColor: typeof b['textColor'] === 'string' ? (b['textColor'] as string) : '#0f172a',\n backgroundColor:\n typeof b['backgroundColor'] === 'string' ? (b['backgroundColor'] as string) : '#f1f5f9',\n borderColor:\n typeof b['borderColor'] === 'string' && b['borderColor']\n ? (b['borderColor'] as string)\n : null,\n }))\n .filter((b) => b.label.length > 0);\n } catch {\n return null;\n }\n}\n\nexport function encodeBadges(badges: TrustBadge[]): string {\n return JSON.stringify(\n badges.map((b) => ({\n id: b.id,\n label: b.label,\n textColor: b.textColor,\n backgroundColor: b.backgroundColor,\n ...(b.borderColor ? { borderColor: b.borderColor } : {}),\n })),\n );\n}\n\n// --- Custom checkout fields codec ---------------------------------------\n\nexport const CUSTOM_FIELDS_MAX = 20;\n// Metadata keys: start with a letter, then letters/digits/underscore/dash.\n// Keeps keys safe for every downstream metadata consumer (dashboards,\n// exports, PSP forwarding).\nexport const CUSTOM_FIELD_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9_-]{0,39}$/;\n\nexport const ALL_CUSTOM_FIELD_TYPES: readonly CustomFieldType[] = [\n 'text',\n 'textarea',\n 'password',\n 'email',\n 'select',\n 'checkbox',\n];\n\n// The two values a checkbox field ever submits. Kept as strings because the\n// whole metadata bag is `Record<string, string>` on the wire.\nexport const CHECKBOX_CHECKED = 'true';\nexport const CHECKBOX_UNCHECKED = 'false';\n\n/** Whether a stored/submitted checkbox value counts as ticked. Tolerant of\n * case and padding so a value round-tripped through a shop integration\n * ('True', ' true ') still reads correctly. */\nexport function isCheckboxChecked(value: string | null | undefined): boolean {\n return typeof value === 'string' && value.trim().toLowerCase() === CHECKBOX_CHECKED;\n}\n\n/** Types whose value is free text, so length bounds and a placeholder apply.\n * `select` and `checkbox` are choice controls and have neither. */\nexport function customFieldIsTextLike(type: CustomFieldType): boolean {\n return type !== 'select' && type !== 'checkbox';\n}\n\n// Rule-builder vocabulary. Kept next to the codec so the editor, the\n// evaluator and the Rust mirror all read from one list.\nexport const CUSTOM_FIELD_CONDITIONS_MAX = 10;\n\nexport const ALL_CUSTOM_FIELD_CONDITION_SOURCES: readonly CustomFieldConditionSource[] = [\n 'metadata',\n 'currency',\n 'amount',\n];\n\nexport const ALL_CUSTOM_FIELD_OPERATORS: readonly CustomFieldOperator[] = [\n 'equals',\n 'not_equals',\n 'contains',\n 'not_contains',\n 'starts_with',\n 'ends_with',\n 'in',\n 'not_in',\n 'exists',\n 'not_exists',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n];\n\n// Which operators make sense per source. Currency is a closed 3-letter set,\n// so substring/numeric operators would only ever confuse; amount is numeric,\n// so string operators don't apply. Metadata is free-form and gets all of them.\nexport const CUSTOM_FIELD_OPERATORS_BY_SOURCE: Record<\n CustomFieldConditionSource,\n readonly CustomFieldOperator[]\n> = {\n metadata: ALL_CUSTOM_FIELD_OPERATORS,\n currency: ['equals', 'not_equals', 'in', 'not_in'],\n amount: ['equals', 'not_equals', 'gt', 'gte', 'lt', 'lte'],\n};\n\n// Operators that ignore the right-hand operand — the editor hides the value\n// input for these, and validation must not demand a value.\nexport const CUSTOM_FIELD_VALUELESS_OPERATORS: readonly CustomFieldOperator[] = [\n 'exists',\n 'not_exists',\n];\n\nexport function customFieldOperatorTakesValue(operator: CustomFieldOperator): boolean {\n return !CUSTOM_FIELD_VALUELESS_OPERATORS.includes(operator);\n}\n\n// The operator a condition falls back to when its source changes and the\n// current operator isn't valid for the new source.\nexport function defaultOperatorForSource(source: CustomFieldConditionSource): CustomFieldOperator {\n return CUSTOM_FIELD_OPERATORS_BY_SOURCE[source][0] ?? 'equals';\n}\n\nexport function defaultCustomFieldVisibility(): CustomFieldVisibility {\n return { mode: 'always', match: 'all', conditions: [] };\n}\n\nfunction parseTranslations(raw: unknown): CustomFieldTranslations {\n // The branding bag stores every value as a string, so a map persisted there\n // arrives as JSON; an import file and a custom field carry it inline. Both\n // reach this, and a string that is not JSON is simply not a map.\n let value = raw;\n if (typeof value === 'string') {\n try {\n value = JSON.parse(value) as unknown;\n } catch {\n return {};\n }\n }\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {};\n const out: CustomFieldTranslations = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n // Own properties only: a persisted key of `__proto__` or `constructor`\n // must not reach the object being built, and `Object.entries` already\n // gives own enumerable keys only — the length check is what drops a blank\n // override, which means \"no override\" rather than \"render nothing\".\n if (typeof v === 'string' && v.trim().length > 0) out[k] = v;\n }\n return out;\n}\n\n/**\n * A translations map for the branding bag, or `undefined` when there is\n * nothing to store.\n *\n * Omitting the key rather than writing `{}` keeps the bag of a merchant who\n * never opened the translations strip byte-identical to what it was before\n * these fields existed.\n */\nfunction encodeTranslations(map: CustomFieldTranslations): string | undefined {\n const entries = Object.entries(map).filter(([, v]) => v.trim().length > 0);\n return entries.length > 0 ? JSON.stringify(Object.fromEntries(entries)) : undefined;\n}\n\n// Normalize one persisted condition. Total: an unusable source/operator\n// falls back rather than dropping the row, so a rule authored by a newer\n// control-center never silently becomes \"always visible\" on an older\n// decoder — it becomes a stricter, still-evaluable rule.\nfunction normalizeCondition(raw: unknown, index: number): CustomFieldCondition | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const c = raw as Record<string, unknown>;\n const source = pickEnum<CustomFieldConditionSource>(\n c['source'],\n ALL_CUSTOM_FIELD_CONDITION_SOURCES,\n 'metadata',\n );\n const allowed = CUSTOM_FIELD_OPERATORS_BY_SOURCE[source];\n const operator = pickEnum<CustomFieldOperator>(\n c['operator'],\n allowed,\n defaultOperatorForSource(source),\n );\n const rawValue = c['value'];\n return {\n id: typeof c['id'] === 'string' && c['id'] ? (c['id'] as string) : `cond-${index}`,\n source,\n // Only metadata conditions carry a key; drop anything else so the\n // encoded form stays canonical.\n key: source === 'metadata' && typeof c['key'] === 'string' ? c['key'].trim() : '',\n operator,\n value:\n typeof rawValue === 'string'\n ? rawValue\n : typeof rawValue === 'number' || typeof rawValue === 'boolean'\n ? String(rawValue)\n : '',\n };\n}\n\nfunction normalizeVisibility(raw: unknown): CustomFieldVisibility {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return defaultCustomFieldVisibility();\n const v = raw as Record<string, unknown>;\n const conditions: CustomFieldCondition[] = Array.isArray(v['conditions'])\n ? (v['conditions'] as unknown[])\n .slice(0, CUSTOM_FIELD_CONDITIONS_MAX)\n .map(normalizeCondition)\n .filter((c): c is CustomFieldCondition => c !== null)\n : [];\n return {\n mode: pickEnum<'always' | 'match'>(v['mode'], ['always', 'match'], 'always'),\n match: pickEnum<'all' | 'any'>(v['match'], ['all', 'any'], 'all'),\n conditions,\n };\n}\n\nfunction parseBoundedInt(raw: unknown): number | null {\n const n = typeof raw === 'number' ? raw : typeof raw === 'string' ? Number(raw) : NaN;\n if (!Number.isInteger(n) || n < 0) return null;\n return Math.min(n, 5000);\n}\n\n// Normalize one persisted/imported field object. Total: anything malformed\n// falls back per-property; returns null only when there is no usable key.\nfunction normalizeCustomField(raw: unknown, index: number): CheckoutCustomField | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const f = raw as Record<string, unknown>;\n const key = typeof f['key'] === 'string' ? f['key'].trim() : '';\n if (!CUSTOM_FIELD_KEY_PATTERN.test(key)) return null;\n\n const type = pickEnum<CustomFieldType>(f['type'], ALL_CUSTOM_FIELD_TYPES, 'text');\n\n const options: CustomFieldOption[] =\n type === 'select' && Array.isArray(f['options'])\n ? (f['options'] as unknown[])\n .filter((o): o is Record<string, unknown> => !!o && typeof o === 'object')\n .map((o) => {\n const value = typeof o['value'] === 'string' ? o['value'] : '';\n return {\n value,\n label: typeof o['label'] === 'string' && o['label'] ? (o['label'] as string) : value,\n labelTranslations: parseTranslations(o['labelTranslations']),\n };\n })\n .filter((o) => o.value.length > 0)\n : [];\n\n // Length bounds are meaningless for choice controls; drop them at decode\n // so a field switched to checkbox/select can't carry stale bounds that\n // would then be validated against 'true'/'false'.\n const textLike = customFieldIsTextLike(type);\n const minLength = textLike ? parseBoundedInt(f['minLength']) : null;\n const maxLength = textLike ? parseBoundedInt(f['maxLength']) : null;\n\n // A checkbox default is a tick state, not free text: anything that isn't\n // truthy normalizes to unchecked, so the control can never start in a\n // third state.\n const rawDefault = typeof f['defaultValue'] === 'string' ? f['defaultValue'] : '';\n const defaultValue =\n type === 'checkbox'\n ? isCheckboxChecked(rawDefault)\n ? CHECKBOX_CHECKED\n : CHECKBOX_UNCHECKED\n : rawDefault;\n\n return {\n id: typeof f['id'] === 'string' && f['id'] ? (f['id'] as string) : `field-${index}`,\n key,\n type,\n label: typeof f['label'] === 'string' && f['label'] ? (f['label'] as string) : key,\n labelTranslations: parseTranslations(f['labelTranslations']),\n placeholder: typeof f['placeholder'] === 'string' ? (f['placeholder'] as string) : '',\n placeholderTranslations: parseTranslations(f['placeholderTranslations']),\n helpText: typeof f['helpText'] === 'string' ? (f['helpText'] as string) : '',\n helpTextTranslations: parseTranslations(f['helpTextTranslations']),\n required: parseBool(f['required'], false),\n enabled: parseBool(f['enabled'], true),\n minLength,\n // Guard inverted bounds at decode so consumers never see min > max.\n maxLength: maxLength !== null && minLength !== null && maxLength < minLength ? null : maxLength,\n defaultValue,\n options,\n visibility: normalizeVisibility(f['visibility']),\n };\n}\n\n// Parse an array of field objects (already JSON-parsed). Null when the\n// input isn't an array — callers fall back to \"no custom fields\". Duplicate\n// keys keep the first occurrence; the list is capped at CUSTOM_FIELDS_MAX.\nexport function parseCustomFieldsLoose(raw: unknown): CheckoutCustomField[] | null {\n if (!Array.isArray(raw)) return null;\n const seen = new Set<string>();\n const out: CheckoutCustomField[] = [];\n for (let i = 0; i < raw.length && out.length < CUSTOM_FIELDS_MAX; i++) {\n const field = normalizeCustomField(raw[i], i);\n if (!field || seen.has(field.key)) continue;\n seen.add(field.key);\n out.push(field);\n }\n return out;\n}\n\n// Decode the JSON-encoded custom fields stored under\n// `sdk_ui_rules.branding.customFields`. Tolerant like `decodeBadges`:\n// malformed payloads fall through to null.\nexport function decodeCustomFields(raw: string | undefined): CheckoutCustomField[] | null {\n if (raw === undefined) return null;\n try {\n return parseCustomFieldsLoose(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\nexport function encodeCustomFields(fields: CheckoutCustomField[]): string {\n const nonEmpty = (m: CustomFieldTranslations): CustomFieldTranslations | undefined => {\n const entries = Object.entries(m).filter(([, v]) => v.trim().length > 0);\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n };\n return JSON.stringify(\n fields.map((f) => ({\n id: f.id,\n key: f.key,\n type: f.type,\n label: f.label,\n ...(nonEmpty(f.labelTranslations)\n ? { labelTranslations: nonEmpty(f.labelTranslations) }\n : {}),\n ...(f.placeholder ? { placeholder: f.placeholder } : {}),\n ...(nonEmpty(f.placeholderTranslations)\n ? { placeholderTranslations: nonEmpty(f.placeholderTranslations) }\n : {}),\n ...(f.helpText ? { helpText: f.helpText } : {}),\n ...(nonEmpty(f.helpTextTranslations)\n ? { helpTextTranslations: nonEmpty(f.helpTextTranslations) }\n : {}),\n ...(f.required ? { required: true } : {}),\n ...(f.enabled ? {} : { enabled: false }),\n // Length bounds only exist for free-text types; a choice control that\n // still carries them is stale state the decoder would drop anyway.\n ...(customFieldIsTextLike(f.type) && f.minLength !== null ? { minLength: f.minLength } : {}),\n ...(customFieldIsTextLike(f.type) && f.maxLength !== null ? { maxLength: f.maxLength } : {}),\n // A checkbox persists only \"starts ticked\"; unticked is the decoder's\n // default, so writing 'false' would be noise on every such field.\n ...(f.type === 'checkbox'\n ? isCheckboxChecked(f.defaultValue)\n ? { defaultValue: CHECKBOX_CHECKED }\n : {}\n : f.defaultValue\n ? { defaultValue: f.defaultValue }\n : {}),\n ...(f.type === 'select' ? { options: f.options } : {}),\n // Omitted for unconditional fields so the stored blob (and every\n // pre-feature payload) stays byte-identical to what it was.\n ...(f.visibility.mode === 'match' ? { visibility: encodeVisibility(f.visibility) } : {}),\n })),\n );\n}\n\nfunction encodeVisibility(v: CustomFieldVisibility): Record<string, unknown> {\n return {\n mode: v.mode,\n match: v.match,\n conditions: v.conditions.map((c) => ({\n id: c.id,\n source: c.source,\n ...(c.source === 'metadata' && c.key ? { key: c.key } : {}),\n operator: c.operator,\n ...(customFieldOperatorTakesValue(c.operator) && c.value ? { value: c.value } : {}),\n })),\n };\n}\n\n// --- Conditional-visibility evaluator -----------------------------------\n\n/** Facts a rule can read. `amount` is in the currency's minor unit (what\n * the payment intent stores); `metadata` values are already flattened to\n * strings by `customFieldContextFromMetadata`. */\nexport interface CustomFieldContext {\n amount: number;\n currency: string;\n metadata: Record<string, string>;\n}\n\n/** Flatten a payment's raw `metadata` object into the string map a rule\n * compares against. Arrays join on `,` so a list-shaped value stays usable\n * with `contains` / `in`; objects fall back to JSON. Mirrors the Rust\n * side's `flatten_metadata`. */\nexport function customFieldContextFromMetadata(raw: unknown): Record<string, string> {\n const out: Record<string, string> = {};\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return out;\n for (const [key, value] of Object.entries(raw as Record<string, unknown>)) {\n const flat = flattenMetadataValue(value);\n if (flat !== null) out[key] = flat;\n }\n return out;\n}\n\nfunction flattenMetadataValue(value: unknown): string | null {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (value === null || value === undefined) return null;\n if (Array.isArray(value)) {\n return value\n .map((v) => flattenMetadataValue(v))\n .filter((v): v is string => v !== null)\n .join(',');\n }\n try {\n return JSON.stringify(value);\n } catch {\n return null;\n }\n}\n\n// Case- and whitespace-insensitive: merchants type `Windows` in the builder\n// and the shop sends `windows`. Exact-case matching would be a support\n// ticket generator.\nfunction norm(value: string): string {\n return value.trim().toLowerCase();\n}\n\n// Decimal-float grammar, deliberately narrower than `Number()`.\n//\n// `Number()` accepts radix-prefixed literals — `Number('0x10') === 16` — while\n// the router's Rust mirror uses `f64::from_str`, which rejects them. Left\n// unconstrained, a metadata value of `0x10` would satisfy `gte 5` in the\n// control-center's builder and fail it on the backend: the merchant sees one\n// rule, buyers get another. This regex is `f64::from_str`'s number grammar\n// (sign, digits with optional point, optional exponent); `inf`/`nan` are\n// excluded here rather than by the finiteness check below, which matches\n// Rust filtering them out too.\nconst DECIMAL_NUMBER_PATTERN = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?$/;\n\n// Both implementations compare as f64, so they round identically. Payment\n// amounts in minor units are far below 2^53, where that is lossless.\nfunction numeric(value: string): number | null {\n const trimmed = value.trim();\n if (!DECIMAL_NUMBER_PATTERN.test(trimmed)) return null;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : null;\n}\n\nfunction splitList(value: string): string[] {\n return value\n .split(',')\n .map((part) => norm(part))\n .filter((part) => part.length > 0);\n}\n\n/** Resolve the left-hand operand. `undefined` means \"the metadata key is\n * absent\" — which only `exists`/`not_exists` distinguish from empty. */\nfunction operandFor(condition: CustomFieldCondition, ctx: CustomFieldContext): string | undefined {\n switch (condition.source) {\n case 'currency':\n return ctx.currency;\n case 'amount':\n return String(ctx.amount);\n case 'metadata':\n return Object.prototype.hasOwnProperty.call(ctx.metadata, condition.key)\n ? ctx.metadata[condition.key]\n : undefined;\n }\n}\n\nexport function evaluateCustomFieldCondition(\n condition: CustomFieldCondition,\n ctx: CustomFieldContext,\n): boolean {\n const raw = operandFor(condition, ctx);\n const actual = raw ?? '';\n const expected = condition.value;\n\n switch (condition.operator) {\n case 'exists':\n return raw !== undefined && raw.trim().length > 0;\n case 'not_exists':\n return raw === undefined || raw.trim().length === 0;\n case 'equals':\n return norm(actual) === norm(expected);\n case 'not_equals':\n return norm(actual) !== norm(expected);\n case 'contains':\n return norm(actual).includes(norm(expected));\n case 'not_contains':\n return !norm(actual).includes(norm(expected));\n case 'starts_with':\n return norm(actual).startsWith(norm(expected));\n case 'ends_with':\n return norm(actual).endsWith(norm(expected));\n case 'in':\n return splitList(expected).includes(norm(actual));\n case 'not_in':\n return !splitList(expected).includes(norm(actual));\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n // Both sides must be numbers. A non-numeric metadata value never\n // matches a numeric comparison (rather than coercing to 0).\n const a = numeric(actual);\n const b = numeric(expected);\n if (a === null || b === null) return false;\n if (condition.operator === 'gt') return a > b;\n if (condition.operator === 'gte') return a >= b;\n if (condition.operator === 'lt') return a < b;\n return a <= b;\n }\n }\n}\n\n/**\n * Whether a field's rule matches the payment.\n *\n * Fail-open in two spots, deliberately: `mode: 'always'` and a `match` rule\n * with no conditions both resolve to visible. A half-authored rule should\n * never silently swallow a field the merchant needs collected — the\n * control-center flags the empty rule as a validation issue instead.\n */\nexport function evaluateCustomFieldVisibility(\n field: CheckoutCustomField,\n ctx: CustomFieldContext,\n): boolean {\n const { mode, match, conditions } = field.visibility;\n if (mode !== 'match' || conditions.length === 0) return true;\n return match === 'any'\n ? conditions.some((c) => evaluateCustomFieldCondition(c, ctx))\n : conditions.every((c) => evaluateCustomFieldCondition(c, ctx));\n}\n\n/** Filter a field list to what the buyer should see for this payment.\n * Disabled fields are dropped here too — the two reasons a field doesn't\n * render are the same to every consumer. */\nexport function visibleCustomFields(\n fields: CheckoutCustomField[],\n ctx: CustomFieldContext,\n): CheckoutCustomField[] {\n return fields.filter((f) => f.enabled && evaluateCustomFieldVisibility(f, ctx));\n}\n\n// Exact-locale-then-base-language lookup. Own-property + string checks so\n// a hostile or odd locale string ('constructor', '__proto__') can never\n// surface a prototype-chain member as a \"translation\".\nfunction translationFor(map: CustomFieldTranslations, locale?: string): string | null {\n if (!locale) return null;\n const own = (k: string): string | null => {\n const v = Object.prototype.hasOwnProperty.call(map, k) ? map[k] : undefined;\n return typeof v === 'string' && v.length > 0 ? v : null;\n };\n const exact = own(locale);\n if (exact) return exact;\n const base = locale.split('-')[0];\n return base && base !== locale ? own(base) : null;\n}\n\n// Resolve the display string for a field part in a buyer locale.\n// Exact locale wins ('de-AT'), then its base language ('de'), then the\n// field's default-language string; labels finally fall back to the key so\n// a field is never rendered nameless.\nexport function customFieldText(\n field: CheckoutCustomField,\n part: 'label' | 'placeholder' | 'helpText',\n locale?: string,\n): string {\n const map =\n part === 'label'\n ? field.labelTranslations\n : part === 'placeholder'\n ? field.placeholderTranslations\n : field.helpTextTranslations;\n const translated = translationFor(map, locale);\n if (translated) return translated;\n const fallback = field[part];\n if (fallback) return fallback;\n return part === 'label' ? field.key : '';\n}\n\nexport function customFieldOptionLabel(option: CustomFieldOption, locale?: string): string {\n return translationFor(option.labelTranslations, locale) ?? (option.label || option.value);\n}\n\n// Read a branding source into a fully-resolved CheckoutBranding.\n// Flat fields are authoritative when set; the bag fills in everything not\n// reachable via flat columns. Persisted `labelStyle: 'floating'` (legacy\n// \"floating\" mock) decodes to `'above'`.\nexport function decodeBranding(source: BrandingSource | null | undefined): CheckoutBranding {\n if (!source) return cloneBranding(DEFAULT_BRANDING);\n\n const extras: Record<string, string> = (source.sdk_ui_rules?.[BRANDING_GROUP_KEY] ??\n {}) as Record<string, string>;\n\n const decodedBadges = decodeBadges(extras['trustBadges']);\n const decodedCustomFields = decodeCustomFields(extras['customFields']);\n\n // Identity name: public payloads call it `merchant_name`, request payloads\n // call it `seller_name`. Same API field; pick whichever is present.\n const displayName = s(source.merchant_name) || s(source.seller_name);\n const logoUrl = s(source.merchant_logo) || s(source.logo);\n\n // Tagline lives in the bag, but `merchant_description` is its public\n // surface. Either may fill it; bag wins if both are set.\n const tagline = s(extras['tagline']) || s(source.merchant_description);\n\n // Stripe label style: the bag's `labelStyle` is the new source of truth;\n // the legacy flat `payment_form_label_type` is consulted only when the\n // bag is empty. `'floating'` (a legacy preview-only value that Stripe\n // Elements never honored) decodes to `'above'`. `'never'` (legacy API\n // wording) decodes to `'hidden'`.\n const labelStyle: LabelStyle = (() => {\n const fromBag = extras['labelStyle'];\n if (fromBag === 'above' || fromBag === 'hidden') return fromBag;\n if (fromBag === 'floating') return 'above';\n const legacy = source.payment_form_label_type;\n if (legacy === 'above' || legacy === 'floating') return 'above';\n if (legacy === 'hidden' || legacy === 'never') return 'hidden';\n return DEFAULT_BRANDING.labelStyle;\n })();\n\n return {\n displayName,\n logoUrl,\n tagline,\n showLogo: parseBool(extras['showLogo'], DEFAULT_BRANDING.showLogo),\n logoShape: pickEnum<LogoShape>(\n extras['logoShape'],\n ['square', 'rounded', 'circle'],\n DEFAULT_BRANDING.logoShape,\n ),\n logoSize: pickEnum<LogoSize>(extras['logoSize'], ['sm', 'md', 'lg'], DEFAULT_BRANDING.logoSize),\n\n primary: s(source.theme) || DEFAULT_BRANDING.primary,\n background: s(source.background_colour) || DEFAULT_BRANDING.background,\n surface: s(extras['surface']) || DEFAULT_BRANDING.surface,\n text: s(extras['text']) || DEFAULT_BRANDING.text,\n heading: s(extras['heading']) || s(extras['text']) || DEFAULT_BRANDING.heading,\n muted: s(extras['muted']) || DEFAULT_BRANDING.muted,\n border: s(extras['border']) || DEFAULT_BRANDING.border,\n accentText: s(extras['accentText']) || s(source.theme) || DEFAULT_BRANDING.accentText,\n buttonBackground:\n s(source.payment_button_colour) || s(source.theme) || DEFAULT_BRANDING.buttonBackground,\n buttonText: s(source.payment_button_text_colour) || DEFAULT_BRANDING.buttonText,\n\n fontFamily: pickEnum<FontFamily>(\n extras['fontFamily'],\n ALL_FONT_FAMILIES,\n DEFAULT_BRANDING.fontFamily,\n ),\n headingWeight: pickEnum<FontWeight>(\n extras['headingWeight'],\n ['regular', 'medium', 'semibold', 'bold'],\n DEFAULT_BRANDING.headingWeight,\n ),\n\n radiusSurface: pickEnum<NonPillRadius>(\n extras['radiusSurface'],\n NON_PILL_RADII,\n DEFAULT_BRANDING.radiusSurface,\n ),\n radiusInput: pickEnum<NonPillRadius>(\n extras['radiusInput'],\n NON_PILL_RADII,\n DEFAULT_BRANDING.radiusInput,\n ),\n radiusButton: pickEnum<CornerRadius>(\n extras['radiusButton'],\n ALL_RADII,\n DEFAULT_BRANDING.radiusButton,\n ),\n radiusBadge: pickEnum<CornerRadius>(\n extras['radiusBadge'],\n ALL_RADII,\n DEFAULT_BRANDING.radiusBadge,\n ),\n surfaceStyle: pickEnum<SurfaceStyle>(\n extras['surfaceStyle'],\n ['flat', 'outlined', 'elevated'],\n DEFAULT_BRANDING.surfaceStyle,\n ),\n surfacePadding: pickEnum<SpacingScale>(\n extras['surfacePadding'],\n ['compact', 'comfortable', 'spacious'],\n DEFAULT_BRANDING.surfacePadding,\n ),\n verticalGap: pickEnum<SpacingScale>(\n extras['verticalGap'],\n ['compact', 'comfortable', 'spacious'],\n DEFAULT_BRANDING.verticalGap,\n ),\n inputSize: pickEnum<SizeScale>(\n extras['inputSize'],\n ['sm', 'md', 'lg'],\n DEFAULT_BRANDING.inputSize,\n ),\n buttonSize: pickEnum<SizeScale>(\n extras['buttonSize'],\n ['sm', 'md', 'lg'],\n DEFAULT_BRANDING.buttonSize,\n ),\n\n showSurcharge: parseBool(extras['showSurcharge'], DEFAULT_BRANDING.showSurcharge),\n surchargePosition: pickEnum<SurchargePosition>(\n extras['surchargePosition'],\n SURCHARGE_POSITIONS,\n DEFAULT_BRANDING.surchargePosition,\n ),\n surchargeStyle: pickEnum<SurchargeStyle>(\n extras['surchargeStyle'],\n SURCHARGE_STYLES,\n DEFAULT_BRANDING.surchargeStyle,\n ),\n surchargeSize: pickEnum<SurchargeSize>(\n extras['surchargeSize'],\n SURCHARGE_SIZES,\n DEFAULT_BRANDING.surchargeSize,\n ),\n surchargeShape: pickEnum<SurchargeShape>(\n extras['surchargeShape'],\n SURCHARGE_SHAPES,\n DEFAULT_BRANDING.surchargeShape,\n ),\n surchargeBorderWidth: pickEnum<SurchargeBorderWidth>(\n extras['surchargeBorderWidth'],\n SURCHARGE_BORDER_WIDTHS,\n DEFAULT_BRANDING.surchargeBorderWidth,\n ),\n surchargeBorderStyle: pickEnum<SurchargeBorderStyle>(\n extras['surchargeBorderStyle'],\n SURCHARGE_BORDER_STYLES,\n DEFAULT_BRANDING.surchargeBorderStyle,\n ),\n surchargeWeight: pickEnum<SurchargeWeight>(\n extras['surchargeWeight'],\n SURCHARGE_WEIGHTS,\n DEFAULT_BRANDING.surchargeWeight,\n ),\n surchargeSign: pickEnum<SurchargeSign>(\n extras['surchargeSign'],\n SURCHARGE_SIGNS,\n DEFAULT_BRANDING.surchargeSign,\n ),\n surchargeUppercase: parseBool(\n extras['surchargeUppercase'],\n DEFAULT_BRANDING.surchargeUppercase,\n ),\n surchargeLabel: pickEnum<SurchargeLabelMode>(\n extras['surchargeLabel'],\n SURCHARGE_LABEL_MODES,\n DEFAULT_BRANDING.surchargeLabel,\n ),\n surchargeFigure: pickEnum<SurchargeFigureMode>(\n extras['surchargeFigure'],\n SURCHARGE_FIGURE_MODES,\n DEFAULT_BRANDING.surchargeFigure,\n ),\n discountFigure: pickEnum<SurchargeFigureMode>(\n extras['discountFigure'],\n SURCHARGE_FIGURE_MODES,\n DEFAULT_BRANDING.discountFigure,\n ),\n surchargeWordTranslations: parseTranslations(extras['surchargeWordTranslations']),\n discountWordTranslations: parseTranslations(extras['discountWordTranslations']),\n headerTextTranslations: parseTranslations(extras['headerTextTranslations']),\n payButtonLabelTranslations: parseTranslations(extras['payButtonLabelTranslations']),\n cardTermsMessageTranslations: parseTranslations(extras['cardTermsMessageTranslations']),\n footerTextTranslations: parseTranslations(extras['footerTextTranslations']),\n surchargeColor: s(extras['surchargeColor']) || DEFAULT_BRANDING.surchargeColor,\n discountColor: s(extras['discountColor']) || DEFAULT_BRANDING.discountColor,\n\n layout: pickEnum<LayoutStyle>(extras['layout'], ['compact', 'split'], DEFAULT_BRANDING.layout),\n summaryPosition: pickEnum<SummaryPosition>(\n extras['summaryPosition'],\n ['left', 'right'],\n DEFAULT_BRANDING.summaryPosition,\n ),\n showOrderSummary: parseBool(extras['showOrderSummary'], DEFAULT_BRANDING.showOrderSummary),\n summaryGradient: parseBool(extras['summaryGradient'], DEFAULT_BRANDING.summaryGradient),\n showTotal: parseBool(extras['showTotal'], DEFAULT_BRANDING.showTotal),\n totalLabel: s(extras['totalLabel']) || DEFAULT_BRANDING.totalLabel,\n showCurrencyCode: parseBool(extras['showCurrencyCode'], DEFAULT_BRANDING.showCurrencyCode),\n showOrderItems: parseBool(extras['showOrderItems'], DEFAULT_BRANDING.showOrderItems),\n\n trustBadges: decodedBadges ?? DEFAULT_BRANDING.trustBadges.map((b) => ({ ...b })),\n customFields: decodedCustomFields ?? [],\n\n headerText: s(source.payment_form_header_text),\n payButtonLabel: s(source.payment_button_text),\n cardTermsMessage: s(source.custom_message_for_card_terms),\n footerText: s(extras['footerText']),\n supportEmail: s(extras['supportEmail']),\n\n paymentLayout: pickEnum<PaymentLayout>(\n source.sdk_layout,\n ['tabs', 'accordion', 'spaced_accordion'],\n DEFAULT_BRANDING.paymentLayout,\n ),\n labelStyle,\n showPoweredBy: source.branding_visibility !== false,\n\n customCss: s(extras['customCss']),\n };\n}\n\n// Encoded request shape — the union of fields the encoder fills. Compatible\n// with `BusinessPaymentLinkConfig` / `PaymentLinkConfigRequest` via\n// structural typing on the consumer side.\nexport interface EncodedBranding {\n theme: string;\n logo: string | null;\n seller_name: string | null;\n sdk_layout: PaymentLayout;\n payment_button_text: string | null;\n payment_button_colour: string;\n payment_button_text_colour: string;\n background_colour: string;\n payment_form_header_text: string | null;\n payment_form_label_type: 'above' | 'never';\n custom_message_for_card_terms: string | null;\n sdk_ui_rules: Record<string, Record<string, string>>;\n branding_visibility: boolean;\n}\n\n// Encode a CheckoutBranding into the API request shape. `base` is the\n// existing config (if any) -- preserves bag entries the form doesn't surface\n// (other sdk_ui_rules groups, business_specific_configs, etc.) by spreading\n// it through.\n//\n// `TBase` is constrained to `object | null | undefined` (not\n// `Record<string, unknown>`) so consumers can pass interface-typed values\n// directly. TS interfaces don't get an implicit string index signature, so\n// they don't structurally satisfy `Record<string, unknown>` even when their\n// property values would all unify to `unknown` — `object` admits them\n// without forcing a cast at every call site. We only spread the value, so\n// no index-signature semantics are needed at runtime.\nexport function encodeBranding<TBase extends object | null | undefined>(\n branding: CheckoutBranding,\n base?: TBase,\n): EncodedBranding & (TBase extends object ? TBase : Record<string, never>) {\n const trim = (v: string): string | null => {\n const t = v.trim();\n return t.length > 0 ? t : null;\n };\n\n // We only read one property off `base` and structural typing on `object`\n // doesn't permit index access, so go through `unknown` here.\n const existingRules = ((base as unknown as Record<string, unknown> | undefined)?.[\n 'sdk_ui_rules'\n ] ?? {}) as Record<string, Record<string, string>>;\n const extras: Record<string, string> = {\n surface: branding.surface,\n text: branding.text,\n heading: branding.heading,\n muted: branding.muted,\n border: branding.border,\n accentText: branding.accentText,\n fontFamily: branding.fontFamily,\n headingWeight: branding.headingWeight,\n radiusSurface: branding.radiusSurface,\n radiusInput: branding.radiusInput,\n radiusButton: branding.radiusButton,\n radiusBadge: branding.radiusBadge,\n surfaceStyle: branding.surfaceStyle,\n surfacePadding: branding.surfacePadding,\n verticalGap: branding.verticalGap,\n inputSize: branding.inputSize,\n buttonSize: branding.buttonSize,\n showSurcharge: String(branding.showSurcharge),\n surchargePosition: branding.surchargePosition,\n surchargeStyle: branding.surchargeStyle,\n surchargeSize: branding.surchargeSize,\n surchargeShape: branding.surchargeShape,\n surchargeBorderWidth: branding.surchargeBorderWidth,\n surchargeBorderStyle: branding.surchargeBorderStyle,\n surchargeWeight: branding.surchargeWeight,\n surchargeSign: branding.surchargeSign,\n surchargeUppercase: String(branding.surchargeUppercase),\n surchargeLabel: branding.surchargeLabel,\n surchargeFigure: branding.surchargeFigure,\n discountFigure: branding.discountFigure,\n surchargeColor: branding.surchargeColor,\n discountColor: branding.discountColor,\n layout: branding.layout,\n summaryPosition: branding.summaryPosition,\n showOrderSummary: String(branding.showOrderSummary),\n summaryGradient: String(branding.summaryGradient),\n showTotal: String(branding.showTotal),\n totalLabel: branding.totalLabel,\n showCurrencyCode: String(branding.showCurrencyCode),\n showOrderItems: String(branding.showOrderItems),\n showLogo: String(branding.showLogo),\n logoShape: branding.logoShape,\n logoSize: branding.logoSize,\n labelStyle: branding.labelStyle,\n trustBadges: encodeBadges(branding.trustBadges),\n };\n // Omit the key entirely when there are no fields — decode treats a\n // missing entry the same as an empty list, and the bag stays clean for\n // merchants who never touch the feature.\n if (branding.customFields.length > 0) {\n extras['customFields'] = encodeCustomFields(branding.customFields);\n }\n // Localized copy, each written only when the merchant actually set one, so\n // an untouched profile's bag is unchanged by this feature existing.\n for (const key of [\n 'surchargeWordTranslations',\n 'discountWordTranslations',\n 'headerTextTranslations',\n 'payButtonLabelTranslations',\n 'cardTermsMessageTranslations',\n 'footerTextTranslations',\n ] as const) {\n const encoded = encodeTranslations(branding[key]);\n if (encoded) extras[key] = encoded;\n }\n const tagline = trim(branding.tagline);\n if (tagline) extras['tagline'] = tagline;\n const footer = trim(branding.footerText);\n if (footer) extras['footerText'] = footer;\n const support = trim(branding.supportEmail);\n if (support) extras['supportEmail'] = support;\n // Persist raw — sanitization runs at render time so we keep the merchant's\n // input as-typed (preserves comments, whitespace) and let the checkout\n // strip dangerous tokens consistently across all readers.\n const css = trim(branding.customCss);\n if (css) extras['customCss'] = css;\n\n const nextRules: Record<string, Record<string, string>> = {\n ...existingRules,\n [BRANDING_GROUP_KEY]: extras,\n };\n\n // Map `hidden` back to the legacy `never` token the API's label type\n // enum understands. `floating` no longer exists.\n const legacyLabel: 'above' | 'never' = branding.labelStyle === 'hidden' ? 'never' : 'above';\n\n const flatFields: EncodedBranding = {\n theme: branding.primary,\n logo: trim(branding.logoUrl),\n seller_name: trim(branding.displayName),\n sdk_layout: branding.paymentLayout,\n payment_button_text: trim(branding.payButtonLabel),\n payment_button_colour: branding.buttonBackground,\n payment_button_text_colour: branding.buttonText,\n background_colour: branding.background,\n payment_form_header_text: trim(branding.headerText),\n payment_form_label_type: legacyLabel,\n custom_message_for_card_terms: trim(branding.cardTermsMessage),\n sdk_ui_rules: nextRules,\n branding_visibility: branding.showPoweredBy,\n };\n\n // Spread `base` first to preserve fields the encoder doesn't surface\n // (show_card_terms, show_card_form_by_default, hide_card_nickname_field,\n // enable_button_only_on_form_ready, skip_status_screen,\n // transaction_details, background_image, details_layout,\n // custom_message_for_payment_method_types, payment_link_ui_rules,\n // color_icon_card_cvc_error, is_setup_mandate_flow,\n // enabled_saved_payment_method, display_sdk_only,\n // business_specific_configs, domain_name, allowed_domains).\n return {\n ...base,\n ...flatFields,\n } as EncodedBranding & (TBase extends object ? TBase : Record<string, never>);\n}\n\n// --- Import / Export envelope ------------------------------------------\n\n// Versioned envelope used by the merchant control-center's \"Import /\n// Export\" buttons. Bumping `version` is informational; the importer is\n// graceful and accepts any version (or no envelope at all).\nexport const BRANDING_EXPORT_FORMAT = 'delopay-checkout-branding';\nexport const BRANDING_EXPORT_VERSION = 1;\n\nexport interface BrandingExport {\n format: typeof BRANDING_EXPORT_FORMAT;\n version: number;\n exported_at: string;\n branding: CheckoutBranding;\n}\n\nexport function buildBrandingExport(branding: CheckoutBranding): BrandingExport {\n return {\n format: BRANDING_EXPORT_FORMAT,\n version: BRANDING_EXPORT_VERSION,\n exported_at: new Date().toISOString(),\n branding: cloneBranding(branding),\n };\n}\n\n// Resolve arbitrary JSON into a fully-typed CheckoutBranding. Designed to\n// never throw — every field is independently validated against its type\n// and silently falls back to the light-mode default if missing or\n// malformed:\n// - extra fields the form doesn't know about are ignored,\n// - missing fields inherit defaults,\n// - hex colors that fail the regex stay at the default,\n// - enums outside the allowed set fall back,\n// - a payload with no recognizable shape produces DEFAULT_BRANDING.\n//\n// Accepts either a bare CheckoutBranding object or an envelope produced by\n// `buildBrandingExport()`. The caller (the import handler) only needs to\n// catch JSON.parse errors; everything past that point is total.\nexport function parseImportedBranding(raw: unknown): CheckoutBranding {\n // Unwrap the envelope if present. Don't gate on version — bumping it is\n // informational; this function is the migration layer.\n const root: Record<string, unknown> | null =\n isObject(raw) && isObject(raw['branding'])\n ? (raw['branding'] as Record<string, unknown>)\n : isObject(raw)\n ? raw\n : null;\n\n if (!root) return cloneBranding(DEFAULT_BRANDING);\n\n const dflt = DEFAULT_BRANDING;\n const sStr = (v: unknown, fallback: string): string => (typeof v === 'string' ? v : fallback);\n const sHex = (v: unknown, fallback: string): string =>\n typeof v === 'string' && isHexColor(v) ? v : fallback;\n\n const trustBadges =\n parseTrustBadgesLoose(root['trustBadges']) ?? dflt.trustBadges.map((b) => ({ ...b }));\n const customFields = parseCustomFieldsLoose(root['customFields']) ?? [];\n\n // `floating` from older exports normalizes to `above`; see decodeBranding.\n const labelStyle: LabelStyle = (() => {\n const v = root['labelStyle'];\n if (v === 'above' || v === 'hidden') return v;\n return dflt.labelStyle;\n })();\n\n return {\n displayName: sStr(root['displayName'], dflt.displayName),\n logoUrl: sStr(root['logoUrl'], dflt.logoUrl),\n tagline: sStr(root['tagline'], dflt.tagline),\n showLogo: parseBool(root['showLogo'], dflt.showLogo),\n logoShape: pickEnum<LogoShape>(\n root['logoShape'],\n ['square', 'rounded', 'circle'],\n dflt.logoShape,\n ),\n logoSize: pickEnum<LogoSize>(root['logoSize'], ['sm', 'md', 'lg'], dflt.logoSize),\n\n primary: sHex(root['primary'], dflt.primary),\n background: sHex(root['background'], dflt.background),\n surface: sHex(root['surface'], dflt.surface),\n text: sHex(root['text'], dflt.text),\n heading: sHex(root['heading'], dflt.heading),\n muted: sHex(root['muted'], dflt.muted),\n border: sHex(root['border'], dflt.border),\n accentText: sHex(root['accentText'], dflt.accentText),\n buttonBackground: sHex(root['buttonBackground'], dflt.buttonBackground),\n buttonText: sHex(root['buttonText'], dflt.buttonText),\n\n fontFamily: pickEnum<FontFamily>(root['fontFamily'], ALL_FONT_FAMILIES, dflt.fontFamily),\n headingWeight: pickEnum<FontWeight>(\n root['headingWeight'],\n ['regular', 'medium', 'semibold', 'bold'],\n dflt.headingWeight,\n ),\n\n radiusSurface: pickEnum<NonPillRadius>(\n root['radiusSurface'],\n NON_PILL_RADII,\n dflt.radiusSurface,\n ),\n radiusInput: pickEnum<NonPillRadius>(root['radiusInput'], NON_PILL_RADII, dflt.radiusInput),\n radiusButton: pickEnum<CornerRadius>(root['radiusButton'], ALL_RADII, dflt.radiusButton),\n radiusBadge: pickEnum<CornerRadius>(root['radiusBadge'], ALL_RADII, dflt.radiusBadge),\n surfaceStyle: pickEnum<SurfaceStyle>(\n root['surfaceStyle'],\n ['flat', 'outlined', 'elevated'],\n dflt.surfaceStyle,\n ),\n surfacePadding: pickEnum<SpacingScale>(\n root['surfacePadding'],\n ['compact', 'comfortable', 'spacious'],\n dflt.surfacePadding,\n ),\n verticalGap: pickEnum<SpacingScale>(\n root['verticalGap'],\n ['compact', 'comfortable', 'spacious'],\n dflt.verticalGap,\n ),\n inputSize: pickEnum<SizeScale>(root['inputSize'], ['sm', 'md', 'lg'], dflt.inputSize),\n buttonSize: pickEnum<SizeScale>(root['buttonSize'], ['sm', 'md', 'lg'], dflt.buttonSize),\n\n showSurcharge: parseBool(root['showSurcharge'], dflt.showSurcharge),\n surchargePosition: pickEnum<SurchargePosition>(\n root['surchargePosition'],\n SURCHARGE_POSITIONS,\n dflt.surchargePosition,\n ),\n surchargeStyle: pickEnum<SurchargeStyle>(\n root['surchargeStyle'],\n SURCHARGE_STYLES,\n dflt.surchargeStyle,\n ),\n surchargeSize: pickEnum<SurchargeSize>(\n root['surchargeSize'],\n SURCHARGE_SIZES,\n dflt.surchargeSize,\n ),\n surchargeShape: pickEnum<SurchargeShape>(\n root['surchargeShape'],\n SURCHARGE_SHAPES,\n dflt.surchargeShape,\n ),\n surchargeBorderWidth: pickEnum<SurchargeBorderWidth>(\n root['surchargeBorderWidth'],\n SURCHARGE_BORDER_WIDTHS,\n dflt.surchargeBorderWidth,\n ),\n surchargeBorderStyle: pickEnum<SurchargeBorderStyle>(\n root['surchargeBorderStyle'],\n SURCHARGE_BORDER_STYLES,\n dflt.surchargeBorderStyle,\n ),\n surchargeWeight: pickEnum<SurchargeWeight>(\n root['surchargeWeight'],\n SURCHARGE_WEIGHTS,\n dflt.surchargeWeight,\n ),\n surchargeSign: pickEnum<SurchargeSign>(\n root['surchargeSign'],\n SURCHARGE_SIGNS,\n dflt.surchargeSign,\n ),\n surchargeUppercase: parseBool(root['surchargeUppercase'], dflt.surchargeUppercase),\n surchargeLabel: pickEnum<SurchargeLabelMode>(\n root['surchargeLabel'],\n SURCHARGE_LABEL_MODES,\n dflt.surchargeLabel,\n ),\n surchargeFigure: pickEnum<SurchargeFigureMode>(\n root['surchargeFigure'],\n SURCHARGE_FIGURE_MODES,\n dflt.surchargeFigure,\n ),\n discountFigure: pickEnum<SurchargeFigureMode>(\n root['discountFigure'],\n SURCHARGE_FIGURE_MODES,\n dflt.discountFigure,\n ),\n surchargeWordTranslations: parseTranslations(root['surchargeWordTranslations']),\n discountWordTranslations: parseTranslations(root['discountWordTranslations']),\n headerTextTranslations: parseTranslations(root['headerTextTranslations']),\n payButtonLabelTranslations: parseTranslations(root['payButtonLabelTranslations']),\n cardTermsMessageTranslations: parseTranslations(root['cardTermsMessageTranslations']),\n footerTextTranslations: parseTranslations(root['footerTextTranslations']),\n surchargeColor: sHex(root['surchargeColor'], dflt.surchargeColor),\n discountColor: sHex(root['discountColor'], dflt.discountColor),\n\n layout: pickEnum<LayoutStyle>(root['layout'], ['compact', 'split'], dflt.layout),\n summaryPosition: pickEnum<SummaryPosition>(\n root['summaryPosition'],\n ['left', 'right'],\n dflt.summaryPosition,\n ),\n showOrderSummary: parseBool(root['showOrderSummary'], dflt.showOrderSummary),\n summaryGradient: parseBool(root['summaryGradient'], dflt.summaryGradient),\n showTotal: parseBool(root['showTotal'], dflt.showTotal),\n totalLabel: sStr(root['totalLabel'], dflt.totalLabel),\n showCurrencyCode: parseBool(root['showCurrencyCode'], dflt.showCurrencyCode),\n showOrderItems: parseBool(root['showOrderItems'], dflt.showOrderItems),\n\n trustBadges,\n customFields,\n\n headerText: sStr(root['headerText'], dflt.headerText),\n payButtonLabel: sStr(root['payButtonLabel'], dflt.payButtonLabel),\n cardTermsMessage: sStr(root['cardTermsMessage'], dflt.cardTermsMessage),\n footerText: sStr(root['footerText'], dflt.footerText),\n supportEmail: sStr(root['supportEmail'], dflt.supportEmail),\n\n paymentLayout: pickEnum<PaymentLayout>(\n root['paymentLayout'],\n ['tabs', 'accordion', 'spaced_accordion'],\n dflt.paymentLayout,\n ),\n labelStyle,\n showPoweredBy: parseBool(root['showPoweredBy'], dflt.showPoweredBy),\n\n customCss: sStr(root['customCss'], dflt.customCss).slice(0, CUSTOM_CSS_MAX_LENGTH),\n };\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\n// Loose trust-badge parser used by the importer. Unlike `decodeBadges`\n// (which reads the JSON-stringified API bag), this accepts an array of\n// objects directly. Returns null when the input isn't an array — the\n// caller falls back to the default badge set; an explicit empty array is\n// honored.\nfunction parseTrustBadgesLoose(raw: unknown): TrustBadge[] | null {\n if (!Array.isArray(raw)) return null;\n return raw\n .filter(isObject)\n .map((b, i) => ({\n id: typeof b['id'] === 'string' && b['id'] ? (b['id'] as string) : `badge-${i}`,\n label: typeof b['label'] === 'string' ? (b['label'] as string) : '',\n textColor:\n typeof b['textColor'] === 'string' && isHexColor(b['textColor'] as string)\n ? (b['textColor'] as string)\n : '#0f172a',\n backgroundColor:\n typeof b['backgroundColor'] === 'string' && isHexColor(b['backgroundColor'] as string)\n ? (b['backgroundColor'] as string)\n : '#f1f5f9',\n borderColor:\n typeof b['borderColor'] === 'string' && isHexColor(b['borderColor'] as string)\n ? (b['borderColor'] as string)\n : null,\n }))\n .filter((b) => b.label.length > 0);\n}\n\n// --- DOM helpers --------------------------------------------------------\n\n// Write branding tokens onto a target element as CSS custom properties.\n// The buyer-facing checkout sets these on `<html>` so every component sees\n// the same set, including Stripe Elements (indirectly via\n// appearance.variables). The merchant control-center's preview component\n// uses an analogous `--p-*` set with `var(--dp-*, fallback)` indirection so\n// a custom-CSS rule like `:root{--dp-primary:red}` overrides the preview\n// without re-typing the whole brand.\nexport function applyBrandingVariables(el: HTMLElement, b: CheckoutBranding): void {\n const set = (k: string, v: string) => {\n el.style.setProperty(k, v);\n };\n\n set('--dp-primary', b.primary);\n set('--dp-bg', b.background);\n set('--dp-surface', b.surface);\n set('--dp-text', b.text);\n set('--dp-heading', b.heading);\n set('--dp-muted', b.muted);\n set('--dp-border', b.border);\n set('--dp-accent-text', b.accentText);\n set('--dp-btn-bg', b.buttonBackground);\n set('--dp-btn-fg', b.buttonText);\n\n set('--dp-radius-surface', radiusValue(b.radiusSurface));\n set('--dp-radius-input', radiusValue(b.radiusInput));\n set('--dp-radius-button', radiusValue(b.radiusButton));\n set('--dp-radius-badge', radiusValue(b.radiusBadge));\n\n set('--dp-font', fontStack(b.fontFamily));\n set('--dp-heading-weight', fontWeightValue(b.headingWeight));\n\n set('--dp-pad-surface', SURFACE_PAD[b.surfacePadding]);\n set('--dp-gap-vertical', VERTICAL_GAP[b.verticalGap]);\n set('--dp-input-pad', INPUT_PAD[b.inputSize]);\n set('--dp-button-pad', BUTTON_PAD[b.buttonSize]);\n\n // Published whatever `showSurcharge` says: the flag decides whether a figure\n // renders, not what colour it would be, and a stylesheet that reads the\n // variable must not get an empty string when the merchant has one configured.\n set('--dp-surcharge', b.surchargeColor);\n set('--dp-discount', b.discountColor);\n // What `solid` writes ON the fill. Computed here rather than in a stylesheet\n // because CSS cannot ask a colour how light it is, and picking one fixed ink\n // would make either a pale amber or a deep emerald unreadable.\n set('--dp-surcharge-ink', readableInkOn(b.surchargeColor));\n set('--dp-discount-ink', readableInkOn(b.discountColor));\n set('--dp-surcharge-size', SURCHARGE_FONT_SIZE[b.surchargeSize]);\n set('--dp-surcharge-pad', SURCHARGE_PAD[b.surchargeSize]);\n set('--dp-surcharge-radius', SURCHARGE_RADIUS[b.surchargeShape]);\n set('--dp-surcharge-weight', SURCHARGE_FONT_WEIGHT[b.surchargeWeight]);\n // `outline` draws nothing BUT its border, so `none` there would erase the\n // style rather than restyle it — it reads as `thin` instead.\n set(\n '--dp-surcharge-border-width',\n SURCHARGE_BORDER_WIDTH[\n b.surchargeStyle === 'outline' && b.surchargeBorderWidth === 'none'\n ? 'thin'\n : b.surchargeBorderWidth\n ],\n );\n set('--dp-surcharge-border-style', b.surchargeBorderStyle);\n\n set('--dp-shadow', shadowFor(b.surfaceStyle));\n set(\n '--dp-surface-border',\n b.surfaceStyle === 'outlined' ? `1px solid ${b.border}` : '1px solid transparent',\n );\n}\n\nexport function shadowFor(style: SurfaceStyle): string {\n switch (style) {\n case 'elevated':\n return '0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 32px -12px rgba(15, 23, 42, 0.08)';\n case 'outlined':\n case 'flat':\n default:\n return 'none';\n }\n}\n","import { Delopay } from './client';\nimport type { DelopayLogger, RequestExtras } from './client';\nimport { DelopayError } from './error';\nimport type {\n ConfirmSubscriptionRequest,\n ConfirmSubscriptionResponse,\n EpayoutsMethodsResponse,\n PaymentConfirmRequest,\n PaymentMethodListResponse,\n PaymentResponse,\n PaymentUpdateRequest,\n PayseproMethodsResponse,\n RecordCheckoutEventRequest,\n RecordCheckoutEventResponse,\n VaultCollectSessionResponse,\n VaultPaymentMethodRequest,\n VaultPaymentMethodResponse,\n} from './types';\n\n/**\n * A publishable (browser-safe) API key. The template type rejects secret\n * keys (`prd_…` / `snd_…`) at compile time, so a checkout cannot be handed\n * a credential that would reach secret-key routes.\n */\nexport type PublishableKey = `pk_${string}`;\n\n/**\n * Drop any caller-supplied credential headers (case-insensitively), so a\n * route can only ever carry the one credential its family requires — the\n * class's isolation guarantee must hold against per-call `headers` too.\n * Non-credential extras (`Idempotency-Key`, `X-Dp-*`, …) pass through.\n */\nfunction withoutCredentialHeaders(extra?: Record<string, string>): Record<string, string> {\n if (!extra) return {};\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(extra)) {\n const lower = key.toLowerCase();\n if (lower === 'api-key' || lower === 'authorization') continue;\n out[key] = value;\n }\n return out;\n}\n\n/** Drop one header (case-insensitively) from a caller-supplied extras map. */\nfunction withoutHeader(headers: Record<string, string>, name: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === name) continue;\n out[key] = value;\n }\n return out;\n}\n\n/** Configuration for a {@link CheckoutSession}. */\nexport interface CheckoutSessionOptions {\n /** The merchant the payment belongs to. */\n merchantId: string;\n /** The payment this session is about. */\n paymentId: string;\n /**\n * The merchant's publishable key (`pk_prd_…` / `pk_snd_…`), from the\n * checkout payload's `pub_key`. Required for the `/payments/*` and\n * `/payment-methods` calls.\n */\n publishableKey?: PublishableKey;\n /**\n * The payment's client secret, from the checkout payload. Required for\n * every `/payment-link/*` call, and rides along on the payment calls.\n */\n clientSecret?: string;\n /** Override the API base URL (e.g. `/api` behind a same-origin proxy). */\n baseUrl?: string;\n /** Use the sandbox environment. Ignored when `baseUrl` is set. */\n sandbox?: boolean;\n /** Per-request timeout in milliseconds. */\n timeout?: number;\n /** Maximum automatic retries for retryable requests. */\n maxRetries?: number;\n debug?: boolean;\n logger?: DelopayLogger;\n}\n\n/**\n * Buyer-side client for a single hosted-checkout payment.\n *\n * Binds the two browser-safe credentials once — the merchant's publishable\n * key and the payment's client secret — and sends each request with exactly\n * the credential its route expects:\n *\n * - `/payment-link/*` side-channel routes authenticate with\n * `Authorization: Bearer <client_secret>`.\n * - `/payments/*` and `/payment-methods` authenticate with the publishable\n * key in the `api-key` header, with the client secret as query parameter\n * or body field.\n *\n * Neither credential can reach a secret-key route: the publishable key is\n * typed to the `pk_` prefix and the client secret only ever leaves as a\n * bearer token / parameter, never as an `api-key`.\n *\n * @example\n * ```typescript\n * const session = new CheckoutSession({\n * merchantId: checkout.merchant_id,\n * paymentId: checkout.payment_id,\n * publishableKey: checkout.pub_key,\n * clientSecret: checkout.client_secret,\n * });\n * const catalog = await session.payseproMethods('de');\n * ```\n */\nexport class CheckoutSession {\n private readonly client: Delopay;\n private readonly merchantId: string;\n private readonly paymentId: string;\n private readonly publishableKey?: PublishableKey;\n private readonly clientSecret?: string;\n\n constructor(options: CheckoutSessionOptions) {\n this.merchantId = options.merchantId;\n this.paymentId = options.paymentId;\n this.publishableKey = options.publishableKey;\n this.clientSecret = options.clientSecret;\n // Constructed WITHOUT a key: every call attaches its own credential\n // explicitly, so a bearer-authenticated route never carries an api-key\n // header and vice versa.\n this.client = new Delopay('', {\n baseUrl: options.baseUrl,\n sandbox: options.sandbox,\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n debug: options.debug,\n logger: options.logger,\n });\n }\n\n private get linkBase(): string {\n return `/payment-link/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`;\n }\n\n /** Headers for the client-secret bearer routes (`/payment-link/*`). */\n private bearerHeaders(extra?: Record<string, string>): Record<string, string> {\n return {\n ...withoutCredentialHeaders(extra),\n Authorization: `Bearer ${this.requireClientSecret()}`,\n };\n }\n\n /** Headers for the publishable-key routes (`/payments/*`, `/payment-methods`). */\n private pkHeaders(extra?: Record<string, string>): Record<string, string> {\n if (!this.publishableKey) {\n throw new DelopayError('This call requires the publishable key', {\n status: 0,\n code: 'MISSING_CREDENTIAL',\n type: 'invalid_request',\n });\n }\n return { ...withoutCredentialHeaders(extra), 'api-key': this.publishableKey };\n }\n\n private requireClientSecret(): string {\n if (!this.clientSecret) {\n throw new DelopayError('This call requires the payment client secret', {\n status: 0,\n code: 'MISSING_CREDENTIAL',\n type: 'invalid_request',\n });\n }\n return this.clientSecret;\n }\n\n /**\n * The hosted checkout's bootstrap payload for a one-time payment —\n * `CheckoutDetails` while payable, a status view once settled.\n *\n * Deliberately unauthenticated: a `pay_` link bootstraps before any\n * credential exists, so no credential header is ever attached (caller\n * extras are still stripped of credentials). The response is a large\n * discriminated union owned by the consuming checkout, which keeps its\n * own types and runtime gates — hence the loose return type.\n *\n * `theme` is the route's one declared query parameter (a named checkout\n * variant). `locale` travels as `Accept-Language` — the only\n * channel the backend's locale resolution reads; a `?locale=` query is\n * silently ignored by this route.\n *\n * `GET /payment-link/data/{merchantId}/{paymentId}`\n */\n async fetchCheckoutData(\n params?: { locale?: string; theme?: string },\n options?: RequestExtras,\n ): Promise<Record<string, unknown>> {\n return this.client.request(\n 'GET',\n `/payment-link/data/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n query: { theme: params?.theme },\n ...options,\n headers: {\n ...(params?.locale\n ? {\n ...withoutHeader(withoutCredentialHeaders(options?.headers), 'accept-language'),\n 'Accept-Language': params.locale,\n }\n : withoutCredentialHeaders(options?.headers)),\n },\n },\n );\n }\n\n /**\n * The subscription twin of {@link CheckoutSession.fetchCheckoutData}: the\n * bootstrap payload for a `sub_` checkout. Authenticated with the\n * subscription's client secret (construct the session with the `sub_…` id\n * in the `paymentId` slot). `locale` travels as `Accept-Language`, same\n * as {@link CheckoutSession.fetchCheckoutData}.\n *\n * `GET /subscriptions/data/{merchantId}/{subscriptionId}`\n */\n async fetchSubscriptionData(\n params?: { locale?: string },\n options?: RequestExtras,\n ): Promise<Record<string, unknown>> {\n return this.client.request(\n 'GET',\n `/subscriptions/data/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n ...options,\n headers: {\n ...(params?.locale\n ? {\n ...withoutHeader(this.bearerHeaders(options?.headers), 'accept-language'),\n 'Accept-Language': params.locale,\n }\n : this.bearerHeaders(options?.headers)),\n },\n },\n );\n }\n\n /**\n * Report buyer/device signals for rails that never reach\n * `/payments/{id}/confirm` (the Stripe SAQ-A rail: raw cards, Apple Pay,\n * Google Pay). Same telemetry contract as\n * {@link CheckoutSession.recordEvent}: sent with `keepalive: true`, and\n * failures resolve instead of rejecting — signals must never block or\n * break a checkout. Unauthenticated by design.\n *\n * `POST /payment-link/client-signals/{merchantId}/{paymentId}`\n */\n async reportClientSignals(\n params: {\n browser_info?: Record<string, unknown>;\n signals: Record<string, unknown>;\n },\n options?: RequestExtras,\n ): Promise<void> {\n try {\n await this.client.request(\n 'POST',\n `/payment-link/client-signals/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n body: params,\n keepalive: true,\n ...options,\n headers: withoutCredentialHeaders(options?.headers),\n },\n );\n } catch {\n // Telemetry: swallowing is the contract, not an oversight.\n }\n }\n\n /**\n * Confirm a subscription (PayPal approval rail). The client secret is\n * attached automatically; the shop's profile id travels as the\n * `X-Profile-Id` header the subscription routes require.\n *\n * `POST /subscriptions/{subscriptionId}/confirm` (publishable key)\n */\n async confirmSubscription(\n subscriptionId: string,\n profileId: string,\n params: Omit<ConfirmSubscriptionRequest, 'client_secret'>,\n options?: RequestExtras,\n ): Promise<ConfirmSubscriptionResponse> {\n return this.client.request(\n 'POST',\n `/subscriptions/${encodeURIComponent(subscriptionId)}/confirm`,\n {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n // Strip any caller-supplied x-profile-id first (case-insensitively):\n // Fetch folds duplicate headers into `caller, pro_x`, and the\n // subscription routes must see exactly one profile scope.\n headers: {\n ...withoutHeader(this.pkHeaders(options?.headers), 'x-profile-id'),\n 'X-Profile-Id': profileId,\n },\n },\n );\n }\n\n /**\n * The Paysepro rail catalog for the buyer's country.\n *\n * `GET /payment-link/{merchantId}/{paymentId}/paysepro/methods`\n *\n * @param country - Lowercase ISO 3166-1 alpha-2 country code.\n */\n async payseproMethods(\n country: string,\n options?: RequestExtras,\n ): Promise<PayseproMethodsResponse> {\n return this.client.request('GET', `${this.linkBase}/paysepro/methods`, {\n query: { cc: country },\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * The e-Payouts rail catalog for the buyer's country, plus the set of\n * countries that have at least one vendor.\n *\n * `GET /payment-link/{merchantId}/{paymentId}/epayouts/methods`\n *\n * @param country - Lowercase ISO 3166-1 alpha-2 country code.\n */\n async epayoutsMethods(\n country: string,\n options?: RequestExtras,\n ): Promise<EpayoutsMethodsResponse> {\n return this.client.request('GET', `${this.linkBase}/epayouts/methods`, {\n query: { cc: country },\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Record a buyer-side checkout event on the payment's status timeline.\n *\n * Telemetry semantics, built in so callers can genuinely fire-and-forget:\n * the request is sent with `keepalive: true` (it survives the document\n * navigating away, e.g. right before a `window.open`), and transport or\n * server failures resolve to `undefined` instead of rejecting — telemetry\n * must never break a checkout or surface an unhandled rejection. Do not\n * `await` this in a click handler that must stay synchronous.\n *\n * A missing client secret still throws `MISSING_CREDENTIAL`: that is a\n * wiring bug, not a telemetry failure.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/checkout-events`\n */\n async recordEvent(\n params: RecordCheckoutEventRequest,\n options?: RequestExtras,\n ): Promise<RecordCheckoutEventResponse | undefined> {\n const headers = this.bearerHeaders(options?.headers);\n try {\n return await this.client.request('POST', `${this.linkBase}/checkout-events`, {\n body: params,\n keepalive: true,\n ...options,\n headers,\n });\n } catch {\n return undefined;\n }\n }\n\n /**\n * A short-lived VGS Collect session for browser-side card capture.\n *\n * **Exactly one refusal means \"this shop has no vault\": a 400 carrying\n * `IR_19`.** Every other refusal means a vault exists and could not be used,\n * and answering it by falling back to the processor's own card pane sends an\n * unprotected card number to the very processor the shop pays to hide it\n * from — the bug this endpoint's error contract exists to prevent.\n *\n * A **404 is not benign.** The router answers it when the shop's vault\n * account cannot be found — the state a shop is left in when its vault\n * connector is deleted while the profile keeps naming the id: it still\n * reports the vault as enabled and still expects its cards cloaked. The same\n * status also covers a payment that does not exist.\n *\n * `GET /payment-link/{merchantId}/{paymentId}/vault/collect-session`\n */\n async vaultCollectSession(options?: RequestExtras): Promise<VaultCollectSessionResponse> {\n return this.client.request('GET', `${this.linkBase}/vault/collect-session`, {\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Register the aliased card as a payment method and mint the one-shot\n * `payment_token` the confirm call spends.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/vault/payment-method`\n */\n async registerVaultPaymentMethod(\n params: VaultPaymentMethodRequest,\n options?: RequestExtras,\n ): Promise<VaultPaymentMethodResponse> {\n return this.client.request('POST', `${this.linkBase}/vault/payment-method`, {\n body: params,\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * The payment's current state — status polling for redirect/popup rails.\n *\n * `GET /payments/{paymentId}` (publishable key + client secret)\n */\n async retrievePayment(options?: RequestExtras): Promise<PaymentResponse> {\n return this.client.request('GET', `/payments/${encodeURIComponent(this.paymentId)}`, {\n query: { client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n\n /**\n * Update the payment before confirmation (e.g. persist custom-field\n * answers as `metadata` on rails that never hit `/confirm`). The client\n * secret is attached automatically.\n *\n * `POST /payments/{paymentId}` (publishable key)\n */\n async updatePayment(\n params: PaymentUpdateRequest,\n options?: RequestExtras,\n ): Promise<PaymentResponse> {\n return this.client.request('POST', `/payments/${encodeURIComponent(this.paymentId)}`, {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n\n /**\n * Confirm the payment. The client secret is attached automatically; pass\n * an `Idempotency-Key` header via `options` to make retries safe.\n *\n * `POST /payments/{paymentId}/confirm` (publishable key)\n */\n async confirmPayment(\n params: PaymentConfirmRequest,\n options?: RequestExtras,\n ): Promise<PaymentResponse> {\n return this.client.request('POST', `/payments/${encodeURIComponent(this.paymentId)}/confirm`, {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n\n /**\n * Payment methods available for this payment.\n *\n * `GET /payment-methods` (publishable key + client secret)\n *\n * @param params - Optional filters; `country` is the highest-precedence\n * geo hint, ahead of billing address and IP geolocation.\n */\n async listPaymentMethods(\n params?: { country?: string },\n options?: RequestExtras,\n ): Promise<PaymentMethodListResponse> {\n return this.client.request('GET', '/payment-methods', {\n query: { client_secret: this.requireClientSecret(), country: params?.country },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n}\n","// **Payment panes** — merchant-configured payment methods that render as\n// DeloPay-drawn tiles in the embedded checkout instead of inside a connector's\n// own embedded form.\n//\n// Why they exist: Stripe only offers Apple Pay / Google Pay / Link when the\n// *top-level* document's domain is registered as a payment method domain on the\n// merchant's Stripe account. In an embedded iframe that domain is the\n// merchant's shop, not the DeloPay checkout — so the wallet silently\n// disappears. A pane replaces it with our own tile that opens the DeloPay\n// hosted checkout at the top level, in a focused single-method view.\n//\n// Nothing here is Apple-Pay-specific, and since the router published a\n// per-connector capability catalogue nothing here is Stripe-specific either:\n// the feature is \"which of a connector's payment methods render as a pane, and\n// how they look\".\n//\n// This module serves SDK consumers: merchants configuring\n// `metadata.native_panes` on a merchant connector account programmatically\n// (codec), reading the resolved `native_panes` off a checkout payload\n// ({@link PaneView}), or building the focused single-method link that goes\n// behind their own button ({@link focusedCheckoutUrl}).\n//\n// The wire shapes are owned by the router (delopay-backend\n// `crates/router/src/core/payment_link/native_panes.rs`) — `native_panes` in\n// the metadata key, the field names and the enum values are contracts with it\n// and with links already in buyers' hands, so the identifiers here were renamed\n// off \"native pane\" and the wire was not.\n//\n// Capability (which connector may publish which method, on which rail) comes\n// from the router at runtime through `connectors.getPanesCatalog()`, not from a\n// table here.\n\n// Type-only, so this module still emits no imports and can be executed\n// standalone. `types.ts` owns the catalogue's wire shapes because they are\n// generated-spec-paired (`scripts/validate-types.ts`); it imports nothing from\n// here, so the dependency runs one way.\nimport type {\n PaneCapability,\n PaneRail,\n PanesCatalogResponse,\n PanesConnectorCatalog,\n PaneSurcharge,\n PaneView,\n PaneVisibility,\n PaneOpenTarget,\n SurchargeDirection,\n} from './types';\n\nexport type {\n PaneCapability,\n PaneRail,\n PanesCatalogResponse,\n PanesConnectorCatalog,\n PaneSurcharge,\n PaneView,\n PaneVisibility,\n PaneOpenTarget,\n SurchargeDirection,\n};\n\n// --- Wire types ---------------------------------------------------------\n\n/**\n * The values {@link decodePanes} recognises. Anything else — a value written by\n * a dashboard newer than this SDK — degrades to `always` rather than throwing\n * or dropping the row: an older SDK reading a newer blob is a normal state\n * during a rollout, and a hard failure there takes out a merchant's whole\n * connector config rather than one tile.\n */\nconst PANE_VISIBILITIES: readonly PaneVisibility[] = ['always', 'embedded_only', 'external_only'];\n\nfunction parseVisibility(raw: unknown): PaneVisibility {\n return PANE_VISIBILITIES.find((value) => value === raw) ?? 'always';\n}\n\n/**\n * One pane exactly as the merchant configures it. Persisted (JSON) under\n * `metadata.native_panes` on the merchant connector account.\n *\n * Field names are the wire contract — renaming one is a migration. The router\n * decodes strictly row by row: a row that fails strict decoding (e.g. a\n * wrong-typed field like `display_order: \"3\"`) is dropped whole with a server\n * log, and the remaining rows still render. This SDK's {@link decodePanes} is\n * additionally per-property tolerant — including clamping `display_order` into\n * the router's `i32` range — so a decode→encode round-trip through the SDK\n * repairs a blob the router would partially drop.\n */\nexport interface Pane {\n /** Catalogue key of the promoted method — see {@link paneMethodInfo}. */\n method: string;\n /** Disabled rows keep their tuning but never reach a buyer. */\n enabled: boolean;\n /** Default-language tile label. Empty falls back to the catalogue name. */\n label: string;\n /** Per-locale overrides of `label`, keyed by checkout locale (`de`, `de-AT`). */\n labelTranslations: Record<string, string>;\n /**\n * Secondary line under the label. `null` means \"use the catalogue default\";\n * an empty string means the merchant deliberately hid the line. That\n * distinction is the whole reason this is nullable and `label` is not.\n */\n sublabel: string | null;\n /** Per-locale overrides of `sublabel`. */\n sublabelTranslations: Record<string, string>;\n /** Section the tile groups under. Empty falls back to the catalogue category. */\n category: string;\n /** Built-in icon key — see {@link PANE_ICON_KEYS}. */\n icon: string;\n /** Custom inline SVG. Sanitized server-side before it reaches a buyer; a\n * rejected payload falls back to the built-in `icon`. */\n iconSvg: string;\n /** Lower renders first; ties break on catalogue order. */\n displayOrder: number;\n /** Where the tile is offered — see {@link PaneVisibility}. */\n visibility: PaneVisibility;\n /** How the embedded checkout opens the focused view — see {@link PaneOpenTarget}. */\n openIn: PaneOpenTarget;\n}\n\n/**\n * Read a resolved tile's placement rule, across every payload version.\n *\n * Prefer this to touching either field. They are independent on the wire — a\n * payload may carry either, both or neither — and each alone loses a placement\n * rule: `embedded_only` cannot express `external_only`, so an `external_only`\n * tile read through it renders inside the merchant iframe the merchant asked\n * to keep it out of; `visibility` is absent on a router that predates it, so\n * an `embedded_only` tile read through it alone renders at top level too,\n * duplicating a method Stripe's own form already offers there.\n *\n * A recognised `visibility` wins. Otherwise the legacy boolean answers: absent\n * (old router) it carries the only placement that router could express, and\n * unrecognised (newer router) the router still sets it under its own fixed\n * rule. Neither path throws, and both degrade toward showing a tile — losing a\n * placement rule, never stranding a method.\n */\nexport function paneViewVisibility(\n view: Pick<PaneView, 'visibility' | 'embedded_only'>,\n): PaneVisibility {\n const declared = PANE_VISIBILITIES.find((value) => value === view.visibility);\n if (declared) return declared;\n return view.embedded_only === true ? 'embedded_only' : 'always';\n}\n\n// --- Catalogue ----------------------------------------------------------\n\n/**\n * A method the frozen Stripe fallback table knows, with the compiled copy the\n * router shipped for it at the time.\n *\n * Only {@link STRIPE_FALLBACK_PANE_METHODS} is typed with this. The live\n * catalogue (`connectors.getPanesCatalog()`) carries capability facts and no\n * copy at all, by design — see {@link PaneCapability}.\n */\nexport interface PaneMethodInfo {\n key: string;\n rail: PaneRail;\n /** Confirm routing key. Pass through verbatim; never derive it. */\n paymentMethod: string;\n /** Confirm routing key. Pass through verbatim; never derive it. */\n paymentMethodType: string;\n /** The focused checkout has to collect a billing country to confirm this. */\n requiresBillingCountry: boolean;\n /** Catalogue default label, shown as the editor's placeholder. */\n defaultLabel: string;\n /** Catalogue default sub-text. */\n defaultSublabel: string;\n /** Catalogue default section. */\n defaultCategory: string;\n /** Catalogue default icon key. */\n defaultIcon: string;\n}\n\n/**\n * What this SDK assumes when the router cannot answer.\n *\n * The capability endpoint does not exist on an older router, which answers\n * `connectors.getPanesCatalog()` with a 404.\n * Rather than leaving a caller with nothing, the pane helpers default to\n * exactly the behaviour they had before that endpoint existed: panes on the\n * Stripe connector only, with the method set the router's Stripe catalogue had\n * at the time.\n *\n * **This is a degradation path, not a mirror. Do not keep it in sync by hand,\n * and do not add a connector or a method to it** — that is what this table was\n * before this ticket, and adding to it would quietly rebuild the mirror. A\n * connector the router serves panes for arrives through the endpoint and needs\n * no entry here; a connector that needs an entry here to appear is a connector\n * the router will not deliver panes for anyway.\n *\n * The only reason to touch this list is to correct what Stripe's catalogue\n * looked like *before* the endpoint existed, and that is history, so there is\n * no such reason. Once the endpoint is reachable it is never consulted for a\n * connector the router answered for.\n *\n * The redirect-rail set is deliberately narrow — every entry is a variant the\n * Stripe connector accepts and that needs no extra buyer input beyond a\n * billing country. `eps` / `p24` / `bancontact` are absent because Stripe\n * hard-requires billing fields the focused checkout never collects (a full\n * name for EPS and Bancontact, an email for Przelewy24), so their tiles could\n * never succeed.\n *\n * `defaultLabel` / `defaultSublabel` are the copy the router compiled at that\n * time and are frozen with the rest of the table. Copy for a method the live\n * catalogue reports belongs to the consumer's own locale files, keyed by\n * `key` — the router ships none.\n */\nexport const STRIPE_FALLBACK_PANE_METHODS: readonly PaneMethodInfo[] = [\n {\n key: 'apple_pay',\n rail: 'wallet',\n paymentMethod: 'wallet',\n paymentMethodType: 'apple_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Apple Pay',\n defaultSublabel: 'Pay with Apple Pay',\n defaultCategory: 'wallet',\n defaultIcon: 'apple',\n },\n {\n key: 'google_pay',\n rail: 'wallet',\n paymentMethod: 'wallet',\n paymentMethodType: 'google_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Google Pay',\n defaultSublabel: 'Pay with Google Pay',\n defaultCategory: 'wallet',\n defaultIcon: 'google',\n },\n {\n key: 'link',\n rail: 'wallet',\n paymentMethod: 'wallet',\n paymentMethodType: 'link',\n requiresBillingCountry: false,\n defaultLabel: 'Link',\n defaultSublabel: 'Pay with saved details',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n {\n key: 'klarna',\n rail: 'redirect',\n paymentMethod: 'pay_later',\n paymentMethodType: 'klarna',\n // Stripe's Klarna needs the buyer's country echoed into the confirm body.\n requiresBillingCountry: true,\n defaultLabel: 'Klarna',\n // NOT the router's current \"Pay later or in 3 instalments\". This table is\n // what a router predating the capability endpoint renders, and that copy\n // only gained the \"3\" in the same release that added the endpoint.\n // Restating the new string here\n // would put copy no reachable router emits in front of a merchant, and\n // would change what the deprecated `nativePaneMethodInfo` has returned\n // since 0.106.0.\n defaultSublabel: 'Pay later or in instalments',\n defaultCategory: 'bnpl',\n defaultIcon: 'bnpl',\n },\n {\n key: 'affirm',\n rail: 'redirect',\n paymentMethod: 'pay_later',\n paymentMethodType: 'affirm',\n requiresBillingCountry: false,\n defaultLabel: 'Affirm',\n defaultSublabel: 'Pay over time',\n defaultCategory: 'bnpl',\n defaultIcon: 'bnpl',\n },\n {\n key: 'ideal',\n rail: 'redirect',\n paymentMethod: 'bank_redirect',\n paymentMethodType: 'ideal',\n requiresBillingCountry: false,\n defaultLabel: 'iDEAL',\n defaultSublabel: 'Pay from your bank',\n defaultCategory: 'bank_redirect',\n defaultIcon: 'bank',\n },\n {\n key: 'alipay',\n rail: 'redirect',\n paymentMethod: 'wallet',\n paymentMethodType: 'ali_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Alipay',\n defaultSublabel: 'Pay with Alipay',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n {\n key: 'revolut_pay',\n rail: 'redirect',\n paymentMethod: 'wallet',\n paymentMethodType: 'revolut_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Revolut Pay',\n defaultSublabel: 'Pay with Revolut',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n {\n key: 'amazon_pay',\n rail: 'redirect',\n paymentMethod: 'wallet',\n paymentMethodType: 'amazon_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Amazon Pay',\n defaultSublabel: 'Pay with Amazon',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n];\n\n/**\n * {@link STRIPE_FALLBACK_PANE_METHODS} in the shape the live endpoint returns,\n * so every helper below takes one type of catalogue and the degradation path\n * is not a second code path. Derived, not written out: two spellings of one\n * table is exactly the drift this ticket removed.\n */\nexport const STRIPE_FALLBACK_PANE_CATALOG: PanesConnectorCatalog = {\n connector: 'stripe',\n allowed_rails: ['wallet', 'redirect'],\n methods: STRIPE_FALLBACK_PANE_METHODS.map((info) => ({\n key: info.key,\n rail: info.rail,\n payment_method: info.paymentMethod,\n payment_method_type: info.paymentMethodType,\n requires_billing_country: info.requiresBillingCountry,\n })),\n};\n\n/**\n * An empty catalogue — a connector the router does not offer panes for.\n * Exported so callers can express \"asked, and the answer was no\" without\n * reaching for `null` in the middle of a computation.\n */\nexport function emptyPaneCatalog(connector: string): PanesConnectorCatalog {\n return { connector, allowed_rails: [], methods: [] };\n}\n\n/**\n * Pull one connector's entry out of a `connectors.getPanesCatalog()` response.\n *\n * Returns {@link emptyPaneCatalog} for a connector the response does not name:\n * \"the router knows this connector and publishes no panes for it\" and \"the\n * router has never heard of it\" are the same answer to a caller building an\n * editor, and both mean \"offer nothing\".\n */\nexport function paneCatalogFor(\n response: PanesCatalogResponse,\n connector: string,\n): PanesConnectorCatalog {\n return (\n response.connectors.find((entry) => entry.connector === connector) ??\n emptyPaneCatalog(connector)\n );\n}\n\n/**\n * Built-in tile icon keys the buyer-facing checkout ships a glyph for.\n *\n * Reconciled against both ends: every key here has a branch in the checkout's\n * `NativePaneIcon.svelte`, and every `default_icon` the router's catalogue\n * publishes is in this list. An icon key the checkout does not ship falls\n * through to `wallet` there, so a key that drifts in renders as the wrong\n * glyph rather than as nothing.\n */\nexport const PANE_ICON_KEYS: readonly string[] = [\n 'wallet',\n 'card',\n 'bank',\n 'apple',\n 'google',\n 'bnpl',\n 'cash',\n // Brand marks, not category glyphs: the checkout draws PayPal's monogram,\n // Klarna's squircle-K and the Bitcoin mark for these, the same logos the\n // bespoke panes they replace already drew. Listed here so a merchant's own\n // dashboard can offer them; the router decides which one a tile *defaults*\n // to, and a router predating them simply keeps sending the old default.\n 'paypal',\n 'klarna',\n 'crypto',\n];\n\n/**\n * Section keys a pane's tile may group under.\n *\n * Reconciled against the router's actual `default_category` values rather than\n * against what the Stripe table happened to need. `crypto` and `game_items`\n * are router defaults (the Cryptomus/NowPayments and Skinsback catalogues) and\n * were missing here, so a merchant configuring one of those panes was shown a\n * category their editor did not recognise.\n *\n * A custom value is allowed and renders as its own section under that literal\n * text. The buyer-facing checkout translates a subset of these into a section\n * header and falls through to the raw key for the rest — `crypto` and\n * `game_items` are the two it has yet to add, tracked in delopay-checkout#70.\n */\nexport const PANE_CATEGORY_KEYS: readonly string[] = [\n 'wallet',\n 'card',\n 'bnpl',\n 'bank_redirect',\n 'bank_transfer',\n 'crypto',\n 'game_items',\n 'cash',\n];\n\n/**\n * Mirror of the router's per-connector cap. Counted differently on each side:\n * {@link decodePanes} stops after 12 *decoded* rows (entries with a usable,\n * non-duplicate `method` — junk and duplicate entries don't consume a slot),\n * while the router caps *accepted* panes (enabled, known, deduplicated) at 12\n * — so an oversized hand-written blob may render a pane this decoder drops.\n * Blobs the SDK itself encodes never exceed the cap.\n */\nexport const PANES_MAX = 12;\n\n/**\n * Look a method up in one connector's catalogue.\n *\n * Pass the entry for the connector being configured, from\n * `connectors.getPanesCatalog()` via {@link paneCatalogFor}. The default is\n * the degradation path and only correct for Stripe on a router that predates\n * the endpoint — see {@link STRIPE_FALLBACK_PANE_CATALOG}.\n */\nexport function paneMethodInfo(\n method: string,\n catalog: PanesConnectorCatalog = STRIPE_FALLBACK_PANE_CATALOG,\n): PaneCapability | undefined {\n return catalog.methods.find((info) => info.key === method);\n}\n\n/** Whether this connector may declare a pane on `rail` at all. A wallet pane\n * on a connector outside its `allowed_rails` is refused at save time — the\n * wallet rail rides on Stripe's Express Checkout Element charging the *same*\n * payment intent the embedded checkout holds, which does not generalise. */\nexport function paneRailAllowed(rail: PaneRail, catalog: PanesConnectorCatalog): boolean {\n return catalog.allowed_rails.includes(rail);\n}\n\n/**\n * The methods a caller may actually offer for this connector: the catalogue's\n * own list, minus anything on a rail the connector does not allow.\n *\n * The router should not report such a pair in the first place, but the two\n * fields are independent in the response and a save that crosses them is\n * refused at the API with an error naming the connector and the method. Filter\n * rather than trust, so a merchant never configures a tile the save will\n * bounce.\n */\nexport function offerablePaneMethods(catalog: PanesConnectorCatalog): PaneCapability[] {\n return catalog.methods.filter((info) => paneRailAllowed(info.rail, catalog));\n}\n\n/** Non-copy display defaults for a tile: which built-in glyph and which\n * section heading a new pane starts on. */\nexport interface PaneDisplayDefaults {\n icon: string;\n category: string;\n}\n\n/**\n * Per-method overrides, for the handful whose brand glyph is not what their\n * payment method would suggest. Everything else is derived from the catalogue\n * entry's `payment_method` below, so a connector the SDK has never heard of\n * still gets a sensible tile rather than a blank one.\n *\n * These have to be keyed by method and not by `payment_method`: `wallet` also\n * routes Link, Alipay, Revolut Pay and Amazon Pay, and `pay_later` also routes\n * Affirm — none of which the SDK has a mark for. Getting this wrong is not a\n * cosmetic slip that the next release fixes, because {@link defaultPane}\n * materialises the value and {@link encodePanes} writes it to\n * `metadata.native_panes`, where a stored `icon` outranks the router's\n * `default_icon` for the life of the pane.\n */\nconst DISPLAY_DEFAULTS_BY_KEY: Readonly<Record<string, PaneDisplayDefaults>> = {\n apple_pay: { icon: 'apple', category: 'wallet' },\n google_pay: { icon: 'google', category: 'wallet' },\n paypal: { icon: 'paypal', category: 'wallet' },\n // Both the Klarna connector's own tile and Stripe's Klarna. Affirm stays on\n // the generic `bnpl` glyph — same rail, no mark of its own.\n klarna: { icon: 'klarna', category: 'bnpl' },\n};\n\n/**\n * Derived from the `payment_method` half of the catalogue's routing pair.\n * Every value here reproduces the router's own `default_icon` /\n * `default_category` for the methods it publishes today, so a tile the SDK\n * lays out and a tile the router lays out agree.\n */\nconst DISPLAY_DEFAULTS_BY_PAYMENT_METHOD: Readonly<Record<string, PaneDisplayDefaults>> = {\n wallet: { icon: 'wallet', category: 'wallet' },\n card: { icon: 'card', category: 'card' },\n card_redirect: { icon: 'card', category: 'card' },\n pay_later: { icon: 'bnpl', category: 'bnpl' },\n bank_redirect: { icon: 'bank', category: 'bank_redirect' },\n bank_transfer: { icon: 'bank', category: 'bank_transfer' },\n bank_debit: { icon: 'bank', category: 'bank_transfer' },\n // Cryptomus and NowPayments publish the same `crypto` key on this rail, and\n // the router defaults both to the Bitcoin mark.\n crypto: { icon: 'crypto', category: 'crypto' },\n // Skinsback, which has no mark: the router defaults it to `wallet` too.\n game_items: { icon: 'wallet', category: 'game_items' },\n cash: { icon: 'cash', category: 'cash' },\n voucher: { icon: 'cash', category: 'cash' },\n};\n\nconst DISPLAY_DEFAULTS_FALLBACK: PaneDisplayDefaults = { icon: 'wallet', category: 'wallet' };\n\n/**\n * What a new tile looks like before the merchant designs it.\n *\n * The router serves capability, not presentation, so the glyph and the section\n * come from here and the accompanying text comes from the caller's own locale\n * files. A method with no entry at all still resolves — that is the point of\n * deriving from `payment_method`: a connector added to the router's catalogue\n * tomorrow needs no SDK release to be designable today.\n */\nexport function paneDisplayDefaults(info: PaneCapability | undefined): PaneDisplayDefaults {\n if (!info) return DISPLAY_DEFAULTS_FALLBACK;\n return (\n DISPLAY_DEFAULTS_BY_KEY[info.key] ??\n DISPLAY_DEFAULTS_BY_PAYMENT_METHOD[info.payment_method] ??\n DISPLAY_DEFAULTS_FALLBACK\n );\n}\n\n// --- Validation ---------------------------------------------------------\n\n/**\n * Why a configured pane would not survive a save or a render.\n *\n * - `method_unknown` — the connector's catalogue does not publish this key, so\n * the router drops the row at render.\n * - `rail_not_allowed` — the method's rail is not in the connector's\n * `allowed_rails`; the API refuses this at save time.\n * - `over_cap` — past the router's per-connector cap of {@link PANES_MAX}; the\n * row is stored but never rendered.\n * - `duplicate_method` — an earlier enabled row already claims this method.\n * The router skips disabled rows and then dedupes, so the first *enabled*\n * row renders and every later one is dropped in silence. Reported on the\n * losing rows, never on the one that survives.\n */\nexport type PaneIssueCode = 'method_unknown' | 'rail_not_allowed' | 'over_cap' | 'duplicate_method';\n\nexport interface PaneIssue {\n /** Index into the list handed to {@link validatePanes}. */\n index: number;\n method: string;\n code: PaneIssueCode;\n}\n\n/**\n * Check a configured list against one connector's catalogue, before writing it\n * to `metadata.native_panes`.\n *\n * The API applies the same rules at save time, so this changes where the\n * merchant finds out, not whether they do — and an SDK caller building an\n * editor would otherwise learn it from a bounced request with no row to point\n * at. An empty result means nothing here will be refused or silently dropped.\n */\nexport function validatePanes(\n panes: readonly Pane[],\n catalog: PanesConnectorCatalog = STRIPE_FALLBACK_PANE_CATALOG,\n): PaneIssue[] {\n const issues: PaneIssue[] = [];\n // Keyed on the catalogue's own key rather than the raw string, because that\n // is what the router dedupes on. Only enabled rows are recorded: a disabled\n // row never reaches the router's `seen` set, so it neither claims a method\n // nor loses to one.\n const claimedBy = new Set<string>();\n panes.forEach((pane, index) => {\n const info = paneMethodInfo(pane.method, catalog);\n if (!info) {\n issues.push({ index, method: pane.method, code: 'method_unknown' });\n } else if (!paneRailAllowed(info.rail, catalog)) {\n issues.push({ index, method: pane.method, code: 'rail_not_allowed' });\n } else if (pane.enabled) {\n // Unknown and rail-refused rows are dropped before the router dedupes,\n // so they cannot claim a key — and reporting two codes for one row would\n // point the merchant at the wrong repair.\n if (claimedBy.has(info.key)) {\n issues.push({ index, method: pane.method, code: 'duplicate_method' });\n } else {\n claimedBy.add(info.key);\n }\n }\n if (index >= PANES_MAX) issues.push({ index, method: pane.method, code: 'over_cap' });\n });\n return issues;\n}\n\n// --- Codec --------------------------------------------------------------\n\n/**\n * A new pane for `method`, with its glyph and section resolved from the\n * connector's catalogue entry rather than from a Stripe-keyed table — so\n * `defaultPane('creem_checkout', catalog)` is a designed tile and not a blank\n * one.\n *\n * Pass the catalogue entry for the connector being configured; the default is\n * the degradation path (see {@link STRIPE_FALLBACK_PANE_CATALOG}). Labels are\n * deliberately left empty: empty means \"use the catalogue default\", which the\n * router resolves at render, and the router ships no copy for a caller to\n * mirror.\n */\nexport function defaultPane(\n method: string,\n catalog: PanesConnectorCatalog = STRIPE_FALLBACK_PANE_CATALOG,\n): Pane {\n const defaults = paneDisplayDefaults(paneMethodInfo(method, catalog));\n return {\n method,\n enabled: true,\n label: '',\n labelTranslations: {},\n sublabel: null,\n sublabelTranslations: {},\n category: defaults.category,\n icon: defaults.icon,\n iconSvg: '',\n displayOrder: 0,\n visibility: 'always',\n openIn: 'tab',\n };\n}\n\nexport function clonePane(pane: Pane): Pane {\n return {\n ...pane,\n labelTranslations: { ...pane.labelTranslations },\n sublabelTranslations: { ...pane.sublabelTranslations },\n };\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseTranslations(raw: unknown): Record<string, string> {\n if (!isObject(raw)) return {};\n const out: Record<string, string> = {};\n for (const [locale, value] of Object.entries(raw)) {\n if (typeof value === 'string' && value.length > 0) out[locale] = value;\n }\n return out;\n}\n\nfunction str(raw: unknown): string {\n return typeof raw === 'string' ? raw : '';\n}\n\n// The router's wire type is an `i32` (`api_models` `display_order`), and a\n// fractional or out-of-range value fails its strict row decode — dropping the\n// whole row server-side while an SDK round-trip would keep the blob looking\n// healthy. Clamped on BOTH decode and encode so this codec never emits a\n// value the router rejects, regardless of where the number came from.\nconst DISPLAY_ORDER_MIN = -2147483648;\nconst DISPLAY_ORDER_MAX = 2147483647;\n\nfunction clampDisplayOrder(raw: number): number {\n if (!Number.isFinite(raw)) return 0;\n return Math.min(DISPLAY_ORDER_MAX, Math.max(DISPLAY_ORDER_MIN, Math.trunc(raw)));\n}\n\n/**\n * Decode the stored `metadata.native_panes` blob into editor rows.\n *\n * Tolerant like the branding codecs: anything malformed falls back per\n * property, rows without a usable `method` are dropped, duplicates keep the\n * first occurrence — except that an enabled row wins over an earlier disabled\n * one for the same method, because that is the row the router renders — and\n * decoding stops after {@link PANES_MAX} decoded rows (dropped junk/duplicate\n * entries don't consume a slot). That is more forgiving than the router, which\n * drops a strict-decode-failing row whole (keeping the rest) and caps accepted\n * panes rather than decoded rows — see {@link Pane} and {@link PANES_MAX}.\n * Returns `null` when the input is not an array so the caller can distinguish\n * \"never configured\" from \"cleared\".\n */\nexport function decodePanes(raw: unknown): Pane[] | null {\n if (!Array.isArray(raw)) return null;\n const decodeRow = (entry: Record<string, unknown>, method: string): Pane => ({\n method,\n enabled: entry['enabled'] !== false,\n label: str(entry['label']),\n labelTranslations: parseTranslations(entry['label_translations']),\n sublabel: typeof entry['sublabel'] === 'string' ? entry['sublabel'] : null,\n sublabelTranslations: parseTranslations(entry['sublabel_translations']),\n category: str(entry['category']),\n icon: str(entry['icon']),\n iconSvg: str(entry['icon_svg']),\n displayOrder: clampDisplayOrder(Number(entry['display_order'])),\n // Anything unrecognised degrades to `always` rather than dropping the row.\n visibility: parseVisibility(entry['visibility']),\n // Same tolerance: an unknown value degrades to the default `tab`.\n openIn: entry['open_in'] === 'popup' ? 'popup' : 'tab',\n });\n\n const indexByMethod = new Map<string, number>();\n const out: Pane[] = [];\n for (const entry of raw) {\n if (out.length >= PANES_MAX) break;\n if (!isObject(entry)) continue;\n const method = str(entry['method']).trim();\n if (!method) continue;\n const kept = indexByMethod.get(method);\n if (kept !== undefined) {\n // Duplicate method. Keep the row the ROUTER would render: it skips\n // disabled rows BEFORE deduping (`native_panes.rs`), so where a blob\n // holds both a disabled and an enabled row for one method, buyers see\n // the enabled one. Keeping the disabled row here would show the merchant\n // a pane that is off while it is live, and persist that on the next save.\n const enabled = entry['enabled'] !== false;\n const existing = out[kept];\n if (enabled && existing && !existing.enabled) out[kept] = decodeRow(entry, method);\n continue;\n }\n indexByMethod.set(method, out.length);\n out.push(decodeRow(entry, method));\n }\n return out;\n}\n\n/**\n * Encode editor rows back into the snake_case blob the connector account\n * stores. Empty optional strings are omitted so the metadata stays small and a\n * merchant who typed nothing round-trips as \"use the catalogue default\" rather\n * than as an explicit empty override.\n *\n * `sublabel` is the exception: an explicitly-empty value is preserved (as `\"\"`)\n * because that is how a merchant hides the second line.\n */\nexport function encodePanes(panes: Pane[]): Record<string, unknown>[] {\n const nonEmpty = (map: Record<string, string>): Record<string, string> | undefined => {\n const entries = Object.entries(map).filter(([, v]) => v.trim().length > 0);\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n };\n return panes.slice(0, PANES_MAX).map((pane) => {\n const labelTranslations = nonEmpty(pane.labelTranslations);\n const sublabelTranslations = nonEmpty(pane.sublabelTranslations);\n return {\n method: pane.method,\n enabled: pane.enabled,\n ...(pane.label.trim() ? { label: pane.label.trim() } : {}),\n ...(labelTranslations ? { label_translations: labelTranslations } : {}),\n // `null` omits the key entirely (catalogue default wins); `''` is sent\n // as-is because that is how the merchant hides the second line.\n ...(pane.sublabel !== null ? { sublabel: pane.sublabel } : {}),\n ...(sublabelTranslations ? { sublabel_translations: sublabelTranslations } : {}),\n ...(pane.category.trim() ? { category: pane.category.trim() } : {}),\n ...(pane.icon.trim() ? { icon: pane.icon.trim() } : {}),\n ...(pane.iconSvg.trim() ? { icon_svg: pane.iconSvg.trim() } : {}),\n // Clamped on encode too, not only decode: the router's strict i32 row\n // decode drops a row whole for a fractional or out-of-range value, so\n // writing e.g. 3.5 or Date.now() verbatim would silently delete the\n // pane at render while every read surface shows it healthy.\n display_order: clampDisplayOrder(pane.displayOrder),\n // Normalised on encode for the same reason `display_order` is clamped:\n // the router's strict row decode drops a row whole on a value outside\n // its enum, and a caller who built a `Pane` by hand (or in plain JS)\n // never went through `decodePanes`. A decoded pane always holds a valid\n // value, so this is a no-op on the round-trip path.\n visibility: parseVisibility(pane.visibility),\n open_in: pane.openIn === 'popup' ? 'popup' : 'tab',\n };\n });\n}\n\n// --- Focused checkout URL ----------------------------------------------\n\nexport interface FocusedCheckoutUrlParams {\n /** Base URL of the DeloPay hosted checkout, e.g. `https://checkout.delopay.net`. */\n checkoutBaseUrl: string;\n merchantId: string;\n paymentId: string;\n /** Pane method key to focus on (`apple_pay`, `klarna`, …). */\n method: string;\n /**\n * Connector that owns the tile, forwarded as `connector=`.\n *\n * A bare `pane=` resolves to the **first payable match in server-sorted\n * order**, which is unambiguous only while one connector publishes a given\n * key. Stripe publishes `klarna` and so does the Klarna connector, so a deep\n * link that names neither charges through whichever tile happens to sort\n * first. Name the connector whenever you know it.\n *\n * Optional because links minted before this parameter existed are already in\n * merchants' pages and still have to resolve.\n */\n connector?: string;\n /**\n * Merchant connector ACCOUNT that owns the tile, forwarded as `mca=`.\n *\n * Needed for the same reason `connector` is, one level down: a profile may\n * hold two enabled accounts of one connector, each publishing its own tile,\n * and the two links would otherwise be identical. Only meaningful alongside\n * `connector`.\n */\n merchantConnectorId?: string;\n /** Optional buyer locale, forwarded as `?locale=`. */\n locale?: string;\n /**\n * Set when the merchant's checkout-custom-field answers are already\n * persisted on the payment — forwarded as `cf=1` so the focused view skips\n * asking a second time. Purely a UI hint: the values live on the intent\n * either way, and the backend only accepts the merchant's configured field\n * keys from a client, so a wrongly-set flag can at worst skip an\n * informational prompt. This is the same hint the embedded pane sets when\n * it opens the focused view.\n */\n customFieldsCollected?: boolean;\n}\n\n/**\n * Build the link to the **focused single-method checkout**: the DeloPay hosted\n * checkout rendered with one payment method, one button, no picker.\n *\n * Two callers:\n * - the embedded checkout, which opens this in a new tab when a buyer clicks\n * a pane tile, and\n * - a merchant running their own checkout, who puts it behind their own\n * button — the same mechanism without an iframe.\n *\n * `method` is not limited to configured panes. A configured pane gets the\n * focused one-button view; `card`, `paypal`, `crypto_currency` and the\n * local-methods catalogs (by method key or vendor code) open the checkout\n * pinned to that method. Methods that exist only as a tab inside a connector's\n * own embedded form — iDEAL, Bancontact, P24 and the like, unless promoted to\n * a pane — cannot be isolated, because the connector owns that surface. An\n * unknown or unavailable method is never a dead end: the checkout shows a\n * notice with a visible \"show all payment methods\" action.\n *\n * Pass {@link FocusedCheckoutUrlParams.connector} (and\n * {@link FocusedCheckoutUrlParams.merchantConnectorId}) whenever you know\n * them. Without them the method key alone picks the first payable match, and\n * more than one connector can publish the same key. Omitting them produces\n * exactly the URL this function has always produced, so links already minted\n * are unaffected.\n *\n * Open it **at the top level** (a new tab or a full-page navigation). The whole\n * point is that the top-level domain is the registered payment method domain;\n * rendering it in an iframe puts you back where you started.\n *\n * If you open it with `window.open`, call that **synchronously inside the click\n * handler** or the popup blocker will eat it, and make sure any iframe you\n * render DeloPay in permits popups (`allow-popups`, plus\n * `allow-popups-to-escape-sandbox` under a restrictive `sandbox`).\n */\nexport function focusedCheckoutUrl(params: FocusedCheckoutUrlParams): string {\n const base = params.checkoutBaseUrl.replace(/\\/+$/, '');\n const path = `${base}/pay/${encodeURIComponent(params.merchantId)}/${encodeURIComponent(\n params.paymentId,\n )}`;\n const query = new URLSearchParams({ pane: params.method });\n // Parameter order matches the embedded checkout's own `focusedUrl`\n // (`NativePanesPane.svelte`), so a merchant's deep link and a tile click\n // produce the same string for the same tile. A blank value is treated as\n // absent rather than emitted empty: `connector=` would otherwise read as a\n // connector named \"\" instead of as \"not specified\".\n const connector = params.connector?.trim();\n if (connector) query.set('connector', connector);\n const merchantConnectorId = params.merchantConnectorId?.trim();\n if (merchantConnectorId) query.set('mca', merchantConnectorId);\n if (params.locale) query.set('locale', params.locale);\n if (params.customFieldsCollected) query.set('cf', '1');\n return `${path}?${query.toString()}`;\n}\n\n// --- Buyer-side checkout events ----------------------------------------\n\n/**\n * The closed vocabulary of buyer-side checkout events recorded on the payment's\n * status timeline. Written through\n * `POST /payment-link/{merchant_id}/{payment_id}/checkout-events`, authorized\n * with the payment's `client_secret` as a bearer token.\n *\n * The `native_pane_` prefix is the router's enum on the wire and does not move\n * with the rename — see the module header.\n */\nexport const CHECKOUT_EVENT_KINDS = [\n 'native_pane_selected',\n 'native_pane_tab_opened',\n 'native_pane_tab_blocked',\n 'native_pane_abandoned',\n 'native_pane_returned',\n] as const;\n\nexport type CheckoutEventKind = (typeof CHECKOUT_EVENT_KINDS)[number];\n\n// --- Deprecated aliases -------------------------------------------------\n//\n// The pre-0.109.0 names, kept so an external `@delopay/sdk` consumer upgrades\n// on their own schedule rather than on ours. **Scheduled for removal in\n// 0.112.0** — see CHANGELOG.md. Nothing in this repo uses them.\n\n/** @deprecated Renamed to {@link Pane}. Removed in 0.112.0. */\nexport type StripeNativePane = Pane;\n/** @deprecated Renamed to {@link PaneView}. Removed in 0.112.0. */\nexport type NativePaneView = PaneView;\n/** @deprecated Renamed to {@link PaneVisibility}. Removed in 0.112.0. */\nexport type NativePaneVisibility = PaneVisibility;\n/** @deprecated Renamed to {@link PaneOpenTarget}. Removed in 0.112.0. */\nexport type NativePaneOpenTarget = PaneOpenTarget;\n/**\n * @deprecated Superseded by {@link PaneMethodInfo}. Removed in 0.112.0.\n *\n * Deliberately **not** an alias of `PaneMethodInfo`: that type gained three\n * required routing fields (`paymentMethod`, `paymentMethodType`,\n * `requiresBillingCountry`), and a consumer who wrote an object literal or a\n * function return against the 0.108 shape would stop compiling on a deprecated\n * name that promises the opposite. This stays the six fields that shape had.\n *\n * `PaneMethodInfo` is structurally assignable to it, so everything this SDK\n * hands back — including {@link nativePaneMethodInfo} — still satisfies it.\n */\nexport interface NativePaneMethodInfo {\n key: string;\n rail: PaneRail;\n /** Catalogue default label, shown as the editor's placeholder. */\n defaultLabel: string;\n /** Catalogue default sub-text. */\n defaultSublabel: string;\n /** Catalogue default section. */\n defaultCategory: string;\n /** Catalogue default icon key. */\n defaultIcon: string;\n}\n\n/**\n * @deprecated Renamed to {@link STRIPE_FALLBACK_PANE_METHODS}, which is a\n * degradation path and not a catalogue mirror. Removed in 0.112.0.\n */\nexport const STRIPE_NATIVE_PANE_METHODS = STRIPE_FALLBACK_PANE_METHODS;\n/** @deprecated Renamed to {@link PANE_ICON_KEYS}. Removed in 0.112.0. */\nexport const NATIVE_PANE_ICON_KEYS = PANE_ICON_KEYS;\n/** @deprecated Renamed to {@link PANE_CATEGORY_KEYS}. Removed in 0.112.0. */\nexport const NATIVE_PANE_CATEGORY_KEYS = PANE_CATEGORY_KEYS;\n/** @deprecated Renamed to {@link PANES_MAX}. Removed in 0.112.0. */\nexport const NATIVE_PANES_MAX = PANES_MAX;\n\n/**\n * @deprecated Superseded by {@link paneMethodInfo}, which takes the connector's\n * catalogue and answers for every connector rather than only for Stripe.\n * Removed in 0.112.0.\n *\n * Kept as its own function rather than as an alias because it must keep its\n * old return type: it answers out of the frozen Stripe table and carries that\n * table's compiled copy, which the live catalogue deliberately does not have.\n */\nexport function nativePaneMethodInfo(method: string): PaneMethodInfo | undefined {\n return STRIPE_FALLBACK_PANE_METHODS.find((info) => info.key === method);\n}\n\n/**\n * @deprecated Superseded by {@link defaultPane}. Removed in 0.112.0.\n *\n * Kept as its own function rather than as an alias because it must keep its\n * old behaviour: it leaves `category` empty and resolves `icon` out of the\n * frozen Stripe table only. `defaultPane` fills both from the connector's\n * catalogue, which is the fix — but a caller on the old name encodes whatever\n * it is handed, and quietly turning a blank field into a stored override is\n * not something a deprecated alias should do to a merchant's saved config.\n */\nexport function defaultNativePane(method: string): Pane {\n const info = nativePaneMethodInfo(method);\n return {\n ...defaultPane(method),\n category: '',\n icon: info?.defaultIcon ?? '',\n };\n}\n\n/** @deprecated Renamed to {@link clonePane}. Removed in 0.112.0. */\nexport const cloneNativePane = clonePane;\n/** @deprecated Renamed to {@link decodePanes}. Removed in 0.112.0. */\nexport const decodeNativePanes = decodePanes;\n/** @deprecated Renamed to {@link encodePanes}. Removed in 0.112.0. */\nexport const encodeNativePanes = encodePanes;\n"],"mappings":"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","names":["isObject","parseTranslations"]}
|