import type { Stripe } from '@stripe/stripe-js'; export type PaymentCurrency = string; /** Stripe's known PaymentIntent states. Only `succeeded` means paid. */ export type PaymentFormIntentStatus = 'requires_payment_method' | 'requires_confirmation' | 'requires_action' | 'processing' | 'requires_capture' | 'canceled' | 'succeeded'; /** Complete invoicing address only. Never contains card details. */ export interface PaymentFormBillingDetails { name: string; address: { line1: string; line2: string | null; city: string; state: string; postalCode: string; country: string; }; } export interface PaymentFormProps { /** Opaque instance id — emitted as `data-component-id` for the agent registry. */ id?: string; /** * Client secret from your server, created via the PaymentIntents API. * * Omit to use **deferred-intent mode** — the Payment Element renders from * just the publishable key (no `clientSecret`, no backend round-trip up * front). In deferred mode supply `onCreatePaymentIntent` to actually * confirm: your server mints + returns the client secret at submit time. */ clientSecret?: string; /** * Deferred-intent setup: `'payment'` collects a charge, `'setup'` saves a * method for later. Ignored when `clientSecret` is supplied (the secret's * own intent type wins). Defaults to `'payment'`. */ mode?: 'payment' | 'setup'; /** Restrict deferred Elements to cards. With a client secret, the server intent controls methods. */ cardOnly?: boolean; /** * Deferred-confirm callback. Called at submit time (after client-side * field validation succeeds) so your server can mint a PaymentIntent and * return its `client_secret`. The returned secret is used ONLY to confirm * and is never logged or sent to any third-party origin. When omitted in * deferred mode the form runs in PREVIEW: fields render + validate, but no * charge is attempted. */ onCreatePaymentIntent?: () => Promise; /** Preview-only validation completed. Awaited without creating or confirming a payment. */ onPreviewValidated?: () => void | Promise; /** Stripe publishable key (`pk_test_…` / `pk_live_…`). */ publishableKey: string; /** Connected account used to create the intent. Ignored by an injected Stripe instance. */ stripeAccount?: string; /** ISO-4217 currency code (e.g. 'EUR', 'USD', 'JPY'). */ currency: PaymentCurrency; /** Amount in the currency's smallest unit (cents for EUR/USD, yen for JPY). */ amount: number; /** Called with the PaymentIntent id on successful confirmation. */ onSuccess?: (paymentIntentId: string) => void; /** Observes confirmed intent states, including payments still awaiting completion. */ onPaymentStatusChange?: (status: PaymentFormIntentStatus, paymentIntentId: string) => void; /** Called with a sanitised error (no PAN digits, no Stripe English strings). */ onError?: (error: { code: string; translatedMessage: string; }) => void; /** Show the billing-address collector below the payment fields. */ billingAddress?: boolean; /** Show and require a complete billing address before confirming payment. */ requireBillingAddress?: boolean; /** Initial name/address for each Elements session. Does not enable or validate the collector. */ defaultBillingDetails?: PaymentFormBillingDetails; /** * Billing details the host has already collected, for example on the * Booking details form. The form then asks for no name or address of * its own, shows card fields only, and sends these with the payment. * It wins over `billingAddress`, `requireBillingAddress` and * `onBillingDetails`, which are ignored while it is set. */ billingDetails?: PaymentFormBillingDetails; /** * Save complete billing details before confirmation or any redirect. Enables * the address collector; rejection blocks payment and permits a retry. * Not called in validation-only preview mode. Never logs or stores details. */ onBillingDetails?: (details: PaymentFormBillingDetails) => void | Promise; /** Locale override — defaults to the active i18next locale. */ locale?: string; /** Accessible label for the form. */ ariaLabel?: string; /** URL Stripe redirects to when a payment method requires it. */ returnUrl?: string; /** Pre-injected Stripe instance — used by tests + stories to bypass the network. */ stripePromise?: Promise | null; /** * Payment Element layout. `tabs` (default) renders methods as a tile row — * best in wide containers. `accordion` stacks them as full-width rows — use * it in narrow columns (< ~400px) where Stripe's tab row clips a partial tile. */ layout?: 'tabs' | 'accordion'; className?: string; } /** * Lifecycle of one payment attempt, as the agent surface reports it. * `succeeded` is only reached once Stripe has confirmed the * PaymentIntent; `failed` covers validation, decline, and processor / * network errors alike (read `getErrorKey()` for which). */ export type PaymentFormStatus = 'idle' | 'processing' | 'succeeded' | 'failed'; export interface PaymentFormHandle { /** * Programmatically submit the form (same flow as the Pay button). * Resolves only once the charge attempt has settled — read * `getStatus()` / `getErrorKey()` afterwards for the outcome. */ submit: () => Promise; /** Clear recoverable errors. A pending or paid attempt requires a new session. */ reset: () => void; /** Lifecycle of the current attempt. */ getStatus: () => PaymentFormStatus; /** * True when Stripe reports the payment fields, and any required billing address, as complete. `submit` * is refused (the button is disabled) while this is false outside * preview mode. */ isComplete: () => boolean; /** * i18n KEY of the current error (e.g. `payment.error.cardDeclined`), * or null. The translated message is deliberately not exposed — the * key is the structural datum, the message is free text. */ getErrorKey: () => string | null; /** * Opaque Stripe PaymentIntent id once a charge succeeded, else null. * The receipt handle — the same id handed to `onSuccess`. Never the * client secret. */ getPaymentIntentId: () => string | null; } export declare function formatPaymentAmount(amount: number, currency: string, locale: string): string; /** * Resolve `returnUrl` against the current origin. Accepts: * - absolute URLs on the same origin as `window.location` * - relative paths (resolved against the current origin) * Rejects (returns `null`): * - cross-origin URLs — would leak `payment_intent_client_secret` * - `javascript:` / `data:` / `file:` / `blob:` schemes * - SSR contexts (no `window`) — the submit path requires a browser * anyway, so rejecting here is the safer default. * See security-hardening.mdx. */ export declare function validateReturnUrl(returnUrl: string | undefined): string | null; /** * Replace any run of 4+ consecutive digits with `****`. Called before any * error text leaves the wrapper. Defensive: even though Stripe's error * strings don't normally contain PANs, a future SDK change could, and we * want a hard guarantee that `console` / analytics / Sentry breadcrumbs * stay clear of anything that looks like card data. */ export declare function stripCardLikeDigits(message: string): string; /** * Map a Stripe error code (e.g. `card_declined`, `incorrect_number`) to a * translation key under `payment.error.*`. Unknown codes fall through to * `payment.error.generic`. */ export declare function stripeErrorCodeToI18nKey(code: string | undefined): string; declare const formVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string; declare const submitButtonVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string; export declare const PaymentForm: import("react").ForwardRefExoticComponent>; export { formVariants as paymentFormVariants, submitButtonVariants as paymentSubmitButtonVariants, }; //# sourceMappingURL=payment-form.d.ts.map