@flopay/react 0.3.15 → 0.3.17

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
@@ -72,6 +72,12 @@ interface FloPayCheckoutProps {
72
72
  onError?: (error: FloPayError) => void;
73
73
  /** Called when a payment is declined or the authentication step fails. */
74
74
  onDecline?: (decline: DeclineEvent) => void;
75
+ /** Called when the full cardholder name input changes. */
76
+ onFullNameChange?: (value: string) => void;
77
+ /** Called when the AVS country dropdown changes. */
78
+ onCountryChange?: (country: string) => void;
79
+ /** Called when the AVS ZIP/postcode input changes. */
80
+ onZipChange?: (zip: string) => void;
75
81
  /** Whether to show the PayPal button (default: true). */
76
82
  showPayPal?: boolean;
77
83
  /** Whether to show Apple Pay button (default: true). Only renders on supported devices. */
@@ -152,7 +158,7 @@ interface FloPayCheckoutProps {
152
158
  * />
153
159
  * ```
154
160
  */
155
- declare function FloPayCheckout({ sessionId: sessionIdProp, createSession: createSessionParams, billingApiUrl, appearance, locale, fallbackPublishableKey, loading: loadingNode, error: errorNode, onComplete, onError, onDecline, showPayPal, showApplePay, showGooglePay, layout, buttonsTheme, buttonsStyles, cardButtonContent, cardBackButtonContent, cardTitleContent, onButtonClick, onBeforeButtonClick, enableAVS, avsLayout, submitLabel, className, children, checkoutMode: checkoutModeProp, confirmLabel, renderConfirmButton, onSessionCompleted, }: FloPayCheckoutProps): React.ReactElement;
161
+ declare function FloPayCheckout({ sessionId: sessionIdProp, createSession: createSessionParams, billingApiUrl, appearance, locale, fallbackPublishableKey, loading: loadingNode, error: errorNode, onComplete, onError, onDecline, onFullNameChange, onCountryChange, onZipChange, showPayPal, showApplePay, showGooglePay, layout, buttonsTheme, buttonsStyles, cardButtonContent, cardBackButtonContent, cardTitleContent, onButtonClick, onBeforeButtonClick, enableAVS, avsLayout, submitLabel, className, children, checkoutMode: checkoutModeProp, confirmLabel, renderConfirmButton, onSessionCompleted, }: FloPayCheckoutProps): React.ReactElement;
156
162
 
157
163
  /**
158
164
  * Returns the current `FloPay` instance, or `null` if the provider
@@ -366,6 +372,8 @@ interface SplitCardFormProps {
366
372
  error?: string | null;
367
373
  /** Called when internal error state changes. */
368
374
  onErrorChange?: (error: string | null) => void;
375
+ /** Callback when the full cardholder name input changes. */
376
+ onFullNameChange?: (value: string) => void;
369
377
  /** Callback when first name changes (from the name input). */
370
378
  onFirstNameChange?: (value: string) => void;
371
379
  /** Callback when last name changes (from the name input). */
package/dist/index.d.ts CHANGED
@@ -72,6 +72,12 @@ interface FloPayCheckoutProps {
72
72
  onError?: (error: FloPayError) => void;
73
73
  /** Called when a payment is declined or the authentication step fails. */
74
74
  onDecline?: (decline: DeclineEvent) => void;
75
+ /** Called when the full cardholder name input changes. */
76
+ onFullNameChange?: (value: string) => void;
77
+ /** Called when the AVS country dropdown changes. */
78
+ onCountryChange?: (country: string) => void;
79
+ /** Called when the AVS ZIP/postcode input changes. */
80
+ onZipChange?: (zip: string) => void;
75
81
  /** Whether to show the PayPal button (default: true). */
76
82
  showPayPal?: boolean;
77
83
  /** Whether to show Apple Pay button (default: true). Only renders on supported devices. */
@@ -152,7 +158,7 @@ interface FloPayCheckoutProps {
152
158
  * />
153
159
  * ```
154
160
  */
155
- declare function FloPayCheckout({ sessionId: sessionIdProp, createSession: createSessionParams, billingApiUrl, appearance, locale, fallbackPublishableKey, loading: loadingNode, error: errorNode, onComplete, onError, onDecline, showPayPal, showApplePay, showGooglePay, layout, buttonsTheme, buttonsStyles, cardButtonContent, cardBackButtonContent, cardTitleContent, onButtonClick, onBeforeButtonClick, enableAVS, avsLayout, submitLabel, className, children, checkoutMode: checkoutModeProp, confirmLabel, renderConfirmButton, onSessionCompleted, }: FloPayCheckoutProps): React.ReactElement;
161
+ declare function FloPayCheckout({ sessionId: sessionIdProp, createSession: createSessionParams, billingApiUrl, appearance, locale, fallbackPublishableKey, loading: loadingNode, error: errorNode, onComplete, onError, onDecline, onFullNameChange, onCountryChange, onZipChange, showPayPal, showApplePay, showGooglePay, layout, buttonsTheme, buttonsStyles, cardButtonContent, cardBackButtonContent, cardTitleContent, onButtonClick, onBeforeButtonClick, enableAVS, avsLayout, submitLabel, className, children, checkoutMode: checkoutModeProp, confirmLabel, renderConfirmButton, onSessionCompleted, }: FloPayCheckoutProps): React.ReactElement;
156
162
 
157
163
  /**
158
164
  * Returns the current `FloPay` instance, or `null` if the provider
@@ -366,6 +372,8 @@ interface SplitCardFormProps {
366
372
  error?: string | null;
367
373
  /** Called when internal error state changes. */
368
374
  onErrorChange?: (error: string | null) => void;
375
+ /** Callback when the full cardholder name input changes. */
376
+ onFullNameChange?: (value: string) => void;
369
377
  /** Callback when first name changes (from the name input). */
370
378
  onFirstNameChange?: (value: string) => void;
371
379
  /** Callback when last name changes (from the name input). */
package/dist/index.mjs CHANGED
@@ -361,6 +361,52 @@ function toCssWeight(value) {
361
361
  if (typeof value === "number" || typeof value === "string") return value;
362
362
  return void 0;
363
363
  }
364
+ function resolveExpressCheckoutLoadState(event, methods) {
365
+ const available = event.availablePaymentMethods;
366
+ if (!available) return "unavailable";
367
+ return methods.some((method) => available[method]) ? "ready" : "unavailable";
368
+ }
369
+ function ExpressCheckoutReadySwap({
370
+ state,
371
+ placeholderTestId,
372
+ children
373
+ }) {
374
+ if (state === "unavailable") return null;
375
+ return /* @__PURE__ */ jsxs2("div", { style: { position: "relative", minHeight: 44 }, children: [
376
+ /* @__PURE__ */ jsx4(
377
+ "div",
378
+ {
379
+ "data-testid": placeholderTestId,
380
+ "aria-hidden": state === "ready",
381
+ style: {
382
+ position: "absolute",
383
+ inset: 0,
384
+ height: 44,
385
+ borderRadius: 8,
386
+ background: "#e5e7eb",
387
+ animation: state === "ready" ? void 0 : "flopay-pulse 1.5s ease-in-out infinite",
388
+ opacity: state === "ready" ? 0 : 1,
389
+ transform: state === "ready" ? "scale(0.985)" : "scale(1)",
390
+ transition: "opacity 140ms ease-out, transform 140ms ease-out",
391
+ pointerEvents: "none"
392
+ }
393
+ }
394
+ ),
395
+ /* @__PURE__ */ jsx4(
396
+ "div",
397
+ {
398
+ style: {
399
+ minHeight: 44,
400
+ opacity: state === "ready" ? 1 : 0,
401
+ transform: state === "ready" ? "translateY(0)" : "translateY(2px)",
402
+ transition: "opacity 140ms ease-out, transform 140ms ease-out",
403
+ pointerEvents: state === "ready" ? "auto" : "none"
404
+ },
405
+ children
406
+ }
407
+ )
408
+ ] });
409
+ }
364
410
  function ProcessingOverlay({ status, errorMessage }) {
365
411
  return /* @__PURE__ */ jsx4("div", { style: {
366
412
  position: "fixed",
@@ -478,7 +524,7 @@ function PayPalButtonInner({
478
524
  }) {
479
525
  const stripe = useStripeRaw();
480
526
  const elements = useStripeElements();
481
- const [ready, setReady] = useState2(false);
527
+ const [loadState, setLoadState] = useState2("loading");
482
528
  const [submitting, setSubmitting] = useState2(false);
483
529
  const paypalResumeAttempted = useRef2(false);
484
530
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
@@ -590,12 +636,11 @@ function PayPalButtonInner({
590
636
  }
591
637
  }, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline]);
592
638
  return /* @__PURE__ */ jsxs2(Fragment2, { children: [
593
- /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsx4(
639
+ /* @__PURE__ */ jsx4(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-paypal-placeholder", children: /* @__PURE__ */ jsx4(
594
640
  ExpressCheckoutElement,
595
641
  {
596
- onReady: () => setReady(true),
597
- onLoadError: () => {
598
- },
642
+ onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
643
+ onLoadError: () => setLoadState("unavailable"),
599
644
  onConfirm: handlePayPalConfirm,
600
645
  onCancel: () => {
601
646
  onDecline?.(buildDeclineEvent("paypal", "PayPal checkout was cancelled."));
@@ -627,7 +672,7 @@ function WalletButtonInner({
627
672
  }) {
628
673
  const stripe = useStripeRaw();
629
674
  const elements = useStripeElements();
630
- const [ready, setReady] = useState2(false);
675
+ const [loadState, setLoadState] = useState2("loading");
631
676
  const [submitting, setSubmitting] = useState2(false);
632
677
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
633
678
  const lastWalletMethodRef = useRef2("card");
@@ -693,12 +738,11 @@ function WalletButtonInner({
693
738
  [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline]
694
739
  );
695
740
  return /* @__PURE__ */ jsxs2(Fragment2, { children: [
696
- /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsx4(
741
+ /* @__PURE__ */ jsx4(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-wallet-placeholder", children: /* @__PURE__ */ jsx4(
697
742
  ExpressCheckoutElement,
698
743
  {
699
- onReady: () => setReady(true),
700
- onLoadError: () => {
701
- },
744
+ onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["applePay", "googlePay"])),
745
+ onLoadError: () => setLoadState("unavailable"),
702
746
  onClick: (event) => {
703
747
  lastWalletMethodRef.current = event.expressPaymentType === "apple_pay" ? "apple_pay" : "google_pay";
704
748
  event.resolve();
@@ -742,6 +786,7 @@ function SplitCardFormInner({
742
786
  isProcessing: externalProcessing,
743
787
  error: externalError,
744
788
  onErrorChange,
789
+ onFullNameChange,
745
790
  onFirstNameChange,
746
791
  onLastNameChange,
747
792
  showPayPal = true,
@@ -860,10 +905,11 @@ function SplitCardFormInner({
860
905
  const showWallets = showApplePay || showGooglePay;
861
906
  const handleNameChange = useCallback((value) => {
862
907
  setFullName(value);
908
+ onFullNameChange?.(value);
863
909
  const parts = value.trim().split(/\s+/);
864
910
  onFirstNameChange?.(parts[0] ?? "");
865
911
  onLastNameChange?.(parts.length > 1 ? parts.slice(1).join(" ") : "");
866
- }, [onFirstNameChange, onLastNameChange]);
912
+ }, [onFullNameChange, onFirstNameChange, onLastNameChange]);
867
913
  const runBeforeCardButtonClick = useCallback(async () => {
868
914
  if (!onBeforeButtonClick) return true;
869
915
  try {
@@ -1625,6 +1671,9 @@ function FloPayCheckout({
1625
1671
  onComplete,
1626
1672
  onError,
1627
1673
  onDecline,
1674
+ onFullNameChange,
1675
+ onCountryChange,
1676
+ onZipChange,
1628
1677
  showPayPal = true,
1629
1678
  showApplePay = true,
1630
1679
  showGooglePay = true,
@@ -2223,6 +2272,7 @@ function FloPayCheckout({
2223
2272
  onComplete,
2224
2273
  onError,
2225
2274
  onDecline,
2275
+ onFullNameChange,
2226
2276
  showPayPal,
2227
2277
  showApplePay,
2228
2278
  showGooglePay,
@@ -2237,6 +2287,8 @@ function FloPayCheckout({
2237
2287
  enableAVS,
2238
2288
  avsLayout,
2239
2289
  country: session?.customer?.country,
2290
+ onCountryChange,
2291
+ onZipChange,
2240
2292
  submitLabel,
2241
2293
  className
2242
2294
  }