@flopay/react 1.8.3 → 1.8.6

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
@@ -59,17 +59,18 @@ function CheckoutPage() {
59
59
 
60
60
  For inline checkout creation, `createSession.account.userId` remains required,
61
61
  but `email`, `firstName`, and `lastName` may be omitted. `FloPayCheckout`
62
- creates a mountable session shell first, then collects and attaches the missing
63
- identity before payment can continue:
62
+ creates a mountable session shell first, immediately attaches the known catalog,
63
+ and collects buyer identity at the method-appropriate point:
64
64
 
65
65
  - Hosted card checkout renders a required email field first, above name, AVS,
66
66
  and the hosted card widget. Submit stays gated until the email passes the
67
67
  shared `isValidEmail()` validator and a name is present.
68
68
  - Apple Pay, Google Pay, other Stripe wallets, and PayPal use provider-returned
69
- email/name automatically when available.
69
+ email/name automatically when available. Their provider UI starts without a
70
+ Flo identity preflight.
70
71
  - A wallet, PayPal, or APM that does not return the missing fields opens a
71
- required second pane for email/name before the SDK creates an intent or
72
- processes payment.
72
+ single required fallback pane after that provider miss (or before submission
73
+ for a method that cannot return identity).
73
74
 
74
75
  The SDK never attaches a blank email. The merchant-supplied `userId` is not
75
76
  replaced by provider data.
@@ -405,7 +406,7 @@ the default layout to `"buttons"` keeps the resolved checkout session and its
405
406
  gateway capabilities, so the **Credit / Debit Card** choice remains available
406
407
  without recreating the session.
407
408
 
408
- > **Deprecated**: the legacy `buttonsTheme` prop (`'default'` / `'minimal'` / `'rounded'` / `'dark'`) still works but new code should use `theme` so the same value drives both the buttons-layout wrapper and the auto-payment fallback. See [ButtonsLayoutStyles reference](https://docs.flopay.com/api-reference/react/flopay-checkout#buttonslayoutstyles-reference) for the underlying override fields.
409
+ > **Deprecated**: the legacy `buttonsTheme` prop (`'default'` / `'minimal'` / `'rounded'` / `'dark'`) still works but new code should use `theme` so the same value drives both the buttons-layout wrapper and the auto-payment fallback. See [ButtonsLayoutStyles reference](https://flopay.com/docs/api-reference/react/flopay-checkout#buttonslayoutstyles-reference) for the underlying override fields.
409
410
 
410
411
  #### Button Hooks
411
412
 
@@ -470,8 +471,9 @@ Skip the backend API route — create the session directly in the component:
470
471
  />
471
472
  ```
472
473
 
473
- The component creates a lightweight shell, renders the form, and claims the
474
- session after buyer identity is available zero merchant backend code needed.
474
+ The component creates a lightweight shell, attaches the catalog immediately,
475
+ renders every otherwise-eligible method, and identifies the buyer later from
476
+ the selected method or its fallback — zero merchant backend code needed.
475
477
 
476
478
  #### Authorisation-only checkout
477
479
 
@@ -549,20 +551,36 @@ When you use `onBeforeButtonClick` with `createSession`, any returned `InlineSes
549
551
 
550
552
  `createSession` checkouts are created in two phases (TeamFloPay/backend#1099):
551
553
  a lightweight session *shell* that skips catalog validation and the
552
- buyer-identity advisory locks, then a background **claim** that attaches buyer
553
- identity, address, products and coupons.
554
+ buyer-identity advisory locks, then a background **claim** that attaches the
555
+ catalog. If the draft already contains an email, that claim also attaches the
556
+ buyer. Otherwise it deliberately omits `accountData` and returns a complete,
557
+ still-anonymous session (`buyerIdentified: false`).
554
558
 
555
559
  `FloPayCheckout` renders from the shell, so the hosted card form mounts and
556
560
  becomes interactive without waiting for either the claim or Stripe.js — Stripe
557
- wallets, APMs and PayPal load in parallel with the claim and appear when it
558
- lands. The card widget's submit button stays gated for that window, because the
561
+ wallets, APMs and PayPal load in parallel with the catalog claim and appear
562
+ from its full `enabledPaymentMethods` list when it lands. The card widget's
563
+ submit button stays gated for that window, because the
559
564
  billing API rejects a charge against an unclaimed session; if a buyer clicks
560
565
  during it, the widget cancels the click and the form asks them to press pay
561
566
  again. In practice the claim resolves while the card is still being filled in.
562
567
 
563
568
  Nothing else changes for you: the same session, the same callbacks, the same
564
569
  results. Catalog and coupon errors still surface as a checkout load error, just
565
- from the claim rather than the create.
570
+ from the claim rather than the create. Missing buyer identity never delays this
571
+ catalog claim: provider-capable methods identify the buyer during payment, and
572
+ `claim(account)` performs a separate buyer-only attachment when manual
573
+ collection is needed.
574
+
575
+ That buyer-only attachment is not specific to detached creation. Any
576
+ still-anonymous session the checkout renders — a one-shot create without an
577
+ email, or an existing session passed as `sessionId` + `nonce` that the billing
578
+ API returns with `buyerIdentified: false` — gets the same late-buyer claim
579
+ rebuilt from the session's nonce, so the email the SDK collects (or a wallet /
580
+ PayPal approval supplies) reaches `PATCH /v1/checkouts/sessions/{id}/claim`
581
+ before payment. The hosted vault widget's charge is refused server-side for a
582
+ session with no bound buyer, so without that claim an email-less session loaded
583
+ by id would never complete.
566
584
 
567
585
  Opt out per session to restore the original single-request create:
568
586
 
@@ -578,7 +596,8 @@ Opt out per session to restore the original single-request create:
578
596
  Detached creation applies only to `checkoutMode: 'full'` (the billing API
579
597
  rejects it for `auto` / `confirm`) and is skipped when `tokenizedData` is
580
598
  supplied. There is **no fallback** to the one-shot create — it requires a
581
- billing API that exposes `PATCH /v1/checkouts/sessions/{id}/claim`.
599
+ billing API `v1.7.12` or newer that exposes the independent catalog/buyer
600
+ `PATCH /v1/checkouts/sessions/{id}/claim` contract.
582
601
 
583
602
  ### Advanced: Manual Provider Setup
584
603
 
@@ -769,6 +788,14 @@ Renderer selection is mutually exclusive per session — direct PayPal takes pri
769
788
 
770
789
  **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.
771
790
 
791
+ **Provider-first buyer identity:** Direct PayPal never hides its Smart Button
792
+ behind a Flo buyer-details preflight. An anonymous buyer starts PayPal normally;
793
+ after approval the SDK reads the payer email/name, attaches valid returned
794
+ details, and continues processing. If PayPal returns incomplete identity, the
795
+ SDK shows exactly one required fallback pane after approval and resumes with
796
+ the collected values. A checkout that supplied buyer details up front keeps its
797
+ existing request bodies and callbacks.
798
+
772
799
  **Flo-owned subscription continuations:** `gateways.paypal.providerObjectType`
773
800
  selects the direct PayPal operation. `'order'` loads the PayPal SDK with
774
801
  `intent=capture` and invokes `createOrder`, even when the checkout session mode
@@ -949,6 +976,7 @@ Key payment-surface props include:
949
976
  | `currency` | `string` | Currency code for PayPal / wallet config (default: `'usd'`) |
950
977
  | `onFirstNameChange` | `(value: string) => void` | First name change callback |
951
978
  | `onLastNameChange` | `(value: string) => void` | Last name change callback |
979
+ | `onBuyerIdentityReady` | `(identity) => MaybePromise<void>?` | Called once checkout has collected a missing buyer email (or a wallet / PayPal approval supplied one) on a still-anonymous session. `FloPayCheckout` wires its late-buyer `PATCH /claim` here — including for custom-layout children, via `CheckoutContext`. A standalone form around a `session` with `buyerIdentified: false` that is given neither a prop nor a context claim builds its own from `sessionId` + `nonce`, so the hosted vault charge is never submitted against an unbound buyer. Supply the prop to take the claim over yourself. |
952
980
  | `onComplete` / `onDecline` / `onError` | callbacks | Observable checkout outcomes. |
953
981
 
954
982
  #### Deferred-vault rollout boundary