@flopay/react 1.0.3 → 1.1.0

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.cjs CHANGED
@@ -36,6 +36,7 @@ __export(index_exports, {
36
36
  CardExpiryElement: () => CardExpiryElement,
37
37
  CardNumberElement: () => CardNumberElement,
38
38
  CheckoutForm: () => CheckoutForm,
39
+ DirectPayPalButton: () => DirectPayPalButton,
39
40
  FloPayAutomaticPaymentButton: () => FloPayAutomaticPaymentButton,
40
41
  FloPayCheckout: () => FloPayCheckout,
41
42
  FloPayProvider: () => FloPayProvider,
@@ -151,9 +152,9 @@ function FloPayProvider({
151
152
  }
152
153
 
153
154
  // src/flopay-checkout.tsx
154
- var import_react8 = __toESM(require("react"), 1);
155
- var import_js3 = require("@flopay/js");
156
- var import_shared7 = require("@flopay/shared");
155
+ var import_react9 = __toESM(require("react"), 1);
156
+ var import_js4 = require("@flopay/js");
157
+ var import_shared8 = require("@flopay/shared");
157
158
 
158
159
  // src/card-button-content.tsx
159
160
  var import_react3 = require("react");
@@ -284,9 +285,9 @@ var AddressElement = createElementComponent("address", "AddressElement");
284
285
 
285
286
  // src/split-card-form.tsx
286
287
  var import_react_stripe_js = require("@stripe/react-stripe-js");
287
- var import_shared4 = require("@flopay/shared");
288
- var import_js = require("@flopay/js");
289
- var import_react7 = require("react");
288
+ var import_shared5 = require("@flopay/shared");
289
+ var import_js2 = require("@flopay/js");
290
+ var import_react8 = require("react");
290
291
 
291
292
  // src/hooks.ts
292
293
  var import_react5 = require("react");
@@ -688,11 +689,562 @@ function isInAppBrowser(userAgent) {
688
689
  return false;
689
690
  }
690
691
 
691
- // src/split-card-form.tsx
692
- var import_shared5 = require("@flopay/shared");
692
+ // src/direct-paypal-button.tsx
693
+ var import_react7 = require("react");
694
+ var import_paypal_js = require("@paypal/paypal-js");
695
+ var import_js = require("@flopay/js");
696
+ var import_shared4 = require("@flopay/shared");
693
697
  var import_jsx_runtime5 = require("react/jsx-runtime");
698
+ var DEFAULT_BUTTON_HEIGHT = 45;
699
+ function DirectPayPalButton({
700
+ sessionId,
701
+ billingApiUrl,
702
+ email,
703
+ clientId,
704
+ environment,
705
+ currency,
706
+ isSubscription,
707
+ onTokenizedBody,
708
+ onComplete,
709
+ onErrorChange,
710
+ onDecline,
711
+ isProcessing = false,
712
+ onLoadStateChange,
713
+ onButtonClick,
714
+ runBeforeButtonClick,
715
+ session,
716
+ existingOrderId,
717
+ debug = false
718
+ }) {
719
+ const containerRef = (0, import_react7.useRef)(null);
720
+ const [ready, setReady] = (0, import_react7.useState)(false);
721
+ const [failed, setFailed] = (0, import_react7.useState)(false);
722
+ const [submitting, setSubmitting] = (0, import_react7.useState)(false);
723
+ const baseUrl = (0, import_react7.useMemo)(() => billingApiUrl.replace(/\/+$/, ""), [billingApiUrl]);
724
+ const [debugLines, setDebugLines] = (0, import_react7.useState)([]);
725
+ const appendDebug = (line) => {
726
+ if (!debug) return;
727
+ setDebugLines((prev) => [...prev, `${(/* @__PURE__ */ new Date()).toISOString().slice(11, 23)} ${line}`]);
728
+ };
729
+ const onTokenizedBodyRef = (0, import_react7.useRef)(onTokenizedBody);
730
+ const onCompleteRef = (0, import_react7.useRef)(onComplete);
731
+ const onErrorChangeRef = (0, import_react7.useRef)(onErrorChange);
732
+ const onDeclineRef = (0, import_react7.useRef)(onDecline);
733
+ const onButtonClickRef = (0, import_react7.useRef)(onButtonClick);
734
+ const onLoadStateChangeRef = (0, import_react7.useRef)(onLoadStateChange);
735
+ const runBeforeButtonClickRef = (0, import_react7.useRef)(runBeforeButtonClick);
736
+ const sessionRef = (0, import_react7.useRef)(session);
737
+ const emailRef = (0, import_react7.useRef)(email);
738
+ const beforeClickRef = (0, import_react7.useRef)(null);
739
+ (0, import_react7.useEffect)(() => {
740
+ onTokenizedBodyRef.current = onTokenizedBody;
741
+ }, [onTokenizedBody]);
742
+ (0, import_react7.useEffect)(() => {
743
+ onCompleteRef.current = onComplete;
744
+ }, [onComplete]);
745
+ (0, import_react7.useEffect)(() => {
746
+ onErrorChangeRef.current = onErrorChange;
747
+ }, [onErrorChange]);
748
+ (0, import_react7.useEffect)(() => {
749
+ onDeclineRef.current = onDecline;
750
+ }, [onDecline]);
751
+ (0, import_react7.useEffect)(() => {
752
+ onButtonClickRef.current = onButtonClick;
753
+ }, [onButtonClick]);
754
+ (0, import_react7.useEffect)(() => {
755
+ onLoadStateChangeRef.current = onLoadStateChange;
756
+ }, [onLoadStateChange]);
757
+ (0, import_react7.useEffect)(() => {
758
+ runBeforeButtonClickRef.current = runBeforeButtonClick;
759
+ }, [runBeforeButtonClick]);
760
+ (0, import_react7.useEffect)(() => {
761
+ sessionRef.current = session;
762
+ }, [session]);
763
+ (0, import_react7.useEffect)(() => {
764
+ emailRef.current = email;
765
+ }, [email]);
766
+ (0, import_react7.useEffect)(() => {
767
+ onLoadStateChangeRef.current?.(ready && !failed);
768
+ }, [ready, failed]);
769
+ const normalizedEnv = (0, import_shared4.normalizeGatewayEnvironment)(environment);
770
+ (0, import_react7.useEffect)(() => {
771
+ const maskedClient = clientId ? `${clientId.slice(0, 6)}\u2026(len ${clientId.length})` : "(empty)";
772
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "(no navigator)";
773
+ appendDebug(`mount clientId=${maskedClient} env=${environment ?? "(unset)"}\u2192${normalizedEnv ?? "live"} ccy=${currency} sub=${isSubscription}`);
774
+ appendDebug(`ua=${ua.slice(0, 80)}${ua.length > 80 ? "\u2026" : ""}`);
775
+ if (!clientId) {
776
+ appendDebug("FAIL: clientId empty \u2014 gateway misconfigured");
777
+ setFailed(true);
778
+ onErrorChangeRef.current?.("Direct PayPal gateway is misconfigured.");
779
+ return;
780
+ }
781
+ if (!containerRef.current) {
782
+ appendDebug("FAIL: containerRef not attached");
783
+ return;
784
+ }
785
+ let cancelled = false;
786
+ let activeButtons = null;
787
+ let rendered = false;
788
+ const container = containerRef.current;
789
+ let containerObserver = null;
790
+ let perfObserver = null;
791
+ const watchdogTimers = [];
792
+ const formatDims = (el) => {
793
+ if (!el || typeof el.getBoundingClientRect !== "function") return "(no rect)";
794
+ const rect = el.getBoundingClientRect();
795
+ return `${Math.round(rect.width)}\xD7${Math.round(rect.height)}`;
796
+ };
797
+ const classifyIframeSrc = (raw) => {
798
+ if (!raw) return "(empty)";
799
+ try {
800
+ const url = new URL(raw, typeof window !== "undefined" ? window.location.href : "https://localhost");
801
+ const path = url.pathname.toLowerCase();
802
+ if (path.includes("checkcaptcha") || path.includes("captcha")) return `CAPTCHA(${url.host}${path})`;
803
+ if (path.includes("risk") || path.includes("challenge")) return `RISK(${url.host}${path})`;
804
+ if (path.includes("smart/buttons")) return `smart-buttons(${url.host})`;
805
+ return `${url.host}${path}`.slice(0, 100);
806
+ } catch {
807
+ return raw.slice(0, 80);
808
+ }
809
+ };
810
+ const describeIframe = (frame) => {
811
+ const src = frame.getAttribute("src");
812
+ const srcdoc = frame.getAttribute("srcdoc");
813
+ const name = frame.getAttribute("name");
814
+ const sandbox = frame.getAttribute("sandbox");
815
+ const parts = [];
816
+ if (src) parts.push(`src=${classifyIframeSrc(src)}`);
817
+ if (srcdoc) parts.push(`srcdoc[${srcdoc.length}ch]`);
818
+ if (!src && !srcdoc) parts.push("src=(empty) srcdoc=(empty)");
819
+ if (name) parts.push(`name=${name.slice(0, 40)}`);
820
+ if (sandbox !== null) parts.push(`sandbox="${sandbox.slice(0, 40)}"`);
821
+ return parts.join(" ");
822
+ };
823
+ const inspectFrameContent = (frame) => {
824
+ if (!(frame instanceof HTMLIFrameElement)) return "";
825
+ try {
826
+ const cd = frame.contentDocument;
827
+ if (!cd) return "cd=null";
828
+ const bodyChildren = cd.body?.children.length ?? 0;
829
+ const bodyLen = cd.body?.innerHTML.length ?? 0;
830
+ const headLen = cd.head?.innerHTML.length ?? 0;
831
+ return `cd=same-origin readyState=${cd.readyState} body[${bodyChildren}children,${bodyLen}ch] head[${headLen}ch]`;
832
+ } catch (err) {
833
+ return `cd=cross-origin(${err.message.slice(0, 30)})`;
834
+ }
835
+ };
836
+ const errorMessages = [];
837
+ const onWindowError = (ev) => {
838
+ const msg = ev.message ?? String(ev.error ?? "(no message)");
839
+ if (msg && (msg.toLowerCase().includes("paypal") || msg.toLowerCase().includes("zoid") || msg.toLowerCase().includes("postrobot") || msg.toLowerCase().includes("storage"))) {
840
+ appendDebug(`window:error ${msg.slice(0, 140)}`);
841
+ errorMessages.push(msg);
842
+ }
843
+ };
844
+ const onUnhandledRejection = (ev) => {
845
+ const reason = ev.reason instanceof Error ? ev.reason.message : String(ev.reason ?? "(no reason)");
846
+ if (reason && (reason.toLowerCase().includes("paypal") || reason.toLowerCase().includes("zoid") || reason.toLowerCase().includes("postrobot") || reason.toLowerCase().includes("storage"))) {
847
+ appendDebug(`window:rejection ${reason.slice(0, 140)}`);
848
+ errorMessages.push(reason);
849
+ }
850
+ };
851
+ if (debug && typeof window !== "undefined") {
852
+ window.addEventListener("error", onWindowError);
853
+ window.addEventListener("unhandledrejection", onUnhandledRejection);
854
+ }
855
+ const paypalRequestCount = { value: 0 };
856
+ if (debug && typeof PerformanceObserver !== "undefined") {
857
+ try {
858
+ perfObserver = new PerformanceObserver((list) => {
859
+ for (const entry of list.getEntries()) {
860
+ if (!entry.name.toLowerCase().includes("paypal")) continue;
861
+ paypalRequestCount.value += 1;
862
+ const dur = Math.round(entry.duration);
863
+ appendDebug(`net ${dur}ms ${entry.name.slice(0, 90)}`);
864
+ }
865
+ });
866
+ perfObserver.observe({ type: "resource", buffered: true });
867
+ } catch {
868
+ }
869
+ }
870
+ const stopDiagnostics = () => {
871
+ containerObserver?.disconnect();
872
+ containerObserver = null;
873
+ perfObserver?.disconnect();
874
+ perfObserver = null;
875
+ while (watchdogTimers.length) clearTimeout(watchdogTimers.pop());
876
+ if (debug && typeof window !== "undefined") {
877
+ window.removeEventListener("error", onWindowError);
878
+ window.removeEventListener("unhandledrejection", onUnhandledRejection);
879
+ }
880
+ };
881
+ const isZoidLifecycleMessage = (message) => {
882
+ if (!message) return false;
883
+ const lower = message.toLowerCase();
884
+ return lower.includes("zoid destroyed") || lower.includes("destroyed all components") || lower.includes("window closed") || lower.includes("detected container element removed");
885
+ };
886
+ const forwardError = (message) => {
887
+ if (cancelled) return;
888
+ if (isZoidLifecycleMessage(message)) return;
889
+ onErrorChangeRef.current?.(message);
890
+ };
891
+ const markRenderFailed = (message) => {
892
+ if (cancelled) return;
893
+ if (isZoidLifecycleMessage(message)) {
894
+ appendDebug(`markRenderFailed:skip-zoid msg=${message.slice(0, 80)}`);
895
+ return;
896
+ }
897
+ setFailed(true);
898
+ forwardError(message);
899
+ };
900
+ setFailed(false);
901
+ const dispatchTokenizedBody = async (body) => {
902
+ const prepared = beforeClickRef.current;
903
+ const effectiveSessionId = prepared?.sessionId ?? sessionId;
904
+ if (onTokenizedBodyRef.current) {
905
+ onTokenizedBodyRef.current(body, {
906
+ sessionId: effectiveSessionId,
907
+ accountPatch: prepared?.accountPatch
908
+ });
909
+ return;
910
+ }
911
+ try {
912
+ const currentSession = sessionRef.current;
913
+ const currentEmail = prepared?.accountPatch?.email ?? emailRef.current;
914
+ const effectiveUserId = prepared?.accountPatch?.userId ?? currentSession?.customer?.id ?? currentSession?.accountData?.userId ?? "";
915
+ const api = new import_js.PaymentAPI(baseUrl);
916
+ const response = await api.processPayment(
917
+ effectiveUserId,
918
+ {
919
+ sessionId: effectiveSessionId,
920
+ tokenizedData: body,
921
+ accountData: {
922
+ userId: effectiveUserId,
923
+ email: currentEmail ?? currentSession?.customer?.email ?? "",
924
+ firstName: prepared?.accountPatch?.firstName ?? currentSession?.customer?.firstName ?? currentSession?.accountData?.firstName ?? "",
925
+ lastName: prepared?.accountPatch?.lastName ?? currentSession?.customer?.lastName ?? currentSession?.accountData?.lastName ?? "",
926
+ country: prepared?.accountPatch?.country ?? currentSession?.customer?.country ?? currentSession?.accountData?.country ?? void 0,
927
+ zip: prepared?.accountPatch?.zip ?? currentSession?.customer?.zip ?? currentSession?.accountData?.zip ?? void 0
928
+ }
929
+ }
930
+ );
931
+ if (response.ok) {
932
+ onCompleteRef.current?.({ status: "succeeded", checkoutMethod: "paypal" });
933
+ return;
934
+ }
935
+ const json = await response.json().catch(() => null);
936
+ const message = json?.["message"] ?? "PayPal payment failed.";
937
+ forwardError(message);
938
+ onDeclineRef.current?.(buildDeclineEvent("paypal", message, {
939
+ code: json?.["code"],
940
+ declineCode: json?.["declineCode"]
941
+ }));
942
+ } catch (err) {
943
+ const message = err instanceof Error ? err.message : "PayPal payment failed.";
944
+ forwardError(message);
945
+ onDeclineRef.current?.(buildDeclineEvent("paypal", message));
946
+ }
947
+ };
948
+ const createPaypalIntent = async (fallbackMessage) => {
949
+ const prepared = beforeClickRef.current;
950
+ const effectiveSessionId = prepared?.sessionId ?? sessionId;
951
+ const effectiveEmail = prepared?.accountPatch?.email ?? emailRef.current;
952
+ const response = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
953
+ method: "POST",
954
+ headers: { "Content-Type": "application/json" },
955
+ body: JSON.stringify({
956
+ sessionId: effectiveSessionId,
957
+ email: effectiveEmail,
958
+ paymentMethodType: "paypal",
959
+ isPaypal: "true"
960
+ })
961
+ });
962
+ const json = await response.json().catch(() => null);
963
+ if (!response.ok) {
964
+ throw new Error(json?.message ?? fallbackMessage);
965
+ }
966
+ const id = json?.data?.id;
967
+ if (!id) {
968
+ throw new Error(fallbackMessage);
969
+ }
970
+ return id;
971
+ };
972
+ appendDebug("loadScript:scheduled (deferred 1 tick)");
973
+ let loadPromise = null;
974
+ const startTimer = setTimeout(() => {
975
+ if (cancelled) {
976
+ appendDebug("loadScript:skipped (cancelled before defer ran)");
977
+ return;
978
+ }
979
+ appendDebug("loadScript:start");
980
+ const paypalSdkEnv = normalizedEnv === "live" ? "production" : normalizedEnv;
981
+ loadPromise = (0, import_paypal_js.loadScript)({
982
+ clientId,
983
+ currency,
984
+ // Subscriptions need the `subscription` vault intent; one-time payments
985
+ // use a standard order capture.
986
+ intent: isSubscription ? "subscription" : "capture",
987
+ vault: isSubscription ? true : void 0,
988
+ // Tell PayPal which environment the clientId belongs to. Without
989
+ // this, PayPal defaults to live endpoints — and a sandbox clientId
990
+ // sent to live silently stalls in zoid's prerender forever (no
991
+ // error, no rejection).
992
+ ...paypalSdkEnv ? { environment: paypalSdkEnv } : {},
993
+ // Namespace the sandbox SDK so it can coexist with a production SDK on
994
+ // the same page without clobbering `window.paypal`.
995
+ ...paypalSdkEnv === "sandbox" ? { dataNamespace: "paypal_sandbox" } : {}
996
+ });
997
+ loadPromise.then((paypal) => {
998
+ appendDebug(`loadScript:resolved cancelled=${cancelled} ns=${!!paypal} buttons=${!!paypal?.Buttons}`);
999
+ if (cancelled || !paypal?.Buttons) {
1000
+ if (!cancelled && !paypal?.Buttons) appendDebug("FAIL: namespace missing Buttons factory");
1001
+ return;
1002
+ }
1003
+ const handleApprove = async (data) => {
1004
+ try {
1005
+ setSubmitting(true);
1006
+ onErrorChangeRef.current?.(null);
1007
+ const token = data.subscriptionID ?? data.orderID ?? "";
1008
+ if (!token) {
1009
+ throw new import_shared4.FloPayError(
1010
+ "PayPal did not return an approval token.",
1011
+ "api_error",
1012
+ { code: "paypal_missing_token" }
1013
+ );
1014
+ }
1015
+ await dispatchTokenizedBody({
1016
+ id: token,
1017
+ isPaypal: true
1018
+ });
1019
+ } catch (err) {
1020
+ forwardError(err instanceof Error ? err.message : "PayPal capture failed.");
1021
+ } finally {
1022
+ setSubmitting(false);
1023
+ }
1024
+ };
1025
+ const buttons = paypal.Buttons({
1026
+ style: { layout: "horizontal", height: DEFAULT_BUTTON_HEIGHT, tagline: false },
1027
+ // PayPal's SDK awaits a Promise returned from `onClick` and aborts
1028
+ // the create-order/create-subscription step when `actions.reject()`
1029
+ // is invoked. Run the consumer's `runBeforeButtonClick` here so
1030
+ // inline-session/account patches land before the order is created,
1031
+ // matching the Stripe-rendered PayPal flow.
1032
+ onClick: async (_data, actions) => {
1033
+ const runner = runBeforeButtonClickRef.current;
1034
+ if (runner) {
1035
+ try {
1036
+ const beforeClick = await runner("paypal");
1037
+ if (!beforeClick.proceed) {
1038
+ beforeClickRef.current = null;
1039
+ await actions.reject();
1040
+ return;
1041
+ }
1042
+ beforeClickRef.current = {
1043
+ sessionId: beforeClick.sessionId,
1044
+ accountPatch: beforeClick.accountPatch
1045
+ };
1046
+ } catch (err) {
1047
+ appendDebug(`onClick:runBeforeButtonClick rejected msg=${(err instanceof Error ? err.message : String(err)).slice(0, 120)}`);
1048
+ beforeClickRef.current = null;
1049
+ await actions.reject();
1050
+ return;
1051
+ }
1052
+ } else {
1053
+ beforeClickRef.current = null;
1054
+ }
1055
+ onButtonClickRef.current?.("paypal");
1056
+ await actions.resolve();
1057
+ },
1058
+ // When the SDK is already holding an order/subscription id from a
1059
+ // prior backend round-trip (the `paypal_direct_required` retry
1060
+ // path), feed it straight to PayPal instead of creating a new one.
1061
+ // Otherwise fall back to the normal create-intent call.
1062
+ createOrder: isSubscription ? void 0 : existingOrderId ? () => Promise.resolve(existingOrderId) : () => createPaypalIntent("Failed to create PayPal order."),
1063
+ createSubscription: isSubscription ? existingOrderId ? () => Promise.resolve(existingOrderId) : () => createPaypalIntent("Failed to create PayPal subscription.") : void 0,
1064
+ onApprove: handleApprove,
1065
+ onCancel: () => {
1066
+ beforeClickRef.current = null;
1067
+ onDeclineRef.current?.(buildDeclineEvent("paypal", "PayPal checkout was cancelled."));
1068
+ },
1069
+ onError: (err) => {
1070
+ const message = err instanceof Error ? err.message : "PayPal failed to render.";
1071
+ appendDebug(`onError rendered=${rendered} msg=${message.slice(0, 120)}`);
1072
+ if (rendered) {
1073
+ forwardError(message);
1074
+ onDeclineRef.current?.(buildDeclineEvent("paypal", message));
1075
+ return;
1076
+ }
1077
+ markRenderFailed(message);
1078
+ }
1079
+ });
1080
+ const eligible = buttons.isEligible();
1081
+ appendDebug(`isEligible=${eligible}`);
1082
+ if (!eligible) {
1083
+ setReady(false);
1084
+ markRenderFailed(
1085
+ "PayPal buttons are not eligible to render in this context (paypal_ineligible)."
1086
+ );
1087
+ return;
1088
+ }
1089
+ const typedButtons = buttons;
1090
+ if (debug) {
1091
+ appendDebug(`container:dims ${formatDims(container)} visibility=${typeof document !== "undefined" ? document.visibilityState : "(no document)"}`);
1092
+ }
1093
+ if (debug && typeof MutationObserver !== "undefined") {
1094
+ containerObserver = new MutationObserver((mutations) => {
1095
+ for (const mutation of mutations) {
1096
+ if (mutation.type === "childList") {
1097
+ mutation.addedNodes.forEach((node) => {
1098
+ if (!(node instanceof Element)) return;
1099
+ const tag = node.tagName.toLowerCase();
1100
+ const title = (node.getAttribute("title") ?? "").slice(0, 40);
1101
+ const detail = tag === "iframe" ? ` ${describeIframe(node)}` : "";
1102
+ appendDebug(`child+ ${tag}${title ? ` title="${title}"` : ""}${detail} dims=${formatDims(node)}`);
1103
+ });
1104
+ } else if (mutation.type === "attributes" && mutation.target instanceof Element) {
1105
+ const target = mutation.target;
1106
+ if (target.tagName.toLowerCase() !== "iframe") continue;
1107
+ const attr = mutation.attributeName;
1108
+ if (attr === "src" || attr === "srcdoc") {
1109
+ appendDebug(`attr~ iframe ${attr}=${attr === "srcdoc" ? `[${(target.getAttribute("srcdoc") ?? "").length}ch]` : classifyIframeSrc(target.getAttribute("src"))} dims=${formatDims(target)}`);
1110
+ }
1111
+ }
1112
+ }
1113
+ });
1114
+ containerObserver.observe(container, {
1115
+ childList: true,
1116
+ subtree: true,
1117
+ attributes: true,
1118
+ attributeFilter: ["src", "srcdoc"]
1119
+ });
1120
+ }
1121
+ const snapshotContainer = (when) => {
1122
+ if (cancelled || rendered) return;
1123
+ const iframes = container.querySelectorAll("iframe");
1124
+ const hasStorageAccess = typeof document !== "undefined" && "hasStorageAccess" in document;
1125
+ appendDebug(`watchdog:${when} container=${formatDims(container)} children=${container.childElementCount} iframes=${iframes.length} visibility=${typeof document !== "undefined" ? document.visibilityState : "(no document)"} cookies=${typeof navigator !== "undefined" ? navigator.cookieEnabled : "?"} hasStorageAccessApi=${hasStorageAccess} paypalNetRequests=${paypalRequestCount.value}`);
1126
+ iframes.forEach((frame, i) => {
1127
+ const title = (frame.getAttribute("title") ?? "").slice(0, 40);
1128
+ appendDebug(` iframe[${i}] ${formatDims(frame)}${title ? ` title="${title}"` : ""} ${describeIframe(frame)}`);
1129
+ const content = inspectFrameContent(frame);
1130
+ if (content) appendDebug(` ${content}`);
1131
+ });
1132
+ if (errorMessages.length === 0) {
1133
+ appendDebug(` (no PayPal/zoid window errors captured)`);
1134
+ }
1135
+ };
1136
+ if (debug) {
1137
+ watchdogTimers.push(setTimeout(() => snapshotContainer("3s"), 3e3));
1138
+ watchdogTimers.push(setTimeout(() => snapshotContainer("8s"), 8e3));
1139
+ watchdogTimers.push(setTimeout(() => snapshotContainer("15s"), 15e3));
1140
+ }
1141
+ appendDebug("render:start");
1142
+ buttons.render(container).then(() => {
1143
+ appendDebug(`render:resolved cancelled=${cancelled}`);
1144
+ stopDiagnostics();
1145
+ if (cancelled) {
1146
+ typedButtons.close().catch(() => {
1147
+ });
1148
+ return;
1149
+ }
1150
+ activeButtons = typedButtons;
1151
+ rendered = true;
1152
+ setReady(true);
1153
+ }).catch((err) => {
1154
+ const message = err instanceof Error ? err.message : "PayPal failed to render.";
1155
+ appendDebug(`render:rejected msg=${message.slice(0, 120)}`);
1156
+ stopDiagnostics();
1157
+ markRenderFailed(message);
1158
+ });
1159
+ }).catch((err) => {
1160
+ const message = err instanceof Error ? err.message : "PayPal SDK failed to load.";
1161
+ appendDebug(`loadScript:rejected msg=${message.slice(0, 120)}`);
1162
+ markRenderFailed(message);
1163
+ });
1164
+ }, 0);
1165
+ return () => {
1166
+ cancelled = true;
1167
+ clearTimeout(startTimer);
1168
+ stopDiagnostics();
1169
+ if (activeButtons) {
1170
+ activeButtons.close().catch(() => {
1171
+ });
1172
+ }
1173
+ };
1174
+ }, [baseUrl, clientId, currency, environment, isSubscription, sessionId, existingOrderId]);
1175
+ const debugPanel = debug ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1176
+ "pre",
1177
+ {
1178
+ "data-testid": "flopay-direct-paypal-debug",
1179
+ style: {
1180
+ margin: "0 0 8px 0",
1181
+ padding: "6px 8px",
1182
+ background: failed ? "#fef2f2" : "#f3f4f6",
1183
+ border: `1px solid ${failed ? "#fca5a5" : "#d1d5db"}`,
1184
+ borderRadius: 6,
1185
+ color: "#111827",
1186
+ font: "11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace",
1187
+ whiteSpace: "pre-wrap",
1188
+ wordBreak: "break-word",
1189
+ maxHeight: 220,
1190
+ overflowY: "auto"
1191
+ },
1192
+ children: [
1193
+ `FloPay/DirectPayPal-debug (ready=${ready} failed=${failed})`,
1194
+ debugLines.length === 0 ? "\n(waiting for first lifecycle event\u2026)" : `
1195
+ ${debugLines.join("\n")}`
1196
+ ]
1197
+ }
1198
+ ) : null;
1199
+ if (failed) {
1200
+ return debug ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: debugPanel }) : null;
1201
+ }
1202
+ return (
1203
+ // Single wrapper so the parent flex container sees exactly one flex item
1204
+ // (otherwise the fragment's placeholder + container become two siblings
1205
+ // and any spacing-sensitive layout has to reason about both). The wrapper
1206
+ // intentionally has no margin/padding so the parent owns all spacing.
1207
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1208
+ debugPanel,
1209
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { position: "relative", minHeight: DEFAULT_BUTTON_HEIGHT }, children: [
1210
+ !ready && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1211
+ "div",
1212
+ {
1213
+ "data-testid": "flopay-direct-paypal-placeholder",
1214
+ style: {
1215
+ position: "absolute",
1216
+ inset: 0,
1217
+ borderRadius: 8,
1218
+ background: "#e5e7eb",
1219
+ animation: "flopay-pulse 1.5s ease-in-out infinite",
1220
+ pointerEvents: "none"
1221
+ }
1222
+ }
1223
+ ),
1224
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1225
+ "div",
1226
+ {
1227
+ ref: containerRef,
1228
+ "data-testid": "flopay-direct-paypal-container",
1229
+ style: {
1230
+ minHeight: DEFAULT_BUTTON_HEIGHT,
1231
+ display: "flex",
1232
+ opacity: ready ? 1 : 0
1233
+ },
1234
+ "aria-busy": submitting || isProcessing
1235
+ }
1236
+ )
1237
+ ] })
1238
+ ] })
1239
+ );
1240
+ }
1241
+
1242
+ // src/split-card-form.tsx
1243
+ var import_shared6 = require("@flopay/shared");
1244
+ var import_jsx_runtime6 = require("react/jsx-runtime");
694
1245
  var WALLET_RESUME_KEY = "flopay_wallet_resume";
695
1246
  var FLOPAY_KEYFRAMES = `
1247
+ .paypal-buttons { margin: 0 !important; vertical-align: top !important; }
696
1248
  @keyframes flopay-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
697
1249
  @keyframes flopay-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
698
1250
  @keyframes flopay-buttons-enter {
@@ -726,13 +1278,13 @@ function getButtonMethodLabel(method) {
726
1278
  }
727
1279
  }
728
1280
  function normalizeBeforeButtonClickError(method, err) {
729
- return err instanceof import_shared5.FloPayError ? err : new import_shared5.FloPayError(
1281
+ return err instanceof import_shared6.FloPayError ? err : new import_shared6.FloPayError(
730
1282
  err instanceof Error ? err.message : `${getButtonMethodLabel(method)} before-click hook failed.`,
731
1283
  "validation_error"
732
1284
  );
733
1285
  }
734
1286
  function FloPayKeyframes() {
735
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: FLOPAY_KEYFRAMES });
1287
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: FLOPAY_KEYFRAMES });
736
1288
  }
737
1289
  function toCssSize(value) {
738
1290
  if (typeof value === "number") return `${value}px`;
@@ -753,8 +1305,8 @@ function ExpressCheckoutReadySwap({
753
1305
  children
754
1306
  }) {
755
1307
  if (state === "unavailable" || state === "load_error") return null;
756
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { position: "relative", minHeight: 44 }, children: [
757
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1308
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { position: "relative", minHeight: 44 }, children: [
1309
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
758
1310
  "div",
759
1311
  {
760
1312
  "data-testid": placeholderTestId,
@@ -773,7 +1325,7 @@ function ExpressCheckoutReadySwap({
773
1325
  }
774
1326
  }
775
1327
  ),
776
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1328
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
777
1329
  "div",
778
1330
  {
779
1331
  style: {
@@ -791,9 +1343,9 @@ function ExpressCheckoutReadySwap({
791
1343
  function isExpressCheckoutRowVisible(state) {
792
1344
  return state !== "unavailable" && state !== "load_error";
793
1345
  }
794
- var SplitCardForm = (0, import_react7.forwardRef)(
1346
+ var SplitCardForm = (0, import_react8.forwardRef)(
795
1347
  function SplitCardForm2(props, ref) {
796
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SplitCardFormInner, { ...props, innerRef: ref });
1348
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SplitCardFormInner, { ...props, innerRef: ref });
797
1349
  }
798
1350
  );
799
1351
  function PayPalButtonInner({
@@ -810,15 +1362,15 @@ function PayPalButtonInner({
810
1362
  }) {
811
1363
  const stripe = (0, import_react_stripe_js.useStripe)();
812
1364
  const elements = (0, import_react_stripe_js.useElements)();
813
- const [loadState, setLoadState] = (0, import_react7.useState)("loading");
814
- (0, import_react7.useEffect)(() => {
1365
+ const [loadState, setLoadState] = (0, import_react8.useState)("loading");
1366
+ (0, import_react8.useEffect)(() => {
815
1367
  onLoadStateChange?.(loadState);
816
1368
  }, [loadState, onLoadStateChange]);
817
- const [submitting, setSubmitting] = (0, import_react7.useState)(false);
818
- const paypalResumeAttempted = (0, import_react7.useRef)(false);
819
- const beforeClickRef = (0, import_react7.useRef)(null);
1369
+ const [submitting, setSubmitting] = (0, import_react8.useState)(false);
1370
+ const paypalResumeAttempted = (0, import_react8.useRef)(false);
1371
+ const beforeClickRef = (0, import_react8.useRef)(null);
820
1372
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
821
- (0, import_react7.useEffect)(() => {
1373
+ (0, import_react8.useEffect)(() => {
822
1374
  if (!stripe || paypalResumeAttempted.current) return;
823
1375
  const params = new URLSearchParams(window.location.search);
824
1376
  const paymentIntentId = params.get("payment_intent");
@@ -865,7 +1417,7 @@ function PayPalButtonInner({
865
1417
  }
866
1418
  })();
867
1419
  }, [stripe, onTokenizedBody, onErrorChange, onDecline]);
868
- const handlePayPalClick = (0, import_react7.useCallback)(async (event) => {
1420
+ const handlePayPalClick = (0, import_react8.useCallback)(async (event) => {
869
1421
  if (isProcessing || submitting) {
870
1422
  event.reject();
871
1423
  return;
@@ -883,7 +1435,7 @@ function PayPalButtonInner({
883
1435
  onButtonClick?.("paypal");
884
1436
  event.resolve();
885
1437
  }, [isProcessing, onButtonClick, runBeforeButtonClick, submitting]);
886
- const handlePayPalConfirm = (0, import_react7.useCallback)(async (event) => {
1438
+ const handlePayPalConfirm = (0, import_react8.useCallback)(async (event) => {
887
1439
  if (!stripe || !elements) return;
888
1440
  let prepared = beforeClickRef.current;
889
1441
  beforeClickRef.current = null;
@@ -975,8 +1527,8 @@ function PayPalButtonInner({
975
1527
  setSubmitting(false);
976
1528
  }
977
1529
  }, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]);
978
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
979
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-paypal-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1530
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1531
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-paypal-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
980
1532
  import_react_stripe_js.ExpressCheckoutElement,
981
1533
  {
982
1534
  onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
@@ -1001,7 +1553,7 @@ function PayPalButtonInner({
1001
1553
  }
1002
1554
  }
1003
1555
  ) }),
1004
- submitting && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ProcessingOverlay, { status: "processing" })
1556
+ submitting && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingOverlay, { status: "processing" })
1005
1557
  ] });
1006
1558
  }
1007
1559
  function WalletButtonInner({
@@ -1019,15 +1571,15 @@ function WalletButtonInner({
1019
1571
  }) {
1020
1572
  const stripe = (0, import_react_stripe_js.useStripe)();
1021
1573
  const elements = (0, import_react_stripe_js.useElements)();
1022
- const [loadState, setLoadState] = (0, import_react7.useState)("loading");
1023
- (0, import_react7.useEffect)(() => {
1574
+ const [loadState, setLoadState] = (0, import_react8.useState)("loading");
1575
+ (0, import_react8.useEffect)(() => {
1024
1576
  onLoadStateChange?.(loadState);
1025
1577
  }, [loadState, onLoadStateChange]);
1026
- const [submitting, setSubmitting] = (0, import_react7.useState)(false);
1578
+ const [submitting, setSubmitting] = (0, import_react8.useState)(false);
1027
1579
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
1028
- const lastWalletMethodRef = (0, import_react7.useRef)("card");
1029
- const beforeClickRef = (0, import_react7.useRef)(null);
1030
- const handleWalletConfirm = (0, import_react7.useCallback)(
1580
+ const lastWalletMethodRef = (0, import_react8.useRef)("card");
1581
+ const beforeClickRef = (0, import_react8.useRef)(null);
1582
+ const handleWalletConfirm = (0, import_react8.useCallback)(
1031
1583
  async (event) => {
1032
1584
  if (!stripe || !elements) return;
1033
1585
  const walletType = event.expressPaymentType;
@@ -1116,12 +1668,16 @@ function WalletButtonInner({
1116
1668
  },
1117
1669
  [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]
1118
1670
  );
1119
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1120
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-wallet-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1671
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1672
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-wallet-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1121
1673
  import_react_stripe_js.ExpressCheckoutElement,
1122
1674
  {
1123
- onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["applePay", "googlePay"])),
1124
- onLoadError: () => setLoadState("load_error"),
1675
+ onReady: (event) => {
1676
+ setLoadState(resolveExpressCheckoutLoadState(event, ["applePay", "googlePay"]));
1677
+ },
1678
+ onLoadError: (e) => {
1679
+ setLoadState("load_error");
1680
+ },
1125
1681
  onClick: async (event) => {
1126
1682
  lastWalletMethodRef.current = event.expressPaymentType === "apple_pay" ? "apple_pay" : "google_pay";
1127
1683
  const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick(lastWalletMethodRef.current) : { proceed: true };
@@ -1156,7 +1712,7 @@ function WalletButtonInner({
1156
1712
  }
1157
1713
  }
1158
1714
  ) }),
1159
- submitting && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ProcessingOverlay, { status: "processing" })
1715
+ submitting && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingOverlay, { status: "processing" })
1160
1716
  ] });
1161
1717
  }
1162
1718
  function SplitCardFormInner({
@@ -1208,55 +1764,64 @@ function SplitCardFormInner({
1208
1764
  totalAmount = 0,
1209
1765
  currency = "usd",
1210
1766
  initialCardOpen = false,
1767
+ directPaypal,
1768
+ isSubscription = false,
1769
+ session,
1770
+ debug = false,
1211
1771
  innerRef
1212
1772
  }) {
1213
1773
  const flopay = useFloPay();
1214
1774
  const paypalFlopay = usePayPalFloPay();
1215
1775
  const elements = useElements();
1216
- const checkout = (0, import_react7.useContext)(CheckoutContext);
1776
+ const checkout = (0, import_react8.useContext)(CheckoutContext);
1217
1777
  const contextBillingUrl = useBillingApiUrl();
1218
- const [processing, setProcessing] = (0, import_react7.useState)(false);
1219
- const [error, setError] = (0, import_react7.useState)(null);
1220
- const [is3DSActive, setIs3DSActive] = (0, import_react7.useState)(false);
1221
- const [selectedCountry, setSelectedCountry] = (0, import_react7.useState)(countryProp ?? "US");
1222
- const [zipCode, setZipCode] = (0, import_react7.useState)(zipProp ?? "");
1223
- const [addressLine1, setAddressLine1] = (0, import_react7.useState)(addressLine1Prop ?? "");
1224
- const [addressLine2, setAddressLine2] = (0, import_react7.useState)(addressLine2Prop ?? "");
1225
- const [city, setCity] = (0, import_react7.useState)(cityProp ?? "");
1226
- const [stateValue, setStateValue] = (0, import_react7.useState)(stateProp ?? "");
1227
- const [accountPatch, setAccountPatch] = (0, import_react7.useState)({});
1228
- const zipCodeRef = (0, import_react7.useRef)(zipProp ?? "");
1229
- const selectedCountryRef = (0, import_react7.useRef)(countryProp ?? "US");
1230
- const addressLine1Ref = (0, import_react7.useRef)(addressLine1Prop ?? "");
1231
- const addressLine2Ref = (0, import_react7.useRef)(addressLine2Prop ?? "");
1232
- const cityRef = (0, import_react7.useRef)(cityProp ?? "");
1233
- const stateRef = (0, import_react7.useRef)(stateProp ?? "");
1234
- const avsConfig = (0, import_react7.useMemo)(() => (0, import_shared4.resolveAVSConfig)(enableAVSProp), [enableAVSProp]);
1778
+ const [processing, setProcessing] = (0, import_react8.useState)(false);
1779
+ const [error, setError] = (0, import_react8.useState)(null);
1780
+ const [is3DSActive, setIs3DSActive] = (0, import_react8.useState)(false);
1781
+ const [selectedCountry, setSelectedCountry] = (0, import_react8.useState)(countryProp ?? "US");
1782
+ const [zipCode, setZipCode] = (0, import_react8.useState)(zipProp ?? "");
1783
+ const [addressLine1, setAddressLine1] = (0, import_react8.useState)(addressLine1Prop ?? "");
1784
+ const [addressLine2, setAddressLine2] = (0, import_react8.useState)(addressLine2Prop ?? "");
1785
+ const [city, setCity] = (0, import_react8.useState)(cityProp ?? "");
1786
+ const [stateValue, setStateValue] = (0, import_react8.useState)(stateProp ?? "");
1787
+ const [accountPatch, setAccountPatch] = (0, import_react8.useState)({});
1788
+ const zipCodeRef = (0, import_react8.useRef)(zipProp ?? "");
1789
+ const selectedCountryRef = (0, import_react8.useRef)(countryProp ?? "US");
1790
+ const addressLine1Ref = (0, import_react8.useRef)(addressLine1Prop ?? "");
1791
+ const addressLine2Ref = (0, import_react8.useRef)(addressLine2Prop ?? "");
1792
+ const cityRef = (0, import_react8.useRef)(cityProp ?? "");
1793
+ const stateRef = (0, import_react8.useRef)(stateProp ?? "");
1794
+ const avsConfig = (0, import_react8.useMemo)(() => (0, import_shared5.resolveAVSConfig)(enableAVSProp), [enableAVSProp]);
1235
1795
  const enableAVS = avsConfig !== null;
1236
- const [viewState, setViewState] = (0, import_react7.useState)(initialCardOpen ? "card" : "buttons");
1796
+ const [viewState, setViewState] = (0, import_react8.useState)(initialCardOpen ? "card" : "buttons");
1237
1797
  const showCardForm = viewState === "expanding" || viewState === "card";
1238
1798
  const TRANSITION_MS = 280;
1239
- const expandToCard = (0, import_react7.useCallback)(() => {
1799
+ const expandToCard = (0, import_react8.useCallback)(() => {
1240
1800
  setViewState("expanding");
1241
1801
  setTimeout(() => setViewState("card"), TRANSITION_MS);
1242
1802
  }, []);
1243
- const collapseToButtons = (0, import_react7.useCallback)(() => {
1803
+ const collapseToButtons = (0, import_react8.useCallback)(() => {
1244
1804
  setViewState("collapsing");
1245
1805
  setTimeout(() => setViewState("buttons"), TRANSITION_MS);
1246
1806
  }, []);
1247
- (0, import_react7.useEffect)(() => {
1807
+ (0, import_react8.useEffect)(() => {
1248
1808
  if (layout === "buttons" && initialCardOpen) {
1249
1809
  setViewState("card");
1250
1810
  }
1251
1811
  }, [layout, initialCardOpen]);
1252
- const [fullName, setFullName] = (0, import_react7.useState)("");
1253
- const [formReady, setFormReady] = (0, import_react7.useState)(false);
1254
- const [overlayStatus, setOverlayStatus] = (0, import_react7.useState)(null);
1255
- const processingRef = (0, import_react7.useRef)(false);
1812
+ const [fullName, setFullName] = (0, import_react8.useState)("");
1813
+ const [formReady, setFormReady] = (0, import_react8.useState)(false);
1814
+ const [overlayStatus, setOverlayStatus] = (0, import_react8.useState)(null);
1815
+ const processingRef = (0, import_react8.useRef)(false);
1816
+ const [paypalDirectRetry, setPaypalDirectRetry] = (0, import_react8.useState)(null);
1817
+ const paypalDirectRetryRef = (0, import_react8.useRef)(paypalDirectRetry);
1818
+ (0, import_react8.useEffect)(() => {
1819
+ paypalDirectRetryRef.current = paypalDirectRetry;
1820
+ }, [paypalDirectRetry]);
1256
1821
  const resolvedBillingApiUrl = billingApiUrl || contextBillingUrl;
1257
1822
  const displayError = externalError ?? error;
1258
- const bStyles = (0, import_react7.useMemo)(() => {
1259
- const base = (0, import_shared4.resolveButtonsLayoutTheme)(buttonsTheme);
1823
+ const bStyles = (0, import_react8.useMemo)(() => {
1824
+ const base = (0, import_shared5.resolveButtonsLayoutTheme)(buttonsTheme);
1260
1825
  if (!buttonsStylesOverride) return base;
1261
1826
  return {
1262
1827
  ...base,
@@ -1273,7 +1838,7 @@ function SplitCardFormInner({
1273
1838
  const isSubmitting = (externalProcessing ?? processing) || isInlineSessionPatchProcessing;
1274
1839
  const isSelfContained = !onTokenizedBody;
1275
1840
  const baseUrl = resolvedBillingApiUrl.replace(/\/+$/, "");
1276
- const resolvedAccount = (0, import_react7.useMemo)(() => mergeAccountPatch({
1841
+ const resolvedAccount = (0, import_react8.useMemo)(() => mergeAccountPatch({
1277
1842
  userId,
1278
1843
  email,
1279
1844
  firstName,
@@ -1281,63 +1846,66 @@ function SplitCardFormInner({
1281
1846
  country: countryProp,
1282
1847
  zip: zipProp
1283
1848
  }, accountPatch), [userId, email, firstName, lastName, countryProp, zipProp, accountPatch]);
1284
- const stripeInstance = (0, import_react7.useMemo)(() => {
1849
+ const stripeInstance = (0, import_react8.useMemo)(() => {
1285
1850
  if (!flopay) return null;
1286
1851
  return flopay.getRawProvider();
1287
1852
  }, [flopay]);
1288
- const paypalStripeInstance = (0, import_react7.useMemo)(() => {
1853
+ const paypalStripeInstance = (0, import_react8.useMemo)(() => {
1289
1854
  if (!paypalFlopay) return null;
1290
1855
  return paypalFlopay.getRawProvider();
1291
1856
  }, [paypalFlopay]);
1292
1857
  const amountInCents = totalAmount || 100;
1293
- const walletOptions = (0, import_react7.useMemo)(() => ({
1858
+ const walletOptions = (0, import_react8.useMemo)(() => ({
1294
1859
  mode: "payment",
1295
1860
  amount: amountInCents,
1296
1861
  currency: currency.toLowerCase(),
1297
1862
  paymentMethodCreation: "manual",
1298
1863
  captureMethod: "manual"
1299
1864
  }), [amountInCents, currency]);
1300
- const paypalOptions = (0, import_react7.useMemo)(() => ({
1865
+ const paypalOptions = (0, import_react8.useMemo)(() => ({
1301
1866
  mode: "payment",
1302
1867
  amount: amountInCents,
1303
1868
  currency: currency.toLowerCase(),
1304
1869
  captureMethod: "manual",
1305
1870
  setupFutureUsage: "off_session"
1306
1871
  }), [amountInCents, currency]);
1307
- const updateError = (0, import_react7.useCallback)(
1872
+ const updateError = (0, import_react8.useCallback)(
1308
1873
  (err) => {
1309
1874
  setError(err);
1310
1875
  onErrorChange?.(err);
1311
1876
  },
1312
1877
  [onErrorChange]
1313
1878
  );
1314
- const emitDecline = (0, import_react7.useCallback)(
1879
+ const emitDecline = (0, import_react8.useCallback)(
1315
1880
  (method, input, overrides) => {
1316
1881
  onDecline?.(buildDeclineEvent(method, input, overrides));
1317
1882
  },
1318
1883
  [onDecline]
1319
1884
  );
1320
1885
  const showWallets = showApplePay || showGooglePay;
1321
- const [paypalLoadState, setPaypalLoadState] = (0, import_react7.useState)("loading");
1322
- const [walletLoadState, setWalletLoadState] = (0, import_react7.useState)("loading");
1323
- const [inAppBrowserDetected, setInAppBrowserDetected] = (0, import_react7.useState)();
1324
- (0, import_react7.useEffect)(() => {
1886
+ const [paypalLoadState, setPaypalLoadState] = (0, import_react8.useState)("loading");
1887
+ const [walletLoadState, setWalletLoadState] = (0, import_react8.useState)("loading");
1888
+ const [directPaypalReady, setDirectPaypalReady] = (0, import_react8.useState)(false);
1889
+ const [inAppBrowserDetected, setInAppBrowserDetected] = (0, import_react8.useState)();
1890
+ (0, import_react8.useEffect)(() => {
1325
1891
  setInAppBrowserDetected(isInAppBrowser());
1326
1892
  }, []);
1327
- const shouldShowPayPal = showPayPal && inAppBrowserDetected === false;
1328
- const shouldShowWallets = showWallets && inAppBrowserDetected === false;
1329
- const shouldRenderPayPal = shouldShowPayPal && !!paypalStripeInstance;
1893
+ const directPaypalConfigured = !!directPaypal?.clientId;
1894
+ const shouldShowPayPal = showPayPal && (directPaypalConfigured || inAppBrowserDetected === false);
1895
+ const shouldShowWallets = showWallets;
1896
+ const shouldRenderDirectPayPal = shouldShowPayPal && directPaypalConfigured;
1897
+ const shouldRenderStripePayPal = shouldShowPayPal && !directPaypalConfigured && !!paypalStripeInstance;
1330
1898
  const shouldRenderWallets = shouldShowWallets && !!stripeInstance;
1331
- const shouldDisplayPayPalRow = shouldRenderPayPal && isExpressCheckoutRowVisible(paypalLoadState);
1899
+ const shouldDisplayPayPalRow = shouldRenderDirectPayPal ? directPaypalReady : shouldRenderStripePayPal && isExpressCheckoutRowVisible(paypalLoadState);
1332
1900
  const shouldDisplayWalletRow = shouldRenderWallets && isExpressCheckoutRowVisible(walletLoadState);
1333
- const handleNameChange = (0, import_react7.useCallback)((value) => {
1901
+ const handleNameChange = (0, import_react8.useCallback)((value) => {
1334
1902
  setFullName(value);
1335
1903
  onFullNameChange?.(value);
1336
1904
  const parts = value.trim().split(/\s+/);
1337
1905
  onFirstNameChange?.(parts[0] ?? "");
1338
1906
  onLastNameChange?.(parts.length > 1 ? parts.slice(1).join(" ") : "");
1339
1907
  }, [onFullNameChange, onFirstNameChange, onLastNameChange]);
1340
- const applyInlineSessionPatch = (0, import_react7.useCallback)(
1908
+ const applyInlineSessionPatch = (0, import_react8.useCallback)(
1341
1909
  (patch, method) => {
1342
1910
  if (!checkout.applyInlineSessionPatch) {
1343
1911
  return Promise.resolve({ error: null, sessionId });
@@ -1354,7 +1922,7 @@ function SplitCardFormInner({
1354
1922
  },
1355
1923
  [checkout.applyInlineSessionPatch, onError, sessionId, updateError]
1356
1924
  );
1357
- const runBeforeButtonClick = (0, import_react7.useCallback)(async (method) => {
1925
+ const runBeforeButtonClick = (0, import_react8.useCallback)(async (method) => {
1358
1926
  if (!onBeforeButtonClick) return { proceed: true };
1359
1927
  try {
1360
1928
  const result = await onBeforeButtonClick({
@@ -1390,7 +1958,7 @@ function SplitCardFormInner({
1390
1958
  return { proceed: false };
1391
1959
  }
1392
1960
  }, [applyInlineSessionPatch, checkout.inlineSessionDraft, onBeforeButtonClick, onError, sessionId, updateError]);
1393
- const processPaymentInternal = (0, import_react7.useCallback)(
1961
+ const processPaymentInternal = (0, import_react8.useCallback)(
1394
1962
  async (tokenizedBody, overrides) => {
1395
1963
  if (processingRef.current) return;
1396
1964
  processingRef.current = true;
@@ -1402,7 +1970,7 @@ function SplitCardFormInner({
1402
1970
  const resolvedCompletionPaymentMethodId = overrides?.completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);
1403
1971
  const requestTokenizedBody = tokenizedBody.originalPaymentMethodId ? { ...tokenizedBody, originalPaymentMethodId: void 0 } : tokenizedBody;
1404
1972
  try {
1405
- const api = new import_js.PaymentAPI(baseUrl);
1973
+ const api = new import_js2.PaymentAPI(baseUrl);
1406
1974
  const response = await api.processPayment(effectiveAccount.userId ?? "", {
1407
1975
  sessionId: effectiveSessionId,
1408
1976
  tokenizedData: requestTokenizedBody,
@@ -1413,18 +1981,18 @@ function SplitCardFormInner({
1413
1981
  lastName: effectiveAccount.lastName ?? fullName.trim().split(/\s+/).slice(1).join(" ") ?? "",
1414
1982
  ...avsConfig ? (() => {
1415
1983
  const c = selectedCountryRef.current;
1416
- const stateVisible = (0, import_shared4.isAVSFieldVisible)(avsConfig.state, c);
1417
- const line1Visible = (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, c);
1418
- const zipVisible = (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, c);
1419
- const derivedState = line1Visible && !stateVisible && zipVisible ? (0, import_shared4.getStateFromPostalCode)(c, zipCodeRef.current ?? "") : null;
1984
+ const stateVisible = (0, import_shared5.isAVSFieldVisible)(avsConfig.state, c);
1985
+ const line1Visible = (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, c);
1986
+ const zipVisible = (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, c);
1987
+ const derivedState = line1Visible && !stateVisible && zipVisible ? (0, import_shared5.getStateFromPostalCode)(c, zipCodeRef.current ?? "") : null;
1420
1988
  const stateValue2 = stateVisible ? stateRef.current : derivedState;
1421
1989
  return {
1422
1990
  country: c,
1423
1991
  ...zipVisible && zipCodeRef.current ? { zip: zipCodeRef.current } : {},
1424
- ...(0, import_shared4.isAVSFieldVisible)(avsConfig.city, c) && cityRef.current ? { city: cityRef.current } : {},
1992
+ ...(0, import_shared5.isAVSFieldVisible)(avsConfig.city, c) && cityRef.current ? { city: cityRef.current } : {},
1425
1993
  ...stateValue2 ? { state: stateValue2 } : {},
1426
1994
  ...line1Visible && addressLine1Ref.current ? { addressLine1: addressLine1Ref.current } : {},
1427
- ...(0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_2, c) && addressLine2Ref.current ? { addressLine2: addressLine2Ref.current } : {}
1995
+ ...(0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_2, c) && addressLine2Ref.current ? { addressLine2: addressLine2Ref.current } : {}
1428
1996
  };
1429
1997
  })() : {}
1430
1998
  },
@@ -1436,17 +2004,18 @@ function SplitCardFormInner({
1436
2004
  // Resolved exposure: which fields were actually shown for the active country.
1437
2005
  // Country-scoped rules (e.g. ['US', 'CA']) are flattened to booleans here.
1438
2006
  avsConfig: avsConfig ? {
1439
- country: (0, import_shared4.isAVSFieldVisible)(avsConfig.country, selectedCountryRef.current),
1440
- postal_code: (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, selectedCountryRef.current),
1441
- address_line_1: (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, selectedCountryRef.current),
1442
- address_line_2: (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_2, selectedCountryRef.current),
1443
- city: (0, import_shared4.isAVSFieldVisible)(avsConfig.city, selectedCountryRef.current),
1444
- state: (0, import_shared4.isAVSFieldVisible)(avsConfig.state, selectedCountryRef.current)
2007
+ country: (0, import_shared5.isAVSFieldVisible)(avsConfig.country, selectedCountryRef.current),
2008
+ postal_code: (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, selectedCountryRef.current),
2009
+ address_line_1: (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, selectedCountryRef.current),
2010
+ address_line_2: (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_2, selectedCountryRef.current),
2011
+ city: (0, import_shared5.isAVSFieldVisible)(avsConfig.city, selectedCountryRef.current),
2012
+ state: (0, import_shared5.isAVSFieldVisible)(avsConfig.state, selectedCountryRef.current)
1445
2013
  } : void 0
1446
2014
  });
1447
2015
  if (response.ok) {
1448
2016
  markSessionRecentlyCompleted(effectiveSessionId);
1449
2017
  setOverlayStatus("success");
2018
+ setPaypalDirectRetry(null);
1450
2019
  await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));
1451
2020
  onComplete?.({
1452
2021
  status: "succeeded",
@@ -1470,18 +2039,18 @@ function SplitCardFormInner({
1470
2039
  const retryCC = selectedCountryRef.current;
1471
2040
  const retryCountry = enableAVS ? retryCC : effectiveAccount.country;
1472
2041
  if (retryCountry) retryBillingAddress["country"] = retryCountry;
1473
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, retryCC) && zipCodeRef.current.trim()) {
2042
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, retryCC) && zipCodeRef.current.trim()) {
1474
2043
  retryBillingAddress["postal_code"] = zipCodeRef.current.trim();
1475
2044
  } else if (!avsConfig && effectiveAccount.zip) {
1476
2045
  retryBillingAddress["postal_code"] = effectiveAccount.zip;
1477
2046
  }
1478
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, retryCC) && addressLine1Ref.current.trim()) retryBillingAddress["line1"] = addressLine1Ref.current.trim();
1479
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_2, retryCC) && addressLine2Ref.current.trim()) retryBillingAddress["line2"] = addressLine2Ref.current.trim();
1480
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.city, retryCC) && cityRef.current.trim()) retryBillingAddress["city"] = cityRef.current.trim();
1481
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.state, retryCC) && stateRef.current.trim()) {
2047
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, retryCC) && addressLine1Ref.current.trim()) retryBillingAddress["line1"] = addressLine1Ref.current.trim();
2048
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_2, retryCC) && addressLine2Ref.current.trim()) retryBillingAddress["line2"] = addressLine2Ref.current.trim();
2049
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.city, retryCC) && cityRef.current.trim()) retryBillingAddress["city"] = cityRef.current.trim();
2050
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.state, retryCC) && stateRef.current.trim()) {
1482
2051
  retryBillingAddress["state"] = stateRef.current.trim();
1483
- } else if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, retryCC) && !(0, import_shared4.isAVSFieldVisible)(avsConfig.state, retryCC) && (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, retryCC)) {
1484
- const derivedRetryState = (0, import_shared4.getStateFromPostalCode)(retryCC, zipCodeRef.current.trim());
2052
+ } else if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, retryCC) && !(0, import_shared5.isAVSFieldVisible)(avsConfig.state, retryCC) && (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, retryCC)) {
2053
+ const derivedRetryState = (0, import_shared5.getStateFromPostalCode)(retryCC, zipCodeRef.current.trim());
1485
2054
  if (derivedRetryState) retryBillingAddress["state"] = derivedRetryState;
1486
2055
  }
1487
2056
  const result = await flopay.confirmPayment({
@@ -1554,6 +2123,24 @@ function SplitCardFormInner({
1554
2123
  }
1555
2124
  return;
1556
2125
  }
2126
+ if (json?.type === "paypal_direct_required") {
2127
+ const orderId = json["orderId"];
2128
+ if (!orderId) {
2129
+ setOverlayStatus("error");
2130
+ updateError("PayPal retry required but no order id provided.");
2131
+ return;
2132
+ }
2133
+ const prevAttempts = paypalDirectRetryRef.current?.attempts ?? 0;
2134
+ if (prevAttempts >= 2) {
2135
+ setOverlayStatus("error");
2136
+ updateError("PayPal payment could not be completed after multiple attempts.");
2137
+ emitDecline("paypal", "paypal_direct_required retry limit exceeded");
2138
+ return;
2139
+ }
2140
+ setPaypalDirectRetry({ orderId, attempts: prevAttempts + 1 });
2141
+ setOverlayStatus(null);
2142
+ return;
2143
+ }
1557
2144
  setOverlayStatus("error");
1558
2145
  const message = json?.message ?? "Payment failed. Please try again.";
1559
2146
  updateError(message);
@@ -1574,7 +2161,7 @@ function SplitCardFormInner({
1574
2161
  },
1575
2162
  [baseUrl, sessionId, resolvedAccount, fullName, chv, flopay, paypalFlopay, onComplete, onError, updateError, emitDecline]
1576
2163
  );
1577
- const dispatchTokenizedBody = (0, import_react7.useCallback)(
2164
+ const dispatchTokenizedBody = (0, import_react8.useCallback)(
1578
2165
  (tokenizedBody, overrides) => {
1579
2166
  if (onTokenizedBody) {
1580
2167
  onTokenizedBody(tokenizedBody);
@@ -1584,7 +2171,7 @@ function SplitCardFormInner({
1584
2171
  },
1585
2172
  [onTokenizedBody, processPaymentInternal]
1586
2173
  );
1587
- (0, import_react7.useImperativeHandle)(innerRef, () => ({
2174
+ (0, import_react8.useImperativeHandle)(innerRef, () => ({
1588
2175
  async handleNextAction(secret) {
1589
2176
  if (!flopay) return;
1590
2177
  setIs3DSActive(true);
@@ -1611,7 +2198,7 @@ function SplitCardFormInner({
1611
2198
  }
1612
2199
  }
1613
2200
  }), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
1614
- (0, import_react7.useEffect)(() => {
2201
+ (0, import_react8.useEffect)(() => {
1615
2202
  if (typeof window === "undefined") return;
1616
2203
  const stored = localStorage.getItem(WALLET_RESUME_KEY);
1617
2204
  if (!stored) return;
@@ -1629,7 +2216,7 @@ function SplitCardFormInner({
1629
2216
  localStorage.removeItem(WALLET_RESUME_KEY);
1630
2217
  }
1631
2218
  }, [sessionId, dispatchTokenizedBody]);
1632
- const handleSubmit = (0, import_react7.useCallback)(
2219
+ const handleSubmit = (0, import_react8.useCallback)(
1633
2220
  async (e) => {
1634
2221
  e.preventDefault();
1635
2222
  if (!flopay || !elements || isSubmitting || processingRef.current) return;
@@ -1643,20 +2230,20 @@ function SplitCardFormInner({
1643
2230
  try {
1644
2231
  if (avsConfig) {
1645
2232
  const country = selectedCountryRef.current;
1646
- if ((0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, country) && !zipCodeRef.current.trim()) {
1647
- updateError((0, import_shared4.getPostalCodeLabel)(country) + " is required");
2233
+ if ((0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, country) && !zipCodeRef.current.trim()) {
2234
+ updateError((0, import_shared5.getPostalCodeLabel)(country) + " is required");
1648
2235
  return;
1649
2236
  }
1650
- if ((0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, country) && !addressLine1Ref.current.trim()) {
2237
+ if ((0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, country) && !addressLine1Ref.current.trim()) {
1651
2238
  updateError("Street address is required");
1652
2239
  return;
1653
2240
  }
1654
- if ((0, import_shared4.isAVSFieldVisible)(avsConfig.city, country) && !cityRef.current.trim()) {
2241
+ if ((0, import_shared5.isAVSFieldVisible)(avsConfig.city, country) && !cityRef.current.trim()) {
1655
2242
  updateError("City is required");
1656
2243
  return;
1657
2244
  }
1658
- if ((0, import_shared4.isAVSFieldVisible)(avsConfig.state, country) && !stateRef.current.trim()) {
1659
- updateError((0, import_shared4.getStateLabel)(country) + " is required");
2245
+ if ((0, import_shared5.isAVSFieldVisible)(avsConfig.state, country) && !stateRef.current.trim()) {
2246
+ updateError((0, import_shared5.getStateLabel)(country) + " is required");
1660
2247
  return;
1661
2248
  }
1662
2249
  }
@@ -1670,18 +2257,18 @@ function SplitCardFormInner({
1670
2257
  const cc = selectedCountryRef.current;
1671
2258
  const avsCountry = enableAVS ? cc : resolvedAccount.country;
1672
2259
  if (avsCountry) billingAddress["country"] = avsCountry;
1673
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, cc) && zipCodeRef.current.trim()) {
2260
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) && zipCodeRef.current.trim()) {
1674
2261
  billingAddress["postal_code"] = zipCodeRef.current.trim();
1675
2262
  } else if (!avsConfig && resolvedAccount.zip) {
1676
2263
  billingAddress["postal_code"] = resolvedAccount.zip;
1677
2264
  }
1678
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, cc) && addressLine1Ref.current.trim()) billingAddress["line1"] = addressLine1Ref.current.trim();
1679
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_2, cc) && addressLine2Ref.current.trim()) billingAddress["line2"] = addressLine2Ref.current.trim();
1680
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.city, cc) && cityRef.current.trim()) billingAddress["city"] = cityRef.current.trim();
1681
- if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.state, cc) && stateRef.current.trim()) {
2265
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, cc) && addressLine1Ref.current.trim()) billingAddress["line1"] = addressLine1Ref.current.trim();
2266
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_2, cc) && addressLine2Ref.current.trim()) billingAddress["line2"] = addressLine2Ref.current.trim();
2267
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) && cityRef.current.trim()) billingAddress["city"] = cityRef.current.trim();
2268
+ if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) && stateRef.current.trim()) {
1682
2269
  billingAddress["state"] = stateRef.current.trim();
1683
- } else if (avsConfig && (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, cc) && !(0, import_shared4.isAVSFieldVisible)(avsConfig.state, cc) && (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, cc)) {
1684
- const derivedSubmitState = (0, import_shared4.getStateFromPostalCode)(cc, zipCodeRef.current.trim());
2270
+ } else if (avsConfig && (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, cc) && !(0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) && (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc)) {
2271
+ const derivedSubmitState = (0, import_shared5.getStateFromPostalCode)(cc, zipCodeRef.current.trim());
1685
2272
  if (derivedSubmitState) billingAddress["state"] = derivedSubmitState;
1686
2273
  }
1687
2274
  const billingDetails = {
@@ -1695,7 +2282,7 @@ function SplitCardFormInner({
1695
2282
  return;
1696
2283
  }
1697
2284
  if (!sessionId || !resolvedAccount.email) {
1698
- throw new import_shared5.FloPayError("Missing sessionId or email", "validation_error");
2285
+ throw new import_shared6.FloPayError("Missing sessionId or email", "validation_error");
1699
2286
  }
1700
2287
  const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
1701
2288
  method: "POST",
@@ -1721,7 +2308,7 @@ function SplitCardFormInner({
1721
2308
  }
1722
2309
  const intentJson = await intentResponse.json();
1723
2310
  const intentClientSecret = intentJson.data?.id;
1724
- if (!intentClientSecret) throw new import_shared5.FloPayError("No client_secret in payment intent response", "api_error");
2311
+ if (!intentClientSecret) throw new import_shared6.FloPayError("No client_secret in payment intent response", "api_error");
1725
2312
  const confirmResult = await flopay.confirmCardPayment({
1726
2313
  clientSecret: intentClientSecret,
1727
2314
  paymentMethodId: pmResult.paymentMethodId
@@ -1742,7 +2329,7 @@ function SplitCardFormInner({
1742
2329
  const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
1743
2330
  const paymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? pmResult.paymentMethodId;
1744
2331
  if (!paymentIntentId) {
1745
- const error2 = new import_shared5.FloPayError("No payment intent returned after confirmation.", "api_error");
2332
+ const error2 = new import_shared6.FloPayError("No payment intent returned after confirmation.", "api_error");
1746
2333
  setOverlayStatus("error");
1747
2334
  updateError(error2.message);
1748
2335
  onError?.(error2);
@@ -1771,7 +2358,7 @@ function SplitCardFormInner({
1771
2358
  );
1772
2359
  const isReady = flopay !== null && elements !== null;
1773
2360
  if (!isReady) {
1774
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
2361
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
1775
2362
  }
1776
2363
  const isButtons = layout === "buttons";
1777
2364
  const resolvedBorder = isButtons ? bStyles.cardInputBorder ?? "#e5e7eb" : "#A4A4FF";
@@ -1814,7 +2401,7 @@ function SplitCardFormInner({
1814
2401
  invalid: { color: "#ef4444" }
1815
2402
  }
1816
2403
  };
1817
- const cardFormBlock = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
2404
+ const cardFormBlock = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
1818
2405
  backgroundColor: cardBg,
1819
2406
  borderRadius: "8px",
1820
2407
  padding: isButtons ? "0" : "1rem",
@@ -1822,7 +2409,7 @@ function SplitCardFormInner({
1822
2409
  ...isButtons ? { padding: bStyles.cardFormContainer?.padding ?? "0" } : {},
1823
2410
  ...sharedInputPlaceholderVars
1824
2411
  }, children: [
1825
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: `
2412
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `
1826
2413
  .flopay-shared-input::placeholder {
1827
2414
  color: var(--flopay-input-placeholder-color);
1828
2415
  opacity: 1;
@@ -1831,12 +2418,12 @@ function SplitCardFormInner({
1831
2418
  font-weight: var(--flopay-input-font-weight);
1832
2419
  }
1833
2420
  ` }),
1834
- isButtons && showCardForm && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
2421
+ isButtons && showCardForm && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
1835
2422
  display: "flex",
1836
2423
  alignItems: "center",
1837
2424
  padding: "0.75rem 0 0.625rem"
1838
2425
  }, children: [
1839
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2426
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1840
2427
  "button",
1841
2428
  {
1842
2429
  type: "button",
@@ -1858,7 +2445,7 @@ function SplitCardFormInner({
1858
2445
  },
1859
2446
  "aria-label": "Back to payment methods",
1860
2447
  children: [
1861
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: {
2448
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: {
1862
2449
  display: "inline-flex",
1863
2450
  alignItems: "center",
1864
2451
  justifyContent: "center",
@@ -1868,12 +2455,12 @@ function SplitCardFormInner({
1868
2455
  backgroundColor: "#f3f4f6",
1869
2456
  transition: "background-color 0.15s",
1870
2457
  ...bStyles.backButtonIcon
1871
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
1872
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
2458
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
2459
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
1873
2460
  ]
1874
2461
  }
1875
2462
  ),
1876
- hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2463
+ hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1877
2464
  flex: 1,
1878
2465
  textAlign: "center",
1879
2466
  fontWeight: 600,
@@ -1881,18 +2468,18 @@ function SplitCardFormInner({
1881
2468
  color: "#262833",
1882
2469
  paddingRight: 80,
1883
2470
  ...bStyles.title
1884
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TitleContentSlot, { content: cardTitleContent }) })
2471
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TitleContentSlot, { content: cardTitleContent }) })
1885
2472
  ] }),
1886
- !isButtons && !hideTitle && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { textAlign: "center", fontWeight: 600, fontSize: "1.1rem", padding: "0.5rem 0", color: "#262833" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TitleContentSlot, { content: cardTitleContent }) }),
1887
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2473
+ !isButtons && !hideTitle && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { textAlign: "center", fontWeight: 600, fontSize: "1.1rem", padding: "0.5rem 0", color: "#262833" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TitleContentSlot, { content: cardTitleContent }) }),
2474
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1888
2475
  backgroundColor: cardInputBg,
1889
2476
  border: `1px solid ${resolvedBorder}`,
1890
2477
  borderTopLeftRadius: "8px",
1891
2478
  borderTopRightRadius: "8px",
1892
2479
  padding: "10px"
1893
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
1894
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex" }, children: [
1895
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2480
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
2481
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex" }, children: [
2482
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1896
2483
  flex: 1,
1897
2484
  backgroundColor: cardInputBg,
1898
2485
  border: `1px solid ${resolvedBorder}`,
@@ -1900,23 +2487,23 @@ function SplitCardFormInner({
1900
2487
  borderRight: "none",
1901
2488
  borderBottomLeftRadius: "8px",
1902
2489
  padding: "10px"
1903
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CardExpiryElement, { options: stripeElementStyle }) }),
1904
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2490
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardExpiryElement, { options: stripeElementStyle }) }),
2491
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1905
2492
  flex: 1,
1906
2493
  backgroundColor: cardInputBg,
1907
2494
  border: `1px solid ${resolvedBorder}`,
1908
2495
  borderTop: "none",
1909
2496
  borderBottomRightRadius: "8px",
1910
2497
  padding: "10px"
1911
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CardCvcElement, { options: stripeElementStyle }) })
2498
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardCvcElement, { options: stripeElementStyle }) })
1912
2499
  ] }),
1913
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2500
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1914
2501
  backgroundColor: cardInputBg,
1915
2502
  border: `1px solid ${resolvedBorder}`,
1916
2503
  borderRadius: "8px",
1917
2504
  marginTop: "0.5rem",
1918
2505
  padding: "10px"
1919
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2506
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1920
2507
  "input",
1921
2508
  {
1922
2509
  className: "flopay-shared-input",
@@ -1954,9 +2541,9 @@ function SplitCardFormInner({
1954
2541
  ...sharedInputTypography,
1955
2542
  ...isButtons && bStyles.nameInput ? bStyles.nameInput : {}
1956
2543
  });
1957
- const stateOpts = (0, import_shared4.getStateOptions)(cc);
1958
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1959
- (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_1, cc) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: inputWrapStyle(bStyles.addressLine1Input), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2544
+ const stateOpts = (0, import_shared5.getStateOptions)(cc);
2545
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2546
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: inputWrapStyle(bStyles.addressLine1Input), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1960
2547
  "input",
1961
2548
  {
1962
2549
  className: "flopay-shared-input",
@@ -1973,7 +2560,7 @@ function SplitCardFormInner({
1973
2560
  style: inputFieldStyle()
1974
2561
  }
1975
2562
  ) }),
1976
- (0, import_shared4.isAVSFieldVisible)(avsConfig.address_line_2, cc) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: inputWrapStyle(bStyles.addressLine2Input), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2563
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_2, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: inputWrapStyle(bStyles.addressLine2Input), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1977
2564
  "input",
1978
2565
  {
1979
2566
  className: "flopay-shared-input",
@@ -1989,21 +2576,21 @@ function SplitCardFormInner({
1989
2576
  style: inputFieldStyle()
1990
2577
  }
1991
2578
  ) }),
1992
- ((0, import_shared4.isAVSFieldVisible)(avsConfig.city, cc) || (0, import_shared4.isAVSFieldVisible)(avsConfig.state, cc)) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
2579
+ ((0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc)) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
1993
2580
  display: "flex",
1994
2581
  gap: "0",
1995
2582
  marginTop: "0.5rem"
1996
2583
  }, children: [
1997
- (0, import_shared4.isAVSFieldVisible)(avsConfig.city, cc) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2584
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1998
2585
  flex: 1,
1999
2586
  backgroundColor: cardInputBg,
2000
2587
  border: `1px solid ${resolvedBorder}`,
2001
2588
  padding: "10px",
2002
2589
  borderTopLeftRadius: "8px",
2003
2590
  borderBottomLeftRadius: "8px",
2004
- ...(0, import_shared4.isAVSFieldVisible)(avsConfig.state, cc) ? { borderRight: "none", borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius: "8px" },
2591
+ ...(0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) ? { borderRight: "none", borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius: "8px" },
2005
2592
  ...isButtons && bStyles.cityInput ? bStyles.cityInput : {}
2006
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2593
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2007
2594
  "input",
2008
2595
  {
2009
2596
  className: "flopay-shared-input",
@@ -2020,16 +2607,16 @@ function SplitCardFormInner({
2020
2607
  style: inputFieldStyle()
2021
2608
  }
2022
2609
  ) }),
2023
- (0, import_shared4.isAVSFieldVisible)(avsConfig.state, cc) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2610
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
2024
2611
  flex: 1,
2025
2612
  backgroundColor: cardInputBg,
2026
2613
  border: `1px solid ${resolvedBorder}`,
2027
2614
  padding: "10px",
2028
2615
  borderTopRightRadius: "8px",
2029
2616
  borderBottomRightRadius: "8px",
2030
- ...(0, import_shared4.isAVSFieldVisible)(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius: "8px" },
2617
+ ...(0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius: "8px" },
2031
2618
  ...isButtons && bStyles.stateInput ? bStyles.stateInput : {}
2032
- }, children: stateOpts ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2619
+ }, children: stateOpts ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2033
2620
  "select",
2034
2621
  {
2035
2622
  value: stateValue,
@@ -2043,15 +2630,15 @@ function SplitCardFormInner({
2043
2630
  "data-testid": "flopay-state",
2044
2631
  style: { ...inputFieldStyle(), cursor: "pointer" },
2045
2632
  children: [
2046
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "", children: (0, import_shared4.getStateLabel)(cc) }),
2047
- stateOpts.map((s) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: s.code, children: s.name }, s.code))
2633
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", children: (0, import_shared5.getStateLabel)(cc) }),
2634
+ stateOpts.map((s) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: s.code, children: s.name }, s.code))
2048
2635
  ]
2049
2636
  }
2050
- ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2637
+ ) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2051
2638
  "input",
2052
2639
  {
2053
2640
  className: "flopay-shared-input",
2054
- placeholder: (0, import_shared4.getStateLabel)(cc),
2641
+ placeholder: (0, import_shared5.getStateLabel)(cc),
2055
2642
  autoComplete: "address-level1",
2056
2643
  value: stateValue,
2057
2644
  onChange: (e) => {
@@ -2065,20 +2652,20 @@ function SplitCardFormInner({
2065
2652
  }
2066
2653
  ) })
2067
2654
  ] }),
2068
- ((0, import_shared4.isAVSFieldVisible)(avsConfig.country, cc) || (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, cc)) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
2655
+ ((0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc)) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
2069
2656
  display: "flex",
2070
2657
  flexDirection: avsLayoutProp === "column" ? "column" : "row",
2071
2658
  gap: avsLayoutProp === "column" ? "0.5rem" : "0",
2072
2659
  marginTop: "0.5rem"
2073
2660
  }, children: [
2074
- (0, import_shared4.isAVSFieldVisible)(avsConfig.country, cc) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2661
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
2075
2662
  flex: avsLayoutProp === "row" ? 1 : void 0,
2076
2663
  backgroundColor: cardInputBg,
2077
2664
  border: `1px solid ${resolvedBorder}`,
2078
2665
  padding: "10px",
2079
- ...avsLayoutProp === "row" && (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, cc) ? { borderRadius: "0", borderTopLeftRadius: "8px", borderBottomLeftRadius: "8px", borderRight: "none" } : { borderRadius: "8px" },
2666
+ ...avsLayoutProp === "row" && (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) ? { borderRadius: "0", borderTopLeftRadius: "8px", borderBottomLeftRadius: "8px", borderRight: "none" } : { borderRadius: "8px" },
2080
2667
  ...isButtons && bStyles.countrySelect ? bStyles.countrySelect : {}
2081
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2668
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2082
2669
  "select",
2083
2670
  {
2084
2671
  value: selectedCountry,
@@ -2093,25 +2680,25 @@ function SplitCardFormInner({
2093
2680
  autoComplete: "country",
2094
2681
  "data-testid": "flopay-country",
2095
2682
  style: { ...inputFieldStyle(), cursor: "pointer" },
2096
- children: import_shared4.COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("option", { value: c.code, children: [
2683
+ children: import_shared5.COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("option", { value: c.code, children: [
2097
2684
  c.flag,
2098
2685
  " ",
2099
2686
  c.name
2100
2687
  ] }, c.code))
2101
2688
  }
2102
2689
  ) }),
2103
- (0, import_shared4.isAVSFieldVisible)(avsConfig.postal_code, cc) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2690
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
2104
2691
  flex: avsLayoutProp === "row" ? 1 : void 0,
2105
2692
  backgroundColor: cardInputBg,
2106
2693
  border: `1px solid ${resolvedBorder}`,
2107
2694
  padding: "10px",
2108
- ...avsLayoutProp === "row" && (0, import_shared4.isAVSFieldVisible)(avsConfig.country, cc) ? { borderRadius: "0", borderTopRightRadius: "8px", borderBottomRightRadius: "8px" } : { borderRadius: "8px" },
2695
+ ...avsLayoutProp === "row" && (0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) ? { borderRadius: "0", borderTopRightRadius: "8px", borderBottomRightRadius: "8px" } : { borderRadius: "8px" },
2109
2696
  ...isButtons && bStyles.zipInput ? bStyles.zipInput : {}
2110
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2697
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2111
2698
  "input",
2112
2699
  {
2113
2700
  className: "flopay-shared-input",
2114
- placeholder: (0, import_shared4.getPostalCodeLabel)(selectedCountry),
2701
+ placeholder: (0, import_shared5.getPostalCodeLabel)(selectedCountry),
2115
2702
  autoComplete: "postal-code",
2116
2703
  value: zipCode,
2117
2704
  onChange: (e) => {
@@ -2128,7 +2715,7 @@ function SplitCardFormInner({
2128
2715
  ] })
2129
2716
  ] });
2130
2717
  })(),
2131
- displayError && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
2718
+ displayError && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
2132
2719
  margin: "0.75rem 0",
2133
2720
  padding: "0.625rem 0.875rem",
2134
2721
  background: "#FEF2F2",
@@ -2142,10 +2729,10 @@ function SplitCardFormInner({
2142
2729
  gap: "0.5rem",
2143
2730
  ...isButtons && bStyles.errorBanner ? bStyles.errorBanner : {}
2144
2731
  }, children: [
2145
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
2732
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
2146
2733
  displayError
2147
2734
  ] }),
2148
- children ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2735
+ children ?? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2149
2736
  "button",
2150
2737
  {
2151
2738
  type: "submit",
@@ -2168,7 +2755,7 @@ function SplitCardFormInner({
2168
2755
  children: isSubmitting ? "PROCESSING..." : submitLabel
2169
2756
  }
2170
2757
  ),
2171
- !isButtons && showSecurityFooter && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2758
+ !isButtons && showSecurityFooter && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
2172
2759
  backgroundColor: "#EFF9F0",
2173
2760
  borderRadius: "8px",
2174
2761
  padding: "0.75rem",
@@ -2185,11 +2772,11 @@ function SplitCardFormInner({
2185
2772
  const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
2186
2773
  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;
2187
2774
  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;
2188
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
2189
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FloPayKeyframes, {}),
2190
- overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
2191
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "grid" }, children: [
2192
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
2775
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
2776
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FloPayKeyframes, {}),
2777
+ overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
2778
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "grid" }, children: [
2779
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
2193
2780
  gridArea: "1 / 1",
2194
2781
  display: "flex",
2195
2782
  flexDirection: "column",
@@ -2198,7 +2785,75 @@ function SplitCardFormInner({
2198
2785
  ...!isButtonsView && !buttonsAnim ? { visibility: "hidden", position: "absolute", pointerEvents: "none", width: "100%" } : {},
2199
2786
  ...buttonsAnim ? { animation: buttonsAnim, pointerEvents: "none" } : {}
2200
2787
  }, children: [
2201
- shouldRenderPayPal && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2788
+ debug && showPayPal && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2789
+ "pre",
2790
+ {
2791
+ "data-testid": "flopay-direct-paypal-gate-debug",
2792
+ style: {
2793
+ margin: 0,
2794
+ padding: "6px 8px",
2795
+ background: "#eef2ff",
2796
+ border: "1px solid #c7d2fe",
2797
+ borderRadius: 6,
2798
+ color: "#111827",
2799
+ font: "11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace",
2800
+ whiteSpace: "pre-wrap",
2801
+ wordBreak: "break-word"
2802
+ },
2803
+ children: [
2804
+ "FloPay/DirectPayPal-debug (parent gate)",
2805
+ ` showPayPal=${showPayPal}`,
2806
+ ` directPaypalConfigured=${directPaypalConfigured}`,
2807
+ ` inAppBrowserDetected=${String(inAppBrowserDetected)}`,
2808
+ ` shouldRenderDirectPayPal=${shouldRenderDirectPayPal}`,
2809
+ ` shouldRenderStripePayPal=${shouldRenderStripePayPal}`,
2810
+ ` hasPaypalStripeInstance=${!!paypalStripeInstance}`
2811
+ ].join("\n")
2812
+ }
2813
+ ),
2814
+ shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2815
+ paypalDirectRetry && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2816
+ "div",
2817
+ {
2818
+ "data-testid": "flopay-paypal-direct-retry-notice",
2819
+ style: {
2820
+ padding: "8px 10px",
2821
+ background: "#fef3c7",
2822
+ border: "1px solid #fcd34d",
2823
+ borderRadius: 6,
2824
+ color: "#78350f",
2825
+ fontSize: 13,
2826
+ lineHeight: 1.4
2827
+ },
2828
+ children: "Please confirm your PayPal payment to complete checkout."
2829
+ }
2830
+ ),
2831
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2832
+ DirectPayPalButton,
2833
+ {
2834
+ sessionId,
2835
+ billingApiUrl: resolvedBillingApiUrl,
2836
+ email: resolvedAccount.email,
2837
+ clientId: directPaypal.clientId,
2838
+ environment: directPaypal.environment,
2839
+ currency: currency.toUpperCase(),
2840
+ isSubscription,
2841
+ onTokenizedBody: dispatchTokenizedBody,
2842
+ onComplete,
2843
+ onErrorChange: updateError,
2844
+ onDecline,
2845
+ onButtonClick,
2846
+ runBeforeButtonClick,
2847
+ isProcessing: isSubmitting,
2848
+ onLoadStateChange: setDirectPaypalReady,
2849
+ session: session ?? null,
2850
+ existingOrderId: paypalDirectRetry?.orderId,
2851
+ debug
2852
+ },
2853
+ paypalDirectRetry?.orderId ?? "fresh"
2854
+ )
2855
+ ] }),
2856
+ shouldRenderStripePayPal && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2202
2857
  PayPalButtonInner,
2203
2858
  {
2204
2859
  sessionId,
@@ -2213,7 +2868,7 @@ function SplitCardFormInner({
2213
2868
  onLoadStateChange: setPaypalLoadState
2214
2869
  }
2215
2870
  ) }),
2216
- shouldRenderWallets ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2871
+ shouldRenderWallets ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2217
2872
  WalletButtonInner,
2218
2873
  {
2219
2874
  sessionId,
@@ -2228,8 +2883,8 @@ function SplitCardFormInner({
2228
2883
  runBeforeButtonClick,
2229
2884
  onLoadStateChange: setWalletLoadState
2230
2885
  }
2231
- ) }) : shouldShowWallets ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
2232
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2886
+ ) }) : shouldShowWallets ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
2887
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2233
2888
  "button",
2234
2889
  {
2235
2890
  type: "button",
@@ -2267,10 +2922,10 @@ function SplitCardFormInner({
2267
2922
  onMouseUp: (e) => {
2268
2923
  e.currentTarget.style.transform = "scale(1)";
2269
2924
  },
2270
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CardButtonContentSlot, { content: cardButtonContent })
2925
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardButtonContentSlot, { content: cardButtonContent })
2271
2926
  }
2272
2927
  ),
2273
- displayError && viewState === "buttons" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
2928
+ displayError && viewState === "buttons" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
2274
2929
  margin: "0.25rem 0",
2275
2930
  padding: "0.625rem 0.875rem",
2276
2931
  background: "#FEF2F2",
@@ -2284,11 +2939,11 @@ function SplitCardFormInner({
2284
2939
  gap: "0.5rem",
2285
2940
  ...bStyles.errorBanner ? bStyles.errorBanner : {}
2286
2941
  }, children: [
2287
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
2942
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
2288
2943
  displayError
2289
2944
  ] })
2290
2945
  ] }),
2291
- isCardView && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
2946
+ isCardView && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
2292
2947
  gridArea: "1 / 1",
2293
2948
  ...cardAnim ? { animation: cardAnim } : {},
2294
2949
  ...viewState === "collapsing" ? { pointerEvents: "none" } : {}
@@ -2296,37 +2951,111 @@ function SplitCardFormInner({
2296
2951
  ] })
2297
2952
  ] });
2298
2953
  }
2299
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
2300
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FloPayKeyframes, {}),
2301
- overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
2302
- shouldRenderWallets && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2303
- WalletButtonInner,
2304
- {
2305
- sessionId,
2306
- email: resolvedAccount.email,
2307
- billingApiUrl: resolvedBillingApiUrl,
2308
- showApplePay,
2309
- showGooglePay,
2310
- onTokenizedBody: dispatchTokenizedBody,
2311
- onErrorChange: updateError,
2312
- onDecline,
2313
- onLoadStateChange: setWalletLoadState
2314
- }
2315
- ) }),
2316
- shouldRenderPayPal && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2317
- PayPalButtonInner,
2318
- {
2319
- sessionId,
2320
- email: resolvedAccount.email,
2321
- billingApiUrl: resolvedBillingApiUrl,
2322
- onTokenizedBody: dispatchTokenizedBody,
2323
- onErrorChange: updateError,
2324
- isProcessing: isSubmitting,
2325
- onDecline,
2326
- onLoadStateChange: setPaypalLoadState
2327
- }
2328
- ) }),
2329
- (shouldDisplayWalletRow || shouldDisplayPayPalRow) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
2954
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
2955
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FloPayKeyframes, {}),
2956
+ overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
2957
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
2958
+ debug && showPayPal && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2959
+ "pre",
2960
+ {
2961
+ "data-testid": "flopay-direct-paypal-gate-debug-default",
2962
+ style: {
2963
+ margin: 0,
2964
+ padding: "6px 8px",
2965
+ background: "#eef2ff",
2966
+ border: "1px solid #c7d2fe",
2967
+ borderRadius: 6,
2968
+ color: "#111827",
2969
+ font: "11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace",
2970
+ whiteSpace: "pre-wrap",
2971
+ wordBreak: "break-word"
2972
+ },
2973
+ children: [
2974
+ "FloPay/DirectPayPal-debug (parent gate)",
2975
+ ` showPayPal=${showPayPal}`,
2976
+ ` directPaypalConfigured=${directPaypalConfigured}`,
2977
+ ` inAppBrowserDetected=${String(inAppBrowserDetected)}`,
2978
+ ` shouldRenderDirectPayPal=${shouldRenderDirectPayPal}`,
2979
+ ` shouldRenderStripePayPal=${shouldRenderStripePayPal}`,
2980
+ ` hasPaypalStripeInstance=${!!paypalStripeInstance}`
2981
+ ].join("\n")
2982
+ }
2983
+ ),
2984
+ shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2985
+ paypalDirectRetry && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2986
+ "div",
2987
+ {
2988
+ "data-testid": "flopay-paypal-direct-retry-notice-default",
2989
+ style: {
2990
+ padding: "8px 10px",
2991
+ background: "#fef3c7",
2992
+ border: "1px solid #fcd34d",
2993
+ borderRadius: 6,
2994
+ color: "#78350f",
2995
+ fontSize: 13,
2996
+ lineHeight: 1.4
2997
+ },
2998
+ children: "Please confirm your PayPal payment to complete checkout."
2999
+ }
3000
+ ),
3001
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3002
+ DirectPayPalButton,
3003
+ {
3004
+ sessionId,
3005
+ billingApiUrl: resolvedBillingApiUrl,
3006
+ email: resolvedAccount.email,
3007
+ clientId: directPaypal.clientId,
3008
+ environment: directPaypal.environment,
3009
+ currency: currency.toUpperCase(),
3010
+ isSubscription,
3011
+ onTokenizedBody: dispatchTokenizedBody,
3012
+ onComplete,
3013
+ onErrorChange: updateError,
3014
+ onDecline,
3015
+ onButtonClick,
3016
+ runBeforeButtonClick,
3017
+ isProcessing: isSubmitting,
3018
+ onLoadStateChange: setDirectPaypalReady,
3019
+ session: session ?? null,
3020
+ existingOrderId: paypalDirectRetry?.orderId,
3021
+ debug
3022
+ },
3023
+ paypalDirectRetry?.orderId ?? "fresh"
3024
+ )
3025
+ ] }),
3026
+ shouldRenderStripePayPal && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3027
+ PayPalButtonInner,
3028
+ {
3029
+ sessionId,
3030
+ email: resolvedAccount.email,
3031
+ billingApiUrl: resolvedBillingApiUrl,
3032
+ onTokenizedBody: dispatchTokenizedBody,
3033
+ onErrorChange: updateError,
3034
+ isProcessing: isSubmitting,
3035
+ onButtonClick,
3036
+ onDecline,
3037
+ runBeforeButtonClick,
3038
+ onLoadStateChange: setPaypalLoadState
3039
+ }
3040
+ ) }),
3041
+ shouldRenderWallets && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3042
+ WalletButtonInner,
3043
+ {
3044
+ sessionId,
3045
+ email: resolvedAccount.email,
3046
+ billingApiUrl: resolvedBillingApiUrl,
3047
+ showApplePay,
3048
+ showGooglePay,
3049
+ onTokenizedBody: dispatchTokenizedBody,
3050
+ onErrorChange: updateError,
3051
+ onButtonClick,
3052
+ onDecline,
3053
+ runBeforeButtonClick,
3054
+ onLoadStateChange: setWalletLoadState
3055
+ }
3056
+ ) })
3057
+ ] }),
3058
+ (shouldDisplayWalletRow || shouldDisplayPayPalRow) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
2330
3059
  display: "flex",
2331
3060
  alignItems: "center",
2332
3061
  gap: "0.75rem",
@@ -2334,17 +3063,17 @@ function SplitCardFormInner({
2334
3063
  color: "#999",
2335
3064
  fontSize: "0.85rem"
2336
3065
  }, children: [
2337
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } }),
2338
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "or pay with card" }),
2339
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
3066
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } }),
3067
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "or pay with card" }),
3068
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
2340
3069
  ] }),
2341
3070
  cardFormBlock
2342
3071
  ] });
2343
3072
  }
2344
3073
 
2345
3074
  // src/saved-payment-flow.ts
2346
- var import_js2 = require("@flopay/js");
2347
- var import_shared6 = require("@flopay/shared");
3075
+ var import_js3 = require("@flopay/js");
3076
+ var import_shared7 = require("@flopay/shared");
2348
3077
  var DEFAULT_SAVED_PAYMENT_DECLINE_METHOD = "card";
2349
3078
  function getRedirectResultFromCheckoutProcessError(error) {
2350
3079
  if (!error?.type || !error.threeDSecureToken) {
@@ -2362,7 +3091,7 @@ function getRedirectResultFromCheckoutProcessError(error) {
2362
3091
  function checkoutProcessErrorToFloPayError(error, fallbackMessage = "Payment failed. Please try again.", options) {
2363
3092
  const checkoutMethod = options?.checkoutMethod ?? error?.checkoutMethod ?? (error?.type === "paypal_redirect_required" ? "paypal" : "card");
2364
3093
  return Object.assign(
2365
- new import_shared6.FloPayError(
3094
+ new import_shared7.FloPayError(
2366
3095
  error?.message ?? fallbackMessage,
2367
3096
  "api_error",
2368
3097
  {
@@ -2417,16 +3146,19 @@ function getRedirectTokenFromProcessResponse(json, options) {
2417
3146
  return candidate;
2418
3147
  }
2419
3148
  }
2420
- const nestedGatewayData = nestedRecord.gatewayData;
2421
- if (nestedGatewayData && typeof nestedGatewayData === "object") {
2422
- const nestedGatewayDataRecord = nestedGatewayData;
2423
- const gatewayCandidates = [
2424
- nestedGatewayDataRecord.stripeClientSecret,
2425
- nestedGatewayDataRecord.clientSecret
2426
- ];
2427
- for (const candidate of gatewayCandidates) {
2428
- if (typeof candidate === "string" && candidate.length > 0 && (!options?.requirePaymentIntentClientSecret || isStripePaymentIntentClientSecret(candidate))) {
2429
- return candidate;
3149
+ const nestedGateways = nestedRecord.gateways;
3150
+ if (nestedGateways && typeof nestedGateways === "object") {
3151
+ const stripeGateway = nestedGateways.stripe;
3152
+ if (stripeGateway && typeof stripeGateway === "object") {
3153
+ const stripeRecord = stripeGateway;
3154
+ const gatewayCandidates = [
3155
+ stripeRecord.stripeClientSecret,
3156
+ stripeRecord.clientSecret
3157
+ ];
3158
+ for (const candidate of gatewayCandidates) {
3159
+ if (typeof candidate === "string" && candidate.length > 0 && (!options?.requirePaymentIntentClientSecret || isStripePaymentIntentClientSecret(candidate))) {
3160
+ return candidate;
3161
+ }
2430
3162
  }
2431
3163
  }
2432
3164
  }
@@ -2451,9 +3183,9 @@ async function recover3DSRedirectResult({
2451
3183
  return null;
2452
3184
  }
2453
3185
  try {
2454
- const api = new import_js2.PaymentAPI(billingApiUrl);
3186
+ const api = new import_js3.PaymentAPI(billingApiUrl);
2455
3187
  const unified = await api.getUnifiedCheckoutSession(sessionId);
2456
- const refreshedToken = unified.provider === "stripe" ? unified.data.stripe?.clientSecret : void 0;
3188
+ const refreshedToken = unified.data.stripe?.clientSecret;
2457
3189
  if (isStripePaymentIntentClientSecret(refreshedToken)) {
2458
3190
  return {
2459
3191
  type: "3ds_required",
@@ -2479,7 +3211,7 @@ async function processSavedPaymentForMode({
2479
3211
  const lastName = session.customer?.lastName ?? session.accountData?.lastName ?? "";
2480
3212
  const country = session.customer?.country ?? session.accountData?.country ?? void 0;
2481
3213
  const zip = session.customer?.zip ?? session.accountData?.zip ?? void 0;
2482
- const api = new import_js2.PaymentAPI(baseUrl);
3214
+ const api = new import_js3.PaymentAPI(baseUrl);
2483
3215
  const response = await retryOnceOnFetchFailure(() => api.processPayment(customerId, {
2484
3216
  sessionId: resolvedSessionId,
2485
3217
  tokenizedData,
@@ -2508,7 +3240,7 @@ async function processSavedPaymentForMode({
2508
3240
  if (json?.type === "paypal_redirect_required" || json?.type === "3ds_required") {
2509
3241
  const redirectToken = getRedirectTokenFromProcessResponse(json);
2510
3242
  if (!redirectToken) {
2511
- throw new import_shared6.FloPayError(
3243
+ throw new import_shared7.FloPayError(
2512
3244
  "Authentication is required but no redirect token was provided.",
2513
3245
  "api_error",
2514
3246
  { code: "authentication_required" }
@@ -2530,7 +3262,7 @@ async function processSavedPaymentForMode({
2530
3262
  return recoveredRedirect;
2531
3263
  }
2532
3264
  throw Object.assign(
2533
- new import_shared6.FloPayError(
3265
+ new import_shared7.FloPayError(
2534
3266
  "Your card requires authentication. Please enter your payment details below.",
2535
3267
  "api_error",
2536
3268
  { code: "authentication_required" }
@@ -2538,7 +3270,7 @@ async function processSavedPaymentForMode({
2538
3270
  { checkoutMethod: "card" }
2539
3271
  );
2540
3272
  }
2541
- throw new import_shared6.FloPayError(
3273
+ throw new import_shared7.FloPayError(
2542
3274
  json?.message ?? "Payment failed. Please try again.",
2543
3275
  "api_error",
2544
3276
  {
@@ -2558,13 +3290,13 @@ async function processSavedPaymentWithIntent({
2558
3290
  const customerEmail = session.customer?.email ?? session.accountData?.email ?? "";
2559
3291
  if (!customerEmail) {
2560
3292
  throw Object.assign(
2561
- new import_shared6.FloPayError("Customer email is required to create a payment intent.", "validation_error", {
3293
+ new import_shared7.FloPayError("Customer email is required to create a payment intent.", "validation_error", {
2562
3294
  param: "email"
2563
3295
  }),
2564
3296
  { checkoutMethod: "card" }
2565
3297
  );
2566
3298
  }
2567
- const api = new import_js2.PaymentAPI(billingApiUrl);
3299
+ const api = new import_js3.PaymentAPI(billingApiUrl);
2568
3300
  const intentResponse = await retryOnceOnFetchFailure(() => api.createPaymentIntent(
2569
3301
  sessionId,
2570
3302
  customerEmail,
@@ -2586,7 +3318,7 @@ async function processSavedPaymentWithIntent({
2586
3318
  });
2587
3319
  if (!intentClientSecret) {
2588
3320
  throw Object.assign(
2589
- new import_shared6.FloPayError("No client secret in payment intent response.", "api_error"),
3321
+ new import_shared7.FloPayError("No client secret in payment intent response.", "api_error"),
2590
3322
  { checkoutMethod: "card" }
2591
3323
  );
2592
3324
  }
@@ -2609,7 +3341,7 @@ async function processSavedPaymentWithIntent({
2609
3341
  const confirmedPaymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? paymentMethodId;
2610
3342
  if (!confirmedPaymentIntentId || confirmResult.status !== "succeeded" && confirmResult.status !== "processing" && confirmResult.status !== "requires_capture") {
2611
3343
  throw Object.assign(
2612
- new import_shared6.FloPayError(
3344
+ new import_shared7.FloPayError(
2613
3345
  `Unfortunately, your payment could not be processed. Please try again using a different payment method or contact your bank for assistance. If the issue persists, feel free to reach out to us for support.`,
2614
3346
  "api_error",
2615
3347
  {
@@ -2657,12 +3389,12 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
2657
3389
  }) {
2658
3390
  const stripe = flopay?.getRawProvider();
2659
3391
  if (!stripe) {
2660
- throw new import_shared6.FloPayError("Payment provider is not available.", "api_error");
3392
+ throw new import_shared7.FloPayError("Payment provider is not available.", "api_error");
2661
3393
  }
2662
3394
  if (redirectResult.type === "3ds_required") {
2663
3395
  if (!attempt3DS || !redirectResult.threeDSecureToken) {
2664
3396
  throw Object.assign(
2665
- new import_shared6.FloPayError(
3397
+ new import_shared7.FloPayError(
2666
3398
  "Your card requires authentication. Please enter your payment details below.",
2667
3399
  "api_error",
2668
3400
  { code: "authentication_required" }
@@ -2678,7 +3410,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
2678
3410
  );
2679
3411
  if (retrieveError) {
2680
3412
  throw Object.assign(
2681
- new import_shared6.FloPayError(
3413
+ new import_shared7.FloPayError(
2682
3414
  retrieveError.message ?? "Failed to retrieve 3DS payment status.",
2683
3415
  "api_error",
2684
3416
  { code: retrieveError.code }
@@ -2704,7 +3436,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
2704
3436
  );
2705
3437
  if (confirmError) {
2706
3438
  throw Object.assign(
2707
- new import_shared6.FloPayError(
3439
+ new import_shared7.FloPayError(
2708
3440
  confirmError.message ?? "3DS authentication failed.",
2709
3441
  "api_error",
2710
3442
  { code: confirmError.code }
@@ -2719,7 +3451,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
2719
3451
  });
2720
3452
  if (nextActionError) {
2721
3453
  throw Object.assign(
2722
- new import_shared6.FloPayError(
3454
+ new import_shared7.FloPayError(
2723
3455
  nextActionError.message ?? "3DS authentication failed.",
2724
3456
  "api_error",
2725
3457
  { code: nextActionError.code }
@@ -2759,7 +3491,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
2759
3491
  });
2760
3492
  }
2761
3493
  throw Object.assign(
2762
- new import_shared6.FloPayError("3DS authentication did not complete successfully.", "api_error"),
3494
+ new import_shared7.FloPayError("3DS authentication did not complete successfully.", "api_error"),
2763
3495
  { checkoutMethod: "card" }
2764
3496
  );
2765
3497
  }
@@ -2767,7 +3499,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
2767
3499
  const paypalStripe = (paypalFlopay ?? flopay)?.getRawProvider();
2768
3500
  if (!paypalStripe) {
2769
3501
  throw Object.assign(
2770
- new import_shared6.FloPayError("PayPal is not available.", "api_error"),
3502
+ new import_shared7.FloPayError("PayPal is not available.", "api_error"),
2771
3503
  { checkoutMethod: "paypal" }
2772
3504
  );
2773
3505
  }
@@ -2777,7 +3509,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
2777
3509
  });
2778
3510
  if (error2) {
2779
3511
  throw Object.assign(
2780
- new import_shared6.FloPayError(
3512
+ new import_shared7.FloPayError(
2781
3513
  error2.message ?? "PayPal authorization failed.",
2782
3514
  "api_error",
2783
3515
  { code: error2.code }
@@ -2800,7 +3532,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
2800
3532
  });
2801
3533
  if (error) {
2802
3534
  throw Object.assign(
2803
- new import_shared6.FloPayError(
3535
+ new import_shared7.FloPayError(
2804
3536
  error.message ?? "PayPal authorization failed.",
2805
3537
  "api_error",
2806
3538
  { code: error.code }
@@ -2813,33 +3545,33 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
2813
3545
  checkoutMethod: "paypal"
2814
3546
  };
2815
3547
  }
2816
- throw new import_shared6.FloPayError("Unsupported payment redirect state.", "api_error");
3548
+ throw new import_shared7.FloPayError("Unsupported payment redirect state.", "api_error");
2817
3549
  }
2818
3550
  function normalizeSavedPaymentError(err) {
2819
- if (err instanceof import_shared6.FloPayError) {
3551
+ if (err instanceof import_shared7.FloPayError) {
2820
3552
  return err;
2821
3553
  }
2822
- return new import_shared6.FloPayError(
3554
+ return new import_shared7.FloPayError(
2823
3555
  err instanceof Error ? err.message : "Payment failed. Please try again.",
2824
3556
  "api_error"
2825
3557
  );
2826
3558
  }
2827
3559
  function resolveSavedPaymentPublishableKeys(unified) {
2828
- let publishableKey;
2829
- let paypalPublishableKey;
2830
- if (unified.provider === "stripe") {
2831
- publishableKey = unified.data.stripe?.publishableKey;
2832
- paypalPublishableKey = unified.data.stripe?.paypalPublishableKey ?? void 0;
2833
- }
3560
+ const publishableKey = unified.data.stripe?.publishableKey;
2834
3561
  if (!publishableKey) {
2835
- throw new import_shared6.FloPayError(
2836
- "No publishable key found in the checkout session. Ensure the session includes gatewayData.publishableKey.",
3562
+ throw new import_shared7.FloPayError(
3563
+ "No publishable key found in the checkout session. Ensure the session advertises gateways.stripe.",
2837
3564
  "validation_error"
2838
3565
  );
2839
3566
  }
2840
3567
  return {
2841
3568
  publishableKey,
2842
- paypalPublishableKey
3569
+ // Direct-PayPal sessions can still use Stripe's PayPal Element for the
3570
+ // saved-PM redirect leg. Prefer the dedicated Stripe-PayPal sub-account
3571
+ // publishable key when the backend advertises one; fall back to the
3572
+ // primary Stripe publishable key so the resume flow still has a Stripe
3573
+ // instance to drive Stripe's PayPal PI.
3574
+ paypalPublishableKey: unified.data.stripe?.paypalPublishableKey ?? publishableKey
2843
3575
  };
2844
3576
  }
2845
3577
  async function loadSavedPaymentProviders({
@@ -2850,11 +3582,11 @@ async function loadSavedPaymentProviders({
2850
3582
  }) {
2851
3583
  const needsSeparatePaypal = Boolean(paypalPublishableKey) && paypalPublishableKey !== publishableKey;
2852
3584
  const [instance, paypalInstanceOrError] = await Promise.all([
2853
- (0, import_js2.loadFloPay)(publishableKey, {
3585
+ (0, import_js3.loadFloPay)(publishableKey, {
2854
3586
  billingApiUrl,
2855
3587
  locale
2856
3588
  }),
2857
- needsSeparatePaypal ? (0, import_js2.loadFloPay)(paypalPublishableKey, {
3589
+ needsSeparatePaypal ? (0, import_js3.loadFloPay)(paypalPublishableKey, {
2858
3590
  billingApiUrl,
2859
3591
  locale
2860
3592
  }).catch((err) => {
@@ -2869,13 +3601,21 @@ async function loadSavedPaymentProviders({
2869
3601
  }
2870
3602
 
2871
3603
  // src/flopay-checkout.tsx
2872
- var import_jsx_runtime6 = require("react/jsx-runtime");
3604
+ var import_jsx_runtime7 = require("react/jsx-runtime");
2873
3605
  var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
2874
3606
  var PAYPAL_RESUME_STORAGE_KEY = "flopay_checkout_saved_payment_resume";
2875
3607
  var sessionInflightMap = /* @__PURE__ */ new Map();
2876
3608
  function sleep(ms) {
2877
3609
  return new Promise((resolve) => setTimeout(resolve, ms));
2878
3610
  }
3611
+ function resolveDirectPaypalConfig(unified) {
3612
+ const clientId = unified?.data.paypal?.publishableKey;
3613
+ if (!clientId) return void 0;
3614
+ return {
3615
+ clientId,
3616
+ environment: unified?.data.paypal?.environment
3617
+ };
3618
+ }
2879
3619
  function canUseStorage() {
2880
3620
  return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
2881
3621
  }
@@ -2949,6 +3689,7 @@ function FloPayCheckout({
2949
3689
  showPayPal = true,
2950
3690
  showApplePay = true,
2951
3691
  showGooglePay = true,
3692
+ debug = false,
2952
3693
  layout,
2953
3694
  buttonsTheme,
2954
3695
  buttonsStyles,
@@ -2969,81 +3710,81 @@ function FloPayCheckout({
2969
3710
  renderConfirmButton,
2970
3711
  onSessionCompleted
2971
3712
  }) {
2972
- const resolvedBillingUrl = (0, import_shared7.resolveBillingApiUrl)(billingApiUrl);
3713
+ const resolvedBillingUrl = (0, import_shared8.resolveBillingApiUrl)(billingApiUrl);
2973
3714
  const checkoutType = createSessionParams ? "embedded_checkout" : "standard_checkout";
2974
3715
  const checkoutLayout = children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout";
2975
- const [unified, setUnified] = (0, import_react8.useState)(null);
2976
- const [flopay, setFloPay] = (0, import_react8.useState)(null);
2977
- const flopayRef = (0, import_react8.useRef)(null);
2978
- const [paypalFlopay, setPaypalFloPay] = (0, import_react8.useState)(null);
2979
- const paypalFlopayRef = (0, import_react8.useRef)(null);
2980
- const [session, setSession] = (0, import_react8.useState)(null);
2981
- const [resolvedSessionId, setResolvedSessionId] = (0, import_react8.useState)(sessionIdProp ?? "");
3716
+ const [unified, setUnified] = (0, import_react9.useState)(null);
3717
+ const [flopay, setFloPay] = (0, import_react9.useState)(null);
3718
+ const flopayRef = (0, import_react9.useRef)(null);
3719
+ const [paypalFlopay, setPaypalFloPay] = (0, import_react9.useState)(null);
3720
+ const paypalFlopayRef = (0, import_react9.useRef)(null);
3721
+ const [session, setSession] = (0, import_react9.useState)(null);
3722
+ const [resolvedSessionId, setResolvedSessionId] = (0, import_react9.useState)(sessionIdProp ?? "");
2982
3723
  const activeSessionId = sessionIdProp ?? resolvedSessionId;
2983
3724
  const initSessionDependency = createSessionParams ? "" : activeSessionId;
2984
- const [isLoading, setIsLoading] = (0, import_react8.useState)(true);
2985
- const [loadError, setLoadError] = (0, import_react8.useState)(null);
2986
- const [currentMode, setCurrentMode] = (0, import_react8.useState)("full");
2987
- const [confirmProcessing, setConfirmProcessing] = (0, import_react8.useState)(false);
2988
- const [modeError, setModeError] = (0, import_react8.useState)(initialErrorMessage);
2989
- const [modeOverlayStatus, setModeOverlayStatus] = (0, import_react8.useState)(null);
2990
- const [modeOverlayError, setModeOverlayError] = (0, import_react8.useState)(null);
2991
- const [createSessionPatch, setCreateSessionPatch] = (0, import_react8.useState)(void 0);
2992
- const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = (0, import_react8.useState)("");
2993
- const [cardBootstrapPending, setCardBootstrapPending] = (0, import_react8.useState)(false);
2994
- const autoCheckoutAttempted = (0, import_react8.useRef)(false);
2995
- const paypalResumeAttempted = (0, import_react8.useRef)(false);
2996
- const savedPaymentKeysRef = (0, import_react8.useRef)(null);
2997
- const onCompleteRef = (0, import_react8.useRef)(onComplete);
3725
+ const [isLoading, setIsLoading] = (0, import_react9.useState)(true);
3726
+ const [loadError, setLoadError] = (0, import_react9.useState)(null);
3727
+ const [currentMode, setCurrentMode] = (0, import_react9.useState)("full");
3728
+ const [confirmProcessing, setConfirmProcessing] = (0, import_react9.useState)(false);
3729
+ const [modeError, setModeError] = (0, import_react9.useState)(initialErrorMessage);
3730
+ const [modeOverlayStatus, setModeOverlayStatus] = (0, import_react9.useState)(null);
3731
+ const [modeOverlayError, setModeOverlayError] = (0, import_react9.useState)(null);
3732
+ const [createSessionPatch, setCreateSessionPatch] = (0, import_react9.useState)(void 0);
3733
+ const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = (0, import_react9.useState)("");
3734
+ const [cardBootstrapPending, setCardBootstrapPending] = (0, import_react9.useState)(false);
3735
+ const autoCheckoutAttempted = (0, import_react9.useRef)(false);
3736
+ const paypalResumeAttempted = (0, import_react9.useRef)(false);
3737
+ const savedPaymentKeysRef = (0, import_react9.useRef)(null);
3738
+ const onCompleteRef = (0, import_react9.useRef)(onComplete);
2998
3739
  onCompleteRef.current = onComplete;
2999
- const onErrorRef = (0, import_react8.useRef)(onError);
3740
+ const onErrorRef = (0, import_react9.useRef)(onError);
3000
3741
  onErrorRef.current = onError;
3001
- const onDeclineRef = (0, import_react8.useRef)(onDecline);
3742
+ const onDeclineRef = (0, import_react9.useRef)(onDecline);
3002
3743
  onDeclineRef.current = onDecline;
3003
- const onSessionCompletedRef = (0, import_react8.useRef)(onSessionCompleted);
3744
+ const onSessionCompletedRef = (0, import_react9.useRef)(onSessionCompleted);
3004
3745
  onSessionCompletedRef.current = onSessionCompleted;
3005
- (0, import_react8.useEffect)(() => {
3746
+ (0, import_react9.useEffect)(() => {
3006
3747
  console.info("[FloPay] Checkout initialized", {
3007
- sdk_version: import_shared7.SDK_VERSION,
3748
+ sdk_version: import_shared8.SDK_VERSION,
3008
3749
  checkout_type: checkoutType,
3009
3750
  checkout_layout: checkoutLayout,
3010
3751
  billing_api_url: resolvedBillingUrl
3011
3752
  });
3012
3753
  }, [checkoutLayout, checkoutType, resolvedBillingUrl]);
3013
- const baseCreateSessionHash = (0, import_react8.useMemo)(
3754
+ const baseCreateSessionHash = (0, import_react9.useMemo)(
3014
3755
  () => createSessionParams ? hashCreateParams(createSessionParams) : "",
3015
3756
  [createSessionParams]
3016
3757
  );
3017
- const activeCreateSessionPatch = (0, import_react8.useMemo)(
3758
+ const activeCreateSessionPatch = (0, import_react9.useMemo)(
3018
3759
  () => createSessionPatchBaseHash === baseCreateSessionHash ? createSessionPatch : void 0,
3019
3760
  [createSessionPatch, createSessionPatchBaseHash, baseCreateSessionHash]
3020
3761
  );
3021
- const effectiveCreateSessionBase = (0, import_react8.useMemo)(
3762
+ const effectiveCreateSessionBase = (0, import_react9.useMemo)(
3022
3763
  () => createSessionParams ? mergeInlineSessionPatch(createSessionParams, activeCreateSessionPatch) : void 0,
3023
3764
  [createSessionParams, activeCreateSessionPatch]
3024
3765
  );
3025
3766
  const effectiveCreateSessionMode = checkoutModeProp ?? effectiveCreateSessionBase?.checkoutMode ?? "full";
3026
- const effectiveCreateSession = (0, import_react8.useMemo)(
3767
+ const effectiveCreateSession = (0, import_react9.useMemo)(
3027
3768
  () => effectiveCreateSessionBase ? {
3028
3769
  ...effectiveCreateSessionBase,
3029
3770
  checkoutMode: effectiveCreateSessionMode
3030
3771
  } : void 0,
3031
3772
  [effectiveCreateSessionBase, effectiveCreateSessionMode]
3032
3773
  );
3033
- (0, import_react8.useEffect)(() => {
3774
+ (0, import_react9.useEffect)(() => {
3034
3775
  setCreateSessionPatch(void 0);
3035
3776
  setCreateSessionPatchBaseHash(baseCreateSessionHash);
3036
3777
  }, [baseCreateSessionHash]);
3037
- (0, import_react8.useEffect)(() => {
3778
+ (0, import_react9.useEffect)(() => {
3038
3779
  setModeError(initialErrorMessage);
3039
3780
  }, [initialErrorMessage]);
3040
- const emitDecline = (0, import_react8.useCallback)(
3781
+ const emitDecline = (0, import_react9.useCallback)(
3041
3782
  (method, input, overrides) => {
3042
3783
  onDeclineRef.current?.(buildDeclineEvent(method, input, overrides));
3043
3784
  },
3044
3785
  []
3045
3786
  );
3046
- const runSavedPaymentFlow = (0, import_react8.useCallback)(
3787
+ const runSavedPaymentFlow = (0, import_react9.useCallback)(
3047
3788
  async (sess, options) => {
3048
3789
  setModeError(null);
3049
3790
  setModeOverlayError(null);
@@ -3072,12 +3813,12 @@ function FloPayCheckout({
3072
3813
  clearPayPalResumeState();
3073
3814
  }
3074
3815
  } else if (options?.initialAutoProcessingPending) {
3075
- const api = new import_js3.PaymentAPI(resolvedBillingUrl);
3816
+ const api = new import_js4.PaymentAPI(resolvedBillingUrl);
3076
3817
  const completed = await api.waitForCheckoutSessionCompletion(options.initialAutoProcessingPending.sessionId, {
3077
3818
  initialDelayMs: options.initialAutoProcessingPending.retryAfterMs
3078
3819
  });
3079
3820
  if (completed.data.session?.status !== "complete") {
3080
- throw new import_shared7.FloPayError("Automatic payment failed. Please try again.", "api_error", {
3821
+ throw new import_shared8.FloPayError("Automatic payment failed. Please try again.", "api_error", {
3081
3822
  code: completed.data.session?.status === "expired" ? "checkout_session_expired" : "checkout_processing_timeout"
3082
3823
  });
3083
3824
  }
@@ -3161,7 +3902,7 @@ function FloPayCheckout({
3161
3902
  resolvedBillingUrl
3162
3903
  ]
3163
3904
  );
3164
- (0, import_react8.useEffect)(() => {
3905
+ (0, import_react9.useEffect)(() => {
3165
3906
  if (typeof window === "undefined" || paypalResumeAttempted.current) {
3166
3907
  return;
3167
3908
  }
@@ -3183,7 +3924,7 @@ function FloPayCheckout({
3183
3924
  try {
3184
3925
  if (params.get("redirect_status") === "failed") {
3185
3926
  throw Object.assign(
3186
- new import_shared7.FloPayError("PayPal payment was declined. Please try again.", "api_error"),
3927
+ new import_shared8.FloPayError("PayPal payment was declined. Please try again.", "api_error"),
3187
3928
  { checkoutMethod: "paypal" }
3188
3929
  );
3189
3930
  }
@@ -3199,14 +3940,14 @@ function FloPayCheckout({
3199
3940
  const paypalStripe = (resumePaypalFlopay ?? resumeFlopay).getRawProvider();
3200
3941
  if (!paypalStripe) {
3201
3942
  throw Object.assign(
3202
- new import_shared7.FloPayError("PayPal is not available.", "api_error"),
3943
+ new import_shared8.FloPayError("PayPal is not available.", "api_error"),
3203
3944
  { checkoutMethod: "paypal" }
3204
3945
  );
3205
3946
  }
3206
3947
  const { paymentIntent, error } = await paypalStripe.retrievePaymentIntent(clientSecret);
3207
3948
  if (error) {
3208
3949
  throw Object.assign(
3209
- new import_shared7.FloPayError(
3950
+ new import_shared8.FloPayError(
3210
3951
  error.message ?? "Failed to retrieve PayPal payment status.",
3211
3952
  "api_error",
3212
3953
  { code: error.code }
@@ -3217,14 +3958,14 @@ function FloPayCheckout({
3217
3958
  const resultStatus = mapPayPalIntentStatusToPaymentResult(paymentIntent?.status);
3218
3959
  if (!paymentIntent || resultStatus === "failed") {
3219
3960
  throw Object.assign(
3220
- new import_shared7.FloPayError("PayPal payment was not completed. Please try again.", "api_error"),
3961
+ new import_shared8.FloPayError("PayPal payment was not completed. Please try again.", "api_error"),
3221
3962
  { checkoutMethod: "paypal" }
3222
3963
  );
3223
3964
  }
3224
3965
  const paymentMethodId = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
3225
3966
  let finalResultStatus = resultStatus;
3226
3967
  if (resumeState.sessionId) {
3227
- const resumeApi = new import_js3.PaymentAPI(resolvedBillingUrl);
3968
+ const resumeApi = new import_js4.PaymentAPI(resolvedBillingUrl);
3228
3969
  const resumeSessionResult = await resumeApi.getUnifiedCheckoutSession(resumeState.sessionId);
3229
3970
  const resumeSession = resumeSessionResult.data.session;
3230
3971
  if (resumeSession && resumeSession.status !== "complete") {
@@ -3241,7 +3982,7 @@ function FloPayCheckout({
3241
3982
  });
3242
3983
  if (processResult.type !== "success") {
3243
3984
  throw Object.assign(
3244
- new import_shared7.FloPayError("Failed to finalize PayPal payment.", "api_error"),
3985
+ new import_shared8.FloPayError("Failed to finalize PayPal payment.", "api_error"),
3245
3986
  { checkoutMethod: "paypal" }
3246
3987
  );
3247
3988
  }
@@ -3278,7 +4019,7 @@ function FloPayCheckout({
3278
4019
  }
3279
4020
  })();
3280
4021
  }, [emitDecline, locale, normalizeSavedPaymentError, resolvedBillingUrl]);
3281
- const initializedHashRef = (0, import_react8.useRef)(null);
4022
+ const initializedHashRef = (0, import_react9.useRef)(null);
3282
4023
  function hashCreateParams(params) {
3283
4024
  const key = JSON.stringify({
3284
4025
  c: params?.clientId,
@@ -3303,23 +4044,23 @@ function FloPayCheckout({
3303
4044
  }
3304
4045
  return `flopay_session_${Math.abs(h).toString(36)}`;
3305
4046
  }
3306
- const createSessionHash = (0, import_react8.useMemo)(
4047
+ const createSessionHash = (0, import_react9.useMemo)(
3307
4048
  () => effectiveCreateSession ? hashCreateParams(effectiveCreateSession) : "",
3308
4049
  [effectiveCreateSession]
3309
4050
  );
3310
- const createSessionParamsRef = (0, import_react8.useRef)(effectiveCreateSession);
4051
+ const createSessionParamsRef = (0, import_react9.useRef)(effectiveCreateSession);
3311
4052
  createSessionParamsRef.current = effectiveCreateSession;
3312
- (0, import_react8.useEffect)(() => {
4053
+ (0, import_react9.useEffect)(() => {
3313
4054
  setResolvedSessionId(sessionIdProp ?? "");
3314
4055
  }, [sessionIdProp]);
3315
- (0, import_react8.useEffect)(() => {
4056
+ (0, import_react9.useEffect)(() => {
3316
4057
  autoCheckoutAttempted.current = false;
3317
4058
  setModeError(initialErrorMessage);
3318
4059
  setModeOverlayError(null);
3319
4060
  setModeOverlayStatus(null);
3320
4061
  }, [createSessionHash, initialErrorMessage, sessionIdProp]);
3321
4062
  async function resolveInlineSession(params, cacheKey) {
3322
- const api = new import_js3.PaymentAPI(resolvedBillingUrl);
4063
+ const api = new import_js4.PaymentAPI(resolvedBillingUrl);
3323
4064
  let sid = typeof window !== "undefined" ? window.sessionStorage.getItem(cacheKey) : null;
3324
4065
  let realResult = null;
3325
4066
  if (sid) {
@@ -3355,11 +4096,11 @@ function FloPayCheckout({
3355
4096
  }
3356
4097
  return { sid: sid ?? "", result: realResult };
3357
4098
  }
3358
- const bootstrapInlineSession = (0, import_react8.useCallback)(
4099
+ const bootstrapInlineSession = (0, import_react9.useCallback)(
3359
4100
  async (patch) => {
3360
4101
  const baseParams = createSessionParamsRef.current;
3361
4102
  if (!baseParams) {
3362
- throw new import_shared7.FloPayError("createSession is required to bootstrap checkout.", "validation_error");
4103
+ throw new import_shared8.FloPayError("createSession is required to bootstrap checkout.", "validation_error");
3363
4104
  }
3364
4105
  const mergedParams = mergeInlineSessionPatch(baseParams, patch);
3365
4106
  const cacheKey = hashCreateParams(mergedParams);
@@ -3416,7 +4157,7 @@ function FloPayCheckout({
3416
4157
  },
3417
4158
  [locale, resolvedBillingUrl]
3418
4159
  );
3419
- const handleInlineSessionPatch = (0, import_react8.useCallback)(async (patch) => {
4160
+ const handleInlineSessionPatch = (0, import_react9.useCallback)(async (patch) => {
3420
4161
  if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) {
3421
4162
  return {
3422
4163
  sessionId: resolvedSessionId,
@@ -3439,7 +4180,7 @@ function FloPayCheckout({
3439
4180
  resolvedSessionId,
3440
4181
  session
3441
4182
  ]);
3442
- (0, import_react8.useEffect)(() => {
4183
+ (0, import_react9.useEffect)(() => {
3443
4184
  let cancelled = false;
3444
4185
  setLoadError(null);
3445
4186
  if (createSessionHash) {
@@ -3483,7 +4224,7 @@ function FloPayCheckout({
3483
4224
  }
3484
4225
  } catch (err) {
3485
4226
  if (cancelled) return;
3486
- const errorCode = err instanceof import_shared7.FloPayError ? err.code : typeof err === "object" && err !== null && "code" in err ? err.code : void 0;
4227
+ const errorCode = err instanceof import_shared8.FloPayError ? err.code : typeof err === "object" && err !== null && "code" in err ? err.code : void 0;
3487
4228
  if (shouldAutoProcessInlineSession && errorCode === "session_auto_completed") {
3488
4229
  autoCheckoutAttempted.current = true;
3489
4230
  setModeOverlayStatus("success");
@@ -3499,7 +4240,7 @@ function FloPayCheckout({
3499
4240
  setModeOverlayStatus(null);
3500
4241
  setModeOverlayError(null);
3501
4242
  }
3502
- const floPayErr = err instanceof import_shared7.FloPayError ? err : new import_shared7.FloPayError(err instanceof Error ? err.message : "Failed to create session", "api_error");
4243
+ const floPayErr = err instanceof import_shared8.FloPayError ? err : new import_shared8.FloPayError(err instanceof Error ? err.message : "Failed to create session", "api_error");
3503
4244
  setLoadError(floPayErr);
3504
4245
  }
3505
4246
  })();
@@ -3510,14 +4251,14 @@ function FloPayCheckout({
3510
4251
  setIsLoading(true);
3511
4252
  async function init() {
3512
4253
  try {
3513
- const api = new import_js3.PaymentAPI(resolvedBillingUrl);
4254
+ const api = new import_js4.PaymentAPI(resolvedBillingUrl);
3514
4255
  const result = await api.getUnifiedCheckoutSession(activeSessionId);
3515
4256
  if (cancelled) return;
3516
4257
  setUnified(result);
3517
4258
  const sess = result.data.session ?? null;
3518
4259
  setSession(sess);
3519
4260
  if (!sess) {
3520
- throw new import_shared7.FloPayError("No session data returned", "api_error");
4261
+ throw new import_shared8.FloPayError("No session data returned", "api_error");
3521
4262
  }
3522
4263
  if (sess.status === "complete") {
3523
4264
  setIsLoading(false);
@@ -3525,7 +4266,7 @@ function FloPayCheckout({
3525
4266
  return;
3526
4267
  }
3527
4268
  if (sess.status === "expired") {
3528
- throw new import_shared7.FloPayError("Checkout session has expired.", "api_error", {
4269
+ throw new import_shared8.FloPayError("Checkout session has expired.", "api_error", {
3529
4270
  code: "checkout_session_expired"
3530
4271
  });
3531
4272
  }
@@ -3559,7 +4300,7 @@ function FloPayCheckout({
3559
4300
  if (!cancelled) setIsLoading(false);
3560
4301
  } catch (err) {
3561
4302
  if (cancelled) return;
3562
- const floPayErr = err instanceof import_shared7.FloPayError ? err : new import_shared7.FloPayError(err instanceof Error ? err.message : "Failed to initialize checkout", "api_error");
4303
+ const floPayErr = err instanceof import_shared8.FloPayError ? err : new import_shared8.FloPayError(err instanceof Error ? err.message : "Failed to initialize checkout", "api_error");
3563
4304
  setLoadError(floPayErr);
3564
4305
  setIsLoading(false);
3565
4306
  }
@@ -3599,7 +4340,7 @@ function FloPayCheckout({
3599
4340
  initSessionDependency,
3600
4341
  runSavedPaymentFlow
3601
4342
  ]);
3602
- const handleConfirmCheckout = (0, import_react8.useCallback)(async () => {
4343
+ const handleConfirmCheckout = (0, import_react9.useCallback)(async () => {
3603
4344
  if (confirmProcessing || !session) return;
3604
4345
  setConfirmProcessing(true);
3605
4346
  setModeError(null);
@@ -3612,17 +4353,17 @@ function FloPayCheckout({
3612
4353
  setConfirmProcessing(false);
3613
4354
  }
3614
4355
  }, [activeSessionId, confirmProcessing, runSavedPaymentFlow, session]);
3615
- const providerOptions = (0, import_react8.useMemo)(() => {
4356
+ const providerOptions = (0, import_react9.useMemo)(() => {
3616
4357
  if (!unified || !session) return void 0;
3617
4358
  const opts = {
3618
4359
  appearance,
3619
4360
  paymentMethodCreation: "manual",
3620
4361
  billingApiUrl: resolvedBillingUrl
3621
4362
  };
3622
- if (unified.provider === "stripe" && unified.data.stripe?.clientSecret) {
4363
+ if (unified.data.stripe?.clientSecret) {
3623
4364
  opts.clientSecret = unified.data.stripe.clientSecret;
3624
4365
  } else {
3625
- const displayTotal = (0, import_shared7.buildCheckoutDisplayData)(session).total;
4366
+ const displayTotal = (0, import_shared8.buildCheckoutDisplayData)(session).total;
3626
4367
  opts.amount = Math.round(displayTotal * 100) || session.amount;
3627
4368
  opts.currency = session.currency?.toLowerCase();
3628
4369
  }
@@ -3631,7 +4372,7 @@ function FloPayCheckout({
3631
4372
  const shouldHandleInlineSessionPatch = Boolean(
3632
4373
  createSessionParams && !children && layout === "buttons" && onBeforeButtonClick && effectiveCreateSessionMode === "full"
3633
4374
  );
3634
- const checkoutValue = (0, import_react8.useMemo)(
4375
+ const checkoutValue = (0, import_react9.useMemo)(
3635
4376
  () => ({
3636
4377
  session,
3637
4378
  loading: isLoading,
@@ -3653,7 +4394,7 @@ function FloPayCheckout({
3653
4394
  ]
3654
4395
  );
3655
4396
  const shouldShowInterimButtons = Boolean(createSessionParams) && layout === "buttons" && (!flopay || !providerOptions);
3656
- const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4397
+ const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3657
4398
  ProcessingOverlay,
3658
4399
  {
3659
4400
  status: modeOverlayStatus,
@@ -3662,31 +4403,31 @@ function FloPayCheckout({
3662
4403
  ) : null;
3663
4404
  if (isLoading) {
3664
4405
  if (loadingNode) {
3665
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
4406
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
3666
4407
  loadingNode,
3667
4408
  modeOverlay
3668
4409
  ] });
3669
4410
  }
3670
4411
  if (layout === "buttons") {
3671
- const skeletonBar = (h) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4412
+ const skeletonBar = (h) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3672
4413
  height: h,
3673
4414
  borderRadius: 8,
3674
4415
  background: "#e5e7eb",
3675
4416
  animation: "flopay-loading-pulse 1.5s ease-in-out infinite"
3676
4417
  } });
3677
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3678
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
4418
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
4419
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
3679
4420
  showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
3680
4421
  (showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
3681
4422
  skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
3682
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
4423
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
3683
4424
  ] }),
3684
4425
  modeOverlay
3685
4426
  ] });
3686
4427
  }
3687
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3688
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", justifyContent: "center", padding: 32 }, children: [
3689
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4428
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
4429
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", justifyContent: "center", padding: 32 }, children: [
4430
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3690
4431
  width: 24,
3691
4432
  height: 24,
3692
4433
  border: "2px solid #e5e7eb",
@@ -3694,16 +4435,16 @@ function FloPayCheckout({
3694
4435
  borderRadius: "50%",
3695
4436
  animation: "spin 0.6s linear infinite"
3696
4437
  } }),
3697
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
4438
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
3698
4439
  ] }),
3699
4440
  modeOverlay
3700
4441
  ] });
3701
4442
  }
3702
4443
  if (loadError) {
3703
4444
  if (errorNode) {
3704
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: errorNode(loadError) });
4445
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: errorNode(loadError) });
3705
4446
  }
3706
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4447
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3707
4448
  "div",
3708
4449
  {
3709
4450
  style: {
@@ -3717,8 +4458,8 @@ function FloPayCheckout({
3717
4458
  ) });
3718
4459
  }
3719
4460
  if (shouldShowInterimButtons) {
3720
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3721
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4461
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
4462
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3722
4463
  InterimButtonsView,
3723
4464
  {
3724
4465
  onButtonClick,
@@ -3736,12 +4477,12 @@ function FloPayCheckout({
3736
4477
  ] });
3737
4478
  }
3738
4479
  if (!flopay || !providerOptions) {
3739
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: modeOverlay });
4480
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: modeOverlay });
3740
4481
  }
3741
4482
  if (currentMode === "confirm") {
3742
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3743
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className, children: [
3744
- modeError && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4483
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
4484
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className, children: [
4485
+ modeError && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3745
4486
  "div",
3746
4487
  {
3747
4488
  style: {
@@ -3756,7 +4497,7 @@ function FloPayCheckout({
3756
4497
  renderConfirmButton ? renderConfirmButton({
3757
4498
  onConfirm: handleConfirmCheckout,
3758
4499
  isProcessing: confirmProcessing
3759
- }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4500
+ }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3760
4501
  "button",
3761
4502
  {
3762
4503
  type: "button",
@@ -3781,9 +4522,9 @@ function FloPayCheckout({
3781
4522
  modeOverlay
3782
4523
  ] });
3783
4524
  }
3784
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3785
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: children ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3786
- modeError && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4525
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
4526
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: children ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
4527
+ modeError && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3787
4528
  "div",
3788
4529
  {
3789
4530
  style: {
@@ -3798,7 +4539,7 @@ function FloPayCheckout({
3798
4539
  children: modeError
3799
4540
  }
3800
4541
  ),
3801
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4542
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3802
4543
  SessionInjector,
3803
4544
  {
3804
4545
  sessionId: activeSessionId,
@@ -3807,7 +4548,7 @@ function FloPayCheckout({
3807
4548
  children
3808
4549
  }
3809
4550
  )
3810
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4551
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3811
4552
  SplitCardForm,
3812
4553
  {
3813
4554
  sessionId: activeSessionId,
@@ -3815,7 +4556,7 @@ function FloPayCheckout({
3815
4556
  userId: session?.customer?.id,
3816
4557
  firstName: session?.customer?.firstName,
3817
4558
  lastName: session?.customer?.lastName,
3818
- totalAmount: session ? Math.round((0, import_shared7.buildCheckoutDisplayData)(session).total * 100) : 0,
4559
+ totalAmount: session ? Math.round((0, import_shared8.buildCheckoutDisplayData)(session).total * 100) : 0,
3819
4560
  currency: session?.currency?.toLowerCase() ?? "usd",
3820
4561
  onComplete,
3821
4562
  onError,
@@ -3846,7 +4587,11 @@ function FloPayCheckout({
3846
4587
  checkoutType: createSessionParams ? "embedded_checkout" : "standard_checkout",
3847
4588
  checkoutLayout: children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout",
3848
4589
  submitLabel,
3849
- className
4590
+ className,
4591
+ directPaypal: resolveDirectPaypalConfig(unified),
4592
+ isSubscription: session?.mode === "subscription",
4593
+ session,
4594
+ debug
3850
4595
  }
3851
4596
  ) }) }),
3852
4597
  modeOverlay
@@ -3858,8 +4603,8 @@ function SessionInjector({
3858
4603
  session,
3859
4604
  children
3860
4605
  }) {
3861
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: import_react8.default.Children.map(children, (child) => {
3862
- if (!import_react8.default.isValidElement(child)) return child;
4606
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: import_react9.default.Children.map(children, (child) => {
4607
+ if (!import_react9.default.isValidElement(child)) return child;
3863
4608
  const existing = child.props;
3864
4609
  const injected = {};
3865
4610
  if (!existing.sessionId) injected.sessionId = sessionId;
@@ -3873,7 +4618,7 @@ function SessionInjector({
3873
4618
  injected.lastName = session.customer.lastName;
3874
4619
  }
3875
4620
  if (Object.keys(injected).length === 0) return child;
3876
- return import_react8.default.cloneElement(child, injected);
4621
+ return import_react9.default.cloneElement(child, injected);
3877
4622
  }) });
3878
4623
  }
3879
4624
  function InterimButtonsView({
@@ -3891,15 +4636,15 @@ function InterimButtonsView({
3891
4636
  cardBackButtonContent,
3892
4637
  cardTitleContent
3893
4638
  }) {
3894
- const [showCardForm, setShowCardForm] = (0, import_react8.useState)(false);
4639
+ const [showCardForm, setShowCardForm] = (0, import_react9.useState)(false);
3895
4640
  const isCardOpenControlled = typeof cardOpen === "boolean";
3896
- (0, import_react8.useEffect)(() => {
4641
+ (0, import_react9.useEffect)(() => {
3897
4642
  if (isCardOpenControlled) {
3898
4643
  setShowCardForm(cardOpen);
3899
4644
  }
3900
4645
  }, [cardOpen, isCardOpenControlled]);
3901
- const bStyles = (0, import_react8.useMemo)(() => {
3902
- const base = (0, import_shared7.resolveButtonsLayoutTheme)(buttonsTheme);
4646
+ const bStyles = (0, import_react9.useMemo)(() => {
4647
+ const base = (0, import_shared8.resolveButtonsLayoutTheme)(buttonsTheme);
3903
4648
  if (!stylesOverride) return base;
3904
4649
  return {
3905
4650
  ...base,
@@ -3912,7 +4657,7 @@ function InterimButtonsView({
3912
4657
  title: { ...base.title, ...stylesOverride.title }
3913
4658
  };
3914
4659
  }, [buttonsTheme, stylesOverride]);
3915
- const skeleton = (h) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4660
+ const skeleton = (h) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3916
4661
  height: h,
3917
4662
  borderRadius: 8,
3918
4663
  background: "#e5e7eb",
@@ -3924,15 +4669,15 @@ function InterimButtonsView({
3924
4669
  const inputBg = bStyles.cardInputBackground ?? "white";
3925
4670
  const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);
3926
4671
  const hideTitle = isEmptySlotContent(cardTitleContent);
3927
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
4672
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
3928
4673
  backgroundColor: bStyles.cardFormContainer?.backgroundColor ?? "white",
3929
4674
  borderRadius: "8px",
3930
4675
  animation: "flopay-interim-expand 0.35s cubic-bezier(0.4, 0, 0.2, 1) both",
3931
4676
  overflow: "hidden",
3932
4677
  ...bStyles.cardFormContainer
3933
4678
  }, children: [
3934
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", alignItems: "center", padding: "0.75rem 0 0.625rem" }, children: [
3935
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4679
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", padding: "0.75rem 0 0.625rem" }, children: [
4680
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3936
4681
  "button",
3937
4682
  {
3938
4683
  type: "button",
@@ -3959,7 +4704,7 @@ function InterimButtonsView({
3959
4704
  ...bStyles.backButton
3960
4705
  },
3961
4706
  children: [
3962
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: {
4707
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
3963
4708
  display: "inline-flex",
3964
4709
  alignItems: "center",
3965
4710
  justifyContent: "center",
@@ -3968,12 +4713,12 @@ function InterimButtonsView({
3968
4713
  borderRadius: "50%",
3969
4714
  backgroundColor: "#f3f4f6",
3970
4715
  ...bStyles.backButtonIcon
3971
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
3972
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
4716
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
4717
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
3973
4718
  ]
3974
4719
  }
3975
4720
  ),
3976
- hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4721
+ hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3977
4722
  flex: 1,
3978
4723
  textAlign: "center",
3979
4724
  fontWeight: 600,
@@ -3981,15 +4726,15 @@ function InterimButtonsView({
3981
4726
  color: "#262833",
3982
4727
  paddingRight: 80,
3983
4728
  ...bStyles.title
3984
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TitleContentSlot, { content: cardTitleContent }) })
4729
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TitleContentSlot, { content: cardTitleContent }) })
3985
4730
  ] }),
3986
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { width: "60%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
3987
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex" }, children: [
3988
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1, backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTop: "none", borderRight: "none", borderBottomLeftRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { width: "50%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
3989
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1, backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTop: "none", borderBottomRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { width: "40%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) })
4731
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { width: "60%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
4732
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex" }, children: [
4733
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1, backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTop: "none", borderRight: "none", borderBottomLeftRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { width: "50%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
4734
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1, backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTop: "none", borderBottomRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { width: "40%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) })
3990
4735
  ] }),
3991
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { width: "45%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
3992
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4736
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { width: "45%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
4737
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3993
4738
  height: 50,
3994
4739
  borderRadius: 8,
3995
4740
  marginTop: 16,
@@ -3998,7 +4743,7 @@ function InterimButtonsView({
3998
4743
  ...bStyles.submitButton,
3999
4744
  opacity: 0.5
4000
4745
  } }),
4001
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `
4746
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
4002
4747
  @keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
4003
4748
  @keyframes flopay-interim-expand {
4004
4749
  0% { opacity: 0; max-height: 0; transform: translateY(-12px); }
@@ -4008,10 +4753,10 @@ function InterimButtonsView({
4008
4753
  ` })
4009
4754
  ] });
4010
4755
  }
4011
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
4756
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
4012
4757
  showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
4013
4758
  (showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
4014
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4759
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4015
4760
  "button",
4016
4761
  {
4017
4762
  type: "button",
@@ -4051,10 +4796,10 @@ function InterimButtonsView({
4051
4796
  onMouseUp: (e) => {
4052
4797
  e.currentTarget.style.transform = "scale(1)";
4053
4798
  },
4054
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardButtonContentSlot, { content: cardButtonContent })
4799
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardButtonContentSlot, { content: cardButtonContent })
4055
4800
  }
4056
4801
  ),
4057
- errorMessage && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
4802
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
4058
4803
  margin: "0.25rem 0",
4059
4804
  padding: "0.625rem 0.875rem",
4060
4805
  background: "#FEF2F2",
@@ -4068,22 +4813,22 @@ function InterimButtonsView({
4068
4813
  gap: "0.5rem",
4069
4814
  ...bStyles.errorBanner
4070
4815
  }, children: [
4071
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
4816
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
4072
4817
  errorMessage
4073
4818
  ] }),
4074
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
4819
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
4075
4820
  ] });
4076
4821
  }
4077
4822
 
4078
4823
  // src/checkout-form.tsx
4079
- var import_js4 = require("@flopay/js");
4080
- var import_shared8 = require("@flopay/shared");
4081
- var import_react9 = require("react");
4082
- var import_jsx_runtime7 = require("react/jsx-runtime");
4824
+ var import_js5 = require("@flopay/js");
4825
+ var import_shared9 = require("@flopay/shared");
4826
+ var import_react10 = require("react");
4827
+ var import_jsx_runtime8 = require("react/jsx-runtime");
4083
4828
  var WALLET_RESUME_KEY2 = "flopay_wallet_resume";
4084
- var CheckoutForm = (0, import_react9.forwardRef)(
4829
+ var CheckoutForm = (0, import_react10.forwardRef)(
4085
4830
  function CheckoutForm2(props, ref) {
4086
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutFormInner, { ...props, innerRef: ref });
4831
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutFormInner, { ...props, innerRef: ref });
4087
4832
  }
4088
4833
  );
4089
4834
  function CheckoutFormInner({
@@ -4112,34 +4857,34 @@ function CheckoutFormInner({
4112
4857
  const paypalFlopay = usePayPalFloPay();
4113
4858
  const elements = useElements();
4114
4859
  const contextBillingUrl = useBillingApiUrl();
4115
- const [processing, setProcessing] = (0, import_react9.useState)(false);
4116
- const [error, setError] = (0, import_react9.useState)(null);
4117
- const [is3DSActive, setIs3DSActive] = (0, import_react9.useState)(false);
4860
+ const [processing, setProcessing] = (0, import_react10.useState)(false);
4861
+ const [error, setError] = (0, import_react10.useState)(null);
4862
+ const [is3DSActive, setIs3DSActive] = (0, import_react10.useState)(false);
4118
4863
  const displayError = externalError ?? error;
4119
4864
  const isSubmitting = externalProcessing ?? processing;
4120
4865
  const isSelfContained = !onTokenizedBody;
4121
4866
  const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
4122
- const updateError = (0, import_react9.useCallback)(
4867
+ const updateError = (0, import_react10.useCallback)(
4123
4868
  (err) => {
4124
4869
  setError(err);
4125
4870
  onErrorChange?.(err);
4126
4871
  },
4127
4872
  [onErrorChange]
4128
4873
  );
4129
- const emitDecline = (0, import_react9.useCallback)(
4874
+ const emitDecline = (0, import_react10.useCallback)(
4130
4875
  (input, overrides) => {
4131
4876
  onDecline?.(buildDeclineEvent("card", input, overrides));
4132
4877
  },
4133
4878
  [onDecline]
4134
4879
  );
4135
- const processPaymentInternal = (0, import_react9.useCallback)(
4880
+ const processPaymentInternal = (0, import_react10.useCallback)(
4136
4881
  async (tokenizedBody, completionPaymentMethodId) => {
4137
4882
  setProcessing(true);
4138
4883
  updateError(null);
4139
4884
  const resolvedCompletionPaymentMethodId = completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);
4140
4885
  const requestTokenizedBody = tokenizedBody.originalPaymentMethodId ? { ...tokenizedBody, originalPaymentMethodId: void 0 } : tokenizedBody;
4141
4886
  try {
4142
- const api = new import_js4.PaymentAPI(baseUrl);
4887
+ const api = new import_js5.PaymentAPI(baseUrl);
4143
4888
  const response = await api.processPayment(userId ?? "", {
4144
4889
  sessionId,
4145
4890
  tokenizedData: requestTokenizedBody,
@@ -4243,7 +4988,7 @@ function CheckoutFormInner({
4243
4988
  },
4244
4989
  [baseUrl, sessionId, userId, email, firstName, lastName, chv, flopay, paypalFlopay, onComplete, onError, onDecline, updateError, emitDecline]
4245
4990
  );
4246
- const dispatchTokenizedBody = (0, import_react9.useCallback)(
4991
+ const dispatchTokenizedBody = (0, import_react10.useCallback)(
4247
4992
  (tokenizedBody) => {
4248
4993
  if (onTokenizedBody) {
4249
4994
  onTokenizedBody(tokenizedBody);
@@ -4253,7 +4998,7 @@ function CheckoutFormInner({
4253
4998
  },
4254
4999
  [onTokenizedBody, processPaymentInternal]
4255
5000
  );
4256
- (0, import_react9.useImperativeHandle)(innerRef, () => ({
5001
+ (0, import_react10.useImperativeHandle)(innerRef, () => ({
4257
5002
  async handleNextAction(secret) {
4258
5003
  if (!flopay) return;
4259
5004
  setIs3DSActive(true);
@@ -4280,7 +5025,7 @@ function CheckoutFormInner({
4280
5025
  }
4281
5026
  }
4282
5027
  }), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
4283
- (0, import_react9.useEffect)(() => {
5028
+ (0, import_react10.useEffect)(() => {
4284
5029
  if (typeof window === "undefined") return;
4285
5030
  const stored = localStorage.getItem(WALLET_RESUME_KEY2);
4286
5031
  if (!stored) return;
@@ -4298,7 +5043,7 @@ function CheckoutFormInner({
4298
5043
  localStorage.removeItem(WALLET_RESUME_KEY2);
4299
5044
  }
4300
5045
  }, [sessionId, dispatchTokenizedBody]);
4301
- const handleSubmit = (0, import_react9.useCallback)(
5046
+ const handleSubmit = (0, import_react10.useCallback)(
4302
5047
  async (e) => {
4303
5048
  e.preventDefault();
4304
5049
  if (!flopay || !elements || isSubmitting) return;
@@ -4322,7 +5067,7 @@ function CheckoutFormInner({
4322
5067
  return;
4323
5068
  }
4324
5069
  if (!sessionId || !email) {
4325
- throw new import_shared8.FloPayError("Missing sessionId or email", "validation_error");
5070
+ throw new import_shared9.FloPayError("Missing sessionId or email", "validation_error");
4326
5071
  }
4327
5072
  const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
4328
5073
  method: "POST",
@@ -4346,7 +5091,7 @@ function CheckoutFormInner({
4346
5091
  }
4347
5092
  const intentJson = await intentResponse.json();
4348
5093
  const intentClientSecret = intentJson.data?.id;
4349
- if (!intentClientSecret) throw new import_shared8.FloPayError("No client_secret in payment intent response", "api_error");
5094
+ if (!intentClientSecret) throw new import_shared9.FloPayError("No client_secret in payment intent response", "api_error");
4350
5095
  const confirmResult = await flopay.confirmCardPayment({
4351
5096
  clientSecret: intentClientSecret,
4352
5097
  paymentMethodId: pmResult.paymentMethodId
@@ -4365,7 +5110,7 @@ function CheckoutFormInner({
4365
5110
  const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
4366
5111
  const paymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? pmResult.paymentMethodId;
4367
5112
  if (!paymentIntentId) {
4368
- const error2 = new import_shared8.FloPayError("No payment intent returned after confirmation.", "api_error");
5113
+ const error2 = new import_shared9.FloPayError("No payment intent returned after confirmation.", "api_error");
4369
5114
  updateError(error2.message);
4370
5115
  onError?.(error2);
4371
5116
  return;
@@ -4388,8 +5133,8 @@ function CheckoutFormInner({
4388
5133
  [flopay, elements, isSubmitting, sessionId, email, baseUrl, isSelfContained, dispatchTokenizedBody, onError, updateError, emitDecline]
4389
5134
  );
4390
5135
  const isReady = flopay !== null && elements !== null;
4391
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
4392
- (is3DSActive || isSubmitting) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { "data-testid": "flopay-overlay", style: {
5136
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
5137
+ (is3DSActive || isSubmitting) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { "data-testid": "flopay-overlay", style: {
4393
5138
  position: "absolute",
4394
5139
  inset: 0,
4395
5140
  background: "rgba(255,255,255,0.7)",
@@ -4398,12 +5143,12 @@ function CheckoutFormInner({
4398
5143
  justifyContent: "center",
4399
5144
  zIndex: 10
4400
5145
  }, children: is3DSActive ? "Verifying payment..." : "Processing..." }),
4401
- !isReady && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." }),
4402
- isReady && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
4403
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PaymentElement, { options: { layout } }),
4404
- showAddress && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AddressElement, { options: { mode: showAddress === true ? "billing" : showAddress } }),
4405
- displayError && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0" }, children: displayError }),
4406
- children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5146
+ !isReady && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." }),
5147
+ isReady && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
5148
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaymentElement, { options: { layout } }),
5149
+ showAddress && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AddressElement, { options: { mode: showAddress === true ? "billing" : showAddress } }),
5150
+ displayError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0" }, children: displayError }),
5151
+ children ?? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
4407
5152
  "button",
4408
5153
  {
4409
5154
  type: "submit",
@@ -4417,10 +5162,10 @@ function CheckoutFormInner({
4417
5162
  }
4418
5163
 
4419
5164
  // src/paypal-button.tsx
4420
- var import_js5 = require("@flopay/js");
4421
- var import_shared9 = require("@flopay/shared");
4422
- var import_react10 = require("react");
4423
- var import_jsx_runtime8 = require("react/jsx-runtime");
5165
+ var import_js6 = require("@flopay/js");
5166
+ var import_shared10 = require("@flopay/shared");
5167
+ var import_react11 = require("react");
5168
+ var import_jsx_runtime9 = require("react/jsx-runtime");
4424
5169
  function PayPalButton({
4425
5170
  sessionId,
4426
5171
  billingApiUrl,
@@ -4437,14 +5182,14 @@ function PayPalButton({
4437
5182
  const flopay = useFloPay();
4438
5183
  const elements = useElements();
4439
5184
  const contextBillingUrl = useBillingApiUrl();
4440
- const [ready, setReady] = (0, import_react10.useState)(false);
4441
- const [submitting, setSubmitting] = (0, import_react10.useState)(false);
4442
- const paypalResumeAttempted = (0, import_react10.useRef)(false);
5185
+ const [ready, setReady] = (0, import_react11.useState)(false);
5186
+ const [submitting, setSubmitting] = (0, import_react11.useState)(false);
5187
+ const paypalResumeAttempted = (0, import_react11.useRef)(false);
4443
5188
  const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
4444
- const processPaymentInternal = (0, import_react10.useCallback)(
5189
+ const processPaymentInternal = (0, import_react11.useCallback)(
4445
5190
  async (tokenizedBody) => {
4446
5191
  try {
4447
- const api = new import_js5.PaymentAPI(baseUrl);
5192
+ const api = new import_js6.PaymentAPI(baseUrl);
4448
5193
  const response = await api.processPayment(userId ?? "", {
4449
5194
  sessionId,
4450
5195
  tokenizedData: tokenizedBody,
@@ -4468,7 +5213,7 @@ function PayPalButton({
4468
5213
  },
4469
5214
  [baseUrl, sessionId, userId, email, firstName, lastName, chv, onComplete, onErrorChange]
4470
5215
  );
4471
- const dispatchTokenizedBody = (0, import_react10.useCallback)(
5216
+ const dispatchTokenizedBody = (0, import_react11.useCallback)(
4472
5217
  (body) => {
4473
5218
  if (onTokenizedBody) {
4474
5219
  onTokenizedBody(body);
@@ -4478,7 +5223,7 @@ function PayPalButton({
4478
5223
  },
4479
5224
  [onTokenizedBody, processPaymentInternal]
4480
5225
  );
4481
- (0, import_react10.useEffect)(() => {
5226
+ (0, import_react11.useEffect)(() => {
4482
5227
  if (!flopay || paypalResumeAttempted.current) return;
4483
5228
  const params = new URLSearchParams(window.location.search);
4484
5229
  const paymentIntentId = params.get("payment_intent");
@@ -4526,13 +5271,13 @@ function PayPalButton({
4526
5271
  }
4527
5272
  })();
4528
5273
  }, [flopay, dispatchTokenizedBody, onErrorChange]);
4529
- const handlePayPalConfirm = (0, import_react10.useCallback)(async () => {
5274
+ const handlePayPalConfirm = (0, import_react11.useCallback)(async () => {
4530
5275
  if (!flopay || !elements) return;
4531
5276
  try {
4532
5277
  setSubmitting(true);
4533
5278
  onErrorChange?.(null);
4534
5279
  if (!sessionId || !email) {
4535
- throw new import_shared9.FloPayError("Missing sessionId or email for PayPal payment", "validation_error");
5280
+ throw new import_shared10.FloPayError("Missing sessionId or email for PayPal payment", "validation_error");
4536
5281
  }
4537
5282
  const result = await flopay.confirmPayPalPayment({
4538
5283
  billingApiUrl: baseUrl,
@@ -4559,11 +5304,11 @@ function PayPalButton({
4559
5304
  }
4560
5305
  }, [flopay, elements, sessionId, email, baseUrl, dispatchTokenizedBody, onErrorChange]);
4561
5306
  if (!flopay || !elements) {
4562
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6, animation: "pulse 1.5s infinite" } });
5307
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6, animation: "pulse 1.5s infinite" } });
4563
5308
  }
4564
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
4565
- !ready && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6 } }),
4566
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: ready ? {} : { display: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5309
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
5310
+ !ready && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6 } }),
5311
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: ready ? {} : { display: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4567
5312
  "button",
4568
5313
  {
4569
5314
  type: "button",
@@ -4585,7 +5330,7 @@ function PayPalButton({
4585
5330
  children: submitting ? "Processing..." : "PayPal"
4586
5331
  }
4587
5332
  ) }),
4588
- (submitting || isProcessing) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
5333
+ (submitting || isProcessing) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: {
4589
5334
  position: "fixed",
4590
5335
  inset: 0,
4591
5336
  background: "rgba(0,0,0,0.4)",
@@ -4593,7 +5338,7 @@ function PayPalButton({
4593
5338
  alignItems: "center",
4594
5339
  justifyContent: "center",
4595
5340
  zIndex: 1e3
4596
- }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
5341
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: {
4597
5342
  background: "white",
4598
5343
  borderRadius: 8,
4599
5344
  padding: "1.5rem",
@@ -4605,20 +5350,20 @@ function PayPalButton({
4605
5350
  }
4606
5351
 
4607
5352
  // src/automatic-payment-button.tsx
4608
- var import_react11 = require("react");
4609
- var import_js6 = require("@flopay/js");
4610
- var import_shared10 = require("@flopay/shared");
4611
- var import_jsx_runtime9 = require("react/jsx-runtime");
5353
+ var import_react12 = require("react");
5354
+ var import_js7 = require("@flopay/js");
5355
+ var import_shared11 = require("@flopay/shared");
5356
+ var import_jsx_runtime10 = require("react/jsx-runtime");
4612
5357
  var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3 = 44;
4613
5358
  var PAYPAL_RESUME_STORAGE_KEY2 = "flopay_automatic_payment_button_resume";
4614
5359
  function sleep2(ms) {
4615
5360
  return new Promise((resolve) => setTimeout(resolve, ms));
4616
5361
  }
4617
5362
  function coerceError(err, fallbackMessage) {
4618
- if (err instanceof import_shared10.FloPayError) {
5363
+ if (err instanceof import_shared11.FloPayError) {
4619
5364
  return err;
4620
5365
  }
4621
- return new import_shared10.FloPayError(
5366
+ return new import_shared11.FloPayError(
4622
5367
  err instanceof Error ? err.message : fallbackMessage,
4623
5368
  "api_error"
4624
5369
  );
@@ -4725,11 +5470,11 @@ function FloPayAutomaticPaymentButton({
4725
5470
  style,
4726
5471
  ...buttonProps
4727
5472
  }) {
4728
- const resolvedBillingUrl = (0, import_react11.useMemo)(
4729
- () => (0, import_shared10.resolveBillingApiUrl)(billingApiUrl),
5473
+ const resolvedBillingUrl = (0, import_react12.useMemo)(
5474
+ () => (0, import_shared11.resolveBillingApiUrl)(billingApiUrl),
4730
5475
  [billingApiUrl]
4731
5476
  );
4732
- const createSessionDraft = (0, import_react11.useMemo)(
5477
+ const createSessionDraft = (0, import_react12.useMemo)(
4733
5478
  () => resolveCreateSessionDraft({
4734
5479
  createSession,
4735
5480
  clientId,
@@ -4755,43 +5500,47 @@ function FloPayAutomaticPaymentButton({
4755
5500
  utmMetadata
4756
5501
  ]
4757
5502
  );
4758
- const [isProcessing, setIsProcessing] = (0, import_react11.useState)(false);
4759
- const [overlayStatus, setOverlayStatus] = (0, import_react11.useState)(null);
4760
- const [overlayError, setOverlayError] = (0, import_react11.useState)(null);
4761
- const [fallbackSession, setFallbackSession] = (0, import_react11.useState)(null);
4762
- const automaticPaymentToken = (0, import_react11.useMemo)(
5503
+ const [isProcessing, setIsProcessing] = (0, import_react12.useState)(false);
5504
+ const [overlayStatus, setOverlayStatus] = (0, import_react12.useState)(null);
5505
+ const [overlayError, setOverlayError] = (0, import_react12.useState)(null);
5506
+ const [fallbackSession, setFallbackSession] = (0, import_react12.useState)(null);
5507
+ const automaticPaymentToken = (0, import_react12.useMemo)(
4763
5508
  () => paymentMethodId ? {
4764
5509
  id: paymentMethodId,
4765
- type: "card",
5510
+ // Saved PayPal `user_payment_method` records are submitted with
5511
+ // `type: 'paypal'` so the backend routes the upsell through the
5512
+ // direct PayPal gateway's vaulted-token flow. Card and wallet PMs
5513
+ // continue to use `type: 'card'`.
5514
+ type: checkoutMethod === "paypal" ? "paypal" : "card",
4766
5515
  ...checkoutMethod === "paypal" ? { isPaypal: true } : {}
4767
5516
  } : void 0,
4768
5517
  [checkoutMethod, paymentMethodId]
4769
5518
  );
4770
- const isMountedRef = (0, import_react11.useRef)(true);
4771
- const resumeAttemptedRef = (0, import_react11.useRef)(false);
4772
- const fallbackSessionRef = (0, import_react11.useRef)(fallbackSession);
4773
- const onSuccessRef = (0, import_react11.useRef)(onSuccess);
4774
- const onErrorRef = (0, import_react11.useRef)(onError);
4775
- const onDeclineRef = (0, import_react11.useRef)(onDecline);
4776
- (0, import_react11.useEffect)(() => {
5519
+ const isMountedRef = (0, import_react12.useRef)(true);
5520
+ const resumeAttemptedRef = (0, import_react12.useRef)(false);
5521
+ const fallbackSessionRef = (0, import_react12.useRef)(fallbackSession);
5522
+ const onSuccessRef = (0, import_react12.useRef)(onSuccess);
5523
+ const onErrorRef = (0, import_react12.useRef)(onError);
5524
+ const onDeclineRef = (0, import_react12.useRef)(onDecline);
5525
+ (0, import_react12.useEffect)(() => {
4777
5526
  fallbackSessionRef.current = fallbackSession;
4778
5527
  }, [fallbackSession]);
4779
- (0, import_react11.useEffect)(() => {
5528
+ (0, import_react12.useEffect)(() => {
4780
5529
  onSuccessRef.current = onSuccess;
4781
5530
  }, [onSuccess]);
4782
- (0, import_react11.useEffect)(() => {
5531
+ (0, import_react12.useEffect)(() => {
4783
5532
  onErrorRef.current = onError;
4784
5533
  }, [onError]);
4785
- (0, import_react11.useEffect)(() => {
5534
+ (0, import_react12.useEffect)(() => {
4786
5535
  onDeclineRef.current = onDecline;
4787
5536
  }, [onDecline]);
4788
- (0, import_react11.useEffect)(() => {
5537
+ (0, import_react12.useEffect)(() => {
4789
5538
  isMountedRef.current = true;
4790
5539
  return () => {
4791
5540
  isMountedRef.current = false;
4792
5541
  };
4793
5542
  }, []);
4794
- (0, import_react11.useEffect)(() => {
5543
+ (0, import_react12.useEffect)(() => {
4795
5544
  if (!fallbackSession || typeof window === "undefined") {
4796
5545
  return;
4797
5546
  }
@@ -4805,13 +5554,13 @@ function FloPayAutomaticPaymentButton({
4805
5554
  window.removeEventListener("keydown", handleKeyDown);
4806
5555
  };
4807
5556
  }, [fallbackSession]);
4808
- const emitDecline = (0, import_react11.useCallback)((error, method = DEFAULT_SAVED_PAYMENT_DECLINE_METHOD) => {
5557
+ const emitDecline = (0, import_react12.useCallback)((error, method = DEFAULT_SAVED_PAYMENT_DECLINE_METHOD) => {
4809
5558
  onDeclineRef.current?.(buildDeclineEvent(method, error, {
4810
5559
  code: error.code,
4811
5560
  declineCode: error.declineCode
4812
5561
  }));
4813
5562
  }, []);
4814
- const showSuccess = (0, import_react11.useCallback)(async (event) => {
5563
+ const showSuccess = (0, import_react12.useCallback)(async (event) => {
4815
5564
  if (!isMountedRef.current) return;
4816
5565
  setOverlayError(null);
4817
5566
  setOverlayStatus("success");
@@ -4819,7 +5568,7 @@ function FloPayAutomaticPaymentButton({
4819
5568
  if (!isMountedRef.current) return;
4820
5569
  onSuccessRef.current?.(event);
4821
5570
  }, []);
4822
- const showError = (0, import_react11.useCallback)(async (error, options) => {
5571
+ const showError = (0, import_react12.useCallback)(async (error, options) => {
4823
5572
  if (!isMountedRef.current) return;
4824
5573
  onErrorRef.current?.(error);
4825
5574
  if (options?.emitDecline) {
@@ -4829,10 +5578,10 @@ function FloPayAutomaticPaymentButton({
4829
5578
  setOverlayStatus("error");
4830
5579
  await sleep2(PROCESSING_OVERLAY_ERROR_DELAY_MS);
4831
5580
  }, [emitDecline]);
4832
- const processResolvedSession = (0, import_react11.useCallback)(async (apiResult, resolvedSessionId, options) => {
5581
+ const processResolvedSession = (0, import_react12.useCallback)(async (apiResult, resolvedSessionId, options) => {
4833
5582
  const session = apiResult.data.session ?? null;
4834
5583
  if (!session) {
4835
- throw new import_shared10.FloPayError("No session data returned", "api_error");
5584
+ throw new import_shared11.FloPayError("No session data returned", "api_error");
4836
5585
  }
4837
5586
  if (session.status === "complete") {
4838
5587
  await showSuccess({
@@ -4844,7 +5593,7 @@ function FloPayAutomaticPaymentButton({
4844
5593
  return;
4845
5594
  }
4846
5595
  if (session.status === "expired") {
4847
- throw new import_shared10.FloPayError("Checkout session has expired.", "api_error", {
5596
+ throw new import_shared11.FloPayError("Checkout session has expired.", "api_error", {
4848
5597
  code: "checkout_session_expired"
4849
5598
  });
4850
5599
  }
@@ -4854,13 +5603,13 @@ function FloPayAutomaticPaymentButton({
4854
5603
  const shouldTreatCreateSessionFlowAsServerAutoAttempt = options?.fromCreateSession && (apiResult.autoProcessingAttempted === true || !!apiResult.autoProcessingError || !!redirectResult);
4855
5604
  const shouldRetryPayPalClientSide = checkoutMethod === "paypal" && automaticPaymentToken?.isPaypal === true && options?.fromCreateSession === true;
4856
5605
  if (apiResult.autoProcessingPending) {
4857
- const api = new import_js6.PaymentAPI(resolvedBillingUrl);
5606
+ const api = new import_js7.PaymentAPI(resolvedBillingUrl);
4858
5607
  const completed = await api.waitForCheckoutSessionCompletion(apiResult.autoProcessingPending.sessionId, {
4859
5608
  initialDelayMs: apiResult.autoProcessingPending.retryAfterMs
4860
5609
  });
4861
5610
  const completedSession = completed.data.session;
4862
5611
  if (!completedSession || completedSession.status !== "complete") {
4863
- throw new import_shared10.FloPayError("Automatic payment failed. Please try again.", "api_error", {
5612
+ throw new import_shared11.FloPayError("Automatic payment failed. Please try again.", "api_error", {
4864
5613
  code: completedSession?.status === "expired" ? "checkout_session_expired" : "checkout_processing_timeout"
4865
5614
  });
4866
5615
  }
@@ -5052,14 +5801,14 @@ function FloPayAutomaticPaymentButton({
5052
5801
  showError,
5053
5802
  showSuccess
5054
5803
  ]);
5055
- const handleButtonClick = (0, import_react11.useCallback)(async (event) => {
5804
+ const handleButtonClick = (0, import_react12.useCallback)(async (event) => {
5056
5805
  buttonProps.onClick?.(event);
5057
5806
  if (event.defaultPrevented || disabled || isProcessing) {
5058
5807
  return;
5059
5808
  }
5060
5809
  setFallbackSession(null);
5061
5810
  if (sessionId && createSessionDraft) {
5062
- const error = new import_shared10.FloPayError(
5811
+ const error = new import_shared11.FloPayError(
5063
5812
  "Provide either sessionId or create-session props, not both.",
5064
5813
  "validation_error"
5065
5814
  );
@@ -5071,7 +5820,7 @@ function FloPayAutomaticPaymentButton({
5071
5820
  return;
5072
5821
  }
5073
5822
  if (!sessionId && !createSessionDraft) {
5074
- const error = new import_shared10.FloPayError(
5823
+ const error = new import_shared11.FloPayError(
5075
5824
  "Provide a sessionId or the props required to create an automatic payment session.",
5076
5825
  "validation_error"
5077
5826
  );
@@ -5086,7 +5835,7 @@ function FloPayAutomaticPaymentButton({
5086
5835
  setOverlayError(null);
5087
5836
  setOverlayStatus("processing");
5088
5837
  try {
5089
- const api = new import_js6.PaymentAPI(resolvedBillingUrl);
5838
+ const api = new import_js7.PaymentAPI(resolvedBillingUrl);
5090
5839
  if (sessionId) {
5091
5840
  const result = await api.getUnifiedCheckoutSession(sessionId);
5092
5841
  await processResolvedSession(result, sessionId);
@@ -5101,7 +5850,7 @@ function FloPayAutomaticPaymentButton({
5101
5850
  fromCreateSession: true
5102
5851
  });
5103
5852
  } catch (err) {
5104
- if (err instanceof import_shared10.FloPayError && err.code === "session_auto_completed") {
5853
+ if (err instanceof import_shared11.FloPayError && err.code === "session_auto_completed") {
5105
5854
  await showSuccess({
5106
5855
  result: { status: "succeeded" },
5107
5856
  session: null,
@@ -5134,7 +5883,7 @@ function FloPayAutomaticPaymentButton({
5134
5883
  showError,
5135
5884
  showSuccess
5136
5885
  ]);
5137
- const handleFallbackComplete = (0, import_react11.useCallback)((result) => {
5886
+ const handleFallbackComplete = (0, import_react12.useCallback)((result) => {
5138
5887
  const activeFallback = fallbackSessionRef.current;
5139
5888
  setFallbackSession(null);
5140
5889
  onSuccessRef.current?.({
@@ -5144,13 +5893,13 @@ function FloPayAutomaticPaymentButton({
5144
5893
  autoCompleted: false
5145
5894
  });
5146
5895
  }, []);
5147
- const handleFallbackError = (0, import_react11.useCallback)((error) => {
5896
+ const handleFallbackError = (0, import_react12.useCallback)((error) => {
5148
5897
  onErrorRef.current?.(error);
5149
5898
  }, []);
5150
- const handleFallbackDecline = (0, import_react11.useCallback)((decline) => {
5899
+ const handleFallbackDecline = (0, import_react12.useCallback)((decline) => {
5151
5900
  onDeclineRef.current?.(decline);
5152
5901
  }, []);
5153
- (0, import_react11.useEffect)(() => {
5902
+ (0, import_react12.useEffect)(() => {
5154
5903
  if (typeof window === "undefined" || resumeAttemptedRef.current) {
5155
5904
  return;
5156
5905
  }
@@ -5171,7 +5920,7 @@ function FloPayAutomaticPaymentButton({
5171
5920
  try {
5172
5921
  if (params.get("redirect_status") === "failed") {
5173
5922
  throw Object.assign(
5174
- new import_shared10.FloPayError("PayPal payment was declined. Please try again.", "api_error"),
5923
+ new import_shared11.FloPayError("PayPal payment was declined. Please try again.", "api_error"),
5175
5924
  { checkoutMethod: "paypal" }
5176
5925
  );
5177
5926
  }
@@ -5187,14 +5936,14 @@ function FloPayAutomaticPaymentButton({
5187
5936
  const paypalStripe = (paypalFlopay ?? flopay).getRawProvider();
5188
5937
  if (!paypalStripe) {
5189
5938
  throw Object.assign(
5190
- new import_shared10.FloPayError("PayPal is not available.", "api_error"),
5939
+ new import_shared11.FloPayError("PayPal is not available.", "api_error"),
5191
5940
  { checkoutMethod: "paypal" }
5192
5941
  );
5193
5942
  }
5194
5943
  const { paymentIntent, error } = await paypalStripe.retrievePaymentIntent(clientSecret);
5195
5944
  if (error) {
5196
5945
  throw Object.assign(
5197
- new import_shared10.FloPayError(
5946
+ new import_shared11.FloPayError(
5198
5947
  error.message ?? "Failed to retrieve PayPal payment status.",
5199
5948
  "api_error",
5200
5949
  { code: error.code }
@@ -5205,23 +5954,23 @@ function FloPayAutomaticPaymentButton({
5205
5954
  const resultStatus = mapPayPalIntentStatusToPaymentResult(paymentIntent?.status);
5206
5955
  if (!paymentIntent || resultStatus === "failed") {
5207
5956
  throw Object.assign(
5208
- new import_shared10.FloPayError("PayPal payment was not completed. Please try again.", "api_error"),
5957
+ new import_shared11.FloPayError("PayPal payment was not completed. Please try again.", "api_error"),
5209
5958
  { checkoutMethod: "paypal" }
5210
5959
  );
5211
5960
  }
5212
5961
  const paymentMethodId2 = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
5213
5962
  if (!resumeState.sessionId) {
5214
5963
  throw Object.assign(
5215
- new import_shared10.FloPayError("Missing session id on PayPal resume.", "api_error"),
5964
+ new import_shared11.FloPayError("Missing session id on PayPal resume.", "api_error"),
5216
5965
  { checkoutMethod: "paypal" }
5217
5966
  );
5218
5967
  }
5219
- const api = new import_js6.PaymentAPI(resolvedBillingUrl);
5968
+ const api = new import_js7.PaymentAPI(resolvedBillingUrl);
5220
5969
  const sessionResult = await api.getUnifiedCheckoutSession(resumeState.sessionId);
5221
5970
  let resumeSession = sessionResult.data.session;
5222
5971
  if (!resumeSession) {
5223
5972
  throw Object.assign(
5224
- new import_shared10.FloPayError("Could not load session to capture PayPal payment.", "api_error"),
5973
+ new import_shared11.FloPayError("Could not load session to capture PayPal payment.", "api_error"),
5225
5974
  { checkoutMethod: "paypal" }
5226
5975
  );
5227
5976
  }
@@ -5240,7 +5989,7 @@ function FloPayAutomaticPaymentButton({
5240
5989
  });
5241
5990
  if (processResult.type !== "success") {
5242
5991
  throw Object.assign(
5243
- new import_shared10.FloPayError("Failed to finalize PayPal payment.", "api_error"),
5992
+ new import_shared11.FloPayError("Failed to finalize PayPal payment.", "api_error"),
5244
5993
  { checkoutMethod: "paypal" }
5245
5994
  );
5246
5995
  }
@@ -5281,8 +6030,8 @@ function FloPayAutomaticPaymentButton({
5281
6030
  }
5282
6031
  })();
5283
6032
  }, [locale, resolvedBillingUrl, showError, showSuccess]);
5284
- const bStyles = (0, import_react11.useMemo)(() => {
5285
- const base = (0, import_shared10.resolveButtonsLayoutTheme)(buttonsTheme);
6033
+ const bStyles = (0, import_react12.useMemo)(() => {
6034
+ const base = (0, import_shared11.resolveButtonsLayoutTheme)(buttonsTheme);
5286
6035
  if (!stylesOverride) return base;
5287
6036
  return {
5288
6037
  ...base,
@@ -5291,8 +6040,8 @@ function FloPayAutomaticPaymentButton({
5291
6040
  };
5292
6041
  }, [buttonsTheme, stylesOverride]);
5293
6042
  const cardButtonSizing = children === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
5294
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
5295
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
6043
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
6044
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5296
6045
  "button",
5297
6046
  {
5298
6047
  ...buttonProps,
@@ -5333,17 +6082,17 @@ function FloPayAutomaticPaymentButton({
5333
6082
  e.currentTarget.style.transform = "scale(1)";
5334
6083
  }
5335
6084
  },
5336
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CardButtonContentSlot, { content: children })
6085
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CardButtonContentSlot, { content: children })
5337
6086
  }
5338
6087
  ),
5339
- overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
6088
+ overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5340
6089
  ProcessingOverlay,
5341
6090
  {
5342
6091
  status: overlayStatus,
5343
6092
  errorMessage: overlayError
5344
6093
  }
5345
6094
  ),
5346
- fallbackSession && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
6095
+ fallbackSession && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5347
6096
  "div",
5348
6097
  {
5349
6098
  "data-testid": "flopay-automatic-payment-fallback",
@@ -5364,7 +6113,7 @@ function FloPayAutomaticPaymentButton({
5364
6113
  padding: "1.5rem",
5365
6114
  zIndex: 1100
5366
6115
  },
5367
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
6116
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5368
6117
  "div",
5369
6118
  {
5370
6119
  style: {
@@ -5380,7 +6129,7 @@ function FloPayAutomaticPaymentButton({
5380
6129
  flexDirection: "column",
5381
6130
  gap: "1rem"
5382
6131
  },
5383
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
6132
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5384
6133
  FloPayCheckout,
5385
6134
  {
5386
6135
  sessionId: fallbackSession.sessionId,
@@ -5408,6 +6157,7 @@ function FloPayAutomaticPaymentButton({
5408
6157
  CardExpiryElement,
5409
6158
  CardNumberElement,
5410
6159
  CheckoutForm,
6160
+ DirectPayPalButton,
5411
6161
  FloPayAutomaticPaymentButton,
5412
6162
  FloPayCheckout,
5413
6163
  FloPayProvider,