@flopay/react 1.4.1 → 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.
package/README.md CHANGED
@@ -53,13 +53,13 @@ function CheckoutPage() {
53
53
  }
54
54
  ```
55
55
 
56
- `FloPayCheckout` automatically fetches the session, initializes the correct payment provider, and renders a `SplitCardForm` with card fields, Apple Pay, Google Pay, and PayPal. Customer data (email, userId, name) is injected from the session.
56
+ `FloPayCheckout` automatically fetches the session, initializes the correct payment providers, and renders a `SplitCardForm` with the hosted vault card widget plus the session's supported wallets, APMs, and PayPal. Customer data (email, userId, name) is injected from the session.
57
57
 
58
58
  #### Checkout Modes
59
59
 
60
60
  `FloPayCheckout` supports three checkout modes matching the billing API's `checkoutMode` field:
61
61
 
62
- - **`full`** (default) — Shows the full payment form with card fields + wallet buttons.
62
+ - **`full`** (default) — Shows the hosted card widget plus supported non-card methods.
63
63
  - **`confirm`** — Hides the payment form and shows a "Confirm Purchase" button. Uses a saved payment method on the backend.
64
64
  - **`auto`** — Auto-submits with a saved payment method after the session loads. Falls back to `full` mode on failure.
65
65
 
@@ -211,7 +211,7 @@ two gateway-level props:
211
211
  ```tsx
212
212
  <FloPayCheckout
213
213
  sessionId="sess_abc123"
214
- showStripe={true} // default: true — card + ECE + PaymentElement
214
+ showStripe={true} // default: true — Stripe wallets/APMs only
215
215
  showPayPal={true} // default: true — DirectPayPal when gateway present,
216
216
  // Stripe-rendered PayPal otherwise
217
217
  onComplete={handleSuccess}
@@ -234,7 +234,7 @@ legacy props will be removed in `2.0`.
234
234
 
235
235
  #### Theming
236
236
 
237
- `FloPayCheckout`, `FloPayAutomaticPaymentButton`, and `SplitCardForm` accept a single `theme` prop that maps to a coherent `{appearance, buttonsLayout}` bundle in `@flopay/shared`'s `THEMES` map. One value styles the Stripe-side appearance, the React-rendered wrapper, the submit button, the inputs, and — for `FloPayAutomaticPaymentButton` — the fallback modal that opens when a saved-payment charge can't complete silently.
237
+ `FloPayCheckout`, `FloPayAutomaticPaymentButton`, and `SplitCardForm` accept a single `theme` prop that maps to a coherent `{appearance, buttonsLayout}` bundle in `@flopay/shared`'s `THEMES` map. One value styles non-card Stripe Elements, the React-rendered wrapper and AVS inputs, the hosted vault widget, and — for `FloPayAutomaticPaymentButton` — the fallback modal that opens when a saved-payment charge can't complete silently.
238
238
 
239
239
  | `theme` | Aesthetic |
240
240
  |---|---|
@@ -380,87 +380,9 @@ When you use `onBeforeButtonClick` with `createSession`, any returned `InlineSes
380
380
 
381
381
  ### Advanced: Manual Provider Setup
382
382
 
383
- For full control over initialization:
384
-
385
- ```tsx
386
- import { loadFloPay } from '@flopay/js';
387
- import { FloPayProvider, CheckoutForm } from '@flopay/react';
388
-
389
- const floPayPromise = loadFloPay('pk_test_...');
390
-
391
- function CheckoutPage() {
392
- return (
393
- <FloPayProvider
394
- flopay={floPayPromise}
395
- options={{
396
- amount: 2999,
397
- currency: 'usd',
398
- }}
399
- >
400
- <CheckoutForm
401
- sessionId="session_uuid"
402
- nonce={sessionNonce}
403
- email="user@example.com"
404
- userId="user_1"
405
- onComplete={(result) => {
406
- if (result.status === 'succeeded') {
407
- window.location.href = '/success';
408
- }
409
- }}
410
- onError={(err) => console.error(err)}
411
- />
412
- </FloPayProvider>
413
- );
414
- }
415
- ```
416
-
417
- `CheckoutForm` handles the full payment lifecycle by default:
418
-
419
- 1. Validate elements via `submitElements()`
420
- 2. Tokenize card via `createPaymentMethod()` -> `pm_xxx`
421
- 3. Create PaymentIntent via billing API
422
- 4. Confirm card payment (handles 3D Secure)
423
- 5. Submit tokenized body to `POST /v1/checkouts/sessions/<id>/process`
424
- 6. If backend returns `3ds_required`, re-confirm with new client secret
425
- 7. Resume wallet payments after redirect (PayPal)
426
-
427
- Pass `nonce` (the session-bound checkout token returned by session creation —
428
- `CheckoutSessionResult.nonce`, or `session.clientSecret` once the session is
429
- loaded). The SDK forwards it as `x-checkout-session-token` on every
430
- continuation call. Post-#640 backends (`TeamFloPay/backend#640`) 401 when the
431
- header is missing. `FloPayCheckout` already plumbs the prop automatically.
432
-
433
- ### Override Mode (Custom Backend)
434
-
435
- Pass `onTokenizedBody` to handle backend submission yourself:
436
-
437
- ```tsx
438
- <CheckoutForm
439
- sessionId="session_uuid"
440
- billingApiUrl="https://billing.example.com"
441
- email="user@example.com"
442
- onTokenizedBody={(body) => {
443
- // body = {
444
- // id: 'pm_xxx',
445
- // type: 'card',
446
- // threeDSecureActionResultTokenId: 'pi_xxx',
447
- // originalPaymentMethodId: 'pm_xxx',
448
- // }
449
- myCustomProcessPayment(body);
450
- }}
451
- />
452
- ```
453
-
454
- > **Vault card path — `onTokenizedBody` does not fire.** When the session uses the
455
- > [vault PCI card form](#vault-pci-card-form), the backend-served widget owns the
456
- > whole charge (tokenize → PaymentIntent → 3DS → result), so there is no
457
- > client-side tokenization step to override. Use `onComplete` / `onDecline` /
458
- > `onError` instead — the SDK relays the widget's terminal outcome to them. The
459
- > legacy Stripe path's `onTokenizedBody` is unchanged.
460
-
461
- ### SplitCardForm (Split Card Fields + PayPal)
462
-
463
- `SplitCardForm` renders separate CardNumber, CardExpiry, and CardCVC fields with an integrated PayPal button. It matches the existing checkout/StripeCardForm layout.
383
+ Use `SplitCardForm` when you need to compose the provider and session yourself.
384
+ Card checkout still requires the backend-hosted vault block; Stripe remains
385
+ limited to wallets/APMs and saved-payment authentication.
464
386
 
465
387
  ```tsx
466
388
  import { FloPayProvider, SplitCardForm } from '@flopay/react';
@@ -480,12 +402,13 @@ function CheckoutPage() {
480
402
  <SplitCardForm
481
403
  sessionId="session_uuid"
482
404
  nonce={sessionNonce}
405
+ session={session}
483
406
  billingApiUrl="https://billing.example.com"
484
407
  email="user@example.com"
485
408
  userId="user_1"
486
- totalAmount={29.99} // dollars (for PayPal Elements config)
409
+ totalAmount={2999} // cents
487
410
  currency="usd"
488
- showPayPal={true} // default: true
411
+ enabledPaymentMethods={session.gateways?.stripe?.enabledPaymentMethods}
489
412
  onComplete={(result) => {
490
413
  if (result.status === 'succeeded') {
491
414
  window.location.href = '/success';
@@ -500,26 +423,33 @@ function CheckoutPage() {
500
423
  }
501
424
  ```
502
425
 
503
- The `SplitCardForm` layout:
504
- 1. Wallet buttons — Apple Pay + Google Pay (via ExpressCheckoutElement in the main Elements instance)
505
- 2. PayPal button (via ExpressCheckoutElement in a separate Elements instance)
506
- 3. "or pay with card" divider
507
- 4. Card Number input
508
- 5. Card Expiry + CVC side by side
509
- 6. Full Name input
510
- 7. Submit button
426
+ The resulting surfaces are:
427
+
428
+ 1. Wallet buttons and supported APM tiles from the session gateway capability.
429
+ 2. Direct or Stripe-hosted PayPal, selected from the session gateways.
430
+ 3. The hosted vault widget for card-capable sessions.
431
+
432
+ Wallets, APMs, and PayPal create intents through
433
+ `POST /v1/checkouts/sessions/{id}/intents`. The discriminated request separates
434
+ provider, payment-method category/type/id, and intent kind. Direct-card intent
435
+ requests are unsupported. Client-observed non-card failures use the
436
+ nonce-protected session decline endpoint and contain no payment tokens,
437
+ provider object IDs, card data, credentials, or PII.
438
+
439
+ If a card-capable backend omits the vault block, card checkout stays hidden.
440
+ Advertised non-card methods remain usable; if none remain,
441
+ `onError` receives `UnsupportedBackendVaultCapability`.
511
442
 
512
443
  #### AVS postcode validation
513
444
 
514
445
  When AVS collection is enabled (`enableAVS`) and the postcode field is shown,
515
446
  `SplitCardForm` validates the postcode **format against the live selected
516
- country before the card is captured**, on both the Stripe and vault card paths.
447
+ country before the hosted vault captures the card**.
517
448
  It reuses `@flopay/shared`'s country-aware
518
449
  [postcode helpers](../shared/README.md#postal-code-helpers) (the same
519
450
  `validator` rules the billing API applies), so client and server agree.
520
451
 
521
- - **Supported country + malformed postcode** → the submit is blocked (the vault
522
- widget's submit button is gated; the Stripe path returns before tokenizing)
452
+ - **Supported country + malformed postcode** → the vault widget's submit is blocked
523
453
  and an inline, country-specific message shows the expected format
524
454
  (e.g. *"Enter a valid ZIP Code (e.g. 12345 or 12345-6789)"*). On the vault
525
455
  path the inline message appears once the field is blurred, since the disabled
@@ -560,17 +490,18 @@ best-effort **in parallel** with the widget's charge:
560
490
 
561
491
  When the billing API returns a hosted vault card form on the session
562
492
  (`session.vault`), the card path renders a **backend-served, self-contained
563
- hosted vault widget** (`VaultCardFields`) instead of Stripe's embedded card
564
- elements (TeamFloPay/backend#823, Model A). The backend embeds this block for
565
- any SDK that advertises `x-flo-sdk-version >= 1.3.0`, so it is fully
493
+ hosted vault widget** (`VaultCardFields`) (TeamFloPay/backend#823, Model A).
494
+ Every card-capable session is
495
+ expected to include this block without SDK-version dispatch. It is fully
566
496
  **server-driven** — there is no consumer prop to toggle it. The widget owns the
567
497
  card fields, its own submit button, card tokenization, the PaymentIntent (created
568
498
  **and** confirmed server-side), **3DS**, and the result, so **no Stripe.js runs
569
499
  on the card path** and PAN / CVC never enter the SDK runtime. Wallets / PayPal /
570
500
  APMs render exactly as before.
571
501
 
572
- Because the widget owns the form, on the vault path `SplitCardForm` hides its own
573
- card fields, cardholder-name input, AVS fields, and submit button. The flow is:
502
+ Because the widget owns the form, `SplitCardForm` exposes no SDK card-entry or
503
+ card-submit controls. Host-collected AVS fields remain outside the PCI
504
+ widget and gate its submit. The flow is:
574
505
 
575
506
  ```text
576
507
  session includes a hosted vault card form (session.vault)
@@ -579,9 +510,8 @@ session includes a hosted vault card form (session.vault)
579
510
  → widget postMessages its outcome → SDK fires onComplete / onDecline / onError
580
511
  ```
581
512
 
582
- - The widget HTML comes from the embedded `session.vault.html` (SDKs ≥ 1.3.0 send
583
- `X-Flo-SDK-Version`, so the backend embeds it on create-session) or, if absent,
584
- from `POST /v1/checkouts/sessions/{id}/vault/capture`.
513
+ - The widget HTML normally comes from embedded `session.vault.html`; the explicit
514
+ recovery/retry path is `POST /v1/checkouts/sessions/{id}/vault/capture`.
585
515
  - **Returning customers** with a card on file (`session.providerPaymentMethodId`)
586
516
  are charged by the backend's auto-checkout cascade.
587
517
  - **3DS** is handled inside the widget — there is no client-side `confirmCardPayment`.
@@ -591,9 +521,10 @@ session includes a hosted vault card form (session.vault)
591
521
 
592
522
  > **Backend dependencies:** the hosted widget must emit the `flopay-vault`
593
523
  > `postMessage` outcome the SDK listens for (otherwise it falls back to its own
594
- > success redirect), handle the 3DS step internally, and own AVS for the vault
595
- > path (the SDK no longer collects it inline; account-level address set at
596
- > session-create still flows to the backend). Because the widget is injected
524
+ > success redirect), handle the 3DS step internally, and use the session account
525
+ > snapshot for AVS. The SDK collects and validates those address fields outside
526
+ > the PCI widget and persists them through the session account endpoint; the
527
+ > widget owns only sensitive card-data capture. Because the widget is injected
597
528
  > **same-window**, every terminal outcome must be bound to the session id, and —
598
529
  > to fully defend against same-window forgery — the backend should mint a
599
530
  > per-session `messageToken` on the vault block and echo it in each
@@ -605,12 +536,35 @@ session includes a hosted vault card form (session.vault)
605
536
  The SDK supports two PayPal paths, selected per-session based on what the billing API advertises under `gateways.*`:
606
537
 
607
538
  - **Direct PayPal** (preferred where available — works inside Facebook, Instagram, and other in-app browsers): when the session exposes `gateways.paypal.publishableKey`, the SDK renders PayPal via the official PayPal JS SDK using `<DirectPayPalButton>`. The PayPal client ID and `environment` (`'sandbox'`/`'live'`) come directly from the backend.
608
- - **Stripe-rendered PayPal fallback** (legacy): when only `gateways.stripe` is configured, PayPal renders through Stripe's `ExpressCheckoutElement` in its own Elements wrapper. This path can't render in Facebook/Instagram in-app browsers.
539
+ - **Stripe-rendered PayPal**: when only `gateways.stripe` is configured, PayPal renders through Stripe's `ExpressCheckoutElement` in its own Elements wrapper. This path can't render in Facebook/Instagram in-app browsers.
609
540
 
610
541
  Renderer selection is mutually exclusive per session — direct PayPal takes priority over Stripe-rendered PayPal. Consumer props such as `showPayPal` continue to gate visibility on the client side.
611
542
 
612
543
  **PayPal-only sessions:** When the backend advertises only `gateways.paypal` (no `gateways.stripe`), `FloPayCheckout` skips Stripe Elements entirely and renders `<DirectPayPalButton>` as the sole payment surface. Sessions that advertise no supported gateway at all throw a `validation_error` explaining the expected shape.
613
544
 
545
+ **Direct PayPal initialization recovery:** PayPal's own cross-window bridge owns
546
+ its 10-second `postMessage init()` acknowledgement deadline; FloPay does not
547
+ change that upstream timeout. If the exact acknowledgement timeout is reported,
548
+ or if `Buttons.render()` is still unsettled after 11 seconds, the SDK hides
549
+ Direct PayPal, waits one second, and makes exactly one background render retry.
550
+ The retry uses a fresh render generation, and callbacks or promise settlements
551
+ from the superseded generation are ignored.
552
+
553
+ In a mixed checkout, card, wallets, APMs, and any other eligible methods remain
554
+ interactive throughout recovery. If both Direct PayPal attempts fail, PayPal
555
+ stays hidden for that component configuration; the SDK emits one sanitized
556
+ console diagnostic and calls neither `onError` nor `onDecline`. Deterministic
557
+ configuration failures and `isEligible() === false` are not automatically
558
+ retried.
559
+
560
+ In a PayPal-only checkout, `FloPayCheckout` shows an accessible retrying status
561
+ instead of a blank surface. After automatic recovery is exhausted, it shows safe
562
+ generic unavailable copy and a **Retry PayPal** button. `onError` fires once with
563
+ a `FloPayError` whose `type` is `api_error` and whose stable `code` is
564
+ `paypal_init_timeout`; `onDecline` does not fire and the raw provider message is
565
+ never rendered. Manual retry reuses the current checkout session and performs
566
+ one fresh render attempt without adding another automatic retry.
567
+
614
568
  The SDK exposes the relevant pieces in three ways:
615
569
 
616
570
  - **`SplitCardForm`** / **`FloPayCheckout`**: pick the renderer automatically based on `gateways.*`. No additional configuration needed.
@@ -622,7 +576,7 @@ The SDK exposes the relevant pieces in three ways:
622
576
  - **`PayPalButton`** (standalone): Must be rendered inside its own `FloPayProvider`:
623
577
 
624
578
  ```tsx
625
- {/* Card fields provider */}
579
+ {/* Main checkout provider */}
626
580
  <FloPayProvider flopay={flopay} options={{ amount, currency }}>
627
581
  <SplitCardForm ... />
628
582
  </FloPayProvider>
@@ -638,31 +592,30 @@ The SDK exposes the relevant pieces in three ways:
638
592
  </FloPayProvider>
639
593
  ```
640
594
 
641
- ### Using Individual Elements
595
+ ### Using Individual Non-card Elements
642
596
 
643
597
  ```tsx
644
- import { FloPayProvider, PaymentElement, CardElement, useFloPay } from '@flopay/react';
598
+ import { AddressElement, PaymentElement } from '@flopay/react';
645
599
 
646
600
  function CustomForm() {
647
- const flopay = useFloPay();
648
-
649
- const handleSubmit = async () => {
650
- if (!flopay) return;
651
- const { error } = await flopay.submitElements();
652
- if (error) return console.error(error);
653
- const { paymentMethodId } = await flopay.createPaymentMethod();
654
- // Use paymentMethodId...
655
- };
656
-
657
601
  return (
658
602
  <div>
659
- <PaymentElement options={{ layout: 'tabs' }} />
660
- <button onClick={handleSubmit}>Pay</button>
603
+ <PaymentElement
604
+ options={{
605
+ layout: 'tabs',
606
+ paymentMethodTypes: ['cashapp', 'ideal'],
607
+ }}
608
+ />
609
+ <AddressElement />
661
610
  </div>
662
611
  );
663
612
  }
664
613
  ```
665
614
 
615
+ These elements support wallet/APM and address collection. `PaymentElement`
616
+ requires a non-empty `paymentMethodTypes` allowlist and rejects `card`; use the
617
+ hosted vault checkout surface for card payments.
618
+
666
619
  ### Using Hooks
667
620
 
668
621
  ```tsx
@@ -685,15 +638,12 @@ function PaymentStatus() {
685
638
  | Component | Description |
686
639
  |-----------|-------------|
687
640
  | `FloPayProvider` | Context provider. Accepts `flopay` (instance or promise), `options?`, and `children`. Creates the elements group automatically. |
688
- | `CheckoutForm` | Drop-in form with unified PaymentElement. Self-contained by default, or override with `onTokenizedBody`. Supports `ref` for imperative `handleNextAction()`. |
689
- | `SplitCardForm` | Split card form (CardNumber + CardExpiry + CardCvc + Full Name). Integrates PayPal via separate Elements instance. Renders the [vault PCI card form](#vault-pci-card-form) when the session includes a hosted vault card form (`session.vault`). Supports `ref` for imperative `handleNextAction()`. |
641
+ | `FloPayCheckout` | Recommended self-contained session checkout. Resolves gateways, mounts hosted-vault cards, and preserves wallets/APMs/PayPal/saved-payment flows. |
642
+ | `SplitCardForm` | Advanced checkout surface combining hosted-vault cards with wallets, APMs, and PayPal. Supports `ref` for imperative next-action handling. |
690
643
  | `VaultCardFields` | Hosted vault PCI card fields. Used internally by `SplitCardForm` on the vault path; consumes a `CardCaptureAdapter` from `useFloPay().cardCapture()`. |
691
644
  | `PayPalButton` | Standalone PayPal button. Requires its own `FloPayProvider` with `paymentMethodCreation` set to something other than `'manual'`. |
692
- | `PaymentElement` | Unified payment element (cards, wallets, etc.) |
693
- | `CardElement` | Combined card input |
694
- | `CardNumberElement` | Card number field |
695
- | `CardExpiryElement` | Card expiry field |
696
- | `CardCvcElement` | Card CVC field |
645
+ | `DirectPayPalButton` | Standalone direct PayPal order/subscription button using the session-scoped intent contract. |
646
+ | `PaymentElement` | Provider element for an explicitly declared non-card `paymentMethodTypes` allowlist. |
697
647
  | `AddressElement` | Address input element |
698
648
 
699
649
  ### Hooks
@@ -711,9 +661,9 @@ function PaymentStatus() {
711
661
  | `flopay` | `Promise<FloPay> \| FloPay` | SDK instance or promise from `loadFloPay()` |
712
662
  | `options.locale` | `string?` | Locale |
713
663
  | `options.appearance` | `FloPayAppearance?` | Theme appearance |
714
- | `options.clientSecret` | `string?` | PaymentIntent client secret (if intent already exists) |
715
- | `options.amount` | `number?` | Amount in cents (used when no `clientSecret`) |
716
- | `options.currency` | `string?` | ISO 4217 currency code (used when no `clientSecret`) |
664
+ | `options.clientSecret` | `string?` | Existing non-card PaymentIntent or SetupIntent secret; the SDK verifies the provider intent against `PaymentElement`'s explicit wallet/APM allowlist before mounting and rejects card or undeclared methods. Card checkout uses the hosted vault. |
665
+ | `options.amount` | `number?` | Amount in cents for deferred non-card Elements without a `clientSecret` |
666
+ | `options.currency` | `string?` | ISO 4217 currency code for deferred non-card Elements without a `clientSecret` |
717
667
  | `options.paymentMethodCreation` | `'manual' \| 'auto'` | How payment methods are created |
718
668
 
719
669
  ### Privacy-safe operational telemetry
@@ -734,38 +684,19 @@ No endpoint, custom tag, user context, message, stack, or metadata can be
734
684
  configured. See [`docs/TELEMETRY.md`](../../docs/TELEMETRY.md) for the complete
735
685
  privacy and retention contract.
736
686
 
737
- ### CheckoutFormProps
738
-
739
- | Prop | Type | Description |
740
- |------|------|-------------|
741
- | `sessionId` | `string` | Checkout session UUID |
742
- | `billingApiUrl` | `string` | Billing API base URL |
743
- | `email` | `string?` | User email |
744
- | `userId` | `string?` | User ID |
745
- | `onComplete` | `(result: PaymentResult) => void` | Success callback |
746
- | `onError` | `(error: FloPayError) => void` | Error callback |
747
- | `onTokenizedBody` | `(body: TokenizedBody) => void` | Override: handle backend submission yourself |
748
- | `layout` | `'tabs' \| 'accordion' \| 'auto'` | PaymentElement layout (default: `'auto'`) |
749
- | `submitLabel` | `string` | Button text (default: `'Pay'`) |
750
- | `showAddress` | `boolean \| 'billing' \| 'shipping'` | Show address element (default: `false`) |
751
- | `className` | `string?` | CSS class for form wrapper |
752
- | `children` | `ReactNode?` | Custom submit button |
753
- | `firstName` | `string?` | Billing first name |
754
- | `lastName` | `string?` | Billing last name |
755
- | `chv` | `string?` | Checkout version for A/B tracking |
756
- | `isProcessing` | `boolean?` | External processing state |
757
- | `error` | `string?` | External error message |
758
- | `onErrorChange` | `(error: string \| null) => void` | Error state change callback |
759
-
760
687
  ### SplitCardFormProps
761
688
 
762
- Shares most props with `CheckoutFormProps`, plus:
689
+ Key payment-surface props include:
763
690
 
764
691
  | Prop | Type | Description |
765
692
  |------|------|-------------|
766
- | `showStripe` | `boolean` | Show the whole Stripe surface (card + ECE + PaymentElement). Default: `true`. Setting `showStripe={false}` together with `showPayPal={false}` (or no PayPal gateway) emits a `FloPayError({ type: 'validation_error' })` via `onError`. |
693
+ | `sessionId` | `string` | Checkout session UUID. |
694
+ | `nonce` | `string` | Session-bound token forwarded on intent, decline, account, and process calls. |
695
+ | `session` | `CheckoutSession?` | Session capability data, including the hosted `vault` block and gateways. |
696
+ | `billingApiUrl` | `string` | Billing API base URL. |
697
+ | `showStripe` | `boolean` | Show Stripe-backed wallets/APMs. Card checkout is controlled by the session vault capability. |
767
698
  | `showPayPal` | `boolean` | Show PayPal. Renderer chosen by `gateways.paypal` presence (DirectPayPal JS SDK when present; Stripe-rendered PayPal otherwise). Default: `true`. |
768
- | `enabledPaymentMethods` | `string[]?` | Per-session list of Stripe method type identifiers (`apple_pay`, `google_pay`, `cashapp`, `klarna`, `link`, `amazon_pay`, `sepa_debit`, `affirm`, `ideal`, …). Normally threaded automatically from `gateways.stripe.enabledPaymentMethods` by `FloPayCheckout`. The SDK partitions it into the ExpressCheckoutElement big-button row (intersected with `STRIPE_EXPRESS_METHODS`) and the accordion PaymentElement region (everything else; `card` is always dropped because the split fields render the card path). |
699
+ | `enabledPaymentMethods` | `string[]?` | Per-session list of Stripe method type identifiers (`apple_pay`, `google_pay`, `cashapp`, `klarna`, `link`, `amazon_pay`, `sepa_debit`, `affirm`, `ideal`, …). Normally threaded automatically from `gateways.stripe.enabledPaymentMethods` by `FloPayCheckout`. The SDK partitions it into the ExpressCheckoutElement big-button row (intersected with `STRIPE_EXPRESS_METHODS`) and the accordion PaymentElement region; `card` is always dropped because the hosted vault owns that path. |
769
700
  | `showApplePay` | `boolean` | *Deprecated.* Apple Pay availability is dashboard-controlled at Stripe and surfaces through `enabledPaymentMethods`. Emits a one-time `console.warn` when supplied alongside `enabledPaymentMethods` and is otherwise ignored. Removed in `2.0`. |
770
701
  | `showGooglePay` | `boolean` | *Deprecated.* See `showApplePay`. |
771
702
  | `directPaypal` | `{ clientId: string; environment?: GatewayEnvironment }?` | *Deprecated input on `FloPayCheckout`* — auto-resolved from `gateways.paypal` on the session response. Still accepted on `SplitCardForm` for advanced consumers wiring providers manually. |
@@ -773,7 +704,7 @@ Shares most props with `CheckoutFormProps`, plus:
773
704
  | `currency` | `string` | Currency code for PayPal / wallet config (default: `'usd'`) |
774
705
  | `onFirstNameChange` | `(value: string) => void` | First name change callback |
775
706
  | `onLastNameChange` | `(value: string) => void` | Last name change callback |
776
- | `submitLabel` | `string` | Button text (default: `'CONFIRM PAYMENT'`) |
707
+ | `onComplete` / `onDecline` / `onError` | callbacks | Observable checkout outcomes. |
777
708
 
778
709
  ### ElementComponentProps (shared by all element components)
779
710
 
@@ -794,10 +725,7 @@ Shares most props with `CheckoutFormProps`, plus:
794
725
  | Type | Description |
795
726
  |------|-------------|
796
727
  | `FloPayProviderProps` | Props for `FloPayProvider` |
797
- | `CheckoutFormProps` | Props for `CheckoutForm` |
798
- | `CheckoutFormRef` | Ref type: `{ handleNextAction(clientSecret) }` |
799
728
  | `SplitCardFormProps` | Props for `SplitCardForm` |
800
- | `SplitCardFormRef` | Ref type: `{ handleNextAction(clientSecret) }` |
801
729
  | `PayPalButtonProps` | Props for `PayPalButton` |
802
730
  | `ElementComponentProps` | Shared props for all element components |
803
731
  | `CheckoutState` | `{ session, loading, error }` |