@flopay/react 1.6.0 → 1.8.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/dist/index.d.cts CHANGED
@@ -1,63 +1,215 @@
1
- import React from 'react';
2
- import { FloPay, FloPayElements } from '@flopay/js';
3
1
  import * as _flopay_shared from '@flopay/shared';
4
- import { FloPayAppearance, InlineSessionDraft, FloPayError, PaymentResult, DeclineEvent, CheckoutButtonMethod, BeforeButtonClickEvent, InlineSessionPatch, CheckoutMode, CheckoutSession, ElementOptions, ElementChangeEvent, TokenizedBody, AVSFieldConfig, GatewayEnvironment, PayPalProviderObjectType, CardCaptureAdapter, VaultCardThemeColors, CheckoutProduct, CheckoutItem, CheckoutSubscription, ThemeId, ButtonsLayoutTheme, ButtonsLayoutStyles } from '@flopay/shared';
5
- export { BeforeButtonClickEvent, CheckoutButtonMethod, DeclineEvent, InlineSessionDraft, InlineSessionPatch, SentryEventLike, SentryStackFrameLike, dropThirdPartyOnlyError } from '@flopay/shared';
2
+ import { InlineSessionDraft, CheckoutButtonMethod, CheckoutProduct, CheckoutItem, CheckoutSubscription, ThemeId, FloPayAppearance, ButtonsLayoutTheme, ButtonsLayoutStyles, PaymentResult, CheckoutSession, FloPayError, DeclineEvent, GatewayEnvironment, PayPalProviderObjectType, TokenizedBody, InlineSessionPatch, FloInstrumentEvent, BeforeButtonClickEvent, CheckoutMode, AVSFieldConfig, CardCaptureAdapter, VaultCardThemeColors } from '@flopay/shared';
3
+ export { BeforeButtonClickEvent, CheckoutButtonMethod, DeclineEvent, FloInstrumentEvent, InlineSessionDraft, InlineSessionPatch, SentryEventLike, SentryStackFrameLike, dropThirdPartyOnlyError } from '@flopay/shared';
4
+ import React from 'react';
6
5
  export { FloPayCardSetup, FloPayCardSetupCancelEvent, FloPayCardSetupCompleteEvent, FloPayCardSetupDeclineEvent, FloPayCardSetupError, FloPayCardSetupProps } from './card-setup-entry.cjs';
6
+ import { FloPay } from '@flopay/js';
7
7
 
8
- /** Props for the `FloPayProvider` component. */
9
- interface FloPayProviderProps {
10
- /** A `FloPay` instance or a promise that resolves to one (from `loadFloPay()`). */
11
- flopay: Promise<FloPay> | FloPay;
8
+ interface FloPayAutomaticPaymentSuccessEvent {
9
+ result: PaymentResult;
10
+ session: CheckoutSession | null;
11
+ sessionId: string | null;
12
+ autoCompleted: boolean;
13
+ }
14
+ interface FloPayAutomaticPaymentButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onError'> {
15
+ sessionId?: string;
12
16
  /**
13
- * Optional Stripe `FloPay` instance used to drive the Stripe-rendered PayPal
14
- * fallback. When omitted or `null`, the Stripe-rendered PayPal button is
15
- * not rendered. Direct PayPal (`gateways.paypal`) does not use this prop.
17
+ * Session-bound checkout token for a consumer-supplied {@link sessionId}
18
+ * (the `nonce` returned when that session was created). Post-#640 backends
19
+ * require it as `x-checkout-session-token` to read the session and to
20
+ * `/process` it; without it the existing-session path 401s with
21
+ * "Missing checkout session token.". Ignored on the create-session path,
22
+ * where the SDK mints and threads the nonce itself.
16
23
  */
17
- paypalFlopay?: Promise<FloPay> | FloPay | null;
18
- /** Optional configuration applied when creating the elements group. */
19
- options?: {
20
- locale?: string;
21
- appearance?: FloPayAppearance;
22
- /**
23
- * Client secret for an existing non-card PaymentIntent or SetupIntent.
24
- * The SDK verifies the provider intent against the `PaymentElement`'s
25
- * explicit `paymentMethodTypes` allowlist before mounting and rejects card
26
- * or undeclared methods. Card checkout uses the hosted vault.
27
- */
28
- clientSecret?: string;
29
- /** Total amount in cents for deferred non-card Elements without a client secret. */
30
- amount?: number;
31
- /** ISO 4217 currency code for deferred non-card Elements without a client secret. */
32
- currency?: string;
33
- /** How non-card payment methods are created: `'manual'` or `'auto'` (needed for PayPal). */
34
- paymentMethodCreation?: 'manual' | 'auto';
35
- /** Requests reusable payment credentials for future payments. */
36
- setupFutureUsage?: 'off_session' | 'on_session';
37
- /** Billing API base URL. Set once here so child components don't need to repeat it. */
38
- billingApiUrl?: string;
39
- };
40
- children: React.ReactNode;
24
+ nonce?: string;
25
+ createSession?: InlineSessionDraft;
26
+ /**
27
+ * @deprecated Ignored. The backend now picks the customer's most recent
28
+ * vaulted payment method via `getLatestByUserId` and rebinds the session's
29
+ * gateway to match it (see `apps/api`'s `createSingle` auto-checkout
30
+ * branch). Passing this prop has no effect it is retained only to avoid
31
+ * breaking existing integrations.
32
+ */
33
+ paymentMethodId?: string;
34
+ /**
35
+ * @deprecated Ignored. The backend orchestrates gateway routing — clients
36
+ * no longer choose between card and PayPal at the SDK boundary. Passing
37
+ * this prop has no effect.
38
+ */
39
+ checkoutMethod?: CheckoutButtonMethod;
40
+ clientId?: string;
41
+ /**
42
+ * Unified products array (TeamFloPay/backend#760). When supplied,
43
+ * `items`/`subscriptions` are ignored. The SDK folds the legacy fields
44
+ * into this shape internally.
45
+ */
46
+ products?: CheckoutProduct[];
47
+ items?: CheckoutItem[];
48
+ subscriptions?: CheckoutSubscription[];
49
+ account?: InlineSessionDraft['account'];
50
+ successUrl?: string;
51
+ cancelUrl?: string;
52
+ couponCodes?: string[];
53
+ tagsData?: InlineSessionDraft['tagsData'];
54
+ utmMetadata?: InlineSessionDraft['utmMetadata'];
55
+ billingApiUrl?: string;
56
+ locale?: string;
57
+ /**
58
+ * High-level theme bundle that styles the button (and the fallback
59
+ * `FloPayCheckout` modal that opens when the saved-payment charge needs
60
+ * user interaction). One of: `'classic'`, `'modern-light'`, `'modern-dark'`,
61
+ * `'bold-light'`, `'bold-dark'`, `'glass-light'`, `'glass-dark'`. Explicit
62
+ * `buttonsStyles` still wins for fine-grained overrides.
63
+ */
64
+ theme?: ThemeId;
65
+ /**
66
+ * Per-checkout appearance overrides layered on top of the chosen `theme`
67
+ * (same shape as {@link FloPayCheckout}'s `appearance`). Its `colorPrimary` /
68
+ * `colorPrimaryHover` / `borderRadius` re-skin the button — and the fallback
69
+ * `FloPayCheckout` modal — so the auto-pay button matches the rest of the
70
+ * themed checkout. Without this the button only saw the bundle's defaults.
71
+ */
72
+ appearance?: FloPayAppearance;
73
+ /**
74
+ * @deprecated Use `theme` instead. Legacy buttons-layout preset
75
+ * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for
76
+ * back-compat.
77
+ */
78
+ buttonsTheme?: ButtonsLayoutTheme;
79
+ buttonsStyles?: ButtonsLayoutStyles;
80
+ onSuccess?: (event: FloPayAutomaticPaymentSuccessEvent) => void;
81
+ onError?: (error: FloPayError) => void;
82
+ onDecline?: (decline: DeclineEvent) => void;
83
+ children?: React.ReactNode;
41
84
  }
85
+ declare function FloPayAutomaticPaymentButton({ sessionId, nonce, createSession, paymentMethodId: _deprecatedPaymentMethodId, checkoutMethod: _deprecatedCheckoutMethod, clientId, products, items, subscriptions, account, successUrl, cancelUrl, couponCodes, tagsData, utmMetadata, billingApiUrl, locale, theme, appearance, buttonsTheme, buttonsStyles: stylesOverride, onSuccess, onError, onDecline, children, disabled, type, style, ...buttonProps }: FloPayAutomaticPaymentButtonProps): React.JSX.Element;
86
+
42
87
  /**
43
- * Provides FloPay SDK context to the component tree.
44
- *
45
- * Wrap provider-context elements with this provider:
46
- *
47
- * ```tsx
48
- * <FloPayProvider flopay={loadFloPay('pk_test_...')}>
49
- * <PaymentElement options={{ paymentMethodTypes: ['cashapp', 'ideal'] }} />
50
- * </FloPayProvider>
51
- * ```
52
- *
53
- * `FloPayCheckout` is a standalone integration that owns its provider and
54
- * session-specific Elements setup:
55
- *
56
- * ```tsx
57
- * <FloPayCheckout sessionId="sess_..." />
58
- * ```
88
+ * Overrides that `SplitCardForm`'s tokenized-body dispatcher uses to apply a
89
+ * `runBeforeButtonClick` patch to the in-flight processPayment call. Kept in
90
+ * sync structurally with `TokenizedBodyOverrides` in `split-card-form.tsx`.
59
91
  */
60
- declare function FloPayProvider({ flopay: floPayProp, paypalFlopay: paypalFloPayProp, options, children, }: FloPayProviderProps): React.ReactElement;
92
+ interface DirectPayPalTokenizedOverrides {
93
+ accountPatch?: InlineSessionPatch['account'];
94
+ sessionId?: string;
95
+ nonce?: string;
96
+ }
97
+ /**
98
+ * Internal handler signature aligned with `SplitCardForm`'s tokenized-body
99
+ * dispatcher. Direct PayPal completes via the backend's process endpoint and
100
+ * never produces a Stripe PaymentIntent, so we still forward a synthetic
101
+ * `TokenizedBody` describing the captured order, optionally with the
102
+ * session/account patch captured at click-time.
103
+ */
104
+ type DirectPayPalTokenizedHandler = (body: TokenizedBody, overrides?: DirectPayPalTokenizedOverrides) => void;
105
+ /** Click-time `runBeforeButtonClick` result, structurally compatible with `SplitCardForm`. */
106
+ interface DirectPayPalBeforeButtonClickResult {
107
+ proceed: boolean;
108
+ accountPatch?: InlineSessionPatch['account'];
109
+ sessionId?: string;
110
+ nonce?: string;
111
+ }
112
+ /**
113
+ * Click-time gate. Mirrors `RunBeforeButtonClick` in `SplitCardForm`: lets the
114
+ * consumer patch the session/account before PayPal creates the order, and lets
115
+ * them abort the click entirely by returning `proceed: false`.
116
+ */
117
+ type DirectPayPalRunBeforeButtonClick = (method: CheckoutButtonMethod) => Promise<DirectPayPalBeforeButtonClickResult>;
118
+ type DirectPayPalInitializationState = 'loading' | 'retrying' | 'ready' | 'exhausted';
119
+ type DirectPayPalTechnicalFailureHandler = (method: 'paypal', err: unknown, options?: {
120
+ code?: string;
121
+ popupBlocked?: boolean;
122
+ }) => void;
123
+ interface DirectPayPalButtonProps {
124
+ /** Checkout session ID. */
125
+ sessionId: string;
126
+ /**
127
+ * Session-bound checkout token returned by session creation. Forwarded as
128
+ * `x-checkout-session-token` on every continuation request — required by
129
+ * post-#640 backends. `FloPayCheckout` plumbs this prop automatically.
130
+ */
131
+ nonce?: string;
132
+ /** Billing API base URL. */
133
+ billingApiUrl: string;
134
+ /** Buyer email. */
135
+ email?: string;
136
+ /** PayPal client identifier (`gateways.paypal.publishableKey`). */
137
+ clientId: string;
138
+ /** Gateway environment, drives the sandbox/live SDK script. */
139
+ environment?: GatewayEnvironment;
140
+ /** ISO 4217 currency code. */
141
+ currency: string;
142
+ /** Whether the session is a subscription (drives intent + flow selection). */
143
+ isSubscription: boolean;
144
+ /**
145
+ * Provider object the backend advertised for this PayPal continuation.
146
+ * When omitted, legacy sessions continue to derive the flow from
147
+ * `isSubscription`. An advertised `'order'`/`'setup_token'` opts intent and
148
+ * process requests into the Flo-owned `paypal_vaulted` payment-method
149
+ * channel; an advertised `'subscription'` or an omission keeps the released
150
+ * `paypal` requests byte-identical.
151
+ */
152
+ providerObjectType?: PayPalProviderObjectType;
153
+ /**
154
+ * If provided, called with the tokenized body once PayPal capture
155
+ * completes. When omitted, the component processes payment internally.
156
+ */
157
+ onTokenizedBody?: DirectPayPalTokenizedHandler;
158
+ /** Called when the full self-contained payment flow succeeds. */
159
+ onComplete?: (result: PaymentResult) => void;
160
+ /** Called when an error occurs. */
161
+ onErrorChange?: (error: string | null) => void;
162
+ /** Decline emitter (mirrors SplitCardForm semantics). */
163
+ onDecline?: (decline: DeclineEvent) => void;
164
+ /** Called for post-click technical failures before PayPal authorization completes. */
165
+ onTechnicalFailure?: DirectPayPalTechnicalFailureHandler;
166
+ /** External processing state. */
167
+ isProcessing?: boolean;
168
+ /** Notify the parent of the loading state for placeholder swapping. */
169
+ onLoadStateChange?: (ready: boolean) => void;
170
+ /** Notify a PayPal-only wrapper about pre-render recovery state. */
171
+ onInitializationStateChange?: (state: DirectPayPalInitializationState) => void;
172
+ /** Disable the automatic retry for a buyer-initiated single manual attempt. */
173
+ allowAutomaticRetry?: boolean;
174
+ /** Tracks button-click for analytics. */
175
+ onButtonClick?: (method: CheckoutButtonMethod) => void;
176
+ /**
177
+ * Click-time gate (runs before PayPal creates the order). When provided, the
178
+ * returned patch is applied to the in-flight create-intent and tokenized
179
+ * dispatch so callers using `onBeforeButtonClick` see the same session/email
180
+ * the Stripe-rendered PayPal flow does.
181
+ */
182
+ runBeforeButtonClick?: DirectPayPalRunBeforeButtonClick;
183
+ /** Backing session — used for self-contained accountData population. */
184
+ session?: CheckoutSession | null;
185
+ /**
186
+ * Pre-existing PayPal Order id (or Subscription id when `isSubscription` is
187
+ * true) to bind the button to. When set, the button skips its usual
188
+ * session-scoped create-intent round-trip on click and feeds this
189
+ * id straight into PayPal's create-order / create-subscription callback.
190
+ *
191
+ * Used by `SplitCardForm`'s `paypal_direct_required` retry path: backend
192
+ * creates a fresh PayPal order after a stalled process attempt and returns
193
+ * its id; the SDK re-renders this button bound to that id so the buyer can
194
+ * confirm with one more click without the backend re-creating the order on
195
+ * each retry.
196
+ *
197
+ * Changing this value remounts the PayPal SDK so the new createOrder
198
+ * binding takes effect (PayPal's render() options aren't live-updatable).
199
+ */
200
+ existingOrderId?: string;
201
+ /** Flo-owned privacy-safe telemetry is enabled by default; set `false` to opt out. */
202
+ telemetry?: boolean;
203
+ /**
204
+ * When true, renders an on-screen lifecycle tracer panel above the button
205
+ * (mount, loadScript, eligibility, render, errors). Intended for debugging
206
+ * in-app browsers (Facebook IAB, etc.) where remote console access is
207
+ * impractical. Off by default — leave disabled in production.
208
+ */
209
+ debug?: boolean;
210
+ }
211
+ /** Public direct-PayPal surface: telemetry accepts only the boolean opt-out. */
212
+ declare function DirectPayPalButton(props: DirectPayPalButtonProps): React.ReactElement | null;
61
213
 
62
214
  /** Props for the all-in-one `FloPayCheckout` wrapper. */
63
215
  interface FloPayCheckoutProps {
@@ -94,6 +246,8 @@ interface FloPayCheckoutProps {
94
246
  onComplete?: (result: PaymentResult) => void;
95
247
  /** Called when a payment error occurs. */
96
248
  onError?: (error: FloPayError) => void;
249
+ /** Receives the versioned, privacy-safe checkout instrument feed. */
250
+ onInstrument?: (event: FloInstrumentEvent) => void;
97
251
  /** Called when a payment is declined or the authentication step fails. */
98
252
  onDecline?: (decline: DeclineEvent) => void;
99
253
  /** Called when the AVS country dropdown changes. */
@@ -189,7 +343,7 @@ interface FloPayCheckoutProps {
189
343
  * In `layout="buttons"` with `createSession`, the returned patch is merged
190
344
  * into the inline session params before the selected flow continues.
191
345
  */
192
- onBeforeButtonClick?: (event: BeforeButtonClickEvent) => void | false | Promise<void | false | InlineSessionPatch> | InlineSessionPatch;
346
+ onBeforeButtonClick?: (event: BeforeButtonClickEvent) => undefined | false | Promise<undefined | false | InlineSessionPatch> | InlineSessionPatch;
193
347
  /**
194
348
  * Enable AVS (Address Verification).
195
349
  * - `true` — show country + postal code (backward compatible default)
@@ -261,7 +415,7 @@ interface FloPayCheckoutProps {
261
415
  * />
262
416
  * ```
263
417
  */
264
- declare function FloPayCheckout({ sessionId: sessionIdProp, nonce: nonceProp, createSession: createSessionParams, billingApiUrl, telemetry, appearance: appearanceOverride, locale, loading: loadingNode, error: errorNode, onComplete, onError, onDecline, onCountryChange, onZipChange, showPayPal, showStripe, enabledPaymentMethods: enabledPaymentMethodsProp, showApplePay, showGooglePay, debug, layout, theme, buttonsTheme, buttonsStyles, cardButtonContent, cardBackButtonContent, cardTitleContent, showSecurityFooter: _showSecurityFooter, onButtonClick, onBeforeButtonClick, enableAVS, cardFieldOrder, cardPreFormSlot, avsLayout, className, initialErrorMessage, children, checkoutMode: checkoutModeProp, confirmLabel, renderConfirmButton, onSessionCompleted, }: FloPayCheckoutProps): React.ReactElement;
418
+ declare function FloPayCheckout({ sessionId: sessionIdProp, nonce: nonceProp, createSession: createSessionParams, billingApiUrl, telemetry, appearance: appearanceOverride, locale, loading: loadingNode, error: errorNode, onComplete, onError, onInstrument, onDecline, onCountryChange, onZipChange, showPayPal, showStripe, enabledPaymentMethods: enabledPaymentMethodsProp, showApplePay, showGooglePay, debug, layout, theme, buttonsTheme, buttonsStyles, cardButtonContent, cardBackButtonContent, cardTitleContent, showSecurityFooter: _showSecurityFooter, onButtonClick, onBeforeButtonClick, enableAVS, cardFieldOrder, cardPreFormSlot, avsLayout, className, initialErrorMessage, children, checkoutMode: checkoutModeProp, confirmLabel, renderConfirmButton, onSessionCompleted, }: FloPayCheckoutProps): React.ReactElement;
265
419
 
266
420
  /**
267
421
  * Returns the current `FloPay` instance, or `null` if the provider
@@ -278,13 +432,6 @@ declare function useFloPay(): FloPay | null;
278
432
  * Must be called within a `<FloPayProvider>`.
279
433
  */
280
434
  declare function usePayPalFloPay(): FloPay | null;
281
- /**
282
- * Returns the current `FloPayElements` instance, or `null` if the
283
- * provider is still loading.
284
- *
285
- * Must be called within a `<FloPayProvider>`.
286
- */
287
- declare function useElements(): FloPayElements | null;
288
435
  /** Checkout state exposed by `useCheckout()`. */
289
436
  interface CheckoutState {
290
437
  session: CheckoutSession | null;
@@ -300,47 +447,43 @@ interface CheckoutState {
300
447
  */
301
448
  declare function useCheckout(): CheckoutState;
302
449
 
303
- /** Common props shared by all element components. */
304
- interface ElementComponentProps {
305
- /** Additional CSS class for the wrapper div. */
306
- className?: string;
307
- /** Element id attribute for the wrapper div. */
308
- id?: string;
309
- /** Inline styles for the wrapper div. */
310
- style?: React.CSSProperties;
311
- /** Options forwarded to the underlying element. */
312
- options?: Partial<ElementOptions>;
313
- /** Fired when the element's value changes. */
314
- onChange?: (event: ElementChangeEvent) => void;
315
- /** Fired when the element is fully rendered and ready. */
316
- onReady?: () => void;
317
- /** Fired when the element gains focus. */
318
- onFocus?: () => void;
319
- /** Fired when the element loses focus. */
320
- onBlur?: () => void;
321
- /** Fired when the Escape key is pressed inside the element. */
322
- onEscape?: () => void;
323
- }
324
- /** Props for the standalone non-card Payment Element. */
325
- interface PaymentElementProps extends Omit<ElementComponentProps, 'options'> {
450
+ /** Props for the `FloPayProvider` component. */
451
+ interface FloPayProviderProps {
452
+ /** A `FloPay` instance or a promise that resolves to one (from `loadFloPay()`). */
453
+ flopay: Promise<FloPay> | FloPay;
326
454
  /**
327
- * Element options with an explicit wallet/APM allowlist. `card` is removed
328
- * at runtime; an empty result is rejected before the provider is called.
455
+ * Optional Stripe `FloPay` instance used to drive the Stripe-rendered PayPal
456
+ * fallback. When omitted or `null`, the Stripe-rendered PayPal button is
457
+ * not rendered. Direct PayPal (`gateways.paypal`) does not use this prop.
329
458
  */
330
- options: Omit<Partial<ElementOptions>, 'paymentMethodTypes'> & {
331
- paymentMethodTypes: readonly string[];
459
+ paypalFlopay?: Promise<FloPay> | FloPay | null;
460
+ /** Optional provider configuration. */
461
+ options?: {
462
+ /** Billing API base URL. Set once here so child components don't need to repeat it. */
463
+ billingApiUrl?: string;
332
464
  };
465
+ /** Receives the versioned, privacy-safe checkout instrument feed. */
466
+ onInstrument?: (event: FloInstrumentEvent) => void;
467
+ children: React.ReactNode;
333
468
  }
334
469
  /**
335
- * Renders a provider Payment Element restricted to the declared non-card
336
- * wallet/APM methods. Card collection is available only through the hosted
337
- * vault checkout surfaces.
338
- */
339
- declare const PaymentElement: React.FC<PaymentElementProps>;
340
- /**
341
- * Renders an address input element.
470
+ * Provides FloPay SDK context to the component tree.
471
+ *
472
+ * Wrap components that consume FloPay context with this provider:
473
+ *
474
+ * ```tsx
475
+ * <FloPayProvider flopay={loadFloPay('pk_test_...')}>
476
+ * <YourCheckout />
477
+ * </FloPayProvider>
478
+ * ```
479
+ *
480
+ * `FloPayCheckout` is a standalone integration that owns its provider:
481
+ *
482
+ * ```tsx
483
+ * <FloPayCheckout sessionId="sess_..." />
484
+ * ```
342
485
  */
343
- declare const AddressElement: React.FC<ElementComponentProps>;
486
+ declare function FloPayProvider({ flopay: floPayProp, paypalFlopay: paypalFloPayProp, options, onInstrument, children, }: FloPayProviderProps): React.ReactElement;
344
487
 
345
488
  type MaybePromise<T> = T | Promise<T>;
346
489
 
@@ -490,7 +633,7 @@ interface SplitCardFormProps {
490
633
  * Called before a payment button continues in `layout="buttons"`.
491
634
  * Runs for card, PayPal, Apple Pay, and Google Pay.
492
635
  */
493
- onBeforeButtonClick?: (event: BeforeButtonClickEvent) => MaybePromise<void | false | InlineSessionPatch>;
636
+ onBeforeButtonClick?: (event: BeforeButtonClickEvent) => MaybePromise<undefined | false | InlineSessionPatch>;
494
637
  /**
495
638
  * Enable AVS (Address Verification).
496
639
  * - `true` — show country + postal code (backward compatible default)
@@ -642,270 +785,4 @@ interface VaultCardFieldsProps {
642
785
  */
643
786
  declare function VaultCardFields({ capture, html, messageToken, expectedOrigin, theme, containerStyle, onReady, onError, onValidation, }: VaultCardFieldsProps): React.ReactElement;
644
787
 
645
- /**
646
- * Props for the `PayPalButton` component.
647
- *
648
- * Must be rendered inside its own `FloPayProvider` with `paymentMethodCreation: undefined`
649
- * (not 'manual') because this PayPal flow needs automatic payment-method creation.
650
- */
651
- interface PayPalButtonProps {
652
- /** The checkout session ID (UUID from billing API). */
653
- sessionId: string;
654
- /**
655
- * Session-bound checkout token returned by session creation. Forwarded as
656
- * `x-checkout-session-token` on continuation requests — required by
657
- * post-#640 backends.
658
- */
659
- nonce?: string;
660
- /** Billing API base URL. Optional — defaults to the value from FloPayProvider or the shared constant. */
661
- billingApiUrl?: string;
662
- /** User's email. */
663
- email?: string;
664
- /** User ID for processing payments. */
665
- userId?: string;
666
- /** First name for billing. */
667
- firstName?: string;
668
- /** Last name for billing. */
669
- lastName?: string;
670
- /** Checkout version for tracking. */
671
- chv?: string;
672
- /**
673
- * Called with tokenized data after PayPal authorization.
674
- * If omitted, the component calls processPayment internally.
675
- */
676
- onTokenizedBody?: (body: TokenizedBody) => void;
677
- /** Called on successful payment (self-contained mode). */
678
- onComplete?: () => void;
679
- /** Called when an error occurs. */
680
- onErrorChange?: (error: string | null) => void;
681
- /** External processing state. */
682
- isProcessing?: boolean;
683
- }
684
- /**
685
- * PayPal button that handles the full PayPal payment flow.
686
- *
687
- * **Important**: PayPal requires its own `FloPayProvider` with automatic
688
- * payment-method creation. Keep it separate from manually created wallet/APM
689
- * Elements groups.
690
- *
691
- * ```tsx
692
- * {/* Main checkout provider *\/}
693
- * <FloPayProvider flopay={flopay} options={{ amount, currency }}>
694
- * <SplitCardForm ... />
695
- * </FloPayProvider>
696
- *
697
- * {/* PayPal provider (no paymentMethodCreation) *\/}
698
- * <FloPayProvider flopay={flopay} options={{ amount, currency, paymentMethodCreation: 'auto' }}>
699
- * <PayPalButton ... />
700
- * </FloPayProvider>
701
- * ```
702
- */
703
- declare function PayPalButton({ sessionId, nonce, billingApiUrl, email, userId, firstName, lastName, chv, onTokenizedBody, onComplete, onErrorChange, isProcessing, }: PayPalButtonProps): React.ReactElement;
704
-
705
- /**
706
- * Overrides that `SplitCardForm`'s tokenized-body dispatcher uses to apply a
707
- * `runBeforeButtonClick` patch to the in-flight processPayment call. Kept in
708
- * sync structurally with `TokenizedBodyOverrides` in `split-card-form.tsx`.
709
- */
710
- interface DirectPayPalTokenizedOverrides {
711
- accountPatch?: InlineSessionPatch['account'];
712
- sessionId?: string;
713
- nonce?: string;
714
- }
715
- /**
716
- * Internal handler signature aligned with `SplitCardForm`'s tokenized-body
717
- * dispatcher. Direct PayPal completes via the backend's process endpoint and
718
- * never produces a Stripe PaymentIntent, so we still forward a synthetic
719
- * `TokenizedBody` describing the captured order, optionally with the
720
- * session/account patch captured at click-time.
721
- */
722
- type DirectPayPalTokenizedHandler = (body: TokenizedBody, overrides?: DirectPayPalTokenizedOverrides) => void;
723
- /** Click-time `runBeforeButtonClick` result, structurally compatible with `SplitCardForm`. */
724
- interface DirectPayPalBeforeButtonClickResult {
725
- proceed: boolean;
726
- accountPatch?: InlineSessionPatch['account'];
727
- sessionId?: string;
728
- nonce?: string;
729
- }
730
- /**
731
- * Click-time gate. Mirrors `RunBeforeButtonClick` in `SplitCardForm`: lets the
732
- * consumer patch the session/account before PayPal creates the order, and lets
733
- * them abort the click entirely by returning `proceed: false`.
734
- */
735
- type DirectPayPalRunBeforeButtonClick = (method: CheckoutButtonMethod) => Promise<DirectPayPalBeforeButtonClickResult>;
736
- type DirectPayPalInitializationState = 'loading' | 'retrying' | 'ready' | 'exhausted';
737
- type DirectPayPalTechnicalFailureHandler = (method: 'paypal', err: unknown, options?: {
738
- code?: string;
739
- popupBlocked?: boolean;
740
- }) => void;
741
- interface DirectPayPalButtonProps {
742
- /** Checkout session ID. */
743
- sessionId: string;
744
- /**
745
- * Session-bound checkout token returned by session creation. Forwarded as
746
- * `x-checkout-session-token` on every continuation request — required by
747
- * post-#640 backends. `FloPayCheckout` plumbs this prop automatically.
748
- */
749
- nonce?: string;
750
- /** Billing API base URL. */
751
- billingApiUrl: string;
752
- /** Buyer email. */
753
- email?: string;
754
- /** PayPal client identifier (`gateways.paypal.publishableKey`). */
755
- clientId: string;
756
- /** Gateway environment, drives the sandbox/live SDK script. */
757
- environment?: GatewayEnvironment;
758
- /** ISO 4217 currency code. */
759
- currency: string;
760
- /** Whether the session is a subscription (drives intent + flow selection). */
761
- isSubscription: boolean;
762
- /**
763
- * Provider object the backend advertised for this PayPal continuation.
764
- * When omitted, legacy sessions continue to derive the flow from
765
- * `isSubscription`. An advertised `'order'`/`'setup_token'` opts intent and
766
- * process requests into the Flo-owned `paypal_vaulted` payment-method
767
- * channel; an advertised `'subscription'` or an omission keeps the released
768
- * `paypal` requests byte-identical.
769
- */
770
- providerObjectType?: PayPalProviderObjectType;
771
- /**
772
- * If provided, called with the tokenized body once PayPal capture
773
- * completes. When omitted, the component processes payment internally.
774
- */
775
- onTokenizedBody?: DirectPayPalTokenizedHandler;
776
- /** Called when the full self-contained payment flow succeeds. */
777
- onComplete?: (result: PaymentResult) => void;
778
- /** Called when an error occurs. */
779
- onErrorChange?: (error: string | null) => void;
780
- /** Decline emitter (mirrors SplitCardForm semantics). */
781
- onDecline?: (decline: DeclineEvent) => void;
782
- /** Called for post-click technical failures before PayPal authorization completes. */
783
- onTechnicalFailure?: DirectPayPalTechnicalFailureHandler;
784
- /** External processing state. */
785
- isProcessing?: boolean;
786
- /** Notify the parent of the loading state for placeholder swapping. */
787
- onLoadStateChange?: (ready: boolean) => void;
788
- /** Notify a PayPal-only wrapper about pre-render recovery state. */
789
- onInitializationStateChange?: (state: DirectPayPalInitializationState) => void;
790
- /** Disable the automatic retry for a buyer-initiated single manual attempt. */
791
- allowAutomaticRetry?: boolean;
792
- /** Tracks button-click for analytics. */
793
- onButtonClick?: (method: CheckoutButtonMethod) => void;
794
- /**
795
- * Click-time gate (runs before PayPal creates the order). When provided, the
796
- * returned patch is applied to the in-flight create-intent and tokenized
797
- * dispatch so callers using `onBeforeButtonClick` see the same session/email
798
- * the Stripe-rendered PayPal flow does.
799
- */
800
- runBeforeButtonClick?: DirectPayPalRunBeforeButtonClick;
801
- /** Backing session — used for self-contained accountData population. */
802
- session?: CheckoutSession | null;
803
- /**
804
- * Pre-existing PayPal Order id (or Subscription id when `isSubscription` is
805
- * true) to bind the button to. When set, the button skips its usual
806
- * session-scoped create-intent round-trip on click and feeds this
807
- * id straight into PayPal's create-order / create-subscription callback.
808
- *
809
- * Used by `SplitCardForm`'s `paypal_direct_required` retry path: backend
810
- * creates a fresh PayPal order after a stalled process attempt and returns
811
- * its id; the SDK re-renders this button bound to that id so the buyer can
812
- * confirm with one more click without the backend re-creating the order on
813
- * each retry.
814
- *
815
- * Changing this value remounts the PayPal SDK so the new createOrder
816
- * binding takes effect (PayPal's render() options aren't live-updatable).
817
- */
818
- existingOrderId?: string;
819
- /** Flo-owned privacy-safe telemetry is enabled by default; set `false` to opt out. */
820
- telemetry?: boolean;
821
- /**
822
- * When true, renders an on-screen lifecycle tracer panel above the button
823
- * (mount, loadScript, eligibility, render, errors). Intended for debugging
824
- * in-app browsers (Facebook IAB, etc.) where remote console access is
825
- * impractical. Off by default — leave disabled in production.
826
- */
827
- debug?: boolean;
828
- }
829
- /** Public direct-PayPal surface: telemetry accepts only the boolean opt-out. */
830
- declare function DirectPayPalButton(props: DirectPayPalButtonProps): React.ReactElement | null;
831
-
832
- interface FloPayAutomaticPaymentSuccessEvent {
833
- result: PaymentResult;
834
- session: CheckoutSession | null;
835
- sessionId: string | null;
836
- autoCompleted: boolean;
837
- }
838
- interface FloPayAutomaticPaymentButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onError'> {
839
- sessionId?: string;
840
- /**
841
- * Session-bound checkout token for a consumer-supplied {@link sessionId}
842
- * (the `nonce` returned when that session was created). Post-#640 backends
843
- * require it as `x-checkout-session-token` to read the session and to
844
- * `/process` it; without it the existing-session path 401s with
845
- * "Missing checkout session token.". Ignored on the create-session path,
846
- * where the SDK mints and threads the nonce itself.
847
- */
848
- nonce?: string;
849
- createSession?: InlineSessionDraft;
850
- /**
851
- * @deprecated Ignored. The backend now picks the customer's most recent
852
- * vaulted payment method via `getLatestByUserId` and rebinds the session's
853
- * gateway to match it (see `apps/api`'s `createSingle` auto-checkout
854
- * branch). Passing this prop has no effect — it is retained only to avoid
855
- * breaking existing integrations.
856
- */
857
- paymentMethodId?: string;
858
- /**
859
- * @deprecated Ignored. The backend orchestrates gateway routing — clients
860
- * no longer choose between card and PayPal at the SDK boundary. Passing
861
- * this prop has no effect.
862
- */
863
- checkoutMethod?: CheckoutButtonMethod;
864
- clientId?: string;
865
- /**
866
- * Unified products array (TeamFloPay/backend#760). When supplied,
867
- * `items`/`subscriptions` are ignored. The SDK folds the legacy fields
868
- * into this shape internally.
869
- */
870
- products?: CheckoutProduct[];
871
- items?: CheckoutItem[];
872
- subscriptions?: CheckoutSubscription[];
873
- account?: InlineSessionDraft['account'];
874
- successUrl?: string;
875
- cancelUrl?: string;
876
- couponCodes?: string[];
877
- tagsData?: InlineSessionDraft['tagsData'];
878
- utmMetadata?: InlineSessionDraft['utmMetadata'];
879
- billingApiUrl?: string;
880
- locale?: string;
881
- /**
882
- * High-level theme bundle that styles the button (and the fallback
883
- * `FloPayCheckout` modal that opens when the saved-payment charge needs
884
- * user interaction). One of: `'classic'`, `'modern-light'`, `'modern-dark'`,
885
- * `'bold-light'`, `'bold-dark'`, `'glass-light'`, `'glass-dark'`. Explicit
886
- * `buttonsStyles` still wins for fine-grained overrides.
887
- */
888
- theme?: ThemeId;
889
- /**
890
- * Per-checkout appearance overrides layered on top of the chosen `theme`
891
- * (same shape as {@link FloPayCheckout}'s `appearance`). Its `colorPrimary` /
892
- * `colorPrimaryHover` / `borderRadius` re-skin the button — and the fallback
893
- * `FloPayCheckout` modal — so the auto-pay button matches the rest of the
894
- * themed checkout. Without this the button only saw the bundle's defaults.
895
- */
896
- appearance?: FloPayAppearance;
897
- /**
898
- * @deprecated Use `theme` instead. Legacy buttons-layout preset
899
- * (`'default' | 'minimal' | 'rounded' | 'dark'`). Still honored for
900
- * back-compat.
901
- */
902
- buttonsTheme?: ButtonsLayoutTheme;
903
- buttonsStyles?: ButtonsLayoutStyles;
904
- onSuccess?: (event: FloPayAutomaticPaymentSuccessEvent) => void;
905
- onError?: (error: FloPayError) => void;
906
- onDecline?: (decline: DeclineEvent) => void;
907
- children?: React.ReactNode;
908
- }
909
- declare function FloPayAutomaticPaymentButton({ sessionId, nonce, createSession, paymentMethodId: _deprecatedPaymentMethodId, checkoutMethod: _deprecatedCheckoutMethod, clientId, products, items, subscriptions, account, successUrl, cancelUrl, couponCodes, tagsData, utmMetadata, billingApiUrl, locale, theme, appearance, buttonsTheme, buttonsStyles: stylesOverride, onSuccess, onError, onDecline, children, disabled, type, style, ...buttonProps }: FloPayAutomaticPaymentButtonProps): React.JSX.Element;
910
-
911
- export { AddressElement, type CheckoutState, DirectPayPalButton, type DirectPayPalButtonProps, type DirectPayPalInitializationState, type ElementComponentProps, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, type PaymentElementProps, SplitCardForm, type SplitCardFormProps, VaultCardFields, type VaultCardFieldsProps, useCheckout, useElements, useFloPay, usePayPalFloPay };
788
+ export { type CheckoutState, DirectPayPalButton, type DirectPayPalButtonProps, type DirectPayPalInitializationState, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, SplitCardForm, type SplitCardFormProps, VaultCardFields, type VaultCardFieldsProps, useCheckout, useFloPay, usePayPalFloPay };