@flopay/react 1.4.7 → 1.4.10

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
@@ -182,6 +182,10 @@ partitions that list into two regions inside `SplitCardForm`:
182
182
  - `PaymentElement` (accordion) — every other enabled method, e.g. `cashapp`,
183
183
  `affirm`, `ideal`, `bancontact`, `sepa_debit`.
184
184
 
185
+ `card` is a capability marker, not a Stripe-rendered method. It keeps the
186
+ **Credit / Debit Card** path available and tells SDK 1.4.9+ that the hosted
187
+ vault form can be requested lazily when `session.vault` is absent.
188
+
185
189
  Enabling Cash App Pay (or any future Stripe method) in the Stripe dashboard is
186
190
  the entire integration change — no SDK redeploy or consumer code update is
187
191
  required. Wallets only render on supported devices regardless of dashboard
@@ -386,8 +390,10 @@ When you use `onBeforeButtonClick` with `createSession`, any returned `InlineSes
386
390
  ### Advanced: Manual Provider Setup
387
391
 
388
392
  Use `SplitCardForm` when you need to compose the provider and session yourself.
389
- Card checkout still requires the backend-hosted vault block; Stripe remains
390
- limited to wallets/APMs and saved-payment authentication.
393
+ Card checkout uses the backend-hosted vault widget; Stripe remains limited to
394
+ wallets/APMs and saved-payment authentication. The session can supply the
395
+ widget eagerly in `session.vault`, or explicitly advertise `card` in
396
+ `gateways.stripe.enabledPaymentMethods` so the SDK recovers it on demand.
391
397
 
392
398
  ```tsx
393
399
  import { FloPayProvider, SplitCardForm } from '@flopay/react';
@@ -432,7 +438,8 @@ The resulting surfaces are:
432
438
 
433
439
  1. Wallet buttons and supported APM tiles from the session gateway capability.
434
440
  2. Direct or Stripe-hosted PayPal, selected from the session gateways.
435
- 3. The hosted vault widget for card-capable sessions.
441
+ 3. The hosted vault widget for sessions with embedded vault HTML or an explicit
442
+ Stripe `card` capability.
436
443
 
437
444
  Wallets, APMs, and PayPal create intents through
438
445
  `POST /v1/checkouts/sessions/{id}/intents`. The discriminated request separates
@@ -441,9 +448,13 @@ requests are unsupported. Client-observed non-card failures use the
441
448
  nonce-protected session decline endpoint and contain no payment tokens,
442
449
  provider object IDs, card data, credentials, or PII.
443
450
 
444
- If a card-capable backend omits the vault block, card checkout stays hidden.
445
- Advertised non-card methods remain usable; if none remain,
446
- `onError` receives `UnsupportedBackendVaultCapability`.
451
+ For SDK 1.4.9+, an explicit Stripe `card` capability keeps card checkout
452
+ visible even when the backend omits the vault block. In `layout="buttons"`,
453
+ `POST /v1/checkouts/sessions/{id}/vault/capture` is deferred until the buyer
454
+ selects Card. An embedded block remains the preferred fast path and causes no
455
+ recovery POST. Sessions that advertise neither an embedded block nor `card`
456
+ do not call the recovery endpoint; their non-card methods remain usable, and
457
+ if none remain, `onError` receives `UnsupportedBackendVaultCapability`.
447
458
 
448
459
  #### AVS postcode validation
449
460
 
@@ -498,30 +509,34 @@ best-effort **in parallel** with the widget's charge:
498
509
 
499
510
  ### Vault PCI card form
500
511
 
501
- When the billing API returns a hosted vault card form on the session
502
- (`session.vault`), the card path renders a **backend-served, self-contained
503
- hosted vault widget** (`VaultCardFields`) (TeamFloPay/backend#823, Model A).
504
- Every card-capable session is
505
- expected to include this block without SDK-version dispatch. It is fully
506
- **server-driven** there is no consumer prop to toggle it. The widget owns the
507
- card fields, its own submit button, card tokenization, the PaymentIntent (created
508
- **and** confirmed server-side), **3DS**, and the result, so **no Stripe.js runs
509
- on the card path** and PAN / CVC never enter the SDK runtime. Wallets / PayPal /
510
- APMs render exactly as before.
512
+ The card path renders a **backend-served, self-contained hosted vault widget**
513
+ (`VaultCardFields`) (TeamFloPay/backend#823, Model A). The billing API may
514
+ return it eagerly in `session.vault`, or advertise `card` under
515
+ `gateways.stripe.enabledPaymentMethods` and let SDK 1.4.9+ request it lazily.
516
+ It is fully **server-driven** there is no consumer prop to toggle it. The
517
+ widget owns the card fields, its own submit button, card tokenization, the
518
+ PaymentIntent (created **and** confirmed server-side), **3DS**, and the result,
519
+ so **no Stripe.js runs on the card path** and PAN / CVC never enter the SDK
520
+ runtime. Wallets / PayPal / APMs render exactly as before.
511
521
 
512
522
  Because the widget owns the form, `SplitCardForm` exposes no SDK card-entry or
513
523
  card-submit controls. Host-collected AVS fields remain outside the PCI
514
524
  widget and gate its submit. The flow is:
515
525
 
516
526
  ```text
517
- session includes a hosted vault card form (session.vault)
518
- → SDK injects the widget HTML (session.vault.html, or POST /vault/capture)
527
+ session embeds session.vault or advertises gateways.stripe.enabledPaymentMethods: ['card']
528
+ → SDK uses embedded HTML, or requests POST /vault/capture when Card is needed
529
+ → concurrent renders/remounts share that active request
519
530
  → buyer pays inside the widget (tokenize → charge → 3DS, all backend-owned)
520
531
  → widget postMessages its outcome → SDK fires onComplete / onDecline / onError
521
532
  ```
522
533
 
523
- - The widget HTML normally comes from embedded `session.vault.html`; the explicit
524
- recovery/retry path is `POST /v1/checkouts/sessions/{id}/vault/capture`.
534
+ - Embedded `session.vault.html` is the preferred fast path during rollout and
535
+ never triggers a recovery request.
536
+ - Deferred capture uses
537
+ `POST /v1/checkouts/sessions/{id}/vault/capture`, with a ten-second timeout,
538
+ bounded transient-network retry, and one shared active request per
539
+ base URL/session/nonce.
525
540
  - **Returning customers** with a card on file (`session.providerPaymentMethodId`)
526
541
  are charged by the backend's auto-checkout cascade.
527
542
  - **3DS** is handled inside the widget — there is no client-side `confirmCardPayment`.
@@ -710,11 +725,11 @@ Key payment-surface props include:
710
725
  |------|------|-------------|
711
726
  | `sessionId` | `string` | Checkout session UUID. |
712
727
  | `nonce` | `string` | Session-bound token forwarded on intent, decline, account, and process calls. |
713
- | `session` | `CheckoutSession?` | Session capability data, including the hosted `vault` block and gateways. |
728
+ | `session` | `CheckoutSession?` | Session capability data, including the optional hosted `vault` fast path and gateways. |
714
729
  | `billingApiUrl` | `string` | Billing API base URL. |
715
- | `showStripe` | `boolean` | Show Stripe-backed wallets/APMs. Card checkout is controlled by the session vault capability. |
730
+ | `showStripe` | `boolean` | Show Stripe-backed wallets/APMs and the hosted card path when the session embeds `vault` or advertises `card`. |
716
731
  | `showPayPal` | `boolean` | Show PayPal. Renderer chosen by `gateways.paypal` presence (DirectPayPal JS SDK when present; Stripe-rendered PayPal otherwise). Default: `true`. |
717
- | `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. |
732
+ | `enabledPaymentMethods` | `string[]?` | Per-session list of Stripe method type identifiers (`card`, `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 non-card methods between ExpressCheckoutElement and PaymentElement; `card` advertises the hosted-vault path and is never rendered by Stripe. |
718
733
  | `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`. |
719
734
  | `showGooglePay` | `boolean` | *Deprecated.* See `showApplePay`. |
720
735
  | `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. |
@@ -724,6 +739,24 @@ Key payment-surface props include:
724
739
  | `onLastNameChange` | `(value: string) => void` | Last name change callback |
725
740
  | `onComplete` / `onDecline` / `onError` | callbacks | Observable checkout outcomes. |
726
741
 
742
+ #### Deferred-vault rollout boundary
743
+
744
+ SDK `1.4.9` is the compatibility boundary for omitting embedded capture
745
+ credentials. Keep the backend's current
746
+ `link session → capture → complete idempotency → 201` ordering for requests
747
+ from older or unknown SDK versions, and until the deployed `@flopay/react`
748
+ population has crossed the adoption threshold chosen by the backend rollout.
749
+ The SDK advertises its version in `x-flo-sdk-version` on session create/read.
750
+
751
+ After that threshold, the backend may omit capture credentials from
752
+ create/read/idempotent-replay responses for requests advertising SDK `>=1.4.9`,
753
+ provided the session explicitly includes `card` in
754
+ `gateways.stripe.enabledPaymentMethods` and the nonce-protected
755
+ `POST /v1/checkouts/sessions/{id}/vault/capture` route remains available.
756
+ Backend rollout verification should confirm that create/read/replay no longer
757
+ invoke PCIVault and that capture issuance occurs only through the deferred
758
+ endpoint when a buyer enters the card path.
759
+
727
760
  ### ElementComponentProps (shared by all element components)
728
761
 
729
762
  | Prop | Type | Description |