@flopay/react 0.3.17 → 0.3.20

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
@@ -102,10 +102,10 @@ interface FloPayCheckoutProps {
102
102
  */
103
103
  onButtonClick?: (method: CheckoutButtonMethod) => void;
104
104
  /**
105
- * Called before the credit/debit card button continues.
106
- * Card only: this does not run for PayPal or wallet buttons.
105
+ * Called before a payment button continues in `layout="buttons"`.
106
+ * Runs for card, PayPal, Apple Pay, and Google Pay.
107
107
  * In `layout="buttons"` with `createSession`, the returned patch is merged
108
- * into the inline session params before the real card session is created.
108
+ * into the inline session params before the selected flow continues.
109
109
  */
110
110
  onBeforeButtonClick?: (event: BeforeButtonClickEvent) => void | false | Promise<void | false | InlineSessionPatch> | InlineSessionPatch;
111
111
  /**
@@ -417,8 +417,8 @@ interface SplitCardFormProps {
417
417
  */
418
418
  onButtonClick?: (method: CheckoutButtonMethod) => void;
419
419
  /**
420
- * Called before the credit/debit card button continues.
421
- * Card only: this does not run for PayPal or wallet buttons.
420
+ * Called before a payment button continues in `layout="buttons"`.
421
+ * Runs for card, PayPal, Apple Pay, and Google Pay.
422
422
  */
423
423
  onBeforeButtonClick?: (event: BeforeButtonClickEvent) => MaybePromise<void | false | InlineSessionPatch>;
424
424
  /**
package/dist/index.d.ts CHANGED
@@ -102,10 +102,10 @@ interface FloPayCheckoutProps {
102
102
  */
103
103
  onButtonClick?: (method: CheckoutButtonMethod) => void;
104
104
  /**
105
- * Called before the credit/debit card button continues.
106
- * Card only: this does not run for PayPal or wallet buttons.
105
+ * Called before a payment button continues in `layout="buttons"`.
106
+ * Runs for card, PayPal, Apple Pay, and Google Pay.
107
107
  * In `layout="buttons"` with `createSession`, the returned patch is merged
108
- * into the inline session params before the real card session is created.
108
+ * into the inline session params before the selected flow continues.
109
109
  */
110
110
  onBeforeButtonClick?: (event: BeforeButtonClickEvent) => void | false | Promise<void | false | InlineSessionPatch> | InlineSessionPatch;
111
111
  /**
@@ -417,8 +417,8 @@ interface SplitCardFormProps {
417
417
  */
418
418
  onButtonClick?: (method: CheckoutButtonMethod) => void;
419
419
  /**
420
- * Called before the credit/debit card button continues.
421
- * Card only: this does not run for PayPal or wallet buttons.
420
+ * Called before a payment button continues in `layout="buttons"`.
421
+ * Runs for card, PayPal, Apple Pay, and Google Pay.
422
422
  */
423
423
  onBeforeButtonClick?: (event: BeforeButtonClickEvent) => MaybePromise<void | false | InlineSessionPatch>;
424
424
  /**
package/dist/index.mjs CHANGED
@@ -350,6 +350,25 @@ var FLOPAY_KEYFRAMES = `
350
350
  100% { opacity: 0; transform: translateX(16px) scale(0.97); }
351
351
  }
352
352
  `;
353
+ var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;
354
+ function getButtonMethodLabel(method) {
355
+ switch (method) {
356
+ case "paypal":
357
+ return "PayPal";
358
+ case "apple_pay":
359
+ return "Apple Pay";
360
+ case "google_pay":
361
+ return "Google Pay";
362
+ default:
363
+ return "Card";
364
+ }
365
+ }
366
+ function normalizeBeforeButtonClickError(method, err) {
367
+ return err instanceof FloPayError2 ? err : new FloPayError2(
368
+ err instanceof Error ? err.message : `${getButtonMethodLabel(method)} before-click hook failed.`,
369
+ "validation_error"
370
+ );
371
+ }
353
372
  function FloPayKeyframes() {
354
373
  return /* @__PURE__ */ jsx4("style", { children: FLOPAY_KEYFRAMES });
355
374
  }
@@ -520,13 +539,15 @@ function PayPalButtonInner({
520
539
  onErrorChange,
521
540
  isProcessing = false,
522
541
  onButtonClick,
523
- onDecline
542
+ onDecline,
543
+ runBeforeButtonClick
524
544
  }) {
525
545
  const stripe = useStripeRaw();
526
546
  const elements = useStripeElements();
527
547
  const [loadState, setLoadState] = useState2("loading");
528
548
  const [submitting, setSubmitting] = useState2(false);
529
549
  const paypalResumeAttempted = useRef2(false);
550
+ const beforeClickRef = useRef2(null);
530
551
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
531
552
  useEffect3(() => {
532
553
  if (!stripe || paypalResumeAttempted.current) return;
@@ -575,13 +596,45 @@ function PayPalButtonInner({
575
596
  }
576
597
  })();
577
598
  }, [stripe, onTokenizedBody, onErrorChange, onDecline]);
578
- const handlePayPalConfirm = useCallback(async (_event) => {
599
+ const handlePayPalClick = useCallback(async (event) => {
600
+ if (isProcessing || submitting) {
601
+ event.reject();
602
+ return;
603
+ }
604
+ const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick("paypal") : { proceed: true };
605
+ if (!beforeClick.proceed) {
606
+ beforeClickRef.current = null;
607
+ event.reject();
608
+ return;
609
+ }
610
+ beforeClickRef.current = {
611
+ accountPatch: beforeClick.accountPatch,
612
+ sessionId: beforeClick.sessionId
613
+ };
614
+ event.resolve();
615
+ }, [isProcessing, runBeforeButtonClick, submitting]);
616
+ const handlePayPalConfirm = useCallback(async (event) => {
579
617
  if (!stripe || !elements) return;
618
+ let prepared = beforeClickRef.current;
619
+ beforeClickRef.current = null;
620
+ if (!prepared && runBeforeButtonClick) {
621
+ const beforeClick = await runBeforeButtonClick("paypal");
622
+ if (!beforeClick.proceed) {
623
+ event.paymentFailed({ reason: "fail", message: "PayPal checkout was cancelled." });
624
+ return;
625
+ }
626
+ prepared = {
627
+ accountPatch: beforeClick.accountPatch,
628
+ sessionId: beforeClick.sessionId
629
+ };
630
+ }
631
+ const effectiveSessionId = prepared?.sessionId ?? sessionId;
632
+ const effectiveEmail = prepared?.accountPatch?.email ?? email;
580
633
  onButtonClick?.("paypal");
581
634
  try {
582
635
  setSubmitting(true);
583
636
  onErrorChange?.(null);
584
- if (!sessionId || !email) {
637
+ if (!effectiveSessionId || !effectiveEmail) {
585
638
  throw new Error("Missing sessionId or email for PayPal payment");
586
639
  }
587
640
  const createPM = stripe.createPaymentMethod;
@@ -593,8 +646,8 @@ function PayPalButtonInner({
593
646
  method: "POST",
594
647
  headers: { "Content-Type": "application/json" },
595
648
  body: JSON.stringify({
596
- sessionId,
597
- email,
649
+ sessionId: effectiveSessionId,
650
+ email: effectiveEmail,
598
651
  paymentMethodType: paymentMethod?.id ?? "paypal",
599
652
  isPaypal: "true"
600
653
  })
@@ -628,21 +681,26 @@ function PayPalButtonInner({
628
681
  type: "card",
629
682
  threeDSecureActionResultTokenId: paymentIntent?.id,
630
683
  isPaypal: true
684
+ }, {
685
+ accountPatch: prepared?.accountPatch,
686
+ sessionId: effectiveSessionId
631
687
  });
632
688
  } catch (err) {
633
689
  onErrorChange?.(err instanceof Error ? err.message : "PayPal payment failed. Please try again.");
634
690
  } finally {
635
691
  setSubmitting(false);
636
692
  }
637
- }, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline]);
693
+ }, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, onButtonClick, runBeforeButtonClick]);
638
694
  return /* @__PURE__ */ jsxs2(Fragment2, { children: [
639
695
  /* @__PURE__ */ jsx4(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-paypal-placeholder", children: /* @__PURE__ */ jsx4(
640
696
  ExpressCheckoutElement,
641
697
  {
642
698
  onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
643
699
  onLoadError: () => setLoadState("unavailable"),
700
+ onClick: handlePayPalClick,
644
701
  onConfirm: handlePayPalConfirm,
645
702
  onCancel: () => {
703
+ beforeClickRef.current = null;
646
704
  onDecline?.(buildDeclineEvent("paypal", "PayPal checkout was cancelled."));
647
705
  },
648
706
  options: {
@@ -668,7 +726,8 @@ function WalletButtonInner({
668
726
  onTokenizedBody,
669
727
  onErrorChange,
670
728
  onButtonClick,
671
- onDecline
729
+ onDecline,
730
+ runBeforeButtonClick
672
731
  }) {
673
732
  const stripe = useStripeRaw();
674
733
  const elements = useStripeElements();
@@ -676,10 +735,29 @@ function WalletButtonInner({
676
735
  const [submitting, setSubmitting] = useState2(false);
677
736
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
678
737
  const lastWalletMethodRef = useRef2("card");
738
+ const beforeClickRef = useRef2(null);
679
739
  const handleWalletConfirm = useCallback(
680
- async (_event) => {
740
+ async (event) => {
681
741
  if (!stripe || !elements) return;
682
- const walletType = _event.expressPaymentType;
742
+ const walletType = event.expressPaymentType;
743
+ let prepared = beforeClickRef.current;
744
+ beforeClickRef.current = null;
745
+ if (!prepared && runBeforeButtonClick) {
746
+ const beforeClick = await runBeforeButtonClick(
747
+ walletType === "apple_pay" ? "apple_pay" : "google_pay"
748
+ );
749
+ if (!beforeClick.proceed) {
750
+ event.paymentFailed({ reason: "fail", message: "Wallet checkout was cancelled." });
751
+ return;
752
+ }
753
+ prepared = {
754
+ accountPatch: beforeClick.accountPatch,
755
+ sessionId: beforeClick.sessionId
756
+ };
757
+ }
758
+ const method = walletType === "apple_pay" ? "apple_pay" : "google_pay";
759
+ const effectiveSessionId = prepared?.sessionId ?? sessionId;
760
+ const effectiveEmail = prepared?.accountPatch?.email ?? email;
683
761
  onButtonClick?.(walletType === "apple_pay" ? "apple_pay" : "google_pay");
684
762
  try {
685
763
  setSubmitting(true);
@@ -694,15 +772,15 @@ function WalletButtonInner({
694
772
  onErrorChange?.(pmError?.message ?? "Failed to create payment method.");
695
773
  return;
696
774
  }
697
- if (!sessionId || !email) {
775
+ if (!effectiveSessionId || !effectiveEmail) {
698
776
  throw new Error("Missing sessionId or email for wallet payment");
699
777
  }
700
778
  const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
701
779
  method: "POST",
702
780
  headers: { "Content-Type": "application/json" },
703
781
  body: JSON.stringify({
704
- sessionId,
705
- email,
782
+ sessionId: effectiveSessionId,
783
+ email: effectiveEmail,
706
784
  paymentMethodType: paymentMethod.id,
707
785
  isPaypal: false
708
786
  })
@@ -716,7 +794,6 @@ function WalletButtonInner({
716
794
  { payment_method: paymentMethod.id }
717
795
  );
718
796
  if (confirmError) {
719
- const method = walletType === "apple_pay" ? "apple_pay" : "google_pay";
720
797
  const message = confirmError.message ?? "Wallet payment failed.";
721
798
  onErrorChange?.(message);
722
799
  onDecline?.(buildDeclineEvent(method, message, {
@@ -728,6 +805,9 @@ function WalletButtonInner({
728
805
  id: paymentMethod.id,
729
806
  type: "card",
730
807
  threeDSecureActionResultTokenId: paymentIntent?.id
808
+ }, {
809
+ accountPatch: prepared?.accountPatch,
810
+ sessionId: effectiveSessionId
731
811
  });
732
812
  } catch (err) {
733
813
  onErrorChange?.(err instanceof Error ? err.message : "Wallet payment failed. Please try again.");
@@ -735,7 +815,7 @@ function WalletButtonInner({
735
815
  setSubmitting(false);
736
816
  }
737
817
  },
738
- [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline]
818
+ [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, onButtonClick, runBeforeButtonClick]
739
819
  );
740
820
  return /* @__PURE__ */ jsxs2(Fragment2, { children: [
741
821
  /* @__PURE__ */ jsx4(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-wallet-placeholder", children: /* @__PURE__ */ jsx4(
@@ -743,12 +823,23 @@ function WalletButtonInner({
743
823
  {
744
824
  onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["applePay", "googlePay"])),
745
825
  onLoadError: () => setLoadState("unavailable"),
746
- onClick: (event) => {
826
+ onClick: async (event) => {
747
827
  lastWalletMethodRef.current = event.expressPaymentType === "apple_pay" ? "apple_pay" : "google_pay";
828
+ const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick(lastWalletMethodRef.current) : { proceed: true };
829
+ if (!beforeClick.proceed) {
830
+ beforeClickRef.current = null;
831
+ event.reject();
832
+ return;
833
+ }
834
+ beforeClickRef.current = {
835
+ accountPatch: beforeClick.accountPatch,
836
+ sessionId: beforeClick.sessionId
837
+ };
748
838
  event.resolve();
749
839
  },
750
840
  onConfirm: handleWalletConfirm,
751
841
  onCancel: () => {
842
+ beforeClickRef.current = null;
752
843
  onDecline?.(buildDeclineEvent(lastWalletMethodRef.current, "Wallet checkout was cancelled."));
753
844
  },
754
845
  options: {
@@ -910,55 +1001,83 @@ function SplitCardFormInner({
910
1001
  onFirstNameChange?.(parts[0] ?? "");
911
1002
  onLastNameChange?.(parts.length > 1 ? parts.slice(1).join(" ") : "");
912
1003
  }, [onFullNameChange, onFirstNameChange, onLastNameChange]);
913
- const runBeforeCardButtonClick = useCallback(async () => {
914
- if (!onBeforeButtonClick) return true;
1004
+ const applyInlineSessionPatch = useCallback(
1005
+ (patch, method) => {
1006
+ if (!checkout.applyInlineSessionPatch) {
1007
+ return Promise.resolve({ error: null, sessionId });
1008
+ }
1009
+ return checkout.applyInlineSessionPatch(patch).then((result) => ({
1010
+ error: null,
1011
+ sessionId: result.sessionId || sessionId
1012
+ })).catch((err) => {
1013
+ const floPayErr = normalizeBeforeButtonClickError(method, err);
1014
+ updateError(floPayErr.message);
1015
+ onError?.(floPayErr);
1016
+ return { error: floPayErr, sessionId };
1017
+ });
1018
+ },
1019
+ [checkout.applyInlineSessionPatch, onError, sessionId, updateError]
1020
+ );
1021
+ const runBeforeButtonClick = useCallback(async (method) => {
1022
+ if (!onBeforeButtonClick) return { proceed: true };
915
1023
  try {
916
1024
  const result = await onBeforeButtonClick({
917
- method: "card",
918
- sessionId: sessionId || void 0
1025
+ method,
1026
+ sessionId: sessionId || void 0,
1027
+ createSession: checkout.inlineSessionDraft
919
1028
  });
920
1029
  if (result === false) {
921
- return false;
1030
+ return { proceed: false };
922
1031
  }
923
1032
  if (result && typeof result === "object") {
924
- await checkout.applyInlineSessionPatch?.(result);
925
1033
  if (result.account) {
926
1034
  setAccountPatch((prev) => ({ ...prev ?? {}, ...result.account }));
927
1035
  }
1036
+ const patchResult = await applyInlineSessionPatch(result, method);
1037
+ if (patchResult.error) {
1038
+ return {
1039
+ proceed: false,
1040
+ accountPatch: result.account
1041
+ };
1042
+ }
1043
+ return {
1044
+ proceed: true,
1045
+ accountPatch: result.account,
1046
+ sessionId: patchResult.sessionId
1047
+ };
928
1048
  }
929
- return true;
1049
+ return { proceed: true };
930
1050
  } catch (err) {
931
- const floPayErr = err instanceof FloPayError2 ? err : new FloPayError2(
932
- err instanceof Error ? err.message : "Card before-click hook failed.",
933
- "validation_error"
934
- );
1051
+ const floPayErr = normalizeBeforeButtonClickError(method, err);
935
1052
  updateError(floPayErr.message);
936
1053
  onError?.(floPayErr);
937
- return false;
1054
+ return { proceed: false };
938
1055
  }
939
- }, [checkout.applyInlineSessionPatch, onBeforeButtonClick, sessionId, updateError, onError]);
1056
+ }, [applyInlineSessionPatch, checkout.inlineSessionDraft, onBeforeButtonClick, onError, sessionId, updateError]);
940
1057
  const processPaymentInternal = useCallback(
941
- async (tokenizedBody) => {
1058
+ async (tokenizedBody, overrides) => {
942
1059
  if (processingRef.current) return;
943
1060
  processingRef.current = true;
944
1061
  setProcessing(true);
945
1062
  setOverlayStatus("processing");
946
1063
  updateError(null);
1064
+ const effectiveSessionId = overrides?.sessionId ?? sessionId;
1065
+ const effectiveAccount = mergeAccountPatch(resolvedAccount, overrides?.accountPatch);
947
1066
  try {
948
1067
  const response = await fetch(`${baseUrl}/v1/checkouts/sessions/process`, {
949
1068
  method: "POST",
950
1069
  headers: {
951
1070
  "Content-Type": "application/json",
952
- "x-user-id": resolvedAccount.userId ?? ""
1071
+ "x-user-id": effectiveAccount.userId ?? ""
953
1072
  },
954
1073
  body: JSON.stringify({
955
- sessionId,
1074
+ sessionId: effectiveSessionId,
956
1075
  tokenizedData: tokenizedBody,
957
1076
  accountData: {
958
- userId: resolvedAccount.userId ?? "",
959
- email: resolvedAccount.email ?? "",
960
- firstName: resolvedAccount.firstName ?? fullName.trim().split(/\s+/)[0] ?? "",
961
- lastName: resolvedAccount.lastName ?? fullName.trim().split(/\s+/).slice(1).join(" ") ?? "",
1077
+ userId: effectiveAccount.userId ?? "",
1078
+ email: effectiveAccount.email ?? "",
1079
+ firstName: effectiveAccount.firstName ?? fullName.trim().split(/\s+/)[0] ?? "",
1080
+ lastName: effectiveAccount.lastName ?? fullName.trim().split(/\s+/).slice(1).join(" ") ?? "",
962
1081
  ...enableAVS ? { zip: zipCodeRef.current, country: selectedCountryRef.current } : {}
963
1082
  },
964
1083
  chv
@@ -1067,11 +1186,11 @@ function SplitCardFormInner({
1067
1186
  [baseUrl, sessionId, resolvedAccount, fullName, chv, flopay, onComplete, onError, updateError, emitDecline]
1068
1187
  );
1069
1188
  const dispatchTokenizedBody = useCallback(
1070
- (tokenizedBody) => {
1189
+ (tokenizedBody, overrides) => {
1071
1190
  if (onTokenizedBody) {
1072
1191
  onTokenizedBody(tokenizedBody);
1073
1192
  } else {
1074
- processPaymentInternal(tokenizedBody);
1193
+ processPaymentInternal(tokenizedBody, overrides);
1075
1194
  }
1076
1195
  },
1077
1196
  [onTokenizedBody, processPaymentInternal]
@@ -1498,6 +1617,7 @@ function SplitCardFormInner({
1498
1617
  if (layout === "buttons") {
1499
1618
  const isButtonsView = viewState === "buttons" || viewState === "expanding";
1500
1619
  const isCardView = viewState === "expanding" || viewState === "card" || viewState === "collapsing";
1620
+ const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
1501
1621
  const buttonsAnim = viewState === "expanding" ? `flopay-buttons-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both` : viewState === "collapsing" ? `flopay-buttons-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both` : void 0;
1502
1622
  const cardAnim = viewState === "expanding" ? `flopay-card-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both` : viewState === "collapsing" ? `flopay-card-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both` : void 0;
1503
1623
  return /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
@@ -1523,9 +1643,10 @@ function SplitCardFormInner({
1523
1643
  onErrorChange: updateError,
1524
1644
  isProcessing: isSubmitting,
1525
1645
  onButtonClick,
1526
- onDecline
1646
+ onDecline,
1647
+ runBeforeButtonClick
1527
1648
  }
1528
- ) }) : showPayPal ? /* @__PURE__ */ jsx4("div", { style: { height: 44, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
1649
+ ) }) : showPayPal ? /* @__PURE__ */ jsx4("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
1529
1650
  showWallets && stripeInstance ? /* @__PURE__ */ jsx4(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx4(
1530
1651
  WalletButtonInner,
1531
1652
  {
@@ -1537,24 +1658,25 @@ function SplitCardFormInner({
1537
1658
  onTokenizedBody: dispatchTokenizedBody,
1538
1659
  onErrorChange: updateError,
1539
1660
  onButtonClick,
1540
- onDecline
1661
+ onDecline,
1662
+ runBeforeButtonClick
1541
1663
  }
1542
- ) }) : showWallets ? /* @__PURE__ */ jsx4("div", { style: { height: 44, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
1664
+ ) }) : showWallets ? /* @__PURE__ */ jsx4("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
1543
1665
  /* @__PURE__ */ jsx4(
1544
1666
  "button",
1545
1667
  {
1546
1668
  type: "button",
1547
1669
  onClick: async () => {
1548
1670
  if (isSubmitting) return;
1549
- const shouldContinue = await runBeforeCardButtonClick();
1550
- if (!shouldContinue) return;
1671
+ const beforeClick = await runBeforeButtonClick("card");
1672
+ if (!beforeClick.proceed) return;
1551
1673
  onButtonClick?.("card");
1552
1674
  expandToCard();
1553
1675
  },
1554
1676
  disabled: isSubmitting,
1555
1677
  style: {
1556
1678
  width: "100%",
1557
- padding: "0.9rem 1rem",
1679
+ ...cardButtonSizing,
1558
1680
  backgroundColor: "white",
1559
1681
  color: "#262833",
1560
1682
  border: "1px solid #d1d5db",
@@ -1653,6 +1775,7 @@ function SplitCardFormInner({
1653
1775
 
1654
1776
  // src/flopay-checkout.tsx
1655
1777
  import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1778
+ var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
1656
1779
  function hasInlineSessionPatchData(patch) {
1657
1780
  if (!patch) return false;
1658
1781
  return Boolean(
@@ -1959,16 +2082,27 @@ function FloPayCheckout({
1959
2082
  [fallbackPublishableKey, locale, resolvedBillingUrl]
1960
2083
  );
1961
2084
  const handleInlineSessionPatch = useCallback2(async (patch) => {
1962
- if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) return;
2085
+ if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) {
2086
+ return {
2087
+ sessionId: resolvedSessionId,
2088
+ session
2089
+ };
2090
+ }
1963
2091
  setCardBootstrapPending(true);
1964
2092
  try {
1965
- await bootstrapInlineSession(patch);
2093
+ const resolved = await bootstrapInlineSession(patch);
2094
+ return {
2095
+ sessionId: resolved.sid,
2096
+ session: resolved.result.data.session ?? null
2097
+ };
1966
2098
  } finally {
1967
2099
  setCardBootstrapPending(false);
1968
2100
  }
1969
2101
  }, [
1970
2102
  bootstrapInlineSession,
1971
- cardBootstrapPending
2103
+ cardBootstrapPending,
2104
+ resolvedSessionId,
2105
+ session
1972
2106
  ]);
1973
2107
  useEffect4(() => {
1974
2108
  let cancelled = false;
@@ -2121,6 +2255,7 @@ function FloPayCheckout({
2121
2255
  loading: isLoading,
2122
2256
  error: loadError,
2123
2257
  checkoutMode: currentMode,
2258
+ inlineSessionDraft: effectiveCreateSession,
2124
2259
  applyInlineSessionPatch: shouldHandleInlineSessionPatch ? handleInlineSessionPatch : void 0,
2125
2260
  inlineSessionPatchProcessing: cardBootstrapPending
2126
2261
  }),
@@ -2129,6 +2264,7 @@ function FloPayCheckout({
2129
2264
  isLoading,
2130
2265
  loadError,
2131
2266
  currentMode,
2267
+ effectiveCreateSession,
2132
2268
  shouldHandleInlineSessionPatch,
2133
2269
  handleInlineSessionPatch,
2134
2270
  cardBootstrapPending
@@ -2145,9 +2281,9 @@ function FloPayCheckout({
2145
2281
  animation: "flopay-loading-pulse 1.5s ease-in-out infinite"
2146
2282
  } });
2147
2283
  return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
2148
- showPayPal && skeletonBar(44),
2149
- (showApplePay || showGooglePay) && skeletonBar(44),
2150
- skeletonBar(48),
2284
+ showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
2285
+ (showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
2286
+ skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
2151
2287
  /* @__PURE__ */ jsx5("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
2152
2288
  ] });
2153
2289
  }
@@ -2361,6 +2497,7 @@ function InterimButtonsView({
2361
2497
  background: "#e5e7eb",
2362
2498
  animation: "flopay-interim-pulse 1.5s ease-in-out infinite"
2363
2499
  } });
2500
+ const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
2364
2501
  if (showCardForm) {
2365
2502
  const inputBorder = bStyles.cardInputBorder ?? "#e5e7eb";
2366
2503
  const inputBg = bStyles.cardInputBackground ?? "white";
@@ -2451,8 +2588,8 @@ function InterimButtonsView({
2451
2588
  ] });
2452
2589
  }
2453
2590
  return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
2454
- showPayPal && skeleton(44),
2455
- (showApplePay || showGooglePay) && skeleton(44),
2591
+ showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
2592
+ (showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
2456
2593
  /* @__PURE__ */ jsx5(
2457
2594
  "button",
2458
2595
  {
@@ -2469,7 +2606,7 @@ function InterimButtonsView({
2469
2606
  disabled: cardLoading,
2470
2607
  style: {
2471
2608
  width: "100%",
2472
- padding: "0.9rem 1rem",
2609
+ ...cardButtonSizing,
2473
2610
  backgroundColor: "white",
2474
2611
  color: "#262833",
2475
2612
  border: "1px solid #d1d5db",