@flopay/react 1.4.0 → 1.4.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/provider.tsx","../src/context.ts","../src/telemetry-bridge.ts","../src/flopay-checkout.tsx","../src/card-button-content.tsx","../src/elements.tsx","../src/split-card-form.tsx","../src/vault-card-fields.tsx","../src/hooks.ts","../src/processing-overlay.tsx","../src/checkout-utils.ts","../src/recent-completion.ts","../src/in-app-browser.ts","../src/direct-paypal-button.tsx","../src/merchant-callback.ts","../src/external-method-recovery.ts","../src/saved-payment-flow.ts","../src/checkout-form.tsx","../src/paypal-button.tsx","../src/automatic-payment-button.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useState, useMemo, useRef } from 'react';\nimport type { FloPay, FloPayElements } from '@flopay/js';\nimport type { FloPayAppearance } from '@flopay/shared';\nimport { resolveBillingApiUrl } from '@flopay/shared';\nimport { FloPayContext } from './context.js';\nimport { getFloPayTelemetryBridge } from './telemetry-bridge.js';\n\n/** Props for the `FloPayProvider` component. */\nexport interface FloPayProviderProps {\n /** A `FloPay` instance or a promise that resolves to one (from `loadFloPay()`). */\n flopay: Promise<FloPay> | FloPay;\n /**\n * Optional Stripe `FloPay` instance used to drive the Stripe-rendered PayPal\n * fallback. When omitted or `null`, the Stripe-rendered PayPal button is\n * not rendered. Direct PayPal (`gateways.paypal`) does not use this prop.\n */\n paypalFlopay?: Promise<FloPay> | FloPay | null;\n /** Optional configuration applied when creating the elements group. */\n options?: {\n locale?: string;\n appearance?: FloPayAppearance;\n clientSecret?: string;\n /** Total amount in smallest currency unit (cents). Used when no clientSecret. */\n amount?: number;\n /** ISO 4217 currency code (lowercase). Used when no clientSecret. */\n currency?: string;\n /** How payment methods are created. 'manual' (default for cards) or 'auto' (needed for PayPal). */\n paymentMethodCreation?: 'manual' | 'auto';\n /** Requests reusable payment credentials for future payments. */\n setupFutureUsage?: 'off_session' | 'on_session';\n /** Billing API base URL. Set once here so child components don't need to repeat it. */\n billingApiUrl?: string;\n };\n children: React.ReactNode;\n}\n\n/**\n * Provides FloPay SDK context to the component tree.\n *\n * Wrap your checkout page (or your entire app) with this provider:\n *\n * ```tsx\n * <FloPayProvider flopay={loadFloPay('pk_test_...')}>\n * <CheckoutForm />\n * </FloPayProvider>\n * ```\n */\nexport function FloPayProvider({\n flopay: floPayProp,\n paypalFlopay: paypalFloPayProp,\n options,\n children,\n}: FloPayProviderProps): React.ReactElement {\n const [flopay, setFloPay] = useState<FloPay | null>(\n floPayProp instanceof Promise ? null : floPayProp,\n );\n const [paypalFlopay, setPaypalFloPay] = useState<FloPay | null>(\n paypalFloPayProp instanceof Promise || !paypalFloPayProp ? null : paypalFloPayProp,\n );\n const [elements, setElements] = useState<FloPayElements | null>(null);\n const mountedAt = useRef<number | null>(null);\n const renderedElements = useRef<FloPayElements | null>(null);\n const interactiveElements = useRef<FloPayElements | null>(null);\n\n useEffect(() => {\n if (!flopay) return;\n const telemetry = getFloPayTelemetryBridge(flopay);\n mountedAt.current = telemetry?.beginCheckout() ?? telemetry?.now() ?? 0;\n telemetry?.log({ name: 'checkout.mount', stage: 'checkout_mount' });\n return () => {\n telemetry?.log({ name: 'checkout.unmount', stage: 'unmount' });\n };\n }, [flopay]);\n\n // Resolve the promise if needed\n useEffect(() => {\n let cancelled = false;\n\n if (floPayProp instanceof Promise) {\n floPayProp.then((instance) => {\n if (!cancelled) {\n setFloPay(instance);\n }\n });\n } else {\n setFloPay(floPayProp);\n }\n\n return () => {\n cancelled = true;\n };\n }, [floPayProp]);\n\n // Resolve the PayPal promise / prop\n useEffect(() => {\n let cancelled = false;\n\n if (!paypalFloPayProp) {\n setPaypalFloPay(null);\n return;\n }\n\n if (paypalFloPayProp instanceof Promise) {\n paypalFloPayProp.then((instance) => {\n if (!cancelled) {\n setPaypalFloPay(instance);\n }\n });\n } else {\n setPaypalFloPay(paypalFloPayProp);\n }\n\n return () => {\n cancelled = true;\n };\n }, [paypalFloPayProp]);\n\n // Create elements group once FloPay is ready\n useEffect(() => {\n if (!flopay) {\n setElements(null);\n return;\n }\n\n const els = flopay.elements({\n appearance: options?.appearance,\n clientSecret: options?.clientSecret,\n amount: options?.amount,\n currency: options?.currency,\n paymentMethodCreation: options?.paymentMethodCreation,\n setupFutureUsage: options?.setupFutureUsage,\n });\n setElements(els);\n\n return () => {\n els.destroy();\n };\n }, [\n flopay,\n options?.appearance,\n options?.clientSecret,\n options?.amount,\n options?.currency,\n options?.paymentMethodCreation,\n options?.setupFutureUsage,\n ]);\n\n // This effect runs only after the elements value has committed through the\n // context, so consumers have rendered with the group before we mark render.\n useEffect(() => {\n if (!flopay || !elements || renderedElements.current === elements) return;\n renderedElements.current = elements;\n const telemetry = getFloPayTelemetryBridge(flopay);\n telemetry?.log({ name: 'checkout.rendered', stage: 'checkout_render' });\n telemetry?.performance({\n stage: 'checkout_render',\n durationMs: telemetry.elapsed(mountedAt.current ?? 0),\n durationMode: 'machine',\n });\n }, [elements, flopay]);\n\n const reportInteractive = useCallback(() => {\n if (!flopay || !elements || interactiveElements.current === elements) return;\n interactiveElements.current = elements;\n const telemetry = getFloPayTelemetryBridge(flopay);\n telemetry?.log({ name: 'checkout.interactive', stage: 'checkout_interactive' });\n telemetry?.performance({\n stage: 'checkout_interactive',\n durationMs: telemetry.elapsed(mountedAt.current ?? 0),\n durationMode: 'machine',\n });\n }, [elements, flopay]);\n\n const resolvedBillingApiUrl = resolveBillingApiUrl(options?.billingApiUrl);\n\n const value = useMemo(\n () => ({\n flopay,\n paypalFlopay,\n elements,\n billingApiUrl: resolvedBillingApiUrl,\n reportInteractive,\n }),\n [flopay, paypalFlopay, elements, resolvedBillingApiUrl, reportInteractive],\n );\n\n return (\n <FloPayContext.Provider value={value}>\n {children}\n </FloPayContext.Provider>\n );\n}\n","import { createContext } from 'react';\nimport type { FloPay, FloPayElements } from '@flopay/js';\nimport type {\n CheckoutMode,\n CheckoutSession,\n FloPayError,\n InlineSessionDraft,\n InlineSessionPatch,\n} from '@flopay/shared';\n\n/** Internal context value for the FloPay provider. */\nexport interface FloPayContextValue {\n flopay: FloPay | null;\n /**\n * Stripe FloPay instance used for the Stripe-rendered PayPal fallback. When\n * direct PayPal (`gateways.paypal`) is configured this isn't used for\n * rendering — DirectPayPalButton talks to PayPal directly — but the\n * Stripe-PayPal saved-PM redirect leg still relies on it.\n * `null` or absent means the Stripe-rendered PayPal fallback is unavailable.\n */\n paypalFlopay?: FloPay | null;\n elements: FloPayElements | null;\n billingApiUrl: string;\n /** Report the first provider control that reaches its actual ready boundary. */\n reportInteractive?: () => void;\n}\n\n/** Internal context value for checkout state. */\nexport interface CheckoutContextValue {\n session: CheckoutSession | null;\n loading: boolean;\n error: FloPayError | null;\n checkoutMode?: CheckoutMode;\n inlineSessionDraft?: InlineSessionDraft;\n applyInlineSessionPatch?: (\n patch: InlineSessionPatch,\n ) => Promise<{ sessionId: string; session: CheckoutSession | null }>;\n inlineSessionPatchProcessing?: boolean;\n}\n\nexport const FloPayContext = createContext<FloPayContextValue>({\n flopay: null,\n paypalFlopay: null,\n elements: null,\n billingApiUrl: '',\n});\n\nexport const CheckoutContext = createContext<CheckoutContextValue>({\n session: null,\n loading: false,\n error: null,\n});\n","import type { FloPay } from '@flopay/js';\nimport type {\n BuildTelemetryErrorEventInput,\n BuildTelemetryLogEventInput,\n BuildTelemetryPerformanceEventInput,\n BuildTelemetryTerminalEventInput,\n TelemetryCheckoutMode,\n TelemetryLayout,\n TelemetrySdkPackage,\n} from '@flopay/shared';\n\nexport type TelemetryErrorInput = Omit<\n BuildTelemetryErrorEventInput,\n 'eventId' | 'sequence'\n>;\nexport type TelemetryLogInput = Omit<\n BuildTelemetryLogEventInput,\n 'eventId' | 'sequence'\n>;\nexport type TelemetryPerformanceInput = Omit<\n BuildTelemetryPerformanceEventInput,\n 'eventId' | 'sequence'\n>;\nexport type TelemetryTerminalInput = Omit<\n BuildTelemetryTerminalEventInput,\n 'eventId' | 'sequence'\n>;\n\nexport interface TelemetryCheckoutContext {\n checkoutMode?: TelemetryCheckoutMode;\n layout?: TelemetryLayout;\n}\n\nexport interface TelemetryBridge {\n error(input: TelemetryErrorInput): void;\n log(input: TelemetryLogInput): void;\n performance(input: TelemetryPerformanceInput): void;\n terminal(input: TelemetryTerminalInput): void;\n now(): number;\n elapsed(startedAt: number): number;\n setCheckoutContext(context: TelemetryCheckoutContext): void;\n beginCheckout(context?: TelemetryCheckoutContext): number;\n disable(): void;\n flush(): Promise<void>;\n destroy(): void;\n}\n\ninterface ReporterFactoryOptions {\n billingApiUrl: string;\n sdkPackage?: TelemetrySdkPackage;\n sdkVersion: string;\n enabled?: boolean;\n clock?: () => number;\n}\n\nconst FLOPAY_TELEMETRY_BRIDGE = Symbol.for('@flopay/js.telemetry.bridge.v1');\nconst TELEMETRY_REPORTER_FACTORY = Symbol.for('@flopay/js.telemetry.reporter-factory.v1');\n\nfunction noopTelemetryBridge(): TelemetryBridge {\n return {\n error: () => {},\n log: () => {},\n performance: () => {},\n terminal: () => {},\n now: () => globalThis.performance?.now() ?? 0,\n elapsed: (startedAt) => Math.max(0, (globalThis.performance?.now() ?? startedAt) - startedAt),\n setCheckoutContext: () => {},\n beginCheckout: () => globalThis.performance?.now() ?? 0,\n disable: () => {},\n flush: async () => {},\n destroy: () => {},\n };\n}\n\nfunction normalizeTelemetryBridge(source: Partial<TelemetryBridge>): TelemetryBridge {\n const fallback = noopTelemetryBridge();\n const bind = <T extends (...args: never[]) => unknown>(\n candidate: T | undefined,\n defaultValue: T,\n ): T => candidate ? candidate.bind(source) as T : defaultValue;\n const now = bind(source.now, fallback.now);\n return {\n error: bind(source.error, fallback.error),\n log: bind(source.log, fallback.log),\n performance: bind(source.performance, fallback.performance),\n terminal: bind(source.terminal, fallback.terminal),\n now,\n elapsed: source.elapsed\n ? source.elapsed.bind(source)\n : (startedAt) => Math.max(0, now() - startedAt),\n setCheckoutContext: bind(source.setCheckoutContext, fallback.setCheckoutContext),\n beginCheckout: bind(source.beginCheckout, fallback.beginCheckout),\n disable: bind(source.disable, fallback.disable),\n flush: bind(source.flush, fallback.flush),\n destroy: bind(source.destroy, fallback.destroy),\n };\n}\n\nexport function createTelemetryBridge(options: ReporterFactoryOptions): TelemetryBridge {\n const factory = (\n (globalThis as Record<PropertyKey, unknown>)[TELEMETRY_REPORTER_FACTORY]\n ) as ((input: ReporterFactoryOptions) => TelemetryBridge) | undefined;\n return normalizeTelemetryBridge(factory?.(options) ?? {});\n}\n\nexport function getFloPayTelemetryBridge(\n floPay: FloPay | null | undefined,\n): TelemetryBridge | undefined {\n if (!floPay) return undefined;\n return (\n (floPay as unknown as Record<PropertyKey, unknown>)[FLOPAY_TELEMETRY_BRIDGE]\n ) as TelemetryBridge | undefined;\n}\n\n/** Test helper for attaching the same hidden bridge shape to a fake FloPay. */\nexport function attachTelemetryBridgeForTest(\n floPay: object,\n bridge: Partial<TelemetryBridge>,\n): void {\n const replacement = normalizeTelemetryBridge(bridge);\n const existing = getFloPayTelemetryBridge(floPay as FloPay);\n if (existing) {\n Object.assign(existing, replacement);\n return;\n }\n Object.defineProperty(floPay, FLOPAY_TELEMETRY_BRIDGE, {\n configurable: true,\n value: replacement,\n });\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { PaymentAPI } from '@flopay/js';\nimport type { FloPay } from '@flopay/js';\nimport type {\n BeforeButtonClickEvent,\n CheckoutButtonMethod,\n FloPayAppearance,\n DeclineEvent,\n InlineSessionDraft,\n InlineSessionParams,\n InlineSessionPatch,\n PaymentResult,\n CheckoutSession,\n CheckoutMode,\n NormalizedCheckoutSession,\n} from '@flopay/shared';\nimport { SDK_VERSION, FloPayError, resolveBillingApiUrl, buildCheckoutDisplayData, resolveButtonsLayoutTheme, resolveTheme } from '@flopay/shared';\nimport type { ButtonsLayoutStyles, ButtonsLayoutTheme } from '@flopay/shared';\nimport {\n BackButtonContentSlot,\n CardButtonContentSlot,\n TitleContentSlot,\n isEmptySlotContent,\n} from './card-button-content.js';\nimport { FloPayProvider } from './provider.js';\nimport { SplitCardForm } from './split-card-form.js';\nimport { InstrumentedDirectPayPalButton } from './direct-paypal-button.js';\nimport { CheckoutContext } from './context.js';\nimport {\n buildDeclineEvent,\n buildSyntheticSession,\n mapPayPalIntentStatusToPaymentResult,\n mergeInlineSessionPatch,\n mergeInlineSessionPatches,\n} from './checkout-utils.js';\nimport {\n PROCESSING_OVERLAY_ERROR_DELAY_MS,\n PROCESSING_OVERLAY_SUCCESS_DELAY_MS,\n ProcessingOverlay,\n type OverlayStatus,\n} from './processing-overlay.js';\nimport {\n checkoutProcessErrorToFloPayError,\n DEFAULT_SAVED_PAYMENT_DECLINE_METHOD,\n getRedirectResultFromCheckoutProcessError,\n handleSavedPaymentRedirectResult,\n loadSavedPaymentProviders,\n normalizeSavedPaymentError,\n processSavedPaymentForMode,\n resolveSavedPaymentPublishableKeys,\n} from './saved-payment-flow.js';\nimport { markSessionRecentlyCompleted, wasSessionRecentlyCompleted } from './recent-completion.js';\nimport {\n createTelemetryBridge,\n getFloPayTelemetryBridge,\n} from './telemetry-bridge.js';\nimport type { TelemetryBridge, TelemetryCheckoutContext } from './telemetry-bridge.js';\nimport { invokeMerchantCallback } from './merchant-callback.js';\n\nconst DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;\nconst PAYPAL_RESUME_STORAGE_KEY = 'flopay_checkout_saved_payment_resume';\n\n// Module-scoped dedup map: cache key → in-flight `POST /v1/checkouts/sessions`\n// promise. Lives for the page-load only. Shared across every FloPayCheckout\n// instance so two mounts that race (StrictMode dev double-mount, Suspense\n// remount, navigation flicker, etc.) await the same POST instead of starting\n// their own and producing two backend sessions for the same cart.\n// `sessionStorage[cacheKey]` is the durable cross-page-load layer; this Map\n// is the within-page-load layer that closes the window between \"POST is in\n// flight\" and \"POST result has been written to sessionStorage\".\nconst sessionInflightMap: Map<string, Promise<{ sid: string; result: NormalizedCheckoutSession }>> = new Map();\n\n// Cross-module signal for \"this session was just /process'd successfully and\n// is mid-completion.\" Lives in sessionStorage (see `recent-completion.ts`) so\n// it survives both real component remounts and the cross-module boundary\n// between SplitCardForm (where /process succeeds) and this file (where\n// `resolveInlineSession` decides whether to clear a complete-status cache\n// hit). Marker is written *before* the 1.2s overlay delay in SplitCardForm,\n// so a bootstrap that re-runs during that delay still detects the session\n// as \"this journey's completion\" and reuses it.\ntype CheckoutLogType = 'standard_checkout' | 'embedded_checkout';\ntype CheckoutLogLayout = 'default_layout' | 'buttons_layout' | 'custom_layout';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction createStandaloneTelemetryReporter(\n billingApiUrl: string,\n enabled: boolean | undefined,\n context: TelemetryCheckoutContext,\n): TelemetryBridge {\n const reporter = createTelemetryBridge({\n billingApiUrl,\n sdkPackage: '@flopay/react',\n sdkVersion: SDK_VERSION,\n enabled: enabled !== false,\n });\n reporter.beginCheckout(context);\n return reporter;\n}\n\nfunction finishStandaloneTelemetry(reporter: TelemetryBridge): void {\n void reporter.flush()\n .catch(() => {})\n .finally(() => reporter.destroy());\n}\n\nfunction reportStandaloneTelemetryError(\n billingApiUrl: string,\n enabled: boolean | undefined,\n context: TelemetryCheckoutContext,\n errorCode:\n | 'CHECKOUT_SESSION_CREATE_FAILED'\n | 'NETWORK_REQUEST_FAILED'\n | 'REDIRECT_RESUME_FAILED'\n | 'RECOVERY_FAILED'\n | 'INTERNAL_SDK_ERROR',\n stage:\n | 'session_create'\n | 'session_read'\n | 'redirect_resume'\n | 'recovery'\n | 'checkout_mount',\n): void {\n const reporter = createStandaloneTelemetryReporter(billingApiUrl, enabled, context);\n reporter.error({\n errorCode,\n stage,\n paymentMethodCategory: 'unknown',\n ...(stage === 'session_read' ? { requestCategory: 'session_read' as const } : {}),\n });\n finishStandaloneTelemetry(reporter);\n}\n\nfunction isExpectedExistingSessionError(error: FloPayError): boolean {\n return error.type === 'validation_error'\n || error.code === 'checkout_session_not_found'\n || error.code === 'checkout_session_expired'\n || error.code === 'checkout_session_completed'\n || error.code === 'session_auto_completed';\n}\n\ninterface PayPalResumeState {\n sessionId: string | null;\n publishableKey: string;\n paypalPublishableKey?: string;\n}\n\ninterface DirectPayPalConfig {\n clientId: string;\n environment?: import('@flopay/shared').GatewayEnvironment;\n}\n\nfunction resolveDirectPaypalConfig(\n unified: NormalizedCheckoutSession | null,\n): DirectPayPalConfig | undefined {\n const clientId = unified?.data.paypal?.publishableKey;\n if (!clientId) return undefined;\n return {\n clientId,\n environment: unified?.data.paypal?.environment,\n };\n}\n\nfunction isPayPalOnlyUnified(unified: NormalizedCheckoutSession | null): boolean {\n if (!unified) return false;\n if (unified.data.stripe?.publishableKey) return false;\n return Boolean(resolveDirectPaypalConfig(unified)?.clientId);\n}\n\nfunction canUseStorage() {\n return typeof window !== 'undefined' && typeof window.sessionStorage !== 'undefined';\n}\n\nfunction readPayPalResumeState(): PayPalResumeState | null {\n if (!canUseStorage()) return null;\n\n try {\n const raw = window.sessionStorage.getItem(PAYPAL_RESUME_STORAGE_KEY);\n if (!raw) return null;\n return JSON.parse(raw) as PayPalResumeState;\n } catch {\n return null;\n }\n}\n\nfunction persistPayPalResumeState(state: PayPalResumeState) {\n if (!canUseStorage()) return;\n\n try {\n window.sessionStorage.setItem(PAYPAL_RESUME_STORAGE_KEY, JSON.stringify(state));\n } catch (error) {\n console.warn('[FloPayCheckout] Failed to persist PayPal resume state.', error);\n }\n}\n\nfunction clearPayPalResumeState() {\n if (!canUseStorage()) return;\n\n try {\n window.sessionStorage.removeItem(PAYPAL_RESUME_STORAGE_KEY);\n } catch (error) {\n console.warn('[FloPayCheckout] Failed to clear PayPal resume state.', error);\n }\n}\n\ninterface CachedInlineSession {\n sid: string;\n nonce?: string;\n}\n\n// The inline-session cache stores the session id *and* its bound nonce: the\n// backend (TeamFloPay/backend#640) rejects a session GET that omits the matching\n// `x-checkout-session-token`, so a bare id can no longer re-fetch a cached\n// session (it 401s). Legacy entries — a bare id string written before nonces\n// were cached — are tolerated on read; they simply miss the nonce and fall\n// through to a fresh create.\nfunction readCachedInlineSession(cacheKey: string): CachedInlineSession | null {\n if (!canUseStorage()) return null;\n\n const raw = window.sessionStorage.getItem(cacheKey);\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as Partial<CachedInlineSession>;\n if (parsed && typeof parsed.sid === 'string' && parsed.sid) {\n return { sid: parsed.sid, nonce: typeof parsed.nonce === 'string' ? parsed.nonce : undefined };\n }\n return null;\n } catch {\n // Legacy bare-id string from before the nonce was cached.\n return { sid: raw };\n }\n}\n\nfunction persistCachedInlineSession(cacheKey: string, sid: string, nonce?: string) {\n if (!canUseStorage()) return;\n\n try {\n window.sessionStorage.setItem(cacheKey, JSON.stringify(nonce ? { sid, nonce } : { sid }));\n } catch (error) {\n console.warn('[FloPayCheckout] Failed to persist checkout session cache.', error);\n }\n}\n\nfunction clearCachedInlineSession(cacheKey: string) {\n if (!canUseStorage()) return;\n\n try {\n window.sessionStorage.removeItem(cacheKey);\n } catch (error) {\n console.warn('[FloPayCheckout] Failed to clear checkout session cache.', error);\n }\n}\n\nfunction clearPayPalRedirectParams() {\n if (typeof window === 'undefined') return;\n\n const url = new URL(window.location.href);\n const keys = ['payment_intent', 'payment_intent_client_secret', 'redirect_status'];\n let changed = false;\n\n for (const key of keys) {\n if (url.searchParams.has(key)) {\n url.searchParams.delete(key);\n changed = true;\n }\n }\n\n if (changed) {\n window.history.replaceState(window.history.state, '', url.toString());\n }\n}\n\nfunction replaceCheckoutModeQueryParam(mode: CheckoutMode) {\n if (typeof window === 'undefined') return;\n\n const url = new URL(window.location.href);\n url.searchParams.set('mode', mode);\n window.history.replaceState(window.history.state, '', url.toString());\n}\n\n/** Props for the all-in-one `FloPayCheckout` wrapper. */\nexport interface FloPayCheckoutProps {\n /** The checkout session ID (UUID from billing API). Required unless `createSession` is provided. */\n sessionId?: string;\n /**\n * Session-bound checkout token (the `nonce` returned when the session was\n * created). Sent as the `x-checkout-session-token` header when fetching a\n * session by `sessionId`. Required by post-#640 backends, which no longer\n * let the UUID alone authorize a session read; harmless on older backends.\n * Only consulted in the `sessionId` flow — inline `createSession` sessions\n * carry their own freshly-minted nonce server-side.\n */\n nonce?: string;\n /**\n * Create a checkout session inline — no separate API route needed.\n * The component POSTs to the billing API, gets the full session back, and renders the form.\n * Alternative to `sessionId` (provide one or the other).\n */\n createSession?: InlineSessionDraft;\n /** Billing API base URL. Defaults to the shared `BILLING_API_URL` constant. */\n billingApiUrl?: string;\n /** Flo-owned privacy-safe telemetry is enabled by default; set `false` to opt out. */\n telemetry?: boolean;\n /** Visual appearance for payment elements. */\n appearance?: FloPayAppearance;\n /** Locale for payment elements (default: 'auto'). */\n locale?: string;\n /** Custom loading UI. Defaults to a simple centered spinner. */\n loading?: React.ReactNode;\n /** Custom error UI. Receives the error. Defaults to showing the error message. */\n error?: (error: FloPayError) => React.ReactNode;\n /** Called when the full payment flow completes successfully. */\n onComplete?: (result: PaymentResult) => void;\n /** Called when a payment error occurs. */\n onError?: (error: FloPayError) => void;\n /** Called when a payment is declined or the authentication step fails. */\n onDecline?: (decline: DeclineEvent) => void;\n /** Called when the full cardholder name input changes. */\n onFullNameChange?: (value: string) => void;\n /** Called when the AVS country dropdown changes. */\n onCountryChange?: (country: string) => void;\n /** Called when the AVS ZIP/postcode input changes. */\n onZipChange?: (zip: string) => void;\n /**\n * Show the PayPal payment surface (default: `true`). Renderer is chosen\n * from `gateways.paypal` on the session — DirectPayPalButton when present,\n * Stripe-rendered PayPal otherwise.\n */\n showPayPal?: boolean;\n /**\n * Show the Stripe-rendered checkout — card fields, ExpressCheckoutElement,\n * and the PaymentElement accordion (default: `true`). When `false`, only\n * `DirectPayPalButton` can render. Both `showStripe=false` and\n * `showPayPal=false` (with no PayPal gateway configured) triggers a\n * bootstrap-time validation error.\n */\n showStripe?: boolean;\n /**\n * @deprecated Apple Pay availability is now driven by\n * `gateways.stripe.enabledPaymentMethods` on the per-session response from\n * the billing API. Setting this prop emits a one-time deprecation warning\n * and is otherwise ignored once the backend ships the list.\n */\n showApplePay?: boolean;\n /**\n * @deprecated See {@link FloPayCheckoutProps.showApplePay}.\n */\n showGooglePay?: boolean;\n /**\n * Enables on-screen diagnostic panels (PayPal gate decision, DirectPayPalButton\n * lifecycle). Intended for debugging in-app browsers (Facebook, Instagram, etc.)\n * where remote console access is impractical. Off by default.\n */\n debug?: boolean;\n /** Layout mode: 'default' (all visible) or 'buttons' (PayPal/wallets + expandable card form). */\n layout?: 'default' | 'buttons';\n /**\n * High-level theme bundle that styles both the Stripe-side appearance and\n * the FloPay wrapper / submit / inputs. One of: `'classic'` (historic FloPay\n * look, no bundle applied), `'modern-light'`, `'modern-dark'`,\n * `'bold-light'`, `'bold-dark'`, `'glass-light'`, `'glass-dark'`. Explicit\n * `appearance` / `buttonsStyles` props still override their respective\n * halves when supplied.\n */\n theme?: import('@flopay/shared').ThemeId;\n /**\n * @deprecated Use `theme` instead. Legacy buttons-layout preset\n * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for\n * back-compat.\n */\n buttonsTheme?: import('@flopay/shared').ButtonsLayoutTheme;\n /** Style overrides merged on top of the resolved theme bundle / buttonsTheme preset. */\n buttonsStyles?: import('@flopay/shared').ButtonsLayoutStyles;\n /** Custom React content rendered inside the card button when `layout=\"buttons\"`. */\n cardButtonContent?: React.ReactNode;\n /** Custom React content rendered for the buttons-layout card back button label. */\n cardBackButtonContent?: React.ReactNode;\n /** Custom React content rendered for the card-form title. */\n cardTitleContent?: React.ReactNode;\n /**\n * @deprecated No longer rendered — the default-layout security footer was\n * removed alongside the theme-bundle refactor. Retained as an optional\n * prop so existing integrations type-check without changes.\n */\n showSecurityFooter?: boolean;\n /**\n * Called when a payment method button is clicked.\n * `method`: `'card'` | `'paypal'` | `'apple_pay'` | `'google_pay'`\n */\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n /**\n * Called before a payment button continues in `layout=\"buttons\"`.\n * Runs for card, PayPal, Apple Pay, and Google Pay.\n * In `layout=\"buttons\"` with `createSession`, the returned patch is merged\n * into the inline session params before the selected flow continues.\n */\n onBeforeButtonClick?: (\n event: BeforeButtonClickEvent,\n ) => void | false | Promise<void | false | InlineSessionPatch> | InlineSessionPatch;\n /**\n * Enable AVS (Address Verification).\n * - `true` — show country + postal code (backward compatible default)\n * - `AVSFieldConfig` — granular per-field control, optionally scoped to country codes\n * - `false` / omitted — AVS disabled\n */\n enableAVS?: boolean | import('@flopay/shared').AVSFieldConfig;\n /**\n * Per-merchant order of the hosted vault card rows — a permutation of\n * `['name','number','expiry']` (`'expiry'` = the expiry+CVV row; submit stays\n * last). Sets both the visual and tab order. Omit for the default\n * (`name`, `number`, `expiry`). Vault card path only.\n */\n cardFieldOrder?: import('@flopay/shared').VaultCardFieldKey[];\n /**\n * Content rendered directly above the card form (below the \"or pay with card\"\n * divider, above the card fields). Used by the demo playground to surface a\n * test-cards helper; harmless to omit in a normal integration.\n */\n cardPreFormSlot?: React.ReactNode;\n /** Layout for AVS fields: 'row' (side-by-side, default) or 'column' (stacked). */\n avsLayout?: 'row' | 'column';\n /** Label for the submit button. */\n submitLabel?: string;\n /** Additional CSS class for the wrapper. */\n className?: string;\n /** Seed an initial checkout error message for the rendered payment form. */\n initialErrorMessage?: string | null;\n /**\n * Override the default `SplitCardForm`. When provided, children are rendered\n * inside the initialized `FloPayProvider` with session props auto-injected.\n */\n children?: React.ReactNode;\n\n // ── Checkout mode props ──\n\n /**\n * Override the session's checkoutMode.\n * - `'full'` — show payment form (default)\n * - `'confirm'` — show confirm button, uses saved payment method\n * - `'auto'` — auto-submit with saved PM, falls back to `'full'` on failure\n */\n checkoutMode?: CheckoutMode;\n /** Label for the confirm button in `confirm` mode. Default: `'Confirm Purchase'`. */\n confirmLabel?: string;\n /** Custom confirm button renderer for `confirm` mode. */\n renderConfirmButton?: (props: {\n onConfirm: () => void;\n isProcessing: boolean;\n }) => React.ReactNode;\n /** Called when the session has already been completed. Receives the successUrl. */\n onSessionCompleted?: (successUrl: string) => void;\n\n /**\n * @deprecated No longer used. The Stripe publishable key is sourced exclusively\n * from the checkout session's `gateways.stripe.publishableKey`. Accepted only\n * for backward compatibility with older consumer code — the value is ignored.\n */\n fallbackPublishableKey?: string;\n}\n\nfunction hasInlineSessionPatchData(\n patch: InlineSessionPatch | undefined,\n): boolean {\n if (!patch) return false;\n\n return Boolean(\n (patch.account && Object.keys(patch.account).length > 0)\n || patch.couponCodes !== undefined\n || patch.tagsData !== undefined\n || patch.utmMetadata !== undefined,\n );\n}\n\n/**\n * All-in-one checkout component. Fetches the session, initializes the\n * payment provider, and renders the appropriate UI based on checkout mode.\n *\n * **Modes:**\n * - `full` (default) — renders `SplitCardForm` with card fields + wallet buttons\n * - `confirm` — renders a \"Confirm Purchase\" button, uses saved payment method\n * - `auto` — auto-submits with saved PM, falls back to `full` on failure\n *\n * ```tsx\n * <FloPayCheckout\n * sessionId=\"sess_abc123\"\n * onComplete={(result) => router.push('/success')}\n * onError={(err) => console.error(err)}\n * />\n * ```\n */\nexport function FloPayCheckout({\n sessionId: sessionIdProp,\n nonce: nonceProp,\n createSession: createSessionParams,\n billingApiUrl,\n telemetry,\n appearance: appearanceOverride,\n locale,\n loading: loadingNode,\n error: errorNode,\n onComplete,\n onError,\n onDecline,\n onFullNameChange,\n onCountryChange,\n onZipChange,\n showPayPal = true,\n showStripe = true,\n showApplePay = true,\n showGooglePay = true,\n debug = false,\n layout,\n theme,\n buttonsTheme,\n buttonsStyles,\n cardButtonContent,\n cardBackButtonContent,\n cardTitleContent,\n showSecurityFooter: _showSecurityFooter,\n onButtonClick,\n onBeforeButtonClick,\n enableAVS,\n cardFieldOrder,\n cardPreFormSlot,\n avsLayout,\n submitLabel,\n className,\n initialErrorMessage = null,\n children,\n checkoutMode: checkoutModeProp,\n confirmLabel,\n renderConfirmButton,\n onSessionCompleted,\n}: FloPayCheckoutProps): React.ReactElement {\n const resolvedBillingUrl = resolveBillingApiUrl(billingApiUrl);\n // High-level `theme` resolves to a coherent {appearance, buttonsLayout}\n // bundle from `@flopay/shared`'s `THEMES` map. Explicit `appearance` /\n // `buttonsStyles` props still win — see the precedence comment in\n // `SplitCardForm`.\n const themeBundle = useMemo(() => resolveTheme(theme), [theme]);\n const appearance = appearanceOverride ?? themeBundle?.appearance;\n const checkoutType: CheckoutLogType = createSessionParams ? 'embedded_checkout' : 'standard_checkout';\n const checkoutLayout: CheckoutLogLayout = children\n ? 'custom_layout'\n : layout === 'buttons'\n ? 'buttons_layout'\n : 'default_layout';\n\n const [unified, setUnified] = useState<NormalizedCheckoutSession | null>(null);\n const [flopay, setFloPay] = useState<FloPay | null>(null);\n const flopayRef = useRef<FloPay | null>(null);\n const [paypalFlopay, setPaypalFloPay] = useState<FloPay | null>(null);\n const paypalFlopayRef = useRef<FloPay | null>(null);\n const [session, setSession] = useState<CheckoutSession | null>(null);\n const [resolvedSessionId, setResolvedSessionId] = useState<string>(sessionIdProp ?? '');\n const activeSessionId = sessionIdProp ?? resolvedSessionId;\n const initSessionDependency = createSessionParams ? '' : activeSessionId;\n const [isLoading, setIsLoading] = useState(true);\n const [loadError, setLoadError] = useState<FloPayError | null>(null);\n const [currentMode, setCurrentMode] = useState<CheckoutMode>('full');\n const [confirmProcessing, setConfirmProcessing] = useState(false);\n const [modeError, setModeError] = useState<string | null>(initialErrorMessage);\n const [modeOverlayStatus, setModeOverlayStatus] = useState<OverlayStatus | null>(null);\n const [modeOverlayError, setModeOverlayError] = useState<string | null>(null);\n const [createSessionPatch, setCreateSessionPatch] = useState<InlineSessionPatch | undefined>(undefined);\n const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = useState('');\n const [cardBootstrapPending, setCardBootstrapPending] = useState(false);\n const autoCheckoutAttempted = useRef(false);\n const paypalResumeAttempted = useRef(false);\n const savedPaymentKeysRef = useRef<{\n publishableKey?: string;\n paypalPublishableKey?: string;\n } | null>(null);\n const telemetryCheckoutContext = useMemo<TelemetryCheckoutContext>(() => ({\n checkoutMode: checkoutModeProp ?? currentMode,\n layout: children ? 'unknown' : layout === 'buttons' ? 'buttons' : 'embedded',\n }), [checkoutModeProp, children, currentMode, layout]);\n\n // Store callbacks in refs to avoid re-triggering the init useEffect\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onDeclineRef = useRef(onDecline);\n onDeclineRef.current = onDecline;\n\n useEffect(() => {\n getFloPayTelemetryBridge(flopay)?.setCheckoutContext(telemetryCheckoutContext);\n if (paypalFlopay && paypalFlopay !== flopay) {\n getFloPayTelemetryBridge(paypalFlopay)?.setCheckoutContext(telemetryCheckoutContext);\n }\n }, [flopay, paypalFlopay, telemetryCheckoutContext]);\n const onSessionCompletedRef = useRef(onSessionCompleted);\n onSessionCompletedRef.current = onSessionCompleted;\n\n useEffect(() => {\n console.info('[FloPay] Checkout initialized', {\n sdk_version: SDK_VERSION,\n checkout_type: checkoutType,\n checkout_layout: checkoutLayout,\n billing_api_url: resolvedBillingUrl,\n });\n }, [checkoutLayout, checkoutType, resolvedBillingUrl]);\n\n const baseCreateSessionHash = useMemo(\n () => createSessionParams ? hashCreateParams(createSessionParams) : '',\n [createSessionParams],\n );\n const activeCreateSessionPatch = useMemo(\n () => createSessionPatchBaseHash === baseCreateSessionHash\n ? createSessionPatch\n : undefined,\n [createSessionPatch, createSessionPatchBaseHash, baseCreateSessionHash],\n );\n const effectiveCreateSessionBase = useMemo(\n () => createSessionParams\n ? mergeInlineSessionPatch(createSessionParams, activeCreateSessionPatch)\n : undefined,\n [createSessionParams, activeCreateSessionPatch],\n );\n const effectiveCreateSessionMode = checkoutModeProp ?? effectiveCreateSessionBase?.checkoutMode ?? 'full';\n const effectiveCreateSession = useMemo(\n () => effectiveCreateSessionBase\n ? {\n ...effectiveCreateSessionBase,\n checkoutMode: effectiveCreateSessionMode,\n }\n : undefined,\n [effectiveCreateSessionBase, effectiveCreateSessionMode],\n );\n\n useEffect(() => {\n setCreateSessionPatch(undefined);\n setCreateSessionPatchBaseHash(baseCreateSessionHash);\n }, [baseCreateSessionHash]);\n\n useEffect(() => {\n setModeError(initialErrorMessage);\n }, [initialErrorMessage]);\n\n const emitDecline = useCallback(\n (\n method: CheckoutButtonMethod,\n input: string | FloPayError,\n overrides?: { code?: string; declineCode?: string },\n ) => {\n invokeMerchantCallback(() => {\n onDeclineRef.current?.(buildDeclineEvent(method, input, overrides));\n });\n },\n [invokeMerchantCallback],\n );\n\n const runSavedPaymentFlow = useCallback(\n async (\n sess: CheckoutSession,\n options?: {\n attempt3DS?: boolean;\n fallbackToFull?: boolean;\n ensureProvidersReady?: () => Promise<unknown>;\n fromCreateSession?: boolean;\n initialAutoProcessingError?: NormalizedCheckoutSession['autoProcessingError'];\n initialAutoProcessingPending?: NormalizedCheckoutSession['autoProcessingPending'];\n autoProcessingAttempted?: boolean;\n sessionId?: string;\n },\n ): Promise<boolean> => {\n setModeError(null);\n setModeOverlayError(null);\n setModeOverlayStatus('processing');\n\n const activeSessionId = options?.sessionId ?? sess.id;\n const activeFloPay = flopayRef.current ?? paypalFlopayRef.current;\n const activeTelemetry = getFloPayTelemetryBridge(activeFloPay);\n const standaloneTelemetry = activeFloPay\n ? null\n : createStandaloneTelemetryReporter(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n );\n const telemetrySource = {\n log: (input: Parameters<TelemetryBridge['log']>[0]) => {\n if (activeTelemetry) activeTelemetry.log(input);\n else standaloneTelemetry?.log(input);\n },\n error: (input: Parameters<TelemetryBridge['error']>[0]) => {\n if (activeTelemetry) activeTelemetry.error(input);\n else standaloneTelemetry?.error(input);\n },\n terminal: (input: Parameters<TelemetryBridge['terminal']>[0]) => {\n if (activeTelemetry) activeTelemetry.terminal(input);\n else standaloneTelemetry?.terminal(input);\n },\n performance: (input: Parameters<TelemetryBridge['performance']>[0]) => {\n if (activeTelemetry) activeTelemetry.performance(input);\n else standaloneTelemetry?.performance(input);\n },\n now: () => activeTelemetry?.now() ?? standaloneTelemetry?.now() ?? 0,\n elapsed: (startedAt: number) => activeTelemetry?.elapsed(startedAt)\n ?? Math.max(0, (standaloneTelemetry?.now() ?? startedAt) - startedAt),\n };\n const processingStartedAt = telemetrySource.now();\n let recoveryFlow = Boolean(\n options?.initialAutoProcessingError || options?.initialAutoProcessingPending,\n );\n let recoveryStarted = false;\n let recoveryStartedAt: number | undefined;\n const startRecovery = () => {\n if (recoveryStarted) return;\n recoveryStarted = true;\n recoveryFlow = true;\n recoveryStartedAt = telemetrySource.now();\n telemetrySource.log({\n name: 'checkout.recovery.started',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.log({\n name: 'operation.recovery.started',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n };\n let processingFinished = false;\n const finishProcessing = () => {\n if (processingFinished) return;\n processingFinished = true;\n telemetrySource.log({\n name: 'payment.processing.completed',\n stage: 'processing',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.performance({\n stage: 'processing',\n durationMs: telemetrySource.elapsed(processingStartedAt),\n durationMode: 'machine',\n paymentMethodCategory: 'saved',\n });\n if (recoveryStartedAt !== undefined) {\n telemetrySource.performance({\n stage: 'recovery',\n durationMs: telemetrySource.elapsed(recoveryStartedAt),\n durationMode: 'machine',\n paymentMethodCategory: 'saved',\n });\n }\n };\n telemetrySource.log({\n name: 'payment.method.selected',\n stage: 'processing',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.log({\n name: 'payment.processing.started',\n stage: 'processing',\n paymentMethodCategory: 'saved',\n });\n if (recoveryFlow) {\n startRecovery();\n }\n\n let completionCallback: (() => unknown) | undefined;\n try {\n const redirectResult = getRedirectResultFromCheckoutProcessError(options?.initialAutoProcessingError);\n let paymentResult: PaymentResult;\n\n if (redirectResult) {\n startRecovery();\n if (\n redirectResult.type === 'paypal_redirect_required'\n && savedPaymentKeysRef.current?.publishableKey\n ) {\n persistPayPalResumeState({\n sessionId: activeSessionId,\n publishableKey: savedPaymentKeysRef.current.publishableKey,\n paypalPublishableKey: savedPaymentKeysRef.current.paypalPublishableKey,\n });\n }\n\n paymentResult = await handleSavedPaymentRedirectResult(redirectResult, {\n flopay: flopayRef.current,\n paypalFlopay: paypalFlopayRef.current,\n attempt3DS: options?.attempt3DS,\n billingApiUrl: resolvedBillingUrl,\n sessionId: activeSessionId,\n session: sess,\n telemetry: false,\n });\n\n if (redirectResult.type === 'paypal_redirect_required') {\n clearPayPalResumeState();\n }\n } else if (options?.initialAutoProcessingPending) {\n const api = new PaymentAPI(resolvedBillingUrl, { telemetry: false });\n const completed = await api.waitForCheckoutSessionCompletion(options.initialAutoProcessingPending.sessionId, {\n initialDelayMs: options.initialAutoProcessingPending.retryAfterMs,\n });\n\n if (completed.data.session?.status !== 'complete') {\n throw new FloPayError('Automatic payment failed. Please try again.', 'api_error', {\n code: completed.data.session?.status === 'expired'\n ? 'checkout_session_expired'\n : 'checkout_processing_timeout',\n });\n }\n\n paymentResult = { status: 'succeeded' };\n } else if (options?.initialAutoProcessingError) {\n throw checkoutProcessErrorToFloPayError(\n options.initialAutoProcessingError,\n 'Automatic payment failed. Please try again.',\n {\n checkoutMethod: options.initialAutoProcessingError.checkoutMethod,\n },\n );\n } else if (options?.fromCreateSession) {\n if (options?.fallbackToFull) {\n setCurrentMode('full');\n replaceCheckoutModeQueryParam('full');\n }\n return false;\n } else {\n const result = await processSavedPaymentForMode({\n billingApiUrl: resolvedBillingUrl,\n sessionId: activeSessionId,\n session: sess,\n telemetry: false,\n });\n if (result.type === 'success') {\n paymentResult = result.result;\n } else {\n startRecovery();\n if (\n result.type === 'paypal_redirect_required'\n && savedPaymentKeysRef.current?.publishableKey\n ) {\n persistPayPalResumeState({\n sessionId: activeSessionId,\n publishableKey: savedPaymentKeysRef.current.publishableKey,\n paypalPublishableKey: savedPaymentKeysRef.current.paypalPublishableKey,\n });\n }\n\n paymentResult = await handleSavedPaymentRedirectResult(result, {\n flopay: flopayRef.current,\n paypalFlopay: paypalFlopayRef.current,\n attempt3DS: options?.attempt3DS,\n billingApiUrl: resolvedBillingUrl,\n sessionId: activeSessionId,\n session: sess,\n telemetry: false,\n });\n\n if (result.type === 'paypal_redirect_required') {\n clearPayPalResumeState();\n }\n }\n }\n\n // Mark before the overlay delay so a bootstrap that re-runs during\n // the delay window detects the completion and reuses the session.\n if (activeSessionId) markSessionRecentlyCompleted(activeSessionId);\n finishProcessing();\n if (recoveryFlow) {\n telemetrySource.log({\n name: 'checkout.recovery.completed',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.log({\n name: 'operation.recovery.completed',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n }\n telemetrySource.terminal({\n outcome: 'payment_succeeded',\n paymentMethodCategory: 'saved',\n });\n setModeOverlayStatus('success');\n await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);\n completionCallback = () => onCompleteRef.current?.(paymentResult);\n } catch (err) {\n const floPayErr = normalizeSavedPaymentError(err);\n const method = floPayErr.checkoutMethod ?? DEFAULT_SAVED_PAYMENT_DECLINE_METHOD;\n\n setModeError(floPayErr.message);\n setModeOverlayError(floPayErr.message);\n if (options?.fallbackToFull) {\n telemetrySource.log({\n name: 'operation.fallback',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n setCurrentMode('full');\n replaceCheckoutModeQueryParam('full');\n }\n finishProcessing();\n const expectedDecline = Boolean(\n floPayErr.declineCode\n || floPayErr.code?.toLowerCase().includes('declin'),\n );\n if (expectedDecline) {\n telemetrySource.terminal({\n outcome: 'payment_declined',\n paymentMethodCategory: 'saved',\n });\n } else {\n telemetrySource.error({\n errorCode: recoveryFlow\n ? 'RECOVERY_FAILED'\n : 'PAYMENT_PROCESSING_FAILED',\n stage: recoveryFlow ? 'recovery' : 'processing',\n paymentMethodCategory: 'saved',\n });\n }\n invokeMerchantCallback(() => onErrorRef.current?.(floPayErr));\n emitDecline(method, floPayErr, {\n code: floPayErr.code,\n declineCode: floPayErr.declineCode,\n });\n setModeOverlayStatus('error');\n\n await Promise.allSettled([\n sleep(PROCESSING_OVERLAY_ERROR_DELAY_MS),\n options?.ensureProvidersReady ? options.ensureProvidersReady() : Promise.resolve(),\n ]);\n if (recoveryFlow) {\n telemetrySource.log({\n name: 'checkout.recovery.completed',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.log({\n name: 'operation.recovery.completed',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n }\n return false;\n } finally {\n finishProcessing();\n if (standaloneTelemetry) finishStandaloneTelemetry(standaloneTelemetry);\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n }\n\n invokeMerchantCallback(completionCallback);\n return true;\n },\n [\n emitDecline,\n invokeMerchantCallback,\n normalizeSavedPaymentError,\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n ],\n );\n\n useEffect(() => {\n if (typeof window === 'undefined' || paypalResumeAttempted.current) {\n return;\n }\n\n const params = new URLSearchParams(window.location.search);\n const clientSecret = params.get('payment_intent_client_secret');\n if (!clientSecret) {\n return;\n }\n\n const resumeState = readPayPalResumeState();\n if (!resumeState) {\n return;\n }\n\n paypalResumeAttempted.current = true;\n\n void (async () => {\n let resumeTelemetry: TelemetryBridge | undefined;\n let redirectResumeStartedAt = 0;\n setModeError(null);\n setModeOverlayError(null);\n setModeOverlayStatus('processing');\n setConfirmProcessing(true);\n\n try {\n if (params.get('redirect_status') === 'failed') {\n throw Object.assign(\n new FloPayError(\n 'PayPal payment was declined. Please try again.',\n 'api_error',\n { declineCode: 'paypal_redirect_failed' },\n ),\n { checkoutMethod: 'paypal' as const },\n );\n }\n\n const {\n flopay: resumeFlopay,\n paypalFlopay: resumePaypalFlopay,\n } = await loadSavedPaymentProviders({\n publishableKey: resumeState.publishableKey,\n paypalPublishableKey: resumeState.paypalPublishableKey,\n billingApiUrl: resolvedBillingUrl,\n locale,\n telemetry,\n });\n resumeTelemetry = getFloPayTelemetryBridge(resumePaypalFlopay ?? resumeFlopay);\n redirectResumeStartedAt = resumeTelemetry?.now() ?? 0;\n resumeTelemetry?.log({\n name: 'provider.redirect.resumed',\n stage: 'redirect_resume',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n resumeTelemetry?.log({\n name: 'operation.recovery.started',\n stage: 'recovery',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n\n const paypalStripe = (resumePaypalFlopay ?? resumeFlopay)?.getRawProvider() as import('@stripe/stripe-js').Stripe | null;\n if (!paypalStripe) {\n throw Object.assign(\n new FloPayError('PayPal is not available.', 'api_error'),\n { checkoutMethod: 'paypal' as const },\n );\n }\n\n const { paymentIntent, error } = await paypalStripe.retrievePaymentIntent(clientSecret);\n if (error) {\n throw Object.assign(\n new FloPayError(\n error.message ?? 'Failed to retrieve PayPal payment status.',\n 'api_error',\n { code: error.code },\n ),\n { checkoutMethod: 'paypal' as const },\n );\n }\n\n const resultStatus = mapPayPalIntentStatusToPaymentResult(paymentIntent?.status);\n\n if (!paymentIntent || resultStatus === 'failed') {\n throw Object.assign(\n new FloPayError('PayPal payment was not completed. Please try again.', 'api_error'),\n { checkoutMethod: 'paypal' as const },\n );\n }\n\n const paymentMethodId = typeof paymentIntent.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent.payment_method?.id;\n\n // Manual-capture PayPal PIs land at `requires_capture` after PayPal\n // authorization. Backend must capture via /process, otherwise the PI\n // sits at requires_capture forever (\"Uncaptured\" in Stripe).\n let finalResultStatus: PaymentResult['status'] = resultStatus;\n if (resumeState.sessionId) {\n const resumeApi = new PaymentAPI(resolvedBillingUrl, { telemetry: false });\n const resumeSessionResult = await resumeApi.getUnifiedCheckoutSession(resumeState.sessionId);\n const resumeSession = resumeSessionResult.data.session;\n if (resumeSession && resumeSession.status !== 'complete') {\n const processResult = await processSavedPaymentForMode({\n billingApiUrl: resolvedBillingUrl,\n sessionId: resumeState.sessionId,\n session: resumeSession,\n telemetry: false,\n tokenizedData: {\n id: paymentMethodId ?? paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n isPaypal: true,\n },\n });\n if (processResult.type !== 'success') {\n throw Object.assign(\n new FloPayError('Failed to finalize PayPal payment.', 'api_error'),\n { checkoutMethod: 'paypal' as const },\n );\n }\n // /process's result.status reflects post-capture state; the\n // pre-capture PI status mapping would otherwise leak through.\n finalResultStatus = processResult.result.status;\n }\n }\n\n if (resumeState.sessionId) markSessionRecentlyCompleted(resumeState.sessionId);\n resumeTelemetry?.log({\n name: 'operation.recovery.completed',\n stage: 'recovery',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n resumeTelemetry?.performance({\n stage: 'redirect_resume',\n durationMs: resumeTelemetry.elapsed(redirectResumeStartedAt),\n durationMode: 'machine',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n resumeTelemetry?.terminal({\n outcome: 'payment_succeeded',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n setModeOverlayStatus('success');\n await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);\n invokeMerchantCallback(() => onCompleteRef.current?.({\n status: finalResultStatus,\n paymentIntentId: paymentIntent.id,\n paymentMethodId,\n checkoutMethod: 'paypal',\n }));\n } catch (err) {\n const floPayErr = normalizeSavedPaymentError(err);\n const method = floPayErr.checkoutMethod ?? 'paypal';\n const expectedDecline = Boolean(\n floPayErr.declineCode\n || floPayErr.code?.toLowerCase().includes('declin'),\n );\n\n if (resumeTelemetry) {\n resumeTelemetry.performance({\n stage: 'redirect_resume',\n durationMs: resumeTelemetry.elapsed(redirectResumeStartedAt),\n durationMode: 'machine',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n if (expectedDecline) {\n resumeTelemetry.terminal({\n outcome: 'payment_declined',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n } else {\n resumeTelemetry.error({\n errorCode: 'REDIRECT_RESUME_FAILED',\n stage: 'redirect_resume',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n }\n } else if (expectedDecline) {\n const reporter = createStandaloneTelemetryReporter(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n );\n reporter.terminal({\n outcome: 'payment_declined',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n finishStandaloneTelemetry(reporter);\n } else {\n reportStandaloneTelemetryError(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n 'REDIRECT_RESUME_FAILED',\n 'redirect_resume',\n );\n }\n\n setModeError(floPayErr.message);\n setModeOverlayError(floPayErr.message);\n invokeMerchantCallback(() => onErrorRef.current?.(floPayErr));\n emitDecline(method, floPayErr, {\n code: floPayErr.code,\n declineCode: floPayErr.declineCode,\n });\n setModeOverlayStatus('error');\n await sleep(PROCESSING_OVERLAY_ERROR_DELAY_MS);\n } finally {\n clearPayPalResumeState();\n clearPayPalRedirectParams();\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n setConfirmProcessing(false);\n }\n })();\n }, [emitDecline, invokeMerchantCallback, locale, normalizeSavedPaymentError, resolvedBillingUrl, telemetry]);\n\n // ── Session creation dedup ──\n // Uses the module-level `sessionInflightMap` (declared near the top of this\n // file) so two FloPayCheckout instances mounted in the same page-load —\n // including React StrictMode's dev double-mount, a Suspense remount, or a\n // navigation that briefly remounts the parent — share the same in-flight\n // POST instead of each starting their own and producing duplicate sessions.\n // A per-component useRef would be reset on each remount and cannot dedupe\n // across instances.\n // Tracks whether init has already completed — prevents redundant re-runs\n // when createSessionParams is a new object ref but semantically identical.\n const initializedHashRef = useRef<string | null>(null);\n\n // ── Deterministic hash for session caching ──\n\n function hashCreateParams(params: InlineSessionDraft | undefined): string {\n // Include only a compact buyer fingerprint in the cache key. The resulting\n // sessionStorage key is hashed, but the checkout session itself is account-\n // bound on the backend; reusing it across emails/users can route payment\n // processing through the wrong persisted gateway.\n //\n // Note: `account.userId` is intentionally excluded. It is a consumer-\n // generated identifier and many consumers (e.g. funnels-next) regenerate\n // it per component mount via `crypto.randomUUID()` — including it here\n // would produce a new hash on every mount, miss the sessionStorage cache,\n // and POST a duplicate session every time. Email + country are sufficient\n // buyer-identity for cross-buyer cache safety.\n const key = JSON.stringify({\n c: params?.clientId,\n cur: params?.currency ?? '',\n a: {\n e: params?.account?.email?.trim().toLowerCase() ?? '',\n country: params?.account?.country ?? '',\n },\n successUrl: params?.successUrl,\n cancelUrl: params?.cancelUrl,\n // Unified products[] is the post-#760 wire shape. Must be included or\n // carts that only set `products` (no legacy items/subscriptions) all\n // hash to the same key — the bootstrap effect's `createSessionHash`\n // dep then never changes when products change, the session-id cache\n // hits the wrong session, and the backend's enabledPaymentMethods\n // result for the *previous* cart sticks until a fresh page-load with\n // the session cache cleared.\n p: params?.products?.map(x => `${x.type ?? ''}:${x.code ?? x.providerItemId ?? x.providerPlanId ?? ''}:${x.totalAmount ?? ''}:${x.overrideAmount ?? ''}:${x.quantity ?? 1}`).sort(),\n i: params?.items?.map(x => `${x.code ?? x.providerItemId ?? ''}:${x.totalAmount ?? ''}:${x.overrideAmount ?? ''}:${x.quantity ?? 1}`).sort(),\n s: params?.subscriptions?.map(x => `${x.code ?? x.providerPlanId ?? ''}:${x.totalAmount ?? ''}:${x.overrideAmount ?? ''}:${x.quantity ?? 1}`).sort(),\n couponCodes: params?.couponCodes,\n tagsData: params?.tagsData,\n utmMetadata: params?.utmMetadata,\n tokenizedData: params?.tokenizedData,\n m: params?.checkoutMode ?? 'full',\n });\n let h = 0;\n for (let i = 0; i < key.length; i++) {\n h = ((h << 5) - h + key.charCodeAt(i)) | 0;\n }\n return `flopay_session_${Math.abs(h).toString(36)}`;\n }\n\n // Stable hash of createSession params — used as effect dependency instead\n // of the raw object, so a new object reference with the same values\n // doesn't re-trigger the effect.\n const createSessionHash = useMemo(\n () => effectiveCreateSession ? hashCreateParams(effectiveCreateSession) : '',\n [effectiveCreateSession],\n );\n // Keep a ref to the latest params so the effect closure always sees them.\n const createSessionParamsRef = useRef(effectiveCreateSession);\n createSessionParamsRef.current = effectiveCreateSession;\n\n useEffect(() => {\n setResolvedSessionId(sessionIdProp ?? '');\n }, [sessionIdProp]);\n\n useEffect(() => {\n autoCheckoutAttempted.current = false;\n setModeError(initialErrorMessage);\n setModeOverlayError(null);\n setModeOverlayStatus(null);\n }, [createSessionHash, initialErrorMessage, sessionIdProp]);\n\n async function resolveInlineSession(\n params: InlineSessionDraft,\n cacheKey: string,\n ): Promise<{ sid: string; result: NormalizedCheckoutSession }> {\n const reporter = createStandaloneTelemetryReporter(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n );\n const api = new PaymentAPI(resolvedBillingUrl, { telemetry: false });\n try {\n const cached = readCachedInlineSession(cacheKey);\n reporter.log({\n name: cached ? 'operation.cache.hit' : 'operation.cache.miss',\n stage: 'session_create',\n requestCategory: 'session_create',\n });\n let sid: string | null = cached?.sid ?? null;\n let realResult: NormalizedCheckoutSession | null = null;\n\n if (sid) {\n try {\n // Forward the cached nonce — the backend rejects a session GET without\n // the matching `x-checkout-session-token` (TeamFloPay/backend#640).\n realResult = await api.getUnifiedCheckoutSession(sid, cached?.nonce);\n const status = realResult.data.session?.status;\n if (status === 'complete') {\n // If this session was completed inside the current page-load — the\n // marker is written synchronously in SplitCardForm the moment\n // /process succeeds, *before* the 1.2s overlay delay — return the\n // completed session as-is. Otherwise the parent's mid-flight\n // onComplete + navigation could race a re-mounted bootstrap into\n // clearing the cache and POSTing a duplicate session that would\n // then be /process'd with the same PI (the source of the\n // duplicate-subscription bug).\n if (wasSessionRecentlyCompleted(sid)) {\n return { sid, result: realResult };\n }\n // Otherwise the cached session is genuinely stale (e.g. user\n // revisits /checkout in a new page-load after a previous successful\n // checkout). Clear and create a new one as before.\n clearCachedInlineSession(cacheKey);\n sid = null;\n realResult = null;\n }\n } catch {\n reporter.log({\n name: 'operation.fallback',\n stage: 'session_read',\n requestCategory: 'session_read',\n });\n clearCachedInlineSession(cacheKey);\n sid = null;\n }\n }\n\n if (!sid) {\n const sessionCreateStartedAt = reporter.now();\n reporter.log({\n name: 'session.create.started',\n stage: 'session_create',\n requestCategory: 'session_create',\n });\n // Inject checkout analytics metadata into the session creation payload\n const paramsWithAnalytics: InlineSessionParams = {\n ...(params as InlineSessionParams),\n avsCheck: !!enableAVS,\n avsConfig: typeof enableAVS === 'object' ? enableAVS : undefined,\n checkoutType: 'embedded_checkout',\n checkoutLayout: children ? 'custom_layout' : layout === 'buttons' ? 'buttons_layout' : 'default_layout',\n };\n try {\n realResult = await api.createAndFetchSession(paramsWithAnalytics);\n reporter.log({\n name: 'session.request.completed',\n stage: 'session_complete',\n requestCategory: 'session_create',\n statusClass: '2xx',\n });\n reporter.performance({\n stage: 'session_create',\n durationMs: reporter.now() - sessionCreateStartedAt,\n durationMode: 'machine',\n requestCategory: 'session_create',\n statusClass: '2xx',\n });\n } catch (error) {\n reporter.performance({\n stage: 'session_create',\n durationMs: reporter.now() - sessionCreateStartedAt,\n durationMode: 'machine',\n requestCategory: 'session_create',\n statusClass: 'network_error',\n });\n if (error instanceof FloPayError && error.type === 'validation_error') {\n reporter.terminal({\n outcome: 'validation_rejected',\n stage: 'session_create',\n paymentMethodCategory: 'unknown',\n });\n } else {\n reporter.error({\n errorCode: 'CHECKOUT_SESSION_CREATE_FAILED',\n stage: 'session_create',\n paymentMethodCategory: 'unknown',\n requestCategory: 'session_create',\n });\n }\n throw error;\n }\n sid = realResult.data.session?.id ?? '';\n if (sid) {\n // Cache the nonce too so a later reuse can re-fetch (see above).\n persistCachedInlineSession(cacheKey, sid, realResult.data.session?.clientSecret);\n }\n }\n\n return { sid: sid ?? '', result: realResult! };\n } finally {\n finishStandaloneTelemetry(reporter);\n }\n }\n\n const bootstrapInlineSession = useCallback(\n async (patch?: InlineSessionPatch) => {\n const baseParams = createSessionParamsRef.current;\n if (!baseParams) {\n throw new FloPayError('createSession is required to bootstrap checkout.', 'validation_error');\n }\n\n const mergedParams = mergeInlineSessionPatch(baseParams, patch);\n // The cache key includes a compact buyer fingerprint because backend\n // sessions are account-bound. Account, coupon, tag, UTM, or cart changes\n // should bootstrap a fresh session instead of reusing a stale gateway.\n const cacheKey = hashCreateParams(mergedParams);\n\n let promise = sessionInflightMap.get(cacheKey);\n if (!promise) {\n promise = resolveInlineSession(mergedParams, cacheKey);\n sessionInflightMap.set(cacheKey, promise);\n }\n\n let resolved: { sid: string; result: NormalizedCheckoutSession };\n try {\n resolved = await promise;\n } finally {\n // Only the inserter clears the map entry — but `delete` on a missing\n // key is a no-op so this is safe to call from every awaiter.\n sessionInflightMap.delete(cacheKey);\n }\n\n initializedHashRef.current = cacheKey;\n\n try {\n if (patch) {\n setCreateSessionPatchBaseHash(baseCreateSessionHash);\n setCreateSessionPatch((prev) => mergeInlineSessionPatches(prev, patch));\n }\n\n const { sid, result: realResult } = resolved;\n\n setUnified(realResult);\n if (realResult.data.session) {\n setSession(realResult.data.session);\n }\n if (sid) {\n setResolvedSessionId(sid);\n }\n\n const {\n publishableKey,\n paypalPublishableKey,\n } = resolveSavedPaymentPublishableKeys(realResult);\n const {\n flopay: instance,\n paypalFlopay: paypalInstance,\n } = await loadSavedPaymentProviders({\n publishableKey,\n paypalPublishableKey,\n billingApiUrl: resolvedBillingUrl,\n locale,\n telemetry,\n });\n\n flopayRef.current = instance;\n setFloPay(instance);\n paypalFlopayRef.current = paypalInstance;\n setPaypalFloPay(paypalInstance);\n\n setIsLoading(false);\n } catch (err) {\n if (initializedHashRef.current === cacheKey) {\n initializedHashRef.current = null;\n }\n throw err;\n }\n\n return resolved;\n },\n [locale, resolvedBillingUrl, telemetry, telemetryCheckoutContext],\n );\n\n const handleInlineSessionPatch = useCallback(async (patch: InlineSessionPatch) => {\n if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) {\n return {\n sessionId: resolvedSessionId,\n session,\n };\n }\n\n setCardBootstrapPending(true);\n try {\n const resolved = await bootstrapInlineSession(patch);\n return {\n sessionId: resolved.sid,\n session: resolved.result.data.session ?? null,\n };\n } finally {\n setCardBootstrapPending(false);\n }\n }, [\n bootstrapInlineSession,\n cardBootstrapPending,\n resolvedSessionId,\n session,\n ]);\n\n // ── Fetch session + initialize ──\n\n useEffect(() => {\n let cancelled = false;\n setLoadError(null);\n\n // ── createSession path: render immediately, resolve in background ──\n if (createSessionHash) {\n const params = createSessionParamsRef.current!;\n setSession(buildSyntheticSession(params, checkoutModeProp));\n setCurrentMode(effectiveCreateSessionMode);\n setIsLoading(false);\n\n // Already initialized with the same params — skip the network bootstrap\n // but keep the synthetic session in sync with any mode override.\n if (initializedHashRef.current === createSessionHash) {\n return () => { cancelled = true; };\n }\n\n (async () => {\n // Skip auto-checkout when resuming from a PayPal redirect — the\n // PayPal-resume effect (above) is the canonical completer for that\n // path. Without this guard, runSavedPaymentFlow races the resume\n // effect and triggers a duplicate POST /v1/checkouts/sessions/process.\n const hasPayPalRedirectParams =\n typeof window !== 'undefined' &&\n new URLSearchParams(window.location.search).has('payment_intent');\n\n const shouldAutoProcessInlineSession =\n effectiveCreateSessionMode === 'auto' &&\n !autoCheckoutAttempted.current &&\n !hasPayPalRedirectParams;\n\n if (shouldAutoProcessInlineSession) {\n setModeError(null);\n setModeOverlayError(null);\n setModeOverlayStatus('processing');\n }\n\n try {\n const resolved = await bootstrapInlineSession();\n const resolvedSession = resolved.result.data.session ?? null;\n savedPaymentKeysRef.current = resolveSavedPaymentPublishableKeys(resolved.result);\n\n // PayPal-only sessions can't run saved-payment auto-checkout:\n // `handleSavedPaymentRedirectResult` requires a Stripe provider for\n // 3DS recovery, and there's no card-on-file to charge. Skip the\n // auto flow and let the render path drop to `DirectPayPalButton`.\n const resolvedPaypalOnly = isPayPalOnlyUnified(resolved.result);\n\n if (\n !cancelled &&\n shouldAutoProcessInlineSession &&\n resolvedSession &&\n !resolvedPaypalOnly\n ) {\n autoCheckoutAttempted.current = true;\n await runSavedPaymentFlow(resolvedSession, {\n attempt3DS: true,\n fallbackToFull: true,\n fromCreateSession: true,\n initialAutoProcessingError: resolved.result.autoProcessingError,\n initialAutoProcessingPending: resolved.result.autoProcessingPending,\n autoProcessingAttempted: resolved.result.autoProcessingAttempted,\n sessionId: resolved.sid || resolvedSession.id,\n });\n return;\n }\n\n if (!cancelled && shouldAutoProcessInlineSession) {\n if (resolvedPaypalOnly) {\n autoCheckoutAttempted.current = true;\n }\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n }\n } catch (err) {\n if (cancelled) return;\n\n const errorCode = err instanceof FloPayError\n ? err.code\n : typeof err === 'object' && err !== null && 'code' in err\n ? (err as { code?: string }).code\n : undefined;\n\n if (\n shouldAutoProcessInlineSession &&\n errorCode === 'session_auto_completed'\n ) {\n autoCheckoutAttempted.current = true;\n setModeOverlayStatus('success');\n await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);\n\n if (!cancelled) {\n invokeMerchantCallback(() => {\n onCompleteRef.current?.({ status: 'succeeded' });\n });\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n }\n return;\n }\n\n if (shouldAutoProcessInlineSession) {\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n }\n\n const floPayErr = err instanceof FloPayError ? err\n : new FloPayError(err instanceof Error ? err.message : 'Failed to create session', 'api_error');\n setLoadError(floPayErr);\n }\n })();\n\n return () => { cancelled = true; };\n }\n\n // ── Existing sessionId flow ──\n setIsLoading(true);\n\n async function init() {\n let sessionReadCompleted = false;\n try {\n const api = new PaymentAPI(resolvedBillingUrl, { telemetry: false });\n const result = await api.getUnifiedCheckoutSession(activeSessionId, nonceProp);\n\n if (cancelled) return;\n setUnified(result);\n\n const sess = result.data.session ?? null;\n setSession(sess);\n\n if (!sess) {\n throw new FloPayError('No session data returned', 'api_error');\n }\n\n if (sess.status === 'complete') {\n setIsLoading(false);\n invokeMerchantCallback(() => {\n onSessionCompletedRef.current?.(sess.successUrl ?? '');\n });\n return;\n }\n\n if (sess.status === 'expired') {\n throw new FloPayError('Checkout session has expired.', 'api_error', {\n code: 'checkout_session_expired',\n });\n }\n\n sessionReadCompleted = true;\n\n const effectiveMode = checkoutModeProp ?? sess.checkoutMode ?? 'full';\n setCurrentMode(effectiveMode);\n\n const hasPayPalRedirectParams =\n typeof window !== 'undefined' &&\n new URLSearchParams(window.location.search).has('payment_intent');\n\n // PayPal-only sessions skip auto saved-payment processing — there's\n // no Stripe provider for 3DS recovery, so the render path drops\n // straight to `DirectPayPalButton`.\n const paypalOnly = isPayPalOnlyUnified(result);\n\n if (\n effectiveMode === 'auto' &&\n !autoCheckoutAttempted.current &&\n !hasPayPalRedirectParams &&\n !paypalOnly\n ) {\n autoCheckoutAttempted.current = true;\n const stripeInitPromise = initStripe(result);\n\n try {\n await runSavedPaymentFlow(sess, {\n attempt3DS: true,\n fallbackToFull: true,\n ensureProvidersReady: () => stripeInitPromise,\n sessionId: activeSessionId || sess.id,\n });\n if (cancelled) return;\n await stripeInitPromise;\n if (!cancelled) {\n setIsLoading(false);\n }\n return;\n } catch {\n if (cancelled) return;\n await stripeInitPromise;\n if (!cancelled) setIsLoading(false);\n return;\n }\n }\n\n await initStripe(result);\n if (!cancelled) setIsLoading(false);\n } catch (err) {\n if (cancelled) return;\n if (!(err instanceof FloPayError)) {\n reportStandaloneTelemetryError(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n 'INTERNAL_SDK_ERROR',\n 'checkout_mount',\n );\n } else if (!sessionReadCompleted && !isExpectedExistingSessionError(err)) {\n reportStandaloneTelemetryError(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n 'NETWORK_REQUEST_FAILED',\n 'session_read',\n );\n }\n const floPayErr = err instanceof FloPayError ? err\n : new FloPayError(err instanceof Error ? err.message : 'Failed to initialize checkout', 'api_error');\n setLoadError(floPayErr);\n setIsLoading(false);\n }\n }\n\n async function initStripe(result: NormalizedCheckoutSession) {\n const {\n publishableKey,\n paypalPublishableKey,\n } = resolveSavedPaymentPublishableKeys(result);\n savedPaymentKeysRef.current = {\n publishableKey,\n paypalPublishableKey,\n };\n const {\n flopay: instance,\n paypalFlopay: paypalInstance,\n } = await loadSavedPaymentProviders({\n publishableKey,\n paypalPublishableKey,\n billingApiUrl: resolvedBillingUrl,\n locale,\n telemetry,\n });\n\n flopayRef.current = instance;\n setFloPay(instance);\n paypalFlopayRef.current = paypalInstance;\n setPaypalFloPay(paypalInstance);\n }\n\n init();\n return () => {\n cancelled = true;\n };\n // Only re-run when the session/config identity changes — NOT when callbacks change.\n // Callbacks are accessed via refs (onCompleteRef, onSessionCompletedRef).\n // `createSessionHash` is a stable string derived from createSessionParams,\n // so a new object reference with the same values won't re-trigger.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n bootstrapInlineSession,\n checkoutModeProp,\n createSessionHash,\n effectiveCreateSessionMode,\n initSessionDependency,\n invokeMerchantCallback,\n nonceProp,\n runSavedPaymentFlow,\n ]);\n\n // ── Confirm mode handler ──\n\n const handleConfirmCheckout = useCallback(async () => {\n if (confirmProcessing || !session) return;\n setConfirmProcessing(true);\n setModeError(null);\n\n try {\n await runSavedPaymentFlow(session, {\n fallbackToFull: true,\n sessionId: activeSessionId || session.id,\n });\n } finally {\n setConfirmProcessing(false);\n }\n }, [activeSessionId, confirmProcessing, runSavedPaymentFlow, session]);\n\n const directPaypalConfig = resolveDirectPaypalConfig(unified);\n // PayPal-only sessions advertise `gateways.paypal` without `gateways.stripe`.\n // Stripe Elements (and the SplitCardForm card surface that depends on them)\n // can't mount in that case, so we render `DirectPayPalButton` as the sole\n // payment surface and bypass `FloPayProvider` entirely.\n const isPaypalOnlySession = isPayPalOnlyUnified(unified);\n\n // Provider options from session data. Only meaningful when Stripe is\n // available — PayPal-only sessions never mount Stripe Elements.\n const providerOptions = useMemo(() => {\n if (!unified || !session || !unified.data.stripe?.publishableKey) return undefined;\n\n const opts: {\n appearance?: FloPayAppearance;\n paymentMethodCreation: 'manual';\n billingApiUrl: string;\n clientSecret?: string;\n amount?: number;\n currency?: string;\n } = {\n appearance,\n paymentMethodCreation: 'manual',\n billingApiUrl: resolvedBillingUrl,\n };\n\n if (unified.data.stripe?.clientSecret) {\n opts.clientSecret = unified.data.stripe.clientSecret;\n } else {\n // Use display total (respects hideItems logic) instead of raw session.amount\n const displayTotal = buildCheckoutDisplayData(session).total;\n opts.amount = Math.round(displayTotal * 100) || session.amount;\n opts.currency = session.currency?.toLowerCase();\n }\n\n return opts;\n }, [unified, session, appearance, resolvedBillingUrl]);\n\n const shouldHandleInlineSessionPatch = Boolean(\n createSessionParams &&\n !children &&\n layout === 'buttons' &&\n onBeforeButtonClick &&\n effectiveCreateSessionMode === 'full',\n );\n\n // Checkout context\n const checkoutValue = useMemo(\n () => ({\n session,\n loading: isLoading,\n error: loadError,\n checkoutMode: currentMode,\n inlineSessionDraft: effectiveCreateSession,\n applyInlineSessionPatch: shouldHandleInlineSessionPatch\n ? handleInlineSessionPatch\n : undefined,\n inlineSessionPatchProcessing: cardBootstrapPending,\n }),\n [\n session,\n isLoading,\n loadError,\n currentMode,\n effectiveCreateSession,\n shouldHandleInlineSessionPatch,\n handleInlineSessionPatch,\n cardBootstrapPending,\n ],\n );\n const shouldShowInterimButtons =\n Boolean(createSessionParams) &&\n layout === 'buttons' &&\n !isPaypalOnlySession &&\n (!flopay || !providerOptions);\n const modeOverlay = modeOverlayStatus\n ? (\n <ProcessingOverlay\n status={modeOverlayStatus}\n errorMessage={modeOverlayError}\n />\n )\n : null;\n\n // ── Loading state ──\n if (isLoading) {\n if (loadingNode) {\n return (\n <>\n {loadingNode}\n {modeOverlay}\n </>\n );\n }\n\n // Buttons layout: show button-shaped skeletons. Wallet/card skeletons are\n // gated on `showStripe` so a PayPal-only checkout doesn't briefly flash\n // Stripe affordances during bootstrap.\n if (layout === 'buttons') {\n // Match the theme's tile border-radius so the loading skeletons line\n // up with the eventual buttons. `bundleRadius` reads from the\n // resolved theme bundle's `cardButton.borderRadius` (e.g. `14px` for\n // modern, `20px` for glass) and falls back to the appearance\n // variable, then `8px` for classic.\n const bundleRadius =\n (themeBundle?.buttonsLayout?.cardButton?.borderRadius as string | number | undefined) ??\n (themeBundle?.appearance.variables?.borderRadius as string | undefined) ??\n 8;\n const skeletonBar = (h: number) => (\n <div style={{\n height: h, borderRadius: bundleRadius, background: '#e5e7eb',\n animation: 'flopay-loading-pulse 1.5s ease-in-out infinite',\n }} />\n );\n return (\n <>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n {showStripe && (showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n {showStripe && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n <style>{`@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }`}</style>\n </div>\n {modeOverlay}\n </>\n );\n }\n\n // Default layout: centered spinner\n return (\n <>\n <div style={{ display: 'flex', justifyContent: 'center', padding: 32 }}>\n <div style={{\n width: 24, height: 24,\n border: '2px solid #e5e7eb', borderTopColor: '#6b7280',\n borderRadius: '50%', animation: 'spin 0.6s linear infinite',\n }} />\n <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>\n </div>\n {modeOverlay}\n </>\n );\n }\n\n // ── Error state ──\n if (loadError) {\n if (errorNode) {\n return (\n <CheckoutContext.Provider value={checkoutValue}>\n {errorNode(loadError)}\n </CheckoutContext.Provider>\n );\n }\n return (\n <CheckoutContext.Provider value={checkoutValue}>\n <div\n role=\"alert\"\n data-testid=\"flopay-load-error\"\n style={{\n padding: 24,\n textAlign: 'center',\n color: '#dc2626',\n fontSize: 14,\n }}\n >\n {loadError.message}\n </div>\n </CheckoutContext.Provider>\n );\n }\n\n // When using createSession + buttons layout, render an interim buttons view\n // while Stripe initializes in the background. The Credit/Debit Card button\n // is fully interactive (expands card form); PayPal/wallets show as skeletons.\n // Once flopay loads, the real SplitCardForm replaces this seamlessly.\n if (shouldShowInterimButtons) {\n return (\n <>\n <CheckoutContext.Provider value={checkoutValue}>\n <InterimButtonsView\n onButtonClick={onButtonClick}\n showPayPal={showPayPal}\n showStripe={showStripe}\n showApplePay={showApplePay}\n showGooglePay={showGooglePay}\n theme={theme}\n buttonsTheme={buttonsTheme}\n buttonsStyles={buttonsStyles}\n cardButtonContent={cardButtonContent}\n cardBackButtonContent={cardBackButtonContent}\n cardTitleContent={cardTitleContent}\n />\n </CheckoutContext.Provider>\n {modeOverlay}\n </>\n );\n }\n\n // PayPal-only session: render DirectPayPalButton as the sole payment\n // surface. Stripe Elements never mount, so we bypass FloPayProvider /\n // SplitCardForm entirely.\n if (isPaypalOnlySession && session && directPaypalConfig) {\n return (\n <>\n <CheckoutContext.Provider value={checkoutValue}>\n <div className={className} style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {modeError && (\n <div\n role=\"alert\"\n data-testid=\"flopay-error\"\n style={{\n padding: '0.625rem 0.875rem',\n background: '#FEF2F2',\n border: '1px solid #FECACA',\n borderRadius: '8px',\n color: '#991B1B',\n fontSize: '0.85rem',\n fontWeight: 600,\n }}\n >\n {modeError}\n </div>\n )}\n <InstrumentedDirectPayPalButton\n sessionId={activeSessionId}\n nonce={session.clientSecret || undefined}\n billingApiUrl={resolvedBillingUrl}\n email={session.customer?.email}\n clientId={directPaypalConfig.clientId}\n environment={directPaypalConfig.environment}\n currency={(session.currency ?? 'usd').toUpperCase()}\n isSubscription={session.mode === 'subscription'}\n onComplete={onComplete}\n onErrorChange={setModeError}\n onDecline={onDecline}\n onButtonClick={onButtonClick}\n session={session}\n telemetry={telemetry}\n telemetryContext={telemetryCheckoutContext}\n debug={debug}\n />\n </div>\n </CheckoutContext.Provider>\n {modeOverlay}\n </>\n );\n }\n\n if (!flopay || !providerOptions) {\n return <>{modeOverlay}</>;\n }\n\n // ── Confirm mode ──\n if (currentMode === 'confirm') {\n return (\n <>\n <CheckoutContext.Provider value={checkoutValue}>\n <FloPayProvider flopay={flopay} paypalFlopay={paypalFlopay} options={providerOptions}>\n <div className={className}>\n {modeError && (\n <div\n style={{\n color: '#dc2626',\n fontSize: '0.875rem',\n marginBottom: '0.75rem',\n textAlign: 'center',\n }}\n >\n {modeError}\n </div>\n )}\n {renderConfirmButton ? (\n renderConfirmButton({\n onConfirm: handleConfirmCheckout,\n isProcessing: confirmProcessing,\n })\n ) : (\n <button\n type=\"button\"\n onClick={handleConfirmCheckout}\n disabled={confirmProcessing}\n style={{\n width: '100%',\n padding: '0.875rem',\n backgroundColor: '#4A49FF',\n color: 'white',\n border: 'none',\n borderRadius: '8px',\n fontSize: '1rem',\n fontWeight: 600,\n cursor: confirmProcessing ? 'not-allowed' : 'pointer',\n opacity: confirmProcessing ? 0.6 : 1,\n }}\n >\n {confirmProcessing\n ? 'Processing...'\n : confirmLabel ?? 'Confirm Purchase'}\n </button>\n )}\n </div>\n </FloPayProvider>\n </CheckoutContext.Provider>\n {modeOverlay}\n </>\n );\n }\n\n // ── Full mode (default / fallback) ──\n return (\n <>\n <CheckoutContext.Provider value={checkoutValue}>\n <FloPayProvider flopay={flopay} paypalFlopay={paypalFlopay} options={providerOptions}>\n {children ? (\n <>\n {modeError && (\n <div\n style={{\n padding: '0.75rem 1rem',\n marginBottom: '0.75rem',\n backgroundColor: '#FEF3C7',\n border: '1px solid #F59E0B',\n borderRadius: '8px',\n color: '#92400E',\n fontSize: '0.875rem',\n }}\n >\n {modeError}\n </div>\n )}\n <SessionInjector\n sessionId={activeSessionId}\n nonce={session?.clientSecret || undefined}\n billingApiUrl={resolvedBillingUrl}\n session={session}\n >\n {children}\n </SessionInjector>\n </>\n ) : (\n <SplitCardForm\n sessionId={activeSessionId}\n nonce={session?.clientSecret || undefined}\n email={session?.customer?.email}\n userId={session?.customer?.id}\n firstName={session?.customer?.firstName}\n lastName={session?.customer?.lastName}\n totalAmount={session ? Math.round(buildCheckoutDisplayData(session).total * 100) : 0}\n currency={session?.currency?.toLowerCase() ?? 'usd'}\n onComplete={onComplete}\n onError={onError}\n onDecline={onDecline}\n error={modeError}\n onErrorChange={setModeError}\n onFullNameChange={onFullNameChange}\n showPayPal={showPayPal}\n showStripe={showStripe}\n enabledPaymentMethods={unified?.data.stripe?.enabledPaymentMethods}\n enabledPaymentMethodCountries={unified?.data.stripe?.enabledPaymentMethodCountries}\n showApplePay={showApplePay}\n showGooglePay={showGooglePay}\n layout={layout}\n theme={theme}\n buttonsTheme={buttonsTheme}\n buttonsStyles={buttonsStyles}\n appearance={appearance}\n cardButtonContent={cardButtonContent}\n cardBackButtonContent={cardBackButtonContent}\n cardTitleContent={cardTitleContent}\n onButtonClick={onButtonClick}\n onBeforeButtonClick={onBeforeButtonClick}\n enableAVS={enableAVS}\n {...(cardFieldOrder ? { cardFieldOrder } : {})}\n {...(cardPreFormSlot ? { cardPreFormSlot } : {})}\n avsLayout={avsLayout}\n country={session?.customer?.country}\n city={session?.customer?.city}\n state={session?.customer?.state}\n onCountryChange={onCountryChange}\n onZipChange={onZipChange}\n avsCheck={!!enableAVS}\n checkoutType={createSessionParams ? 'embedded_checkout' : 'standard_checkout'}\n checkoutLayout={children ? 'custom_layout' : layout === 'buttons' ? 'buttons_layout' : 'default_layout'}\n submitLabel={submitLabel}\n className={className}\n directPaypal={resolveDirectPaypalConfig(unified)}\n isSubscription={session?.mode === 'subscription'}\n session={session}\n debug={debug}\n />\n )}\n </FloPayProvider>\n </CheckoutContext.Provider>\n {modeOverlay}\n </>\n );\n}\n\n/**\n * Auto-injects session props into child form components.\n * Explicit props on children take precedence over injected values.\n */\nfunction SessionInjector({\n sessionId,\n nonce,\n billingApiUrl,\n session,\n children,\n}: {\n sessionId: string;\n nonce?: string;\n billingApiUrl: string;\n session: CheckoutSession | null;\n children: React.ReactNode;\n}) {\n return (\n <>\n {React.Children.map(children, (child) => {\n if (!React.isValidElement(child)) return child;\n\n const existing = child.props as Record<string, unknown>;\n const injected: Record<string, unknown> = {};\n\n if (!existing.sessionId) injected.sessionId = sessionId;\n if (!existing.nonce && nonce) injected.nonce = nonce;\n if (!existing.billingApiUrl) injected.billingApiUrl = billingApiUrl;\n\n if (session?.customer) {\n if (!existing.email) injected.email = session.customer.email;\n if (!existing.userId) injected.userId = session.customer.id;\n if (!existing.firstName)\n injected.firstName = session.customer.firstName;\n if (!existing.lastName)\n injected.lastName = session.customer.lastName;\n }\n\n if (Object.keys(injected).length === 0) return child;\n return React.cloneElement(child, injected);\n })}\n </>\n );\n}\n\n/**\n * Interim buttons view rendered while Stripe initializes in the background.\n * Shows skeleton bars for PayPal/wallets and a fully interactive Credit/Debit Card button.\n */\nfunction InterimButtonsView({\n onButtonClick,\n onCardButtonClick,\n cardLoading = false,\n cardOpen,\n errorMessage,\n showPayPal,\n showStripe = true,\n showApplePay,\n showGooglePay,\n theme,\n buttonsTheme,\n buttonsStyles: stylesOverride,\n cardButtonContent,\n cardBackButtonContent,\n cardTitleContent,\n}: {\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n onCardButtonClick?: () => void | Promise<void>;\n cardLoading?: boolean;\n cardOpen?: boolean;\n errorMessage?: string | null;\n showPayPal: boolean;\n showStripe?: boolean;\n showApplePay: boolean;\n showGooglePay: boolean;\n theme?: import('@flopay/shared').ThemeId;\n buttonsTheme?: ButtonsLayoutTheme;\n buttonsStyles?: ButtonsLayoutStyles;\n cardButtonContent?: React.ReactNode;\n cardBackButtonContent?: React.ReactNode;\n cardTitleContent?: React.ReactNode;\n}) {\n const [showCardForm, setShowCardForm] = useState(false);\n const isCardOpenControlled = typeof cardOpen === 'boolean';\n\n useEffect(() => {\n if (isCardOpenControlled) {\n setShowCardForm(cardOpen);\n }\n }, [cardOpen, isCardOpenControlled]);\n\n const themeBundle = useMemo(() => resolveTheme(theme), [theme]);\n const bStyles = useMemo<ButtonsLayoutStyles>(() => {\n const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme(buttonsTheme);\n if (!stylesOverride) return base;\n return {\n ...base,\n ...stylesOverride,\n cardButton: { ...base.cardButton, ...stylesOverride.cardButton },\n cardFormContainer: { ...base.cardFormContainer, ...stylesOverride.cardFormContainer },\n backButton: { ...base.backButton, ...stylesOverride.backButton },\n backButtonIcon: { ...base.backButtonIcon, ...stylesOverride.backButtonIcon },\n submitButton: { ...base.submitButton, ...stylesOverride.submitButton },\n title: { ...base.title, ...stylesOverride.title },\n };\n }, [themeBundle, buttonsTheme, stylesOverride]);\n\n // Match the theme's tile radius so the interim skeletons line up with the\n // eventual buttons. Same derivation as the FloPayCheckout loading path\n // above — keeps the two skeleton surfaces consistent.\n const skeletonRadius =\n (themeBundle?.buttonsLayout?.cardButton?.borderRadius as string | number | undefined) ??\n (themeBundle?.appearance.variables?.borderRadius as string | undefined) ??\n 8;\n const skeleton = (h: number) => (\n <div style={{\n height: h, borderRadius: skeletonRadius, background: '#e5e7eb',\n animation: 'flopay-interim-pulse 1.5s ease-in-out infinite',\n }} />\n );\n const cardButtonSizing = cardButtonContent === undefined\n ? { boxSizing: 'border-box' as const, height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: '0 1rem' }\n : { padding: '0.9rem 1rem' };\n\n if (showCardForm) {\n // Show a card form placeholder with back button — real form takes over when Stripe loads\n const inputBorder = bStyles.cardInputBorder ?? '#e5e7eb';\n const inputBg = bStyles.cardInputBackground ?? 'white';\n const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);\n const hideTitle = isEmptySlotContent(cardTitleContent);\n return (\n <div style={{\n backgroundColor: (bStyles.cardFormContainer?.backgroundColor as string) ?? 'white',\n borderRadius: '8px',\n animation: 'flopay-interim-expand 0.35s cubic-bezier(0.4, 0, 0.2, 1) both',\n overflow: 'hidden',\n ...bStyles.cardFormContainer as React.CSSProperties,\n }}>\n <div style={{ display: 'flex', alignItems: 'center', padding: '0.75rem 0 0.625rem' }}>\n <button\n type=\"button\"\n onClick={() => {\n if (!isCardOpenControlled) {\n setShowCardForm(false);\n }\n }}\n aria-label=\"Back to payment methods\"\n disabled={isCardOpenControlled || cardLoading}\n style={{\n display: 'inline-flex', alignItems: 'center', gap: hideBackButtonLabel ? 0 : '0.5rem',\n background: 'none', border: 'none',\n color: '#4b5563', fontSize: '0.85rem', fontWeight: 500,\n padding: 0, flexShrink: 0, opacity: isCardOpenControlled || cardLoading ? 0.6 : 1,\n cursor: isCardOpenControlled || cardLoading ? 'not-allowed' : 'pointer',\n ...bStyles.backButton as React.CSSProperties,\n }}\n >\n <span style={{\n display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: '50%',\n backgroundColor: '#f3f4f6',\n ...bStyles.backButtonIcon as React.CSSProperties,\n }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n </span>\n <BackButtonContentSlot content={cardBackButtonContent} />\n </button>\n {hideTitle ? (\n <div style={{ flex: 1 }} />\n ) : (\n <div style={{\n flex: 1, textAlign: 'center', fontWeight: 600, fontSize: '1.05rem',\n color: '#262833', paddingRight: 80,\n ...bStyles.title as React.CSSProperties,\n }}>\n <TitleContentSlot content={cardTitleContent} />\n </div>\n )}\n </div>\n {/* Skeleton card fields */}\n <div style={{ backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }}>\n <div style={{ width: '60%', height: 14, borderRadius: 4, background: '#e5e7eb', animation: 'flopay-interim-pulse 1.5s ease-in-out infinite' }} />\n </div>\n <div style={{ display: 'flex' }}>\n <div style={{\n flex: 1, backgroundColor: inputBg,\n borderTop: 'none', borderRight: 'none',\n borderBottom: `1px solid ${inputBorder}`, borderLeft: `1px solid ${inputBorder}`,\n borderBottomLeftRadius: 8, padding: 12, height: 45,\n }}>\n <div style={{ width: '50%', height: 14, borderRadius: 4, background: '#e5e7eb', animation: 'flopay-interim-pulse 1.5s ease-in-out infinite' }} />\n </div>\n <div style={{\n flex: 1, backgroundColor: inputBg,\n borderTop: 'none',\n borderRight: `1px solid ${inputBorder}`,\n borderBottom: `1px solid ${inputBorder}`,\n borderLeft: `1px solid ${inputBorder}`,\n borderBottomRightRadius: 8, padding: 12, height: 45,\n }}>\n <div style={{ width: '40%', height: 14, borderRadius: 4, background: '#e5e7eb', animation: 'flopay-interim-pulse 1.5s ease-in-out infinite' }} />\n </div>\n </div>\n <div style={{ backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }}>\n <div style={{ width: '45%', height: 14, borderRadius: 4, background: '#e5e7eb', animation: 'flopay-interim-pulse 1.5s ease-in-out infinite' }} />\n </div>\n <div style={{\n height: 50, borderRadius: 8, marginTop: 16, background: '#c8c8ff',\n animation: 'flopay-interim-pulse 1.5s ease-in-out infinite',\n ...bStyles.submitButton as React.CSSProperties,\n opacity: 0.5,\n }} />\n <style>{`\n @keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }\n @keyframes flopay-interim-expand {\n 0% { opacity: 0; max-height: 0; transform: translateY(-12px); }\n 40% { opacity: 1; }\n 100% { opacity: 1; max-height: 600px; transform: translateY(0); }\n }\n `}</style>\n </div>\n );\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n {showStripe && (showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n {showStripe && (\n <button\n type=\"button\"\n onClick={async () => {\n if (cardLoading) return;\n if (onCardButtonClick) {\n await onCardButtonClick();\n return;\n }\n onButtonClick?.('card');\n setShowCardForm(true);\n }}\n disabled={cardLoading}\n style={{\n width: '100%',\n ...cardButtonSizing,\n backgroundColor: 'white', color: '#262833',\n border: '1px solid #d1d5db', borderRadius: '8px',\n fontSize: bStyles.cardButtonFontSize ?? '0.95rem', fontWeight: 600,\n cursor: cardLoading ? 'not-allowed' : 'pointer', display: 'flex',\n alignItems: 'center', justifyContent: 'center', gap: '0.625rem',\n boxShadow: '0 1px 2px rgba(0,0,0,0.04)',\n transition: 'transform 0.1s',\n position: 'relative',\n opacity: cardLoading ? 0.6 : 1,\n ...bStyles.cardButton as React.CSSProperties,\n }}\n onMouseDown={(e) => { e.currentTarget.style.transform = 'scale(0.985)'; }}\n onMouseUp={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}\n >\n <CardButtonContentSlot content={cardButtonContent} />\n </button>\n )}\n {errorMessage && (\n <div style={{\n margin: '0.25rem 0', padding: '0.625rem 0.875rem',\n background: '#FEF2F2', border: '1px solid #FECACA', borderRadius: '8px',\n color: '#991B1B', fontSize: '0.85rem', fontWeight: 600,\n display: 'flex', alignItems: 'center', gap: '0.5rem',\n ...(bStyles.errorBanner as React.CSSProperties | undefined),\n }}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" style={{ flexShrink: 0 }}>\n <path d=\"M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" stroke=\"#DC2626\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n {errorMessage}\n </div>\n )}\n <style>{`@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }`}</style>\n </div>\n );\n}\n","import React from 'react';\n\nexport function DefaultCardButtonContent(): React.ReactElement {\n return (\n <>\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"5\" rx=\"2\" />\n <line x1=\"2\" x2=\"22\" y1=\"10\" y2=\"10\" />\n </svg>\n Credit / Debit Card\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#9ca3af\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ position: 'absolute', right: '1rem' }}\n aria-hidden=\"true\"\n >\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n </>\n );\n}\n\nexport function DefaultBackButtonContent(): React.ReactElement {\n return <>Go back</>;\n}\n\nexport function DefaultTitleContent(): React.ReactElement {\n return <>Secure card checkout</>;\n}\n\nexport function isEmptySlotContent(content: React.ReactNode | undefined): boolean {\n return content !== undefined && (content === '' || content === null || content === false);\n}\n\nexport function CardButtonContentSlot({\n content,\n}: {\n content?: React.ReactNode;\n}): React.ReactElement {\n return <>{content === undefined ? <DefaultCardButtonContent /> : content}</>;\n}\n\nexport function BackButtonContentSlot({\n content,\n}: {\n content?: React.ReactNode;\n}): React.ReactElement {\n return <>{content === undefined ? <DefaultBackButtonContent /> : content}</>;\n}\n\nexport function TitleContentSlot({\n content,\n}: {\n content?: React.ReactNode;\n}): React.ReactElement {\n return <>{content === undefined ? <DefaultTitleContent /> : content}</>;\n}\n","import React, { useEffect, useRef, useContext } from 'react';\nimport type { ElementType, ElementChangeEvent, ElementOptions, MountedElement } from '@flopay/shared';\nimport { FloPayContext } from './context.js';\n\n/** Common props shared by all element components. */\nexport interface ElementComponentProps {\n /** Additional CSS class for the wrapper div. */\n className?: string;\n /** Element id attribute for the wrapper div. */\n id?: string;\n /** Inline styles for the wrapper div. */\n style?: React.CSSProperties;\n /** Options forwarded to the underlying element. */\n options?: Partial<ElementOptions>;\n /** Fired when the element's value changes. */\n onChange?: (event: ElementChangeEvent) => void;\n /** Fired when the element is fully rendered and ready. */\n onReady?: () => void;\n /** Fired when the element gains focus. */\n onFocus?: () => void;\n /** Fired when the element loses focus. */\n onBlur?: () => void;\n /** Fired when the Escape key is pressed inside the element. */\n onEscape?: () => void;\n}\n\n/**\n * Generic element component factory.\n *\n * Each element component:\n * 1. Gets the Elements instance from context\n * 2. Creates the appropriate element type\n * 3. Mounts it to a ref'd container div\n * 4. Forwards events as props\n * 5. Cleans up on unmount\n *\n * TODO: In a future phase, each element will render inside an iframe\n * for PCI DSS SAQ-A compliance. For now, they wrap the provider's\n * elements directly.\n */\nfunction createElementComponent(\n elementType: ElementType,\n displayName: string,\n): React.FC<ElementComponentProps> {\n function ElementComponent({\n className,\n id,\n style,\n options,\n onChange,\n onReady,\n onFocus,\n onBlur,\n onEscape,\n }: ElementComponentProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const elementRef = useRef<MountedElement | null>(null);\n const { elements, reportInteractive } = useContext(FloPayContext);\n\n useEffect(() => {\n if (!elements || !containerRef.current) return;\n\n let mounted = true;\n\n (async () => {\n // Reuse existing element if Stripe already created one of this type\n // (handles React Strict Mode double-mount).\n let element = elements.getElement(elementType);\n if (!element) {\n element = await elements.create(elementType, options);\n }\n\n if (!mounted || !containerRef.current) {\n return;\n }\n\n element.mount(containerRef.current);\n elementRef.current = element;\n\n if (onChange) element.on('change', onChange as (...args: unknown[]) => void);\n element.on('ready', () => {\n reportInteractive?.();\n onReady?.();\n });\n if (onFocus) element.on('focus', onFocus as (...args: unknown[]) => void);\n if (onBlur) element.on('blur', onBlur as (...args: unknown[]) => void);\n if (onEscape) element.on('escape', onEscape as (...args: unknown[]) => void);\n })();\n\n return () => {\n mounted = false;\n // Unmount only — don't destroy. Stripe Elements tracks elements\n // internally; destroying prevents reuse on Strict Mode remount.\n // Guard with try/catch: the element may already be destroyed if\n // the parent provider recreated the Elements group (e.g. on\n // appearance change).\n if (elementRef.current) {\n try {\n elementRef.current.unmount();\n } catch {\n // Element already destroyed — safe to ignore\n }\n elementRef.current = null;\n }\n };\n }, [elements, reportInteractive]);\n\n return <div ref={containerRef} className={className} id={id} style={style} />;\n }\n\n ElementComponent.displayName = displayName;\n return ElementComponent;\n}\n\n/**\n * Renders the unified Payment Element — a single component that accepts\n * cards, wallets, and other payment methods.\n *\n * TODO: Will render inside an iframe for PCI compliance in a future phase.\n */\nexport const PaymentElement = createElementComponent('payment', 'PaymentElement');\n\n/**\n * Renders a combined card input (number + expiry + CVC).\n *\n * TODO: Will render inside an iframe for PCI compliance in a future phase.\n */\nexport const CardElement = createElementComponent('card', 'CardElement');\n\n/**\n * Renders a card number input field.\n *\n * TODO: Will render inside an iframe for PCI compliance in a future phase.\n */\nexport const CardNumberElement = createElementComponent('cardNumber', 'CardNumberElement');\n\n/**\n * Renders a card expiry input field.\n *\n * TODO: Will render inside an iframe for PCI compliance in a future phase.\n */\nexport const CardExpiryElement = createElementComponent('cardExpiry', 'CardExpiryElement');\n\n/**\n * Renders a card CVC input field.\n *\n * TODO: Will render inside an iframe for PCI compliance in a future phase.\n */\nexport const CardCvcElement = createElementComponent('cardCvc', 'CardCvcElement');\n\n/**\n * Renders an address input element.\n */\nexport const AddressElement = createElementComponent('address', 'AddressElement');\n","import {\n CardCvcElement,\n CardExpiryElement,\n CardNumberElement,\n} from './elements.js';\nimport {\n ExpressCheckoutElement,\n PaymentElement,\n Elements as StripeElements,\n useElements as useStripeElements,\n useStripe as useStripeRaw,\n} from '@stripe/react-stripe-js';\nimport type {\n BeforeButtonClickEvent,\n CardCaptureAdapter,\n CardCaptureMountOptions,\n CheckoutButtonMethod,\n CheckoutSession,\n VaultCaptureBlock,\n DeclineEvent,\n GatewayEnvironment,\n InlineSessionPatch,\n PaymentResult,\n TokenizedBody,\n ButtonsLayoutStyles,\n AVSFieldConfig,\n} from '@flopay/shared';\nimport {\n resolveButtonsLayoutTheme,\n getPostalCodeLabel,\n getStateLabel,\n getStateOptions,\n COUNTRY_OPTIONS,\n resolveAVSConfig,\n isAVSFieldVisible,\n getStateFromPostalCode,\n isPostalCodeSupported,\n isValidPostalCode,\n getPostalCodeExample,\n filterStripeMethodsByCountry,\n getStripeMethodDisplayName,\n hasVendoredStripeMethodLogo,\n needsStripeMethodExplicitConfirm,\n resolveStripeMethodBrandVariant,\n partitionStripeMethods,\n stripeExpressMethodToOptionKey,\n} from '@flopay/shared';\nimport { PaymentAPI } from '@flopay/js';\nimport { VaultCardFields } from './vault-card-fields.js';\nimport React, { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport type {\n Stripe,\n StripeExpressCheckoutElementConfirmEvent,\n StripeExpressCheckoutElementReadyEvent,\n} from '@stripe/stripe-js';\nimport { useBillingApiUrl, useElements, useFloPay, usePayPalFloPay } from './hooks.js';\nimport { getFloPayTelemetryBridge } from './telemetry-bridge.js';\nimport { CheckoutContext } from './context.js';\nimport {\n BackButtonContentSlot,\n CardButtonContentSlot,\n TitleContentSlot,\n isEmptySlotContent,\n} from './card-button-content.js';\nimport {\n PROCESSING_OVERLAY_ERROR_DELAY_MS,\n PROCESSING_OVERLAY_SUCCESS_DELAY_MS,\n ProcessingOverlay,\n type OverlayStatus,\n} from './processing-overlay.js';\nimport {\n buildDeclineEvent,\n buildFloPayApiErrorFromResponse,\n mergeAccountPatch,\n resolvePaymentIntentPaymentMethodId,\n resolveTokenizedPaymentMethodId,\n resolveWalletElementsMode,\n retrievePaymentIntentFromProvider,\n} from './checkout-utils.js';\nimport { markSessionRecentlyCompleted } from './recent-completion.js';\nimport { isInAppBrowser } from './in-app-browser.js';\nimport { DirectPayPalButton } from './direct-paypal-button.js';\nimport { invokeMerchantCallback } from './merchant-callback.js';\nimport {\n EXTERNAL_METHOD_CALLBACK_GRACE_MS,\n getProviderDeclineCode,\n getProviderErrorCode,\n isProviderDecline,\n isPopupBlockedError,\n sanitizeExternalFailureCode,\n} from './external-method-recovery.js';\n\nimport { FloPayError, isSetupIntentClientSecret, resolveTheme } from '@flopay/shared';\n\n/**\n * localStorage key for persisting Stripe-redirect payment state across the\n * round-trip to an external authorization page (PayPal, Cash App Pay, Klarna,\n * iDEAL, …). The legacy `flopay_wallet_resume` key is still read for one\n * minor — payloads written by older SDK builds keep resuming after upgrade.\n */\nconst STRIPE_RESUME_KEY = 'flopay_stripe_resume';\nconst LEGACY_WALLET_RESUME_KEY = 'flopay_wallet_resume';\n// PayPal-direct (ExpressCheckoutElement) uses its own resume effect; this key\n// carries the effective session / nonce / accountPatch across the redirect so\n// the resume handler can /process against the same session PayPal authorized\n// (an inline-session bootstrap inside `runBeforeButtonClick` would otherwise\n// be lost when the page reloads after the PayPal round-trip).\nconst PAYPAL_RESUME_KEY = 'flopay_paypal_resume';\n\n/**\n * True when an error from `patchAccountSnapshot` is a client validation\n * rejection (HTTP 4xx) — e.g. the backend's country-aware postcode check\n * refusing the address. These must surface to the buyer (inline + `onError`).\n * A transient 5xx / network / abort failure is NOT a validation error and stays\n * best-effort (the backend listener falls back to the session baseline).\n */\nfunction isAccountValidationError(err: unknown): boolean {\n return (\n err instanceof FloPayError &&\n typeof err.statusCode === 'number' &&\n err.statusCode >= 400 &&\n err.statusCode < 500\n );\n}\n\n/**\n * Normalize a {@link VaultCaptureBlock} into the adapter's\n * {@link CardCaptureMountOptions}, threading the `messageToken` / `expectedOrigin`\n * authenticity markers through when the backend supplies them. Returns `null`\n * when there is no widget HTML to mount.\n */\nfunction toVaultMount(block: VaultCaptureBlock | undefined): CardCaptureMountOptions | null {\n if (!block?.html) return null;\n return {\n html: block.html,\n ...(block.messageToken ? { messageToken: block.messageToken } : {}),\n ...(block.expectedOrigin ? { expectedOrigin: block.expectedOrigin } : {}),\n };\n}\n\ntype MaybePromise<T> = T | Promise<T>;\n\n/**\n * Darken a `#rrggbb` color by `amount` (0–1) — used to derive a flo-button hover\n * shade from the primary when the theme doesn't supply an explicit\n * `colorPrimaryHover`. Returns the input unchanged for non-hex values.\n */\nexport function darkenHex(hex: string, amount = 0.12): string {\n const match = /^#?([0-9a-fA-F]{6})$/.exec(hex.trim());\n if (!match) return hex;\n const value = parseInt(match[1], 16);\n const scale = Math.max(0, Math.min(1, 1 - amount));\n const r = Math.round(((value >> 16) & 0xff) * scale);\n const g = Math.round(((value >> 8) & 0xff) * scale);\n const b = Math.round((value & 0xff) * scale);\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}`;\n}\n\n// ─── Global keyframes (always present — not gated behind overlay render) ────\n\n// PayPal SDK's .paypal-buttons wrapper is `display: inline-block` with a\n// default margin. In a block container it leaves baseline-descender space\n// below, which visually doubles the parent's flex `gap`. Force margin: 0 +\n// vertical-align: top to neutralise both.\nconst FLOPAY_KEYFRAMES = `\n.paypal-buttons { margin: 0 !important; vertical-align: top !important; }\n@keyframes flopay-spin { to { transform: rotate(360deg); } }\n@keyframes flopay-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }\n@keyframes flopay-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }\n@keyframes flopay-buttons-enter {\n 0% { opacity: 0; transform: translateX(-16px) scale(0.97); }\n 100% { opacity: 1; transform: translateX(0) scale(1); }\n}\n@keyframes flopay-buttons-exit {\n 0% { opacity: 1; transform: translateX(0) scale(1); }\n 100% { opacity: 0; transform: translateX(-16px) scale(0.97); }\n}\n@keyframes flopay-card-enter {\n 0% { opacity: 0; transform: translateX(16px) scale(0.97); }\n 100% { opacity: 1; transform: translateX(0) scale(1); }\n}\n@keyframes flopay-card-exit {\n 0% { opacity: 1; transform: translateX(0) scale(1); }\n 100% { opacity: 0; transform: translateX(16px) scale(0.97); }\n}\n`;\n\nconst DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;\n\n/**\n * Shared \"primary button\" base style for the two buyer-action buttons in the\n * buttons-layout (the \"Credit / Debit Card\" button + `FloPayAutomaticPaymentButton`).\n *\n * - `'classic'` / no theme: white background, grey border — historic look\n * that lines up with the wallet ECE row's flat tiles.\n * - Any theme bundle (`modern-*`, `bold-*`, `glass-*`): `colorPrimary`\n * (`resolvedPrimaryColor` — already merged with any `appearance` override)\n * drives the `backgroundColor`, exactly like the \"Confirm Payment\" submit\n * CTA, so all three flo buttons (submit, card, auto-pay) share one fill and\n * a per-checkout `colorPrimary` override re-skins every one of them. The\n * bundle's `submitButton` still supplies `color` / `border` / `borderRadius`\n * / `boxShadow` so typography + shape stay on-theme. Hover (`colorPrimaryHover`)\n * is applied by each button's `onMouseEnter`/`onMouseLeave` at the call site.\n */\nexport function derivePrimaryTileStyle(opts: {\n themeBundle: import('@flopay/shared').ThemeBundle | null | undefined;\n resolvedPrimaryColor: string;\n resolvedBorderRadius: string;\n submitButtonStyle?: React.CSSProperties;\n /**\n * Raw `appearance.colorPrimary` (undefined when the merchant didn't set one).\n * When present it forces a primary-filled tile even with no theme bundle\n * (the `classic` preset), so an explicit `colorPrimary` override always wins\n * over the historic white tile.\n */\n explicitPrimaryColor?: string;\n}): React.CSSProperties {\n // Historic white tile only when there's neither a theme bundle nor an\n // explicit `colorPrimary` override to honor.\n if (!opts.themeBundle && !opts.explicitPrimaryColor) {\n return {\n backgroundColor: 'white',\n color: '#262833',\n border: '1px solid #d1d5db',\n borderRadius: opts.resolvedBorderRadius,\n boxShadow: '0 1px 2px rgba(0,0,0,0.04)',\n };\n }\n // A theme bundle reads color / border / radius / shadow off its submit CTA so\n // the tile mirrors it; an explicit override with no bundle gets a clean\n // primary fill (white text, no border, theme radius).\n const submit = opts.themeBundle ? (opts.submitButtonStyle ?? {}) : {};\n return {\n // `colorPrimary` wins so a per-checkout override re-skins the card / auto-pay\n // buttons in lock-step with the submit CTA (which also keys off it).\n backgroundColor: opts.resolvedPrimaryColor,\n color: (submit.color as string | undefined) ?? 'white',\n border: (submit.border as string | undefined) ?? 'none',\n borderRadius: (submit.borderRadius as string | number | undefined) ?? opts.resolvedBorderRadius,\n boxShadow: submit.boxShadow as string | undefined,\n };\n}\n\n// Buttons-panel hide style used in `layout=\"buttons\"` when the card form is in\n// view. PayPal's Stripe ExpressCheckoutElement (and the direct PayPal SDK)\n// renders its button into a cross-origin iframe whose painted content ignores\n// the parent's `visibility: hidden`. Without `height: 0 + overflow: hidden`\n// the PayPal button stays visually painted on the card-details step even\n// though it is logically hidden. Keeping the panel mounted (rather than\n// unmounting) preserves PayPal/wallet Elements state across the transition.\nconst BUTTONS_PANEL_HIDDEN_STYLE: React.CSSProperties = {\n visibility: 'hidden',\n position: 'absolute',\n pointerEvents: 'none',\n width: '100%',\n height: 0,\n overflow: 'hidden',\n};\n\ntype TokenizedBodyOverrides = {\n accountPatch?: InlineSessionPatch['account'];\n completionPaymentMethodId?: string;\n sessionId?: string;\n nonce?: string;\n};\n\ntype InternalTokenizedBodyHandler = (\n body: TokenizedBody,\n overrides?: TokenizedBodyOverrides,\n) => void;\n\ntype BeforeButtonClickPatchResult = {\n error: FloPayError | null;\n sessionId?: string;\n nonce?: string;\n};\n\ntype BeforeButtonClickResult = {\n proceed: boolean;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n};\n\ntype RunBeforeButtonClick = (method: CheckoutButtonMethod) => Promise<BeforeButtonClickResult>;\ntype ExternalAttemptPrepared = Pick<BeforeButtonClickResult, 'accountPatch' | 'sessionId' | 'nonce'>;\n\ntype ExternalMethodTechnicalFailureHandler = (\n method: string,\n err: unknown,\n options?: { code?: string; popupBlocked?: boolean },\n) => void;\n\nconst EXTERNAL_METHOD_RECOVERY_BUTTON_STYLE: React.CSSProperties = {\n width: '100%',\n minHeight: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT,\n margin: '0 0 0.5rem',\n padding: '0.75rem 0.875rem',\n border: '1px solid #2563eb',\n borderRadius: 8,\n background: '#eff6ff',\n color: '#1d4ed8',\n fontSize: '0.95rem',\n fontWeight: 700,\n cursor: 'pointer',\n};\n\nfunction getButtonMethodLabel(method: CheckoutButtonMethod): string {\n switch (method) {\n case 'paypal': return 'PayPal';\n case 'apple_pay': return 'Apple Pay';\n case 'google_pay': return 'Google Pay';\n default: return 'Card';\n }\n}\n\nfunction checkoutButtonMethodFromProviderMethod(method: string | undefined): CheckoutButtonMethod {\n if (method === 'paypal') return 'paypal';\n if (method === 'apple_pay') return 'apple_pay';\n return 'google_pay';\n}\n\nfunction getExternalMethodDisplayName(method: string): string {\n return method === 'paypal' ? 'PayPal' : getStripeMethodDisplayName(method);\n}\n\nfunction buildExternalMethodRecoveryMessage(method: string, popupBlocked: boolean): string {\n const base = `We couldn't open ${getExternalMethodDisplayName(method)}. Try again or choose another payment method.`;\n return popupBlocked ? `${base} Allow pop-ups for this site, then try again.` : base;\n}\n\nfunction useExternalAttemptReconciliation(onMissingTerminal: ExternalMethodTechnicalFailureHandler) {\n const generationRef = useRef(0);\n const invalidatedGenerationRef = useRef<number | null>(null);\n const attemptRef = useRef<{\n generation: number;\n method: string;\n timer: ReturnType<typeof setTimeout> | null;\n yieldedControl: boolean;\n } | null>(null);\n\n const clearAttemptTimer = useCallback((targetAttempt = attemptRef.current) => {\n const attempt = targetAttempt;\n if (attempt?.timer) {\n clearTimeout(attempt.timer);\n attempt.timer = null;\n }\n }, []);\n\n const armAttemptTimer = useCallback((\n attempt: NonNullable<typeof attemptRef.current>,\n delayMs: number,\n ) => {\n if (typeof document !== 'undefined' && document.visibilityState !== 'visible') return;\n\n clearAttemptTimer(attempt);\n attempt.timer = setTimeout(() => {\n attempt.timer = null;\n if (attemptRef.current?.generation !== attempt.generation) return;\n attemptRef.current = null;\n invalidatedGenerationRef.current = attempt.generation;\n onMissingTerminal(\n attempt.method,\n new Error('External payment method returned without a terminal callback.'),\n { code: 'external_method_missing_terminal_callback' },\n );\n }, delayMs);\n }, [clearAttemptTimer, onMissingTerminal]);\n\n const armRecoveryTimer = useCallback((attempt: NonNullable<typeof attemptRef.current>) => {\n if (!attempt.yieldedControl) return;\n armAttemptTimer(attempt, EXTERNAL_METHOD_CALLBACK_GRACE_MS);\n }, [armAttemptTimer]);\n\n const startAttempt = useCallback((method: string) => {\n clearAttemptTimer();\n const generation = generationRef.current + 1;\n generationRef.current = generation;\n invalidatedGenerationRef.current = null;\n const attempt = { generation, method, timer: null, yieldedControl: false };\n attemptRef.current = attempt;\n return generation;\n }, [clearAttemptTimer]);\n\n const finishAttempt = useCallback((generation?: number) => {\n const attempt = attemptRef.current;\n if (typeof generation === 'number' && attempt?.generation !== generation) return false;\n clearAttemptTimer(attempt);\n attemptRef.current = null;\n if (typeof generation !== 'number' || invalidatedGenerationRef.current === generation) {\n invalidatedGenerationRef.current = null;\n }\n return true;\n }, [clearAttemptTimer]);\n\n const invalidateAttempt = useCallback((generation?: number) => {\n const attempt = attemptRef.current;\n const targetGeneration = generation ?? attempt?.generation ?? generationRef.current;\n if (!generation || attempt?.generation === generation) {\n clearAttemptTimer(attempt);\n attemptRef.current = null;\n }\n invalidatedGenerationRef.current = targetGeneration;\n }, [clearAttemptTimer]);\n\n const isAttemptInvalidated = useCallback(\n (generation?: number) => invalidatedGenerationRef.current === (generation ?? generationRef.current),\n [],\n );\n\n const isAttemptCurrent = useCallback(\n (generation: number) => (\n attemptRef.current?.generation === generation &&\n invalidatedGenerationRef.current !== generation\n ),\n [],\n );\n\n const scheduleRecoveryIfReturned = useCallback(() => {\n const attempt = attemptRef.current;\n if (!attempt) return;\n armRecoveryTimer(attempt);\n }, [armRecoveryTimer]);\n\n const markAttemptYieldedControl = useCallback(() => {\n const attempt = attemptRef.current;\n if (!attempt) return;\n attempt.yieldedControl = true;\n clearAttemptTimer(attempt);\n }, [clearAttemptTimer]);\n\n useEffect(() => {\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'visible') {\n scheduleRecoveryIfReturned();\n } else {\n markAttemptYieldedControl();\n }\n };\n const handleBlur = () => {\n markAttemptYieldedControl();\n };\n document.addEventListener('visibilitychange', handleVisibilityChange);\n window.addEventListener('blur', handleBlur);\n window.addEventListener('focus', scheduleRecoveryIfReturned);\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n window.removeEventListener('blur', handleBlur);\n window.removeEventListener('focus', scheduleRecoveryIfReturned);\n clearAttemptTimer();\n };\n }, [clearAttemptTimer, markAttemptYieldedControl, scheduleRecoveryIfReturned]);\n\n return { startAttempt, finishAttempt, invalidateAttempt, isAttemptInvalidated, isAttemptCurrent };\n}\n\n/**\n * Inline copy for a postcode that is non-empty but malformed for the selected\n * country, appending the country-specific expected format when we have one\n * (e.g. \"Enter a valid ZIP Code (e.g. 12345 or 12345-6789)\"). Shared by the\n * vault inline hint and the Stripe submit-time validation so both read alike.\n */\nfunction malformedPostcodeMessage(country: string): string {\n const example = getPostalCodeExample(country);\n return `Enter a valid ${getPostalCodeLabel(country)}${example ? ` (e.g. ${example})` : ''}`;\n}\n\n/**\n * Pure country-aware postcode state, the single source of truth for the\n * required/empty/malformed rules. Called with React state from the live\n * `postalCodeState` memo (drives the inline hint + vault gate) and with ref\n * values from `handleSubmit` (dodges stale closures at submit time); keeping\n * one implementation stops the two call sites drifting as the rules evolve. A\n * locale `validator` supports makes the postcode required *and* format-checked;\n * an unsupported / no-postcode locale fails open (`empty`/`malformed` stay\n * false). `visible` is the AVS field's per-country visibility, computed by the\n * caller since it depends on the caller's `avsConfig`.\n */\nfunction computePostalCodeState(country: string, zip: string, visible: boolean) {\n const supported = isPostalCodeSupported(country);\n const trimmed = zip.trim();\n const required = visible && supported;\n const empty = required && !trimmed;\n const malformed = required && !!trimmed && !isValidPostalCode(country, trimmed);\n return { visible, supported, required, empty, malformed };\n}\n\nfunction normalizeBeforeButtonClickError(\n method: CheckoutButtonMethod,\n err: unknown,\n): FloPayError {\n return err instanceof FloPayError\n ? err\n : new FloPayError(\n err instanceof Error ? err.message : `${getButtonMethodLabel(method)} before-click hook failed.`,\n 'validation_error',\n );\n}\n\nfunction FloPayKeyframes() {\n return <style>{FLOPAY_KEYFRAMES}</style>;\n}\n\nfunction toCssSize(value: string | number | undefined): string | undefined {\n if (typeof value === 'number') return `${value}px`;\n return value;\n}\n\nfunction toCssWeight(value: string | number | undefined): string | number | undefined {\n if (typeof value === 'number' || typeof value === 'string') return value;\n return undefined;\n}\n\n/**\n * Express-checkout element load states.\n *\n * - `loading`: initial — waiting for ExpressCheckoutElement's `ready` event.\n * - `ready`: at least one of the requested methods is available on this\n * device. Element renders.\n * - `unavailable`: the element initialized fine but `availablePaymentMethods`\n * reported none of the requested methods. The row collapses so buyers can\n * continue with another payment method.\n * - `load_error`: Stripe's `onLoadError` fired — the element couldn't\n * initialize at all (script blocked, network failure).\n */\ntype ExpressCheckoutLoadState = 'loading' | 'ready' | 'unavailable' | 'load_error';\n\nfunction resolveExpressCheckoutLoadState(\n event: StripeExpressCheckoutElementReadyEvent,\n methods: Array<string>,\n): ExpressCheckoutLoadState {\n const available = event.availablePaymentMethods as Record<string, boolean | undefined> | undefined;\n if (!available) return 'unavailable';\n\n return methods.some((method) => available[method]) ? 'ready' : 'unavailable';\n}\n\nfunction ExpressCheckoutReadySwap({\n state,\n placeholderTestId,\n borderRadius = 8,\n children,\n}: {\n state: ExpressCheckoutLoadState;\n placeholderTestId?: string;\n /**\n * Border radius for the pulse-skeleton placeholder. Defaults to `8` for\n * the classic look; consumers pass the theme's `borderRadius` (or the\n * theme bundle's `cardButton.borderRadius`) so the skeleton matches the\n * eventual button's corners — otherwise the placeholder reads as\n * visually unrelated to the wallet tile that replaces it.\n */\n borderRadius?: string | number;\n children: React.ReactNode;\n}) {\n if (state === 'unavailable' || state === 'load_error') return null;\n\n return (\n <div style={{ position: 'relative', minHeight: 44 }}>\n <div\n data-testid={placeholderTestId}\n aria-hidden={state === 'ready'}\n style={{\n position: 'absolute',\n inset: 0,\n height: 44,\n borderRadius,\n background: '#e5e7eb',\n animation: state === 'ready' ? undefined : 'flopay-pulse 1.5s ease-in-out infinite',\n opacity: state === 'ready' ? 0 : 1,\n transform: state === 'ready' ? 'scale(0.985)' : 'scale(1)',\n transition: 'opacity 140ms ease-out, transform 140ms ease-out',\n pointerEvents: 'none',\n }}\n />\n <div\n style={{\n minHeight: 44,\n opacity: state === 'ready' ? 1 : 0,\n transform: state === 'ready' ? 'translateY(0)' : 'translateY(2px)',\n transition: 'opacity 140ms ease-out, transform 140ms ease-out',\n pointerEvents: state === 'ready' ? 'auto' : 'none',\n }}\n >\n {children}\n </div>\n </div>\n );\n}\n\nfunction isExpressCheckoutRowVisible(state: ExpressCheckoutLoadState): boolean {\n return state !== 'unavailable' && state !== 'load_error';\n}\n\n/** Methods exposed via ref for external 3DS handling. */\nexport interface SplitCardFormRef {\n handleNextAction: (clientSecret: string) => Promise<void>;\n}\n\n/** Props for the `SplitCardForm` component. */\nexport interface SplitCardFormProps {\n /** The checkout session ID (UUID from billing API). */\n sessionId: string;\n /**\n * Session-bound checkout token returned by session creation\n * (`CheckoutSessionResult.nonce` or `session.clientSecret`). Forwarded as\n * `x-checkout-session-token` on every continuation request — required by\n * post-#640 backends. `FloPayCheckout` plumbs this prop automatically.\n */\n nonce?: string;\n /** Billing API base URL. Optional — defaults to the value from FloPayProvider or the shared constant. */\n billingApiUrl?: string;\n /** User's email (required for creating payment intents). */\n email?: string;\n /** User ID (required for processing payments). */\n userId?: string;\n /** Called when the full payment flow completes successfully. */\n onComplete?: (result: PaymentResult) => void;\n /** Called when a payment error occurs. */\n onError?: (error: FloPayError) => void;\n /** Called when a payment is declined or the authentication step fails. */\n onDecline?: (decline: DeclineEvent) => void;\n /**\n * **Override**: If provided, delegates backend submission to the caller.\n * When omitted, processes internally (calls processPayment + handles 3DS).\n */\n onTokenizedBody?: (tokenizedBody: TokenizedBody) => void;\n /** First name for billing. */\n firstName?: string;\n /** Last name for billing. */\n lastName?: string;\n /** Checkout version for A/B tracking. */\n chv?: string;\n /** Label for the submit button. */\n submitLabel?: string;\n /** Additional CSS class for the form wrapper. */\n className?: string;\n /** Custom children (overrides default submit button). */\n children?: React.ReactNode;\n /** External processing state. */\n isProcessing?: boolean;\n /** External error message. */\n error?: string | null;\n /** Called when internal error state changes. */\n onErrorChange?: (error: string | null) => void;\n /** Callback when the full cardholder name input changes. */\n onFullNameChange?: (value: string) => void;\n /** Callback when first name changes (from the name input). */\n onFirstNameChange?: (value: string) => void;\n /** Callback when last name changes (from the name input). */\n onLastNameChange?: (value: string) => void;\n /**\n * Show the PayPal payment surface above card fields. Defaults to `true`.\n * The renderer is chosen from `session.gateways.paypal`: when that gateway\n * is configured, `DirectPayPalButton` (PayPal JS SDK) takes over and Stripe\n * drops `paypal` from its express row to avoid double-rendering; otherwise\n * PayPal renders inside `ExpressCheckoutElement` (using either a dedicated\n * `gateways.stripe.paypalPublishableKey` sub-account or the main Stripe\n * account when the enabled-methods list includes `paypal`).\n */\n showPayPal?: boolean;\n /**\n * Show the Stripe-rendered checkout (card fields + ExpressCheckoutElement +\n * PaymentElement). Defaults to `true`. When `false`, every Stripe surface\n * is hidden — only `DirectPayPalButton` can render. Setting both\n * `showStripe={false}` and `showPayPal={false}` (with no PayPal gateway\n * configured) throws a bootstrap-time validation error.\n */\n showStripe?: boolean;\n /**\n * Per-session list of Stripe payment method type identifiers (as returned\n * by the billing API on `gateways.stripe.enabledPaymentMethods`). When\n * supplied, drives the contents of the `ExpressCheckoutElement` row and the\n * accordion `PaymentElement` instead of the historic hardcoded\n * Apple/Google/PayPal set. When omitted, the SDK falls back to the legacy\n * `showApplePay`/`showGooglePay`/`showPayPal` toggles.\n */\n enabledPaymentMethods?: string[];\n /**\n * Per-method buyer-country gate from `gateways.stripe.enabledPaymentMethodCountries`\n * (method → allowed ISO-3166-1 alpha-2 countries; a method absent here has no\n * country gate). The SDK filters the rendered tile row by the buyer's *live*\n * country against this map, so per-method country eligibility comes from the\n * backend rather than a hardcoded SDK table. When omitted (legacy backend),\n * the SDK falls back to its built-in {@link STRIPE_METHOD_COUNTRIES} table.\n */\n enabledPaymentMethodCountries?: Record<string, string[]>;\n /**\n * @deprecated The Apple Pay / Google Pay surface is now driven by the\n * `gateways.stripe.enabledPaymentMethods` list returned per-session by the\n * billing API. Pass {@link SplitCardFormProps.enabledPaymentMethods} (or\n * upgrade the backend so `FloPayCheckout` threads it through automatically).\n * Setting this prop emits a one-time deprecation warning and is otherwise\n * ignored when `enabledPaymentMethods` is supplied.\n */\n showApplePay?: boolean;\n /**\n * @deprecated See {@link SplitCardFormProps.showApplePay}.\n */\n showGooglePay?: boolean;\n /**\n * Layout mode for the payment form.\n * - `'default'` — all payment methods + card form shown together (current behavior)\n * - `'buttons'` — PayPal, wallets, and a \"Credit / Debit Card\" button; clicking the card\n * button expands the card form with a back button to return to the button view\n */\n layout?: 'default' | 'buttons';\n /**\n * High-level theme bundle that styles the whole checkout (Stripe-side\n * appearance + FloPay wrapper / submit button / inputs). One of:\n * `'classic'` (historic FloPay look, no bundle applied), `'modern-light'`,\n * `'modern-dark'`, `'bold-light'`, `'bold-dark'`, `'glass-light'`,\n * `'glass-dark'`. Explicit `appearance` / `buttonsStyles` props still\n * override their respective halves when provided.\n */\n theme?: import('@flopay/shared').ThemeId;\n /**\n * @deprecated Use `theme` instead. Legacy buttons-layout preset\n * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for\n * back-compat — the new union accepts the bundle ids too but you should\n * migrate to the `theme` prop.\n */\n buttonsTheme?: import('@flopay/shared').ButtonsLayoutTheme;\n /** Style overrides merged on top of the resolved theme bundle / buttonsTheme preset. */\n buttonsStyles?: import('@flopay/shared').ButtonsLayoutStyles;\n /**\n * Appearance from `FloPayProvider` / `FloPayCheckout`. Threaded through so\n * the React-rendered wrapper, submit button, title, and per-element card\n * field styling can derive colors from `appearance.variables` when no\n * explicit `buttonsStyles` is supplied. Bundle consumers (`THEMES[id]`) get\n * a coherent look without having to forward both halves manually.\n */\n appearance?: import('@flopay/shared').FloPayAppearance;\n /** Custom React content rendered inside the card button when `layout=\"buttons\"`. */\n cardButtonContent?: React.ReactNode;\n /** Custom React content rendered for the buttons-layout card back button label. */\n cardBackButtonContent?: React.ReactNode;\n /** Custom React content rendered for the card-form title. */\n cardTitleContent?: React.ReactNode;\n /**\n * @deprecated No longer rendered — the default-layout security footer was\n * removed alongside the theme-bundle refactor. Retained as an optional\n * prop so existing integrations type-check without changes.\n */\n showSecurityFooter?: boolean;\n /**\n * Called when a payment method button is clicked.\n * `method`: `'card'` | `'paypal'` | `'apple_pay'` | `'google_pay'`\n */\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n /**\n * Called before a payment button continues in `layout=\"buttons\"`.\n * Runs for card, PayPal, Apple Pay, and Google Pay.\n */\n onBeforeButtonClick?: (\n event: BeforeButtonClickEvent,\n ) => MaybePromise<void | false | InlineSessionPatch>;\n /**\n * Enable AVS (Address Verification).\n * - `true` — show country + postal code (backward compatible default)\n * - `AVSFieldConfig` — granular per-field control, optionally scoped to country codes\n * - `false` / omitted — AVS disabled\n */\n enableAVS?: boolean | AVSFieldConfig;\n /**\n * Per-merchant order of the hosted vault card rows — a permutation of\n * `['name','number','expiry']` (`'expiry'` is the combined expiry+CVV row;\n * the submit button stays last). Drives both the visual order and the tab\n * order inside the widget. Omit for the default (`name`, `number`, `expiry`).\n * Only applies on the vault card path.\n */\n cardFieldOrder?: import('@flopay/shared').VaultCardFieldKey[];\n /** Content rendered above the card form (below the wallet divider). */\n cardPreFormSlot?: React.ReactNode;\n /** Layout for AVS fields: 'row' (side-by-side, default) or 'column' (stacked). */\n avsLayout?: 'row' | 'column';\n /** Pre-filled country code (ISO 3166-1 alpha-2) for AVS. */\n country?: string;\n /** Pre-filled ZIP/postal code for AVS. */\n zip?: string;\n /** Pre-filled street address (line 1) for AVS. Typically from a partner GeoIP / profile lookup. */\n addressLine1?: string;\n /** Pre-filled apt/suite/unit (line 2) for AVS. */\n addressLine2?: string;\n /** Pre-filled city for AVS. Typically from a partner GeoIP / profile lookup. */\n city?: string;\n /** Pre-filled state/province for AVS. Typically from a partner GeoIP / profile lookup. */\n state?: string;\n /** Callback when AVS country changes. */\n onCountryChange?: (country: string) => void;\n /** Callback when AVS ZIP/postal code changes. */\n onZipChange?: (zip: string) => void;\n // ── Checkout analytics metadata ──\n /** Whether AVS was enabled (sent to backend for analytics). */\n avsCheck?: boolean;\n /** Checkout type: 'standard_checkout' or 'embedded_checkout'. */\n checkoutType?: string;\n /** Checkout layout: 'default_layout', 'buttons_layout', or 'custom_layout'. */\n checkoutLayout?: string;\n /** Total amount in cents (smallest currency unit). Used for wallet/PayPal Elements config. */\n totalAmount?: number;\n /** Currency code (used for PayPal Elements config). */\n currency?: string;\n /** Render the card form expanded on first paint when `layout=\"buttons\"`. */\n initialCardOpen?: boolean;\n /**\n * Direct PayPal gateway configuration. When provided, PayPal renders via\n * the official PayPal JS SDK (in-app browser compliant) instead of via\n * Stripe's ExpressCheckoutElement. Selection is mutually exclusive:\n * setting this disables the Stripe-rendered PayPal path automatically.\n */\n directPaypal?: {\n clientId: string;\n environment?: GatewayEnvironment;\n };\n /** Whether the active session represents a subscription (drives direct PayPal intent). */\n isSubscription?: boolean;\n /** Backing session — forwarded to direct-PayPal so it can populate accountData. */\n session?: CheckoutSession | null;\n /**\n * Enables on-screen diagnostic panels for the PayPal/wallet gating decision\n * and the `DirectPayPalButton` lifecycle. Intended for debugging in-app\n * browsers where remote console access is impractical. Off by default.\n */\n debug?: boolean;\n}\n\n/**\n * Split card checkout form matching `checkout/StripeCardForm`:\n * PayPal button → divider → CardNumber → CardExpiry + CardCVC → Full Name → Submit.\n *\n * PayPal uses its own Stripe Elements instance (no `paymentMethodCreation`)\n * exactly like checkout does with two separate `<Elements>` wrappers.\n */\nexport const SplitCardForm = forwardRef<SplitCardFormRef, SplitCardFormProps>(\n function SplitCardForm(props, ref) {\n return <SplitCardFormInner {...props} innerRef={ref} />;\n },\n);\n\n// ─── PayPal button (own Elements instance) ──────────────────────────────────\n// Mirrors checkout/StripeCardForm's StripePayPalButtonInner exactly.\n\nfunction PayPalButtonInner({\n sessionId,\n nonce,\n email,\n billingApiUrl,\n onTokenizedBody,\n onErrorChange,\n isProcessing = false,\n onButtonClick,\n onDecline,\n onTechnicalFailure,\n runBeforeButtonClick,\n onLoadStateChange,\n placeholderBorderRadius,\n}: {\n sessionId: string;\n nonce?: string;\n email?: string;\n billingApiUrl: string;\n onTokenizedBody: InternalTokenizedBodyHandler;\n onErrorChange?: (error: string | null) => void;\n isProcessing?: boolean;\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n onDecline?: (decline: DeclineEvent) => void;\n onTechnicalFailure?: ExternalMethodTechnicalFailureHandler;\n runBeforeButtonClick?: RunBeforeButtonClick;\n onLoadStateChange?: (state: ExpressCheckoutLoadState) => void;\n placeholderBorderRadius?: string | number;\n}) {\n const flopay = useFloPay();\n const stripe = useStripeRaw();\n const elements = useStripeElements();\n const [loadState, setLoadState] = useState<ExpressCheckoutLoadState>('loading');\n useEffect(() => {\n onLoadStateChange?.(loadState);\n }, [loadState, onLoadStateChange]);\n const [submitting, setSubmitting] = useState(false);\n const paypalResumeAttempted = useRef(false);\n const focusTargetRef = useRef<HTMLDivElement | null>(null);\n const recoveryActionRef = useRef<HTMLButtonElement | null>(null);\n const [surfaceKey, setSurfaceKey] = useState(0);\n const [showRecoveryAction, setShowRecoveryAction] = useState(false);\n const pendingProviderFocusRef = useRef(false);\n const attemptContextBySurfaceRef = useRef(new Map<number, {\n generation: number;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n }>());\n const baseUrl = billingApiUrl.replace(/\\/+$/, '');\n const {\n startAttempt,\n finishAttempt,\n invalidateAttempt,\n isAttemptInvalidated,\n isAttemptCurrent,\n } = useExternalAttemptReconciliation((method, err, options) => {\n onTechnicalFailure?.(method, err, {\n ...options,\n popupBlocked: options?.popupBlocked ?? isPopupBlockedError(err),\n });\n setShowRecoveryAction(true);\n setSurfaceKey((key) => key + 1);\n });\n useEffect(() => {\n if (showRecoveryAction) recoveryActionRef.current?.focus();\n }, [showRecoveryAction, surfaceKey]);\n const resetSurface = useCallback(() => {\n setSurfaceKey((key) => key + 1);\n }, []);\n const recoverTechnicalFailure = useCallback((err: unknown, code?: string, generation?: number) => {\n invalidateAttempt(generation);\n onTechnicalFailure?.('paypal', err, { code, popupBlocked: isPopupBlockedError(err) });\n setShowRecoveryAction(true);\n resetSurface();\n }, [invalidateAttempt, onTechnicalFailure, resetSurface]);\n const focusProviderSurface = useCallback(() => {\n window.setTimeout(() => {\n const target = focusTargetRef.current?.querySelector<HTMLElement>('iframe');\n (target ?? focusTargetRef.current)?.focus();\n }, 0);\n }, []);\n useEffect(() => {\n if (!pendingProviderFocusRef.current) return;\n pendingProviderFocusRef.current = false;\n focusProviderSurface();\n }, [focusProviderSurface, surfaceKey]);\n const handleRecoveryActionClick = useCallback(() => {\n setShowRecoveryAction(false);\n onErrorChange?.(null);\n focusProviderSurface();\n }, [focusProviderSurface, onErrorChange]);\n\n // Resume PayPal redirect return — detect payment_intent in URL\n useEffect(() => {\n if (!stripe || paypalResumeAttempted.current) return;\n\n const params = new URLSearchParams(window.location.search);\n const paymentIntentId = params.get('payment_intent');\n const clientSecret = params.get('payment_intent_client_secret');\n const redirectStatus = params.get('redirect_status');\n\n if (!paymentIntentId || !clientSecret) return;\n paypalResumeAttempted.current = true;\n\n // Recover the effective session / nonce / accountPatch persisted by\n // `handlePayPalConfirm` before the redirect. Without this, an inline-\n // session bootstrap done inside `runBeforeButtonClick` (which set its\n // own sessionId + nonce) would be lost — the post-reload props expose\n // the freshly re-bootstrapped base session, not the one PayPal\n // authorized — and /process would 401 against the wrong nonce.\n let persistedOverrides: TokenizedBodyOverrides | undefined;\n try {\n const raw = localStorage.getItem(PAYPAL_RESUME_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as {\n clientSecret?: string;\n sessionId?: string;\n nonce?: string;\n accountPatch?: InlineSessionPatch['account'];\n };\n // Only honor the payload if it matches this PI — a stale entry from\n // an abandoned earlier attempt should not retarget the current resume.\n if (parsed.clientSecret === clientSecret) {\n persistedOverrides = {\n ...(parsed.accountPatch ? { accountPatch: parsed.accountPatch } : {}),\n ...(parsed.sessionId ? { sessionId: parsed.sessionId } : {}),\n ...(parsed.nonce ? { nonce: parsed.nonce } : {}),\n };\n }\n }\n } catch { /* ignore corrupt payload */ }\n try { localStorage.removeItem(PAYPAL_RESUME_KEY); } catch { /* ignore */ }\n\n // Strip Stripe's PayPal-redirect params from the URL up front, before any\n // async work. The resume `useRef` guard above is reset on remount — if a\n // remount races our async resume, the only way to stop it from re-firing\n // for the same PI is to make sure the URL no longer signals \"we're inside\n // a resume.\" Doing this synchronously (rather than only after a successful\n // /process) closes that re-entry window for every branch below.\n const cleanedUrl = new URL(window.location.href);\n cleanedUrl.searchParams.delete('payment_intent');\n cleanedUrl.searchParams.delete('payment_intent_client_secret');\n cleanedUrl.searchParams.delete('redirect_status');\n window.history.replaceState({}, '', cleanedUrl.toString());\n\n (async () => {\n try {\n setSubmitting(true);\n\n if (redirectStatus === 'failed') {\n const message = 'PayPal payment was declined. Please try again.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('paypal', message));\n return;\n }\n\n const { paymentIntent, error } = await stripe.retrievePaymentIntent(clientSecret);\n if (error) {\n onErrorChange?.(error.message ?? 'Failed to retrieve PayPal payment status.');\n return;\n }\n\n if (paymentIntent && (paymentIntent.status === 'requires_capture' || paymentIntent.status === 'succeeded')) {\n const paymentMethodId = typeof paymentIntent.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent.payment_method?.id;\n\n onTokenizedBody({\n id: paymentMethodId ?? paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n isPaypal: true,\n }, persistedOverrides);\n } else {\n const message = 'PayPal payment was not completed. Please try again.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('paypal', message));\n }\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'Failed to complete PayPal payment.');\n } finally {\n setSubmitting(false);\n }\n })();\n }, [stripe, onTokenizedBody, onErrorChange, onDecline]);\n\n const handlePayPalClick = useCallback(async (\n event: { resolve: () => void; reject: () => void },\n ) => {\n if (isProcessing || submitting) {\n event.reject();\n return;\n }\n\n const beforeClick = runBeforeButtonClick\n ? await runBeforeButtonClick('paypal')\n : { proceed: true } as BeforeButtonClickResult;\n\n if (!beforeClick.proceed) {\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n event.reject();\n return;\n }\n\n const generation = startAttempt('paypal');\n attemptContextBySurfaceRef.current.set(surfaceKey, {\n generation,\n accountPatch: beforeClick.accountPatch,\n sessionId: beforeClick.sessionId,\n nonce: beforeClick.nonce,\n });\n setShowRecoveryAction(false);\n onButtonClick?.('paypal');\n event.resolve();\n }, [attemptContextBySurfaceRef, isProcessing, onButtonClick, runBeforeButtonClick, startAttempt, submitting, surfaceKey]);\n\n // PayPal confirm handler — called by ExpressCheckoutElement onConfirm\n const handlePayPalConfirm = useCallback(async (event: StripeExpressCheckoutElementConfirmEvent) => {\n if (!stripe || !elements) return;\n const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);\n if (attemptContext && !isAttemptCurrent(attemptContext.generation)) {\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n return;\n }\n if (!attemptContext && isAttemptInvalidated()) return;\n if (attemptContext && !finishAttempt(attemptContext.generation)) return;\n if (!attemptContext) finishAttempt();\n\n let prepared: ExternalAttemptPrepared | null = attemptContext ?? null;\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n\n if (!prepared && runBeforeButtonClick) {\n const beforeClick = await runBeforeButtonClick('paypal');\n if (!beforeClick.proceed) {\n event.paymentFailed({ reason: 'fail', message: 'PayPal checkout was cancelled.' });\n return;\n }\n prepared = {\n accountPatch: beforeClick.accountPatch,\n sessionId: beforeClick.sessionId,\n nonce: beforeClick.nonce,\n };\n }\n\n const effectiveSessionId = prepared?.sessionId ?? sessionId;\n const effectiveNonce = prepared?.nonce ?? nonce;\n const effectiveEmail = prepared?.accountPatch?.email ?? email;\n\n try {\n setSubmitting(true);\n onErrorChange?.(null);\n\n if (!effectiveSessionId || !effectiveEmail) {\n throw new Error('Missing sessionId or email for PayPal payment');\n }\n\n const createPM = stripe.createPaymentMethod as unknown as (\n params: { type: string },\n ) => Promise<{ error?: { message?: string }; paymentMethod?: { id: string } }>;\n\n const { error: pmError, paymentMethod } = await createPM({ type: 'paypal' });\n if (pmError) {\n recoverTechnicalFailure(pmError, 'stripe_paypal_create_payment_method_failed', attemptContext?.generation);\n event.paymentFailed({ reason: 'fail' });\n return;\n }\n\n // 1. Create PaymentIntent via backend with the PayPal payment method.\n // isPaypal must be string 'true' — backend checks === 'true'.\n\n const intentHeaders: Record<string, string> = { 'Content-Type': 'application/json' };\n if (effectiveNonce) intentHeaders['x-checkout-session-token'] = effectiveNonce;\n const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {\n method: 'POST',\n headers: intentHeaders,\n body: JSON.stringify({\n sessionId: effectiveSessionId,\n email: effectiveEmail,\n paymentMethodType: paymentMethod?.id ?? 'paypal',\n isPaypal: 'true',\n setupFutureUsage: 'off_session',\n setup_future_usage: 'off_session',\n }),\n });\n\n if (!intentResponse.ok) {\n const intentError = await buildFloPayApiErrorFromResponse(\n intentResponse,\n 'Failed to create payment intent',\n );\n onErrorChange?.(intentError.message);\n onDecline?.(buildDeclineEvent('paypal', intentError));\n event.paymentFailed({ reason: 'fail', message: intentError.message });\n return;\n }\n const intentJson = await intentResponse.json() as { data?: { id?: string } };\n const intentClientSecret = intentJson.data?.id;\n if (!intentClientSecret) throw new Error('No client_secret in payment intent response');\n\n // 2. Confirm payment — PayPal will redirect or complete inline.\n const confirmParams: Record<string, unknown> = {\n return_url: window.location.href,\n };\n if (paymentMethod?.id) {\n confirmParams['payment_method'] = paymentMethod.id;\n }\n\n // Persist the resume payload before `confirmPayment` — if the buyer is\n // redirected to PayPal, the page reload on return wipes React state, so\n // the resume effect has to recover `effectiveSessionId`/`effectiveNonce`\n // from storage to /process against the same session PayPal authorized.\n // Keyed by `intentClientSecret` so a stale payload from a prior attempt\n // can't replay against a different PaymentIntent.\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem(PAYPAL_RESUME_KEY, JSON.stringify({\n clientSecret: intentClientSecret,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n accountPatch: prepared?.accountPatch,\n }));\n } catch { /* localStorage unavailable */ }\n }\n\n const { error: confirmError, paymentIntent } = await stripe.confirmPayment({\n clientSecret: intentClientSecret,\n confirmParams: confirmParams as { return_url: string },\n redirect: 'if_required',\n });\n\n if (confirmError) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(PAYPAL_RESUME_KEY); } catch { /* ignore */ }\n }\n if (isProviderDecline(confirmError)) {\n const message = confirmError.message ?? 'Your payment was declined.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('paypal', message, {\n code: getProviderErrorCode(confirmError),\n declineCode: getProviderDeclineCode(confirmError),\n }));\n } else {\n recoverTechnicalFailure(confirmError, 'stripe_paypal_confirm_failed', attemptContext?.generation);\n }\n return;\n }\n\n // Inline-complete path (no redirect happened) — the resume effect won't\n // fire, so drop the persisted payload now to avoid replay on next mount.\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(PAYPAL_RESUME_KEY); } catch { /* ignore */ }\n }\n\n const confirmedPmId = typeof paymentIntent?.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent?.payment_method?.id;\n\n onTokenizedBody({\n id: confirmedPmId ?? paymentIntent?.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent?.id,\n isPaypal: true,\n }, {\n accountPatch: prepared?.accountPatch,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n });\n return;\n } catch (err) {\n recoverTechnicalFailure(err, 'stripe_paypal_failed', attemptContext?.generation);\n } finally {\n setSubmitting(false);\n }\n }, [stripe, elements, sessionId, nonce, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick, recoverTechnicalFailure, finishAttempt, isAttemptCurrent, isAttemptInvalidated, surfaceKey]);\n\n return (\n <>\n <ExpressCheckoutReadySwap\n state={loadState}\n placeholderTestId=\"flopay-paypal-placeholder\"\n borderRadius={placeholderBorderRadius}\n >\n <div\n ref={focusTargetRef}\n tabIndex={-1}\n data-testid=\"flopay-paypal-focus-target\"\n aria-label=\"PayPal payment method\"\n style={{ borderRadius: 8, outlineOffset: 4 }}\n >\n {showRecoveryAction && (\n <button\n ref={recoveryActionRef}\n type=\"button\"\n data-testid=\"flopay-paypal-retry-button\"\n onClick={handleRecoveryActionClick}\n style={EXTERNAL_METHOD_RECOVERY_BUTTON_STYLE}\n >\n Try PayPal again\n </button>\n )}\n <ExpressCheckoutElement\n key={surfaceKey}\n onReady={(event) => setLoadState(resolveExpressCheckoutLoadState(event, ['paypal']))}\n onLoadError={() => setLoadState('load_error')}\n onClick={handlePayPalClick}\n onConfirm={handlePayPalConfirm}\n onCancel={() => {\n const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n getFloPayTelemetryBridge(flopay)?.terminal({\n outcome: 'payment_cancelled',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n invalidateAttempt(attemptContext?.generation);\n setShowRecoveryAction(false);\n pendingProviderFocusRef.current = true;\n resetSurface();\n }}\n options={{\n buttonType: { paypal: 'paypal' } as Record<string, string>,\n billingAddressRequired: false,\n phoneNumberRequired: false,\n shippingAddressRequired: false,\n paymentMethods: {\n applePay: 'never',\n googlePay: 'never',\n paypal: 'auto',\n link: 'never',\n },\n } as Parameters<typeof ExpressCheckoutElement>[0]['options']}\n />\n </div>\n </ExpressCheckoutReadySwap>\n {submitting && <ProcessingOverlay status=\"processing\" />}\n </>\n );\n}\n\n// ─── Wallet buttons (Apple Pay / Google Pay — own Elements instance) ────────\n// Uses raw stripe + elements from its own StripeElements context,\n// matching checkout/StripeCardForm's handleExpressCheckoutConfirm exactly.\n\nfunction WalletButtonInner({\n sessionId,\n nonce,\n email,\n billingApiUrl,\n expressMethods,\n onTokenizedBody,\n onErrorChange,\n onButtonClick,\n onDecline,\n onTechnicalFailure,\n runBeforeButtonClick,\n onLoadStateChange,\n placeholderBorderRadius,\n}: {\n sessionId: string;\n nonce?: string;\n email?: string;\n billingApiUrl: string;\n /**\n * Stripe-wire method identifiers to render in the ExpressCheckoutElement\n * (`apple_pay`, `google_pay`, `link`, `amazon_pay`, `klarna`, `paypal`).\n * Already filtered against {@link STRIPE_EXPRESS_METHODS}; `paypal` is\n * dropped upstream when `DirectPayPalButton` owns the PayPal surface.\n */\n expressMethods: string[];\n onTokenizedBody: InternalTokenizedBodyHandler;\n onErrorChange?: (error: string | null) => void;\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n onDecline?: (decline: DeclineEvent) => void;\n onTechnicalFailure?: ExternalMethodTechnicalFailureHandler;\n runBeforeButtonClick?: RunBeforeButtonClick;\n onLoadStateChange?: (state: ExpressCheckoutLoadState) => void;\n placeholderBorderRadius?: string | number;\n}) {\n const flopay = useFloPay();\n const stripe = useStripeRaw();\n const elements = useStripeElements();\n const [loadState, setLoadState] = useState<ExpressCheckoutLoadState>('loading');\n useEffect(() => {\n onLoadStateChange?.(loadState);\n }, [loadState, onLoadStateChange]);\n const [submitting, setSubmitting] = useState(false);\n const baseUrl = billingApiUrl.replace(/\\/+$/, '');\n const focusTargetRef = useRef<HTMLDivElement | null>(null);\n const recoveryActionRef = useRef<HTMLButtonElement | null>(null);\n const [surfaceKey, setSurfaceKey] = useState(0);\n const [showRecoveryAction, setShowRecoveryAction] = useState(false);\n const [recoveryActionMethod, setRecoveryActionMethod] = useState<string>('google_pay');\n const pendingProviderFocusRef = useRef(false);\n const lastWalletProviderMethodRef = useRef<string>('google_pay');\n const lastWalletMethodRef = useRef<CheckoutButtonMethod>('google_pay');\n const attemptContextBySurfaceRef = useRef(new Map<number, {\n generation: number;\n method: string;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n }>());\n const {\n startAttempt,\n finishAttempt,\n invalidateAttempt,\n isAttemptInvalidated,\n isAttemptCurrent,\n } = useExternalAttemptReconciliation((method, err, options) => {\n onTechnicalFailure?.(method, err, {\n ...options,\n popupBlocked: options?.popupBlocked ?? isPopupBlockedError(err),\n });\n setRecoveryActionMethod(method);\n setShowRecoveryAction(true);\n setSurfaceKey((key) => key + 1);\n });\n useEffect(() => {\n if (showRecoveryAction) recoveryActionRef.current?.focus();\n }, [showRecoveryAction, surfaceKey]);\n const resetSurface = useCallback(() => {\n setSurfaceKey((key) => key + 1);\n }, []);\n const recoverTechnicalFailure = useCallback((method: string, err: unknown, code?: string, generation?: number) => {\n invalidateAttempt(generation);\n onTechnicalFailure?.(method, err, { code, popupBlocked: isPopupBlockedError(err) });\n setRecoveryActionMethod(method);\n setShowRecoveryAction(true);\n resetSurface();\n }, [invalidateAttempt, onTechnicalFailure, resetSurface]);\n const focusProviderSurface = useCallback(() => {\n window.setTimeout(() => {\n const target = focusTargetRef.current?.querySelector<HTMLElement>('iframe');\n (target ?? focusTargetRef.current)?.focus();\n }, 0);\n }, []);\n useEffect(() => {\n if (!pendingProviderFocusRef.current) return;\n pendingProviderFocusRef.current = false;\n focusProviderSurface();\n }, [focusProviderSurface, surfaceKey]);\n const handleRecoveryActionClick = useCallback(() => {\n setShowRecoveryAction(false);\n onErrorChange?.(null);\n focusProviderSurface();\n }, [focusProviderSurface, onErrorChange]);\n\n const handleWalletConfirm = useCallback(\n async (event: StripeExpressCheckoutElementConfirmEvent) => {\n if (!stripe || !elements) return;\n const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);\n if (attemptContext && !isAttemptCurrent(attemptContext.generation)) {\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n return;\n }\n if (!attemptContext && isAttemptInvalidated()) return;\n if (attemptContext && !finishAttempt(attemptContext.generation)) return;\n if (!attemptContext) finishAttempt();\n\n // Detect wallet type from the express checkout event. Stripe's\n // `expressPaymentType` covers Apple/Google Pay; the SDK collapses\n // anything else (Link, Amazon Pay, Klarna) onto `google_pay` for the\n // existing analytics enum surface.\n const walletType = (event as unknown as { expressPaymentType?: string }).expressPaymentType\n ?? attemptContext?.method\n ?? lastWalletProviderMethodRef.current;\n let prepared: ExternalAttemptPrepared | null = attemptContext ?? null;\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n\n const buttonMethod = checkoutButtonMethodFromProviderMethod(walletType);\n if (!prepared && runBeforeButtonClick) {\n const beforeClick = await runBeforeButtonClick(buttonMethod);\n if (!beforeClick.proceed) {\n event.paymentFailed({ reason: 'fail', message: 'Wallet checkout was cancelled.' });\n return;\n }\n prepared = {\n accountPatch: beforeClick.accountPatch,\n sessionId: beforeClick.sessionId,\n nonce: beforeClick.nonce,\n };\n }\n\n const method = buttonMethod;\n const effectiveSessionId = prepared?.sessionId ?? sessionId;\n const effectiveNonce = prepared?.nonce ?? nonce;\n const effectiveEmail = prepared?.accountPatch?.email ?? email;\n\n try {\n setSubmitting(true);\n onErrorChange?.(null);\n\n // 1. Submit elements (validates wallet payment sheet)\n const { error: submitError } = await elements.submit();\n if (submitError) {\n recoverTechnicalFailure(walletType, submitError, 'stripe_wallet_submit_failed', attemptContext?.generation);\n return;\n }\n\n // 2. Create PaymentMethod from wallet token via the wallet's own Elements\n const { error: pmError, paymentMethod } = await stripe.createPaymentMethod({ elements });\n if (pmError || !paymentMethod) {\n recoverTechnicalFailure(walletType, pmError ?? new Error('Failed to create payment method.'), 'stripe_wallet_create_payment_method_failed', attemptContext?.generation);\n return;\n }\n\n if (!effectiveSessionId || !effectiveEmail) {\n throw new Error('Missing sessionId or email for wallet payment');\n }\n\n // 3. Create PaymentIntent via backend\n const intentHeaders: Record<string, string> = { 'Content-Type': 'application/json' };\n if (effectiveNonce) intentHeaders['x-checkout-session-token'] = effectiveNonce;\n const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {\n method: 'POST',\n headers: intentHeaders,\n body: JSON.stringify({\n sessionId: effectiveSessionId,\n email: effectiveEmail,\n paymentMethodType: paymentMethod.id,\n isPaypal: false,\n }),\n });\n\n if (!intentResponse.ok) {\n const intentError = await buildFloPayApiErrorFromResponse(\n intentResponse,\n 'Failed to create payment intent',\n );\n onErrorChange?.(intentError.message);\n onDecline?.(buildDeclineEvent(method, intentError));\n event.paymentFailed({ reason: 'fail', message: intentError.message });\n return;\n }\n const intentJson = await intentResponse.json() as { data?: { id?: string } };\n const intentClientSecret = intentJson.data?.id;\n if (!intentClientSecret) throw new Error('No client_secret in payment intent response');\n\n // 4. Confirm the intent (handles 3DS automatically). Trial-only / $0\n // wallet checkouts get a SetupIntent from the server — Stripe's\n // confirmCardPayment rejects `seti_` secrets, so confirm the card\n // setup instead. The captured card is attached to the SetupIntent and\n // charged when the trial ends.\n const { error: confirmError, intentId } = isSetupIntentClientSecret(intentClientSecret)\n ? await stripe\n .confirmCardSetup(intentClientSecret, { payment_method: paymentMethod.id })\n .then((r) => ({ error: r.error, intentId: r.setupIntent?.id }))\n : await stripe\n .confirmCardPayment(intentClientSecret, { payment_method: paymentMethod.id })\n .then((r) => ({ error: r.error, intentId: r.paymentIntent?.id }));\n\n if (confirmError) {\n if (isProviderDecline(confirmError)) {\n const message = confirmError.message ?? 'Your payment was declined.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent(method, message, {\n code: getProviderErrorCode(confirmError),\n declineCode: getProviderDeclineCode(confirmError),\n }));\n } else {\n recoverTechnicalFailure(walletType, confirmError, 'stripe_wallet_confirm_failed', attemptContext?.generation);\n }\n return;\n }\n\n // 5. Send PM + PI to process endpoint\n onTokenizedBody({\n id: paymentMethod.id,\n type: 'card',\n threeDSecureActionResultTokenId: intentId,\n }, {\n accountPatch: prepared?.accountPatch,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n });\n } catch (err) {\n recoverTechnicalFailure(walletType, err, 'stripe_wallet_failed', attemptContext?.generation);\n } finally {\n setSubmitting(false);\n }\n },\n [stripe, elements, sessionId, nonce, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick, recoverTechnicalFailure, finishAttempt, isAttemptCurrent, isAttemptInvalidated, surfaceKey],\n );\n\n // ExpressCheckoutElement's `paymentMethods` map uses camelCase keys; every\n // method not present in `expressMethods` is explicitly set to `'never'` so\n // Stripe collapses it instead of falling back to its own defaults. Only\n // `applePay` and `googlePay` accept `'always'`; `link`, `klarna`, `amazonPay`,\n // and `paypal` are typed as `'auto' | 'never'` by Stripe and throw an\n // IntegrationError at mount if `'always'` is passed.\n const expressMethodMap = useMemo(() => {\n const allKeys = ['applePay', 'googlePay', 'paypal', 'link', 'amazonPay', 'klarna'] as const;\n const alwaysCapable = new Set<string>(['applePay', 'googlePay']);\n const enabledKeys = new Set(expressMethods.map(stripeExpressMethodToOptionKey));\n const out: Record<string, 'always' | 'auto' | 'never'> = {};\n for (const key of allKeys) {\n if (!enabledKeys.has(key)) {\n out[key] = 'never';\n } else {\n out[key] = alwaysCapable.has(key) ? 'always' : 'auto';\n }\n }\n return out;\n }, [expressMethods]);\n const availableMethodKeys = useMemo(\n () => expressMethods.map(stripeExpressMethodToOptionKey),\n [expressMethods],\n );\n\n return (\n <>\n <ExpressCheckoutReadySwap\n state={loadState}\n placeholderTestId=\"flopay-wallet-placeholder\"\n borderRadius={placeholderBorderRadius}\n >\n <div\n ref={focusTargetRef}\n tabIndex={-1}\n data-testid=\"flopay-wallet-focus-target\"\n aria-label=\"Wallet payment methods\"\n style={{ borderRadius: 8, outlineOffset: 4 }}\n >\n {showRecoveryAction && (\n <button\n ref={recoveryActionRef}\n type=\"button\"\n data-testid=\"flopay-wallet-retry-button\"\n onClick={handleRecoveryActionClick}\n style={EXTERNAL_METHOD_RECOVERY_BUTTON_STYLE}\n >\n Try {getExternalMethodDisplayName(recoveryActionMethod)} again\n </button>\n )}\n <ExpressCheckoutElement\n key={surfaceKey}\n onReady={(event) => {\n setLoadState(resolveExpressCheckoutLoadState(event, availableMethodKeys));\n }}\n onLoadError={(_event) => {\n setLoadState('load_error');\n getFloPayTelemetryBridge(flopay)?.error({\n errorCode: 'PROVIDER_LOAD_FAILED',\n stage: 'provider_load',\n provider: 'stripe',\n paymentMethodCategory: 'wallet',\n requestCategory: 'provider_sdk',\n });\n }}\n onClick={async (event) => {\n lastWalletProviderMethodRef.current = event.expressPaymentType;\n lastWalletMethodRef.current = checkoutButtonMethodFromProviderMethod(event.expressPaymentType);\n\n const beforeClick = runBeforeButtonClick\n ? await runBeforeButtonClick(lastWalletMethodRef.current)\n : { proceed: true } as BeforeButtonClickResult;\n\n if (!beforeClick.proceed) {\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n event.reject();\n return;\n }\n\n const generation = startAttempt(event.expressPaymentType);\n attemptContextBySurfaceRef.current.set(surfaceKey, {\n generation,\n method: event.expressPaymentType,\n accountPatch: beforeClick.accountPatch,\n sessionId: beforeClick.sessionId,\n nonce: beforeClick.nonce,\n });\n setShowRecoveryAction(false);\n onButtonClick?.(lastWalletMethodRef.current);\n event.resolve();\n }}\n onConfirm={handleWalletConfirm}\n onCancel={() => {\n const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n getFloPayTelemetryBridge(flopay)?.terminal({\n outcome: 'payment_cancelled',\n provider: 'stripe',\n paymentMethodCategory: 'wallet',\n });\n invalidateAttempt(attemptContext?.generation);\n setShowRecoveryAction(false);\n pendingProviderFocusRef.current = true;\n resetSurface();\n }}\n options={{\n buttonType: { applePay: 'plain', googlePay: 'plain' } as Record<string, string>,\n paymentMethods: expressMethodMap,\n layout: { maxColumns: 1, overflow: 'never' },\n } as Parameters<typeof ExpressCheckoutElement>[0]['options']}\n />\n </div>\n </ExpressCheckoutReadySwap>\n {submitting && <ProcessingOverlay status=\"processing\" />}\n </>\n );\n}\n\n// ─── Stripe PaymentElement (non-express APMs: Cash App Pay / Klarna / Affirm / iDEAL / SEPA …) ─\n\n/**\n * PaymentElement region — rendered as one button per enabled APM, styled to\n * match the wallet ECE row above it. Each button's behaviour is determined\n * by {@link needsStripeMethodExplicitConfirm} in the shared method matrix:\n *\n * - **Auto-confirm methods** (Cash App, Affirm, …): clicking the button\n * swaps it for a loading spinner, and the SDK goes straight to\n * `stripe.confirmPayment({ payment_method_data: { type, billing_details } })`\n * with no PaymentElement involvement. Stripe takes over with its popup /\n * redirect; on cancel the spinner reverts back to the button.\n *\n * - **Input-form methods** (SEPA Debit, EPS, iDEAL, …): clicking the\n * button collapses the row to just that method and mounts an inline\n * PaymentElement scoped to `paymentMethodTypes: [method]` in a separate\n * Elements group. The inline form shows the method's required input\n * (IBAN, bank picker, …) plus a \"Pay with X\" button. A back link\n * restores the full button row.\n *\n * Each expanded form mounts its own {@link StripeElements} group rather\n * than sharing a parent group across methods, because `paymentMethodTypes`\n * cannot be mutated on an existing Elements group (`elements.update()`\n * explicitly rejects it). The trade-off is a ~500ms `/v1/elements/sessions`\n * call on first expansion of each method — acceptable cost for the focused\n * per-method UX.\n */\n\n/**\n * Reusable method-tile button — same 44px contract as the wallet ECE row.\n * Lifted out so both the unselected list and the expanded-method header\n * reuse the same shape and theming. The pressed state (`submitting`)\n * replaces the label with a spinner so the buyer sees feedback during the\n * `POST /payments/intents` → `stripe.confirmPayment` round-trip on\n * auto-confirm methods.\n */\nfunction StripeMethodButton({\n method,\n themeId,\n submitting = false,\n disabled = false,\n highlighted = false,\n hasNextStep = false,\n onClick,\n backgroundColor,\n borderColor,\n textColor,\n borderRadius,\n fontFamily,\n}: {\n method: string;\n /**\n * Active FloPay theme id — drives which `STRIPE_METHOD_MATRIX[method]\n * .theme.{light,dark}` variant the button picks up its brand colors\n * (and eventually logo) from. `null`/`undefined`/`classic` falls back\n * to the matrix's `light` variant; any `*-dark` theme picks the `dark`\n * variant.\n */\n themeId?: import('@flopay/shared').ThemeId | null;\n submitting?: boolean;\n disabled?: boolean;\n highlighted?: boolean;\n /**\n * Render a right-chevron at the trailing edge of the button label,\n * signalling that clicking the tile drills into a second page (the\n * inline form for input-requiring APMs like SEPA Debit / EPS / iDEAL).\n * Auto-confirm methods (Cash App, Affirm) leave this off — their click\n * goes straight to Stripe's authorization UI with no intermediate page.\n */\n hasNextStep?: boolean;\n onClick: () => void;\n backgroundColor?: string;\n borderColor?: string;\n textColor?: string;\n borderRadius?: string | number;\n fontFamily?: string;\n}) {\n // Resolution order:\n // 1. Brand variant pulled from `STRIPE_METHOD_MATRIX[method].theme`\n // keyed by mode — gives Cash App green, Klarna pink, etc., out of\n // the box. Brand wins over the surrounding theme bundle's neutral\n // `cardButton` styling because the *method's* identity is more\n // specific than the *layout's* tile design — and the parent always\n // passes the theme bundle's `cardButton` colors through the prop\n // channel, so otherwise no branded button would ever surface.\n // 2. Inline `buttonAppearance` prop — bundle-level overrides for\n // methods without a brand variant in the matrix.\n // 3. Defaults — white + grey border, matching the legacy tile.\n const brand = resolveStripeMethodBrandVariant(method, themeId);\n const resolvedBackground = brand?.backgroundColor ?? backgroundColor ?? '#ffffff';\n const resolvedBorder = brand?.borderColor ?? borderColor ?? '#d1d5db';\n const resolvedTextColor = brand?.textColor ?? textColor ?? '#262833';\n return (\n <button\n type=\"button\"\n data-testid={`flopay-stripe-method-button-${method}`}\n data-method={method}\n onClick={() => { if (!submitting && !disabled) onClick(); }}\n disabled={submitting || disabled}\n aria-busy={submitting || undefined}\n style={{\n position: 'relative',\n width: '100%',\n boxSizing: 'border-box',\n height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT,\n padding: '0 1rem',\n backgroundColor: resolvedBackground,\n color: resolvedTextColor,\n border: `1px solid ${resolvedBorder}`,\n borderRadius: borderRadius ?? 8,\n fontSize: '0.95rem',\n fontWeight: 600,\n fontFamily,\n cursor: submitting || disabled ? 'not-allowed' : 'pointer',\n opacity: disabled && !submitting ? 0.55 : 1,\n // Submitting state pulses the whole button background, mirroring\n // the wallet ECE's `flopay-pulse` skeleton. This keeps the loading\n // affordance consistent between embedded wallets (Apple Pay,\n // Google Pay) and these custom APM tile buttons — same animation\n // curve, same duration, only the surface colour changes (grey for\n // the wallet skeleton vs. brand colour for an in-flight tile).\n animation: submitting ? 'flopay-pulse 1.5s ease-in-out infinite' : undefined,\n display: 'flex',\n alignItems: 'center',\n // Always center the logo+name group. The drill-in chevron (input\n // methods) is absolutely positioned at the right edge below so it\n // doesn't pull the label off-center.\n justifyContent: 'center',\n gap: 8,\n transition: 'transform 0.1s, opacity 140ms ease-out, border-color 140ms ease-out',\n boxShadow: highlighted ? '0 0 0 2px rgba(74, 73, 255, 0.15)' : undefined,\n }}\n >\n {submitting ? (\n // Pulse-skeleton parity with the wallet ECE: no spinner, just the\n // status text on top of the pulsing background. Keeps the loading\n // affordance shape-equivalent across both kinds of tile.\n <span style={{ margin: '0 auto' }}>\n {`Connecting to ${getStripeMethodDisplayName(method)}…`}\n </span>\n ) : (\n <>\n {/* Group: logo + name sit adjacent (8px gap) so the brand mark\n reads as part of the same label, not as a separately\n left-justified icon. The group is always centered (the button's\n `justifyContent: 'center'`); the drill-in chevron is absolutely\n positioned at the right edge so it never pulls the label\n off-center. */}\n <span\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n // Real vendored logos are self-contained brand cards, so they\n // get an 8px gap from the label. The generated placeholder\n // monogram reads as part of the label (the tile's first letter),\n // so it sits flush (0px) against the name.\n gap: hasVendoredStripeMethodLogo(method) ? 8 : 0,\n }}\n >\n {brand?.logoSvg && (\n <span\n aria-hidden=\"true\"\n style={{\n // 3:2 box matching the vendored datatrans logos' 120×80\n // viewBox. Each logo ships with its own white rounded-rect\n // background baked in, so the mark stays legible on any\n // brand-coloured tile without an extra chip wrapper here.\n width: 30,\n height: 20,\n flexShrink: 0,\n display: 'inline-flex',\n borderRadius: 3,\n overflow: 'hidden',\n }}\n // Logo markup originates from the matrix (`StripeMethodEntry\n // .theme.{light,dark}.logoSvg`); we trust it here because the\n // matrix is owned by the SDK, not user input.\n dangerouslySetInnerHTML={{ __html: brand.logoSvg }}\n />\n )}\n <span>{getStripeMethodDisplayName(method)}</span>\n </span>\n {hasNextStep && (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={resolvedTextColor}\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n position: 'absolute',\n right: '1rem',\n top: '50%',\n transform: 'translateY(-50%)',\n flexShrink: 0,\n opacity: 0.7,\n }}\n aria-hidden=\"true\"\n >\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n )}\n </>\n )}\n </button>\n );\n}\n\n/**\n * Inline form rendered beneath the selected method button for APMs that\n * need data collection. Mounts a single-method PaymentElement (Stripe's\n * accordion with one item, default-expanded) plus the \"Pay with X\" submit\n * button. Lives inside its own `<StripeElements>` group keyed by method, so\n * switching between methods unmounts the previous group cleanly.\n */\nfunction StripeMethodInlineForm({\n method,\n sessionId,\n nonce,\n email,\n billingName,\n billingApiUrl,\n onTokenizedBody,\n onErrorChange,\n onDecline,\n onCancel,\n runBeforeButtonClick,\n onButtonClick,\n isProcessing,\n submitButtonColor,\n submitButtonBorderRadius,\n submitButtonStyle,\n errorText,\n}: {\n method: string;\n sessionId: string;\n nonce?: string;\n email?: string;\n billingName?: string;\n billingApiUrl: string;\n onTokenizedBody: InternalTokenizedBodyHandler;\n onErrorChange?: (error: string | null) => void;\n onDecline?: (decline: DeclineEvent) => void;\n onCancel: () => void;\n /**\n * Error/decline message to surface on *this* inner page, beneath the \"Pay\n * with X\" button. The parent owns the error state (so it clears on screen\n * navigation); the form just renders it where the buyer is actually looking\n * instead of leaving it on the method-selection screen behind.\n */\n errorText?: string | null;\n runBeforeButtonClick?: RunBeforeButtonClick;\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n isProcessing?: boolean;\n submitButtonColor: string;\n submitButtonBorderRadius: string | number;\n submitButtonStyle?: React.CSSProperties;\n}) {\n const flopay = useFloPay();\n const stripe = useStripeRaw();\n const elements = useStripeElements();\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n const [isMethodComplete, setIsMethodComplete] = useState(false);\n const [loadState, setLoadState] = useState<'loading' | 'ready' | 'load_error'>('loading');\n const baseUrl = billingApiUrl.replace(/\\/+$/, '');\n\n const handlePay = useCallback(async () => {\n if (!stripe || !elements || isProcessing || submittingRef.current || !isMethodComplete) return;\n submittingRef.current = true;\n setSubmitting(true);\n\n const beforeClick = runBeforeButtonClick\n ? await runBeforeButtonClick('card')\n : { proceed: true } as BeforeButtonClickResult;\n if (!beforeClick.proceed) {\n submittingRef.current = false;\n setSubmitting(false);\n return;\n }\n onButtonClick?.('card');\n\n const effectiveSessionId = beforeClick.sessionId ?? sessionId;\n const effectiveNonce = beforeClick.nonce ?? nonce;\n const effectiveEmail = beforeClick.accountPatch?.email ?? email;\n\n try {\n onErrorChange?.(null);\n\n const submitRes = await elements.submit();\n if (submitRes.error) {\n onErrorChange?.(submitRes.error.message ?? 'Payment failed.');\n return;\n }\n\n const pmRes = await stripe.createPaymentMethod({ elements });\n if (pmRes.error || !pmRes.paymentMethod) {\n onErrorChange?.(pmRes.error?.message ?? 'Failed to create payment method.');\n return;\n }\n const paymentMethod = pmRes.paymentMethod;\n\n if (!effectiveSessionId || !effectiveEmail) {\n throw new Error('Missing sessionId or email for payment.');\n }\n\n // Send the resolved wire type so the backend scopes the PI to just\n // this method (`payment_method_types: [<type>]`) — avoids the\n // `apple_pay invalid` PI-creation reject path on accounts without\n // domain verification.\n const intentHeaders: Record<string, string> = { 'Content-Type': 'application/json' };\n if (effectiveNonce) intentHeaders['x-checkout-session-token'] = effectiveNonce;\n const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {\n method: 'POST',\n headers: intentHeaders,\n body: JSON.stringify({\n sessionId: effectiveSessionId,\n email: effectiveEmail,\n paymentMethodType: paymentMethod.type || method,\n isPaypal: false,\n }),\n });\n if (!intentResponse.ok) {\n const intentError = await buildFloPayApiErrorFromResponse(intentResponse, 'Failed to create payment intent');\n onErrorChange?.(intentError.message);\n onDecline?.(buildDeclineEvent('card', intentError));\n return;\n }\n const intentJson = await intentResponse.json() as { data?: { id?: string } };\n const intentClientSecret = intentJson.data?.id;\n if (!intentClientSecret) throw new Error('No client_secret in payment intent response');\n\n // Persist the resume payload before confirmPayment — same contract as\n // the legacy region, picked up by the resume handler on redirect return.\n // `clientSecret` / `nonce` / `accountPatch` mirror the PayPal recovery\n // payload: when a `runBeforeButtonClick` bootstrap created a fresh\n // session, the post-redirect re-bootstrap exposes a different base\n // session via props, so /process must use the persisted (authorized)\n // sessionId + nonce — not the fresh prop pair — to avoid a 401.\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem(STRIPE_RESUME_KEY, JSON.stringify({\n clientSecret: intentClientSecret,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n accountPatch: beforeClick.accountPatch,\n paymentMethodId: paymentMethod.id,\n paymentMethodType: paymentMethod.type ?? method,\n gateway: 'stripe',\n }));\n } catch { /* localStorage unavailable */ }\n }\n\n const { error: confirmError, paymentIntent } = await stripe.confirmPayment({\n clientSecret: intentClientSecret,\n confirmParams: {\n return_url: window.location.href,\n payment_method: paymentMethod.id,\n } as { return_url: string; payment_method?: string },\n redirect: 'if_required',\n });\n\n if (confirmError) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const message = confirmError.message ?? 'Payment failed.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('card', message, { code: confirmError.code }));\n return;\n }\n\n const SUCCESSFUL_PI_STATUSES = new Set(['succeeded', 'requires_capture', 'processing']);\n const piStatus = paymentIntent?.status;\n if (!piStatus || !SUCCESSFUL_PI_STATUSES.has(piStatus)) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const message = piStatus === 'canceled'\n ? 'Payment was canceled.'\n : 'Payment was not completed. Please try again.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('card', message, { code: piStatus ?? 'missing_payment_intent' }));\n return;\n }\n\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const confirmedPmId = typeof paymentIntent?.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent?.payment_method?.id;\n\n onTokenizedBody({\n id: confirmedPmId ?? paymentMethod.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent?.id,\n gateway: 'stripe',\n paymentMethodType: paymentMethod.type ?? method,\n }, {\n accountPatch: beforeClick.accountPatch,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n });\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'Payment failed. Please try again.');\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }, [stripe, elements, isProcessing, isMethodComplete, runBeforeButtonClick, onButtonClick,\n sessionId, nonce, email, baseUrl, method, onTokenizedBody, onErrorChange, onDecline]);\n\n // The back/cancel control is rendered by the parent (\"Go back\" button at\n // the top of the 2nd-page panel that mirrors the card form's 2nd page),\n // so `onCancel` is intentionally unused here — kept on the prop signature\n // so other call sites that still embed the form inline can wire their\n // own back link if needed.\n void onCancel;\n\n return (\n <div data-testid={`flopay-stripe-method-form-${method}`} style={{ display: 'flex', flexDirection: 'column' }}>\n <PaymentElement\n onReady={() => setLoadState('ready')}\n onLoadError={() => {\n setLoadState('load_error');\n getFloPayTelemetryBridge(flopay)?.error({\n errorCode: 'PROVIDER_LOAD_FAILED',\n stage: 'provider_load',\n provider: 'stripe',\n paymentMethodCategory: 'apm',\n requestCategory: 'provider_sdk',\n });\n }}\n onChange={(event) => {\n const evRecord = event as unknown as { complete?: boolean };\n setIsMethodComplete(!!evRecord.complete);\n }}\n // Single-method group: only this method's accordion item renders,\n // default-expanded so the inline form (IBAN / bank picker) is\n // immediately visible.\n options={{\n layout: { type: 'accordion', defaultCollapsed: false, radios: 'never' },\n defaultValues: {\n billingDetails: {\n name: billingName && billingName.trim().length >= 3\n ? billingName.trim()\n : 'FloPay Customer',\n ...(email ? { email } : {}),\n },\n },\n } as unknown as Parameters<typeof PaymentElement>[0]['options']}\n />\n\n <button\n type=\"button\"\n data-testid={`flopay-stripe-method-pay-${method}`}\n onClick={() => { void handlePay(); }}\n disabled={!isMethodComplete || submitting || isProcessing || loadState !== 'ready'}\n style={{\n width: '100%',\n marginTop: '0.75rem',\n padding: '0.875rem',\n backgroundColor: submitButtonColor,\n color: 'white',\n border: 'none',\n borderRadius: submitButtonBorderRadius,\n fontSize: '1rem',\n fontWeight: 600,\n cursor: (!isMethodComplete || submitting || isProcessing || loadState !== 'ready') ? 'not-allowed' : 'pointer',\n opacity: (!isMethodComplete || submitting || isProcessing || loadState !== 'ready') ? 0.5 : 1,\n transition: 'opacity 120ms ease-out',\n ...(submitButtonStyle ?? {}),\n }}\n >\n {submitting ? 'Processing…' : `Pay with ${getStripeMethodDisplayName(method)}`}\n </button>\n\n {errorText && (\n <div role=\"alert\" data-testid=\"flopay-error\" style={{\n margin: '0.75rem 0 0', padding: '0.625rem 0.875rem',\n background: '#FEF2F2', border: '1px solid #FECACA', borderRadius: '8px',\n color: '#991B1B', fontSize: '0.85rem', fontWeight: 600,\n display: 'flex', alignItems: 'center', gap: '0.5rem',\n }}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" style={{ flexShrink: 0 }}>\n <path d=\"M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" stroke=\"#DC2626\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n {errorText}\n </div>\n )}\n </div>\n );\n}\nfunction StripePaymentElementInner({\n sessionId,\n nonce,\n email,\n billingName,\n billingApiUrl,\n paymentElementMethods,\n stripeInstance,\n paymentElementBaseOptions,\n onTokenizedBody,\n onErrorChange,\n onButtonClick,\n onDecline,\n runBeforeButtonClick,\n onLoadStateChange,\n isProcessing = false,\n submitButtonColor = '#4A49FF',\n submitButtonBorderRadius = 8,\n submitButtonStyle,\n buttonAppearance,\n themeId,\n onExpandApm,\n expandedApmMethod,\n}: {\n sessionId: string;\n nonce?: string;\n email?: string;\n /**\n * Buyer's full name, prefilled into the inline PaymentElement's billing\n * details so `elements.submit()` for methods that mandate a name (SEPA,\n * Bancontact, Klarna, …) doesn't reject with `invalid_name_<method>`.\n * Falls back to `'FloPay Customer'` only if the session has no buyer\n * name at all.\n */\n billingName?: string;\n billingApiUrl: string;\n paymentElementMethods: string[];\n /**\n * Raw Stripe instance from the parent `FloPayProvider`. The component\n * uses it directly for `confirmPayment` on auto-confirm methods (no\n * Elements group needed) and as the `stripe` prop on each expanded\n * method's inline `<StripeElements>` group.\n */\n stripeInstance: Stripe | null;\n /**\n * Shared Elements options (mode/amount/currency/appearance) without\n * `paymentMethodTypes`. Each expanded method spreads this and adds its\n * own `paymentMethodTypes: [method]` to scope its inline form.\n */\n paymentElementBaseOptions: Record<string, unknown>;\n onTokenizedBody: InternalTokenizedBodyHandler;\n onErrorChange?: (error: string | null) => void;\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n onDecline?: (decline: DeclineEvent) => void;\n runBeforeButtonClick?: RunBeforeButtonClick;\n onLoadStateChange?: (state: 'loading' | 'ready' | 'load_error') => void;\n isProcessing?: boolean;\n submitButtonColor?: string;\n submitButtonBorderRadius?: string | number;\n submitButtonStyle?: React.CSSProperties;\n /**\n * Theme overrides applied to each method tile button. Defaults to the\n * historic white-with-grey-border styling that matches the legacy\n * \"Credit / Debit Card\" button in the buttons-layout flow.\n */\n buttonAppearance?: {\n backgroundColor?: string;\n borderColor?: string;\n textColor?: string;\n borderRadius?: string | number;\n fontFamily?: string;\n };\n /**\n * Active FloPay theme id — passed through to each tile so it can look up\n * its per-mode brand styling from `STRIPE_METHOD_MATRIX[method].theme`.\n * `null`/`undefined`/`classic` resolves to the matrix's `light` variant;\n * any `*-dark` theme resolves to the `dark` variant.\n */\n themeId?: import('@flopay/shared').ThemeId | null;\n /**\n * Called when the buyer clicks a tile for a method that requires inline\n * data collection (SEPA Debit IBAN, EPS bank picker, …). The parent\n * decides how to present the expanded form — typically by transitioning\n * to a second page (mirroring the card-form 2nd page in buttons layout).\n * Auto-confirm methods (Cash App, Affirm) don't call this; they handle\n * the click locally with a button spinner + direct `confirmPayment`.\n */\n onExpandApm?: (method: string) => void;\n /**\n * The method whose 2nd-page form is currently visible (parent-managed).\n * Used to disable the *other* tile buttons during the drill-in so the\n * buyer either submits or backs out before switching methods.\n */\n expandedApmMethod?: string | null;\n}) {\n const baseUrl = billingApiUrl.replace(/\\/+$/, '');\n // Which method is showing its expanded inline form (input methods only).\n const [expandedMethod, setExpandedMethod] = useState<string | null>(null);\n // Which method is mid-`confirmPayment` (auto-confirm methods only). The\n // tile button replaces its label with a spinner while this is set.\n const [submittingMethod, setSubmittingMethod] = useState<string | null>(null);\n const submittingRef = useRef(false);\n\n // The legacy `StripePaymentElementInner` mounted one big PaymentElement,\n // so the `load_state` signal came from the element's `ready`/`loaderror`\n // events. The custom-button version has no upfront PaymentElement —\n // signal ready as soon as we have a Stripe instance and at least one\n // method to render, so the parent's gate (`shouldDisplayPaymentElementRow`)\n // can stop showing the loading skeleton.\n useEffect(() => {\n if (paymentElementMethods.length > 0 && stripeInstance) {\n onLoadStateChange?.('ready');\n } else if (!stripeInstance) {\n onLoadStateChange?.('loading');\n }\n }, [paymentElementMethods.length, stripeInstance, onLoadStateChange]);\n\n // ─── Auto-confirm flow (Cash App / Affirm / …) ─────────────────────────\n // No PaymentElement: the method has no inline data to collect, so we go\n // POST /intents → stripe.confirmPayment with `payment_method_data.type`\n // and let Stripe handle tokenization + popup/redirect inside its own UI.\n // Saves a `/v1/elements/sessions` round-trip per click compared to the\n // PaymentElement-driven path used for input methods.\n const handleAutoConfirm = useCallback(async (method: string) => {\n if (!stripeInstance) return;\n if (submittingRef.current || isProcessing) return;\n submittingRef.current = true;\n setSubmittingMethod(method);\n\n const beforeClick = runBeforeButtonClick\n ? await runBeforeButtonClick('card')\n : { proceed: true } as BeforeButtonClickResult;\n if (!beforeClick.proceed) {\n submittingRef.current = false;\n setSubmittingMethod(null);\n return;\n }\n onButtonClick?.('card');\n\n const effectiveSessionId = beforeClick.sessionId ?? sessionId;\n const effectiveNonce = beforeClick.nonce ?? nonce;\n const effectiveEmail = beforeClick.accountPatch?.email ?? email;\n\n try {\n onErrorChange?.(null);\n\n if (!effectiveSessionId || !effectiveEmail) {\n throw new Error('Missing sessionId or email for payment.');\n }\n\n const intentHeaders: Record<string, string> = { 'Content-Type': 'application/json' };\n if (effectiveNonce) intentHeaders['x-checkout-session-token'] = effectiveNonce;\n const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {\n method: 'POST',\n headers: intentHeaders,\n body: JSON.stringify({\n sessionId: effectiveSessionId,\n email: effectiveEmail,\n // Wire type, not pm_xxx — backend scopes `payment_method_types`\n // to this single method so unrelated account-wide methods\n // (apple_pay without domain verification, …) don't poison PI\n // creation.\n paymentMethodType: method,\n isPaypal: false,\n }),\n });\n if (!intentResponse.ok) {\n const intentError = await buildFloPayApiErrorFromResponse(intentResponse, 'Failed to create payment intent');\n onErrorChange?.(intentError.message);\n onDecline?.(buildDeclineEvent('card', intentError));\n return;\n }\n const intentJson = await intentResponse.json() as { data?: { id?: string } };\n const intentClientSecret = intentJson.data?.id;\n if (!intentClientSecret) throw new Error('No client_secret in payment intent response');\n\n // Persist the resume payload before confirmPayment in case Stripe\n // redirects (Cash App Pay does on some platforms; Affirm always\n // does). The parent's resume handler picks this up on return.\n // `clientSecret` / `nonce` / `accountPatch` mirror the PayPal recovery\n // payload: when a `runBeforeButtonClick` bootstrap created a fresh\n // session, the post-redirect re-bootstrap exposes a different base\n // session via props, so /process must use the persisted (authorized)\n // sessionId + nonce — not the fresh prop pair — to avoid a 401.\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem(STRIPE_RESUME_KEY, JSON.stringify({\n clientSecret: intentClientSecret,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n accountPatch: beforeClick.accountPatch,\n paymentMethodType: method,\n gateway: 'stripe',\n }));\n } catch { /* localStorage unavailable in private mode */ }\n }\n\n const { error: confirmError, paymentIntent } = await stripeInstance.confirmPayment({\n clientSecret: intentClientSecret,\n confirmParams: {\n return_url: window.location.href,\n // Inline the method data — no Elements / PaymentElement\n // required. Stripe creates the PaymentMethod during confirm\n // and proceeds to its popup/redirect UI.\n payment_method_data: {\n type: method,\n billing_details: {\n name: billingName && billingName.trim().length >= 3 ? billingName.trim() : 'FloPay Customer',\n ...(effectiveEmail ? { email: effectiveEmail } : {}),\n },\n },\n } as never,\n redirect: 'if_required',\n });\n\n if (confirmError) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const message = confirmError.message ?? 'Payment failed.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('card', message, { code: confirmError.code }));\n return;\n }\n\n // `redirect: 'if_required'` returns *without* `confirmError` even\n // when the buyer closed an inline confirmation UI without\n // approving — `paymentIntent.status` is the authoritative signal.\n const SUCCESSFUL_PI_STATUSES = new Set(['succeeded', 'requires_capture', 'processing']);\n const piStatus = paymentIntent?.status;\n if (!piStatus || !SUCCESSFUL_PI_STATUSES.has(piStatus)) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const message = piStatus === 'canceled'\n ? 'Payment was canceled.'\n : 'Payment was not completed. Please try again.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('card', message, { code: piStatus ?? 'missing_payment_intent' }));\n return;\n }\n\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const confirmedPmId = typeof paymentIntent?.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent?.payment_method?.id;\n\n onTokenizedBody({\n id: confirmedPmId ?? paymentIntent?.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent?.id,\n gateway: 'stripe',\n paymentMethodType: method,\n }, {\n accountPatch: beforeClick.accountPatch,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n });\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'Payment failed. Please try again.');\n } finally {\n submittingRef.current = false;\n setSubmittingMethod(null);\n }\n }, [stripeInstance, isProcessing, runBeforeButtonClick, onButtonClick, sessionId, nonce, email,\n baseUrl, billingName, onTokenizedBody, onErrorChange, onDecline]);\n\n // Fallback expansion state for callers that *don't* provide `onExpandApm`\n // (e.g. the default-layout site, which has no concept of a 2nd page).\n // When the parent owns the navigation (buttons layout), we never touch\n // this and read from `expandedApmMethod` instead.\n const [localExpandedMethod, setLocalExpandedMethod] = useState<string | null>(null);\n const activeExpandedMethod = onExpandApm ? (expandedApmMethod ?? null) : localExpandedMethod;\n\n const handleMethodClick = useCallback((method: string) => {\n if (submittingRef.current || isProcessing) return;\n // While one method is expanded, the other tile buttons are disabled —\n // the buyer has to submit or back out before switching.\n if (activeExpandedMethod && activeExpandedMethod !== method) return;\n\n if (needsStripeMethodExplicitConfirm(method)) {\n if (onExpandApm) {\n // Parent (buttons layout) drives the `viewState` machine and\n // mounts the 2nd-page form there.\n onExpandApm(method);\n } else {\n // Default-layout fallback — expand the form inline beneath the\n // tile button. Same Elements-group-per-method scoping, just\n // without the page transition.\n setLocalExpandedMethod(method);\n }\n } else {\n void handleAutoConfirm(method);\n }\n }, [activeExpandedMethod, isProcessing, handleAutoConfirm, onExpandApm]);\n\n // Per-method Elements options for the local (default-layout) inline form.\n // Mirrors the buttons-layout's `apmInlineOptions` derivation in the\n // parent component.\n const localInlineElementsOptions = useMemo(() => {\n if (!localExpandedMethod) return null;\n return {\n ...paymentElementBaseOptions,\n paymentMethodTypes: [localExpandedMethod],\n } as Parameters<typeof StripeElements>[0]['options'];\n }, [localExpandedMethod, paymentElementBaseOptions]);\n\n return (\n <div\n data-testid=\"flopay-stripe-payment-element-region\"\n style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}\n >\n {paymentElementMethods.map((method) => {\n const isExpanded = expandedApmMethod === method;\n const isSubmittingThis = submittingMethod === method;\n const otherInProgress =\n (submittingMethod !== null && submittingMethod !== method) ||\n (expandedApmMethod !== null && expandedApmMethod !== undefined && expandedApmMethod !== method);\n\n return (\n <React.Fragment key={method}>\n <StripeMethodButton\n method={method}\n themeId={themeId}\n submitting={isSubmittingThis}\n disabled={otherInProgress}\n highlighted={isExpanded}\n // Tile buttons for input methods drill into a 2nd page; the\n // trailing chevron echoes the \"Credit / Debit Card\" button so\n // the affordance reads the same across both kinds of tiles.\n hasNextStep={needsStripeMethodExplicitConfirm(method)}\n onClick={() => handleMethodClick(method)}\n backgroundColor={buttonAppearance?.backgroundColor}\n borderColor={buttonAppearance?.borderColor}\n textColor={buttonAppearance?.textColor}\n borderRadius={buttonAppearance?.borderRadius}\n fontFamily={buttonAppearance?.fontFamily}\n />\n {/* Default-layout fallback: when the parent hasn't wired a 2nd\n page (`onExpandApm`), expand the form inline beneath the\n tile button. Buttons layout never hits this branch — it\n renders the form on its own gridArea-1/1 panel instead. */}\n {!onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && (\n <StripeElements\n key={method}\n stripe={stripeInstance}\n options={localInlineElementsOptions}\n >\n <StripeMethodInlineForm\n method={method}\n sessionId={sessionId}\n email={email}\n billingName={billingName}\n billingApiUrl={billingApiUrl}\n onTokenizedBody={onTokenizedBody}\n onErrorChange={onErrorChange}\n onDecline={onDecline}\n onCancel={() => setLocalExpandedMethod(null)}\n runBeforeButtonClick={runBeforeButtonClick}\n onButtonClick={onButtonClick}\n isProcessing={isProcessing}\n submitButtonColor={submitButtonColor}\n submitButtonBorderRadius={submitButtonBorderRadius}\n submitButtonStyle={submitButtonStyle}\n />\n </StripeElements>\n )}\n </React.Fragment>\n );\n })}\n </div>\n );\n}\n\n// ─── Main form ──────────────────────────────────────────────────────────────\n\nfunction SplitCardFormInner({\n sessionId,\n nonce,\n billingApiUrl,\n email,\n userId,\n onComplete,\n onError,\n onDecline,\n onTokenizedBody,\n firstName,\n lastName,\n chv,\n submitLabel = 'CONFIRM PAYMENT',\n className,\n children,\n isProcessing: externalProcessing,\n error: externalError,\n onErrorChange,\n onFullNameChange,\n onFirstNameChange,\n onLastNameChange,\n showPayPal = true,\n showStripe = true,\n enabledPaymentMethods,\n enabledPaymentMethodCountries,\n showApplePay = true,\n showGooglePay = true,\n layout = 'default',\n theme,\n buttonsTheme,\n buttonsStyles: buttonsStylesOverride,\n appearance: appearanceOverride,\n cardButtonContent,\n cardBackButtonContent,\n cardTitleContent,\n showSecurityFooter: _showSecurityFooter,\n onButtonClick,\n onBeforeButtonClick,\n enableAVS: enableAVSProp,\n cardFieldOrder,\n cardPreFormSlot,\n avsLayout: avsLayoutProp = 'row',\n country: countryProp,\n zip: zipProp,\n addressLine1: addressLine1Prop,\n addressLine2: addressLine2Prop,\n city: cityProp,\n state: stateProp,\n onCountryChange,\n onZipChange,\n avsCheck: avsCheckProp,\n checkoutType: checkoutTypeProp,\n checkoutLayout: checkoutLayoutProp,\n totalAmount = 0,\n currency = 'usd',\n initialCardOpen = false,\n directPaypal,\n isSubscription = false,\n session,\n debug = false,\n innerRef,\n}: SplitCardFormProps & { innerRef: React.Ref<SplitCardFormRef> }) {\n const flopay = useFloPay();\n const paypalFlopay = usePayPalFloPay();\n const elements = useElements();\n const checkout = useContext(CheckoutContext);\n const contextBillingUrl = useBillingApiUrl();\n const [processing, setProcessing] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [is3DSActive, setIs3DSActive] = useState(false);\n const [selectedCountry, setSelectedCountry] = useState(countryProp ?? 'US');\n const [zipCode, setZipCode] = useState(zipProp ?? '');\n const [addressLine1, setAddressLine1] = useState(addressLine1Prop ?? '');\n const [addressLine2, setAddressLine2] = useState(addressLine2Prop ?? '');\n const [city, setCity] = useState(cityProp ?? '');\n const [stateValue, setStateValue] = useState(stateProp ?? '');\n const [accountPatch, setAccountPatch] = useState<InlineSessionPatch['account']>({});\n const zipCodeRef = useRef(zipProp ?? '');\n const selectedCountryRef = useRef(countryProp ?? 'US');\n const addressLine1Ref = useRef(addressLine1Prop ?? '');\n const addressLine2Ref = useRef(addressLine2Prop ?? '');\n const cityRef = useRef(cityProp ?? '');\n const stateRef = useRef(stateProp ?? '');\n\n // Resolve AVS config: boolean → default config, object → as-is, falsy → null\n const avsConfig = useMemo(() => resolveAVSConfig(enableAVSProp), [enableAVSProp]);\n const enableAVS = avsConfig !== null;\n\n // ── Vault PCI card capture (TeamFloPay/backend#823, Model A) ──\n // For SDK >= 1.3.0 the vault IS the card path: the backend embeds its hosted\n // vault widget (a self-contained PCI form that owns tokenization, the charge,\n // 3DS, and the result) as the top-level `session.vault` block whenever the SDK\n // advertises `x-flo-sdk-version >= 1.3.0` on create. That embedded block — not\n // a per-client gateway flag — is the primary activation signal; the backend\n // does not emit a `gateways.pcivault` entry alongside it. We still honour a\n // `gateways.pcivault` advertisement as a legacy signal so a session that\n // defers the form to the `/vault/capture` fetch keeps working. When the vault\n // is active we render the widget (injecting its HTML and relaying its outcome —\n // no Stripe.js on the card path); when the backend supplied no form we fall\n // back to Stripe's embedded card elements so checkout still works.\n const vaultBlockReady = Boolean(session?.vault?.html);\n const vaultGatewayAdvertised = Boolean(session?.gateways?.pcivault);\n const vaultActive = Boolean(\n showStripe && (vaultBlockReady || vaultGatewayAdvertised) && flopay && sessionId,\n );\n const cardCapture = useMemo<CardCaptureAdapter | null>(() => {\n if (!flopay || !vaultActive || !sessionId) return null;\n return flopay.cardCapture({ sessionId });\n }, [flopay, vaultActive, sessionId]);\n // ── Postcode format state for the live selected country ──\n // Country-aware postcode validation, mirroring the backend (#887) by reusing\n // the same `validator` rules. Computed for *both* card paths (vault + Stripe)\n // so the submit gate and the inline hint agree. A locale `validator` supports\n // makes the postcode required *and* format-checked; an unsupported /\n // no-postcode locale fails open — the field stays visible but optional and\n // never blocks (`empty`/`malformed` stay false).\n const postalCodeState = useMemo(() => {\n const cc = selectedCountry;\n const visible = avsConfig ? isAVSFieldVisible(avsConfig.postal_code, cc) : false;\n return computePostalCodeState(cc, zipCode, visible);\n }, [avsConfig, selectedCountry, zipCode]);\n // ── AVS validity for the vault submit gate ──\n // The vault's submit button lives inside the (cross-origin) widget and the\n // card fields are PCI-isolated, so the host can only validate the merchant-DOM\n // AVS inputs. When a required AVS field for the selected country is empty — or\n // the postcode is malformed for a supported locale — we push `blocked` to the\n // widget, which disables its submit button until the buyer fixes them (the\n // widget validates the card itself on submit).\n const { avsInvalid, invalidAvsFields } = useMemo<{\n avsInvalid: boolean;\n invalidAvsFields: { line1: boolean; city: boolean; state: boolean; zip: boolean };\n }>(() => {\n const none = { line1: false, city: false, state: false, zip: false };\n if (!vaultActive || !avsConfig) return { avsInvalid: false, invalidAvsFields: none };\n const cc = selectedCountry;\n // `line2` and the country `select` are never required.\n const isEmpty = (field: boolean | string[] | undefined, value: string) =>\n isAVSFieldVisible(field, cc) && !value.trim();\n const invalidAvsFields = {\n line1: isEmpty(avsConfig.address_line_1, addressLine1),\n city: isEmpty(avsConfig.city, city),\n state: isEmpty(avsConfig.state, stateValue),\n // Empty (required) or malformed both block; unsupported/no-postcode\n // locales never block (`postalCodeState` fails open above).\n zip: postalCodeState.empty || postalCodeState.malformed,\n };\n const avsInvalid =\n invalidAvsFields.line1 || invalidAvsFields.city || invalidAvsFields.state || invalidAvsFields.zip;\n return { avsInvalid, invalidAvsFields };\n }, [vaultActive, avsConfig, selectedCountry, addressLine1, city, stateValue, postalCodeState]);\n // Set once the buyer clicks the (enabled) vault submit with valid AVS — after\n // that, an AVS field that *becomes* incomplete gets a red outline, matching how\n // the widget rings its own invalid card fields after a submit attempt.\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = useState(false);\n // Set once the buyer blurs the postcode field. A malformed postcode blocks the\n // (vault) submit, so `hasAttemptedSubmit` can never flip to reveal the error —\n // we surface the inline expected-format message on blur instead.\n const [zipTouched, setZipTouched] = useState(false);\n // Hosted widget mount options: prefer the block embedded on the create-session\n // response (`session.vault`); otherwise fetch it from the idempotent\n // `POST /vault/capture` endpoint (covers sessions loaded by id, or backends\n // that don't embed the block). Carries the `html` plus the optional\n // `messageToken` / `expectedOrigin` the adapter uses to authenticate the\n // widget's terminal `postMessage` outcomes. Resolved by an effect once the\n // error/overlay callbacks below are in scope.\n const [vaultMount, setVaultMount] = useState<CardCaptureMountOptions | null>(() =>\n toVaultMount(session?.vault),\n );\n\n // Buttons ↔ Card ↔ APM transition state machine. The `apm-*` branches\n // mirror the `card` branches one-for-one so the inline-form APM 2nd\n // page (SEPA / EPS / iDEAL / …) animates in and out the same way as the\n // card form's 2nd page, with the same back-button + title chrome.\n type ViewState =\n | 'buttons'\n | 'expanding'\n | 'card'\n | 'collapsing'\n | 'apm-expanding'\n | 'apm-form'\n | 'apm-collapsing';\n const [viewState, setViewState] = useState<ViewState>(initialCardOpen ? 'card' : 'buttons');\n const [expandedApmMethod, setExpandedApmMethod] = useState<string | null>(null);\n const showCardForm = viewState === 'expanding' || viewState === 'card';\n const TRANSITION_MS = 280;\n\n const expandToCard = useCallback(() => {\n setViewState('expanding');\n setTimeout(() => setViewState('card'), TRANSITION_MS);\n }, []);\n\n const collapseToButtons = useCallback(() => {\n setViewState('collapsing');\n setTimeout(() => setViewState('buttons'), TRANSITION_MS);\n }, []);\n\n const expandToApm = useCallback((method: string) => {\n setExpandedApmMethod(method);\n setViewState('apm-expanding');\n setTimeout(() => setViewState('apm-form'), TRANSITION_MS);\n }, []);\n\n const collapseFromApm = useCallback(() => {\n setViewState('apm-collapsing');\n setTimeout(() => {\n setViewState('buttons');\n setExpandedApmMethod(null);\n }, TRANSITION_MS);\n }, []);\n\n useEffect(() => {\n if (layout === 'buttons' && initialCardOpen) {\n setViewState('card');\n }\n }, [layout, initialCardOpen]);\n const [fullName, setFullName] = useState('');\n const [formReady, setFormReady] = useState(false);\n const [overlayStatus, setOverlayStatus] = useState<OverlayStatus | null>(null);\n const processingRef = useRef(false);\n\n // `paypal_direct_required` retry surface. Set when /process returns the\n // discriminator with a fresh PayPal Order/Subscription id — re-binds the\n // direct PayPal button to that id so the buyer can confirm with one more\n // click. Cleared on success or when the buyer dismisses. `attempts` caps\n // the loop at 2 retries so a backend stuck throwing the same exception\n // can't trap the buyer forever.\n const [paypalDirectRetry, setPaypalDirectRetry] = useState<{\n orderId: string;\n attempts: number;\n } | null>(null);\n // Ref-mirror so the processPaymentInternal callback can read current\n // attempt count without recreating on every retry-state change (which\n // would invalidate downstream effects depending on the callback).\n const paypalDirectRetryRef = useRef(paypalDirectRetry);\n useEffect(() => { paypalDirectRetryRef.current = paypalDirectRetry; }, [paypalDirectRetry]);\n\n const resolvedBillingApiUrl = billingApiUrl || contextBillingUrl;\n const displayError = externalError ?? error;\n\n // Resolution order for the wrapper / button styles:\n // 1. `theme` bundle (high-level — pulls a coherent ButtonsLayoutStyles from THEMES)\n // 2. Legacy `buttonsTheme` preset (for back-compat — only applied when `theme` is absent)\n // 3. Explicit `buttonsStyles` override (per-field merge on top of either base)\n // Resolution order for the Stripe-side `appearance`:\n // 1. Explicit `appearance` prop (wins outright)\n // 2. `theme` bundle's appearance (when `appearance` is not supplied)\n const themeBundle = useMemo(() => resolveTheme(theme), [theme]);\n const bStyles = useMemo<ButtonsLayoutStyles>(() => {\n const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme(buttonsTheme);\n if (!buttonsStylesOverride) return base;\n return {\n ...base,\n ...buttonsStylesOverride,\n cardButton: { ...base.cardButton, ...buttonsStylesOverride.cardButton },\n cardFormContainer: { ...base.cardFormContainer, ...buttonsStylesOverride.cardFormContainer },\n backButton: { ...base.backButton, ...buttonsStylesOverride.backButton },\n backButtonIcon: { ...base.backButtonIcon, ...buttonsStylesOverride.backButtonIcon },\n submitButton: { ...base.submitButton, ...buttonsStylesOverride.submitButton },\n title: { ...base.title, ...buttonsStylesOverride.title },\n };\n }, [themeBundle, buttonsTheme, buttonsStylesOverride]);\n const appearance = appearanceOverride ?? themeBundle?.appearance;\n // Colors pushed into the hosted vault widget so the backend-rendered card form\n // matches the merchant's theme. The SDK owns *all* theming here — every value\n // resolves from the theme bundle / appearance overrides (same precedence the\n // SDK uses for its own AVS + card inputs); the backend ships only neutral\n // fallbacks for when a var is absent. Declared with the other hooks — above\n // any early return — so hook order stays stable across the `isReady` gate.\n const vaultThemeColors = useMemo<import('@flopay/shared').VaultCardThemeColors>(() => {\n const vars = appearance?.variables;\n const asString = (value: unknown): string | undefined =>\n typeof value === 'string' && value ? value : undefined;\n // Mirror the SDK submit-button resolution: a merchant who customized the\n // submit colour via `buttonsStyles.submitButton.backgroundColor` (rather\n // than `appearance.variables.colorPrimary`) should see that same colour on\n // the hosted vault submit instead of the indigo fallback.\n const submitButtonStyle = bStyles.submitButton as React.CSSProperties | undefined;\n const primary =\n asString(vars?.colorPrimary)\n ?? asString(submitButtonStyle?.backgroundColor)\n ?? '#4A49FF';\n const isButtonsLayout = layout === 'buttons';\n const nameInput = bStyles.nameInput;\n // Mirror the SDK (Stripe) card inputs *exactly* — same resolution order the\n // SDK uses for its own AVS / card fields below (`resolvedBorder`,\n // `cardInputBg`, `resolvedInputColor`, `resolvedPlaceholderColor`,\n // `resolvedInputFontFamily/Size`) — so the hosted vault form is visually\n // indistinguishable from the SDK fields for every theme + buttons-layout\n // bundle. The surface stays transparent (form CSS) so the surrounding\n // checkout shows through.\n return {\n primaryColor: primary,\n primaryHoverColor: asString(vars?.colorPrimaryHover) ?? darkenHex(primary, 0.12),\n inputBackgroundColor:\n asString(bStyles.cardInputBackground) ?? asString(vars?.colorBackground) ?? '#ffffff',\n textColor:\n asString(bStyles.cardInputColor)\n ?? asString(nameInput?.color)\n ?? asString(vars?.colorText)\n ?? '#262833',\n borderColor: asString(bStyles.cardInputBorder) ?? (isButtonsLayout ? '#e5e7eb' : '#A4A4FF'),\n placeholderColor: asString(bStyles.cardInputPlaceholderColor) ?? '#9ca3af',\n errorColor: asString(vars?.colorDanger) ?? '#dc2626',\n successColor: '#16a34a',\n fontFamily:\n asString(nameInput?.fontFamily) ?? asString(vars?.fontFamily) ?? 'Poppins, sans-serif',\n fontSize: asString(bStyles.cardInputFontSize) ?? asString(vars?.fontSizeBase) ?? '16px',\n // `resolvedInputFontWeight` equivalent — sent as a string (the widget's\n // theme applier only honors string values) so vault inputs/placeholders\n // match the AVS fields' weight per theme (default 400).\n fontWeight: String(toCssWeight(nameInput?.fontWeight) ?? 400),\n borderRadius: asString(vars?.borderRadius) ?? '8px',\n };\n }, [appearance, bStyles, layout]);\n const isInlineSessionPatchProcessing = checkout.inlineSessionPatchProcessing ?? false;\n const isSubmitting = (externalProcessing ?? processing) || isInlineSessionPatchProcessing;\n const isSelfContained = !onTokenizedBody;\n const baseUrl = resolvedBillingApiUrl.replace(/\\/+$/, '');\n const resolvedAccount = useMemo(() => mergeAccountPatch({\n userId,\n email,\n firstName,\n lastName,\n country: countryProp,\n zip: zipProp,\n }, accountPatch), [userId, email, firstName, lastName, countryProp, zipProp, accountPatch]);\n\n // Get raw Stripe instance for wallet Elements provider (primary Stripe account).\n const stripeInstance = useMemo(() => {\n if (!flopay) return null;\n return flopay.getRawProvider() as Stripe | null;\n }, [flopay]);\n\n // Get raw Stripe instance for the Stripe-rendered PayPal Elements provider.\n // When direct PayPal is configured (`directPaypal`) or no PayPal FloPay\n // instance is available, the Stripe-rendered PayPal path is suppressed.\n const paypalStripeInstance = useMemo(() => {\n if (!paypalFlopay) return null;\n return paypalFlopay.getRawProvider() as Stripe | null;\n }, [paypalFlopay]);\n\n // totalAmount is in cents (smallest currency unit) when passed from FloPayCheckout.\n // Stripe Elements `amount` expects cents.\n //\n // The `|| 100` is a $1.00 placeholder so the payment-mode Elements groups that\n // never display an amount (split card fields, the PaymentElement accordion)\n // still render for a $0-today cart — Stripe rejects `amount: 0` in payment\n // mode. The wallet/Express Checkout row, which DOES show the amount, uses\n // `resolveWalletElementsMode` below to run in setup mode for $0 instead, so it\n // never surfaces this placeholder as a misleading \"$1.00\" charge.\n const amountInCents = totalAmount || 100;\n\n // `FloPayAppearance` is a superset of Stripe's `Appearance` type (it adds\n // `variables.fontSizeBase` etc.) — the Stripe public typings reject the\n // wider shape, but the runtime accepts every extra field. Cast through\n // `Record<string, unknown>` so the spread below stays type-safe at the\n // option-construction site without `any`.\n const stripeAppearanceProp = appearance\n ? { appearance: appearance as unknown as Record<string, unknown> }\n : null;\n\n // PaymentElement-specific appearance: target Stripe's `.AccordionItem` and\n // `.AccordionItemContents` so each method card visually matches the 44px\n // wallet ECE buttons above it. Stripe accepts `padding` / `borderRadius` /\n // border styling in `rules`; `height` is not a supported property, so we\n // pin via padding (10px top/bottom × ~24px line-height ≈ 44px total).\n //\n // Stripe's default `spacedAccordionItems` rendering paints a subtle drop\n // shadow under each method card. The wallet ECE row above this region uses\n // flat buttons with no shadow, so we explicitly null the shadow here for\n // visual parity — without this, Cash App Pay sat noticeably \"above\" the\n // wallet buttons stacked just above it. Consumer overrides still win via\n // the `baseRules` spread.\n const paymentElementAppearance = useMemo(() => {\n const base = (appearance ?? {}) as Record<string, unknown>;\n const baseRules = (base.rules as Record<string, Record<string, string>> | undefined) ?? {};\n return {\n ...base,\n rules: {\n ...baseRules,\n '.AccordionItem': {\n padding: '10px 14px',\n boxShadow: 'none',\n ...(baseRules['.AccordionItem'] ?? {}),\n },\n '.AccordionItemContents': {\n padding: '6px 14px 12px',\n boxShadow: 'none',\n ...(baseRules['.AccordionItemContents'] ?? {}),\n },\n },\n };\n }, [appearance]);\n\n // Wallet (Apple/Google Pay) Elements options — uses paymentMethodCreation: 'manual'\n // to match the main card Elements, allowing explicit createPaymentMethod() calls.\n // `appearance` is forwarded so the ExpressCheckoutElement iframe inherits the\n // shared theme variables (e.g. `borderRadius`) instead of falling back to\n // Stripe's defaults.\n const walletOptions = useMemo(() => {\n // $0-today (free trial) → setup mode (no charge shown on the Apple/Google\n // Pay sheet); any positive total → payment mode with the real amount.\n const modeOptions = resolveWalletElementsMode(totalAmount);\n return {\n ...modeOptions,\n currency: currency.toLowerCase(),\n paymentMethodCreation: 'manual' as const,\n // captureMethod only applies to payment mode; Stripe rejects it in setup.\n ...(modeOptions.mode === 'payment' ? { captureMethod: 'manual' as const } : {}),\n ...stripeAppearanceProp,\n };\n }, [totalAmount, currency, stripeAppearanceProp]);\n\n // PayPal Elements options — no paymentMethodCreation (matches checkout)\n const paypalOptions = useMemo(() => ({\n mode: 'payment' as const,\n amount: amountInCents,\n currency: currency.toLowerCase(),\n captureMethod: 'manual' as const,\n setupFutureUsage: 'off_session' as const,\n ...stripeAppearanceProp,\n }), [amountInCents, currency, stripeAppearanceProp]);\n\n const updateError = useCallback(\n (err: string | null) => {\n setError(err);\n onErrorChange?.(err);\n },\n [onErrorChange],\n );\n\n // The vault submit-gate is driven by the client-validity effect below (it\n // gates the widget's submit button on the synchronous AVS check, whose\n // postcode half mirrors the backend validator — see that effect for why the\n // gate must stay synchronous). The adapter re-pushes the latest gate value on\n // `ready`, so a pre-ready push is never lost.\n\n // Push the per-merchant card-field order + autofocus into the widget. The\n // widget reorders its rows (DOM order → tab order) and focuses its first field\n // unless AVS fields are rendered above it (then the host focuses the first AVS\n // field — see below). Re-pushed on `ready` by the adapter.\n useEffect(() => {\n if (!vaultActive || !cardCapture) return;\n cardCapture.setCardFieldOrder?.(cardFieldOrder ?? null, avsConfig == null);\n }, [vaultActive, cardCapture, cardFieldOrder, avsConfig]);\n\n // Clear any stale error whenever the buyer moves between screens — selecting a\n // method (card or APM → its form) or hitting \"Go back\" (→ the buttons home).\n // A decline/error from one screen must not linger onto the next: e.g. the\n // vault's \"fill in all required card details\", or an APM decline that\n // otherwise stayed on the method-selection screen behind the inner page.\n // These are the four transition states; the settled states\n // (`buttons`/`card`/`apm-form`) keep whatever error their own flow set.\n useEffect(() => {\n if (\n viewState === 'expanding' ||\n viewState === 'collapsing' ||\n viewState === 'apm-expanding' ||\n viewState === 'apm-collapsing'\n ) {\n updateError(null);\n }\n }, [viewState, updateError]);\n\n const emitDecline = useCallback(\n (\n method: CheckoutButtonMethod,\n input: string | FloPayError,\n overrides?: { code?: string; declineCode?: string },\n ) => {\n onDecline?.(buildDeclineEvent(method, input, overrides));\n },\n [onDecline],\n );\n\n const recoverExternalMethodTechnicalFailure = useCallback<ExternalMethodTechnicalFailureHandler>(\n (method, err, options) => {\n const popupBlocked = options?.popupBlocked ?? isPopupBlockedError(err);\n const message = buildExternalMethodRecoveryMessage(method, popupBlocked);\n const providerCode =\n sanitizeExternalFailureCode(options?.code) ??\n getProviderErrorCode(err) ??\n 'external_payment_method_failed';\n const floPayError = new FloPayError(message, 'api_error', {\n code: 'external_payment_method_failed',\n param: method,\n });\n\n setOverlayStatus(null);\n if (layout === 'buttons') {\n setViewState('buttons');\n setExpandedApmMethod(null);\n }\n updateError(message);\n onError?.(floPayError);\n console.error('[FloPay] External payment method failed:', {\n method,\n code: providerCode,\n popupBlocked,\n });\n },\n [layout, onError, updateError],\n );\n\n // ── Vault widget HTML resolution (Model A) ──\n // Prefer the block embedded on the create-session response; otherwise fetch\n // it from the idempotent `POST /vault/capture` endpoint. Runs only when the\n // vault is active (an embedded `vault` block, or a legacy `gateways.pcivault`\n // advertisement that defers the form to the fetch path).\n useEffect(() => {\n if (!vaultActive || !sessionId) {\n setVaultMount(null);\n return;\n }\n const embedded = toVaultMount(session?.vault);\n if (embedded) {\n setVaultMount(embedded);\n return;\n }\n // Drop any block from a previous session before the fetch resolves so the\n // adapter never mounts widget HTML tied to the wrong checkout session.\n setVaultMount(null);\n let active = true;\n new PaymentAPI(baseUrl)\n .getVaultCapture(sessionId, nonce)\n .then((block) => {\n if (!active) return;\n const mount = toVaultMount(block);\n if (mount) {\n setVaultMount(mount);\n } else {\n updateError('Failed to load the secure card form.');\n }\n })\n .catch((err: unknown) => {\n if (active) {\n updateError(err instanceof Error ? err.message : 'Failed to load the secure card form.');\n }\n });\n return () => {\n active = false;\n };\n }, [\n vaultActive,\n sessionId,\n session?.vault?.html,\n session?.vault?.messageToken,\n session?.vault?.expectedOrigin,\n baseUrl,\n nonce,\n updateError,\n ]);\n\n // Latest volatile inputs the vault-outcome handlers read, captured in a ref so\n // the outcome subscription effect below can depend only on the *stable*\n // `[vaultActive, cardCapture]` pair. Previously these (consumer callbacks like\n // `onComplete`/`onError`/`onDecline`, plus `resolvedAccount`/`fullName`/AVS)\n // were effect deps; an integration passing inline callbacks re-rendered the\n // parent mid-payment, churning their identity, tearing the effect down, and —\n // because the widget emits `complete` only once — dropping the terminal\n // `onComplete` during the success-overlay hold (buyer stuck on \"PAYMENT\n // SUCCESSFUL\"). Mirrors the ref pattern FloPayCheckout already uses for its\n // own callbacks. Read at event time, so a change never re-subscribes.\n const vaultOutcomeRef = useRef({\n onComplete,\n onError,\n updateError,\n emitDecline,\n resolvedAccount,\n fullName,\n avsConfig,\n avsCheckProp,\n sessionId,\n nonce,\n baseUrl,\n });\n vaultOutcomeRef.current = {\n onComplete,\n onError,\n updateError,\n emitDecline,\n resolvedAccount,\n fullName,\n avsConfig,\n avsCheckProp,\n sessionId,\n nonce,\n baseUrl,\n };\n // One-shot latch: guarantees the terminal `onComplete` fires exactly once for\n // the mounted capture even if the component re-renders or unmounts during the\n // ~1.2s success-overlay hold. A succeeded payment must always reach the\n // consumer, so completion is gated on this latch rather than on effect\n // teardown. Reset when the effect (re)subscribes for a new capture instance.\n const vaultCompletedRef = useRef(false);\n\n // Build the `patchAccountSnapshot` body from the live refs + latest resolved\n // account / AVS context (read from `vaultOutcomeRef` so this stays identity-\n // stable and never re-subscribes the outcome effect). Called from the\n // `submitting` handler to persist the billing snapshot best-effort.\n const buildVaultAccountSnapshot = useCallback(() => {\n const { resolvedAccount, avsConfig, fullName, avsCheckProp } = vaultOutcomeRef.current;\n const cc = selectedCountryRef.current || resolvedAccount.country || 'US';\n const stateVisible = avsConfig ? isAVSFieldVisible(avsConfig.state, cc) : false;\n const line1Visible = avsConfig ? isAVSFieldVisible(avsConfig.address_line_1, cc) : false;\n const zipVisible = avsConfig ? isAVSFieldVisible(avsConfig.postal_code, cc) : false;\n const cityVisible = avsConfig ? isAVSFieldVisible(avsConfig.city, cc) : false;\n const line2Visible = avsConfig ? isAVSFieldVisible(avsConfig.address_line_2, cc) : false;\n const derivedState =\n line1Visible && !stateVisible && zipVisible\n ? getStateFromPostalCode(cc, (zipCodeRef.current ?? '').trim())\n : null;\n const stateValue = stateVisible ? stateRef.current : derivedState;\n return {\n accountData: {\n userId: resolvedAccount.userId ?? '',\n email: resolvedAccount.email ?? '',\n firstName: resolvedAccount.firstName ?? fullName.trim().split(/\\s+/)[0] ?? '',\n lastName: resolvedAccount.lastName ?? fullName.trim().split(/\\s+/).slice(1).join(' ') ?? '',\n ...(zipVisible && zipCodeRef.current ? { zip: zipCodeRef.current } : {}),\n ...(cityVisible && cityRef.current ? { city: cityRef.current } : {}),\n ...(stateValue ? { state: stateValue } : {}),\n ...(line1Visible && addressLine1Ref.current\n ? { addressLine1: addressLine1Ref.current }\n : {}),\n ...(line2Visible && addressLine2Ref.current\n ? { addressLine2: addressLine2Ref.current }\n : {}),\n country: cc,\n },\n ...(avsCheckProp !== undefined ? { avsCheck: avsCheckProp } : {}),\n ...(avsConfig\n ? {\n avsConfig: {\n country: isAVSFieldVisible(avsConfig.country, cc),\n postal_code: zipVisible,\n address_line_1: line1Visible,\n address_line_2: line2Visible,\n city: cityVisible,\n state: stateVisible,\n },\n }\n : {}),\n };\n }, []);\n\n // ── Vault submit gate ← client-side AVS validity (sdk#124) ──\n // The hosted widget's submit button lives inside its cross-origin iframe, so\n // the host can only gate it (disable/enable) — it cannot pause or cancel a\n // charge once the button is clicked, and a click landing while the gate is\n // *closed* is silently swallowed by the widget with no way to auto-resubmit on\n // release. That makes an async gate (hold closed → PATCH round-trip → open)\n // unsafe: a buyer (or the /theme single-click preview) who clicks before the\n // round-trip resolves has their click dropped, the widget never POSTs, and no\n // `checkout_transaction_attempt` is ever written — the df4c14ae hang.\n //\n // So we gate purely on the *synchronous* client-side AVS validity. The\n // postcode half of that check now mirrors the backend validator verbatim\n // (`isValidPostalCode` ← `validator@13.15.35`, d1fcf91), so a postcode the\n // server's `PATCH /account` would 400 on is already blocked here, before the\n // button ever enables — no async round-trip needed to enforce it. The account\n // snapshot is persisted best-effort in the `submitting` handler below (which\n // still classifies a 4xx and surfaces it), matching pre-#124 charge behaviour.\n // The adapter re-pushes the latest gate value on `ready`, so a pre-ready push\n // is never lost.\n useEffect(() => {\n if (!vaultActive || !cardCapture) return;\n cardCapture.setSubmitGate?.(avsInvalid);\n }, [vaultActive, cardCapture, avsInvalid]);\n\n // ── Vault widget outcome → consumer callbacks (Model A) ──\n // The hosted widget owns the charge + 3DS and reports a terminal result via\n // `postMessage`; the SDK only relays it to `onComplete` / `onDecline` /\n // `onError`. The widget renders its own status UI, so the SDK does not drive\n // its own processing overlay here. (Until the backend emits these messages,\n // the widget falls back to its own success redirect.)\n useEffect(() => {\n if (!vaultActive || !cardCapture) return;\n // Fresh capture instance → allow a completion again (a new checkout session\n // re-creates `cardCapture`, which is the only way this effect re-runs).\n vaultCompletedRef.current = false;\n // Guards the trailing decline/error overlay *state writes* below from firing\n // after the effect tears down (unmount / dep change). The terminal\n // `onComplete` is deliberately NOT gated on this — it fires once via\n // `vaultCompletedRef` so a succeeded payment always reaches the consumer.\n let cancelled = false;\n // ── Buyer-hits-pay AVS sync (TeamFloPay/backend#823 Gap 5) ──\n // The hosted vault widget emits `submitting` when the buyer clicks the\n // iframe's submit button, *before* it POSTs to PCIVault. The submit gate\n // already let a client-valid address through (client postcode rules mirror\n // the backend validator), so here we persist the billing snapshot in\n // parallel with the charge — see the PATCH below for the best-effort /\n // 4xx-surfacing semantics.\n const offSubmitting = cardCapture.on('submitting', () => {\n // A real submit fired (button was enabled → AVS was valid). From now on,\n // an AVS field that becomes incomplete gets a red outline.\n setHasAttemptedSubmit(true);\n // Drive the SDK's full-component processing overlay (the widget suppresses\n // its own in-iframe overlay) so the \"Processing payment\" state covers the\n // whole card — matching the Stripe path.\n setOverlayStatus('processing');\n const { baseUrl, sessionId, nonce, updateError, onError } = vaultOutcomeRef.current;\n if (!sessionId || !nonce) return;\n // Persist the billing snapshot best-effort so the listener (which runs\n // after the PCIVault webhook + DB lookup, ~hundreds of ms later) sees the\n // up-to-date address/AVS when it mints the Stripe PaymentMethod and\n // snapshots into `user_payment_method` / `checkout_transaction_attempts`.\n // This runs in parallel with the widget's charge (the gate already let a\n // client-valid address through), so a 4xx here is surfaced for the buyer's\n // next attempt but cannot cancel the in-flight charge. A transient\n // 5xx/network failure stays silent — the listener falls back to the\n // session baseline.\n void new PaymentAPI(baseUrl)\n .patchAccountSnapshot(sessionId, nonce, buildVaultAccountSnapshot())\n .catch((err: unknown) => {\n if (!isAccountValidationError(err)) return;\n const message =\n err instanceof Error\n ? err.message\n : 'Please check your billing address and try again.';\n updateError(message);\n setOverlayStatus(null);\n onError?.(err instanceof FloPayError ? err : new FloPayError(message, 'api_error'));\n });\n });\n // Terminal outcomes drive the same overlay transitions as the Stripe path:\n // success → green check (held `SUCCESS_DELAY`) then onComplete; decline/error\n // → red cross + message (held `ERROR_DELAY`) then the overlay clears, leaving\n // the inline error banner.\n const offComplete = cardCapture.on('complete', async (event) => {\n // Mark completed *before* the success-overlay delay so a remount during it\n // can't clear the cache and POST a duplicate session (double-charge).\n markSessionRecentlyCompleted(event.sessionId ?? vaultOutcomeRef.current.sessionId);\n setOverlayStatus('success');\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));\n // Fire exactly once. NOT gated on `cancelled`: a re-render or unmount\n // during the hold must not swallow a succeeded payment — the widget emits\n // `complete` only once, so a dropped callback is unrecoverable.\n if (vaultCompletedRef.current) return;\n vaultCompletedRef.current = true;\n vaultOutcomeRef.current.onComplete?.({\n status: 'succeeded',\n paymentIntentId: event.intentId,\n checkoutMethod: 'card',\n });\n });\n const offDecline = cardCapture.on('decline', async (event) => {\n const { updateError, emitDecline } = vaultOutcomeRef.current;\n const message = event.message ?? 'Your payment was declined. Please try another card or contact your bank.';\n updateError(message);\n setOverlayStatus('error');\n emitDecline('card', message, event.declineReason ? { declineCode: event.declineReason } : undefined);\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n if (cancelled) return;\n setOverlayStatus(null);\n });\n const offError = cardCapture.on('error', async (event) => {\n const { updateError, onError } = vaultOutcomeRef.current;\n const message = event.message ?? 'There was a problem processing your payment. Please try again.';\n updateError(message);\n setOverlayStatus('error');\n onError?.(new FloPayError(message, 'api_error'));\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n if (cancelled) return;\n setOverlayStatus(null);\n });\n return () => {\n cancelled = true;\n offSubmitting();\n offComplete();\n offDecline();\n offError();\n };\n // Depends only on the stable capture identity: all volatile inputs\n // (consumer callbacks, resolvedAccount, fullName, AVS) are read from\n // `vaultOutcomeRef` at event time, so churning them never re-subscribes and\n // never tears down an in-flight terminal outcome. `cardCapture` is\n // re-created only when the session (and thus the widget) changes.\n }, [vaultActive, cardCapture]);\n\n // ── Method partitioning ──\n //\n // Backend now ships `enabledPaymentMethods` per-session (e.g. ['apple_pay',\n // 'cashapp', 'google_pay', 'link', 'sepa_debit']). We partition it into:\n // - `expressMethods`: the subset supported by `ExpressCheckoutElement`\n // (filtered against STRIPE_EXPRESS_METHODS).\n // - `paymentElementMethods`: everything else (Cash App Pay, Affirm, iDEAL,\n // SEPA debit, …) — rendered in the accordion PaymentElement region.\n //\n // PayPal is dropped from the express set when `DirectPayPalButton` owns the\n // PayPal surface (controlled by `gateways.paypal` upstream → `directPaypal`\n // prop here), so the SDK doesn't double-render.\n //\n // Legacy fallback: when the billing API hasn't been upgraded to ship\n // `enabledPaymentMethods`, fall back to the historic\n // `showApplePay`/`showGooglePay` toggle behaviour so existing integrations\n // keep working unchanged.\n const directPaypalConfigured = !!directPaypal?.clientId;\n // `hasEnabledMethodsPayload` distinguishes \"backend shipped the field\" from\n // \"backend shipped the field with at least one entry\". A provided-but-empty\n // array means the new gateway-driven path is in effect with no enabled\n // methods — it must NOT fall back to legacy `showApplePay`/`showGooglePay`\n // behaviour, and PayPal must stay suppressed unless `'paypal'` is in the\n // list (or `directPaypal` is configured separately).\n const hasEnabledMethodsPayload = Array.isArray(enabledPaymentMethods);\n const hasEnabledMethods = hasEnabledMethodsPayload && enabledPaymentMethods.length > 0;\n const paypalEnabled = hasEnabledMethodsPayload && enabledPaymentMethods.includes('paypal');\n const { expressMethods, paymentElementMethods } = useMemo(\n () => partitionStripeMethods(enabledPaymentMethods, {\n excludePaypal: directPaypalConfigured,\n }),\n [enabledPaymentMethods, directPaypalConfigured],\n );\n // Get raw Stripe instance early so we can decide whether PayPal renders\n // separately. `paypalStripeInstance` lives on the dedicated PayPal sub-\n // account when `gateways.stripe.paypalPublishableKey` is set; otherwise\n // PayPal can ride along inside the main wallet ECE.\n const paypalRenderedSeparately = directPaypalConfigured || !!paypalFlopay;\n // Drop PayPal from the main wallet ECE only when something else is going\n // to render it (DirectPayPal or the dedicated PayPal sub-account\n // PayPalButtonInner). When neither is configured, PayPal stays in the\n // express set so Stripe still shows the button on supported envs.\n const expressMethodsForWalletRow = useMemo(\n () => paypalRenderedSeparately\n ? expressMethods.filter((m) => m !== 'paypal')\n : expressMethods,\n [expressMethods, paypalRenderedSeparately],\n );\n const legacyExpressMethods = useMemo(() => {\n const out: string[] = [];\n if (showApplePay) out.push('apple_pay');\n if (showGooglePay) out.push('google_pay');\n return out;\n }, [showApplePay, showGooglePay]);\n // Final list driving WalletButtonInner. New path wins when the backend\n // ships the field; legacy props are used as the fallback only.\n // `hasEnabledMethodsPayload` (not `hasEnabledMethods`) gates the new-vs-legacy\n // switch: a provided-but-empty `enabledPaymentMethods=[]` means \"no methods\n // enabled\" under the new path, not \"fall back to legacy props\".\n const walletExpressMethods = hasEnabledMethodsPayload ? expressMethodsForWalletRow : legacyExpressMethods;\n const showWallets = showStripe && walletExpressMethods.length > 0;\n\n // Currency and amount are fixed for the life of the session, and the backend\n // already drops methods that violate them from `enabledPaymentMethods` (so a\n // USD cart never lists `bancontact`, a sub-$35 cart never lists `affirm`).\n // We therefore do NOT re-filter currency/amount here — the backend is the\n // single source of truth for those.\n //\n // Country is the one axis the SDK must apply itself: the buyer can change\n // their billing country inline via AVS *after* the session was created, so\n // the backend ships a country-agnostic superset plus a per-method country\n // gate (`enabledPaymentMethodCountries`), and we filter the tile row by the\n // buyer's *live* country here (e.g. switching to NL surfaces iDEAL, to BE\n // Bancontact). `selectedCountry` tracks the AVS country select; we fall back\n // to the static `country` prop when AVS isn't shown, and to the SDK's\n // built-in country table for legacy backends that don't send the gate.\n const apmCountry = enableAVS ? selectedCountry : countryProp;\n const paymentElementMethodsForCurrency = useMemo(() => {\n const target = apmCountry?.trim().toUpperCase();\n if (!target) return paymentElementMethods;\n if (!enabledPaymentMethodCountries) {\n return filterStripeMethodsByCountry(paymentElementMethods, apmCountry);\n }\n return paymentElementMethods.filter((method) => {\n const allowed = enabledPaymentMethodCountries[method];\n // A method without an entry (or an empty list) has no country gate.\n return !allowed || allowed.length === 0 || allowed.includes(target);\n });\n }, [paymentElementMethods, apmCountry, enabledPaymentMethodCountries]);\n\n // PaymentElement Elements options — same `paymentMethodCreation: 'manual'`\n // mode as the card Elements so `createPaymentMethod({ elements })` works.\n // `paymentMethodTypes` is filtered to the non-express portion of the\n // backend-supplied enabled list (and to the methods Stripe accepts for the\n // session currency *and* amount) so the accordion never double-renders the\n // big buttons the wallet row already shows, and never includes a method\n // Stripe will reject.\n //\n // `captureMethod` is intentionally omitted (defaults to `automatic`): most\n // PaymentElement APMs (Cash App Pay, Affirm, Klarna, iDEAL, SEPA debit,\n // Bancontact, EPS, Giropay, …) do not support `manual` capture, and Stripe\n // rejects the entire Elements mount with a 400 on\n // `/v1/elements?type=deferred_intent` (\"Frame not initialized\"). The\n // accordion ends up rendered as an empty `<div class=\"\">` shell. Letting\n // capture default keeps the deferred-intent options accepted for the full\n // set of APMs we partition into this region.\n //\n // `appearance` is forwarded so the PaymentElement iframe picks up the same\n // theme variables (colours, border radius, font family) as the card row.\n // Without this, Stripe falls back to its grey defaults and the accordion\n // looks visually unrelated to the rest of the FloPay surface.\n // Base options for every per-method `<StripeElements>` group mounted by\n // `StripePaymentElementInner` (one per expanded inline form). The child\n // spreads this and tacks on `paymentMethodTypes: [<method>]` per group.\n // The per-method split is what lets each expanded form scope its\n // accordion to a single method without an `elements.update({\n // paymentMethodTypes })` call (which Stripe refuses).\n const paymentElementBaseOptions = useMemo(() => ({\n mode: 'payment' as const,\n amount: amountInCents,\n currency: currency.toLowerCase(),\n paymentMethodCreation: 'manual' as const,\n appearance: paymentElementAppearance,\n }), [amountInCents, currency, paymentElementAppearance]);\n\n // Stripe's PayPal ExpressCheckoutElement breaks inside known in-app browsers\n // and the existing flow gated it on `inAppBrowserDetected`. With the\n // gateway-driven model the renderer decision moves to `gateways.paypal`\n // (DirectPayPalButton when present, Stripe-rendered PayPal otherwise). When\n // backend ships `enabledPaymentMethods`, the in-app-browser gate is no\n // longer consulted — gateway configuration alone drives renderer choice.\n // Legacy backends keep the historic UA-based gate.\n const [paypalLoadState, setPaypalLoadState] = useState<ExpressCheckoutLoadState>('loading');\n const [walletLoadState, setWalletLoadState] = useState<ExpressCheckoutLoadState>('loading');\n const [paymentElementLoadState, setPaymentElementLoadState] = useState<'loading' | 'ready' | 'load_error'>('loading');\n const [directPaypalReady, setDirectPaypalReady] = useState(false);\n const [inAppBrowserDetected, setInAppBrowserDetected] = useState<boolean>();\n useEffect(() => {\n setInAppBrowserDetected(isInAppBrowser());\n }, []);\n // When the backend ships `enabledPaymentMethods`, the presence/absence of\n // `'paypal'` in that list decides PayPal visibility — a non-empty list that\n // omits `'paypal'` must suppress PayPal even if `paypalFlopay` is configured.\n // Only fall back to the legacy in-app-browser gate when no payload was sent\n // at all. `directPaypal` overrides both paths.\n const shouldShowPayPal = showPayPal\n && (directPaypalConfigured\n || (hasEnabledMethodsPayload\n ? paypalEnabled\n : inAppBrowserDetected === false));\n const shouldShowWallets = showStripe && showWallets;\n const shouldRenderDirectPayPal = shouldShowPayPal && directPaypalConfigured;\n const shouldRenderStripePayPal = shouldShowPayPal && !directPaypalConfigured && !!paypalStripeInstance;\n const shouldRenderWallets = shouldShowWallets && !!stripeInstance;\n // Suppress the entire PaymentElement region when the currency filter empties\n // the list — Stripe Elements won't mount with `paymentMethodTypes: []` and\n // we'd otherwise paint a blank divider row.\n const shouldRenderPaymentElement = showStripe\n && hasEnabledMethods\n && paymentElementMethodsForCurrency.length > 0\n && !!stripeInstance;\n const shouldDisplayPayPalRow = shouldRenderDirectPayPal\n ? directPaypalReady\n : shouldRenderStripePayPal && isExpressCheckoutRowVisible(paypalLoadState);\n const shouldDisplayWalletRow = shouldRenderWallets && isExpressCheckoutRowVisible(walletLoadState);\n const shouldDisplayPaymentElementRow = shouldRenderPaymentElement && paymentElementLoadState !== 'load_error';\n\n // ── Boot-time validation: nothing to render ──\n //\n // Both `showStripe` and `showPayPal` were turned off (or off + no PayPal\n // gateway present) — there's no payment surface to render. Surface this\n // as `onError` rather than silently rendering an empty form so the bug is\n // caught during integration.\n const validationFiredRef = useRef(false);\n useEffect(() => {\n if (validationFiredRef.current) return;\n if (!showStripe && !showPayPal) {\n validationFiredRef.current = true;\n const err = new FloPayError(\n 'FloPay: both `showStripe` and `showPayPal` are false — nothing to render.',\n 'validation_error',\n );\n onError?.(err);\n updateError(err.message);\n } else if (!showStripe && showPayPal && !directPaypalConfigured && !paypalStripeInstance) {\n validationFiredRef.current = true;\n const err = new FloPayError(\n 'FloPay: `showStripe` is false and no PayPal gateway is configured for this session — nothing to render.',\n 'validation_error',\n );\n onError?.(err);\n updateError(err.message);\n }\n }, [showStripe, showPayPal, directPaypalConfigured, paypalStripeInstance, onError, updateError]);\n\n // ── Deprecation warnings ──\n //\n // Emitted once per mount when consumers pass the legacy\n // `showApplePay`/`showGooglePay`/`directPaypal` props alongside the new\n // `enabledPaymentMethods` surface. The legacy props are *not* fed into the\n // new path (`enabledPaymentMethods` wins outright), so silently honouring\n // them would surprise consumers; the warning makes the migration visible.\n const deprecationLoggedRef = useRef(false);\n useEffect(() => {\n if (deprecationLoggedRef.current) return;\n if (!hasEnabledMethods) return;\n const stale: string[] = [];\n if (showApplePay !== true) stale.push('showApplePay');\n if (showGooglePay !== true) stale.push('showGooglePay');\n if (stale.length === 0) return;\n deprecationLoggedRef.current = true;\n // eslint-disable-next-line no-console\n console.warn(\n `[FloPay] ${stale.join(' / ')} ${stale.length === 1 ? 'is' : 'are'} deprecated: ` +\n 'the Apple Pay / Google Pay surface is now driven by ' +\n '`gateways.stripe.enabledPaymentMethods` on the session response. ' +\n 'Remove the legacy prop(s) to silence this warning.',\n );\n }, [hasEnabledMethods, showApplePay, showGooglePay]);\n\n const handleNameChange = useCallback((value: string) => {\n setFullName(value);\n onFullNameChange?.(value);\n const parts = value.trim().split(/\\s+/);\n onFirstNameChange?.(parts[0] ?? '');\n onLastNameChange?.(parts.length > 1 ? parts.slice(1).join(' ') : '');\n }, [onFullNameChange, onFirstNameChange, onLastNameChange]);\n\n const applyInlineSessionPatch = useCallback(\n (patch: InlineSessionPatch, method: CheckoutButtonMethod): Promise<BeforeButtonClickPatchResult> => {\n if (!checkout.applyInlineSessionPatch) {\n return Promise.resolve({ error: null, sessionId, nonce });\n }\n\n return checkout.applyInlineSessionPatch(patch)\n .then((result) => ({\n error: null,\n sessionId: result.sessionId || sessionId,\n // A freshly bootstrapped session carries its own nonce on\n // `session.clientSecret`. Pair it with the new sessionId so\n // downstream continuation calls don't send the new id with the\n // prior session-bound token.\n nonce: result.session?.clientSecret || nonce,\n }))\n .catch((err) => {\n const floPayErr = normalizeBeforeButtonClickError(method, err);\n updateError(floPayErr.message);\n onError?.(floPayErr);\n return { error: floPayErr, sessionId, nonce };\n });\n },\n [checkout.applyInlineSessionPatch, nonce, onError, sessionId, updateError],\n );\n\n const runBeforeButtonClick = useCallback(async (\n method: CheckoutButtonMethod,\n ): Promise<BeforeButtonClickResult> => {\n if (!onBeforeButtonClick) return { proceed: true };\n\n try {\n const result = await onBeforeButtonClick({\n method,\n sessionId: sessionId || undefined,\n createSession: checkout.inlineSessionDraft,\n });\n\n if (result === false) {\n return { proceed: false };\n }\n\n if (result && typeof result === 'object') {\n if (result.account) {\n setAccountPatch((prev) => ({ ...(prev ?? {}), ...result.account }));\n }\n\n const patchResult = await applyInlineSessionPatch(result, method);\n if (patchResult.error) {\n return {\n proceed: false,\n accountPatch: result.account,\n };\n }\n\n return {\n proceed: true,\n accountPatch: result.account,\n sessionId: patchResult.sessionId,\n nonce: patchResult.nonce,\n };\n }\n\n return { proceed: true };\n } catch (err) {\n const floPayErr = normalizeBeforeButtonClickError(method, err);\n updateError(floPayErr.message);\n onError?.(floPayErr);\n return { proceed: false };\n }\n }, [applyInlineSessionPatch, checkout.inlineSessionDraft, onBeforeButtonClick, onError, sessionId, updateError]);\n\n // ── Internal processPayment + 3DS retry ──\n\n const processPaymentInternal = useCallback(\n async (tokenizedBody: TokenizedBody, overrides?: TokenizedBodyOverrides) => {\n // Prevent double-processing\n if (processingRef.current) return;\n processingRef.current = true;\n\n setProcessing(true);\n setOverlayStatus('processing');\n updateError(null);\n\n const effectiveSessionId = overrides?.sessionId ?? sessionId;\n // Keep the nonce paired with the (possibly overridden) sessionId.\n // `runBeforeButtonClick`/`applyInlineSessionPatch` can bootstrap a\n // fresh session and hand back its nonce; using the stale\n // component-level nonce here would send the new id with the prior\n // session-bound token and 401 on the continuation route.\n const effectiveNonce = overrides?.nonce ?? nonce;\n const effectiveAccount = mergeAccountPatch(resolvedAccount, overrides?.accountPatch);\n const resolvedCompletionPaymentMethodId =\n overrides?.completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);\n const requestTokenizedBody = tokenizedBody.originalPaymentMethodId\n ? { ...tokenizedBody, originalPaymentMethodId: undefined }\n : tokenizedBody;\n\n try {\n const api = new PaymentAPI(baseUrl);\n const response = await api.processPayment(effectiveAccount.userId ?? '', {\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n tokenizedData: requestTokenizedBody,\n accountData: {\n userId: effectiveAccount.userId ?? '',\n email: effectiveAccount.email ?? '',\n firstName: effectiveAccount.firstName ?? fullName.trim().split(/\\s+/)[0] ?? '',\n lastName: effectiveAccount.lastName ?? fullName.trim().split(/\\s+/).slice(1).join(' ') ?? '',\n ...(avsConfig ? (() => {\n const c = selectedCountryRef.current;\n const stateVisible = isAVSFieldVisible(avsConfig.state, c);\n const line1Visible = isAVSFieldVisible(avsConfig.address_line_1, c);\n const zipVisible = isAVSFieldVisible(avsConfig.postal_code, c);\n // When line1 is collected but state is hidden, derive state\n // from the ZIP for US/CA so Stripe AVS still gets a state signal.\n const derivedState = (line1Visible && !stateVisible && zipVisible)\n ? getStateFromPostalCode(c, (zipCodeRef.current ?? '').trim())\n : null;\n const stateValue = stateVisible ? stateRef.current : derivedState;\n return {\n country: c,\n ...(zipVisible && zipCodeRef.current ? { zip: zipCodeRef.current } : {}),\n ...(isAVSFieldVisible(avsConfig.city, c) && cityRef.current ? { city: cityRef.current } : {}),\n ...(stateValue ? { state: stateValue } : {}),\n ...(line1Visible && addressLine1Ref.current ? { addressLine1: addressLine1Ref.current } : {}),\n ...(isAVSFieldVisible(avsConfig.address_line_2, c) && addressLine2Ref.current ? { addressLine2: addressLine2Ref.current } : {}),\n };\n })() : {}),\n },\n chv,\n // Checkout analytics metadata\n avsCheck: avsCheckProp ?? false,\n checkoutType: checkoutTypeProp,\n checkoutLayout: checkoutLayoutProp,\n // Resolved exposure: which fields were actually shown for the active country.\n // Country-scoped rules (e.g. ['US', 'CA']) are flattened to booleans here.\n avsConfig: avsConfig ? {\n country: isAVSFieldVisible(avsConfig.country, selectedCountryRef.current),\n postal_code: isAVSFieldVisible(avsConfig.postal_code, selectedCountryRef.current),\n address_line_1: isAVSFieldVisible(avsConfig.address_line_1, selectedCountryRef.current),\n address_line_2: isAVSFieldVisible(avsConfig.address_line_2, selectedCountryRef.current),\n city: isAVSFieldVisible(avsConfig.city, selectedCountryRef.current),\n state: isAVSFieldVisible(avsConfig.state, selectedCountryRef.current),\n } : undefined,\n });\n\n if (response.ok) {\n // Mark the session as completed *now*, before the 1.2s success\n // overlay delay below. A bootstrap that re-runs during that delay\n // (real remount, navigation flicker, etc.) would otherwise see the\n // backend status flipped to 'complete', clear the cache, and POST\n // a duplicate session that would then be /process'd with the\n // original PaymentIntent — double-charging the buyer.\n markSessionRecentlyCompleted(effectiveSessionId);\n setOverlayStatus('success');\n // Clear any pending paypal_direct_required retry — process\n // succeeded, so the re-bound retry button is no longer needed.\n setPaypalDirectRetry(null);\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));\n onComplete?.({\n status: 'succeeded',\n paymentIntentId: tokenizedBody.threeDSecureActionResultTokenId,\n paymentMethodId: resolvedCompletionPaymentMethodId,\n checkoutMethod: tokenizedBody.isPaypal ? 'paypal' : 'card',\n });\n return;\n }\n\n const json = await response.json().catch(() => null) as Record<string, unknown> | null;\n\n if (json?.type === '3ds_required') {\n const secret = json['threeDSecureToken'] as string;\n if (!flopay || !secret) {\n setOverlayStatus('error');\n updateError('3DS authentication required but no token provided.');\n return;\n }\n\n setIs3DSActive(true);\n try {\n // Only include AVS fields that are currently visible for the selected country.\n const retryBillingAddress: Record<string, string> = {};\n const retryCC = selectedCountryRef.current;\n const retryCountry = enableAVS ? retryCC : effectiveAccount.country;\n if (retryCountry) retryBillingAddress['country'] = retryCountry;\n if (avsConfig && isAVSFieldVisible(avsConfig.postal_code, retryCC) && zipCodeRef.current.trim()) {\n retryBillingAddress['postal_code'] = zipCodeRef.current.trim();\n } else if (!avsConfig && effectiveAccount.zip) {\n retryBillingAddress['postal_code'] = effectiveAccount.zip;\n }\n if (avsConfig && isAVSFieldVisible(avsConfig.address_line_1, retryCC) && addressLine1Ref.current.trim()) retryBillingAddress['line1'] = addressLine1Ref.current.trim();\n if (avsConfig && isAVSFieldVisible(avsConfig.address_line_2, retryCC) && addressLine2Ref.current.trim()) retryBillingAddress['line2'] = addressLine2Ref.current.trim();\n if (avsConfig && isAVSFieldVisible(avsConfig.city, retryCC) && cityRef.current.trim()) retryBillingAddress['city'] = cityRef.current.trim();\n if (avsConfig && isAVSFieldVisible(avsConfig.state, retryCC) && stateRef.current.trim()) {\n retryBillingAddress['state'] = stateRef.current.trim();\n } else if (\n avsConfig\n && isAVSFieldVisible(avsConfig.address_line_1, retryCC)\n && !isAVSFieldVisible(avsConfig.state, retryCC)\n && isAVSFieldVisible(avsConfig.postal_code, retryCC)\n ) {\n const derivedRetryState = getStateFromPostalCode(retryCC, zipCodeRef.current.trim());\n if (derivedRetryState) retryBillingAddress['state'] = derivedRetryState;\n }\n const result = await flopay.confirmPayment({\n clientSecret: secret,\n returnUrl: window.location.href,\n billingDetails: {\n ...(effectiveAccount.email ? { email: effectiveAccount.email } : {}),\n ...(fullName.trim() ? { name: fullName.trim() } : {}),\n ...(Object.keys(retryBillingAddress).length > 0 ? { address: retryBillingAddress } : {}),\n },\n });\n\n if (result.error) {\n setOverlayStatus('error');\n updateError(result.error.message);\n onError?.(result.error);\n emitDecline('card', result.error);\n return;\n }\n\n if (result.status === 'succeeded' || result.status === 'processing') {\n // Allow re-entry for 3DS retry\n processingRef.current = false;\n await processPaymentInternal({\n id: result.paymentIntentId,\n type: 'card',\n threeDSecureActionResultTokenId: result.paymentIntentId,\n }, {\n // Preserve the session/nonce/account overrides resolved\n // above so the retry talks to the same (possibly\n // freshly bootstrapped) session as the original attempt.\n accountPatch: overrides?.accountPatch,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n completionPaymentMethodId: resolvedCompletionPaymentMethodId,\n });\n }\n } finally {\n setIs3DSActive(false);\n }\n return;\n }\n\n // PayPal redirect required — backend created a PI that needs PayPal authorization.\n // Confirm the payment which triggers redirect to PayPal. On return, the\n // PayPalButtonInner's resume handler picks up the payment_intent URL params.\n if (json?.type === 'paypal_redirect_required') {\n const secret = json['threeDSecureToken'] as string;\n const savedPmId = (json['paymentMethodId'] as string) || tokenizedBody.id || '';\n if (!flopay || !secret) {\n setOverlayStatus('error');\n updateError('PayPal authorization required but no token provided.');\n return;\n }\n\n try {\n // PayPal PaymentIntents live on the PayPal Stripe account — route\n // the confirmation through the PayPal Stripe instance.\n const paypalStripe = paypalFlopay?.getRawProvider() as Stripe | null;\n if (!paypalStripe) {\n updateError('PayPal is not available.');\n return;\n }\n\n const confirmParams: Record<string, unknown> = {\n return_url: window.location.href,\n };\n if (savedPmId) {\n confirmParams['payment_method'] = savedPmId;\n }\n\n const { error: confirmError } = await paypalStripe.confirmPayment({\n clientSecret: secret,\n confirmParams: confirmParams as { return_url: string },\n redirect: 'if_required',\n });\n\n if (confirmError) {\n setOverlayStatus('error');\n const message = confirmError.message ?? 'PayPal payment failed.';\n updateError(message);\n emitDecline('paypal', message, {\n code: confirmError.code,\n });\n }\n } catch (err) {\n setOverlayStatus('error');\n updateError(err instanceof Error ? err.message : 'PayPal authorization failed.');\n }\n return;\n }\n\n // Direct PayPal retry — backend created a fresh PayPal order\n // (typically after a failed inline-session reuse) and wants the SDK\n // to relaunch the PayPal popup against that order id. Re-binds the\n // existing DirectPayPalButton via `paypalDirectRetry` state; the\n // buyer clicks the same button again, PayPal opens with the new\n // order, and onApprove fires another /process call. Bounded to 2\n // retries so a misconfigured backend can't trap the buyer.\n if (json?.type === 'paypal_direct_required') {\n const orderId = json['orderId'] as string | undefined;\n if (!orderId) {\n setOverlayStatus('error');\n updateError('PayPal retry required but no order id provided.');\n return;\n }\n const prevAttempts = paypalDirectRetryRef.current?.attempts ?? 0;\n if (prevAttempts >= 2) {\n setOverlayStatus('error');\n updateError('PayPal payment could not be completed after multiple attempts.');\n emitDecline('paypal', 'paypal_direct_required retry limit exceeded');\n return;\n }\n setPaypalDirectRetry({ orderId, attempts: prevAttempts + 1 });\n // Hide the processing overlay so the buyer can see and act on the\n // re-bound PayPal button. Don't emitDecline — this isn't a decline.\n setOverlayStatus(null);\n return;\n }\n\n setOverlayStatus('error');\n const message = (json?.message as string) ?? 'Payment failed. Please try again.';\n updateError(message);\n emitDecline(tokenizedBody.isPaypal ? 'paypal' : 'card', message, {\n code: (json?.code ?? json?.gatewayErrorCode) as string | undefined,\n declineCode: (json?.declineCode ?? json?.gatewayDeclineReason) as string | undefined,\n });\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n } catch (err) {\n setOverlayStatus('error');\n updateError(err instanceof Error ? err.message : 'An unexpected error occurred');\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n } finally {\n setProcessing(false);\n setOverlayStatus(null);\n processingRef.current = false;\n }\n },\n [baseUrl, sessionId, nonce, resolvedAccount, fullName, chv, flopay, paypalFlopay, onComplete, onError, updateError, emitDecline],\n );\n\n const dispatchTokenizedBody = useCallback(\n (tokenizedBody: TokenizedBody, overrides?: TokenizedBodyOverrides) => {\n if (onTokenizedBody) {\n onTokenizedBody(tokenizedBody);\n } else {\n processPaymentInternal(tokenizedBody, overrides);\n }\n },\n [onTokenizedBody, processPaymentInternal],\n );\n\n // ── Imperative 3DS handler ──\n\n useImperativeHandle(innerRef, () => ({\n async handleNextAction(secret: string) {\n if (!flopay) return;\n\n setIs3DSActive(true);\n try {\n const result = await flopay.confirmPayment({\n clientSecret: secret,\n returnUrl: window.location.href,\n });\n\n if (result.error) {\n updateError(result.error.message);\n onError?.(result.error);\n emitDecline('card', result.error);\n } else if (result.status === 'succeeded' || result.status === 'processing') {\n dispatchTokenizedBody({\n id: result.paymentIntentId,\n type: 'card',\n threeDSecureActionResultTokenId: result.paymentIntentId,\n });\n }\n } catch (err) {\n updateError(err instanceof Error ? err.message : 'Payment authentication failed.');\n } finally {\n setIs3DSActive(false);\n }\n },\n }), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);\n\n // ── Stripe resume (Cash App Pay / Klarna / iDEAL / Bancontact / …) ──\n //\n // Method-agnostic handler for the buyer returning from any Stripe\n // redirect-based payment method. The PaymentElement region writes its\n // tokenization state to `STRIPE_RESUME_KEY` (or the legacy\n // `flopay_wallet_resume` for back-compat with old SDK builds) *before*\n // calling `confirmPayment`, then we verify the PI status on return.\n //\n // Two gates before we hand off to /process — both required to avoid the\n // class of bugs where the SDK marches to /success on an uncharged PI:\n //\n // 1. **URL params must be present.** Stripe redirects buyers back with\n // `payment_intent` / `payment_intent_client_secret` / `redirect_status`\n // on the query string. If those are missing — the buyer hit back, the\n // auth tab was closed, or this is just a normal `/theme` mount — we\n // do nothing, even if `STRIPE_RESUME_KEY` is still in localStorage.\n //\n // 2. **Stripe-side PI status must be successful.** We `retrievePaymentIntent`\n // and only dispatch when the actual status is one of\n // `succeeded` / `requires_capture` / `processing`. A `redirect_status`\n // of `failed`, a buyer who closed the popup without approving (PI stuck\n // at `requires_action`), or a canceled PI all route to `onDecline`.\n //\n // PayPal-direct uses its own resume effect (`PayPalButtonInner`); this\n // handler intentionally excludes the PayPal Stripe sub-account flow to\n // avoid double-dispatch.\n const stripeResumeAttemptedRef = useRef(false);\n useEffect(() => {\n if (typeof window === 'undefined' || stripeResumeAttemptedRef.current) return;\n\n const params = new URLSearchParams(window.location.search);\n const paymentIntentId = params.get('payment_intent');\n const clientSecret = params.get('payment_intent_client_secret');\n const redirectStatus = params.get('redirect_status');\n\n // No `payment_intent` URL param = buyer didn't actually return from a\n // Stripe redirect. Skip even if `STRIPE_RESUME_KEY` is in localStorage:\n // that key is set *before* confirmPayment, so it lives in localStorage\n // between click and authorization. A page reload, navigation, or close\n // of the auth tab would otherwise replay it as a phantom success.\n if (!paymentIntentId || !clientSecret) return;\n\n const readPayload = (key: string) => {\n const raw = localStorage.getItem(key);\n if (!raw) return null;\n try {\n return JSON.parse(raw) as {\n clientSecret?: string;\n sessionId?: string;\n nonce?: string;\n accountPatch?: InlineSessionPatch['account'];\n paymentIntentId?: string;\n paymentMethodId?: string;\n paymentMethodType?: string;\n gateway?: string;\n tokenType?: string;\n tokenId?: string;\n status?: string;\n } | null;\n } catch {\n localStorage.removeItem(key);\n return null;\n }\n };\n\n const payload =\n readPayload(STRIPE_RESUME_KEY) ?? readPayload(LEGACY_WALLET_RESUME_KEY);\n\n // Recover the effective session / nonce / accountPatch persisted by the\n // APM confirm sites before the redirect. Without this, an inline-session\n // bootstrap done inside `runBeforeButtonClick` (which set its own\n // sessionId + nonce) is lost — the post-reload props expose the freshly\n // re-bootstrapped base session — and /process would 401 against the\n // wrong nonce. Mirrors the PayPal resume contract at ~L609-635.\n //\n // Gate on `clientSecret` matching this PI so a stale entry from an\n // abandoned earlier attempt can't retarget the current resume. Legacy\n // payloads (no `clientSecret`) keep the original session-match guard so\n // an old SDK build's writer cannot dispatch against the wrong session.\n let persistedOverrides: TokenizedBodyOverrides | undefined;\n if (payload?.clientSecret) {\n if (payload.clientSecret !== clientSecret) return;\n persistedOverrides = {\n ...(payload.accountPatch ? { accountPatch: payload.accountPatch } : {}),\n ...(payload.sessionId ? { sessionId: payload.sessionId } : {}),\n ...(payload.nonce ? { nonce: payload.nonce } : {}),\n };\n } else if (payload?.sessionId && payload.sessionId !== sessionId) {\n return;\n }\n\n stripeResumeAttemptedRef.current = true;\n localStorage.removeItem(STRIPE_RESUME_KEY);\n localStorage.removeItem(LEGACY_WALLET_RESUME_KEY);\n\n // Strip Stripe's redirect params synchronously before any async work, so\n // a remount that races our async retrieval can't re-enter this effect\n // for the same PI.\n const cleanedUrl = new URL(window.location.href);\n cleanedUrl.searchParams.delete('payment_intent');\n cleanedUrl.searchParams.delete('payment_intent_client_secret');\n cleanedUrl.searchParams.delete('redirect_status');\n window.history.replaceState({}, '', cleanedUrl.toString());\n\n const paymentMethodType =\n payload?.paymentMethodType ?? payload?.tokenType ?? 'card';\n const declineMethod: CheckoutButtonMethod = 'card';\n\n (async () => {\n const rawProvider = flopay?.getRawProvider() as Stripe | null | undefined;\n if (!rawProvider) {\n const message = 'Payment is not available — please refresh and try again.';\n updateError(message);\n emitDecline(declineMethod, message);\n return;\n }\n\n if (redirectStatus === 'failed') {\n const message = 'Payment was declined. Please try again.';\n updateError(message);\n emitDecline(declineMethod, message);\n return;\n }\n\n const { paymentIntent, error } = await rawProvider.retrievePaymentIntent(clientSecret);\n if (error) {\n const message = error.message ?? 'Failed to retrieve payment status.';\n updateError(message);\n emitDecline(declineMethod, message, { code: error.code });\n return;\n }\n\n const piStatus = paymentIntent?.status;\n const successful = piStatus === 'succeeded' || piStatus === 'requires_capture' || piStatus === 'processing';\n if (!paymentIntent || !successful) {\n const message = piStatus === 'canceled'\n ? 'Payment was canceled.'\n : 'Payment was not completed. Please try again.';\n updateError(message);\n emitDecline(declineMethod, message, { code: piStatus ?? 'missing_payment_intent' });\n return;\n }\n\n const resolvedPmId = typeof paymentIntent.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent.payment_method?.id;\n\n dispatchTokenizedBody({\n id: resolvedPmId ?? payload?.paymentMethodId ?? payload?.tokenId ?? paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n gateway: (payload?.gateway as 'stripe' | 'paypal' | undefined) ?? 'stripe',\n paymentMethodType,\n }, persistedOverrides);\n })();\n }, [sessionId, dispatchTokenizedBody, flopay, updateError, emitDecline]);\n\n // ── Card submit ──\n\n const handleSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault();\n if (!flopay || !elements || isSubmitting || processingRef.current) return;\n // Vault path: the hosted widget owns submission + the charge + 3DS, so\n // the SDK renders no submit button here. Guard in case a host form wires\n // its own submit (TeamFloPay/backend#823, Model A).\n if (vaultActive) return;\n\n if (layout !== 'buttons') {\n onButtonClick?.('card');\n }\n setProcessing(true);\n setOverlayStatus('processing');\n updateError(null);\n\n // Track whether we handed off to processPaymentInternal (which manages its own overlay)\n let handedOff = false;\n\n try {\n // Matches checkout/StripeCardForm exactly:\n // 1. createPaymentMethod → 2. createPaymentIntent → 3. confirmCardPayment → 4. onTokenizedBody\n\n // 0. Validate AVS fields — all visible fields are required (except address_line_2).\n // Read from refs for the latest value — state may not have flushed\n // if the user typed and clicked submit in quick succession.\n if (avsConfig) {\n const country = selectedCountryRef.current;\n // Read from refs (not state) and reuse the same pure state helper as\n // the live `postalCodeState` memo so the submit gate and the inline\n // hint apply identical rules. Supported locale: postcode required\n // *and* format-checked (mirrors backend #887) so a malformed value is\n // caught before the card is tokenized. Unsupported / no-postcode\n // locale: optional (`empty`/`malformed` stay false, both skipped).\n const postal = computePostalCodeState(\n country,\n zipCodeRef.current,\n isAVSFieldVisible(avsConfig.postal_code, country),\n );\n if (postal.empty) {\n // Mark the field touched so `showPostcodeError` reveals the inline\n // per-field treatment (red border, aria-invalid, inline message) on\n // this first submit — a buyer may click submit without ever blurring\n // the postcode (pre-filled, or tab/click straight to pay). The vault\n // path flips `hasAttemptedSubmit` from the widget's `submitting`\n // event, but that never fires on the Stripe path.\n setZipTouched(true);\n updateError(getPostalCodeLabel(country) + ' is required');\n return;\n }\n if (postal.malformed) {\n setZipTouched(true);\n updateError(malformedPostcodeMessage(country));\n return;\n }\n if (isAVSFieldVisible(avsConfig.address_line_1, country) && !addressLine1Ref.current.trim()) {\n updateError('Street address is required');\n return;\n }\n if (isAVSFieldVisible(avsConfig.city, country) && !cityRef.current.trim()) {\n updateError('City is required');\n return;\n }\n if (isAVSFieldVisible(avsConfig.state, country) && !stateRef.current.trim()) {\n updateError(getStateLabel(country) + ' is required');\n return;\n }\n }\n\n // 1. Validate elements (Stripe card path only — vault hosted fields\n // validate inside the PCI boundary on submit()).\n if (!vaultActive) {\n const submitResult = await flopay.submitElements();\n if (submitResult.error) {\n updateError(submitResult.error.message);\n onError?.(submitResult.error);\n return;\n }\n }\n\n // 2. Build AVS billing_details (shared by both card paths).\n // Only include fields that are currently visible for the selected country.\n // Only include fields that are currently visible for the selected country.\n const billingAddress: Record<string, string> = {};\n const cc = selectedCountryRef.current;\n const avsCountry = enableAVS ? cc : resolvedAccount.country;\n if (avsCountry) billingAddress['country'] = avsCountry;\n if (avsConfig && isAVSFieldVisible(avsConfig.postal_code, cc) && zipCodeRef.current.trim()) {\n billingAddress['postal_code'] = zipCodeRef.current.trim();\n } else if (!avsConfig && resolvedAccount.zip) {\n billingAddress['postal_code'] = resolvedAccount.zip;\n }\n if (avsConfig && isAVSFieldVisible(avsConfig.address_line_1, cc) && addressLine1Ref.current.trim()) billingAddress['line1'] = addressLine1Ref.current.trim();\n if (avsConfig && isAVSFieldVisible(avsConfig.address_line_2, cc) && addressLine2Ref.current.trim()) billingAddress['line2'] = addressLine2Ref.current.trim();\n if (avsConfig && isAVSFieldVisible(avsConfig.city, cc) && cityRef.current.trim()) billingAddress['city'] = cityRef.current.trim();\n if (avsConfig && isAVSFieldVisible(avsConfig.state, cc) && stateRef.current.trim()) {\n billingAddress['state'] = stateRef.current.trim();\n } else if (\n avsConfig\n && isAVSFieldVisible(avsConfig.address_line_1, cc)\n && !isAVSFieldVisible(avsConfig.state, cc)\n && isAVSFieldVisible(avsConfig.postal_code, cc)\n ) {\n const derivedSubmitState = getStateFromPostalCode(cc, zipCodeRef.current.trim());\n if (derivedSubmitState) billingAddress['state'] = derivedSubmitState;\n }\n\n const billingDetails = {\n ...(resolvedAccount.email ? { email: resolvedAccount.email } : {}),\n ...(fullName.trim() ? { name: fullName.trim() } : {}),\n ...(Object.keys(billingAddress).length > 0 ? { address: billingAddress } : {}),\n };\n if (!sessionId || !resolvedAccount.email) {\n throw new FloPayError('Missing sessionId or email', 'validation_error');\n }\n\n // The vault path has no SDK submit button — the hosted widget owns\n // submission, the charge, 3DS, and the result (TeamFloPay/backend#823).\n // `handleSubmit` therefore only runs the Stripe card path. The early\n // `if (vaultActive) return` guard above is the belt-and-braces stop.\n {\n // ── Stripe card path (legacy) ──\n const pmResult = await flopay.createPaymentMethod(billingDetails);\n if (pmResult.error || !pmResult.paymentMethodId) {\n updateError(pmResult.error?.message ?? 'Failed to create payment method.');\n return;\n }\n\n // 3. Create PaymentIntent via billing API (backend uses capture_method: 'manual')\n const intentHeaders: Record<string, string> = { 'Content-Type': 'application/json' };\n if (nonce) intentHeaders['x-checkout-session-token'] = nonce;\n const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {\n method: 'POST',\n headers: intentHeaders,\n body: JSON.stringify({\n sessionId,\n email: resolvedAccount.email,\n paymentMethodType: pmResult.paymentMethodId,\n isPaypal: false,\n }),\n });\n\n if (!intentResponse.ok) {\n const intentError = await buildFloPayApiErrorFromResponse(\n intentResponse,\n 'Failed to create payment intent',\n );\n setOverlayStatus('error');\n updateError(intentError.message);\n onError?.(intentError);\n emitDecline('card', intentError);\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n return;\n }\n\n const intentJson = await intentResponse.json() as { data?: { id?: string } };\n const intentClientSecret = intentJson.data?.id;\n if (!intentClientSecret) throw new FloPayError('No client_secret in payment intent response', 'api_error');\n\n // 4. Confirm card payment (handles 3DS automatically via Stripe)\n const confirmResult = await flopay.confirmCardPayment({\n clientSecret: intentClientSecret,\n paymentMethodId: pmResult.paymentMethodId,\n });\n\n if (confirmResult.error) {\n setOverlayStatus('error');\n updateError(confirmResult.error.message);\n onError?.(confirmResult.error);\n emitDecline('card', confirmResult.error);\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n return;\n }\n\n const rawProvider = typeof flopay.getRawProvider === 'function' ? flopay.getRawProvider() : null;\n const confirmedPaymentIntent = await retrievePaymentIntentFromProvider(\n rawProvider,\n intentClientSecret,\n );\n const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;\n const paymentMethodId =\n confirmResult.paymentMethodId\n ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent)\n ?? pmResult.paymentMethodId;\n\n if (!paymentIntentId) {\n const error = new FloPayError('No payment intent returned after confirmation.', 'api_error');\n setOverlayStatus('error');\n updateError(error.message);\n onError?.(error);\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n return;\n }\n\n // 5. Send PM + PI to processPaymentInternal (or parent via onTokenizedBody)\n // In self-contained mode, processPaymentInternal manages overlay lifecycle.\n handedOff = isSelfContained;\n dispatchTokenizedBody({\n id: paymentMethodId,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntentId,\n originalPaymentMethodId: pmResult.paymentMethodId,\n });\n }\n } catch (err) {\n setOverlayStatus('error');\n updateError(err instanceof Error ? err.message : 'An unexpected error occurred');\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n } finally {\n if (!handedOff) {\n setProcessing(false);\n setOverlayStatus(null);\n }\n }\n },\n [flopay, elements, isSubmitting, sessionId, nonce, resolvedAccount.email, baseUrl, isSelfContained, vaultActive, dispatchTokenizedBody, onButtonClick, onError, updateError, emitDecline, layout],\n );\n\n // The vault (pcivault) card path runs no Stripe.js, so it must not wait on a\n // Stripe Elements instance — gating it on `elements` would strand the hosted\n // widget behind the loading state. `vaultActive` already requires `flopay`.\n const isReady = flopay !== null && (vaultActive || elements !== null);\n\n if (!isReady) {\n return <div data-testid=\"flopay-loading\" aria-busy=\"true\">Loading payment form...</div>;\n }\n\n const isButtons = layout === 'buttons';\n // Three-tier fallback for visual styling:\n // 1. `bStyles` (resolved from `buttonsTheme` + `buttonsStyles` override) —\n // the explicit, coherent bundle. Wins when present.\n // 2. `appearance.variables` from FloPayProvider — covers consumers who\n // pass only the Stripe-side appearance and still expect the React\n // wrapper / submit / inputs to recolor.\n // 3. Hardcoded layout defaults — back-compat for callers passing neither.\n // This is what makes `<FloPayCheckout appearance={THEMES['glass-dark'].appearance} />`\n // produce a visible recolor even before the demo forwards the buttonsLayout half.\n const appearanceVars = appearance?.variables;\n // `appearance.colorBackground` is, in Stripe terms, the *input* surface — not\n // the outer FloPay wrapper. Treat the SDK's default white as \"consumer did\n // not theme the wrapper\" so the historic `#EDEDFF` FloPay tint stays put on\n // the classic preset. Themed bundles supply non-white backgrounds and still\n // flow through to the wrapper as expected.\n const SDK_DEFAULT_WHITES = new Set(['#FFFFFF', '#ffffff', '#fff', '#FFF', 'white']);\n const appearanceColorBg = appearanceVars?.colorBackground;\n const themedWrapperBg =\n appearanceColorBg && !SDK_DEFAULT_WHITES.has(appearanceColorBg) ? appearanceColorBg : undefined;\n const resolvedBorder = bStyles.cardInputBorder ?? (isButtons ? '#e5e7eb' : '#A4A4FF');\n // After the first submit attempt, ring AVS fields that are (re)incomplete —\n // bridges the gap with the widget's own post-submit invalid-card outlines.\n const resolvedDangerColor = appearanceVars?.colorDanger ?? '#dc2626';\n const avsBorderColor = (fieldInvalid: boolean): string =>\n hasAttemptedSubmit && fieldInvalid ? resolvedDangerColor : resolvedBorder;\n // A malformed *or* blank-but-required postcode blocks the vault submit, so\n // `hasAttemptedSubmit` can never flip to reveal it — surface the outline +\n // inline message once the field is blurred (or a submit was attempted) on\n // either card path. `empty` and `malformed` are mutually exclusive, so the\n // inline copy below can branch cleanly between the required/format variants.\n const showPostcodeError =\n (postalCodeState.malformed || postalCodeState.empty) && (zipTouched || hasAttemptedSubmit);\n const zipBorderColor = showPostcodeError\n ? resolvedDangerColor\n : avsBorderColor(invalidAvsFields.zip);\n const cardBg =\n (bStyles.cardFormContainer?.backgroundColor as string)\n ?? themedWrapperBg\n ?? (isButtons ? 'white' : '#EDEDFF');\n const cardInputBg =\n bStyles.cardInputBackground\n ?? appearanceVars?.colorBackground\n ?? 'white';\n const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);\n const hideTitle = isEmptySlotContent(cardTitleContent);\n const nameInputOverrides = bStyles.nameInput;\n const resolvedInputFontSize = bStyles.cardInputFontSize\n ?? toCssSize(nameInputOverrides?.fontSize)\n ?? appearanceVars?.fontSizeBase\n ?? '16px';\n const resolvedInputFontFamily = typeof nameInputOverrides?.fontFamily === 'string'\n ? nameInputOverrides.fontFamily\n : (appearanceVars?.fontFamily ?? 'Poppins, sans-serif');\n const resolvedInputFontWeight = toCssWeight(nameInputOverrides?.fontWeight) ?? 400;\n const resolvedInputColor = bStyles.cardInputColor\n ?? (typeof nameInputOverrides?.color === 'string' ? nameInputOverrides.color : undefined)\n ?? appearanceVars?.colorText\n ?? '#262833';\n const resolvedPlaceholderColor = bStyles.cardInputPlaceholderColor ?? '#9ca3af';\n const resolvedBorderRadius = appearanceVars?.borderRadius ?? '8px';\n // Button corner radius: the `borderRadius` appearance prop takes precedence\n // over a theme bundle's `cardButton.borderRadius`, then the 8px default.\n const buttonBorderRadius =\n (appearanceVars?.borderRadius as string | number | undefined)\n ?? (bStyles.cardButton?.borderRadius as string | number | undefined)\n ?? resolvedBorderRadius;\n // `colorPrimary` drives the submit button background when no buttonsStyles\n // override is supplied. Default keeps the historic FloPay indigo.\n const resolvedPrimaryColor = appearanceVars?.colorPrimary ?? '#4A49FF';\n // Hover background for flo buttons: explicit `colorPrimaryHover` wins, else a\n // slightly darker shade of the primary so every theme gets a real hover.\n const resolvedPrimaryHoverColor = appearanceVars?.colorPrimaryHover ?? darkenHex(resolvedPrimaryColor, 0.12);\n const resolvedTitleColor = appearanceVars?.colorText ?? '#262833';\n const sharedInputTypography: React.CSSProperties = {\n fontSize: resolvedInputFontSize,\n fontFamily: resolvedInputFontFamily,\n fontWeight: resolvedInputFontWeight,\n color: resolvedInputColor,\n WebkitFontSmoothing: 'antialiased',\n MozOsxFontSmoothing: 'grayscale',\n };\n const sharedInputPlaceholderVars = {\n '--flopay-input-placeholder-color': resolvedPlaceholderColor,\n '--flopay-input-font-size': resolvedInputFontSize,\n '--flopay-input-font-family': resolvedInputFontFamily,\n '--flopay-input-font-weight': String(resolvedInputFontWeight),\n } as React.CSSProperties;\n\n // Stripe Element style — keeps the iframe typography aligned with the plain text inputs.\n const stripeElementStyle = {\n style: {\n base: {\n ...sharedInputTypography,\n fontSmoothing: 'antialiased',\n '::placeholder': {\n color: resolvedPlaceholderColor,\n fontSize: resolvedInputFontSize,\n fontFamily: resolvedInputFontFamily,\n fontWeight: resolvedInputFontWeight,\n },\n },\n invalid: { color: '#ef4444' },\n },\n };\n\n // ── Card fields block (shared between both layouts) ──\n const containerOverrides = (bStyles.cardFormContainer ?? {}) as React.CSSProperties;\n const containerPadding = containerOverrides.padding ?? (isButtons ? '0' : '1rem');\n const containerRadius = containerOverrides.borderRadius ?? resolvedBorderRadius;\n // The hosted vault widget (or its loading skeleton). Extracted so it can be\n // rendered *after* the AVS block on the vault path — the AVS fields live in\n // the merchant DOM and must precede the widget iframe in the DOM so the tab\n // order runs AVS (top-left→bottom-right) → card fields, not the reverse.\n const vaultCardFieldsNode =\n cardCapture && vaultMount ? (\n <VaultCardFields\n capture={cardCapture}\n html={vaultMount.html}\n messageToken={vaultMount.messageToken}\n expectedOrigin={vaultMount.expectedOrigin}\n theme={vaultThemeColors}\n onReady={() => {\n setFormReady(true);\n // With AVS above the widget, the widget suppresses its own card-number\n // autofocus; the host moves the cursor to the first AVS field\n // (top-left). pcd_form still focuses its card number at an unpredictable\n // time, so rather than race it we bounce the first focus that lands on\n // the vault iframe over to the first AVS field (one-shot, with a\n // fallback in case the iframe never grabs focus).\n if (!avsConfig || typeof document === 'undefined') return;\n const focusFirstAvs = () => {\n const block = document.querySelector('[data-testid=\"flopay-avs-fields\"]');\n const first = block?.querySelector(\n 'input:not([disabled]), select:not([disabled])',\n ) as HTMLElement | null;\n first?.focus();\n };\n // Move the cursor to the first AVS field now. pcd_form loads from a CDN\n // and auto-focuses its card number at an unpredictable later time, so we\n // also watch for focus landing on the vault iframe and bounce it back to\n // the AVS — one-shot, so a later genuine user click on the card isn't\n // hijacked. Focusing an AVS field sticks (pcd_form doesn't re-grab).\n focusFirstAvs();\n let tries = 0;\n const timer = window.setInterval(() => {\n tries += 1;\n const active = document.activeElement;\n const onIframe =\n !!active && active.tagName === 'IFRAME' && active.id === 'flopay_vault_form_iframe';\n if (onIframe) {\n focusFirstAvs();\n window.clearInterval(timer);\n } else if (tries >= 50) {\n window.clearInterval(timer);\n }\n }, 100);\n }}\n onError={(message) => updateError(message)}\n onValidation={(message) => {\n updateError(message);\n // A non-empty inline-validation message after submit means pcd_form\n // rejected the card client-side and won't charge (no terminal event) —\n // drop the processing overlay so the buyer can fix the field. During\n // typing the overlay isn't up, so this is a no-op.\n if (message) setOverlayStatus(null);\n }}\n />\n ) : (\n <div\n data-testid=\"flopay-vault-loading\"\n style={{\n minHeight: 120, display: 'flex', alignItems: 'center', justifyContent: 'center',\n color: '#6b7280', fontSize: 14,\n }}\n >\n Loading secure card form…\n </div>\n );\n const cardFormBlock = (\n <div style={{\n backgroundColor: cardBg, borderRadius: containerRadius,\n ...containerOverrides,\n padding: containerPadding,\n ...sharedInputPlaceholderVars,\n // Flex column (BOTH layouts, so default and buttons>card never diverge) so\n // AVS can be ordered above the vault widget — its submit lives inside the\n // iframe, so AVS can't sit between fields and button; it goes above the\n // card form instead of after the button.\n display: 'flex', flexDirection: 'column',\n }}>\n <style>{`\n .flopay-shared-input::placeholder {\n color: var(--flopay-input-placeholder-color);\n opacity: 1;\n font-size: var(--flopay-input-font-size);\n font-family: var(--flopay-input-font-family);\n font-weight: var(--flopay-input-font-weight);\n }\n `}</style>\n {/* Header: back button + title on same row (buttons layout) */}\n {isButtons && showCardForm && (\n <div style={{\n display: 'flex', alignItems: 'center', padding: '0.75rem 0 0.625rem',\n // Keep the header on top when AVS is ordered above the card on vault.\n order: vaultActive ? -2 : 0,\n }}>\n <button\n type=\"button\"\n onClick={collapseToButtons}\n style={{\n display: 'inline-flex', alignItems: 'center', gap: hideBackButtonLabel ? 0 : '0.5rem',\n background: 'none', border: 'none', cursor: 'pointer',\n color: '#4b5563', fontSize: bStyles.backButtonFontSize ?? '0.85rem', fontWeight: 500,\n padding: 0, transition: 'color 0.15s', flexShrink: 0,\n ...bStyles.backButton as React.CSSProperties,\n }}\n aria-label=\"Back to payment methods\"\n >\n <span style={{\n display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: '50%',\n backgroundColor: '#f3f4f6', transition: 'background-color 0.15s',\n ...bStyles.backButtonIcon as React.CSSProperties,\n }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n </span>\n <BackButtonContentSlot content={cardBackButtonContent} />\n </button>\n {hideTitle ? (\n <div style={{ flex: 1 }} />\n ) : (\n <div style={{\n flex: 1, textAlign: 'center', fontWeight: 600,\n fontSize: bStyles.titleFontSize ?? '1.05rem',\n color: '#262833', paddingRight: 80,\n ...bStyles.title as React.CSSProperties,\n }}>\n <TitleContentSlot content={cardTitleContent} />\n </div>\n )}\n </div>\n )}\n\n {/* Title (default layout only) */}\n {!isButtons && !hideTitle && (\n <div style={{\n textAlign: 'center', fontWeight: 600, fontSize: '1.1rem', padding: '0.5rem 0',\n color: resolvedTitleColor,\n // Keep the title at the very top on the vault path. The card-form slot\n // (-2) and AVS block (-1) are ordered below it but above the card form.\n order: vaultActive ? -3 : 0,\n ...(bStyles.title as React.CSSProperties | undefined),\n }}>\n <TitleContentSlot content={cardTitleContent} />\n </div>\n )}\n\n {/* Card fields — backend-rendered vault widget (when the session\n advertises the `pcivault` gateway) or Stripe's embedded card elements\n (legacy path). The vault widget owns its own fields, submit button,\n charge, and 3DS (TeamFloPay/backend#823, Model A). */}\n {/* Stripe-path card fields only. The vault widget renders below the AVS\n block (see `vaultCardFieldsNode`) so AVS precedes it in the DOM/tab\n order. */}\n {!vaultActive && (\n <>\n {/* Card Number */}\n <div style={{\n backgroundColor: cardInputBg, border: `1px solid ${resolvedBorder}`,\n borderTopLeftRadius: resolvedBorderRadius, borderTopRightRadius: resolvedBorderRadius, padding: '10px',\n }}>\n <CardNumberElement onReady={() => setFormReady(true)} options={stripeElementStyle} />\n </div>\n\n {/* Expiry + CVC */}\n <div style={{ display: 'flex' }}>\n <div style={{\n flex: 1, backgroundColor: cardInputBg,\n // Longhand only — mixing `border` shorthand with per-side\n // overrides triggers React's \"shorthand vs longhand\" warning\n // because render order isn't deterministic.\n borderTop: 'none', borderRight: 'none',\n borderBottom: `1px solid ${resolvedBorder}`,\n borderLeft: `1px solid ${resolvedBorder}`,\n borderBottomLeftRadius: resolvedBorderRadius, padding: '10px',\n }}>\n <CardExpiryElement options={stripeElementStyle} />\n </div>\n <div style={{\n flex: 1, backgroundColor: cardInputBg,\n borderTop: 'none',\n borderRight: `1px solid ${resolvedBorder}`,\n borderBottom: `1px solid ${resolvedBorder}`,\n borderLeft: `1px solid ${resolvedBorder}`,\n borderBottomRightRadius: resolvedBorderRadius, padding: '10px',\n }}>\n <CardCvcElement options={stripeElementStyle} />\n </div>\n </div>\n </>\n )}\n\n {/* Full Name — Stripe path only. The vault widget collects the\n cardholder name inside its own PCI boundary. */}\n {!vaultActive && (\n <div style={{\n backgroundColor: cardInputBg, border: `1px solid ${resolvedBorder}`,\n borderRadius: resolvedBorderRadius, marginTop: '0.5rem', padding: '10px',\n }}>\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-cc-name\"\n name=\"cc-name\"\n placeholder=\"Full Name on Card\"\n autoComplete=\"cc-name\"\n value={fullName}\n onChange={(e) => handleNameChange(e.target.value)}\n disabled={isSubmitting}\n required\n style={{\n width: '100%', border: 'none', outline: 'none', background: 'transparent',\n ...sharedInputTypography,\n ...(isButtons && bStyles.nameInput ? bStyles.nameInput as React.CSSProperties : {}),\n }}\n />\n </div>\n )}\n\n {/* AVS Address Fields — rendered on BOTH the Stripe and vault paths.\n Addresses aren't PCI-sensitive, so the SDK collects them in the\n merchant DOM and the vault `submitting` handler PATCHes them onto the\n account snapshot before the charge mints the payment method. On the\n Stripe path they sit after the card fields (before the submit button);\n on the vault path the submit lives inside the iframe, so they're\n ordered above the card form via flex `order`. */}\n {avsConfig && (\n <div style={{ order: vaultActive ? -1 : 0 }} data-testid=\"flopay-avs-fields\">\n {(() => {\n const cc = selectedCountry;\n // AVS field box + input. Rendered identically in both layouts (the\n // buttons layout used to layer the theme's `nameInput`/`*Input` box on\n // top, producing a double-bordered field); the wrapper div *is* the box,\n // the input stays borderless/transparent. `invalid` rings it red once the\n // buyer has attempted submit.\n const inputWrapStyle = (invalid = false): React.CSSProperties => ({\n backgroundColor: cardInputBg, border: `1px solid ${avsBorderColor(invalid)}`,\n borderRadius: resolvedBorderRadius, marginTop: '0.5rem', padding: '10px',\n });\n const inputFieldStyle = (): React.CSSProperties => ({\n width: '100%', border: 'none', outline: 'none', background: 'transparent',\n ...sharedInputTypography,\n });\n const stateOpts = getStateOptions(cc);\n\n return (\n <>\n {/* Street Address (line 1) */}\n {isAVSFieldVisible(avsConfig.address_line_1, cc) && (\n <div style={inputWrapStyle(invalidAvsFields.line1)}>\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-address-line1\"\n name=\"billing-address-line1\"\n placeholder=\"Street Address (e.g. 123 Main St)\"\n autoComplete=\"billing address-line1\"\n value={addressLine1}\n onChange={(e) => { addressLine1Ref.current = e.target.value; setAddressLine1(e.target.value); }}\n disabled={isSubmitting}\n required\n data-testid=\"flopay-address-line1\"\n style={inputFieldStyle()}\n />\n </div>\n )}\n\n {/* Apt, Suite, etc. (line 2) — optional, never gated. */}\n {isAVSFieldVisible(avsConfig.address_line_2, cc) && (\n <div style={inputWrapStyle()}>\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-address-line2\"\n name=\"billing-address-line2\"\n placeholder=\"Apt, Suite, Unit (optional)\"\n autoComplete=\"billing address-line2\"\n value={addressLine2}\n onChange={(e) => { addressLine2Ref.current = e.target.value; setAddressLine2(e.target.value); }}\n disabled={isSubmitting}\n data-testid=\"flopay-address-line2\"\n style={inputFieldStyle()}\n />\n </div>\n )}\n\n {/* City + State row */}\n {(isAVSFieldVisible(avsConfig.city, cc) || isAVSFieldVisible(avsConfig.state, cc)) && (\n <div style={{\n display: 'flex', gap: '0', marginTop: '0.5rem',\n }}>\n {isAVSFieldVisible(avsConfig.city, cc) && (\n <div style={{\n flex: 1, backgroundColor: cardInputBg,\n borderTop: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,\n borderRight: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,\n borderBottom: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,\n borderLeft: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,\n padding: '10px',\n borderTopLeftRadius: resolvedBorderRadius, borderBottomLeftRadius: resolvedBorderRadius,\n ...(isAVSFieldVisible(avsConfig.state, cc) ? { borderRight: 'none', borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius: resolvedBorderRadius }),\n }}>\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-city\"\n name=\"billing-city\"\n placeholder=\"City\"\n autoComplete=\"billing address-level2\"\n value={city}\n onChange={(e) => { cityRef.current = e.target.value; setCity(e.target.value); }}\n disabled={isSubmitting}\n required\n data-testid=\"flopay-city\"\n style={inputFieldStyle()}\n />\n </div>\n )}\n {isAVSFieldVisible(avsConfig.state, cc) && (\n <div style={{\n flex: 1, backgroundColor: cardInputBg, border: `1px solid ${avsBorderColor(invalidAvsFields.state)}`,\n padding: '10px',\n borderTopRightRadius: resolvedBorderRadius, borderBottomRightRadius: resolvedBorderRadius,\n ...(isAVSFieldVisible(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius: resolvedBorderRadius }),\n }}>\n {stateOpts ? (\n <select\n id=\"flopay-billing-state\"\n name=\"billing-state\"\n value={stateValue}\n onChange={(e) => { stateRef.current = e.target.value; setStateValue(e.target.value); }}\n disabled={isSubmitting}\n autoComplete=\"billing address-level1\"\n required\n data-testid=\"flopay-state\"\n style={{ ...inputFieldStyle(), cursor: 'pointer' }}\n >\n <option value=\"\">{getStateLabel(cc)}</option>\n {stateOpts.map((s) => (\n <option key={s.code} value={s.code}>{s.name}</option>\n ))}\n </select>\n ) : (\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-state\"\n name=\"billing-state\"\n placeholder={getStateLabel(cc)}\n autoComplete=\"billing address-level1\"\n value={stateValue}\n onChange={(e) => { stateRef.current = e.target.value; setStateValue(e.target.value); }}\n disabled={isSubmitting}\n required\n data-testid=\"flopay-state\"\n style={inputFieldStyle()}\n />\n )}\n </div>\n )}\n </div>\n )}\n\n {/* Country + ZIP/Postcode row */}\n {(isAVSFieldVisible(avsConfig.country, cc) || isAVSFieldVisible(avsConfig.postal_code, cc)) && (\n <div style={{\n display: 'flex',\n flexDirection: avsLayoutProp === 'column' ? 'column' : 'row',\n gap: avsLayoutProp === 'column' ? '0.5rem' : '0',\n marginTop: '0.5rem',\n }}>\n {isAVSFieldVisible(avsConfig.country, cc) && (\n <div style={{\n flex: avsLayoutProp === 'row' ? 1 : undefined,\n backgroundColor: cardInputBg,\n borderTop: `1px solid ${resolvedBorder}`,\n borderRight: `1px solid ${resolvedBorder}`,\n borderBottom: `1px solid ${resolvedBorder}`,\n borderLeft: `1px solid ${resolvedBorder}`,\n padding: '10px',\n ...(avsLayoutProp === 'row' && isAVSFieldVisible(avsConfig.postal_code, cc)\n ? { borderRadius: '0', borderTopLeftRadius: resolvedBorderRadius, borderBottomLeftRadius: resolvedBorderRadius, borderRight: 'none' }\n : { borderRadius: resolvedBorderRadius }),\n }}>\n <select\n id=\"flopay-billing-country\"\n name=\"billing-country\"\n value={selectedCountry}\n onChange={(e) => {\n selectedCountryRef.current = e.target.value;\n setSelectedCountry(e.target.value);\n onCountryChange?.(e.target.value);\n // Reset state when country changes (different state lists)\n stateRef.current = '';\n setStateValue('');\n }}\n disabled={isSubmitting}\n autoComplete=\"billing country\"\n data-testid=\"flopay-country\"\n style={{ ...inputFieldStyle(), cursor: 'pointer' }}\n >\n {COUNTRY_OPTIONS.map((c) => (\n <option key={c.code} value={c.code}>{c.flag} {c.name}</option>\n ))}\n </select>\n </div>\n )}\n {isAVSFieldVisible(avsConfig.postal_code, cc) && (\n <div style={{\n flex: avsLayoutProp === 'row' ? 1 : undefined,\n backgroundColor: cardInputBg, border: `1px solid ${zipBorderColor}`,\n padding: '10px',\n ...(avsLayoutProp === 'row' && isAVSFieldVisible(avsConfig.country, cc)\n ? { borderRadius: '0', borderTopRightRadius: resolvedBorderRadius, borderBottomRightRadius: resolvedBorderRadius }\n : { borderRadius: resolvedBorderRadius }),\n }}>\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-postal-code\"\n name=\"billing-postal-code\"\n placeholder={getPostalCodeLabel(selectedCountry)}\n autoComplete=\"billing postal-code\"\n value={zipCode}\n onChange={(e) => {\n zipCodeRef.current = e.target.value;\n setZipCode(e.target.value);\n onZipChange?.(e.target.value);\n }}\n onBlur={() => setZipTouched(true)}\n disabled={isSubmitting}\n // Supported locales require a postcode; unsupported /\n // no-postcode locales leave the field optional. Use\n // `required` (not `.supported`) so the field can't be\n // mis-marked required if this JSX is ever hoisted outside\n // the `isAVSFieldVisible` gate — inside it the two agree.\n required={postalCodeState.required}\n aria-invalid={showPostcodeError || undefined}\n aria-describedby={showPostcodeError ? 'flopay-billing-postal-code-error' : undefined}\n data-testid=\"flopay-zip\"\n style={inputFieldStyle()}\n />\n </div>\n )}\n </div>\n )}\n\n {/* Inline postcode feedback, shown before any card capture — both\n variants also block the vault submit gate above. A blank\n required postcode shows the required message; a non-blank but\n malformed one shows the country-specific expected format. */}\n {showPostcodeError && (\n <div\n id=\"flopay-billing-postal-code-error\"\n role=\"alert\"\n data-testid=\"flopay-zip-error\"\n style={{\n marginTop: '0.375rem',\n color: resolvedDangerColor,\n ...sharedInputTypography,\n fontSize: '0.75rem',\n }}\n >\n {postalCodeState.empty\n ? `${getPostalCodeLabel(cc)} is required`\n : malformedPostcodeMessage(cc)}\n </div>\n )}\n </>\n );\n })()}\n </div>\n )}\n\n {/* Optional host content (e.g. the demo's test-cards helper). On the vault\n path it sits at the top of the card form — directly below the title and\n above the AVS block + card iframe — via flex `order` (title -3, slot -2,\n AVS -1, card form 0). */}\n {vaultActive && cardPreFormSlot && (\n <div style={{ order: -2, width: '100%' }}>{cardPreFormSlot}</div>\n )}\n\n {/* Vault widget — rendered after the AVS block so AVS fields precede the\n card iframe in the DOM (tab order: AVS → card). On the Stripe path the\n card fields render above (in the `!vaultActive` block). */}\n {vaultActive && vaultCardFieldsNode}\n\n {displayError && (\n <div role=\"alert\" data-testid=\"flopay-error\" style={{\n margin: '0.75rem 0', padding: '0.625rem 0.875rem',\n background: '#FEF2F2', border: '1px solid #FECACA', borderRadius: '8px',\n color: '#991B1B', fontSize: '0.85rem', fontWeight: 600,\n display: 'flex', alignItems: 'center', gap: '0.5rem',\n ...(bStyles.errorBanner ? bStyles.errorBanner as React.CSSProperties : {}),\n }}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" style={{ flexShrink: 0 }}>\n <path d=\"M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" stroke=\"#DC2626\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n {displayError}\n </div>\n )}\n\n {/* Submit — Stripe path only. The vault widget renders + owns its own\n submit button (it drives the charge through the backend). */}\n {!vaultActive && (children ?? (\n <button\n type=\"submit\"\n disabled={!formReady || isSubmitting}\n data-testid=\"flopay-submit\"\n onMouseEnter={(e) => {\n if (formReady && !isSubmitting) e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor =\n (bStyles.submitButton as React.CSSProperties | undefined)?.backgroundColor as string ?? resolvedPrimaryColor;\n }}\n style={{\n width: '100%', padding: '0.875rem', marginTop: '1rem',\n backgroundColor: resolvedPrimaryColor, color: 'white', border: 'none',\n borderRadius: resolvedBorderRadius,\n fontSize: bStyles.submitButtonFontSize ?? '1rem',\n fontWeight: 600,\n cursor: !formReady || isSubmitting ? 'not-allowed' : 'pointer',\n opacity: !formReady || isSubmitting ? 0.5 : 1,\n transition: 'background-color 0.15s',\n ...(bStyles.submitButton as React.CSSProperties),\n }}\n >\n {isSubmitting ? 'PROCESSING...' : submitLabel}\n </button>\n ))}\n </div>\n );\n\n // ── Parent-side debug panels ──\n //\n // Surface the parent-gate decisions for each gateway on-screen so the most\n // common misconfigurations (session missing `gateways.paypal.publishableKey`,\n // Stripe filtering by currency, empty `enabledPaymentMethods`, …) are\n // visible without opening DevTools. When the gateway is disabled via its\n // `show*` prop we still emit a single-line marker so the absence is\n // obvious — silent omission used to look identical to a debug-off SDK.\n const gateDebugStyle: React.CSSProperties = {\n margin: 0,\n padding: '6px 8px',\n background: '#eef2ff',\n border: '1px solid #c7d2fe',\n borderRadius: 6,\n color: '#111827',\n font: '11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n };\n // Reflect the session-response gateways. The DirectPayPal renderer is named\n // after the PayPal JS SDK path, so its \"enabled\" condition is the presence\n // of `gateways.paypal` upstream — surfaced here as `directPaypal.clientId`.\n // Likewise the Stripe parent gate is \"enabled\" when `gateways.stripe.publishable\\\n // Key` was wired up into a Stripe instance. Without either, the matching\n // renderer cannot run on this session regardless of the `show*` toggles, so\n // the panel collapses to the single \"not enabled\" marker.\n const renderDirectPaypalGateDebug = (testId: string) => {\n if (!debug) return null;\n if (!showPayPal || !directPaypalConfigured) {\n return (\n <pre data-testid={testId} style={gateDebugStyle}>\n {'FloPay/DirectPayPal-debug - not enabled'}\n </pre>\n );\n }\n return (\n <pre data-testid={testId} style={gateDebugStyle}>{[\n 'FloPay/DirectPayPal-debug (parent gate)',\n ` showPayPal=${showPayPal}`,\n ` directPaypalConfigured=${directPaypalConfigured}`,\n ` inAppBrowserDetected=${String(inAppBrowserDetected)}`,\n ` shouldRenderDirectPayPal=${shouldRenderDirectPayPal}`,\n ` shouldRenderStripePayPal=${shouldRenderStripePayPal}`,\n ` hasPaypalStripeInstance=${!!paypalStripeInstance}`,\n ].join('\\n')}</pre>\n );\n };\n const renderStripeGateDebug = (testId: string) => {\n if (!debug) return null;\n if (!showStripe || !stripeInstance) {\n return (\n <pre data-testid={testId} style={gateDebugStyle}>\n {'FloPay/Stripe-debug - not enabled'}\n </pre>\n );\n }\n return (\n <pre data-testid={testId} style={gateDebugStyle}>{[\n 'FloPay/Stripe-debug (parent gate)',\n ` showStripe=${showStripe}`,\n ` currency=${currency}`,\n ` amountInCents=${amountInCents}`,\n ` enabledPaymentMethods: ${JSON.stringify(enabledPaymentMethods ?? [])}`,\n ` enabledPaymentMethodsProvided=${hasEnabledMethodsPayload}`,\n ` hasEnabledMethods=${hasEnabledMethods}`,\n ` expressMethods: ${JSON.stringify(expressMethods)}`,\n ` walletExpressMethods: ${JSON.stringify(walletExpressMethods)}`,\n ` paymentElementMethods: ${JSON.stringify(paymentElementMethods)}`,\n ` paymentElementMethodsForCurrency: ${JSON.stringify(paymentElementMethodsForCurrency)}`,\n ` hasStripeInstance=${!!stripeInstance}`,\n ` shouldRenderWallets=${shouldRenderWallets}`,\n ` shouldRenderPaymentElement=${shouldRenderPaymentElement}`,\n ].join('\\n')}</pre>\n );\n };\n\n // ── APM 2nd-page derivations (shared by both layouts) ──\n // Lifted out of the layout branches so the default-layout (card form\n // visible inline) can also use the 2nd-page drill-in for input-form\n // APMs — without this, default-layout clicks on SEPA / EPS / iDEAL\n // were stuck on the local inline-expansion fallback path.\n const isApmView = viewState === 'apm-expanding' || viewState === 'apm-form' || viewState === 'apm-collapsing';\n const apmAnim = viewState === 'apm-expanding'\n ? `flopay-card-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both`\n : viewState === 'apm-collapsing'\n ? `flopay-card-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both`\n : undefined;\n // Per-method Elements options for the APM 2nd page. Built lazily by\n // method — the group only mounts while `viewState` is in the apm-*\n // family, so switching APMs (back → choose another) tears down the\n // previous Stripe Elements instance cleanly.\n const apmInlineOptions = expandedApmMethod ? {\n ...paymentElementBaseOptions,\n paymentMethodTypes: [expandedApmMethod],\n } as Parameters<typeof StripeElements>[0]['options'] : null;\n\n // ── Buttons layout ──\n if (layout === 'buttons') {\n const isButtonsView =\n viewState === 'buttons' ||\n viewState === 'expanding' ||\n viewState === 'apm-expanding';\n const isCardView = viewState === 'expanding' || viewState === 'card' || viewState === 'collapsing';\n const cardButtonSizing = cardButtonContent === undefined\n ? { boxSizing: 'border-box' as const, height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: '0 1rem' }\n : { padding: '0.9rem 1rem' };\n\n // The buttons panel slides out the same way whether we're going to the\n // card 2nd page or an APM 2nd page — same exit/enter animations so\n // the two drill-ins feel identical.\n const buttonsAnim = (viewState === 'expanding' || viewState === 'apm-expanding')\n ? `flopay-buttons-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both`\n : (viewState === 'collapsing' || viewState === 'apm-collapsing')\n ? `flopay-buttons-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both`\n : undefined;\n\n const cardAnim = viewState === 'expanding'\n ? `flopay-card-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both`\n : viewState === 'collapsing'\n ? `flopay-card-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both`\n : undefined;\n\n return (\n <form onSubmit={handleSubmit} className={className} style={{ position: 'relative' }}>\n <FloPayKeyframes />\n {overlayStatus && <ProcessingOverlay status={overlayStatus} errorMessage={displayError} />}\n\n {/* Container — uses grid overlap so both views can coexist during transition */}\n <div style={{ display: 'grid' }}>\n\n {/* Payment method buttons — always mounted to preserve PayPal/wallet Elements */}\n <div\n data-testid=\"flopay-buttons-panel\"\n aria-hidden={!isButtonsView && !buttonsAnim ? true : undefined}\n style={{\n gridArea: '1 / 1',\n display: 'flex', flexDirection: 'column', gap: '0.5rem',\n // When card form is showing (and not transitioning), hide but keep mounted.\n ...(!isButtonsView && !buttonsAnim ? BUTTONS_PANEL_HIDDEN_STYLE : {}),\n ...(buttonsAnim ? { animation: buttonsAnim, pointerEvents: 'none' as const } : {}),\n }}>\n {renderDirectPaypalGateDebug('flopay-direct-paypal-gate-debug')}\n {renderStripeGateDebug('flopay-stripe-gate-debug')}\n {/* PayPal — Direct PayPal JS SDK when configured, otherwise Stripe-rendered PayPal */}\n {shouldRenderDirectPayPal && directPaypal && (\n <>\n {paypalDirectRetry && (\n <div\n data-testid=\"flopay-paypal-direct-retry-notice\"\n style={{\n padding: '8px 10px',\n background: '#fef3c7',\n border: '1px solid #fcd34d',\n borderRadius: 6,\n color: '#78350f',\n fontSize: 13,\n lineHeight: 1.4,\n }}\n >\n Please confirm your PayPal payment to complete checkout.\n </div>\n )}\n <DirectPayPalButton\n // Force a remount when the retry id changes so PayPal's\n // SDK picks up the new createOrder binding (render()\n // options aren't live-updatable). `key` matches the\n // existingOrderId effect-dep update on the child.\n key={paypalDirectRetry?.orderId ?? 'fresh'}\n sessionId={sessionId}\n nonce={nonce}\n billingApiUrl={resolvedBillingApiUrl}\n email={resolvedAccount.email}\n clientId={directPaypal.clientId}\n environment={directPaypal.environment}\n currency={currency.toUpperCase()}\n isSubscription={isSubscription}\n onTokenizedBody={dispatchTokenizedBody}\n onComplete={onComplete}\n onErrorChange={updateError}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n onButtonClick={onButtonClick}\n runBeforeButtonClick={runBeforeButtonClick}\n isProcessing={isSubmitting}\n onLoadStateChange={setDirectPaypalReady}\n session={session ?? null}\n existingOrderId={paypalDirectRetry?.orderId}\n debug={debug}\n />\n </>\n )}\n {shouldRenderStripePayPal && (\n <StripeElements stripe={paypalStripeInstance} options={paypalOptions}>\n <PayPalButtonInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingApiUrl={resolvedBillingApiUrl}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n isProcessing={isSubmitting}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setPaypalLoadState}\n placeholderBorderRadius={buttonBorderRadius}\n />\n </StripeElements>\n )}\n\n {/* Wallets / express methods (Apple Pay / Google Pay / Link / Amazon Pay / Klarna) */}\n {shouldRenderWallets ? (\n <StripeElements stripe={stripeInstance} options={walletOptions}>\n <WalletButtonInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingApiUrl={resolvedBillingApiUrl}\n expressMethods={walletExpressMethods}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setWalletLoadState}\n placeholderBorderRadius={buttonBorderRadius}\n />\n </StripeElements>\n ) : shouldShowWallets ? (\n <div style={{ height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: buttonBorderRadius, background: '#e5e7eb', animation: 'flopay-pulse 1.5s ease-in-out infinite' }} />\n ) : null}\n\n {/* PaymentElement region — Cash App Pay / Affirm / iDEAL / SEPA … */}\n {shouldRenderPaymentElement && (\n <StripePaymentElementInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingName={[resolvedAccount.firstName, resolvedAccount.lastName].filter(Boolean).join(' ').trim() || undefined}\n billingApiUrl={resolvedBillingApiUrl}\n paymentElementMethods={paymentElementMethodsForCurrency}\n stripeInstance={stripeInstance}\n paymentElementBaseOptions={paymentElementBaseOptions}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setPaymentElementLoadState}\n isProcessing={isSubmitting}\n submitButtonColor={resolvedPrimaryColor}\n submitButtonBorderRadius={resolvedBorderRadius}\n submitButtonStyle={bStyles.submitButton as React.CSSProperties | undefined}\n // Input-form methods (SEPA / EPS / iDEAL / Bacs) drill\n // into a 2nd-page panel rendered alongside the card\n // form below. `StripePaymentElementInner` itself only\n // renders the tile-button row; the parent owns the\n // navigation state machine.\n onExpandApm={expandToApm}\n expandedApmMethod={expandedApmMethod}\n themeId={theme}\n // The `buttonAppearance` override is only used as a\n // *fallback* — `STRIPE_METHOD_MATRIX[<method>].theme`\n // takes precedence inside the tile, so brand-styled\n // methods (Cash App green, Klarna pink, …) keep their\n // brand colors regardless of the bundle's `cardButton`\n // styling. Methods with no `theme` entry pick up the\n // bundle's neutral tile here.\n buttonAppearance={{\n backgroundColor: bStyles.cardButton?.backgroundColor as string | undefined,\n borderColor: bStyles.cardInputBorder,\n textColor: bStyles.cardButton?.color as string | undefined,\n borderRadius: buttonBorderRadius,\n }}\n />\n )}\n\n {/* Credit / Debit Card button — gated on `showStripe` so the\n PayPal-only flow doesn't expose an unusable card option.\n Themed: `derivePrimaryTileStyle` flips the base from white\n + grey border (classic) to a primary-colored fill that\n mirrors the theme's submit/CTA action. */}\n {showStripe && (\n <button\n type=\"button\"\n onClick={async () => {\n if (isSubmitting) return;\n const beforeClick = await runBeforeButtonClick('card');\n if (!beforeClick.proceed) return;\n onButtonClick?.('card');\n expandToCard();\n }}\n disabled={isSubmitting}\n style={{\n width: '100%',\n ...cardButtonSizing,\n // `bStyles.cardButton` first — supplies the bundle's\n // padding / typography / border-radius — then the\n // primary surface overrides on top, so the card button\n // ends up wearing the *submit* button's colours rather\n // than the bundle's neutral white-tile `cardButton`\n // colours. Without this order flip, every non-classic\n // bundle's `cardButton.backgroundColor` was winning\n // over the primary fill we just derived above it.\n ...bStyles.cardButton as React.CSSProperties,\n ...derivePrimaryTileStyle({\n themeBundle,\n resolvedPrimaryColor,\n resolvedBorderRadius,\n submitButtonStyle: bStyles.submitButton as React.CSSProperties | undefined,\n explicitPrimaryColor: appearanceVars?.colorPrimary as string | undefined,\n }),\n fontSize: bStyles.cardButtonFontSize ?? '0.95rem', fontWeight: 600,\n cursor: isSubmitting ? 'not-allowed' : 'pointer', display: 'flex',\n alignItems: 'center', justifyContent: 'center', gap: '0.625rem',\n transition: 'background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s',\n position: 'relative',\n opacity: isSubmitting ? 0.6 : 1,\n }}\n // Hover on any primary-filled button (themed bundle OR an\n // explicit `colorPrimary` override). The classic white tile\n // with no override keeps its static look. `colorPrimaryHover`\n // (or a derived darker shade) on enter, `colorPrimary` on leave.\n onMouseEnter={(e) => {\n if (!isSubmitting && (themeBundle || appearanceVars?.colorPrimary)) {\n e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;\n }\n }}\n onMouseLeave={(e) => {\n if (themeBundle || appearanceVars?.colorPrimary) e.currentTarget.style.backgroundColor = resolvedPrimaryColor;\n }}\n onMouseDown={(e) => { e.currentTarget.style.transform = 'scale(0.985)'; }}\n onMouseUp={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}\n >\n <CardButtonContentSlot content={cardButtonContent} />\n </button>\n )}\n\n {displayError && viewState === 'buttons' && (\n <div role=\"alert\" data-testid=\"flopay-error\" style={{\n margin: '0.25rem 0', padding: '0.625rem 0.875rem',\n background: '#FEF2F2', border: '1px solid #FECACA', borderRadius: '8px',\n color: '#991B1B', fontSize: '0.85rem', fontWeight: 600,\n display: 'flex', alignItems: 'center', gap: '0.5rem',\n ...(bStyles.errorBanner ? bStyles.errorBanner as React.CSSProperties : {}),\n }}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" style={{ flexShrink: 0 }}>\n <path d=\"M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" stroke=\"#DC2626\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n {displayError}\n </div>\n )}\n </div>\n\n {/* Card form — gated on `showStripe` (PayPal-only flow hides it). */}\n {showStripe && isCardView && (\n <div style={{\n gridArea: '1 / 1',\n ...(cardAnim ? { animation: cardAnim } : {}),\n ...(viewState === 'collapsing' ? { pointerEvents: 'none' as const } : {}),\n }}>\n {cardFormBlock}\n </div>\n )}\n\n {/* APM 2nd page — mirrors the card-form 2nd page exactly:\n same gridArea, same back-button chrome, same enter/exit\n animations. The only differences are the title (method\n display name) and the body (single-method Stripe\n PaymentElement instead of the split-card fields). */}\n {showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && (\n <div style={{\n gridArea: '1 / 1',\n ...(apmAnim ? { animation: apmAnim } : {}),\n ...(viewState === 'apm-collapsing' ? { pointerEvents: 'none' as const } : {}),\n }}>\n <div style={{\n backgroundColor: cardBg, borderRadius: containerRadius,\n ...containerOverrides,\n padding: containerPadding,\n }}>\n {/* Header: back button + method-name title — pixel-for-\n pixel the same chrome as the card-form header. */}\n <div style={{\n display: 'flex', alignItems: 'center', padding: '0.75rem 0 0.625rem',\n }}>\n <button\n type=\"button\"\n data-testid=\"flopay-apm-back-button\"\n onClick={collapseFromApm}\n style={{\n display: 'inline-flex', alignItems: 'center', gap: hideBackButtonLabel ? 0 : '0.5rem',\n background: 'none', border: 'none', cursor: 'pointer',\n color: '#4b5563', fontSize: bStyles.backButtonFontSize ?? '0.85rem', fontWeight: 500,\n padding: 0, transition: 'color 0.15s', flexShrink: 0,\n ...bStyles.backButton as React.CSSProperties,\n }}\n aria-label=\"Back to payment methods\"\n >\n <span style={{\n display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: '50%',\n backgroundColor: '#f3f4f6', transition: 'background-color 0.15s',\n ...bStyles.backButtonIcon as React.CSSProperties,\n }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n </span>\n <BackButtonContentSlot content={cardBackButtonContent} />\n </button>\n <div style={{\n flex: 1, textAlign: 'center', fontWeight: 600,\n fontSize: bStyles.titleFontSize ?? '1.05rem',\n color: resolvedTitleColor, paddingRight: 80,\n ...bStyles.title as React.CSSProperties,\n }}>\n {`Pay with ${getStripeMethodDisplayName(expandedApmMethod)}`}\n </div>\n </div>\n\n {/* Per-method Elements group: keyed by method so switching\n APMs unmounts the previous group cleanly. */}\n <StripeElements\n key={expandedApmMethod}\n stripe={stripeInstance}\n options={apmInlineOptions}\n >\n <StripeMethodInlineForm\n method={expandedApmMethod}\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingName={[resolvedAccount.firstName, resolvedAccount.lastName].filter(Boolean).join(' ').trim() || undefined}\n billingApiUrl={resolvedBillingApiUrl}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onDecline={onDecline}\n onCancel={collapseFromApm}\n runBeforeButtonClick={runBeforeButtonClick}\n onButtonClick={onButtonClick}\n isProcessing={isSubmitting}\n submitButtonColor={resolvedPrimaryColor}\n submitButtonBorderRadius={resolvedBorderRadius}\n submitButtonStyle={bStyles.submitButton as React.CSSProperties | undefined}\n errorText={displayError}\n />\n </StripeElements>\n </div>\n </div>\n )}\n </div>\n </form>\n );\n }\n\n // ── Default layout ──\n // When an input-form APM is expanded, render *only* its 2nd-page panel\n // (back button + scoped PaymentElement + Pay button) — the wallet row,\n // APM tiles, divider and card form all step aside so the buyer's focus\n // is on completing the inline form. Hitting \"Go back\" restores the\n // normal layout. Same chrome as the buttons-layout 2nd page so the\n // experience is consistent across both layouts.\n if (isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && showStripe) {\n return (\n <form onSubmit={handleSubmit} className={className} style={{ position: 'relative' }}>\n <FloPayKeyframes />\n {overlayStatus && <ProcessingOverlay status={overlayStatus} errorMessage={displayError} />}\n <div style={{\n ...(apmAnim ? { animation: apmAnim } : {}),\n ...(viewState === 'apm-collapsing' ? { pointerEvents: 'none' as const } : {}),\n }}>\n <div style={{\n backgroundColor: cardBg, borderRadius: containerRadius,\n ...containerOverrides,\n padding: containerPadding,\n }}>\n {/* Back-button chrome — same circle icon + theme back-button\n styling as the card form 2nd page in the buttons layout. */}\n <div style={{\n display: 'flex', alignItems: 'center', padding: '0.75rem 0 0.625rem',\n }}>\n <button\n type=\"button\"\n data-testid=\"flopay-apm-back-button-default\"\n onClick={collapseFromApm}\n style={{\n display: 'inline-flex', alignItems: 'center', gap: hideBackButtonLabel ? 0 : '0.5rem',\n background: 'none', border: 'none', cursor: 'pointer',\n color: '#4b5563', fontSize: bStyles.backButtonFontSize ?? '0.85rem', fontWeight: 500,\n padding: 0, transition: 'color 0.15s', flexShrink: 0,\n ...bStyles.backButton as React.CSSProperties,\n }}\n aria-label=\"Back to payment methods\"\n >\n <span style={{\n display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: '50%',\n backgroundColor: '#f3f4f6', transition: 'background-color 0.15s',\n ...bStyles.backButtonIcon as React.CSSProperties,\n }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n </span>\n <BackButtonContentSlot content={cardBackButtonContent} />\n </button>\n <div style={{\n flex: 1, textAlign: 'center', fontWeight: 600,\n fontSize: bStyles.titleFontSize ?? '1.05rem',\n color: resolvedTitleColor, paddingRight: 80,\n ...bStyles.title as React.CSSProperties,\n }}>\n {`Pay with ${getStripeMethodDisplayName(expandedApmMethod)}`}\n </div>\n </div>\n\n <StripeElements\n key={expandedApmMethod}\n stripe={stripeInstance}\n options={apmInlineOptions}\n >\n <StripeMethodInlineForm\n method={expandedApmMethod}\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingName={[resolvedAccount.firstName, resolvedAccount.lastName].filter(Boolean).join(' ').trim() || undefined}\n billingApiUrl={resolvedBillingApiUrl}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onDecline={onDecline}\n onCancel={collapseFromApm}\n runBeforeButtonClick={runBeforeButtonClick}\n onButtonClick={onButtonClick}\n isProcessing={isSubmitting}\n submitButtonColor={resolvedPrimaryColor}\n submitButtonBorderRadius={resolvedBorderRadius}\n submitButtonStyle={bStyles.submitButton as React.CSSProperties | undefined}\n errorText={displayError}\n />\n </StripeElements>\n </div>\n </div>\n </form>\n );\n }\n\n return (\n <form onSubmit={handleSubmit} className={className} style={{ position: 'relative' }}>\n <FloPayKeyframes />\n {overlayStatus && <ProcessingOverlay status={overlayStatus} errorMessage={displayError} />}\n\n {/* Express-checkout row — flex column with `gap` matches the buttons\n layout, so wallet/PayPal/Stripe-PayPal always sit `0.5rem` apart\n regardless of which combination is rendered. Order matches the\n buttons layout: PayPal first, then wallets. */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {renderDirectPaypalGateDebug('flopay-direct-paypal-gate-debug-default')}\n {renderStripeGateDebug('flopay-stripe-gate-debug-default')}\n {/* PayPal — Direct PayPal JS SDK when configured, otherwise Stripe-rendered PayPal */}\n {shouldRenderDirectPayPal && directPaypal && (\n <>\n {paypalDirectRetry && (\n <div\n data-testid=\"flopay-paypal-direct-retry-notice-default\"\n style={{\n padding: '8px 10px',\n background: '#fef3c7',\n border: '1px solid #fcd34d',\n borderRadius: 6,\n color: '#78350f',\n fontSize: 13,\n lineHeight: 1.4,\n }}\n >\n Please confirm your PayPal payment to complete checkout.\n </div>\n )}\n <DirectPayPalButton\n // Remount when retry id changes so PayPal SDK picks up the\n // new createOrder binding.\n key={paypalDirectRetry?.orderId ?? 'fresh'}\n sessionId={sessionId}\n nonce={nonce}\n billingApiUrl={resolvedBillingApiUrl}\n email={resolvedAccount.email}\n clientId={directPaypal.clientId}\n environment={directPaypal.environment}\n currency={currency.toUpperCase()}\n isSubscription={isSubscription}\n onTokenizedBody={dispatchTokenizedBody}\n onComplete={onComplete}\n onErrorChange={updateError}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n onButtonClick={onButtonClick}\n runBeforeButtonClick={runBeforeButtonClick}\n isProcessing={isSubmitting}\n onLoadStateChange={setDirectPaypalReady}\n session={session ?? null}\n existingOrderId={paypalDirectRetry?.orderId}\n debug={debug}\n />\n </>\n )}\n {shouldRenderStripePayPal && (\n <StripeElements stripe={paypalStripeInstance} options={paypalOptions}>\n <PayPalButtonInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingApiUrl={resolvedBillingApiUrl}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n isProcessing={isSubmitting}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setPaypalLoadState}\n placeholderBorderRadius={buttonBorderRadius}\n />\n </StripeElements>\n )}\n\n {/* Wallet / express buttons — own Stripe Elements instance */}\n {shouldRenderWallets && (\n <StripeElements stripe={stripeInstance} options={walletOptions}>\n <WalletButtonInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingApiUrl={resolvedBillingApiUrl}\n expressMethods={walletExpressMethods}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setWalletLoadState}\n placeholderBorderRadius={buttonBorderRadius}\n />\n </StripeElements>\n )}\n\n {/* PaymentElement region — non-express APMs (Cash App Pay, Klarna, iDEAL, SEPA, …) */}\n {shouldRenderPaymentElement && (\n <StripePaymentElementInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingName={[resolvedAccount.firstName, resolvedAccount.lastName].filter(Boolean).join(' ').trim() || undefined}\n billingApiUrl={resolvedBillingApiUrl}\n paymentElementMethods={paymentElementMethodsForCurrency}\n stripeInstance={stripeInstance}\n paymentElementBaseOptions={paymentElementBaseOptions}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setPaymentElementLoadState}\n isProcessing={isSubmitting}\n submitButtonColor={resolvedPrimaryColor}\n submitButtonBorderRadius={resolvedBorderRadius}\n submitButtonStyle={bStyles.submitButton as React.CSSProperties | undefined}\n themeId={theme}\n // Route input-form APM clicks (SEPA / EPS / iDEAL / Bacs)\n // through the parent's `viewState` machine — same 2nd-page\n // pattern as the buttons-layout, just without the in/out\n // transition since the default layout doesn't pre-render the\n // panel alongside an animated buttons row.\n onExpandApm={expandToApm}\n expandedApmMethod={expandedApmMethod}\n buttonAppearance={{\n backgroundColor: bStyles.cardButton?.backgroundColor as string | undefined,\n borderColor: bStyles.cardInputBorder,\n textColor: bStyles.cardButton?.color as string | undefined,\n borderRadius: buttonBorderRadius,\n }}\n />\n )}\n </div>\n\n {/* Divider between wallet/PayPal buttons and card fields — only when\n the card form is actually going to render. */}\n {showStripe && (shouldDisplayWalletRow || shouldDisplayPayPalRow || shouldDisplayPaymentElementRow) && (\n <div style={{\n display: 'flex', alignItems: 'center', gap: '0.75rem',\n margin: '0.5rem 0 0.75rem', color: '#999', fontSize: '0.85rem',\n }}>\n <div style={{ flex: 1, height: 1, backgroundColor: '#ddd' }} />\n <span>or pay with card</span>\n <div style={{ flex: 1, height: 1, backgroundColor: '#ddd' }} />\n </div>\n )}\n\n {showStripe && cardFormBlock}\n </form>\n );\n}\n","import React, { useEffect, useRef } from 'react';\nimport type { CardCaptureAdapter, VaultCardThemeColors } from '@flopay/shared';\n\n/** Props for {@link VaultCardFields}. */\nexport interface VaultCardFieldsProps {\n /**\n * The card-capture adapter (typically `useFloPay().cardCapture()`). Owns\n * injecting + bootstrapping the hosted vault widget. Changing this instance\n * (or {@link VaultCardFieldsProps.html}) remounts the widget.\n */\n capture: CardCaptureAdapter;\n /**\n * Server-rendered hosted vault widget HTML (the session's\n * {@link CheckoutSession.vault} block `html`, or one fetched from\n * `POST /vault/capture`). The widget owns the card fields, submit button,\n * tokenization, charge, and 3DS; this component only injects it.\n */\n html: string;\n /**\n * Per-session integrity token (the vault block's `messageToken`). Forwarded\n * to the adapter so it can reject forged terminal `postMessage` outcomes that\n * omit/mismatch it. Omitted when the backend does not (yet) mint one.\n */\n messageToken?: string;\n /**\n * Exact origin expected for the widget's terminal `postMessage` outcomes\n * (the vault block's `expectedOrigin`). Forwarded to the adapter's origin\n * gate; omitted to skip it.\n */\n expectedOrigin?: string;\n /**\n * Merchant theme colors pushed into the hosted widget so the card form\n * matches the surrounding checkout. Applied live on change (no remount).\n */\n theme?: VaultCardThemeColors;\n /** Inline styles for the container the widget mounts into. */\n containerStyle?: React.CSSProperties;\n /** Fired once the widget is injected and bootstrapping. */\n onReady?: () => void;\n /**\n * Fired with a load/runtime error message from the widget, or `null` when it\n * clears. Wired to the card form's shared error banner. Terminal payment\n * outcomes (`complete` / `decline`) are observed by the parent form directly\n * off the same adapter and are not surfaced here.\n */\n onError?: (message: string | null) => void;\n /**\n * Fired with the widget's inline field-validation message (live, debounced by\n * the widget to changes), or `null` when validation clears. Surfaced in the\n * card form's error banner and the merchant `onError`.\n */\n onValidation?: (message: string | null) => void;\n}\n\n/**\n * Renders the backend-served vault PCI card widget in place of provider-owned\n * (Stripe) card elements (TeamFloPay/backend#823, Model A). The hosted widget\n * is a self-contained form: PAN / CVC, the submit button, the charge, and 3DS\n * all live inside it. This component only injects the widget HTML through the\n * {@link CardCaptureAdapter} and bridges its `ready` / `error` lifecycle events\n * back to the surrounding card form.\n */\nexport function VaultCardFields({\n capture,\n html,\n messageToken,\n expectedOrigin,\n theme,\n containerStyle,\n onReady,\n onError,\n onValidation,\n}: VaultCardFieldsProps): React.ReactElement {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const onReadyRef = useRef(onReady);\n const onErrorRef = useRef(onError);\n const onValidationRef = useRef(onValidation);\n onReadyRef.current = onReady;\n onErrorRef.current = onError;\n onValidationRef.current = onValidation;\n // Latest theme for the mount path (so a remount re-applies it) without making\n // `theme` a remount trigger — live changes go through the effect below.\n const themeRef = useRef(theme);\n themeRef.current = theme;\n\n // Mount once per capture instance + widget HTML; remount when either changes.\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n let active = true;\n let readyEmitted = false;\n const emitReadyOnce = () => {\n if (!active || readyEmitted) return;\n readyEmitted = true;\n onReadyRef.current?.();\n };\n\n const offReady = capture.on('ready', () => {\n emitReadyOnce();\n });\n const offError = capture.on('error', (event) => {\n onErrorRef.current?.(event.message ?? 'There was a problem loading the secure card form.');\n });\n const offValidation = capture.on('validation', (event) => {\n onValidationRef.current?.(event.message ?? null);\n });\n\n const mountOptions = {\n html,\n ...(messageToken ? { messageToken } : {}),\n ...(expectedOrigin ? { expectedOrigin } : {}),\n ...(themeRef.current ? { theme: themeRef.current } : {}),\n };\n\n capture\n .mount(el, mountOptions)\n .then(() => {\n emitReadyOnce();\n })\n .catch((err: unknown) => {\n if (active) {\n onErrorRef.current?.(\n err instanceof Error ? err.message : 'Failed to load the secure card form.',\n );\n }\n });\n\n return () => {\n active = false;\n offReady();\n offError();\n offValidation();\n capture.unmount();\n };\n }, [capture, html, messageToken, expectedOrigin]);\n\n // Live theme updates — re-skin the mounted widget on a runtime theme switch\n // without a remount. The adapter no-ops until the widget is ready, then its\n // `ready` handler re-pushes the latest theme.\n useEffect(() => {\n if (theme) capture.applyTheme?.(theme);\n }, [capture, theme]);\n\n return (\n <div ref={containerRef} data-testid=\"flopay-vault-card-fields\" style={containerStyle} />\n );\n}\n","import { useContext } from 'react';\nimport type { FloPay, FloPayElements } from '@flopay/js';\nimport type { CheckoutSession, FloPayError } from '@flopay/shared';\nimport { resolveBillingApiUrl } from '@flopay/shared';\nimport { FloPayContext, CheckoutContext } from './context.js';\nimport type { CheckoutContextValue } from './context.js';\n\n/**\n * Returns the current `FloPay` instance, or `null` if the provider\n * is still loading (i.e. the `loadFloPay()` promise has not resolved yet).\n *\n * Must be called within a `<FloPayProvider>`.\n */\nexport function useFloPay(): FloPay | null {\n const ctx = useContext(FloPayContext);\n return ctx.flopay;\n}\n\n/**\n * Returns the Stripe `FloPay` instance dedicated to the Stripe-rendered\n * PayPal fallback, or `null` if PayPal is disabled for this session. Direct\n * PayPal (`gateways.paypal`) does not use this instance.\n *\n * Must be called within a `<FloPayProvider>`.\n */\nexport function usePayPalFloPay(): FloPay | null {\n const ctx = useContext(FloPayContext);\n return ctx.paypalFlopay ?? null;\n}\n\n/**\n * Returns the current `FloPayElements` instance, or `null` if the\n * provider is still loading.\n *\n * Must be called within a `<FloPayProvider>`.\n */\nexport function useElements(): FloPayElements | null {\n const ctx = useContext(FloPayContext);\n return ctx.elements;\n}\n\n/** Checkout state exposed by `useCheckout()`. */\nexport interface CheckoutState {\n session: CheckoutSession | null;\n loading: boolean;\n error: FloPayError | null;\n}\n\n/**\n * Returns the current checkout session state.\n *\n * Must be called within a `<CheckoutProvider>` (typically rendered\n * internally by `<CheckoutForm>`).\n */\nexport function useCheckout(): CheckoutState {\n return useContext(CheckoutContext);\n}\n\n/**\n * Returns the resolved billing API URL from the provider context.\n * Falls back to the default `BILLING_API_URL` constant.\n */\nexport function useBillingApiUrl(): string {\n const ctx = useContext(FloPayContext);\n return ctx.billingApiUrl || resolveBillingApiUrl();\n}\n","import React from 'react';\n\nexport type OverlayStatus = 'processing' | 'success' | 'error';\n\nexport const PROCESSING_OVERLAY_SUCCESS_DELAY_MS = 1200;\nexport const PROCESSING_OVERLAY_ERROR_DELAY_MS = 1500;\n\nexport function ProcessingOverlay({\n status,\n errorMessage,\n}: {\n status: OverlayStatus;\n errorMessage?: string | null;\n}) {\n return (\n <div\n data-testid=\"flopay-processing-overlay\"\n data-status={status}\n role=\"dialog\"\n aria-modal=\"true\"\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.35)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n backdropFilter: 'blur(2px)',\n }}\n >\n <div\n style={{\n background: 'white',\n borderRadius: 12,\n padding: '2rem 2.5rem',\n textAlign: 'center',\n boxShadow: '0 8px 32px rgba(0,0,0,0.18)',\n minWidth: 240,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 16,\n }}\n >\n <div style={{ width: 48, height: 48, position: 'relative' }}>\n {status === 'processing' && (\n <svg\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ animation: 'flopay-spin 0.8s linear infinite' }}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"#e5e7eb\" strokeWidth=\"3\" />\n <path d=\"M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z\" fill=\"#4A49FF\" />\n </svg>\n )}\n {status === 'success' && (\n <div style={{ animation: 'flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)' }}>\n <svg width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"11\" fill=\"#22c55e\" />\n <path\n d=\"M7 12.5l3 3 7-7\"\n stroke=\"white\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n strokeDasharray: 20,\n strokeDashoffset: 20,\n animation: 'flopay-draw 0.4s 0.15s ease forwards',\n }}\n />\n </svg>\n </div>\n )}\n {status === 'error' && (\n <div style={{ animation: 'flopay-shake 0.4s ease' }}>\n <svg width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"11\" fill=\"#ef4444\" />\n <path\n d=\"M8 8l8 8M16 8l-8 8\"\n stroke=\"white\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n style={{\n strokeDasharray: 12,\n strokeDashoffset: 12,\n animation: 'flopay-draw 0.3s 0.1s ease forwards',\n }}\n />\n </svg>\n </div>\n )}\n </div>\n <span\n style={{\n fontSize: 14,\n fontWeight: 600,\n letterSpacing: '0.05em',\n color: status === 'success' ? '#16a34a' : status === 'error' ? '#dc2626' : '#374151',\n }}\n >\n {status === 'processing' && 'PROCESSING...'}\n {status === 'success' && 'PAYMENT SUCCESSFUL'}\n {status === 'error' && 'PAYMENT FAILED'}\n </span>\n {status === 'success' && (\n <p\n style={{\n fontSize: 13,\n color: '#6b7280',\n fontWeight: 400,\n maxWidth: 260,\n lineHeight: 1.4,\n margin: 0,\n }}\n >\n You will be automatically redirected, do not close or navigate away from this window.\n </p>\n )}\n {status === 'error' && errorMessage && (\n <p\n style={{\n fontSize: 13,\n color: '#6b7280',\n fontWeight: 400,\n maxWidth: 260,\n lineHeight: 1.4,\n margin: 0,\n }}\n >\n {errorMessage}\n </p>\n )}\n <style>{`\n @keyframes flopay-spin { to { transform: rotate(360deg); } }\n @keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }\n @keyframes flopay-draw { to { stroke-dashoffset: 0; } }\n @keyframes flopay-shake { 0%,100% { transform: translateX(0); } 20%,60% { transform: translateX(-4px); } 40%,80% { transform: translateX(4px); } }\n `}</style>\n </div>\n </div>\n );\n}\n","import type {\n CheckoutAccount,\n CheckoutButtonMethod,\n CheckoutMode,\n CheckoutSession,\n DeclineEvent,\n InlineSessionDraft,\n InlineSessionParams,\n InlineSessionPatch,\n PaymentResult,\n TokenizedBody,\n} from '@flopay/shared';\nimport { FloPayError, isSetupIntentClientSecret } from '@flopay/shared';\n\nexport function mergeInlineSessionPatches(\n base: InlineSessionPatch | undefined,\n patch: InlineSessionPatch | undefined,\n): InlineSessionPatch | undefined {\n if (!patch) return base;\n if (!base) return patch;\n\n return {\n account: { ...(base.account ?? {}), ...(patch.account ?? {}) },\n couponCodes: patch.couponCodes ?? base.couponCodes,\n tagsData: {\n ...(base.tagsData ?? {}),\n ...(patch.tagsData ?? {}),\n },\n utmMetadata: patch.utmMetadata ?? base.utmMetadata,\n };\n}\n\nexport function mergeInlineSessionPatch(\n params: InlineSessionDraft,\n patch: InlineSessionPatch | undefined,\n): InlineSessionDraft {\n if (!patch) return params;\n\n return {\n ...params,\n account: {\n ...params.account,\n ...(patch.account ?? {}),\n },\n couponCodes: patch.couponCodes ?? params.couponCodes,\n tagsData: {\n ...(params.tagsData ?? {}),\n ...(patch.tagsData ?? {}),\n },\n utmMetadata: patch.utmMetadata ?? params.utmMetadata,\n };\n}\n\nexport function buildSyntheticSession(\n params: InlineSessionDraft,\n checkoutModeOverride?: CheckoutMode,\n): CheckoutSession {\n const inputProducts = params.products ?? [\n ...(params.subscriptions ?? []).map((s) => ({\n type: 'subscription' as const,\n code: s.code ?? s.providerPlanId,\n name: s.subscriptionName ?? s.providerPlanName ?? s.code ?? s.providerPlanId ?? null,\n quantity: s.quantity ?? 1,\n totalAmount: s.totalAmount,\n overrideAmount: s.overrideAmount,\n currency: s.currency,\n metadata: s.metadata,\n })),\n ...(params.items ?? []).map((i) => ({\n type: 'item' as const,\n code: i.code ?? i.providerItemId,\n name: i.itemName ?? i.providerItemName ?? i.code ?? i.providerItemId ?? null,\n quantity: i.quantity ?? 1,\n totalAmount: i.totalAmount,\n overrideAmount: i.overrideAmount,\n currency: i.currency,\n metadata: i.metadata,\n })),\n ];\n\n const totalAmount = inputProducts.reduce(\n (sum, p) => sum + ((p.overrideAmount ?? p.totalAmount) ?? 0),\n 0,\n );\n const currency = params.currency\n ?? inputProducts.find((p) => p.currency)?.currency\n ?? 'USD';\n\n return {\n id: '',\n clientSecret: '',\n mode: inputProducts.some((p) => p.type === 'subscription') ? 'subscription' : 'payment',\n amount: Math.round(totalAmount * 100),\n currency,\n status: 'open',\n customer: {\n id: params.account.userId,\n email: params.account.email ?? '',\n firstName: params.account.firstName,\n lastName: params.account.lastName,\n gender: params.account.gender ?? undefined,\n city: params.account.city ?? undefined,\n state: params.account.state ?? undefined,\n country: params.account.country ?? undefined,\n zip: params.account.zip ?? undefined,\n },\n successUrl: params.successUrl,\n cancelUrl: params.cancelUrl,\n checkoutMode: (checkoutModeOverride ?? params.checkoutMode ?? 'full') as CheckoutMode,\n products: inputProducts.map((p, idx) => ({\n uuid: `synthetic-${p.type ?? 'item'}-${idx}`,\n checkoutSessionId: '',\n type: p.type ?? 'item',\n code: p.code,\n name: p.name ?? null,\n quantity: p.quantity ?? 1,\n totalAmount: p.totalAmount,\n overrideAmount: p.overrideAmount ?? null,\n currency: p.currency ?? currency,\n metadata: p.metadata ?? null,\n })),\n };\n}\n\nexport function ensureInlineSessionReady(\n params: InlineSessionDraft,\n): asserts params is InlineSessionParams {\n if (!params.account.email?.trim()) {\n throw new FloPayError(\n 'Email is required before continuing with card checkout.',\n 'validation_error',\n { param: 'createSession.account.email' },\n );\n }\n}\n\nexport function splitFullName(name: string | null | undefined): {\n firstName?: string;\n lastName?: string;\n} {\n const parts = name?.trim().split(/\\s+/).filter(Boolean) ?? [];\n if (parts.length === 0) return {};\n return {\n firstName: parts[0],\n lastName: parts.length > 1 ? parts.slice(1).join(' ') : undefined,\n };\n}\n\nexport function mergeAccountPatch<T extends {\n userId?: string;\n email?: string;\n firstName?: string;\n lastName?: string;\n country?: string | null;\n zip?: string | null;\n}>(\n base: T,\n patch: Partial<CheckoutAccount> | undefined,\n): T {\n if (!patch) return base;\n return {\n ...base,\n ...patch,\n };\n}\n\nexport function buildDeclineEvent(\n method: CheckoutButtonMethod,\n input: string | FloPayError,\n overrides?: {\n code?: string;\n declineCode?: string;\n },\n): DeclineEvent {\n const message = typeof input === 'string' ? input : input.message;\n const code = typeof input === 'string' ? overrides?.code : overrides?.code ?? input.code;\n const declineCode = typeof input === 'string'\n ? overrides?.declineCode\n : overrides?.declineCode ?? input.declineCode;\n\n return {\n method,\n message,\n ...(code ? { code } : {}),\n ...(declineCode ? { declineCode } : {}),\n };\n}\n\ntype ApiErrorPayload = Record<string, unknown> | null;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction readString(payload: ApiErrorPayload, key: string): string | undefined {\n const value = payload?.[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nconst FRIENDLY_MESSAGE_OVERRIDES: Array<{ match: RegExp; replacement: string }> = [\n {\n match: /^paypal authorization required\\.?$/i,\n replacement: 'For your additional security, please re-authenticate this payment via PayPal.',\n },\n];\n\nexport function applyFriendlyMessageOverride(message: string | undefined | null): string | undefined {\n if (typeof message !== 'string') return message ?? undefined;\n const trimmed = message.trim();\n if (!trimmed) return message;\n for (const { match, replacement } of FRIENDLY_MESSAGE_OVERRIDES) {\n if (match.test(trimmed)) return replacement;\n }\n return message;\n}\n\nexport function buildFloPayApiError(\n payload: ApiErrorPayload,\n fallbackMessage: string,\n): FloPayError {\n const nestedError = isRecord(payload?.error) ? payload.error : null;\n const rawMessage =\n readString(payload, 'message') ??\n readString(nestedError, 'message') ??\n fallbackMessage;\n const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;\n const code =\n readString(payload, 'code') ??\n readString(payload, 'gatewayErrorCode') ??\n readString(nestedError, 'code');\n const declineCode =\n readString(payload, 'declineCode') ??\n readString(payload, 'gatewayDeclineReason') ??\n readString(payload, 'decline_code') ??\n readString(nestedError, 'decline_code');\n\n return new FloPayError(message, 'api_error', {\n ...(code ? { code } : {}),\n ...(declineCode ? { declineCode } : {}),\n });\n}\n\nexport async function buildFloPayApiErrorFromResponse(\n response: Response,\n fallbackMessage: string,\n): Promise<FloPayError> {\n const payload = await response.json().catch(() => null) as ApiErrorPayload;\n return buildFloPayApiError(payload, fallbackMessage);\n}\n\nexport function mapPayPalIntentStatusToPaymentResult(\n status: string | null | undefined,\n): PaymentResult['status'] {\n if (status === 'succeeded') {\n return 'succeeded';\n }\n\n if (status === 'processing' || status === 'requires_capture') {\n return 'processing';\n }\n\n return 'failed';\n}\n\nexport type StripePaymentIntentLike = {\n id?: string;\n status?: string;\n payment_method?: string | { id?: string | null } | null;\n};\n\ntype PaymentIntentRetriever = {\n retrievePaymentIntent?: (clientSecret: string) => Promise<{\n paymentIntent?: StripePaymentIntentLike | null;\n error?: { message?: string; code?: string };\n }>;\n retrieveSetupIntent?: (clientSecret: string) => Promise<{\n setupIntent?: StripePaymentIntentLike | null;\n error?: { message?: string; code?: string };\n }>;\n};\n\nexport function resolvePaymentIntentPaymentMethodId(\n paymentIntent: StripePaymentIntentLike | null | undefined,\n): string | undefined {\n const paymentMethod = paymentIntent?.payment_method;\n if (typeof paymentMethod === 'string' && paymentMethod.startsWith('pm_')) {\n return paymentMethod;\n }\n if (paymentMethod && typeof paymentMethod === 'object' && typeof paymentMethod.id === 'string') {\n return paymentMethod.id;\n }\n return undefined;\n}\n\nexport async function retrievePaymentIntentFromProvider(\n provider: unknown,\n clientSecret: string,\n): Promise<StripePaymentIntentLike | null> {\n const retriever = provider as PaymentIntentRetriever | null;\n\n // Trial-only / $0 checkouts confirm a SetupIntent. Stripe's\n // retrievePaymentIntent rejects `seti_` secrets, so retrieve the SetupIntent\n // instead — it exposes the same id/status/payment_method fields the caller\n // reads to drive /process.\n if (isSetupIntentClientSecret(clientSecret)) {\n if (!retriever?.retrieveSetupIntent) {\n return null;\n }\n\n const { setupIntent, error } = await retriever.retrieveSetupIntent(clientSecret);\n if (error) {\n throw new FloPayError(error.message ?? 'Failed to retrieve setup intent.', 'api_error', {\n ...(error.code ? { code: error.code } : {}),\n });\n }\n\n return setupIntent ?? null;\n }\n\n if (!retriever?.retrievePaymentIntent) {\n return null;\n }\n\n const { paymentIntent, error } = await retriever.retrievePaymentIntent(clientSecret);\n if (error) {\n throw new FloPayError(error.message ?? 'Failed to retrieve payment intent.', 'api_error', {\n ...(error.code ? { code: error.code } : {}),\n });\n }\n\n return paymentIntent ?? null;\n}\n\n/**\n * Deferred Stripe Elements mode for the wallet / Express Checkout row\n * (Apple Pay, Google Pay).\n *\n * A $0-today cart (free trial) cannot run in `payment` mode: Stripe rejects a\n * `$0` amount with \"amount must be greater than 0\", and the historic\n * `amount: totalAmount || 100` floor surfaced a misleading **$1.00** charge on\n * the wallet sheet. Those carts run in `setup` mode instead — the wallet\n * collects the card for the trial with no amount shown, matching the backend's\n * SetupIntent. Any positive amount keeps `payment` mode with the real total.\n *\n * @param amountInMinorUnits cart total due today, in the smallest currency unit.\n */\nexport function resolveWalletElementsMode(\n amountInMinorUnits: number | undefined,\n): { mode: 'setup' } | { mode: 'payment'; amount: number } {\n if (typeof amountInMinorUnits !== 'number' || !Number.isFinite(amountInMinorUnits) || amountInMinorUnits <= 0) {\n return { mode: 'setup' };\n }\n return { mode: 'payment', amount: amountInMinorUnits };\n}\n\nexport function resolveTokenizedPaymentMethodId(\n tokenizedBody: TokenizedBody | null | undefined,\n): string | undefined {\n const candidates = [\n tokenizedBody?.id,\n tokenizedBody?.originalPaymentMethodId,\n ];\n\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.startsWith('pm_')) {\n return candidate;\n }\n }\n\n return undefined;\n}\n","// Cross-component, cross-remount signal for \"this session was just /process'd\n// successfully and is mid-completion.\" Written synchronously by SplitCardForm\n// (and the saved-payment / auto-mode flows in FloPayCheckout) the moment the\n// `/process` response is OK — *before* the 1.2s success-overlay delay — so a\n// bootstrap that re-runs during the overlay window can detect that the cache\n// hit's `status: 'complete'` is from THIS journey rather than treat it as\n// a stale leftover and POST a duplicate session.\n//\n// Backed by `sessionStorage` rather than module state because:\n// 1. SplitCardForm and FloPayCheckout are different modules; sessionStorage\n// is the cheapest cross-module bus.\n// 2. It survives a real component remount (which resets useRef/useState)\n// without needing a module-level Map.\n// 3. The TTL gives natural staleness — a buyer who genuinely returns to\n// `/checkout` long after a previous successful checkout still gets the\n// \"clear stale cache and POST a fresh session\" path.\n\nconst STORAGE_KEY_PREFIX = 'flopay_recent_completion_';\nconst RECENT_COMPLETION_TTL_MS = 60 * 1000;\n\ninterface PersistedRecentCompletion {\n expiresAt: number;\n}\n\nexport function markSessionRecentlyCompleted(sessionId: string | null | undefined): void {\n if (!sessionId || typeof window === 'undefined') return;\n try {\n const payload: PersistedRecentCompletion = {\n expiresAt: Date.now() + RECENT_COMPLETION_TTL_MS,\n };\n window.sessionStorage.setItem(STORAGE_KEY_PREFIX + sessionId, JSON.stringify(payload));\n } catch {\n // sessionStorage unavailable (private mode etc.); not safety-critical.\n }\n}\n\nexport function wasSessionRecentlyCompleted(sessionId: string | null | undefined): boolean {\n if (!sessionId || typeof window === 'undefined') return false;\n try {\n const raw = window.sessionStorage.getItem(STORAGE_KEY_PREFIX + sessionId);\n if (!raw) return false;\n const parsed = JSON.parse(raw) as PersistedRecentCompletion;\n if (typeof parsed?.expiresAt !== 'number') {\n window.sessionStorage.removeItem(STORAGE_KEY_PREFIX + sessionId);\n return false;\n }\n if (parsed.expiresAt <= Date.now()) {\n window.sessionStorage.removeItem(STORAGE_KEY_PREFIX + sessionId);\n return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Internal heuristic detector for in-app browser / WebView environments where\n * PayPal and digital wallets often fail to initialize.\n *\n * `SplitCardForm` uses this as a proactive signal to avoid mounting\n * unsupported express-checkout rows before Stripe reports availability.\n * Stripe load state still covers the long tail: ad-blockers, new WebViews we\n * haven't seen, and account misconfiguration surfacing as `unavailable`.\n *\n * Tradeoffs:\n * - False positives possible. Some modern WebViews (iOS SFSafariViewController\n * on recent iOS, Chrome Custom Tabs) handle PayPal fine but match these\n * patterns. Card checkout remains available, so we accept it.\n * - False negatives possible. New social-app WebViews ship without us knowing.\n * That's why Stripe's reactive load-state collapse remains in place.\n *\n * SSR-safe: returns `false` when `navigator` is undefined.\n */\nexport function isInAppBrowser(userAgent?: string): boolean {\n const ua = userAgent ?? (typeof navigator !== 'undefined' ? navigator.userAgent : '');\n if (!ua) return false;\n\n // Named in-app browsers — most common offenders.\n // FBAN/FBAV/FB_IAB/FBIOS = Facebook + Messenger.\n // musical_ly/BytedanceWebview/TikTok = TikTok across regions.\n if (/FBAN|FBAV|FB_IAB|FBIOS|Instagram|musical_ly|BytedanceWebview|TikTok/i.test(ua)) {\n return true;\n }\n if (/Twitter|Snapchat|Pinterest|LinkedInApp|Line\\/|MicroMessenger|GSA\\//i.test(ua)) {\n return true;\n }\n\n // Generic Android WebView: Chrome UA with the `; wv)` token.\n if (/Android.*;\\s?wv\\)/.test(ua)) return true;\n\n // Generic iOS WebView: iPhone/iPad/iPod with AppleWebKit but no `Safari/`\n // token. Real Mobile Safari always emits `Safari/` — WebViews don't.\n if (/(iPhone|iPad|iPod).*AppleWebKit(?!.*Safari)/.test(ua)) return true;\n\n return false;\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { loadScript } from '@paypal/paypal-js';\nimport type { PayPalNamespace } from '@paypal/paypal-js';\nimport { PaymentAPI } from '@flopay/js';\nimport type {\n CheckoutButtonMethod,\n CheckoutSession,\n DeclineEvent,\n GatewayEnvironment,\n InlineSessionPatch,\n PaymentResult,\n TokenizedBody,\n} from '@flopay/shared';\nimport { FloPayError, SDK_VERSION, normalizeGatewayEnvironment } from '@flopay/shared';\nimport { applyFriendlyMessageOverride, buildDeclineEvent } from './checkout-utils.js';\nimport { useFloPay } from './hooks.js';\nimport {\n createTelemetryBridge,\n getFloPayTelemetryBridge,\n} from './telemetry-bridge.js';\nimport type { TelemetryCheckoutContext, TelemetryBridge } from './telemetry-bridge.js';\nimport { invokeMerchantCallback } from './merchant-callback.js';\nimport {\n EXTERNAL_METHOD_CALLBACK_GRACE_MS,\n isPopupBlockedError,\n} from './external-method-recovery.js';\n\nconst DEFAULT_BUTTON_HEIGHT = 45;\nconst DIRECT_PAYPAL_RECOVERY_MESSAGE =\n \"We couldn't open PayPal. Try again or choose another payment method.\";\nconst DIRECT_PAYPAL_RECOVERY_ACTION_STYLE: React.CSSProperties = {\n width: '100%',\n minHeight: DEFAULT_BUTTON_HEIGHT,\n margin: '0 0 0.5rem',\n padding: '0.75rem 0.875rem',\n border: '1px solid #2563eb',\n borderRadius: 8,\n background: '#eff6ff',\n color: '#1d4ed8',\n fontSize: '0.95rem',\n fontWeight: 700,\n cursor: 'pointer',\n};\n\ninterface DirectPayPalAttemptContext {\n generation: number;\n surfaceKey: number;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n}\n\nfunction buildDirectPayPalRecoveryMessage(popupBlocked: boolean): string {\n return popupBlocked\n ? `${DIRECT_PAYPAL_RECOVERY_MESSAGE} Allow pop-ups for this site, then try again.`\n : DIRECT_PAYPAL_RECOVERY_MESSAGE;\n}\n\n/**\n * Overrides that `SplitCardForm`'s tokenized-body dispatcher uses to apply a\n * `runBeforeButtonClick` patch to the in-flight processPayment call. Kept in\n * sync structurally with `TokenizedBodyOverrides` in `split-card-form.tsx`.\n */\nexport interface DirectPayPalTokenizedOverrides {\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n}\n\n/**\n * Internal handler signature aligned with `SplitCardForm`'s tokenized-body\n * dispatcher. Direct PayPal completes via the backend's process endpoint and\n * never produces a Stripe PaymentIntent, so we still forward a synthetic\n * `TokenizedBody` describing the captured order, optionally with the\n * session/account patch captured at click-time.\n */\nexport type DirectPayPalTokenizedHandler = (\n body: TokenizedBody,\n overrides?: DirectPayPalTokenizedOverrides,\n) => void;\n\n/** Click-time `runBeforeButtonClick` result, structurally compatible with `SplitCardForm`. */\nexport interface DirectPayPalBeforeButtonClickResult {\n proceed: boolean;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n}\n\n/**\n * Click-time gate. Mirrors `RunBeforeButtonClick` in `SplitCardForm`: lets the\n * consumer patch the session/account before PayPal creates the order, and lets\n * them abort the click entirely by returning `proceed: false`.\n */\nexport type DirectPayPalRunBeforeButtonClick = (\n method: CheckoutButtonMethod,\n) => Promise<DirectPayPalBeforeButtonClickResult>;\n\nexport type DirectPayPalTechnicalFailureHandler = (\n method: 'paypal',\n err: unknown,\n options?: { code?: string; popupBlocked?: boolean },\n) => void;\n\nexport interface DirectPayPalButtonProps {\n /** Checkout session ID. */\n sessionId: string;\n /**\n * Session-bound checkout token returned by session creation. Forwarded as\n * `x-checkout-session-token` on every continuation request — required by\n * post-#640 backends. `FloPayCheckout` plumbs this prop automatically.\n */\n nonce?: string;\n /** Billing API base URL. */\n billingApiUrl: string;\n /** Buyer email. */\n email?: string;\n /** PayPal client identifier (`gateways.paypal.publishableKey`). */\n clientId: string;\n /** Gateway environment, drives the sandbox/live SDK script. */\n environment?: GatewayEnvironment;\n /** ISO 4217 currency code. */\n currency: string;\n /** Whether the session is a subscription (drives intent + flow selection). */\n isSubscription: boolean;\n /**\n * If provided, called with the tokenized body once PayPal capture\n * completes. When omitted, the component processes payment internally.\n */\n onTokenizedBody?: DirectPayPalTokenizedHandler;\n /** Called when the full self-contained payment flow succeeds. */\n onComplete?: (result: PaymentResult) => void;\n /** Called when an error occurs. */\n onErrorChange?: (error: string | null) => void;\n /** Decline emitter (mirrors SplitCardForm semantics). */\n onDecline?: (decline: DeclineEvent) => void;\n /** Called for post-click technical failures before PayPal authorization completes. */\n onTechnicalFailure?: DirectPayPalTechnicalFailureHandler;\n /** External processing state. */\n isProcessing?: boolean;\n /** Notify the parent of the loading state for placeholder swapping. */\n onLoadStateChange?: (ready: boolean) => void;\n /** Tracks button-click for analytics. */\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n /**\n * Click-time gate (runs before PayPal creates the order). When provided, the\n * returned patch is applied to the in-flight create-intent and tokenized\n * dispatch so callers using `onBeforeButtonClick` see the same session/email\n * the Stripe-rendered PayPal flow does.\n */\n runBeforeButtonClick?: DirectPayPalRunBeforeButtonClick;\n /** Backing session — used for self-contained accountData population. */\n session?: CheckoutSession | null;\n /**\n * Pre-existing PayPal Order id (or Subscription id when `isSubscription` is\n * true) to bind the button to. When set, the button skips its usual\n * `POST /v1/checkouts/payments/intents` round-trip on click and feeds this\n * id straight into PayPal's create-order / create-subscription callback.\n *\n * Used by `SplitCardForm`'s `paypal_direct_required` retry path: backend\n * creates a fresh PayPal order after a stalled process attempt and returns\n * its id; the SDK re-renders this button bound to that id so the buyer can\n * confirm with one more click without the backend re-creating the order on\n * each retry.\n *\n * Changing this value remounts the PayPal SDK so the new createOrder\n * binding takes effect (PayPal's render() options aren't live-updatable).\n */\n existingOrderId?: string;\n /** Flo-owned privacy-safe telemetry is enabled by default; set `false` to opt out. */\n telemetry?: boolean;\n /**\n * When true, renders an on-screen lifecycle tracer panel above the button\n * (mount, loadScript, eligibility, render, errors). Intended for debugging\n * in-app browsers (Facebook IAB, etc.) where remote console access is\n * impractical. Off by default — leave disabled in production.\n */\n debug?: boolean;\n}\n\ninterface InstrumentedDirectPayPalButtonProps extends DirectPayPalButtonProps {\n telemetryContext?: TelemetryCheckoutContext;\n}\n\ninterface CreatePaypalOrderResponseData {\n /** Order ID for one-time payments. */\n id?: string;\n /** Approval URL the buyer is redirected to (in-app browser flow). */\n approveUrl?: string;\n}\n\n/**\n * Direct PayPal renderer powered by the official PayPal JS SDK.\n *\n * Renders inside Facebook / Instagram / Meta in-app browsers where Stripe's\n * PayPal ExpressCheckoutElement breaks. Selection between this and the Stripe-\n * rendered PayPal happens at the caller site based on whether the session\n * advertises `gateways.paypal.publishableKey`.\n */\nfunction DirectPayPalButtonImplementation({\n sessionId,\n nonce,\n billingApiUrl,\n email,\n clientId,\n environment,\n currency,\n isSubscription,\n onTokenizedBody,\n onComplete,\n onErrorChange,\n onDecline,\n onTechnicalFailure,\n isProcessing = false,\n onLoadStateChange,\n onButtonClick,\n runBeforeButtonClick,\n session,\n existingOrderId,\n telemetry,\n telemetryContext,\n debug = false,\n}: InstrumentedDirectPayPalButtonProps): React.ReactElement | null {\n const flopay = useFloPay();\n const standaloneTelemetry = useMemo(() => {\n if (flopay) return null;\n const reporter = createTelemetryBridge({\n billingApiUrl,\n sdkPackage: '@flopay/react',\n sdkVersion: SDK_VERSION,\n enabled: telemetry !== false,\n });\n reporter.setCheckoutContext(telemetryContext ?? {});\n reporter.beginCheckout(telemetryContext ?? {});\n return reporter;\n }, [\n billingApiUrl,\n flopay,\n telemetry,\n telemetryContext?.checkoutMode,\n telemetryContext?.layout,\n ]);\n const floPayTelemetry = useMemo(() => getFloPayTelemetryBridge(flopay), [flopay]);\n useEffect(() => () => {\n if (!standaloneTelemetry) return;\n void standaloneTelemetry.flush()\n .catch(() => {})\n .finally(() => standaloneTelemetry.destroy());\n }, [standaloneTelemetry]);\n const telemetrySource = useMemo(() => ({\n error: (input: Parameters<TelemetryBridge['error']>[0]) => {\n if (floPayTelemetry) floPayTelemetry.error(input);\n else standaloneTelemetry?.error(input);\n },\n log: (input: Parameters<TelemetryBridge['log']>[0]) => {\n if (floPayTelemetry) floPayTelemetry.log(input);\n else standaloneTelemetry?.log(input);\n },\n performance: (input: Parameters<TelemetryBridge['performance']>[0]) => {\n if (floPayTelemetry) floPayTelemetry.performance(input);\n else standaloneTelemetry?.performance(input);\n },\n terminal: (input: Parameters<TelemetryBridge['terminal']>[0]) => {\n if (floPayTelemetry) floPayTelemetry.terminal(input);\n else standaloneTelemetry?.terminal(input);\n },\n startTiming: () => floPayTelemetry?.now() ?? standaloneTelemetry?.now() ?? 0,\n elapsed: (startedAt: number) => floPayTelemetry?.elapsed(startedAt)\n ?? Math.max(0, (standaloneTelemetry?.now() ?? startedAt) - startedAt),\n }), [floPayTelemetry, standaloneTelemetry]);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const providerStartedAt = useRef(0);\n const focusTargetRef = useRef<HTMLButtonElement | null>(null);\n const pendingProviderFocusRef = useRef(false);\n const [ready, setReady] = useState(false);\n const [renderGeneration, setRenderGeneration] = useState(0);\n const activeRenderGenerationRef = useRef(0);\n const [showRetryFocusTarget, setShowRetryFocusTarget] = useState(false);\n // `failed` flips to true when PayPal can't load/render at all — SDK script\n // failure, ineligibility, render rejection, or a zoid lifecycle teardown.\n // It hides the loading placeholder (and the whole row) so users don't see\n // a perpetual skeleton when PayPal is unavailable.\n const [failed, setFailed] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const baseUrl = useMemo(() => billingApiUrl.replace(/\\/+$/, ''), [billingApiUrl]);\n\n // Optional on-screen lifecycle tracer, gated by the `debug` prop. Each\n // lifecycle stage appends a line. Use this for IAB debugging (Facebook,\n // Instagram, TikTok, etc.) where console access is impractical. When\n // `debug` is false the writes are no-ops, so there's no state churn or\n // memory cost in production.\n const [debugLines, setDebugLines] = useState<string[]>([]);\n const appendDebug = (line: string) => {\n if (!debug) return;\n setDebugLines((prev) => [...prev, `${new Date().toISOString().slice(11, 23)} ${line}`]);\n };\n\n // Ref-pin every callback so the render effect below can read the latest\n // handler without listing them as dependencies. Without this, an unstable\n // parent callback (e.g. an inline `onTokenizedBody={(body) => …}`) re-fires\n // the effect on every render, which tears down PayPal's buttons mid-render\n // and surfaces as \"Detected container element removed from DOM\".\n const onTokenizedBodyRef = useRef(onTokenizedBody);\n const onCompleteRef = useRef(onComplete);\n const onErrorChangeRef = useRef(onErrorChange);\n const onDeclineRef = useRef(onDecline);\n const onTechnicalFailureRef = useRef(onTechnicalFailure);\n const onButtonClickRef = useRef(onButtonClick);\n const onLoadStateChangeRef = useRef(onLoadStateChange);\n const runBeforeButtonClickRef = useRef(runBeforeButtonClick);\n const sessionRef = useRef(session);\n const emailRef = useRef(email);\n const nonceRef = useRef(nonce);\n // Captures the latest `runBeforeButtonClick` patch so the in-flight\n // create-intent and tokenized dispatch can use the patched sessionId/nonce/email\n // even though the PayPal SDK callbacks closed over the original props at\n // mount-time. Cleared on cancel/teardown to avoid stale patches leaking into\n // a later click.\n const beforeClickRef = useRef<DirectPayPalAttemptContext | null>(null);\n const attemptGenerationRef = useRef(0);\n const attemptRef = useRef<{\n generation: number;\n timer: ReturnType<typeof setTimeout> | null;\n yieldedControl: boolean;\n } | null>(null);\n const invalidatedAttemptGenerationRef = useRef<number | null>(null);\n const attemptContextBySurfaceRef = useRef(new Map<number, DirectPayPalAttemptContext>());\n const approvalContextByTokenRef = useRef(new Map<string, DirectPayPalAttemptContext>());\n useEffect(() => { onTokenizedBodyRef.current = onTokenizedBody; }, [onTokenizedBody]);\n useEffect(() => { onCompleteRef.current = onComplete; }, [onComplete]);\n useEffect(() => { onErrorChangeRef.current = onErrorChange; }, [onErrorChange]);\n useEffect(() => { onDeclineRef.current = onDecline; }, [onDecline]);\n useEffect(() => { onTechnicalFailureRef.current = onTechnicalFailure; }, [onTechnicalFailure]);\n useEffect(() => { onButtonClickRef.current = onButtonClick; }, [onButtonClick]);\n useEffect(() => { onLoadStateChangeRef.current = onLoadStateChange; }, [onLoadStateChange]);\n useEffect(() => { runBeforeButtonClickRef.current = runBeforeButtonClick; }, [runBeforeButtonClick]);\n useEffect(() => { sessionRef.current = session; }, [session]);\n useEffect(() => { emailRef.current = email; }, [email]);\n useEffect(() => { nonceRef.current = nonce; }, [nonce]);\n useEffect(() => { activeRenderGenerationRef.current = renderGeneration; }, [renderGeneration]);\n useEffect(() => {\n if (showRetryFocusTarget) focusTargetRef.current?.focus();\n }, [showRetryFocusTarget, renderGeneration]);\n\n const focusRetryTarget = useCallback(() => {\n window.setTimeout(() => {\n focusTargetRef.current?.focus();\n }, 0);\n }, []);\n\n const remountPayPalButtons = useCallback(() => {\n setReady(false);\n setRenderGeneration((current) => current + 1);\n }, []);\n\n const focusPayPalSurface = useCallback(() => {\n setShowRetryFocusTarget(false);\n const target = containerRef.current?.querySelector<HTMLElement>(\n 'iframe, button, [tabindex]:not([tabindex=\"-1\"])',\n );\n (target ?? containerRef.current)?.focus?.();\n }, []);\n useEffect(() => {\n if (!ready || !pendingProviderFocusRef.current) return;\n pendingProviderFocusRef.current = false;\n focusPayPalSurface();\n }, [focusPayPalSurface, ready, renderGeneration]);\n\n const notifyTechnicalFailure = useCallback((\n err: unknown,\n options?: { code?: string; popupBlocked?: boolean },\n ) => {\n const handler = onTechnicalFailureRef.current;\n if (handler) {\n handler('paypal', err, options);\n return;\n }\n onErrorChangeRef.current?.(\n buildDirectPayPalRecoveryMessage(options?.popupBlocked ?? isPopupBlockedError(err)),\n );\n }, []);\n\n const clearAttemptTimer = () => {\n if (attemptRef.current?.timer) {\n clearTimeout(attemptRef.current.timer);\n attemptRef.current.timer = null;\n }\n };\n const startAttempt = () => {\n clearAttemptTimer();\n const generation = attemptGenerationRef.current + 1;\n attemptGenerationRef.current = generation;\n invalidatedAttemptGenerationRef.current = null;\n attemptRef.current = { generation, timer: null, yieldedControl: false };\n setShowRetryFocusTarget(false);\n return generation;\n };\n const finishAttempt = (generation?: number) => {\n if (generation !== undefined && attemptRef.current?.generation !== generation) return false;\n clearAttemptTimer();\n attemptRef.current = null;\n invalidatedAttemptGenerationRef.current = null;\n return true;\n };\n const invalidateAttempt = (options?: {\n generation?: number;\n remount?: boolean;\n showRetry?: boolean;\n focus?: boolean;\n }) => {\n const generation =\n options?.generation ?? attemptRef.current?.generation ?? attemptGenerationRef.current;\n if (!options?.generation || attemptRef.current?.generation === generation) {\n clearAttemptTimer();\n attemptRef.current = null;\n }\n invalidatedAttemptGenerationRef.current = generation;\n if (options?.showRetry) setShowRetryFocusTarget(true);\n if (options?.remount) remountPayPalButtons();\n if (options?.focus !== false) focusRetryTarget();\n };\n const isAttemptActive = (generation: number) => (\n attemptRef.current?.generation === generation\n && invalidatedAttemptGenerationRef.current !== generation\n );\n const armMissingCallbackRecovery = (attempt: NonNullable<typeof attemptRef.current>) => {\n if (typeof document !== 'undefined' && document.visibilityState !== 'visible') return;\n\n clearAttemptTimer();\n attempt.timer = setTimeout(() => {\n if (attemptRef.current?.generation !== attempt.generation) return;\n attemptRef.current = null;\n invalidatedAttemptGenerationRef.current = attempt.generation;\n notifyTechnicalFailure(\n new Error('External payment method returned without a terminal callback.'),\n { code: 'external_method_missing_terminal_callback' },\n );\n setShowRetryFocusTarget(true);\n remountPayPalButtons();\n focusRetryTarget();\n }, EXTERNAL_METHOD_CALLBACK_GRACE_MS);\n };\n const scheduleMissingCallbackRecovery = () => {\n const attempt = attemptRef.current;\n if (!attempt?.yieldedControl) return;\n armMissingCallbackRecovery(attempt);\n };\n const markAttemptYieldedControl = () => {\n const attempt = attemptRef.current;\n if (!attempt) return;\n attempt.yieldedControl = true;\n clearAttemptTimer();\n };\n const registerApprovalContext = (token: string) => {\n const context = beforeClickRef.current;\n if (context) {\n approvalContextByTokenRef.current.set(token, context);\n }\n return token;\n };\n useEffect(() => {\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'visible') {\n scheduleMissingCallbackRecovery();\n } else {\n markAttemptYieldedControl();\n }\n };\n document.addEventListener('visibilitychange', handleVisibilityChange);\n window.addEventListener('focus', scheduleMissingCallbackRecovery);\n window.addEventListener('blur', markAttemptYieldedControl);\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n window.removeEventListener('focus', scheduleMissingCallbackRecovery);\n window.removeEventListener('blur', markAttemptYieldedControl);\n clearAttemptTimer();\n };\n }, []);\n\n useEffect(() => {\n // Parent's `directPaypalReady` drives the divider visibility — keep it\n // false while we're still trying, true once PayPal is interactive, and\n // false again if we've definitively failed.\n invokeMerchantCallback(() => onLoadStateChangeRef.current?.(ready && !failed));\n }, [ready, failed]);\n\n // Collapse FloPay's `stage`/`production` aliases down to the gateway-native\n // `sandbox`/`live` pair PayPal's SDK actually understands. Done up-front so\n // every downstream check (the debug trace, the loadScript options, the\n // dataNamespace branch) sees a single canonical value.\n const normalizedEnv = normalizeGatewayEnvironment(environment);\n\n useEffect(() => {\n // FloPay/DirectPayPal-debug\n const maskedClient = clientId ? `${clientId.slice(0, 6)}…(len ${clientId.length})` : '(empty)';\n const ua = typeof navigator !== 'undefined' ? navigator.userAgent : '(no navigator)';\n appendDebug(`mount clientId=${maskedClient} env=${environment ?? '(unset)'}→${normalizedEnv ?? 'live'} ccy=${currency} sub=${isSubscription}`);\n appendDebug(`ua=${ua.slice(0, 80)}${ua.length > 80 ? '…' : ''}`);\n\n if (!clientId) {\n appendDebug('FAIL: clientId empty — gateway misconfigured');\n setFailed(true);\n telemetrySource.error({\n errorCode: 'CONFIGURATION_INVALID',\n stage: 'provider_load',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'provider_sdk',\n });\n // Silent on-screen: PayPal row simply doesn't render. Other gateways\n // (card, wallets) stay interactive. See markRenderFailed for the same\n // policy applied to script-load/ineligibility/render failures.\n console.error('[FloPay] DirectPayPal: clientId empty — gateway misconfigured');\n return;\n }\n if (!containerRef.current) {\n appendDebug('FAIL: containerRef not attached');\n return;\n }\n providerStartedAt.current = telemetrySource.startTiming();\n telemetrySource.log({\n name: 'provider.load.started',\n stage: 'provider_load',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n\n let cancelled = false;\n // `activeButtons` is only set AFTER `render()` resolves successfully —\n // calling `buttons.close()` while zoid is still mounting the iframe\n // surfaces as \"zoid destroyed all components\" + a stuck placeholder. The\n // render `.then` handler handles the \"unmounted during render\" case\n // itself (sees `cancelled` and closes its own buttons), so cleanup only\n // needs to handle fully-mounted teardown.\n let activeButtons: { close: () => Promise<void> } | null = null;\n let overlayStartedAt: number | null = null;\n const finishOverlay = () => {\n if (overlayStartedAt === null) return;\n telemetrySource.log({\n name: 'provider.overlay.returned',\n stage: 'overlay_return',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.performance({\n stage: 'overlay_return',\n durationMs: telemetrySource.elapsed(overlayStartedAt),\n durationMode: 'buyer',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n overlayStartedAt = null;\n };\n // Tracks whether `render()` has resolved. PayPal's `onError` fires for\n // both render-time failures (SDK script error, ineligibility, iframe\n // mount issues) AND runtime failures after the user clicks (e.g.\n // `createOrder` rejection bubbling up from the backend). Render-time\n // failures should hide the button — runtime failures must not, or the\n // user loses the ability to retry.\n let rendered = false;\n const container = containerRef.current;\n\n // Diagnostics owned by the effect so cleanup can tear them down. The\n // observer + watchdog snapshot the DOM around `buttons.render()` so we\n // can see *why* a render hangs (CAPTCHA challenge swap, zero-size parent,\n // hidden tab) — render() never resolves or rejects in those cases, so\n // the existing trace dead-ends at \"render:start\" with no further signal.\n let containerObserver: MutationObserver | null = null;\n let perfObserver: PerformanceObserver | null = null;\n const watchdogTimers: ReturnType<typeof setTimeout>[] = [];\n const formatDims = (el: Element | null): string => {\n if (!el || typeof el.getBoundingClientRect !== 'function') return '(no rect)';\n const rect = el.getBoundingClientRect();\n return `${Math.round(rect.width)}×${Math.round(rect.height)}`;\n };\n const classifyIframeSrc = (raw: string | null): string => {\n if (!raw) return '(empty)';\n try {\n const url = new URL(raw, typeof window !== 'undefined' ? window.location.href : 'https://localhost');\n const path = url.pathname.toLowerCase();\n if (path.includes('checkcaptcha') || path.includes('captcha')) return `CAPTCHA(${url.host}${path})`;\n if (path.includes('risk') || path.includes('challenge')) return `RISK(${url.host}${path})`;\n if (path.includes('smart/buttons')) return `smart-buttons(${url.host})`;\n return `${url.host}${path}`.slice(0, 100);\n } catch {\n return raw.slice(0, 80);\n }\n };\n // Describe an iframe's loaded content: zoid uses both `src` (network) and\n // `srcdoc` (inline HTML, no network roundtrip). When both are empty the\n // iframe is genuinely blank — which means zoid's content injection never\n // completed and is a strong signal of a postMessage handshake failure.\n const describeIframe = (frame: Element): string => {\n const src = frame.getAttribute('src');\n const srcdoc = frame.getAttribute('srcdoc');\n const name = frame.getAttribute('name');\n const sandbox = frame.getAttribute('sandbox');\n const parts: string[] = [];\n if (src) parts.push(`src=${classifyIframeSrc(src)}`);\n if (srcdoc) parts.push(`srcdoc[${srcdoc.length}ch]`);\n if (!src && !srcdoc) parts.push('src=(empty) srcdoc=(empty)');\n if (name) parts.push(`name=${name.slice(0, 40)}`);\n if (sandbox !== null) parts.push(`sandbox=\"${sandbox.slice(0, 40)}\"`);\n return parts.join(' ');\n };\n // Peek inside an iframe's actual rendered document. Zoid uses\n // `contentDocument.write()` for same-origin frames, which doesn't update\n // src/srcdoc attributes — so the attributes can lie. This is the\n // ground-truth: if body has children, content IS there (and the issue is\n // render() not resolving); if body is empty, zoid never wrote into it\n // (handshake failure). Cross-origin throws, which is itself useful — it\n // means PayPal navigated the frame to its own origin (network worked).\n const inspectFrameContent = (frame: Element): string => {\n if (!(frame instanceof HTMLIFrameElement)) return '';\n try {\n const cd = frame.contentDocument;\n if (!cd) return 'cd=null';\n const bodyChildren = cd.body?.children.length ?? 0;\n const bodyLen = cd.body?.innerHTML.length ?? 0;\n const headLen = cd.head?.innerHTML.length ?? 0;\n return `cd=same-origin readyState=${cd.readyState} body[${bodyChildren}children,${bodyLen}ch] head[${headLen}ch]`;\n } catch (err) {\n return `cd=cross-origin(${(err as Error).message.slice(0, 30)})`;\n }\n };\n // Capture window-scoped errors and promise rejections while the lifecycle\n // is in flight. PayPal's zoid framework swallows postMessage / storage\n // failures into the console rather than rejecting render(), so capturing\n // these is often the only way to see the real cause of a hung render.\n const errorMessages: string[] = [];\n const onWindowError = (ev: ErrorEvent) => {\n const msg = ev.message ?? String(ev.error ?? '(no message)');\n if (msg && (msg.toLowerCase().includes('paypal') || msg.toLowerCase().includes('zoid') || msg.toLowerCase().includes('postrobot') || msg.toLowerCase().includes('storage'))) {\n appendDebug(`window:error ${msg.slice(0, 140)}`);\n errorMessages.push(msg);\n }\n };\n const onUnhandledRejection = (ev: PromiseRejectionEvent) => {\n const reason = ev.reason instanceof Error ? ev.reason.message : String(ev.reason ?? '(no reason)');\n if (reason && (reason.toLowerCase().includes('paypal') || reason.toLowerCase().includes('zoid') || reason.toLowerCase().includes('postrobot') || reason.toLowerCase().includes('storage'))) {\n appendDebug(`window:rejection ${reason.slice(0, 140)}`);\n errorMessages.push(reason);\n }\n };\n if (debug && typeof window !== 'undefined') {\n window.addEventListener('error', onWindowError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n }\n // Network telemetry: every paypal.com resource entry gets logged with\n // duration. If we see zero entries, an ad blocker / DNS filter / firewall\n // is intercepting before requests even hit the network. If we see hung\n // duration=0 entries, the request started but never completed (common\n // with privacy extensions that hold but don't reject requests).\n const paypalRequestCount = { value: 0 };\n if (debug && typeof PerformanceObserver !== 'undefined') {\n try {\n perfObserver = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n if (!entry.name.toLowerCase().includes('paypal')) continue;\n paypalRequestCount.value += 1;\n const dur = Math.round(entry.duration);\n appendDebug(`net ${dur}ms ${entry.name.slice(0, 90)}`);\n }\n });\n perfObserver.observe({ type: 'resource', buffered: true });\n } catch {\n // Older browsers may not support PerformanceObserver with type/buffered\n // syntax — fail silently, the other diagnostics still work.\n }\n }\n const stopDiagnostics = () => {\n containerObserver?.disconnect();\n containerObserver = null;\n perfObserver?.disconnect();\n perfObserver = null;\n while (watchdogTimers.length) clearTimeout(watchdogTimers.pop()!);\n if (debug && typeof window !== 'undefined') {\n window.removeEventListener('error', onWindowError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n }\n };\n\n /**\n * Zoid (PayPal's iframe framework) emits \"zoid destroyed all components\"\n * and similar lifecycle messages through `onError` whenever its\n * components are torn down — page navigation, force reload, React 18\n * StrictMode dev mount/unmount, or a parent unmounting mid-render.\n * Those events aren't payment errors; surfacing them in our error\n * banner misleads users and blocks them from completing checkout.\n */\n const isZoidLifecycleMessage = (message: string | undefined): boolean => {\n if (!message) return false;\n const lower = message.toLowerCase();\n return lower.includes('zoid destroyed')\n || lower.includes('destroyed all components')\n || lower.includes('window closed')\n || lower.includes('detected container element removed');\n };\n\n const forwardError = (message: string) => {\n if (cancelled) return;\n if (isZoidLifecycleMessage(message)) return;\n const friendly = applyFriendlyMessageOverride(message) ?? message;\n invokeMerchantCallback(() => onErrorChangeRef.current?.(friendly));\n };\n\n /**\n * Used by load/render-time error paths: hides the placeholder (and the\n * whole row) so users don't stare at a perpetual skeleton when PayPal\n * can't load. Logs to console for diagnostics but never calls\n * `onErrorChange` — pre-render failures (script load 400, ineligibility,\n * render rejection) would otherwise paint a checkout-blocking red banner\n * even though card / wallet / other gateways remain usable. The row\n * silently collapses; the parent's `directPaypalReady` stays false.\n *\n * Zoid lifecycle messages (e.g. \"zoid destroyed all components\") fire\n * during mount/unmount churn — most commonly React StrictMode's\n * mount → cleanup → mount cycle in dev. On iOS Facebook IAB the surviving\n * mount's render rejects with this message even though nothing is wrong,\n * because WKWebView's iframe init races the rapid cycle. Treat these as\n * transient: don't flip `failed = true` (which would permanently hide the\n * button) — the deferred-load guard above prevents the double-load that\n * triggered this in the first place, so a fresh attempt should succeed.\n */\n const markRenderFailed = (message: string) => {\n if (cancelled) return;\n if (isZoidLifecycleMessage(message)) {\n appendDebug(`markRenderFailed:skip-zoid msg=${message.slice(0, 80)}`);\n return;\n }\n setFailed(true);\n if (!message.includes('paypal_ineligible')) {\n telemetrySource.error({\n errorCode: 'PROVIDER_LOAD_FAILED',\n stage: 'provider_load',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'provider_sdk',\n });\n }\n console.error('[FloPay] DirectPayPal load/render failure:', message);\n };\n\n // Reset failure state at the start of every effect run so a config\n // change (clientId/environment/sessionId/currency etc.) re-attempts the\n // render cleanly rather than inheriting a sticky failure from the\n // previous configuration.\n setFailed(false);\n\n const dispatchTokenizedBody = async (\n body: TokenizedBody,\n prepared = beforeClickRef.current,\n ) => {\n const effectiveSessionId = prepared?.sessionId ?? sessionId;\n if (onTokenizedBodyRef.current) {\n await onTokenizedBodyRef.current(body, {\n sessionId: effectiveSessionId,\n accountPatch: prepared?.accountPatch,\n nonce: prepared?.nonce,\n });\n return;\n }\n const processingStartedAt = telemetrySource.startTiming();\n telemetrySource.log({\n name: 'payment.processing.started',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n const finishProcessing = () => {\n telemetrySource.log({\n name: 'payment.processing.completed',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.performance({\n stage: 'processing',\n durationMs: telemetrySource.elapsed(processingStartedAt),\n durationMode: 'machine',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n };\n try {\n const currentSession = sessionRef.current;\n const currentEmail = prepared?.accountPatch?.email ?? emailRef.current;\n const effectiveUserId = prepared?.accountPatch?.userId\n ?? currentSession?.customer?.id\n ?? currentSession?.accountData?.userId\n ?? '';\n const api = new PaymentAPI(baseUrl, { telemetry: false });\n const response = await api.processPayment(\n effectiveUserId,\n {\n sessionId: effectiveSessionId,\n nonce: prepared?.nonce ?? nonceRef.current,\n tokenizedData: body,\n accountData: {\n userId: effectiveUserId,\n email: currentEmail ?? currentSession?.customer?.email ?? '',\n firstName: prepared?.accountPatch?.firstName\n ?? currentSession?.customer?.firstName\n ?? currentSession?.accountData?.firstName\n ?? '',\n lastName: prepared?.accountPatch?.lastName\n ?? currentSession?.customer?.lastName\n ?? currentSession?.accountData?.lastName\n ?? '',\n country: prepared?.accountPatch?.country\n ?? currentSession?.customer?.country\n ?? currentSession?.accountData?.country\n ?? undefined,\n zip: prepared?.accountPatch?.zip\n ?? currentSession?.customer?.zip\n ?? currentSession?.accountData?.zip\n ?? undefined,\n },\n },\n );\n\n if (response.ok) {\n finishProcessing();\n telemetrySource.terminal({\n outcome: 'payment_succeeded',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n } else {\n const json = (await response.json().catch(() => null)) as Record<string, unknown> | null;\n const rawMessage = (json?.['message'] as string | undefined) ?? 'PayPal payment failed.';\n const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;\n finishProcessing();\n if (typeof json?.['declineCode'] === 'string') {\n telemetrySource.terminal({\n outcome: 'payment_declined',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n } else {\n telemetrySource.error({\n errorCode: 'PAYMENT_PROCESSING_FAILED',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'process_payment',\n statusClass: response.status >= 500\n ? '5xx'\n : response.status >= 400\n ? '4xx'\n : response.status >= 300\n ? '3xx'\n : 'unknown',\n });\n }\n forwardError(message);\n invokeMerchantCallback(() =>\n onDeclineRef.current?.(buildDeclineEvent('paypal', message, {\n code: json?.['code'] as string | undefined,\n declineCode: json?.['declineCode'] as string | undefined,\n })));\n return;\n }\n } catch (err) {\n finishProcessing();\n telemetrySource.error({\n errorCode: 'NETWORK_REQUEST_FAILED',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'process_payment',\n statusClass: 'network_error',\n });\n const rawMessage = err instanceof Error ? err.message : 'PayPal payment failed.';\n const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;\n forwardError(message);\n invokeMerchantCallback(() =>\n onDeclineRef.current?.(buildDeclineEvent('paypal', message)));\n return;\n }\n\n invokeMerchantCallback(() =>\n onCompleteRef.current?.({ status: 'succeeded', checkoutMethod: 'paypal' }));\n };\n\n const createPaypalIntent = async (fallbackMessage: string): Promise<string> => {\n const prepared = beforeClickRef.current;\n const effectiveSessionId = prepared?.sessionId ?? sessionId;\n const effectiveEmail = prepared?.accountPatch?.email ?? emailRef.current;\n // isPaypal must be string 'true' — backend checks === 'true'.\n const intentHeaders: Record<string, string> = { 'Content-Type': 'application/json' };\n const currentNonce = prepared?.nonce ?? nonceRef.current;\n if (currentNonce) intentHeaders['x-checkout-session-token'] = currentNonce;\n telemetrySource.log({\n name: 'payment.intent.started',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'intent_create',\n });\n const response = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {\n method: 'POST',\n headers: intentHeaders,\n body: JSON.stringify({\n sessionId: effectiveSessionId,\n email: effectiveEmail,\n paymentMethodType: 'paypal',\n isPaypal: 'true',\n }),\n });\n const json = (await response.json().catch(() => null)) as\n | { data?: CreatePaypalOrderResponseData; message?: string }\n | null;\n if (!response.ok) {\n throw new Error(json?.message ?? fallbackMessage);\n }\n const id = json?.data?.id;\n if (!id) {\n throw new Error(fallbackMessage);\n }\n telemetrySource.log({\n name: 'payment.intent.completed',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'intent_create',\n statusClass: '2xx',\n });\n return id;\n };\n\n // Defer the PayPal lifecycle by one macrotask so any rapid mount → cleanup\n // → mount cycle (React StrictMode in dev, or a parent that briefly mounts\n // us before late-arriving props like `email` cause it to re-render) has\n // finished before we touch PayPal's SDK. Without this, both the dead and\n // surviving mounts call `loadScript` in the same tick; on iOS Facebook\n // IAB the surviving mount's `render()` then rejects with \"zoid destroyed\n // all components\" because zoid's iframe init races the synchronous\n // teardown. clearTimeout in the cleanup ensures the dead mount never even\n // starts the load.\n const effectRenderGeneration = renderGeneration;\n appendDebug('loadScript:scheduled (deferred 1 tick)');\n let loadPromise: Promise<PayPalNamespace | null> | null = null;\n const startTimer = setTimeout(() => {\n if (cancelled) {\n appendDebug('loadScript:skipped (cancelled before defer ran)');\n return;\n }\n appendDebug('loadScript:start');\n // PayPal SDK uses `'production'` (not `'live'`) for prod mode, so\n // re-map after our internal normalize step.\n const paypalSdkEnv: 'sandbox' | 'production' | undefined =\n normalizedEnv === 'live' ? 'production' : normalizedEnv;\n loadPromise = loadScript({\n clientId,\n currency,\n // Subscriptions need the `subscription` vault intent; one-time payments\n // use a standard order capture.\n intent: isSubscription ? 'subscription' : 'capture',\n vault: isSubscription ? true : undefined,\n // Tell PayPal which environment the clientId belongs to. Without\n // this, PayPal defaults to live endpoints — and a sandbox clientId\n // sent to live silently stalls in zoid's prerender forever (no\n // error, no rejection).\n ...(paypalSdkEnv ? { environment: paypalSdkEnv } : {}),\n // Namespace the sandbox SDK so it can coexist with a production SDK on\n // the same page without clobbering `window.paypal`.\n ...(paypalSdkEnv === 'sandbox' ? { dataNamespace: 'paypal_sandbox' } : {}),\n });\n loadPromise\n .then((paypal) => {\n appendDebug(`loadScript:resolved cancelled=${cancelled} ns=${!!paypal} buttons=${!!paypal?.Buttons}`);\n if (cancelled || !paypal?.Buttons) {\n if (!cancelled && !paypal?.Buttons) appendDebug('FAIL: namespace missing Buttons factory');\n return;\n }\n telemetrySource.log({\n name: 'provider.availability.checked',\n stage: 'provider_ready',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n\n const handleApprove = async (data: { orderID?: string; subscriptionID?: string }) => {\n if (cancelled || activeRenderGenerationRef.current !== effectRenderGeneration) return;\n const token = data.subscriptionID ?? data.orderID ?? '';\n const context = token\n ? approvalContextByTokenRef.current.get(token)\n : attemptContextBySurfaceRef.current.get(effectRenderGeneration);\n if (!context || !isAttemptActive(context.generation)) return;\n if (!finishAttempt(context.generation)) return;\n approvalContextByTokenRef.current.delete(token);\n attemptContextBySurfaceRef.current.delete(context.surfaceKey);\n finishOverlay();\n try {\n setSubmitting(true);\n invokeMerchantCallback(() => onErrorChangeRef.current?.(null));\n if (!token) {\n throw new FloPayError(\n 'PayPal did not return an approval token.',\n 'api_error',\n { code: 'paypal_missing_token' },\n );\n }\n await dispatchTokenizedBody({\n id: token,\n isPaypal: true,\n }, context);\n } catch (err) {\n forwardError(err instanceof Error ? err.message : 'PayPal capture failed.');\n } finally {\n setSubmitting(false);\n }\n };\n\n const buttons = paypal.Buttons!({\n style: { layout: 'horizontal', height: DEFAULT_BUTTON_HEIGHT, tagline: false },\n // PayPal's SDK awaits a Promise returned from `onClick` and aborts\n // the create-order/create-subscription step when `actions.reject()`\n // is invoked. Run the consumer's `runBeforeButtonClick` here so\n // inline-session/account patches land before the order is created,\n // matching the Stripe-rendered PayPal flow.\n onClick: async (_data: unknown, actions: { resolve: () => Promise<void>; reject: () => Promise<void> }) => {\n const runner = runBeforeButtonClickRef.current;\n let prepared: Pick<\n DirectPayPalAttemptContext,\n 'accountPatch' | 'sessionId' | 'nonce'\n > = {};\n if (runner) {\n try {\n const beforeClick = await runner('paypal');\n if (!beforeClick.proceed) {\n beforeClickRef.current = null;\n attemptContextBySurfaceRef.current.delete(effectRenderGeneration);\n await actions.reject();\n return;\n }\n prepared = {\n sessionId: beforeClick.sessionId,\n accountPatch: beforeClick.accountPatch,\n nonce: beforeClick.nonce,\n };\n } catch (err) {\n appendDebug(`onClick:runBeforeButtonClick rejected msg=${(err instanceof Error ? err.message : String(err)).slice(0, 120)}`);\n beforeClickRef.current = null;\n attemptContextBySurfaceRef.current.delete(effectRenderGeneration);\n await actions.reject();\n return;\n }\n }\n invokeMerchantCallback(() => onButtonClickRef.current?.('paypal'));\n const generation = startAttempt();\n const context: DirectPayPalAttemptContext = {\n generation,\n surfaceKey: effectRenderGeneration,\n ...prepared,\n };\n beforeClickRef.current = context;\n attemptContextBySurfaceRef.current.set(effectRenderGeneration, context);\n await actions.resolve();\n telemetrySource.log({\n name: 'payment.method.selected',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.log({\n name: 'provider.popup.opened',\n stage: 'overlay_open',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.log({\n name: 'provider.overlay.opened',\n stage: 'overlay_open',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n overlayStartedAt = telemetrySource.startTiming();\n },\n // When the SDK is already holding an order/subscription id from a\n // prior backend round-trip (the `paypal_direct_required` retry\n // path), feed it straight to PayPal instead of creating a new one.\n // Otherwise fall back to the normal create-intent call.\n createOrder: isSubscription\n ? undefined\n : existingOrderId\n ? () => Promise.resolve(registerApprovalContext(existingOrderId))\n : () => createPaypalIntent('Failed to create PayPal order.')\n .then(registerApprovalContext),\n createSubscription: isSubscription\n ? existingOrderId\n ? () => Promise.resolve(registerApprovalContext(existingOrderId))\n : () => createPaypalIntent('Failed to create PayPal subscription.')\n .then(registerApprovalContext)\n : undefined,\n onApprove: handleApprove,\n onCancel: () => {\n const context = attemptContextBySurfaceRef.current.get(effectRenderGeneration) ?? beforeClickRef.current;\n if (context) attemptContextBySurfaceRef.current.delete(context.surfaceKey);\n beforeClickRef.current = null;\n finishOverlay();\n telemetrySource.terminal({\n outcome: 'payment_cancelled',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n pendingProviderFocusRef.current = true;\n invalidateAttempt({ generation: context?.generation, remount: true, focus: false });\n },\n onError: (err) => {\n if (cancelled || activeRenderGenerationRef.current !== effectRenderGeneration) return;\n const message = err instanceof Error ? err.message : 'PayPal failed to render.';\n appendDebug(`onError rendered=${rendered} msg=${message.slice(0, 120)}`);\n // Post-render: a runtime failure (e.g. backend rejected the\n // create-order/subscription call) — keep the button visible so\n // the user can retry, and route it through the parent's\n // pre-authorization technical recovery contract.\n if (rendered) {\n const context = attemptContextBySurfaceRef.current.get(effectRenderGeneration) ?? beforeClickRef.current;\n if (context && !isAttemptActive(context.generation)) return;\n if (!context && invalidatedAttemptGenerationRef.current === attemptGenerationRef.current) return;\n if (isZoidLifecycleMessage(message)) {\n finishAttempt(context?.generation);\n return;\n }\n finishOverlay();\n const lower = message.toLowerCase();\n telemetrySource.error({\n errorCode: lower.includes('popup') && lower.includes('block')\n ? 'POPUP_BLOCKED'\n : 'PROVIDER_RUNTIME_FAILED',\n stage: 'provider_ready',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'provider_sdk',\n });\n if (context) attemptContextBySurfaceRef.current.delete(context.surfaceKey);\n beforeClickRef.current = null;\n invalidateAttempt({ generation: context?.generation, remount: true, showRetry: true, focus: true });\n notifyTechnicalFailure(err, { code: 'paypal_runtime_failed' });\n return;\n }\n // Pre-render: actual render-time issue or zoid teardown; mark\n // failed so we hide the placeholder. `markRenderFailed` filters\n // zoid lifecycle messages out of the forwarded error so the\n // consumer doesn't see noise.\n markRenderFailed(message);\n },\n } as Parameters<NonNullable<typeof paypal.Buttons>>[0]);\n\n const eligible = buttons.isEligible();\n appendDebug(`isEligible=${eligible}`);\n telemetrySource.log({\n name: 'provider.eligibility.checked',\n stage: 'provider_ready',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n if (!eligible) {\n setReady(false);\n markRenderFailed(\n 'PayPal buttons are not eligible to render in this context (paypal_ineligible).',\n );\n return;\n }\n\n const typedButtons = buttons as { close: () => Promise<void> };\n\n // Pre-render container snapshot. A 0-width parent (flex column\n // collapse, display:none ancestor, etc.) is a common silent failure:\n // PayPal renders happily into a zero-size box and the user sees\n // nothing. Logging dims here catches that before render starts.\n if (debug) {\n appendDebug(`container:dims ${formatDims(container)} visibility=${typeof document !== 'undefined' ? document.visibilityState : '(no document)'}`);\n }\n\n // MutationObserver: log every PayPal injection AND every attribute\n // change. Zoid creates iframes with empty src/srcdoc first and then\n // sets the content attribute asynchronously — without `attributes:\n // true` we'd never see when (or whether) the content load actually\n // happens. The iframe's title=PayPal first appears as a childList\n // mutation; `src`/`srcdoc` then appears as an attribute mutation.\n if (debug && typeof MutationObserver !== 'undefined') {\n containerObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.type === 'childList') {\n mutation.addedNodes.forEach((node) => {\n if (!(node instanceof Element)) return;\n const tag = node.tagName.toLowerCase();\n const title = (node.getAttribute('title') ?? '').slice(0, 40);\n const detail = tag === 'iframe' ? ` ${describeIframe(node)}` : '';\n appendDebug(`child+ ${tag}${title ? ` title=\"${title}\"` : ''}${detail} dims=${formatDims(node)}`);\n });\n } else if (mutation.type === 'attributes' && mutation.target instanceof Element) {\n const target = mutation.target;\n if (target.tagName.toLowerCase() !== 'iframe') continue;\n const attr = mutation.attributeName;\n if (attr === 'src' || attr === 'srcdoc') {\n appendDebug(`attr~ iframe ${attr}=${attr === 'srcdoc' ? `[${(target.getAttribute('srcdoc') ?? '').length}ch]` : classifyIframeSrc(target.getAttribute('src'))} dims=${formatDims(target)}`);\n }\n }\n }\n });\n containerObserver.observe(container, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['src', 'srcdoc'],\n });\n }\n\n // Render watchdog. Snapshots the container + iframes at 3s/8s/15s\n // if render() hasn't resolved. Uses describeIframe so we see src,\n // srcdoc length, name (zoid uses iframe names for postMessage\n // routing), and sandbox attribute — enough to distinguish \"iframe\n // shell exists but content never loaded\" (postMessage/storage\n // failure) from \"iframe loaded but render() didn't fire\" (PayPal\n // SDK internal bug or unmounted parent).\n const snapshotContainer = (when: string) => {\n if (cancelled || rendered) return;\n const iframes = container.querySelectorAll('iframe');\n const hasStorageAccess = typeof document !== 'undefined' && 'hasStorageAccess' in document;\n appendDebug(`watchdog:${when} container=${formatDims(container)} children=${container.childElementCount} iframes=${iframes.length} visibility=${typeof document !== 'undefined' ? document.visibilityState : '(no document)'} cookies=${typeof navigator !== 'undefined' ? navigator.cookieEnabled : '?'} hasStorageAccessApi=${hasStorageAccess} paypalNetRequests=${paypalRequestCount.value}`);\n iframes.forEach((frame, i) => {\n const title = (frame.getAttribute('title') ?? '').slice(0, 40);\n appendDebug(` iframe[${i}] ${formatDims(frame)}${title ? ` title=\"${title}\"` : ''} ${describeIframe(frame)}`);\n const content = inspectFrameContent(frame);\n if (content) appendDebug(` ${content}`);\n });\n if (errorMessages.length === 0) {\n appendDebug(` (no PayPal/zoid window errors captured)`);\n }\n };\n if (debug) {\n watchdogTimers.push(setTimeout(() => snapshotContainer('3s'), 3000));\n watchdogTimers.push(setTimeout(() => snapshotContainer('8s'), 8000));\n watchdogTimers.push(setTimeout(() => snapshotContainer('15s'), 15000));\n }\n\n appendDebug('render:start');\n buttons.render(container).then(() => {\n appendDebug(`render:resolved cancelled=${cancelled}`);\n stopDiagnostics();\n if (cancelled) {\n // Component unmounted while render was in flight — render is now\n // complete, so close gracefully here instead of from cleanup\n // (cleanup couldn't see `activeButtons` yet at the time it ran).\n typedButtons.close().catch(() => {});\n return;\n }\n activeButtons = typedButtons;\n rendered = true;\n setReady(true);\n telemetrySource.log({\n name: 'provider.ready',\n stage: 'provider_ready',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.performance({\n stage: 'provider_ready',\n durationMs: telemetrySource.elapsed(providerStartedAt.current),\n durationMode: 'machine',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n }).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : 'PayPal failed to render.';\n appendDebug(`render:rejected msg=${message.slice(0, 120)}`);\n stopDiagnostics();\n markRenderFailed(message);\n });\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : 'PayPal SDK failed to load.';\n appendDebug(`loadScript:rejected msg=${message.slice(0, 120)}`);\n markRenderFailed(message);\n });\n }, 0);\n\n return () => {\n cancelled = true;\n // If the deferred load never fired (e.g. StrictMode's synchronous\n // cleanup), clearTimeout prevents the dead mount from ever calling\n // loadScript. The surviving mount's deferred timer runs next tick and\n // owns the lifecycle alone.\n clearTimeout(startTimer);\n stopDiagnostics();\n // Prefer PayPal's graceful teardown over `container.innerHTML = ''`,\n // which races the SDK's async `render()` and triggers\n // \"Detected container element removed from DOM\".\n if (activeButtons) {\n activeButtons.close().catch(() => {});\n }\n };\n }, [baseUrl, clientId, currency, environment, isSubscription, sessionId, existingOrderId, renderGeneration, telemetrySource]);\n\n // On-screen lifecycle tracer, only rendered when `debug` is true.\n const debugPanel = debug ? (\n <pre\n data-testid=\"flopay-direct-paypal-debug\"\n style={{\n margin: '0 0 8px 0',\n padding: '6px 8px',\n background: failed ? '#fef2f2' : '#f3f4f6',\n border: `1px solid ${failed ? '#fca5a5' : '#d1d5db'}`,\n borderRadius: 6,\n color: '#111827',\n font: '11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n maxHeight: 220,\n overflowY: 'auto',\n }}\n >\n {`FloPay/DirectPayPal-debug (ready=${ready} failed=${failed})`}\n {debugLines.length === 0 ? '\\n(waiting for first lifecycle event…)' : `\\n${debugLines.join('\\n')}`}\n </pre>\n ) : null;\n\n // If PayPal can't load/render at all, render nothing in production, or only\n // the diagnostic panel when `debug` is on (so the failure mode stays visible\n // on screen).\n if (failed) {\n return debug ? <div>{debugPanel}</div> : null;\n }\n\n return (\n // Single wrapper so the parent flex container sees exactly one flex item\n // (otherwise the fragment's placeholder + container become two siblings\n // and any spacing-sensitive layout has to reason about both). The wrapper\n // intentionally has no margin/padding so the parent owns all spacing.\n <div>\n {debugPanel}\n {/*\n Stacking context: the container must stay in the layout flow with\n non-zero dimensions for PayPal's zoid framework to mount its iframes —\n a `display: none` parent leaves the iframe 0×0 and `render()` never\n resolves. The placeholder absolutely-positions over the container so\n the user sees a skeleton until PayPal's button is interactive.\n */}\n <div style={{ position: 'relative', minHeight: DEFAULT_BUTTON_HEIGHT }}>\n {!ready && (\n <div\n data-testid=\"flopay-direct-paypal-placeholder\"\n style={{\n position: 'absolute',\n inset: 0,\n borderRadius: 8,\n background: '#e5e7eb',\n animation: 'flopay-pulse 1.5s ease-in-out infinite',\n pointerEvents: 'none',\n }}\n />\n )}\n <div\n key={renderGeneration}\n ref={containerRef}\n data-testid=\"flopay-direct-paypal-container\"\n tabIndex={-1}\n aria-label=\"PayPal payment method\"\n // `display: flex` makes PayPal's injected `.paypal-buttons` a flex\n // child instead of an inline-block. That kills the baseline descender\n // space that would otherwise read as a phantom margin below the\n // button (looking like a doubled flex `gap` in the parent column).\n // `opacity: 0` (not `display: none`) keeps the container measurable\n // so PayPal can render into it before `ready` flips true.\n style={{\n minHeight: DEFAULT_BUTTON_HEIGHT,\n display: 'flex',\n opacity: ready ? 1 : 0,\n }}\n aria-busy={submitting || isProcessing}\n />\n </div>\n {showRetryFocusTarget && (\n <button\n ref={focusTargetRef}\n type=\"button\"\n data-testid=\"flopay-direct-paypal-focus-target\"\n onClick={focusPayPalSurface}\n style={DIRECT_PAYPAL_RECOVERY_ACTION_STYLE}\n >\n Try PayPal again\n </button>\n )}\n </div>\n );\n}\n\n/** Public direct-PayPal surface: telemetry accepts only the boolean opt-out. */\nexport function DirectPayPalButton(\n props: DirectPayPalButtonProps,\n): React.ReactElement | null {\n return <DirectPayPalButtonImplementation {...props} />;\n}\n\n/** Internal FloPayCheckout bridge for closed SDK-owned dimensions. */\nexport function InstrumentedDirectPayPalButton(\n props: InstrumentedDirectPayPalButtonProps,\n): React.ReactElement | null {\n return <DirectPayPalButtonImplementation {...props} />;\n}\n","/**\n * Invoke merchant-owned code without allowing its failure to alter checkout.\n * Failures stay local to the merchant console and are never sent as Flo\n * telemetry because the SDK cannot act on merchant implementation errors.\n */\nexport function invokeMerchantCallback(callback: (() => unknown) | undefined): void {\n if (!callback) return;\n const reportFailure = (error: unknown): void => {\n console.error('[FloPay] Merchant callback failed; checkout continued.', error);\n };\n try {\n void Promise.resolve(callback()).catch(reportFailure);\n } catch (error) {\n reportFailure(error);\n }\n}\n","export const EXTERNAL_METHOD_CALLBACK_GRACE_MS = 600;\n\nfunction getProviderErrorMessage(err: unknown): string | undefined {\n if (err instanceof Error) return err.message;\n if (typeof err === 'object' && err !== null) {\n const message = (err as { message?: unknown }).message;\n return typeof message === 'string' ? message : undefined;\n }\n return typeof err === 'string' ? err : undefined;\n}\n\nexport function sanitizeExternalFailureCode(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return /^[a-z0-9_.-]{1,64}$/i.test(trimmed) ? trimmed : undefined;\n}\n\nexport function getProviderErrorCode(err: unknown): string | undefined {\n if (typeof err !== 'object' || err === null) return undefined;\n const record = err as { code?: unknown; type?: unknown; name?: unknown };\n return (\n sanitizeExternalFailureCode(record.code) ??\n sanitizeExternalFailureCode(record.type) ??\n sanitizeExternalFailureCode(record.name)\n );\n}\n\nexport function getProviderDeclineCode(err: unknown): string | undefined {\n if (typeof err !== 'object' || err === null) return undefined;\n return sanitizeExternalFailureCode((err as { decline_code?: unknown }).decline_code);\n}\n\nexport function isProviderDecline(err: unknown): boolean {\n if (typeof err !== 'object' || err === null) return false;\n const type = sanitizeExternalFailureCode((err as { type?: unknown }).type)?.toLowerCase();\n return type === 'card_error' || getProviderDeclineCode(err) !== undefined;\n}\n\nexport function isPopupBlockedError(err: unknown): boolean {\n const message = getProviderErrorMessage(err)?.toLowerCase() ?? '';\n const code = getProviderErrorCode(err)?.toLowerCase() ?? '';\n const signal = `${code} ${message}`;\n return signal.includes('popup') && signal.includes('block');\n}\n","import type {FloPay} from '@flopay/js';\nimport {loadFloPay, PaymentAPI} from '@flopay/js';\nimport type {\n CheckoutButtonMethod,\n CheckoutProcessError,\n CheckoutSession,\n NormalizedCheckoutSession,\n PaymentResult,\n TokenizedBody,\n} from '@flopay/shared';\nimport {FloPayError, isSetupIntentClientSecret} from '@flopay/shared';\nimport {\n applyFriendlyMessageOverride,\n buildFloPayApiError,\n resolvePaymentIntentPaymentMethodId,\n resolveTokenizedPaymentMethodId,\n retrievePaymentIntentFromProvider,\n} from './checkout-utils.js';\n\nexport const DEFAULT_SAVED_PAYMENT_DECLINE_METHOD: CheckoutButtonMethod = 'card';\n\n/** The `payment_method` shape shared by Stripe PaymentIntents and SetupIntents. */\ntype ResolvedIntentPaymentMethod = string | { id?: string | null } | null;\n\n/** The intent fields the saved-card 3DS-resume path reads, common to both kinds. */\ntype ResumeIntent = { id: string; status: string; payment_method?: ResolvedIntentPaymentMethod };\n\ntype ResumeIntentOp = { error?: { message?: string; code?: string }; intent: ResumeIntent | null } | null;\n\n/**\n * Retrieve the in-flight intent after a 3DS redirect. Trial-only / $0 saved-card\n * checkouts confirm a SetupIntent (`seti_…`), so route those through\n * `retrieveSetupIntent` — Stripe's `retrievePaymentIntent` rejects setup secrets.\n * Returns `null` when the provider can't retrieve the relevant intent kind.\n */\nasync function retrieveResumeIntent(\n stripe: import('@stripe/stripe-js').Stripe,\n clientSecret: string,\n isSetupIntent: boolean,\n): Promise<ResumeIntentOp> {\n if (isSetupIntent) {\n if (typeof stripe.retrieveSetupIntent !== 'function') return null;\n const { setupIntent, error } = await stripe.retrieveSetupIntent(clientSecret);\n return { error, intent: setupIntent ?? null };\n }\n if (typeof stripe.retrievePaymentIntent !== 'function') return null;\n const { paymentIntent, error } = await stripe.retrievePaymentIntent(clientSecret);\n return { error, intent: paymentIntent ?? null };\n}\n\n/**\n * Confirm the in-flight intent with the saved payment method after a 3DS\n * redirect. SetupIntent secrets go through `confirmCardSetup` (confirmCardPayment\n * rejects them). Returns `null` when the relevant confirm method is unavailable\n * so the caller can fall back to `handleNextAction`.\n */\nasync function confirmResumeIntent(\n stripe: import('@stripe/stripe-js').Stripe,\n clientSecret: string,\n data: { payment_method: string; return_url: string },\n isSetupIntent: boolean,\n): Promise<ResumeIntentOp> {\n if (isSetupIntent) {\n if (typeof stripe.confirmCardSetup !== 'function') return null;\n const { setupIntent, error } = await stripe.confirmCardSetup(clientSecret, data);\n return { error, intent: setupIntent ?? null };\n }\n if (typeof stripe.confirmCardPayment !== 'function') return null;\n const { paymentIntent, error } = await stripe.confirmCardPayment(clientSecret, data);\n return { error, intent: paymentIntent ?? null };\n}\n\nexport type ProcessRedirectResult = {\n type: 'paypal_redirect_required' | '3ds_required';\n threeDSecureToken: string;\n paymentMethodId?: string;\n};\n\nexport type SavedPaymentProcessResult =\n | ProcessRedirectResult\n | {\n type: 'success';\n result: PaymentResult;\n };\n\nexport type SavedPaymentFlowError = FloPayError & {\n checkoutMethod?: CheckoutButtonMethod;\n};\n\nexport function getRedirectResultFromCheckoutProcessError(\n error?: CheckoutProcessError | null,\n): ProcessRedirectResult | null {\n if (!error?.type || !error.threeDSecureToken) {\n return null;\n }\n\n if (\n error.type !== '3ds_required' &&\n error.type !== 'paypal_redirect_required'\n ) {\n return null;\n }\n\n return {\n type: error.type,\n threeDSecureToken: error.threeDSecureToken,\n paymentMethodId: error.paymentMethodId,\n };\n}\n\n/**\n * Render a provider-hosted 3DS challenge in a full-page overlay iframe and\n * resolve once the buyer completes (or abandons) it. Used by the auto-checkout\n * upsell flow when the saved PM requires a fresh 3DS challenge — the\n * SDK-rendered overlay sits at the host page level so the buyer can interact\n * with the challenge directly (mirrors the in-widget vault flow but without a\n * widget iframe to relay messages through).\n *\n * The provider's challenge eventually redirects to `/v1/vault/3ds/return`,\n * which postMessages `flopay-vault-3ds-return` back to the parent (this\n * window). The promise resolves on receipt of that message — but only when it\n * arrives from the challenge iframe (`event.source`) and the billing API\n * origin, so a sibling frame on the merchant page can't dismiss the challenge\n * early by forging the marker string. We then call `/3ds/complete` to drive the\n * backend's sync resolver to write the terminal attempt row.\n *\n * The overlay carries `role=\"dialog\"`/`aria-modal` and moves focus into the\n * iframe on mount, restoring the prior focus target on teardown, so keyboard /\n * screen-reader buyers aren't stranded on the obscured page.\n *\n * Pass `input.signal` (an `AbortSignal`) to cancel: SPA callers tie it to\n * component unmount / route change so an abandoned challenge tears down its\n * overlay and rejects immediately instead of stranding the iframe.\n *\n * Times out after 5 minutes — a buyer who walks away or whose popup blocker\n * intercepts the iframe (rare; CSP almost always permits iframing Stripe's\n * hosted challenge) gets a deterministic error path instead of locking the\n * checkout UI forever.\n */\n/**\n * Outcome the backend's `/3ds/complete` sync resolver returns to the SDK.\n * Mirrors `ThreeDsResolveOutcome` on the backend without importing it. The\n * caller branches on `status`:\n * - `succeeded` → show success\n * - `declined` → throw a decline FloPayError (no need to poll\n * session-status — the session stays `pending` on a\n * decline, so polling would just time out)\n * - `pending` / `requires_action` / `timeout` / `no_attempt` → fall back\n * to the session-status poll\n */\nexport type AutoCheckoutThreeDsOutcome =\n | { status: 'succeeded'; providerIntentId?: string | null }\n | {\n status: 'declined';\n providerIntentId?: string | null;\n declineReason?: string | null;\n gatewayDeclineReason?: string | null;\n }\n | { status: 'requires_action'; providerIntentId?: string | null; nextActionRedirectUrl?: string | null }\n | { status: 'pending'; providerIntentId?: string | null }\n | { status: 'timeout'; providerIntentId?: string | null }\n | { status: 'no_attempt' }\n | { status: 'unknown' };\n\nfunction isTerminalAutoCheckoutThreeDsOutcome(outcome: AutoCheckoutThreeDsOutcome): boolean {\n return outcome.status === 'succeeded' || outcome.status === 'declined';\n}\n\nexport async function runAutoCheckoutThreeDsChallenge(input: {\n billingApiUrl: string;\n sessionId: string;\n nonce: string;\n nextActionRedirectUrl: string;\n /**\n * Optional cancellation hook. SPA callers pass a signal tied to component\n * unmount / route change so an abandoned challenge tears down its overlay\n * (and rejects the promise) immediately, rather than leaving a full-page\n * iframe stranded until the 5-minute timeout fires.\n */\n signal?: AbortSignal;\n}): Promise<AutoCheckoutThreeDsOutcome> {\n if (typeof document === 'undefined' || typeof window === 'undefined') {\n throw new FloPayError('3DS challenge requires a browser environment.', 'api_error', {\n code: 'three_ds_no_window',\n });\n }\n if (input.signal?.aborted) {\n throw new FloPayError('Card authentication was cancelled.', 'api_error', {\n code: 'three_ds_aborted',\n });\n }\n const CHALLENGE_TIMEOUT_MS = 300_000;\n const CHALLENGE_POLL_INTERVAL_MS = 1_000;\n // Per-completion-request cap. Without it, a stalled `/3ds/complete` fetch\n // would wedge `pollInFlight` (which gates the 1s poll loop) until the\n // 5-minute overlay timeout fires.\n const COMPLETE_REQUEST_TIMEOUT_MS = 15_000;\n const completionEndpoint = `${input.billingApiUrl.replace(/\\/$/, '')}/v1/checkouts/sessions/${encodeURIComponent(\n input.sessionId,\n )}/3ds/complete`;\n const completeThreeDs = async (): Promise<AutoCheckoutThreeDsOutcome> => {\n // Combine the caller's cancellation signal with a per-request timeout:\n // cancellation propagates to the in-flight fetch (so an abandoned challenge\n // doesn't leave a request running), and a stalled request can't wedge\n // `pollInFlight` until the 5-minute overlay timeout fires.\n const controller = new AbortController();\n const onParentAbort = (): void => controller.abort();\n if (input.signal?.aborted) {\n controller.abort();\n } else {\n input.signal?.addEventListener('abort', onParentAbort);\n }\n const requestTimeout = window.setTimeout(() => controller.abort(), COMPLETE_REQUEST_TIMEOUT_MS);\n try {\n const response = await fetch(completionEndpoint, {\n method: 'POST',\n headers: {\n 'x-checkout-session-token': input.nonce,\n 'content-type': 'application/json',\n },\n body: '{}',\n signal: controller.signal,\n });\n if (!response.ok) {\n return { status: 'unknown' };\n }\n const json = (await response.json().catch(() => null)) as Record<string, unknown> | null;\n return coerceThreeDsOutcome(json);\n } catch {\n // Best-effort: the backend webhook will resolve the PI even if this call\n // fails (abort, timeout, or network blip). Don't surface it as an auth\n // failure — the session-status poll fallback in the caller handles it.\n return { status: 'unknown' };\n } finally {\n window.clearTimeout(requestTimeout);\n input.signal?.removeEventListener('abort', onParentAbort);\n }\n };\n // Remember the buyer's focus target so we can restore it when the modal tears\n // down — keyboard / screen-reader users would otherwise be stranded on the\n // obscured page behind the overlay.\n const previousFocus =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n const backdrop = document.createElement('div');\n backdrop.setAttribute('data-flopay-auto-3ds-overlay', '1');\n // Dialog semantics so assistive tech announces the challenge as a modal and\n // traps attention on it rather than the obscured page underneath.\n backdrop.setAttribute('role', 'dialog');\n backdrop.setAttribute('aria-modal', 'true');\n backdrop.setAttribute('aria-label', 'Card authentication');\n backdrop.style.cssText = [\n 'position:fixed',\n 'inset:0',\n 'z-index:2147483647',\n 'background:rgba(15,23,42,0.6)',\n 'display:flex',\n 'align-items:center',\n 'justify-content:center',\n 'padding:16px',\n ].join(';');\n const frame = document.createElement('iframe');\n frame.setAttribute('title', 'Card authentication');\n frame.setAttribute('allow', 'payment');\n frame.tabIndex = 0;\n frame.style.cssText = [\n 'width:min(100%,460px)',\n 'height:min(100%,640px)',\n 'border:0',\n 'border-radius:12px',\n 'background:#fff',\n 'box-shadow:0 12px 30px rgba(0,0,0,0.35)',\n ].join(';');\n frame.src = input.nextActionRedirectUrl;\n backdrop.appendChild(frame);\n document.body.appendChild(backdrop);\n // Move keyboard focus into the challenge once it's in the DOM.\n frame.focus();\n\n // The 3DS return page is served by the billing API (the issuer challenge\n // redirects there), so only accept the `flopay-vault-3ds-return` message when\n // it originates from our challenge iframe AND the billing API origin. This\n // stops a sibling frame on the merchant page from dismissing the challenge\n // early by forging the marker string.\n let expectedReturnOrigin: string | null = null;\n try {\n expectedReturnOrigin = new URL(input.billingApiUrl, window.location.href).origin;\n } catch {\n expectedReturnOrigin = null;\n }\n\n try {\n const polledOutcome = await new Promise<AutoCheckoutThreeDsOutcome | null>((resolve, reject) => {\n let settled = false;\n let timer = 0;\n let pollTimer = 0;\n let loadPollTimer = 0;\n let pollInFlight = false;\n const cleanup = (): void => {\n window.clearTimeout(timer);\n window.clearInterval(pollTimer);\n window.clearTimeout(loadPollTimer);\n window.removeEventListener('message', listener);\n frame.removeEventListener('load', onFrameLoad);\n input.signal?.removeEventListener('abort', onAbort);\n };\n const maybeResolveFromBackend = async (): Promise<void> => {\n if (settled || pollInFlight) return;\n pollInFlight = true;\n try {\n const outcome = await completeThreeDs();\n if (settled || !isTerminalAutoCheckoutThreeDsOutcome(outcome)) return;\n settled = true;\n cleanup();\n resolve(outcome);\n } finally {\n pollInFlight = false;\n }\n };\n const onFrameLoad = (): void => {\n window.clearTimeout(loadPollTimer);\n loadPollTimer = window.setTimeout(() => {\n void maybeResolveFromBackend();\n }, 250);\n };\n const onAbort = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(\n new FloPayError('Card authentication was cancelled.', 'api_error', {\n code: 'three_ds_aborted',\n }),\n );\n };\n const listener = (event: MessageEvent): void => {\n // Reject messages that don't come from our challenge iframe / the\n // billing API origin so an unrelated frame can't resolve the challenge.\n if (event.source !== frame.contentWindow) return;\n if (expectedReturnOrigin && event.origin !== expectedReturnOrigin) return;\n const data = event.data;\n if (!data || typeof data !== 'object') return;\n const record = data as Record<string, unknown>;\n if (record['source'] !== 'flopay-vault-3ds-return') return;\n if (settled) return;\n settled = true;\n cleanup();\n resolve(null);\n };\n timer = window.setTimeout(() => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(\n new FloPayError('Card authentication timed out.', 'api_error', {\n code: 'three_ds_timeout',\n }),\n );\n }, CHALLENGE_TIMEOUT_MS);\n pollTimer = window.setInterval(() => {\n void maybeResolveFromBackend();\n }, CHALLENGE_POLL_INTERVAL_MS);\n frame.addEventListener('load', onFrameLoad);\n window.addEventListener('message', listener);\n input.signal?.addEventListener('abort', onAbort);\n // Guard the (rare) abort that lands between the top-of-function check and\n // here — addEventListener won't fire for an already-aborted signal.\n if (input.signal?.aborted) onAbort();\n });\n\n if (polledOutcome) {\n return polledOutcome;\n }\n\n // Sync-resolve the PI on the backend. The response gives us the\n // definitive outcome — for declines the session stays `pending` so\n // polling session-status would time out; we use the response directly\n // instead.\n return await completeThreeDs();\n } finally {\n backdrop.parentNode?.removeChild(backdrop);\n // Return focus to wherever the buyer was before the modal opened.\n if (previousFocus?.isConnected) {\n previousFocus.focus();\n }\n }\n}\n\nfunction coerceThreeDsOutcome(json: Record<string, unknown> | null): AutoCheckoutThreeDsOutcome {\n if (!json || typeof json !== 'object') return { status: 'unknown' };\n const status = typeof json['status'] === 'string' ? json['status'] : 'unknown';\n const providerIntentId = typeof json['providerIntentId'] === 'string' ? json['providerIntentId'] : null;\n switch (status) {\n case 'succeeded':\n return { status: 'succeeded', providerIntentId };\n case 'declined':\n return {\n status: 'declined',\n providerIntentId,\n declineReason: typeof json['declineReason'] === 'string' ? json['declineReason'] : null,\n gatewayDeclineReason:\n typeof json['gatewayDeclineReason'] === 'string' ? json['gatewayDeclineReason'] : null,\n };\n case 'requires_action':\n return {\n status: 'requires_action',\n providerIntentId,\n nextActionRedirectUrl:\n typeof json['nextActionRedirectUrl'] === 'string' ? json['nextActionRedirectUrl'] : null,\n };\n case 'pending':\n return { status: 'pending', providerIntentId };\n case 'timeout':\n return { status: 'timeout', providerIntentId };\n case 'no_attempt':\n return { status: 'no_attempt' };\n default:\n return { status: 'unknown' };\n }\n}\n\nexport function checkoutProcessErrorToFloPayError(\n error?: CheckoutProcessError | null,\n fallbackMessage = 'Payment failed. Please try again.',\n options?: {\n checkoutMethod?: CheckoutButtonMethod;\n },\n): SavedPaymentFlowError {\n const checkoutMethod = options?.checkoutMethod\n ?? error?.checkoutMethod\n ?? (error?.type === 'paypal_redirect_required'\n ? 'paypal' as const\n : 'card' as const);\n\n const rawMessage = error?.message ?? fallbackMessage;\n const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;\n\n return Object.assign(\n new FloPayError(\n message,\n 'api_error',\n {\n code: error?.gatewayErrorCode,\n },\n ),\n { checkoutMethod },\n ) satisfies SavedPaymentFlowError;\n}\n\nfunction resolveSavedPaymentReturnUrl(session: CheckoutSession): string | undefined {\n if (typeof window !== 'undefined' && window.location.href) {\n return window.location.href;\n }\n\n return session.successUrl || session.cancelUrl || undefined;\n}\n\nfunction isStripePaymentIntentClientSecret(value: unknown): value is string {\n return typeof value === 'string'\n && value.startsWith('pi_')\n && value.includes('_secret_');\n}\n\nasync function retryOnceOnFetchFailure<T>(action: () => Promise<T>): Promise<T> {\n try {\n return await action();\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (!/failed to fetch|fetch failed/i.test(message)) {\n throw err;\n }\n\n return action();\n }\n}\n\nfunction getRedirectTokenFromProcessResponse(\n json: Record<string, unknown> | null,\n options?: { requirePaymentIntentClientSecret?: boolean },\n): string | undefined {\n const directCandidates = [\n json?.threeDSecureToken,\n json?.clientSecret,\n json?.stripeClientSecret,\n ];\n for (const candidate of directCandidates) {\n if (\n typeof candidate === 'string'\n && candidate.length > 0\n && (\n !options?.requirePaymentIntentClientSecret\n || isStripePaymentIntentClientSecret(candidate)\n )\n ) {\n return candidate;\n }\n }\n\n const nested = json?.data;\n if (nested && typeof nested === 'object') {\n const nestedRecord = nested as Record<string, unknown>;\n const nestedCandidates = [\n nestedRecord.threeDSecureToken,\n nestedRecord.clientSecret,\n nestedRecord.stripeClientSecret,\n nestedRecord.id,\n ];\n for (const candidate of nestedCandidates) {\n if (\n typeof candidate === 'string'\n && candidate.length > 0\n && (\n !options?.requirePaymentIntentClientSecret\n || isStripePaymentIntentClientSecret(candidate)\n )\n ) {\n return candidate;\n }\n }\n\n const nestedGateways = nestedRecord.gateways;\n if (nestedGateways && typeof nestedGateways === 'object') {\n const stripeGateway = (nestedGateways as Record<string, unknown>).stripe;\n if (stripeGateway && typeof stripeGateway === 'object') {\n const stripeRecord = stripeGateway as Record<string, unknown>;\n const gatewayCandidates = [\n stripeRecord.stripeClientSecret,\n stripeRecord.clientSecret,\n ];\n for (const candidate of gatewayCandidates) {\n if (\n typeof candidate === 'string'\n && candidate.length > 0\n && (\n !options?.requirePaymentIntentClientSecret\n || isStripePaymentIntentClientSecret(candidate)\n )\n ) {\n return candidate;\n }\n }\n }\n }\n }\n\n return undefined;\n}\n\nasync function recover3DSRedirectResult({\n billingApiUrl,\n sessionId,\n nonce,\n responseJson,\n}: {\n billingApiUrl: string;\n sessionId?: string | null;\n nonce?: string;\n responseJson: Record<string, unknown> | null;\n}): Promise<ProcessRedirectResult | null> {\n const directToken = getRedirectTokenFromProcessResponse(responseJson, {\n requirePaymentIntentClientSecret: true,\n });\n if (typeof directToken === 'string' && directToken.length > 0) {\n return {\n type: '3ds_required',\n threeDSecureToken: directToken,\n };\n }\n\n if (!sessionId) {\n return null;\n }\n\n try {\n const api = new PaymentAPI(billingApiUrl, { telemetry: false });\n const unified = await api.getUnifiedCheckoutSession(sessionId, nonce);\n const refreshedToken = unified.data.stripe?.clientSecret;\n\n if (isStripePaymentIntentClientSecret(refreshedToken)) {\n return {\n type: '3ds_required',\n threeDSecureToken: refreshedToken,\n };\n }\n } catch {\n // Preserve the original authentication_required error if the recovery fetch fails.\n }\n\n return null;\n}\n\nexport async function processSavedPaymentForMode({\n billingApiUrl,\n sessionId,\n session,\n nonce,\n tokenizedData,\n returnUrl,\n telemetry,\n}: {\n billingApiUrl: string;\n sessionId?: string | null;\n session: CheckoutSession;\n /**\n * Session-bound checkout token. Defaults to `session.clientSecret`, but\n * callers that resolved the session via a GET (which doesn't echo the nonce)\n * must pass it explicitly so `/process` and 3DS recovery stay authorized.\n */\n nonce?: string;\n tokenizedData?: TokenizedBody;\n returnUrl?: string;\n /** Disable the JS reporter when an enclosing React operation owns telemetry. */\n telemetry?: boolean;\n}): Promise<SavedPaymentProcessResult> {\n const baseUrl = billingApiUrl.replace(/\\/+$/, '');\n const resolvedSessionId = sessionId ?? session.id;\n const resolvedNonce = nonce ?? session.clientSecret;\n const customerId = session.customer?.id ?? session.accountData?.userId ?? '';\n const customerEmail = session.customer?.email ?? session.accountData?.email ?? '';\n const firstName = session.customer?.firstName ?? session.accountData?.firstName ?? '';\n const lastName = session.customer?.lastName ?? session.accountData?.lastName ?? '';\n const country = session.customer?.country ?? session.accountData?.country ?? undefined;\n const zip = session.customer?.zip ?? session.accountData?.zip ?? undefined;\n const api = new PaymentAPI(\n baseUrl,\n telemetry === false ? { telemetry: false } : undefined,\n );\n\n const response = await retryOnceOnFetchFailure(() => api.processPayment(customerId, {\n sessionId: resolvedSessionId,\n nonce: resolvedNonce,\n tokenizedData,\n accountData: {\n userId: customerId,\n email: customerEmail,\n firstName,\n lastName,\n country,\n zip,\n },\n returnUrl: returnUrl ?? resolveSavedPaymentReturnUrl(session),\n }));\n\n if (response.ok) {\n return {\n type: 'success',\n result: {\n status: 'succeeded',\n paymentIntentId: tokenizedData?.threeDSecureActionResultTokenId,\n paymentMethodId: resolveTokenizedPaymentMethodId(tokenizedData),\n checkoutMethod: tokenizedData\n ? tokenizedData.isPaypal ? 'paypal' : 'card'\n : undefined,\n },\n };\n }\n\n const json = (await response.json().catch(() => null)) as Record<string, unknown> | null;\n\n if (\n (json?.type === 'paypal_redirect_required' || json?.type === '3ds_required')\n ) {\n const redirectToken = getRedirectTokenFromProcessResponse(json);\n if (!redirectToken) {\n throw new FloPayError(\n 'Authentication is required but no redirect token was provided.',\n 'api_error',\n { code: 'authentication_required' },\n );\n }\n\n return {\n type: json.type as ProcessRedirectResult['type'],\n threeDSecureToken: redirectToken,\n paymentMethodId: json.paymentMethodId as string | undefined,\n };\n }\n\n if (json?.gatewayErrorCode === 'authentication_required') {\n const recoveredRedirect = await recover3DSRedirectResult({\n billingApiUrl: baseUrl,\n sessionId: resolvedSessionId,\n nonce: resolvedNonce,\n responseJson: json,\n });\n\n if (recoveredRedirect) {\n return recoveredRedirect;\n }\n\n throw Object.assign(\n new FloPayError(\n 'Your card requires authentication. Please enter your payment details below.',\n 'api_error',\n { code: 'authentication_required' },\n ),\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n throw new FloPayError(\n (json?.message as string) ?? 'Payment failed. Please try again.',\n 'api_error',\n {\n code: (json?.code ?? json?.gatewayErrorCode) as string | undefined,\n declineCode: (json?.declineCode ?? json?.gatewayDeclineReason) as string | undefined,\n },\n );\n}\n\nexport async function processSavedPaymentWithIntent({\n billingApiUrl,\n sessionId,\n session,\n paymentMethodId,\n flopay,\n returnUrl,\n}: {\n billingApiUrl: string;\n sessionId: string;\n session: CheckoutSession;\n paymentMethodId: string;\n flopay: FloPay;\n returnUrl?: string;\n}): Promise<PaymentResult> {\n const customerEmail = session.customer?.email ?? session.accountData?.email ?? '';\n if (!customerEmail) {\n throw Object.assign(\n new FloPayError('Customer email is required to create a payment intent.', 'validation_error', {\n param: 'email',\n }),\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n const api = new PaymentAPI(billingApiUrl);\n const intentResponse = await retryOnceOnFetchFailure(() => api.createPaymentIntent(\n sessionId,\n customerEmail,\n paymentMethodId,\n session.clientSecret ? { nonce: session.clientSecret } : undefined,\n ));\n const intentJson = (await intentResponse.json().catch(() => null)) as Record<string, unknown> | null;\n\n if (!intentResponse.ok) {\n const intentError = buildFloPayApiError(\n intentJson,\n 'Failed to create payment intent.',\n );\n\n throw Object.assign(\n intentError,\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n const intentClientSecret = getRedirectTokenFromProcessResponse(intentJson, {\n requirePaymentIntentClientSecret: true,\n });\n if (!intentClientSecret) {\n throw Object.assign(\n new FloPayError('No client secret in payment intent response.', 'api_error'),\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n const confirmResult = await flopay.confirmCardPayment({\n clientSecret: intentClientSecret,\n paymentMethodId,\n });\n\n if (confirmResult.error) {\n throw Object.assign(\n confirmResult.error,\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n const rawProvider = typeof flopay.getRawProvider === 'function' ? flopay.getRawProvider() : null;\n const confirmedPaymentIntent = await retrievePaymentIntentFromProvider(\n rawProvider,\n intentClientSecret,\n );\n const confirmedPaymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;\n const confirmedPaymentMethodId =\n confirmResult.paymentMethodId\n ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent)\n ?? paymentMethodId;\n\n if (\n !confirmedPaymentIntentId\n || (\n confirmResult.status !== 'succeeded'\n && confirmResult.status !== 'processing'\n && confirmResult.status !== 'requires_capture'\n )\n ) {\n throw Object.assign(\n new FloPayError(\n `Unfortunately, your payment could not be processed. Please try again using a different payment method or contact your bank for assistance. If the issue persists, feel free to reach out to us for support.`,\n 'api_error',\n {\n code: confirmResult.status === 'requires_action'\n ? 'authentication_required'\n : undefined,\n },\n ),\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n const followUp = await processSavedPaymentForMode({\n billingApiUrl,\n sessionId,\n session,\n tokenizedData: {\n id: confirmedPaymentMethodId,\n type: 'card',\n threeDSecureActionResultTokenId: confirmedPaymentIntentId,\n },\n returnUrl,\n });\n\n const finalResult = followUp.type === 'success'\n ? followUp.result\n : await handleSavedPaymentRedirectResult(followUp, {\n flopay,\n paypalFlopay: null,\n attempt3DS: true,\n billingApiUrl,\n sessionId,\n session,\n returnUrl,\n });\n\n return {\n ...finalResult,\n paymentIntentId: finalResult.paymentIntentId ?? confirmedPaymentIntentId,\n paymentMethodId: finalResult.paymentMethodId ?? confirmedPaymentMethodId,\n checkoutMethod: finalResult.checkoutMethod ?? 'card',\n };\n}\n\nexport async function handleSavedPaymentRedirectResult(\n redirectResult: ProcessRedirectResult,\n {\n flopay,\n paypalFlopay,\n attempt3DS,\n billingApiUrl,\n sessionId,\n session,\n returnUrl,\n telemetry,\n }: {\n flopay: FloPay | null;\n paypalFlopay: FloPay | null;\n attempt3DS?: boolean;\n billingApiUrl: string;\n sessionId?: string | null;\n session: CheckoutSession;\n returnUrl?: string;\n /** Disable nested JS reporting when the enclosing React recovery owns telemetry. */\n telemetry?: boolean;\n },\n): Promise<PaymentResult> {\n const stripe = flopay?.getRawProvider() as import('@stripe/stripe-js').Stripe | null;\n if (!stripe) {\n throw new FloPayError('Payment provider is not available.', 'api_error');\n }\n\n if (redirectResult.type === '3ds_required') {\n if (!attempt3DS || !redirectResult.threeDSecureToken) {\n throw Object.assign(\n new FloPayError(\n 'Your card requires authentication. Please enter your payment details below.',\n 'api_error',\n { code: 'authentication_required' },\n ),\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n // Trial-only / $0 saved-card checkouts confirm a SetupIntent, which can\n // itself require 3DS. After the redirect the resume token is a `seti_`\n // secret — Stripe's retrievePaymentIntent / confirmCardPayment reject it,\n // so the SetupIntent APIs must run. Both intent kinds share the id/status/\n // payment_method fields the downstream status gate and /process call read.\n const isSetupIntent = isSetupIntentClientSecret(redirectResult.threeDSecureToken);\n let paymentIntent: ResumeIntent | null = null;\n let savedPaymentMethodId = redirectResult.paymentMethodId;\n\n const retrieved = await retrieveResumeIntent(stripe, redirectResult.threeDSecureToken, isSetupIntent);\n if (retrieved) {\n if (retrieved.error) {\n throw Object.assign(\n new FloPayError(\n retrieved.error.message ?? `Failed to retrieve 3DS ${isSetupIntent ? 'setup' : 'payment'} status.`,\n 'api_error',\n { code: retrieved.error.code },\n ),\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n const existingIntent = retrieved.intent;\n if (!savedPaymentMethodId && existingIntent?.payment_method) {\n if (typeof existingIntent.payment_method === 'string') {\n savedPaymentMethodId = existingIntent.payment_method;\n } else if ('id' in existingIntent.payment_method) {\n savedPaymentMethodId = existingIntent.payment_method.id ?? undefined;\n }\n }\n }\n\n const confirmed = savedPaymentMethodId\n ? await confirmResumeIntent(\n stripe,\n redirectResult.threeDSecureToken,\n {\n payment_method: savedPaymentMethodId,\n return_url: returnUrl ?? resolveSavedPaymentReturnUrl(session) ?? window.location.href,\n },\n isSetupIntent,\n )\n : null;\n if (confirmed) {\n if (confirmed.error) {\n throw Object.assign(\n new FloPayError(\n confirmed.error.message ?? '3DS authentication failed.',\n 'api_error',\n { code: confirmed.error.code },\n ),\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n paymentIntent = confirmed.intent;\n } else {\n const nextAction = await stripe.handleNextAction({\n clientSecret: redirectResult.threeDSecureToken,\n });\n\n if (nextAction.error) {\n throw Object.assign(\n new FloPayError(\n nextAction.error.message ?? '3DS authentication failed.',\n 'api_error',\n { code: nextAction.error.code },\n ),\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n // handleNextAction resolves both intent kinds; its TS type only surfaces\n // `paymentIntent`, so read `setupIntent` off the result for `seti_` tokens.\n paymentIntent =\n (isSetupIntent\n ? (nextAction as { setupIntent?: { id: string; status: string; payment_method?: ResolvedIntentPaymentMethod } })\n .setupIntent\n : nextAction.paymentIntent) ?? null;\n }\n\n if (paymentIntent && (\n paymentIntent.status === 'requires_capture' ||\n paymentIntent.status === 'succeeded' ||\n paymentIntent.status === 'processing'\n )) {\n const followUp = await processSavedPaymentForMode({\n billingApiUrl,\n sessionId,\n session,\n telemetry,\n tokenizedData: {\n id: paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n },\n returnUrl,\n });\n\n if (followUp.type === 'success') {\n return {\n ...followUp.result,\n paymentIntentId: followUp.result.paymentIntentId ?? paymentIntent.id,\n paymentMethodId: followUp.result.paymentMethodId ?? savedPaymentMethodId,\n };\n }\n\n return handleSavedPaymentRedirectResult(followUp, {\n flopay,\n paypalFlopay,\n attempt3DS,\n billingApiUrl,\n sessionId,\n session,\n returnUrl,\n telemetry,\n });\n }\n\n throw Object.assign(\n new FloPayError('3DS authentication did not complete successfully.', 'api_error'),\n { checkoutMethod: 'card' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n if (redirectResult.type === 'paypal_redirect_required') {\n const paypalStripe = (paypalFlopay ?? flopay)?.getRawProvider() as import('@stripe/stripe-js').Stripe | null;\n if (!paypalStripe) {\n throw Object.assign(\n new FloPayError('PayPal is not available.', 'api_error'),\n { checkoutMethod: 'paypal' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n if (redirectResult.paymentMethodId) {\n // Backend attached the saved PM and confirmed the PI server-side, so\n // the PI is in `requires_action` with the PayPal redirect baked into\n // next_action.redirect_to_url. Use `handleNextAction` to drive that\n // redirect — `confirmPayment` would error with\n // `payment_intent_unexpected_state` on a PI that's already past the\n // confirmation step.\n const { error } = await paypalStripe.handleNextAction({\n clientSecret: redirectResult.threeDSecureToken,\n });\n\n if (error) {\n throw Object.assign(\n new FloPayError(\n error.message ?? 'PayPal authorization failed.',\n 'api_error',\n { code: error.code },\n ),\n { checkoutMethod: 'paypal' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n return {\n status: 'succeeded',\n checkoutMethod: 'paypal',\n };\n }\n\n // No `paymentMethodId` on the redirect result: backend created the PI\n // without attaching a PM, so it's sitting in `requires_payment_method`.\n // Drive the redirect by passing `payment_method_data: { type: 'paypal' }`\n // — Stripe creates a fresh PayPal PM during the redirect and attaches it\n // to the PI. No Elements instance needed; no saved-PM reference needed\n // either, so this works for true cross-account scenarios as well.\n const { error } = await paypalStripe.confirmPayment({\n clientSecret: redirectResult.threeDSecureToken,\n confirmParams: {\n return_url: returnUrl ?? resolveSavedPaymentReturnUrl(session) ?? window.location.href,\n payment_method_data: { type: 'paypal' },\n } as { return_url: string },\n redirect: 'if_required',\n });\n\n if (error) {\n throw Object.assign(\n new FloPayError(\n error.message ?? 'PayPal authorization failed.',\n 'api_error',\n { code: error.code },\n ),\n { checkoutMethod: 'paypal' as CheckoutButtonMethod },\n ) satisfies SavedPaymentFlowError;\n }\n\n return {\n status: 'succeeded',\n checkoutMethod: 'paypal',\n };\n }\n\n throw new FloPayError('Unsupported payment redirect state.', 'api_error');\n}\n\nexport function normalizeSavedPaymentError(err: unknown): SavedPaymentFlowError {\n if (err instanceof FloPayError) {\n const friendly = applyFriendlyMessageOverride(err.message);\n if (friendly && friendly !== err.message) {\n return Object.assign(\n new FloPayError(friendly, err.type, {\n code: err.code,\n declineCode: err.declineCode,\n param: err.param,\n statusCode: err.statusCode,\n }),\n { checkoutMethod: (err as SavedPaymentFlowError).checkoutMethod },\n ) as SavedPaymentFlowError;\n }\n return err as SavedPaymentFlowError;\n }\n\n const rawMessage = err instanceof Error ? err.message : 'Payment failed. Please try again.';\n const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;\n\n return new FloPayError(message, 'api_error') as SavedPaymentFlowError;\n}\n\n/**\n * Resolve the generic, provider-agnostic payment method id for a card already\n * on file for a returning customer, or `null` when none is present.\n *\n * For the vault flow (TeamFloPay/backend#823) the backend attaches a generic\n * `providerPaymentMethodId` to the session when a card is on file. The id is\n * opaque to the SDK — Stripe behind the vault returns a `pm_…`, but other card\n * providers can return their own token. Under the Model-A hosted-widget flow\n * the backend's auto-checkout cascade owns returning-customer charging; this\n * helper remains for callers that surface \"card on file\" affordances.\n */\nexport function resolveReturningCustomerPaymentMethodId(\n session: CheckoutSession,\n): string | null {\n const id = session.providerPaymentMethodId;\n return typeof id === 'string' && id.length > 0 ? id : null;\n}\n\n/**\n * Stripe Elements publishable keys resolved from a normalized session. The\n * \"PayPal\" entry here refers to the legacy Stripe-rendered PayPal account\n * (`gateways.stripe`'s dedicated PayPal sub-account), not the new direct\n * PayPal gateway — direct PayPal lives in `gateways.paypal` and is rendered\n * via the official PayPal JS SDK rather than through Stripe Elements.\n *\n * For PayPal-only sessions (`gateways.paypal` set, no `gateways.stripe`),\n * `publishableKey` is `undefined` and the caller should skip Stripe Elements\n * entirely. Only throws when the session advertises no supported gateway at\n * all.\n */\nexport function resolveSavedPaymentPublishableKeys(\n unified: NormalizedCheckoutSession,\n): {\n publishableKey?: string;\n paypalPublishableKey?: string;\n} {\n const publishableKey = unified.data.stripe?.publishableKey;\n const hasDirectPaypal = Boolean(unified.data.paypal?.publishableKey);\n\n if (!publishableKey && !hasDirectPaypal) {\n throw new FloPayError(\n 'Session advertises no supported gateways (expected `gateways.stripe` and/or `gateways.paypal`).',\n 'validation_error',\n );\n }\n\n if (!publishableKey) {\n // Direct-PayPal-only session: no Stripe Elements at all.\n return {};\n }\n\n return {\n publishableKey,\n // Direct-PayPal sessions can still use Stripe's PayPal Element for the\n // saved-PM redirect leg. Prefer the dedicated Stripe-PayPal sub-account\n // publishable key when the backend advertises one; fall back to the\n // primary Stripe publishable key so the resume flow still has a Stripe\n // instance to drive Stripe's PayPal PI.\n paypalPublishableKey: unified.data.stripe?.paypalPublishableKey ?? publishableKey,\n };\n}\n\nexport async function loadSavedPaymentProviders({\n publishableKey,\n paypalPublishableKey,\n billingApiUrl,\n locale,\n telemetry,\n}: {\n publishableKey?: string;\n paypalPublishableKey?: string;\n billingApiUrl: string;\n locale?: string;\n telemetry?: boolean;\n}): Promise<{\n flopay: FloPay | null;\n paypalFlopay: FloPay | null;\n}> {\n if (!publishableKey) {\n // PayPal-only session: no Stripe Elements instance to load. The\n // saved-PM Stripe-PayPal resume leg isn't available, but direct PayPal\n // doesn't need it.\n return { flopay: null, paypalFlopay: null };\n }\n\n const needsSeparatePaypal =\n Boolean(paypalPublishableKey) && paypalPublishableKey !== publishableKey;\n\n const [instance, paypalInstanceOrError] = await Promise.all([\n loadFloPay(publishableKey, {\n billingApiUrl,\n locale,\n telemetry,\n }),\n needsSeparatePaypal\n ? loadFloPay(paypalPublishableKey!, {\n billingApiUrl,\n locale,\n telemetry,\n }).catch((err: unknown) => {\n console.warn('[FloPay] Failed to load PayPal Stripe instance:', err);\n return null;\n })\n : Promise.resolve(null),\n ]);\n\n return {\n flopay: instance,\n paypalFlopay: paypalPublishableKey\n ? needsSeparatePaypal\n ? (paypalInstanceOrError as FloPay | null)\n : instance\n : null,\n };\n}\n","import type {\n DeclineEvent,\n PaymentResult,\n TokenizedBody,\n} from '@flopay/shared';\nimport { PaymentAPI } from '@flopay/js';\nimport { FloPayError } from '@flopay/shared';\nimport React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react';\nimport { useFloPay, usePayPalFloPay, useElements, useBillingApiUrl } from './hooks.js';\nimport { PaymentElement } from './elements.js';\nimport { AddressElement } from './elements.js';\nimport {\n buildDeclineEvent,\n buildFloPayApiErrorFromResponse,\n resolvePaymentIntentPaymentMethodId,\n resolveTokenizedPaymentMethodId,\n retrievePaymentIntentFromProvider,\n} from './checkout-utils.js';\n\n/** localStorage key for persisting wallet payment state across redirects. */\nconst WALLET_RESUME_KEY = 'flopay_wallet_resume';\n\n/** Methods exposed via ref for external 3DS handling. */\nexport interface CheckoutFormRef {\n handleNextAction: (clientSecret: string) => Promise<void>;\n}\n\n/** Props for the drop-in `CheckoutForm` component. */\nexport interface CheckoutFormProps {\n /** The checkout session ID (UUID from billing API). */\n sessionId: string;\n /**\n * Session-bound checkout token returned by session creation\n * (`CheckoutSessionResult.nonce` or `session.clientSecret`). Forwarded as\n * `x-checkout-session-token` on every continuation request — required by\n * post-#640 backends (`TeamFloPay/backend#640`), which 401 the call when the\n * header is missing or does not match the session's stored nonce.\n * `FloPayCheckout` plumbs this prop automatically.\n */\n nonce?: string;\n /** Billing API base URL. Optional — defaults to the value from FloPayProvider or the shared constant. */\n billingApiUrl?: string;\n /** User's email (required for creating payment intents). */\n email?: string;\n /** User ID (required for processing payments). */\n userId?: string;\n /**\n * Called when the full payment flow completes successfully.\n * By default the form handles everything: tokenize → create intent →\n * confirm → processPayment → 3DS retry. You just handle the success.\n */\n onComplete?: (result: PaymentResult) => void;\n /** Called when a payment error occurs. */\n onError?: (error: FloPayError) => void;\n /** Called when a payment is declined or the authentication step fails. */\n onDecline?: (decline: DeclineEvent) => void;\n /**\n * **Override**: If provided, the form tokenizes the card and confirms\n * the payment, but delegates backend submission to the caller.\n * When omitted, the form calls `processPayment` internally.\n */\n onTokenizedBody?: (tokenizedBody: TokenizedBody) => void;\n /** Layout style for the PaymentElement. */\n layout?: 'tabs' | 'accordion' | 'auto';\n /** Label for the submit button. */\n submitLabel?: string;\n /** Whether to show an address element. */\n showAddress?: boolean | 'billing' | 'shipping';\n /** Additional CSS class for the form wrapper. */\n className?: string;\n /** Custom children (e.g. a custom submit button). Overrides the default button. */\n children?: React.ReactNode;\n /** First name for billing. */\n firstName?: string;\n /** Last name for billing. */\n lastName?: string;\n /** Checkout version for A/B tracking. */\n chv?: string;\n /** External processing state (used when onTokenizedBody is provided). */\n isProcessing?: boolean;\n /** External error message (used when onTokenizedBody is provided). */\n error?: string | null;\n /** Called when internal error state changes. */\n onErrorChange?: (error: string | null) => void;\n}\n\n/**\n * Drop-in checkout form that handles the full payment lifecycle by default.\n *\n * **Default (self-contained) mode** — just provide config + onComplete:\n * ```tsx\n * <CheckoutForm\n * sessionId=\"uuid\"\n * billingApiUrl=\"https://api.example.com\"\n * email=\"user@example.com\"\n * userId=\"user_1\"\n * onComplete={(result) => router.push('/success')}\n * />\n * ```\n *\n * The form handles internally:\n * 1. Validate → tokenize card → create PaymentIntent → confirm (3DS)\n * 2. Submit token to `POST /v1/checkouts/sessions/process`\n * 3. If backend returns `3ds_required` → re-confirm with new client secret\n * 4. Wallet resume after redirect (PayPal, etc.)\n *\n * **Override mode** — provide `onTokenizedBody` to handle backend submission yourself:\n * ```tsx\n * <CheckoutForm\n * ...\n * onTokenizedBody={(body) => myCustomProcessPayment(body)}\n * />\n * ```\n */\nexport const CheckoutForm = forwardRef<CheckoutFormRef, CheckoutFormProps>(\n function CheckoutForm(props, ref) {\n return <CheckoutFormInner {...props} innerRef={ref} />;\n },\n);\n\n// ─── Internal implementation ────────────────────────────────────────────────\n\nfunction CheckoutFormInner({\n sessionId,\n nonce,\n billingApiUrl,\n email,\n userId,\n onComplete,\n onError,\n onDecline,\n onTokenizedBody,\n layout = 'auto',\n submitLabel = 'Pay',\n showAddress = false,\n className,\n children,\n firstName,\n lastName,\n chv,\n isProcessing: externalProcessing,\n error: externalError,\n onErrorChange,\n innerRef,\n}: CheckoutFormProps & { innerRef: React.Ref<CheckoutFormRef> }) {\n const flopay = useFloPay();\n const paypalFlopay = usePayPalFloPay();\n const elements = useElements();\n const contextBillingUrl = useBillingApiUrl();\n const [processing, setProcessing] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [is3DSActive, setIs3DSActive] = useState(false);\n\n const displayError = externalError ?? error;\n const isSubmitting = externalProcessing ?? processing;\n const isSelfContained = !onTokenizedBody;\n const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\\/+$/, '');\n\n const updateError = useCallback(\n (err: string | null) => {\n setError(err);\n onErrorChange?.(err);\n },\n [onErrorChange],\n );\n\n const emitDecline = useCallback(\n (\n input: string | FloPayError,\n overrides?: { code?: string; declineCode?: string },\n ) => {\n onDecline?.(buildDeclineEvent('card', input, overrides));\n },\n [onDecline],\n );\n\n // ── Internal: call processPayment and handle 3DS/PayPal responses ──\n\n const processPaymentInternal = useCallback(\n async (\n tokenizedBody: TokenizedBody,\n completionPaymentMethodId?: string,\n ) => {\n setProcessing(true);\n updateError(null);\n\n const resolvedCompletionPaymentMethodId =\n completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);\n const requestTokenizedBody = tokenizedBody.originalPaymentMethodId\n ? { ...tokenizedBody, originalPaymentMethodId: undefined }\n : tokenizedBody;\n\n try {\n const api = new PaymentAPI(baseUrl);\n const response = await api.processPayment(userId ?? '', {\n sessionId,\n nonce,\n tokenizedData: requestTokenizedBody,\n accountData: {\n userId: userId ?? '',\n email: email ?? '',\n firstName: firstName ?? '',\n lastName: lastName ?? '',\n },\n chv,\n });\n\n if (response.ok) {\n onComplete?.({\n status: 'succeeded',\n paymentIntentId: tokenizedBody.threeDSecureActionResultTokenId,\n paymentMethodId: resolvedCompletionPaymentMethodId,\n checkoutMethod: tokenizedBody.isPaypal ? 'paypal' : 'card',\n });\n return;\n }\n\n const json = await response.json().catch(() => null) as Record<string, unknown> | null;\n\n // 3DS required — confirm with new client secret, then resubmit\n if (json?.type === '3ds_required') {\n const secret = json['threeDSecureToken'] as string;\n if (!flopay || !secret) {\n updateError('3DS authentication required but no token provided.');\n return;\n }\n\n setIs3DSActive(true);\n try {\n const retryFullName = `${firstName ?? ''} ${lastName ?? ''}`.trim();\n const result = await flopay.confirmPayment({\n clientSecret: secret,\n returnUrl: window.location.href,\n billingDetails: {\n ...(email ? { email } : {}),\n ...(retryFullName ? { name: retryFullName } : {}),\n },\n });\n\n if (result.error) {\n updateError(result.error.message);\n onError?.(result.error);\n emitDecline(result.error);\n return;\n }\n\n if (result.status === 'succeeded' || result.status === 'processing') {\n // Resubmit with the 3DS result. Keep the original reusable PM for\n // completion callbacks, but do not resend it in the process body:\n // the billing API may derive idempotency keys from that PM.\n await processPaymentInternal({\n id: result.paymentIntentId,\n type: 'card',\n threeDSecureActionResultTokenId: result.paymentIntentId,\n }, resolvedCompletionPaymentMethodId);\n }\n } finally {\n setIs3DSActive(false);\n }\n return;\n }\n\n // PayPal redirect required — the Stripe-rendered PayPal path. Routes\n // confirmation through the PayPal FloPay instance (falls back to the\n // primary Stripe instance when no dedicated PayPal sub-account is\n // configured).\n if (json?.type === 'paypal_redirect_required') {\n const secret = (json['threeDSecureToken'] ?? json['clientSecret']) as string | undefined;\n const pmId = json['paymentMethodId'] as string | undefined;\n const paypalStripe = (paypalFlopay ?? flopay)?.getRawProvider() as\n | import('@stripe/stripe-js').Stripe\n | null;\n\n if (!paypalStripe || !secret) {\n const message = 'PayPal is not available.';\n updateError(message);\n onDecline?.(buildDeclineEvent('paypal', message));\n return;\n }\n\n // Store state for resume after redirect.\n localStorage.setItem(WALLET_RESUME_KEY, JSON.stringify({\n sessionId,\n paymentIntentId: '',\n tokenType: 'card',\n tokenId: pmId ?? '',\n status: 'pending_redirect',\n }));\n\n const confirmParams: Record<string, unknown> = {\n return_url: window.location.href,\n };\n if (pmId) confirmParams['payment_method'] = pmId;\n\n const { error: confirmError } = await paypalStripe.confirmPayment({\n clientSecret: secret,\n confirmParams: confirmParams as { return_url: string },\n redirect: 'if_required',\n });\n\n if (confirmError) {\n const message = confirmError.message ?? 'PayPal payment failed.';\n updateError(message);\n onDecline?.(buildDeclineEvent('paypal', message, { code: confirmError.code }));\n }\n return;\n }\n\n // Generic error\n const errorMessage = (json?.message as string) ?? 'Payment failed. Please try again.';\n updateError(errorMessage);\n emitDecline(errorMessage, {\n code: json?.code as string | undefined,\n declineCode: (json?.declineCode ?? json?.gatewayDeclineReason) as string | undefined,\n });\n } catch (err) {\n updateError(err instanceof Error ? err.message : 'An unexpected error occurred');\n } finally {\n setProcessing(false);\n }\n },\n [baseUrl, sessionId, nonce, userId, email, firstName, lastName, chv, flopay, paypalFlopay, onComplete, onError, onDecline, updateError, emitDecline],\n );\n\n // ── Dispatch tokenized body: self-contained or delegated ──\n\n const dispatchTokenizedBody = useCallback(\n (tokenizedBody: TokenizedBody) => {\n if (onTokenizedBody) {\n // Delegated mode — caller handles backend submission\n onTokenizedBody(tokenizedBody);\n } else {\n // Self-contained mode — process internally\n processPaymentInternal(tokenizedBody);\n }\n },\n [onTokenizedBody, processPaymentInternal],\n );\n\n // ── Expose imperative 3DS handler (for delegated mode) ──\n\n useImperativeHandle(innerRef, () => ({\n async handleNextAction(secret: string) {\n if (!flopay) return;\n\n setIs3DSActive(true);\n try {\n const result = await flopay.confirmPayment({\n clientSecret: secret,\n returnUrl: window.location.href,\n });\n\n if (result.error) {\n updateError(result.error.message);\n onError?.(result.error);\n emitDecline(result.error);\n } else if (result.status === 'succeeded' || result.status === 'processing') {\n dispatchTokenizedBody({\n id: result.paymentIntentId,\n type: 'card',\n threeDSecureActionResultTokenId: result.paymentIntentId,\n });\n }\n } catch (err) {\n updateError(err instanceof Error ? err.message : 'Payment authentication failed.');\n } finally {\n setIs3DSActive(false);\n }\n },\n }), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);\n\n // ── Resume wallet payments after redirect ──\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const stored = localStorage.getItem(WALLET_RESUME_KEY);\n if (!stored) return;\n\n try {\n const payload = JSON.parse(stored) as {\n sessionId: string;\n paymentIntentId: string;\n tokenType: string;\n tokenId: string;\n status: string;\n };\n\n if (payload.sessionId === sessionId) {\n localStorage.removeItem(WALLET_RESUME_KEY);\n dispatchTokenizedBody({\n id: payload.tokenId,\n type: payload.tokenType,\n threeDSecureActionResultTokenId: payload.paymentIntentId,\n });\n }\n } catch {\n localStorage.removeItem(WALLET_RESUME_KEY);\n }\n }, [sessionId, dispatchTokenizedBody]);\n\n // ── Submit: tokenize → create intent → confirm → dispatch ──\n\n const handleSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault();\n if (!flopay || !elements || isSubmitting) return;\n\n setProcessing(true);\n updateError(null);\n let handedOff = false;\n\n try {\n // Matches checkout/StripeCardForm exactly:\n // 1. createPaymentMethod → 2. createPaymentIntent → 3. confirmCardPayment → 4. onTokenizedBody\n\n // 1. Validate\n const submitResult = await flopay.submitElements();\n if (submitResult.error) {\n updateError(submitResult.error.message);\n onError?.(submitResult.error);\n return;\n }\n\n // 2. Tokenize card → PaymentMethod\n const fullName = `${firstName ?? ''} ${lastName ?? ''}`.trim();\n const pmResult = await flopay.createPaymentMethod({\n ...(email ? { email } : {}),\n ...(fullName ? { name: fullName } : {}),\n });\n if (pmResult.error || !pmResult.paymentMethodId) {\n updateError(pmResult.error?.message ?? 'Failed to create payment method.');\n return;\n }\n\n if (!sessionId || !email) {\n throw new FloPayError('Missing sessionId or email', 'validation_error');\n }\n\n // 3. Create PaymentIntent via billing API (backend uses capture_method: 'manual')\n const intentHeaders: Record<string, string> = { 'Content-Type': 'application/json' };\n if (nonce) intentHeaders['x-checkout-session-token'] = nonce;\n const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {\n method: 'POST',\n headers: intentHeaders,\n body: JSON.stringify({\n sessionId,\n email,\n paymentMethodType: pmResult.paymentMethodId,\n isPaypal: false,\n }),\n });\n\n if (!intentResponse.ok) {\n const intentError = await buildFloPayApiErrorFromResponse(\n intentResponse,\n 'Failed to create payment intent',\n );\n updateError(intentError.message);\n onError?.(intentError);\n emitDecline(intentError);\n return;\n }\n\n const intentJson = await intentResponse.json() as { data?: { id?: string } };\n const intentClientSecret = intentJson.data?.id;\n if (!intentClientSecret) throw new FloPayError('No client_secret in payment intent response', 'api_error');\n\n // 4. Confirm card payment (handles 3DS automatically via Stripe)\n const confirmResult = await flopay.confirmCardPayment({\n clientSecret: intentClientSecret,\n paymentMethodId: pmResult.paymentMethodId,\n });\n\n if (confirmResult.error) {\n updateError(confirmResult.error.message);\n onError?.(confirmResult.error);\n emitDecline(confirmResult.error);\n return;\n }\n\n const rawProvider = typeof flopay.getRawProvider === 'function' ? flopay.getRawProvider() : null;\n const confirmedPaymentIntent = await retrievePaymentIntentFromProvider(\n rawProvider,\n intentClientSecret,\n );\n const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;\n const paymentMethodId =\n confirmResult.paymentMethodId\n ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent)\n ?? pmResult.paymentMethodId;\n\n if (!paymentIntentId) {\n const error = new FloPayError('No payment intent returned after confirmation.', 'api_error');\n updateError(error.message);\n onError?.(error);\n return;\n }\n\n // 5. Send PM + PI to processPaymentInternal (or parent via onTokenizedBody)\n handedOff = isSelfContained;\n dispatchTokenizedBody({\n id: paymentMethodId,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntentId,\n originalPaymentMethodId: pmResult.paymentMethodId,\n });\n } catch (err) {\n updateError(err instanceof Error ? err.message : 'An unexpected error occurred');\n } finally {\n if (!handedOff) {\n setProcessing(false);\n }\n }\n },\n [flopay, elements, isSubmitting, sessionId, nonce, email, firstName, lastName, baseUrl, isSelfContained, dispatchTokenizedBody, onError, updateError, emitDecline],\n );\n\n const isReady = flopay !== null && elements !== null;\n\n return (\n <form onSubmit={handleSubmit} className={className} style={{ position: 'relative' }}>\n {(is3DSActive || isSubmitting) && (\n <div data-testid=\"flopay-overlay\" style={{\n position: 'absolute', inset: 0,\n background: 'rgba(255,255,255,0.7)',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n zIndex: 10,\n }}>\n {is3DSActive ? 'Verifying payment...' : 'Processing...'}\n </div>\n )}\n\n {!isReady && (\n <div data-testid=\"flopay-loading\" aria-busy=\"true\">\n Loading payment form...\n </div>\n )}\n\n {isReady && (\n <>\n <PaymentElement options={{ layout }} />\n\n {showAddress && (\n <AddressElement options={{ mode: showAddress === true ? 'billing' : showAddress }} />\n )}\n\n {displayError && (\n <div role=\"alert\" data-testid=\"flopay-error\" style={{ color: 'red', margin: '0.75rem 0' }}>\n {displayError}\n </div>\n )}\n\n {children ?? (\n <button\n type=\"submit\"\n disabled={isSubmitting || !isReady}\n data-testid=\"flopay-submit\"\n >\n {isSubmitting ? 'Processing...' : submitLabel}\n </button>\n )}\n </>\n )}\n </form>\n );\n}\n","import type { TokenizedBody } from '@flopay/shared';\nimport { PaymentAPI } from '@flopay/js';\nimport { FloPayError } from '@flopay/shared';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { useFloPay, useElements, useBillingApiUrl } from './hooks.js';\n\n/**\n * Props for the `PayPalButton` component.\n *\n * Must be rendered inside its own `FloPayProvider` with `paymentMethodCreation: undefined`\n * (not 'manual') — PayPal cannot share the same Elements instance as card fields.\n */\nexport interface PayPalButtonProps {\n /** The checkout session ID (UUID from billing API). */\n sessionId: string;\n /**\n * Session-bound checkout token returned by session creation. Forwarded as\n * `x-checkout-session-token` on continuation requests — required by\n * post-#640 backends.\n */\n nonce?: string;\n /** Billing API base URL. Optional — defaults to the value from FloPayProvider or the shared constant. */\n billingApiUrl?: string;\n /** User's email. */\n email?: string;\n /** User ID for processing payments. */\n userId?: string;\n /** First name for billing. */\n firstName?: string;\n /** Last name for billing. */\n lastName?: string;\n /** Checkout version for tracking. */\n chv?: string;\n /**\n * Called with tokenized data after PayPal authorization.\n * If omitted, the component calls processPayment internally.\n */\n onTokenizedBody?: (body: TokenizedBody) => void;\n /** Called on successful payment (self-contained mode). */\n onComplete?: () => void;\n /** Called when an error occurs. */\n onErrorChange?: (error: string | null) => void;\n /** External processing state. */\n isProcessing?: boolean;\n}\n\n/**\n * PayPal button that handles the full PayPal payment flow.\n *\n * **Important**: PayPal requires its own `FloPayProvider` — it cannot share\n * the same Stripe Elements instance as card fields when they use\n * `paymentMethodCreation: 'manual'`. This matches `checkout/StripeCardForm`\n * which renders PayPal in a separate `<Elements>` wrapper.\n *\n * ```tsx\n * {/* Card fields provider (paymentMethodCreation: 'manual') *\\/}\n * <FloPayProvider flopay={flopay} options={{ amount, currency }}>\n * <SplitCardForm ... />\n * </FloPayProvider>\n *\n * {/* PayPal provider (no paymentMethodCreation) *\\/}\n * <FloPayProvider flopay={flopay} options={{ amount, currency, paymentMethodCreation: 'auto' }}>\n * <PayPalButton ... />\n * </FloPayProvider>\n * ```\n */\nexport function PayPalButton({\n sessionId,\n nonce,\n billingApiUrl,\n email,\n userId,\n firstName,\n lastName,\n chv,\n onTokenizedBody,\n onComplete,\n onErrorChange,\n isProcessing = false,\n}: PayPalButtonProps): React.ReactElement {\n const flopay = useFloPay();\n const elements = useElements();\n const contextBillingUrl = useBillingApiUrl();\n const [ready, setReady] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const paypalResumeAttempted = useRef(false);\n const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\\/+$/, '');\n\n // ── Internal processPayment (self-contained mode) ──\n\n const processPaymentInternal = useCallback(\n async (tokenizedBody: TokenizedBody) => {\n try {\n const api = new PaymentAPI(baseUrl);\n const response = await api.processPayment(userId ?? '', {\n sessionId,\n nonce,\n tokenizedData: tokenizedBody,\n accountData: {\n userId: userId ?? '',\n email: email ?? '',\n firstName: firstName ?? '',\n lastName: lastName ?? '',\n },\n chv,\n });\n\n if (response.ok) {\n onComplete?.();\n return;\n }\n\n const json = await response.json().catch(() => null) as Record<string, unknown> | null;\n onErrorChange?.((json?.message as string) ?? 'Payment failed. Please try again.');\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'An unexpected error occurred');\n }\n },\n [baseUrl, sessionId, nonce, userId, email, firstName, lastName, chv, onComplete, onErrorChange],\n );\n\n const dispatchTokenizedBody = useCallback(\n (body: TokenizedBody) => {\n if (onTokenizedBody) {\n onTokenizedBody(body);\n } else {\n processPaymentInternal(body);\n }\n },\n [onTokenizedBody, processPaymentInternal],\n );\n\n // ── Resume PayPal redirect return ──\n\n useEffect(() => {\n if (!flopay || paypalResumeAttempted.current) return;\n\n const params = new URLSearchParams(window.location.search);\n const paymentIntentId = params.get('payment_intent');\n const clientSecret = params.get('payment_intent_client_secret');\n const redirectStatus = params.get('redirect_status');\n\n if (!paymentIntentId || !clientSecret) return;\n paypalResumeAttempted.current = true;\n\n (async () => {\n try {\n setSubmitting(true);\n\n if (redirectStatus === 'failed') {\n onErrorChange?.('PayPal payment was declined. Please try again.');\n return;\n }\n\n // Retrieve the PaymentIntent to check status (matches checkout/StripeCardForm resume)\n const provider = flopay.getRawProvider() as { retrievePaymentIntent?: (cs: string) => Promise<{ paymentIntent?: { id: string; status: string; payment_method: string | { id: string } }; error?: { message: string } }> } | null;\n if (!provider?.retrievePaymentIntent) {\n onErrorChange?.('Cannot retrieve PayPal payment status.');\n return;\n }\n\n const { paymentIntent, error: retrieveError } = await provider.retrievePaymentIntent(clientSecret);\n if (retrieveError) {\n onErrorChange?.(retrieveError.message ?? 'Failed to retrieve PayPal payment status.');\n return;\n }\n\n if (paymentIntent && (paymentIntent.status === 'requires_capture' || paymentIntent.status === 'succeeded')) {\n const pmId = typeof paymentIntent.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent.payment_method?.id;\n\n dispatchTokenizedBody({\n id: pmId ?? paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n isPaypal: true,\n });\n\n // Clean up URL params\n const url = new URL(window.location.href);\n url.searchParams.delete('payment_intent');\n url.searchParams.delete('payment_intent_client_secret');\n url.searchParams.delete('redirect_status');\n window.history.replaceState({}, '', url.toString());\n } else {\n onErrorChange?.('PayPal payment was not completed. Please try again.');\n }\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'Failed to complete PayPal payment.');\n } finally {\n setSubmitting(false);\n }\n })();\n }, [flopay, dispatchTokenizedBody, onErrorChange]);\n\n // ── PayPal confirm handler ──\n\n const handlePayPalConfirm = useCallback(async () => {\n if (!flopay || !elements) return;\n\n try {\n setSubmitting(true);\n onErrorChange?.(null);\n\n if (!sessionId || !email) {\n throw new FloPayError('Missing sessionId or email for PayPal payment', 'validation_error');\n }\n\n const result = await flopay.confirmPayPalPayment({\n billingApiUrl: baseUrl,\n sessionId,\n nonce,\n email,\n returnUrl: window.location.href,\n });\n\n if (result.error) {\n onErrorChange?.(result.error.message);\n return;\n }\n\n // Defensive future inline-completion path: `confirmPayPalPayment` currently\n // redirects and returns no `paymentIntentId`, so the redirect-resume effect\n // is what normally reaches `dispatchTokenizedBody`. If\n // `confirmPayPalPayment` ever starts completing inline, it must also return\n // `paymentIntentId` so this branch can finish the checkout immediately.\n if (\n result.paymentIntentId\n && (result.status === 'succeeded' || result.status === 'processing' || result.status === 'requires_capture')\n ) {\n dispatchTokenizedBody({\n id: result.paymentMethodId ?? result.paymentIntentId,\n type: 'card',\n threeDSecureActionResultTokenId: result.paymentIntentId,\n isPaypal: true,\n });\n }\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'PayPal payment failed. Please try again.');\n } finally {\n setSubmitting(false);\n }\n }, [flopay, elements, sessionId, nonce, email, baseUrl, dispatchTokenizedBody, onErrorChange]);\n\n if (!flopay || !elements) {\n return <div style={{ height: 45, background: '#f0f0f0', borderRadius: 6, animation: 'pulse 1.5s infinite' }} />;\n }\n\n return (\n <>\n {!ready && (\n <div style={{ height: 45, background: '#f0f0f0', borderRadius: 6 }} />\n )}\n <div style={ready ? {} : { display: 'none' }}>\n <button\n type=\"button\"\n onClick={handlePayPalConfirm}\n disabled={submitting || isProcessing}\n style={{\n width: '100%',\n height: 45,\n backgroundColor: '#ffc439',\n color: '#003087',\n border: 'none',\n borderRadius: 6,\n fontSize: '1rem',\n fontWeight: 700,\n cursor: submitting || isProcessing ? 'not-allowed' : 'pointer',\n opacity: submitting || isProcessing ? 0.6 : 1,\n }}\n ref={() => setReady(true)}\n >\n {submitting ? 'Processing...' : 'PayPal'}\n </button>\n </div>\n\n {(submitting || isProcessing) && (\n <div style={{\n position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.4)',\n display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000,\n }}>\n <div style={{\n background: 'white', borderRadius: 8, padding: '1.5rem',\n textAlign: 'center', boxShadow: '0 4px 24px rgba(0,0,0,0.15)', width: 280,\n }}>\n Processing PayPal payment...\n </div>\n </div>\n )}\n </>\n );\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { PaymentAPI } from '@flopay/js';\nimport type {\n CheckoutButtonMethod,\n CheckoutSession,\n DeclineEvent,\n FloPayAppearance,\n InlineSessionDraft,\n PaymentResult,\n ThemeId,\n} from '@flopay/shared';\nimport type {\n ButtonsLayoutStyles,\n ButtonsLayoutTheme,\n CheckoutItem,\n CheckoutProduct,\n CheckoutSubscription,\n} from '@flopay/shared';\nimport { FloPayError, resolveBillingApiUrl, resolveButtonsLayoutTheme, resolveTheme } from '@flopay/shared';\nimport { CardButtonContentSlot } from './card-button-content.js';\nimport { buildDeclineEvent } from './checkout-utils.js';\nimport { FloPayCheckout } from './flopay-checkout.js';\nimport { darkenHex, derivePrimaryTileStyle } from './split-card-form.js';\nimport {\n PROCESSING_OVERLAY_ERROR_DELAY_MS,\n PROCESSING_OVERLAY_SUCCESS_DELAY_MS,\n ProcessingOverlay,\n type OverlayStatus,\n} from './processing-overlay.js';\nimport {\n type AutoCheckoutThreeDsOutcome,\n checkoutProcessErrorToFloPayError,\n DEFAULT_SAVED_PAYMENT_DECLINE_METHOD,\n normalizeSavedPaymentError,\n processSavedPaymentForMode,\n runAutoCheckoutThreeDsChallenge,\n} from './saved-payment-flow.js';\n\nconst DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction coerceError(err: unknown, fallbackMessage: string): FloPayError {\n if (err instanceof FloPayError) {\n return err;\n }\n\n return new FloPayError(\n err instanceof Error ? err.message : fallbackMessage,\n 'api_error',\n );\n}\n\nfunction shouldShowFallbackCheckout(\n error: FloPayError & { checkoutMethod?: CheckoutButtonMethod },\n sessionId: string | null,\n): boolean {\n if (!sessionId) return false;\n if (error.type === 'validation_error') return false;\n if (error.checkoutMethod && error.checkoutMethod !== 'card' && error.checkoutMethod !== 'paypal') {\n return false;\n }\n return true;\n}\n\nexport interface FloPayAutomaticPaymentSuccessEvent {\n result: PaymentResult;\n session: CheckoutSession | null;\n sessionId: string | null;\n autoCompleted: boolean;\n}\n\nexport interface FloPayAutomaticPaymentButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onError'> {\n sessionId?: string;\n /**\n * Session-bound checkout token for a consumer-supplied {@link sessionId}\n * (the `nonce` returned when that session was created). Post-#640 backends\n * require it as `x-checkout-session-token` to read the session and to\n * `/process` it; without it the existing-session path 401s with\n * \"Missing checkout session token.\". Ignored on the create-session path,\n * where the SDK mints and threads the nonce itself.\n */\n nonce?: string;\n createSession?: InlineSessionDraft;\n /**\n * @deprecated Ignored. The backend now picks the customer's most recent\n * vaulted payment method via `getLatestByUserId` and rebinds the session's\n * gateway to match it (see `apps/api`'s `createSingle` auto-checkout\n * branch). Passing this prop has no effect — it is retained only to avoid\n * breaking existing integrations.\n */\n paymentMethodId?: string;\n /**\n * @deprecated Ignored. The backend orchestrates gateway routing — clients\n * no longer choose between card and PayPal at the SDK boundary. Passing\n * this prop has no effect.\n */\n checkoutMethod?: CheckoutButtonMethod;\n clientId?: string;\n /**\n * Unified products array (TeamFloPay/backend#760). When supplied,\n * `items`/`subscriptions` are ignored. The SDK folds the legacy fields\n * into this shape internally.\n */\n products?: CheckoutProduct[];\n items?: CheckoutItem[];\n subscriptions?: CheckoutSubscription[];\n account?: InlineSessionDraft['account'];\n successUrl?: string;\n cancelUrl?: string;\n couponCodes?: string[];\n tagsData?: InlineSessionDraft['tagsData'];\n utmMetadata?: InlineSessionDraft['utmMetadata'];\n billingApiUrl?: string;\n locale?: string;\n /**\n * High-level theme bundle that styles the button (and the fallback\n * `FloPayCheckout` modal that opens when the saved-payment charge needs\n * user interaction). One of: `'classic'`, `'modern-light'`, `'modern-dark'`,\n * `'bold-light'`, `'bold-dark'`, `'glass-light'`, `'glass-dark'`. Explicit\n * `buttonsStyles` still wins for fine-grained overrides.\n */\n theme?: ThemeId;\n /**\n * Per-checkout appearance overrides layered on top of the chosen `theme`\n * (same shape as {@link FloPayCheckout}'s `appearance`). Its `colorPrimary` /\n * `colorPrimaryHover` / `borderRadius` re-skin the button — and the fallback\n * `FloPayCheckout` modal — so the auto-pay button matches the rest of the\n * themed checkout. Without this the button only saw the bundle's defaults.\n */\n appearance?: FloPayAppearance;\n /**\n * @deprecated Use `theme` instead. Legacy buttons-layout preset\n * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for\n * back-compat.\n */\n buttonsTheme?: ButtonsLayoutTheme;\n buttonsStyles?: ButtonsLayoutStyles;\n onSuccess?: (event: FloPayAutomaticPaymentSuccessEvent) => void;\n onError?: (error: FloPayError) => void;\n onDecline?: (decline: DeclineEvent) => void;\n children?: React.ReactNode;\n}\n\nfunction resolveCreateSessionDraft(props: FloPayAutomaticPaymentButtonProps): InlineSessionDraft | null {\n if (props.createSession) {\n return {\n ...props.createSession,\n checkoutMode: 'auto',\n };\n }\n\n if (!props.clientId || !props.account || !props.successUrl || !props.cancelUrl) {\n return null;\n }\n\n // Enforce the documented precedence: when `products` is supplied the legacy\n // `items`/`subscriptions` are dropped so the draft can't carry an ambiguous\n // cart. `createAndFetchSession` folds the legacy fields into `products[]`\n // only when `products` is absent (`params.products ?? foldIntoProducts(...)`).\n // Use `!= null` so `products={null}` is treated as absent too, matching the\n // `??` semantics downstream — otherwise the legacy fields would be dropped\n // here but `null ?? foldIntoProducts(undefined, undefined)` would yield `[]`.\n const hasProducts = props.products != null;\n\n return {\n clientId: props.clientId,\n products: props.products,\n items: hasProducts ? undefined : props.items,\n subscriptions: hasProducts ? undefined : props.subscriptions,\n account: props.account,\n successUrl: props.successUrl,\n cancelUrl: props.cancelUrl,\n couponCodes: props.couponCodes,\n tagsData: props.tagsData,\n utmMetadata: props.utmMetadata,\n checkoutMode: 'auto',\n };\n}\n\nexport function FloPayAutomaticPaymentButton({\n sessionId,\n nonce,\n createSession,\n // Deprecated — accepted for back-compat and silently ignored. Backend\n // resolves the customer's latest payment method server-side.\n paymentMethodId: _deprecatedPaymentMethodId,\n checkoutMethod: _deprecatedCheckoutMethod,\n clientId,\n products,\n items,\n subscriptions,\n account,\n successUrl,\n cancelUrl,\n couponCodes,\n tagsData,\n utmMetadata,\n billingApiUrl,\n locale,\n theme,\n appearance,\n buttonsTheme,\n buttonsStyles: stylesOverride,\n onSuccess,\n onError,\n onDecline,\n children,\n disabled = false,\n type = 'button',\n style,\n ...buttonProps\n}: FloPayAutomaticPaymentButtonProps) {\n const resolvedBillingUrl = useMemo(\n () => resolveBillingApiUrl(billingApiUrl),\n [billingApiUrl],\n );\n const createSessionDraft = useMemo(\n () => resolveCreateSessionDraft({\n createSession,\n clientId,\n products,\n items,\n subscriptions,\n account,\n successUrl,\n cancelUrl,\n couponCodes,\n tagsData,\n utmMetadata,\n }),\n [\n account,\n cancelUrl,\n clientId,\n couponCodes,\n createSession,\n products,\n items,\n subscriptions,\n successUrl,\n tagsData,\n utmMetadata,\n ],\n );\n const [isProcessing, setIsProcessing] = useState(false);\n const [overlayStatus, setOverlayStatus] = useState<OverlayStatus | null>(null);\n const [overlayError, setOverlayError] = useState<string | null>(null);\n const [fallbackSession, setFallbackSession] = useState<{\n sessionId: string;\n errorMessage: string;\n /**\n * Session-bound checkout token carried over from the auto-process attempt.\n * Without it the fallback checkout's session GET 401s on post-#640 backends\n * (`x-checkout-session-token` is required to read the session row).\n */\n nonce?: string;\n } | null>(null);\n\n const isMountedRef = useRef(true);\n // Aborts the in-flight 3DS challenge overlay when the component unmounts so a\n // route change / navigation can't leave a stranded full-page iframe behind.\n const threeDsAbortRef = useRef<AbortController | null>(null);\n const fallbackSessionRef = useRef(fallbackSession);\n const onSuccessRef = useRef(onSuccess);\n const onErrorRef = useRef(onError);\n const onDeclineRef = useRef(onDecline);\n\n useEffect(() => {\n fallbackSessionRef.current = fallbackSession;\n }, [fallbackSession]);\n\n useEffect(() => {\n onSuccessRef.current = onSuccess;\n }, [onSuccess]);\n\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n useEffect(() => {\n onDeclineRef.current = onDecline;\n }, [onDecline]);\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n threeDsAbortRef.current?.abort();\n };\n }, []);\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setFallbackSession(null);\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, []);\n\n const emitDecline = useCallback((error: FloPayError, method = DEFAULT_SAVED_PAYMENT_DECLINE_METHOD) => {\n onDeclineRef.current?.(buildDeclineEvent(method, error, {\n code: error.code,\n declineCode: error.declineCode,\n }));\n }, []);\n\n const showSuccess = useCallback(async (event: FloPayAutomaticPaymentSuccessEvent) => {\n if (!isMountedRef.current) return;\n\n setOverlayError(null);\n setOverlayStatus('success');\n await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);\n\n if (!isMountedRef.current) return;\n onSuccessRef.current?.(event);\n }, []);\n\n const showError = useCallback(async (\n error: FloPayError,\n options?: {\n emitDecline?: boolean;\n method?: CheckoutButtonMethod;\n },\n ) => {\n if (!isMountedRef.current) return;\n\n onErrorRef.current?.(error);\n if (options?.emitDecline) {\n emitDecline(error, options.method);\n }\n\n setOverlayError(error.message);\n setOverlayStatus('error');\n await sleep(PROCESSING_OVERLAY_ERROR_DELAY_MS);\n }, [emitDecline]);\n\n const processResolvedSession = useCallback(async (\n apiResult: Awaited<ReturnType<PaymentAPI['getUnifiedCheckoutSession']>>,\n resolvedSessionId: string | null,\n options?: {\n fromCreateSession?: boolean;\n },\n ) => {\n const session = apiResult.data.session ?? null;\n if (!session) {\n throw new FloPayError('No session data returned', 'api_error');\n }\n\n // The create-session path mints the nonce on the session (`clientSecret`);\n // the existing-session path carries it via the `nonce` prop, since a session\n // GET does not echo the token back. Prefer whichever is populated so every\n // continuation call (/process, fallback session GET) stays authorized.\n const effectiveNonce = session.clientSecret || nonce;\n\n if (session.status === 'complete') {\n await showSuccess({\n result: { status: 'succeeded' },\n session,\n sessionId: session.id || resolvedSessionId,\n autoCompleted: false,\n });\n return;\n }\n\n if (session.status === 'expired') {\n throw new FloPayError('Checkout session has expired.', 'api_error', {\n code: 'checkout_session_expired',\n });\n }\n\n try {\n if (apiResult.autoProcessingPending) {\n const api = new PaymentAPI(resolvedBillingUrl);\n const completed = await api.waitForCheckoutSessionCompletion(apiResult.autoProcessingPending.sessionId, {\n initialDelayMs: apiResult.autoProcessingPending.retryAfterMs,\n });\n const completedSession = completed.data.session;\n\n if (!completedSession || completedSession.status !== 'complete') {\n throw new FloPayError('Automatic payment failed. Please try again.', 'api_error', {\n code: completedSession?.status === 'expired'\n ? 'checkout_session_expired'\n : 'checkout_processing_timeout',\n });\n }\n\n await showSuccess({\n result: { status: 'succeeded' },\n session: completedSession,\n sessionId: completedSession.id || resolvedSessionId,\n autoCompleted: false,\n });\n return;\n }\n\n if (apiResult.autoProcessingError) {\n // 3DS challenge required on the saved PM: render the provider-hosted\n // challenge in a full-page overlay instead of treating it as a hard\n // failure. Successful completion drives backend's `/3ds/complete`\n // sync resolver and we fall through to the saved-payment success\n // path; failures (decline / timeout) propagate as a normal\n // FloPayError so the host sees `onDecline` / `onError`.\n //\n // `3ds_required` matches `CheckoutExceptionTypeEnum.ThreeDSecureRequired`\n // on the backend (the enum's literal value, not its symbol). Other\n // SDK sites (`split-card-form`, `checkout-form`) use the same\n // string — keep them in lockstep so a backend enum rename is a\n // single coordinated edit.\n if (\n apiResult.autoProcessingError.type === '3ds_required'\n && apiResult.autoProcessingError.nextActionRedirectUrl\n && resolvedSessionId\n && effectiveNonce\n ) {\n const threeDsAbort = new AbortController();\n threeDsAbortRef.current = threeDsAbort;\n let outcome: AutoCheckoutThreeDsOutcome;\n try {\n outcome = await runAutoCheckoutThreeDsChallenge({\n billingApiUrl: resolvedBillingUrl,\n sessionId: resolvedSessionId,\n nonce: effectiveNonce,\n nextActionRedirectUrl: apiResult.autoProcessingError.nextActionRedirectUrl,\n signal: threeDsAbort.signal,\n });\n } finally {\n if (threeDsAbortRef.current === threeDsAbort) {\n threeDsAbortRef.current = null;\n }\n }\n\n // Decline path: the session stays in `pending` on a decline (only\n // a successful charge flips it to `complete`), so polling\n // session-status would just time out with \"Checkout is still\n // processing.\" Use `/3ds/complete`'s own response directly — the\n // resolver already wrote the terminal Decline attempt row and\n // told us the outcome.\n if (outcome.status === 'declined') {\n throw checkoutProcessErrorToFloPayError(\n {\n type: outcome.declineReason ?? 'decline',\n message: 'Card was declined.',\n gatewayErrorCode: outcome.gatewayDeclineReason ?? undefined,\n },\n 'Card was declined.',\n {\n checkoutMethod: apiResult.autoProcessingError.checkoutMethod,\n },\n );\n }\n\n // Success path: confirm via session-status poll so we hand\n // `showSuccess` the fully populated completed session.\n // Pending / requires_action / unknown also fall through here —\n // the poll either resolves once the webhook lands or times out\n // with the normal \"still processing\" error.\n const api = new PaymentAPI(resolvedBillingUrl);\n const completed = await api.waitForCheckoutSessionCompletion(resolvedSessionId, {\n initialDelayMs: 0,\n nonce: effectiveNonce,\n });\n const completedSession = completed.data.session;\n if (!completedSession || completedSession.status !== 'complete') {\n throw checkoutProcessErrorToFloPayError(\n {\n type: 'unknown',\n message: 'Card authentication was not completed.',\n },\n 'Card authentication was not completed.',\n {\n checkoutMethod: apiResult.autoProcessingError.checkoutMethod,\n },\n );\n }\n await showSuccess({\n result: { status: 'succeeded' },\n session: completedSession,\n sessionId: completedSession.id || resolvedSessionId,\n autoCompleted: false,\n });\n return;\n }\n\n throw checkoutProcessErrorToFloPayError(\n apiResult.autoProcessingError,\n 'Automatic payment failed. Please try again.',\n {\n checkoutMethod: apiResult.autoProcessingError.checkoutMethod,\n },\n );\n }\n\n if (options?.fromCreateSession && apiResult.autoProcessingAttempted === true) {\n throw checkoutProcessErrorToFloPayError(\n {\n type: 'unknown',\n message: 'Automatic payment failed. Please try again.',\n },\n 'Automatic payment failed. Please try again.',\n );\n }\n\n // Existing-session path: backend's `createSingle` auto-checkout did not\n // run, so kick off /process. The SDK no longer ships client-built\n // `tokenizedData` — the backend resolves the customer's latest vaulted\n // payment method server-side (see `apps/api`'s `process` /\n // `processPendingSession` for the orchestration that owns this now).\n const result = await processSavedPaymentForMode({\n billingApiUrl: resolvedBillingUrl,\n sessionId: resolvedSessionId ?? session.id,\n session,\n nonce: effectiveNonce,\n });\n\n if (result.type !== 'success') {\n // The backend should not be requesting a client-side redirect when it\n // owns gateway routing. Anything other than `success` is treated as a\n // failure and falls through to the standard error path (fallback\n // checkout for recoverable cases).\n throw checkoutProcessErrorToFloPayError(\n {\n type: 'unknown',\n message: 'Automatic payment failed. Please try again.',\n },\n 'Automatic payment failed. Please try again.',\n );\n }\n\n await showSuccess({\n result: result.result,\n session,\n sessionId: session.id || resolvedSessionId,\n autoCompleted: false,\n });\n } catch (err) {\n const floPayErr = normalizeSavedPaymentError(err);\n const fallbackSessionId = session.id || resolvedSessionId;\n\n await showError(floPayErr, {\n emitDecline: true,\n method: floPayErr.checkoutMethod ?? DEFAULT_SAVED_PAYMENT_DECLINE_METHOD,\n });\n if (\n shouldShowFallbackCheckout(floPayErr, fallbackSessionId) &&\n fallbackSessionId &&\n isMountedRef.current\n ) {\n setFallbackSession({\n sessionId: fallbackSessionId,\n errorMessage: floPayErr.message,\n nonce: effectiveNonce || undefined,\n });\n }\n }\n }, [\n nonce,\n resolvedBillingUrl,\n showError,\n showSuccess,\n ]);\n\n const handleButtonClick = useCallback(async (event: React.MouseEvent<HTMLButtonElement>) => {\n buttonProps.onClick?.(event);\n\n if (event.defaultPrevented || disabled || isProcessing) {\n return;\n }\n\n setFallbackSession(null);\n\n if (sessionId && createSessionDraft) {\n const error = new FloPayError(\n 'Provide either sessionId or create-session props, not both.',\n 'validation_error',\n );\n await showError(error);\n if (isMountedRef.current) {\n setOverlayStatus(null);\n setOverlayError(null);\n }\n return;\n }\n\n if (!sessionId && !createSessionDraft) {\n const error = new FloPayError(\n 'Provide a sessionId or the props required to create an automatic payment session.',\n 'validation_error',\n );\n await showError(error);\n if (isMountedRef.current) {\n setOverlayStatus(null);\n setOverlayError(null);\n }\n return;\n }\n\n setIsProcessing(true);\n setOverlayError(null);\n setOverlayStatus('processing');\n\n try {\n const api = new PaymentAPI(resolvedBillingUrl);\n\n if (sessionId) {\n const result = await api.getUnifiedCheckoutSession(sessionId, nonce);\n await processResolvedSession(result, sessionId);\n return;\n }\n\n try {\n const result = await api.createAndFetchSession({\n ...createSessionDraft!,\n });\n await processResolvedSession(result, result.data.session?.id ?? null, {\n fromCreateSession: true,\n });\n } catch (err) {\n if (err instanceof FloPayError && err.code === 'session_auto_completed') {\n await showSuccess({\n result: { status: 'succeeded' },\n session: null,\n sessionId: null,\n autoCompleted: true,\n });\n return;\n }\n\n throw err;\n }\n } catch (err) {\n await showError(\n coerceError(err, 'Automatic payment failed. Please try again.'),\n );\n } finally {\n if (isMountedRef.current) {\n setOverlayStatus(null);\n setOverlayError(null);\n setIsProcessing(false);\n }\n }\n }, [\n buttonProps,\n createSessionDraft,\n disabled,\n isProcessing,\n nonce,\n processResolvedSession,\n resolvedBillingUrl,\n sessionId,\n showError,\n showSuccess,\n ]);\n\n const handleFallbackComplete = useCallback((result: PaymentResult) => {\n const activeFallback = fallbackSessionRef.current;\n setFallbackSession(null);\n onSuccessRef.current?.({\n result,\n session: null,\n sessionId: activeFallback?.sessionId ?? null,\n autoCompleted: false,\n });\n }, []);\n\n const handleFallbackError = useCallback((error: FloPayError) => {\n onErrorRef.current?.(error);\n }, []);\n\n const handleFallbackDecline = useCallback((decline: DeclineEvent) => {\n onDeclineRef.current?.(decline);\n }, []);\n\n // Resolution: `theme` (high-level bundle) takes precedence over the legacy\n // `buttonsTheme` preset; explicit `buttonsStyles` overrides individual fields\n // on top of whichever base was chosen.\n const themeBundle = useMemo(() => resolveTheme(theme), [theme]);\n const bStyles = useMemo<ButtonsLayoutStyles>(() => {\n const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme(buttonsTheme);\n if (!stylesOverride) return base;\n return {\n ...base,\n ...stylesOverride,\n cardButton: { ...base.cardButton, ...stylesOverride.cardButton },\n };\n }, [themeBundle, buttonsTheme, stylesOverride]);\n\n // Per-checkout `appearance` overrides are *layered on top of* the bundle's\n // appearance (per the prop's \"layered on top\" contract): merge variables\n // per-key — the checkout-level value wins, but unspecified keys keep the\n // theme's values instead of reverting to hardcoded defaults. Replacing the\n // whole object (the old `appearance ?? themeBundle.appearance`) dropped theme\n // colours on a partial override and desynced this button from the fallback\n // modal. These drive the button fill (`colorPrimary`) + hover\n // (`colorPrimaryHover`) so a custom theme re-skins the auto-pay button in\n // lock-step with the rest of the checkout.\n const resolvedAppearance = useMemo<FloPayAppearance | undefined>(() => {\n const bundleAppearance = themeBundle?.appearance;\n if (!appearance) return bundleAppearance;\n if (!bundleAppearance) return appearance;\n return {\n ...bundleAppearance,\n ...appearance,\n variables: {\n ...bundleAppearance.variables,\n ...appearance.variables,\n },\n };\n }, [appearance, themeBundle]);\n const resolvedAppearanceVars = resolvedAppearance?.variables;\n const resolvedPrimaryColor =\n (resolvedAppearanceVars?.colorPrimary as string | undefined) ?? '#4A49FF';\n const resolvedPrimaryHoverColor =\n (resolvedAppearanceVars?.colorPrimaryHover as string | undefined)\n ?? darkenHex(resolvedPrimaryColor, 0.12);\n const resolvedButtonBorderRadius =\n (resolvedAppearanceVars?.borderRadius as string | undefined) ?? '8px';\n\n const cardButtonSizing = children === undefined\n ? { boxSizing: 'border-box' as const, height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: '0 1rem' }\n : { padding: '0.9rem 1rem' };\n\n return (\n <>\n <button\n {...buttonProps}\n type={type}\n onClick={handleButtonClick}\n disabled={disabled || isProcessing}\n aria-busy={isProcessing}\n style={{\n width: '100%',\n ...cardButtonSizing,\n // `bStyles.cardButton` first so the bundle's padding / typography\n // / radius / shadow come through, then `derivePrimaryTileStyle`\n // on top so the auto-pay button carries the *submit* button's\n // background and text colours — making it visually identical to\n // the \"Confirm Payment\" / \"Pay with X\" actions it stands in for.\n // `resolvedPrimaryColor` is the *merged* appearance value, so a\n // per-checkout `colorPrimary` override re-skins this button too.\n // Inline `style` consumer override stays at the end so explicit\n // per-button overrides still win.\n ...bStyles.cardButton as React.CSSProperties,\n ...derivePrimaryTileStyle({\n themeBundle,\n resolvedPrimaryColor,\n resolvedBorderRadius: resolvedButtonBorderRadius,\n submitButtonStyle: bStyles.submitButton as React.CSSProperties | undefined,\n explicitPrimaryColor: resolvedAppearanceVars?.colorPrimary as string | undefined,\n }),\n fontSize: bStyles.cardButtonFontSize ?? '0.95rem',\n fontWeight: 600,\n cursor: disabled || isProcessing ? 'not-allowed' : 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '0.625rem',\n transition: 'background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s',\n position: 'relative',\n opacity: disabled || isProcessing ? 0.6 : 1,\n ...style,\n }}\n onMouseEnter={(e) => {\n buttonProps.onMouseEnter?.(e);\n // Hover on any primary-filled button (themed bundle OR an explicit\n // `colorPrimary` override); the classic white tile with no override\n // keeps its static look. Skip while disabled / processing.\n if (!e.defaultPrevented && !disabled && !isProcessing && (themeBundle || resolvedAppearanceVars?.colorPrimary)) {\n e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;\n }\n }}\n onMouseLeave={(e) => {\n buttonProps.onMouseLeave?.(e);\n if (!e.defaultPrevented && (themeBundle || resolvedAppearanceVars?.colorPrimary)) {\n e.currentTarget.style.backgroundColor = resolvedPrimaryColor;\n }\n }}\n onMouseDown={(e) => {\n buttonProps.onMouseDown?.(e);\n if (!e.defaultPrevented) {\n e.currentTarget.style.transform = 'scale(0.985)';\n }\n }}\n onMouseUp={(e) => {\n buttonProps.onMouseUp?.(e);\n if (!e.defaultPrevented) {\n e.currentTarget.style.transform = 'scale(1)';\n }\n }}\n >\n <CardButtonContentSlot content={children} />\n </button>\n {overlayStatus && (\n <ProcessingOverlay\n status={overlayStatus}\n errorMessage={overlayError}\n />\n )}\n {fallbackSession && (\n <div\n data-testid=\"flopay-automatic-payment-fallback\"\n role=\"dialog\"\n aria-modal=\"true\"\n onClick={(event) => {\n if (event.target === event.currentTarget) {\n setFallbackSession(null);\n }\n }}\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0, 0, 0, 0.45)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '1.5rem',\n zIndex: 1100,\n }}\n >\n <div\n style={{\n width: '100%',\n maxWidth: 520,\n maxHeight: '90vh',\n overflowY: 'auto',\n background: 'white',\n borderRadius: 20,\n padding: '1.5rem',\n boxShadow: '0 24px 80px rgba(15, 23, 42, 0.28)',\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n }}\n >\n <FloPayCheckout\n sessionId={fallbackSession.sessionId}\n nonce={fallbackSession.nonce}\n checkoutMode=\"full\"\n billingApiUrl={resolvedBillingUrl}\n locale={locale}\n theme={theme}\n {...(resolvedAppearance ? { appearance: resolvedAppearance } : {})}\n buttonsTheme={buttonsTheme}\n buttonsStyles={stylesOverride}\n initialErrorMessage={fallbackSession.errorMessage}\n cardTitleContent={null}\n onComplete={handleFallbackComplete}\n onError={handleFallbackError}\n onDecline={handleFallbackDecline}\n />\n </div>\n </div>\n )}\n </>\n );\n}\n"],"mappings":"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","names":["React","useCallback","useEffect","useMemo","useRef","useState","PaymentAPI","SDK_VERSION","FloPayError","resolveBillingApiUrl","resolveButtonsLayoutTheme","resolveTheme","jsx","useEffect","useRef","jsx","useRef","useEffect","PaymentElement","PaymentAPI","useEffect","useRef","jsx","React","useCallback","useContext","useEffect","useMemo","useRef","useState","useContext","resolveBillingApiUrl","useContext","resolveBillingApiUrl","jsx","jsxs","error","useCallback","useEffect","useMemo","useRef","useState","FloPayError","jsx","jsxs","useMemo","useEffect","useRef","useState","useCallback","FloPayError","FloPayError","isSetupIntentClientSecret","Fragment","jsx","jsxs","useRef","useCallback","useEffect","SplitCardForm","useState","useMemo","PaymentElement","React","useContext","invalidAvsFields","avsInvalid","PaymentAPI","resolvedAccount","avsConfig","fullName","avsCheckProp","stateValue","baseUrl","sessionId","nonce","updateError","onError","emitDecline","message","error","PaymentAPI","FloPayError","isSetupIntentClientSecret","error","FloPayError","PaymentAPI","FloPayError","isSetupIntentClientSecret","error","FloPayError","Fragment","jsx","jsxs","DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT","SDK_VERSION","resolveBillingApiUrl","useMemo","resolveTheme","useState","useRef","useEffect","useCallback","activeSessionId","PaymentAPI","FloPayError","React","resolveButtonsLayoutTheme","PaymentAPI","FloPayError","forwardRef","useCallback","useEffect","useImperativeHandle","useState","Fragment","jsx","jsxs","forwardRef","CheckoutForm","useState","useCallback","PaymentAPI","useImperativeHandle","useEffect","FloPayError","error","PaymentAPI","FloPayError","useCallback","useEffect","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useCallback","PaymentAPI","useEffect","FloPayError","useCallback","useEffect","useMemo","useRef","useState","PaymentAPI","FloPayError","resolveBillingApiUrl","resolveButtonsLayoutTheme","resolveTheme","Fragment","jsx","jsxs","DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT","sleep","FloPayError","useMemo","resolveBillingApiUrl","useState","useRef","useEffect","useCallback","PaymentAPI","resolveTheme","resolveButtonsLayoutTheme"]}
1
+ {"version":3,"sources":["../src/provider.tsx","../src/context.ts","../src/telemetry-bridge.ts","../src/flopay-checkout.tsx","../src/card-button-content.tsx","../src/split-card-form.tsx","../src/vault-card-fields.tsx","../src/error-banner.tsx","../src/payment-logos.generated.ts","../src/hooks.ts","../src/processing-overlay.tsx","../src/checkout-utils.ts","../src/recent-completion.ts","../src/in-app-browser.ts","../src/direct-paypal-button.tsx","../src/merchant-callback.ts","../src/external-method-recovery.ts","../src/saved-payment-flow.ts","../src/elements.tsx","../src/paypal-button.tsx","../src/automatic-payment-button.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useState, useMemo, useRef } from 'react';\nimport type { FloPay, FloPayElements } from '@flopay/js';\nimport type { FloPayAppearance } from '@flopay/shared';\nimport { resolveBillingApiUrl } from '@flopay/shared';\nimport { FloPayContext } from './context.js';\nimport { getFloPayTelemetryBridge } from './telemetry-bridge.js';\n\n/** Props for the `FloPayProvider` component. */\nexport interface FloPayProviderProps {\n /** A `FloPay` instance or a promise that resolves to one (from `loadFloPay()`). */\n flopay: Promise<FloPay> | FloPay;\n /**\n * Optional Stripe `FloPay` instance used to drive the Stripe-rendered PayPal\n * fallback. When omitted or `null`, the Stripe-rendered PayPal button is\n * not rendered. Direct PayPal (`gateways.paypal`) does not use this prop.\n */\n paypalFlopay?: Promise<FloPay> | FloPay | null;\n /** Optional configuration applied when creating the elements group. */\n options?: {\n locale?: string;\n appearance?: FloPayAppearance;\n /**\n * Client secret for an existing non-card PaymentIntent or SetupIntent.\n * The SDK verifies the provider intent against the `PaymentElement`'s\n * explicit `paymentMethodTypes` allowlist before mounting and rejects card\n * or undeclared methods. Card checkout uses the hosted vault.\n */\n clientSecret?: string;\n /** Total amount in cents for deferred non-card Elements without a client secret. */\n amount?: number;\n /** ISO 4217 currency code for deferred non-card Elements without a client secret. */\n currency?: string;\n /** How non-card payment methods are created: `'manual'` or `'auto'` (needed for PayPal). */\n paymentMethodCreation?: 'manual' | 'auto';\n /** Requests reusable payment credentials for future payments. */\n setupFutureUsage?: 'off_session' | 'on_session';\n /** Billing API base URL. Set once here so child components don't need to repeat it. */\n billingApiUrl?: string;\n };\n children: React.ReactNode;\n}\n\n/**\n * Provides FloPay SDK context to the component tree.\n *\n * Wrap provider-context elements with this provider:\n *\n * ```tsx\n * <FloPayProvider flopay={loadFloPay('pk_test_...')}>\n * <PaymentElement options={{ paymentMethodTypes: ['cashapp', 'ideal'] }} />\n * </FloPayProvider>\n * ```\n *\n * `FloPayCheckout` is a standalone integration that owns its provider and\n * session-specific Elements setup:\n *\n * ```tsx\n * <FloPayCheckout sessionId=\"sess_...\" />\n * ```\n */\nexport function FloPayProvider({\n flopay: floPayProp,\n paypalFlopay: paypalFloPayProp,\n options,\n children,\n}: FloPayProviderProps): React.ReactElement {\n const [flopay, setFloPay] = useState<FloPay | null>(\n floPayProp instanceof Promise ? null : floPayProp,\n );\n const [paypalFlopay, setPaypalFloPay] = useState<FloPay | null>(\n paypalFloPayProp instanceof Promise || !paypalFloPayProp ? null : paypalFloPayProp,\n );\n const [elements, setElements] = useState<FloPayElements | null>(null);\n const mountedAt = useRef<number | null>(null);\n const renderedElements = useRef<FloPayElements | null>(null);\n const interactiveElements = useRef<FloPayElements | null>(null);\n\n useEffect(() => {\n if (!flopay) return;\n const telemetry = getFloPayTelemetryBridge(flopay);\n mountedAt.current = telemetry?.beginCheckout() ?? telemetry?.now() ?? 0;\n telemetry?.log({ name: 'checkout.mount', stage: 'checkout_mount' });\n return () => {\n telemetry?.log({ name: 'checkout.unmount', stage: 'unmount' });\n };\n }, [flopay]);\n\n // Resolve the promise if needed\n useEffect(() => {\n let cancelled = false;\n\n if (floPayProp instanceof Promise) {\n floPayProp.then((instance) => {\n if (!cancelled) {\n setFloPay(instance);\n }\n });\n } else {\n setFloPay(floPayProp);\n }\n\n return () => {\n cancelled = true;\n };\n }, [floPayProp]);\n\n // Resolve the PayPal promise / prop\n useEffect(() => {\n let cancelled = false;\n\n if (!paypalFloPayProp) {\n setPaypalFloPay(null);\n return;\n }\n\n if (paypalFloPayProp instanceof Promise) {\n paypalFloPayProp.then((instance) => {\n if (!cancelled) {\n setPaypalFloPay(instance);\n }\n });\n } else {\n setPaypalFloPay(paypalFloPayProp);\n }\n\n return () => {\n cancelled = true;\n };\n }, [paypalFloPayProp]);\n\n // Create elements group once FloPay is ready\n useEffect(() => {\n if (!flopay) {\n setElements(null);\n return;\n }\n\n const els = flopay.elements({\n appearance: options?.appearance,\n clientSecret: options?.clientSecret,\n amount: options?.amount,\n currency: options?.currency,\n paymentMethodCreation: options?.paymentMethodCreation,\n setupFutureUsage: options?.setupFutureUsage,\n });\n setElements(els);\n\n return () => {\n els.destroy();\n };\n }, [\n flopay,\n options?.appearance,\n options?.clientSecret,\n options?.amount,\n options?.currency,\n options?.paymentMethodCreation,\n options?.setupFutureUsage,\n ]);\n\n // This effect runs only after the elements value has committed through the\n // context, so consumers have rendered with the group before we mark render.\n useEffect(() => {\n if (!flopay || !elements || renderedElements.current === elements) return;\n renderedElements.current = elements;\n const telemetry = getFloPayTelemetryBridge(flopay);\n telemetry?.log({ name: 'checkout.rendered', stage: 'checkout_render' });\n telemetry?.performance({\n stage: 'checkout_render',\n durationMs: telemetry.elapsed(mountedAt.current ?? 0),\n durationMode: 'machine',\n });\n }, [elements, flopay]);\n\n const reportInteractive = useCallback(() => {\n if (!flopay || !elements || interactiveElements.current === elements) return;\n interactiveElements.current = elements;\n const telemetry = getFloPayTelemetryBridge(flopay);\n telemetry?.log({ name: 'checkout.interactive', stage: 'checkout_interactive' });\n telemetry?.performance({\n stage: 'checkout_interactive',\n durationMs: telemetry.elapsed(mountedAt.current ?? 0),\n durationMode: 'machine',\n });\n }, [elements, flopay]);\n\n const resolvedBillingApiUrl = resolveBillingApiUrl(options?.billingApiUrl);\n\n const value = useMemo(\n () => ({\n flopay,\n paypalFlopay,\n elements,\n billingApiUrl: resolvedBillingApiUrl,\n reportInteractive,\n }),\n [flopay, paypalFlopay, elements, resolvedBillingApiUrl, reportInteractive],\n );\n\n return (\n <FloPayContext.Provider value={value}>\n {children}\n </FloPayContext.Provider>\n );\n}\n","import { createContext } from 'react';\nimport type { FloPay, FloPayElements } from '@flopay/js';\nimport type {\n CheckoutMode,\n CheckoutSession,\n FloPayError,\n InlineSessionDraft,\n InlineSessionPatch,\n} from '@flopay/shared';\n\n/** Internal context value for the FloPay provider. */\nexport interface FloPayContextValue {\n flopay: FloPay | null;\n /**\n * Stripe FloPay instance used for the Stripe-rendered PayPal fallback. When\n * direct PayPal (`gateways.paypal`) is configured this isn't used for\n * rendering — DirectPayPalButton talks to PayPal directly — but the\n * Stripe-PayPal saved-PM redirect leg still relies on it.\n * `null` or absent means the Stripe-rendered PayPal fallback is unavailable.\n */\n paypalFlopay?: FloPay | null;\n elements: FloPayElements | null;\n billingApiUrl: string;\n /** Report the first provider control that reaches its actual ready boundary. */\n reportInteractive?: () => void;\n}\n\n/** Internal context value for checkout state. */\nexport interface CheckoutContextValue {\n session: CheckoutSession | null;\n loading: boolean;\n error: FloPayError | null;\n checkoutMode?: CheckoutMode;\n inlineSessionDraft?: InlineSessionDraft;\n applyInlineSessionPatch?: (\n patch: InlineSessionPatch,\n ) => Promise<{ sessionId: string; session: CheckoutSession | null }>;\n inlineSessionPatchProcessing?: boolean;\n}\n\nexport const FloPayContext = createContext<FloPayContextValue>({\n flopay: null,\n paypalFlopay: null,\n elements: null,\n billingApiUrl: '',\n});\n\nexport const CheckoutContext = createContext<CheckoutContextValue>({\n session: null,\n loading: false,\n error: null,\n});\n","import type { FloPay } from '@flopay/js';\nimport type {\n BuildTelemetryErrorEventInput,\n BuildTelemetryLogEventInput,\n BuildTelemetryPerformanceEventInput,\n BuildTelemetryTerminalEventInput,\n TelemetryCheckoutMode,\n TelemetryLayout,\n TelemetrySdkPackage,\n} from '@flopay/shared';\n\nexport type TelemetryErrorInput = Omit<\n BuildTelemetryErrorEventInput,\n 'eventId' | 'sequence'\n>;\nexport type TelemetryLogInput = Omit<\n BuildTelemetryLogEventInput,\n 'eventId' | 'sequence'\n>;\nexport type TelemetryPerformanceInput = Omit<\n BuildTelemetryPerformanceEventInput,\n 'eventId' | 'sequence'\n>;\nexport type TelemetryTerminalInput = Omit<\n BuildTelemetryTerminalEventInput,\n 'eventId' | 'sequence'\n>;\n\nexport interface TelemetryCheckoutContext {\n checkoutMode?: TelemetryCheckoutMode;\n layout?: TelemetryLayout;\n}\n\nexport interface TelemetryBridge {\n error(input: TelemetryErrorInput): void;\n log(input: TelemetryLogInput): void;\n performance(input: TelemetryPerformanceInput): void;\n terminal(input: TelemetryTerminalInput): void;\n now(): number;\n elapsed(startedAt: number): number;\n setCheckoutContext(context: TelemetryCheckoutContext): void;\n beginCheckout(context?: TelemetryCheckoutContext): number;\n disable(): void;\n flush(): Promise<void>;\n destroy(): void;\n}\n\ninterface ReporterFactoryOptions {\n billingApiUrl: string;\n sdkPackage?: TelemetrySdkPackage;\n sdkVersion: string;\n enabled?: boolean;\n clock?: () => number;\n}\n\nconst FLOPAY_TELEMETRY_BRIDGE = Symbol.for('@flopay/js.telemetry.bridge.v1');\nconst TELEMETRY_REPORTER_FACTORY = Symbol.for('@flopay/js.telemetry.reporter-factory.v1');\n\nfunction noopTelemetryBridge(): TelemetryBridge {\n return {\n error: () => {},\n log: () => {},\n performance: () => {},\n terminal: () => {},\n now: () => globalThis.performance?.now() ?? 0,\n elapsed: (startedAt) => Math.max(0, (globalThis.performance?.now() ?? startedAt) - startedAt),\n setCheckoutContext: () => {},\n beginCheckout: () => globalThis.performance?.now() ?? 0,\n disable: () => {},\n flush: async () => {},\n destroy: () => {},\n };\n}\n\nfunction normalizeTelemetryBridge(source: Partial<TelemetryBridge>): TelemetryBridge {\n const fallback = noopTelemetryBridge();\n const bind = <T extends (...args: never[]) => unknown>(\n candidate: T | undefined,\n defaultValue: T,\n ): T => candidate ? candidate.bind(source) as T : defaultValue;\n const now = bind(source.now, fallback.now);\n return {\n error: bind(source.error, fallback.error),\n log: bind(source.log, fallback.log),\n performance: bind(source.performance, fallback.performance),\n terminal: bind(source.terminal, fallback.terminal),\n now,\n elapsed: source.elapsed\n ? source.elapsed.bind(source)\n : (startedAt) => Math.max(0, now() - startedAt),\n setCheckoutContext: bind(source.setCheckoutContext, fallback.setCheckoutContext),\n beginCheckout: bind(source.beginCheckout, fallback.beginCheckout),\n disable: bind(source.disable, fallback.disable),\n flush: bind(source.flush, fallback.flush),\n destroy: bind(source.destroy, fallback.destroy),\n };\n}\n\nexport function createTelemetryBridge(options: ReporterFactoryOptions): TelemetryBridge {\n const factory = (\n (globalThis as Record<PropertyKey, unknown>)[TELEMETRY_REPORTER_FACTORY]\n ) as ((input: ReporterFactoryOptions) => TelemetryBridge) | undefined;\n return normalizeTelemetryBridge(factory?.(options) ?? {});\n}\n\nexport function getFloPayTelemetryBridge(\n floPay: FloPay | null | undefined,\n): TelemetryBridge | undefined {\n if (!floPay) return undefined;\n return (\n (floPay as unknown as Record<PropertyKey, unknown>)[FLOPAY_TELEMETRY_BRIDGE]\n ) as TelemetryBridge | undefined;\n}\n\n/** Test helper for attaching the same hidden bridge shape to a fake FloPay. */\nexport function attachTelemetryBridgeForTest(\n floPay: object,\n bridge: Partial<TelemetryBridge>,\n): void {\n const replacement = normalizeTelemetryBridge(bridge);\n const existing = getFloPayTelemetryBridge(floPay as FloPay);\n if (existing) {\n Object.assign(existing, replacement);\n return;\n }\n Object.defineProperty(floPay, FLOPAY_TELEMETRY_BRIDGE, {\n configurable: true,\n value: replacement,\n });\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { PaymentAPI } from '@flopay/js';\nimport type { FloPay } from '@flopay/js';\nimport type {\n BeforeButtonClickEvent,\n CheckoutButtonMethod,\n FloPayAppearance,\n DeclineEvent,\n InlineSessionDraft,\n InlineSessionParams,\n InlineSessionPatch,\n PaymentResult,\n CheckoutSession,\n CheckoutMode,\n NormalizedCheckoutSession,\n} from '@flopay/shared';\nimport { SDK_VERSION, FloPayError, resolveBillingApiUrl, buildCheckoutDisplayData, resolveButtonsLayoutTheme, resolveTheme } from '@flopay/shared';\nimport type { ButtonsLayoutStyles, ButtonsLayoutTheme } from '@flopay/shared';\nimport {\n BackButtonContentSlot,\n CardButtonContentSlot,\n TitleContentSlot,\n isEmptySlotContent,\n} from './card-button-content.js';\nimport { FloPayProvider } from './provider.js';\nimport { SplitCardForm } from './split-card-form.js';\nimport { ErrorBanner } from './error-banner.js';\nimport { InstrumentedDirectPayPalButton } from './direct-paypal-button.js';\nimport type { DirectPayPalInitializationState } from './direct-paypal-button.js';\nimport { CheckoutContext } from './context.js';\nimport {\n buildDeclineEvent,\n buildSyntheticSession,\n mapPayPalIntentStatusToPaymentResult,\n mergeInlineSessionPatch,\n mergeInlineSessionPatches,\n} from './checkout-utils.js';\nimport {\n PROCESSING_OVERLAY_ERROR_DELAY_MS,\n PROCESSING_OVERLAY_SUCCESS_DELAY_MS,\n ProcessingOverlay,\n type OverlayStatus,\n} from './processing-overlay.js';\nimport {\n checkoutProcessErrorToFloPayError,\n DEFAULT_SAVED_PAYMENT_DECLINE_METHOD,\n getRedirectResultFromCheckoutProcessError,\n handleSavedPaymentRedirectResult,\n loadSavedPaymentProviders,\n normalizeSavedPaymentError,\n processSavedPaymentForMode,\n resolveSavedPaymentPublishableKeys,\n} from './saved-payment-flow.js';\nimport { markSessionRecentlyCompleted, wasSessionRecentlyCompleted } from './recent-completion.js';\nimport {\n createTelemetryBridge,\n getFloPayTelemetryBridge,\n} from './telemetry-bridge.js';\nimport type { TelemetryBridge, TelemetryCheckoutContext } from './telemetry-bridge.js';\nimport { invokeMerchantCallback } from './merchant-callback.js';\n\nconst DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;\nconst PAYPAL_RESUME_STORAGE_KEY = 'flopay_checkout_saved_payment_resume';\n\n// Module-scoped dedup map: cache key → in-flight `POST /v1/checkouts/sessions`\n// promise. Lives for the page-load only. Shared across every FloPayCheckout\n// instance so two mounts that race (StrictMode dev double-mount, Suspense\n// remount, navigation flicker, etc.) await the same POST instead of starting\n// their own and producing two backend sessions for the same cart.\n// `sessionStorage[cacheKey]` is the durable cross-page-load layer; this Map\n// is the within-page-load layer that closes the window between \"POST is in\n// flight\" and \"POST result has been written to sessionStorage\".\nconst sessionInflightMap: Map<string, Promise<{ sid: string; result: NormalizedCheckoutSession }>> = new Map();\n\n// Cross-module signal for \"this session was just /process'd successfully and\n// is mid-completion.\" Lives in sessionStorage (see `recent-completion.ts`) so\n// it survives both real component remounts and the cross-module boundary\n// between SplitCardForm (where /process succeeds) and this file (where\n// `resolveInlineSession` decides whether to clear a complete-status cache\n// hit). Marker is written *before* the 1.2s overlay delay in SplitCardForm,\n// so a bootstrap that re-runs during that delay still detects the session\n// as \"this journey's completion\" and reuses it.\ntype CheckoutLogType = 'standard_checkout' | 'embedded_checkout';\ntype CheckoutLogLayout = 'default_layout' | 'buttons_layout' | 'custom_layout';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction createStandaloneTelemetryReporter(\n billingApiUrl: string,\n enabled: boolean | undefined,\n context: TelemetryCheckoutContext,\n): TelemetryBridge {\n const reporter = createTelemetryBridge({\n billingApiUrl,\n sdkPackage: '@flopay/react',\n sdkVersion: SDK_VERSION,\n enabled: enabled !== false,\n });\n reporter.beginCheckout(context);\n return reporter;\n}\n\nfunction finishStandaloneTelemetry(reporter: TelemetryBridge): void {\n void reporter.flush()\n .catch(() => {})\n .finally(() => reporter.destroy());\n}\n\nfunction reportStandaloneTelemetryError(\n billingApiUrl: string,\n enabled: boolean | undefined,\n context: TelemetryCheckoutContext,\n errorCode:\n | 'CHECKOUT_SESSION_CREATE_FAILED'\n | 'NETWORK_REQUEST_FAILED'\n | 'REDIRECT_RESUME_FAILED'\n | 'RECOVERY_FAILED'\n | 'INTERNAL_SDK_ERROR',\n stage:\n | 'session_create'\n | 'session_read'\n | 'redirect_resume'\n | 'recovery'\n | 'checkout_mount',\n): void {\n const reporter = createStandaloneTelemetryReporter(billingApiUrl, enabled, context);\n reporter.error({\n errorCode,\n stage,\n paymentMethodCategory: 'unknown',\n ...(stage === 'session_read' ? { requestCategory: 'session_read' as const } : {}),\n });\n finishStandaloneTelemetry(reporter);\n}\n\nfunction isExpectedExistingSessionError(error: FloPayError): boolean {\n return error.type === 'validation_error'\n || error.code === 'checkout_session_not_found'\n || error.code === 'checkout_session_expired'\n || error.code === 'checkout_session_completed'\n || error.code === 'session_auto_completed';\n}\n\ninterface PayPalResumeState {\n sessionId: string | null;\n publishableKey: string;\n paypalPublishableKey?: string;\n}\n\ninterface DirectPayPalConfig {\n clientId: string;\n environment?: import('@flopay/shared').GatewayEnvironment;\n}\n\nfunction resolveDirectPaypalConfig(\n unified: NormalizedCheckoutSession | null,\n): DirectPayPalConfig | undefined {\n const clientId = unified?.data.paypal?.publishableKey;\n if (!clientId) return undefined;\n return {\n clientId,\n environment: unified?.data.paypal?.environment,\n };\n}\n\nfunction isPayPalOnlyUnified(unified: NormalizedCheckoutSession | null): boolean {\n if (!unified) return false;\n if (unified.data.stripe?.publishableKey) return false;\n return Boolean(resolveDirectPaypalConfig(unified)?.clientId);\n}\n\nfunction canUseStorage() {\n return typeof window !== 'undefined' && typeof window.sessionStorage !== 'undefined';\n}\n\nfunction readPayPalResumeState(): PayPalResumeState | null {\n if (!canUseStorage()) return null;\n\n try {\n const raw = window.sessionStorage.getItem(PAYPAL_RESUME_STORAGE_KEY);\n if (!raw) return null;\n return JSON.parse(raw) as PayPalResumeState;\n } catch {\n return null;\n }\n}\n\nfunction persistPayPalResumeState(state: PayPalResumeState) {\n if (!canUseStorage()) return;\n\n try {\n window.sessionStorage.setItem(PAYPAL_RESUME_STORAGE_KEY, JSON.stringify(state));\n } catch (error) {\n console.warn('[FloPayCheckout] Failed to persist PayPal resume state.', error);\n }\n}\n\nfunction clearPayPalResumeState() {\n if (!canUseStorage()) return;\n\n try {\n window.sessionStorage.removeItem(PAYPAL_RESUME_STORAGE_KEY);\n } catch (error) {\n console.warn('[FloPayCheckout] Failed to clear PayPal resume state.', error);\n }\n}\n\ninterface CachedInlineSession {\n sid: string;\n nonce?: string;\n}\n\n// The inline-session cache stores the session id *and* its bound nonce: the\n// backend (TeamFloPay/backend#640) rejects a session GET that omits the matching\n// `x-checkout-session-token`, so a bare id can no longer re-fetch a cached\n// session (it 401s). Legacy entries — a bare id string written before nonces\n// were cached — are tolerated on read; they simply miss the nonce and fall\n// through to a fresh create.\nfunction readCachedInlineSession(cacheKey: string): CachedInlineSession | null {\n if (!canUseStorage()) return null;\n\n const raw = window.sessionStorage.getItem(cacheKey);\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as Partial<CachedInlineSession>;\n if (parsed && typeof parsed.sid === 'string' && parsed.sid) {\n return { sid: parsed.sid, nonce: typeof parsed.nonce === 'string' ? parsed.nonce : undefined };\n }\n return null;\n } catch {\n // Legacy bare-id string from before the nonce was cached.\n return { sid: raw };\n }\n}\n\nfunction persistCachedInlineSession(cacheKey: string, sid: string, nonce?: string) {\n if (!canUseStorage()) return;\n\n try {\n window.sessionStorage.setItem(cacheKey, JSON.stringify(nonce ? { sid, nonce } : { sid }));\n } catch (error) {\n console.warn('[FloPayCheckout] Failed to persist checkout session cache.', error);\n }\n}\n\nfunction clearCachedInlineSession(cacheKey: string) {\n if (!canUseStorage()) return;\n\n try {\n window.sessionStorage.removeItem(cacheKey);\n } catch (error) {\n console.warn('[FloPayCheckout] Failed to clear checkout session cache.', error);\n }\n}\n\nfunction clearPayPalRedirectParams() {\n if (typeof window === 'undefined') return;\n\n const url = new URL(window.location.href);\n const keys = ['payment_intent', 'payment_intent_client_secret', 'redirect_status'];\n let changed = false;\n\n for (const key of keys) {\n if (url.searchParams.has(key)) {\n url.searchParams.delete(key);\n changed = true;\n }\n }\n\n if (changed) {\n window.history.replaceState(window.history.state, '', url.toString());\n }\n}\n\nfunction replaceCheckoutModeQueryParam(mode: CheckoutMode) {\n if (typeof window === 'undefined') return;\n\n const url = new URL(window.location.href);\n url.searchParams.set('mode', mode);\n window.history.replaceState(window.history.state, '', url.toString());\n}\n\n/** Props for the all-in-one `FloPayCheckout` wrapper. */\nexport interface FloPayCheckoutProps {\n /** The checkout session ID (UUID from billing API). Required unless `createSession` is provided. */\n sessionId?: string;\n /**\n * Session-bound checkout token (the `nonce` returned when the session was\n * created). Sent as the `x-checkout-session-token` header when fetching a\n * session by `sessionId`. Required by post-#640 backends, which no longer\n * let the UUID alone authorize a session read; harmless on older backends.\n * Only consulted in the `sessionId` flow — inline `createSession` sessions\n * carry their own freshly-minted nonce server-side.\n */\n nonce?: string;\n /**\n * Create a checkout session inline — no separate API route needed.\n * The component POSTs to the billing API, gets the full session back, and renders the form.\n * Alternative to `sessionId` (provide one or the other).\n */\n createSession?: InlineSessionDraft;\n /** Billing API base URL. Defaults to the shared `BILLING_API_URL` constant. */\n billingApiUrl?: string;\n /** Flo-owned privacy-safe telemetry is enabled by default; set `false` to opt out. */\n telemetry?: boolean;\n /** Visual appearance for payment elements. */\n appearance?: FloPayAppearance;\n /** Locale for payment elements (default: 'auto'). */\n locale?: string;\n /** Custom loading UI. Defaults to a simple centered spinner. */\n loading?: React.ReactNode;\n /** Custom error UI. Receives the error. Defaults to showing the error message. */\n error?: (error: FloPayError) => React.ReactNode;\n /** Called when the full payment flow completes successfully. */\n onComplete?: (result: PaymentResult) => void;\n /** Called when a payment error occurs. */\n onError?: (error: FloPayError) => void;\n /** Called when a payment is declined or the authentication step fails. */\n onDecline?: (decline: DeclineEvent) => void;\n /** Called when the AVS country dropdown changes. */\n onCountryChange?: (country: string) => void;\n /** Called when the AVS ZIP/postcode input changes. */\n onZipChange?: (zip: string) => void;\n /**\n * Show the PayPal payment surface (default: `true`). Renderer is chosen\n * from `gateways.paypal` on the session — DirectPayPalButton when present,\n * Stripe-rendered PayPal otherwise.\n */\n showPayPal?: boolean;\n /**\n * Show Stripe-rendered wallets/APMs alongside the vault-hosted card surface\n * (default: `true`). When `false`, only\n * `DirectPayPalButton` can render. Both `showStripe=false` and\n * `showPayPal=false` (with no PayPal gateway configured) triggers a\n * bootstrap-time validation error.\n */\n showStripe?: boolean;\n /**\n * @deprecated Apple Pay availability is now driven by\n * `gateways.stripe.enabledPaymentMethods` on the per-session response from\n * the billing API. Setting this prop emits a one-time deprecation warning\n * and is otherwise ignored once the backend ships the list.\n */\n showApplePay?: boolean;\n /**\n * @deprecated See {@link FloPayCheckoutProps.showApplePay}.\n */\n showGooglePay?: boolean;\n /**\n * Enables on-screen diagnostic panels (PayPal gate decision, DirectPayPalButton\n * lifecycle). Intended for debugging in-app browsers (Facebook, Instagram, etc.)\n * where remote console access is impractical. Off by default.\n */\n debug?: boolean;\n /** Layout mode: 'default' (all visible) or 'buttons' (PayPal/wallets + expandable card form). */\n layout?: 'default' | 'buttons';\n /**\n * High-level theme bundle that styles non-card Stripe Elements, the FloPay\n * wrapper / AVS inputs, and the hosted vault widget. One of: `'classic'`\n * (historic FloPay look, no bundle applied), `'modern-light'`, `'modern-dark'`,\n * `'bold-light'`, `'bold-dark'`, `'glass-light'`, `'glass-dark'`. Explicit\n * `appearance` / `buttonsStyles` props still override their respective\n * halves when supplied.\n */\n theme?: import('@flopay/shared').ThemeId;\n /**\n * @deprecated Use `theme` instead. Legacy buttons-layout preset\n * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for\n * back-compat.\n */\n buttonsTheme?: import('@flopay/shared').ButtonsLayoutTheme;\n /** Style overrides merged on top of the resolved theme bundle / buttonsTheme preset. */\n buttonsStyles?: import('@flopay/shared').ButtonsLayoutStyles;\n /** Custom React content rendered inside the card button when `layout=\"buttons\"`. */\n cardButtonContent?: React.ReactNode;\n /** Custom React content rendered for the buttons-layout card back button label. */\n cardBackButtonContent?: React.ReactNode;\n /** Custom React content rendered for the card-form title. */\n cardTitleContent?: React.ReactNode;\n /**\n * @deprecated No longer rendered — the default-layout security footer was\n * removed alongside the theme-bundle refactor. Retained as an optional\n * prop so existing integrations type-check without changes.\n */\n showSecurityFooter?: boolean;\n /**\n * Called when a payment method button is clicked.\n * `method`: `'card'` | `'paypal'` | `'apple_pay'` | `'google_pay'`\n */\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n /**\n * Called before a payment button continues in `layout=\"buttons\"`.\n * Runs for card, PayPal, Apple Pay, and Google Pay.\n * In `layout=\"buttons\"` with `createSession`, the returned patch is merged\n * into the inline session params before the selected flow continues.\n */\n onBeforeButtonClick?: (\n event: BeforeButtonClickEvent,\n ) => void | false | Promise<void | false | InlineSessionPatch> | InlineSessionPatch;\n /**\n * Enable AVS (Address Verification).\n * - `true` — show country + postal code (backward compatible default)\n * - `AVSFieldConfig` — granular per-field control, optionally scoped to country codes\n * - `false` / omitted — AVS disabled\n */\n enableAVS?: boolean | import('@flopay/shared').AVSFieldConfig;\n /**\n * Per-merchant order of the hosted vault card rows — a permutation of\n * `['name','number','expiry']` (`'expiry'` = the expiry+CVV row; submit stays\n * last). Sets both the visual and tab order. Omit for the default\n * (`name`, `number`, `expiry`). Vault card path only.\n */\n cardFieldOrder?: import('@flopay/shared').VaultCardFieldKey[];\n /**\n * Content rendered directly above the hosted vault card widget (below the\n * \"or pay with card\" divider). Used by the demo playground to surface a\n * test-cards helper; harmless to omit in a normal integration.\n */\n cardPreFormSlot?: React.ReactNode;\n /** Layout for AVS fields: 'row' (side-by-side, default) or 'column' (stacked). */\n avsLayout?: 'row' | 'column';\n /** Additional CSS class for the wrapper. */\n className?: string;\n /** Seed an initial checkout error message for the rendered payment form. */\n initialErrorMessage?: string | null;\n /**\n * Override the default `SplitCardForm`. When provided, children are rendered\n * inside the initialized `FloPayProvider` with session props auto-injected.\n */\n children?: React.ReactNode;\n\n // ── Checkout mode props ──\n\n /**\n * Override the session's checkoutMode.\n * - `'full'` — show payment form (default)\n * - `'confirm'` — show confirm button, uses saved payment method\n * - `'auto'` — auto-submit with saved PM, falls back to `'full'` on failure\n */\n checkoutMode?: CheckoutMode;\n /** Label for the confirm button in `confirm` mode. Default: `'Confirm Purchase'`. */\n confirmLabel?: string;\n /** Custom confirm button renderer for `confirm` mode. */\n renderConfirmButton?: (props: {\n onConfirm: () => void;\n isProcessing: boolean;\n }) => React.ReactNode;\n /** Called when the session has already been completed. Receives the successUrl. */\n onSessionCompleted?: (successUrl: string) => void;\n\n /**\n * @deprecated No longer used. The Stripe publishable key is sourced exclusively\n * from the checkout session's `gateways.stripe.publishableKey`. Accepted only\n * for backward compatibility with older consumer code — the value is ignored.\n */\n fallbackPublishableKey?: string;\n}\n\nfunction hasInlineSessionPatchData(\n patch: InlineSessionPatch | undefined,\n): boolean {\n if (!patch) return false;\n\n return Boolean(\n (patch.account && Object.keys(patch.account).length > 0)\n || patch.couponCodes !== undefined\n || patch.tagsData !== undefined\n || patch.utmMetadata !== undefined,\n );\n}\n\n/**\n * All-in-one checkout component. Fetches the session, initializes the\n * payment provider, and renders the appropriate UI based on checkout mode.\n *\n * **Modes:**\n * - `full` (default) — renders hosted-vault card capture, wallets, APMs, and PayPal\n * - `confirm` — renders a \"Confirm Purchase\" button, uses saved payment method\n * - `auto` — auto-submits with saved PM, falls back to `full` on failure\n *\n * ```tsx\n * <FloPayCheckout\n * sessionId=\"sess_abc123\"\n * onComplete={(result) => router.push('/success')}\n * onError={(err) => console.error(err)}\n * />\n * ```\n */\nexport function FloPayCheckout({\n sessionId: sessionIdProp,\n nonce: nonceProp,\n createSession: createSessionParams,\n billingApiUrl,\n telemetry,\n appearance: appearanceOverride,\n locale,\n loading: loadingNode,\n error: errorNode,\n onComplete,\n onError,\n onDecline,\n onCountryChange,\n onZipChange,\n showPayPal = true,\n showStripe = true,\n showApplePay = true,\n showGooglePay = true,\n debug = false,\n layout,\n theme,\n buttonsTheme,\n buttonsStyles,\n cardButtonContent,\n cardBackButtonContent,\n cardTitleContent,\n showSecurityFooter: _showSecurityFooter,\n onButtonClick,\n onBeforeButtonClick,\n enableAVS,\n cardFieldOrder,\n cardPreFormSlot,\n avsLayout,\n className,\n initialErrorMessage = null,\n children,\n checkoutMode: checkoutModeProp,\n confirmLabel,\n renderConfirmButton,\n onSessionCompleted,\n}: FloPayCheckoutProps): React.ReactElement {\n const resolvedBillingUrl = resolveBillingApiUrl(billingApiUrl);\n // High-level `theme` resolves to a coherent {appearance, buttonsLayout}\n // bundle from `@flopay/shared`'s `THEMES` map. Explicit `appearance` /\n // `buttonsStyles` props still win — see the precedence comment in\n // `SplitCardForm`.\n const themeBundle = useMemo(() => resolveTheme(theme), [theme]);\n const appearance = appearanceOverride ?? themeBundle?.appearance;\n const checkoutType: CheckoutLogType = createSessionParams ? 'embedded_checkout' : 'standard_checkout';\n const checkoutLayout: CheckoutLogLayout = children\n ? 'custom_layout'\n : layout === 'buttons'\n ? 'buttons_layout'\n : 'default_layout';\n\n const [unified, setUnified] = useState<NormalizedCheckoutSession | null>(null);\n const [flopay, setFloPay] = useState<FloPay | null>(null);\n const flopayRef = useRef<FloPay | null>(null);\n const [paypalFlopay, setPaypalFloPay] = useState<FloPay | null>(null);\n const paypalFlopayRef = useRef<FloPay | null>(null);\n const [session, setSession] = useState<CheckoutSession | null>(null);\n const [resolvedSessionId, setResolvedSessionId] = useState<string>(sessionIdProp ?? '');\n const activeSessionId = sessionIdProp ?? resolvedSessionId;\n const initSessionDependency = createSessionParams ? '' : activeSessionId;\n const [isLoading, setIsLoading] = useState(true);\n const [loadError, setLoadError] = useState<FloPayError | null>(null);\n const [currentMode, setCurrentMode] = useState<CheckoutMode>('full');\n const [confirmProcessing, setConfirmProcessing] = useState(false);\n const [modeError, setModeError] = useState<string | null>(initialErrorMessage);\n const [modeOverlayStatus, setModeOverlayStatus] = useState<OverlayStatus | null>(null);\n const [modeOverlayError, setModeOverlayError] = useState<string | null>(null);\n const [createSessionPatch, setCreateSessionPatch] = useState<InlineSessionPatch | undefined>(undefined);\n const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = useState('');\n const [cardBootstrapPending, setCardBootstrapPending] = useState(false);\n const [paypalInitializationState, setPaypalInitializationState] =\n useState<DirectPayPalInitializationState>('loading');\n const [paypalManualRetryGeneration, setPaypalManualRetryGeneration] = useState(0);\n const autoCheckoutAttempted = useRef(false);\n const paypalResumeAttempted = useRef(false);\n const paypalInitializationErrorEmittedRef = useRef(false);\n const savedPaymentKeysRef = useRef<{\n publishableKey?: string;\n paypalPublishableKey?: string;\n } | null>(null);\n const telemetryCheckoutContext = useMemo<TelemetryCheckoutContext>(() => ({\n checkoutMode: checkoutModeProp ?? currentMode,\n layout: children ? 'unknown' : layout === 'buttons' ? 'buttons' : 'embedded',\n }), [checkoutModeProp, children, currentMode, layout]);\n\n // Store callbacks in refs to avoid re-triggering the init useEffect\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onDeclineRef = useRef(onDecline);\n onDeclineRef.current = onDecline;\n\n useEffect(() => {\n getFloPayTelemetryBridge(flopay)?.setCheckoutContext(telemetryCheckoutContext);\n if (paypalFlopay && paypalFlopay !== flopay) {\n getFloPayTelemetryBridge(paypalFlopay)?.setCheckoutContext(telemetryCheckoutContext);\n }\n }, [flopay, paypalFlopay, telemetryCheckoutContext]);\n const onSessionCompletedRef = useRef(onSessionCompleted);\n onSessionCompletedRef.current = onSessionCompleted;\n\n const handlePayPalInitializationStateChange = useCallback(\n (state: DirectPayPalInitializationState) => {\n setPaypalInitializationState(state);\n if (state !== 'exhausted' || paypalInitializationErrorEmittedRef.current) return;\n paypalInitializationErrorEmittedRef.current = true;\n onErrorRef.current?.(new FloPayError(\n 'PayPal is temporarily unavailable. Please try again.',\n 'api_error',\n { code: 'paypal_init_timeout' },\n ));\n },\n [],\n );\n\n const retryPayPalInitialization = useCallback(() => {\n setPaypalInitializationState('retrying');\n setPaypalManualRetryGeneration((generation) => generation + 1);\n }, []);\n\n useEffect(() => {\n setPaypalInitializationState('loading');\n setPaypalManualRetryGeneration(0);\n paypalInitializationErrorEmittedRef.current = false;\n }, [activeSessionId]);\n\n useEffect(() => {\n console.info('[FloPay] Checkout initialized', {\n sdk_version: SDK_VERSION,\n checkout_type: checkoutType,\n checkout_layout: checkoutLayout,\n billing_api_url: resolvedBillingUrl,\n });\n }, [checkoutLayout, checkoutType, resolvedBillingUrl]);\n\n const baseCreateSessionHash = useMemo(\n () => createSessionParams ? hashCreateParams(createSessionParams) : '',\n [createSessionParams],\n );\n const activeCreateSessionPatch = useMemo(\n () => createSessionPatchBaseHash === baseCreateSessionHash\n ? createSessionPatch\n : undefined,\n [createSessionPatch, createSessionPatchBaseHash, baseCreateSessionHash],\n );\n const effectiveCreateSessionBase = useMemo(\n () => createSessionParams\n ? mergeInlineSessionPatch(createSessionParams, activeCreateSessionPatch)\n : undefined,\n [createSessionParams, activeCreateSessionPatch],\n );\n const effectiveCreateSessionMode = checkoutModeProp ?? effectiveCreateSessionBase?.checkoutMode ?? 'full';\n const effectiveCreateSession = useMemo(\n () => effectiveCreateSessionBase\n ? {\n ...effectiveCreateSessionBase,\n checkoutMode: effectiveCreateSessionMode,\n }\n : undefined,\n [effectiveCreateSessionBase, effectiveCreateSessionMode],\n );\n\n useEffect(() => {\n setCreateSessionPatch(undefined);\n setCreateSessionPatchBaseHash(baseCreateSessionHash);\n }, [baseCreateSessionHash]);\n\n useEffect(() => {\n setModeError(initialErrorMessage);\n }, [initialErrorMessage]);\n\n const emitDecline = useCallback(\n (\n method: CheckoutButtonMethod,\n input: string | FloPayError,\n overrides?: { code?: string; declineCode?: string },\n ) => {\n invokeMerchantCallback(() => {\n onDeclineRef.current?.(buildDeclineEvent(method, input, overrides));\n });\n },\n [invokeMerchantCallback],\n );\n\n const runSavedPaymentFlow = useCallback(\n async (\n sess: CheckoutSession,\n options?: {\n attempt3DS?: boolean;\n fallbackToFull?: boolean;\n ensureProvidersReady?: () => Promise<unknown>;\n fromCreateSession?: boolean;\n initialAutoProcessingError?: NormalizedCheckoutSession['autoProcessingError'];\n initialAutoProcessingPending?: NormalizedCheckoutSession['autoProcessingPending'];\n autoProcessingAttempted?: boolean;\n sessionId?: string;\n },\n ): Promise<boolean> => {\n setModeError(null);\n setModeOverlayError(null);\n setModeOverlayStatus('processing');\n\n const activeSessionId = options?.sessionId ?? sess.id;\n const activeFloPay = flopayRef.current ?? paypalFlopayRef.current;\n const activeTelemetry = getFloPayTelemetryBridge(activeFloPay);\n const standaloneTelemetry = activeFloPay\n ? null\n : createStandaloneTelemetryReporter(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n );\n const telemetrySource = {\n log: (input: Parameters<TelemetryBridge['log']>[0]) => {\n if (activeTelemetry) activeTelemetry.log(input);\n else standaloneTelemetry?.log(input);\n },\n error: (input: Parameters<TelemetryBridge['error']>[0]) => {\n if (activeTelemetry) activeTelemetry.error(input);\n else standaloneTelemetry?.error(input);\n },\n terminal: (input: Parameters<TelemetryBridge['terminal']>[0]) => {\n if (activeTelemetry) activeTelemetry.terminal(input);\n else standaloneTelemetry?.terminal(input);\n },\n performance: (input: Parameters<TelemetryBridge['performance']>[0]) => {\n if (activeTelemetry) activeTelemetry.performance(input);\n else standaloneTelemetry?.performance(input);\n },\n now: () => activeTelemetry?.now() ?? standaloneTelemetry?.now() ?? 0,\n elapsed: (startedAt: number) => activeTelemetry?.elapsed(startedAt)\n ?? Math.max(0, (standaloneTelemetry?.now() ?? startedAt) - startedAt),\n };\n const processingStartedAt = telemetrySource.now();\n let recoveryFlow = Boolean(\n options?.initialAutoProcessingError || options?.initialAutoProcessingPending,\n );\n let recoveryStarted = false;\n let recoveryStartedAt: number | undefined;\n const startRecovery = () => {\n if (recoveryStarted) return;\n recoveryStarted = true;\n recoveryFlow = true;\n recoveryStartedAt = telemetrySource.now();\n telemetrySource.log({\n name: 'checkout.recovery.started',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.log({\n name: 'operation.recovery.started',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n };\n let processingFinished = false;\n const finishProcessing = () => {\n if (processingFinished) return;\n processingFinished = true;\n telemetrySource.log({\n name: 'payment.processing.completed',\n stage: 'processing',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.performance({\n stage: 'processing',\n durationMs: telemetrySource.elapsed(processingStartedAt),\n durationMode: 'machine',\n paymentMethodCategory: 'saved',\n });\n if (recoveryStartedAt !== undefined) {\n telemetrySource.performance({\n stage: 'recovery',\n durationMs: telemetrySource.elapsed(recoveryStartedAt),\n durationMode: 'machine',\n paymentMethodCategory: 'saved',\n });\n }\n };\n telemetrySource.log({\n name: 'payment.method.selected',\n stage: 'processing',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.log({\n name: 'payment.processing.started',\n stage: 'processing',\n paymentMethodCategory: 'saved',\n });\n if (recoveryFlow) {\n startRecovery();\n }\n\n let completionCallback: (() => unknown) | undefined;\n try {\n const redirectResult = getRedirectResultFromCheckoutProcessError(options?.initialAutoProcessingError);\n let paymentResult: PaymentResult;\n\n if (redirectResult) {\n startRecovery();\n if (\n redirectResult.type === 'paypal_redirect_required'\n && savedPaymentKeysRef.current?.publishableKey\n ) {\n persistPayPalResumeState({\n sessionId: activeSessionId,\n publishableKey: savedPaymentKeysRef.current.publishableKey,\n paypalPublishableKey: savedPaymentKeysRef.current.paypalPublishableKey,\n });\n }\n\n paymentResult = await handleSavedPaymentRedirectResult(redirectResult, {\n flopay: flopayRef.current,\n paypalFlopay: paypalFlopayRef.current,\n attempt3DS: options?.attempt3DS,\n billingApiUrl: resolvedBillingUrl,\n sessionId: activeSessionId,\n session: sess,\n telemetry: false,\n });\n\n if (redirectResult.type === 'paypal_redirect_required') {\n clearPayPalResumeState();\n }\n } else if (options?.initialAutoProcessingPending) {\n const api = new PaymentAPI(resolvedBillingUrl, { telemetry: false });\n const completed = await api.waitForCheckoutSessionCompletion(options.initialAutoProcessingPending.sessionId, {\n initialDelayMs: options.initialAutoProcessingPending.retryAfterMs,\n });\n\n if (completed.data.session?.status !== 'complete') {\n throw new FloPayError('Automatic payment failed. Please try again.', 'api_error', {\n code: completed.data.session?.status === 'expired'\n ? 'checkout_session_expired'\n : 'checkout_processing_timeout',\n });\n }\n\n paymentResult = { status: 'succeeded' };\n } else if (options?.initialAutoProcessingError) {\n throw checkoutProcessErrorToFloPayError(\n options.initialAutoProcessingError,\n 'Automatic payment failed. Please try again.',\n {\n checkoutMethod: options.initialAutoProcessingError.checkoutMethod,\n },\n );\n } else if (options?.fromCreateSession) {\n if (options?.fallbackToFull) {\n setCurrentMode('full');\n replaceCheckoutModeQueryParam('full');\n }\n return false;\n } else {\n const result = await processSavedPaymentForMode({\n billingApiUrl: resolvedBillingUrl,\n sessionId: activeSessionId,\n session: sess,\n telemetry: false,\n });\n if (result.type === 'success') {\n paymentResult = result.result;\n } else {\n startRecovery();\n if (\n result.type === 'paypal_redirect_required'\n && savedPaymentKeysRef.current?.publishableKey\n ) {\n persistPayPalResumeState({\n sessionId: activeSessionId,\n publishableKey: savedPaymentKeysRef.current.publishableKey,\n paypalPublishableKey: savedPaymentKeysRef.current.paypalPublishableKey,\n });\n }\n\n paymentResult = await handleSavedPaymentRedirectResult(result, {\n flopay: flopayRef.current,\n paypalFlopay: paypalFlopayRef.current,\n attempt3DS: options?.attempt3DS,\n billingApiUrl: resolvedBillingUrl,\n sessionId: activeSessionId,\n session: sess,\n telemetry: false,\n });\n\n if (result.type === 'paypal_redirect_required') {\n clearPayPalResumeState();\n }\n }\n }\n\n // Mark before the overlay delay so a bootstrap that re-runs during\n // the delay window detects the completion and reuses the session.\n if (activeSessionId) markSessionRecentlyCompleted(activeSessionId);\n finishProcessing();\n if (recoveryFlow) {\n telemetrySource.log({\n name: 'checkout.recovery.completed',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.log({\n name: 'operation.recovery.completed',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n }\n telemetrySource.terminal({\n outcome: 'payment_succeeded',\n paymentMethodCategory: 'saved',\n });\n setModeOverlayStatus('success');\n await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);\n completionCallback = () => onCompleteRef.current?.(paymentResult);\n } catch (err) {\n const floPayErr = normalizeSavedPaymentError(err);\n const method = floPayErr.checkoutMethod ?? DEFAULT_SAVED_PAYMENT_DECLINE_METHOD;\n\n setModeError(floPayErr.message);\n setModeOverlayError(floPayErr.message);\n if (options?.fallbackToFull) {\n telemetrySource.log({\n name: 'operation.fallback',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n setCurrentMode('full');\n replaceCheckoutModeQueryParam('full');\n }\n finishProcessing();\n const expectedDecline = Boolean(\n floPayErr.declineCode\n || floPayErr.code?.toLowerCase().includes('declin'),\n );\n if (expectedDecline) {\n telemetrySource.terminal({\n outcome: 'payment_declined',\n paymentMethodCategory: 'saved',\n });\n } else {\n telemetrySource.error({\n errorCode: recoveryFlow\n ? 'RECOVERY_FAILED'\n : 'PAYMENT_PROCESSING_FAILED',\n stage: recoveryFlow ? 'recovery' : 'processing',\n paymentMethodCategory: 'saved',\n });\n }\n invokeMerchantCallback(() => onErrorRef.current?.(floPayErr));\n emitDecline(method, floPayErr, {\n code: floPayErr.code,\n declineCode: floPayErr.declineCode,\n });\n setModeOverlayStatus('error');\n\n await Promise.allSettled([\n sleep(PROCESSING_OVERLAY_ERROR_DELAY_MS),\n options?.ensureProvidersReady ? options.ensureProvidersReady() : Promise.resolve(),\n ]);\n if (recoveryFlow) {\n telemetrySource.log({\n name: 'checkout.recovery.completed',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n telemetrySource.log({\n name: 'operation.recovery.completed',\n stage: 'recovery',\n paymentMethodCategory: 'saved',\n });\n }\n return false;\n } finally {\n finishProcessing();\n if (standaloneTelemetry) finishStandaloneTelemetry(standaloneTelemetry);\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n }\n\n invokeMerchantCallback(completionCallback);\n return true;\n },\n [\n emitDecline,\n invokeMerchantCallback,\n normalizeSavedPaymentError,\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n ],\n );\n\n useEffect(() => {\n if (typeof window === 'undefined' || paypalResumeAttempted.current) {\n return;\n }\n\n const params = new URLSearchParams(window.location.search);\n const clientSecret = params.get('payment_intent_client_secret');\n if (!clientSecret) {\n return;\n }\n\n const resumeState = readPayPalResumeState();\n if (!resumeState) {\n return;\n }\n\n paypalResumeAttempted.current = true;\n\n void (async () => {\n let resumeTelemetry: TelemetryBridge | undefined;\n let redirectResumeStartedAt = 0;\n setModeError(null);\n setModeOverlayError(null);\n setModeOverlayStatus('processing');\n setConfirmProcessing(true);\n\n try {\n if (params.get('redirect_status') === 'failed') {\n throw Object.assign(\n new FloPayError(\n 'PayPal payment was declined. Please try again.',\n 'api_error',\n { declineCode: 'paypal_redirect_failed' },\n ),\n { checkoutMethod: 'paypal' as const },\n );\n }\n\n const {\n flopay: resumeFlopay,\n paypalFlopay: resumePaypalFlopay,\n } = await loadSavedPaymentProviders({\n publishableKey: resumeState.publishableKey,\n paypalPublishableKey: resumeState.paypalPublishableKey,\n billingApiUrl: resolvedBillingUrl,\n locale,\n telemetry,\n });\n resumeTelemetry = getFloPayTelemetryBridge(resumePaypalFlopay ?? resumeFlopay);\n redirectResumeStartedAt = resumeTelemetry?.now() ?? 0;\n resumeTelemetry?.log({\n name: 'provider.redirect.resumed',\n stage: 'redirect_resume',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n resumeTelemetry?.log({\n name: 'operation.recovery.started',\n stage: 'recovery',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n\n const paypalStripe = (resumePaypalFlopay ?? resumeFlopay)?.getRawProvider() as import('@stripe/stripe-js').Stripe | null;\n if (!paypalStripe) {\n throw Object.assign(\n new FloPayError('PayPal is not available.', 'api_error'),\n { checkoutMethod: 'paypal' as const },\n );\n }\n\n const { paymentIntent, error } = await paypalStripe.retrievePaymentIntent(clientSecret);\n if (error) {\n throw Object.assign(\n new FloPayError(\n error.message ?? 'Failed to retrieve PayPal payment status.',\n 'api_error',\n { code: error.code },\n ),\n { checkoutMethod: 'paypal' as const },\n );\n }\n\n const resultStatus = mapPayPalIntentStatusToPaymentResult(paymentIntent?.status);\n\n if (!paymentIntent || resultStatus === 'failed') {\n throw Object.assign(\n new FloPayError('PayPal payment was not completed. Please try again.', 'api_error'),\n { checkoutMethod: 'paypal' as const },\n );\n }\n\n const paymentMethodId = typeof paymentIntent.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent.payment_method?.id;\n\n // Manual-capture PayPal PIs land at `requires_capture` after PayPal\n // authorization. Backend must capture via /process, otherwise the PI\n // sits at requires_capture forever (\"Uncaptured\" in Stripe).\n let finalResultStatus: PaymentResult['status'] = resultStatus;\n if (resumeState.sessionId) {\n const resumeApi = new PaymentAPI(resolvedBillingUrl, { telemetry: false });\n const resumeSessionResult = await resumeApi.getUnifiedCheckoutSession(resumeState.sessionId);\n const resumeSession = resumeSessionResult.data.session;\n if (resumeSession && resumeSession.status !== 'complete') {\n const processResult = await processSavedPaymentForMode({\n billingApiUrl: resolvedBillingUrl,\n sessionId: resumeState.sessionId,\n session: resumeSession,\n telemetry: false,\n tokenizedData: {\n id: paymentMethodId ?? paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n isPaypal: true,\n },\n });\n if (processResult.type !== 'success') {\n throw Object.assign(\n new FloPayError('Failed to finalize PayPal payment.', 'api_error'),\n { checkoutMethod: 'paypal' as const },\n );\n }\n // /process's result.status reflects post-capture state; the\n // pre-capture PI status mapping would otherwise leak through.\n finalResultStatus = processResult.result.status;\n }\n }\n\n if (resumeState.sessionId) markSessionRecentlyCompleted(resumeState.sessionId);\n resumeTelemetry?.log({\n name: 'operation.recovery.completed',\n stage: 'recovery',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n resumeTelemetry?.performance({\n stage: 'redirect_resume',\n durationMs: resumeTelemetry.elapsed(redirectResumeStartedAt),\n durationMode: 'machine',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n resumeTelemetry?.terminal({\n outcome: 'payment_succeeded',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n setModeOverlayStatus('success');\n await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);\n invokeMerchantCallback(() => onCompleteRef.current?.({\n status: finalResultStatus,\n paymentIntentId: paymentIntent.id,\n paymentMethodId,\n checkoutMethod: 'paypal',\n }));\n } catch (err) {\n const floPayErr = normalizeSavedPaymentError(err);\n const method = floPayErr.checkoutMethod ?? 'paypal';\n const expectedDecline = Boolean(\n floPayErr.declineCode\n || floPayErr.code?.toLowerCase().includes('declin'),\n );\n\n if (resumeTelemetry) {\n resumeTelemetry.performance({\n stage: 'redirect_resume',\n durationMs: resumeTelemetry.elapsed(redirectResumeStartedAt),\n durationMode: 'machine',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n if (expectedDecline) {\n resumeTelemetry.terminal({\n outcome: 'payment_declined',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n } else {\n resumeTelemetry.error({\n errorCode: 'REDIRECT_RESUME_FAILED',\n stage: 'redirect_resume',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n }\n } else if (expectedDecline) {\n const reporter = createStandaloneTelemetryReporter(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n );\n reporter.terminal({\n outcome: 'payment_declined',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n finishStandaloneTelemetry(reporter);\n } else {\n reportStandaloneTelemetryError(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n 'REDIRECT_RESUME_FAILED',\n 'redirect_resume',\n );\n }\n\n setModeError(floPayErr.message);\n setModeOverlayError(floPayErr.message);\n invokeMerchantCallback(() => onErrorRef.current?.(floPayErr));\n emitDecline(method, floPayErr, {\n code: floPayErr.code,\n declineCode: floPayErr.declineCode,\n });\n setModeOverlayStatus('error');\n await sleep(PROCESSING_OVERLAY_ERROR_DELAY_MS);\n } finally {\n clearPayPalResumeState();\n clearPayPalRedirectParams();\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n setConfirmProcessing(false);\n }\n })();\n }, [emitDecline, invokeMerchantCallback, locale, normalizeSavedPaymentError, resolvedBillingUrl, telemetry]);\n\n // ── Session creation dedup ──\n // Uses the module-level `sessionInflightMap` (declared near the top of this\n // file) so two FloPayCheckout instances mounted in the same page-load —\n // including React StrictMode's dev double-mount, a Suspense remount, or a\n // navigation that briefly remounts the parent — share the same in-flight\n // POST instead of each starting their own and producing duplicate sessions.\n // A per-component useRef would be reset on each remount and cannot dedupe\n // across instances.\n // Tracks whether init has already completed — prevents redundant re-runs\n // when createSessionParams is a new object ref but semantically identical.\n const initializedHashRef = useRef<string | null>(null);\n\n // ── Deterministic hash for session caching ──\n\n function hashCreateParams(params: InlineSessionDraft | undefined): string {\n // Include only a compact buyer fingerprint in the cache key. The resulting\n // sessionStorage key is hashed, but the checkout session itself is account-\n // bound on the backend; reusing it across emails/users can route payment\n // processing through the wrong persisted gateway.\n //\n // Note: `account.userId` is intentionally excluded. It is a consumer-\n // generated identifier and many consumers (e.g. funnels-next) regenerate\n // it per component mount via `crypto.randomUUID()` — including it here\n // would produce a new hash on every mount, miss the sessionStorage cache,\n // and POST a duplicate session every time. Email + country are sufficient\n // buyer-identity for cross-buyer cache safety.\n const key = JSON.stringify({\n c: params?.clientId,\n cur: params?.currency ?? '',\n a: {\n e: params?.account?.email?.trim().toLowerCase() ?? '',\n country: params?.account?.country ?? '',\n },\n successUrl: params?.successUrl,\n cancelUrl: params?.cancelUrl,\n // Unified products[] is the post-#760 wire shape. Must be included or\n // carts that only set `products` (no legacy items/subscriptions) all\n // hash to the same key — the bootstrap effect's `createSessionHash`\n // dep then never changes when products change, the session-id cache\n // hits the wrong session, and the backend's enabledPaymentMethods\n // result for the *previous* cart sticks until a fresh page-load with\n // the session cache cleared.\n p: params?.products?.map(x => `${x.type ?? ''}:${x.code ?? x.providerItemId ?? x.providerPlanId ?? ''}:${x.totalAmount ?? ''}:${x.overrideAmount ?? ''}:${x.quantity ?? 1}`).sort(),\n i: params?.items?.map(x => `${x.code ?? x.providerItemId ?? ''}:${x.totalAmount ?? ''}:${x.overrideAmount ?? ''}:${x.quantity ?? 1}`).sort(),\n s: params?.subscriptions?.map(x => `${x.code ?? x.providerPlanId ?? ''}:${x.totalAmount ?? ''}:${x.overrideAmount ?? ''}:${x.quantity ?? 1}`).sort(),\n couponCodes: params?.couponCodes,\n tagsData: params?.tagsData,\n utmMetadata: params?.utmMetadata,\n tokenizedData: params?.tokenizedData,\n m: params?.checkoutMode ?? 'full',\n });\n let h = 0;\n for (let i = 0; i < key.length; i++) {\n h = ((h << 5) - h + key.charCodeAt(i)) | 0;\n }\n return `flopay_session_${Math.abs(h).toString(36)}`;\n }\n\n // Stable hash of createSession params — used as effect dependency instead\n // of the raw object, so a new object reference with the same values\n // doesn't re-trigger the effect.\n const createSessionHash = useMemo(\n () => effectiveCreateSession ? hashCreateParams(effectiveCreateSession) : '',\n [effectiveCreateSession],\n );\n // Keep a ref to the latest params so the effect closure always sees them.\n const createSessionParamsRef = useRef(effectiveCreateSession);\n createSessionParamsRef.current = effectiveCreateSession;\n\n useEffect(() => {\n setResolvedSessionId(sessionIdProp ?? '');\n }, [sessionIdProp]);\n\n useEffect(() => {\n autoCheckoutAttempted.current = false;\n setModeError(initialErrorMessage);\n setModeOverlayError(null);\n setModeOverlayStatus(null);\n }, [createSessionHash, initialErrorMessage, sessionIdProp]);\n\n async function resolveInlineSession(\n params: InlineSessionDraft,\n cacheKey: string,\n ): Promise<{ sid: string; result: NormalizedCheckoutSession }> {\n const reporter = createStandaloneTelemetryReporter(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n );\n const api = new PaymentAPI(resolvedBillingUrl, { telemetry: false });\n try {\n const cached = readCachedInlineSession(cacheKey);\n reporter.log({\n name: cached ? 'operation.cache.hit' : 'operation.cache.miss',\n stage: 'session_create',\n requestCategory: 'session_create',\n });\n let sid: string | null = cached?.sid ?? null;\n let realResult: NormalizedCheckoutSession | null = null;\n\n if (sid) {\n try {\n // Forward the cached nonce — the backend rejects a session GET without\n // the matching `x-checkout-session-token` (TeamFloPay/backend#640).\n realResult = await api.getUnifiedCheckoutSession(sid, cached?.nonce);\n const status = realResult.data.session?.status;\n if (status === 'complete') {\n // If this session was completed inside the current page-load — the\n // marker is written synchronously in SplitCardForm the moment\n // /process succeeds, *before* the 1.2s overlay delay — return the\n // completed session as-is. Otherwise the parent's mid-flight\n // onComplete + navigation could race a re-mounted bootstrap into\n // clearing the cache and POSTing a duplicate session that would\n // then be /process'd with the same PI (the source of the\n // duplicate-subscription bug).\n if (wasSessionRecentlyCompleted(sid)) {\n return { sid, result: realResult };\n }\n // Otherwise the cached session is genuinely stale (e.g. user\n // revisits /checkout in a new page-load after a previous successful\n // checkout). Clear and create a new one as before.\n clearCachedInlineSession(cacheKey);\n sid = null;\n realResult = null;\n }\n } catch {\n reporter.log({\n name: 'operation.fallback',\n stage: 'session_read',\n requestCategory: 'session_read',\n });\n clearCachedInlineSession(cacheKey);\n sid = null;\n }\n }\n\n if (!sid) {\n const sessionCreateStartedAt = reporter.now();\n reporter.log({\n name: 'session.create.started',\n stage: 'session_create',\n requestCategory: 'session_create',\n });\n // Inject checkout analytics metadata into the session creation payload\n const paramsWithAnalytics: InlineSessionParams = {\n ...(params as InlineSessionParams),\n avsCheck: !!enableAVS,\n avsConfig: typeof enableAVS === 'object' ? enableAVS : undefined,\n checkoutType: 'embedded_checkout',\n checkoutLayout: children ? 'custom_layout' : layout === 'buttons' ? 'buttons_layout' : 'default_layout',\n };\n try {\n realResult = await api.createAndFetchSession(paramsWithAnalytics);\n reporter.log({\n name: 'session.request.completed',\n stage: 'session_complete',\n requestCategory: 'session_create',\n statusClass: '2xx',\n });\n reporter.performance({\n stage: 'session_create',\n durationMs: reporter.now() - sessionCreateStartedAt,\n durationMode: 'machine',\n requestCategory: 'session_create',\n statusClass: '2xx',\n });\n } catch (error) {\n reporter.performance({\n stage: 'session_create',\n durationMs: reporter.now() - sessionCreateStartedAt,\n durationMode: 'machine',\n requestCategory: 'session_create',\n statusClass: 'network_error',\n });\n if (error instanceof FloPayError && error.type === 'validation_error') {\n reporter.terminal({\n outcome: 'validation_rejected',\n stage: 'session_create',\n paymentMethodCategory: 'unknown',\n });\n } else {\n reporter.error({\n errorCode: 'CHECKOUT_SESSION_CREATE_FAILED',\n stage: 'session_create',\n paymentMethodCategory: 'unknown',\n requestCategory: 'session_create',\n });\n }\n throw error;\n }\n sid = realResult.data.session?.id ?? '';\n if (sid) {\n // Cache the nonce too so a later reuse can re-fetch (see above).\n persistCachedInlineSession(cacheKey, sid, realResult.data.session?.clientSecret);\n }\n }\n\n return { sid: sid ?? '', result: realResult! };\n } finally {\n finishStandaloneTelemetry(reporter);\n }\n }\n\n const bootstrapInlineSession = useCallback(\n async (patch?: InlineSessionPatch) => {\n const baseParams = createSessionParamsRef.current;\n if (!baseParams) {\n throw new FloPayError('createSession is required to bootstrap checkout.', 'validation_error');\n }\n\n const mergedParams = mergeInlineSessionPatch(baseParams, patch);\n // The cache key includes a compact buyer fingerprint because backend\n // sessions are account-bound. Account, coupon, tag, UTM, or cart changes\n // should bootstrap a fresh session instead of reusing a stale gateway.\n const cacheKey = hashCreateParams(mergedParams);\n\n let promise = sessionInflightMap.get(cacheKey);\n if (!promise) {\n promise = resolveInlineSession(mergedParams, cacheKey);\n sessionInflightMap.set(cacheKey, promise);\n }\n\n let resolved: { sid: string; result: NormalizedCheckoutSession };\n try {\n resolved = await promise;\n } finally {\n // Only the inserter clears the map entry — but `delete` on a missing\n // key is a no-op so this is safe to call from every awaiter.\n sessionInflightMap.delete(cacheKey);\n }\n\n initializedHashRef.current = cacheKey;\n\n try {\n if (patch) {\n setCreateSessionPatchBaseHash(baseCreateSessionHash);\n setCreateSessionPatch((prev) => mergeInlineSessionPatches(prev, patch));\n }\n\n const { sid, result: realResult } = resolved;\n\n setUnified(realResult);\n if (realResult.data.session) {\n setSession(realResult.data.session);\n }\n if (sid) {\n setResolvedSessionId(sid);\n }\n\n const {\n publishableKey,\n paypalPublishableKey,\n } = resolveSavedPaymentPublishableKeys(realResult);\n const {\n flopay: instance,\n paypalFlopay: paypalInstance,\n } = await loadSavedPaymentProviders({\n publishableKey,\n paypalPublishableKey,\n billingApiUrl: resolvedBillingUrl,\n locale,\n telemetry,\n });\n\n flopayRef.current = instance;\n setFloPay(instance);\n paypalFlopayRef.current = paypalInstance;\n setPaypalFloPay(paypalInstance);\n\n setIsLoading(false);\n } catch (err) {\n if (initializedHashRef.current === cacheKey) {\n initializedHashRef.current = null;\n }\n throw err;\n }\n\n return resolved;\n },\n [locale, resolvedBillingUrl, telemetry, telemetryCheckoutContext],\n );\n\n const handleInlineSessionPatch = useCallback(async (patch: InlineSessionPatch) => {\n if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) {\n return {\n sessionId: resolvedSessionId,\n session,\n };\n }\n\n setCardBootstrapPending(true);\n try {\n const resolved = await bootstrapInlineSession(patch);\n return {\n sessionId: resolved.sid,\n session: resolved.result.data.session ?? null,\n };\n } finally {\n setCardBootstrapPending(false);\n }\n }, [\n bootstrapInlineSession,\n cardBootstrapPending,\n resolvedSessionId,\n session,\n ]);\n\n // ── Fetch session + initialize ──\n\n useEffect(() => {\n let cancelled = false;\n setLoadError(null);\n\n // ── createSession path: render immediately, resolve in background ──\n if (createSessionHash) {\n const params = createSessionParamsRef.current!;\n setSession(buildSyntheticSession(params, checkoutModeProp));\n setCurrentMode(effectiveCreateSessionMode);\n setIsLoading(false);\n\n // Already initialized with the same params — skip the network bootstrap\n // but keep the synthetic session in sync with any mode override.\n if (initializedHashRef.current === createSessionHash) {\n return () => { cancelled = true; };\n }\n\n (async () => {\n // Skip auto-checkout when resuming from a PayPal redirect — the\n // PayPal-resume effect (above) is the canonical completer for that\n // path. Without this guard, runSavedPaymentFlow races the resume\n // effect and triggers a duplicate POST /v1/checkouts/sessions/process.\n const hasPayPalRedirectParams =\n typeof window !== 'undefined' &&\n new URLSearchParams(window.location.search).has('payment_intent');\n\n const shouldAutoProcessInlineSession =\n effectiveCreateSessionMode === 'auto' &&\n !autoCheckoutAttempted.current &&\n !hasPayPalRedirectParams;\n\n if (shouldAutoProcessInlineSession) {\n setModeError(null);\n setModeOverlayError(null);\n setModeOverlayStatus('processing');\n }\n\n try {\n const resolved = await bootstrapInlineSession();\n const resolvedSession = resolved.result.data.session ?? null;\n savedPaymentKeysRef.current = resolveSavedPaymentPublishableKeys(resolved.result);\n\n // PayPal-only sessions can't run saved-payment auto-checkout:\n // `handleSavedPaymentRedirectResult` requires a Stripe provider for\n // 3DS recovery, and there's no card-on-file to charge. Skip the\n // auto flow and let the render path drop to `DirectPayPalButton`.\n const resolvedPaypalOnly = isPayPalOnlyUnified(resolved.result);\n\n if (\n !cancelled &&\n shouldAutoProcessInlineSession &&\n resolvedSession &&\n !resolvedPaypalOnly\n ) {\n autoCheckoutAttempted.current = true;\n await runSavedPaymentFlow(resolvedSession, {\n attempt3DS: true,\n fallbackToFull: true,\n fromCreateSession: true,\n initialAutoProcessingError: resolved.result.autoProcessingError,\n initialAutoProcessingPending: resolved.result.autoProcessingPending,\n autoProcessingAttempted: resolved.result.autoProcessingAttempted,\n sessionId: resolved.sid || resolvedSession.id,\n });\n return;\n }\n\n if (!cancelled && shouldAutoProcessInlineSession) {\n if (resolvedPaypalOnly) {\n autoCheckoutAttempted.current = true;\n }\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n }\n } catch (err) {\n if (cancelled) return;\n\n const errorCode = err instanceof FloPayError\n ? err.code\n : typeof err === 'object' && err !== null && 'code' in err\n ? (err as { code?: string }).code\n : undefined;\n\n if (\n shouldAutoProcessInlineSession &&\n errorCode === 'session_auto_completed'\n ) {\n autoCheckoutAttempted.current = true;\n setModeOverlayStatus('success');\n await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);\n\n if (!cancelled) {\n invokeMerchantCallback(() => {\n onCompleteRef.current?.({ status: 'succeeded' });\n });\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n }\n return;\n }\n\n if (shouldAutoProcessInlineSession) {\n setModeOverlayStatus(null);\n setModeOverlayError(null);\n }\n\n const floPayErr = err instanceof FloPayError ? err\n : new FloPayError(err instanceof Error ? err.message : 'Failed to create session', 'api_error');\n setLoadError(floPayErr);\n }\n })();\n\n return () => { cancelled = true; };\n }\n\n // ── Existing sessionId flow ──\n setIsLoading(true);\n\n async function init() {\n let sessionReadCompleted = false;\n try {\n const api = new PaymentAPI(resolvedBillingUrl, { telemetry: false });\n const result = await api.getUnifiedCheckoutSession(activeSessionId, nonceProp);\n\n if (cancelled) return;\n setUnified(result);\n\n const sess = result.data.session ?? null;\n setSession(sess);\n\n if (!sess) {\n throw new FloPayError('No session data returned', 'api_error');\n }\n\n if (sess.status === 'complete') {\n setIsLoading(false);\n invokeMerchantCallback(() => {\n onSessionCompletedRef.current?.(sess.successUrl ?? '');\n });\n return;\n }\n\n if (sess.status === 'expired') {\n throw new FloPayError('Checkout session has expired.', 'api_error', {\n code: 'checkout_session_expired',\n });\n }\n\n sessionReadCompleted = true;\n\n const effectiveMode = checkoutModeProp ?? sess.checkoutMode ?? 'full';\n setCurrentMode(effectiveMode);\n\n const hasPayPalRedirectParams =\n typeof window !== 'undefined' &&\n new URLSearchParams(window.location.search).has('payment_intent');\n\n // PayPal-only sessions skip auto saved-payment processing — there's\n // no Stripe provider for 3DS recovery, so the render path drops\n // straight to `DirectPayPalButton`.\n const paypalOnly = isPayPalOnlyUnified(result);\n\n if (\n effectiveMode === 'auto' &&\n !autoCheckoutAttempted.current &&\n !hasPayPalRedirectParams &&\n !paypalOnly\n ) {\n autoCheckoutAttempted.current = true;\n const stripeInitPromise = initStripe(result);\n\n try {\n await runSavedPaymentFlow(sess, {\n attempt3DS: true,\n fallbackToFull: true,\n ensureProvidersReady: () => stripeInitPromise,\n sessionId: activeSessionId || sess.id,\n });\n if (cancelled) return;\n await stripeInitPromise;\n if (!cancelled) {\n setIsLoading(false);\n }\n return;\n } catch {\n if (cancelled) return;\n await stripeInitPromise;\n if (!cancelled) setIsLoading(false);\n return;\n }\n }\n\n await initStripe(result);\n if (!cancelled) setIsLoading(false);\n } catch (err) {\n if (cancelled) return;\n if (!(err instanceof FloPayError)) {\n reportStandaloneTelemetryError(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n 'INTERNAL_SDK_ERROR',\n 'checkout_mount',\n );\n } else if (!sessionReadCompleted && !isExpectedExistingSessionError(err)) {\n reportStandaloneTelemetryError(\n resolvedBillingUrl,\n telemetry,\n telemetryCheckoutContext,\n 'NETWORK_REQUEST_FAILED',\n 'session_read',\n );\n }\n const floPayErr = err instanceof FloPayError ? err\n : new FloPayError(err instanceof Error ? err.message : 'Failed to initialize checkout', 'api_error');\n setLoadError(floPayErr);\n setIsLoading(false);\n }\n }\n\n async function initStripe(result: NormalizedCheckoutSession) {\n const {\n publishableKey,\n paypalPublishableKey,\n } = resolveSavedPaymentPublishableKeys(result);\n savedPaymentKeysRef.current = {\n publishableKey,\n paypalPublishableKey,\n };\n const {\n flopay: instance,\n paypalFlopay: paypalInstance,\n } = await loadSavedPaymentProviders({\n publishableKey,\n paypalPublishableKey,\n billingApiUrl: resolvedBillingUrl,\n locale,\n telemetry,\n });\n\n flopayRef.current = instance;\n setFloPay(instance);\n paypalFlopayRef.current = paypalInstance;\n setPaypalFloPay(paypalInstance);\n }\n\n init();\n return () => {\n cancelled = true;\n };\n // Only re-run when the session/config identity changes — NOT when callbacks change.\n // Callbacks are accessed via refs (onCompleteRef, onSessionCompletedRef).\n // `createSessionHash` is a stable string derived from createSessionParams,\n // so a new object reference with the same values won't re-trigger.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n bootstrapInlineSession,\n checkoutModeProp,\n createSessionHash,\n effectiveCreateSessionMode,\n initSessionDependency,\n invokeMerchantCallback,\n nonceProp,\n runSavedPaymentFlow,\n ]);\n\n // ── Confirm mode handler ──\n\n const handleConfirmCheckout = useCallback(async () => {\n if (confirmProcessing || !session) return;\n setConfirmProcessing(true);\n setModeError(null);\n\n try {\n await runSavedPaymentFlow(session, {\n fallbackToFull: true,\n sessionId: activeSessionId || session.id,\n });\n } finally {\n setConfirmProcessing(false);\n }\n }, [activeSessionId, confirmProcessing, runSavedPaymentFlow, session]);\n\n const directPaypalConfig = resolveDirectPaypalConfig(unified);\n // PayPal-only sessions advertise `gateways.paypal` without Stripe-backed\n // wallets/APMs or a hosted vault card capability. Render `DirectPayPalButton`\n // as the sole payment surface and bypass `FloPayProvider` entirely.\n const isPaypalOnlySession = isPayPalOnlyUnified(unified);\n\n // Provider options from session data. Only meaningful when Stripe is\n // available — PayPal-only sessions never mount Stripe Elements.\n const providerOptions = useMemo(() => {\n if (!unified || !session || !unified.data.stripe?.publishableKey) return undefined;\n\n const opts: {\n appearance?: FloPayAppearance;\n paymentMethodCreation: 'manual';\n billingApiUrl: string;\n clientSecret?: string;\n amount?: number;\n currency?: string;\n } = {\n appearance,\n paymentMethodCreation: 'manual',\n billingApiUrl: resolvedBillingUrl,\n };\n\n if (unified.data.stripe?.clientSecret) {\n opts.clientSecret = unified.data.stripe.clientSecret;\n } else {\n // Use display total (respects hideItems logic) instead of raw session.amount\n const displayTotal = buildCheckoutDisplayData(session).total;\n opts.amount = Math.round(displayTotal * 100) || session.amount;\n opts.currency = session.currency?.toLowerCase();\n }\n\n return opts;\n }, [unified, session, appearance, resolvedBillingUrl]);\n\n const shouldHandleInlineSessionPatch = Boolean(\n createSessionParams &&\n !children &&\n layout === 'buttons' &&\n onBeforeButtonClick &&\n effectiveCreateSessionMode === 'full',\n );\n\n // Checkout context\n const checkoutValue = useMemo(\n () => ({\n session,\n loading: isLoading,\n error: loadError,\n checkoutMode: currentMode,\n inlineSessionDraft: effectiveCreateSession,\n applyInlineSessionPatch: shouldHandleInlineSessionPatch\n ? handleInlineSessionPatch\n : undefined,\n inlineSessionPatchProcessing: cardBootstrapPending,\n }),\n [\n session,\n isLoading,\n loadError,\n currentMode,\n effectiveCreateSession,\n shouldHandleInlineSessionPatch,\n handleInlineSessionPatch,\n cardBootstrapPending,\n ],\n );\n const shouldShowInterimButtons =\n Boolean(createSessionParams) &&\n layout === 'buttons' &&\n !isPaypalOnlySession &&\n (!flopay || !providerOptions);\n const modeOverlay = modeOverlayStatus\n ? (\n <ProcessingOverlay\n status={modeOverlayStatus}\n errorMessage={modeOverlayError}\n />\n )\n : null;\n\n // ── Loading state ──\n if (isLoading) {\n if (loadingNode) {\n return (\n <>\n {loadingNode}\n {modeOverlay}\n </>\n );\n }\n\n // Buttons layout: show button-shaped skeletons. Wallet/card skeletons are\n // gated on `showStripe` so a PayPal-only checkout doesn't briefly flash\n // Stripe affordances during bootstrap.\n if (layout === 'buttons') {\n // Match the theme's tile border-radius so the loading skeletons line\n // up with the eventual buttons. `bundleRadius` reads from the\n // resolved theme bundle's `cardButton.borderRadius` (e.g. `14px` for\n // modern, `20px` for glass) and falls back to the appearance\n // variable, then `8px` for classic.\n const bundleRadius =\n (themeBundle?.buttonsLayout?.cardButton?.borderRadius as string | number | undefined) ??\n (themeBundle?.appearance.variables?.borderRadius as string | undefined) ??\n 8;\n const skeletonBar = (h: number) => (\n <div style={{\n height: h, borderRadius: bundleRadius, background: '#e5e7eb',\n animation: 'flopay-loading-pulse 1.5s ease-in-out infinite',\n }} />\n );\n return (\n <>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n {showStripe && (showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n {showStripe && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n <style>{`@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }`}</style>\n </div>\n {modeOverlay}\n </>\n );\n }\n\n // Default layout: centered spinner\n return (\n <>\n <div style={{ display: 'flex', justifyContent: 'center', padding: 32 }}>\n <div style={{\n width: 24, height: 24,\n border: '2px solid #e5e7eb', borderTopColor: '#6b7280',\n borderRadius: '50%', animation: 'spin 0.6s linear infinite',\n }} />\n <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>\n </div>\n {modeOverlay}\n </>\n );\n }\n\n // ── Error state ──\n if (loadError) {\n if (errorNode) {\n return (\n <CheckoutContext.Provider value={checkoutValue}>\n {errorNode(loadError)}\n </CheckoutContext.Provider>\n );\n }\n return (\n <CheckoutContext.Provider value={checkoutValue}>\n <div\n role=\"alert\"\n data-testid=\"flopay-load-error\"\n style={{\n padding: 24,\n textAlign: 'center',\n color: '#dc2626',\n fontSize: 14,\n }}\n >\n {loadError.message}\n </div>\n </CheckoutContext.Provider>\n );\n }\n\n // When using createSession + buttons layout, render an interim buttons view\n // while non-card Stripe methods initialize in the background. The Credit /\n // Debit Card button expands a hosted-vault placeholder; PayPal/wallets show\n // as skeletons. Once provider setup finishes, SplitCardForm replaces it.\n if (shouldShowInterimButtons) {\n return (\n <>\n <CheckoutContext.Provider value={checkoutValue}>\n <InterimButtonsView\n onButtonClick={onButtonClick}\n showPayPal={showPayPal}\n showStripe={showStripe}\n showApplePay={showApplePay}\n showGooglePay={showGooglePay}\n theme={theme}\n buttonsTheme={buttonsTheme}\n buttonsStyles={buttonsStyles}\n cardButtonContent={cardButtonContent}\n cardBackButtonContent={cardBackButtonContent}\n cardTitleContent={cardTitleContent}\n />\n </CheckoutContext.Provider>\n {modeOverlay}\n </>\n );\n }\n\n // PayPal-only session: render DirectPayPalButton as the sole payment\n // surface. Stripe Elements never mount, so we bypass FloPayProvider /\n // SplitCardForm entirely.\n if (isPaypalOnlySession && session && directPaypalConfig) {\n return (\n <>\n <CheckoutContext.Provider value={checkoutValue}>\n <div className={className} style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {modeError && (\n <ErrorBanner icon={false}>{modeError}</ErrorBanner>\n )}\n {paypalInitializationState === 'retrying' && (\n <div role=\"status\" aria-live=\"polite\">\n PayPal is temporarily unavailable. Retrying…\n </div>\n )}\n {paypalInitializationState === 'exhausted' && (\n <div role=\"alert\">\n <div>PayPal is temporarily unavailable. Please try again.</div>\n <button type=\"button\" onClick={retryPayPalInitialization}>\n Retry PayPal\n </button>\n </div>\n )}\n {paypalInitializationState !== 'exhausted' && (\n <div\n aria-hidden={paypalInitializationState === 'retrying' ? true : undefined}\n style={paypalInitializationState === 'retrying'\n ? { position: 'relative', height: 0, opacity: 0, pointerEvents: 'none' }\n : undefined}\n >\n <InstrumentedDirectPayPalButton\n key={`paypal-init-${paypalManualRetryGeneration}`}\n sessionId={activeSessionId}\n nonce={session.clientSecret || undefined}\n billingApiUrl={resolvedBillingUrl}\n email={session.customer?.email}\n clientId={directPaypalConfig.clientId}\n environment={directPaypalConfig.environment}\n currency={(session.currency ?? 'usd').toUpperCase()}\n isSubscription={session.mode === 'subscription'}\n onComplete={onComplete}\n onErrorChange={setModeError}\n onDecline={onDecline}\n onButtonClick={onButtonClick}\n onInitializationStateChange={handlePayPalInitializationStateChange}\n allowAutomaticRetry={paypalManualRetryGeneration === 0}\n session={session}\n telemetry={telemetry}\n telemetryContext={telemetryCheckoutContext}\n debug={debug}\n />\n </div>\n )}\n </div>\n </CheckoutContext.Provider>\n {modeOverlay}\n </>\n );\n }\n\n if (!flopay || !providerOptions) {\n return <>{modeOverlay}</>;\n }\n\n // ── Confirm mode ──\n if (currentMode === 'confirm') {\n return (\n <>\n <CheckoutContext.Provider value={checkoutValue}>\n <FloPayProvider flopay={flopay} paypalFlopay={paypalFlopay} options={providerOptions}>\n <div className={className}>\n {modeError && (\n <div\n style={{\n color: '#dc2626',\n fontSize: '0.875rem',\n marginBottom: '0.75rem',\n textAlign: 'center',\n }}\n >\n {modeError}\n </div>\n )}\n {renderConfirmButton ? (\n renderConfirmButton({\n onConfirm: handleConfirmCheckout,\n isProcessing: confirmProcessing,\n })\n ) : (\n <button\n type=\"button\"\n onClick={handleConfirmCheckout}\n disabled={confirmProcessing}\n style={{\n width: '100%',\n padding: '0.875rem',\n backgroundColor: '#4A49FF',\n color: 'white',\n border: 'none',\n borderRadius: '8px',\n fontSize: '1rem',\n fontWeight: 600,\n cursor: confirmProcessing ? 'not-allowed' : 'pointer',\n opacity: confirmProcessing ? 0.6 : 1,\n }}\n >\n {confirmProcessing\n ? 'Processing...'\n : confirmLabel ?? 'Confirm Purchase'}\n </button>\n )}\n </div>\n </FloPayProvider>\n </CheckoutContext.Provider>\n {modeOverlay}\n </>\n );\n }\n\n // ── Full mode (default / fallback) ──\n return (\n <>\n <CheckoutContext.Provider value={checkoutValue}>\n <FloPayProvider flopay={flopay} paypalFlopay={paypalFlopay} options={providerOptions}>\n {children ? (\n <>\n {modeError && (\n <div\n style={{\n padding: '0.75rem 1rem',\n marginBottom: '0.75rem',\n backgroundColor: '#FEF3C7',\n border: '1px solid #F59E0B',\n borderRadius: '8px',\n color: '#92400E',\n fontSize: '0.875rem',\n }}\n >\n {modeError}\n </div>\n )}\n <SessionInjector\n sessionId={activeSessionId}\n nonce={session?.clientSecret || undefined}\n billingApiUrl={resolvedBillingUrl}\n session={session}\n >\n {children}\n </SessionInjector>\n </>\n ) : (\n <SplitCardForm\n sessionId={activeSessionId}\n nonce={session?.clientSecret || undefined}\n email={session?.customer?.email}\n userId={session?.customer?.id}\n firstName={session?.customer?.firstName}\n lastName={session?.customer?.lastName}\n totalAmount={session ? Math.round(buildCheckoutDisplayData(session).total * 100) : 0}\n currency={session?.currency?.toLowerCase() ?? 'usd'}\n onComplete={onComplete}\n onError={onError}\n onDecline={onDecline}\n error={modeError}\n onErrorChange={setModeError}\n showPayPal={showPayPal}\n showStripe={showStripe}\n enabledPaymentMethods={unified?.data.stripe?.enabledPaymentMethods}\n enabledPaymentMethodCountries={unified?.data.stripe?.enabledPaymentMethodCountries}\n showApplePay={showApplePay}\n showGooglePay={showGooglePay}\n layout={layout}\n theme={theme}\n buttonsTheme={buttonsTheme}\n buttonsStyles={buttonsStyles}\n appearance={appearance}\n cardButtonContent={cardButtonContent}\n cardBackButtonContent={cardBackButtonContent}\n cardTitleContent={cardTitleContent}\n onButtonClick={onButtonClick}\n onBeforeButtonClick={onBeforeButtonClick}\n enableAVS={enableAVS}\n {...(cardFieldOrder ? { cardFieldOrder } : {})}\n {...(cardPreFormSlot ? { cardPreFormSlot } : {})}\n avsLayout={avsLayout}\n country={session?.customer?.country}\n city={session?.customer?.city}\n state={session?.customer?.state}\n onCountryChange={onCountryChange}\n onZipChange={onZipChange}\n avsCheck={!!enableAVS}\n checkoutType={createSessionParams ? 'embedded_checkout' : 'standard_checkout'}\n checkoutLayout={children ? 'custom_layout' : layout === 'buttons' ? 'buttons_layout' : 'default_layout'}\n className={className}\n directPaypal={resolveDirectPaypalConfig(unified)}\n isSubscription={session?.mode === 'subscription'}\n session={session}\n debug={debug}\n />\n )}\n </FloPayProvider>\n </CheckoutContext.Provider>\n {modeOverlay}\n </>\n );\n}\n\n/**\n * Auto-injects session props into child form components.\n * Explicit props on children take precedence over injected values.\n */\nfunction SessionInjector({\n sessionId,\n nonce,\n billingApiUrl,\n session,\n children,\n}: {\n sessionId: string;\n nonce?: string;\n billingApiUrl: string;\n session: CheckoutSession | null;\n children: React.ReactNode;\n}) {\n return (\n <>\n {React.Children.map(children, (child) => {\n if (!React.isValidElement(child)) return child;\n\n const existing = child.props as Record<string, unknown>;\n const injected: Record<string, unknown> = {};\n\n if (!existing.sessionId) injected.sessionId = sessionId;\n if (!existing.nonce && nonce) injected.nonce = nonce;\n if (!existing.billingApiUrl) injected.billingApiUrl = billingApiUrl;\n\n if (session?.customer) {\n if (!existing.email) injected.email = session.customer.email;\n if (!existing.userId) injected.userId = session.customer.id;\n if (!existing.firstName)\n injected.firstName = session.customer.firstName;\n if (!existing.lastName)\n injected.lastName = session.customer.lastName;\n }\n\n if (Object.keys(injected).length === 0) return child;\n return React.cloneElement(child, injected);\n })}\n </>\n );\n}\n\n/**\n * Interim buttons view rendered while Stripe initializes in the background.\n * Shows skeleton bars for PayPal/wallets and a fully interactive Credit/Debit Card button.\n */\nfunction InterimButtonsView({\n onButtonClick,\n showPayPal,\n showStripe = true,\n showApplePay,\n showGooglePay,\n theme,\n buttonsTheme,\n buttonsStyles: stylesOverride,\n cardButtonContent,\n cardBackButtonContent,\n cardTitleContent,\n}: {\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n showPayPal: boolean;\n showStripe?: boolean;\n showApplePay: boolean;\n showGooglePay: boolean;\n theme?: import('@flopay/shared').ThemeId;\n buttonsTheme?: ButtonsLayoutTheme;\n buttonsStyles?: ButtonsLayoutStyles;\n cardButtonContent?: React.ReactNode;\n cardBackButtonContent?: React.ReactNode;\n cardTitleContent?: React.ReactNode;\n}) {\n const [showCardForm, setShowCardForm] = useState(false);\n\n const themeBundle = useMemo(() => resolveTheme(theme), [theme]);\n const bStyles = useMemo<ButtonsLayoutStyles>(() => {\n const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme(buttonsTheme);\n if (!stylesOverride) return base;\n return {\n ...base,\n ...stylesOverride,\n cardButton: { ...base.cardButton, ...stylesOverride.cardButton },\n cardFormContainer: { ...base.cardFormContainer, ...stylesOverride.cardFormContainer },\n backButton: { ...base.backButton, ...stylesOverride.backButton },\n backButtonIcon: { ...base.backButtonIcon, ...stylesOverride.backButtonIcon },\n submitButton: { ...base.submitButton, ...stylesOverride.submitButton },\n title: { ...base.title, ...stylesOverride.title },\n };\n }, [themeBundle, buttonsTheme, stylesOverride]);\n\n // Match the theme's tile radius so the interim skeletons line up with the\n // eventual buttons. Same derivation as the FloPayCheckout loading path\n // above — keeps the two skeleton surfaces consistent.\n const skeletonRadius =\n (themeBundle?.buttonsLayout?.cardButton?.borderRadius as string | number | undefined) ??\n (themeBundle?.appearance.variables?.borderRadius as string | undefined) ??\n 8;\n const skeleton = (h: number) => (\n <div style={{\n height: h, borderRadius: skeletonRadius, background: '#e5e7eb',\n animation: 'flopay-interim-pulse 1.5s ease-in-out infinite',\n }} />\n );\n const cardButtonSizing = cardButtonContent === undefined\n ? { boxSizing: 'border-box' as const, height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: '0 1rem' }\n : { padding: '0.9rem 1rem' };\n\n if (showCardForm) {\n // Show a hosted-vault placeholder with a back button until provider setup completes.\n const inputBorder = bStyles.cardInputBorder ?? '#e5e7eb';\n const inputBg = bStyles.cardInputBackground ?? 'white';\n const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);\n const hideTitle = isEmptySlotContent(cardTitleContent);\n return (\n <div style={{\n backgroundColor: (bStyles.cardFormContainer?.backgroundColor as string) ?? 'white',\n borderRadius: '8px',\n animation: 'flopay-interim-expand 0.35s cubic-bezier(0.4, 0, 0.2, 1) both',\n overflow: 'hidden',\n ...bStyles.cardFormContainer as React.CSSProperties,\n }}>\n <div style={{ display: 'flex', alignItems: 'center', padding: '0.75rem 0 0.625rem' }}>\n <button\n type=\"button\"\n onClick={() => setShowCardForm(false)}\n aria-label=\"Back to payment methods\"\n style={{\n display: 'inline-flex', alignItems: 'center', gap: hideBackButtonLabel ? 0 : '0.5rem',\n background: 'none', border: 'none',\n color: '#4b5563', fontSize: '0.85rem', fontWeight: 500,\n padding: 0, flexShrink: 0, opacity: 1,\n cursor: 'pointer',\n ...bStyles.backButton as React.CSSProperties,\n }}\n >\n <span style={{\n display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: '50%',\n backgroundColor: '#f3f4f6',\n ...bStyles.backButtonIcon as React.CSSProperties,\n }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n </span>\n <BackButtonContentSlot content={cardBackButtonContent} />\n </button>\n {hideTitle ? (\n <div style={{ flex: 1 }} />\n ) : (\n <div style={{\n flex: 1, textAlign: 'center', fontWeight: 600, fontSize: '1.05rem',\n color: '#262833', paddingRight: 80,\n ...bStyles.title as React.CSSProperties,\n }}>\n <TitleContentSlot content={cardTitleContent} />\n </div>\n )}\n </div>\n {/* Skeleton for the hosted vault card widget */}\n <div style={{ backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }}>\n <div style={{ width: '60%', height: 14, borderRadius: 4, background: '#e5e7eb', animation: 'flopay-interim-pulse 1.5s ease-in-out infinite' }} />\n </div>\n <div style={{ display: 'flex' }}>\n <div style={{\n flex: 1, backgroundColor: inputBg,\n borderTop: 'none', borderRight: 'none',\n borderBottom: `1px solid ${inputBorder}`, borderLeft: `1px solid ${inputBorder}`,\n borderBottomLeftRadius: 8, padding: 12, height: 45,\n }}>\n <div style={{ width: '50%', height: 14, borderRadius: 4, background: '#e5e7eb', animation: 'flopay-interim-pulse 1.5s ease-in-out infinite' }} />\n </div>\n <div style={{\n flex: 1, backgroundColor: inputBg,\n borderTop: 'none',\n borderRight: `1px solid ${inputBorder}`,\n borderBottom: `1px solid ${inputBorder}`,\n borderLeft: `1px solid ${inputBorder}`,\n borderBottomRightRadius: 8, padding: 12, height: 45,\n }}>\n <div style={{ width: '40%', height: 14, borderRadius: 4, background: '#e5e7eb', animation: 'flopay-interim-pulse 1.5s ease-in-out infinite' }} />\n </div>\n </div>\n <div style={{ backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }}>\n <div style={{ width: '45%', height: 14, borderRadius: 4, background: '#e5e7eb', animation: 'flopay-interim-pulse 1.5s ease-in-out infinite' }} />\n </div>\n <div style={{\n height: 50, borderRadius: 8, marginTop: 16, background: '#c8c8ff',\n animation: 'flopay-interim-pulse 1.5s ease-in-out infinite',\n ...bStyles.submitButton as React.CSSProperties,\n opacity: 0.5,\n }} />\n <style>{`\n @keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }\n @keyframes flopay-interim-expand {\n 0% { opacity: 0; max-height: 0; transform: translateY(-12px); }\n 40% { opacity: 1; }\n 100% { opacity: 1; max-height: 600px; transform: translateY(0); }\n }\n `}</style>\n </div>\n );\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n {showStripe && (showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT)}\n {showStripe && (\n <button\n type=\"button\"\n onClick={() => {\n onButtonClick?.('card');\n setShowCardForm(true);\n }}\n style={{\n width: '100%',\n ...cardButtonSizing,\n backgroundColor: 'white', color: '#262833',\n border: '1px solid #d1d5db', borderRadius: '8px',\n fontSize: bStyles.cardButtonFontSize ?? '0.95rem', fontWeight: 600,\n cursor: 'pointer', display: 'flex',\n alignItems: 'center', justifyContent: 'center', gap: '0.625rem',\n boxShadow: '0 1px 2px rgba(0,0,0,0.04)',\n transition: 'transform 0.1s',\n position: 'relative',\n opacity: 1,\n ...bStyles.cardButton as React.CSSProperties,\n }}\n onMouseDown={(e) => { e.currentTarget.style.transform = 'scale(0.985)'; }}\n onMouseUp={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}\n >\n <CardButtonContentSlot content={cardButtonContent} />\n </button>\n )}\n <style>{`@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }`}</style>\n </div>\n );\n}\n","import React from 'react';\n\nexport function DefaultCardButtonContent(): React.ReactElement {\n return (\n <>\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"5\" rx=\"2\" />\n <line x1=\"2\" x2=\"22\" y1=\"10\" y2=\"10\" />\n </svg>\n Credit / Debit Card\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#9ca3af\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ position: 'absolute', right: '1rem' }}\n aria-hidden=\"true\"\n >\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n </>\n );\n}\n\nexport function DefaultBackButtonContent(): React.ReactElement {\n return <>Go back</>;\n}\n\nexport function DefaultTitleContent(): React.ReactElement {\n return <>Secure card checkout</>;\n}\n\nexport function isEmptySlotContent(content: React.ReactNode | undefined): boolean {\n return content !== undefined && (content === '' || content === null || content === false);\n}\n\nexport function CardButtonContentSlot({\n content,\n}: {\n content?: React.ReactNode;\n}): React.ReactElement {\n return <>{content === undefined ? <DefaultCardButtonContent /> : content}</>;\n}\n\nexport function BackButtonContentSlot({\n content,\n}: {\n content?: React.ReactNode;\n}): React.ReactElement {\n return <>{content === undefined ? <DefaultBackButtonContent /> : content}</>;\n}\n\nexport function TitleContentSlot({\n content,\n}: {\n content?: React.ReactNode;\n}): React.ReactElement {\n return <>{content === undefined ? <DefaultTitleContent /> : content}</>;\n}\n","import {\n ExpressCheckoutElement,\n PaymentElement,\n Elements as StripeElements,\n useElements as useStripeElements,\n useStripe as useStripeRaw,\n} from '@stripe/react-stripe-js';\nimport type {\n BeforeButtonClickEvent,\n CardCaptureAdapter,\n CardCaptureMountOptions,\n CheckoutButtonMethod,\n CheckoutSession,\n VaultCaptureBlock,\n DeclineEvent,\n GatewayEnvironment,\n InlineSessionPatch,\n PaymentResult,\n TokenizedBody,\n ButtonsLayoutStyles,\n AVSFieldConfig,\n SessionIntentDeclineRequest,\n} from '@flopay/shared';\nimport {\n resolveButtonsLayoutTheme,\n getPostalCodeLabel,\n getStateLabel,\n getStateOptions,\n COUNTRY_OPTIONS,\n resolveAVSConfig,\n isAVSFieldVisible,\n getStateFromPostalCode,\n isPostalCodeSupported,\n isValidPostalCode,\n getPostalCodeExample,\n filterStripeMethodsByCountry,\n getStripeMethodDisplayName,\n hasVendoredStripeMethodLogo,\n needsStripeMethodExplicitConfirm,\n resolveStripeMethodBrandVariant,\n partitionStripeMethods,\n stripeExpressMethodToOptionKey,\n} from '@flopay/shared';\nimport { PaymentAPI } from '@flopay/js';\nimport { VaultCardFields } from './vault-card-fields.js';\nimport { ErrorBanner } from './error-banner.js';\nimport { PAYMENT_METHOD_LOGO_URLS } from './payment-logos.generated.js';\nimport React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';\nimport type {\n Stripe,\n StripeExpressCheckoutElementConfirmEvent,\n StripeExpressCheckoutElementReadyEvent,\n} from '@stripe/stripe-js';\nimport { useBillingApiUrl, useFloPay, usePayPalFloPay } from './hooks.js';\nimport { getFloPayTelemetryBridge } from './telemetry-bridge.js';\nimport { CheckoutContext } from './context.js';\nimport {\n BackButtonContentSlot,\n CardButtonContentSlot,\n TitleContentSlot,\n isEmptySlotContent,\n} from './card-button-content.js';\nimport {\n PROCESSING_OVERLAY_ERROR_DELAY_MS,\n PROCESSING_OVERLAY_SUCCESS_DELAY_MS,\n ProcessingOverlay,\n type OverlayStatus,\n} from './processing-overlay.js';\nimport {\n buildDeclineEvent,\n isSuccessfulPaymentIntentStatus,\n mergeAccountPatch,\n resolvePaymentIntentPaymentMethodId,\n resolveTokenizedPaymentMethodId,\n resolveWalletElementsMode,\n retrievePaymentIntentFromProvider,\n} from './checkout-utils.js';\nimport { markSessionRecentlyCompleted } from './recent-completion.js';\nimport { isInAppBrowser } from './in-app-browser.js';\nimport { DirectPayPalButton } from './direct-paypal-button.js';\nimport type { DirectPayPalInitializationState } from './direct-paypal-button.js';\nimport { invokeMerchantCallback } from './merchant-callback.js';\nimport {\n EXTERNAL_METHOD_CALLBACK_GRACE_MS,\n getProviderDeclineCode,\n getProviderErrorCode,\n isProviderDecline,\n isPopupBlockedError,\n sanitizeExternalFailureCode,\n} from './external-method-recovery.js';\n\nimport { FloPayError, isSetupIntentClientSecret, resolveTheme } from '@flopay/shared';\n\n/**\n * localStorage key for persisting Stripe-redirect payment state across the\n * round-trip to an external authorization page (PayPal, Cash App Pay, Klarna,\n * iDEAL, …). The legacy `flopay_wallet_resume` key is still read for one\n * minor — payloads written by older SDK builds keep resuming after upgrade.\n */\nconst STRIPE_RESUME_KEY = 'flopay_stripe_resume';\nconst LEGACY_WALLET_RESUME_KEY = 'flopay_wallet_resume';\n// PayPal-direct (ExpressCheckoutElement) uses its own resume effect; this key\n// carries the effective session / nonce / accountPatch across the redirect so\n// the resume handler can /process against the same session PayPal authorized\n// (an inline-session bootstrap inside `runBeforeButtonClick` would otherwise\n// be lost when the page reloads after the PayPal round-trip).\nconst PAYPAL_RESUME_KEY = 'flopay_paypal_resume';\n\nasync function reportNonCardDecline({\n billingApiUrl,\n sessionId,\n nonce,\n request,\n}: {\n billingApiUrl: string;\n sessionId: string;\n nonce?: string;\n request: SessionIntentDeclineRequest;\n}): Promise<void> {\n if (!sessionId || !nonce) return;\n try {\n await new PaymentAPI(billingApiUrl, { telemetry: false }).reportSessionIntentDecline(\n sessionId,\n nonce,\n request,\n );\n } catch {\n // Best-effort decline classification must not replace the provider error.\n }\n}\n\n/**\n * True when an error from `patchAccountSnapshot` is a client validation\n * rejection (HTTP 4xx) — e.g. the backend's country-aware postcode check\n * refusing the address. These must surface to the buyer (inline + `onError`).\n * A transient 5xx / network / abort failure is NOT a validation error and stays\n * best-effort (the backend listener falls back to the session baseline).\n */\nfunction isAccountValidationError(err: unknown): boolean {\n return (\n err instanceof FloPayError &&\n typeof err.statusCode === 'number' &&\n err.statusCode >= 400 &&\n err.statusCode < 500\n );\n}\n\n/**\n * Normalize a {@link VaultCaptureBlock} into the adapter's\n * {@link CardCaptureMountOptions}, threading the `messageToken` / `expectedOrigin`\n * authenticity markers through when the backend supplies them. Returns `null`\n * when there is no widget HTML to mount.\n */\nfunction toVaultMount(block: VaultCaptureBlock | undefined): CardCaptureMountOptions | null {\n if (!block?.html) return null;\n return {\n html: block.html,\n ...(block.messageToken ? { messageToken: block.messageToken } : {}),\n ...(block.expectedOrigin ? { expectedOrigin: block.expectedOrigin } : {}),\n };\n}\n\ntype MaybePromise<T> = T | Promise<T>;\n\n/**\n * Darken a `#rrggbb` color by `amount` (0–1) — used to derive a flo-button hover\n * shade from the primary when the theme doesn't supply an explicit\n * `colorPrimaryHover`. Returns the input unchanged for non-hex values.\n */\nexport function darkenHex(hex: string, amount = 0.12): string {\n const match = /^#?([0-9a-fA-F]{6})$/.exec(hex.trim());\n if (!match) return hex;\n const value = parseInt(match[1], 16);\n const scale = Math.max(0, Math.min(1, 1 - amount));\n const r = Math.round(((value >> 16) & 0xff) * scale);\n const g = Math.round(((value >> 8) & 0xff) * scale);\n const b = Math.round((value & 0xff) * scale);\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}`;\n}\n\n// ─── Global keyframes (always present — not gated behind overlay render) ────\n\n// PayPal SDK's .paypal-buttons wrapper is `display: inline-block` with a\n// default margin. In a block container it leaves baseline-descender space\n// below, which visually doubles the parent's flex `gap`. Force margin: 0 +\n// vertical-align: top to neutralise both.\nconst FLOPAY_KEYFRAMES = `\n.paypal-buttons { margin: 0 !important; vertical-align: top !important; }\n@keyframes flopay-spin { to { transform: rotate(360deg); } }\n@keyframes flopay-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }\n@keyframes flopay-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }\n@keyframes flopay-buttons-enter {\n 0% { opacity: 0; transform: translateX(-16px) scale(0.97); }\n 100% { opacity: 1; transform: translateX(0) scale(1); }\n}\n@keyframes flopay-buttons-exit {\n 0% { opacity: 1; transform: translateX(0) scale(1); }\n 100% { opacity: 0; transform: translateX(-16px) scale(0.97); }\n}\n@keyframes flopay-card-enter {\n 0% { opacity: 0; transform: translateX(16px) scale(0.97); }\n 100% { opacity: 1; transform: translateX(0) scale(1); }\n}\n@keyframes flopay-card-exit {\n 0% { opacity: 1; transform: translateX(0) scale(1); }\n 100% { opacity: 0; transform: translateX(16px) scale(0.97); }\n}\n`;\n\nconst DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;\n\n/**\n * Shared \"primary button\" base style for the two buyer-action buttons in the\n * buttons-layout (the \"Credit / Debit Card\" button + `FloPayAutomaticPaymentButton`).\n *\n * - `'classic'` / no theme: white background, grey border — historic look\n * that lines up with the wallet ECE row's flat tiles.\n * - Any theme bundle (`modern-*`, `bold-*`, `glass-*`): `colorPrimary`\n * (`resolvedPrimaryColor` — already merged with any `appearance` override)\n * drives the `backgroundColor`, exactly like the \"Confirm Payment\" submit\n * CTA, so all three flo buttons (submit, card, auto-pay) share one fill and\n * a per-checkout `colorPrimary` override re-skins every one of them. The\n * bundle's `submitButton` still supplies `color` / `border` / `borderRadius`\n * / `boxShadow` so typography + shape stay on-theme. Hover (`colorPrimaryHover`)\n * is applied by each button's `onMouseEnter`/`onMouseLeave` at the call site.\n */\nexport function derivePrimaryTileStyle(opts: {\n themeBundle: import('@flopay/shared').ThemeBundle | null | undefined;\n resolvedPrimaryColor: string;\n resolvedBorderRadius: string;\n submitButtonStyle?: React.CSSProperties;\n /**\n * Raw `appearance.colorPrimary` (undefined when the merchant didn't set one).\n * When present it forces a primary-filled tile even with no theme bundle\n * (the `classic` preset), so an explicit `colorPrimary` override always wins\n * over the historic white tile.\n */\n explicitPrimaryColor?: string;\n}): React.CSSProperties {\n // Historic white tile only when there's neither a theme bundle nor an\n // explicit `colorPrimary` override to honor.\n if (!opts.themeBundle && !opts.explicitPrimaryColor) {\n return {\n backgroundColor: 'white',\n color: '#262833',\n border: '1px solid #d1d5db',\n borderRadius: opts.resolvedBorderRadius,\n boxShadow: '0 1px 2px rgba(0,0,0,0.04)',\n };\n }\n // A theme bundle reads color / border / radius / shadow off its submit CTA so\n // the tile mirrors it; an explicit override with no bundle gets a clean\n // primary fill (white text, no border, theme radius).\n const submit = opts.themeBundle ? (opts.submitButtonStyle ?? {}) : {};\n return {\n // `colorPrimary` wins so a per-checkout override re-skins the card / auto-pay\n // buttons in lock-step with the submit CTA (which also keys off it).\n backgroundColor: opts.resolvedPrimaryColor,\n color: (submit.color as string | undefined) ?? 'white',\n border: (submit.border as string | undefined) ?? 'none',\n borderRadius: (submit.borderRadius as string | number | undefined) ?? opts.resolvedBorderRadius,\n boxShadow: submit.boxShadow as string | undefined,\n };\n}\n\n// Buttons-panel hide style used in `layout=\"buttons\"` when the card form is in\n// view. PayPal's Stripe ExpressCheckoutElement (and the direct PayPal SDK)\n// renders its button into a cross-origin iframe whose painted content ignores\n// the parent's `visibility: hidden`. Without `height: 0 + overflow: hidden`\n// the PayPal button stays visually painted on the card-details step even\n// though it is logically hidden. Keeping the panel mounted (rather than\n// unmounting) preserves PayPal/wallet Elements state across the transition.\nconst BUTTONS_PANEL_HIDDEN_STYLE: React.CSSProperties = {\n visibility: 'hidden',\n position: 'absolute',\n pointerEvents: 'none',\n width: '100%',\n height: 0,\n overflow: 'hidden',\n};\n\ntype TokenizedBodyOverrides = {\n accountPatch?: InlineSessionPatch['account'];\n completionPaymentMethodId?: string;\n sessionId?: string;\n nonce?: string;\n};\n\ntype InternalTokenizedBodyHandler = (\n body: TokenizedBody,\n overrides?: TokenizedBodyOverrides,\n) => void;\n\ntype BeforeButtonClickPatchResult = {\n error: FloPayError | null;\n sessionId?: string;\n nonce?: string;\n};\n\ntype BeforeButtonClickResult = {\n proceed: boolean;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n};\n\ntype RunBeforeButtonClick = (method: CheckoutButtonMethod) => Promise<BeforeButtonClickResult>;\ntype ExternalAttemptPrepared = Pick<BeforeButtonClickResult, 'accountPatch' | 'sessionId' | 'nonce'>;\n\ntype ExternalMethodTechnicalFailureHandler = (\n method: string,\n err: unknown,\n options?: { code?: string; popupBlocked?: boolean },\n) => void;\n\nconst EXTERNAL_METHOD_RECOVERY_BUTTON_STYLE: React.CSSProperties = {\n width: '100%',\n minHeight: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT,\n margin: '0 0 0.5rem',\n padding: '0.75rem 0.875rem',\n border: '1px solid #2563eb',\n borderRadius: 8,\n background: '#eff6ff',\n color: '#1d4ed8',\n fontSize: '0.95rem',\n fontWeight: 700,\n cursor: 'pointer',\n};\n\nfunction getButtonMethodLabel(method: CheckoutButtonMethod): string {\n switch (method) {\n case 'paypal': return 'PayPal';\n case 'apple_pay': return 'Apple Pay';\n case 'google_pay': return 'Google Pay';\n default: return 'Card';\n }\n}\n\nfunction checkoutButtonMethodFromProviderMethod(method: string | undefined): CheckoutButtonMethod {\n if (method === 'paypal') return 'paypal';\n if (method === 'apple_pay') return 'apple_pay';\n return 'google_pay';\n}\n\nfunction getExternalMethodDisplayName(method: string): string {\n return method === 'paypal' ? 'PayPal' : getStripeMethodDisplayName(method);\n}\n\nfunction buildExternalMethodRecoveryMessage(method: string, popupBlocked: boolean): string {\n const base = `We couldn't open ${getExternalMethodDisplayName(method)}. Try again or choose another payment method.`;\n return popupBlocked ? `${base} Allow pop-ups for this site, then try again.` : base;\n}\n\nfunction useExternalAttemptReconciliation(onMissingTerminal: ExternalMethodTechnicalFailureHandler) {\n const generationRef = useRef(0);\n const invalidatedGenerationRef = useRef<number | null>(null);\n const attemptRef = useRef<{\n generation: number;\n method: string;\n timer: ReturnType<typeof setTimeout> | null;\n yieldedControl: boolean;\n } | null>(null);\n\n const clearAttemptTimer = useCallback((targetAttempt = attemptRef.current) => {\n const attempt = targetAttempt;\n if (attempt?.timer) {\n clearTimeout(attempt.timer);\n attempt.timer = null;\n }\n }, []);\n\n const armAttemptTimer = useCallback((\n attempt: NonNullable<typeof attemptRef.current>,\n delayMs: number,\n ) => {\n if (typeof document !== 'undefined' && document.visibilityState !== 'visible') return;\n\n clearAttemptTimer(attempt);\n attempt.timer = setTimeout(() => {\n attempt.timer = null;\n if (attemptRef.current?.generation !== attempt.generation) return;\n attemptRef.current = null;\n invalidatedGenerationRef.current = attempt.generation;\n onMissingTerminal(\n attempt.method,\n new Error('External payment method returned without a terminal callback.'),\n { code: 'external_method_missing_terminal_callback' },\n );\n }, delayMs);\n }, [clearAttemptTimer, onMissingTerminal]);\n\n const armRecoveryTimer = useCallback((attempt: NonNullable<typeof attemptRef.current>) => {\n if (!attempt.yieldedControl) return;\n armAttemptTimer(attempt, EXTERNAL_METHOD_CALLBACK_GRACE_MS);\n }, [armAttemptTimer]);\n\n const startAttempt = useCallback((method: string) => {\n clearAttemptTimer();\n const generation = generationRef.current + 1;\n generationRef.current = generation;\n invalidatedGenerationRef.current = null;\n const attempt = { generation, method, timer: null, yieldedControl: false };\n attemptRef.current = attempt;\n return generation;\n }, [clearAttemptTimer]);\n\n const finishAttempt = useCallback((generation?: number) => {\n const attempt = attemptRef.current;\n if (typeof generation === 'number' && attempt?.generation !== generation) return false;\n clearAttemptTimer(attempt);\n attemptRef.current = null;\n if (typeof generation !== 'number' || invalidatedGenerationRef.current === generation) {\n invalidatedGenerationRef.current = null;\n }\n return true;\n }, [clearAttemptTimer]);\n\n const invalidateAttempt = useCallback((generation?: number) => {\n const attempt = attemptRef.current;\n const targetGeneration = generation ?? attempt?.generation ?? generationRef.current;\n if (!generation || attempt?.generation === generation) {\n clearAttemptTimer(attempt);\n attemptRef.current = null;\n }\n invalidatedGenerationRef.current = targetGeneration;\n }, [clearAttemptTimer]);\n\n const isAttemptInvalidated = useCallback(\n (generation?: number) => invalidatedGenerationRef.current === (generation ?? generationRef.current),\n [],\n );\n\n const isAttemptCurrent = useCallback(\n (generation: number) => (\n attemptRef.current?.generation === generation &&\n invalidatedGenerationRef.current !== generation\n ),\n [],\n );\n\n const scheduleRecoveryIfReturned = useCallback(() => {\n const attempt = attemptRef.current;\n if (!attempt) return;\n armRecoveryTimer(attempt);\n }, [armRecoveryTimer]);\n\n const markAttemptYieldedControl = useCallback(() => {\n const attempt = attemptRef.current;\n if (!attempt) return;\n attempt.yieldedControl = true;\n clearAttemptTimer(attempt);\n }, [clearAttemptTimer]);\n\n useEffect(() => {\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'visible') {\n scheduleRecoveryIfReturned();\n } else {\n markAttemptYieldedControl();\n }\n };\n const handleBlur = () => {\n markAttemptYieldedControl();\n };\n document.addEventListener('visibilitychange', handleVisibilityChange);\n window.addEventListener('blur', handleBlur);\n window.addEventListener('focus', scheduleRecoveryIfReturned);\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n window.removeEventListener('blur', handleBlur);\n window.removeEventListener('focus', scheduleRecoveryIfReturned);\n clearAttemptTimer();\n };\n }, [clearAttemptTimer, markAttemptYieldedControl, scheduleRecoveryIfReturned]);\n\n return { startAttempt, finishAttempt, invalidateAttempt, isAttemptInvalidated, isAttemptCurrent };\n}\n\n/**\n * Inline copy for a postcode that is non-empty but malformed for the selected\n * country, appending the country-specific expected format when we have one\n * (e.g. \"Enter a valid ZIP Code (e.g. 12345 or 12345-6789)\"). Shared by the\n * vault inline hint and the Stripe submit-time validation so both read alike.\n */\nfunction malformedPostcodeMessage(country: string): string {\n const example = getPostalCodeExample(country);\n return `Enter a valid ${getPostalCodeLabel(country)}${example ? ` (e.g. ${example})` : ''}`;\n}\n\n/**\n * Pure country-aware postcode state, the single source of truth for the\n * required/empty/malformed rules. Called with React state from the live\n * `postalCodeState` memo (drives the inline hint + vault gate) and with ref\n * values from `handleSubmit` (dodges stale closures at submit time); keeping\n * one implementation stops the two call sites drifting as the rules evolve. A\n * locale `validator` supports makes the postcode required *and* format-checked;\n * an unsupported / no-postcode locale fails open (`empty`/`malformed` stay\n * false). `visible` is the AVS field's per-country visibility, computed by the\n * caller since it depends on the caller's `avsConfig`.\n */\nfunction computePostalCodeState(country: string, zip: string, visible: boolean) {\n const supported = isPostalCodeSupported(country);\n const trimmed = zip.trim();\n const required = visible && supported;\n const empty = required && !trimmed;\n const malformed = required && !!trimmed && !isValidPostalCode(country, trimmed);\n return { visible, supported, required, empty, malformed };\n}\n\nfunction normalizeBeforeButtonClickError(\n method: CheckoutButtonMethod,\n err: unknown,\n): FloPayError {\n return err instanceof FloPayError\n ? err\n : new FloPayError(\n err instanceof Error ? err.message : `${getButtonMethodLabel(method)} before-click hook failed.`,\n 'validation_error',\n );\n}\n\nfunction FloPayKeyframes() {\n return <style>{FLOPAY_KEYFRAMES}</style>;\n}\n\nfunction toCssSize(value: string | number | undefined): string | undefined {\n if (typeof value === 'number') return `${value}px`;\n return value;\n}\n\nfunction toCssWeight(value: string | number | undefined): string | number | undefined {\n if (typeof value === 'number' || typeof value === 'string') return value;\n return undefined;\n}\n\n/**\n * Express-checkout element load states.\n *\n * - `loading`: initial — waiting for ExpressCheckoutElement's `ready` event.\n * - `ready`: at least one of the requested methods is available on this\n * device. Element renders.\n * - `unavailable`: the element initialized fine but `availablePaymentMethods`\n * reported none of the requested methods. The row collapses so buyers can\n * continue with another payment method.\n * - `load_error`: Stripe's `onLoadError` fired — the element couldn't\n * initialize at all (script blocked, network failure).\n */\ntype ExpressCheckoutLoadState = 'loading' | 'ready' | 'unavailable' | 'load_error';\n\nfunction resolveExpressCheckoutLoadState(\n event: StripeExpressCheckoutElementReadyEvent,\n methods: Array<string>,\n): ExpressCheckoutLoadState {\n const available = event.availablePaymentMethods as Record<string, boolean | undefined> | undefined;\n if (!available) return 'unavailable';\n\n return methods.some((method) => available[method]) ? 'ready' : 'unavailable';\n}\n\nfunction ExpressCheckoutReadySwap({\n state,\n placeholderTestId,\n borderRadius = 8,\n children,\n}: {\n state: ExpressCheckoutLoadState;\n placeholderTestId?: string;\n /**\n * Border radius for the pulse-skeleton placeholder. Defaults to `8` for\n * the classic look; consumers pass the theme's `borderRadius` (or the\n * theme bundle's `cardButton.borderRadius`) so the skeleton matches the\n * eventual button's corners — otherwise the placeholder reads as\n * visually unrelated to the wallet tile that replaces it.\n */\n borderRadius?: string | number;\n children: React.ReactNode;\n}) {\n if (state === 'unavailable' || state === 'load_error') return null;\n\n return (\n <div style={{ position: 'relative', minHeight: 44 }}>\n <div\n data-testid={placeholderTestId}\n aria-hidden={state === 'ready'}\n style={{\n position: 'absolute',\n inset: 0,\n height: 44,\n borderRadius,\n background: '#e5e7eb',\n animation: state === 'ready' ? undefined : 'flopay-pulse 1.5s ease-in-out infinite',\n opacity: state === 'ready' ? 0 : 1,\n transform: state === 'ready' ? 'scale(0.985)' : 'scale(1)',\n transition: 'opacity 140ms ease-out, transform 140ms ease-out',\n pointerEvents: 'none',\n }}\n />\n <div\n style={{\n minHeight: 44,\n opacity: state === 'ready' ? 1 : 0,\n transform: state === 'ready' ? 'translateY(0)' : 'translateY(2px)',\n transition: 'opacity 140ms ease-out, transform 140ms ease-out',\n pointerEvents: state === 'ready' ? 'auto' : 'none',\n }}\n >\n {children}\n </div>\n </div>\n );\n}\n\nfunction isExpressCheckoutRowVisible(state: ExpressCheckoutLoadState): boolean {\n return state !== 'unavailable' && state !== 'load_error';\n}\n\n/** Props for the `SplitCardForm` component. */\nexport interface SplitCardFormProps {\n /** The checkout session ID (UUID from billing API). */\n sessionId: string;\n /**\n * Session-bound checkout token returned by session creation\n * (`CheckoutSessionResult.nonce` or `session.clientSecret`). Forwarded as\n * `x-checkout-session-token` on every continuation request — required by\n * post-#640 backends. `FloPayCheckout` plumbs this prop automatically.\n */\n nonce?: string;\n /** Billing API base URL. Optional — defaults to the value from FloPayProvider or the shared constant. */\n billingApiUrl?: string;\n /** User's email (required for creating payment intents). */\n email?: string;\n /** User ID (required for processing payments). */\n userId?: string;\n /** Called when the full payment flow completes successfully. */\n onComplete?: (result: PaymentResult) => void;\n /** Called when a payment error occurs. */\n onError?: (error: FloPayError) => void;\n /** Called when a payment is declined or the authentication step fails. */\n onDecline?: (decline: DeclineEvent) => void;\n /**\n * **Override**: If provided, delegates backend submission to the caller.\n * When omitted, processes internally (calls processPayment + handles 3DS).\n */\n onTokenizedBody?: (tokenizedBody: TokenizedBody) => void;\n /** First name for billing. */\n firstName?: string;\n /** Last name for billing. */\n lastName?: string;\n /** Checkout version for A/B tracking. */\n chv?: string;\n /** Additional CSS class for the form wrapper. */\n className?: string;\n /** External processing state. */\n isProcessing?: boolean;\n /** External error message. */\n error?: string | null;\n /** Called when internal error state changes. */\n onErrorChange?: (error: string | null) => void;\n /**\n * Show the PayPal payment surface above the hosted vault card surface. Defaults to `true`.\n * The renderer is chosen from `session.gateways.paypal`: when that gateway\n * is configured, `DirectPayPalButton` (PayPal JS SDK) takes over and Stripe\n * drops `paypal` from its express row to avoid double-rendering; otherwise\n * PayPal renders inside `ExpressCheckoutElement` (using either a dedicated\n * `gateways.stripe.paypalPublishableKey` sub-account or the main Stripe\n * account when the enabled-methods list includes `paypal`).\n */\n showPayPal?: boolean;\n /**\n * Show Stripe-rendered wallets and APMs (ExpressCheckoutElement +\n * PaymentElement). Defaults to `true`. When `false`, every Stripe surface\n * is hidden — only `DirectPayPalButton` can render. Setting both\n * `showStripe={false}` and `showPayPal={false}` (with no PayPal gateway\n * configured) throws a bootstrap-time validation error.\n */\n showStripe?: boolean;\n /**\n * Per-session list of Stripe payment method type identifiers (as returned\n * by the billing API on `gateways.stripe.enabledPaymentMethods`). When\n * supplied, drives the contents of the `ExpressCheckoutElement` row and the\n * accordion `PaymentElement` instead of the historic hardcoded\n * Apple/Google/PayPal set. When omitted, the SDK falls back to the legacy\n * `showApplePay`/`showGooglePay`/`showPayPal` toggles.\n */\n enabledPaymentMethods?: string[];\n /**\n * Per-method buyer-country gate from `gateways.stripe.enabledPaymentMethodCountries`\n * (method → allowed ISO-3166-1 alpha-2 countries; a method absent here has no\n * country gate). The SDK filters the rendered tile row by the buyer's *live*\n * country against this map, so per-method country eligibility comes from the\n * backend rather than a hardcoded SDK table. When omitted (legacy backend),\n * the SDK falls back to its built-in {@link STRIPE_METHOD_COUNTRIES} table.\n */\n enabledPaymentMethodCountries?: Record<string, string[]>;\n /**\n * @deprecated The Apple Pay / Google Pay surface is now driven by the\n * `gateways.stripe.enabledPaymentMethods` list returned per-session by the\n * billing API. Pass {@link SplitCardFormProps.enabledPaymentMethods} (or\n * upgrade the backend so `FloPayCheckout` threads it through automatically).\n * Setting this prop emits a one-time deprecation warning and is otherwise\n * ignored when `enabledPaymentMethods` is supplied.\n */\n showApplePay?: boolean;\n /**\n * @deprecated See {@link SplitCardFormProps.showApplePay}.\n */\n showGooglePay?: boolean;\n /**\n * Layout mode for the payment form.\n * - `'default'` — all payment methods + card form shown together (current behavior)\n * - `'buttons'` — PayPal, wallets, and a \"Credit / Debit Card\" button; clicking the card\n * button expands the card form with a back button to return to the button view\n */\n layout?: 'default' | 'buttons';\n /**\n * High-level theme bundle that styles non-card Stripe Elements, the FloPay\n * wrapper / AVS inputs, and the hosted vault widget. One of:\n * `'classic'` (historic FloPay look, no bundle applied), `'modern-light'`,\n * `'modern-dark'`, `'bold-light'`, `'bold-dark'`, `'glass-light'`,\n * `'glass-dark'`. Explicit `appearance` / `buttonsStyles` props still\n * override their respective halves when provided.\n */\n theme?: import('@flopay/shared').ThemeId;\n /**\n * @deprecated Use `theme` instead. Legacy buttons-layout preset\n * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for\n * back-compat — the new union accepts the bundle ids too but you should\n * migrate to the `theme` prop.\n */\n buttonsTheme?: import('@flopay/shared').ButtonsLayoutTheme;\n /** Style overrides merged on top of the resolved theme bundle / buttonsTheme preset. */\n buttonsStyles?: import('@flopay/shared').ButtonsLayoutStyles;\n /**\n * Appearance from `FloPayProvider` / `FloPayCheckout`. Threaded through so\n * the React-rendered wrapper, AVS inputs, title, and hosted vault widget can\n * derive colors from `appearance.variables` when no explicit `buttonsStyles`\n * is supplied. Bundle consumers (`THEMES[id]`) get a coherent look without\n * having to forward both halves manually.\n */\n appearance?: import('@flopay/shared').FloPayAppearance;\n /** Custom React content rendered inside the card button when `layout=\"buttons\"`. */\n cardButtonContent?: React.ReactNode;\n /** Custom React content rendered for the buttons-layout card back button label. */\n cardBackButtonContent?: React.ReactNode;\n /** Custom React content rendered for the card-form title. */\n cardTitleContent?: React.ReactNode;\n /**\n * @deprecated No longer rendered — the default-layout security footer was\n * removed alongside the theme-bundle refactor. Retained as an optional\n * prop so existing integrations type-check without changes.\n */\n showSecurityFooter?: boolean;\n /**\n * Called when a payment method button is clicked.\n * `method`: `'card'` | `'paypal'` | `'apple_pay'` | `'google_pay'`\n */\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n /**\n * Called before a payment button continues in `layout=\"buttons\"`.\n * Runs for card, PayPal, Apple Pay, and Google Pay.\n */\n onBeforeButtonClick?: (\n event: BeforeButtonClickEvent,\n ) => MaybePromise<void | false | InlineSessionPatch>;\n /**\n * Enable AVS (Address Verification).\n * - `true` — show country + postal code (backward compatible default)\n * - `AVSFieldConfig` — granular per-field control, optionally scoped to country codes\n * - `false` / omitted — AVS disabled\n */\n enableAVS?: boolean | AVSFieldConfig;\n /**\n * Per-merchant order of the hosted vault card rows — a permutation of\n * `['name','number','expiry']` (`'expiry'` is the combined expiry+CVV row;\n * the submit button stays last). Drives both the visual order and the tab\n * order inside the widget. Omit for the default (`name`, `number`, `expiry`).\n * Only applies on the vault card path.\n */\n cardFieldOrder?: import('@flopay/shared').VaultCardFieldKey[];\n /** Content rendered above the hosted vault card widget (below the wallet divider). */\n cardPreFormSlot?: React.ReactNode;\n /** Layout for AVS fields: 'row' (side-by-side, default) or 'column' (stacked). */\n avsLayout?: 'row' | 'column';\n /** Pre-filled country code (ISO 3166-1 alpha-2) for AVS. */\n country?: string;\n /** Pre-filled ZIP/postal code for AVS. */\n zip?: string;\n /** Pre-filled street address (line 1) for AVS. Typically from a partner GeoIP / profile lookup. */\n addressLine1?: string;\n /** Pre-filled apt/suite/unit (line 2) for AVS. */\n addressLine2?: string;\n /** Pre-filled city for AVS. Typically from a partner GeoIP / profile lookup. */\n city?: string;\n /** Pre-filled state/province for AVS. Typically from a partner GeoIP / profile lookup. */\n state?: string;\n /** Callback when AVS country changes. */\n onCountryChange?: (country: string) => void;\n /** Callback when AVS ZIP/postal code changes. */\n onZipChange?: (zip: string) => void;\n // ── Checkout analytics metadata ──\n /** Whether AVS was enabled (sent to backend for analytics). */\n avsCheck?: boolean;\n /** Checkout type: 'standard_checkout' or 'embedded_checkout'. */\n checkoutType?: string;\n /** Checkout layout: 'default_layout', 'buttons_layout', or 'custom_layout'. */\n checkoutLayout?: string;\n /** Total amount in cents (smallest currency unit). Used for wallet/PayPal Elements config. */\n totalAmount?: number;\n /** Currency code (used for PayPal Elements config). */\n currency?: string;\n /** Render the card form expanded on first paint when `layout=\"buttons\"`. */\n initialCardOpen?: boolean;\n /**\n * Direct PayPal gateway configuration. When provided, PayPal renders via\n * the official PayPal JS SDK (in-app browser compliant) instead of via\n * Stripe's ExpressCheckoutElement. Selection is mutually exclusive:\n * setting this disables the Stripe-rendered PayPal path automatically.\n */\n directPaypal?: {\n clientId: string;\n environment?: GatewayEnvironment;\n };\n /** Whether the active session represents a subscription (drives direct PayPal intent). */\n isSubscription?: boolean;\n /** Backing session — forwarded to direct-PayPal so it can populate accountData. */\n session?: CheckoutSession | null;\n /**\n * Enables on-screen diagnostic panels for the PayPal/wallet gating decision\n * and the `DirectPayPalButton` lifecycle. Intended for debugging in-app\n * browsers where remote console access is impractical. Off by default.\n */\n debug?: boolean;\n}\n\n/**\n * Checkout surface combining hosted vault card capture with wallets, APMs,\n * and PayPal. Card entry is hosted-vault-only.\n *\n * Stripe-hosted PayPal uses its own Elements instance; direct PayPal uses the\n * official PayPal SDK when the session advertises that gateway.\n */\nexport function SplitCardForm(props: SplitCardFormProps) {\n return <SplitCardFormInner {...props} />;\n}\n\n// ─── PayPal button (own Elements instance) ──────────────────────────────────\n// Stripe-rendered PayPal surface with its own Elements instance.\n\nfunction PayPalButtonInner({\n sessionId,\n nonce,\n email,\n billingApiUrl,\n onTokenizedBody,\n onErrorChange,\n isProcessing = false,\n onButtonClick,\n onDecline,\n onTechnicalFailure,\n runBeforeButtonClick,\n onLoadStateChange,\n placeholderBorderRadius,\n}: {\n sessionId: string;\n nonce?: string;\n email?: string;\n billingApiUrl: string;\n onTokenizedBody: InternalTokenizedBodyHandler;\n onErrorChange?: (error: string | null) => void;\n isProcessing?: boolean;\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n onDecline?: (decline: DeclineEvent) => void;\n onTechnicalFailure?: ExternalMethodTechnicalFailureHandler;\n runBeforeButtonClick?: RunBeforeButtonClick;\n onLoadStateChange?: (state: ExpressCheckoutLoadState) => void;\n placeholderBorderRadius?: string | number;\n}) {\n const flopay = useFloPay();\n const stripe = useStripeRaw();\n const elements = useStripeElements();\n const [loadState, setLoadState] = useState<ExpressCheckoutLoadState>('loading');\n useEffect(() => {\n onLoadStateChange?.(loadState);\n }, [loadState, onLoadStateChange]);\n const [submitting, setSubmitting] = useState(false);\n const paypalResumeAttempted = useRef(false);\n const focusTargetRef = useRef<HTMLDivElement | null>(null);\n const recoveryActionRef = useRef<HTMLButtonElement | null>(null);\n const [surfaceKey, setSurfaceKey] = useState(0);\n const [showRecoveryAction, setShowRecoveryAction] = useState(false);\n const pendingProviderFocusRef = useRef(false);\n const attemptContextBySurfaceRef = useRef(new Map<number, {\n generation: number;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n }>());\n const {\n startAttempt,\n finishAttempt,\n invalidateAttempt,\n isAttemptInvalidated,\n isAttemptCurrent,\n } = useExternalAttemptReconciliation((method, err, options) => {\n onTechnicalFailure?.(method, err, {\n ...options,\n popupBlocked: options?.popupBlocked ?? isPopupBlockedError(err),\n });\n setShowRecoveryAction(true);\n setSurfaceKey((key) => key + 1);\n });\n useEffect(() => {\n if (showRecoveryAction) recoveryActionRef.current?.focus();\n }, [showRecoveryAction, surfaceKey]);\n const resetSurface = useCallback(() => {\n setSurfaceKey((key) => key + 1);\n }, []);\n const recoverTechnicalFailure = useCallback((err: unknown, code?: string, generation?: number) => {\n invalidateAttempt(generation);\n onTechnicalFailure?.('paypal', err, { code, popupBlocked: isPopupBlockedError(err) });\n setShowRecoveryAction(true);\n resetSurface();\n }, [invalidateAttempt, onTechnicalFailure, resetSurface]);\n const focusProviderSurface = useCallback(() => {\n window.setTimeout(() => {\n const target = focusTargetRef.current?.querySelector<HTMLElement>('iframe');\n (target ?? focusTargetRef.current)?.focus();\n }, 0);\n }, []);\n useEffect(() => {\n if (!pendingProviderFocusRef.current) return;\n pendingProviderFocusRef.current = false;\n focusProviderSurface();\n }, [focusProviderSurface, surfaceKey]);\n const handleRecoveryActionClick = useCallback(() => {\n setShowRecoveryAction(false);\n onErrorChange?.(null);\n focusProviderSurface();\n }, [focusProviderSurface, onErrorChange]);\n\n // Resume PayPal redirect return — detect payment_intent in URL\n useEffect(() => {\n if (!stripe || paypalResumeAttempted.current) return;\n\n const params = new URLSearchParams(window.location.search);\n const paymentIntentId = params.get('payment_intent');\n const clientSecret = params.get('payment_intent_client_secret');\n const redirectStatus = params.get('redirect_status');\n\n if (!paymentIntentId || !clientSecret) return;\n paypalResumeAttempted.current = true;\n\n // Recover the effective session / nonce / accountPatch persisted by\n // `handlePayPalConfirm` before the redirect. Without this, an inline-\n // session bootstrap done inside `runBeforeButtonClick` (which set its\n // own sessionId + nonce) would be lost — the post-reload props expose\n // the freshly re-bootstrapped base session, not the one PayPal\n // authorized — and /process would 401 against the wrong nonce.\n let persistedOverrides: TokenizedBodyOverrides | undefined;\n try {\n const raw = localStorage.getItem(PAYPAL_RESUME_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as {\n clientSecret?: string;\n sessionId?: string;\n nonce?: string;\n accountPatch?: InlineSessionPatch['account'];\n };\n // Only honor the payload if it matches this PI — a stale entry from\n // an abandoned earlier attempt should not retarget the current resume.\n if (parsed.clientSecret === clientSecret) {\n persistedOverrides = {\n ...(parsed.accountPatch ? { accountPatch: parsed.accountPatch } : {}),\n ...(parsed.sessionId ? { sessionId: parsed.sessionId } : {}),\n ...(parsed.nonce ? { nonce: parsed.nonce } : {}),\n };\n }\n }\n } catch { /* ignore corrupt payload */ }\n try { localStorage.removeItem(PAYPAL_RESUME_KEY); } catch { /* ignore */ }\n\n // Strip Stripe's PayPal-redirect params from the URL up front, before any\n // async work. The resume `useRef` guard above is reset on remount — if a\n // remount races our async resume, the only way to stop it from re-firing\n // for the same PI is to make sure the URL no longer signals \"we're inside\n // a resume.\" Doing this synchronously (rather than only after a successful\n // /process) closes that re-entry window for every branch below.\n const cleanedUrl = new URL(window.location.href);\n cleanedUrl.searchParams.delete('payment_intent');\n cleanedUrl.searchParams.delete('payment_intent_client_secret');\n cleanedUrl.searchParams.delete('redirect_status');\n window.history.replaceState({}, '', cleanedUrl.toString());\n\n (async () => {\n try {\n setSubmitting(true);\n\n if (redirectStatus === 'failed') {\n const message = 'PayPal payment was declined. Please try again.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('paypal', message));\n return;\n }\n\n const { paymentIntent, error } = await stripe.retrievePaymentIntent(clientSecret);\n if (error) {\n onErrorChange?.(error.message ?? 'Failed to retrieve PayPal payment status.');\n return;\n }\n\n if (paymentIntent && (paymentIntent.status === 'requires_capture' || paymentIntent.status === 'succeeded')) {\n const paymentMethodId = typeof paymentIntent.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent.payment_method?.id;\n\n onTokenizedBody({\n id: paymentMethodId ?? paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n isPaypal: true,\n }, persistedOverrides);\n } else {\n const message = 'PayPal payment was not completed. Please try again.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('paypal', message));\n }\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'Failed to complete PayPal payment.');\n } finally {\n setSubmitting(false);\n }\n })();\n }, [stripe, onTokenizedBody, onErrorChange, onDecline]);\n\n const handlePayPalClick = useCallback(async (\n event: { resolve: () => void; reject: () => void },\n ) => {\n if (isProcessing || submitting) {\n event.reject();\n return;\n }\n\n const beforeClick = runBeforeButtonClick\n ? await runBeforeButtonClick('paypal')\n : { proceed: true } as BeforeButtonClickResult;\n\n if (!beforeClick.proceed) {\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n event.reject();\n return;\n }\n\n const generation = startAttempt('paypal');\n attemptContextBySurfaceRef.current.set(surfaceKey, {\n generation,\n accountPatch: beforeClick.accountPatch,\n sessionId: beforeClick.sessionId,\n nonce: beforeClick.nonce,\n });\n setShowRecoveryAction(false);\n onButtonClick?.('paypal');\n event.resolve();\n }, [attemptContextBySurfaceRef, isProcessing, onButtonClick, runBeforeButtonClick, startAttempt, submitting, surfaceKey]);\n\n // PayPal confirm handler — called by ExpressCheckoutElement onConfirm\n const handlePayPalConfirm = useCallback(async (event: StripeExpressCheckoutElementConfirmEvent) => {\n if (!stripe || !elements) return;\n const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);\n if (attemptContext && !isAttemptCurrent(attemptContext.generation)) {\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n return;\n }\n if (!attemptContext && isAttemptInvalidated()) return;\n if (attemptContext && !finishAttempt(attemptContext.generation)) return;\n if (!attemptContext) finishAttempt();\n\n let prepared: ExternalAttemptPrepared | null = attemptContext ?? null;\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n\n if (!prepared && runBeforeButtonClick) {\n const beforeClick = await runBeforeButtonClick('paypal');\n if (!beforeClick.proceed) {\n event.paymentFailed({ reason: 'fail', message: 'PayPal checkout was cancelled.' });\n return;\n }\n prepared = {\n accountPatch: beforeClick.accountPatch,\n sessionId: beforeClick.sessionId,\n nonce: beforeClick.nonce,\n };\n }\n\n const effectiveSessionId = prepared?.sessionId ?? sessionId;\n const effectiveNonce = prepared?.nonce ?? nonce;\n const effectiveEmail = prepared?.accountPatch?.email ?? email;\n\n try {\n setSubmitting(true);\n onErrorChange?.(null);\n\n if (!effectiveSessionId || !effectiveEmail) {\n throw new Error('Missing sessionId or email for PayPal payment');\n }\n\n const createPM = stripe.createPaymentMethod as unknown as (\n params: { type: string },\n ) => Promise<{ error?: { message?: string }; paymentMethod?: { id: string } }>;\n\n const { error: pmError, paymentMethod } = await createPM({ type: 'paypal' });\n if (pmError) {\n recoverTechnicalFailure(pmError, 'stripe_paypal_create_payment_method_failed', attemptContext?.generation);\n event.paymentFailed({ reason: 'fail' });\n return;\n }\n\n // 1. Create the Stripe-hosted PayPal intent through the session-scoped\n // provider-neutral non-card contract.\n const intent = await new PaymentAPI(billingApiUrl).createSessionIntent(\n effectiveSessionId,\n effectiveNonce ?? '',\n {\n provider: 'stripe',\n paymentMethodCategory: 'wallet',\n paymentMethodType: 'paypal',\n paymentMethodId: paymentMethod?.id ?? null,\n intentKind: 'payment',\n },\n );\n if (intent.provider !== 'stripe') {\n throw new Error('Invalid provider returned for PayPal intent');\n }\n const intentClientSecret = intent.clientSecret;\n\n // 2. Confirm payment — PayPal will redirect or complete inline.\n const confirmParams: Record<string, unknown> = {\n return_url: window.location.href,\n };\n if (paymentMethod?.id) {\n confirmParams['payment_method'] = paymentMethod.id;\n }\n\n // Persist the resume payload before `confirmPayment` — if the buyer is\n // redirected to PayPal, the page reload on return wipes React state, so\n // the resume effect has to recover `effectiveSessionId`/`effectiveNonce`\n // from storage to /process against the same session PayPal authorized.\n // Keyed by `intentClientSecret` so a stale payload from a prior attempt\n // can't replay against a different PaymentIntent.\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem(PAYPAL_RESUME_KEY, JSON.stringify({\n clientSecret: intentClientSecret,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n accountPatch: prepared?.accountPatch,\n }));\n } catch { /* localStorage unavailable */ }\n }\n\n const { error: confirmError, paymentIntent } = await stripe.confirmPayment({\n clientSecret: intentClientSecret,\n confirmParams: confirmParams as { return_url: string },\n redirect: 'if_required',\n });\n\n if (confirmError) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(PAYPAL_RESUME_KEY); } catch { /* ignore */ }\n }\n if (isProviderDecline(confirmError)) {\n const message = confirmError.message ?? 'Your payment was declined.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('paypal', message, {\n code: getProviderErrorCode(confirmError),\n declineCode: getProviderDeclineCode(confirmError),\n }));\n await reportNonCardDecline({\n billingApiUrl,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n request: {\n provider: 'stripe',\n paymentMethodCategory: 'wallet',\n paymentMethodType: 'paypal',\n providerDeclineReason: getProviderErrorCode(confirmError) ?? 'provider_declined',\n },\n });\n } else {\n recoverTechnicalFailure(confirmError, 'stripe_paypal_confirm_failed', attemptContext?.generation);\n }\n return;\n }\n\n // Inline-complete path (no redirect happened) — the resume effect won't\n // fire, so drop the persisted payload now to avoid replay on next mount.\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(PAYPAL_RESUME_KEY); } catch { /* ignore */ }\n }\n\n const confirmedPmId = typeof paymentIntent?.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent?.payment_method?.id;\n\n onTokenizedBody({\n id: confirmedPmId ?? paymentIntent?.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent?.id,\n isPaypal: true,\n }, {\n accountPatch: prepared?.accountPatch,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n });\n return;\n } catch (err) {\n recoverTechnicalFailure(err, 'stripe_paypal_failed', attemptContext?.generation);\n } finally {\n setSubmitting(false);\n }\n }, [stripe, elements, sessionId, nonce, email, billingApiUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick, recoverTechnicalFailure, finishAttempt, isAttemptCurrent, isAttemptInvalidated, surfaceKey]);\n\n return (\n <>\n <ExpressCheckoutReadySwap\n state={loadState}\n placeholderTestId=\"flopay-paypal-placeholder\"\n borderRadius={placeholderBorderRadius}\n >\n <div\n ref={focusTargetRef}\n tabIndex={-1}\n data-testid=\"flopay-paypal-focus-target\"\n aria-label=\"PayPal payment method\"\n style={{ borderRadius: 8, outlineOffset: 4 }}\n >\n {showRecoveryAction && (\n <button\n ref={recoveryActionRef}\n type=\"button\"\n data-testid=\"flopay-paypal-retry-button\"\n onClick={handleRecoveryActionClick}\n style={EXTERNAL_METHOD_RECOVERY_BUTTON_STYLE}\n >\n Try PayPal again\n </button>\n )}\n <ExpressCheckoutElement\n key={surfaceKey}\n onReady={(event) => setLoadState(resolveExpressCheckoutLoadState(event, ['paypal']))}\n onLoadError={() => setLoadState('load_error')}\n onClick={handlePayPalClick}\n onConfirm={handlePayPalConfirm}\n onCancel={() => {\n const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n getFloPayTelemetryBridge(flopay)?.terminal({\n outcome: 'payment_cancelled',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n invalidateAttempt(attemptContext?.generation);\n setShowRecoveryAction(false);\n pendingProviderFocusRef.current = true;\n resetSurface();\n }}\n options={{\n buttonType: { paypal: 'paypal' } as Record<string, string>,\n billingAddressRequired: false,\n phoneNumberRequired: false,\n shippingAddressRequired: false,\n paymentMethods: {\n applePay: 'never',\n googlePay: 'never',\n paypal: 'auto',\n link: 'never',\n },\n } as Parameters<typeof ExpressCheckoutElement>[0]['options']}\n />\n </div>\n </ExpressCheckoutReadySwap>\n {submitting && <ProcessingOverlay status=\"processing\" />}\n </>\n );\n}\n\n// ─── Wallet buttons (Apple Pay / Google Pay — own Elements instance) ────────\n// Uses raw stripe + elements from its own StripeElements context,\n// Wallet confirmation through its dedicated Elements instance.\n\nfunction WalletButtonInner({\n sessionId,\n nonce,\n email,\n billingApiUrl,\n intentKind,\n expressMethods,\n onTokenizedBody,\n onErrorChange,\n onButtonClick,\n onDecline,\n onTechnicalFailure,\n runBeforeButtonClick,\n onLoadStateChange,\n placeholderBorderRadius,\n}: {\n sessionId: string;\n nonce?: string;\n email?: string;\n billingApiUrl: string;\n intentKind: 'payment' | 'setup';\n /**\n * Stripe-wire method identifiers to render in the ExpressCheckoutElement\n * (`apple_pay`, `google_pay`, `link`, `amazon_pay`, `klarna`, `paypal`).\n * Already filtered against {@link STRIPE_EXPRESS_METHODS}; `paypal` is\n * dropped upstream when `DirectPayPalButton` owns the PayPal surface.\n */\n expressMethods: string[];\n onTokenizedBody: InternalTokenizedBodyHandler;\n onErrorChange?: (error: string | null) => void;\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n onDecline?: (decline: DeclineEvent) => void;\n onTechnicalFailure?: ExternalMethodTechnicalFailureHandler;\n runBeforeButtonClick?: RunBeforeButtonClick;\n onLoadStateChange?: (state: ExpressCheckoutLoadState) => void;\n placeholderBorderRadius?: string | number;\n}) {\n const flopay = useFloPay();\n const stripe = useStripeRaw();\n const elements = useStripeElements();\n const [loadState, setLoadState] = useState<ExpressCheckoutLoadState>('loading');\n useEffect(() => {\n onLoadStateChange?.(loadState);\n }, [loadState, onLoadStateChange]);\n const [submitting, setSubmitting] = useState(false);\n const focusTargetRef = useRef<HTMLDivElement | null>(null);\n const recoveryActionRef = useRef<HTMLButtonElement | null>(null);\n const [surfaceKey, setSurfaceKey] = useState(0);\n const [showRecoveryAction, setShowRecoveryAction] = useState(false);\n const [recoveryActionMethod, setRecoveryActionMethod] = useState<string>('google_pay');\n const pendingProviderFocusRef = useRef(false);\n const lastWalletProviderMethodRef = useRef<string>('google_pay');\n const lastWalletMethodRef = useRef<CheckoutButtonMethod>('google_pay');\n const attemptContextBySurfaceRef = useRef(new Map<number, {\n generation: number;\n method: string;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n }>());\n const {\n startAttempt,\n finishAttempt,\n invalidateAttempt,\n isAttemptInvalidated,\n isAttemptCurrent,\n } = useExternalAttemptReconciliation((method, err, options) => {\n onTechnicalFailure?.(method, err, {\n ...options,\n popupBlocked: options?.popupBlocked ?? isPopupBlockedError(err),\n });\n setRecoveryActionMethod(method);\n setShowRecoveryAction(true);\n setSurfaceKey((key) => key + 1);\n });\n useEffect(() => {\n if (showRecoveryAction) recoveryActionRef.current?.focus();\n }, [showRecoveryAction, surfaceKey]);\n const resetSurface = useCallback(() => {\n setSurfaceKey((key) => key + 1);\n }, []);\n const recoverTechnicalFailure = useCallback((method: string, err: unknown, code?: string, generation?: number) => {\n invalidateAttempt(generation);\n onTechnicalFailure?.(method, err, { code, popupBlocked: isPopupBlockedError(err) });\n setRecoveryActionMethod(method);\n setShowRecoveryAction(true);\n resetSurface();\n }, [invalidateAttempt, onTechnicalFailure, resetSurface]);\n const focusProviderSurface = useCallback(() => {\n window.setTimeout(() => {\n const target = focusTargetRef.current?.querySelector<HTMLElement>('iframe');\n (target ?? focusTargetRef.current)?.focus();\n }, 0);\n }, []);\n useEffect(() => {\n if (!pendingProviderFocusRef.current) return;\n pendingProviderFocusRef.current = false;\n focusProviderSurface();\n }, [focusProviderSurface, surfaceKey]);\n const handleRecoveryActionClick = useCallback(() => {\n setShowRecoveryAction(false);\n onErrorChange?.(null);\n focusProviderSurface();\n }, [focusProviderSurface, onErrorChange]);\n\n const handleWalletConfirm = useCallback(\n async (event: StripeExpressCheckoutElementConfirmEvent) => {\n if (!stripe || !elements) return;\n const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);\n if (attemptContext && !isAttemptCurrent(attemptContext.generation)) {\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n return;\n }\n if (!attemptContext && isAttemptInvalidated()) return;\n if (attemptContext && !finishAttempt(attemptContext.generation)) return;\n if (!attemptContext) finishAttempt();\n\n // Detect wallet type from the express checkout event. Stripe's\n // `expressPaymentType` covers Apple/Google Pay; the SDK collapses\n // anything else (Link, Amazon Pay, Klarna) onto `google_pay` for the\n // existing analytics enum surface.\n const walletType = (event as unknown as { expressPaymentType?: string }).expressPaymentType\n ?? attemptContext?.method\n ?? lastWalletProviderMethodRef.current;\n let prepared: ExternalAttemptPrepared | null = attemptContext ?? null;\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n\n const buttonMethod = checkoutButtonMethodFromProviderMethod(walletType);\n if (!prepared && runBeforeButtonClick) {\n const beforeClick = await runBeforeButtonClick(buttonMethod);\n if (!beforeClick.proceed) {\n event.paymentFailed({ reason: 'fail', message: 'Wallet checkout was cancelled.' });\n return;\n }\n prepared = {\n accountPatch: beforeClick.accountPatch,\n sessionId: beforeClick.sessionId,\n nonce: beforeClick.nonce,\n };\n }\n\n const method = buttonMethod;\n const effectiveSessionId = prepared?.sessionId ?? sessionId;\n const effectiveNonce = prepared?.nonce ?? nonce;\n const effectiveEmail = prepared?.accountPatch?.email ?? email;\n\n try {\n setSubmitting(true);\n onErrorChange?.(null);\n\n // 1. Submit elements (validates wallet payment sheet)\n const { error: submitError } = await elements.submit();\n if (submitError) {\n recoverTechnicalFailure(walletType, submitError, 'stripe_wallet_submit_failed', attemptContext?.generation);\n return;\n }\n\n // 2. Create PaymentMethod from wallet token via the wallet's own Elements\n const { error: pmError, paymentMethod } = await stripe.createPaymentMethod({ elements });\n if (pmError || !paymentMethod) {\n recoverTechnicalFailure(walletType, pmError ?? new Error('Failed to create payment method.'), 'stripe_wallet_create_payment_method_failed', attemptContext?.generation);\n return;\n }\n\n if (!effectiveSessionId || !effectiveEmail) {\n throw new Error('Missing sessionId or email for wallet payment');\n }\n\n // 3. Create the provider intent through the nonce-protected,\n // session-scoped non-card contract.\n const intent = await new PaymentAPI(billingApiUrl).createSessionIntent(\n effectiveSessionId,\n effectiveNonce ?? '',\n {\n provider: 'stripe',\n paymentMethodCategory: 'wallet',\n paymentMethodType: walletType ?? buttonMethod,\n paymentMethodId: paymentMethod.id,\n intentKind,\n },\n );\n if (intent.provider !== 'stripe') {\n throw new Error('Invalid provider returned for wallet intent');\n }\n const intentClientSecret = intent.clientSecret;\n\n // 4. Confirm the intent (handles 3DS automatically). Trial-only / $0\n // wallet checkouts get a SetupIntent from the server — Stripe's\n // confirmCardPayment rejects `seti_` secrets, so confirm the card\n // setup instead. The captured card is attached to the SetupIntent and\n // charged when the trial ends.\n const { error: confirmError, intentId } = isSetupIntentClientSecret(intentClientSecret)\n ? await stripe\n .confirmCardSetup(intentClientSecret, { payment_method: paymentMethod.id })\n .then((r) => ({ error: r.error, intentId: r.setupIntent?.id }))\n : await stripe\n .confirmCardPayment(intentClientSecret, { payment_method: paymentMethod.id })\n .then((r) => ({ error: r.error, intentId: r.paymentIntent?.id }));\n\n if (confirmError) {\n if (isProviderDecline(confirmError)) {\n const message = confirmError.message ?? 'Your payment was declined.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent(method, message, {\n code: getProviderErrorCode(confirmError),\n declineCode: getProviderDeclineCode(confirmError),\n }));\n await reportNonCardDecline({\n billingApiUrl,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n request: {\n provider: 'stripe',\n paymentMethodCategory: 'wallet',\n paymentMethodType: walletType ?? buttonMethod,\n providerDeclineReason: getProviderErrorCode(confirmError) ?? 'provider_declined',\n },\n });\n } else {\n recoverTechnicalFailure(walletType, confirmError, 'stripe_wallet_confirm_failed', attemptContext?.generation);\n }\n return;\n }\n\n // 5. Send PM + PI to process endpoint\n onTokenizedBody({\n id: paymentMethod.id,\n type: 'card',\n threeDSecureActionResultTokenId: intentId,\n }, {\n accountPatch: prepared?.accountPatch,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n });\n } catch (err) {\n recoverTechnicalFailure(walletType, err, 'stripe_wallet_failed', attemptContext?.generation);\n } finally {\n setSubmitting(false);\n }\n },\n [stripe, elements, sessionId, nonce, email, billingApiUrl, intentKind, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick, recoverTechnicalFailure, finishAttempt, isAttemptCurrent, isAttemptInvalidated, surfaceKey],\n );\n\n // ExpressCheckoutElement's `paymentMethods` map uses camelCase keys; every\n // method not present in `expressMethods` is explicitly set to `'never'` so\n // Stripe collapses it instead of falling back to its own defaults. Only\n // `applePay` and `googlePay` accept `'always'`; `link`, `klarna`, `amazonPay`,\n // and `paypal` are typed as `'auto' | 'never'` by Stripe and throw an\n // IntegrationError at mount if `'always'` is passed.\n const expressMethodMap = useMemo(() => {\n const allKeys = ['applePay', 'googlePay', 'paypal', 'link', 'amazonPay', 'klarna'] as const;\n const alwaysCapable = new Set<string>(['applePay', 'googlePay']);\n const enabledKeys = new Set(expressMethods.map(stripeExpressMethodToOptionKey));\n const out: Record<string, 'always' | 'auto' | 'never'> = {};\n for (const key of allKeys) {\n if (!enabledKeys.has(key)) {\n out[key] = 'never';\n } else {\n out[key] = alwaysCapable.has(key) ? 'always' : 'auto';\n }\n }\n return out;\n }, [expressMethods]);\n const availableMethodKeys = useMemo(\n () => expressMethods.map(stripeExpressMethodToOptionKey),\n [expressMethods],\n );\n\n return (\n <>\n <ExpressCheckoutReadySwap\n state={loadState}\n placeholderTestId=\"flopay-wallet-placeholder\"\n borderRadius={placeholderBorderRadius}\n >\n <div\n ref={focusTargetRef}\n tabIndex={-1}\n data-testid=\"flopay-wallet-focus-target\"\n aria-label=\"Wallet payment methods\"\n style={{ borderRadius: 8, outlineOffset: 4 }}\n >\n {showRecoveryAction && (\n <button\n ref={recoveryActionRef}\n type=\"button\"\n data-testid=\"flopay-wallet-retry-button\"\n onClick={handleRecoveryActionClick}\n style={EXTERNAL_METHOD_RECOVERY_BUTTON_STYLE}\n >\n Try {getExternalMethodDisplayName(recoveryActionMethod)} again\n </button>\n )}\n <ExpressCheckoutElement\n key={surfaceKey}\n onReady={(event) => {\n setLoadState(resolveExpressCheckoutLoadState(event, availableMethodKeys));\n }}\n onLoadError={(_event) => {\n setLoadState('load_error');\n getFloPayTelemetryBridge(flopay)?.error({\n errorCode: 'PROVIDER_LOAD_FAILED',\n stage: 'provider_load',\n provider: 'stripe',\n paymentMethodCategory: 'wallet',\n requestCategory: 'provider_sdk',\n });\n }}\n onClick={async (event) => {\n lastWalletProviderMethodRef.current = event.expressPaymentType;\n lastWalletMethodRef.current = checkoutButtonMethodFromProviderMethod(event.expressPaymentType);\n\n const beforeClick = runBeforeButtonClick\n ? await runBeforeButtonClick(lastWalletMethodRef.current)\n : { proceed: true } as BeforeButtonClickResult;\n\n if (!beforeClick.proceed) {\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n event.reject();\n return;\n }\n\n const generation = startAttempt(event.expressPaymentType);\n attemptContextBySurfaceRef.current.set(surfaceKey, {\n generation,\n method: event.expressPaymentType,\n accountPatch: beforeClick.accountPatch,\n sessionId: beforeClick.sessionId,\n nonce: beforeClick.nonce,\n });\n setShowRecoveryAction(false);\n onButtonClick?.(lastWalletMethodRef.current);\n event.resolve();\n }}\n onConfirm={handleWalletConfirm}\n onCancel={() => {\n const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);\n attemptContextBySurfaceRef.current.delete(surfaceKey);\n getFloPayTelemetryBridge(flopay)?.terminal({\n outcome: 'payment_cancelled',\n provider: 'stripe',\n paymentMethodCategory: 'wallet',\n });\n invalidateAttempt(attemptContext?.generation);\n setShowRecoveryAction(false);\n pendingProviderFocusRef.current = true;\n resetSurface();\n }}\n options={{\n buttonType: { applePay: 'plain', googlePay: 'plain' } as Record<string, string>,\n paymentMethods: expressMethodMap,\n layout: { maxColumns: 1, overflow: 'never' },\n } as Parameters<typeof ExpressCheckoutElement>[0]['options']}\n />\n </div>\n </ExpressCheckoutReadySwap>\n {submitting && <ProcessingOverlay status=\"processing\" />}\n </>\n );\n}\n\n// ─── Stripe PaymentElement (non-express APMs: Cash App Pay / Klarna / Affirm / iDEAL / SEPA …) ─\n\n/**\n * PaymentElement region — rendered as one button per enabled APM, styled to\n * match the wallet ECE row above it. Each button's behaviour is determined\n * by {@link needsStripeMethodExplicitConfirm} in the shared method matrix:\n *\n * - **Auto-confirm methods** (Cash App, Affirm, …): clicking the button\n * swaps it for a loading spinner, and the SDK goes straight to\n * `stripe.confirmPayment({ payment_method_data: { type, billing_details } })`\n * with no PaymentElement involvement. Stripe takes over with its popup /\n * redirect; on cancel the spinner reverts back to the button.\n *\n * - **Input-form methods** (SEPA Debit, EPS, iDEAL, …): clicking the\n * button collapses the row to just that method and mounts an inline\n * PaymentElement scoped to `paymentMethodTypes: [method]` in a separate\n * Elements group. The inline form shows the method's required input\n * (IBAN, bank picker, …) plus a \"Pay with X\" button. A back link\n * restores the full button row.\n *\n * Each expanded form mounts its own {@link StripeElements} group rather\n * than sharing a parent group across methods, because `paymentMethodTypes`\n * cannot be mutated on an existing Elements group (`elements.update()`\n * explicitly rejects it). The trade-off is a ~500ms `/v1/elements/sessions`\n * call on first expansion of each method — acceptable cost for the focused\n * per-method UX.\n */\n\n/**\n * Reusable method-tile button — same 44px contract as the wallet ECE row.\n * Lifted out so both the unselected list and the expanded-method header\n * reuse the same shape and theming. The pressed state (`submitting`)\n * replaces the label with a spinner so the buyer sees feedback during the\n * session-scoped intent creation → `stripe.confirmPayment` round-trip on\n * auto-confirm methods.\n */\nfunction StripeMethodButton({\n method,\n themeId,\n submitting = false,\n disabled = false,\n highlighted = false,\n hasNextStep = false,\n onClick,\n backgroundColor,\n borderColor,\n textColor,\n borderRadius,\n fontFamily,\n}: {\n method: string;\n /**\n * Active FloPay theme id — drives which `STRIPE_METHOD_MATRIX[method]\n * .theme.{light,dark}` variant the button picks up its brand colors\n * (and eventually logo) from. `null`/`undefined`/`classic` falls back\n * to the matrix's `light` variant; any `*-dark` theme picks the `dark`\n * variant.\n */\n themeId?: import('@flopay/shared').ThemeId | null;\n submitting?: boolean;\n disabled?: boolean;\n highlighted?: boolean;\n /**\n * Render a right-chevron at the trailing edge of the button label,\n * signalling that clicking the tile drills into a second page (the\n * inline form for input-requiring APMs like SEPA Debit / EPS / iDEAL).\n * Auto-confirm methods (Cash App, Affirm) leave this off — their click\n * goes straight to Stripe's authorization UI with no intermediate page.\n */\n hasNextStep?: boolean;\n onClick: () => void;\n backgroundColor?: string;\n borderColor?: string;\n textColor?: string;\n borderRadius?: string | number;\n fontFamily?: string;\n}) {\n // Resolution order:\n // 1. Brand variant pulled from `STRIPE_METHOD_MATRIX[method].theme`\n // keyed by mode — gives Cash App green, Klarna pink, etc., out of\n // the box. Brand wins over the surrounding theme bundle's neutral\n // `cardButton` styling because the *method's* identity is more\n // specific than the *layout's* tile design — and the parent always\n // passes the theme bundle's `cardButton` colors through the prop\n // channel, so otherwise no branded button would ever surface.\n // 2. Inline `buttonAppearance` prop — bundle-level overrides for\n // methods without a brand variant in the matrix.\n // 3. Defaults — white + grey border, matching the legacy tile.\n const brand = resolveStripeMethodBrandVariant(method, themeId);\n const vendoredLogoUrl = PAYMENT_METHOD_LOGO_URLS[method];\n const resolvedBackground = brand?.backgroundColor ?? backgroundColor ?? '#ffffff';\n const resolvedBorder = brand?.borderColor ?? borderColor ?? '#d1d5db';\n const resolvedTextColor = brand?.textColor ?? textColor ?? '#262833';\n return (\n <button\n type=\"button\"\n data-testid={`flopay-stripe-method-button-${method}`}\n data-method={method}\n onClick={() => { if (!submitting && !disabled) onClick(); }}\n disabled={submitting || disabled}\n aria-busy={submitting || undefined}\n style={{\n position: 'relative',\n width: '100%',\n boxSizing: 'border-box',\n height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT,\n padding: '0 1rem',\n backgroundColor: resolvedBackground,\n color: resolvedTextColor,\n border: `1px solid ${resolvedBorder}`,\n borderRadius: borderRadius ?? 8,\n fontSize: '0.95rem',\n fontWeight: 600,\n fontFamily,\n cursor: submitting || disabled ? 'not-allowed' : 'pointer',\n opacity: disabled && !submitting ? 0.55 : 1,\n // Submitting state pulses the whole button background, mirroring\n // the wallet ECE's `flopay-pulse` skeleton. This keeps the loading\n // affordance consistent between embedded wallets (Apple Pay,\n // Google Pay) and these custom APM tile buttons — same animation\n // curve, same duration, only the surface colour changes (grey for\n // the wallet skeleton vs. brand colour for an in-flight tile).\n animation: submitting ? 'flopay-pulse 1.5s ease-in-out infinite' : undefined,\n display: 'flex',\n alignItems: 'center',\n // Always center the logo+name group. The drill-in chevron (input\n // methods) is absolutely positioned at the right edge below so it\n // doesn't pull the label off-center.\n justifyContent: 'center',\n gap: 8,\n transition: 'transform 0.1s, opacity 140ms ease-out, border-color 140ms ease-out',\n boxShadow: highlighted ? '0 0 0 2px rgba(74, 73, 255, 0.15)' : undefined,\n }}\n >\n {submitting ? (\n // Pulse-skeleton parity with the wallet ECE: no spinner, just the\n // status text on top of the pulsing background. Keeps the loading\n // affordance shape-equivalent across both kinds of tile.\n <span style={{ margin: '0 auto' }}>\n {`Connecting to ${getStripeMethodDisplayName(method)}…`}\n </span>\n ) : (\n <>\n {/* Group: logo + name sit adjacent (8px gap) so the brand mark\n reads as part of the same label, not as a separately\n left-justified icon. The group is always centered (the button's\n `justifyContent: 'center'`); the drill-in chevron is absolutely\n positioned at the right edge so it never pulls the label\n off-center. */}\n <span\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n // Real vendored logos are self-contained brand cards, so they\n // get an 8px gap from the label. The generated placeholder\n // monogram reads as part of the label (the tile's first letter),\n // so it sits flush (0px) against the name.\n gap: hasVendoredStripeMethodLogo(method) ? 8 : 0,\n }}\n >\n {vendoredLogoUrl ? (\n // Vendored brand logo — an <img> asset (not inline SVG) so its\n // bytes ship as a sibling file, out of the JS bundle. 3:2 box\n // matching the datatrans logos' 120×80 viewBox; each ships its own\n // white rounded-rect background so it stays legible on any tile.\n <img\n src={vendoredLogoUrl}\n alt=\"\"\n aria-hidden=\"true\"\n // Decorative brand mark, never LCP-critical: defer the fetch and\n // decode off the main thread so it never competes with critical\n // resources or blocks rendering during checkout load. The fixed\n // 30×20 box below reserves space, so lazy loading causes no shift.\n loading=\"lazy\"\n decoding=\"async\"\n width={30}\n height={20}\n style={{\n width: 30,\n height: 20,\n flexShrink: 0,\n borderRadius: 3,\n objectFit: 'contain',\n display: 'inline-flex',\n }}\n />\n ) : brand?.logoSvg ? (\n <span\n aria-hidden=\"true\"\n style={{\n width: 30,\n height: 20,\n flexShrink: 0,\n display: 'inline-flex',\n borderRadius: 3,\n overflow: 'hidden',\n }}\n // Placeholder monogram markup originates from the matrix\n // (`StripeMethodEntry.theme.{light,dark}.logoSvg`); we trust it\n // here because the matrix is owned by the SDK, not user input.\n dangerouslySetInnerHTML={{ __html: brand.logoSvg }}\n />\n ) : null}\n <span>{getStripeMethodDisplayName(method)}</span>\n </span>\n {hasNextStep && (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={resolvedTextColor}\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n position: 'absolute',\n right: '1rem',\n top: '50%',\n transform: 'translateY(-50%)',\n flexShrink: 0,\n opacity: 0.7,\n }}\n aria-hidden=\"true\"\n >\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n )}\n </>\n )}\n </button>\n );\n}\n\n/**\n * Inline form rendered beneath the selected method button for APMs that\n * need data collection. Mounts a single-method PaymentElement (Stripe's\n * accordion with one item, default-expanded) plus the \"Pay with X\" submit\n * button. Lives inside its own `<StripeElements>` group keyed by method, so\n * switching between methods unmounts the previous group cleanly.\n */\nfunction StripeMethodInlineForm({\n method,\n sessionId,\n nonce,\n email,\n billingName,\n billingApiUrl,\n onTokenizedBody,\n onErrorChange,\n onDecline,\n onCancel,\n runBeforeButtonClick,\n onButtonClick,\n isProcessing,\n submitButtonColor,\n submitButtonBorderRadius,\n submitButtonStyle,\n errorText,\n}: {\n method: string;\n sessionId: string;\n nonce?: string;\n email?: string;\n billingName?: string;\n billingApiUrl: string;\n onTokenizedBody: InternalTokenizedBodyHandler;\n onErrorChange?: (error: string | null) => void;\n onDecline?: (decline: DeclineEvent) => void;\n onCancel: () => void;\n /**\n * Error/decline message to surface on *this* inner page, beneath the \"Pay\n * with X\" button. The parent owns the error state (so it clears on screen\n * navigation); the form just renders it where the buyer is actually looking\n * instead of leaving it on the method-selection screen behind.\n */\n errorText?: string | null;\n runBeforeButtonClick?: RunBeforeButtonClick;\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n isProcessing?: boolean;\n submitButtonColor: string;\n submitButtonBorderRadius: string | number;\n submitButtonStyle?: React.CSSProperties;\n}) {\n const flopay = useFloPay();\n const stripe = useStripeRaw();\n const elements = useStripeElements();\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n const [isMethodComplete, setIsMethodComplete] = useState(false);\n const [loadState, setLoadState] = useState<'loading' | 'ready' | 'load_error'>('loading');\n\n const handlePay = useCallback(async () => {\n if (!stripe || !elements || isProcessing || submittingRef.current || !isMethodComplete) return;\n submittingRef.current = true;\n setSubmitting(true);\n\n const beforeClick = runBeforeButtonClick\n ? await runBeforeButtonClick('card')\n : { proceed: true } as BeforeButtonClickResult;\n if (!beforeClick.proceed) {\n submittingRef.current = false;\n setSubmitting(false);\n return;\n }\n onButtonClick?.('card');\n\n const effectiveSessionId = beforeClick.sessionId ?? sessionId;\n const effectiveNonce = beforeClick.nonce ?? nonce;\n const effectiveEmail = beforeClick.accountPatch?.email ?? email;\n\n try {\n onErrorChange?.(null);\n\n const submitRes = await elements.submit();\n if (submitRes.error) {\n onErrorChange?.(submitRes.error.message ?? 'Payment failed.');\n return;\n }\n\n const pmRes = await stripe.createPaymentMethod({ elements });\n if (pmRes.error || !pmRes.paymentMethod) {\n onErrorChange?.(pmRes.error?.message ?? 'Failed to create payment method.');\n return;\n }\n const paymentMethod = pmRes.paymentMethod;\n\n if (!effectiveSessionId || !effectiveEmail) {\n throw new Error('Missing sessionId or email for payment.');\n }\n\n // Scope the PI by the bare method type, not the pre-created PaymentMethod\n // id. The backend keys `payment_method_types` off `paymentMethodType` only\n // when `paymentMethodId` is null; a non-null id is treated as a card PM and\n // scopes the PI to `card`, which then rejects a non-card method (bancontact,\n // eps, sepa_debit, …) at confirm. The PM we just created is attached\n // client-side in `confirmPayment` below, against the now type-scoped PI.\n const paymentMethodType = paymentMethod.type || method;\n const intent = await new PaymentAPI(billingApiUrl).createSessionIntent(\n effectiveSessionId,\n effectiveNonce ?? '',\n {\n provider: 'stripe',\n paymentMethodCategory: 'apm',\n paymentMethodType,\n paymentMethodId: null,\n intentKind: 'payment',\n },\n );\n if (intent.provider !== 'stripe') {\n throw new Error('Invalid provider returned for APM intent');\n }\n const intentClientSecret = intent.clientSecret;\n\n // Persist the resume payload before confirmPayment — the shared resume\n // handler picks it up after a redirect return.\n // `clientSecret` / `nonce` / `accountPatch` mirror the PayPal recovery\n // payload: when a `runBeforeButtonClick` bootstrap created a fresh\n // session, the post-redirect re-bootstrap exposes a different base\n // session via props, so /process must use the persisted (authorized)\n // sessionId + nonce — not the fresh prop pair — to avoid a 401.\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem(STRIPE_RESUME_KEY, JSON.stringify({\n clientSecret: intentClientSecret,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n accountPatch: beforeClick.accountPatch,\n paymentMethodId: paymentMethod.id,\n paymentMethodType: paymentMethod.type ?? method,\n gateway: 'stripe',\n }));\n } catch { /* localStorage unavailable */ }\n }\n\n const { error: confirmError, paymentIntent } = await stripe.confirmPayment({\n clientSecret: intentClientSecret,\n confirmParams: {\n return_url: window.location.href,\n payment_method: paymentMethod.id,\n } as { return_url: string; payment_method?: string },\n redirect: 'if_required',\n });\n\n if (confirmError) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const message = confirmError.message ?? 'Payment failed.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('card', message, { code: confirmError.code }));\n await reportNonCardDecline({\n billingApiUrl,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n request: {\n provider: 'stripe',\n paymentMethodCategory: 'apm',\n paymentMethodType: method,\n providerDeclineReason: confirmError.code ?? 'provider_declined',\n },\n });\n return;\n }\n\n const piStatus = paymentIntent?.status;\n if (!isSuccessfulPaymentIntentStatus(piStatus)) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const message = piStatus === 'canceled'\n ? 'Payment was canceled.'\n : 'Payment was not completed. Please try again.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('card', message, { code: piStatus ?? 'missing_payment_intent' }));\n return;\n }\n\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const confirmedPmId = typeof paymentIntent?.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent?.payment_method?.id;\n\n onTokenizedBody({\n id: confirmedPmId ?? paymentMethod.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent?.id,\n gateway: 'stripe',\n paymentMethodType: paymentMethod.type ?? method,\n }, {\n accountPatch: beforeClick.accountPatch,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n });\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'Payment failed. Please try again.');\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }, [stripe, elements, isProcessing, isMethodComplete, runBeforeButtonClick, onButtonClick,\n sessionId, nonce, email, billingApiUrl, method, onTokenizedBody, onErrorChange, onDecline]);\n\n // The back/cancel control is rendered by the parent (\"Go back\" button at\n // the top of the 2nd-page panel that mirrors the card form's 2nd page),\n // so `onCancel` is intentionally unused here — kept on the prop signature\n // so other call sites that still embed the form inline can wire their\n // own back link if needed.\n void onCancel;\n\n return (\n <div data-testid={`flopay-stripe-method-form-${method}`} style={{ display: 'flex', flexDirection: 'column' }}>\n <PaymentElement\n onReady={() => setLoadState('ready')}\n onLoadError={() => {\n setLoadState('load_error');\n getFloPayTelemetryBridge(flopay)?.error({\n errorCode: 'PROVIDER_LOAD_FAILED',\n stage: 'provider_load',\n provider: 'stripe',\n paymentMethodCategory: 'apm',\n requestCategory: 'provider_sdk',\n });\n }}\n onChange={(event) => {\n const evRecord = event as unknown as { complete?: boolean };\n setIsMethodComplete(!!evRecord.complete);\n }}\n // Single-method group: only this method's accordion item renders,\n // default-expanded so the inline form (IBAN / bank picker) is\n // immediately visible.\n options={{\n layout: { type: 'accordion', defaultCollapsed: false, radios: 'never' },\n defaultValues: {\n billingDetails: {\n name: billingName && billingName.trim().length >= 3\n ? billingName.trim()\n : 'FloPay Customer',\n ...(email ? { email } : {}),\n },\n },\n } as unknown as Parameters<typeof PaymentElement>[0]['options']}\n />\n\n <button\n type=\"button\"\n data-testid={`flopay-stripe-method-pay-${method}`}\n onClick={() => { void handlePay(); }}\n disabled={!isMethodComplete || submitting || isProcessing || loadState !== 'ready'}\n style={{\n width: '100%',\n marginTop: '0.75rem',\n padding: '0.875rem',\n backgroundColor: submitButtonColor,\n color: 'white',\n border: 'none',\n borderRadius: submitButtonBorderRadius,\n fontSize: '1rem',\n fontWeight: 600,\n cursor: (!isMethodComplete || submitting || isProcessing || loadState !== 'ready') ? 'not-allowed' : 'pointer',\n opacity: (!isMethodComplete || submitting || isProcessing || loadState !== 'ready') ? 0.5 : 1,\n transition: 'opacity 120ms ease-out',\n ...(submitButtonStyle ?? {}),\n }}\n >\n {submitting ? 'Processing…' : `Pay with ${getStripeMethodDisplayName(method)}`}\n </button>\n\n {errorText && (\n <ErrorBanner margin=\"0.75rem 0 0\">{errorText}</ErrorBanner>\n )}\n </div>\n );\n}\nfunction StripePaymentElementInner({\n sessionId,\n nonce,\n email,\n billingName,\n billingApiUrl,\n paymentElementMethods,\n stripeInstance,\n paymentElementBaseOptions,\n onTokenizedBody,\n onErrorChange,\n onButtonClick,\n onDecline,\n runBeforeButtonClick,\n onLoadStateChange,\n isProcessing = false,\n submitButtonColor = '#4A49FF',\n submitButtonBorderRadius = 8,\n submitButtonStyle,\n buttonAppearance,\n themeId,\n onExpandApm,\n expandedApmMethod,\n}: {\n sessionId: string;\n nonce?: string;\n email?: string;\n /**\n * Buyer's full name, prefilled into the inline PaymentElement's billing\n * details so `elements.submit()` for methods that mandate a name (SEPA,\n * Bancontact, Klarna, …) doesn't reject with `invalid_name_<method>`.\n * Falls back to `'FloPay Customer'` only if the session has no buyer\n * name at all.\n */\n billingName?: string;\n billingApiUrl: string;\n paymentElementMethods: string[];\n /**\n * Raw Stripe instance from the parent `FloPayProvider`. The component\n * uses it directly for `confirmPayment` on auto-confirm methods (no\n * Elements group needed) and as the `stripe` prop on each expanded\n * method's inline `<StripeElements>` group.\n */\n stripeInstance: Stripe | null;\n /**\n * Shared Elements options (mode/amount/currency/appearance) without\n * `paymentMethodTypes`. Each expanded method spreads this and adds its\n * own `paymentMethodTypes: [method]` to scope its inline form.\n */\n paymentElementBaseOptions: Record<string, unknown>;\n onTokenizedBody: InternalTokenizedBodyHandler;\n onErrorChange?: (error: string | null) => void;\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n onDecline?: (decline: DeclineEvent) => void;\n runBeforeButtonClick?: RunBeforeButtonClick;\n onLoadStateChange?: (state: 'loading' | 'ready' | 'load_error') => void;\n isProcessing?: boolean;\n submitButtonColor?: string;\n submitButtonBorderRadius?: string | number;\n submitButtonStyle?: React.CSSProperties;\n /**\n * Theme overrides applied to each method tile button. Defaults to the\n * historic white-with-grey-border styling that matches the legacy\n * \"Credit / Debit Card\" button in the buttons-layout flow.\n */\n buttonAppearance?: {\n backgroundColor?: string;\n borderColor?: string;\n textColor?: string;\n borderRadius?: string | number;\n fontFamily?: string;\n };\n /**\n * Active FloPay theme id — passed through to each tile so it can look up\n * its per-mode brand styling from `STRIPE_METHOD_MATRIX[method].theme`.\n * `null`/`undefined`/`classic` resolves to the matrix's `light` variant;\n * any `*-dark` theme resolves to the `dark` variant.\n */\n themeId?: import('@flopay/shared').ThemeId | null;\n /**\n * Called when the buyer clicks a tile for a method that requires inline\n * data collection (SEPA Debit IBAN, EPS bank picker, …). The parent\n * decides how to present the expanded form — typically by transitioning\n * to a second page (mirroring the card-form 2nd page in buttons layout).\n * Auto-confirm methods (Cash App, Affirm) don't call this; they handle\n * the click locally with a button spinner + direct `confirmPayment`.\n */\n onExpandApm?: (method: string) => void;\n /**\n * The method whose 2nd-page form is currently visible (parent-managed).\n * Used to disable the *other* tile buttons during the drill-in so the\n * buyer either submits or backs out before switching methods.\n */\n expandedApmMethod?: string | null;\n}) {\n // Which method is showing its expanded inline form (input methods only).\n const [expandedMethod, setExpandedMethod] = useState<string | null>(null);\n // Which method is mid-`confirmPayment` (auto-confirm methods only). The\n // tile button replaces its label with a spinner while this is set.\n const [submittingMethod, setSubmittingMethod] = useState<string | null>(null);\n const submittingRef = useRef(false);\n\n // The earlier single-accordion implementation took its `load_state` signal\n // from the PaymentElement's `ready`/`loaderror`\n // events. The custom-button version has no upfront PaymentElement —\n // signal ready as soon as we have a Stripe instance and at least one\n // method to render, so the parent's gate (`shouldDisplayPaymentElementRow`)\n // can stop showing the loading skeleton.\n useEffect(() => {\n if (paymentElementMethods.length > 0 && stripeInstance) {\n onLoadStateChange?.('ready');\n } else if (!stripeInstance) {\n onLoadStateChange?.('loading');\n }\n }, [paymentElementMethods.length, stripeInstance, onLoadStateChange]);\n\n // ─── Auto-confirm flow (Cash App / Affirm / …) ─────────────────────────\n // No PaymentElement: the method has no inline data to collect, so we go\n // POST /intents → stripe.confirmPayment with `payment_method_data.type`\n // and let Stripe handle tokenization + popup/redirect inside its own UI.\n // Saves a `/v1/elements/sessions` round-trip per click compared to the\n // PaymentElement-driven path used for input methods.\n const handleAutoConfirm = useCallback(async (method: string) => {\n if (!stripeInstance) return;\n if (submittingRef.current || isProcessing) return;\n submittingRef.current = true;\n setSubmittingMethod(method);\n\n const beforeClick = runBeforeButtonClick\n ? await runBeforeButtonClick('card')\n : { proceed: true } as BeforeButtonClickResult;\n if (!beforeClick.proceed) {\n submittingRef.current = false;\n setSubmittingMethod(null);\n return;\n }\n onButtonClick?.('card');\n\n const effectiveSessionId = beforeClick.sessionId ?? sessionId;\n const effectiveNonce = beforeClick.nonce ?? nonce;\n const effectiveEmail = beforeClick.accountPatch?.email ?? email;\n\n try {\n onErrorChange?.(null);\n\n if (!effectiveSessionId || !effectiveEmail) {\n throw new Error('Missing sessionId or email for payment.');\n }\n\n const intent = await new PaymentAPI(billingApiUrl).createSessionIntent(\n effectiveSessionId,\n effectiveNonce ?? '',\n {\n provider: 'stripe',\n paymentMethodCategory: 'apm',\n paymentMethodType: method,\n paymentMethodId: null,\n intentKind: 'payment',\n },\n );\n if (intent.provider !== 'stripe') {\n throw new Error('Invalid provider returned for APM intent');\n }\n const intentClientSecret = intent.clientSecret;\n\n // Persist the resume payload before confirmPayment in case Stripe\n // redirects (Cash App Pay does on some platforms; Affirm always\n // does). The parent's resume handler picks this up on return.\n // `clientSecret` / `nonce` / `accountPatch` mirror the PayPal recovery\n // payload: when a `runBeforeButtonClick` bootstrap created a fresh\n // session, the post-redirect re-bootstrap exposes a different base\n // session via props, so /process must use the persisted (authorized)\n // sessionId + nonce — not the fresh prop pair — to avoid a 401.\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem(STRIPE_RESUME_KEY, JSON.stringify({\n clientSecret: intentClientSecret,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n accountPatch: beforeClick.accountPatch,\n paymentMethodType: method,\n gateway: 'stripe',\n }));\n } catch { /* localStorage unavailable in private mode */ }\n }\n\n const { error: confirmError, paymentIntent } = await stripeInstance.confirmPayment({\n clientSecret: intentClientSecret,\n confirmParams: {\n return_url: window.location.href,\n // Inline the method data — no Elements / PaymentElement\n // required. Stripe creates the PaymentMethod during confirm\n // and proceeds to its popup/redirect UI.\n payment_method_data: {\n type: method,\n billing_details: {\n name: billingName && billingName.trim().length >= 3 ? billingName.trim() : 'FloPay Customer',\n ...(effectiveEmail ? { email: effectiveEmail } : {}),\n },\n },\n } as never,\n redirect: 'if_required',\n });\n\n if (confirmError) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const message = confirmError.message ?? 'Payment failed.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('card', message, { code: confirmError.code }));\n await reportNonCardDecline({\n billingApiUrl,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n request: {\n provider: 'stripe',\n paymentMethodCategory: 'apm',\n paymentMethodType: method,\n providerDeclineReason: confirmError.code ?? 'provider_declined',\n },\n });\n return;\n }\n\n // `redirect: 'if_required'` returns *without* `confirmError` even\n // when the buyer closed an inline confirmation UI without\n // approving — `paymentIntent.status` is the authoritative signal.\n const piStatus = paymentIntent?.status;\n if (!isSuccessfulPaymentIntentStatus(piStatus)) {\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const message = piStatus === 'canceled'\n ? 'Payment was canceled.'\n : 'Payment was not completed. Please try again.';\n onErrorChange?.(message);\n onDecline?.(buildDeclineEvent('card', message, { code: piStatus ?? 'missing_payment_intent' }));\n return;\n }\n\n if (typeof window !== 'undefined') {\n try { localStorage.removeItem(STRIPE_RESUME_KEY); } catch { /* ignore */ }\n }\n const confirmedPmId = typeof paymentIntent?.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent?.payment_method?.id;\n\n onTokenizedBody({\n id: confirmedPmId ?? paymentIntent?.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent?.id,\n gateway: 'stripe',\n paymentMethodType: method,\n }, {\n accountPatch: beforeClick.accountPatch,\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n });\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'Payment failed. Please try again.');\n } finally {\n submittingRef.current = false;\n setSubmittingMethod(null);\n }\n }, [stripeInstance, isProcessing, runBeforeButtonClick, onButtonClick, sessionId, nonce, email,\n billingApiUrl, billingName, onTokenizedBody, onErrorChange, onDecline]);\n\n // Fallback expansion state for callers that *don't* provide `onExpandApm`\n // (e.g. the default-layout site, which has no concept of a 2nd page).\n // When the parent owns the navigation (buttons layout), we never touch\n // this and read from `expandedApmMethod` instead.\n const [localExpandedMethod, setLocalExpandedMethod] = useState<string | null>(null);\n const activeExpandedMethod = onExpandApm ? (expandedApmMethod ?? null) : localExpandedMethod;\n\n const handleMethodClick = useCallback((method: string) => {\n if (submittingRef.current || isProcessing) return;\n // While one method is expanded, the other tile buttons are disabled —\n // the buyer has to submit or back out before switching.\n if (activeExpandedMethod && activeExpandedMethod !== method) return;\n\n if (needsStripeMethodExplicitConfirm(method)) {\n if (onExpandApm) {\n // Parent (buttons layout) drives the `viewState` machine and\n // mounts the 2nd-page form there.\n onExpandApm(method);\n } else {\n // Default-layout fallback — expand the form inline beneath the\n // tile button. Same Elements-group-per-method scoping, just\n // without the page transition.\n setLocalExpandedMethod(method);\n }\n } else {\n void handleAutoConfirm(method);\n }\n }, [activeExpandedMethod, isProcessing, handleAutoConfirm, onExpandApm]);\n\n // Per-method Elements options for the local (default-layout) inline form.\n // Mirrors the buttons-layout's `apmInlineOptions` derivation in the\n // parent component.\n const localInlineElementsOptions = useMemo(() => {\n if (!localExpandedMethod) return null;\n return {\n ...paymentElementBaseOptions,\n paymentMethodTypes: [localExpandedMethod],\n } as Parameters<typeof StripeElements>[0]['options'];\n }, [localExpandedMethod, paymentElementBaseOptions]);\n\n return (\n <div\n data-testid=\"flopay-stripe-payment-element-region\"\n style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}\n >\n {paymentElementMethods.map((method) => {\n const isExpanded = expandedApmMethod === method;\n const isSubmittingThis = submittingMethod === method;\n const otherInProgress =\n (submittingMethod !== null && submittingMethod !== method) ||\n (expandedApmMethod !== null && expandedApmMethod !== undefined && expandedApmMethod !== method);\n\n return (\n <React.Fragment key={method}>\n <StripeMethodButton\n method={method}\n themeId={themeId}\n submitting={isSubmittingThis}\n disabled={otherInProgress}\n highlighted={isExpanded}\n // Tile buttons for input methods drill into a 2nd page; the\n // trailing chevron echoes the \"Credit / Debit Card\" button so\n // the affordance reads the same across both kinds of tiles.\n hasNextStep={needsStripeMethodExplicitConfirm(method)}\n onClick={() => handleMethodClick(method)}\n backgroundColor={buttonAppearance?.backgroundColor}\n borderColor={buttonAppearance?.borderColor}\n textColor={buttonAppearance?.textColor}\n borderRadius={buttonAppearance?.borderRadius}\n fontFamily={buttonAppearance?.fontFamily}\n />\n {/* Default-layout fallback: when the parent hasn't wired a 2nd\n page (`onExpandApm`), expand the form inline beneath the\n tile button. Buttons layout never hits this branch — it\n renders the form on its own gridArea-1/1 panel instead. */}\n {!onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && (\n <StripeElements\n key={method}\n stripe={stripeInstance}\n options={localInlineElementsOptions}\n >\n <StripeMethodInlineForm\n method={method}\n sessionId={sessionId}\n email={email}\n billingName={billingName}\n billingApiUrl={billingApiUrl}\n onTokenizedBody={onTokenizedBody}\n onErrorChange={onErrorChange}\n onDecline={onDecline}\n onCancel={() => setLocalExpandedMethod(null)}\n runBeforeButtonClick={runBeforeButtonClick}\n onButtonClick={onButtonClick}\n isProcessing={isProcessing}\n submitButtonColor={submitButtonColor}\n submitButtonBorderRadius={submitButtonBorderRadius}\n submitButtonStyle={submitButtonStyle}\n />\n </StripeElements>\n )}\n </React.Fragment>\n );\n })}\n </div>\n );\n}\n\n// ─── Main form ──────────────────────────────────────────────────────────────\n\nfunction SplitCardFormInner({\n sessionId,\n nonce,\n billingApiUrl,\n email,\n userId,\n onComplete,\n onError,\n onDecline,\n onTokenizedBody,\n firstName,\n lastName,\n chv,\n className,\n isProcessing: externalProcessing,\n error: externalError,\n onErrorChange,\n showPayPal = true,\n showStripe = true,\n enabledPaymentMethods,\n enabledPaymentMethodCountries,\n showApplePay = true,\n showGooglePay = true,\n layout = 'default',\n theme,\n buttonsTheme,\n buttonsStyles: buttonsStylesOverride,\n appearance: appearanceOverride,\n cardButtonContent,\n cardBackButtonContent,\n cardTitleContent,\n showSecurityFooter: _showSecurityFooter,\n onButtonClick,\n onBeforeButtonClick,\n enableAVS: enableAVSProp,\n cardFieldOrder,\n cardPreFormSlot,\n avsLayout: avsLayoutProp = 'row',\n country: countryProp,\n zip: zipProp,\n addressLine1: addressLine1Prop,\n addressLine2: addressLine2Prop,\n city: cityProp,\n state: stateProp,\n onCountryChange,\n onZipChange,\n avsCheck: avsCheckProp,\n checkoutType: checkoutTypeProp,\n checkoutLayout: checkoutLayoutProp,\n totalAmount = 0,\n currency = 'usd',\n initialCardOpen = false,\n directPaypal,\n isSubscription = false,\n session,\n debug = false,\n}: SplitCardFormProps) {\n const flopay = useFloPay();\n const paypalFlopay = usePayPalFloPay();\n const checkout = useContext(CheckoutContext);\n const contextBillingUrl = useBillingApiUrl();\n const [processing, setProcessing] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [selectedCountry, setSelectedCountry] = useState(countryProp ?? 'US');\n const [zipCode, setZipCode] = useState(zipProp ?? '');\n const [addressLine1, setAddressLine1] = useState(addressLine1Prop ?? '');\n const [addressLine2, setAddressLine2] = useState(addressLine2Prop ?? '');\n const [city, setCity] = useState(cityProp ?? '');\n const [stateValue, setStateValue] = useState(stateProp ?? '');\n const [accountPatch, setAccountPatch] = useState<InlineSessionPatch['account']>({});\n const zipCodeRef = useRef(zipProp ?? '');\n const selectedCountryRef = useRef(countryProp ?? 'US');\n const addressLine1Ref = useRef(addressLine1Prop ?? '');\n const addressLine2Ref = useRef(addressLine2Prop ?? '');\n const cityRef = useRef(cityProp ?? '');\n const stateRef = useRef(stateProp ?? '');\n\n // Resolve AVS config: boolean → default config, object → as-is, falsy → null\n const avsConfig = useMemo(() => resolveAVSConfig(enableAVSProp), [enableAVSProp]);\n const enableAVS = avsConfig !== null;\n\n // ── Vault PCI card capture (TeamFloPay/backend#823, Model A) ──\n // The vault IS the card path. Card-capable sessions embed the hosted widget\n // as `session.vault`; `gateways.pcivault` remains a recovery signal for\n // sessions that defer the form to `/vault/capture`. If neither is present,\n // card is unavailable while supported non-card methods remain usable.\n const vaultBlockReady = Boolean(session?.vault?.html);\n const vaultGatewayAdvertised = Boolean(session?.gateways?.pcivault);\n const vaultCapabilityAvailable = vaultBlockReady || vaultGatewayAdvertised;\n const vaultActive = Boolean(\n showStripe && vaultCapabilityAvailable && flopay && sessionId,\n );\n const cardCapture = useMemo<CardCaptureAdapter | null>(() => {\n if (!flopay || !vaultActive || !sessionId) return null;\n return flopay.cardCapture({ sessionId });\n }, [flopay, vaultActive, sessionId]);\n // ── Postcode format state for the live selected country ──\n // Country-aware postcode validation, mirroring the backend (#887) by reusing\n // the same `validator` rules. The hosted-vault submit gate and inline hint\n // share this result. A locale `validator` supports\n // makes the postcode required *and* format-checked; an unsupported /\n // no-postcode locale fails open — the field stays visible but optional and\n // never blocks (`empty`/`malformed` stay false).\n const postalCodeState = useMemo(() => {\n const cc = selectedCountry;\n const visible = avsConfig ? isAVSFieldVisible(avsConfig.postal_code, cc) : false;\n return computePostalCodeState(cc, zipCode, visible);\n }, [avsConfig, selectedCountry, zipCode]);\n // ── AVS validity for the vault submit gate ──\n // The vault's submit button lives inside the (cross-origin) widget and the\n // card fields are PCI-isolated, so the host can only validate the merchant-DOM\n // AVS inputs. When a required AVS field for the selected country is empty — or\n // the postcode is malformed for a supported locale — we push `blocked` to the\n // widget, which disables its submit button until the buyer fixes them (the\n // widget validates the card itself on submit).\n const { avsInvalid, invalidAvsFields } = useMemo<{\n avsInvalid: boolean;\n invalidAvsFields: { line1: boolean; city: boolean; state: boolean; zip: boolean };\n }>(() => {\n const none = { line1: false, city: false, state: false, zip: false };\n if (!vaultActive || !avsConfig) return { avsInvalid: false, invalidAvsFields: none };\n const cc = selectedCountry;\n // `line2` and the country `select` are never required.\n const isEmpty = (field: boolean | string[] | undefined, value: string) =>\n isAVSFieldVisible(field, cc) && !value.trim();\n const invalidAvsFields = {\n line1: isEmpty(avsConfig.address_line_1, addressLine1),\n city: isEmpty(avsConfig.city, city),\n state: isEmpty(avsConfig.state, stateValue),\n // Empty (required) or malformed both block; unsupported/no-postcode\n // locales never block (`postalCodeState` fails open above).\n zip: postalCodeState.empty || postalCodeState.malformed,\n };\n const avsInvalid =\n invalidAvsFields.line1 || invalidAvsFields.city || invalidAvsFields.state || invalidAvsFields.zip;\n return { avsInvalid, invalidAvsFields };\n }, [vaultActive, avsConfig, selectedCountry, addressLine1, city, stateValue, postalCodeState]);\n // Set once the buyer clicks the (enabled) vault submit with valid AVS — after\n // that, an AVS field that *becomes* incomplete gets a red outline, matching how\n // the widget rings its own invalid card fields after a submit attempt.\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = useState(false);\n // Set once the buyer blurs the postcode field. A malformed postcode blocks the\n // (vault) submit, so `hasAttemptedSubmit` can never flip to reveal the error —\n // we surface the inline expected-format message on blur instead.\n const [zipTouched, setZipTouched] = useState(false);\n // Hosted widget mount options: prefer the block embedded on the create-session\n // response (`session.vault`); otherwise fetch it from the idempotent\n // `POST /vault/capture` endpoint (covers sessions loaded by id, or backends\n // that don't embed the block). Carries the `html` plus the optional\n // `messageToken` / `expectedOrigin` the adapter uses to authenticate the\n // widget's terminal `postMessage` outcomes. Resolved by an effect once the\n // error/overlay callbacks below are in scope.\n const [vaultMount, setVaultMount] = useState<CardCaptureMountOptions | null>(() =>\n toVaultMount(session?.vault),\n );\n\n // Buttons ↔ Card ↔ APM transition state machine. The `apm-*` branches\n // mirror the `card` branches one-for-one so the inline-form APM 2nd\n // page (SEPA / EPS / iDEAL / …) animates in and out the same way as the\n // card form's 2nd page, with the same back-button + title chrome.\n type ViewState =\n | 'buttons'\n | 'expanding'\n | 'card'\n | 'collapsing'\n | 'apm-expanding'\n | 'apm-form'\n | 'apm-collapsing';\n const [viewState, setViewState] = useState<ViewState>(\n initialCardOpen && vaultCapabilityAvailable ? 'card' : 'buttons',\n );\n const [expandedApmMethod, setExpandedApmMethod] = useState<string | null>(null);\n const showCardForm = viewState === 'expanding' || viewState === 'card';\n const TRANSITION_MS = 280;\n\n const expandToCard = useCallback(() => {\n setViewState('expanding');\n setTimeout(() => setViewState('card'), TRANSITION_MS);\n }, []);\n\n const collapseToButtons = useCallback(() => {\n setViewState('collapsing');\n setTimeout(() => setViewState('buttons'), TRANSITION_MS);\n }, []);\n\n const expandToApm = useCallback((method: string) => {\n setExpandedApmMethod(method);\n setViewState('apm-expanding');\n setTimeout(() => setViewState('apm-form'), TRANSITION_MS);\n }, []);\n\n const collapseFromApm = useCallback(() => {\n setViewState('apm-collapsing');\n setTimeout(() => {\n setViewState('buttons');\n setExpandedApmMethod(null);\n }, TRANSITION_MS);\n }, []);\n\n useEffect(() => {\n if (layout === 'buttons' && initialCardOpen && vaultCapabilityAvailable) {\n setViewState('card');\n }\n }, [layout, initialCardOpen, vaultCapabilityAvailable]);\n const [overlayStatus, setOverlayStatus] = useState<OverlayStatus | null>(null);\n const processingRef = useRef(false);\n\n // `paypal_direct_required` retry surface. Set when /process returns the\n // discriminator with a fresh PayPal Order/Subscription id — re-binds the\n // direct PayPal button to that id so the buyer can confirm with one more\n // click. Cleared on success or when the buyer dismisses. `attempts` caps\n // the loop at 2 retries so a backend stuck throwing the same exception\n // can't trap the buyer forever.\n const [paypalDirectRetry, setPaypalDirectRetry] = useState<{\n orderId: string;\n attempts: number;\n } | null>(null);\n // Ref-mirror so the processPaymentInternal callback can read current\n // attempt count without recreating on every retry-state change (which\n // would invalidate downstream effects depending on the callback).\n const paypalDirectRetryRef = useRef(paypalDirectRetry);\n useEffect(() => { paypalDirectRetryRef.current = paypalDirectRetry; }, [paypalDirectRetry]);\n\n const resolvedBillingApiUrl = billingApiUrl || contextBillingUrl;\n const displayError = externalError ?? error;\n\n // Resolution order for the wrapper / button styles:\n // 1. `theme` bundle (high-level — pulls a coherent ButtonsLayoutStyles from THEMES)\n // 2. Legacy `buttonsTheme` preset (for back-compat — only applied when `theme` is absent)\n // 3. Explicit `buttonsStyles` override (per-field merge on top of either base)\n // Resolution order for the Stripe-side `appearance`:\n // 1. Explicit `appearance` prop (wins outright)\n // 2. `theme` bundle's appearance (when `appearance` is not supplied)\n const themeBundle = useMemo(() => resolveTheme(theme), [theme]);\n const bStyles = useMemo<ButtonsLayoutStyles>(() => {\n const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme(buttonsTheme);\n if (!buttonsStylesOverride) return base;\n return {\n ...base,\n ...buttonsStylesOverride,\n cardButton: { ...base.cardButton, ...buttonsStylesOverride.cardButton },\n cardFormContainer: { ...base.cardFormContainer, ...buttonsStylesOverride.cardFormContainer },\n backButton: { ...base.backButton, ...buttonsStylesOverride.backButton },\n backButtonIcon: { ...base.backButtonIcon, ...buttonsStylesOverride.backButtonIcon },\n submitButton: { ...base.submitButton, ...buttonsStylesOverride.submitButton },\n title: { ...base.title, ...buttonsStylesOverride.title },\n };\n }, [themeBundle, buttonsTheme, buttonsStylesOverride]);\n const appearance = appearanceOverride ?? themeBundle?.appearance;\n // Colors pushed into the hosted vault widget so the backend-rendered card form\n // matches the merchant's theme. The SDK owns *all* theming here — every value\n // resolves from the theme bundle / appearance overrides (same precedence the\n // SDK uses for its merchant-hosted AVS inputs); the backend ships only neutral\n // fallbacks for when a var is absent. Declared with the other hooks — above\n // any early return — so hook order stays stable across the `isReady` gate.\n const vaultThemeColors = useMemo<import('@flopay/shared').VaultCardThemeColors>(() => {\n const vars = appearance?.variables;\n const asString = (value: unknown): string | undefined =>\n typeof value === 'string' && value ? value : undefined;\n // Mirror the SDK submit-button resolution: a merchant who customized the\n // submit colour via `buttonsStyles.submitButton.backgroundColor` (rather\n // than `appearance.variables.colorPrimary`) should see that same colour on\n // the hosted vault submit instead of the indigo fallback.\n const submitButtonStyle = bStyles.submitButton as React.CSSProperties | undefined;\n const primary =\n asString(vars?.colorPrimary)\n ?? asString(submitButtonStyle?.backgroundColor)\n ?? '#4A49FF';\n const isButtonsLayout = layout === 'buttons';\n const nameInput = bStyles.nameInput;\n // Match the surrounding SDK form — use the same resolution order as the\n // merchant-hosted AVS fields below (`resolvedBorder`,\n // `cardInputBg`, `resolvedInputColor`, `resolvedPlaceholderColor`,\n // `resolvedInputFontFamily/Size`) — so the hosted vault form is visually\n // indistinguishable from the SDK fields for every theme + buttons-layout\n // bundle. The surface stays transparent (form CSS) so the surrounding\n // checkout shows through.\n return {\n primaryColor: primary,\n primaryHoverColor: asString(vars?.colorPrimaryHover) ?? darkenHex(primary, 0.12),\n inputBackgroundColor:\n asString(bStyles.cardInputBackground) ?? asString(vars?.colorBackground) ?? '#ffffff',\n textColor:\n asString(bStyles.cardInputColor)\n ?? asString(nameInput?.color)\n ?? asString(vars?.colorText)\n ?? '#262833',\n borderColor: asString(bStyles.cardInputBorder) ?? (isButtonsLayout ? '#e5e7eb' : '#A4A4FF'),\n placeholderColor: asString(bStyles.cardInputPlaceholderColor) ?? '#9ca3af',\n errorColor: asString(vars?.colorDanger) ?? '#dc2626',\n successColor: '#16a34a',\n fontFamily:\n asString(nameInput?.fontFamily) ?? asString(vars?.fontFamily) ?? 'Poppins, sans-serif',\n fontSize: asString(bStyles.cardInputFontSize) ?? asString(vars?.fontSizeBase) ?? '16px',\n // `resolvedInputFontWeight` equivalent — sent as a string (the widget's\n // theme applier only honors string values) so vault inputs/placeholders\n // match the AVS fields' weight per theme (default 400).\n fontWeight: String(toCssWeight(nameInput?.fontWeight) ?? 400),\n borderRadius: asString(vars?.borderRadius) ?? '8px',\n };\n }, [appearance, bStyles, layout]);\n const isInlineSessionPatchProcessing = checkout.inlineSessionPatchProcessing ?? false;\n const isSubmitting = (externalProcessing ?? processing) || isInlineSessionPatchProcessing;\n const baseUrl = resolvedBillingApiUrl.replace(/\\/+$/, '');\n const resolvedAccount = useMemo(() => mergeAccountPatch({\n userId,\n email,\n firstName,\n lastName,\n country: countryProp,\n zip: zipProp,\n }, accountPatch), [userId, email, firstName, lastName, countryProp, zipProp, accountPatch]);\n const resolvedBillingName = [resolvedAccount.firstName, resolvedAccount.lastName]\n .filter((part): part is string => Boolean(part?.trim()))\n .join(' ');\n\n // Get raw Stripe instance for wallet Elements provider (primary Stripe account).\n const stripeInstance = useMemo(() => {\n if (!flopay) return null;\n return flopay.getRawProvider() as Stripe | null;\n }, [flopay]);\n\n // Get raw Stripe instance for the Stripe-rendered PayPal Elements provider.\n // When direct PayPal is configured (`directPaypal`) or no PayPal FloPay\n // instance is available, the Stripe-rendered PayPal path is suppressed.\n const paypalStripeInstance = useMemo(() => {\n if (!paypalFlopay) return null;\n return paypalFlopay.getRawProvider() as Stripe | null;\n }, [paypalFlopay]);\n\n // totalAmount is in cents (smallest currency unit) when passed from FloPayCheckout.\n // Stripe Elements `amount` expects cents.\n //\n // The `|| 100` is a $1.00 placeholder so payment-mode Elements groups that\n // never display an amount (the per-method PaymentElement forms)\n // still render for a $0-today cart — Stripe rejects `amount: 0` in payment\n // mode. The wallet/Express Checkout row, which DOES show the amount, uses\n // `resolveWalletElementsMode` below to run in setup mode for $0 instead, so it\n // never surfaces this placeholder as a misleading \"$1.00\" charge.\n const amountInCents = totalAmount || 100;\n\n // `FloPayAppearance` is a superset of Stripe's `Appearance` type (it adds\n // `variables.fontSizeBase` etc.) — the Stripe public typings reject the\n // wider shape, but the runtime accepts every extra field. Cast through\n // `Record<string, unknown>` so the spread below stays type-safe at the\n // option-construction site without `any`.\n const stripeAppearanceProp = appearance\n ? { appearance: appearance as unknown as Record<string, unknown> }\n : null;\n\n // PaymentElement-specific appearance: target Stripe's `.AccordionItem` and\n // `.AccordionItemContents` so each method card visually matches the 44px\n // wallet ECE buttons above it. Stripe accepts `padding` / `borderRadius` /\n // border styling in `rules`; `height` is not a supported property, so we\n // pin via padding (10px top/bottom × ~24px line-height ≈ 44px total).\n //\n // Stripe's default `spacedAccordionItems` rendering paints a subtle drop\n // shadow under each method card. The wallet ECE row above this region uses\n // flat buttons with no shadow, so we explicitly null the shadow here for\n // visual parity — without this, Cash App Pay sat noticeably \"above\" the\n // wallet buttons stacked just above it. Consumer overrides still win via\n // the `baseRules` spread.\n const paymentElementAppearance = useMemo(() => {\n const base = (appearance ?? {}) as Record<string, unknown>;\n const baseRules = (base.rules as Record<string, Record<string, string>> | undefined) ?? {};\n return {\n ...base,\n rules: {\n ...baseRules,\n '.AccordionItem': {\n padding: '10px 14px',\n boxShadow: 'none',\n ...(baseRules['.AccordionItem'] ?? {}),\n },\n '.AccordionItemContents': {\n padding: '6px 14px 12px',\n boxShadow: 'none',\n ...(baseRules['.AccordionItemContents'] ?? {}),\n },\n },\n };\n }, [appearance]);\n\n // Wallet (Apple/Google Pay) Elements options use manual payment-method creation\n // so the wallet token can be sent through the session-scoped intent contract.\n // `appearance` is forwarded so the ExpressCheckoutElement iframe inherits the\n // shared theme variables (e.g. `borderRadius`) instead of falling back to\n // Stripe's defaults.\n const walletOptions = useMemo(() => {\n // $0-today (free trial) → setup mode (no charge shown on the Apple/Google\n // Pay sheet); any positive total → payment mode with the real amount.\n const modeOptions = resolveWalletElementsMode(totalAmount);\n return {\n ...modeOptions,\n currency: currency.toLowerCase(),\n paymentMethodCreation: 'manual' as const,\n // captureMethod only applies to payment mode; Stripe rejects it in setup.\n ...(modeOptions.mode === 'payment' ? { captureMethod: 'manual' as const } : {}),\n ...stripeAppearanceProp,\n };\n }, [totalAmount, currency, stripeAppearanceProp]);\n\n // PayPal Elements options — no paymentMethodCreation (matches checkout)\n const paypalOptions = useMemo(() => ({\n mode: 'payment' as const,\n amount: amountInCents,\n currency: currency.toLowerCase(),\n captureMethod: 'manual' as const,\n setupFutureUsage: 'off_session' as const,\n ...stripeAppearanceProp,\n }), [amountInCents, currency, stripeAppearanceProp]);\n\n const updateError = useCallback(\n (err: string | null) => {\n setError(err);\n onErrorChange?.(err);\n },\n [onErrorChange],\n );\n\n // The vault submit-gate is driven by the client-validity effect below (it\n // gates the widget's submit button on the synchronous AVS check, whose\n // postcode half mirrors the backend validator — see that effect for why the\n // gate must stay synchronous). The adapter re-pushes the latest gate value on\n // `ready`, so a pre-ready push is never lost.\n\n // Push the per-merchant card-field order + autofocus into the widget. The\n // widget reorders its rows (DOM order → tab order) and focuses its first field\n // unless AVS fields are rendered above it (then the host focuses the first AVS\n // field — see below). Re-pushed on `ready` by the adapter.\n useEffect(() => {\n if (!vaultActive || !cardCapture) return;\n cardCapture.setCardFieldOrder?.(cardFieldOrder ?? null, avsConfig == null);\n }, [vaultActive, cardCapture, cardFieldOrder, avsConfig]);\n\n // Clear any stale error whenever the buyer moves between screens — selecting a\n // method (card or APM → its form) or hitting \"Go back\" (→ the buttons home).\n // A decline/error from one screen must not linger onto the next: e.g. the\n // vault's \"fill in all required card details\", or an APM decline that\n // otherwise stayed on the method-selection screen behind the inner page.\n // These are the four transition states; the settled states\n // (`buttons`/`card`/`apm-form`) keep whatever error their own flow set.\n useEffect(() => {\n if (\n viewState === 'expanding' ||\n viewState === 'collapsing' ||\n viewState === 'apm-expanding' ||\n viewState === 'apm-collapsing'\n ) {\n updateError(null);\n }\n }, [viewState, updateError]);\n\n const emitDecline = useCallback(\n (\n method: CheckoutButtonMethod,\n input: string | FloPayError,\n overrides?: { code?: string; declineCode?: string },\n ) => {\n onDecline?.(buildDeclineEvent(method, input, overrides));\n },\n [onDecline],\n );\n\n const recoverExternalMethodTechnicalFailure = useCallback<ExternalMethodTechnicalFailureHandler>(\n (method, err, options) => {\n const popupBlocked = options?.popupBlocked ?? isPopupBlockedError(err);\n const message = buildExternalMethodRecoveryMessage(method, popupBlocked);\n const providerCode =\n sanitizeExternalFailureCode(options?.code) ??\n getProviderErrorCode(err) ??\n 'external_payment_method_failed';\n const floPayError = new FloPayError(message, 'api_error', {\n code: 'external_payment_method_failed',\n param: method,\n });\n\n setOverlayStatus(null);\n if (layout === 'buttons') {\n setViewState('buttons');\n setExpandedApmMethod(null);\n }\n updateError(message);\n onError?.(floPayError);\n console.error('[FloPay] External payment method failed:', {\n method,\n code: providerCode,\n popupBlocked,\n });\n },\n [layout, onError, updateError],\n );\n\n // ── Vault widget HTML resolution (Model A) ──\n // Prefer the block embedded on the create-session response; otherwise fetch\n // it from the idempotent `POST /vault/capture` endpoint. Runs only when the\n // vault is active (an embedded `vault` block, or a `gateways.pcivault`\n // advertisement that defers the form to the fetch path).\n useEffect(() => {\n if (!vaultActive || !sessionId) {\n setVaultMount(null);\n return;\n }\n const embedded = toVaultMount(session?.vault);\n if (embedded) {\n setVaultMount(embedded);\n return;\n }\n // Drop any block from a previous session before the fetch resolves so the\n // adapter never mounts widget HTML tied to the wrong checkout session.\n setVaultMount(null);\n let active = true;\n new PaymentAPI(baseUrl)\n .getVaultCapture(sessionId, nonce)\n .then((block) => {\n if (!active) return;\n const mount = toVaultMount(block);\n if (mount) {\n setVaultMount(mount);\n } else {\n updateError('Failed to load the secure card form.');\n }\n })\n .catch((err: unknown) => {\n if (active) {\n updateError(err instanceof Error ? err.message : 'Failed to load the secure card form.');\n }\n });\n return () => {\n active = false;\n };\n }, [\n vaultActive,\n sessionId,\n session?.vault?.html,\n session?.vault?.messageToken,\n session?.vault?.expectedOrigin,\n baseUrl,\n nonce,\n updateError,\n ]);\n\n // Latest volatile inputs the vault-outcome handlers read, captured in a ref so\n // the outcome subscription effect below can depend only on the *stable*\n // `[vaultActive, cardCapture]` pair. Previously these (consumer callbacks like\n // `onComplete`/`onError`/`onDecline`, plus `resolvedAccount`/AVS)\n // were effect deps; an integration passing inline callbacks re-rendered the\n // parent mid-payment, churning their identity, tearing the effect down, and —\n // because the widget emits `complete` only once — dropping the terminal\n // `onComplete` during the success-overlay hold (buyer stuck on \"PAYMENT\n // SUCCESSFUL\"). Mirrors the ref pattern FloPayCheckout already uses for its\n // own callbacks. Read at event time, so a change never re-subscribes.\n const vaultOutcomeRef = useRef({\n onComplete,\n onError,\n updateError,\n emitDecline,\n resolvedAccount,\n avsConfig,\n avsCheckProp,\n sessionId,\n nonce,\n baseUrl,\n });\n vaultOutcomeRef.current = {\n onComplete,\n onError,\n updateError,\n emitDecline,\n resolvedAccount,\n avsConfig,\n avsCheckProp,\n sessionId,\n nonce,\n baseUrl,\n };\n // One-shot latch: guarantees the terminal `onComplete` fires exactly once for\n // the mounted capture even if the component re-renders or unmounts during the\n // ~1.2s success-overlay hold. A succeeded payment must always reach the\n // consumer, so completion is gated on this latch rather than on effect\n // teardown. Reset when the effect (re)subscribes for a new capture instance.\n const vaultCompletedRef = useRef(false);\n\n // Build the `patchAccountSnapshot` body from the live refs + latest resolved\n // account / AVS context (read from `vaultOutcomeRef` so this stays identity-\n // stable and never re-subscribes the outcome effect). Called from the\n // `submitting` handler to persist the billing snapshot best-effort.\n const buildVaultAccountSnapshot = useCallback(() => {\n const { resolvedAccount, avsConfig, avsCheckProp } = vaultOutcomeRef.current;\n const cc = selectedCountryRef.current || resolvedAccount.country || 'US';\n const stateVisible = avsConfig ? isAVSFieldVisible(avsConfig.state, cc) : false;\n const line1Visible = avsConfig ? isAVSFieldVisible(avsConfig.address_line_1, cc) : false;\n const zipVisible = avsConfig ? isAVSFieldVisible(avsConfig.postal_code, cc) : false;\n const cityVisible = avsConfig ? isAVSFieldVisible(avsConfig.city, cc) : false;\n const line2Visible = avsConfig ? isAVSFieldVisible(avsConfig.address_line_2, cc) : false;\n const derivedState =\n line1Visible && !stateVisible && zipVisible\n ? getStateFromPostalCode(cc, (zipCodeRef.current ?? '').trim())\n : null;\n const stateValue = stateVisible ? stateRef.current : derivedState;\n return {\n accountData: {\n userId: resolvedAccount.userId ?? '',\n email: resolvedAccount.email ?? '',\n firstName: resolvedAccount.firstName ?? '',\n lastName: resolvedAccount.lastName ?? '',\n ...(zipVisible && zipCodeRef.current ? { zip: zipCodeRef.current } : {}),\n ...(cityVisible && cityRef.current ? { city: cityRef.current } : {}),\n ...(stateValue ? { state: stateValue } : {}),\n ...(line1Visible && addressLine1Ref.current\n ? { addressLine1: addressLine1Ref.current }\n : {}),\n ...(line2Visible && addressLine2Ref.current\n ? { addressLine2: addressLine2Ref.current }\n : {}),\n country: cc,\n },\n ...(avsCheckProp !== undefined ? { avsCheck: avsCheckProp } : {}),\n ...(avsConfig\n ? {\n avsConfig: {\n country: isAVSFieldVisible(avsConfig.country, cc),\n postal_code: zipVisible,\n address_line_1: line1Visible,\n address_line_2: line2Visible,\n city: cityVisible,\n state: stateVisible,\n },\n }\n : {}),\n };\n }, []);\n\n // ── Vault submit gate ← client-side AVS validity (sdk#124) ──\n // The hosted widget's submit button lives inside its cross-origin iframe, so\n // the host can only gate it (disable/enable) — it cannot pause or cancel a\n // charge once the button is clicked, and a click landing while the gate is\n // *closed* is silently swallowed by the widget with no way to auto-resubmit on\n // release. That makes an async gate (hold closed → PATCH round-trip → open)\n // unsafe: a buyer (or the /theme single-click preview) who clicks before the\n // round-trip resolves has their click dropped, the widget never POSTs, and no\n // `checkout_transaction_attempt` is ever written — the df4c14ae hang.\n //\n // So we gate purely on the *synchronous* client-side AVS validity. The\n // postcode half of that check now mirrors the backend validator verbatim\n // (`isValidPostalCode` ← `validator@13.15.35`, d1fcf91), so a postcode the\n // server's `PATCH /account` would 400 on is already blocked here, before the\n // button ever enables — no async round-trip needed to enforce it. The account\n // snapshot is persisted best-effort in the `submitting` handler below (which\n // still classifies a 4xx and surfaces it), matching pre-#124 charge behaviour.\n // The adapter re-pushes the latest gate value on `ready`, so a pre-ready push\n // is never lost.\n useEffect(() => {\n if (!vaultActive || !cardCapture) return;\n cardCapture.setSubmitGate?.(avsInvalid);\n }, [vaultActive, cardCapture, avsInvalid]);\n\n // ── Vault widget outcome → consumer callbacks (Model A) ──\n // The hosted widget owns the charge + 3DS and reports a terminal result via\n // `postMessage`; the SDK only relays it to `onComplete` / `onDecline` /\n // `onError`. The widget renders its own status UI, so the SDK does not drive\n // its own processing overlay here. (Until the backend emits these messages,\n // the widget falls back to its own success redirect.)\n useEffect(() => {\n if (!vaultActive || !cardCapture) return;\n // Fresh capture instance → allow a completion again (a new checkout session\n // re-creates `cardCapture`, which is the only way this effect re-runs).\n vaultCompletedRef.current = false;\n // Guards the trailing decline/error overlay *state writes* below from firing\n // after the effect tears down (unmount / dep change). The terminal\n // `onComplete` is deliberately NOT gated on this — it fires once via\n // `vaultCompletedRef` so a succeeded payment always reaches the consumer.\n let cancelled = false;\n // ── Buyer-hits-pay AVS sync (TeamFloPay/backend#823 Gap 5) ──\n // The hosted vault widget emits `submitting` when the buyer clicks the\n // iframe's submit button, *before* it POSTs to PCIVault. The submit gate\n // already let a client-valid address through (client postcode rules mirror\n // the backend validator), so here we persist the billing snapshot in\n // parallel with the charge — see the PATCH below for the best-effort /\n // 4xx-surfacing semantics.\n const offSubmitting = cardCapture.on('submitting', () => {\n // A real submit fired (button was enabled → AVS was valid). From now on,\n // an AVS field that becomes incomplete gets a red outline.\n setHasAttemptedSubmit(true);\n // Drive the SDK's full-component processing overlay (the widget suppresses\n // its own in-iframe overlay) so the \"Processing payment\" state covers the\n // whole hosted card surface.\n setOverlayStatus('processing');\n const { baseUrl, sessionId, nonce, updateError, onError } = vaultOutcomeRef.current;\n if (!sessionId || !nonce) return;\n // Persist the billing snapshot best-effort so the listener (which runs\n // after the PCIVault webhook + DB lookup, ~hundreds of ms later) sees the\n // up-to-date address/AVS when it mints the Stripe PaymentMethod and\n // snapshots into `user_payment_method` / `checkout_transaction_attempts`.\n // This runs in parallel with the widget's charge (the gate already let a\n // client-valid address through), so a 4xx here is surfaced for the buyer's\n // next attempt but cannot cancel the in-flight charge. A transient\n // 5xx/network failure stays silent — the listener falls back to the\n // session baseline.\n void new PaymentAPI(baseUrl)\n .patchAccountSnapshot(sessionId, nonce, buildVaultAccountSnapshot())\n .catch((err: unknown) => {\n if (!isAccountValidationError(err)) return;\n const message =\n err instanceof Error\n ? err.message\n : 'Please check your billing address and try again.';\n updateError(message);\n setOverlayStatus(null);\n onError?.(err instanceof FloPayError ? err : new FloPayError(message, 'api_error'));\n });\n });\n // Terminal outcomes drive the same overlay transitions as non-card methods:\n // success → green check (held `SUCCESS_DELAY`) then onComplete; decline/error\n // → red cross + message (held `ERROR_DELAY`) then the overlay clears, leaving\n // the inline error banner.\n const offComplete = cardCapture.on('complete', async (event) => {\n // Mark completed *before* the success-overlay delay so a remount during it\n // can't clear the cache and POST a duplicate session (double-charge).\n markSessionRecentlyCompleted(event.sessionId ?? vaultOutcomeRef.current.sessionId);\n setOverlayStatus('success');\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));\n // Fire exactly once. NOT gated on `cancelled`: a re-render or unmount\n // during the hold must not swallow a succeeded payment — the widget emits\n // `complete` only once, so a dropped callback is unrecoverable.\n if (vaultCompletedRef.current) return;\n vaultCompletedRef.current = true;\n vaultOutcomeRef.current.onComplete?.({\n status: 'succeeded',\n paymentIntentId: event.intentId,\n checkoutMethod: 'card',\n });\n });\n const offDecline = cardCapture.on('decline', async (event) => {\n const { updateError, emitDecline } = vaultOutcomeRef.current;\n const message = event.message ?? 'Your payment was declined. Please try another card or contact your bank.';\n updateError(message);\n setOverlayStatus('error');\n emitDecline('card', message, event.declineReason ? { declineCode: event.declineReason } : undefined);\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n if (cancelled) return;\n setOverlayStatus(null);\n });\n const offError = cardCapture.on('error', async (event) => {\n const { updateError, onError } = vaultOutcomeRef.current;\n const message = event.message ?? 'There was a problem processing your payment. Please try again.';\n updateError(message);\n setOverlayStatus('error');\n onError?.(new FloPayError(message, 'api_error'));\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n if (cancelled) return;\n setOverlayStatus(null);\n });\n return () => {\n cancelled = true;\n offSubmitting();\n offComplete();\n offDecline();\n offError();\n };\n // Depends only on the stable capture identity: all volatile inputs\n // (consumer callbacks, resolvedAccount, AVS) are read from\n // `vaultOutcomeRef` at event time, so churning them never re-subscribes and\n // never tears down an in-flight terminal outcome. `cardCapture` is\n // re-created only when the session (and thus the widget) changes.\n }, [vaultActive, cardCapture]);\n\n // ── Method partitioning ──\n //\n // Backend now ships `enabledPaymentMethods` per-session (e.g. ['apple_pay',\n // 'cashapp', 'google_pay', 'link', 'sepa_debit']). We partition it into:\n // - `expressMethods`: the subset supported by `ExpressCheckoutElement`\n // (filtered against STRIPE_EXPRESS_METHODS).\n // - `paymentElementMethods`: everything else (Cash App Pay, Affirm, iDEAL,\n // SEPA debit, …) — rendered in the accordion PaymentElement region.\n //\n // PayPal is dropped from the express set when `DirectPayPalButton` owns the\n // PayPal surface (controlled by `gateways.paypal` upstream → `directPaypal`\n // prop here), so the SDK doesn't double-render.\n //\n // Legacy fallback: when the billing API hasn't been upgraded to ship\n // `enabledPaymentMethods`, fall back to the historic\n // `showApplePay`/`showGooglePay` toggle behaviour so existing integrations\n // keep working unchanged.\n const directPaypalConfigured = !!directPaypal?.clientId;\n // `hasEnabledMethodsPayload` distinguishes \"backend shipped the field\" from\n // \"backend shipped the field with at least one entry\". A provided-but-empty\n // array means the new gateway-driven path is in effect with no enabled\n // methods — it must NOT fall back to legacy `showApplePay`/`showGooglePay`\n // behaviour, and PayPal must stay suppressed unless `'paypal'` is in the\n // list (or `directPaypal` is configured separately).\n const hasEnabledMethodsPayload = Array.isArray(enabledPaymentMethods);\n const hasEnabledMethods = hasEnabledMethodsPayload && enabledPaymentMethods.length > 0;\n const paypalEnabled = hasEnabledMethodsPayload && enabledPaymentMethods.includes('paypal');\n const { expressMethods, paymentElementMethods } = useMemo(\n () => partitionStripeMethods(enabledPaymentMethods, {\n excludePaypal: directPaypalConfigured,\n }),\n [enabledPaymentMethods, directPaypalConfigured],\n );\n // Get raw Stripe instance early so we can decide whether PayPal renders\n // separately. `paypalStripeInstance` lives on the dedicated PayPal sub-\n // account when `gateways.stripe.paypalPublishableKey` is set; otherwise\n // PayPal can ride along inside the main wallet ECE.\n const paypalRenderedSeparately = directPaypalConfigured || !!paypalFlopay;\n // Drop PayPal from the main wallet ECE only when something else is going\n // to render it (DirectPayPal or the dedicated PayPal sub-account\n // PayPalButtonInner). When neither is configured, PayPal stays in the\n // express set so Stripe still shows the button on supported envs.\n const expressMethodsForWalletRow = useMemo(\n () => paypalRenderedSeparately\n ? expressMethods.filter((m) => m !== 'paypal')\n : expressMethods,\n [expressMethods, paypalRenderedSeparately],\n );\n const legacyExpressMethods = useMemo(() => {\n const out: string[] = [];\n if (showApplePay) out.push('apple_pay');\n if (showGooglePay) out.push('google_pay');\n return out;\n }, [showApplePay, showGooglePay]);\n // Final list driving WalletButtonInner. New path wins when the backend\n // ships the field; legacy props are used as the fallback only.\n // `hasEnabledMethodsPayload` (not `hasEnabledMethods`) gates the new-vs-legacy\n // switch: a provided-but-empty `enabledPaymentMethods=[]` means \"no methods\n // enabled\" under the new path, not \"fall back to legacy props\".\n const walletExpressMethods = hasEnabledMethodsPayload ? expressMethodsForWalletRow : legacyExpressMethods;\n const showWallets = showStripe && walletExpressMethods.length > 0;\n\n // Currency and amount are fixed for the life of the session, and the backend\n // already drops methods that violate them from `enabledPaymentMethods` (so a\n // USD cart never lists `bancontact`, a sub-$35 cart never lists `affirm`).\n // We therefore do NOT re-filter currency/amount here — the backend is the\n // single source of truth for those.\n //\n // Country is the one axis the SDK must apply itself: the buyer can change\n // their billing country inline via AVS *after* the session was created, so\n // the backend ships a country-agnostic superset plus a per-method country\n // gate (`enabledPaymentMethodCountries`), and we filter the tile row by the\n // buyer's *live* country here (e.g. switching to NL surfaces iDEAL, to BE\n // Bancontact). `selectedCountry` tracks the AVS country select; we fall back\n // to the static `country` prop when AVS isn't shown, and to the SDK's\n // built-in country table for legacy backends that don't send the gate.\n const apmCountry = enableAVS ? selectedCountry : countryProp;\n const paymentElementMethodsForCurrency = useMemo(() => {\n const target = apmCountry?.trim().toUpperCase();\n if (!target) return paymentElementMethods;\n if (!enabledPaymentMethodCountries) {\n return filterStripeMethodsByCountry(paymentElementMethods, apmCountry);\n }\n return paymentElementMethods.filter((method) => {\n const allowed = enabledPaymentMethodCountries[method];\n // A method without an entry (or an empty list) has no country gate.\n return !allowed || allowed.length === 0 || allowed.includes(target);\n });\n }, [paymentElementMethods, apmCountry, enabledPaymentMethodCountries]);\n\n // PaymentElement Elements options use manual payment-method creation so the\n // selected APM can be sent through the session-scoped intent contract.\n // `paymentMethodTypes` is filtered to the non-express portion of the\n // backend-supplied enabled list (and to the methods Stripe accepts for the\n // session currency *and* amount) so the accordion never double-renders the\n // big buttons the wallet row already shows, and never includes a method\n // Stripe will reject.\n //\n // `captureMethod` is intentionally omitted (defaults to `automatic`): most\n // PaymentElement APMs (Cash App Pay, Affirm, Klarna, iDEAL, SEPA debit,\n // Bancontact, EPS, Giropay, …) do not support `manual` capture, and Stripe\n // rejects the entire Elements mount with a 400 on\n // `/v1/elements?type=deferred_intent` (\"Frame not initialized\"). The\n // accordion ends up rendered as an empty `<div class=\"\">` shell. Letting\n // capture default keeps the deferred-intent options accepted for the full\n // set of APMs we partition into this region.\n //\n // `appearance` is forwarded so the PaymentElement iframe picks up the same\n // theme variables (colours, border radius, font family) as the card row.\n // Without this, Stripe falls back to its grey defaults and the accordion\n // looks visually unrelated to the rest of the FloPay surface.\n // Base options for every per-method `<StripeElements>` group mounted by\n // `StripePaymentElementInner` (one per expanded inline form). The child\n // spreads this and tacks on `paymentMethodTypes: [<method>]` per group.\n // The per-method split is what lets each expanded form scope its\n // accordion to a single method without an `elements.update({\n // paymentMethodTypes })` call (which Stripe refuses).\n const paymentElementBaseOptions = useMemo(() => ({\n mode: 'payment' as const,\n amount: amountInCents,\n currency: currency.toLowerCase(),\n paymentMethodCreation: 'manual' as const,\n appearance: paymentElementAppearance,\n }), [amountInCents, currency, paymentElementAppearance]);\n\n // Stripe's PayPal ExpressCheckoutElement breaks inside known in-app browsers\n // and the existing flow gated it on `inAppBrowserDetected`. With the\n // gateway-driven model the renderer decision moves to `gateways.paypal`\n // (DirectPayPalButton when present, Stripe-rendered PayPal otherwise). When\n // backend ships `enabledPaymentMethods`, the in-app-browser gate is no\n // longer consulted — gateway configuration alone drives renderer choice.\n // Legacy backends keep the historic UA-based gate.\n const [paypalLoadState, setPaypalLoadState] = useState<ExpressCheckoutLoadState>('loading');\n const [walletLoadState, setWalletLoadState] = useState<ExpressCheckoutLoadState>('loading');\n const [paymentElementLoadState, setPaymentElementLoadState] = useState<'loading' | 'ready' | 'load_error'>('loading');\n const [directPaypalReady, setDirectPaypalReady] = useState(false);\n const [directPaypalInitializationState, setDirectPaypalInitializationState] =\n useState<DirectPayPalInitializationState>('loading');\n const [inAppBrowserDetected, setInAppBrowserDetected] = useState<boolean>();\n useEffect(() => {\n setInAppBrowserDetected(isInAppBrowser());\n }, []);\n // When the backend ships `enabledPaymentMethods`, the presence/absence of\n // `'paypal'` in that list decides PayPal visibility — a non-empty list that\n // omits `'paypal'` must suppress PayPal even if `paypalFlopay` is configured.\n // Only fall back to the legacy in-app-browser gate when no payload was sent\n // at all. `directPaypal` overrides both paths.\n const shouldShowPayPal = showPayPal\n && (directPaypalConfigured\n || (hasEnabledMethodsPayload\n ? paypalEnabled\n : inAppBrowserDetected === false));\n const shouldShowWallets = showStripe && showWallets;\n const shouldRenderDirectPayPal = shouldShowPayPal && directPaypalConfigured;\n const directPaypalUnavailable = directPaypalInitializationState === 'retrying'\n || directPaypalInitializationState === 'exhausted';\n const shouldRenderStripePayPal = shouldShowPayPal\n && !!paypalStripeInstance\n && (!directPaypalConfigured || directPaypalUnavailable);\n const shouldRenderWallets = shouldShowWallets && !!stripeInstance;\n // Suppress the entire PaymentElement region when the currency filter empties\n // the list — Stripe Elements won't mount with `paymentMethodTypes: []` and\n // we'd otherwise paint a blank divider row.\n const shouldRenderPaymentElement = showStripe\n && hasEnabledMethods\n && paymentElementMethodsForCurrency.length > 0\n && !!stripeInstance;\n const shouldDisplayPayPalRow = shouldRenderDirectPayPal && !directPaypalUnavailable\n ? directPaypalReady\n : shouldRenderStripePayPal && isExpressCheckoutRowVisible(paypalLoadState);\n const shouldDisplayWalletRow = shouldRenderWallets && isExpressCheckoutRowVisible(walletLoadState);\n const shouldDisplayPaymentElementRow = shouldRenderPaymentElement && paymentElementLoadState !== 'load_error';\n const expressSurfaceUsable = (state: ExpressCheckoutLoadState) =>\n state === 'loading' || state === 'ready';\n const hasUsableNonCardCapability = shouldRenderDirectPayPal\n || (shouldRenderStripePayPal && expressSurfaceUsable(paypalLoadState))\n || (shouldRenderWallets && expressSurfaceUsable(walletLoadState))\n || (shouldRenderPaymentElement && paymentElementLoadState !== 'load_error');\n\n // ── Boot-time validation: nothing to render ──\n //\n // Both `showStripe` and `showPayPal` were turned off (or off + no PayPal\n // gateway present) — there's no payment surface to render. Surface this\n // as `onError` rather than silently rendering an empty form so the bug is\n // caught during integration.\n const validationFiredRef = useRef(false);\n useEffect(() => {\n if (validationFiredRef.current) return;\n if (!showStripe && !showPayPal) {\n validationFiredRef.current = true;\n const err = new FloPayError(\n 'FloPay: both `showStripe` and `showPayPal` are false — nothing to render.',\n 'validation_error',\n );\n onError?.(err);\n updateError(err.message);\n } else if (!showStripe && showPayPal && !directPaypalConfigured && !paypalStripeInstance) {\n validationFiredRef.current = true;\n const err = new FloPayError(\n 'FloPay: `showStripe` is false and no PayPal gateway is configured for this session — nothing to render.',\n 'validation_error',\n );\n onError?.(err);\n updateError(err.message);\n } else if (\n inAppBrowserDetected !== undefined\n && !vaultCapabilityAvailable\n && !hasUsableNonCardCapability\n ) {\n validationFiredRef.current = true;\n const err = new FloPayError(\n 'FloPay: this checkout session has no vault card capability and no usable supported non-card payment methods. Upgrade the billing backend integration.',\n 'api_error',\n { code: 'UnsupportedBackendVaultCapability' },\n );\n onError?.(err);\n updateError(err.message);\n }\n }, [\n showStripe,\n showPayPal,\n directPaypalConfigured,\n paypalStripeInstance,\n inAppBrowserDetected,\n vaultCapabilityAvailable,\n hasUsableNonCardCapability,\n onError,\n updateError,\n ]);\n\n // ── Deprecation warnings ──\n //\n // Emitted once per mount when consumers pass the legacy\n // `showApplePay`/`showGooglePay`/`directPaypal` props alongside the new\n // `enabledPaymentMethods` surface. The legacy props are *not* fed into the\n // new path (`enabledPaymentMethods` wins outright), so silently honouring\n // them would surprise consumers; the warning makes the migration visible.\n const deprecationLoggedRef = useRef(false);\n useEffect(() => {\n if (deprecationLoggedRef.current) return;\n if (!hasEnabledMethods) return;\n const stale: string[] = [];\n if (showApplePay !== true) stale.push('showApplePay');\n if (showGooglePay !== true) stale.push('showGooglePay');\n if (stale.length === 0) return;\n deprecationLoggedRef.current = true;\n // eslint-disable-next-line no-console\n console.warn(\n `[FloPay] ${stale.join(' / ')} ${stale.length === 1 ? 'is' : 'are'} deprecated: ` +\n 'the Apple Pay / Google Pay surface is now driven by ' +\n '`gateways.stripe.enabledPaymentMethods` on the session response. ' +\n 'Remove the legacy prop(s) to silence this warning.',\n );\n }, [hasEnabledMethods, showApplePay, showGooglePay]);\n\n const applyInlineSessionPatch = useCallback(\n (patch: InlineSessionPatch, method: CheckoutButtonMethod): Promise<BeforeButtonClickPatchResult> => {\n if (!checkout.applyInlineSessionPatch) {\n return Promise.resolve({ error: null, sessionId, nonce });\n }\n\n return checkout.applyInlineSessionPatch(patch)\n .then((result) => ({\n error: null,\n sessionId: result.sessionId || sessionId,\n // A freshly bootstrapped session carries its own nonce on\n // `session.clientSecret`. Pair it with the new sessionId so\n // downstream continuation calls don't send the new id with the\n // prior session-bound token.\n nonce: result.session?.clientSecret || nonce,\n }))\n .catch((err) => {\n const floPayErr = normalizeBeforeButtonClickError(method, err);\n updateError(floPayErr.message);\n onError?.(floPayErr);\n return { error: floPayErr, sessionId, nonce };\n });\n },\n [checkout.applyInlineSessionPatch, nonce, onError, sessionId, updateError],\n );\n\n const runBeforeButtonClick = useCallback(async (\n method: CheckoutButtonMethod,\n ): Promise<BeforeButtonClickResult> => {\n if (!onBeforeButtonClick) return { proceed: true };\n\n try {\n const result = await onBeforeButtonClick({\n method,\n sessionId: sessionId || undefined,\n createSession: checkout.inlineSessionDraft,\n });\n\n if (result === false) {\n return { proceed: false };\n }\n\n if (result && typeof result === 'object') {\n if (result.account) {\n setAccountPatch((prev) => ({ ...(prev ?? {}), ...result.account }));\n }\n\n const patchResult = await applyInlineSessionPatch(result, method);\n if (patchResult.error) {\n return {\n proceed: false,\n accountPatch: result.account,\n };\n }\n\n return {\n proceed: true,\n accountPatch: result.account,\n sessionId: patchResult.sessionId,\n nonce: patchResult.nonce,\n };\n }\n\n return { proceed: true };\n } catch (err) {\n const floPayErr = normalizeBeforeButtonClickError(method, err);\n updateError(floPayErr.message);\n onError?.(floPayErr);\n return { proceed: false };\n }\n }, [applyInlineSessionPatch, checkout.inlineSessionDraft, onBeforeButtonClick, onError, sessionId, updateError]);\n\n // ── Internal processPayment + 3DS retry ──\n\n const processPaymentInternal = useCallback(\n async (tokenizedBody: TokenizedBody, overrides?: TokenizedBodyOverrides) => {\n // Prevent double-processing\n if (processingRef.current) return;\n processingRef.current = true;\n\n setProcessing(true);\n setOverlayStatus('processing');\n updateError(null);\n\n const effectiveSessionId = overrides?.sessionId ?? sessionId;\n // Keep the nonce paired with the (possibly overridden) sessionId.\n // `runBeforeButtonClick`/`applyInlineSessionPatch` can bootstrap a\n // fresh session and hand back its nonce; using the stale\n // component-level nonce here would send the new id with the prior\n // session-bound token and 401 on the continuation route.\n const effectiveNonce = overrides?.nonce ?? nonce;\n const effectiveAccount = mergeAccountPatch(resolvedAccount, overrides?.accountPatch);\n const resolvedCompletionPaymentMethodId =\n overrides?.completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);\n const requestTokenizedBody = tokenizedBody.originalPaymentMethodId\n ? { ...tokenizedBody, originalPaymentMethodId: undefined }\n : tokenizedBody;\n\n try {\n const api = new PaymentAPI(baseUrl);\n const response = await api.processPayment(effectiveAccount.userId ?? '', {\n sessionId: effectiveSessionId,\n nonce: effectiveNonce,\n tokenizedData: requestTokenizedBody,\n accountData: {\n userId: effectiveAccount.userId ?? '',\n email: effectiveAccount.email ?? '',\n firstName: effectiveAccount.firstName ?? '',\n lastName: effectiveAccount.lastName ?? '',\n ...(avsConfig ? (() => {\n const c = selectedCountryRef.current;\n const stateVisible = isAVSFieldVisible(avsConfig.state, c);\n const line1Visible = isAVSFieldVisible(avsConfig.address_line_1, c);\n const zipVisible = isAVSFieldVisible(avsConfig.postal_code, c);\n // When line1 is collected but state is hidden, derive state\n // from the ZIP for US/CA so Stripe AVS still gets a state signal.\n const derivedState = (line1Visible && !stateVisible && zipVisible)\n ? getStateFromPostalCode(c, (zipCodeRef.current ?? '').trim())\n : null;\n const stateValue = stateVisible ? stateRef.current : derivedState;\n return {\n country: c,\n ...(zipVisible && zipCodeRef.current ? { zip: zipCodeRef.current } : {}),\n ...(isAVSFieldVisible(avsConfig.city, c) && cityRef.current ? { city: cityRef.current } : {}),\n ...(stateValue ? { state: stateValue } : {}),\n ...(line1Visible && addressLine1Ref.current ? { addressLine1: addressLine1Ref.current } : {}),\n ...(isAVSFieldVisible(avsConfig.address_line_2, c) && addressLine2Ref.current ? { addressLine2: addressLine2Ref.current } : {}),\n };\n })() : {}),\n },\n chv,\n // Checkout analytics metadata\n avsCheck: avsCheckProp ?? false,\n checkoutType: checkoutTypeProp,\n checkoutLayout: checkoutLayoutProp,\n // Resolved exposure: which fields were actually shown for the active country.\n // Country-scoped rules (e.g. ['US', 'CA']) are flattened to booleans here.\n avsConfig: avsConfig ? {\n country: isAVSFieldVisible(avsConfig.country, selectedCountryRef.current),\n postal_code: isAVSFieldVisible(avsConfig.postal_code, selectedCountryRef.current),\n address_line_1: isAVSFieldVisible(avsConfig.address_line_1, selectedCountryRef.current),\n address_line_2: isAVSFieldVisible(avsConfig.address_line_2, selectedCountryRef.current),\n city: isAVSFieldVisible(avsConfig.city, selectedCountryRef.current),\n state: isAVSFieldVisible(avsConfig.state, selectedCountryRef.current),\n } : undefined,\n });\n\n if (response.ok) {\n // Mark the session as completed *now*, before the 1.2s success\n // overlay delay below. A bootstrap that re-runs during that delay\n // (real remount, navigation flicker, etc.) would otherwise see the\n // backend status flipped to 'complete', clear the cache, and POST\n // a duplicate session that would then be /process'd with the\n // original PaymentIntent — double-charging the buyer.\n markSessionRecentlyCompleted(effectiveSessionId);\n setOverlayStatus('success');\n // Clear any pending paypal_direct_required retry — process\n // succeeded, so the re-bound retry button is no longer needed.\n setPaypalDirectRetry(null);\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));\n onComplete?.({\n status: 'succeeded',\n paymentIntentId: tokenizedBody.threeDSecureActionResultTokenId,\n paymentMethodId: resolvedCompletionPaymentMethodId,\n checkoutMethod: tokenizedBody.isPaypal ? 'paypal' : 'card',\n });\n return;\n }\n\n const json = await response.json().catch(() => null) as Record<string, unknown> | null;\n\n // PayPal redirect required — backend created a PI that needs PayPal authorization.\n // Confirm the payment which triggers redirect to PayPal. On return, the\n // PayPalButtonInner's resume handler picks up the payment_intent URL params.\n if (json?.type === 'paypal_redirect_required') {\n const secret = json['threeDSecureToken'] as string;\n const savedPmId = (json['paymentMethodId'] as string) || tokenizedBody.id || '';\n if (!flopay || !secret) {\n setOverlayStatus('error');\n updateError('PayPal authorization required but no token provided.');\n return;\n }\n\n try {\n // PayPal PaymentIntents live on the PayPal Stripe account — route\n // the confirmation through the PayPal Stripe instance.\n const paypalStripe = paypalFlopay?.getRawProvider() as Stripe | null;\n if (!paypalStripe) {\n updateError('PayPal is not available.');\n return;\n }\n\n const confirmParams: Record<string, unknown> = {\n return_url: window.location.href,\n };\n if (savedPmId) {\n confirmParams['payment_method'] = savedPmId;\n }\n\n const { error: confirmError } = await paypalStripe.confirmPayment({\n clientSecret: secret,\n confirmParams: confirmParams as { return_url: string },\n redirect: 'if_required',\n });\n\n if (confirmError) {\n setOverlayStatus('error');\n const message = confirmError.message ?? 'PayPal payment failed.';\n updateError(message);\n emitDecline('paypal', message, {\n code: confirmError.code,\n });\n }\n } catch (err) {\n setOverlayStatus('error');\n updateError(err instanceof Error ? err.message : 'PayPal authorization failed.');\n }\n return;\n }\n\n // Direct PayPal retry — backend created a fresh PayPal order\n // (typically after a failed inline-session reuse) and wants the SDK\n // to relaunch the PayPal popup against that order id. Re-binds the\n // existing DirectPayPalButton via `paypalDirectRetry` state; the\n // buyer clicks the same button again, PayPal opens with the new\n // order, and onApprove fires another /process call. Bounded to 2\n // retries so a misconfigured backend can't trap the buyer.\n if (json?.type === 'paypal_direct_required') {\n const orderId = json['orderId'] as string | undefined;\n if (!orderId) {\n setOverlayStatus('error');\n updateError('PayPal retry required but no order id provided.');\n return;\n }\n const prevAttempts = paypalDirectRetryRef.current?.attempts ?? 0;\n if (prevAttempts >= 2) {\n setOverlayStatus('error');\n updateError('PayPal payment could not be completed after multiple attempts.');\n emitDecline('paypal', 'paypal_direct_required retry limit exceeded');\n return;\n }\n // The order id changes DirectPayPalButton's key and starts a fresh\n // provider lifecycle. Reset the parent-owned visibility state in\n // the same render so a stale exhausted fallback cannot remain next\n // to the newly mounted Direct PayPal loading surface.\n setDirectPaypalReady(false);\n setDirectPaypalInitializationState('loading');\n setPaypalDirectRetry({ orderId, attempts: prevAttempts + 1 });\n // Hide the processing overlay so the buyer can see and act on the\n // re-bound PayPal button. Don't emitDecline — this isn't a decline.\n setOverlayStatus(null);\n return;\n }\n\n setOverlayStatus('error');\n const message = (json?.message as string) ?? 'Payment failed. Please try again.';\n updateError(message);\n emitDecline(tokenizedBody.isPaypal ? 'paypal' : 'card', message, {\n code: (json?.code ?? json?.gatewayErrorCode) as string | undefined,\n declineCode: (json?.declineCode ?? json?.gatewayDeclineReason) as string | undefined,\n });\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n } catch (err) {\n setOverlayStatus('error');\n updateError(err instanceof Error ? err.message : 'An unexpected error occurred');\n await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));\n } finally {\n setProcessing(false);\n setOverlayStatus(null);\n processingRef.current = false;\n }\n },\n [baseUrl, sessionId, nonce, resolvedAccount, resolvedBillingName, chv, flopay, paypalFlopay, onComplete, onError, updateError, emitDecline],\n );\n\n const dispatchTokenizedBody = useCallback(\n (tokenizedBody: TokenizedBody, overrides?: TokenizedBodyOverrides) => {\n if (onTokenizedBody) {\n onTokenizedBody(tokenizedBody);\n } else {\n processPaymentInternal(tokenizedBody, overrides);\n }\n },\n [onTokenizedBody, processPaymentInternal],\n );\n\n // ── Stripe resume (Cash App Pay / Klarna / iDEAL / Bancontact / …) ──\n //\n // Method-agnostic handler for the buyer returning from any Stripe\n // redirect-based payment method. The PaymentElement region writes its\n // tokenization state to `STRIPE_RESUME_KEY` (or the legacy\n // `flopay_wallet_resume` for back-compat with old SDK builds) *before*\n // calling `confirmPayment`, then we verify the PI status on return.\n //\n // Two gates before we hand off to /process — both required to avoid the\n // class of bugs where the SDK marches to /success on an uncharged PI:\n //\n // 1. **URL params must be present.** Stripe redirects buyers back with\n // `payment_intent` / `payment_intent_client_secret` / `redirect_status`\n // on the query string. If those are missing — the buyer hit back, the\n // auth tab was closed, or this is just a normal `/theme` mount — we\n // do nothing, even if `STRIPE_RESUME_KEY` is still in localStorage.\n //\n // 2. **Stripe-side PI status must be successful.** We `retrievePaymentIntent`\n // and only dispatch when the actual status is one of\n // `succeeded` / `requires_capture` / `processing`. A `redirect_status`\n // of `failed`, a buyer who closed the popup without approving (PI stuck\n // at `requires_action`), or a canceled PI all route to `onDecline`.\n //\n // PayPal-direct uses its own resume effect (`PayPalButtonInner`); this\n // handler intentionally excludes the PayPal Stripe sub-account flow to\n // avoid double-dispatch.\n const stripeResumeAttemptedRef = useRef(false);\n useEffect(() => {\n if (typeof window === 'undefined' || stripeResumeAttemptedRef.current) return;\n\n const params = new URLSearchParams(window.location.search);\n const paymentIntentId = params.get('payment_intent');\n const clientSecret = params.get('payment_intent_client_secret');\n const redirectStatus = params.get('redirect_status');\n\n // No `payment_intent` URL param = buyer didn't actually return from a\n // Stripe redirect. Skip even if `STRIPE_RESUME_KEY` is in localStorage:\n // that key is set *before* confirmPayment, so it lives in localStorage\n // between click and authorization. A page reload, navigation, or close\n // of the auth tab would otherwise replay it as a phantom success.\n if (!paymentIntentId || !clientSecret) return;\n\n const readPayload = (key: string) => {\n const raw = localStorage.getItem(key);\n if (!raw) return null;\n try {\n return JSON.parse(raw) as {\n clientSecret?: string;\n sessionId?: string;\n nonce?: string;\n accountPatch?: InlineSessionPatch['account'];\n paymentIntentId?: string;\n paymentMethodId?: string;\n paymentMethodType?: string;\n gateway?: string;\n tokenType?: string;\n tokenId?: string;\n status?: string;\n } | null;\n } catch {\n localStorage.removeItem(key);\n return null;\n }\n };\n\n const payload =\n readPayload(STRIPE_RESUME_KEY) ?? readPayload(LEGACY_WALLET_RESUME_KEY);\n\n // Recover the effective session / nonce / accountPatch persisted by the\n // APM confirm sites before the redirect. Without this, an inline-session\n // bootstrap done inside `runBeforeButtonClick` (which set its own\n // sessionId + nonce) is lost — the post-reload props expose the freshly\n // re-bootstrapped base session — and /process would 401 against the\n // wrong nonce. Mirrors the PayPal resume contract at ~L609-635.\n //\n // Gate on `clientSecret` matching this PI so a stale entry from an\n // abandoned earlier attempt can't retarget the current resume. Legacy\n // payloads (no `clientSecret`) keep the original session-match guard so\n // an old SDK build's writer cannot dispatch against the wrong session.\n let persistedOverrides: TokenizedBodyOverrides | undefined;\n if (payload?.clientSecret) {\n if (payload.clientSecret !== clientSecret) return;\n persistedOverrides = {\n ...(payload.accountPatch ? { accountPatch: payload.accountPatch } : {}),\n ...(payload.sessionId ? { sessionId: payload.sessionId } : {}),\n ...(payload.nonce ? { nonce: payload.nonce } : {}),\n };\n } else if (payload?.sessionId && payload.sessionId !== sessionId) {\n return;\n }\n\n stripeResumeAttemptedRef.current = true;\n localStorage.removeItem(STRIPE_RESUME_KEY);\n localStorage.removeItem(LEGACY_WALLET_RESUME_KEY);\n\n // Strip Stripe's redirect params synchronously before any async work, so\n // a remount that races our async retrieval can't re-enter this effect\n // for the same PI.\n const cleanedUrl = new URL(window.location.href);\n cleanedUrl.searchParams.delete('payment_intent');\n cleanedUrl.searchParams.delete('payment_intent_client_secret');\n cleanedUrl.searchParams.delete('redirect_status');\n window.history.replaceState({}, '', cleanedUrl.toString());\n\n const paymentMethodType =\n payload?.paymentMethodType ?? payload?.tokenType ?? 'card';\n const declineMethod: CheckoutButtonMethod = 'card';\n\n (async () => {\n const rawProvider = flopay?.getRawProvider() as Stripe | null | undefined;\n if (!rawProvider) {\n const message = 'Payment is not available — please refresh and try again.';\n updateError(message);\n emitDecline(declineMethod, message);\n return;\n }\n\n if (redirectStatus === 'failed') {\n const message = 'Payment was declined. Please try again.';\n updateError(message);\n emitDecline(declineMethod, message);\n return;\n }\n\n const { paymentIntent, error } = await rawProvider.retrievePaymentIntent(clientSecret);\n if (error) {\n const message = error.message ?? 'Failed to retrieve payment status.';\n updateError(message);\n emitDecline(declineMethod, message, { code: error.code });\n return;\n }\n\n const piStatus = paymentIntent?.status;\n const successful = isSuccessfulPaymentIntentStatus(piStatus);\n if (!paymentIntent || !successful) {\n const message = piStatus === 'canceled'\n ? 'Payment was canceled.'\n : 'Payment was not completed. Please try again.';\n updateError(message);\n emitDecline(declineMethod, message, { code: piStatus ?? 'missing_payment_intent' });\n return;\n }\n\n const resolvedPmId = typeof paymentIntent.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent.payment_method?.id;\n\n dispatchTokenizedBody({\n id: resolvedPmId ?? payload?.paymentMethodId ?? payload?.tokenId ?? paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n gateway: (payload?.gateway as 'stripe' | 'paypal' | undefined) ?? 'stripe',\n paymentMethodType,\n }, persistedOverrides);\n })();\n }, [sessionId, dispatchTokenizedBody, flopay, updateError, emitDecline]);\n\n // ── Card submit ──\n\n // Card submission is owned by the hosted vault widget. The host form only\n // prevents its native submit behavior; wallet/APM buttons run their own flows.\n const handleSubmit = useCallback((event: React.FormEvent) => {\n event.preventDefault();\n }, []);\n // Vault capture and non-card surfaces initialize from their provider instances.\n const isReady = flopay !== null;\n\n if (!isReady) {\n return <div data-testid=\"flopay-loading\" aria-busy=\"true\">Loading payment form...</div>;\n }\n\n const isButtons = layout === 'buttons';\n // Three-tier fallback for visual styling:\n // 1. `bStyles` (resolved from `buttonsTheme` + `buttonsStyles` override) —\n // the explicit, coherent bundle. Wins when present.\n // 2. `appearance.variables` from FloPayProvider — covers consumers who\n // pass only the non-card Stripe appearance and still expect the React\n // wrapper, AVS inputs, and hosted vault widget to recolor.\n // 3. Hardcoded layout defaults — back-compat for callers passing neither.\n // This is what makes `<FloPayCheckout appearance={THEMES['glass-dark'].appearance} />`\n // produce a visible recolor even before the demo forwards the buttonsLayout half.\n const appearanceVars = appearance?.variables;\n // `appearance.colorBackground` is, in Stripe terms, the *input* surface — not\n // the outer FloPay wrapper. Treat the SDK's default white as \"consumer did\n // not theme the wrapper\" so the historic `#EDEDFF` FloPay tint stays put on\n // the classic preset. Themed bundles supply non-white backgrounds and still\n // flow through to the wrapper as expected.\n const SDK_DEFAULT_WHITES = new Set(['#FFFFFF', '#ffffff', '#fff', '#FFF', 'white']);\n const appearanceColorBg = appearanceVars?.colorBackground;\n const themedWrapperBg =\n appearanceColorBg && !SDK_DEFAULT_WHITES.has(appearanceColorBg) ? appearanceColorBg : undefined;\n const resolvedBorder = bStyles.cardInputBorder ?? (isButtons ? '#e5e7eb' : '#A4A4FF');\n // After the first submit attempt, ring AVS fields that are (re)incomplete —\n // bridges the gap with the widget's own post-submit invalid-card outlines.\n const resolvedDangerColor = appearanceVars?.colorDanger ?? '#dc2626';\n const avsBorderColor = (fieldInvalid: boolean): string =>\n hasAttemptedSubmit && fieldInvalid ? resolvedDangerColor : resolvedBorder;\n // A malformed *or* blank-but-required postcode blocks the vault submit, so\n // `hasAttemptedSubmit` can never flip to reveal it — surface the outline +\n // inline message once the field is blurred (or a submit was attempted) on\n // either card path. `empty` and `malformed` are mutually exclusive, so the\n // inline copy below can branch cleanly between the required/format variants.\n const showPostcodeError =\n (postalCodeState.malformed || postalCodeState.empty) && (zipTouched || hasAttemptedSubmit);\n const zipBorderColor = showPostcodeError\n ? resolvedDangerColor\n : avsBorderColor(invalidAvsFields.zip);\n const cardBg =\n (bStyles.cardFormContainer?.backgroundColor as string)\n ?? themedWrapperBg\n ?? (isButtons ? 'white' : '#EDEDFF');\n const cardInputBg =\n bStyles.cardInputBackground\n ?? appearanceVars?.colorBackground\n ?? 'white';\n const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);\n const hideTitle = isEmptySlotContent(cardTitleContent);\n const nameInputOverrides = bStyles.nameInput;\n const resolvedInputFontSize = bStyles.cardInputFontSize\n ?? toCssSize(nameInputOverrides?.fontSize)\n ?? appearanceVars?.fontSizeBase\n ?? '16px';\n const resolvedInputFontFamily = typeof nameInputOverrides?.fontFamily === 'string'\n ? nameInputOverrides.fontFamily\n : (appearanceVars?.fontFamily ?? 'Poppins, sans-serif');\n const resolvedInputFontWeight = toCssWeight(nameInputOverrides?.fontWeight) ?? 400;\n const resolvedInputColor = bStyles.cardInputColor\n ?? (typeof nameInputOverrides?.color === 'string' ? nameInputOverrides.color : undefined)\n ?? appearanceVars?.colorText\n ?? '#262833';\n const resolvedPlaceholderColor = bStyles.cardInputPlaceholderColor ?? '#9ca3af';\n const resolvedBorderRadius = appearanceVars?.borderRadius ?? '8px';\n // Button corner radius: the `borderRadius` appearance prop takes precedence\n // over a theme bundle's `cardButton.borderRadius`, then the 8px default.\n const buttonBorderRadius =\n (appearanceVars?.borderRadius as string | number | undefined)\n ?? (bStyles.cardButton?.borderRadius as string | number | undefined)\n ?? resolvedBorderRadius;\n // `colorPrimary` drives the submit button background when no buttonsStyles\n // override is supplied. Default keeps the historic FloPay indigo.\n const resolvedPrimaryColor = appearanceVars?.colorPrimary ?? '#4A49FF';\n // Hover background for flo buttons: explicit `colorPrimaryHover` wins, else a\n // slightly darker shade of the primary so every theme gets a real hover.\n const resolvedPrimaryHoverColor = appearanceVars?.colorPrimaryHover ?? darkenHex(resolvedPrimaryColor, 0.12);\n const resolvedTitleColor = appearanceVars?.colorText ?? '#262833';\n const sharedInputTypography: React.CSSProperties = {\n fontSize: resolvedInputFontSize,\n fontFamily: resolvedInputFontFamily,\n fontWeight: resolvedInputFontWeight,\n color: resolvedInputColor,\n WebkitFontSmoothing: 'antialiased',\n MozOsxFontSmoothing: 'grayscale',\n };\n const sharedInputPlaceholderVars = {\n '--flopay-input-placeholder-color': resolvedPlaceholderColor,\n '--flopay-input-font-size': resolvedInputFontSize,\n '--flopay-input-font-family': resolvedInputFontFamily,\n '--flopay-input-font-weight': String(resolvedInputFontWeight),\n } as React.CSSProperties;\n\n // ── Card fields block (shared between both layouts) ──\n const containerOverrides = (bStyles.cardFormContainer ?? {}) as React.CSSProperties;\n const containerPadding = containerOverrides.padding ?? (isButtons ? '0' : '1rem');\n const containerRadius = containerOverrides.borderRadius ?? resolvedBorderRadius;\n // The hosted vault widget (or its loading skeleton). Extracted so it can be\n // rendered *after* the AVS block on the vault path — the AVS fields live in\n // the merchant DOM and must precede the widget iframe in the DOM so the tab\n // order runs AVS (top-left→bottom-right) → card fields, not the reverse.\n const vaultCardFieldsNode =\n cardCapture && vaultMount ? (\n <VaultCardFields\n capture={cardCapture}\n html={vaultMount.html}\n messageToken={vaultMount.messageToken}\n expectedOrigin={vaultMount.expectedOrigin}\n theme={vaultThemeColors}\n onReady={() => {\n // With AVS above the widget, the widget suppresses its own card-number\n // autofocus; the host moves the cursor to the first AVS field\n // (top-left). pcd_form still focuses its card number at an unpredictable\n // time, so rather than race it we bounce the first focus that lands on\n // the vault iframe over to the first AVS field (one-shot, with a\n // fallback in case the iframe never grabs focus).\n if (!avsConfig || typeof document === 'undefined') return;\n const focusFirstAvs = () => {\n const block = document.querySelector('[data-testid=\"flopay-avs-fields\"]');\n const first = block?.querySelector(\n 'input:not([disabled]), select:not([disabled])',\n ) as HTMLElement | null;\n first?.focus();\n };\n // Move the cursor to the first AVS field now. pcd_form loads from a CDN\n // and auto-focuses its card number at an unpredictable later time, so we\n // also watch for focus landing on the vault iframe and bounce it back to\n // the AVS — one-shot, so a later genuine user click on the card isn't\n // hijacked. Focusing an AVS field sticks (pcd_form doesn't re-grab).\n focusFirstAvs();\n let tries = 0;\n const timer = window.setInterval(() => {\n tries += 1;\n const active = document.activeElement;\n const onIframe =\n !!active && active.tagName === 'IFRAME' && active.id === 'flopay_vault_form_iframe';\n if (onIframe) {\n focusFirstAvs();\n window.clearInterval(timer);\n } else if (tries >= 50) {\n window.clearInterval(timer);\n }\n }, 100);\n }}\n onError={(message) => updateError(message)}\n onValidation={(message) => {\n updateError(message);\n // A non-empty inline-validation message after submit means pcd_form\n // rejected the card client-side and won't charge (no terminal event) —\n // drop the processing overlay so the buyer can fix the field. During\n // typing the overlay isn't up, so this is a no-op.\n if (message) setOverlayStatus(null);\n }}\n />\n ) : (\n <div\n data-testid=\"flopay-vault-loading\"\n style={{\n minHeight: 120, display: 'flex', alignItems: 'center', justifyContent: 'center',\n color: '#6b7280', fontSize: 14,\n }}\n >\n Loading secure card form…\n </div>\n );\n const cardFormBlock = (\n <div style={{\n backgroundColor: cardBg, borderRadius: containerRadius,\n ...containerOverrides,\n padding: containerPadding,\n ...sharedInputPlaceholderVars,\n // Flex column (BOTH layouts, so default and buttons>card never diverge) so\n // AVS can be ordered above the vault widget — its submit lives inside the\n // iframe, so AVS can't sit between fields and button; it goes above the\n // card form instead of after the button.\n display: 'flex', flexDirection: 'column',\n }}>\n <style>{`\n .flopay-shared-input::placeholder {\n color: var(--flopay-input-placeholder-color);\n opacity: 1;\n font-size: var(--flopay-input-font-size);\n font-family: var(--flopay-input-font-family);\n font-weight: var(--flopay-input-font-weight);\n }\n `}</style>\n {/* Header: back button + title on same row (buttons layout) */}\n {isButtons && showCardForm && (\n <div style={{\n display: 'flex', alignItems: 'center', padding: '0.75rem 0 0.625rem',\n // Keep the header on top when AVS is ordered above the card on vault.\n order: vaultActive ? -2 : 0,\n }}>\n <button\n type=\"button\"\n onClick={collapseToButtons}\n style={{\n display: 'inline-flex', alignItems: 'center', gap: hideBackButtonLabel ? 0 : '0.5rem',\n background: 'none', border: 'none', cursor: 'pointer',\n color: '#4b5563', fontSize: bStyles.backButtonFontSize ?? '0.85rem', fontWeight: 500,\n padding: 0, transition: 'color 0.15s', flexShrink: 0,\n ...bStyles.backButton as React.CSSProperties,\n }}\n aria-label=\"Back to payment methods\"\n >\n <span style={{\n display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: '50%',\n backgroundColor: '#f3f4f6', transition: 'background-color 0.15s',\n ...bStyles.backButtonIcon as React.CSSProperties,\n }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n </span>\n <BackButtonContentSlot content={cardBackButtonContent} />\n </button>\n {hideTitle ? (\n <div style={{ flex: 1 }} />\n ) : (\n <div style={{\n flex: 1, textAlign: 'center', fontWeight: 600,\n fontSize: bStyles.titleFontSize ?? '1.05rem',\n color: '#262833', paddingRight: 80,\n ...bStyles.title as React.CSSProperties,\n }}>\n <TitleContentSlot content={cardTitleContent} />\n </div>\n )}\n </div>\n )}\n\n {/* Title (default layout only) */}\n {!isButtons && !hideTitle && (\n <div style={{\n textAlign: 'center', fontWeight: 600, fontSize: '1.1rem', padding: '0.5rem 0',\n color: resolvedTitleColor,\n // Keep the title at the very top on the vault path. The card-form slot\n // (-2) and AVS block (-1) are ordered below it but above the card form.\n order: vaultActive ? -3 : 0,\n ...(bStyles.title as React.CSSProperties | undefined),\n }}>\n <TitleContentSlot content={cardTitleContent} />\n </div>\n )}\n\n\n {/* AVS Address Fields — rendered outside the hosted vault widget.\n Addresses aren't PCI-sensitive, so the SDK collects them in the\n merchant DOM and the vault `submitting` handler PATCHes them onto the\n account snapshot. Because the submit lives inside the iframe, these\n fields are ordered above the hosted card form via flex `order`. */}\n {avsConfig && (\n <div style={{ order: vaultActive ? -1 : 0 }} data-testid=\"flopay-avs-fields\">\n {(() => {\n const cc = selectedCountry;\n // AVS field box + input. Rendered identically in both layouts (the\n // buttons layout used to layer the theme's `nameInput`/`*Input` box on\n // top, producing a double-bordered field); the wrapper div *is* the box,\n // the input stays borderless/transparent. `invalid` rings it red once the\n // buyer has attempted submit.\n const inputWrapStyle = (invalid = false): React.CSSProperties => ({\n backgroundColor: cardInputBg, border: `1px solid ${avsBorderColor(invalid)}`,\n borderRadius: resolvedBorderRadius, marginTop: '0.5rem', padding: '10px',\n });\n const inputFieldStyle = (): React.CSSProperties => ({\n width: '100%', border: 'none', outline: 'none', background: 'transparent',\n ...sharedInputTypography,\n });\n const stateOpts = getStateOptions(cc);\n\n return (\n <>\n {/* Street Address (line 1) */}\n {isAVSFieldVisible(avsConfig.address_line_1, cc) && (\n <div style={inputWrapStyle(invalidAvsFields.line1)}>\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-address-line1\"\n name=\"billing-address-line1\"\n placeholder=\"Street Address (e.g. 123 Main St)\"\n autoComplete=\"billing address-line1\"\n value={addressLine1}\n onChange={(e) => { addressLine1Ref.current = e.target.value; setAddressLine1(e.target.value); }}\n disabled={isSubmitting}\n required\n data-testid=\"flopay-address-line1\"\n style={inputFieldStyle()}\n />\n </div>\n )}\n\n {/* Apt, Suite, etc. (line 2) — optional, never gated. */}\n {isAVSFieldVisible(avsConfig.address_line_2, cc) && (\n <div style={inputWrapStyle()}>\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-address-line2\"\n name=\"billing-address-line2\"\n placeholder=\"Apt, Suite, Unit (optional)\"\n autoComplete=\"billing address-line2\"\n value={addressLine2}\n onChange={(e) => { addressLine2Ref.current = e.target.value; setAddressLine2(e.target.value); }}\n disabled={isSubmitting}\n data-testid=\"flopay-address-line2\"\n style={inputFieldStyle()}\n />\n </div>\n )}\n\n {/* City + State row */}\n {(isAVSFieldVisible(avsConfig.city, cc) || isAVSFieldVisible(avsConfig.state, cc)) && (\n <div style={{\n display: 'flex', gap: '0', marginTop: '0.5rem',\n }}>\n {isAVSFieldVisible(avsConfig.city, cc) && (\n <div style={{\n flex: 1, backgroundColor: cardInputBg,\n borderTop: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,\n borderRight: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,\n borderBottom: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,\n borderLeft: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,\n padding: '10px',\n borderTopLeftRadius: resolvedBorderRadius, borderBottomLeftRadius: resolvedBorderRadius,\n ...(isAVSFieldVisible(avsConfig.state, cc) ? { borderRight: 'none', borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius: resolvedBorderRadius }),\n }}>\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-city\"\n name=\"billing-city\"\n placeholder=\"City\"\n autoComplete=\"billing address-level2\"\n value={city}\n onChange={(e) => { cityRef.current = e.target.value; setCity(e.target.value); }}\n disabled={isSubmitting}\n required\n data-testid=\"flopay-city\"\n style={inputFieldStyle()}\n />\n </div>\n )}\n {isAVSFieldVisible(avsConfig.state, cc) && (\n <div style={{\n flex: 1, backgroundColor: cardInputBg, border: `1px solid ${avsBorderColor(invalidAvsFields.state)}`,\n padding: '10px',\n borderTopRightRadius: resolvedBorderRadius, borderBottomRightRadius: resolvedBorderRadius,\n ...(isAVSFieldVisible(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius: resolvedBorderRadius }),\n }}>\n {stateOpts ? (\n <select\n id=\"flopay-billing-state\"\n name=\"billing-state\"\n value={stateValue}\n onChange={(e) => { stateRef.current = e.target.value; setStateValue(e.target.value); }}\n disabled={isSubmitting}\n autoComplete=\"billing address-level1\"\n required\n data-testid=\"flopay-state\"\n style={{ ...inputFieldStyle(), cursor: 'pointer' }}\n >\n <option value=\"\">{getStateLabel(cc)}</option>\n {stateOpts.map((s) => (\n <option key={s.code} value={s.code}>{s.name}</option>\n ))}\n </select>\n ) : (\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-state\"\n name=\"billing-state\"\n placeholder={getStateLabel(cc)}\n autoComplete=\"billing address-level1\"\n value={stateValue}\n onChange={(e) => { stateRef.current = e.target.value; setStateValue(e.target.value); }}\n disabled={isSubmitting}\n required\n data-testid=\"flopay-state\"\n style={inputFieldStyle()}\n />\n )}\n </div>\n )}\n </div>\n )}\n\n {/* Country + ZIP/Postcode row */}\n {(isAVSFieldVisible(avsConfig.country, cc) || isAVSFieldVisible(avsConfig.postal_code, cc)) && (\n <div style={{\n display: 'flex',\n flexDirection: avsLayoutProp === 'column' ? 'column' : 'row',\n gap: avsLayoutProp === 'column' ? '0.5rem' : '0',\n marginTop: '0.5rem',\n }}>\n {isAVSFieldVisible(avsConfig.country, cc) && (\n <div style={{\n flex: avsLayoutProp === 'row' ? 1 : undefined,\n backgroundColor: cardInputBg,\n borderTop: `1px solid ${resolvedBorder}`,\n borderRight: `1px solid ${resolvedBorder}`,\n borderBottom: `1px solid ${resolvedBorder}`,\n borderLeft: `1px solid ${resolvedBorder}`,\n padding: '10px',\n ...(avsLayoutProp === 'row' && isAVSFieldVisible(avsConfig.postal_code, cc)\n ? { borderRadius: '0', borderTopLeftRadius: resolvedBorderRadius, borderBottomLeftRadius: resolvedBorderRadius, borderRight: 'none' }\n : { borderRadius: resolvedBorderRadius }),\n }}>\n <select\n id=\"flopay-billing-country\"\n name=\"billing-country\"\n value={selectedCountry}\n onChange={(e) => {\n selectedCountryRef.current = e.target.value;\n setSelectedCountry(e.target.value);\n onCountryChange?.(e.target.value);\n // Reset state when country changes (different state lists)\n stateRef.current = '';\n setStateValue('');\n }}\n disabled={isSubmitting}\n autoComplete=\"billing country\"\n data-testid=\"flopay-country\"\n style={{ ...inputFieldStyle(), cursor: 'pointer' }}\n >\n {COUNTRY_OPTIONS.map((c) => (\n <option key={c.code} value={c.code}>{c.flag} {c.name}</option>\n ))}\n </select>\n </div>\n )}\n {isAVSFieldVisible(avsConfig.postal_code, cc) && (\n <div style={{\n flex: avsLayoutProp === 'row' ? 1 : undefined,\n backgroundColor: cardInputBg, border: `1px solid ${zipBorderColor}`,\n padding: '10px',\n ...(avsLayoutProp === 'row' && isAVSFieldVisible(avsConfig.country, cc)\n ? { borderRadius: '0', borderTopRightRadius: resolvedBorderRadius, borderBottomRightRadius: resolvedBorderRadius }\n : { borderRadius: resolvedBorderRadius }),\n }}>\n <input\n className=\"flopay-shared-input\"\n id=\"flopay-billing-postal-code\"\n name=\"billing-postal-code\"\n placeholder={getPostalCodeLabel(selectedCountry)}\n autoComplete=\"billing postal-code\"\n value={zipCode}\n onChange={(e) => {\n zipCodeRef.current = e.target.value;\n setZipCode(e.target.value);\n onZipChange?.(e.target.value);\n }}\n onBlur={() => setZipTouched(true)}\n disabled={isSubmitting}\n // Supported locales require a postcode; unsupported /\n // no-postcode locales leave the field optional. Use\n // `required` (not `.supported`) so the field can't be\n // mis-marked required if this JSX is ever hoisted outside\n // the `isAVSFieldVisible` gate — inside it the two agree.\n required={postalCodeState.required}\n aria-invalid={showPostcodeError || undefined}\n aria-describedby={showPostcodeError ? 'flopay-billing-postal-code-error' : undefined}\n data-testid=\"flopay-zip\"\n style={inputFieldStyle()}\n />\n </div>\n )}\n </div>\n )}\n\n {/* Inline postcode feedback, shown before any card capture — both\n variants also block the vault submit gate above. A blank\n required postcode shows the required message; a non-blank but\n malformed one shows the country-specific expected format. */}\n {showPostcodeError && (\n <div\n id=\"flopay-billing-postal-code-error\"\n role=\"alert\"\n data-testid=\"flopay-zip-error\"\n style={{\n marginTop: '0.375rem',\n color: resolvedDangerColor,\n ...sharedInputTypography,\n fontSize: '0.75rem',\n }}\n >\n {postalCodeState.empty\n ? `${getPostalCodeLabel(cc)} is required`\n : malformedPostcodeMessage(cc)}\n </div>\n )}\n </>\n );\n })()}\n </div>\n )}\n\n {/* Optional host content (e.g. the demo's test-cards helper). On the vault\n path it sits at the top of the card form — directly below the title and\n above the AVS block + card iframe — via flex `order` (title -3, slot -2,\n AVS -1, card form 0). */}\n {vaultActive && cardPreFormSlot && (\n <div style={{ order: -2, width: '100%' }}>{cardPreFormSlot}</div>\n )}\n\n {/* Vault widget — rendered after the AVS block so AVS fields precede the\n card iframe in the DOM (tab order: AVS → card). */}\n {vaultActive && vaultCardFieldsNode}\n\n {displayError && (\n <ErrorBanner margin=\"0.75rem 0\" styleOverride={bStyles.errorBanner as React.CSSProperties | undefined}>\n {displayError}\n </ErrorBanner>\n )}\n\n </div>\n );\n\n // ── Parent-side debug panels ──\n //\n // Surface the parent-gate decisions for each gateway on-screen so the most\n // common misconfigurations (session missing `gateways.paypal.publishableKey`,\n // Stripe filtering by currency, empty `enabledPaymentMethods`, …) are\n // visible without opening DevTools. When the gateway is disabled via its\n // `show*` prop we still emit a single-line marker so the absence is\n // obvious — silent omission used to look identical to a debug-off SDK.\n const gateDebugStyle: React.CSSProperties = {\n margin: 0,\n padding: '6px 8px',\n background: '#eef2ff',\n border: '1px solid #c7d2fe',\n borderRadius: 6,\n color: '#111827',\n font: '11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n };\n // Reflect the session-response gateways. The DirectPayPal renderer is named\n // after the PayPal JS SDK path, so its \"enabled\" condition is the presence\n // of `gateways.paypal` upstream — surfaced here as `directPaypal.clientId`.\n // Likewise the Stripe parent gate is \"enabled\" when `gateways.stripe.publishable\\\n // Key` was wired up into a Stripe instance. Without either, the matching\n // renderer cannot run on this session regardless of the `show*` toggles, so\n // the panel collapses to the single \"not enabled\" marker.\n const renderDirectPaypalGateDebug = (testId: string) => {\n if (!debug) return null;\n if (!showPayPal || !directPaypalConfigured) {\n return (\n <pre data-testid={testId} style={gateDebugStyle}>\n {'FloPay/DirectPayPal-debug - not enabled'}\n </pre>\n );\n }\n return (\n <pre data-testid={testId} style={gateDebugStyle}>{[\n 'FloPay/DirectPayPal-debug (parent gate)',\n ` showPayPal=${showPayPal}`,\n ` directPaypalConfigured=${directPaypalConfigured}`,\n ` inAppBrowserDetected=${String(inAppBrowserDetected)}`,\n ` shouldRenderDirectPayPal=${shouldRenderDirectPayPal}`,\n ` shouldRenderStripePayPal=${shouldRenderStripePayPal}`,\n ` hasPaypalStripeInstance=${!!paypalStripeInstance}`,\n ].join('\\n')}</pre>\n );\n };\n const renderStripeGateDebug = (testId: string) => {\n if (!debug) return null;\n if (!showStripe || !stripeInstance) {\n return (\n <pre data-testid={testId} style={gateDebugStyle}>\n {'FloPay/Stripe-debug - not enabled'}\n </pre>\n );\n }\n return (\n <pre data-testid={testId} style={gateDebugStyle}>{[\n 'FloPay/Stripe-debug (parent gate)',\n ` showStripe=${showStripe}`,\n ` currency=${currency}`,\n ` amountInCents=${amountInCents}`,\n ` enabledPaymentMethods: ${JSON.stringify(enabledPaymentMethods ?? [])}`,\n ` enabledPaymentMethodsProvided=${hasEnabledMethodsPayload}`,\n ` hasEnabledMethods=${hasEnabledMethods}`,\n ` expressMethods: ${JSON.stringify(expressMethods)}`,\n ` walletExpressMethods: ${JSON.stringify(walletExpressMethods)}`,\n ` paymentElementMethods: ${JSON.stringify(paymentElementMethods)}`,\n ` paymentElementMethodsForCurrency: ${JSON.stringify(paymentElementMethodsForCurrency)}`,\n ` hasStripeInstance=${!!stripeInstance}`,\n ` shouldRenderWallets=${shouldRenderWallets}`,\n ` shouldRenderPaymentElement=${shouldRenderPaymentElement}`,\n ].join('\\n')}</pre>\n );\n };\n\n // ── APM 2nd-page derivations (shared by both layouts) ──\n // Lifted out of the layout branches so the default-layout (card form\n // visible inline) can also use the 2nd-page drill-in for input-form\n // APMs — without this, default-layout clicks on SEPA / EPS / iDEAL\n // were stuck on the local inline-expansion fallback path.\n const isApmView = viewState === 'apm-expanding' || viewState === 'apm-form' || viewState === 'apm-collapsing';\n const apmAnim = viewState === 'apm-expanding'\n ? `flopay-card-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both`\n : viewState === 'apm-collapsing'\n ? `flopay-card-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both`\n : undefined;\n // Per-method Elements options for the APM 2nd page. Built lazily by\n // method — the group only mounts while `viewState` is in the apm-*\n // family, so switching APMs (back → choose another) tears down the\n // previous Stripe Elements instance cleanly.\n const apmInlineOptions = expandedApmMethod ? {\n ...paymentElementBaseOptions,\n paymentMethodTypes: [expandedApmMethod],\n } as Parameters<typeof StripeElements>[0]['options'] : null;\n\n // ── Buttons layout ──\n if (layout === 'buttons') {\n const isButtonsView =\n viewState === 'buttons' ||\n viewState === 'expanding' ||\n viewState === 'apm-expanding';\n const isCardView = viewState === 'expanding' || viewState === 'card' || viewState === 'collapsing';\n const cardButtonSizing = cardButtonContent === undefined\n ? { boxSizing: 'border-box' as const, height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: '0 1rem' }\n : { padding: '0.9rem 1rem' };\n\n // The buttons panel slides out the same way whether we're going to the\n // card 2nd page or an APM 2nd page — same exit/enter animations so\n // the two drill-ins feel identical.\n const buttonsAnim = (viewState === 'expanding' || viewState === 'apm-expanding')\n ? `flopay-buttons-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both`\n : (viewState === 'collapsing' || viewState === 'apm-collapsing')\n ? `flopay-buttons-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both`\n : undefined;\n\n const cardAnim = viewState === 'expanding'\n ? `flopay-card-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both`\n : viewState === 'collapsing'\n ? `flopay-card-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both`\n : undefined;\n\n return (\n <form onSubmit={handleSubmit} className={className} style={{ position: 'relative' }}>\n <FloPayKeyframes />\n {overlayStatus && <ProcessingOverlay status={overlayStatus} errorMessage={displayError} />}\n\n {/* Container — uses grid overlap so both views can coexist during transition */}\n <div style={{ display: 'grid' }}>\n\n {/* Payment method buttons — always mounted to preserve PayPal/wallet Elements */}\n <div\n data-testid=\"flopay-buttons-panel\"\n aria-hidden={!isButtonsView && !buttonsAnim ? true : undefined}\n style={{\n gridArea: '1 / 1',\n display: 'flex', flexDirection: 'column', gap: '0.5rem',\n // When card form is showing (and not transitioning), hide but keep mounted.\n ...(!isButtonsView && !buttonsAnim ? BUTTONS_PANEL_HIDDEN_STYLE : {}),\n ...(buttonsAnim ? { animation: buttonsAnim, pointerEvents: 'none' as const } : {}),\n }}>\n {renderDirectPaypalGateDebug('flopay-direct-paypal-gate-debug')}\n {renderStripeGateDebug('flopay-stripe-gate-debug')}\n {/* PayPal — Direct PayPal JS SDK when configured, otherwise Stripe-rendered PayPal */}\n {shouldRenderDirectPayPal && directPaypal && (\n <>\n {paypalDirectRetry && (\n <div\n data-testid=\"flopay-paypal-direct-retry-notice\"\n style={{\n padding: '8px 10px',\n background: '#fef3c7',\n border: '1px solid #fcd34d',\n borderRadius: 6,\n color: '#78350f',\n fontSize: 13,\n lineHeight: 1.4,\n }}\n >\n Please confirm your PayPal payment to complete checkout.\n </div>\n )}\n <DirectPayPalButton\n // Force a remount when the retry id changes so PayPal's\n // SDK picks up the new createOrder binding (render()\n // options aren't live-updatable). `key` matches the\n // existingOrderId effect-dep update on the child.\n key={paypalDirectRetry?.orderId ?? 'fresh'}\n sessionId={sessionId}\n nonce={nonce}\n billingApiUrl={resolvedBillingApiUrl}\n email={resolvedAccount.email}\n clientId={directPaypal.clientId}\n environment={directPaypal.environment}\n currency={currency.toUpperCase()}\n isSubscription={isSubscription}\n onTokenizedBody={dispatchTokenizedBody}\n onComplete={onComplete}\n onErrorChange={updateError}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n onButtonClick={onButtonClick}\n runBeforeButtonClick={runBeforeButtonClick}\n isProcessing={isSubmitting}\n onLoadStateChange={setDirectPaypalReady}\n onInitializationStateChange={setDirectPaypalInitializationState}\n session={session ?? null}\n existingOrderId={paypalDirectRetry?.orderId}\n debug={debug}\n />\n </>\n )}\n {shouldRenderStripePayPal && (\n <StripeElements stripe={paypalStripeInstance} options={paypalOptions}>\n <PayPalButtonInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingApiUrl={resolvedBillingApiUrl}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n isProcessing={isSubmitting}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setPaypalLoadState}\n placeholderBorderRadius={buttonBorderRadius}\n />\n </StripeElements>\n )}\n\n {/* Wallets / express methods (Apple Pay / Google Pay / Link / Amazon Pay / Klarna) */}\n {shouldRenderWallets ? (\n <StripeElements stripe={stripeInstance} options={walletOptions}>\n <WalletButtonInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingApiUrl={resolvedBillingApiUrl}\n intentKind={totalAmount > 0 ? 'payment' : 'setup'}\n expressMethods={walletExpressMethods}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setWalletLoadState}\n placeholderBorderRadius={buttonBorderRadius}\n />\n </StripeElements>\n ) : shouldShowWallets ? (\n <div style={{ height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: buttonBorderRadius, background: '#e5e7eb', animation: 'flopay-pulse 1.5s ease-in-out infinite' }} />\n ) : null}\n\n {/* PaymentElement region — Cash App Pay / Affirm / iDEAL / SEPA … */}\n {shouldRenderPaymentElement && (\n <StripePaymentElementInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingName={[resolvedAccount.firstName, resolvedAccount.lastName].filter(Boolean).join(' ').trim() || undefined}\n billingApiUrl={resolvedBillingApiUrl}\n paymentElementMethods={paymentElementMethodsForCurrency}\n stripeInstance={stripeInstance}\n paymentElementBaseOptions={paymentElementBaseOptions}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setPaymentElementLoadState}\n isProcessing={isSubmitting}\n submitButtonColor={resolvedPrimaryColor}\n submitButtonBorderRadius={resolvedBorderRadius}\n submitButtonStyle={bStyles.submitButton as React.CSSProperties | undefined}\n // Input-form methods (SEPA / EPS / iDEAL / Bacs) drill\n // into a 2nd-page panel rendered alongside the card\n // form below. `StripePaymentElementInner` itself only\n // renders the tile-button row; the parent owns the\n // navigation state machine.\n onExpandApm={expandToApm}\n expandedApmMethod={expandedApmMethod}\n themeId={theme}\n // The `buttonAppearance` override is only used as a\n // *fallback* — `STRIPE_METHOD_MATRIX[<method>].theme`\n // takes precedence inside the tile, so brand-styled\n // methods (Cash App green, Klarna pink, …) keep their\n // brand colors regardless of the bundle's `cardButton`\n // styling. Methods with no `theme` entry pick up the\n // bundle's neutral tile here.\n buttonAppearance={{\n backgroundColor: bStyles.cardButton?.backgroundColor as string | undefined,\n borderColor: bStyles.cardInputBorder,\n textColor: bStyles.cardButton?.color as string | undefined,\n borderRadius: buttonBorderRadius,\n }}\n />\n )}\n\n {/* Credit / Debit Card button — gated on vault capability so the\n PayPal-only flow doesn't expose an unusable card option.\n Themed: `derivePrimaryTileStyle` flips the base from white\n + grey border (classic) to a primary-colored fill that\n mirrors the theme's submit/CTA action. */}\n {vaultActive && (\n <button\n type=\"button\"\n onClick={async () => {\n if (isSubmitting) return;\n const beforeClick = await runBeforeButtonClick('card');\n if (!beforeClick.proceed) return;\n onButtonClick?.('card');\n expandToCard();\n }}\n disabled={isSubmitting}\n style={{\n width: '100%',\n ...cardButtonSizing,\n // `bStyles.cardButton` first — supplies the bundle's\n // padding / typography / border-radius — then the\n // primary surface overrides on top, so the card button\n // ends up wearing the *submit* button's colours rather\n // than the bundle's neutral white-tile `cardButton`\n // colours. Without this order flip, every non-classic\n // bundle's `cardButton.backgroundColor` was winning\n // over the primary fill we just derived above it.\n ...bStyles.cardButton as React.CSSProperties,\n ...derivePrimaryTileStyle({\n themeBundle,\n resolvedPrimaryColor,\n resolvedBorderRadius,\n submitButtonStyle: bStyles.submitButton as React.CSSProperties | undefined,\n explicitPrimaryColor: appearanceVars?.colorPrimary as string | undefined,\n }),\n fontSize: bStyles.cardButtonFontSize ?? '0.95rem', fontWeight: 600,\n cursor: isSubmitting ? 'not-allowed' : 'pointer', display: 'flex',\n alignItems: 'center', justifyContent: 'center', gap: '0.625rem',\n transition: 'background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s',\n position: 'relative',\n opacity: isSubmitting ? 0.6 : 1,\n }}\n // Hover on any primary-filled button (themed bundle OR an\n // explicit `colorPrimary` override). The classic white tile\n // with no override keeps its static look. `colorPrimaryHover`\n // (or a derived darker shade) on enter, `colorPrimary` on leave.\n onMouseEnter={(e) => {\n if (!isSubmitting && (themeBundle || appearanceVars?.colorPrimary)) {\n e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;\n }\n }}\n onMouseLeave={(e) => {\n if (themeBundle || appearanceVars?.colorPrimary) e.currentTarget.style.backgroundColor = resolvedPrimaryColor;\n }}\n onMouseDown={(e) => { e.currentTarget.style.transform = 'scale(0.985)'; }}\n onMouseUp={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}\n >\n <CardButtonContentSlot content={cardButtonContent} />\n </button>\n )}\n\n {displayError && viewState === 'buttons' && (\n <ErrorBanner margin=\"0.25rem 0\" styleOverride={bStyles.errorBanner as React.CSSProperties | undefined}>\n {displayError}\n </ErrorBanner>\n )}\n </div>\n\n {/* Card form is available only through the hosted vault widget. */}\n {vaultActive && isCardView && (\n <div style={{\n gridArea: '1 / 1',\n ...(cardAnim ? { animation: cardAnim } : {}),\n ...(viewState === 'collapsing' ? { pointerEvents: 'none' as const } : {}),\n }}>\n {cardFormBlock}\n </div>\n )}\n\n {/* APM 2nd page — mirrors the card-form 2nd page exactly:\n same gridArea, same back-button chrome, same enter/exit\n animations. The only differences are the title (method\n display name) and the body (single-method Stripe\n PaymentElement instead of the split-card fields). */}\n {showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && (\n <div style={{\n gridArea: '1 / 1',\n ...(apmAnim ? { animation: apmAnim } : {}),\n ...(viewState === 'apm-collapsing' ? { pointerEvents: 'none' as const } : {}),\n }}>\n <div style={{\n backgroundColor: cardBg, borderRadius: containerRadius,\n ...containerOverrides,\n padding: containerPadding,\n }}>\n {/* Header: back button + method-name title — pixel-for-\n pixel the same chrome as the card-form header. */}\n <div style={{\n display: 'flex', alignItems: 'center', padding: '0.75rem 0 0.625rem',\n }}>\n <button\n type=\"button\"\n data-testid=\"flopay-apm-back-button\"\n onClick={collapseFromApm}\n style={{\n display: 'inline-flex', alignItems: 'center', gap: hideBackButtonLabel ? 0 : '0.5rem',\n background: 'none', border: 'none', cursor: 'pointer',\n color: '#4b5563', fontSize: bStyles.backButtonFontSize ?? '0.85rem', fontWeight: 500,\n padding: 0, transition: 'color 0.15s', flexShrink: 0,\n ...bStyles.backButton as React.CSSProperties,\n }}\n aria-label=\"Back to payment methods\"\n >\n <span style={{\n display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: '50%',\n backgroundColor: '#f3f4f6', transition: 'background-color 0.15s',\n ...bStyles.backButtonIcon as React.CSSProperties,\n }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n </span>\n <BackButtonContentSlot content={cardBackButtonContent} />\n </button>\n <div style={{\n flex: 1, textAlign: 'center', fontWeight: 600,\n fontSize: bStyles.titleFontSize ?? '1.05rem',\n color: resolvedTitleColor, paddingRight: 80,\n ...bStyles.title as React.CSSProperties,\n }}>\n {`Pay with ${getStripeMethodDisplayName(expandedApmMethod)}`}\n </div>\n </div>\n\n {/* Per-method Elements group: keyed by method so switching\n APMs unmounts the previous group cleanly. */}\n <StripeElements\n key={expandedApmMethod}\n stripe={stripeInstance}\n options={apmInlineOptions}\n >\n <StripeMethodInlineForm\n method={expandedApmMethod}\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingName={[resolvedAccount.firstName, resolvedAccount.lastName].filter(Boolean).join(' ').trim() || undefined}\n billingApiUrl={resolvedBillingApiUrl}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onDecline={onDecline}\n onCancel={collapseFromApm}\n runBeforeButtonClick={runBeforeButtonClick}\n onButtonClick={onButtonClick}\n isProcessing={isSubmitting}\n submitButtonColor={resolvedPrimaryColor}\n submitButtonBorderRadius={resolvedBorderRadius}\n submitButtonStyle={bStyles.submitButton as React.CSSProperties | undefined}\n errorText={displayError}\n />\n </StripeElements>\n </div>\n </div>\n )}\n </div>\n </form>\n );\n }\n\n // ── Default layout ──\n // When an input-form APM is expanded, render *only* its 2nd-page panel\n // (back button + scoped PaymentElement + Pay button) — the wallet row,\n // APM tiles, divider and card form all step aside so the buyer's focus\n // is on completing the inline form. Hitting \"Go back\" restores the\n // normal layout. Same chrome as the buttons-layout 2nd page so the\n // experience is consistent across both layouts.\n if (isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && showStripe) {\n return (\n <form onSubmit={handleSubmit} className={className} style={{ position: 'relative' }}>\n <FloPayKeyframes />\n {overlayStatus && <ProcessingOverlay status={overlayStatus} errorMessage={displayError} />}\n <div style={{\n ...(apmAnim ? { animation: apmAnim } : {}),\n ...(viewState === 'apm-collapsing' ? { pointerEvents: 'none' as const } : {}),\n }}>\n <div style={{\n backgroundColor: cardBg, borderRadius: containerRadius,\n ...containerOverrides,\n padding: containerPadding,\n }}>\n {/* Back-button chrome — same circle icon + theme back-button\n styling as the card form 2nd page in the buttons layout. */}\n <div style={{\n display: 'flex', alignItems: 'center', padding: '0.75rem 0 0.625rem',\n }}>\n <button\n type=\"button\"\n data-testid=\"flopay-apm-back-button-default\"\n onClick={collapseFromApm}\n style={{\n display: 'inline-flex', alignItems: 'center', gap: hideBackButtonLabel ? 0 : '0.5rem',\n background: 'none', border: 'none', cursor: 'pointer',\n color: '#4b5563', fontSize: bStyles.backButtonFontSize ?? '0.85rem', fontWeight: 500,\n padding: 0, transition: 'color 0.15s', flexShrink: 0,\n ...bStyles.backButton as React.CSSProperties,\n }}\n aria-label=\"Back to payment methods\"\n >\n <span style={{\n display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: '50%',\n backgroundColor: '#f3f4f6', transition: 'background-color 0.15s',\n ...bStyles.backButtonIcon as React.CSSProperties,\n }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n </span>\n <BackButtonContentSlot content={cardBackButtonContent} />\n </button>\n <div style={{\n flex: 1, textAlign: 'center', fontWeight: 600,\n fontSize: bStyles.titleFontSize ?? '1.05rem',\n color: resolvedTitleColor, paddingRight: 80,\n ...bStyles.title as React.CSSProperties,\n }}>\n {`Pay with ${getStripeMethodDisplayName(expandedApmMethod)}`}\n </div>\n </div>\n\n <StripeElements\n key={expandedApmMethod}\n stripe={stripeInstance}\n options={apmInlineOptions}\n >\n <StripeMethodInlineForm\n method={expandedApmMethod}\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingName={[resolvedAccount.firstName, resolvedAccount.lastName].filter(Boolean).join(' ').trim() || undefined}\n billingApiUrl={resolvedBillingApiUrl}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onDecline={onDecline}\n onCancel={collapseFromApm}\n runBeforeButtonClick={runBeforeButtonClick}\n onButtonClick={onButtonClick}\n isProcessing={isSubmitting}\n submitButtonColor={resolvedPrimaryColor}\n submitButtonBorderRadius={resolvedBorderRadius}\n submitButtonStyle={bStyles.submitButton as React.CSSProperties | undefined}\n errorText={displayError}\n />\n </StripeElements>\n </div>\n </div>\n </form>\n );\n }\n\n return (\n <form onSubmit={handleSubmit} className={className} style={{ position: 'relative' }}>\n <FloPayKeyframes />\n {overlayStatus && <ProcessingOverlay status={overlayStatus} errorMessage={displayError} />}\n\n {/* Express-checkout row — flex column with `gap` matches the buttons\n layout, so wallet/PayPal/Stripe-PayPal always sit `0.5rem` apart\n regardless of which combination is rendered. Order matches the\n buttons layout: PayPal first, then wallets. */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {renderDirectPaypalGateDebug('flopay-direct-paypal-gate-debug-default')}\n {renderStripeGateDebug('flopay-stripe-gate-debug-default')}\n {/* PayPal — Direct PayPal JS SDK when configured, otherwise Stripe-rendered PayPal */}\n {shouldRenderDirectPayPal && directPaypal && (\n <>\n {paypalDirectRetry && (\n <div\n data-testid=\"flopay-paypal-direct-retry-notice-default\"\n style={{\n padding: '8px 10px',\n background: '#fef3c7',\n border: '1px solid #fcd34d',\n borderRadius: 6,\n color: '#78350f',\n fontSize: 13,\n lineHeight: 1.4,\n }}\n >\n Please confirm your PayPal payment to complete checkout.\n </div>\n )}\n <DirectPayPalButton\n // Remount when retry id changes so PayPal SDK picks up the\n // new createOrder binding.\n key={paypalDirectRetry?.orderId ?? 'fresh'}\n sessionId={sessionId}\n nonce={nonce}\n billingApiUrl={resolvedBillingApiUrl}\n email={resolvedAccount.email}\n clientId={directPaypal.clientId}\n environment={directPaypal.environment}\n currency={currency.toUpperCase()}\n isSubscription={isSubscription}\n onTokenizedBody={dispatchTokenizedBody}\n onComplete={onComplete}\n onErrorChange={updateError}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n onButtonClick={onButtonClick}\n runBeforeButtonClick={runBeforeButtonClick}\n isProcessing={isSubmitting}\n onLoadStateChange={setDirectPaypalReady}\n onInitializationStateChange={setDirectPaypalInitializationState}\n session={session ?? null}\n existingOrderId={paypalDirectRetry?.orderId}\n debug={debug}\n />\n </>\n )}\n {shouldRenderStripePayPal && (\n <StripeElements stripe={paypalStripeInstance} options={paypalOptions}>\n <PayPalButtonInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingApiUrl={resolvedBillingApiUrl}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n isProcessing={isSubmitting}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setPaypalLoadState}\n placeholderBorderRadius={buttonBorderRadius}\n />\n </StripeElements>\n )}\n\n {/* Wallet / express buttons — own Stripe Elements instance */}\n {shouldRenderWallets && (\n <StripeElements stripe={stripeInstance} options={walletOptions}>\n <WalletButtonInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingApiUrl={resolvedBillingApiUrl}\n intentKind={totalAmount > 0 ? 'payment' : 'setup'}\n expressMethods={walletExpressMethods}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n onTechnicalFailure={recoverExternalMethodTechnicalFailure}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setWalletLoadState}\n placeholderBorderRadius={buttonBorderRadius}\n />\n </StripeElements>\n )}\n\n {/* PaymentElement region — non-express APMs (Cash App Pay, Klarna, iDEAL, SEPA, …) */}\n {shouldRenderPaymentElement && (\n <StripePaymentElementInner\n sessionId={sessionId}\n nonce={nonce}\n email={resolvedAccount.email}\n billingName={[resolvedAccount.firstName, resolvedAccount.lastName].filter(Boolean).join(' ').trim() || undefined}\n billingApiUrl={resolvedBillingApiUrl}\n paymentElementMethods={paymentElementMethodsForCurrency}\n stripeInstance={stripeInstance}\n paymentElementBaseOptions={paymentElementBaseOptions}\n onTokenizedBody={dispatchTokenizedBody}\n onErrorChange={updateError}\n onButtonClick={onButtonClick}\n onDecline={onDecline}\n runBeforeButtonClick={runBeforeButtonClick}\n onLoadStateChange={setPaymentElementLoadState}\n isProcessing={isSubmitting}\n submitButtonColor={resolvedPrimaryColor}\n submitButtonBorderRadius={resolvedBorderRadius}\n submitButtonStyle={bStyles.submitButton as React.CSSProperties | undefined}\n themeId={theme}\n // Route input-form APM clicks (SEPA / EPS / iDEAL / Bacs)\n // through the parent's `viewState` machine — same 2nd-page\n // pattern as the buttons-layout, just without the in/out\n // transition since the default layout doesn't pre-render the\n // panel alongside an animated buttons row.\n onExpandApm={expandToApm}\n expandedApmMethod={expandedApmMethod}\n buttonAppearance={{\n backgroundColor: bStyles.cardButton?.backgroundColor as string | undefined,\n borderColor: bStyles.cardInputBorder,\n textColor: bStyles.cardButton?.color as string | undefined,\n borderRadius: buttonBorderRadius,\n }}\n />\n )}\n </div>\n\n {/* Divider between wallet/PayPal buttons and card fields — only when\n the card form is actually going to render. */}\n {vaultActive && (shouldDisplayWalletRow || shouldDisplayPayPalRow || shouldDisplayPaymentElementRow) && (\n <div style={{\n display: 'flex', alignItems: 'center', gap: '0.75rem',\n margin: '0.5rem 0 0.75rem', color: '#999', fontSize: '0.85rem',\n }}>\n <div style={{ flex: 1, height: 1, backgroundColor: '#ddd' }} />\n <span>or pay with card</span>\n <div style={{ flex: 1, height: 1, backgroundColor: '#ddd' }} />\n </div>\n )}\n\n {vaultActive && cardFormBlock}\n </form>\n );\n}\n","import React, { useEffect, useRef } from 'react';\nimport type { CardCaptureAdapter, VaultCardThemeColors } from '@flopay/shared';\n\n/** Props for {@link VaultCardFields}. */\nexport interface VaultCardFieldsProps {\n /**\n * The card-capture adapter (typically `useFloPay().cardCapture()`). Owns\n * injecting + bootstrapping the hosted vault widget. Changing this instance\n * (or {@link VaultCardFieldsProps.html}) remounts the widget.\n */\n capture: CardCaptureAdapter;\n /**\n * Server-rendered hosted vault widget HTML (the session's\n * {@link CheckoutSession.vault} block `html`, or one fetched from\n * `POST /vault/capture`). The widget owns the card fields, submit button,\n * tokenization, charge, and 3DS; this component only injects it.\n */\n html: string;\n /**\n * Per-session integrity token (the vault block's `messageToken`). Forwarded\n * to the adapter so it can reject forged terminal `postMessage` outcomes that\n * omit/mismatch it. Omitted when the backend does not (yet) mint one.\n */\n messageToken?: string;\n /**\n * Exact origin expected for the widget's terminal `postMessage` outcomes\n * (the vault block's `expectedOrigin`). Forwarded to the adapter's origin\n * gate; omitted to skip it.\n */\n expectedOrigin?: string;\n /**\n * Merchant theme colors pushed into the hosted widget so the card form\n * matches the surrounding checkout. Applied live on change (no remount).\n */\n theme?: VaultCardThemeColors;\n /** Inline styles for the container the widget mounts into. */\n containerStyle?: React.CSSProperties;\n /** Fired once the widget is injected and bootstrapping. */\n onReady?: () => void;\n /**\n * Fired with a load/runtime error message from the widget, or `null` when it\n * clears. Wired to the card form's shared error banner. Terminal payment\n * outcomes (`complete` / `decline`) are observed by the parent form directly\n * off the same adapter and are not surfaced here.\n */\n onError?: (message: string | null) => void;\n /**\n * Fired with the widget's inline field-validation message (live, debounced by\n * the widget to changes), or `null` when validation clears. Surfaced in the\n * card form's error banner and the merchant `onError`.\n */\n onValidation?: (message: string | null) => void;\n}\n\n/**\n * Renders the backend-served vault PCI card widget\n * (TeamFloPay/backend#823, Model A). The hosted widget\n * is a self-contained form: PAN / CVC, the submit button, the charge, and 3DS\n * all live inside it. This component only injects the widget HTML through the\n * {@link CardCaptureAdapter} and bridges its `ready` / `error` lifecycle events\n * back to the surrounding card form.\n */\nexport function VaultCardFields({\n capture,\n html,\n messageToken,\n expectedOrigin,\n theme,\n containerStyle,\n onReady,\n onError,\n onValidation,\n}: VaultCardFieldsProps): React.ReactElement {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const onReadyRef = useRef(onReady);\n const onErrorRef = useRef(onError);\n const onValidationRef = useRef(onValidation);\n onReadyRef.current = onReady;\n onErrorRef.current = onError;\n onValidationRef.current = onValidation;\n // Latest theme for the mount path (so a remount re-applies it) without making\n // `theme` a remount trigger — live changes go through the effect below.\n const themeRef = useRef(theme);\n themeRef.current = theme;\n\n // Mount once per capture instance + widget HTML; remount when either changes.\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n let active = true;\n let readyEmitted = false;\n const emitReadyOnce = () => {\n if (!active || readyEmitted) return;\n readyEmitted = true;\n onReadyRef.current?.();\n };\n\n const offReady = capture.on('ready', () => {\n emitReadyOnce();\n });\n const offError = capture.on('error', (event) => {\n onErrorRef.current?.(event.message ?? 'There was a problem loading the secure card form.');\n });\n const offValidation = capture.on('validation', (event) => {\n onValidationRef.current?.(event.message ?? null);\n });\n\n const mountOptions = {\n html,\n ...(messageToken ? { messageToken } : {}),\n ...(expectedOrigin ? { expectedOrigin } : {}),\n ...(themeRef.current ? { theme: themeRef.current } : {}),\n };\n\n capture\n .mount(el, mountOptions)\n .then(() => {\n emitReadyOnce();\n })\n .catch((err: unknown) => {\n if (active) {\n onErrorRef.current?.(\n err instanceof Error ? err.message : 'Failed to load the secure card form.',\n );\n }\n });\n\n return () => {\n active = false;\n offReady();\n offError();\n offValidation();\n capture.unmount();\n };\n }, [capture, html, messageToken, expectedOrigin]);\n\n // Live theme updates — re-skin the mounted widget on a runtime theme switch\n // without a remount. The adapter no-ops until the widget is ready, then its\n // `ready` handler re-pushes the latest theme.\n useEffect(() => {\n if (theme) capture.applyTheme?.(theme);\n }, [capture, theme]);\n\n return (\n <div ref={containerRef} data-testid=\"flopay-vault-card-fields\" style={containerStyle} />\n );\n}\n","import React from 'react';\n\n/**\n * The shared red error banner rendered across the checkout surfaces\n * (`role=\"alert\"`, `data-testid=\"flopay-error\"`). Consolidates what were four\n * copy-pasted inline blocks so the colours, warning icon, and a11y attributes\n * live in one place.\n *\n * - `margin` — per-call spacing (the call sites use `0.75rem 0 0`, `0.75rem 0`,\n * `0.25rem 0`, or none), passed straight to the container.\n * - `icon` — the warning glyph + flex layout. Card-form banners show it; the\n * simpler PayPal-only mode banner does not, so it opts out with `icon={false}`\n * to preserve its original icon-less, non-flex appearance.\n * - `styleOverride` — theme-driven overrides (`bStyles.errorBanner`), applied\n * last so they win, exactly as the inline versions did.\n */\nexport function ErrorBanner({\n children,\n margin,\n icon = true,\n styleOverride,\n}: {\n children: React.ReactNode;\n margin?: string | number;\n icon?: boolean;\n styleOverride?: React.CSSProperties;\n}): React.ReactElement {\n return (\n <div\n role=\"alert\"\n data-testid=\"flopay-error\"\n style={{\n margin,\n padding: '0.625rem 0.875rem',\n background: '#FEF2F2',\n border: '1px solid #FECACA',\n borderRadius: '8px',\n color: '#991B1B',\n fontSize: '0.85rem',\n fontWeight: 600,\n ...(icon ? { display: 'flex', alignItems: 'center', gap: '0.5rem' } : {}),\n ...(styleOverride ?? {}),\n }}\n >\n {icon && (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" style={{ flexShrink: 0 }}>\n <path\n d=\"M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n stroke=\"#DC2626\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n {children}\n </div>\n );\n}\n","// AUTO-GENERATED — do not edit by hand.\n// Source: https://github.com/datatrans/payment-logos @ 6538b978b60523224332031bf4ac267730268abb (assets/apm/*.svg)\n// Regenerate: pnpm --filter @flopay/shared fetch:logos\n//\n// Vendored APM brand logos shipped as sibling .svg assets (not inline JS) so a\n// card-only checkout never ships their bytes. Resolved via new URL(…, import.meta.url)\n// so the consumer's bundler emits + rewrites the asset; the tile renders them in an <img>.\nexport const PAYMENT_METHOD_LOGO_URLS: Record<string, string> = {\n 'alipay': new URL('./payment-logos/alipay.svg', import.meta.url).href,\n 'bancontact': new URL('./payment-logos/bancontact.svg', import.meta.url).href,\n 'blik': new URL('./payment-logos/blik.svg', import.meta.url).href,\n 'eps': new URL('./payment-logos/eps.svg', import.meta.url).href,\n 'giropay': new URL('./payment-logos/giropay.svg', import.meta.url).href,\n 'ideal': new URL('./payment-logos/ideal.svg', import.meta.url).href,\n 'klarna': new URL('./payment-logos/klarna.svg', import.meta.url).href,\n 'p24': new URL('./payment-logos/p24.svg', import.meta.url).href,\n 'sepa_debit': new URL('./payment-logos/sepa_debit.svg', import.meta.url).href,\n 'wechat_pay': new URL('./payment-logos/wechat_pay.svg', import.meta.url).href,\n};\n","import { useContext } from 'react';\nimport type { FloPay, FloPayElements } from '@flopay/js';\nimport type { CheckoutSession, FloPayError } from '@flopay/shared';\nimport { resolveBillingApiUrl } from '@flopay/shared';\nimport { FloPayContext, CheckoutContext } from './context.js';\nimport type { CheckoutContextValue } from './context.js';\n\n/**\n * Returns the current `FloPay` instance, or `null` if the provider\n * is still loading (i.e. the `loadFloPay()` promise has not resolved yet).\n *\n * Must be called within a `<FloPayProvider>`.\n */\nexport function useFloPay(): FloPay | null {\n const ctx = useContext(FloPayContext);\n return ctx.flopay;\n}\n\n/**\n * Returns the Stripe `FloPay` instance dedicated to the Stripe-rendered\n * PayPal fallback, or `null` if PayPal is disabled for this session. Direct\n * PayPal (`gateways.paypal`) does not use this instance.\n *\n * Must be called within a `<FloPayProvider>`.\n */\nexport function usePayPalFloPay(): FloPay | null {\n const ctx = useContext(FloPayContext);\n return ctx.paypalFlopay ?? null;\n}\n\n/**\n * Returns the current `FloPayElements` instance, or `null` if the\n * provider is still loading.\n *\n * Must be called within a `<FloPayProvider>`.\n */\nexport function useElements(): FloPayElements | null {\n const ctx = useContext(FloPayContext);\n return ctx.elements;\n}\n\n/** Checkout state exposed by `useCheckout()`. */\nexport interface CheckoutState {\n session: CheckoutSession | null;\n loading: boolean;\n error: FloPayError | null;\n}\n\n/**\n * Returns the current checkout session state.\n *\n * Must be called within the checkout context rendered by `<FloPayCheckout>`.\n */\nexport function useCheckout(): CheckoutState {\n return useContext(CheckoutContext);\n}\n\n/**\n * Returns the resolved billing API URL from the provider context.\n * Falls back to the default `BILLING_API_URL` constant.\n */\nexport function useBillingApiUrl(): string {\n const ctx = useContext(FloPayContext);\n return ctx.billingApiUrl || resolveBillingApiUrl();\n}\n","import React from 'react';\n\nexport type OverlayStatus = 'processing' | 'success' | 'error';\n\nexport const PROCESSING_OVERLAY_SUCCESS_DELAY_MS = 1200;\nexport const PROCESSING_OVERLAY_ERROR_DELAY_MS = 1500;\n\nexport function ProcessingOverlay({\n status,\n errorMessage,\n}: {\n status: OverlayStatus;\n errorMessage?: string | null;\n}) {\n return (\n <div\n data-testid=\"flopay-processing-overlay\"\n data-status={status}\n role=\"dialog\"\n aria-modal=\"true\"\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.35)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 1000,\n backdropFilter: 'blur(2px)',\n }}\n >\n <div\n style={{\n background: 'white',\n borderRadius: 12,\n padding: '2rem 2.5rem',\n textAlign: 'center',\n boxShadow: '0 8px 32px rgba(0,0,0,0.18)',\n minWidth: 240,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 16,\n }}\n >\n <div style={{ width: 48, height: 48, position: 'relative' }}>\n {status === 'processing' && (\n <svg\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ animation: 'flopay-spin 0.8s linear infinite' }}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"#e5e7eb\" strokeWidth=\"3\" />\n <path d=\"M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z\" fill=\"#4A49FF\" />\n </svg>\n )}\n {status === 'success' && (\n <div style={{ animation: 'flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)' }}>\n <svg width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"11\" fill=\"#22c55e\" />\n <path\n d=\"M7 12.5l3 3 7-7\"\n stroke=\"white\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n strokeDasharray: 20,\n strokeDashoffset: 20,\n animation: 'flopay-draw 0.4s 0.15s ease forwards',\n }}\n />\n </svg>\n </div>\n )}\n {status === 'error' && (\n <div style={{ animation: 'flopay-shake 0.4s ease' }}>\n <svg width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"11\" fill=\"#ef4444\" />\n <path\n d=\"M8 8l8 8M16 8l-8 8\"\n stroke=\"white\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n style={{\n strokeDasharray: 12,\n strokeDashoffset: 12,\n animation: 'flopay-draw 0.3s 0.1s ease forwards',\n }}\n />\n </svg>\n </div>\n )}\n </div>\n <span\n style={{\n fontSize: 14,\n fontWeight: 600,\n letterSpacing: '0.05em',\n color: status === 'success' ? '#16a34a' : status === 'error' ? '#dc2626' : '#374151',\n }}\n >\n {status === 'processing' && 'PROCESSING...'}\n {status === 'success' && 'PAYMENT SUCCESSFUL'}\n {status === 'error' && 'PAYMENT FAILED'}\n </span>\n {status === 'success' && (\n <p\n style={{\n fontSize: 13,\n color: '#6b7280',\n fontWeight: 400,\n maxWidth: 260,\n lineHeight: 1.4,\n margin: 0,\n }}\n >\n You will be automatically redirected, do not close or navigate away from this window.\n </p>\n )}\n {status === 'error' && errorMessage && (\n <p\n style={{\n fontSize: 13,\n color: '#6b7280',\n fontWeight: 400,\n maxWidth: 260,\n lineHeight: 1.4,\n margin: 0,\n }}\n >\n {errorMessage}\n </p>\n )}\n <style>{`\n @keyframes flopay-spin { to { transform: rotate(360deg); } }\n @keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }\n @keyframes flopay-draw { to { stroke-dashoffset: 0; } }\n @keyframes flopay-shake { 0%,100% { transform: translateX(0); } 20%,60% { transform: translateX(-4px); } 40%,80% { transform: translateX(4px); } }\n `}</style>\n </div>\n </div>\n );\n}\n","import type {\n CheckoutAccount,\n CheckoutButtonMethod,\n CheckoutMode,\n CheckoutSession,\n DeclineEvent,\n InlineSessionDraft,\n InlineSessionParams,\n InlineSessionPatch,\n PaymentResult,\n TokenizedBody,\n} from '@flopay/shared';\nimport { FloPayError, isSetupIntentClientSecret } from '@flopay/shared';\n\nexport function mergeInlineSessionPatches(\n base: InlineSessionPatch | undefined,\n patch: InlineSessionPatch | undefined,\n): InlineSessionPatch | undefined {\n if (!patch) return base;\n if (!base) return patch;\n\n return {\n account: { ...(base.account ?? {}), ...(patch.account ?? {}) },\n couponCodes: patch.couponCodes ?? base.couponCodes,\n tagsData: {\n ...(base.tagsData ?? {}),\n ...(patch.tagsData ?? {}),\n },\n utmMetadata: patch.utmMetadata ?? base.utmMetadata,\n };\n}\n\nexport function mergeInlineSessionPatch(\n params: InlineSessionDraft,\n patch: InlineSessionPatch | undefined,\n): InlineSessionDraft {\n if (!patch) return params;\n\n return {\n ...params,\n account: {\n ...params.account,\n ...(patch.account ?? {}),\n },\n couponCodes: patch.couponCodes ?? params.couponCodes,\n tagsData: {\n ...(params.tagsData ?? {}),\n ...(patch.tagsData ?? {}),\n },\n utmMetadata: patch.utmMetadata ?? params.utmMetadata,\n };\n}\n\nexport function buildSyntheticSession(\n params: InlineSessionDraft,\n checkoutModeOverride?: CheckoutMode,\n): CheckoutSession {\n const inputProducts = params.products ?? [\n ...(params.subscriptions ?? []).map((s) => ({\n type: 'subscription' as const,\n code: s.code ?? s.providerPlanId,\n name: s.subscriptionName ?? s.providerPlanName ?? s.code ?? s.providerPlanId ?? null,\n quantity: s.quantity ?? 1,\n totalAmount: s.totalAmount,\n overrideAmount: s.overrideAmount,\n currency: s.currency,\n metadata: s.metadata,\n })),\n ...(params.items ?? []).map((i) => ({\n type: 'item' as const,\n code: i.code ?? i.providerItemId,\n name: i.itemName ?? i.providerItemName ?? i.code ?? i.providerItemId ?? null,\n quantity: i.quantity ?? 1,\n totalAmount: i.totalAmount,\n overrideAmount: i.overrideAmount,\n currency: i.currency,\n metadata: i.metadata,\n })),\n ];\n\n const totalAmount = inputProducts.reduce(\n (sum, p) => sum + ((p.overrideAmount ?? p.totalAmount) ?? 0),\n 0,\n );\n const currency = params.currency\n ?? inputProducts.find((p) => p.currency)?.currency\n ?? 'USD';\n\n return {\n id: '',\n clientSecret: '',\n mode: inputProducts.some((p) => p.type === 'subscription') ? 'subscription' : 'payment',\n amount: Math.round(totalAmount * 100),\n currency,\n status: 'open',\n customer: {\n id: params.account.userId,\n email: params.account.email ?? '',\n firstName: params.account.firstName,\n lastName: params.account.lastName,\n gender: params.account.gender ?? undefined,\n city: params.account.city ?? undefined,\n state: params.account.state ?? undefined,\n country: params.account.country ?? undefined,\n zip: params.account.zip ?? undefined,\n },\n successUrl: params.successUrl,\n cancelUrl: params.cancelUrl,\n checkoutMode: (checkoutModeOverride ?? params.checkoutMode ?? 'full') as CheckoutMode,\n products: inputProducts.map((p, idx) => ({\n uuid: `synthetic-${p.type ?? 'item'}-${idx}`,\n checkoutSessionId: '',\n type: p.type ?? 'item',\n code: p.code,\n name: p.name ?? null,\n quantity: p.quantity ?? 1,\n totalAmount: p.totalAmount,\n overrideAmount: p.overrideAmount ?? null,\n currency: p.currency ?? currency,\n metadata: p.metadata ?? null,\n })),\n };\n}\n\nexport function ensureInlineSessionReady(\n params: InlineSessionDraft,\n): asserts params is InlineSessionParams {\n if (!params.account.email?.trim()) {\n throw new FloPayError(\n 'Email is required before continuing with card checkout.',\n 'validation_error',\n { param: 'createSession.account.email' },\n );\n }\n}\n\nexport function splitFullName(name: string | null | undefined): {\n firstName?: string;\n lastName?: string;\n} {\n const parts = name?.trim().split(/\\s+/).filter(Boolean) ?? [];\n if (parts.length === 0) return {};\n return {\n firstName: parts[0],\n lastName: parts.length > 1 ? parts.slice(1).join(' ') : undefined,\n };\n}\n\nexport function mergeAccountPatch<T extends {\n userId?: string;\n email?: string;\n firstName?: string;\n lastName?: string;\n country?: string | null;\n zip?: string | null;\n}>(\n base: T,\n patch: Partial<CheckoutAccount> | undefined,\n): T {\n if (!patch) return base;\n return {\n ...base,\n ...patch,\n };\n}\n\nexport function buildDeclineEvent(\n method: CheckoutButtonMethod,\n input: string | FloPayError,\n overrides?: {\n code?: string;\n declineCode?: string;\n },\n): DeclineEvent {\n const message = typeof input === 'string' ? input : input.message;\n const code = typeof input === 'string' ? overrides?.code : overrides?.code ?? input.code;\n const declineCode = typeof input === 'string'\n ? overrides?.declineCode\n : overrides?.declineCode ?? input.declineCode;\n\n return {\n method,\n message,\n ...(code ? { code } : {}),\n ...(declineCode ? { declineCode } : {}),\n };\n}\n\nconst FRIENDLY_MESSAGE_OVERRIDES: Array<{ match: RegExp; replacement: string }> = [\n {\n match: /^paypal authorization required\\.?$/i,\n replacement: 'For your additional security, please re-authenticate this payment via PayPal.',\n },\n];\n\nexport function applyFriendlyMessageOverride(message: string | undefined | null): string | undefined {\n if (typeof message !== 'string') return message ?? undefined;\n const trimmed = message.trim();\n if (!trimmed) return message;\n for (const { match, replacement } of FRIENDLY_MESSAGE_OVERRIDES) {\n if (match.test(trimmed)) return replacement;\n }\n return message;\n}\n\n\n/**\n * The Stripe PaymentIntent statuses the checkout treats as a completed charge:\n * `succeeded`, `requires_capture` (manual-capture authorization), and\n * `processing` (async settlement). Centralizes the triad that was inlined —\n * both as a `Set` and as `||` chains — at several confirm sites.\n */\nexport function isSuccessfulPaymentIntentStatus(status: string | null | undefined): boolean {\n return status === 'succeeded' || status === 'requires_capture' || status === 'processing';\n}\n\nexport function mapPayPalIntentStatusToPaymentResult(\n status: string | null | undefined,\n): PaymentResult['status'] {\n if (status === 'succeeded') {\n return 'succeeded';\n }\n\n if (status === 'processing' || status === 'requires_capture') {\n return 'processing';\n }\n\n return 'failed';\n}\n\nexport type StripePaymentIntentLike = {\n id?: string;\n status?: string;\n payment_method?: string | { id?: string | null } | null;\n};\n\ntype PaymentIntentRetriever = {\n retrievePaymentIntent?: (clientSecret: string) => Promise<{\n paymentIntent?: StripePaymentIntentLike | null;\n error?: { message?: string; code?: string };\n }>;\n retrieveSetupIntent?: (clientSecret: string) => Promise<{\n setupIntent?: StripePaymentIntentLike | null;\n error?: { message?: string; code?: string };\n }>;\n};\n\nexport function resolvePaymentIntentPaymentMethodId(\n paymentIntent: StripePaymentIntentLike | null | undefined,\n): string | undefined {\n const paymentMethod = paymentIntent?.payment_method;\n if (typeof paymentMethod === 'string' && paymentMethod.startsWith('pm_')) {\n return paymentMethod;\n }\n if (paymentMethod && typeof paymentMethod === 'object' && typeof paymentMethod.id === 'string') {\n return paymentMethod.id;\n }\n return undefined;\n}\n\nexport async function retrievePaymentIntentFromProvider(\n provider: unknown,\n clientSecret: string,\n): Promise<StripePaymentIntentLike | null> {\n const retriever = provider as PaymentIntentRetriever | null;\n\n // Trial-only / $0 checkouts confirm a SetupIntent. Stripe's\n // retrievePaymentIntent rejects `seti_` secrets, so retrieve the SetupIntent\n // instead — it exposes the same id/status/payment_method fields the caller\n // reads to drive /process.\n if (isSetupIntentClientSecret(clientSecret)) {\n if (!retriever?.retrieveSetupIntent) {\n return null;\n }\n\n const { setupIntent, error } = await retriever.retrieveSetupIntent(clientSecret);\n if (error) {\n throw new FloPayError(error.message ?? 'Failed to retrieve setup intent.', 'api_error', {\n ...(error.code ? { code: error.code } : {}),\n });\n }\n\n return setupIntent ?? null;\n }\n\n if (!retriever?.retrievePaymentIntent) {\n return null;\n }\n\n const { paymentIntent, error } = await retriever.retrievePaymentIntent(clientSecret);\n if (error) {\n throw new FloPayError(error.message ?? 'Failed to retrieve payment intent.', 'api_error', {\n ...(error.code ? { code: error.code } : {}),\n });\n }\n\n return paymentIntent ?? null;\n}\n\n/**\n * Deferred Stripe Elements mode for the wallet / Express Checkout row\n * (Apple Pay, Google Pay).\n *\n * A $0-today cart (free trial) cannot run in `payment` mode: Stripe rejects a\n * `$0` amount with \"amount must be greater than 0\", and the historic\n * `amount: totalAmount || 100` floor surfaced a misleading **$1.00** charge on\n * the wallet sheet. Those carts run in `setup` mode instead — the wallet\n * collects the card for the trial with no amount shown, matching the backend's\n * SetupIntent. Any positive amount keeps `payment` mode with the real total.\n *\n * @param amountInMinorUnits cart total due today, in the smallest currency unit.\n */\nexport function resolveWalletElementsMode(\n amountInMinorUnits: number | undefined,\n): { mode: 'setup' } | { mode: 'payment'; amount: number } {\n if (typeof amountInMinorUnits !== 'number' || !Number.isFinite(amountInMinorUnits) || amountInMinorUnits <= 0) {\n return { mode: 'setup' };\n }\n return { mode: 'payment', amount: amountInMinorUnits };\n}\n\nexport function resolveTokenizedPaymentMethodId(\n tokenizedBody: TokenizedBody | null | undefined,\n): string | undefined {\n const candidates = [\n tokenizedBody?.id,\n tokenizedBody?.originalPaymentMethodId,\n ];\n\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.startsWith('pm_')) {\n return candidate;\n }\n }\n\n return undefined;\n}\n","// Cross-component, cross-remount signal for \"this session was just /process'd\n// successfully and is mid-completion.\" Written synchronously by SplitCardForm\n// (and the saved-payment / auto-mode flows in FloPayCheckout) the moment the\n// `/process` response is OK — *before* the 1.2s success-overlay delay — so a\n// bootstrap that re-runs during the overlay window can detect that the cache\n// hit's `status: 'complete'` is from THIS journey rather than treat it as\n// a stale leftover and POST a duplicate session.\n//\n// Backed by `sessionStorage` rather than module state because:\n// 1. SplitCardForm and FloPayCheckout are different modules; sessionStorage\n// is the cheapest cross-module bus.\n// 2. It survives a real component remount (which resets useRef/useState)\n// without needing a module-level Map.\n// 3. The TTL gives natural staleness — a buyer who genuinely returns to\n// `/checkout` long after a previous successful checkout still gets the\n// \"clear stale cache and POST a fresh session\" path.\n\nconst STORAGE_KEY_PREFIX = 'flopay_recent_completion_';\nconst RECENT_COMPLETION_TTL_MS = 60 * 1000;\n\ninterface PersistedRecentCompletion {\n expiresAt: number;\n}\n\nexport function markSessionRecentlyCompleted(sessionId: string | null | undefined): void {\n if (!sessionId || typeof window === 'undefined') return;\n try {\n const payload: PersistedRecentCompletion = {\n expiresAt: Date.now() + RECENT_COMPLETION_TTL_MS,\n };\n window.sessionStorage.setItem(STORAGE_KEY_PREFIX + sessionId, JSON.stringify(payload));\n } catch {\n // sessionStorage unavailable (private mode etc.); not safety-critical.\n }\n}\n\nexport function wasSessionRecentlyCompleted(sessionId: string | null | undefined): boolean {\n if (!sessionId || typeof window === 'undefined') return false;\n try {\n const raw = window.sessionStorage.getItem(STORAGE_KEY_PREFIX + sessionId);\n if (!raw) return false;\n const parsed = JSON.parse(raw) as PersistedRecentCompletion;\n if (typeof parsed?.expiresAt !== 'number') {\n window.sessionStorage.removeItem(STORAGE_KEY_PREFIX + sessionId);\n return false;\n }\n if (parsed.expiresAt <= Date.now()) {\n window.sessionStorage.removeItem(STORAGE_KEY_PREFIX + sessionId);\n return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Internal heuristic detector for in-app browser / WebView environments where\n * PayPal and digital wallets often fail to initialize.\n *\n * `SplitCardForm` uses this as a proactive signal to avoid mounting\n * unsupported express-checkout rows before Stripe reports availability.\n * Stripe load state still covers the long tail: ad-blockers, new WebViews we\n * haven't seen, and account misconfiguration surfacing as `unavailable`.\n *\n * Tradeoffs:\n * - False positives possible. Some modern WebViews (iOS SFSafariViewController\n * on recent iOS, Chrome Custom Tabs) handle PayPal fine but match these\n * patterns. Card checkout remains available, so we accept it.\n * - False negatives possible. New social-app WebViews ship without us knowing.\n * That's why Stripe's reactive load-state collapse remains in place.\n *\n * SSR-safe: returns `false` when `navigator` is undefined.\n */\nexport function isInAppBrowser(userAgent?: string): boolean {\n const ua = userAgent ?? (typeof navigator !== 'undefined' ? navigator.userAgent : '');\n if (!ua) return false;\n\n // Named in-app browsers — most common offenders.\n // FBAN/FBAV/FB_IAB/FBIOS = Facebook + Messenger.\n // musical_ly/BytedanceWebview/TikTok = TikTok across regions.\n if (/FBAN|FBAV|FB_IAB|FBIOS|Instagram|musical_ly|BytedanceWebview|TikTok/i.test(ua)) {\n return true;\n }\n if (/Twitter|Snapchat|Pinterest|LinkedInApp|Line\\/|MicroMessenger|GSA\\//i.test(ua)) {\n return true;\n }\n\n // Generic Android WebView: Chrome UA with the `; wv)` token.\n if (/Android.*;\\s?wv\\)/.test(ua)) return true;\n\n // Generic iOS WebView: iPhone/iPad/iPod with AppleWebKit but no `Safari/`\n // token. Real Mobile Safari always emits `Safari/` — WebViews don't.\n if (/(iPhone|iPad|iPod).*AppleWebKit(?!.*Safari)/.test(ua)) return true;\n\n return false;\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { loadScript } from '@paypal/paypal-js';\nimport type { PayPalNamespace } from '@paypal/paypal-js';\nimport { PaymentAPI } from '@flopay/js';\nimport type {\n CheckoutButtonMethod,\n CheckoutSession,\n DeclineEvent,\n GatewayEnvironment,\n InlineSessionPatch,\n PaymentResult,\n TokenizedBody,\n} from '@flopay/shared';\nimport {\n FloPayError,\n SDK_VERSION,\n generateIdempotencyKey,\n normalizeGatewayEnvironment,\n} from '@flopay/shared';\nimport { applyFriendlyMessageOverride, buildDeclineEvent } from './checkout-utils.js';\nimport { useFloPay } from './hooks.js';\nimport {\n createTelemetryBridge,\n getFloPayTelemetryBridge,\n} from './telemetry-bridge.js';\nimport type { TelemetryCheckoutContext, TelemetryBridge } from './telemetry-bridge.js';\nimport { invokeMerchantCallback } from './merchant-callback.js';\nimport {\n EXTERNAL_METHOD_CALLBACK_GRACE_MS,\n getProviderDeclineCode,\n getProviderErrorCode,\n isProviderDecline,\n isPopupBlockedError,\n} from './external-method-recovery.js';\n\nconst DEFAULT_BUTTON_HEIGHT = 45;\nconst PAYPAL_INIT_RETRY_DELAY_MS = 1_000;\nconst PAYPAL_RENDER_WATCHDOG_MS = 11_000;\nconst PAYPAL_INIT_ACKNOWLEDGEMENT_HOSTS = [\n 'https://www.paypal.com',\n 'https://www.sandbox.paypal.com',\n] as const;\nconst DIRECT_PAYPAL_RECOVERY_MESSAGE =\n \"We couldn't open PayPal. Try again or choose another payment method.\";\nconst DIRECT_PAYPAL_RECOVERY_ACTION_STYLE: React.CSSProperties = {\n width: '100%',\n minHeight: DEFAULT_BUTTON_HEIGHT,\n margin: '0 0 0.5rem',\n padding: '0.75rem 0.875rem',\n border: '1px solid #2563eb',\n borderRadius: 8,\n background: '#eff6ff',\n color: '#1d4ed8',\n fontSize: '0.95rem',\n fontWeight: 700,\n cursor: 'pointer',\n};\n\ninterface DirectPayPalAttemptContext {\n generation: number;\n surfaceKey: number;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n}\n\nfunction isPayPalInitAcknowledgementTimeout(message: string): boolean {\n return message.includes('No ack for postMessage init()')\n && PAYPAL_INIT_ACKNOWLEDGEMENT_HOSTS.some((host) => message.includes(host))\n && message.includes('10000ms');\n}\n\nfunction buildDirectPayPalRecoveryMessage(popupBlocked: boolean): string {\n return popupBlocked\n ? `${DIRECT_PAYPAL_RECOVERY_MESSAGE} Allow pop-ups for this site, then try again.`\n : DIRECT_PAYPAL_RECOVERY_MESSAGE;\n}\n\n/**\n * Overrides that `SplitCardForm`'s tokenized-body dispatcher uses to apply a\n * `runBeforeButtonClick` patch to the in-flight processPayment call. Kept in\n * sync structurally with `TokenizedBodyOverrides` in `split-card-form.tsx`.\n */\nexport interface DirectPayPalTokenizedOverrides {\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n}\n\n/**\n * Internal handler signature aligned with `SplitCardForm`'s tokenized-body\n * dispatcher. Direct PayPal completes via the backend's process endpoint and\n * never produces a Stripe PaymentIntent, so we still forward a synthetic\n * `TokenizedBody` describing the captured order, optionally with the\n * session/account patch captured at click-time.\n */\nexport type DirectPayPalTokenizedHandler = (\n body: TokenizedBody,\n overrides?: DirectPayPalTokenizedOverrides,\n) => void;\n\n/** Click-time `runBeforeButtonClick` result, structurally compatible with `SplitCardForm`. */\nexport interface DirectPayPalBeforeButtonClickResult {\n proceed: boolean;\n accountPatch?: InlineSessionPatch['account'];\n sessionId?: string;\n nonce?: string;\n}\n\n/**\n * Click-time gate. Mirrors `RunBeforeButtonClick` in `SplitCardForm`: lets the\n * consumer patch the session/account before PayPal creates the order, and lets\n * them abort the click entirely by returning `proceed: false`.\n */\nexport type DirectPayPalRunBeforeButtonClick = (\n method: CheckoutButtonMethod,\n) => Promise<DirectPayPalBeforeButtonClickResult>;\n\nexport type DirectPayPalInitializationState =\n | 'loading'\n | 'retrying'\n | 'ready'\n | 'exhausted';\n\nexport type DirectPayPalTechnicalFailureHandler = (\n method: 'paypal',\n err: unknown,\n options?: { code?: string; popupBlocked?: boolean },\n) => void;\n\nexport interface DirectPayPalButtonProps {\n /** Checkout session ID. */\n sessionId: string;\n /**\n * Session-bound checkout token returned by session creation. Forwarded as\n * `x-checkout-session-token` on every continuation request — required by\n * post-#640 backends. `FloPayCheckout` plumbs this prop automatically.\n */\n nonce?: string;\n /** Billing API base URL. */\n billingApiUrl: string;\n /** Buyer email. */\n email?: string;\n /** PayPal client identifier (`gateways.paypal.publishableKey`). */\n clientId: string;\n /** Gateway environment, drives the sandbox/live SDK script. */\n environment?: GatewayEnvironment;\n /** ISO 4217 currency code. */\n currency: string;\n /** Whether the session is a subscription (drives intent + flow selection). */\n isSubscription: boolean;\n /**\n * If provided, called with the tokenized body once PayPal capture\n * completes. When omitted, the component processes payment internally.\n */\n onTokenizedBody?: DirectPayPalTokenizedHandler;\n /** Called when the full self-contained payment flow succeeds. */\n onComplete?: (result: PaymentResult) => void;\n /** Called when an error occurs. */\n onErrorChange?: (error: string | null) => void;\n /** Decline emitter (mirrors SplitCardForm semantics). */\n onDecline?: (decline: DeclineEvent) => void;\n /** Called for post-click technical failures before PayPal authorization completes. */\n onTechnicalFailure?: DirectPayPalTechnicalFailureHandler;\n /** External processing state. */\n isProcessing?: boolean;\n /** Notify the parent of the loading state for placeholder swapping. */\n onLoadStateChange?: (ready: boolean) => void;\n /** Notify a PayPal-only wrapper about pre-render recovery state. */\n onInitializationStateChange?: (state: DirectPayPalInitializationState) => void;\n /** Disable the automatic retry for a buyer-initiated single manual attempt. */\n allowAutomaticRetry?: boolean;\n /** Tracks button-click for analytics. */\n onButtonClick?: (method: CheckoutButtonMethod) => void;\n /**\n * Click-time gate (runs before PayPal creates the order). When provided, the\n * returned patch is applied to the in-flight create-intent and tokenized\n * dispatch so callers using `onBeforeButtonClick` see the same session/email\n * the Stripe-rendered PayPal flow does.\n */\n runBeforeButtonClick?: DirectPayPalRunBeforeButtonClick;\n /** Backing session — used for self-contained accountData population. */\n session?: CheckoutSession | null;\n /**\n * Pre-existing PayPal Order id (or Subscription id when `isSubscription` is\n * true) to bind the button to. When set, the button skips its usual\n * session-scoped create-intent round-trip on click and feeds this\n * id straight into PayPal's create-order / create-subscription callback.\n *\n * Used by `SplitCardForm`'s `paypal_direct_required` retry path: backend\n * creates a fresh PayPal order after a stalled process attempt and returns\n * its id; the SDK re-renders this button bound to that id so the buyer can\n * confirm with one more click without the backend re-creating the order on\n * each retry.\n *\n * Changing this value remounts the PayPal SDK so the new createOrder\n * binding takes effect (PayPal's render() options aren't live-updatable).\n */\n existingOrderId?: string;\n /** Flo-owned privacy-safe telemetry is enabled by default; set `false` to opt out. */\n telemetry?: boolean;\n /**\n * When true, renders an on-screen lifecycle tracer panel above the button\n * (mount, loadScript, eligibility, render, errors). Intended for debugging\n * in-app browsers (Facebook IAB, etc.) where remote console access is\n * impractical. Off by default — leave disabled in production.\n */\n debug?: boolean;\n}\n\ninterface InstrumentedDirectPayPalButtonProps extends DirectPayPalButtonProps {\n telemetryContext?: TelemetryCheckoutContext;\n}\n\n/**\n * Direct PayPal renderer powered by the official PayPal JS SDK.\n *\n * Renders inside Facebook / Instagram / Meta in-app browsers where Stripe's\n * PayPal ExpressCheckoutElement breaks. Selection between this and the Stripe-\n * rendered PayPal happens at the caller site based on whether the session\n * advertises `gateways.paypal.publishableKey`.\n */\nfunction DirectPayPalButtonImplementation({\n sessionId,\n nonce,\n billingApiUrl,\n email,\n clientId,\n environment,\n currency,\n isSubscription,\n onTokenizedBody,\n onComplete,\n onErrorChange,\n onDecline,\n onTechnicalFailure,\n isProcessing = false,\n onLoadStateChange,\n onInitializationStateChange,\n allowAutomaticRetry = true,\n onButtonClick,\n runBeforeButtonClick,\n session,\n existingOrderId,\n telemetry,\n telemetryContext,\n debug = false,\n}: InstrumentedDirectPayPalButtonProps): React.ReactElement | null {\n const flopay = useFloPay();\n const standaloneTelemetry = useMemo(() => {\n if (flopay) return null;\n const reporter = createTelemetryBridge({\n billingApiUrl,\n sdkPackage: '@flopay/react',\n sdkVersion: SDK_VERSION,\n enabled: telemetry !== false,\n });\n reporter.setCheckoutContext(telemetryContext ?? {});\n reporter.beginCheckout(telemetryContext ?? {});\n return reporter;\n }, [\n billingApiUrl,\n flopay,\n telemetry,\n telemetryContext?.checkoutMode,\n telemetryContext?.layout,\n ]);\n const floPayTelemetry = useMemo(() => getFloPayTelemetryBridge(flopay), [flopay]);\n useEffect(() => () => {\n if (!standaloneTelemetry) return;\n void standaloneTelemetry.flush()\n .catch(() => {})\n .finally(() => standaloneTelemetry.destroy());\n }, [standaloneTelemetry]);\n const telemetrySource = useMemo(() => ({\n error: (input: Parameters<TelemetryBridge['error']>[0]) => {\n if (floPayTelemetry) floPayTelemetry.error(input);\n else standaloneTelemetry?.error(input);\n },\n log: (input: Parameters<TelemetryBridge['log']>[0]) => {\n if (floPayTelemetry) floPayTelemetry.log(input);\n else standaloneTelemetry?.log(input);\n },\n performance: (input: Parameters<TelemetryBridge['performance']>[0]) => {\n if (floPayTelemetry) floPayTelemetry.performance(input);\n else standaloneTelemetry?.performance(input);\n },\n terminal: (input: Parameters<TelemetryBridge['terminal']>[0]) => {\n if (floPayTelemetry) floPayTelemetry.terminal(input);\n else standaloneTelemetry?.terminal(input);\n },\n startTiming: () => floPayTelemetry?.now() ?? standaloneTelemetry?.now() ?? 0,\n elapsed: (startedAt: number) => floPayTelemetry?.elapsed(startedAt)\n ?? Math.max(0, (standaloneTelemetry?.now() ?? startedAt) - startedAt),\n }), [floPayTelemetry, standaloneTelemetry]);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const providerStartedAt = useRef(0);\n const focusTargetRef = useRef<HTMLButtonElement | null>(null);\n const pendingProviderFocusRef = useRef(false);\n const [ready, setReady] = useState(false);\n const [recovering, setRecovering] = useState(false);\n const [renderGeneration, setRenderGeneration] = useState(0);\n const activeRenderGenerationRef = useRef(0);\n const [showRetryFocusTarget, setShowRetryFocusTarget] = useState(false);\n const automaticRetryUsedRef = useRef(false);\n const initializationFailureLoggedRef = useRef(false);\n // `failed` flips to true when PayPal can't load/render at all — SDK script\n // failure, ineligibility, render rejection, or a zoid lifecycle teardown.\n // It hides the loading placeholder (and the whole row) so users don't see\n // a perpetual skeleton when PayPal is unavailable.\n const [failed, setFailed] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const baseUrl = useMemo(() => billingApiUrl.replace(/\\/+$/, ''), [billingApiUrl]);\n const initializationConfigKey = useMemo(\n () => JSON.stringify([\n baseUrl,\n clientId,\n currency,\n environment ?? '',\n isSubscription,\n sessionId,\n existingOrderId ?? '',\n ]),\n [baseUrl, clientId, currency, environment, existingOrderId, isSubscription, sessionId],\n );\n const initializationConfigKeyRef = useRef(initializationConfigKey);\n const initializationConfigChanged =\n initializationConfigKeyRef.current !== initializationConfigKey;\n\n // Optional on-screen lifecycle tracer, gated by the `debug` prop. Each\n // lifecycle stage appends a line. Use this for IAB debugging (Facebook,\n // Instagram, TikTok, etc.) where console access is impractical. When\n // `debug` is false the writes are no-ops, so there's no state churn or\n // memory cost in production.\n const [debugLines, setDebugLines] = useState<string[]>([]);\n const appendDebug = (line: string) => {\n if (!debug) return;\n setDebugLines((prev) => [...prev, `${new Date().toISOString().slice(11, 23)} ${line}`]);\n };\n\n // Ref-pin every callback so the render effect below can read the latest\n // handler without listing them as dependencies. Without this, an unstable\n // parent callback (e.g. an inline `onTokenizedBody={(body) => …}`) re-fires\n // the effect on every render, which tears down PayPal's buttons mid-render\n // and surfaces as \"Detected container element removed from DOM\".\n const onTokenizedBodyRef = useRef(onTokenizedBody);\n const onCompleteRef = useRef(onComplete);\n const onErrorChangeRef = useRef(onErrorChange);\n const onDeclineRef = useRef(onDecline);\n const onTechnicalFailureRef = useRef(onTechnicalFailure);\n const onButtonClickRef = useRef(onButtonClick);\n const onLoadStateChangeRef = useRef(onLoadStateChange);\n const onInitializationStateChangeRef = useRef(onInitializationStateChange);\n const runBeforeButtonClickRef = useRef(runBeforeButtonClick);\n const sessionRef = useRef(session);\n const emailRef = useRef(email);\n const nonceRef = useRef(nonce);\n // Captures the latest `runBeforeButtonClick` patch so the in-flight\n // create-intent and tokenized dispatch can use the patched sessionId/nonce/email\n // even though the PayPal SDK callbacks closed over the original props at\n // mount-time. Cleared on cancel/teardown to avoid stale patches leaking into\n // a later click.\n const beforeClickRef = useRef<DirectPayPalAttemptContext | null>(null);\n const attemptGenerationRef = useRef(0);\n const attemptRef = useRef<{\n generation: number;\n timer: ReturnType<typeof setTimeout> | null;\n yieldedControl: boolean;\n } | null>(null);\n const invalidatedAttemptGenerationRef = useRef<number | null>(null);\n const attemptContextBySurfaceRef = useRef(new Map<number, DirectPayPalAttemptContext>());\n const approvalContextByTokenRef = useRef(new Map<string, DirectPayPalAttemptContext>());\n const componentMountedRef = useRef(false);\n useEffect(() => {\n componentMountedRef.current = true;\n return () => {\n componentMountedRef.current = false;\n };\n }, []);\n useEffect(() => { onTokenizedBodyRef.current = onTokenizedBody; }, [onTokenizedBody]);\n useEffect(() => { onCompleteRef.current = onComplete; }, [onComplete]);\n useEffect(() => { onErrorChangeRef.current = onErrorChange; }, [onErrorChange]);\n useEffect(() => { onDeclineRef.current = onDecline; }, [onDecline]);\n useEffect(() => { onTechnicalFailureRef.current = onTechnicalFailure; }, [onTechnicalFailure]);\n useEffect(() => { onButtonClickRef.current = onButtonClick; }, [onButtonClick]);\n useEffect(() => { onLoadStateChangeRef.current = onLoadStateChange; }, [onLoadStateChange]);\n useEffect(() => {\n onInitializationStateChangeRef.current = onInitializationStateChange;\n }, [onInitializationStateChange]);\n useEffect(() => { runBeforeButtonClickRef.current = runBeforeButtonClick; }, [runBeforeButtonClick]);\n useEffect(() => { sessionRef.current = session; }, [session]);\n useEffect(() => { emailRef.current = email; }, [email]);\n useEffect(() => { nonceRef.current = nonce; }, [nonce]);\n useEffect(() => { activeRenderGenerationRef.current = renderGeneration; }, [renderGeneration]);\n useEffect(() => {\n if (showRetryFocusTarget) focusTargetRef.current?.focus();\n }, [showRetryFocusTarget, renderGeneration]);\n\n const focusRetryTarget = useCallback(() => {\n window.setTimeout(() => {\n focusTargetRef.current?.focus();\n }, 0);\n }, []);\n\n const remountPayPalButtons = useCallback(() => {\n setReady(false);\n setRenderGeneration((current) => current + 1);\n }, []);\n\n const focusPayPalSurface = useCallback(() => {\n setShowRetryFocusTarget(false);\n const target = containerRef.current?.querySelector<HTMLElement>(\n 'iframe, button, [tabindex]:not([tabindex=\"-1\"])',\n );\n (target ?? containerRef.current)?.focus?.();\n }, []);\n useEffect(() => {\n if (!ready || !pendingProviderFocusRef.current) return;\n pendingProviderFocusRef.current = false;\n focusPayPalSurface();\n }, [focusPayPalSurface, ready, renderGeneration]);\n\n const notifyTechnicalFailure = useCallback((\n err: unknown,\n options?: { code?: string; popupBlocked?: boolean },\n ) => {\n const handler = onTechnicalFailureRef.current;\n if (handler) {\n handler('paypal', err, options);\n return;\n }\n onErrorChangeRef.current?.(\n buildDirectPayPalRecoveryMessage(options?.popupBlocked ?? isPopupBlockedError(err)),\n );\n }, []);\n\n const clearAttemptTimer = () => {\n if (attemptRef.current?.timer) {\n clearTimeout(attemptRef.current.timer);\n attemptRef.current.timer = null;\n }\n };\n const startAttempt = () => {\n clearAttemptTimer();\n const generation = attemptGenerationRef.current + 1;\n attemptGenerationRef.current = generation;\n invalidatedAttemptGenerationRef.current = null;\n attemptRef.current = { generation, timer: null, yieldedControl: false };\n setShowRetryFocusTarget(false);\n return generation;\n };\n const finishAttempt = (generation?: number) => {\n if (generation !== undefined && attemptRef.current?.generation !== generation) return false;\n clearAttemptTimer();\n attemptRef.current = null;\n invalidatedAttemptGenerationRef.current = null;\n return true;\n };\n const invalidateAttempt = (options?: {\n generation?: number;\n remount?: boolean;\n showRetry?: boolean;\n focus?: boolean;\n }) => {\n const generation =\n options?.generation ?? attemptRef.current?.generation ?? attemptGenerationRef.current;\n if (!options?.generation || attemptRef.current?.generation === generation) {\n clearAttemptTimer();\n attemptRef.current = null;\n }\n invalidatedAttemptGenerationRef.current = generation;\n if (options?.showRetry) setShowRetryFocusTarget(true);\n if (options?.remount) remountPayPalButtons();\n if (options?.focus !== false) focusRetryTarget();\n };\n const isAttemptActive = (generation: number) => (\n attemptRef.current?.generation === generation\n && invalidatedAttemptGenerationRef.current !== generation\n );\n const armMissingCallbackRecovery = (attempt: NonNullable<typeof attemptRef.current>) => {\n if (typeof document !== 'undefined' && document.visibilityState !== 'visible') return;\n\n clearAttemptTimer();\n attempt.timer = setTimeout(() => {\n if (attemptRef.current?.generation !== attempt.generation) return;\n attemptRef.current = null;\n invalidatedAttemptGenerationRef.current = attempt.generation;\n notifyTechnicalFailure(\n new Error('External payment method returned without a terminal callback.'),\n { code: 'external_method_missing_terminal_callback' },\n );\n setShowRetryFocusTarget(true);\n remountPayPalButtons();\n focusRetryTarget();\n }, EXTERNAL_METHOD_CALLBACK_GRACE_MS);\n };\n const scheduleMissingCallbackRecovery = () => {\n const attempt = attemptRef.current;\n if (!attempt?.yieldedControl) return;\n armMissingCallbackRecovery(attempt);\n };\n const markAttemptYieldedControl = () => {\n const attempt = attemptRef.current;\n if (!attempt) return;\n attempt.yieldedControl = true;\n clearAttemptTimer();\n };\n const registerApprovalContext = (token: string) => {\n const context = beforeClickRef.current;\n if (context) {\n approvalContextByTokenRef.current.set(token, context);\n }\n return token;\n };\n useEffect(() => {\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'visible') {\n scheduleMissingCallbackRecovery();\n } else {\n markAttemptYieldedControl();\n }\n };\n document.addEventListener('visibilitychange', handleVisibilityChange);\n window.addEventListener('focus', scheduleMissingCallbackRecovery);\n window.addEventListener('blur', markAttemptYieldedControl);\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n window.removeEventListener('focus', scheduleMissingCallbackRecovery);\n window.removeEventListener('blur', markAttemptYieldedControl);\n clearAttemptTimer();\n };\n }, []);\n\n useEffect(() => {\n if (initializationConfigKeyRef.current === initializationConfigKey) return;\n initializationConfigKeyRef.current = initializationConfigKey;\n automaticRetryUsedRef.current = false;\n initializationFailureLoggedRef.current = false;\n setReady(false);\n setRecovering(false);\n setFailed(false);\n onInitializationStateChangeRef.current?.('loading');\n }, [initializationConfigKey]);\n\n useEffect(() => {\n // Parent's `directPaypalReady` drives the divider visibility — keep it\n // false while we're still trying, true once PayPal is interactive, and\n // false again if we've definitively failed.\n invokeMerchantCallback(() => onLoadStateChangeRef.current?.(ready && !failed));\n }, [ready, failed]);\n\n // Collapse FloPay's `stage`/`production` aliases down to the gateway-native\n // `sandbox`/`live` pair PayPal's SDK actually understands. Done up-front so\n // every downstream check (the debug trace, the loadScript options, the\n // dataNamespace branch) sees a single canonical value.\n const normalizedEnv = normalizeGatewayEnvironment(environment);\n\n useEffect(() => {\n // FloPay/DirectPayPal-debug\n const maskedClient = clientId ? `${clientId.slice(0, 6)}…(len ${clientId.length})` : '(empty)';\n const ua = typeof navigator !== 'undefined' ? navigator.userAgent : '(no navigator)';\n appendDebug(`mount clientId=${maskedClient} env=${environment ?? '(unset)'}→${normalizedEnv ?? 'live'} ccy=${currency} sub=${isSubscription}`);\n appendDebug(`ua=${ua.slice(0, 80)}${ua.length > 80 ? '…' : ''}`);\n\n if (!clientId) {\n appendDebug('FAIL: clientId empty — gateway misconfigured');\n setFailed(true);\n telemetrySource.error({\n errorCode: 'CONFIGURATION_INVALID',\n stage: 'provider_load',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'provider_sdk',\n });\n // Silent on-screen: PayPal row simply doesn't render. Other gateways\n // (card, wallets) stay interactive. See markRenderFailed for the same\n // policy applied to script-load/ineligibility/render failures.\n console.error('[FloPay] DirectPayPal: clientId empty — gateway misconfigured');\n return;\n }\n if (!containerRef.current) {\n appendDebug('FAIL: containerRef not attached');\n return;\n }\n providerStartedAt.current = telemetrySource.startTiming();\n telemetrySource.log({\n name: 'provider.load.started',\n stage: 'provider_load',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n\n let cancelled = false;\n let superseded = false;\n const isInactive = () => cancelled || superseded;\n let paypalIntentIdempotencyKey: string | undefined;\n let paypalIntentAttemptActive = false;\n const beginPaypalIntentAttempt = () => {\n paypalIntentIdempotencyKey = generateIdempotencyKey();\n if (!paypalIntentIdempotencyKey) {\n console.warn(\n '[FloPay] DirectPayPal: secure idempotency key unavailable; retries may not be deduplicated.',\n );\n }\n paypalIntentAttemptActive = true;\n };\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let preRenderFailureHandled = false;\n // `ownedButtons` is captured as soon as the Buttons instance exists so\n // supersession/teardown can close it. The render `.then` handler no\n // longer stashes a separate reference.\n let ownedButtons: { close: () => Promise<void> } | null = null;\n let ownedButtonsClosed = false;\n const closeOwnedButtons = () => {\n if (!ownedButtons || ownedButtonsClosed) return;\n ownedButtonsClosed = true;\n ownedButtons.close().catch(() => {});\n };\n let overlayStartedAt: number | null = null;\n const finishOverlay = () => {\n if (overlayStartedAt === null) return;\n telemetrySource.log({\n name: 'provider.overlay.returned',\n stage: 'overlay_return',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.performance({\n stage: 'overlay_return',\n durationMs: telemetrySource.elapsed(overlayStartedAt),\n durationMode: 'buyer',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n overlayStartedAt = null;\n };\n // Tracks whether `render()` has resolved. PayPal's `onError` fires for\n // both render-time failures (SDK script error, ineligibility, iframe\n // mount issues) AND runtime failures after the user clicks (e.g.\n // `createOrder` rejection bubbling up from the backend). Render-time\n // failures should hide the button — runtime failures must not, or the\n // user loses the ability to retry.\n let rendered = false;\n const container = containerRef.current;\n\n // Diagnostics owned by the effect so cleanup can tear them down. The\n // observer + watchdog snapshot the DOM around `buttons.render()` so we\n // can see *why* a render hangs (CAPTCHA challenge swap, zero-size parent,\n // hidden tab) — render() never resolves or rejects in those cases, so\n // the existing trace dead-ends at \"render:start\" with no further signal.\n let containerObserver: MutationObserver | null = null;\n let perfObserver: PerformanceObserver | null = null;\n const watchdogTimers: ReturnType<typeof setTimeout>[] = [];\n const formatDims = (el: Element | null): string => {\n if (!el || typeof el.getBoundingClientRect !== 'function') return '(no rect)';\n const rect = el.getBoundingClientRect();\n return `${Math.round(rect.width)}×${Math.round(rect.height)}`;\n };\n const classifyIframeSrc = (raw: string | null): string => {\n if (!raw) return '(empty)';\n try {\n const url = new URL(raw, typeof window !== 'undefined' ? window.location.href : 'https://localhost');\n const path = url.pathname.toLowerCase();\n if (path.includes('checkcaptcha') || path.includes('captcha')) return `CAPTCHA(${url.host}${path})`;\n if (path.includes('risk') || path.includes('challenge')) return `RISK(${url.host}${path})`;\n if (path.includes('smart/buttons')) return `smart-buttons(${url.host})`;\n return `${url.host}${path}`.slice(0, 100);\n } catch {\n return raw.slice(0, 80);\n }\n };\n // Describe an iframe's loaded content: zoid uses both `src` (network) and\n // `srcdoc` (inline HTML, no network roundtrip). When both are empty the\n // iframe is genuinely blank — which means zoid's content injection never\n // completed and is a strong signal of a postMessage handshake failure.\n const describeIframe = (frame: Element): string => {\n const src = frame.getAttribute('src');\n const srcdoc = frame.getAttribute('srcdoc');\n const name = frame.getAttribute('name');\n const sandbox = frame.getAttribute('sandbox');\n const parts: string[] = [];\n if (src) parts.push(`src=${classifyIframeSrc(src)}`);\n if (srcdoc) parts.push(`srcdoc[${srcdoc.length}ch]`);\n if (!src && !srcdoc) parts.push('src=(empty) srcdoc=(empty)');\n if (name) parts.push(`name=${name.slice(0, 40)}`);\n if (sandbox !== null) parts.push(`sandbox=\"${sandbox.slice(0, 40)}\"`);\n return parts.join(' ');\n };\n // Peek inside an iframe's actual rendered document. Zoid uses\n // `contentDocument.write()` for same-origin frames, which doesn't update\n // src/srcdoc attributes — so the attributes can lie. This is the\n // ground-truth: if body has children, content IS there (and the issue is\n // render() not resolving); if body is empty, zoid never wrote into it\n // (handshake failure). Cross-origin throws, which is itself useful — it\n // means PayPal navigated the frame to its own origin (network worked).\n const inspectFrameContent = (frame: Element): string => {\n if (!(frame instanceof HTMLIFrameElement)) return '';\n try {\n const cd = frame.contentDocument;\n if (!cd) return 'cd=null';\n const bodyChildren = cd.body?.children.length ?? 0;\n const bodyLen = cd.body?.innerHTML.length ?? 0;\n const headLen = cd.head?.innerHTML.length ?? 0;\n return `cd=same-origin readyState=${cd.readyState} body[${bodyChildren}children,${bodyLen}ch] head[${headLen}ch]`;\n } catch (err) {\n return `cd=cross-origin(${(err as Error).message.slice(0, 30)})`;\n }\n };\n // Capture window-scoped errors and promise rejections while the lifecycle\n // is in flight. PayPal's zoid framework swallows postMessage / storage\n // failures into the console rather than rejecting render(), so capturing\n // these is often the only way to see the real cause of a hung render.\n const errorMessages: string[] = [];\n const onWindowError = (ev: ErrorEvent) => {\n if (isInactive()) return;\n const msg = ev.message ?? String(ev.error ?? '(no message)');\n if (msg && (msg.toLowerCase().includes('paypal') || msg.toLowerCase().includes('zoid') || msg.toLowerCase().includes('postrobot') || msg.toLowerCase().includes('storage'))) {\n appendDebug(`window:error ${msg.slice(0, 140)}`);\n errorMessages.push(msg);\n }\n };\n const onUnhandledRejection = (ev: PromiseRejectionEvent) => {\n if (isInactive()) return;\n const reason = ev.reason instanceof Error ? ev.reason.message : String(ev.reason ?? '(no reason)');\n if (reason && (reason.toLowerCase().includes('paypal') || reason.toLowerCase().includes('zoid') || reason.toLowerCase().includes('postrobot') || reason.toLowerCase().includes('storage'))) {\n appendDebug(`window:rejection ${reason.slice(0, 140)}`);\n errorMessages.push(reason);\n }\n };\n if (debug && typeof window !== 'undefined') {\n window.addEventListener('error', onWindowError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n }\n // Network telemetry: every paypal.com resource entry gets logged with\n // duration. If we see zero entries, an ad blocker / DNS filter / firewall\n // is intercepting before requests even hit the network. If we see hung\n // duration=0 entries, the request started but never completed (common\n // with privacy extensions that hold but don't reject requests).\n const paypalRequestCount = { value: 0 };\n if (debug && typeof PerformanceObserver !== 'undefined') {\n try {\n perfObserver = new PerformanceObserver((list) => {\n if (isInactive()) return;\n for (const entry of list.getEntries()) {\n if (!entry.name.toLowerCase().includes('paypal')) continue;\n paypalRequestCount.value += 1;\n const dur = Math.round(entry.duration);\n appendDebug(`net ${dur}ms ${entry.name.slice(0, 90)}`);\n }\n });\n perfObserver.observe({ type: 'resource', buffered: true });\n } catch {\n // Older browsers may not support PerformanceObserver with type/buffered\n // syntax — fail silently, the other diagnostics still work.\n }\n }\n const stopDiagnostics = () => {\n containerObserver?.disconnect();\n containerObserver = null;\n perfObserver?.disconnect();\n perfObserver = null;\n while (watchdogTimers.length) clearTimeout(watchdogTimers.pop()!);\n if (debug && typeof window !== 'undefined') {\n window.removeEventListener('error', onWindowError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n }\n };\n\n /**\n * Zoid (PayPal's iframe framework) emits \"zoid destroyed all components\"\n * and similar lifecycle messages through `onError` whenever its\n * components are torn down — page navigation, force reload, React 18\n * StrictMode dev mount/unmount, or a parent unmounting mid-render.\n * Those events aren't payment errors; surfacing them in our error\n * banner misleads users and blocks them from completing checkout.\n */\n const isZoidLifecycleMessage = (message: string | undefined): boolean => {\n if (!message) return false;\n const lower = message.toLowerCase();\n return lower.includes('zoid destroyed')\n || lower.includes('destroyed all components')\n || lower.includes('window closed')\n || lower.includes('detected container element removed');\n };\n\n const forwardError = (message: string) => {\n if (isInactive()) return;\n if (isZoidLifecycleMessage(message)) return;\n const friendly = applyFriendlyMessageOverride(message) ?? message;\n invokeMerchantCallback(() => onErrorChangeRef.current?.(friendly));\n };\n\n /**\n * Used by load/render-time error paths: hides the placeholder (and the\n * whole row) so users don't stare at a perpetual skeleton when PayPal\n * can't load. Logs to console for diagnostics but never calls\n * `onErrorChange` — pre-render failures (script load 400, ineligibility,\n * render rejection) would otherwise paint a checkout-blocking red banner\n * even though card / wallet / other gateways remain usable. The row\n * silently collapses; the parent's `directPaypalReady` stays false.\n *\n * Callbacks from torn-down generations are filtered before this helper is\n * reached. An active-generation lifecycle rejection is therefore a\n * definitive, non-retryable render failure and follows the same passive\n * unavailability path as other generic render failures.\n */\n const markRenderFailed = (message: string) => {\n if (cancelled) return;\n setFailed(true);\n if (!message.includes('paypal_ineligible')) {\n telemetrySource.error({\n errorCode: 'PROVIDER_LOAD_FAILED',\n stage: 'provider_load',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'provider_sdk',\n });\n }\n console.error('[FloPay] DirectPayPal load/render failure:', message);\n };\n\n const handlePreRenderFailure = (message: string, retryable = false) => {\n if (cancelled) return;\n const isRecoveryAttempt =\n automaticRetryUsedRef.current || !allowAutomaticRetry;\n if (preRenderFailureHandled) return;\n preRenderFailureHandled = true;\n // Invalidate this generation before tearing down its PayPal surface.\n // `cancelled` is reserved for effect cleanup so the retry timer can\n // still advance to a fresh generation after this one is superseded.\n superseded = true;\n stopDiagnostics();\n closeOwnedButtons();\n const isRetryableInitializationFailure =\n retryable\n || isPayPalInitAcknowledgementTimeout(message);\n if (\n isRetryableInitializationFailure\n && allowAutomaticRetry\n && !automaticRetryUsedRef.current\n ) {\n automaticRetryUsedRef.current = true;\n setReady(false);\n setSubmitting(false);\n setRecovering(true);\n onInitializationStateChangeRef.current?.('retrying');\n retryTimer = setTimeout(() => {\n if (cancelled) return;\n setRenderGeneration((generation) => generation + 1);\n }, PAYPAL_INIT_RETRY_DELAY_MS);\n return;\n }\n if (isRetryableInitializationFailure || isRecoveryAttempt) {\n setReady(false);\n setSubmitting(false);\n setRecovering(false);\n setFailed(true);\n onInitializationStateChangeRef.current?.('exhausted');\n if (!initializationFailureLoggedRef.current) {\n initializationFailureLoggedRef.current = true;\n const failureCode = isPayPalInitAcknowledgementTimeout(message)\n ? 'paypal_init_timeout'\n : retryable\n ? 'paypal_render_timeout'\n : 'paypal_init_failure';\n console.error(\n '[FloPay] Direct PayPal initialization failed:',\n failureCode,\n );\n }\n return;\n }\n markRenderFailed(message);\n };\n\n // Reset failure state at the start of every effect run so a config\n // change (clientId/environment/sessionId/currency etc.) re-attempts the\n // render cleanly rather than inheriting a sticky failure from the\n // previous configuration.\n setFailed(false);\n\n const dispatchTokenizedBody = async (\n body: TokenizedBody,\n prepared = beforeClickRef.current,\n ) => {\n if (isInactive()) return;\n const effectiveSessionId = prepared?.sessionId ?? sessionId;\n if (onTokenizedBodyRef.current) {\n await onTokenizedBodyRef.current(body, {\n sessionId: effectiveSessionId,\n accountPatch: prepared?.accountPatch,\n nonce: prepared?.nonce,\n });\n return;\n }\n const processingStartedAt = telemetrySource.startTiming();\n telemetrySource.log({\n name: 'payment.processing.started',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n const finishProcessing = () => {\n telemetrySource.log({\n name: 'payment.processing.completed',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.performance({\n stage: 'processing',\n durationMs: telemetrySource.elapsed(processingStartedAt),\n durationMode: 'machine',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n };\n try {\n const currentSession = sessionRef.current;\n const currentEmail = prepared?.accountPatch?.email ?? emailRef.current;\n const effectiveUserId = prepared?.accountPatch?.userId\n ?? currentSession?.customer?.id\n ?? currentSession?.accountData?.userId\n ?? '';\n const api = new PaymentAPI(baseUrl, { telemetry: false });\n const response = await api.processPayment(\n effectiveUserId,\n {\n sessionId: effectiveSessionId,\n nonce: prepared?.nonce ?? nonceRef.current,\n tokenizedData: body,\n accountData: {\n userId: effectiveUserId,\n email: currentEmail ?? currentSession?.customer?.email ?? '',\n firstName: prepared?.accountPatch?.firstName\n ?? currentSession?.customer?.firstName\n ?? currentSession?.accountData?.firstName\n ?? '',\n lastName: prepared?.accountPatch?.lastName\n ?? currentSession?.customer?.lastName\n ?? currentSession?.accountData?.lastName\n ?? '',\n country: prepared?.accountPatch?.country\n ?? currentSession?.customer?.country\n ?? currentSession?.accountData?.country\n ?? undefined,\n zip: prepared?.accountPatch?.zip\n ?? currentSession?.customer?.zip\n ?? currentSession?.accountData?.zip\n ?? undefined,\n },\n },\n );\n\n if (response.ok) {\n // A configuration change supersedes this render generation, but an\n // actual component unmount must not swallow a payment the backend\n // has already completed. The merchant still needs the terminal\n // callback to avoid treating a successful charge as abandoned.\n if (superseded || (cancelled && componentMountedRef.current)) return;\n finishProcessing();\n telemetrySource.terminal({\n outcome: 'payment_succeeded',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n invokeMerchantCallback(() =>\n onCompleteRef.current?.({ status: 'succeeded', checkoutMethod: 'paypal' }));\n return;\n }\n\n if (isInactive()) return;\n\n const json = (await response.json().catch(() => null)) as Record<string, unknown> | null;\n const rawMessage = (json?.['message'] as string | undefined) ?? 'PayPal payment failed.';\n const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;\n finishProcessing();\n if (typeof json?.['declineCode'] === 'string') {\n telemetrySource.terminal({\n outcome: 'payment_declined',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n } else {\n telemetrySource.error({\n errorCode: 'PAYMENT_PROCESSING_FAILED',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'process_payment',\n statusClass: response.status >= 500\n ? '5xx'\n : response.status >= 400\n ? '4xx'\n : response.status >= 300\n ? '3xx'\n : 'unknown',\n });\n }\n forwardError(message);\n invokeMerchantCallback(() =>\n onDeclineRef.current?.(buildDeclineEvent('paypal', message, {\n code: json?.['code'] as string | undefined,\n declineCode: json?.['declineCode'] as string | undefined,\n })));\n return;\n } catch (err) {\n if (isInactive()) return;\n finishProcessing();\n telemetrySource.error({\n errorCode: 'NETWORK_REQUEST_FAILED',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'process_payment',\n statusClass: 'network_error',\n });\n const rawMessage = err instanceof Error ? err.message : 'PayPal payment failed.';\n const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;\n forwardError(message);\n invokeMerchantCallback(() =>\n onDeclineRef.current?.(buildDeclineEvent('paypal', message)));\n return;\n }\n\n };\n\n const supersededRenderError = () => new FloPayError(\n 'PayPal render was superseded.',\n 'api_error',\n { code: 'paypal_render_superseded' },\n );\n\n const resolveExistingOrder = (orderId: string): Promise<string> =>\n isInactive() ? Promise.reject(supersededRenderError()) : Promise.resolve(orderId);\n\n const createPaypalIntent = async (fallbackMessage: string): Promise<string> => {\n if (isInactive()) {\n throw supersededRenderError();\n }\n if (!paypalIntentAttemptActive) beginPaypalIntentAttempt();\n const prepared = beforeClickRef.current;\n const effectiveSessionId = prepared?.sessionId ?? sessionId;\n const currentNonce = prepared?.nonce ?? nonceRef.current;\n telemetrySource.log({\n name: 'payment.intent.started',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'intent_create',\n });\n const intent = await new PaymentAPI(baseUrl, { telemetry: false }).createSessionIntent(\n effectiveSessionId,\n currentNonce ?? '',\n {\n provider: 'paypal',\n paymentMethodCategory: 'wallet',\n paymentMethodType: 'paypal',\n paymentMethodId: null,\n intentKind: isSubscription ? 'subscription' : 'order',\n },\n { idempotencyKey: paypalIntentIdempotencyKey },\n );\n if (isInactive()) {\n throw supersededRenderError();\n }\n if (intent.provider !== 'paypal') {\n throw new Error(fallbackMessage);\n }\n telemetrySource.log({\n name: 'payment.intent.completed',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'intent_create',\n statusClass: '2xx',\n });\n return intent.providerObjectId;\n };\n\n const reportPayPalDecline = (\n error: unknown,\n context?: DirectPayPalAttemptContext | null,\n ) => {\n const currentNonce = context?.nonce ?? nonceRef.current;\n if (!currentNonce) return;\n const effectiveSessionId = context?.sessionId ?? sessionId;\n const providerDeclineReason = getProviderDeclineCode(error)\n ?? getProviderErrorCode(error)\n ?? 'provider_declined';\n void new PaymentAPI(baseUrl, { telemetry: false }).reportSessionIntentDecline(\n effectiveSessionId,\n currentNonce,\n {\n provider: 'paypal',\n paymentMethodCategory: 'wallet',\n paymentMethodType: 'paypal',\n providerDeclineReason,\n },\n ).catch(() => {\n // Best-effort decline classification must not replace the provider error.\n });\n };\n\n // Defer the PayPal lifecycle by one macrotask so any rapid mount → cleanup\n // → mount cycle (React StrictMode in dev, or a parent that briefly mounts\n // us before late-arriving props like `email` cause it to re-render) has\n // finished before we touch PayPal's SDK. Without this, both the dead and\n // surviving mounts call `loadScript` in the same tick; on iOS Facebook\n // IAB the surviving mount's `render()` then rejects with \"zoid destroyed\n // all components\" because zoid's iframe init races the synchronous\n // teardown. clearTimeout in the cleanup ensures the dead mount never even\n // starts the load.\n const effectRenderGeneration = renderGeneration;\n appendDebug('loadScript:scheduled (deferred 1 tick)');\n let loadPromise: Promise<PayPalNamespace | null> | null = null;\n const startTimer = setTimeout(() => {\n if (cancelled) {\n appendDebug('loadScript:skipped (cancelled before defer ran)');\n return;\n }\n appendDebug('loadScript:start');\n // PayPal SDK uses `'production'` (not `'live'`) for prod mode, so\n // re-map after our internal normalize step.\n const paypalSdkEnv: 'sandbox' | 'production' | undefined =\n normalizedEnv === 'live' ? 'production' : normalizedEnv;\n loadPromise = loadScript({\n clientId,\n currency,\n // Subscriptions need the `subscription` vault intent; one-time payments\n // use a standard order capture.\n intent: isSubscription ? 'subscription' : 'capture',\n vault: isSubscription ? true : undefined,\n // Tell PayPal which environment the clientId belongs to. Without\n // this, PayPal defaults to live endpoints — and a sandbox clientId\n // sent to live silently stalls in zoid's prerender forever (no\n // error, no rejection).\n ...(paypalSdkEnv ? { environment: paypalSdkEnv } : {}),\n // Namespace the sandbox SDK so it can coexist with a production SDK on\n // the same page without clobbering `window.paypal`.\n ...(paypalSdkEnv === 'sandbox' ? { dataNamespace: 'paypal_sandbox' } : {}),\n });\n loadPromise\n .then((paypal) => {\n appendDebug(`loadScript:resolved inactive=${isInactive()} ns=${!!paypal} buttons=${!!paypal?.Buttons}`);\n if (isInactive()) return;\n if (!paypal?.Buttons) {\n appendDebug('FAIL: namespace missing Buttons factory');\n handlePreRenderFailure('PayPal SDK did not expose the Buttons factory.');\n return;\n }\n telemetrySource.log({\n name: 'provider.availability.checked',\n stage: 'provider_ready',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n\n const handleApprove = async (data: { orderID?: string; subscriptionID?: string }) => {\n if (isInactive() || activeRenderGenerationRef.current !== effectRenderGeneration) return;\n const token = data.subscriptionID ?? data.orderID ?? '';\n const context = token\n ? approvalContextByTokenRef.current.get(token)\n : attemptContextBySurfaceRef.current.get(effectRenderGeneration);\n if (!context || !isAttemptActive(context.generation)) return;\n if (!finishAttempt(context.generation)) return;\n approvalContextByTokenRef.current.delete(token);\n attemptContextBySurfaceRef.current.delete(context.surfaceKey);\n finishOverlay();\n try {\n setSubmitting(true);\n invokeMerchantCallback(() => onErrorChangeRef.current?.(null));\n if (!token) {\n throw new FloPayError(\n 'PayPal did not return an approval token.',\n 'api_error',\n { code: 'paypal_missing_token' },\n );\n }\n await dispatchTokenizedBody({\n id: token,\n isPaypal: true,\n }, context);\n } catch (err) {\n forwardError(err instanceof Error ? err.message : 'PayPal capture failed.');\n } finally {\n if (!isInactive()) setSubmitting(false);\n }\n };\n\n const buttons = paypal.Buttons!({\n style: { layout: 'horizontal', height: DEFAULT_BUTTON_HEIGHT, tagline: false },\n // PayPal's SDK awaits a Promise returned from `onClick` and aborts\n // the create-order/create-subscription step when `actions.reject()`\n // is invoked. Run the consumer's `runBeforeButtonClick` here so\n // inline-session/account patches land before the order is created,\n // matching the Stripe-rendered PayPal flow.\n onClick: async (_data: unknown, actions: { resolve: () => Promise<void>; reject: () => Promise<void> }) => {\n if (isInactive()) {\n await actions.reject();\n return;\n }\n beginPaypalIntentAttempt();\n const runner = runBeforeButtonClickRef.current;\n let prepared: Pick<\n DirectPayPalAttemptContext,\n 'accountPatch' | 'sessionId' | 'nonce'\n > = {};\n if (runner) {\n try {\n const beforeClick = await runner('paypal');\n if (isInactive()) {\n await actions.reject();\n return;\n }\n if (!beforeClick.proceed) {\n beforeClickRef.current = null;\n attemptContextBySurfaceRef.current.delete(effectRenderGeneration);\n await actions.reject();\n return;\n }\n prepared = {\n sessionId: beforeClick.sessionId,\n accountPatch: beforeClick.accountPatch,\n nonce: beforeClick.nonce,\n };\n } catch (err) {\n appendDebug(`onClick:runBeforeButtonClick rejected msg=${(err instanceof Error ? err.message : String(err)).slice(0, 120)}`);\n beforeClickRef.current = null;\n attemptContextBySurfaceRef.current.delete(effectRenderGeneration);\n await actions.reject();\n return;\n }\n }\n invokeMerchantCallback(() => onButtonClickRef.current?.('paypal'));\n const generation = startAttempt();\n const context: DirectPayPalAttemptContext = {\n generation,\n surfaceKey: effectRenderGeneration,\n ...prepared,\n };\n beforeClickRef.current = context;\n attemptContextBySurfaceRef.current.set(effectRenderGeneration, context);\n await actions.resolve();\n telemetrySource.log({\n name: 'payment.method.selected',\n stage: 'processing',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.log({\n name: 'provider.popup.opened',\n stage: 'overlay_open',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.log({\n name: 'provider.overlay.opened',\n stage: 'overlay_open',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n overlayStartedAt = telemetrySource.startTiming();\n },\n // When the SDK is already holding an order/subscription id from a\n // prior backend round-trip (the `paypal_direct_required` retry\n // path), feed it straight to PayPal instead of creating a new one.\n // Otherwise fall back to the normal create-intent call.\n createOrder: isSubscription\n ? undefined\n : existingOrderId\n ? () => resolveExistingOrder(existingOrderId).then(registerApprovalContext)\n : () => createPaypalIntent('Failed to create PayPal order.')\n .then(registerApprovalContext),\n createSubscription: isSubscription\n ? existingOrderId\n ? () => resolveExistingOrder(existingOrderId).then(registerApprovalContext)\n : () => createPaypalIntent('Failed to create PayPal subscription.')\n .then(registerApprovalContext)\n : undefined,\n onApprove: handleApprove,\n onCancel: () => {\n if (isInactive()) return;\n const context = attemptContextBySurfaceRef.current.get(effectRenderGeneration) ?? beforeClickRef.current;\n if (context) attemptContextBySurfaceRef.current.delete(context.surfaceKey);\n beforeClickRef.current = null;\n finishOverlay();\n telemetrySource.terminal({\n outcome: 'payment_cancelled',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n pendingProviderFocusRef.current = true;\n invalidateAttempt({ generation: context?.generation, remount: true, focus: false });\n },\n onError: (err) => {\n if (isInactive() || activeRenderGenerationRef.current !== effectRenderGeneration) return;\n const message = err instanceof Error ? err.message : 'PayPal failed to render.';\n appendDebug(`onError rendered=${rendered} msg=${message.slice(0, 120)}`);\n // Post-render: a runtime failure (e.g. backend rejected the\n // create-order/subscription call) — keep the button visible so\n // the user can retry, and route it through the parent's\n // pre-authorization technical recovery contract.\n if (rendered) {\n const context = attemptContextBySurfaceRef.current.get(effectRenderGeneration) ?? beforeClickRef.current;\n if (context && !isAttemptActive(context.generation)) return;\n if (!context && invalidatedAttemptGenerationRef.current === attemptGenerationRef.current) return;\n if (isZoidLifecycleMessage(message)) {\n finishAttempt(context?.generation);\n return;\n }\n finishOverlay();\n const lower = message.toLowerCase();\n telemetrySource.error({\n errorCode: lower.includes('popup') && lower.includes('block')\n ? 'POPUP_BLOCKED'\n : 'PROVIDER_RUNTIME_FAILED',\n stage: 'provider_ready',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n requestCategory: 'provider_sdk',\n });\n if (isProviderDecline(err)) {\n reportPayPalDecline(err, context);\n }\n if (context) attemptContextBySurfaceRef.current.delete(context.surfaceKey);\n beforeClickRef.current = null;\n invalidateAttempt({ generation: context?.generation, remount: true, showRetry: true, focus: true });\n notifyTechnicalFailure(err, { code: 'paypal_runtime_failed' });\n return;\n }\n // Pre-render: actual render-time issue or zoid teardown; mark\n // failed so we hide the placeholder. `markRenderFailed` filters\n // zoid lifecycle messages out of the forwarded error so the\n // consumer doesn't see noise.\n handlePreRenderFailure(message);\n },\n } as Parameters<NonNullable<typeof paypal.Buttons>>[0]);\n\n const eligible = buttons.isEligible();\n appendDebug(`isEligible=${eligible}`);\n telemetrySource.log({\n name: 'provider.eligibility.checked',\n stage: 'provider_ready',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n if (!eligible) {\n setReady(false);\n handlePreRenderFailure(\n 'PayPal buttons are not eligible to render in this context (paypal_ineligible).',\n );\n return;\n }\n\n const typedButtons = buttons as { close: () => Promise<void> };\n ownedButtons = typedButtons;\n\n // Pre-render container snapshot. A 0-width parent (flex column\n // collapse, display:none ancestor, etc.) is a common silent failure:\n // PayPal renders happily into a zero-size box and the user sees\n // nothing. Logging dims here catches that before render starts.\n if (debug) {\n appendDebug(`container:dims ${formatDims(container)} visibility=${typeof document !== 'undefined' ? document.visibilityState : '(no document)'}`);\n }\n\n // MutationObserver: log every PayPal injection AND every attribute\n // change. Zoid creates iframes with empty src/srcdoc first and then\n // sets the content attribute asynchronously — without `attributes:\n // true` we'd never see when (or whether) the content load actually\n // happens. The iframe's title=PayPal first appears as a childList\n // mutation; `src`/`srcdoc` then appears as an attribute mutation.\n if (debug && typeof MutationObserver !== 'undefined') {\n containerObserver = new MutationObserver((mutations) => {\n if (isInactive()) return;\n for (const mutation of mutations) {\n if (mutation.type === 'childList') {\n mutation.addedNodes.forEach((node) => {\n if (!(node instanceof Element)) return;\n const tag = node.tagName.toLowerCase();\n const title = (node.getAttribute('title') ?? '').slice(0, 40);\n const detail = tag === 'iframe' ? ` ${describeIframe(node)}` : '';\n appendDebug(`child+ ${tag}${title ? ` title=\"${title}\"` : ''}${detail} dims=${formatDims(node)}`);\n });\n } else if (mutation.type === 'attributes' && mutation.target instanceof Element) {\n const target = mutation.target;\n if (target.tagName.toLowerCase() !== 'iframe') continue;\n const attr = mutation.attributeName;\n if (attr === 'src' || attr === 'srcdoc') {\n appendDebug(`attr~ iframe ${attr}=${attr === 'srcdoc' ? `[${(target.getAttribute('srcdoc') ?? '').length}ch]` : classifyIframeSrc(target.getAttribute('src'))} dims=${formatDims(target)}`);\n }\n }\n }\n });\n containerObserver.observe(container, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['src', 'srcdoc'],\n });\n }\n\n // Render watchdog. Snapshots the container + iframes at 3s/8s/15s\n // if render() hasn't resolved. Uses describeIframe so we see src,\n // srcdoc length, name (zoid uses iframe names for postMessage\n // routing), and sandbox attribute — enough to distinguish \"iframe\n // shell exists but content never loaded\" (postMessage/storage\n // failure) from \"iframe loaded but render() didn't fire\" (PayPal\n // SDK internal bug or unmounted parent).\n const snapshotContainer = (when: string) => {\n if (isInactive() || rendered) return;\n const iframes = container.querySelectorAll('iframe');\n const hasStorageAccess = typeof document !== 'undefined' && 'hasStorageAccess' in document;\n appendDebug(`watchdog:${when} container=${formatDims(container)} children=${container.childElementCount} iframes=${iframes.length} visibility=${typeof document !== 'undefined' ? document.visibilityState : '(no document)'} cookies=${typeof navigator !== 'undefined' ? navigator.cookieEnabled : '?'} hasStorageAccessApi=${hasStorageAccess} paypalNetRequests=${paypalRequestCount.value}`);\n iframes.forEach((frame, i) => {\n const title = (frame.getAttribute('title') ?? '').slice(0, 40);\n appendDebug(` iframe[${i}] ${formatDims(frame)}${title ? ` title=\"${title}\"` : ''} ${describeIframe(frame)}`);\n const content = inspectFrameContent(frame);\n if (content) appendDebug(` ${content}`);\n });\n if (errorMessages.length === 0) {\n appendDebug(` (no PayPal/zoid window errors captured)`);\n }\n };\n if (debug) {\n watchdogTimers.push(setTimeout(() => snapshotContainer('3s'), 3000));\n watchdogTimers.push(setTimeout(() => snapshotContainer('8s'), 8000));\n watchdogTimers.push(setTimeout(() => snapshotContainer('15s'), 15000));\n }\n\n appendDebug('render:start');\n watchdogTimers.push(setTimeout(() => {\n if (isInactive() || rendered) return;\n appendDebug('watchdog:11s retryable render timeout');\n handlePreRenderFailure(\n 'PayPal Buttons render did not settle within 11000ms.',\n true,\n );\n }, PAYPAL_RENDER_WATCHDOG_MS));\n buttons.render(container).then(() => {\n appendDebug(`render:resolved inactive=${isInactive()}`);\n stopDiagnostics();\n if (isInactive()) {\n closeOwnedButtons();\n return;\n }\n rendered = true;\n setReady(true);\n setRecovering(false);\n onInitializationStateChangeRef.current?.('ready');\n telemetrySource.log({\n name: 'provider.ready',\n stage: 'provider_ready',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n telemetrySource.performance({\n stage: 'provider_ready',\n durationMs: telemetrySource.elapsed(providerStartedAt.current),\n durationMode: 'machine',\n provider: 'paypal',\n paymentMethodCategory: 'paypal',\n });\n }).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : 'PayPal failed to render.';\n appendDebug(`render:rejected msg=${message.slice(0, 120)}`);\n stopDiagnostics();\n handlePreRenderFailure(message);\n });\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : 'PayPal SDK failed to load.';\n appendDebug(`loadScript:rejected msg=${message.slice(0, 120)}`);\n handlePreRenderFailure(message);\n });\n }, 0);\n\n return () => {\n cancelled = true;\n // If the deferred load never fired (e.g. StrictMode's synchronous\n // cleanup), clearTimeout prevents the dead mount from ever calling\n // loadScript. The surviving mount's deferred timer runs next tick and\n // owns the lifecycle alone.\n clearTimeout(startTimer);\n if (retryTimer) clearTimeout(retryTimer);\n stopDiagnostics();\n // Prefer PayPal's graceful teardown over `container.innerHTML = ''`,\n // which races the SDK's async `render()` and triggers\n // \"Detected container element removed from DOM\".\n closeOwnedButtons();\n };\n }, [allowAutomaticRetry, baseUrl, clientId, currency, environment, isSubscription, sessionId, existingOrderId, renderGeneration, telemetrySource]);\n\n // On-screen lifecycle tracer, only rendered when `debug` is true.\n const debugPanel = debug ? (\n <pre\n data-testid=\"flopay-direct-paypal-debug\"\n style={{\n margin: '0 0 8px 0',\n padding: '6px 8px',\n background: failed ? '#fef2f2' : '#f3f4f6',\n border: `1px solid ${failed ? '#fca5a5' : '#d1d5db'}`,\n borderRadius: 6,\n color: '#111827',\n font: '11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n maxHeight: 220,\n overflowY: 'auto',\n }}\n >\n {`FloPay/DirectPayPal-debug (ready=${ready} failed=${failed})`}\n {debugLines.length === 0 ? '\\n(waiting for first lifecycle event…)' : `\\n${debugLines.join('\\n')}`}\n </pre>\n ) : null;\n\n // If PayPal can't load/render at all, render nothing in production, or only\n // the diagnostic panel when `debug` is on (so the failure mode stays visible\n // on screen).\n if (failed && !initializationConfigChanged) {\n return debug ? <div>{debugPanel}</div> : null;\n }\n\n return (\n // Single wrapper so the parent flex container sees exactly one flex item\n // (otherwise the fragment's placeholder + container become two siblings\n // and any spacing-sensitive layout has to reason about both). The wrapper\n // intentionally has no margin/padding so the parent owns all spacing.\n <div>\n {debugPanel}\n {/*\n Stacking context: the container must stay in the layout flow with\n non-zero dimensions for PayPal's zoid framework to mount its iframes —\n a `display: none` parent leaves the iframe 0×0 and `render()` never\n resolves. The placeholder absolutely-positions over the container so\n the user sees a skeleton until PayPal's button is interactive.\n */}\n <div\n key={renderGeneration}\n aria-hidden={recovering ? true : undefined}\n style={recovering\n ? {\n position: 'relative',\n height: 0,\n opacity: 0,\n pointerEvents: 'none',\n }\n : { position: 'relative', minHeight: DEFAULT_BUTTON_HEIGHT }}\n >\n {!ready && !recovering && (\n <div\n data-testid=\"flopay-direct-paypal-placeholder\"\n style={{\n position: 'absolute',\n inset: 0,\n borderRadius: 8,\n background: '#e5e7eb',\n animation: 'flopay-pulse 1.5s ease-in-out infinite',\n pointerEvents: 'none',\n }}\n />\n )}\n <div\n key={renderGeneration}\n ref={containerRef}\n data-testid=\"flopay-direct-paypal-container\"\n tabIndex={-1}\n aria-label=\"PayPal payment method\"\n // `display: flex` makes PayPal's injected `.paypal-buttons` a flex\n // child instead of an inline-block. That kills the baseline descender\n // space that would otherwise read as a phantom margin below the\n // button (looking like a doubled flex `gap` in the parent column).\n // `opacity: 0` (not `display: none`) keeps the container measurable\n // so PayPal can render into it before `ready` flips true.\n style={{\n minHeight: DEFAULT_BUTTON_HEIGHT,\n display: 'flex',\n opacity: ready ? 1 : 0,\n }}\n aria-busy={submitting || isProcessing}\n />\n </div>\n {showRetryFocusTarget && (\n <button\n ref={focusTargetRef}\n type=\"button\"\n data-testid=\"flopay-direct-paypal-focus-target\"\n onClick={focusPayPalSurface}\n style={DIRECT_PAYPAL_RECOVERY_ACTION_STYLE}\n >\n Try PayPal again\n </button>\n )}\n </div>\n );\n}\n\n/** Public direct-PayPal surface: telemetry accepts only the boolean opt-out. */\nexport function DirectPayPalButton(\n props: DirectPayPalButtonProps,\n): React.ReactElement | null {\n return <DirectPayPalButtonImplementation {...props} />;\n}\n\n/** Internal FloPayCheckout bridge for closed SDK-owned dimensions. */\nexport function InstrumentedDirectPayPalButton(\n props: InstrumentedDirectPayPalButtonProps,\n): React.ReactElement | null {\n return <DirectPayPalButtonImplementation {...props} />;\n}\n","/**\n * Invoke merchant-owned code without allowing its failure to alter checkout.\n * Failures stay local to the merchant console and are never sent as Flo\n * telemetry because the SDK cannot act on merchant implementation errors.\n */\nexport function invokeMerchantCallback(callback: (() => unknown) | undefined): void {\n if (!callback) return;\n const reportFailure = (error: unknown): void => {\n console.error('[FloPay] Merchant callback failed; checkout continued.', error);\n };\n try {\n void Promise.resolve(callback()).catch(reportFailure);\n } catch (error) {\n reportFailure(error);\n }\n}\n","export const EXTERNAL_METHOD_CALLBACK_GRACE_MS = 600;\n\nfunction getProviderErrorMessage(err: unknown): string | undefined {\n if (err instanceof Error) return err.message;\n if (typeof err === 'object' && err !== null) {\n const message = (err as { message?: unknown }).message;\n return typeof message === 'string' ? message : undefined;\n }\n return typeof err === 'string' ? err : undefined;\n}\n\nexport function sanitizeExternalFailureCode(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return /^[a-z0-9_.-]{1,64}$/i.test(trimmed) ? trimmed : undefined;\n}\n\nexport function getProviderErrorCode(err: unknown): string | undefined {\n if (typeof err !== 'object' || err === null) return undefined;\n const record = err as { code?: unknown; type?: unknown; name?: unknown };\n return (\n sanitizeExternalFailureCode(record.code) ??\n sanitizeExternalFailureCode(record.type) ??\n sanitizeExternalFailureCode(record.name)\n );\n}\n\nexport function getProviderDeclineCode(err: unknown): string | undefined {\n if (typeof err !== 'object' || err === null) return undefined;\n return sanitizeExternalFailureCode((err as { decline_code?: unknown }).decline_code);\n}\n\nexport function isProviderDecline(err: unknown): boolean {\n if (typeof err !== 'object' || err === null) return false;\n const type = sanitizeExternalFailureCode((err as { type?: unknown }).type)?.toLowerCase();\n return type === 'card_error' || getProviderDeclineCode(err) !== undefined;\n}\n\nexport function isPopupBlockedError(err: unknown): boolean {\n const message = getProviderErrorMessage(err)?.toLowerCase() ?? '';\n const code = getProviderErrorCode(err)?.toLowerCase() ?? '';\n const signal = `${code} ${message}`;\n return signal.includes('popup') && signal.includes('block');\n}\n","import type {FloPay} from '@flopay/js';\nimport {loadFloPay, PaymentAPI} from '@flopay/js';\nimport type {\n CheckoutButtonMethod,\n CheckoutProcessError,\n CheckoutSession,\n NormalizedCheckoutSession,\n PaymentResult,\n TokenizedBody,\n} from '@flopay/shared';\nimport {FloPayError, isSetupIntentClientSecret} from '@flopay/shared';\nimport {\n applyFriendlyMessageOverride,\n resolveTokenizedPaymentMethodId,\n} from './checkout-utils.js';\n\nexport const DEFAULT_SAVED_PAYMENT_DECLINE_METHOD: CheckoutButtonMethod = 'card';\n\n/** The `payment_method` shape shared by Stripe PaymentIntents and SetupIntents. */\ntype ResolvedIntentPaymentMethod = string | { id?: string | null } | null;\n\n/** The intent fields the saved-card 3DS-resume path reads, common to both kinds. */\ntype ResumeIntent = { id: string; status: string; payment_method?: ResolvedIntentPaymentMethod };\n\ntype ResumeIntentOp = { error?: { message?: string; code?: string }; intent: ResumeIntent | null } | null;\n\n/**\n * Retrieve the in-flight intent after a 3DS redirect. Trial-only / $0 saved-card\n * checkouts confirm a SetupIntent (`seti_…`), so route those through\n * `retrieveSetupIntent` — Stripe's `retrievePaymentIntent` rejects setup secrets.\n * Returns `null` when the provider can't retrieve the relevant intent kind.\n */\nasync function retrieveResumeIntent(\n stripe: import('@stripe/stripe-js').Stripe,\n clientSecret: string,\n isSetupIntent: boolean,\n): Promise<ResumeIntentOp> {\n if (isSetupIntent) {\n if (typeof stripe.retrieveSetupIntent !== 'function') return null;\n const { setupIntent, error } = await stripe.retrieveSetupIntent(clientSecret);\n return { error, intent: setupIntent ?? null };\n }\n if (typeof stripe.retrievePaymentIntent !== 'function') return null;\n const { paymentIntent, error } = await stripe.retrievePaymentIntent(clientSecret);\n return { error, intent: paymentIntent ?? null };\n}\n\n/**\n * Confirm the in-flight intent with the saved payment method after a 3DS\n * redirect. SetupIntent secrets go through `confirmCardSetup` (confirmCardPayment\n * rejects them). Returns `null` when the relevant confirm method is unavailable\n * so the caller can fall back to `handleNextAction`.\n */\nasync function confirmResumeIntent(\n stripe: import('@stripe/stripe-js').Stripe,\n clientSecret: string,\n data: { payment_method: string; return_url: string },\n isSetupIntent: boolean,\n): Promise<ResumeIntentOp> {\n if (isSetupIntent) {\n if (typeof stripe.confirmCardSetup !== 'function') return null;\n const { setupIntent, error } = await stripe.confirmCardSetup(clientSecret, data);\n return { error, intent: setupIntent ?? null };\n }\n if (typeof stripe.confirmCardPayment !== 'function') return null;\n const { paymentIntent, error } = await stripe.confirmCardPayment(clientSecret, data);\n return { error, intent: paymentIntent ?? null };\n}\n\nexport type ProcessRedirectResult = {\n type: 'paypal_redirect_required' | '3ds_required';\n threeDSecureToken: string;\n paymentMethodId?: string;\n};\n\nexport type SavedPaymentProcessResult =\n | ProcessRedirectResult\n | {\n type: 'success';\n result: PaymentResult;\n };\n\nexport type SavedPaymentFlowError = FloPayError & {\n checkoutMethod?: CheckoutButtonMethod;\n};\n\n/**\n * Tag a `FloPayError` with the originating checkout method so the React\n * recovery layer can route it. Collapses the tag-and-assert idiom that was\n * repeated at every throw site in this module into one typed call.\n */\nfunction withCheckoutMethod(\n error: FloPayError,\n checkoutMethod: CheckoutButtonMethod,\n): SavedPaymentFlowError {\n return Object.assign(error, { checkoutMethod });\n}\n\nexport function getRedirectResultFromCheckoutProcessError(\n error?: CheckoutProcessError | null,\n): ProcessRedirectResult | null {\n if (!error?.type || !error.threeDSecureToken) {\n return null;\n }\n\n if (\n error.type !== '3ds_required' &&\n error.type !== 'paypal_redirect_required'\n ) {\n return null;\n }\n\n return {\n type: error.type,\n threeDSecureToken: error.threeDSecureToken,\n paymentMethodId: error.paymentMethodId,\n };\n}\n\n/**\n * Render a provider-hosted 3DS challenge in a full-page overlay iframe and\n * resolve once the buyer completes (or abandons) it. Used by the auto-checkout\n * upsell flow when the saved PM requires a fresh 3DS challenge — the\n * SDK-rendered overlay sits at the host page level so the buyer can interact\n * with the challenge directly (mirrors the in-widget vault flow but without a\n * widget iframe to relay messages through).\n *\n * The provider's challenge eventually redirects to `/v1/vault/3ds/return`,\n * which postMessages `flopay-vault-3ds-return` back to the parent (this\n * window). The promise resolves on receipt of that message — but only when it\n * arrives from the challenge iframe (`event.source`) and the billing API\n * origin, so a sibling frame on the merchant page can't dismiss the challenge\n * early by forging the marker string. We then call `/3ds/complete` to drive the\n * backend's sync resolver to write the terminal attempt row.\n *\n * The overlay carries `role=\"dialog\"`/`aria-modal` and moves focus into the\n * iframe on mount, restoring the prior focus target on teardown, so keyboard /\n * screen-reader buyers aren't stranded on the obscured page.\n *\n * Pass `input.signal` (an `AbortSignal`) to cancel: SPA callers tie it to\n * component unmount / route change so an abandoned challenge tears down its\n * overlay and rejects immediately instead of stranding the iframe.\n *\n * Times out after 5 minutes — a buyer who walks away or whose popup blocker\n * intercepts the iframe (rare; CSP almost always permits iframing Stripe's\n * hosted challenge) gets a deterministic error path instead of locking the\n * checkout UI forever.\n */\n/**\n * Outcome the backend's `/3ds/complete` sync resolver returns to the SDK.\n * Mirrors `ThreeDsResolveOutcome` on the backend without importing it. The\n * caller branches on `status`:\n * - `succeeded` → show success\n * - `declined` → throw a decline FloPayError (no need to poll\n * session-status — the session stays `pending` on a\n * decline, so polling would just time out)\n * - `pending` / `requires_action` / `timeout` / `no_attempt` → fall back\n * to the session-status poll\n */\nexport type AutoCheckoutThreeDsOutcome =\n | { status: 'succeeded'; providerIntentId?: string | null }\n | {\n status: 'declined';\n providerIntentId?: string | null;\n declineReason?: string | null;\n gatewayDeclineReason?: string | null;\n }\n | { status: 'requires_action'; providerIntentId?: string | null; nextActionRedirectUrl?: string | null }\n | { status: 'pending'; providerIntentId?: string | null }\n | { status: 'timeout'; providerIntentId?: string | null }\n | { status: 'no_attempt' }\n | { status: 'unknown' };\n\nfunction isTerminalAutoCheckoutThreeDsOutcome(outcome: AutoCheckoutThreeDsOutcome): boolean {\n return outcome.status === 'succeeded' || outcome.status === 'declined';\n}\n\nexport async function runAutoCheckoutThreeDsChallenge(input: {\n billingApiUrl: string;\n sessionId: string;\n nonce: string;\n nextActionRedirectUrl: string;\n /**\n * Optional cancellation hook. SPA callers pass a signal tied to component\n * unmount / route change so an abandoned challenge tears down its overlay\n * (and rejects the promise) immediately, rather than leaving a full-page\n * iframe stranded until the 5-minute timeout fires.\n */\n signal?: AbortSignal;\n}): Promise<AutoCheckoutThreeDsOutcome> {\n if (typeof document === 'undefined' || typeof window === 'undefined') {\n throw new FloPayError('3DS challenge requires a browser environment.', 'api_error', {\n code: 'three_ds_no_window',\n });\n }\n if (input.signal?.aborted) {\n throw new FloPayError('Card authentication was cancelled.', 'api_error', {\n code: 'three_ds_aborted',\n });\n }\n const CHALLENGE_TIMEOUT_MS = 300_000;\n const CHALLENGE_POLL_INTERVAL_MS = 1_000;\n // Per-completion-request cap. Without it, a stalled `/3ds/complete` fetch\n // would wedge `pollInFlight` (which gates the 1s poll loop) until the\n // 5-minute overlay timeout fires.\n const COMPLETE_REQUEST_TIMEOUT_MS = 15_000;\n const completionEndpoint = `${input.billingApiUrl.replace(/\\/$/, '')}/v1/checkouts/sessions/${encodeURIComponent(\n input.sessionId,\n )}/3ds/complete`;\n const completeThreeDs = async (): Promise<AutoCheckoutThreeDsOutcome> => {\n // Combine the caller's cancellation signal with a per-request timeout:\n // cancellation propagates to the in-flight fetch (so an abandoned challenge\n // doesn't leave a request running), and a stalled request can't wedge\n // `pollInFlight` until the 5-minute overlay timeout fires.\n const controller = new AbortController();\n const onParentAbort = (): void => controller.abort();\n if (input.signal?.aborted) {\n controller.abort();\n } else {\n input.signal?.addEventListener('abort', onParentAbort);\n }\n const requestTimeout = window.setTimeout(() => controller.abort(), COMPLETE_REQUEST_TIMEOUT_MS);\n try {\n const response = await fetch(completionEndpoint, {\n method: 'POST',\n headers: {\n 'x-checkout-session-token': input.nonce,\n 'content-type': 'application/json',\n },\n body: '{}',\n signal: controller.signal,\n });\n if (!response.ok) {\n return { status: 'unknown' };\n }\n const json = (await response.json().catch(() => null)) as Record<string, unknown> | null;\n return coerceThreeDsOutcome(json);\n } catch {\n // Best-effort: the backend webhook will resolve the PI even if this call\n // fails (abort, timeout, or network blip). Don't surface it as an auth\n // failure — the session-status poll fallback in the caller handles it.\n return { status: 'unknown' };\n } finally {\n window.clearTimeout(requestTimeout);\n input.signal?.removeEventListener('abort', onParentAbort);\n }\n };\n // Remember the buyer's focus target so we can restore it when the modal tears\n // down — keyboard / screen-reader users would otherwise be stranded on the\n // obscured page behind the overlay.\n const previousFocus =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n const backdrop = document.createElement('div');\n backdrop.setAttribute('data-flopay-auto-3ds-overlay', '1');\n // Dialog semantics so assistive tech announces the challenge as a modal and\n // traps attention on it rather than the obscured page underneath.\n backdrop.setAttribute('role', 'dialog');\n backdrop.setAttribute('aria-modal', 'true');\n backdrop.setAttribute('aria-label', 'Card authentication');\n backdrop.style.cssText = [\n 'position:fixed',\n 'inset:0',\n 'z-index:2147483647',\n 'background:rgba(15,23,42,0.6)',\n 'display:flex',\n 'align-items:center',\n 'justify-content:center',\n 'padding:16px',\n ].join(';');\n const frame = document.createElement('iframe');\n frame.setAttribute('title', 'Card authentication');\n frame.setAttribute('allow', 'payment');\n frame.tabIndex = 0;\n frame.style.cssText = [\n 'width:min(100%,460px)',\n 'height:min(100%,640px)',\n 'border:0',\n 'border-radius:12px',\n 'background:#fff',\n 'box-shadow:0 12px 30px rgba(0,0,0,0.35)',\n ].join(';');\n frame.src = input.nextActionRedirectUrl;\n backdrop.appendChild(frame);\n document.body.appendChild(backdrop);\n // Move keyboard focus into the challenge once it's in the DOM.\n frame.focus();\n\n // The 3DS return page is served by the billing API (the issuer challenge\n // redirects there), so only accept the `flopay-vault-3ds-return` message when\n // it originates from our challenge iframe AND the billing API origin. This\n // stops a sibling frame on the merchant page from dismissing the challenge\n // early by forging the marker string.\n let expectedReturnOrigin: string | null = null;\n try {\n expectedReturnOrigin = new URL(input.billingApiUrl, window.location.href).origin;\n } catch {\n expectedReturnOrigin = null;\n }\n\n try {\n const polledOutcome = await new Promise<AutoCheckoutThreeDsOutcome | null>((resolve, reject) => {\n let settled = false;\n let timer = 0;\n let pollTimer = 0;\n let loadPollTimer = 0;\n let pollInFlight = false;\n const cleanup = (): void => {\n window.clearTimeout(timer);\n window.clearInterval(pollTimer);\n window.clearTimeout(loadPollTimer);\n window.removeEventListener('message', listener);\n frame.removeEventListener('load', onFrameLoad);\n input.signal?.removeEventListener('abort', onAbort);\n };\n const maybeResolveFromBackend = async (): Promise<void> => {\n if (settled || pollInFlight) return;\n pollInFlight = true;\n try {\n const outcome = await completeThreeDs();\n if (settled || !isTerminalAutoCheckoutThreeDsOutcome(outcome)) return;\n settled = true;\n cleanup();\n resolve(outcome);\n } finally {\n pollInFlight = false;\n }\n };\n const onFrameLoad = (): void => {\n window.clearTimeout(loadPollTimer);\n loadPollTimer = window.setTimeout(() => {\n void maybeResolveFromBackend();\n }, 250);\n };\n const onAbort = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(\n new FloPayError('Card authentication was cancelled.', 'api_error', {\n code: 'three_ds_aborted',\n }),\n );\n };\n const listener = (event: MessageEvent): void => {\n // Reject messages that don't come from our challenge iframe / the\n // billing API origin so an unrelated frame can't resolve the challenge.\n if (event.source !== frame.contentWindow) return;\n if (expectedReturnOrigin && event.origin !== expectedReturnOrigin) return;\n const data = event.data;\n if (!data || typeof data !== 'object') return;\n const record = data as Record<string, unknown>;\n if (record['source'] !== 'flopay-vault-3ds-return') return;\n if (settled) return;\n settled = true;\n cleanup();\n resolve(null);\n };\n timer = window.setTimeout(() => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(\n new FloPayError('Card authentication timed out.', 'api_error', {\n code: 'three_ds_timeout',\n }),\n );\n }, CHALLENGE_TIMEOUT_MS);\n pollTimer = window.setInterval(() => {\n void maybeResolveFromBackend();\n }, CHALLENGE_POLL_INTERVAL_MS);\n frame.addEventListener('load', onFrameLoad);\n window.addEventListener('message', listener);\n input.signal?.addEventListener('abort', onAbort);\n // Guard the (rare) abort that lands between the top-of-function check and\n // here — addEventListener won't fire for an already-aborted signal.\n if (input.signal?.aborted) onAbort();\n });\n\n if (polledOutcome) {\n return polledOutcome;\n }\n\n // Sync-resolve the PI on the backend. The response gives us the\n // definitive outcome — for declines the session stays `pending` so\n // polling session-status would time out; we use the response directly\n // instead.\n return await completeThreeDs();\n } finally {\n backdrop.parentNode?.removeChild(backdrop);\n // Return focus to wherever the buyer was before the modal opened.\n if (previousFocus?.isConnected) {\n previousFocus.focus();\n }\n }\n}\n\nfunction coerceThreeDsOutcome(json: Record<string, unknown> | null): AutoCheckoutThreeDsOutcome {\n if (!json || typeof json !== 'object') return { status: 'unknown' };\n const status = typeof json['status'] === 'string' ? json['status'] : 'unknown';\n const providerIntentId = typeof json['providerIntentId'] === 'string' ? json['providerIntentId'] : null;\n switch (status) {\n case 'succeeded':\n return { status: 'succeeded', providerIntentId };\n case 'declined':\n return {\n status: 'declined',\n providerIntentId,\n declineReason: typeof json['declineReason'] === 'string' ? json['declineReason'] : null,\n gatewayDeclineReason:\n typeof json['gatewayDeclineReason'] === 'string' ? json['gatewayDeclineReason'] : null,\n };\n case 'requires_action':\n return {\n status: 'requires_action',\n providerIntentId,\n nextActionRedirectUrl:\n typeof json['nextActionRedirectUrl'] === 'string' ? json['nextActionRedirectUrl'] : null,\n };\n case 'pending':\n return { status: 'pending', providerIntentId };\n case 'timeout':\n return { status: 'timeout', providerIntentId };\n case 'no_attempt':\n return { status: 'no_attempt' };\n default:\n return { status: 'unknown' };\n }\n}\n\nexport function checkoutProcessErrorToFloPayError(\n error?: CheckoutProcessError | null,\n fallbackMessage = 'Payment failed. Please try again.',\n options?: {\n checkoutMethod?: CheckoutButtonMethod;\n },\n): SavedPaymentFlowError {\n const checkoutMethod = options?.checkoutMethod\n ?? error?.checkoutMethod\n ?? (error?.type === 'paypal_redirect_required'\n ? 'paypal' as const\n : 'card' as const);\n\n const rawMessage = error?.message ?? fallbackMessage;\n const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;\n\n return withCheckoutMethod(\n new FloPayError(\n message,\n 'api_error',\n {\n code: error?.gatewayErrorCode,\n },\n ),\n checkoutMethod,\n );\n}\n\nfunction resolveSavedPaymentReturnUrl(session: CheckoutSession): string | undefined {\n if (typeof window !== 'undefined' && window.location.href) {\n return window.location.href;\n }\n\n return session.successUrl || session.cancelUrl || undefined;\n}\n\nfunction isStripePaymentIntentClientSecret(value: unknown): value is string {\n return typeof value === 'string'\n && value.startsWith('pi_')\n && value.includes('_secret_');\n}\n\nasync function retryOnceOnFetchFailure<T>(action: () => Promise<T>): Promise<T> {\n try {\n return await action();\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (!/failed to fetch|fetch failed/i.test(message)) {\n throw err;\n }\n\n return action();\n }\n}\n\nfunction getRedirectTokenFromProcessResponse(\n json: Record<string, unknown> | null,\n options?: { requirePaymentIntentClientSecret?: boolean },\n): string | undefined {\n const directCandidates = [\n json?.threeDSecureToken,\n json?.clientSecret,\n json?.stripeClientSecret,\n ];\n for (const candidate of directCandidates) {\n if (\n typeof candidate === 'string'\n && candidate.length > 0\n && (\n !options?.requirePaymentIntentClientSecret\n || isStripePaymentIntentClientSecret(candidate)\n )\n ) {\n return candidate;\n }\n }\n\n const nested = json?.data;\n if (nested && typeof nested === 'object') {\n const nestedRecord = nested as Record<string, unknown>;\n const nestedCandidates = [\n nestedRecord.threeDSecureToken,\n nestedRecord.clientSecret,\n nestedRecord.stripeClientSecret,\n nestedRecord.id,\n ];\n for (const candidate of nestedCandidates) {\n if (\n typeof candidate === 'string'\n && candidate.length > 0\n && (\n !options?.requirePaymentIntentClientSecret\n || isStripePaymentIntentClientSecret(candidate)\n )\n ) {\n return candidate;\n }\n }\n\n const nestedGateways = nestedRecord.gateways;\n if (nestedGateways && typeof nestedGateways === 'object') {\n const stripeGateway = (nestedGateways as Record<string, unknown>).stripe;\n if (stripeGateway && typeof stripeGateway === 'object') {\n const stripeRecord = stripeGateway as Record<string, unknown>;\n const gatewayCandidates = [\n stripeRecord.stripeClientSecret,\n stripeRecord.clientSecret,\n ];\n for (const candidate of gatewayCandidates) {\n if (\n typeof candidate === 'string'\n && candidate.length > 0\n && (\n !options?.requirePaymentIntentClientSecret\n || isStripePaymentIntentClientSecret(candidate)\n )\n ) {\n return candidate;\n }\n }\n }\n }\n }\n\n return undefined;\n}\n\nasync function recover3DSRedirectResult({\n billingApiUrl,\n sessionId,\n nonce,\n responseJson,\n}: {\n billingApiUrl: string;\n sessionId?: string | null;\n nonce?: string;\n responseJson: Record<string, unknown> | null;\n}): Promise<ProcessRedirectResult | null> {\n const directToken = getRedirectTokenFromProcessResponse(responseJson, {\n requirePaymentIntentClientSecret: true,\n });\n if (typeof directToken === 'string' && directToken.length > 0) {\n return {\n type: '3ds_required',\n threeDSecureToken: directToken,\n };\n }\n\n if (!sessionId) {\n return null;\n }\n\n try {\n const api = new PaymentAPI(billingApiUrl, { telemetry: false });\n const unified = await api.getUnifiedCheckoutSession(sessionId, nonce);\n const refreshedToken = unified.data.stripe?.clientSecret;\n\n if (isStripePaymentIntentClientSecret(refreshedToken)) {\n return {\n type: '3ds_required',\n threeDSecureToken: refreshedToken,\n };\n }\n } catch {\n // Preserve the original authentication_required error if the recovery fetch fails.\n }\n\n return null;\n}\n\nexport async function processSavedPaymentForMode({\n billingApiUrl,\n sessionId,\n session,\n nonce,\n tokenizedData,\n returnUrl,\n telemetry,\n}: {\n billingApiUrl: string;\n sessionId?: string | null;\n session: CheckoutSession;\n /**\n * Session-bound checkout token. Defaults to `session.clientSecret`, but\n * callers that resolved the session via a GET (which doesn't echo the nonce)\n * must pass it explicitly so `/process` and 3DS recovery stay authorized.\n */\n nonce?: string;\n tokenizedData?: TokenizedBody;\n returnUrl?: string;\n /** Disable the JS reporter when an enclosing React operation owns telemetry. */\n telemetry?: boolean;\n}): Promise<SavedPaymentProcessResult> {\n const baseUrl = billingApiUrl.replace(/\\/+$/, '');\n const resolvedSessionId = sessionId ?? session.id;\n const resolvedNonce = nonce ?? session.clientSecret;\n const customerId = session.customer?.id ?? session.accountData?.userId ?? '';\n const customerEmail = session.customer?.email ?? session.accountData?.email ?? '';\n const firstName = session.customer?.firstName ?? session.accountData?.firstName ?? '';\n const lastName = session.customer?.lastName ?? session.accountData?.lastName ?? '';\n const country = session.customer?.country ?? session.accountData?.country ?? undefined;\n const zip = session.customer?.zip ?? session.accountData?.zip ?? undefined;\n const api = new PaymentAPI(\n baseUrl,\n telemetry === false ? { telemetry: false } : undefined,\n );\n\n const response = await retryOnceOnFetchFailure(() => api.processPayment(customerId, {\n sessionId: resolvedSessionId,\n nonce: resolvedNonce,\n tokenizedData,\n accountData: {\n userId: customerId,\n email: customerEmail,\n firstName,\n lastName,\n country,\n zip,\n },\n returnUrl: returnUrl ?? resolveSavedPaymentReturnUrl(session),\n }));\n\n if (response.ok) {\n return {\n type: 'success',\n result: {\n status: 'succeeded',\n paymentIntentId: tokenizedData?.threeDSecureActionResultTokenId,\n paymentMethodId: resolveTokenizedPaymentMethodId(tokenizedData),\n checkoutMethod: tokenizedData\n ? tokenizedData.isPaypal ? 'paypal' : 'card'\n : undefined,\n },\n };\n }\n\n const json = (await response.json().catch(() => null)) as Record<string, unknown> | null;\n\n if (\n (json?.type === 'paypal_redirect_required' || json?.type === '3ds_required')\n ) {\n const redirectToken = getRedirectTokenFromProcessResponse(json);\n if (!redirectToken) {\n throw new FloPayError(\n 'Authentication is required but no redirect token was provided.',\n 'api_error',\n { code: 'authentication_required' },\n );\n }\n\n return {\n type: json.type as ProcessRedirectResult['type'],\n threeDSecureToken: redirectToken,\n paymentMethodId: json.paymentMethodId as string | undefined,\n };\n }\n\n if (json?.gatewayErrorCode === 'authentication_required') {\n const recoveredRedirect = await recover3DSRedirectResult({\n billingApiUrl: baseUrl,\n sessionId: resolvedSessionId,\n nonce: resolvedNonce,\n responseJson: json,\n });\n\n if (recoveredRedirect) {\n return recoveredRedirect;\n }\n\n throw withCheckoutMethod(\n new FloPayError(\n 'Your card requires authentication. Please enter your payment details below.',\n 'api_error',\n { code: 'authentication_required' },\n ),\n 'card',\n );\n }\n\n throw new FloPayError(\n (json?.message as string) ?? 'Payment failed. Please try again.',\n 'api_error',\n {\n code: (json?.code ?? json?.gatewayErrorCode) as string | undefined,\n declineCode: (json?.declineCode ?? json?.gatewayDeclineReason) as string | undefined,\n },\n );\n}\n\nexport async function handleSavedPaymentRedirectResult(\n redirectResult: ProcessRedirectResult,\n {\n flopay,\n paypalFlopay,\n attempt3DS,\n billingApiUrl,\n sessionId,\n session,\n returnUrl,\n telemetry,\n }: {\n flopay: FloPay | null;\n paypalFlopay: FloPay | null;\n attempt3DS?: boolean;\n billingApiUrl: string;\n sessionId?: string | null;\n session: CheckoutSession;\n returnUrl?: string;\n /** Disable nested JS reporting when the enclosing React recovery owns telemetry. */\n telemetry?: boolean;\n },\n): Promise<PaymentResult> {\n const stripe = flopay?.getRawProvider() as import('@stripe/stripe-js').Stripe | null;\n if (!stripe) {\n throw new FloPayError('Payment provider is not available.', 'api_error');\n }\n\n if (redirectResult.type === '3ds_required') {\n if (!attempt3DS || !redirectResult.threeDSecureToken) {\n throw withCheckoutMethod(\n new FloPayError(\n 'Your card requires authentication. Please enter your payment details below.',\n 'api_error',\n { code: 'authentication_required' },\n ),\n 'card',\n );\n }\n\n // Trial-only / $0 saved-card checkouts confirm a SetupIntent, which can\n // itself require 3DS. After the redirect the resume token is a `seti_`\n // secret — Stripe's retrievePaymentIntent / confirmCardPayment reject it,\n // so the SetupIntent APIs must run. Both intent kinds share the id/status/\n // payment_method fields the downstream status gate and /process call read.\n const isSetupIntent = isSetupIntentClientSecret(redirectResult.threeDSecureToken);\n let paymentIntent: ResumeIntent | null = null;\n let savedPaymentMethodId = redirectResult.paymentMethodId;\n\n const retrieved = await retrieveResumeIntent(stripe, redirectResult.threeDSecureToken, isSetupIntent);\n if (retrieved) {\n if (retrieved.error) {\n throw withCheckoutMethod(\n new FloPayError(\n retrieved.error.message ?? `Failed to retrieve 3DS ${isSetupIntent ? 'setup' : 'payment'} status.`,\n 'api_error',\n { code: retrieved.error.code },\n ),\n 'card',\n );\n }\n\n const existingIntent = retrieved.intent;\n if (!savedPaymentMethodId && existingIntent?.payment_method) {\n if (typeof existingIntent.payment_method === 'string') {\n savedPaymentMethodId = existingIntent.payment_method;\n } else if ('id' in existingIntent.payment_method) {\n savedPaymentMethodId = existingIntent.payment_method.id ?? undefined;\n }\n }\n }\n\n const confirmed = savedPaymentMethodId\n ? await confirmResumeIntent(\n stripe,\n redirectResult.threeDSecureToken,\n {\n payment_method: savedPaymentMethodId,\n return_url: returnUrl ?? resolveSavedPaymentReturnUrl(session) ?? window.location.href,\n },\n isSetupIntent,\n )\n : null;\n if (confirmed) {\n if (confirmed.error) {\n throw withCheckoutMethod(\n new FloPayError(\n confirmed.error.message ?? '3DS authentication failed.',\n 'api_error',\n { code: confirmed.error.code },\n ),\n 'card',\n );\n }\n\n paymentIntent = confirmed.intent;\n } else {\n const nextAction = await stripe.handleNextAction({\n clientSecret: redirectResult.threeDSecureToken,\n });\n\n if (nextAction.error) {\n throw withCheckoutMethod(\n new FloPayError(\n nextAction.error.message ?? '3DS authentication failed.',\n 'api_error',\n { code: nextAction.error.code },\n ),\n 'card',\n );\n }\n\n // handleNextAction resolves both intent kinds; its TS type only surfaces\n // `paymentIntent`, so read `setupIntent` off the result for `seti_` tokens.\n paymentIntent =\n (isSetupIntent\n ? (nextAction as { setupIntent?: { id: string; status: string; payment_method?: ResolvedIntentPaymentMethod } })\n .setupIntent\n : nextAction.paymentIntent) ?? null;\n }\n\n if (paymentIntent && (\n paymentIntent.status === 'requires_capture' ||\n paymentIntent.status === 'succeeded' ||\n paymentIntent.status === 'processing'\n )) {\n const followUp = await processSavedPaymentForMode({\n billingApiUrl,\n sessionId,\n session,\n telemetry,\n tokenizedData: {\n id: paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n },\n returnUrl,\n });\n\n if (followUp.type === 'success') {\n return {\n ...followUp.result,\n paymentIntentId: followUp.result.paymentIntentId ?? paymentIntent.id,\n paymentMethodId: followUp.result.paymentMethodId ?? savedPaymentMethodId,\n };\n }\n\n return handleSavedPaymentRedirectResult(followUp, {\n flopay,\n paypalFlopay,\n attempt3DS,\n billingApiUrl,\n sessionId,\n session,\n returnUrl,\n telemetry,\n });\n }\n\n throw withCheckoutMethod(\n new FloPayError('3DS authentication did not complete successfully.', 'api_error'),\n 'card',\n );\n }\n\n if (redirectResult.type === 'paypal_redirect_required') {\n const paypalStripe = (paypalFlopay ?? flopay)?.getRawProvider() as import('@stripe/stripe-js').Stripe | null;\n if (!paypalStripe) {\n throw withCheckoutMethod(\n new FloPayError('PayPal is not available.', 'api_error'),\n 'paypal',\n );\n }\n\n if (redirectResult.paymentMethodId) {\n // Backend attached the saved PM and confirmed the PI server-side, so\n // the PI is in `requires_action` with the PayPal redirect baked into\n // next_action.redirect_to_url. Use `handleNextAction` to drive that\n // redirect — `confirmPayment` would error with\n // `payment_intent_unexpected_state` on a PI that's already past the\n // confirmation step.\n const { error } = await paypalStripe.handleNextAction({\n clientSecret: redirectResult.threeDSecureToken,\n });\n\n if (error) {\n throw withCheckoutMethod(\n new FloPayError(\n error.message ?? 'PayPal authorization failed.',\n 'api_error',\n { code: error.code },\n ),\n 'paypal',\n );\n }\n\n return {\n status: 'succeeded',\n checkoutMethod: 'paypal',\n };\n }\n\n // No `paymentMethodId` on the redirect result: backend created the PI\n // without attaching a PM, so it's sitting in `requires_payment_method`.\n // Drive the redirect by passing `payment_method_data: { type: 'paypal' }`\n // — Stripe creates a fresh PayPal PM during the redirect and attaches it\n // to the PI. No Elements instance needed; no saved-PM reference needed\n // either, so this works for true cross-account scenarios as well.\n const { error } = await paypalStripe.confirmPayment({\n clientSecret: redirectResult.threeDSecureToken,\n confirmParams: {\n return_url: returnUrl ?? resolveSavedPaymentReturnUrl(session) ?? window.location.href,\n payment_method_data: { type: 'paypal' },\n } as { return_url: string },\n redirect: 'if_required',\n });\n\n if (error) {\n throw withCheckoutMethod(\n new FloPayError(\n error.message ?? 'PayPal authorization failed.',\n 'api_error',\n { code: error.code },\n ),\n 'paypal',\n );\n }\n\n return {\n status: 'succeeded',\n checkoutMethod: 'paypal',\n };\n }\n\n throw new FloPayError('Unsupported payment redirect state.', 'api_error');\n}\n\nexport function normalizeSavedPaymentError(err: unknown): SavedPaymentFlowError {\n if (err instanceof FloPayError) {\n const friendly = applyFriendlyMessageOverride(err.message);\n if (friendly && friendly !== err.message) {\n return Object.assign(\n new FloPayError(friendly, err.type, {\n code: err.code,\n declineCode: err.declineCode,\n param: err.param,\n statusCode: err.statusCode,\n }),\n { checkoutMethod: (err as SavedPaymentFlowError).checkoutMethod },\n ) as SavedPaymentFlowError;\n }\n return err as SavedPaymentFlowError;\n }\n\n const rawMessage = err instanceof Error ? err.message : 'Payment failed. Please try again.';\n const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;\n\n return new FloPayError(message, 'api_error') as SavedPaymentFlowError;\n}\n\n/**\n * Resolve the generic, provider-agnostic payment method id for a card already\n * on file for a returning customer, or `null` when none is present.\n *\n * For the vault flow (TeamFloPay/backend#823) the backend attaches a generic\n * `providerPaymentMethodId` to the session when a card is on file. The id is\n * opaque to the SDK — Stripe behind the vault returns a `pm_…`, but other card\n * providers can return their own token. Under the Model-A hosted-widget flow\n * the backend's auto-checkout cascade owns returning-customer charging; this\n * helper remains for callers that surface \"card on file\" affordances.\n */\nexport function resolveReturningCustomerPaymentMethodId(\n session: CheckoutSession,\n): string | null {\n const id = session.providerPaymentMethodId;\n return typeof id === 'string' && id.length > 0 ? id : null;\n}\n\n/**\n * Stripe Elements publishable keys resolved from a normalized session. The\n * \"PayPal\" entry here refers to the legacy Stripe-rendered PayPal account\n * (`gateways.stripe`'s dedicated PayPal sub-account), not the new direct\n * PayPal gateway — direct PayPal lives in `gateways.paypal` and is rendered\n * via the official PayPal JS SDK rather than through Stripe Elements.\n *\n * For PayPal-only sessions (`gateways.paypal` set, no `gateways.stripe`),\n * `publishableKey` is `undefined` and the caller should skip Stripe Elements\n * entirely. Only throws when the session advertises no supported gateway at\n * all.\n */\nexport function resolveSavedPaymentPublishableKeys(\n unified: NormalizedCheckoutSession,\n): {\n publishableKey?: string;\n paypalPublishableKey?: string;\n} {\n const publishableKey = unified.data.stripe?.publishableKey;\n const hasDirectPaypal = Boolean(unified.data.paypal?.publishableKey);\n\n if (!publishableKey && !hasDirectPaypal) {\n throw new FloPayError(\n 'Session advertises no supported gateways (expected `gateways.stripe` and/or `gateways.paypal`).',\n 'validation_error',\n );\n }\n\n if (!publishableKey) {\n // Direct-PayPal-only session: no Stripe Elements at all.\n return {};\n }\n\n return {\n publishableKey,\n // Direct-PayPal sessions can still use Stripe's PayPal Element for the\n // saved-PM redirect leg. Prefer the dedicated Stripe-PayPal sub-account\n // publishable key when the backend advertises one; fall back to the\n // primary Stripe publishable key so the resume flow still has a Stripe\n // instance to drive Stripe's PayPal PI.\n paypalPublishableKey: unified.data.stripe?.paypalPublishableKey ?? publishableKey,\n };\n}\n\nexport async function loadSavedPaymentProviders({\n publishableKey,\n paypalPublishableKey,\n billingApiUrl,\n locale,\n telemetry,\n}: {\n publishableKey?: string;\n paypalPublishableKey?: string;\n billingApiUrl: string;\n locale?: string;\n telemetry?: boolean;\n}): Promise<{\n flopay: FloPay | null;\n paypalFlopay: FloPay | null;\n}> {\n if (!publishableKey) {\n // PayPal-only session: no Stripe Elements instance to load. The\n // saved-PM Stripe-PayPal resume leg isn't available, but direct PayPal\n // doesn't need it.\n return { flopay: null, paypalFlopay: null };\n }\n\n const needsSeparatePaypal =\n Boolean(paypalPublishableKey) && paypalPublishableKey !== publishableKey;\n\n const [instance, paypalInstanceOrError] = await Promise.all([\n loadFloPay(publishableKey, {\n billingApiUrl,\n locale,\n telemetry,\n }),\n needsSeparatePaypal\n ? loadFloPay(paypalPublishableKey!, {\n billingApiUrl,\n locale,\n telemetry,\n }).catch((err: unknown) => {\n console.warn('[FloPay] Failed to load PayPal Stripe instance:', err);\n return null;\n })\n : Promise.resolve(null),\n ]);\n\n return {\n flopay: instance,\n paypalFlopay: paypalPublishableKey\n ? needsSeparatePaypal\n ? (paypalInstanceOrError as FloPay | null)\n : instance\n : null,\n };\n}\n","import React, { useEffect, useRef, useContext } from 'react';\nimport type { ElementType, ElementChangeEvent, ElementOptions, MountedElement } from '@flopay/shared';\nimport { FloPayContext } from './context.js';\n\n/** Common props shared by all element components. */\nexport interface ElementComponentProps {\n /** Additional CSS class for the wrapper div. */\n className?: string;\n /** Element id attribute for the wrapper div. */\n id?: string;\n /** Inline styles for the wrapper div. */\n style?: React.CSSProperties;\n /** Options forwarded to the underlying element. */\n options?: Partial<ElementOptions>;\n /** Fired when the element's value changes. */\n onChange?: (event: ElementChangeEvent) => void;\n /** Fired when the element is fully rendered and ready. */\n onReady?: () => void;\n /** Fired when the element gains focus. */\n onFocus?: () => void;\n /** Fired when the element loses focus. */\n onBlur?: () => void;\n /** Fired when the Escape key is pressed inside the element. */\n onEscape?: () => void;\n}\n\n/**\n * Generic element component factory.\n *\n * Each element component:\n * 1. Gets the Elements instance from context\n * 2. Creates the appropriate element type\n * 3. Mounts it to a ref'd container div\n * 4. Forwards events as props\n * 5. Cleans up on unmount\n *\n * Provider elements own their secure embedded UI; this wrapper only manages\n * lifecycle and event forwarding.\n */\nfunction createElementComponent(\n elementType: ElementType,\n displayName: string,\n): React.FC<ElementComponentProps> {\n function ElementComponent({\n className,\n id,\n style,\n options,\n onChange,\n onReady,\n onFocus,\n onBlur,\n onEscape,\n }: ElementComponentProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const elementRef = useRef<MountedElement | null>(null);\n const { elements, reportInteractive } = useContext(FloPayContext);\n\n useEffect(() => {\n if (!elements || !containerRef.current) return;\n\n let mounted = true;\n\n (async () => {\n // Reuse existing element if Stripe already created one of this type\n // (handles React Strict Mode double-mount).\n let element = elements.getElement(elementType);\n if (!element) {\n element = await elements.create(elementType, options);\n }\n\n if (!mounted || !containerRef.current) {\n return;\n }\n\n element.mount(containerRef.current);\n elementRef.current = element;\n\n if (onChange) element.on('change', onChange as (...args: unknown[]) => void);\n element.on('ready', () => {\n reportInteractive?.();\n onReady?.();\n });\n if (onFocus) element.on('focus', onFocus as (...args: unknown[]) => void);\n if (onBlur) element.on('blur', onBlur as (...args: unknown[]) => void);\n if (onEscape) element.on('escape', onEscape as (...args: unknown[]) => void);\n })();\n\n return () => {\n mounted = false;\n // Unmount only — don't destroy. Stripe Elements tracks elements\n // internally; destroying prevents reuse on Strict Mode remount.\n // Guard with try/catch: the element may already be destroyed if\n // the parent provider recreated the Elements group (e.g. on\n // appearance change).\n if (elementRef.current) {\n try {\n elementRef.current.unmount();\n } catch {\n // Element already destroyed — safe to ignore\n }\n elementRef.current = null;\n }\n };\n }, [elements, reportInteractive]);\n\n return <div ref={containerRef} className={className} id={id} style={style} />;\n }\n\n ElementComponent.displayName = displayName;\n return ElementComponent;\n}\n\n/** Props for the standalone non-card Payment Element. */\nexport interface PaymentElementProps extends Omit<ElementComponentProps, 'options'> {\n /**\n * Element options with an explicit wallet/APM allowlist. `card` is removed\n * at runtime; an empty result is rejected before the provider is called.\n */\n options: Omit<Partial<ElementOptions>, 'paymentMethodTypes'> & {\n paymentMethodTypes: readonly string[];\n };\n}\n\n/**\n * Renders a provider Payment Element restricted to the declared non-card\n * wallet/APM methods. Card collection is available only through the hosted\n * vault checkout surfaces.\n */\nexport const PaymentElement = createElementComponent(\n 'payment',\n 'PaymentElement',\n) as React.FC<PaymentElementProps>;\n\n/**\n * Renders an address input element.\n */\nexport const AddressElement = createElementComponent('address', 'AddressElement');\n","import type { TokenizedBody } from '@flopay/shared';\nimport { PaymentAPI } from '@flopay/js';\nimport { FloPayError } from '@flopay/shared';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { useFloPay, useElements, useBillingApiUrl } from './hooks.js';\n\n/**\n * Props for the `PayPalButton` component.\n *\n * Must be rendered inside its own `FloPayProvider` with `paymentMethodCreation: undefined`\n * (not 'manual') because this PayPal flow needs automatic payment-method creation.\n */\nexport interface PayPalButtonProps {\n /** The checkout session ID (UUID from billing API). */\n sessionId: string;\n /**\n * Session-bound checkout token returned by session creation. Forwarded as\n * `x-checkout-session-token` on continuation requests — required by\n * post-#640 backends.\n */\n nonce?: string;\n /** Billing API base URL. Optional — defaults to the value from FloPayProvider or the shared constant. */\n billingApiUrl?: string;\n /** User's email. */\n email?: string;\n /** User ID for processing payments. */\n userId?: string;\n /** First name for billing. */\n firstName?: string;\n /** Last name for billing. */\n lastName?: string;\n /** Checkout version for tracking. */\n chv?: string;\n /**\n * Called with tokenized data after PayPal authorization.\n * If omitted, the component calls processPayment internally.\n */\n onTokenizedBody?: (body: TokenizedBody) => void;\n /** Called on successful payment (self-contained mode). */\n onComplete?: () => void;\n /** Called when an error occurs. */\n onErrorChange?: (error: string | null) => void;\n /** External processing state. */\n isProcessing?: boolean;\n}\n\n/**\n * PayPal button that handles the full PayPal payment flow.\n *\n * **Important**: PayPal requires its own `FloPayProvider` with automatic\n * payment-method creation. Keep it separate from manually created wallet/APM\n * Elements groups.\n *\n * ```tsx\n * {/* Main checkout provider *\\/}\n * <FloPayProvider flopay={flopay} options={{ amount, currency }}>\n * <SplitCardForm ... />\n * </FloPayProvider>\n *\n * {/* PayPal provider (no paymentMethodCreation) *\\/}\n * <FloPayProvider flopay={flopay} options={{ amount, currency, paymentMethodCreation: 'auto' }}>\n * <PayPalButton ... />\n * </FloPayProvider>\n * ```\n */\nexport function PayPalButton({\n sessionId,\n nonce,\n billingApiUrl,\n email,\n userId,\n firstName,\n lastName,\n chv,\n onTokenizedBody,\n onComplete,\n onErrorChange,\n isProcessing = false,\n}: PayPalButtonProps): React.ReactElement {\n const flopay = useFloPay();\n const elements = useElements();\n const contextBillingUrl = useBillingApiUrl();\n const [ready, setReady] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const paypalResumeAttempted = useRef(false);\n const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\\/+$/, '');\n\n // ── Internal processPayment (self-contained mode) ──\n\n const processPaymentInternal = useCallback(\n async (tokenizedBody: TokenizedBody) => {\n try {\n const api = new PaymentAPI(baseUrl);\n const response = await api.processPayment(userId ?? '', {\n sessionId,\n nonce,\n tokenizedData: tokenizedBody,\n accountData: {\n userId: userId ?? '',\n email: email ?? '',\n firstName: firstName ?? '',\n lastName: lastName ?? '',\n },\n chv,\n });\n\n if (response.ok) {\n onComplete?.();\n return;\n }\n\n const json = await response.json().catch(() => null) as Record<string, unknown> | null;\n onErrorChange?.((json?.message as string) ?? 'Payment failed. Please try again.');\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'An unexpected error occurred');\n }\n },\n [baseUrl, sessionId, nonce, userId, email, firstName, lastName, chv, onComplete, onErrorChange],\n );\n\n const dispatchTokenizedBody = useCallback(\n (body: TokenizedBody) => {\n if (onTokenizedBody) {\n onTokenizedBody(body);\n } else {\n processPaymentInternal(body);\n }\n },\n [onTokenizedBody, processPaymentInternal],\n );\n\n // ── Resume PayPal redirect return ──\n\n useEffect(() => {\n if (!flopay || paypalResumeAttempted.current) return;\n\n const params = new URLSearchParams(window.location.search);\n const paymentIntentId = params.get('payment_intent');\n const clientSecret = params.get('payment_intent_client_secret');\n const redirectStatus = params.get('redirect_status');\n\n if (!paymentIntentId || !clientSecret) return;\n paypalResumeAttempted.current = true;\n\n (async () => {\n try {\n setSubmitting(true);\n\n if (redirectStatus === 'failed') {\n onErrorChange?.('PayPal payment was declined. Please try again.');\n return;\n }\n\n // Retrieve the PaymentIntent to check the PayPal redirect result.\n const provider = flopay.getRawProvider() as { retrievePaymentIntent?: (cs: string) => Promise<{ paymentIntent?: { id: string; status: string; payment_method: string | { id: string } }; error?: { message: string } }> } | null;\n if (!provider?.retrievePaymentIntent) {\n onErrorChange?.('Cannot retrieve PayPal payment status.');\n return;\n }\n\n const { paymentIntent, error: retrieveError } = await provider.retrievePaymentIntent(clientSecret);\n if (retrieveError) {\n onErrorChange?.(retrieveError.message ?? 'Failed to retrieve PayPal payment status.');\n return;\n }\n\n if (paymentIntent && (paymentIntent.status === 'requires_capture' || paymentIntent.status === 'succeeded')) {\n const pmId = typeof paymentIntent.payment_method === 'string'\n ? paymentIntent.payment_method\n : paymentIntent.payment_method?.id;\n\n dispatchTokenizedBody({\n id: pmId ?? paymentIntent.id,\n type: 'card',\n threeDSecureActionResultTokenId: paymentIntent.id,\n isPaypal: true,\n });\n\n // Clean up URL params\n const url = new URL(window.location.href);\n url.searchParams.delete('payment_intent');\n url.searchParams.delete('payment_intent_client_secret');\n url.searchParams.delete('redirect_status');\n window.history.replaceState({}, '', url.toString());\n } else {\n onErrorChange?.('PayPal payment was not completed. Please try again.');\n }\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'Failed to complete PayPal payment.');\n } finally {\n setSubmitting(false);\n }\n })();\n }, [flopay, dispatchTokenizedBody, onErrorChange]);\n\n // ── PayPal confirm handler ──\n\n const handlePayPalConfirm = useCallback(async () => {\n if (!flopay || !elements) return;\n\n try {\n setSubmitting(true);\n onErrorChange?.(null);\n\n if (!sessionId || !email) {\n throw new FloPayError('Missing sessionId or email for PayPal payment', 'validation_error');\n }\n\n const result = await flopay.confirmPayPalPayment({\n billingApiUrl: baseUrl,\n sessionId,\n nonce,\n email,\n returnUrl: window.location.href,\n });\n\n if (result.error) {\n onErrorChange?.(result.error.message);\n return;\n }\n\n // Defensive future inline-completion path: `confirmPayPalPayment` currently\n // redirects and returns no `paymentIntentId`, so the redirect-resume effect\n // is what normally reaches `dispatchTokenizedBody`. If\n // `confirmPayPalPayment` ever starts completing inline, it must also return\n // `paymentIntentId` so this branch can finish the checkout immediately.\n if (\n result.paymentIntentId\n && (result.status === 'succeeded' || result.status === 'processing' || result.status === 'requires_capture')\n ) {\n dispatchTokenizedBody({\n id: result.paymentMethodId ?? result.paymentIntentId,\n type: 'card',\n threeDSecureActionResultTokenId: result.paymentIntentId,\n isPaypal: true,\n });\n }\n } catch (err) {\n onErrorChange?.(err instanceof Error ? err.message : 'PayPal payment failed. Please try again.');\n } finally {\n setSubmitting(false);\n }\n }, [flopay, elements, sessionId, nonce, email, baseUrl, dispatchTokenizedBody, onErrorChange]);\n\n if (!flopay || !elements) {\n return <div style={{ height: 45, background: '#f0f0f0', borderRadius: 6, animation: 'pulse 1.5s infinite' }} />;\n }\n\n return (\n <>\n {!ready && (\n <div style={{ height: 45, background: '#f0f0f0', borderRadius: 6 }} />\n )}\n <div style={ready ? {} : { display: 'none' }}>\n <button\n type=\"button\"\n onClick={handlePayPalConfirm}\n disabled={submitting || isProcessing}\n style={{\n width: '100%',\n height: 45,\n backgroundColor: '#ffc439',\n color: '#003087',\n border: 'none',\n borderRadius: 6,\n fontSize: '1rem',\n fontWeight: 700,\n cursor: submitting || isProcessing ? 'not-allowed' : 'pointer',\n opacity: submitting || isProcessing ? 0.6 : 1,\n }}\n ref={() => setReady(true)}\n >\n {submitting ? 'Processing...' : 'PayPal'}\n </button>\n </div>\n\n {(submitting || isProcessing) && (\n <div style={{\n position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.4)',\n display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000,\n }}>\n <div style={{\n background: 'white', borderRadius: 8, padding: '1.5rem',\n textAlign: 'center', boxShadow: '0 4px 24px rgba(0,0,0,0.15)', width: 280,\n }}>\n Processing PayPal payment...\n </div>\n </div>\n )}\n </>\n );\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { PaymentAPI } from '@flopay/js';\nimport type {\n CheckoutButtonMethod,\n CheckoutSession,\n DeclineEvent,\n FloPayAppearance,\n InlineSessionDraft,\n PaymentResult,\n ThemeId,\n} from '@flopay/shared';\nimport type {\n ButtonsLayoutStyles,\n ButtonsLayoutTheme,\n CheckoutItem,\n CheckoutProduct,\n CheckoutSubscription,\n} from '@flopay/shared';\nimport { FloPayError, resolveBillingApiUrl, resolveButtonsLayoutTheme, resolveTheme } from '@flopay/shared';\nimport { CardButtonContentSlot } from './card-button-content.js';\nimport { buildDeclineEvent } from './checkout-utils.js';\nimport { FloPayCheckout } from './flopay-checkout.js';\nimport { darkenHex, derivePrimaryTileStyle } from './split-card-form.js';\nimport {\n PROCESSING_OVERLAY_ERROR_DELAY_MS,\n PROCESSING_OVERLAY_SUCCESS_DELAY_MS,\n ProcessingOverlay,\n type OverlayStatus,\n} from './processing-overlay.js';\nimport {\n type AutoCheckoutThreeDsOutcome,\n checkoutProcessErrorToFloPayError,\n DEFAULT_SAVED_PAYMENT_DECLINE_METHOD,\n normalizeSavedPaymentError,\n processSavedPaymentForMode,\n runAutoCheckoutThreeDsChallenge,\n} from './saved-payment-flow.js';\n\nconst DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction coerceError(err: unknown, fallbackMessage: string): FloPayError {\n if (err instanceof FloPayError) {\n return err;\n }\n\n return new FloPayError(\n err instanceof Error ? err.message : fallbackMessage,\n 'api_error',\n );\n}\n\nfunction shouldShowFallbackCheckout(\n error: FloPayError & { checkoutMethod?: CheckoutButtonMethod },\n sessionId: string | null,\n): boolean {\n if (!sessionId) return false;\n if (error.type === 'validation_error') return false;\n if (error.checkoutMethod && error.checkoutMethod !== 'card' && error.checkoutMethod !== 'paypal') {\n return false;\n }\n return true;\n}\n\nexport interface FloPayAutomaticPaymentSuccessEvent {\n result: PaymentResult;\n session: CheckoutSession | null;\n sessionId: string | null;\n autoCompleted: boolean;\n}\n\nexport interface FloPayAutomaticPaymentButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onError'> {\n sessionId?: string;\n /**\n * Session-bound checkout token for a consumer-supplied {@link sessionId}\n * (the `nonce` returned when that session was created). Post-#640 backends\n * require it as `x-checkout-session-token` to read the session and to\n * `/process` it; without it the existing-session path 401s with\n * \"Missing checkout session token.\". Ignored on the create-session path,\n * where the SDK mints and threads the nonce itself.\n */\n nonce?: string;\n createSession?: InlineSessionDraft;\n /**\n * @deprecated Ignored. The backend now picks the customer's most recent\n * vaulted payment method via `getLatestByUserId` and rebinds the session's\n * gateway to match it (see `apps/api`'s `createSingle` auto-checkout\n * branch). Passing this prop has no effect — it is retained only to avoid\n * breaking existing integrations.\n */\n paymentMethodId?: string;\n /**\n * @deprecated Ignored. The backend orchestrates gateway routing — clients\n * no longer choose between card and PayPal at the SDK boundary. Passing\n * this prop has no effect.\n */\n checkoutMethod?: CheckoutButtonMethod;\n clientId?: string;\n /**\n * Unified products array (TeamFloPay/backend#760). When supplied,\n * `items`/`subscriptions` are ignored. The SDK folds the legacy fields\n * into this shape internally.\n */\n products?: CheckoutProduct[];\n items?: CheckoutItem[];\n subscriptions?: CheckoutSubscription[];\n account?: InlineSessionDraft['account'];\n successUrl?: string;\n cancelUrl?: string;\n couponCodes?: string[];\n tagsData?: InlineSessionDraft['tagsData'];\n utmMetadata?: InlineSessionDraft['utmMetadata'];\n billingApiUrl?: string;\n locale?: string;\n /**\n * High-level theme bundle that styles the button (and the fallback\n * `FloPayCheckout` modal that opens when the saved-payment charge needs\n * user interaction). One of: `'classic'`, `'modern-light'`, `'modern-dark'`,\n * `'bold-light'`, `'bold-dark'`, `'glass-light'`, `'glass-dark'`. Explicit\n * `buttonsStyles` still wins for fine-grained overrides.\n */\n theme?: ThemeId;\n /**\n * Per-checkout appearance overrides layered on top of the chosen `theme`\n * (same shape as {@link FloPayCheckout}'s `appearance`). Its `colorPrimary` /\n * `colorPrimaryHover` / `borderRadius` re-skin the button — and the fallback\n * `FloPayCheckout` modal — so the auto-pay button matches the rest of the\n * themed checkout. Without this the button only saw the bundle's defaults.\n */\n appearance?: FloPayAppearance;\n /**\n * @deprecated Use `theme` instead. Legacy buttons-layout preset\n * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for\n * back-compat.\n */\n buttonsTheme?: ButtonsLayoutTheme;\n buttonsStyles?: ButtonsLayoutStyles;\n onSuccess?: (event: FloPayAutomaticPaymentSuccessEvent) => void;\n onError?: (error: FloPayError) => void;\n onDecline?: (decline: DeclineEvent) => void;\n children?: React.ReactNode;\n}\n\nfunction resolveCreateSessionDraft(props: FloPayAutomaticPaymentButtonProps): InlineSessionDraft | null {\n if (props.createSession) {\n return {\n ...props.createSession,\n checkoutMode: 'auto',\n };\n }\n\n if (!props.clientId || !props.account || !props.successUrl || !props.cancelUrl) {\n return null;\n }\n\n // Enforce the documented precedence: when `products` is supplied the legacy\n // `items`/`subscriptions` are dropped so the draft can't carry an ambiguous\n // cart. `createAndFetchSession` folds the legacy fields into `products[]`\n // only when `products` is absent (`params.products ?? foldIntoProducts(...)`).\n // Use `!= null` so `products={null}` is treated as absent too, matching the\n // `??` semantics downstream — otherwise the legacy fields would be dropped\n // here but `null ?? foldIntoProducts(undefined, undefined)` would yield `[]`.\n const hasProducts = props.products != null;\n\n return {\n clientId: props.clientId,\n products: props.products,\n items: hasProducts ? undefined : props.items,\n subscriptions: hasProducts ? undefined : props.subscriptions,\n account: props.account,\n successUrl: props.successUrl,\n cancelUrl: props.cancelUrl,\n couponCodes: props.couponCodes,\n tagsData: props.tagsData,\n utmMetadata: props.utmMetadata,\n checkoutMode: 'auto',\n };\n}\n\nexport function FloPayAutomaticPaymentButton({\n sessionId,\n nonce,\n createSession,\n // Deprecated — accepted for back-compat and silently ignored. Backend\n // resolves the customer's latest payment method server-side.\n paymentMethodId: _deprecatedPaymentMethodId,\n checkoutMethod: _deprecatedCheckoutMethod,\n clientId,\n products,\n items,\n subscriptions,\n account,\n successUrl,\n cancelUrl,\n couponCodes,\n tagsData,\n utmMetadata,\n billingApiUrl,\n locale,\n theme,\n appearance,\n buttonsTheme,\n buttonsStyles: stylesOverride,\n onSuccess,\n onError,\n onDecline,\n children,\n disabled = false,\n type = 'button',\n style,\n ...buttonProps\n}: FloPayAutomaticPaymentButtonProps) {\n const resolvedBillingUrl = useMemo(\n () => resolveBillingApiUrl(billingApiUrl),\n [billingApiUrl],\n );\n const createSessionDraft = useMemo(\n () => resolveCreateSessionDraft({\n createSession,\n clientId,\n products,\n items,\n subscriptions,\n account,\n successUrl,\n cancelUrl,\n couponCodes,\n tagsData,\n utmMetadata,\n }),\n [\n account,\n cancelUrl,\n clientId,\n couponCodes,\n createSession,\n products,\n items,\n subscriptions,\n successUrl,\n tagsData,\n utmMetadata,\n ],\n );\n const [isProcessing, setIsProcessing] = useState(false);\n const [overlayStatus, setOverlayStatus] = useState<OverlayStatus | null>(null);\n const [overlayError, setOverlayError] = useState<string | null>(null);\n const [fallbackSession, setFallbackSession] = useState<{\n sessionId: string;\n errorMessage: string;\n /**\n * Session-bound checkout token carried over from the auto-process attempt.\n * Without it the fallback checkout's session GET 401s on post-#640 backends\n * (`x-checkout-session-token` is required to read the session row).\n */\n nonce?: string;\n } | null>(null);\n\n const isMountedRef = useRef(true);\n // Aborts the in-flight 3DS challenge overlay when the component unmounts so a\n // route change / navigation can't leave a stranded full-page iframe behind.\n const threeDsAbortRef = useRef<AbortController | null>(null);\n const fallbackSessionRef = useRef(fallbackSession);\n const onSuccessRef = useRef(onSuccess);\n const onErrorRef = useRef(onError);\n const onDeclineRef = useRef(onDecline);\n\n useEffect(() => {\n fallbackSessionRef.current = fallbackSession;\n }, [fallbackSession]);\n\n useEffect(() => {\n onSuccessRef.current = onSuccess;\n }, [onSuccess]);\n\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n useEffect(() => {\n onDeclineRef.current = onDecline;\n }, [onDecline]);\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n threeDsAbortRef.current?.abort();\n };\n }, []);\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setFallbackSession(null);\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, []);\n\n const emitDecline = useCallback((error: FloPayError, method = DEFAULT_SAVED_PAYMENT_DECLINE_METHOD) => {\n onDeclineRef.current?.(buildDeclineEvent(method, error, {\n code: error.code,\n declineCode: error.declineCode,\n }));\n }, []);\n\n const showSuccess = useCallback(async (event: FloPayAutomaticPaymentSuccessEvent) => {\n if (!isMountedRef.current) return;\n\n setOverlayError(null);\n setOverlayStatus('success');\n await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);\n\n if (!isMountedRef.current) return;\n onSuccessRef.current?.(event);\n }, []);\n\n const showError = useCallback(async (\n error: FloPayError,\n options?: {\n emitDecline?: boolean;\n method?: CheckoutButtonMethod;\n },\n ) => {\n if (!isMountedRef.current) return;\n\n onErrorRef.current?.(error);\n if (options?.emitDecline) {\n emitDecline(error, options.method);\n }\n\n setOverlayError(error.message);\n setOverlayStatus('error');\n await sleep(PROCESSING_OVERLAY_ERROR_DELAY_MS);\n }, [emitDecline]);\n\n const processResolvedSession = useCallback(async (\n apiResult: Awaited<ReturnType<PaymentAPI['getUnifiedCheckoutSession']>>,\n resolvedSessionId: string | null,\n options?: {\n fromCreateSession?: boolean;\n },\n ) => {\n const session = apiResult.data.session ?? null;\n if (!session) {\n throw new FloPayError('No session data returned', 'api_error');\n }\n\n // The create-session path mints the nonce on the session (`clientSecret`);\n // the existing-session path carries it via the `nonce` prop, since a session\n // GET does not echo the token back. Prefer whichever is populated so every\n // continuation call (/process, fallback session GET) stays authorized.\n const effectiveNonce = session.clientSecret || nonce;\n\n if (session.status === 'complete') {\n await showSuccess({\n result: { status: 'succeeded' },\n session,\n sessionId: session.id || resolvedSessionId,\n autoCompleted: false,\n });\n return;\n }\n\n if (session.status === 'expired') {\n throw new FloPayError('Checkout session has expired.', 'api_error', {\n code: 'checkout_session_expired',\n });\n }\n\n try {\n if (apiResult.autoProcessingPending) {\n const api = new PaymentAPI(resolvedBillingUrl);\n const completed = await api.waitForCheckoutSessionCompletion(apiResult.autoProcessingPending.sessionId, {\n initialDelayMs: apiResult.autoProcessingPending.retryAfterMs,\n });\n const completedSession = completed.data.session;\n\n if (!completedSession || completedSession.status !== 'complete') {\n throw new FloPayError('Automatic payment failed. Please try again.', 'api_error', {\n code: completedSession?.status === 'expired'\n ? 'checkout_session_expired'\n : 'checkout_processing_timeout',\n });\n }\n\n await showSuccess({\n result: { status: 'succeeded' },\n session: completedSession,\n sessionId: completedSession.id || resolvedSessionId,\n autoCompleted: false,\n });\n return;\n }\n\n if (apiResult.autoProcessingError) {\n // 3DS challenge required on the saved PM: render the provider-hosted\n // challenge in a full-page overlay instead of treating it as a hard\n // failure. Successful completion drives backend's `/3ds/complete`\n // sync resolver and we fall through to the saved-payment success\n // path; failures (decline / timeout) propagate as a normal\n // FloPayError so the host sees `onDecline` / `onError`.\n //\n // `3ds_required` matches `CheckoutExceptionTypeEnum.ThreeDSecureRequired`\n // on the backend (the enum's literal value, not its symbol). Other\n // SDK sites (`split-card-form`, `checkout-form`) use the same\n // string — keep them in lockstep so a backend enum rename is a\n // single coordinated edit.\n if (\n apiResult.autoProcessingError.type === '3ds_required'\n && apiResult.autoProcessingError.nextActionRedirectUrl\n && resolvedSessionId\n && effectiveNonce\n ) {\n const threeDsAbort = new AbortController();\n threeDsAbortRef.current = threeDsAbort;\n let outcome: AutoCheckoutThreeDsOutcome;\n try {\n outcome = await runAutoCheckoutThreeDsChallenge({\n billingApiUrl: resolvedBillingUrl,\n sessionId: resolvedSessionId,\n nonce: effectiveNonce,\n nextActionRedirectUrl: apiResult.autoProcessingError.nextActionRedirectUrl,\n signal: threeDsAbort.signal,\n });\n } finally {\n if (threeDsAbortRef.current === threeDsAbort) {\n threeDsAbortRef.current = null;\n }\n }\n\n // Decline path: the session stays in `pending` on a decline (only\n // a successful charge flips it to `complete`), so polling\n // session-status would just time out with \"Checkout is still\n // processing.\" Use `/3ds/complete`'s own response directly — the\n // resolver already wrote the terminal Decline attempt row and\n // told us the outcome.\n if (outcome.status === 'declined') {\n throw checkoutProcessErrorToFloPayError(\n {\n type: outcome.declineReason ?? 'decline',\n message: 'Card was declined.',\n gatewayErrorCode: outcome.gatewayDeclineReason ?? undefined,\n },\n 'Card was declined.',\n {\n checkoutMethod: apiResult.autoProcessingError.checkoutMethod,\n },\n );\n }\n\n // Success path: confirm via session-status poll so we hand\n // `showSuccess` the fully populated completed session.\n // Pending / requires_action / unknown also fall through here —\n // the poll either resolves once the webhook lands or times out\n // with the normal \"still processing\" error.\n const api = new PaymentAPI(resolvedBillingUrl);\n const completed = await api.waitForCheckoutSessionCompletion(resolvedSessionId, {\n initialDelayMs: 0,\n nonce: effectiveNonce,\n });\n const completedSession = completed.data.session;\n if (!completedSession || completedSession.status !== 'complete') {\n throw checkoutProcessErrorToFloPayError(\n {\n type: 'unknown',\n message: 'Card authentication was not completed.',\n },\n 'Card authentication was not completed.',\n {\n checkoutMethod: apiResult.autoProcessingError.checkoutMethod,\n },\n );\n }\n await showSuccess({\n result: { status: 'succeeded' },\n session: completedSession,\n sessionId: completedSession.id || resolvedSessionId,\n autoCompleted: false,\n });\n return;\n }\n\n throw checkoutProcessErrorToFloPayError(\n apiResult.autoProcessingError,\n 'Automatic payment failed. Please try again.',\n {\n checkoutMethod: apiResult.autoProcessingError.checkoutMethod,\n },\n );\n }\n\n if (options?.fromCreateSession && apiResult.autoProcessingAttempted === true) {\n throw checkoutProcessErrorToFloPayError(\n {\n type: 'unknown',\n message: 'Automatic payment failed. Please try again.',\n },\n 'Automatic payment failed. Please try again.',\n );\n }\n\n // Existing-session path: backend's `createSingle` auto-checkout did not\n // run, so kick off /process. The SDK no longer ships client-built\n // `tokenizedData` — the backend resolves the customer's latest vaulted\n // payment method server-side (see `apps/api`'s `process` /\n // `processPendingSession` for the orchestration that owns this now).\n const result = await processSavedPaymentForMode({\n billingApiUrl: resolvedBillingUrl,\n sessionId: resolvedSessionId ?? session.id,\n session,\n nonce: effectiveNonce,\n });\n\n if (result.type !== 'success') {\n // The backend should not be requesting a client-side redirect when it\n // owns gateway routing. Anything other than `success` is treated as a\n // failure and falls through to the standard error path (fallback\n // checkout for recoverable cases).\n throw checkoutProcessErrorToFloPayError(\n {\n type: 'unknown',\n message: 'Automatic payment failed. Please try again.',\n },\n 'Automatic payment failed. Please try again.',\n );\n }\n\n await showSuccess({\n result: result.result,\n session,\n sessionId: session.id || resolvedSessionId,\n autoCompleted: false,\n });\n } catch (err) {\n const floPayErr = normalizeSavedPaymentError(err);\n const fallbackSessionId = session.id || resolvedSessionId;\n\n await showError(floPayErr, {\n emitDecline: true,\n method: floPayErr.checkoutMethod ?? DEFAULT_SAVED_PAYMENT_DECLINE_METHOD,\n });\n if (\n shouldShowFallbackCheckout(floPayErr, fallbackSessionId) &&\n fallbackSessionId &&\n isMountedRef.current\n ) {\n setFallbackSession({\n sessionId: fallbackSessionId,\n errorMessage: floPayErr.message,\n nonce: effectiveNonce || undefined,\n });\n }\n }\n }, [\n nonce,\n resolvedBillingUrl,\n showError,\n showSuccess,\n ]);\n\n const handleButtonClick = useCallback(async (event: React.MouseEvent<HTMLButtonElement>) => {\n buttonProps.onClick?.(event);\n\n if (event.defaultPrevented || disabled || isProcessing) {\n return;\n }\n\n setFallbackSession(null);\n\n if (sessionId && createSessionDraft) {\n const error = new FloPayError(\n 'Provide either sessionId or create-session props, not both.',\n 'validation_error',\n );\n await showError(error);\n if (isMountedRef.current) {\n setOverlayStatus(null);\n setOverlayError(null);\n }\n return;\n }\n\n if (!sessionId && !createSessionDraft) {\n const error = new FloPayError(\n 'Provide a sessionId or the props required to create an automatic payment session.',\n 'validation_error',\n );\n await showError(error);\n if (isMountedRef.current) {\n setOverlayStatus(null);\n setOverlayError(null);\n }\n return;\n }\n\n setIsProcessing(true);\n setOverlayError(null);\n setOverlayStatus('processing');\n\n try {\n const api = new PaymentAPI(resolvedBillingUrl);\n\n if (sessionId) {\n const result = await api.getUnifiedCheckoutSession(sessionId, nonce);\n await processResolvedSession(result, sessionId);\n return;\n }\n\n try {\n const result = await api.createAndFetchSession({\n ...createSessionDraft!,\n });\n await processResolvedSession(result, result.data.session?.id ?? null, {\n fromCreateSession: true,\n });\n } catch (err) {\n if (err instanceof FloPayError && err.code === 'session_auto_completed') {\n await showSuccess({\n result: { status: 'succeeded' },\n session: null,\n sessionId: null,\n autoCompleted: true,\n });\n return;\n }\n\n throw err;\n }\n } catch (err) {\n await showError(\n coerceError(err, 'Automatic payment failed. Please try again.'),\n );\n } finally {\n if (isMountedRef.current) {\n setOverlayStatus(null);\n setOverlayError(null);\n setIsProcessing(false);\n }\n }\n }, [\n buttonProps,\n createSessionDraft,\n disabled,\n isProcessing,\n nonce,\n processResolvedSession,\n resolvedBillingUrl,\n sessionId,\n showError,\n showSuccess,\n ]);\n\n const handleFallbackComplete = useCallback((result: PaymentResult) => {\n const activeFallback = fallbackSessionRef.current;\n setFallbackSession(null);\n onSuccessRef.current?.({\n result,\n session: null,\n sessionId: activeFallback?.sessionId ?? null,\n autoCompleted: false,\n });\n }, []);\n\n const handleFallbackError = useCallback((error: FloPayError) => {\n onErrorRef.current?.(error);\n }, []);\n\n const handleFallbackDecline = useCallback((decline: DeclineEvent) => {\n onDeclineRef.current?.(decline);\n }, []);\n\n // Resolution: `theme` (high-level bundle) takes precedence over the legacy\n // `buttonsTheme` preset; explicit `buttonsStyles` overrides individual fields\n // on top of whichever base was chosen.\n const themeBundle = useMemo(() => resolveTheme(theme), [theme]);\n const bStyles = useMemo<ButtonsLayoutStyles>(() => {\n const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme(buttonsTheme);\n if (!stylesOverride) return base;\n return {\n ...base,\n ...stylesOverride,\n cardButton: { ...base.cardButton, ...stylesOverride.cardButton },\n };\n }, [themeBundle, buttonsTheme, stylesOverride]);\n\n // Per-checkout `appearance` overrides are *layered on top of* the bundle's\n // appearance (per the prop's \"layered on top\" contract): merge variables\n // per-key — the checkout-level value wins, but unspecified keys keep the\n // theme's values instead of reverting to hardcoded defaults. Replacing the\n // whole object (the old `appearance ?? themeBundle.appearance`) dropped theme\n // colours on a partial override and desynced this button from the fallback\n // modal. These drive the button fill (`colorPrimary`) + hover\n // (`colorPrimaryHover`) so a custom theme re-skins the auto-pay button in\n // lock-step with the rest of the checkout.\n const resolvedAppearance = useMemo<FloPayAppearance | undefined>(() => {\n const bundleAppearance = themeBundle?.appearance;\n if (!appearance) return bundleAppearance;\n if (!bundleAppearance) return appearance;\n return {\n ...bundleAppearance,\n ...appearance,\n variables: {\n ...bundleAppearance.variables,\n ...appearance.variables,\n },\n };\n }, [appearance, themeBundle]);\n const resolvedAppearanceVars = resolvedAppearance?.variables;\n const resolvedPrimaryColor =\n (resolvedAppearanceVars?.colorPrimary as string | undefined) ?? '#4A49FF';\n const resolvedPrimaryHoverColor =\n (resolvedAppearanceVars?.colorPrimaryHover as string | undefined)\n ?? darkenHex(resolvedPrimaryColor, 0.12);\n const resolvedButtonBorderRadius =\n (resolvedAppearanceVars?.borderRadius as string | undefined) ?? '8px';\n\n const cardButtonSizing = children === undefined\n ? { boxSizing: 'border-box' as const, height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: '0 1rem' }\n : { padding: '0.9rem 1rem' };\n\n return (\n <>\n <button\n {...buttonProps}\n type={type}\n onClick={handleButtonClick}\n disabled={disabled || isProcessing}\n aria-busy={isProcessing}\n style={{\n width: '100%',\n ...cardButtonSizing,\n // `bStyles.cardButton` first so the bundle's padding / typography\n // / radius / shadow come through, then `derivePrimaryTileStyle`\n // on top so the auto-pay button carries the *submit* button's\n // background and text colours — making it visually identical to\n // the \"Confirm Payment\" / \"Pay with X\" actions it stands in for.\n // `resolvedPrimaryColor` is the *merged* appearance value, so a\n // per-checkout `colorPrimary` override re-skins this button too.\n // Inline `style` consumer override stays at the end so explicit\n // per-button overrides still win.\n ...bStyles.cardButton as React.CSSProperties,\n ...derivePrimaryTileStyle({\n themeBundle,\n resolvedPrimaryColor,\n resolvedBorderRadius: resolvedButtonBorderRadius,\n submitButtonStyle: bStyles.submitButton as React.CSSProperties | undefined,\n explicitPrimaryColor: resolvedAppearanceVars?.colorPrimary as string | undefined,\n }),\n fontSize: bStyles.cardButtonFontSize ?? '0.95rem',\n fontWeight: 600,\n cursor: disabled || isProcessing ? 'not-allowed' : 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '0.625rem',\n transition: 'background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s',\n position: 'relative',\n opacity: disabled || isProcessing ? 0.6 : 1,\n ...style,\n }}\n onMouseEnter={(e) => {\n buttonProps.onMouseEnter?.(e);\n // Hover on any primary-filled button (themed bundle OR an explicit\n // `colorPrimary` override); the classic white tile with no override\n // keeps its static look. Skip while disabled / processing.\n if (!e.defaultPrevented && !disabled && !isProcessing && (themeBundle || resolvedAppearanceVars?.colorPrimary)) {\n e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;\n }\n }}\n onMouseLeave={(e) => {\n buttonProps.onMouseLeave?.(e);\n if (!e.defaultPrevented && (themeBundle || resolvedAppearanceVars?.colorPrimary)) {\n e.currentTarget.style.backgroundColor = resolvedPrimaryColor;\n }\n }}\n onMouseDown={(e) => {\n buttonProps.onMouseDown?.(e);\n if (!e.defaultPrevented) {\n e.currentTarget.style.transform = 'scale(0.985)';\n }\n }}\n onMouseUp={(e) => {\n buttonProps.onMouseUp?.(e);\n if (!e.defaultPrevented) {\n e.currentTarget.style.transform = 'scale(1)';\n }\n }}\n >\n <CardButtonContentSlot content={children} />\n </button>\n {overlayStatus && (\n <ProcessingOverlay\n status={overlayStatus}\n errorMessage={overlayError}\n />\n )}\n {fallbackSession && (\n <div\n data-testid=\"flopay-automatic-payment-fallback\"\n role=\"dialog\"\n aria-modal=\"true\"\n onClick={(event) => {\n if (event.target === event.currentTarget) {\n setFallbackSession(null);\n }\n }}\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0, 0, 0, 0.45)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '1.5rem',\n zIndex: 1100,\n }}\n >\n <div\n style={{\n width: '100%',\n maxWidth: 520,\n maxHeight: '90vh',\n overflowY: 'auto',\n background: 'white',\n borderRadius: 20,\n padding: '1.5rem',\n boxShadow: '0 24px 80px rgba(15, 23, 42, 0.28)',\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n }}\n >\n <FloPayCheckout\n sessionId={fallbackSession.sessionId}\n nonce={fallbackSession.nonce}\n checkoutMode=\"full\"\n billingApiUrl={resolvedBillingUrl}\n locale={locale}\n theme={theme}\n {...(resolvedAppearance ? { appearance: resolvedAppearance } : {})}\n buttonsTheme={buttonsTheme}\n buttonsStyles={stylesOverride}\n initialErrorMessage={fallbackSession.errorMessage}\n cardTitleContent={null}\n onComplete={handleFallbackComplete}\n onError={handleFallbackError}\n onDecline={handleFallbackDecline}\n />\n </div>\n </div>\n )}\n </>\n );\n}\n"],"mappings":"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","names":["React","useCallback","useEffect","useMemo","useRef","useState","PaymentAPI","SDK_VERSION","FloPayError","resolveBillingApiUrl","resolveButtonsLayoutTheme","resolveTheme","jsx","PaymentAPI","useEffect","useRef","jsx","jsx","jsxs","React","useCallback","useContext","useEffect","useMemo","useRef","useState","resolveBillingApiUrl","resolveBillingApiUrl","jsx","jsxs","useCallback","useEffect","useMemo","useRef","useState","FloPayError","jsx","jsxs","useMemo","useEffect","useRef","useState","useCallback","FloPayError","FloPayError","isSetupIntentClientSecret","Fragment","jsx","jsxs","PaymentAPI","useRef","useCallback","useEffect","useState","useMemo","React","useContext","invalidAvsFields","avsInvalid","resolvedAccount","avsConfig","avsCheckProp","stateValue","baseUrl","sessionId","nonce","updateError","onError","emitDecline","message","error","PaymentAPI","FloPayError","isSetupIntentClientSecret","error","FloPayError","PaymentAPI","isSetupIntentClientSecret","FloPayError","Fragment","jsx","jsxs","DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT","SDK_VERSION","resolveBillingApiUrl","useMemo","resolveTheme","useState","useRef","useEffect","useCallback","FloPayError","activeSessionId","PaymentAPI","React","resolveButtonsLayoutTheme","useEffect","useRef","useContext","jsx","useRef","useContext","useEffect","PaymentElement","PaymentAPI","FloPayError","useCallback","useEffect","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useCallback","PaymentAPI","useEffect","FloPayError","useCallback","useEffect","useMemo","useRef","useState","PaymentAPI","FloPayError","resolveBillingApiUrl","resolveButtonsLayoutTheme","resolveTheme","Fragment","jsx","jsxs","DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT","sleep","FloPayError","useMemo","resolveBillingApiUrl","useState","useRef","useEffect","useCallback","PaymentAPI","resolveTheme","resolveButtonsLayoutTheme"]}