import * as _flopay_shared from '@flopay/shared'; import { InlineSessionDraft, CheckoutButtonMethod, CheckoutProduct, CheckoutItem, CheckoutSubscription, ThemeId, FloPayAppearance, ButtonsLayoutTheme, ButtonsLayoutStyles, PaymentResult, CheckoutSession, FloPayError, DeclineEvent, InlineSessionPatch, GatewayEnvironment, PayPalProviderObjectType, PayPalApprovalPresentation, TokenizedBody, FloInstrumentEvent, BeforeButtonClickEvent, CheckoutMode, AVSFieldConfig, CardCaptureAdapter, VaultCardThemeColors } from '@flopay/shared'; export { BeforeButtonClickEvent, CheckoutButtonMethod, DeclineEvent, FloInstrumentEvent, InlineSessionDraft, InlineSessionPatch, SentryEventLike, SentryStackFrameLike, dropThirdPartyOnlyError } from '@flopay/shared'; import React from 'react'; export { FloPayCardSetup, FloPayCardSetupCancelEvent, FloPayCardSetupCompleteEvent, FloPayCardSetupDeclineEvent, FloPayCardSetupError, FloPayCardSetupProps } from './card-setup-entry.js'; import { FloPay } from '@flopay/js'; interface FloPayAutomaticPaymentSuccessEvent { result: PaymentResult; session: CheckoutSession | null; sessionId: string | null; autoCompleted: boolean; } interface FloPayAutomaticPaymentButtonProps extends Omit, 'children' | 'onError'> { sessionId?: string; /** * Session-bound checkout token for a consumer-supplied {@link sessionId} * (the `nonce` returned when that session was created). Post-#640 backends * require it as `x-checkout-session-token` to read the session and to * `/process` it; without it the existing-session path 401s with * "Missing checkout session token.". Ignored on the create-session path, * where the SDK mints and threads the nonce itself. */ nonce?: string; createSession?: InlineSessionDraft; /** * @deprecated Ignored. The backend now picks the customer's most recent * vaulted payment method via `getLatestByUserId` and rebinds the session's * gateway to match it (see `apps/api`'s `createSingle` auto-checkout * branch). Passing this prop has no effect — it is retained only to avoid * breaking existing integrations. */ paymentMethodId?: string; /** * @deprecated Ignored. The backend orchestrates gateway routing — clients * no longer choose between card and PayPal at the SDK boundary. Passing * this prop has no effect. */ checkoutMethod?: CheckoutButtonMethod; clientId?: string; /** * Unified products array (TeamFloPay/backend#760). When supplied, * `items`/`subscriptions` are ignored. The SDK folds the legacy fields * into this shape internally. */ products?: CheckoutProduct[]; items?: CheckoutItem[]; subscriptions?: CheckoutSubscription[]; account?: InlineSessionDraft['account']; successUrl?: string; cancelUrl?: string; couponCodes?: string[]; tagsData?: InlineSessionDraft['tagsData']; utmMetadata?: InlineSessionDraft['utmMetadata']; billingApiUrl?: string; locale?: string; /** * High-level theme bundle that styles the button (and the fallback * `FloPayCheckout` modal that opens when the saved-payment charge needs * user interaction). One of: `'classic'`, `'modern-light'`, `'modern-dark'`, * `'bold-light'`, `'bold-dark'`, `'glass-light'`, `'glass-dark'`. Explicit * `buttonsStyles` still wins for fine-grained overrides. */ theme?: ThemeId; /** * Per-checkout appearance overrides layered on top of the chosen `theme` * (same shape as {@link FloPayCheckout}'s `appearance`). Its `colorPrimary` / * `colorPrimaryHover` / `borderRadius` re-skin the button — and the fallback * `FloPayCheckout` modal — so the auto-pay button matches the rest of the * themed checkout. Without this the button only saw the bundle's defaults. */ appearance?: FloPayAppearance; /** * @deprecated Use `theme` instead. Legacy buttons-layout preset * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for * back-compat. */ buttonsTheme?: ButtonsLayoutTheme; buttonsStyles?: ButtonsLayoutStyles; onSuccess?: (event: FloPayAutomaticPaymentSuccessEvent) => void; onError?: (error: FloPayError) => void; onDecline?: (decline: DeclineEvent) => void; children?: React.ReactNode; } declare function FloPayAutomaticPaymentButton({ sessionId, nonce, createSession, paymentMethodId: _deprecatedPaymentMethodId, checkoutMethod: _deprecatedCheckoutMethod, clientId, products, items, subscriptions, account, successUrl, cancelUrl, couponCodes, tagsData, utmMetadata, billingApiUrl, locale, theme, appearance, buttonsTheme, buttonsStyles: stylesOverride, onSuccess, onError, onDecline, children, disabled, type, style, ...buttonProps }: FloPayAutomaticPaymentButtonProps): React.JSX.Element; /** * Overrides that `SplitCardForm`'s tokenized-body dispatcher uses to apply a * `runBeforeButtonClick` patch to the in-flight processPayment call. Kept in * sync structurally with `TokenizedBodyOverrides` in `split-card-form.tsx`. */ interface DirectPayPalTokenizedOverrides { accountPatch?: InlineSessionPatch['account']; sessionId?: string; nonce?: string; } /** * Internal handler signature aligned with `SplitCardForm`'s tokenized-body * dispatcher. Direct PayPal completes via the backend's process endpoint and * never produces a Stripe PaymentIntent, so we still forward a synthetic * `TokenizedBody` describing the captured order, optionally with the * session/account patch captured at click-time. */ type DirectPayPalTokenizedHandler = (body: TokenizedBody, overrides?: DirectPayPalTokenizedOverrides) => void; /** Click-time `runBeforeButtonClick` result, structurally compatible with `SplitCardForm`. */ interface DirectPayPalBeforeButtonClickResult { proceed: boolean; accountPatch?: InlineSessionPatch['account']; sessionId?: string; nonce?: string; } /** * Click-time gate. Mirrors `RunBeforeButtonClick` in `SplitCardForm`: lets the * consumer patch the session/account before PayPal creates the order, and lets * them abort the click entirely by returning `proceed: false`. */ type DirectPayPalRunBeforeButtonClick = (method: CheckoutButtonMethod) => Promise; type DirectPayPalInitializationState = 'loading' | 'retrying' | 'ready' | 'exhausted'; type DirectPayPalTechnicalFailureHandler = (method: 'paypal', err: unknown, options?: { code?: string; popupBlocked?: boolean; }) => void; interface DirectPayPalButtonProps { /** Checkout session ID. */ sessionId: string; /** * Session-bound checkout token returned by session creation. Forwarded as * `x-checkout-session-token` on every continuation request — required by * post-#640 backends. `FloPayCheckout` plumbs this prop automatically. */ nonce?: string; /** Billing API base URL. */ billingApiUrl: string; /** Buyer email. */ email?: string; /** Buyer name already attached to the checkout, when available. */ billingName?: string; /** Attaches buyer identity collected from PayPal before checkout continues. */ onBuyerIdentityReady?: (identity: NonNullable) => void | Promise; /** PayPal client identifier (`gateways.paypal.publishableKey`). */ clientId: string; /** Gateway environment, drives the sandbox/live SDK script. */ environment?: GatewayEnvironment; /** ISO 4217 currency code. */ currency: string; /** Whether the session is a subscription (drives intent + flow selection). */ isSubscription: boolean; /** * @deprecated Pass the backing {@link DirectPayPalButtonProps.session}; its * `gateways.paypal.providerObjectType` advertisement is authoritative. This * prop remains as a fallback for integrations that have not yet forwarded * the session. When neither source advertises a provider object, legacy * sessions continue to derive the flow from `isSubscription`. */ providerObjectType?: PayPalProviderObjectType; /** * Backend-advertised approval presentation. The backing session value is * authoritative when both are supplied. No return URL can be provided here. */ approvalPresentation?: PayPalApprovalPresentation; /** * If provided, called with the tokenized body once PayPal capture * completes. When omitted, the component processes payment internally. */ onTokenizedBody?: DirectPayPalTokenizedHandler; /** Called when the full self-contained payment flow succeeds. */ onComplete?: (result: PaymentResult) => void; /** Called when an error occurs. */ onErrorChange?: (error: string | null) => void; /** Decline emitter (mirrors SplitCardForm semantics). */ onDecline?: (decline: DeclineEvent) => void; /** Called for post-click technical failures before PayPal authorization completes. */ onTechnicalFailure?: DirectPayPalTechnicalFailureHandler; /** External processing state. */ isProcessing?: boolean; /** Notify the parent of the loading state for placeholder swapping. */ onLoadStateChange?: (ready: boolean) => void; /** Notify a PayPal-only wrapper about pre-render recovery state. */ onInitializationStateChange?: (state: DirectPayPalInitializationState) => void; /** Disable the automatic retry for a buyer-initiated single manual attempt. */ allowAutomaticRetry?: boolean; /** Tracks button-click for analytics. */ onButtonClick?: (method: CheckoutButtonMethod) => void; /** * Click-time gate (runs before PayPal creates the order). When provided, the * returned patch is applied to the in-flight create-intent and tokenized * dispatch so callers using `onBeforeButtonClick` see the same session/email * the Stripe-rendered PayPal flow does. */ runBeforeButtonClick?: DirectPayPalRunBeforeButtonClick; /** Backing session — used for self-contained accountData population. */ session?: CheckoutSession | null; /** * Pre-existing PayPal Order id (or Subscription id when `isSubscription` is * true) to bind the button to. When set, the button skips its usual * session-scoped create-intent round-trip on click and feeds this * id straight into PayPal's create-order / create-subscription callback. * * Used by `SplitCardForm`'s `paypal_direct_required` retry path: backend * creates a fresh PayPal order after a stalled process attempt and returns * its id; the SDK re-renders this button bound to that id so the buyer can * confirm with one more click without the backend re-creating the order on * each retry. * * Changing this value remounts the PayPal SDK so the new createOrder * binding takes effect (PayPal's render() options aren't live-updatable). */ existingOrderId?: string; /** Flo-owned privacy-safe telemetry is enabled by default; set `false` to opt out. */ telemetry?: boolean; /** * When true, renders an on-screen lifecycle tracer panel above the button * (mount, loadScript, eligibility, render, errors). Intended for debugging * in-app browsers (Facebook IAB, etc.) where remote console access is * impractical. Off by default — leave disabled in production. */ debug?: boolean; } /** Public direct-PayPal surface: telemetry accepts only the boolean opt-out. */ declare function DirectPayPalButton(props: DirectPayPalButtonProps): React.ReactElement | null; /** Props for the all-in-one `FloPayCheckout` wrapper. */ interface FloPayCheckoutProps { /** The checkout session ID (UUID from billing API). Required unless `createSession` is provided. */ sessionId?: string; /** * Session-bound checkout token (the `nonce` returned when the session was * created). Sent as the `x-checkout-session-token` header when fetching a * session by `sessionId`. Required by post-#640 backends, which no longer * let the UUID alone authorize a session read; harmless on older backends. * Only consulted in the `sessionId` flow — inline `createSession` sessions * carry their own freshly-minted nonce server-side. */ nonce?: string; /** * Create a checkout session inline — no separate API route needed. * The component POSTs to the billing API, gets the full session back, and renders the form. * Alternative to `sessionId` (provide one or the other). */ createSession?: InlineSessionDraft; /** Billing API base URL. Defaults to the shared `BILLING_API_URL` constant. */ billingApiUrl?: string; /** Flo-owned privacy-safe telemetry is enabled by default; set `false` to opt out. */ telemetry?: boolean; /** Visual appearance for payment elements. */ appearance?: FloPayAppearance; /** Locale for payment elements (default: 'auto'). */ locale?: string; /** Custom loading UI. Defaults to a simple centered spinner. */ loading?: React.ReactNode; /** Custom error UI. Receives the error. Defaults to showing the error message. */ error?: (error: FloPayError) => React.ReactNode; /** Called when the full payment flow completes successfully. */ onComplete?: (result: PaymentResult) => void; /** Called when a payment error occurs. */ onError?: (error: FloPayError) => void; /** Receives the versioned, privacy-safe checkout instrument feed. */ onInstrument?: (event: FloInstrumentEvent) => void; /** Called when a payment is declined or the authentication step fails. */ onDecline?: (decline: DeclineEvent) => void; /** Called when the AVS country dropdown changes. */ onCountryChange?: (country: string) => void; /** Called when the AVS ZIP/postcode input changes. */ onZipChange?: (zip: string) => void; /** * Show the PayPal payment surface (default: `true`). Renderer is chosen * from `gateways.paypal` on the session — DirectPayPalButton when present, * Stripe-rendered PayPal otherwise. */ showPayPal?: boolean; /** * Show Stripe-rendered wallets/APMs alongside the vault-hosted card surface * (default: `true`). When `false`, only * `DirectPayPalButton` can render. Both `showStripe=false` and * `showPayPal=false` (with no PayPal gateway configured) triggers a * bootstrap-time validation error. */ showStripe?: boolean; /** * Override the wallet/APM list the session advertises via * `gateways.stripe.enabledPaymentMethods`. Omit (the default) and the * backend's per-session list is used, which is what a normal integration * wants. * * Pass an explicit list to narrow it, or `[]` to render the hosted card form * on its own — the empty array means "no methods enabled", not "fall back to * the backend list". This is the supported way to get a card-only checkout: * `showStripe={false}` also gates the vault, so it takes the card form down * with the wallets. * * Narrowing only. Naming a method the backend hasn't enabled for the session * will not turn it on. */ enabledPaymentMethods?: string[]; /** * @deprecated Apple Pay availability is now driven by * `gateways.stripe.enabledPaymentMethods` on the per-session response from * the billing API. Setting this prop emits a one-time deprecation warning * and is otherwise ignored once the backend ships the list. */ showApplePay?: boolean; /** * @deprecated See {@link FloPayCheckoutProps.showApplePay}. */ showGooglePay?: boolean; /** * Enables on-screen diagnostic panels (PayPal gate decision, DirectPayPalButton * lifecycle). Intended for debugging in-app browsers (Facebook, Instagram, etc.) * where remote console access is impractical. Off by default. */ debug?: boolean; /** Layout mode: 'default' (all visible) or 'buttons' (PayPal/wallets + expandable card form). */ layout?: 'default' | 'buttons'; /** * High-level theme bundle that styles non-card Stripe Elements, the FloPay * wrapper / AVS inputs, and the hosted vault widget. One of: `'classic'` * (historic FloPay look, no bundle applied), `'modern-light'`, `'modern-dark'`, * `'bold-light'`, `'bold-dark'`, `'glass-light'`, `'glass-dark'`. Explicit * `appearance` / `buttonsStyles` props still override their respective * halves when supplied. */ theme?: _flopay_shared.ThemeId; /** * @deprecated Use `theme` instead. Legacy buttons-layout preset * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for * back-compat. */ buttonsTheme?: _flopay_shared.ButtonsLayoutTheme; /** Style overrides merged on top of the resolved theme bundle / buttonsTheme preset. */ buttonsStyles?: _flopay_shared.ButtonsLayoutStyles; /** Custom React content rendered inside the card button when `layout="buttons"`. */ cardButtonContent?: React.ReactNode; /** Custom React content rendered for the buttons-layout card back button label. */ cardBackButtonContent?: React.ReactNode; /** Custom React content rendered for the card-form title. */ cardTitleContent?: React.ReactNode; /** * @deprecated No longer rendered — the default-layout security footer was * removed alongside the theme-bundle refactor. Retained as an optional * prop so existing integrations type-check without changes. */ showSecurityFooter?: boolean; /** * Called when a payment method button is clicked. * `method`: `'card'` | `'paypal'` | `'apple_pay'` | `'google_pay'` */ onButtonClick?: (method: CheckoutButtonMethod) => void; /** * Called before a payment button continues in `layout="buttons"`. * Runs for card, PayPal, Apple Pay, and Google Pay. * In `layout="buttons"` with `createSession`, the returned patch is merged * into the inline session params before the selected flow continues. */ onBeforeButtonClick?: (event: BeforeButtonClickEvent) => undefined | false | Promise | InlineSessionPatch; /** * Enable AVS (Address Verification). * - `true` — show country + postal code (backward compatible default) * - `AVSFieldConfig` — granular per-field control, optionally scoped to country codes * - `false` / omitted — AVS disabled */ enableAVS?: boolean | _flopay_shared.AVSFieldConfig; /** * Per-merchant order of the hosted vault card rows — a permutation of * `['name','number','expiry']` (`'expiry'` = the expiry+CVV row; submit stays * last). Sets both the visual and tab order. Omit for the default * (`name`, `number`, `expiry`). Vault card path only. */ cardFieldOrder?: _flopay_shared.VaultCardFieldKey[]; /** * Content rendered directly above the hosted vault card widget (below the * "or pay with card" divider). Used by the demo playground to surface a * test-cards helper; harmless to omit in a normal integration. */ cardPreFormSlot?: React.ReactNode; /** Layout for AVS fields: 'row' (side-by-side, default) or 'column' (stacked). */ avsLayout?: 'row' | 'column'; /** * Final wording for the hosted card form's submit button in full checkout * (billing API v1.9.35+), e.g. `'Pay $10'`. Pass final, already-localized * plain text from your own order summary — the SDK does not format amounts * or translate. Updates apply live without remounting the card form or * clearing entered card details; omitting or clearing it (or passing `null` * or blank text) shows the hosted default, `CONFIRM PAYMENT`. Direct * custom-layout children receive it unless they set their own `submitLabel`. * * Only the hosted card submit button changes: `confirmLabel` still owns the * saved-payment confirm button, `cardButtonContent` the buttons-layout card * tile, and wallet, PayPal, processing, and retry wording is unchanged. */ submitLabel?: string | null; /** Additional CSS class for the wrapper. */ className?: string; /** Seed an initial checkout error message for the rendered payment form. */ initialErrorMessage?: string | null; /** * Override the default `SplitCardForm`. When provided, children are rendered * inside the initialized `FloPayProvider` with session props auto-injected. */ children?: React.ReactNode; /** * Override the session's checkoutMode. * - `'full'` — show payment form (default) * - `'confirm'` — show confirm button, uses saved payment method * - `'auto'` — auto-submit with saved PM, falls back to `'full'` on failure */ checkoutMode?: CheckoutMode; /** * Label for the saved-payment confirm button in `confirm` mode. Default: * `'Confirm Purchase'`. Full checkout's hosted card button uses * {@link FloPayCheckoutProps.submitLabel} instead. */ confirmLabel?: string; /** Custom confirm button renderer for `confirm` mode. */ renderConfirmButton?: (props: { onConfirm: () => void; isProcessing: boolean; }) => React.ReactNode; /** Called when the session has already been completed. Receives the successUrl. */ onSessionCompleted?: (successUrl: string) => void; /** * @deprecated No longer used. The Stripe publishable key is sourced exclusively * from the checkout session's `gateways.stripe.publishableKey`. Accepted only * for backward compatibility with older consumer code — the value is ignored. */ fallbackPublishableKey?: string; } /** * All-in-one checkout component. Fetches the session, initializes the * payment provider, and renders the appropriate UI based on checkout mode. * * **Modes:** * - `full` (default) — renders hosted-vault card capture, wallets, APMs, and PayPal * - `confirm` — renders a "Confirm Purchase" button, uses saved payment method * - `auto` — auto-submits with saved PM, falls back to `full` on failure * * ```tsx * router.push('/success')} * onError={(err) => console.error(err)} * /> * ``` */ declare function FloPayCheckout({ sessionId: sessionIdProp, nonce: nonceProp, createSession: createSessionParams, billingApiUrl, telemetry, appearance: appearanceOverride, locale, loading: loadingNode, error: errorNode, onComplete, onError, onInstrument, onDecline, onCountryChange, onZipChange, showPayPal, showStripe, enabledPaymentMethods: enabledPaymentMethodsProp, showApplePay, showGooglePay, debug, layout, theme, buttonsTheme, buttonsStyles, cardButtonContent, cardBackButtonContent, cardTitleContent, showSecurityFooter: _showSecurityFooter, onButtonClick, onBeforeButtonClick, enableAVS, cardFieldOrder, cardPreFormSlot, avsLayout, submitLabel, className, initialErrorMessage, children, checkoutMode: checkoutModeProp, confirmLabel, renderConfirmButton, onSessionCompleted, }: FloPayCheckoutProps): React.ReactElement; /** * Returns the current `FloPay` instance, or `null` if the provider * is still loading (i.e. the `loadFloPay()` promise has not resolved yet). * * Must be called within a ``. */ declare function useFloPay(): FloPay | null; /** * Returns the Stripe `FloPay` instance dedicated to the Stripe-rendered * PayPal fallback, or `null` if PayPal is disabled for this session. Direct * PayPal (`gateways.paypal`) does not use this instance. * * Must be called within a ``. */ declare function usePayPalFloPay(): FloPay | null; /** Checkout state exposed by `useCheckout()`. */ interface CheckoutState { session: CheckoutSession | null; loading: boolean; error: FloPayError | null; /** True while a detached session shell is not yet safe to charge. */ claimPending?: boolean; } /** * Returns the current checkout session state. * * Must be called within the checkout context rendered by ``. */ declare function useCheckout(): CheckoutState; /** Props for the `FloPayProvider` component. */ interface FloPayProviderProps { /** A `FloPay` instance or a promise that resolves to one (from `loadFloPay()`). */ flopay: Promise | FloPay | null; /** * Optional Stripe `FloPay` instance used to drive the Stripe-rendered PayPal * fallback. When omitted or `null`, the Stripe-rendered PayPal button is * not rendered. Direct PayPal (`gateways.paypal`) does not use this prop. */ paypalFlopay?: Promise | FloPay | null; /** Optional provider configuration. */ options?: { /** Billing API base URL. Set once here so child components don't need to repeat it. */ billingApiUrl?: string; }; /** Receives the versioned, privacy-safe checkout instrument feed. */ onInstrument?: (event: FloInstrumentEvent) => void; children: React.ReactNode; } /** * Provides FloPay SDK context to the component tree. * * Wrap components that consume FloPay context with this provider: * * ```tsx * * * * ``` * * `FloPayCheckout` is a standalone integration that owns its provider: * * ```tsx * * ``` */ declare function FloPayProvider({ flopay: floPayProp, paypalFlopay: paypalFloPayProp, options, onInstrument, children, }: FloPayProviderProps): React.ReactElement; type MaybePromise = T | Promise; interface SplitCardFormProps { /** The checkout session ID (UUID from billing API). */ sessionId: string; /** * Session-bound checkout token returned by session creation * (`CheckoutSessionResult.nonce` or `session.clientSecret`). Forwarded as * `x-checkout-session-token` on every continuation request — required by * post-#640 backends. `FloPayCheckout` plumbs this prop automatically. */ nonce?: string; /** Billing API base URL. Optional — defaults to the value from FloPayProvider or the shared constant. */ billingApiUrl?: string; /** Flo-owned privacy-safe telemetry is enabled by default; set false to opt out. */ telemetry?: boolean; /** User's email (required for creating payment intents). */ email?: string; /** User ID (required for processing payments). */ userId?: string; /** Called when the full payment flow completes successfully. */ onComplete?: (result: PaymentResult) => void; /** Called when a payment error occurs. */ onError?: (error: FloPayError) => void; /** Called when a payment is declined or the authentication step fails. */ onDecline?: (decline: DeclineEvent) => void; /** * **Override**: If provided, delegates backend submission to the caller. * When omitted, processes internally (calls processPayment + handles 3DS). */ onTokenizedBody?: (tokenizedBody: TokenizedBody) => void; /** First name for billing. */ firstName?: string; /** Last name for billing. */ lastName?: string; /** Checkout version for A/B tracking. */ chv?: string; /** Additional CSS class for the form wrapper. */ className?: string; /** * Final wording for the hosted card form's submit button — the control that * starts the card payment — e.g. `'Pay $10'` (billing API v1.9.35+). Pass * the final, already-localized plain text from your own order summary; the * SDK does not format amounts or translate. * * Changes apply live without remounting the card form, so buyer-entered * card details, focus, and caret are kept. Omitting it, passing `null`, or * clearing it after a label was shown restores the hosted default * (`CONFIRM PAYMENT`); blank, oversized, or invalid text also shows the * default. It does not change wallet, PayPal, processing, or retry wording, * the buttons-layout card tile (`cardButtonContent`), or the saved-payment * confirm button (`FloPayCheckout`'s `confirmLabel`). */ submitLabel?: string | null; /** External processing state. */ isProcessing?: boolean; /** External error message. */ error?: string | null; /** Called when internal error state changes. */ onErrorChange?: (error: string | null) => void; /** * Show the PayPal payment surface above the hosted vault card surface. Defaults to `true`. * The renderer is chosen from `session.gateways.paypal`: when that gateway * is configured, `DirectPayPalButton` (PayPal JS SDK) takes over and Stripe * drops `paypal` from its express row to avoid double-rendering; otherwise * PayPal renders inside `ExpressCheckoutElement` (using either a dedicated * `gateways.stripe.paypalPublishableKey` sub-account or the main Stripe * account when the enabled-methods list includes `paypal`). */ showPayPal?: boolean; /** * Show Stripe-rendered wallets and APMs (ExpressCheckoutElement + * PaymentElement). Defaults to `true`. When `false`, every Stripe surface * is hidden — only `DirectPayPalButton` can render. Setting both * `showStripe={false}` and `showPayPal={false}` (with no PayPal gateway * configured) throws a bootstrap-time validation error. */ showStripe?: boolean; /** * Per-session list of Stripe payment method type identifiers (as returned * by the billing API on `gateways.stripe.enabledPaymentMethods`). When * supplied, drives the contents of the `ExpressCheckoutElement` row and the * accordion `PaymentElement` instead of the historic hardcoded * Apple/Google/PayPal set. `card` is reserved for the hosted card path: it * advertises that `/vault/capture` recovery is available when the session * has no embedded vault block. When omitted, the SDK falls back to the * legacy `showApplePay`/`showGooglePay`/`showPayPal` toggles. */ enabledPaymentMethods?: string[]; /** * Per-method buyer-country gate from `gateways.stripe.enabledPaymentMethodCountries` * (method → allowed ISO-3166-1 alpha-2 countries; a method absent here has no * country gate). The SDK filters the rendered tile row by the buyer's *live* * country against this map, so per-method country eligibility comes from the * backend rather than a hardcoded SDK table. When omitted (legacy backend), * the SDK falls back to its built-in {@link STRIPE_METHOD_COUNTRIES} table. */ enabledPaymentMethodCountries?: Record; /** * @deprecated The Apple Pay / Google Pay surface is now driven by the * `gateways.stripe.enabledPaymentMethods` list returned per-session by the * billing API. Pass {@link SplitCardFormProps.enabledPaymentMethods} (or * upgrade the backend so `FloPayCheckout` threads it through automatically). * Setting this prop emits a one-time deprecation warning and is otherwise * ignored when `enabledPaymentMethods` is supplied. */ showApplePay?: boolean; /** * @deprecated See {@link SplitCardFormProps.showApplePay}. */ showGooglePay?: boolean; /** * Layout mode for the payment form. * - `'default'` — all payment methods + card form shown together (current behavior) * - `'buttons'` — PayPal, wallets, and a "Credit / Debit Card" button; clicking the card * button expands the card form with a back button to return to the button view */ layout?: 'default' | 'buttons'; /** * High-level theme bundle that styles non-card Stripe Elements, the FloPay * wrapper / AVS inputs, and the hosted vault widget. One of: * `'classic'` (historic FloPay look, no bundle applied), `'modern-light'`, * `'modern-dark'`, `'bold-light'`, `'bold-dark'`, `'glass-light'`, * `'glass-dark'`. Explicit `appearance` / `buttonsStyles` props still * override their respective halves when provided. */ theme?: _flopay_shared.ThemeId; /** * @deprecated Use `theme` instead. Legacy buttons-layout preset * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for * back-compat — the new union accepts the bundle ids too but you should * migrate to the `theme` prop. */ buttonsTheme?: _flopay_shared.ButtonsLayoutTheme; /** Style overrides merged on top of the resolved theme bundle / buttonsTheme preset. */ buttonsStyles?: _flopay_shared.ButtonsLayoutStyles; /** * Appearance from `FloPayProvider` / `FloPayCheckout`. Threaded through so * the React-rendered wrapper, AVS inputs, title, and hosted vault widget can * derive colors from `appearance.variables` when no explicit `buttonsStyles` * is supplied. Bundle consumers (`THEMES[id]`) get a coherent look without * having to forward both halves manually. */ appearance?: _flopay_shared.FloPayAppearance; /** Custom React content rendered inside the card button when `layout="buttons"`. */ cardButtonContent?: React.ReactNode; /** Custom React content rendered for the buttons-layout card back button label. */ cardBackButtonContent?: React.ReactNode; /** Custom React content rendered for the card-form title. */ cardTitleContent?: React.ReactNode; /** * @deprecated No longer rendered — the default-layout security footer was * removed alongside the theme-bundle refactor. Retained as an optional * prop so existing integrations type-check without changes. */ showSecurityFooter?: boolean; /** * Called when a payment method button is clicked. * `method`: `'card'` | `'paypal'` | `'apple_pay'` | `'google_pay'` */ onButtonClick?: (method: CheckoutButtonMethod) => void; /** * Called before a payment button continues in `layout="buttons"`. * Runs for card, PayPal, Apple Pay, and Google Pay. */ onBeforeButtonClick?: (event: BeforeButtonClickEvent) => MaybePromise; /** * Called after checkout collects a missing buyer email/name. FloPayCheckout * uses this to claim an email-less detached session before payment continues. */ onBuyerIdentityReady?: (identity: NonNullable) => MaybePromise; /** * Enable AVS (Address Verification). * - `true` — show country + postal code (backward compatible default) * - `AVSFieldConfig` — granular per-field control, optionally scoped to country codes * - `false` / omitted — AVS disabled */ enableAVS?: boolean | AVSFieldConfig; /** * Per-merchant order of the hosted vault card rows — a permutation of * `['name','number','expiry']` (`'expiry'` is the combined expiry+CVV row; * the submit button stays last). Drives both the visual order and the tab * order inside the widget. Omit for the default (`name`, `number`, `expiry`). * Only applies on the vault card path. */ cardFieldOrder?: _flopay_shared.VaultCardFieldKey[]; /** Content rendered above the hosted vault card widget (below the wallet divider). */ cardPreFormSlot?: React.ReactNode; /** Layout for AVS fields: 'row' (side-by-side, default) or 'column' (stacked). */ avsLayout?: 'row' | 'column'; /** Pre-filled country code (ISO 3166-1 alpha-2) for AVS. */ country?: string; /** Pre-filled ZIP/postal code for AVS. */ zip?: string; /** Pre-filled street address (line 1) for AVS. Typically from a partner GeoIP / profile lookup. */ addressLine1?: string; /** Pre-filled apt/suite/unit (line 2) for AVS. */ addressLine2?: string; /** Pre-filled city for AVS. Typically from a partner GeoIP / profile lookup. */ city?: string; /** Pre-filled state/province for AVS. Typically from a partner GeoIP / profile lookup. */ state?: string; /** Callback when AVS country changes. */ onCountryChange?: (country: string) => void; /** Callback when AVS ZIP/postal code changes. */ onZipChange?: (zip: string) => void; /** Whether AVS was enabled (sent to backend for analytics). */ avsCheck?: boolean; /** Checkout type: 'standard_checkout' or 'embedded_checkout'. */ checkoutType?: string; /** Checkout layout: 'default_layout', 'buttons_layout', or 'custom_layout'. */ checkoutLayout?: string; /** Total amount in cents (smallest currency unit). Used for wallet/PayPal Elements config. */ totalAmount?: number; /** Currency code (used for PayPal Elements config). */ currency?: string; /** Render the card form expanded on first paint when `layout="buttons"`. */ initialCardOpen?: boolean; /** * Direct PayPal gateway configuration. When provided, PayPal renders via * the official PayPal JS SDK (in-app browser compliant) instead of via * Stripe's ExpressCheckoutElement. Selection is mutually exclusive: * setting this disables the Stripe-rendered PayPal path automatically. */ directPaypal?: { clientId: string; environment?: GatewayEnvironment; /** * @deprecated The active session's * `gateways.paypal.providerObjectType` advertisement is authoritative. * Retained as a fallback for integrations that do not supply a session. */ providerObjectType?: PayPalProviderObjectType; /** Backend-advertised non-popup presentation for one-time PayPal Orders. */ approvalPresentation?: _flopay_shared.PayPalApprovalPresentation; }; /** Whether the active session represents a subscription (drives direct PayPal intent). */ isSubscription?: boolean; /** Backing session — forwarded to direct-PayPal so it can populate accountData. */ session?: CheckoutSession | null; /** * True while a **detached** session's claim is waiting for buyer identity or * is still in flight (TeamFloPay/backend#1099). * * The hosted card widget is already mounted and the buyer can fill it in, but * the session has no cart attached yet, so nothing may be submitted: the * billing API rejects process / intent calls on an unclaimed session with * `409 checkout_session_data_attachment_required`, and holds an unclaimed * vault charge with a retryable `503`. While true, card submit stays gated. * Non-card surfaces also stay hidden unless they are needed to collect the * missing identity; all payment continuations enable when the claim lands. * `FloPayCheckout` plumbs this prop automatically. */ dataAttachmentPending?: boolean; /** * True when the pending detached claim is waiting for this form to collect * buyer identity. Non-card collection surfaces remain available, while all * payment continuations still await `onBuyerIdentityReady`. */ dataAttachmentRequiresIdentity?: boolean; /** * Enables on-screen diagnostic panels for the PayPal/wallet gating decision * and the `DirectPayPalButton` lifecycle. Intended for debugging in-app * browsers where remote console access is impractical. Off by default. */ debug?: boolean; } /** * Checkout surface combining hosted vault card capture with wallets, APMs, * and PayPal. Card entry is hosted-vault-only. * * Stripe-hosted PayPal uses its own Elements instance; direct PayPal uses the * official PayPal SDK when the session advertises that gateway. */ declare function SplitCardForm(props: SplitCardFormProps): React.JSX.Element; /** Props for {@link VaultCardFields}. */ interface VaultCardFieldsProps { /** * The card-capture adapter (typically `useFloPay().cardCapture()`). Owns * injecting + bootstrapping the hosted vault widget. Changing this instance * (or {@link VaultCardFieldsProps.html}) remounts the widget. */ capture: CardCaptureAdapter; /** * Server-rendered hosted vault widget HTML (the session's * {@link CheckoutSession.vault} block `html`, or one fetched from * `POST /vault/capture`). The widget owns the card fields, submit button, * tokenization, charge, and 3DS; this component only injects it. */ html: string; /** * Per-session integrity token (the vault block's `messageToken`). Forwarded * to the adapter so it can reject forged terminal `postMessage` outcomes that * omit/mismatch it. Omitted when the backend does not (yet) mint one. */ messageToken?: string; /** * Exact origin expected for the widget's terminal `postMessage` outcomes * (the vault block's `expectedOrigin`). Forwarded to the adapter's origin * gate; omitted to skip it. */ expectedOrigin?: string; /** * Merchant theme colors pushed into the hosted widget so the card form * matches the surrounding checkout. Applied live on change (no remount). * `null` is the explicit classic reset: after a theme was applied it tells * the hosted form to restore every historical neutral value. Omitted (or * `null` from the start) leaves the widget's own defaults untouched. */ theme?: VaultCardThemeColors | null; /** * Final, already-localized wording for the hosted card form's submit button * (e.g. `'Pay $10'`), billing API v1.9.35+. Applied live on change (no * remount, buyer-entered card data kept). `null` is the same as omitting it: * omitting or clearing it after a label was shown restores the session * default (`CONFIRM PAYMENT`, or `ADD CARD` for card setup); blank text also * shows the default. */ submitLabel?: string | null; /** * Inline styles for the container the widget mounts into. Applied as a * whole declaration list in key order on every change (not diffed property * by property), so a shorthand and a longhand of the same family cascade * deterministically across live updates — the surface the card-setup preset * treatment and a merchant `containerStyle` share. */ containerStyle?: React.CSSProperties; /** Fired once the widget is injected and bootstrapping. */ onReady?: () => void; /** * Fired with a load/runtime error message from the widget, or `null` when it * clears. Wired to the card form's shared error banner. Terminal payment * outcomes (`complete` / `decline`) are observed by the parent form directly * off the same adapter and are not surfaced here. */ onError?: (message: string | null) => void; /** * Fired with the widget's inline field-validation message (live, debounced by * the widget to changes), or `null` when validation clears. Surfaced in the * card form's error banner and the merchant `onError`. */ onValidation?: (message: string | null) => void; } /** * Renders the backend-served vault PCI card widget * (TeamFloPay/backend#823, Model A). The hosted widget * is a self-contained form: PAN / CVC, the submit button, the charge, and 3DS * all live inside it. This component only injects the widget HTML through the * {@link CardCaptureAdapter} and bridges its `ready` / `error` lifecycle events * back to the surrounding card form. */ declare function VaultCardFields({ capture, html, messageToken, expectedOrigin, theme, submitLabel, containerStyle, onReady, onError, onValidation, }: VaultCardFieldsProps): React.ReactElement; export { type CheckoutState, DirectPayPalButton, type DirectPayPalButtonProps, type DirectPayPalInitializationState, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, SplitCardForm, type SplitCardFormProps, VaultCardFields, type VaultCardFieldsProps, useCheckout, useFloPay, usePayPalFloPay };