@flopay/react 1.2.7 → 1.3.0

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
@@ -406,6 +406,13 @@ Pass `onTokenizedBody` to handle backend submission yourself:
406
406
  />
407
407
  ```
408
408
 
409
+ > **Vault card path — `onTokenizedBody` does not fire.** When the session uses the
410
+ > [vault PCI card form](#vault-pci-card-form), the backend-served widget owns the
411
+ > whole charge (tokenize → PaymentIntent → 3DS → result), so there is no
412
+ > client-side tokenization step to override. Use `onComplete` / `onDecline` /
413
+ > `onError` instead — the SDK relays the widget's terminal outcome to them. The
414
+ > legacy Stripe path's `onTokenizedBody` is unchanged.
415
+
409
416
  ### SplitCardForm (Split Card Fields + PayPal)
410
417
 
411
418
  `SplitCardForm` renders separate CardNumber, CardExpiry, and CardCVC fields with an integrated PayPal button. It matches the existing checkout/StripeCardForm layout.
@@ -457,6 +464,50 @@ The `SplitCardForm` layout:
457
464
  6. Full Name input
458
465
  7. Submit button
459
466
 
467
+ ### Vault PCI card form
468
+
469
+ When the billing API returns a hosted vault card form on the session
470
+ (`session.vault`), the card path renders a **backend-served, self-contained
471
+ hosted vault widget** (`VaultCardFields`) instead of Stripe's embedded card
472
+ elements (TeamFloPay/backend#823, Model A). The backend embeds this block for
473
+ any SDK that advertises `x-flo-sdk-version >= 1.3.0`, so it is fully
474
+ **server-driven** — there is no consumer prop to toggle it. The widget owns the
475
+ card fields, its own submit button, card tokenization, the PaymentIntent (created
476
+ **and** confirmed server-side), **3DS**, and the result, so **no Stripe.js runs
477
+ on the card path** and PAN / CVC never enter the SDK runtime. Wallets / PayPal /
478
+ APMs render exactly as before.
479
+
480
+ Because the widget owns the form, on the vault path `SplitCardForm` hides its own
481
+ card fields, cardholder-name input, AVS fields, and submit button. The flow is:
482
+
483
+ ```text
484
+ session includes a hosted vault card form (session.vault)
485
+ → SDK injects the widget HTML (session.vault.html, or POST /vault/capture)
486
+ → buyer pays inside the widget (tokenize → charge → 3DS, all backend-owned)
487
+ → widget postMessages its outcome → SDK fires onComplete / onDecline / onError
488
+ ```
489
+
490
+ - The widget HTML comes from the embedded `session.vault.html` (SDKs ≥ 1.3.0 send
491
+ `X-Flo-SDK-Version`, so the backend embeds it on create-session) or, if absent,
492
+ from `POST /v1/checkouts/sessions/{id}/vault/capture`.
493
+ - **Returning customers** with a card on file (`session.providerPaymentMethodId`)
494
+ are charged by the backend's auto-checkout cascade.
495
+ - **3DS** is handled inside the widget — there is no client-side `confirmCardPayment`.
496
+
497
+ **Failure modes:** the widget renders its own status / decline UI; `onDecline` /
498
+ `onError` receive the mapped reason + message so consumers can react.
499
+
500
+ > **Backend dependencies:** the hosted widget must emit the `flopay-vault`
501
+ > `postMessage` outcome the SDK listens for (otherwise it falls back to its own
502
+ > success redirect), handle the 3DS step internally, and own AVS for the vault
503
+ > path (the SDK no longer collects it inline; account-level address set at
504
+ > session-create still flows to the backend). Because the widget is injected
505
+ > **same-window**, every terminal outcome must be bound to the session id, and —
506
+ > to fully defend against same-window forgery — the backend should mint a
507
+ > per-session `messageToken` on the vault block and echo it in each
508
+ > `postMessage`; the SDK threads it through and rejects outcomes that omit or
509
+ > mismatch it (TeamFloPay/backend#823).
510
+
460
511
  ### PayPal Handling
461
512
 
462
513
  The SDK supports two PayPal paths, selected per-session based on what the billing API advertises under `gateways.*`:
@@ -543,7 +594,8 @@ function PaymentStatus() {
543
594
  |-----------|-------------|
544
595
  | `FloPayProvider` | Context provider. Accepts `flopay` (instance or promise), `options?`, and `children`. Creates the elements group automatically. |
545
596
  | `CheckoutForm` | Drop-in form with unified PaymentElement. Self-contained by default, or override with `onTokenizedBody`. Supports `ref` for imperative `handleNextAction()`. |
546
- | `SplitCardForm` | Split card form (CardNumber + CardExpiry + CardCvc + Full Name). Integrates PayPal via separate Elements instance. Supports `ref` for imperative `handleNextAction()`. |
597
+ | `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()`. |
598
+ | `VaultCardFields` | Hosted vault PCI card fields. Used internally by `SplitCardForm` on the vault path; consumes a `CardCaptureAdapter` from `useFloPay().cardCapture()`. |
547
599
  | `PayPalButton` | Standalone PayPal button. Requires its own `FloPayProvider` with `paymentMethodCreation` set to something other than `'manual'`. |
548
600
  | `PaymentElement` | Unified payment element (cards, wallets, etc.) |
549
601
  | `CardElement` | Combined card input |