@flopay/react 1.2.8 → 1.3.1
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 +76 -1
- package/dist/index.cjs +1455 -637
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +104 -4
- package/dist/index.d.ts +104 -4
- package/dist/index.mjs +1258 -440
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
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,73 @@ The `SplitCardForm` layout:
|
|
|
457
464
|
6. Full Name input
|
|
458
465
|
7. Submit button
|
|
459
466
|
|
|
467
|
+
#### AVS postcode validation
|
|
468
|
+
|
|
469
|
+
When AVS collection is enabled (`enableAVS`) and the postcode field is shown,
|
|
470
|
+
`SplitCardForm` validates the postcode **format against the live selected
|
|
471
|
+
country before the card is captured**, on both the Stripe and vault card paths.
|
|
472
|
+
It reuses `@flopay/shared`'s country-aware
|
|
473
|
+
[postcode helpers](../shared/README.md#postal-code-helpers) (the same
|
|
474
|
+
`validator` rules the billing API applies), so client and server agree.
|
|
475
|
+
|
|
476
|
+
- **Supported country + malformed postcode** → the submit is blocked (the vault
|
|
477
|
+
widget's submit button is gated; the Stripe path returns before tokenizing)
|
|
478
|
+
and an inline, country-specific message shows the expected format
|
|
479
|
+
(e.g. *"Enter a valid ZIP Code (e.g. 12345 or 12345-6789)"*). On the vault
|
|
480
|
+
path the inline message appears once the field is blurred, since the disabled
|
|
481
|
+
submit means it can't be reached by a submit attempt.
|
|
482
|
+
- **Supported country + empty postcode** → the same submit gate applies, and
|
|
483
|
+
once the field is blurred (or a submit is attempted) an inline *required*
|
|
484
|
+
message shows (e.g. *"ZIP Code is required"*) rather than the expected-format
|
|
485
|
+
copy.
|
|
486
|
+
- **Country with no postal system** (or a locale `validator` doesn't recognise)
|
|
487
|
+
→ the postcode field is shown but **optional**: empty and format checks are
|
|
488
|
+
both skipped, so these buyers are never blocked.
|
|
489
|
+
|
|
490
|
+
### Vault PCI card form
|
|
491
|
+
|
|
492
|
+
When the billing API returns a hosted vault card form on the session
|
|
493
|
+
(`session.vault`), the card path renders a **backend-served, self-contained
|
|
494
|
+
hosted vault widget** (`VaultCardFields`) instead of Stripe's embedded card
|
|
495
|
+
elements (TeamFloPay/backend#823, Model A). The backend embeds this block for
|
|
496
|
+
any SDK that advertises `x-flo-sdk-version >= 1.3.0`, so it is fully
|
|
497
|
+
**server-driven** — there is no consumer prop to toggle it. The widget owns the
|
|
498
|
+
card fields, its own submit button, card tokenization, the PaymentIntent (created
|
|
499
|
+
**and** confirmed server-side), **3DS**, and the result, so **no Stripe.js runs
|
|
500
|
+
on the card path** and PAN / CVC never enter the SDK runtime. Wallets / PayPal /
|
|
501
|
+
APMs render exactly as before.
|
|
502
|
+
|
|
503
|
+
Because the widget owns the form, on the vault path `SplitCardForm` hides its own
|
|
504
|
+
card fields, cardholder-name input, AVS fields, and submit button. The flow is:
|
|
505
|
+
|
|
506
|
+
```text
|
|
507
|
+
session includes a hosted vault card form (session.vault)
|
|
508
|
+
→ SDK injects the widget HTML (session.vault.html, or POST /vault/capture)
|
|
509
|
+
→ buyer pays inside the widget (tokenize → charge → 3DS, all backend-owned)
|
|
510
|
+
→ widget postMessages its outcome → SDK fires onComplete / onDecline / onError
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
- The widget HTML comes from the embedded `session.vault.html` (SDKs ≥ 1.3.0 send
|
|
514
|
+
`X-Flo-SDK-Version`, so the backend embeds it on create-session) or, if absent,
|
|
515
|
+
from `POST /v1/checkouts/sessions/{id}/vault/capture`.
|
|
516
|
+
- **Returning customers** with a card on file (`session.providerPaymentMethodId`)
|
|
517
|
+
are charged by the backend's auto-checkout cascade.
|
|
518
|
+
- **3DS** is handled inside the widget — there is no client-side `confirmCardPayment`.
|
|
519
|
+
|
|
520
|
+
**Failure modes:** the widget renders its own status / decline UI; `onDecline` /
|
|
521
|
+
`onError` receive the mapped reason + message so consumers can react.
|
|
522
|
+
|
|
523
|
+
> **Backend dependencies:** the hosted widget must emit the `flopay-vault`
|
|
524
|
+
> `postMessage` outcome the SDK listens for (otherwise it falls back to its own
|
|
525
|
+
> success redirect), handle the 3DS step internally, and own AVS for the vault
|
|
526
|
+
> path (the SDK no longer collects it inline; account-level address set at
|
|
527
|
+
> session-create still flows to the backend). Because the widget is injected
|
|
528
|
+
> **same-window**, every terminal outcome must be bound to the session id, and —
|
|
529
|
+
> to fully defend against same-window forgery — the backend should mint a
|
|
530
|
+
> per-session `messageToken` on the vault block and echo it in each
|
|
531
|
+
> `postMessage`; the SDK threads it through and rejects outcomes that omit or
|
|
532
|
+
> mismatch it (TeamFloPay/backend#823).
|
|
533
|
+
|
|
460
534
|
### PayPal Handling
|
|
461
535
|
|
|
462
536
|
The SDK supports two PayPal paths, selected per-session based on what the billing API advertises under `gateways.*`:
|
|
@@ -543,7 +617,8 @@ function PaymentStatus() {
|
|
|
543
617
|
|-----------|-------------|
|
|
544
618
|
| `FloPayProvider` | Context provider. Accepts `flopay` (instance or promise), `options?`, and `children`. Creates the elements group automatically. |
|
|
545
619
|
| `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()`. |
|
|
620
|
+
| `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()`. |
|
|
621
|
+
| `VaultCardFields` | Hosted vault PCI card fields. Used internally by `SplitCardForm` on the vault path; consumes a `CardCaptureAdapter` from `useFloPay().cardCapture()`. |
|
|
547
622
|
| `PayPalButton` | Standalone PayPal button. Requires its own `FloPayProvider` with `paymentMethodCreation` set to something other than `'manual'`. |
|
|
548
623
|
| `PaymentElement` | Unified payment element (cards, wallets, etc.) |
|
|
549
624
|
| `CardElement` | Combined card input |
|