@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/README.md +11 -4
- package/dist/index.cjs +1244 -494
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +141 -11
- package/dist/index.d.ts +141 -11
- package/dist/index.mjs +1154 -405
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -100,9 +100,9 @@ function FloPayProvider({
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
// src/flopay-checkout.tsx
|
|
103
|
-
import
|
|
104
|
-
import { PaymentAPI as
|
|
105
|
-
import { SDK_VERSION, FloPayError as
|
|
103
|
+
import React7, { useCallback as useCallback2, useEffect as useEffect5, useMemo as useMemo4, useRef as useRef4, useState as useState4 } from "react";
|
|
104
|
+
import { PaymentAPI as PaymentAPI4 } from "@flopay/js";
|
|
105
|
+
import { SDK_VERSION, FloPayError as FloPayError5, resolveBillingApiUrl as resolveBillingApiUrl3, buildCheckoutDisplayData, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme2 } from "@flopay/shared";
|
|
106
106
|
|
|
107
107
|
// src/card-button-content.tsx
|
|
108
108
|
import "react";
|
|
@@ -248,8 +248,8 @@ import {
|
|
|
248
248
|
isAVSFieldVisible,
|
|
249
249
|
getStateFromPostalCode
|
|
250
250
|
} from "@flopay/shared";
|
|
251
|
-
import { PaymentAPI } from "@flopay/js";
|
|
252
|
-
import { forwardRef, useCallback, useContext as useContext3, useEffect as
|
|
251
|
+
import { PaymentAPI as PaymentAPI2 } from "@flopay/js";
|
|
252
|
+
import { forwardRef, useCallback, useContext as useContext3, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
|
|
253
253
|
|
|
254
254
|
// src/hooks.ts
|
|
255
255
|
import { useContext as useContext2 } from "react";
|
|
@@ -651,11 +651,562 @@ function isInAppBrowser(userAgent) {
|
|
|
651
651
|
return false;
|
|
652
652
|
}
|
|
653
653
|
|
|
654
|
+
// src/direct-paypal-button.tsx
|
|
655
|
+
import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
656
|
+
import { loadScript } from "@paypal/paypal-js";
|
|
657
|
+
import { PaymentAPI } from "@flopay/js";
|
|
658
|
+
import { FloPayError as FloPayError2, normalizeGatewayEnvironment } from "@flopay/shared";
|
|
659
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
660
|
+
var DEFAULT_BUTTON_HEIGHT = 45;
|
|
661
|
+
function DirectPayPalButton({
|
|
662
|
+
sessionId,
|
|
663
|
+
billingApiUrl,
|
|
664
|
+
email,
|
|
665
|
+
clientId,
|
|
666
|
+
environment,
|
|
667
|
+
currency,
|
|
668
|
+
isSubscription,
|
|
669
|
+
onTokenizedBody,
|
|
670
|
+
onComplete,
|
|
671
|
+
onErrorChange,
|
|
672
|
+
onDecline,
|
|
673
|
+
isProcessing = false,
|
|
674
|
+
onLoadStateChange,
|
|
675
|
+
onButtonClick,
|
|
676
|
+
runBeforeButtonClick,
|
|
677
|
+
session,
|
|
678
|
+
existingOrderId,
|
|
679
|
+
debug = false
|
|
680
|
+
}) {
|
|
681
|
+
const containerRef = useRef2(null);
|
|
682
|
+
const [ready, setReady] = useState2(false);
|
|
683
|
+
const [failed, setFailed] = useState2(false);
|
|
684
|
+
const [submitting, setSubmitting] = useState2(false);
|
|
685
|
+
const baseUrl = useMemo2(() => billingApiUrl.replace(/\/+$/, ""), [billingApiUrl]);
|
|
686
|
+
const [debugLines, setDebugLines] = useState2([]);
|
|
687
|
+
const appendDebug = (line) => {
|
|
688
|
+
if (!debug) return;
|
|
689
|
+
setDebugLines((prev) => [...prev, `${(/* @__PURE__ */ new Date()).toISOString().slice(11, 23)} ${line}`]);
|
|
690
|
+
};
|
|
691
|
+
const onTokenizedBodyRef = useRef2(onTokenizedBody);
|
|
692
|
+
const onCompleteRef = useRef2(onComplete);
|
|
693
|
+
const onErrorChangeRef = useRef2(onErrorChange);
|
|
694
|
+
const onDeclineRef = useRef2(onDecline);
|
|
695
|
+
const onButtonClickRef = useRef2(onButtonClick);
|
|
696
|
+
const onLoadStateChangeRef = useRef2(onLoadStateChange);
|
|
697
|
+
const runBeforeButtonClickRef = useRef2(runBeforeButtonClick);
|
|
698
|
+
const sessionRef = useRef2(session);
|
|
699
|
+
const emailRef = useRef2(email);
|
|
700
|
+
const beforeClickRef = useRef2(null);
|
|
701
|
+
useEffect3(() => {
|
|
702
|
+
onTokenizedBodyRef.current = onTokenizedBody;
|
|
703
|
+
}, [onTokenizedBody]);
|
|
704
|
+
useEffect3(() => {
|
|
705
|
+
onCompleteRef.current = onComplete;
|
|
706
|
+
}, [onComplete]);
|
|
707
|
+
useEffect3(() => {
|
|
708
|
+
onErrorChangeRef.current = onErrorChange;
|
|
709
|
+
}, [onErrorChange]);
|
|
710
|
+
useEffect3(() => {
|
|
711
|
+
onDeclineRef.current = onDecline;
|
|
712
|
+
}, [onDecline]);
|
|
713
|
+
useEffect3(() => {
|
|
714
|
+
onButtonClickRef.current = onButtonClick;
|
|
715
|
+
}, [onButtonClick]);
|
|
716
|
+
useEffect3(() => {
|
|
717
|
+
onLoadStateChangeRef.current = onLoadStateChange;
|
|
718
|
+
}, [onLoadStateChange]);
|
|
719
|
+
useEffect3(() => {
|
|
720
|
+
runBeforeButtonClickRef.current = runBeforeButtonClick;
|
|
721
|
+
}, [runBeforeButtonClick]);
|
|
722
|
+
useEffect3(() => {
|
|
723
|
+
sessionRef.current = session;
|
|
724
|
+
}, [session]);
|
|
725
|
+
useEffect3(() => {
|
|
726
|
+
emailRef.current = email;
|
|
727
|
+
}, [email]);
|
|
728
|
+
useEffect3(() => {
|
|
729
|
+
onLoadStateChangeRef.current?.(ready && !failed);
|
|
730
|
+
}, [ready, failed]);
|
|
731
|
+
const normalizedEnv = normalizeGatewayEnvironment(environment);
|
|
732
|
+
useEffect3(() => {
|
|
733
|
+
const maskedClient = clientId ? `${clientId.slice(0, 6)}\u2026(len ${clientId.length})` : "(empty)";
|
|
734
|
+
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "(no navigator)";
|
|
735
|
+
appendDebug(`mount clientId=${maskedClient} env=${environment ?? "(unset)"}\u2192${normalizedEnv ?? "live"} ccy=${currency} sub=${isSubscription}`);
|
|
736
|
+
appendDebug(`ua=${ua.slice(0, 80)}${ua.length > 80 ? "\u2026" : ""}`);
|
|
737
|
+
if (!clientId) {
|
|
738
|
+
appendDebug("FAIL: clientId empty \u2014 gateway misconfigured");
|
|
739
|
+
setFailed(true);
|
|
740
|
+
onErrorChangeRef.current?.("Direct PayPal gateway is misconfigured.");
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
if (!containerRef.current) {
|
|
744
|
+
appendDebug("FAIL: containerRef not attached");
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
let cancelled = false;
|
|
748
|
+
let activeButtons = null;
|
|
749
|
+
let rendered = false;
|
|
750
|
+
const container = containerRef.current;
|
|
751
|
+
let containerObserver = null;
|
|
752
|
+
let perfObserver = null;
|
|
753
|
+
const watchdogTimers = [];
|
|
754
|
+
const formatDims = (el) => {
|
|
755
|
+
if (!el || typeof el.getBoundingClientRect !== "function") return "(no rect)";
|
|
756
|
+
const rect = el.getBoundingClientRect();
|
|
757
|
+
return `${Math.round(rect.width)}\xD7${Math.round(rect.height)}`;
|
|
758
|
+
};
|
|
759
|
+
const classifyIframeSrc = (raw) => {
|
|
760
|
+
if (!raw) return "(empty)";
|
|
761
|
+
try {
|
|
762
|
+
const url = new URL(raw, typeof window !== "undefined" ? window.location.href : "https://localhost");
|
|
763
|
+
const path = url.pathname.toLowerCase();
|
|
764
|
+
if (path.includes("checkcaptcha") || path.includes("captcha")) return `CAPTCHA(${url.host}${path})`;
|
|
765
|
+
if (path.includes("risk") || path.includes("challenge")) return `RISK(${url.host}${path})`;
|
|
766
|
+
if (path.includes("smart/buttons")) return `smart-buttons(${url.host})`;
|
|
767
|
+
return `${url.host}${path}`.slice(0, 100);
|
|
768
|
+
} catch {
|
|
769
|
+
return raw.slice(0, 80);
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
const describeIframe = (frame) => {
|
|
773
|
+
const src = frame.getAttribute("src");
|
|
774
|
+
const srcdoc = frame.getAttribute("srcdoc");
|
|
775
|
+
const name = frame.getAttribute("name");
|
|
776
|
+
const sandbox = frame.getAttribute("sandbox");
|
|
777
|
+
const parts = [];
|
|
778
|
+
if (src) parts.push(`src=${classifyIframeSrc(src)}`);
|
|
779
|
+
if (srcdoc) parts.push(`srcdoc[${srcdoc.length}ch]`);
|
|
780
|
+
if (!src && !srcdoc) parts.push("src=(empty) srcdoc=(empty)");
|
|
781
|
+
if (name) parts.push(`name=${name.slice(0, 40)}`);
|
|
782
|
+
if (sandbox !== null) parts.push(`sandbox="${sandbox.slice(0, 40)}"`);
|
|
783
|
+
return parts.join(" ");
|
|
784
|
+
};
|
|
785
|
+
const inspectFrameContent = (frame) => {
|
|
786
|
+
if (!(frame instanceof HTMLIFrameElement)) return "";
|
|
787
|
+
try {
|
|
788
|
+
const cd = frame.contentDocument;
|
|
789
|
+
if (!cd) return "cd=null";
|
|
790
|
+
const bodyChildren = cd.body?.children.length ?? 0;
|
|
791
|
+
const bodyLen = cd.body?.innerHTML.length ?? 0;
|
|
792
|
+
const headLen = cd.head?.innerHTML.length ?? 0;
|
|
793
|
+
return `cd=same-origin readyState=${cd.readyState} body[${bodyChildren}children,${bodyLen}ch] head[${headLen}ch]`;
|
|
794
|
+
} catch (err) {
|
|
795
|
+
return `cd=cross-origin(${err.message.slice(0, 30)})`;
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
const errorMessages = [];
|
|
799
|
+
const onWindowError = (ev) => {
|
|
800
|
+
const msg = ev.message ?? String(ev.error ?? "(no message)");
|
|
801
|
+
if (msg && (msg.toLowerCase().includes("paypal") || msg.toLowerCase().includes("zoid") || msg.toLowerCase().includes("postrobot") || msg.toLowerCase().includes("storage"))) {
|
|
802
|
+
appendDebug(`window:error ${msg.slice(0, 140)}`);
|
|
803
|
+
errorMessages.push(msg);
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
const onUnhandledRejection = (ev) => {
|
|
807
|
+
const reason = ev.reason instanceof Error ? ev.reason.message : String(ev.reason ?? "(no reason)");
|
|
808
|
+
if (reason && (reason.toLowerCase().includes("paypal") || reason.toLowerCase().includes("zoid") || reason.toLowerCase().includes("postrobot") || reason.toLowerCase().includes("storage"))) {
|
|
809
|
+
appendDebug(`window:rejection ${reason.slice(0, 140)}`);
|
|
810
|
+
errorMessages.push(reason);
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
if (debug && typeof window !== "undefined") {
|
|
814
|
+
window.addEventListener("error", onWindowError);
|
|
815
|
+
window.addEventListener("unhandledrejection", onUnhandledRejection);
|
|
816
|
+
}
|
|
817
|
+
const paypalRequestCount = { value: 0 };
|
|
818
|
+
if (debug && typeof PerformanceObserver !== "undefined") {
|
|
819
|
+
try {
|
|
820
|
+
perfObserver = new PerformanceObserver((list) => {
|
|
821
|
+
for (const entry of list.getEntries()) {
|
|
822
|
+
if (!entry.name.toLowerCase().includes("paypal")) continue;
|
|
823
|
+
paypalRequestCount.value += 1;
|
|
824
|
+
const dur = Math.round(entry.duration);
|
|
825
|
+
appendDebug(`net ${dur}ms ${entry.name.slice(0, 90)}`);
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
perfObserver.observe({ type: "resource", buffered: true });
|
|
829
|
+
} catch {
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
const stopDiagnostics = () => {
|
|
833
|
+
containerObserver?.disconnect();
|
|
834
|
+
containerObserver = null;
|
|
835
|
+
perfObserver?.disconnect();
|
|
836
|
+
perfObserver = null;
|
|
837
|
+
while (watchdogTimers.length) clearTimeout(watchdogTimers.pop());
|
|
838
|
+
if (debug && typeof window !== "undefined") {
|
|
839
|
+
window.removeEventListener("error", onWindowError);
|
|
840
|
+
window.removeEventListener("unhandledrejection", onUnhandledRejection);
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
const isZoidLifecycleMessage = (message) => {
|
|
844
|
+
if (!message) return false;
|
|
845
|
+
const lower = message.toLowerCase();
|
|
846
|
+
return lower.includes("zoid destroyed") || lower.includes("destroyed all components") || lower.includes("window closed") || lower.includes("detected container element removed");
|
|
847
|
+
};
|
|
848
|
+
const forwardError = (message) => {
|
|
849
|
+
if (cancelled) return;
|
|
850
|
+
if (isZoidLifecycleMessage(message)) return;
|
|
851
|
+
onErrorChangeRef.current?.(message);
|
|
852
|
+
};
|
|
853
|
+
const markRenderFailed = (message) => {
|
|
854
|
+
if (cancelled) return;
|
|
855
|
+
if (isZoidLifecycleMessage(message)) {
|
|
856
|
+
appendDebug(`markRenderFailed:skip-zoid msg=${message.slice(0, 80)}`);
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
setFailed(true);
|
|
860
|
+
forwardError(message);
|
|
861
|
+
};
|
|
862
|
+
setFailed(false);
|
|
863
|
+
const dispatchTokenizedBody = async (body) => {
|
|
864
|
+
const prepared = beforeClickRef.current;
|
|
865
|
+
const effectiveSessionId = prepared?.sessionId ?? sessionId;
|
|
866
|
+
if (onTokenizedBodyRef.current) {
|
|
867
|
+
onTokenizedBodyRef.current(body, {
|
|
868
|
+
sessionId: effectiveSessionId,
|
|
869
|
+
accountPatch: prepared?.accountPatch
|
|
870
|
+
});
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
try {
|
|
874
|
+
const currentSession = sessionRef.current;
|
|
875
|
+
const currentEmail = prepared?.accountPatch?.email ?? emailRef.current;
|
|
876
|
+
const effectiveUserId = prepared?.accountPatch?.userId ?? currentSession?.customer?.id ?? currentSession?.accountData?.userId ?? "";
|
|
877
|
+
const api = new PaymentAPI(baseUrl);
|
|
878
|
+
const response = await api.processPayment(
|
|
879
|
+
effectiveUserId,
|
|
880
|
+
{
|
|
881
|
+
sessionId: effectiveSessionId,
|
|
882
|
+
tokenizedData: body,
|
|
883
|
+
accountData: {
|
|
884
|
+
userId: effectiveUserId,
|
|
885
|
+
email: currentEmail ?? currentSession?.customer?.email ?? "",
|
|
886
|
+
firstName: prepared?.accountPatch?.firstName ?? currentSession?.customer?.firstName ?? currentSession?.accountData?.firstName ?? "",
|
|
887
|
+
lastName: prepared?.accountPatch?.lastName ?? currentSession?.customer?.lastName ?? currentSession?.accountData?.lastName ?? "",
|
|
888
|
+
country: prepared?.accountPatch?.country ?? currentSession?.customer?.country ?? currentSession?.accountData?.country ?? void 0,
|
|
889
|
+
zip: prepared?.accountPatch?.zip ?? currentSession?.customer?.zip ?? currentSession?.accountData?.zip ?? void 0
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
);
|
|
893
|
+
if (response.ok) {
|
|
894
|
+
onCompleteRef.current?.({ status: "succeeded", checkoutMethod: "paypal" });
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
const json = await response.json().catch(() => null);
|
|
898
|
+
const message = json?.["message"] ?? "PayPal payment failed.";
|
|
899
|
+
forwardError(message);
|
|
900
|
+
onDeclineRef.current?.(buildDeclineEvent("paypal", message, {
|
|
901
|
+
code: json?.["code"],
|
|
902
|
+
declineCode: json?.["declineCode"]
|
|
903
|
+
}));
|
|
904
|
+
} catch (err) {
|
|
905
|
+
const message = err instanceof Error ? err.message : "PayPal payment failed.";
|
|
906
|
+
forwardError(message);
|
|
907
|
+
onDeclineRef.current?.(buildDeclineEvent("paypal", message));
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
const createPaypalIntent = async (fallbackMessage) => {
|
|
911
|
+
const prepared = beforeClickRef.current;
|
|
912
|
+
const effectiveSessionId = prepared?.sessionId ?? sessionId;
|
|
913
|
+
const effectiveEmail = prepared?.accountPatch?.email ?? emailRef.current;
|
|
914
|
+
const response = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
|
|
915
|
+
method: "POST",
|
|
916
|
+
headers: { "Content-Type": "application/json" },
|
|
917
|
+
body: JSON.stringify({
|
|
918
|
+
sessionId: effectiveSessionId,
|
|
919
|
+
email: effectiveEmail,
|
|
920
|
+
paymentMethodType: "paypal",
|
|
921
|
+
isPaypal: "true"
|
|
922
|
+
})
|
|
923
|
+
});
|
|
924
|
+
const json = await response.json().catch(() => null);
|
|
925
|
+
if (!response.ok) {
|
|
926
|
+
throw new Error(json?.message ?? fallbackMessage);
|
|
927
|
+
}
|
|
928
|
+
const id = json?.data?.id;
|
|
929
|
+
if (!id) {
|
|
930
|
+
throw new Error(fallbackMessage);
|
|
931
|
+
}
|
|
932
|
+
return id;
|
|
933
|
+
};
|
|
934
|
+
appendDebug("loadScript:scheduled (deferred 1 tick)");
|
|
935
|
+
let loadPromise = null;
|
|
936
|
+
const startTimer = setTimeout(() => {
|
|
937
|
+
if (cancelled) {
|
|
938
|
+
appendDebug("loadScript:skipped (cancelled before defer ran)");
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
appendDebug("loadScript:start");
|
|
942
|
+
const paypalSdkEnv = normalizedEnv === "live" ? "production" : normalizedEnv;
|
|
943
|
+
loadPromise = loadScript({
|
|
944
|
+
clientId,
|
|
945
|
+
currency,
|
|
946
|
+
// Subscriptions need the `subscription` vault intent; one-time payments
|
|
947
|
+
// use a standard order capture.
|
|
948
|
+
intent: isSubscription ? "subscription" : "capture",
|
|
949
|
+
vault: isSubscription ? true : void 0,
|
|
950
|
+
// Tell PayPal which environment the clientId belongs to. Without
|
|
951
|
+
// this, PayPal defaults to live endpoints — and a sandbox clientId
|
|
952
|
+
// sent to live silently stalls in zoid's prerender forever (no
|
|
953
|
+
// error, no rejection).
|
|
954
|
+
...paypalSdkEnv ? { environment: paypalSdkEnv } : {},
|
|
955
|
+
// Namespace the sandbox SDK so it can coexist with a production SDK on
|
|
956
|
+
// the same page without clobbering `window.paypal`.
|
|
957
|
+
...paypalSdkEnv === "sandbox" ? { dataNamespace: "paypal_sandbox" } : {}
|
|
958
|
+
});
|
|
959
|
+
loadPromise.then((paypal) => {
|
|
960
|
+
appendDebug(`loadScript:resolved cancelled=${cancelled} ns=${!!paypal} buttons=${!!paypal?.Buttons}`);
|
|
961
|
+
if (cancelled || !paypal?.Buttons) {
|
|
962
|
+
if (!cancelled && !paypal?.Buttons) appendDebug("FAIL: namespace missing Buttons factory");
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
const handleApprove = async (data) => {
|
|
966
|
+
try {
|
|
967
|
+
setSubmitting(true);
|
|
968
|
+
onErrorChangeRef.current?.(null);
|
|
969
|
+
const token = data.subscriptionID ?? data.orderID ?? "";
|
|
970
|
+
if (!token) {
|
|
971
|
+
throw new FloPayError2(
|
|
972
|
+
"PayPal did not return an approval token.",
|
|
973
|
+
"api_error",
|
|
974
|
+
{ code: "paypal_missing_token" }
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
await dispatchTokenizedBody({
|
|
978
|
+
id: token,
|
|
979
|
+
isPaypal: true
|
|
980
|
+
});
|
|
981
|
+
} catch (err) {
|
|
982
|
+
forwardError(err instanceof Error ? err.message : "PayPal capture failed.");
|
|
983
|
+
} finally {
|
|
984
|
+
setSubmitting(false);
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
const buttons = paypal.Buttons({
|
|
988
|
+
style: { layout: "horizontal", height: DEFAULT_BUTTON_HEIGHT, tagline: false },
|
|
989
|
+
// PayPal's SDK awaits a Promise returned from `onClick` and aborts
|
|
990
|
+
// the create-order/create-subscription step when `actions.reject()`
|
|
991
|
+
// is invoked. Run the consumer's `runBeforeButtonClick` here so
|
|
992
|
+
// inline-session/account patches land before the order is created,
|
|
993
|
+
// matching the Stripe-rendered PayPal flow.
|
|
994
|
+
onClick: async (_data, actions) => {
|
|
995
|
+
const runner = runBeforeButtonClickRef.current;
|
|
996
|
+
if (runner) {
|
|
997
|
+
try {
|
|
998
|
+
const beforeClick = await runner("paypal");
|
|
999
|
+
if (!beforeClick.proceed) {
|
|
1000
|
+
beforeClickRef.current = null;
|
|
1001
|
+
await actions.reject();
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
beforeClickRef.current = {
|
|
1005
|
+
sessionId: beforeClick.sessionId,
|
|
1006
|
+
accountPatch: beforeClick.accountPatch
|
|
1007
|
+
};
|
|
1008
|
+
} catch (err) {
|
|
1009
|
+
appendDebug(`onClick:runBeforeButtonClick rejected msg=${(err instanceof Error ? err.message : String(err)).slice(0, 120)}`);
|
|
1010
|
+
beforeClickRef.current = null;
|
|
1011
|
+
await actions.reject();
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
} else {
|
|
1015
|
+
beforeClickRef.current = null;
|
|
1016
|
+
}
|
|
1017
|
+
onButtonClickRef.current?.("paypal");
|
|
1018
|
+
await actions.resolve();
|
|
1019
|
+
},
|
|
1020
|
+
// When the SDK is already holding an order/subscription id from a
|
|
1021
|
+
// prior backend round-trip (the `paypal_direct_required` retry
|
|
1022
|
+
// path), feed it straight to PayPal instead of creating a new one.
|
|
1023
|
+
// Otherwise fall back to the normal create-intent call.
|
|
1024
|
+
createOrder: isSubscription ? void 0 : existingOrderId ? () => Promise.resolve(existingOrderId) : () => createPaypalIntent("Failed to create PayPal order."),
|
|
1025
|
+
createSubscription: isSubscription ? existingOrderId ? () => Promise.resolve(existingOrderId) : () => createPaypalIntent("Failed to create PayPal subscription.") : void 0,
|
|
1026
|
+
onApprove: handleApprove,
|
|
1027
|
+
onCancel: () => {
|
|
1028
|
+
beforeClickRef.current = null;
|
|
1029
|
+
onDeclineRef.current?.(buildDeclineEvent("paypal", "PayPal checkout was cancelled."));
|
|
1030
|
+
},
|
|
1031
|
+
onError: (err) => {
|
|
1032
|
+
const message = err instanceof Error ? err.message : "PayPal failed to render.";
|
|
1033
|
+
appendDebug(`onError rendered=${rendered} msg=${message.slice(0, 120)}`);
|
|
1034
|
+
if (rendered) {
|
|
1035
|
+
forwardError(message);
|
|
1036
|
+
onDeclineRef.current?.(buildDeclineEvent("paypal", message));
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
markRenderFailed(message);
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
const eligible = buttons.isEligible();
|
|
1043
|
+
appendDebug(`isEligible=${eligible}`);
|
|
1044
|
+
if (!eligible) {
|
|
1045
|
+
setReady(false);
|
|
1046
|
+
markRenderFailed(
|
|
1047
|
+
"PayPal buttons are not eligible to render in this context (paypal_ineligible)."
|
|
1048
|
+
);
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
const typedButtons = buttons;
|
|
1052
|
+
if (debug) {
|
|
1053
|
+
appendDebug(`container:dims ${formatDims(container)} visibility=${typeof document !== "undefined" ? document.visibilityState : "(no document)"}`);
|
|
1054
|
+
}
|
|
1055
|
+
if (debug && typeof MutationObserver !== "undefined") {
|
|
1056
|
+
containerObserver = new MutationObserver((mutations) => {
|
|
1057
|
+
for (const mutation of mutations) {
|
|
1058
|
+
if (mutation.type === "childList") {
|
|
1059
|
+
mutation.addedNodes.forEach((node) => {
|
|
1060
|
+
if (!(node instanceof Element)) return;
|
|
1061
|
+
const tag = node.tagName.toLowerCase();
|
|
1062
|
+
const title = (node.getAttribute("title") ?? "").slice(0, 40);
|
|
1063
|
+
const detail = tag === "iframe" ? ` ${describeIframe(node)}` : "";
|
|
1064
|
+
appendDebug(`child+ ${tag}${title ? ` title="${title}"` : ""}${detail} dims=${formatDims(node)}`);
|
|
1065
|
+
});
|
|
1066
|
+
} else if (mutation.type === "attributes" && mutation.target instanceof Element) {
|
|
1067
|
+
const target = mutation.target;
|
|
1068
|
+
if (target.tagName.toLowerCase() !== "iframe") continue;
|
|
1069
|
+
const attr = mutation.attributeName;
|
|
1070
|
+
if (attr === "src" || attr === "srcdoc") {
|
|
1071
|
+
appendDebug(`attr~ iframe ${attr}=${attr === "srcdoc" ? `[${(target.getAttribute("srcdoc") ?? "").length}ch]` : classifyIframeSrc(target.getAttribute("src"))} dims=${formatDims(target)}`);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1076
|
+
containerObserver.observe(container, {
|
|
1077
|
+
childList: true,
|
|
1078
|
+
subtree: true,
|
|
1079
|
+
attributes: true,
|
|
1080
|
+
attributeFilter: ["src", "srcdoc"]
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
const snapshotContainer = (when) => {
|
|
1084
|
+
if (cancelled || rendered) return;
|
|
1085
|
+
const iframes = container.querySelectorAll("iframe");
|
|
1086
|
+
const hasStorageAccess = typeof document !== "undefined" && "hasStorageAccess" in document;
|
|
1087
|
+
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}`);
|
|
1088
|
+
iframes.forEach((frame, i) => {
|
|
1089
|
+
const title = (frame.getAttribute("title") ?? "").slice(0, 40);
|
|
1090
|
+
appendDebug(` iframe[${i}] ${formatDims(frame)}${title ? ` title="${title}"` : ""} ${describeIframe(frame)}`);
|
|
1091
|
+
const content = inspectFrameContent(frame);
|
|
1092
|
+
if (content) appendDebug(` ${content}`);
|
|
1093
|
+
});
|
|
1094
|
+
if (errorMessages.length === 0) {
|
|
1095
|
+
appendDebug(` (no PayPal/zoid window errors captured)`);
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1098
|
+
if (debug) {
|
|
1099
|
+
watchdogTimers.push(setTimeout(() => snapshotContainer("3s"), 3e3));
|
|
1100
|
+
watchdogTimers.push(setTimeout(() => snapshotContainer("8s"), 8e3));
|
|
1101
|
+
watchdogTimers.push(setTimeout(() => snapshotContainer("15s"), 15e3));
|
|
1102
|
+
}
|
|
1103
|
+
appendDebug("render:start");
|
|
1104
|
+
buttons.render(container).then(() => {
|
|
1105
|
+
appendDebug(`render:resolved cancelled=${cancelled}`);
|
|
1106
|
+
stopDiagnostics();
|
|
1107
|
+
if (cancelled) {
|
|
1108
|
+
typedButtons.close().catch(() => {
|
|
1109
|
+
});
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1112
|
+
activeButtons = typedButtons;
|
|
1113
|
+
rendered = true;
|
|
1114
|
+
setReady(true);
|
|
1115
|
+
}).catch((err) => {
|
|
1116
|
+
const message = err instanceof Error ? err.message : "PayPal failed to render.";
|
|
1117
|
+
appendDebug(`render:rejected msg=${message.slice(0, 120)}`);
|
|
1118
|
+
stopDiagnostics();
|
|
1119
|
+
markRenderFailed(message);
|
|
1120
|
+
});
|
|
1121
|
+
}).catch((err) => {
|
|
1122
|
+
const message = err instanceof Error ? err.message : "PayPal SDK failed to load.";
|
|
1123
|
+
appendDebug(`loadScript:rejected msg=${message.slice(0, 120)}`);
|
|
1124
|
+
markRenderFailed(message);
|
|
1125
|
+
});
|
|
1126
|
+
}, 0);
|
|
1127
|
+
return () => {
|
|
1128
|
+
cancelled = true;
|
|
1129
|
+
clearTimeout(startTimer);
|
|
1130
|
+
stopDiagnostics();
|
|
1131
|
+
if (activeButtons) {
|
|
1132
|
+
activeButtons.close().catch(() => {
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
};
|
|
1136
|
+
}, [baseUrl, clientId, currency, environment, isSubscription, sessionId, existingOrderId]);
|
|
1137
|
+
const debugPanel = debug ? /* @__PURE__ */ jsxs3(
|
|
1138
|
+
"pre",
|
|
1139
|
+
{
|
|
1140
|
+
"data-testid": "flopay-direct-paypal-debug",
|
|
1141
|
+
style: {
|
|
1142
|
+
margin: "0 0 8px 0",
|
|
1143
|
+
padding: "6px 8px",
|
|
1144
|
+
background: failed ? "#fef2f2" : "#f3f4f6",
|
|
1145
|
+
border: `1px solid ${failed ? "#fca5a5" : "#d1d5db"}`,
|
|
1146
|
+
borderRadius: 6,
|
|
1147
|
+
color: "#111827",
|
|
1148
|
+
font: "11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
1149
|
+
whiteSpace: "pre-wrap",
|
|
1150
|
+
wordBreak: "break-word",
|
|
1151
|
+
maxHeight: 220,
|
|
1152
|
+
overflowY: "auto"
|
|
1153
|
+
},
|
|
1154
|
+
children: [
|
|
1155
|
+
`FloPay/DirectPayPal-debug (ready=${ready} failed=${failed})`,
|
|
1156
|
+
debugLines.length === 0 ? "\n(waiting for first lifecycle event\u2026)" : `
|
|
1157
|
+
${debugLines.join("\n")}`
|
|
1158
|
+
]
|
|
1159
|
+
}
|
|
1160
|
+
) : null;
|
|
1161
|
+
if (failed) {
|
|
1162
|
+
return debug ? /* @__PURE__ */ jsx5("div", { children: debugPanel }) : null;
|
|
1163
|
+
}
|
|
1164
|
+
return (
|
|
1165
|
+
// Single wrapper so the parent flex container sees exactly one flex item
|
|
1166
|
+
// (otherwise the fragment's placeholder + container become two siblings
|
|
1167
|
+
// and any spacing-sensitive layout has to reason about both). The wrapper
|
|
1168
|
+
// intentionally has no margin/padding so the parent owns all spacing.
|
|
1169
|
+
/* @__PURE__ */ jsxs3("div", { children: [
|
|
1170
|
+
debugPanel,
|
|
1171
|
+
/* @__PURE__ */ jsxs3("div", { style: { position: "relative", minHeight: DEFAULT_BUTTON_HEIGHT }, children: [
|
|
1172
|
+
!ready && /* @__PURE__ */ jsx5(
|
|
1173
|
+
"div",
|
|
1174
|
+
{
|
|
1175
|
+
"data-testid": "flopay-direct-paypal-placeholder",
|
|
1176
|
+
style: {
|
|
1177
|
+
position: "absolute",
|
|
1178
|
+
inset: 0,
|
|
1179
|
+
borderRadius: 8,
|
|
1180
|
+
background: "#e5e7eb",
|
|
1181
|
+
animation: "flopay-pulse 1.5s ease-in-out infinite",
|
|
1182
|
+
pointerEvents: "none"
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
),
|
|
1186
|
+
/* @__PURE__ */ jsx5(
|
|
1187
|
+
"div",
|
|
1188
|
+
{
|
|
1189
|
+
ref: containerRef,
|
|
1190
|
+
"data-testid": "flopay-direct-paypal-container",
|
|
1191
|
+
style: {
|
|
1192
|
+
minHeight: DEFAULT_BUTTON_HEIGHT,
|
|
1193
|
+
display: "flex",
|
|
1194
|
+
opacity: ready ? 1 : 0
|
|
1195
|
+
},
|
|
1196
|
+
"aria-busy": submitting || isProcessing
|
|
1197
|
+
}
|
|
1198
|
+
)
|
|
1199
|
+
] })
|
|
1200
|
+
] })
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
654
1204
|
// src/split-card-form.tsx
|
|
655
|
-
import { FloPayError as
|
|
656
|
-
import { Fragment as Fragment2, jsx as
|
|
1205
|
+
import { FloPayError as FloPayError3 } from "@flopay/shared";
|
|
1206
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
657
1207
|
var WALLET_RESUME_KEY = "flopay_wallet_resume";
|
|
658
1208
|
var FLOPAY_KEYFRAMES = `
|
|
1209
|
+
.paypal-buttons { margin: 0 !important; vertical-align: top !important; }
|
|
659
1210
|
@keyframes flopay-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
660
1211
|
@keyframes flopay-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
|
|
661
1212
|
@keyframes flopay-buttons-enter {
|
|
@@ -689,13 +1240,13 @@ function getButtonMethodLabel(method) {
|
|
|
689
1240
|
}
|
|
690
1241
|
}
|
|
691
1242
|
function normalizeBeforeButtonClickError(method, err) {
|
|
692
|
-
return err instanceof
|
|
1243
|
+
return err instanceof FloPayError3 ? err : new FloPayError3(
|
|
693
1244
|
err instanceof Error ? err.message : `${getButtonMethodLabel(method)} before-click hook failed.`,
|
|
694
1245
|
"validation_error"
|
|
695
1246
|
);
|
|
696
1247
|
}
|
|
697
1248
|
function FloPayKeyframes() {
|
|
698
|
-
return /* @__PURE__ */
|
|
1249
|
+
return /* @__PURE__ */ jsx6("style", { children: FLOPAY_KEYFRAMES });
|
|
699
1250
|
}
|
|
700
1251
|
function toCssSize(value) {
|
|
701
1252
|
if (typeof value === "number") return `${value}px`;
|
|
@@ -716,8 +1267,8 @@ function ExpressCheckoutReadySwap({
|
|
|
716
1267
|
children
|
|
717
1268
|
}) {
|
|
718
1269
|
if (state === "unavailable" || state === "load_error") return null;
|
|
719
|
-
return /* @__PURE__ */
|
|
720
|
-
/* @__PURE__ */
|
|
1270
|
+
return /* @__PURE__ */ jsxs4("div", { style: { position: "relative", minHeight: 44 }, children: [
|
|
1271
|
+
/* @__PURE__ */ jsx6(
|
|
721
1272
|
"div",
|
|
722
1273
|
{
|
|
723
1274
|
"data-testid": placeholderTestId,
|
|
@@ -736,7 +1287,7 @@ function ExpressCheckoutReadySwap({
|
|
|
736
1287
|
}
|
|
737
1288
|
}
|
|
738
1289
|
),
|
|
739
|
-
/* @__PURE__ */
|
|
1290
|
+
/* @__PURE__ */ jsx6(
|
|
740
1291
|
"div",
|
|
741
1292
|
{
|
|
742
1293
|
style: {
|
|
@@ -756,7 +1307,7 @@ function isExpressCheckoutRowVisible(state) {
|
|
|
756
1307
|
}
|
|
757
1308
|
var SplitCardForm = forwardRef(
|
|
758
1309
|
function SplitCardForm2(props, ref) {
|
|
759
|
-
return /* @__PURE__ */
|
|
1310
|
+
return /* @__PURE__ */ jsx6(SplitCardFormInner, { ...props, innerRef: ref });
|
|
760
1311
|
}
|
|
761
1312
|
);
|
|
762
1313
|
function PayPalButtonInner({
|
|
@@ -773,15 +1324,15 @@ function PayPalButtonInner({
|
|
|
773
1324
|
}) {
|
|
774
1325
|
const stripe = useStripeRaw();
|
|
775
1326
|
const elements = useStripeElements();
|
|
776
|
-
const [loadState, setLoadState] =
|
|
777
|
-
|
|
1327
|
+
const [loadState, setLoadState] = useState3("loading");
|
|
1328
|
+
useEffect4(() => {
|
|
778
1329
|
onLoadStateChange?.(loadState);
|
|
779
1330
|
}, [loadState, onLoadStateChange]);
|
|
780
|
-
const [submitting, setSubmitting] =
|
|
781
|
-
const paypalResumeAttempted =
|
|
782
|
-
const beforeClickRef =
|
|
1331
|
+
const [submitting, setSubmitting] = useState3(false);
|
|
1332
|
+
const paypalResumeAttempted = useRef3(false);
|
|
1333
|
+
const beforeClickRef = useRef3(null);
|
|
783
1334
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
784
|
-
|
|
1335
|
+
useEffect4(() => {
|
|
785
1336
|
if (!stripe || paypalResumeAttempted.current) return;
|
|
786
1337
|
const params = new URLSearchParams(window.location.search);
|
|
787
1338
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -938,8 +1489,8 @@ function PayPalButtonInner({
|
|
|
938
1489
|
setSubmitting(false);
|
|
939
1490
|
}
|
|
940
1491
|
}, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]);
|
|
941
|
-
return /* @__PURE__ */
|
|
942
|
-
/* @__PURE__ */
|
|
1492
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1493
|
+
/* @__PURE__ */ jsx6(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-paypal-placeholder", children: /* @__PURE__ */ jsx6(
|
|
943
1494
|
ExpressCheckoutElement,
|
|
944
1495
|
{
|
|
945
1496
|
onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
|
|
@@ -964,7 +1515,7 @@ function PayPalButtonInner({
|
|
|
964
1515
|
}
|
|
965
1516
|
}
|
|
966
1517
|
) }),
|
|
967
|
-
submitting && /* @__PURE__ */
|
|
1518
|
+
submitting && /* @__PURE__ */ jsx6(ProcessingOverlay, { status: "processing" })
|
|
968
1519
|
] });
|
|
969
1520
|
}
|
|
970
1521
|
function WalletButtonInner({
|
|
@@ -982,14 +1533,14 @@ function WalletButtonInner({
|
|
|
982
1533
|
}) {
|
|
983
1534
|
const stripe = useStripeRaw();
|
|
984
1535
|
const elements = useStripeElements();
|
|
985
|
-
const [loadState, setLoadState] =
|
|
986
|
-
|
|
1536
|
+
const [loadState, setLoadState] = useState3("loading");
|
|
1537
|
+
useEffect4(() => {
|
|
987
1538
|
onLoadStateChange?.(loadState);
|
|
988
1539
|
}, [loadState, onLoadStateChange]);
|
|
989
|
-
const [submitting, setSubmitting] =
|
|
1540
|
+
const [submitting, setSubmitting] = useState3(false);
|
|
990
1541
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
991
|
-
const lastWalletMethodRef =
|
|
992
|
-
const beforeClickRef =
|
|
1542
|
+
const lastWalletMethodRef = useRef3("card");
|
|
1543
|
+
const beforeClickRef = useRef3(null);
|
|
993
1544
|
const handleWalletConfirm = useCallback(
|
|
994
1545
|
async (event) => {
|
|
995
1546
|
if (!stripe || !elements) return;
|
|
@@ -1079,12 +1630,16 @@ function WalletButtonInner({
|
|
|
1079
1630
|
},
|
|
1080
1631
|
[stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]
|
|
1081
1632
|
);
|
|
1082
|
-
return /* @__PURE__ */
|
|
1083
|
-
/* @__PURE__ */
|
|
1633
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1634
|
+
/* @__PURE__ */ jsx6(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-wallet-placeholder", children: /* @__PURE__ */ jsx6(
|
|
1084
1635
|
ExpressCheckoutElement,
|
|
1085
1636
|
{
|
|
1086
|
-
onReady: (event) =>
|
|
1087
|
-
|
|
1637
|
+
onReady: (event) => {
|
|
1638
|
+
setLoadState(resolveExpressCheckoutLoadState(event, ["applePay", "googlePay"]));
|
|
1639
|
+
},
|
|
1640
|
+
onLoadError: (e) => {
|
|
1641
|
+
setLoadState("load_error");
|
|
1642
|
+
},
|
|
1088
1643
|
onClick: async (event) => {
|
|
1089
1644
|
lastWalletMethodRef.current = event.expressPaymentType === "apple_pay" ? "apple_pay" : "google_pay";
|
|
1090
1645
|
const beforeClick = runBeforeButtonClick ? await runBeforeButtonClick(lastWalletMethodRef.current) : { proceed: true };
|
|
@@ -1119,7 +1674,7 @@ function WalletButtonInner({
|
|
|
1119
1674
|
}
|
|
1120
1675
|
}
|
|
1121
1676
|
) }),
|
|
1122
|
-
submitting && /* @__PURE__ */
|
|
1677
|
+
submitting && /* @__PURE__ */ jsx6(ProcessingOverlay, { status: "processing" })
|
|
1123
1678
|
] });
|
|
1124
1679
|
}
|
|
1125
1680
|
function SplitCardFormInner({
|
|
@@ -1171,6 +1726,10 @@ function SplitCardFormInner({
|
|
|
1171
1726
|
totalAmount = 0,
|
|
1172
1727
|
currency = "usd",
|
|
1173
1728
|
initialCardOpen = false,
|
|
1729
|
+
directPaypal,
|
|
1730
|
+
isSubscription = false,
|
|
1731
|
+
session,
|
|
1732
|
+
debug = false,
|
|
1174
1733
|
innerRef
|
|
1175
1734
|
}) {
|
|
1176
1735
|
const flopay = useFloPay();
|
|
@@ -1178,25 +1737,25 @@ function SplitCardFormInner({
|
|
|
1178
1737
|
const elements = useElements();
|
|
1179
1738
|
const checkout = useContext3(CheckoutContext);
|
|
1180
1739
|
const contextBillingUrl = useBillingApiUrl();
|
|
1181
|
-
const [processing, setProcessing] =
|
|
1182
|
-
const [error, setError] =
|
|
1183
|
-
const [is3DSActive, setIs3DSActive] =
|
|
1184
|
-
const [selectedCountry, setSelectedCountry] =
|
|
1185
|
-
const [zipCode, setZipCode] =
|
|
1186
|
-
const [addressLine1, setAddressLine1] =
|
|
1187
|
-
const [addressLine2, setAddressLine2] =
|
|
1188
|
-
const [city, setCity] =
|
|
1189
|
-
const [stateValue, setStateValue] =
|
|
1190
|
-
const [accountPatch, setAccountPatch] =
|
|
1191
|
-
const zipCodeRef =
|
|
1192
|
-
const selectedCountryRef =
|
|
1193
|
-
const addressLine1Ref =
|
|
1194
|
-
const addressLine2Ref =
|
|
1195
|
-
const cityRef =
|
|
1196
|
-
const stateRef =
|
|
1197
|
-
const avsConfig =
|
|
1740
|
+
const [processing, setProcessing] = useState3(false);
|
|
1741
|
+
const [error, setError] = useState3(null);
|
|
1742
|
+
const [is3DSActive, setIs3DSActive] = useState3(false);
|
|
1743
|
+
const [selectedCountry, setSelectedCountry] = useState3(countryProp ?? "US");
|
|
1744
|
+
const [zipCode, setZipCode] = useState3(zipProp ?? "");
|
|
1745
|
+
const [addressLine1, setAddressLine1] = useState3(addressLine1Prop ?? "");
|
|
1746
|
+
const [addressLine2, setAddressLine2] = useState3(addressLine2Prop ?? "");
|
|
1747
|
+
const [city, setCity] = useState3(cityProp ?? "");
|
|
1748
|
+
const [stateValue, setStateValue] = useState3(stateProp ?? "");
|
|
1749
|
+
const [accountPatch, setAccountPatch] = useState3({});
|
|
1750
|
+
const zipCodeRef = useRef3(zipProp ?? "");
|
|
1751
|
+
const selectedCountryRef = useRef3(countryProp ?? "US");
|
|
1752
|
+
const addressLine1Ref = useRef3(addressLine1Prop ?? "");
|
|
1753
|
+
const addressLine2Ref = useRef3(addressLine2Prop ?? "");
|
|
1754
|
+
const cityRef = useRef3(cityProp ?? "");
|
|
1755
|
+
const stateRef = useRef3(stateProp ?? "");
|
|
1756
|
+
const avsConfig = useMemo3(() => resolveAVSConfig(enableAVSProp), [enableAVSProp]);
|
|
1198
1757
|
const enableAVS = avsConfig !== null;
|
|
1199
|
-
const [viewState, setViewState] =
|
|
1758
|
+
const [viewState, setViewState] = useState3(initialCardOpen ? "card" : "buttons");
|
|
1200
1759
|
const showCardForm = viewState === "expanding" || viewState === "card";
|
|
1201
1760
|
const TRANSITION_MS = 280;
|
|
1202
1761
|
const expandToCard = useCallback(() => {
|
|
@@ -1207,18 +1766,23 @@ function SplitCardFormInner({
|
|
|
1207
1766
|
setViewState("collapsing");
|
|
1208
1767
|
setTimeout(() => setViewState("buttons"), TRANSITION_MS);
|
|
1209
1768
|
}, []);
|
|
1210
|
-
|
|
1769
|
+
useEffect4(() => {
|
|
1211
1770
|
if (layout === "buttons" && initialCardOpen) {
|
|
1212
1771
|
setViewState("card");
|
|
1213
1772
|
}
|
|
1214
1773
|
}, [layout, initialCardOpen]);
|
|
1215
|
-
const [fullName, setFullName] =
|
|
1216
|
-
const [formReady, setFormReady] =
|
|
1217
|
-
const [overlayStatus, setOverlayStatus] =
|
|
1218
|
-
const processingRef =
|
|
1774
|
+
const [fullName, setFullName] = useState3("");
|
|
1775
|
+
const [formReady, setFormReady] = useState3(false);
|
|
1776
|
+
const [overlayStatus, setOverlayStatus] = useState3(null);
|
|
1777
|
+
const processingRef = useRef3(false);
|
|
1778
|
+
const [paypalDirectRetry, setPaypalDirectRetry] = useState3(null);
|
|
1779
|
+
const paypalDirectRetryRef = useRef3(paypalDirectRetry);
|
|
1780
|
+
useEffect4(() => {
|
|
1781
|
+
paypalDirectRetryRef.current = paypalDirectRetry;
|
|
1782
|
+
}, [paypalDirectRetry]);
|
|
1219
1783
|
const resolvedBillingApiUrl = billingApiUrl || contextBillingUrl;
|
|
1220
1784
|
const displayError = externalError ?? error;
|
|
1221
|
-
const bStyles =
|
|
1785
|
+
const bStyles = useMemo3(() => {
|
|
1222
1786
|
const base = resolveButtonsLayoutTheme(buttonsTheme);
|
|
1223
1787
|
if (!buttonsStylesOverride) return base;
|
|
1224
1788
|
return {
|
|
@@ -1236,7 +1800,7 @@ function SplitCardFormInner({
|
|
|
1236
1800
|
const isSubmitting = (externalProcessing ?? processing) || isInlineSessionPatchProcessing;
|
|
1237
1801
|
const isSelfContained = !onTokenizedBody;
|
|
1238
1802
|
const baseUrl = resolvedBillingApiUrl.replace(/\/+$/, "");
|
|
1239
|
-
const resolvedAccount =
|
|
1803
|
+
const resolvedAccount = useMemo3(() => mergeAccountPatch({
|
|
1240
1804
|
userId,
|
|
1241
1805
|
email,
|
|
1242
1806
|
firstName,
|
|
@@ -1244,23 +1808,23 @@ function SplitCardFormInner({
|
|
|
1244
1808
|
country: countryProp,
|
|
1245
1809
|
zip: zipProp
|
|
1246
1810
|
}, accountPatch), [userId, email, firstName, lastName, countryProp, zipProp, accountPatch]);
|
|
1247
|
-
const stripeInstance =
|
|
1811
|
+
const stripeInstance = useMemo3(() => {
|
|
1248
1812
|
if (!flopay) return null;
|
|
1249
1813
|
return flopay.getRawProvider();
|
|
1250
1814
|
}, [flopay]);
|
|
1251
|
-
const paypalStripeInstance =
|
|
1815
|
+
const paypalStripeInstance = useMemo3(() => {
|
|
1252
1816
|
if (!paypalFlopay) return null;
|
|
1253
1817
|
return paypalFlopay.getRawProvider();
|
|
1254
1818
|
}, [paypalFlopay]);
|
|
1255
1819
|
const amountInCents = totalAmount || 100;
|
|
1256
|
-
const walletOptions =
|
|
1820
|
+
const walletOptions = useMemo3(() => ({
|
|
1257
1821
|
mode: "payment",
|
|
1258
1822
|
amount: amountInCents,
|
|
1259
1823
|
currency: currency.toLowerCase(),
|
|
1260
1824
|
paymentMethodCreation: "manual",
|
|
1261
1825
|
captureMethod: "manual"
|
|
1262
1826
|
}), [amountInCents, currency]);
|
|
1263
|
-
const paypalOptions =
|
|
1827
|
+
const paypalOptions = useMemo3(() => ({
|
|
1264
1828
|
mode: "payment",
|
|
1265
1829
|
amount: amountInCents,
|
|
1266
1830
|
currency: currency.toLowerCase(),
|
|
@@ -1281,17 +1845,20 @@ function SplitCardFormInner({
|
|
|
1281
1845
|
[onDecline]
|
|
1282
1846
|
);
|
|
1283
1847
|
const showWallets = showApplePay || showGooglePay;
|
|
1284
|
-
const [paypalLoadState, setPaypalLoadState] =
|
|
1285
|
-
const [walletLoadState, setWalletLoadState] =
|
|
1286
|
-
const [
|
|
1287
|
-
|
|
1848
|
+
const [paypalLoadState, setPaypalLoadState] = useState3("loading");
|
|
1849
|
+
const [walletLoadState, setWalletLoadState] = useState3("loading");
|
|
1850
|
+
const [directPaypalReady, setDirectPaypalReady] = useState3(false);
|
|
1851
|
+
const [inAppBrowserDetected, setInAppBrowserDetected] = useState3();
|
|
1852
|
+
useEffect4(() => {
|
|
1288
1853
|
setInAppBrowserDetected(isInAppBrowser());
|
|
1289
1854
|
}, []);
|
|
1290
|
-
const
|
|
1291
|
-
const
|
|
1292
|
-
const
|
|
1855
|
+
const directPaypalConfigured = !!directPaypal?.clientId;
|
|
1856
|
+
const shouldShowPayPal = showPayPal && (directPaypalConfigured || inAppBrowserDetected === false);
|
|
1857
|
+
const shouldShowWallets = showWallets;
|
|
1858
|
+
const shouldRenderDirectPayPal = shouldShowPayPal && directPaypalConfigured;
|
|
1859
|
+
const shouldRenderStripePayPal = shouldShowPayPal && !directPaypalConfigured && !!paypalStripeInstance;
|
|
1293
1860
|
const shouldRenderWallets = shouldShowWallets && !!stripeInstance;
|
|
1294
|
-
const shouldDisplayPayPalRow =
|
|
1861
|
+
const shouldDisplayPayPalRow = shouldRenderDirectPayPal ? directPaypalReady : shouldRenderStripePayPal && isExpressCheckoutRowVisible(paypalLoadState);
|
|
1295
1862
|
const shouldDisplayWalletRow = shouldRenderWallets && isExpressCheckoutRowVisible(walletLoadState);
|
|
1296
1863
|
const handleNameChange = useCallback((value) => {
|
|
1297
1864
|
setFullName(value);
|
|
@@ -1365,7 +1932,7 @@ function SplitCardFormInner({
|
|
|
1365
1932
|
const resolvedCompletionPaymentMethodId = overrides?.completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);
|
|
1366
1933
|
const requestTokenizedBody = tokenizedBody.originalPaymentMethodId ? { ...tokenizedBody, originalPaymentMethodId: void 0 } : tokenizedBody;
|
|
1367
1934
|
try {
|
|
1368
|
-
const api = new
|
|
1935
|
+
const api = new PaymentAPI2(baseUrl);
|
|
1369
1936
|
const response = await api.processPayment(effectiveAccount.userId ?? "", {
|
|
1370
1937
|
sessionId: effectiveSessionId,
|
|
1371
1938
|
tokenizedData: requestTokenizedBody,
|
|
@@ -1410,6 +1977,7 @@ function SplitCardFormInner({
|
|
|
1410
1977
|
if (response.ok) {
|
|
1411
1978
|
markSessionRecentlyCompleted(effectiveSessionId);
|
|
1412
1979
|
setOverlayStatus("success");
|
|
1980
|
+
setPaypalDirectRetry(null);
|
|
1413
1981
|
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));
|
|
1414
1982
|
onComplete?.({
|
|
1415
1983
|
status: "succeeded",
|
|
@@ -1517,6 +2085,24 @@ function SplitCardFormInner({
|
|
|
1517
2085
|
}
|
|
1518
2086
|
return;
|
|
1519
2087
|
}
|
|
2088
|
+
if (json?.type === "paypal_direct_required") {
|
|
2089
|
+
const orderId = json["orderId"];
|
|
2090
|
+
if (!orderId) {
|
|
2091
|
+
setOverlayStatus("error");
|
|
2092
|
+
updateError("PayPal retry required but no order id provided.");
|
|
2093
|
+
return;
|
|
2094
|
+
}
|
|
2095
|
+
const prevAttempts = paypalDirectRetryRef.current?.attempts ?? 0;
|
|
2096
|
+
if (prevAttempts >= 2) {
|
|
2097
|
+
setOverlayStatus("error");
|
|
2098
|
+
updateError("PayPal payment could not be completed after multiple attempts.");
|
|
2099
|
+
emitDecline("paypal", "paypal_direct_required retry limit exceeded");
|
|
2100
|
+
return;
|
|
2101
|
+
}
|
|
2102
|
+
setPaypalDirectRetry({ orderId, attempts: prevAttempts + 1 });
|
|
2103
|
+
setOverlayStatus(null);
|
|
2104
|
+
return;
|
|
2105
|
+
}
|
|
1520
2106
|
setOverlayStatus("error");
|
|
1521
2107
|
const message = json?.message ?? "Payment failed. Please try again.";
|
|
1522
2108
|
updateError(message);
|
|
@@ -1574,7 +2160,7 @@ function SplitCardFormInner({
|
|
|
1574
2160
|
}
|
|
1575
2161
|
}
|
|
1576
2162
|
}), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
|
|
1577
|
-
|
|
2163
|
+
useEffect4(() => {
|
|
1578
2164
|
if (typeof window === "undefined") return;
|
|
1579
2165
|
const stored = localStorage.getItem(WALLET_RESUME_KEY);
|
|
1580
2166
|
if (!stored) return;
|
|
@@ -1658,7 +2244,7 @@ function SplitCardFormInner({
|
|
|
1658
2244
|
return;
|
|
1659
2245
|
}
|
|
1660
2246
|
if (!sessionId || !resolvedAccount.email) {
|
|
1661
|
-
throw new
|
|
2247
|
+
throw new FloPayError3("Missing sessionId or email", "validation_error");
|
|
1662
2248
|
}
|
|
1663
2249
|
const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
|
|
1664
2250
|
method: "POST",
|
|
@@ -1684,7 +2270,7 @@ function SplitCardFormInner({
|
|
|
1684
2270
|
}
|
|
1685
2271
|
const intentJson = await intentResponse.json();
|
|
1686
2272
|
const intentClientSecret = intentJson.data?.id;
|
|
1687
|
-
if (!intentClientSecret) throw new
|
|
2273
|
+
if (!intentClientSecret) throw new FloPayError3("No client_secret in payment intent response", "api_error");
|
|
1688
2274
|
const confirmResult = await flopay.confirmCardPayment({
|
|
1689
2275
|
clientSecret: intentClientSecret,
|
|
1690
2276
|
paymentMethodId: pmResult.paymentMethodId
|
|
@@ -1705,7 +2291,7 @@ function SplitCardFormInner({
|
|
|
1705
2291
|
const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
|
|
1706
2292
|
const paymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? pmResult.paymentMethodId;
|
|
1707
2293
|
if (!paymentIntentId) {
|
|
1708
|
-
const error2 = new
|
|
2294
|
+
const error2 = new FloPayError3("No payment intent returned after confirmation.", "api_error");
|
|
1709
2295
|
setOverlayStatus("error");
|
|
1710
2296
|
updateError(error2.message);
|
|
1711
2297
|
onError?.(error2);
|
|
@@ -1734,7 +2320,7 @@ function SplitCardFormInner({
|
|
|
1734
2320
|
);
|
|
1735
2321
|
const isReady = flopay !== null && elements !== null;
|
|
1736
2322
|
if (!isReady) {
|
|
1737
|
-
return /* @__PURE__ */
|
|
2323
|
+
return /* @__PURE__ */ jsx6("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
|
|
1738
2324
|
}
|
|
1739
2325
|
const isButtons = layout === "buttons";
|
|
1740
2326
|
const resolvedBorder = isButtons ? bStyles.cardInputBorder ?? "#e5e7eb" : "#A4A4FF";
|
|
@@ -1777,7 +2363,7 @@ function SplitCardFormInner({
|
|
|
1777
2363
|
invalid: { color: "#ef4444" }
|
|
1778
2364
|
}
|
|
1779
2365
|
};
|
|
1780
|
-
const cardFormBlock = /* @__PURE__ */
|
|
2366
|
+
const cardFormBlock = /* @__PURE__ */ jsxs4("div", { style: {
|
|
1781
2367
|
backgroundColor: cardBg,
|
|
1782
2368
|
borderRadius: "8px",
|
|
1783
2369
|
padding: isButtons ? "0" : "1rem",
|
|
@@ -1785,7 +2371,7 @@ function SplitCardFormInner({
|
|
|
1785
2371
|
...isButtons ? { padding: bStyles.cardFormContainer?.padding ?? "0" } : {},
|
|
1786
2372
|
...sharedInputPlaceholderVars
|
|
1787
2373
|
}, children: [
|
|
1788
|
-
/* @__PURE__ */
|
|
2374
|
+
/* @__PURE__ */ jsx6("style", { children: `
|
|
1789
2375
|
.flopay-shared-input::placeholder {
|
|
1790
2376
|
color: var(--flopay-input-placeholder-color);
|
|
1791
2377
|
opacity: 1;
|
|
@@ -1794,12 +2380,12 @@ function SplitCardFormInner({
|
|
|
1794
2380
|
font-weight: var(--flopay-input-font-weight);
|
|
1795
2381
|
}
|
|
1796
2382
|
` }),
|
|
1797
|
-
isButtons && showCardForm && /* @__PURE__ */
|
|
2383
|
+
isButtons && showCardForm && /* @__PURE__ */ jsxs4("div", { style: {
|
|
1798
2384
|
display: "flex",
|
|
1799
2385
|
alignItems: "center",
|
|
1800
2386
|
padding: "0.75rem 0 0.625rem"
|
|
1801
2387
|
}, children: [
|
|
1802
|
-
/* @__PURE__ */
|
|
2388
|
+
/* @__PURE__ */ jsxs4(
|
|
1803
2389
|
"button",
|
|
1804
2390
|
{
|
|
1805
2391
|
type: "button",
|
|
@@ -1821,7 +2407,7 @@ function SplitCardFormInner({
|
|
|
1821
2407
|
},
|
|
1822
2408
|
"aria-label": "Back to payment methods",
|
|
1823
2409
|
children: [
|
|
1824
|
-
/* @__PURE__ */
|
|
2410
|
+
/* @__PURE__ */ jsx6("span", { style: {
|
|
1825
2411
|
display: "inline-flex",
|
|
1826
2412
|
alignItems: "center",
|
|
1827
2413
|
justifyContent: "center",
|
|
@@ -1831,12 +2417,12 @@ function SplitCardFormInner({
|
|
|
1831
2417
|
backgroundColor: "#f3f4f6",
|
|
1832
2418
|
transition: "background-color 0.15s",
|
|
1833
2419
|
...bStyles.backButtonIcon
|
|
1834
|
-
}, children: /* @__PURE__ */
|
|
1835
|
-
/* @__PURE__ */
|
|
2420
|
+
}, children: /* @__PURE__ */ jsx6("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx6("path", { d: "M15 18l-6-6 6-6" }) }) }),
|
|
2421
|
+
/* @__PURE__ */ jsx6(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
1836
2422
|
]
|
|
1837
2423
|
}
|
|
1838
2424
|
),
|
|
1839
|
-
hideTitle ? /* @__PURE__ */
|
|
2425
|
+
hideTitle ? /* @__PURE__ */ jsx6("div", { style: { flex: 1 } }) : /* @__PURE__ */ jsx6("div", { style: {
|
|
1840
2426
|
flex: 1,
|
|
1841
2427
|
textAlign: "center",
|
|
1842
2428
|
fontWeight: 600,
|
|
@@ -1844,18 +2430,18 @@ function SplitCardFormInner({
|
|
|
1844
2430
|
color: "#262833",
|
|
1845
2431
|
paddingRight: 80,
|
|
1846
2432
|
...bStyles.title
|
|
1847
|
-
}, children: /* @__PURE__ */
|
|
2433
|
+
}, children: /* @__PURE__ */ jsx6(TitleContentSlot, { content: cardTitleContent }) })
|
|
1848
2434
|
] }),
|
|
1849
|
-
!isButtons && !hideTitle && /* @__PURE__ */
|
|
1850
|
-
/* @__PURE__ */
|
|
2435
|
+
!isButtons && !hideTitle && /* @__PURE__ */ jsx6("div", { style: { textAlign: "center", fontWeight: 600, fontSize: "1.1rem", padding: "0.5rem 0", color: "#262833" }, children: /* @__PURE__ */ jsx6(TitleContentSlot, { content: cardTitleContent }) }),
|
|
2436
|
+
/* @__PURE__ */ jsx6("div", { style: {
|
|
1851
2437
|
backgroundColor: cardInputBg,
|
|
1852
2438
|
border: `1px solid ${resolvedBorder}`,
|
|
1853
2439
|
borderTopLeftRadius: "8px",
|
|
1854
2440
|
borderTopRightRadius: "8px",
|
|
1855
2441
|
padding: "10px"
|
|
1856
|
-
}, children: /* @__PURE__ */
|
|
1857
|
-
/* @__PURE__ */
|
|
1858
|
-
/* @__PURE__ */
|
|
2442
|
+
}, children: /* @__PURE__ */ jsx6(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
|
|
2443
|
+
/* @__PURE__ */ jsxs4("div", { style: { display: "flex" }, children: [
|
|
2444
|
+
/* @__PURE__ */ jsx6("div", { style: {
|
|
1859
2445
|
flex: 1,
|
|
1860
2446
|
backgroundColor: cardInputBg,
|
|
1861
2447
|
border: `1px solid ${resolvedBorder}`,
|
|
@@ -1863,23 +2449,23 @@ function SplitCardFormInner({
|
|
|
1863
2449
|
borderRight: "none",
|
|
1864
2450
|
borderBottomLeftRadius: "8px",
|
|
1865
2451
|
padding: "10px"
|
|
1866
|
-
}, children: /* @__PURE__ */
|
|
1867
|
-
/* @__PURE__ */
|
|
2452
|
+
}, children: /* @__PURE__ */ jsx6(CardExpiryElement, { options: stripeElementStyle }) }),
|
|
2453
|
+
/* @__PURE__ */ jsx6("div", { style: {
|
|
1868
2454
|
flex: 1,
|
|
1869
2455
|
backgroundColor: cardInputBg,
|
|
1870
2456
|
border: `1px solid ${resolvedBorder}`,
|
|
1871
2457
|
borderTop: "none",
|
|
1872
2458
|
borderBottomRightRadius: "8px",
|
|
1873
2459
|
padding: "10px"
|
|
1874
|
-
}, children: /* @__PURE__ */
|
|
2460
|
+
}, children: /* @__PURE__ */ jsx6(CardCvcElement, { options: stripeElementStyle }) })
|
|
1875
2461
|
] }),
|
|
1876
|
-
/* @__PURE__ */
|
|
2462
|
+
/* @__PURE__ */ jsx6("div", { style: {
|
|
1877
2463
|
backgroundColor: cardInputBg,
|
|
1878
2464
|
border: `1px solid ${resolvedBorder}`,
|
|
1879
2465
|
borderRadius: "8px",
|
|
1880
2466
|
marginTop: "0.5rem",
|
|
1881
2467
|
padding: "10px"
|
|
1882
|
-
}, children: /* @__PURE__ */
|
|
2468
|
+
}, children: /* @__PURE__ */ jsx6(
|
|
1883
2469
|
"input",
|
|
1884
2470
|
{
|
|
1885
2471
|
className: "flopay-shared-input",
|
|
@@ -1918,8 +2504,8 @@ function SplitCardFormInner({
|
|
|
1918
2504
|
...isButtons && bStyles.nameInput ? bStyles.nameInput : {}
|
|
1919
2505
|
});
|
|
1920
2506
|
const stateOpts = getStateOptions(cc);
|
|
1921
|
-
return /* @__PURE__ */
|
|
1922
|
-
isAVSFieldVisible(avsConfig.address_line_1, cc) && /* @__PURE__ */
|
|
2507
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
2508
|
+
isAVSFieldVisible(avsConfig.address_line_1, cc) && /* @__PURE__ */ jsx6("div", { style: inputWrapStyle(bStyles.addressLine1Input), children: /* @__PURE__ */ jsx6(
|
|
1923
2509
|
"input",
|
|
1924
2510
|
{
|
|
1925
2511
|
className: "flopay-shared-input",
|
|
@@ -1936,7 +2522,7 @@ function SplitCardFormInner({
|
|
|
1936
2522
|
style: inputFieldStyle()
|
|
1937
2523
|
}
|
|
1938
2524
|
) }),
|
|
1939
|
-
isAVSFieldVisible(avsConfig.address_line_2, cc) && /* @__PURE__ */
|
|
2525
|
+
isAVSFieldVisible(avsConfig.address_line_2, cc) && /* @__PURE__ */ jsx6("div", { style: inputWrapStyle(bStyles.addressLine2Input), children: /* @__PURE__ */ jsx6(
|
|
1940
2526
|
"input",
|
|
1941
2527
|
{
|
|
1942
2528
|
className: "flopay-shared-input",
|
|
@@ -1952,12 +2538,12 @@ function SplitCardFormInner({
|
|
|
1952
2538
|
style: inputFieldStyle()
|
|
1953
2539
|
}
|
|
1954
2540
|
) }),
|
|
1955
|
-
(isAVSFieldVisible(avsConfig.city, cc) || isAVSFieldVisible(avsConfig.state, cc)) && /* @__PURE__ */
|
|
2541
|
+
(isAVSFieldVisible(avsConfig.city, cc) || isAVSFieldVisible(avsConfig.state, cc)) && /* @__PURE__ */ jsxs4("div", { style: {
|
|
1956
2542
|
display: "flex",
|
|
1957
2543
|
gap: "0",
|
|
1958
2544
|
marginTop: "0.5rem"
|
|
1959
2545
|
}, children: [
|
|
1960
|
-
isAVSFieldVisible(avsConfig.city, cc) && /* @__PURE__ */
|
|
2546
|
+
isAVSFieldVisible(avsConfig.city, cc) && /* @__PURE__ */ jsx6("div", { style: {
|
|
1961
2547
|
flex: 1,
|
|
1962
2548
|
backgroundColor: cardInputBg,
|
|
1963
2549
|
border: `1px solid ${resolvedBorder}`,
|
|
@@ -1966,7 +2552,7 @@ function SplitCardFormInner({
|
|
|
1966
2552
|
borderBottomLeftRadius: "8px",
|
|
1967
2553
|
...isAVSFieldVisible(avsConfig.state, cc) ? { borderRight: "none", borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius: "8px" },
|
|
1968
2554
|
...isButtons && bStyles.cityInput ? bStyles.cityInput : {}
|
|
1969
|
-
}, children: /* @__PURE__ */
|
|
2555
|
+
}, children: /* @__PURE__ */ jsx6(
|
|
1970
2556
|
"input",
|
|
1971
2557
|
{
|
|
1972
2558
|
className: "flopay-shared-input",
|
|
@@ -1983,7 +2569,7 @@ function SplitCardFormInner({
|
|
|
1983
2569
|
style: inputFieldStyle()
|
|
1984
2570
|
}
|
|
1985
2571
|
) }),
|
|
1986
|
-
isAVSFieldVisible(avsConfig.state, cc) && /* @__PURE__ */
|
|
2572
|
+
isAVSFieldVisible(avsConfig.state, cc) && /* @__PURE__ */ jsx6("div", { style: {
|
|
1987
2573
|
flex: 1,
|
|
1988
2574
|
backgroundColor: cardInputBg,
|
|
1989
2575
|
border: `1px solid ${resolvedBorder}`,
|
|
@@ -1992,7 +2578,7 @@ function SplitCardFormInner({
|
|
|
1992
2578
|
borderBottomRightRadius: "8px",
|
|
1993
2579
|
...isAVSFieldVisible(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius: "8px" },
|
|
1994
2580
|
...isButtons && bStyles.stateInput ? bStyles.stateInput : {}
|
|
1995
|
-
}, children: stateOpts ? /* @__PURE__ */
|
|
2581
|
+
}, children: stateOpts ? /* @__PURE__ */ jsxs4(
|
|
1996
2582
|
"select",
|
|
1997
2583
|
{
|
|
1998
2584
|
value: stateValue,
|
|
@@ -2006,11 +2592,11 @@ function SplitCardFormInner({
|
|
|
2006
2592
|
"data-testid": "flopay-state",
|
|
2007
2593
|
style: { ...inputFieldStyle(), cursor: "pointer" },
|
|
2008
2594
|
children: [
|
|
2009
|
-
/* @__PURE__ */
|
|
2010
|
-
stateOpts.map((s) => /* @__PURE__ */
|
|
2595
|
+
/* @__PURE__ */ jsx6("option", { value: "", children: getStateLabel(cc) }),
|
|
2596
|
+
stateOpts.map((s) => /* @__PURE__ */ jsx6("option", { value: s.code, children: s.name }, s.code))
|
|
2011
2597
|
]
|
|
2012
2598
|
}
|
|
2013
|
-
) : /* @__PURE__ */
|
|
2599
|
+
) : /* @__PURE__ */ jsx6(
|
|
2014
2600
|
"input",
|
|
2015
2601
|
{
|
|
2016
2602
|
className: "flopay-shared-input",
|
|
@@ -2028,20 +2614,20 @@ function SplitCardFormInner({
|
|
|
2028
2614
|
}
|
|
2029
2615
|
) })
|
|
2030
2616
|
] }),
|
|
2031
|
-
(isAVSFieldVisible(avsConfig.country, cc) || isAVSFieldVisible(avsConfig.postal_code, cc)) && /* @__PURE__ */
|
|
2617
|
+
(isAVSFieldVisible(avsConfig.country, cc) || isAVSFieldVisible(avsConfig.postal_code, cc)) && /* @__PURE__ */ jsxs4("div", { style: {
|
|
2032
2618
|
display: "flex",
|
|
2033
2619
|
flexDirection: avsLayoutProp === "column" ? "column" : "row",
|
|
2034
2620
|
gap: avsLayoutProp === "column" ? "0.5rem" : "0",
|
|
2035
2621
|
marginTop: "0.5rem"
|
|
2036
2622
|
}, children: [
|
|
2037
|
-
isAVSFieldVisible(avsConfig.country, cc) && /* @__PURE__ */
|
|
2623
|
+
isAVSFieldVisible(avsConfig.country, cc) && /* @__PURE__ */ jsx6("div", { style: {
|
|
2038
2624
|
flex: avsLayoutProp === "row" ? 1 : void 0,
|
|
2039
2625
|
backgroundColor: cardInputBg,
|
|
2040
2626
|
border: `1px solid ${resolvedBorder}`,
|
|
2041
2627
|
padding: "10px",
|
|
2042
2628
|
...avsLayoutProp === "row" && isAVSFieldVisible(avsConfig.postal_code, cc) ? { borderRadius: "0", borderTopLeftRadius: "8px", borderBottomLeftRadius: "8px", borderRight: "none" } : { borderRadius: "8px" },
|
|
2043
2629
|
...isButtons && bStyles.countrySelect ? bStyles.countrySelect : {}
|
|
2044
|
-
}, children: /* @__PURE__ */
|
|
2630
|
+
}, children: /* @__PURE__ */ jsx6(
|
|
2045
2631
|
"select",
|
|
2046
2632
|
{
|
|
2047
2633
|
value: selectedCountry,
|
|
@@ -2056,21 +2642,21 @@ function SplitCardFormInner({
|
|
|
2056
2642
|
autoComplete: "country",
|
|
2057
2643
|
"data-testid": "flopay-country",
|
|
2058
2644
|
style: { ...inputFieldStyle(), cursor: "pointer" },
|
|
2059
|
-
children: COUNTRY_OPTIONS.map((c) => /* @__PURE__ */
|
|
2645
|
+
children: COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ jsxs4("option", { value: c.code, children: [
|
|
2060
2646
|
c.flag,
|
|
2061
2647
|
" ",
|
|
2062
2648
|
c.name
|
|
2063
2649
|
] }, c.code))
|
|
2064
2650
|
}
|
|
2065
2651
|
) }),
|
|
2066
|
-
isAVSFieldVisible(avsConfig.postal_code, cc) && /* @__PURE__ */
|
|
2652
|
+
isAVSFieldVisible(avsConfig.postal_code, cc) && /* @__PURE__ */ jsx6("div", { style: {
|
|
2067
2653
|
flex: avsLayoutProp === "row" ? 1 : void 0,
|
|
2068
2654
|
backgroundColor: cardInputBg,
|
|
2069
2655
|
border: `1px solid ${resolvedBorder}`,
|
|
2070
2656
|
padding: "10px",
|
|
2071
2657
|
...avsLayoutProp === "row" && isAVSFieldVisible(avsConfig.country, cc) ? { borderRadius: "0", borderTopRightRadius: "8px", borderBottomRightRadius: "8px" } : { borderRadius: "8px" },
|
|
2072
2658
|
...isButtons && bStyles.zipInput ? bStyles.zipInput : {}
|
|
2073
|
-
}, children: /* @__PURE__ */
|
|
2659
|
+
}, children: /* @__PURE__ */ jsx6(
|
|
2074
2660
|
"input",
|
|
2075
2661
|
{
|
|
2076
2662
|
className: "flopay-shared-input",
|
|
@@ -2091,7 +2677,7 @@ function SplitCardFormInner({
|
|
|
2091
2677
|
] })
|
|
2092
2678
|
] });
|
|
2093
2679
|
})(),
|
|
2094
|
-
displayError && /* @__PURE__ */
|
|
2680
|
+
displayError && /* @__PURE__ */ jsxs4("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
2095
2681
|
margin: "0.75rem 0",
|
|
2096
2682
|
padding: "0.625rem 0.875rem",
|
|
2097
2683
|
background: "#FEF2F2",
|
|
@@ -2105,10 +2691,10 @@ function SplitCardFormInner({
|
|
|
2105
2691
|
gap: "0.5rem",
|
|
2106
2692
|
...isButtons && bStyles.errorBanner ? bStyles.errorBanner : {}
|
|
2107
2693
|
}, children: [
|
|
2108
|
-
/* @__PURE__ */
|
|
2694
|
+
/* @__PURE__ */ jsx6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx6("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" }) }),
|
|
2109
2695
|
displayError
|
|
2110
2696
|
] }),
|
|
2111
|
-
children ?? /* @__PURE__ */
|
|
2697
|
+
children ?? /* @__PURE__ */ jsx6(
|
|
2112
2698
|
"button",
|
|
2113
2699
|
{
|
|
2114
2700
|
type: "submit",
|
|
@@ -2131,7 +2717,7 @@ function SplitCardFormInner({
|
|
|
2131
2717
|
children: isSubmitting ? "PROCESSING..." : submitLabel
|
|
2132
2718
|
}
|
|
2133
2719
|
),
|
|
2134
|
-
!isButtons && showSecurityFooter && /* @__PURE__ */
|
|
2720
|
+
!isButtons && showSecurityFooter && /* @__PURE__ */ jsx6("div", { style: {
|
|
2135
2721
|
backgroundColor: "#EFF9F0",
|
|
2136
2722
|
borderRadius: "8px",
|
|
2137
2723
|
padding: "0.75rem",
|
|
@@ -2148,11 +2734,11 @@ function SplitCardFormInner({
|
|
|
2148
2734
|
const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
2149
2735
|
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;
|
|
2150
2736
|
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;
|
|
2151
|
-
return /* @__PURE__ */
|
|
2152
|
-
/* @__PURE__ */
|
|
2153
|
-
overlayStatus && /* @__PURE__ */
|
|
2154
|
-
/* @__PURE__ */
|
|
2155
|
-
/* @__PURE__ */
|
|
2737
|
+
return /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
2738
|
+
/* @__PURE__ */ jsx6(FloPayKeyframes, {}),
|
|
2739
|
+
overlayStatus && /* @__PURE__ */ jsx6(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
2740
|
+
/* @__PURE__ */ jsxs4("div", { style: { display: "grid" }, children: [
|
|
2741
|
+
/* @__PURE__ */ jsxs4("div", { style: {
|
|
2156
2742
|
gridArea: "1 / 1",
|
|
2157
2743
|
display: "flex",
|
|
2158
2744
|
flexDirection: "column",
|
|
@@ -2161,7 +2747,75 @@ function SplitCardFormInner({
|
|
|
2161
2747
|
...!isButtonsView && !buttonsAnim ? { visibility: "hidden", position: "absolute", pointerEvents: "none", width: "100%" } : {},
|
|
2162
2748
|
...buttonsAnim ? { animation: buttonsAnim, pointerEvents: "none" } : {}
|
|
2163
2749
|
}, children: [
|
|
2164
|
-
|
|
2750
|
+
debug && showPayPal && /* @__PURE__ */ jsx6(
|
|
2751
|
+
"pre",
|
|
2752
|
+
{
|
|
2753
|
+
"data-testid": "flopay-direct-paypal-gate-debug",
|
|
2754
|
+
style: {
|
|
2755
|
+
margin: 0,
|
|
2756
|
+
padding: "6px 8px",
|
|
2757
|
+
background: "#eef2ff",
|
|
2758
|
+
border: "1px solid #c7d2fe",
|
|
2759
|
+
borderRadius: 6,
|
|
2760
|
+
color: "#111827",
|
|
2761
|
+
font: "11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
2762
|
+
whiteSpace: "pre-wrap",
|
|
2763
|
+
wordBreak: "break-word"
|
|
2764
|
+
},
|
|
2765
|
+
children: [
|
|
2766
|
+
"FloPay/DirectPayPal-debug (parent gate)",
|
|
2767
|
+
` showPayPal=${showPayPal}`,
|
|
2768
|
+
` directPaypalConfigured=${directPaypalConfigured}`,
|
|
2769
|
+
` inAppBrowserDetected=${String(inAppBrowserDetected)}`,
|
|
2770
|
+
` shouldRenderDirectPayPal=${shouldRenderDirectPayPal}`,
|
|
2771
|
+
` shouldRenderStripePayPal=${shouldRenderStripePayPal}`,
|
|
2772
|
+
` hasPaypalStripeInstance=${!!paypalStripeInstance}`
|
|
2773
|
+
].join("\n")
|
|
2774
|
+
}
|
|
2775
|
+
),
|
|
2776
|
+
shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
2777
|
+
paypalDirectRetry && /* @__PURE__ */ jsx6(
|
|
2778
|
+
"div",
|
|
2779
|
+
{
|
|
2780
|
+
"data-testid": "flopay-paypal-direct-retry-notice",
|
|
2781
|
+
style: {
|
|
2782
|
+
padding: "8px 10px",
|
|
2783
|
+
background: "#fef3c7",
|
|
2784
|
+
border: "1px solid #fcd34d",
|
|
2785
|
+
borderRadius: 6,
|
|
2786
|
+
color: "#78350f",
|
|
2787
|
+
fontSize: 13,
|
|
2788
|
+
lineHeight: 1.4
|
|
2789
|
+
},
|
|
2790
|
+
children: "Please confirm your PayPal payment to complete checkout."
|
|
2791
|
+
}
|
|
2792
|
+
),
|
|
2793
|
+
/* @__PURE__ */ jsx6(
|
|
2794
|
+
DirectPayPalButton,
|
|
2795
|
+
{
|
|
2796
|
+
sessionId,
|
|
2797
|
+
billingApiUrl: resolvedBillingApiUrl,
|
|
2798
|
+
email: resolvedAccount.email,
|
|
2799
|
+
clientId: directPaypal.clientId,
|
|
2800
|
+
environment: directPaypal.environment,
|
|
2801
|
+
currency: currency.toUpperCase(),
|
|
2802
|
+
isSubscription,
|
|
2803
|
+
onTokenizedBody: dispatchTokenizedBody,
|
|
2804
|
+
onComplete,
|
|
2805
|
+
onErrorChange: updateError,
|
|
2806
|
+
onDecline,
|
|
2807
|
+
onButtonClick,
|
|
2808
|
+
runBeforeButtonClick,
|
|
2809
|
+
isProcessing: isSubmitting,
|
|
2810
|
+
onLoadStateChange: setDirectPaypalReady,
|
|
2811
|
+
session: session ?? null,
|
|
2812
|
+
existingOrderId: paypalDirectRetry?.orderId,
|
|
2813
|
+
debug
|
|
2814
|
+
},
|
|
2815
|
+
paypalDirectRetry?.orderId ?? "fresh"
|
|
2816
|
+
)
|
|
2817
|
+
] }),
|
|
2818
|
+
shouldRenderStripePayPal && /* @__PURE__ */ jsx6(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx6(
|
|
2165
2819
|
PayPalButtonInner,
|
|
2166
2820
|
{
|
|
2167
2821
|
sessionId,
|
|
@@ -2176,7 +2830,7 @@ function SplitCardFormInner({
|
|
|
2176
2830
|
onLoadStateChange: setPaypalLoadState
|
|
2177
2831
|
}
|
|
2178
2832
|
) }),
|
|
2179
|
-
shouldRenderWallets ? /* @__PURE__ */
|
|
2833
|
+
shouldRenderWallets ? /* @__PURE__ */ jsx6(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx6(
|
|
2180
2834
|
WalletButtonInner,
|
|
2181
2835
|
{
|
|
2182
2836
|
sessionId,
|
|
@@ -2191,8 +2845,8 @@ function SplitCardFormInner({
|
|
|
2191
2845
|
runBeforeButtonClick,
|
|
2192
2846
|
onLoadStateChange: setWalletLoadState
|
|
2193
2847
|
}
|
|
2194
|
-
) }) : shouldShowWallets ? /* @__PURE__ */
|
|
2195
|
-
/* @__PURE__ */
|
|
2848
|
+
) }) : shouldShowWallets ? /* @__PURE__ */ jsx6("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
|
|
2849
|
+
/* @__PURE__ */ jsx6(
|
|
2196
2850
|
"button",
|
|
2197
2851
|
{
|
|
2198
2852
|
type: "button",
|
|
@@ -2230,10 +2884,10 @@ function SplitCardFormInner({
|
|
|
2230
2884
|
onMouseUp: (e) => {
|
|
2231
2885
|
e.currentTarget.style.transform = "scale(1)";
|
|
2232
2886
|
},
|
|
2233
|
-
children: /* @__PURE__ */
|
|
2887
|
+
children: /* @__PURE__ */ jsx6(CardButtonContentSlot, { content: cardButtonContent })
|
|
2234
2888
|
}
|
|
2235
2889
|
),
|
|
2236
|
-
displayError && viewState === "buttons" && /* @__PURE__ */
|
|
2890
|
+
displayError && viewState === "buttons" && /* @__PURE__ */ jsxs4("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
2237
2891
|
margin: "0.25rem 0",
|
|
2238
2892
|
padding: "0.625rem 0.875rem",
|
|
2239
2893
|
background: "#FEF2F2",
|
|
@@ -2247,11 +2901,11 @@ function SplitCardFormInner({
|
|
|
2247
2901
|
gap: "0.5rem",
|
|
2248
2902
|
...bStyles.errorBanner ? bStyles.errorBanner : {}
|
|
2249
2903
|
}, children: [
|
|
2250
|
-
/* @__PURE__ */
|
|
2904
|
+
/* @__PURE__ */ jsx6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx6("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" }) }),
|
|
2251
2905
|
displayError
|
|
2252
2906
|
] })
|
|
2253
2907
|
] }),
|
|
2254
|
-
isCardView && /* @__PURE__ */
|
|
2908
|
+
isCardView && /* @__PURE__ */ jsx6("div", { style: {
|
|
2255
2909
|
gridArea: "1 / 1",
|
|
2256
2910
|
...cardAnim ? { animation: cardAnim } : {},
|
|
2257
2911
|
...viewState === "collapsing" ? { pointerEvents: "none" } : {}
|
|
@@ -2259,37 +2913,111 @@ function SplitCardFormInner({
|
|
|
2259
2913
|
] })
|
|
2260
2914
|
] });
|
|
2261
2915
|
}
|
|
2262
|
-
return /* @__PURE__ */
|
|
2263
|
-
/* @__PURE__ */
|
|
2264
|
-
overlayStatus && /* @__PURE__ */
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2916
|
+
return /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
2917
|
+
/* @__PURE__ */ jsx6(FloPayKeyframes, {}),
|
|
2918
|
+
overlayStatus && /* @__PURE__ */ jsx6(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
2919
|
+
/* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
2920
|
+
debug && showPayPal && /* @__PURE__ */ jsx6(
|
|
2921
|
+
"pre",
|
|
2922
|
+
{
|
|
2923
|
+
"data-testid": "flopay-direct-paypal-gate-debug-default",
|
|
2924
|
+
style: {
|
|
2925
|
+
margin: 0,
|
|
2926
|
+
padding: "6px 8px",
|
|
2927
|
+
background: "#eef2ff",
|
|
2928
|
+
border: "1px solid #c7d2fe",
|
|
2929
|
+
borderRadius: 6,
|
|
2930
|
+
color: "#111827",
|
|
2931
|
+
font: "11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
2932
|
+
whiteSpace: "pre-wrap",
|
|
2933
|
+
wordBreak: "break-word"
|
|
2934
|
+
},
|
|
2935
|
+
children: [
|
|
2936
|
+
"FloPay/DirectPayPal-debug (parent gate)",
|
|
2937
|
+
` showPayPal=${showPayPal}`,
|
|
2938
|
+
` directPaypalConfigured=${directPaypalConfigured}`,
|
|
2939
|
+
` inAppBrowserDetected=${String(inAppBrowserDetected)}`,
|
|
2940
|
+
` shouldRenderDirectPayPal=${shouldRenderDirectPayPal}`,
|
|
2941
|
+
` shouldRenderStripePayPal=${shouldRenderStripePayPal}`,
|
|
2942
|
+
` hasPaypalStripeInstance=${!!paypalStripeInstance}`
|
|
2943
|
+
].join("\n")
|
|
2944
|
+
}
|
|
2945
|
+
),
|
|
2946
|
+
shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
2947
|
+
paypalDirectRetry && /* @__PURE__ */ jsx6(
|
|
2948
|
+
"div",
|
|
2949
|
+
{
|
|
2950
|
+
"data-testid": "flopay-paypal-direct-retry-notice-default",
|
|
2951
|
+
style: {
|
|
2952
|
+
padding: "8px 10px",
|
|
2953
|
+
background: "#fef3c7",
|
|
2954
|
+
border: "1px solid #fcd34d",
|
|
2955
|
+
borderRadius: 6,
|
|
2956
|
+
color: "#78350f",
|
|
2957
|
+
fontSize: 13,
|
|
2958
|
+
lineHeight: 1.4
|
|
2959
|
+
},
|
|
2960
|
+
children: "Please confirm your PayPal payment to complete checkout."
|
|
2961
|
+
}
|
|
2962
|
+
),
|
|
2963
|
+
/* @__PURE__ */ jsx6(
|
|
2964
|
+
DirectPayPalButton,
|
|
2965
|
+
{
|
|
2966
|
+
sessionId,
|
|
2967
|
+
billingApiUrl: resolvedBillingApiUrl,
|
|
2968
|
+
email: resolvedAccount.email,
|
|
2969
|
+
clientId: directPaypal.clientId,
|
|
2970
|
+
environment: directPaypal.environment,
|
|
2971
|
+
currency: currency.toUpperCase(),
|
|
2972
|
+
isSubscription,
|
|
2973
|
+
onTokenizedBody: dispatchTokenizedBody,
|
|
2974
|
+
onComplete,
|
|
2975
|
+
onErrorChange: updateError,
|
|
2976
|
+
onDecline,
|
|
2977
|
+
onButtonClick,
|
|
2978
|
+
runBeforeButtonClick,
|
|
2979
|
+
isProcessing: isSubmitting,
|
|
2980
|
+
onLoadStateChange: setDirectPaypalReady,
|
|
2981
|
+
session: session ?? null,
|
|
2982
|
+
existingOrderId: paypalDirectRetry?.orderId,
|
|
2983
|
+
debug
|
|
2984
|
+
},
|
|
2985
|
+
paypalDirectRetry?.orderId ?? "fresh"
|
|
2986
|
+
)
|
|
2987
|
+
] }),
|
|
2988
|
+
shouldRenderStripePayPal && /* @__PURE__ */ jsx6(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx6(
|
|
2989
|
+
PayPalButtonInner,
|
|
2990
|
+
{
|
|
2991
|
+
sessionId,
|
|
2992
|
+
email: resolvedAccount.email,
|
|
2993
|
+
billingApiUrl: resolvedBillingApiUrl,
|
|
2994
|
+
onTokenizedBody: dispatchTokenizedBody,
|
|
2995
|
+
onErrorChange: updateError,
|
|
2996
|
+
isProcessing: isSubmitting,
|
|
2997
|
+
onButtonClick,
|
|
2998
|
+
onDecline,
|
|
2999
|
+
runBeforeButtonClick,
|
|
3000
|
+
onLoadStateChange: setPaypalLoadState
|
|
3001
|
+
}
|
|
3002
|
+
) }),
|
|
3003
|
+
shouldRenderWallets && /* @__PURE__ */ jsx6(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx6(
|
|
3004
|
+
WalletButtonInner,
|
|
3005
|
+
{
|
|
3006
|
+
sessionId,
|
|
3007
|
+
email: resolvedAccount.email,
|
|
3008
|
+
billingApiUrl: resolvedBillingApiUrl,
|
|
3009
|
+
showApplePay,
|
|
3010
|
+
showGooglePay,
|
|
3011
|
+
onTokenizedBody: dispatchTokenizedBody,
|
|
3012
|
+
onErrorChange: updateError,
|
|
3013
|
+
onButtonClick,
|
|
3014
|
+
onDecline,
|
|
3015
|
+
runBeforeButtonClick,
|
|
3016
|
+
onLoadStateChange: setWalletLoadState
|
|
3017
|
+
}
|
|
3018
|
+
) })
|
|
3019
|
+
] }),
|
|
3020
|
+
(shouldDisplayWalletRow || shouldDisplayPayPalRow) && /* @__PURE__ */ jsxs4("div", { style: {
|
|
2293
3021
|
display: "flex",
|
|
2294
3022
|
alignItems: "center",
|
|
2295
3023
|
gap: "0.75rem",
|
|
@@ -2297,17 +3025,17 @@ function SplitCardFormInner({
|
|
|
2297
3025
|
color: "#999",
|
|
2298
3026
|
fontSize: "0.85rem"
|
|
2299
3027
|
}, children: [
|
|
2300
|
-
/* @__PURE__ */
|
|
2301
|
-
/* @__PURE__ */
|
|
2302
|
-
/* @__PURE__ */
|
|
3028
|
+
/* @__PURE__ */ jsx6("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } }),
|
|
3029
|
+
/* @__PURE__ */ jsx6("span", { children: "or pay with card" }),
|
|
3030
|
+
/* @__PURE__ */ jsx6("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
|
|
2303
3031
|
] }),
|
|
2304
3032
|
cardFormBlock
|
|
2305
3033
|
] });
|
|
2306
3034
|
}
|
|
2307
3035
|
|
|
2308
3036
|
// src/saved-payment-flow.ts
|
|
2309
|
-
import { loadFloPay, PaymentAPI as
|
|
2310
|
-
import { FloPayError as
|
|
3037
|
+
import { loadFloPay, PaymentAPI as PaymentAPI3 } from "@flopay/js";
|
|
3038
|
+
import { FloPayError as FloPayError4 } from "@flopay/shared";
|
|
2311
3039
|
var DEFAULT_SAVED_PAYMENT_DECLINE_METHOD = "card";
|
|
2312
3040
|
function getRedirectResultFromCheckoutProcessError(error) {
|
|
2313
3041
|
if (!error?.type || !error.threeDSecureToken) {
|
|
@@ -2325,7 +3053,7 @@ function getRedirectResultFromCheckoutProcessError(error) {
|
|
|
2325
3053
|
function checkoutProcessErrorToFloPayError(error, fallbackMessage = "Payment failed. Please try again.", options) {
|
|
2326
3054
|
const checkoutMethod = options?.checkoutMethod ?? error?.checkoutMethod ?? (error?.type === "paypal_redirect_required" ? "paypal" : "card");
|
|
2327
3055
|
return Object.assign(
|
|
2328
|
-
new
|
|
3056
|
+
new FloPayError4(
|
|
2329
3057
|
error?.message ?? fallbackMessage,
|
|
2330
3058
|
"api_error",
|
|
2331
3059
|
{
|
|
@@ -2380,16 +3108,19 @@ function getRedirectTokenFromProcessResponse(json, options) {
|
|
|
2380
3108
|
return candidate;
|
|
2381
3109
|
}
|
|
2382
3110
|
}
|
|
2383
|
-
const
|
|
2384
|
-
if (
|
|
2385
|
-
const
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
3111
|
+
const nestedGateways = nestedRecord.gateways;
|
|
3112
|
+
if (nestedGateways && typeof nestedGateways === "object") {
|
|
3113
|
+
const stripeGateway = nestedGateways.stripe;
|
|
3114
|
+
if (stripeGateway && typeof stripeGateway === "object") {
|
|
3115
|
+
const stripeRecord = stripeGateway;
|
|
3116
|
+
const gatewayCandidates = [
|
|
3117
|
+
stripeRecord.stripeClientSecret,
|
|
3118
|
+
stripeRecord.clientSecret
|
|
3119
|
+
];
|
|
3120
|
+
for (const candidate of gatewayCandidates) {
|
|
3121
|
+
if (typeof candidate === "string" && candidate.length > 0 && (!options?.requirePaymentIntentClientSecret || isStripePaymentIntentClientSecret(candidate))) {
|
|
3122
|
+
return candidate;
|
|
3123
|
+
}
|
|
2393
3124
|
}
|
|
2394
3125
|
}
|
|
2395
3126
|
}
|
|
@@ -2414,9 +3145,9 @@ async function recover3DSRedirectResult({
|
|
|
2414
3145
|
return null;
|
|
2415
3146
|
}
|
|
2416
3147
|
try {
|
|
2417
|
-
const api = new
|
|
3148
|
+
const api = new PaymentAPI3(billingApiUrl);
|
|
2418
3149
|
const unified = await api.getUnifiedCheckoutSession(sessionId);
|
|
2419
|
-
const refreshedToken = unified.
|
|
3150
|
+
const refreshedToken = unified.data.stripe?.clientSecret;
|
|
2420
3151
|
if (isStripePaymentIntentClientSecret(refreshedToken)) {
|
|
2421
3152
|
return {
|
|
2422
3153
|
type: "3ds_required",
|
|
@@ -2442,7 +3173,7 @@ async function processSavedPaymentForMode({
|
|
|
2442
3173
|
const lastName = session.customer?.lastName ?? session.accountData?.lastName ?? "";
|
|
2443
3174
|
const country = session.customer?.country ?? session.accountData?.country ?? void 0;
|
|
2444
3175
|
const zip = session.customer?.zip ?? session.accountData?.zip ?? void 0;
|
|
2445
|
-
const api = new
|
|
3176
|
+
const api = new PaymentAPI3(baseUrl);
|
|
2446
3177
|
const response = await retryOnceOnFetchFailure(() => api.processPayment(customerId, {
|
|
2447
3178
|
sessionId: resolvedSessionId,
|
|
2448
3179
|
tokenizedData,
|
|
@@ -2471,7 +3202,7 @@ async function processSavedPaymentForMode({
|
|
|
2471
3202
|
if (json?.type === "paypal_redirect_required" || json?.type === "3ds_required") {
|
|
2472
3203
|
const redirectToken = getRedirectTokenFromProcessResponse(json);
|
|
2473
3204
|
if (!redirectToken) {
|
|
2474
|
-
throw new
|
|
3205
|
+
throw new FloPayError4(
|
|
2475
3206
|
"Authentication is required but no redirect token was provided.",
|
|
2476
3207
|
"api_error",
|
|
2477
3208
|
{ code: "authentication_required" }
|
|
@@ -2493,7 +3224,7 @@ async function processSavedPaymentForMode({
|
|
|
2493
3224
|
return recoveredRedirect;
|
|
2494
3225
|
}
|
|
2495
3226
|
throw Object.assign(
|
|
2496
|
-
new
|
|
3227
|
+
new FloPayError4(
|
|
2497
3228
|
"Your card requires authentication. Please enter your payment details below.",
|
|
2498
3229
|
"api_error",
|
|
2499
3230
|
{ code: "authentication_required" }
|
|
@@ -2501,7 +3232,7 @@ async function processSavedPaymentForMode({
|
|
|
2501
3232
|
{ checkoutMethod: "card" }
|
|
2502
3233
|
);
|
|
2503
3234
|
}
|
|
2504
|
-
throw new
|
|
3235
|
+
throw new FloPayError4(
|
|
2505
3236
|
json?.message ?? "Payment failed. Please try again.",
|
|
2506
3237
|
"api_error",
|
|
2507
3238
|
{
|
|
@@ -2521,13 +3252,13 @@ async function processSavedPaymentWithIntent({
|
|
|
2521
3252
|
const customerEmail = session.customer?.email ?? session.accountData?.email ?? "";
|
|
2522
3253
|
if (!customerEmail) {
|
|
2523
3254
|
throw Object.assign(
|
|
2524
|
-
new
|
|
3255
|
+
new FloPayError4("Customer email is required to create a payment intent.", "validation_error", {
|
|
2525
3256
|
param: "email"
|
|
2526
3257
|
}),
|
|
2527
3258
|
{ checkoutMethod: "card" }
|
|
2528
3259
|
);
|
|
2529
3260
|
}
|
|
2530
|
-
const api = new
|
|
3261
|
+
const api = new PaymentAPI3(billingApiUrl);
|
|
2531
3262
|
const intentResponse = await retryOnceOnFetchFailure(() => api.createPaymentIntent(
|
|
2532
3263
|
sessionId,
|
|
2533
3264
|
customerEmail,
|
|
@@ -2549,7 +3280,7 @@ async function processSavedPaymentWithIntent({
|
|
|
2549
3280
|
});
|
|
2550
3281
|
if (!intentClientSecret) {
|
|
2551
3282
|
throw Object.assign(
|
|
2552
|
-
new
|
|
3283
|
+
new FloPayError4("No client secret in payment intent response.", "api_error"),
|
|
2553
3284
|
{ checkoutMethod: "card" }
|
|
2554
3285
|
);
|
|
2555
3286
|
}
|
|
@@ -2572,7 +3303,7 @@ async function processSavedPaymentWithIntent({
|
|
|
2572
3303
|
const confirmedPaymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? paymentMethodId;
|
|
2573
3304
|
if (!confirmedPaymentIntentId || confirmResult.status !== "succeeded" && confirmResult.status !== "processing" && confirmResult.status !== "requires_capture") {
|
|
2574
3305
|
throw Object.assign(
|
|
2575
|
-
new
|
|
3306
|
+
new FloPayError4(
|
|
2576
3307
|
`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.`,
|
|
2577
3308
|
"api_error",
|
|
2578
3309
|
{
|
|
@@ -2620,12 +3351,12 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
2620
3351
|
}) {
|
|
2621
3352
|
const stripe = flopay?.getRawProvider();
|
|
2622
3353
|
if (!stripe) {
|
|
2623
|
-
throw new
|
|
3354
|
+
throw new FloPayError4("Payment provider is not available.", "api_error");
|
|
2624
3355
|
}
|
|
2625
3356
|
if (redirectResult.type === "3ds_required") {
|
|
2626
3357
|
if (!attempt3DS || !redirectResult.threeDSecureToken) {
|
|
2627
3358
|
throw Object.assign(
|
|
2628
|
-
new
|
|
3359
|
+
new FloPayError4(
|
|
2629
3360
|
"Your card requires authentication. Please enter your payment details below.",
|
|
2630
3361
|
"api_error",
|
|
2631
3362
|
{ code: "authentication_required" }
|
|
@@ -2641,7 +3372,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
2641
3372
|
);
|
|
2642
3373
|
if (retrieveError) {
|
|
2643
3374
|
throw Object.assign(
|
|
2644
|
-
new
|
|
3375
|
+
new FloPayError4(
|
|
2645
3376
|
retrieveError.message ?? "Failed to retrieve 3DS payment status.",
|
|
2646
3377
|
"api_error",
|
|
2647
3378
|
{ code: retrieveError.code }
|
|
@@ -2667,7 +3398,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
2667
3398
|
);
|
|
2668
3399
|
if (confirmError) {
|
|
2669
3400
|
throw Object.assign(
|
|
2670
|
-
new
|
|
3401
|
+
new FloPayError4(
|
|
2671
3402
|
confirmError.message ?? "3DS authentication failed.",
|
|
2672
3403
|
"api_error",
|
|
2673
3404
|
{ code: confirmError.code }
|
|
@@ -2682,7 +3413,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
2682
3413
|
});
|
|
2683
3414
|
if (nextActionError) {
|
|
2684
3415
|
throw Object.assign(
|
|
2685
|
-
new
|
|
3416
|
+
new FloPayError4(
|
|
2686
3417
|
nextActionError.message ?? "3DS authentication failed.",
|
|
2687
3418
|
"api_error",
|
|
2688
3419
|
{ code: nextActionError.code }
|
|
@@ -2722,7 +3453,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
2722
3453
|
});
|
|
2723
3454
|
}
|
|
2724
3455
|
throw Object.assign(
|
|
2725
|
-
new
|
|
3456
|
+
new FloPayError4("3DS authentication did not complete successfully.", "api_error"),
|
|
2726
3457
|
{ checkoutMethod: "card" }
|
|
2727
3458
|
);
|
|
2728
3459
|
}
|
|
@@ -2730,7 +3461,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
2730
3461
|
const paypalStripe = (paypalFlopay ?? flopay)?.getRawProvider();
|
|
2731
3462
|
if (!paypalStripe) {
|
|
2732
3463
|
throw Object.assign(
|
|
2733
|
-
new
|
|
3464
|
+
new FloPayError4("PayPal is not available.", "api_error"),
|
|
2734
3465
|
{ checkoutMethod: "paypal" }
|
|
2735
3466
|
);
|
|
2736
3467
|
}
|
|
@@ -2740,7 +3471,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
2740
3471
|
});
|
|
2741
3472
|
if (error2) {
|
|
2742
3473
|
throw Object.assign(
|
|
2743
|
-
new
|
|
3474
|
+
new FloPayError4(
|
|
2744
3475
|
error2.message ?? "PayPal authorization failed.",
|
|
2745
3476
|
"api_error",
|
|
2746
3477
|
{ code: error2.code }
|
|
@@ -2763,7 +3494,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
2763
3494
|
});
|
|
2764
3495
|
if (error) {
|
|
2765
3496
|
throw Object.assign(
|
|
2766
|
-
new
|
|
3497
|
+
new FloPayError4(
|
|
2767
3498
|
error.message ?? "PayPal authorization failed.",
|
|
2768
3499
|
"api_error",
|
|
2769
3500
|
{ code: error.code }
|
|
@@ -2776,33 +3507,33 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
2776
3507
|
checkoutMethod: "paypal"
|
|
2777
3508
|
};
|
|
2778
3509
|
}
|
|
2779
|
-
throw new
|
|
3510
|
+
throw new FloPayError4("Unsupported payment redirect state.", "api_error");
|
|
2780
3511
|
}
|
|
2781
3512
|
function normalizeSavedPaymentError(err) {
|
|
2782
|
-
if (err instanceof
|
|
3513
|
+
if (err instanceof FloPayError4) {
|
|
2783
3514
|
return err;
|
|
2784
3515
|
}
|
|
2785
|
-
return new
|
|
3516
|
+
return new FloPayError4(
|
|
2786
3517
|
err instanceof Error ? err.message : "Payment failed. Please try again.",
|
|
2787
3518
|
"api_error"
|
|
2788
3519
|
);
|
|
2789
3520
|
}
|
|
2790
3521
|
function resolveSavedPaymentPublishableKeys(unified) {
|
|
2791
|
-
|
|
2792
|
-
let paypalPublishableKey;
|
|
2793
|
-
if (unified.provider === "stripe") {
|
|
2794
|
-
publishableKey = unified.data.stripe?.publishableKey;
|
|
2795
|
-
paypalPublishableKey = unified.data.stripe?.paypalPublishableKey ?? void 0;
|
|
2796
|
-
}
|
|
3522
|
+
const publishableKey = unified.data.stripe?.publishableKey;
|
|
2797
3523
|
if (!publishableKey) {
|
|
2798
|
-
throw new
|
|
2799
|
-
"No publishable key found in the checkout session. Ensure the session
|
|
3524
|
+
throw new FloPayError4(
|
|
3525
|
+
"No publishable key found in the checkout session. Ensure the session advertises gateways.stripe.",
|
|
2800
3526
|
"validation_error"
|
|
2801
3527
|
);
|
|
2802
3528
|
}
|
|
2803
3529
|
return {
|
|
2804
3530
|
publishableKey,
|
|
2805
|
-
|
|
3531
|
+
// Direct-PayPal sessions can still use Stripe's PayPal Element for the
|
|
3532
|
+
// saved-PM redirect leg. Prefer the dedicated Stripe-PayPal sub-account
|
|
3533
|
+
// publishable key when the backend advertises one; fall back to the
|
|
3534
|
+
// primary Stripe publishable key so the resume flow still has a Stripe
|
|
3535
|
+
// instance to drive Stripe's PayPal PI.
|
|
3536
|
+
paypalPublishableKey: unified.data.stripe?.paypalPublishableKey ?? publishableKey
|
|
2806
3537
|
};
|
|
2807
3538
|
}
|
|
2808
3539
|
async function loadSavedPaymentProviders({
|
|
@@ -2832,13 +3563,21 @@ async function loadSavedPaymentProviders({
|
|
|
2832
3563
|
}
|
|
2833
3564
|
|
|
2834
3565
|
// src/flopay-checkout.tsx
|
|
2835
|
-
import { Fragment as Fragment3, jsx as
|
|
3566
|
+
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2836
3567
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
|
|
2837
3568
|
var PAYPAL_RESUME_STORAGE_KEY = "flopay_checkout_saved_payment_resume";
|
|
2838
3569
|
var sessionInflightMap = /* @__PURE__ */ new Map();
|
|
2839
3570
|
function sleep(ms) {
|
|
2840
3571
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2841
3572
|
}
|
|
3573
|
+
function resolveDirectPaypalConfig(unified) {
|
|
3574
|
+
const clientId = unified?.data.paypal?.publishableKey;
|
|
3575
|
+
if (!clientId) return void 0;
|
|
3576
|
+
return {
|
|
3577
|
+
clientId,
|
|
3578
|
+
environment: unified?.data.paypal?.environment
|
|
3579
|
+
};
|
|
3580
|
+
}
|
|
2842
3581
|
function canUseStorage() {
|
|
2843
3582
|
return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
|
|
2844
3583
|
}
|
|
@@ -2912,6 +3651,7 @@ function FloPayCheckout({
|
|
|
2912
3651
|
showPayPal = true,
|
|
2913
3652
|
showApplePay = true,
|
|
2914
3653
|
showGooglePay = true,
|
|
3654
|
+
debug = false,
|
|
2915
3655
|
layout,
|
|
2916
3656
|
buttonsTheme,
|
|
2917
3657
|
buttonsStyles,
|
|
@@ -2935,37 +3675,37 @@ function FloPayCheckout({
|
|
|
2935
3675
|
const resolvedBillingUrl = resolveBillingApiUrl3(billingApiUrl);
|
|
2936
3676
|
const checkoutType = createSessionParams ? "embedded_checkout" : "standard_checkout";
|
|
2937
3677
|
const checkoutLayout = children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout";
|
|
2938
|
-
const [unified, setUnified] =
|
|
2939
|
-
const [flopay, setFloPay] =
|
|
2940
|
-
const flopayRef =
|
|
2941
|
-
const [paypalFlopay, setPaypalFloPay] =
|
|
2942
|
-
const paypalFlopayRef =
|
|
2943
|
-
const [session, setSession] =
|
|
2944
|
-
const [resolvedSessionId, setResolvedSessionId] =
|
|
3678
|
+
const [unified, setUnified] = useState4(null);
|
|
3679
|
+
const [flopay, setFloPay] = useState4(null);
|
|
3680
|
+
const flopayRef = useRef4(null);
|
|
3681
|
+
const [paypalFlopay, setPaypalFloPay] = useState4(null);
|
|
3682
|
+
const paypalFlopayRef = useRef4(null);
|
|
3683
|
+
const [session, setSession] = useState4(null);
|
|
3684
|
+
const [resolvedSessionId, setResolvedSessionId] = useState4(sessionIdProp ?? "");
|
|
2945
3685
|
const activeSessionId = sessionIdProp ?? resolvedSessionId;
|
|
2946
3686
|
const initSessionDependency = createSessionParams ? "" : activeSessionId;
|
|
2947
|
-
const [isLoading, setIsLoading] =
|
|
2948
|
-
const [loadError, setLoadError] =
|
|
2949
|
-
const [currentMode, setCurrentMode] =
|
|
2950
|
-
const [confirmProcessing, setConfirmProcessing] =
|
|
2951
|
-
const [modeError, setModeError] =
|
|
2952
|
-
const [modeOverlayStatus, setModeOverlayStatus] =
|
|
2953
|
-
const [modeOverlayError, setModeOverlayError] =
|
|
2954
|
-
const [createSessionPatch, setCreateSessionPatch] =
|
|
2955
|
-
const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] =
|
|
2956
|
-
const [cardBootstrapPending, setCardBootstrapPending] =
|
|
2957
|
-
const autoCheckoutAttempted =
|
|
2958
|
-
const paypalResumeAttempted =
|
|
2959
|
-
const savedPaymentKeysRef =
|
|
2960
|
-
const onCompleteRef =
|
|
3687
|
+
const [isLoading, setIsLoading] = useState4(true);
|
|
3688
|
+
const [loadError, setLoadError] = useState4(null);
|
|
3689
|
+
const [currentMode, setCurrentMode] = useState4("full");
|
|
3690
|
+
const [confirmProcessing, setConfirmProcessing] = useState4(false);
|
|
3691
|
+
const [modeError, setModeError] = useState4(initialErrorMessage);
|
|
3692
|
+
const [modeOverlayStatus, setModeOverlayStatus] = useState4(null);
|
|
3693
|
+
const [modeOverlayError, setModeOverlayError] = useState4(null);
|
|
3694
|
+
const [createSessionPatch, setCreateSessionPatch] = useState4(void 0);
|
|
3695
|
+
const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = useState4("");
|
|
3696
|
+
const [cardBootstrapPending, setCardBootstrapPending] = useState4(false);
|
|
3697
|
+
const autoCheckoutAttempted = useRef4(false);
|
|
3698
|
+
const paypalResumeAttempted = useRef4(false);
|
|
3699
|
+
const savedPaymentKeysRef = useRef4(null);
|
|
3700
|
+
const onCompleteRef = useRef4(onComplete);
|
|
2961
3701
|
onCompleteRef.current = onComplete;
|
|
2962
|
-
const onErrorRef =
|
|
3702
|
+
const onErrorRef = useRef4(onError);
|
|
2963
3703
|
onErrorRef.current = onError;
|
|
2964
|
-
const onDeclineRef =
|
|
3704
|
+
const onDeclineRef = useRef4(onDecline);
|
|
2965
3705
|
onDeclineRef.current = onDecline;
|
|
2966
|
-
const onSessionCompletedRef =
|
|
3706
|
+
const onSessionCompletedRef = useRef4(onSessionCompleted);
|
|
2967
3707
|
onSessionCompletedRef.current = onSessionCompleted;
|
|
2968
|
-
|
|
3708
|
+
useEffect5(() => {
|
|
2969
3709
|
console.info("[FloPay] Checkout initialized", {
|
|
2970
3710
|
sdk_version: SDK_VERSION,
|
|
2971
3711
|
checkout_type: checkoutType,
|
|
@@ -2973,31 +3713,31 @@ function FloPayCheckout({
|
|
|
2973
3713
|
billing_api_url: resolvedBillingUrl
|
|
2974
3714
|
});
|
|
2975
3715
|
}, [checkoutLayout, checkoutType, resolvedBillingUrl]);
|
|
2976
|
-
const baseCreateSessionHash =
|
|
3716
|
+
const baseCreateSessionHash = useMemo4(
|
|
2977
3717
|
() => createSessionParams ? hashCreateParams(createSessionParams) : "",
|
|
2978
3718
|
[createSessionParams]
|
|
2979
3719
|
);
|
|
2980
|
-
const activeCreateSessionPatch =
|
|
3720
|
+
const activeCreateSessionPatch = useMemo4(
|
|
2981
3721
|
() => createSessionPatchBaseHash === baseCreateSessionHash ? createSessionPatch : void 0,
|
|
2982
3722
|
[createSessionPatch, createSessionPatchBaseHash, baseCreateSessionHash]
|
|
2983
3723
|
);
|
|
2984
|
-
const effectiveCreateSessionBase =
|
|
3724
|
+
const effectiveCreateSessionBase = useMemo4(
|
|
2985
3725
|
() => createSessionParams ? mergeInlineSessionPatch(createSessionParams, activeCreateSessionPatch) : void 0,
|
|
2986
3726
|
[createSessionParams, activeCreateSessionPatch]
|
|
2987
3727
|
);
|
|
2988
3728
|
const effectiveCreateSessionMode = checkoutModeProp ?? effectiveCreateSessionBase?.checkoutMode ?? "full";
|
|
2989
|
-
const effectiveCreateSession =
|
|
3729
|
+
const effectiveCreateSession = useMemo4(
|
|
2990
3730
|
() => effectiveCreateSessionBase ? {
|
|
2991
3731
|
...effectiveCreateSessionBase,
|
|
2992
3732
|
checkoutMode: effectiveCreateSessionMode
|
|
2993
3733
|
} : void 0,
|
|
2994
3734
|
[effectiveCreateSessionBase, effectiveCreateSessionMode]
|
|
2995
3735
|
);
|
|
2996
|
-
|
|
3736
|
+
useEffect5(() => {
|
|
2997
3737
|
setCreateSessionPatch(void 0);
|
|
2998
3738
|
setCreateSessionPatchBaseHash(baseCreateSessionHash);
|
|
2999
3739
|
}, [baseCreateSessionHash]);
|
|
3000
|
-
|
|
3740
|
+
useEffect5(() => {
|
|
3001
3741
|
setModeError(initialErrorMessage);
|
|
3002
3742
|
}, [initialErrorMessage]);
|
|
3003
3743
|
const emitDecline = useCallback2(
|
|
@@ -3035,12 +3775,12 @@ function FloPayCheckout({
|
|
|
3035
3775
|
clearPayPalResumeState();
|
|
3036
3776
|
}
|
|
3037
3777
|
} else if (options?.initialAutoProcessingPending) {
|
|
3038
|
-
const api = new
|
|
3778
|
+
const api = new PaymentAPI4(resolvedBillingUrl);
|
|
3039
3779
|
const completed = await api.waitForCheckoutSessionCompletion(options.initialAutoProcessingPending.sessionId, {
|
|
3040
3780
|
initialDelayMs: options.initialAutoProcessingPending.retryAfterMs
|
|
3041
3781
|
});
|
|
3042
3782
|
if (completed.data.session?.status !== "complete") {
|
|
3043
|
-
throw new
|
|
3783
|
+
throw new FloPayError5("Automatic payment failed. Please try again.", "api_error", {
|
|
3044
3784
|
code: completed.data.session?.status === "expired" ? "checkout_session_expired" : "checkout_processing_timeout"
|
|
3045
3785
|
});
|
|
3046
3786
|
}
|
|
@@ -3124,7 +3864,7 @@ function FloPayCheckout({
|
|
|
3124
3864
|
resolvedBillingUrl
|
|
3125
3865
|
]
|
|
3126
3866
|
);
|
|
3127
|
-
|
|
3867
|
+
useEffect5(() => {
|
|
3128
3868
|
if (typeof window === "undefined" || paypalResumeAttempted.current) {
|
|
3129
3869
|
return;
|
|
3130
3870
|
}
|
|
@@ -3146,7 +3886,7 @@ function FloPayCheckout({
|
|
|
3146
3886
|
try {
|
|
3147
3887
|
if (params.get("redirect_status") === "failed") {
|
|
3148
3888
|
throw Object.assign(
|
|
3149
|
-
new
|
|
3889
|
+
new FloPayError5("PayPal payment was declined. Please try again.", "api_error"),
|
|
3150
3890
|
{ checkoutMethod: "paypal" }
|
|
3151
3891
|
);
|
|
3152
3892
|
}
|
|
@@ -3162,14 +3902,14 @@ function FloPayCheckout({
|
|
|
3162
3902
|
const paypalStripe = (resumePaypalFlopay ?? resumeFlopay).getRawProvider();
|
|
3163
3903
|
if (!paypalStripe) {
|
|
3164
3904
|
throw Object.assign(
|
|
3165
|
-
new
|
|
3905
|
+
new FloPayError5("PayPal is not available.", "api_error"),
|
|
3166
3906
|
{ checkoutMethod: "paypal" }
|
|
3167
3907
|
);
|
|
3168
3908
|
}
|
|
3169
3909
|
const { paymentIntent, error } = await paypalStripe.retrievePaymentIntent(clientSecret);
|
|
3170
3910
|
if (error) {
|
|
3171
3911
|
throw Object.assign(
|
|
3172
|
-
new
|
|
3912
|
+
new FloPayError5(
|
|
3173
3913
|
error.message ?? "Failed to retrieve PayPal payment status.",
|
|
3174
3914
|
"api_error",
|
|
3175
3915
|
{ code: error.code }
|
|
@@ -3180,14 +3920,14 @@ function FloPayCheckout({
|
|
|
3180
3920
|
const resultStatus = mapPayPalIntentStatusToPaymentResult(paymentIntent?.status);
|
|
3181
3921
|
if (!paymentIntent || resultStatus === "failed") {
|
|
3182
3922
|
throw Object.assign(
|
|
3183
|
-
new
|
|
3923
|
+
new FloPayError5("PayPal payment was not completed. Please try again.", "api_error"),
|
|
3184
3924
|
{ checkoutMethod: "paypal" }
|
|
3185
3925
|
);
|
|
3186
3926
|
}
|
|
3187
3927
|
const paymentMethodId = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
3188
3928
|
let finalResultStatus = resultStatus;
|
|
3189
3929
|
if (resumeState.sessionId) {
|
|
3190
|
-
const resumeApi = new
|
|
3930
|
+
const resumeApi = new PaymentAPI4(resolvedBillingUrl);
|
|
3191
3931
|
const resumeSessionResult = await resumeApi.getUnifiedCheckoutSession(resumeState.sessionId);
|
|
3192
3932
|
const resumeSession = resumeSessionResult.data.session;
|
|
3193
3933
|
if (resumeSession && resumeSession.status !== "complete") {
|
|
@@ -3204,7 +3944,7 @@ function FloPayCheckout({
|
|
|
3204
3944
|
});
|
|
3205
3945
|
if (processResult.type !== "success") {
|
|
3206
3946
|
throw Object.assign(
|
|
3207
|
-
new
|
|
3947
|
+
new FloPayError5("Failed to finalize PayPal payment.", "api_error"),
|
|
3208
3948
|
{ checkoutMethod: "paypal" }
|
|
3209
3949
|
);
|
|
3210
3950
|
}
|
|
@@ -3241,7 +3981,7 @@ function FloPayCheckout({
|
|
|
3241
3981
|
}
|
|
3242
3982
|
})();
|
|
3243
3983
|
}, [emitDecline, locale, normalizeSavedPaymentError, resolvedBillingUrl]);
|
|
3244
|
-
const initializedHashRef =
|
|
3984
|
+
const initializedHashRef = useRef4(null);
|
|
3245
3985
|
function hashCreateParams(params) {
|
|
3246
3986
|
const key = JSON.stringify({
|
|
3247
3987
|
c: params?.clientId,
|
|
@@ -3266,23 +4006,23 @@ function FloPayCheckout({
|
|
|
3266
4006
|
}
|
|
3267
4007
|
return `flopay_session_${Math.abs(h).toString(36)}`;
|
|
3268
4008
|
}
|
|
3269
|
-
const createSessionHash =
|
|
4009
|
+
const createSessionHash = useMemo4(
|
|
3270
4010
|
() => effectiveCreateSession ? hashCreateParams(effectiveCreateSession) : "",
|
|
3271
4011
|
[effectiveCreateSession]
|
|
3272
4012
|
);
|
|
3273
|
-
const createSessionParamsRef =
|
|
4013
|
+
const createSessionParamsRef = useRef4(effectiveCreateSession);
|
|
3274
4014
|
createSessionParamsRef.current = effectiveCreateSession;
|
|
3275
|
-
|
|
4015
|
+
useEffect5(() => {
|
|
3276
4016
|
setResolvedSessionId(sessionIdProp ?? "");
|
|
3277
4017
|
}, [sessionIdProp]);
|
|
3278
|
-
|
|
4018
|
+
useEffect5(() => {
|
|
3279
4019
|
autoCheckoutAttempted.current = false;
|
|
3280
4020
|
setModeError(initialErrorMessage);
|
|
3281
4021
|
setModeOverlayError(null);
|
|
3282
4022
|
setModeOverlayStatus(null);
|
|
3283
4023
|
}, [createSessionHash, initialErrorMessage, sessionIdProp]);
|
|
3284
4024
|
async function resolveInlineSession(params, cacheKey) {
|
|
3285
|
-
const api = new
|
|
4025
|
+
const api = new PaymentAPI4(resolvedBillingUrl);
|
|
3286
4026
|
let sid = typeof window !== "undefined" ? window.sessionStorage.getItem(cacheKey) : null;
|
|
3287
4027
|
let realResult = null;
|
|
3288
4028
|
if (sid) {
|
|
@@ -3322,7 +4062,7 @@ function FloPayCheckout({
|
|
|
3322
4062
|
async (patch) => {
|
|
3323
4063
|
const baseParams = createSessionParamsRef.current;
|
|
3324
4064
|
if (!baseParams) {
|
|
3325
|
-
throw new
|
|
4065
|
+
throw new FloPayError5("createSession is required to bootstrap checkout.", "validation_error");
|
|
3326
4066
|
}
|
|
3327
4067
|
const mergedParams = mergeInlineSessionPatch(baseParams, patch);
|
|
3328
4068
|
const cacheKey = hashCreateParams(mergedParams);
|
|
@@ -3402,7 +4142,7 @@ function FloPayCheckout({
|
|
|
3402
4142
|
resolvedSessionId,
|
|
3403
4143
|
session
|
|
3404
4144
|
]);
|
|
3405
|
-
|
|
4145
|
+
useEffect5(() => {
|
|
3406
4146
|
let cancelled = false;
|
|
3407
4147
|
setLoadError(null);
|
|
3408
4148
|
if (createSessionHash) {
|
|
@@ -3446,7 +4186,7 @@ function FloPayCheckout({
|
|
|
3446
4186
|
}
|
|
3447
4187
|
} catch (err) {
|
|
3448
4188
|
if (cancelled) return;
|
|
3449
|
-
const errorCode = err instanceof
|
|
4189
|
+
const errorCode = err instanceof FloPayError5 ? err.code : typeof err === "object" && err !== null && "code" in err ? err.code : void 0;
|
|
3450
4190
|
if (shouldAutoProcessInlineSession && errorCode === "session_auto_completed") {
|
|
3451
4191
|
autoCheckoutAttempted.current = true;
|
|
3452
4192
|
setModeOverlayStatus("success");
|
|
@@ -3462,7 +4202,7 @@ function FloPayCheckout({
|
|
|
3462
4202
|
setModeOverlayStatus(null);
|
|
3463
4203
|
setModeOverlayError(null);
|
|
3464
4204
|
}
|
|
3465
|
-
const floPayErr = err instanceof
|
|
4205
|
+
const floPayErr = err instanceof FloPayError5 ? err : new FloPayError5(err instanceof Error ? err.message : "Failed to create session", "api_error");
|
|
3466
4206
|
setLoadError(floPayErr);
|
|
3467
4207
|
}
|
|
3468
4208
|
})();
|
|
@@ -3473,14 +4213,14 @@ function FloPayCheckout({
|
|
|
3473
4213
|
setIsLoading(true);
|
|
3474
4214
|
async function init() {
|
|
3475
4215
|
try {
|
|
3476
|
-
const api = new
|
|
4216
|
+
const api = new PaymentAPI4(resolvedBillingUrl);
|
|
3477
4217
|
const result = await api.getUnifiedCheckoutSession(activeSessionId);
|
|
3478
4218
|
if (cancelled) return;
|
|
3479
4219
|
setUnified(result);
|
|
3480
4220
|
const sess = result.data.session ?? null;
|
|
3481
4221
|
setSession(sess);
|
|
3482
4222
|
if (!sess) {
|
|
3483
|
-
throw new
|
|
4223
|
+
throw new FloPayError5("No session data returned", "api_error");
|
|
3484
4224
|
}
|
|
3485
4225
|
if (sess.status === "complete") {
|
|
3486
4226
|
setIsLoading(false);
|
|
@@ -3488,7 +4228,7 @@ function FloPayCheckout({
|
|
|
3488
4228
|
return;
|
|
3489
4229
|
}
|
|
3490
4230
|
if (sess.status === "expired") {
|
|
3491
|
-
throw new
|
|
4231
|
+
throw new FloPayError5("Checkout session has expired.", "api_error", {
|
|
3492
4232
|
code: "checkout_session_expired"
|
|
3493
4233
|
});
|
|
3494
4234
|
}
|
|
@@ -3522,7 +4262,7 @@ function FloPayCheckout({
|
|
|
3522
4262
|
if (!cancelled) setIsLoading(false);
|
|
3523
4263
|
} catch (err) {
|
|
3524
4264
|
if (cancelled) return;
|
|
3525
|
-
const floPayErr = err instanceof
|
|
4265
|
+
const floPayErr = err instanceof FloPayError5 ? err : new FloPayError5(err instanceof Error ? err.message : "Failed to initialize checkout", "api_error");
|
|
3526
4266
|
setLoadError(floPayErr);
|
|
3527
4267
|
setIsLoading(false);
|
|
3528
4268
|
}
|
|
@@ -3575,14 +4315,14 @@ function FloPayCheckout({
|
|
|
3575
4315
|
setConfirmProcessing(false);
|
|
3576
4316
|
}
|
|
3577
4317
|
}, [activeSessionId, confirmProcessing, runSavedPaymentFlow, session]);
|
|
3578
|
-
const providerOptions =
|
|
4318
|
+
const providerOptions = useMemo4(() => {
|
|
3579
4319
|
if (!unified || !session) return void 0;
|
|
3580
4320
|
const opts = {
|
|
3581
4321
|
appearance,
|
|
3582
4322
|
paymentMethodCreation: "manual",
|
|
3583
4323
|
billingApiUrl: resolvedBillingUrl
|
|
3584
4324
|
};
|
|
3585
|
-
if (unified.
|
|
4325
|
+
if (unified.data.stripe?.clientSecret) {
|
|
3586
4326
|
opts.clientSecret = unified.data.stripe.clientSecret;
|
|
3587
4327
|
} else {
|
|
3588
4328
|
const displayTotal = buildCheckoutDisplayData(session).total;
|
|
@@ -3594,7 +4334,7 @@ function FloPayCheckout({
|
|
|
3594
4334
|
const shouldHandleInlineSessionPatch = Boolean(
|
|
3595
4335
|
createSessionParams && !children && layout === "buttons" && onBeforeButtonClick && effectiveCreateSessionMode === "full"
|
|
3596
4336
|
);
|
|
3597
|
-
const checkoutValue =
|
|
4337
|
+
const checkoutValue = useMemo4(
|
|
3598
4338
|
() => ({
|
|
3599
4339
|
session,
|
|
3600
4340
|
loading: isLoading,
|
|
@@ -3616,7 +4356,7 @@ function FloPayCheckout({
|
|
|
3616
4356
|
]
|
|
3617
4357
|
);
|
|
3618
4358
|
const shouldShowInterimButtons = Boolean(createSessionParams) && layout === "buttons" && (!flopay || !providerOptions);
|
|
3619
|
-
const modeOverlay = modeOverlayStatus ? /* @__PURE__ */
|
|
4359
|
+
const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ jsx7(
|
|
3620
4360
|
ProcessingOverlay,
|
|
3621
4361
|
{
|
|
3622
4362
|
status: modeOverlayStatus,
|
|
@@ -3625,31 +4365,31 @@ function FloPayCheckout({
|
|
|
3625
4365
|
) : null;
|
|
3626
4366
|
if (isLoading) {
|
|
3627
4367
|
if (loadingNode) {
|
|
3628
|
-
return /* @__PURE__ */
|
|
4368
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3629
4369
|
loadingNode,
|
|
3630
4370
|
modeOverlay
|
|
3631
4371
|
] });
|
|
3632
4372
|
}
|
|
3633
4373
|
if (layout === "buttons") {
|
|
3634
|
-
const skeletonBar = (h) => /* @__PURE__ */
|
|
4374
|
+
const skeletonBar = (h) => /* @__PURE__ */ jsx7("div", { style: {
|
|
3635
4375
|
height: h,
|
|
3636
4376
|
borderRadius: 8,
|
|
3637
4377
|
background: "#e5e7eb",
|
|
3638
4378
|
animation: "flopay-loading-pulse 1.5s ease-in-out infinite"
|
|
3639
4379
|
} });
|
|
3640
|
-
return /* @__PURE__ */
|
|
3641
|
-
/* @__PURE__ */
|
|
4380
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4381
|
+
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
3642
4382
|
showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
3643
4383
|
(showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
3644
4384
|
skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
3645
|
-
/* @__PURE__ */
|
|
4385
|
+
/* @__PURE__ */ jsx7("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
3646
4386
|
] }),
|
|
3647
4387
|
modeOverlay
|
|
3648
4388
|
] });
|
|
3649
4389
|
}
|
|
3650
|
-
return /* @__PURE__ */
|
|
3651
|
-
/* @__PURE__ */
|
|
3652
|
-
/* @__PURE__ */
|
|
4390
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4391
|
+
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", justifyContent: "center", padding: 32 }, children: [
|
|
4392
|
+
/* @__PURE__ */ jsx7("div", { style: {
|
|
3653
4393
|
width: 24,
|
|
3654
4394
|
height: 24,
|
|
3655
4395
|
border: "2px solid #e5e7eb",
|
|
@@ -3657,16 +4397,16 @@ function FloPayCheckout({
|
|
|
3657
4397
|
borderRadius: "50%",
|
|
3658
4398
|
animation: "spin 0.6s linear infinite"
|
|
3659
4399
|
} }),
|
|
3660
|
-
/* @__PURE__ */
|
|
4400
|
+
/* @__PURE__ */ jsx7("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
|
|
3661
4401
|
] }),
|
|
3662
4402
|
modeOverlay
|
|
3663
4403
|
] });
|
|
3664
4404
|
}
|
|
3665
4405
|
if (loadError) {
|
|
3666
4406
|
if (errorNode) {
|
|
3667
|
-
return /* @__PURE__ */
|
|
4407
|
+
return /* @__PURE__ */ jsx7(CheckoutContext.Provider, { value: checkoutValue, children: errorNode(loadError) });
|
|
3668
4408
|
}
|
|
3669
|
-
return /* @__PURE__ */
|
|
4409
|
+
return /* @__PURE__ */ jsx7(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx7(
|
|
3670
4410
|
"div",
|
|
3671
4411
|
{
|
|
3672
4412
|
style: {
|
|
@@ -3680,8 +4420,8 @@ function FloPayCheckout({
|
|
|
3680
4420
|
) });
|
|
3681
4421
|
}
|
|
3682
4422
|
if (shouldShowInterimButtons) {
|
|
3683
|
-
return /* @__PURE__ */
|
|
3684
|
-
/* @__PURE__ */
|
|
4423
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4424
|
+
/* @__PURE__ */ jsx7(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx7(
|
|
3685
4425
|
InterimButtonsView,
|
|
3686
4426
|
{
|
|
3687
4427
|
onButtonClick,
|
|
@@ -3699,12 +4439,12 @@ function FloPayCheckout({
|
|
|
3699
4439
|
] });
|
|
3700
4440
|
}
|
|
3701
4441
|
if (!flopay || !providerOptions) {
|
|
3702
|
-
return /* @__PURE__ */
|
|
4442
|
+
return /* @__PURE__ */ jsx7(Fragment3, { children: modeOverlay });
|
|
3703
4443
|
}
|
|
3704
4444
|
if (currentMode === "confirm") {
|
|
3705
|
-
return /* @__PURE__ */
|
|
3706
|
-
/* @__PURE__ */
|
|
3707
|
-
modeError && /* @__PURE__ */
|
|
4445
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4446
|
+
/* @__PURE__ */ jsx7(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx7(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: /* @__PURE__ */ jsxs5("div", { className, children: [
|
|
4447
|
+
modeError && /* @__PURE__ */ jsx7(
|
|
3708
4448
|
"div",
|
|
3709
4449
|
{
|
|
3710
4450
|
style: {
|
|
@@ -3719,7 +4459,7 @@ function FloPayCheckout({
|
|
|
3719
4459
|
renderConfirmButton ? renderConfirmButton({
|
|
3720
4460
|
onConfirm: handleConfirmCheckout,
|
|
3721
4461
|
isProcessing: confirmProcessing
|
|
3722
|
-
}) : /* @__PURE__ */
|
|
4462
|
+
}) : /* @__PURE__ */ jsx7(
|
|
3723
4463
|
"button",
|
|
3724
4464
|
{
|
|
3725
4465
|
type: "button",
|
|
@@ -3744,9 +4484,9 @@ function FloPayCheckout({
|
|
|
3744
4484
|
modeOverlay
|
|
3745
4485
|
] });
|
|
3746
4486
|
}
|
|
3747
|
-
return /* @__PURE__ */
|
|
3748
|
-
/* @__PURE__ */
|
|
3749
|
-
modeError && /* @__PURE__ */
|
|
4487
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4488
|
+
/* @__PURE__ */ jsx7(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx7(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: children ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4489
|
+
modeError && /* @__PURE__ */ jsx7(
|
|
3750
4490
|
"div",
|
|
3751
4491
|
{
|
|
3752
4492
|
style: {
|
|
@@ -3761,7 +4501,7 @@ function FloPayCheckout({
|
|
|
3761
4501
|
children: modeError
|
|
3762
4502
|
}
|
|
3763
4503
|
),
|
|
3764
|
-
/* @__PURE__ */
|
|
4504
|
+
/* @__PURE__ */ jsx7(
|
|
3765
4505
|
SessionInjector,
|
|
3766
4506
|
{
|
|
3767
4507
|
sessionId: activeSessionId,
|
|
@@ -3770,7 +4510,7 @@ function FloPayCheckout({
|
|
|
3770
4510
|
children
|
|
3771
4511
|
}
|
|
3772
4512
|
)
|
|
3773
|
-
] }) : /* @__PURE__ */
|
|
4513
|
+
] }) : /* @__PURE__ */ jsx7(
|
|
3774
4514
|
SplitCardForm,
|
|
3775
4515
|
{
|
|
3776
4516
|
sessionId: activeSessionId,
|
|
@@ -3809,7 +4549,11 @@ function FloPayCheckout({
|
|
|
3809
4549
|
checkoutType: createSessionParams ? "embedded_checkout" : "standard_checkout",
|
|
3810
4550
|
checkoutLayout: children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout",
|
|
3811
4551
|
submitLabel,
|
|
3812
|
-
className
|
|
4552
|
+
className,
|
|
4553
|
+
directPaypal: resolveDirectPaypalConfig(unified),
|
|
4554
|
+
isSubscription: session?.mode === "subscription",
|
|
4555
|
+
session,
|
|
4556
|
+
debug
|
|
3813
4557
|
}
|
|
3814
4558
|
) }) }),
|
|
3815
4559
|
modeOverlay
|
|
@@ -3821,8 +4565,8 @@ function SessionInjector({
|
|
|
3821
4565
|
session,
|
|
3822
4566
|
children
|
|
3823
4567
|
}) {
|
|
3824
|
-
return /* @__PURE__ */
|
|
3825
|
-
if (!
|
|
4568
|
+
return /* @__PURE__ */ jsx7(Fragment3, { children: React7.Children.map(children, (child) => {
|
|
4569
|
+
if (!React7.isValidElement(child)) return child;
|
|
3826
4570
|
const existing = child.props;
|
|
3827
4571
|
const injected = {};
|
|
3828
4572
|
if (!existing.sessionId) injected.sessionId = sessionId;
|
|
@@ -3836,7 +4580,7 @@ function SessionInjector({
|
|
|
3836
4580
|
injected.lastName = session.customer.lastName;
|
|
3837
4581
|
}
|
|
3838
4582
|
if (Object.keys(injected).length === 0) return child;
|
|
3839
|
-
return
|
|
4583
|
+
return React7.cloneElement(child, injected);
|
|
3840
4584
|
}) });
|
|
3841
4585
|
}
|
|
3842
4586
|
function InterimButtonsView({
|
|
@@ -3854,14 +4598,14 @@ function InterimButtonsView({
|
|
|
3854
4598
|
cardBackButtonContent,
|
|
3855
4599
|
cardTitleContent
|
|
3856
4600
|
}) {
|
|
3857
|
-
const [showCardForm, setShowCardForm] =
|
|
4601
|
+
const [showCardForm, setShowCardForm] = useState4(false);
|
|
3858
4602
|
const isCardOpenControlled = typeof cardOpen === "boolean";
|
|
3859
|
-
|
|
4603
|
+
useEffect5(() => {
|
|
3860
4604
|
if (isCardOpenControlled) {
|
|
3861
4605
|
setShowCardForm(cardOpen);
|
|
3862
4606
|
}
|
|
3863
4607
|
}, [cardOpen, isCardOpenControlled]);
|
|
3864
|
-
const bStyles =
|
|
4608
|
+
const bStyles = useMemo4(() => {
|
|
3865
4609
|
const base = resolveButtonsLayoutTheme2(buttonsTheme);
|
|
3866
4610
|
if (!stylesOverride) return base;
|
|
3867
4611
|
return {
|
|
@@ -3875,7 +4619,7 @@ function InterimButtonsView({
|
|
|
3875
4619
|
title: { ...base.title, ...stylesOverride.title }
|
|
3876
4620
|
};
|
|
3877
4621
|
}, [buttonsTheme, stylesOverride]);
|
|
3878
|
-
const skeleton = (h) => /* @__PURE__ */
|
|
4622
|
+
const skeleton = (h) => /* @__PURE__ */ jsx7("div", { style: {
|
|
3879
4623
|
height: h,
|
|
3880
4624
|
borderRadius: 8,
|
|
3881
4625
|
background: "#e5e7eb",
|
|
@@ -3887,15 +4631,15 @@ function InterimButtonsView({
|
|
|
3887
4631
|
const inputBg = bStyles.cardInputBackground ?? "white";
|
|
3888
4632
|
const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);
|
|
3889
4633
|
const hideTitle = isEmptySlotContent(cardTitleContent);
|
|
3890
|
-
return /* @__PURE__ */
|
|
4634
|
+
return /* @__PURE__ */ jsxs5("div", { style: {
|
|
3891
4635
|
backgroundColor: bStyles.cardFormContainer?.backgroundColor ?? "white",
|
|
3892
4636
|
borderRadius: "8px",
|
|
3893
4637
|
animation: "flopay-interim-expand 0.35s cubic-bezier(0.4, 0, 0.2, 1) both",
|
|
3894
4638
|
overflow: "hidden",
|
|
3895
4639
|
...bStyles.cardFormContainer
|
|
3896
4640
|
}, children: [
|
|
3897
|
-
/* @__PURE__ */
|
|
3898
|
-
/* @__PURE__ */
|
|
4641
|
+
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", alignItems: "center", padding: "0.75rem 0 0.625rem" }, children: [
|
|
4642
|
+
/* @__PURE__ */ jsxs5(
|
|
3899
4643
|
"button",
|
|
3900
4644
|
{
|
|
3901
4645
|
type: "button",
|
|
@@ -3922,7 +4666,7 @@ function InterimButtonsView({
|
|
|
3922
4666
|
...bStyles.backButton
|
|
3923
4667
|
},
|
|
3924
4668
|
children: [
|
|
3925
|
-
/* @__PURE__ */
|
|
4669
|
+
/* @__PURE__ */ jsx7("span", { style: {
|
|
3926
4670
|
display: "inline-flex",
|
|
3927
4671
|
alignItems: "center",
|
|
3928
4672
|
justifyContent: "center",
|
|
@@ -3931,12 +4675,12 @@ function InterimButtonsView({
|
|
|
3931
4675
|
borderRadius: "50%",
|
|
3932
4676
|
backgroundColor: "#f3f4f6",
|
|
3933
4677
|
...bStyles.backButtonIcon
|
|
3934
|
-
}, children: /* @__PURE__ */
|
|
3935
|
-
/* @__PURE__ */
|
|
4678
|
+
}, children: /* @__PURE__ */ jsx7("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx7("path", { d: "M15 18l-6-6 6-6" }) }) }),
|
|
4679
|
+
/* @__PURE__ */ jsx7(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
3936
4680
|
]
|
|
3937
4681
|
}
|
|
3938
4682
|
),
|
|
3939
|
-
hideTitle ? /* @__PURE__ */
|
|
4683
|
+
hideTitle ? /* @__PURE__ */ jsx7("div", { style: { flex: 1 } }) : /* @__PURE__ */ jsx7("div", { style: {
|
|
3940
4684
|
flex: 1,
|
|
3941
4685
|
textAlign: "center",
|
|
3942
4686
|
fontWeight: 600,
|
|
@@ -3944,15 +4688,15 @@ function InterimButtonsView({
|
|
|
3944
4688
|
color: "#262833",
|
|
3945
4689
|
paddingRight: 80,
|
|
3946
4690
|
...bStyles.title
|
|
3947
|
-
}, children: /* @__PURE__ */
|
|
4691
|
+
}, children: /* @__PURE__ */ jsx7(TitleContentSlot, { content: cardTitleContent }) })
|
|
3948
4692
|
] }),
|
|
3949
|
-
/* @__PURE__ */
|
|
3950
|
-
/* @__PURE__ */
|
|
3951
|
-
/* @__PURE__ */
|
|
3952
|
-
/* @__PURE__ */
|
|
4693
|
+
/* @__PURE__ */ jsx7("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx7("div", { style: { width: "60%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
4694
|
+
/* @__PURE__ */ jsxs5("div", { style: { display: "flex" }, children: [
|
|
4695
|
+
/* @__PURE__ */ jsx7("div", { style: { flex: 1, backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTop: "none", borderRight: "none", borderBottomLeftRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx7("div", { style: { width: "50%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
4696
|
+
/* @__PURE__ */ jsx7("div", { style: { flex: 1, backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTop: "none", borderBottomRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx7("div", { style: { width: "40%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) })
|
|
3953
4697
|
] }),
|
|
3954
|
-
/* @__PURE__ */
|
|
3955
|
-
/* @__PURE__ */
|
|
4698
|
+
/* @__PURE__ */ jsx7("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx7("div", { style: { width: "45%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
4699
|
+
/* @__PURE__ */ jsx7("div", { style: {
|
|
3956
4700
|
height: 50,
|
|
3957
4701
|
borderRadius: 8,
|
|
3958
4702
|
marginTop: 16,
|
|
@@ -3961,7 +4705,7 @@ function InterimButtonsView({
|
|
|
3961
4705
|
...bStyles.submitButton,
|
|
3962
4706
|
opacity: 0.5
|
|
3963
4707
|
} }),
|
|
3964
|
-
/* @__PURE__ */
|
|
4708
|
+
/* @__PURE__ */ jsx7("style", { children: `
|
|
3965
4709
|
@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
3966
4710
|
@keyframes flopay-interim-expand {
|
|
3967
4711
|
0% { opacity: 0; max-height: 0; transform: translateY(-12px); }
|
|
@@ -3971,10 +4715,10 @@ function InterimButtonsView({
|
|
|
3971
4715
|
` })
|
|
3972
4716
|
] });
|
|
3973
4717
|
}
|
|
3974
|
-
return /* @__PURE__ */
|
|
4718
|
+
return /* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
3975
4719
|
showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
3976
4720
|
(showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
3977
|
-
/* @__PURE__ */
|
|
4721
|
+
/* @__PURE__ */ jsx7(
|
|
3978
4722
|
"button",
|
|
3979
4723
|
{
|
|
3980
4724
|
type: "button",
|
|
@@ -4014,10 +4758,10 @@ function InterimButtonsView({
|
|
|
4014
4758
|
onMouseUp: (e) => {
|
|
4015
4759
|
e.currentTarget.style.transform = "scale(1)";
|
|
4016
4760
|
},
|
|
4017
|
-
children: /* @__PURE__ */
|
|
4761
|
+
children: /* @__PURE__ */ jsx7(CardButtonContentSlot, { content: cardButtonContent })
|
|
4018
4762
|
}
|
|
4019
4763
|
),
|
|
4020
|
-
errorMessage && /* @__PURE__ */
|
|
4764
|
+
errorMessage && /* @__PURE__ */ jsxs5("div", { style: {
|
|
4021
4765
|
margin: "0.25rem 0",
|
|
4022
4766
|
padding: "0.625rem 0.875rem",
|
|
4023
4767
|
background: "#FEF2F2",
|
|
@@ -4031,22 +4775,22 @@ function InterimButtonsView({
|
|
|
4031
4775
|
gap: "0.5rem",
|
|
4032
4776
|
...bStyles.errorBanner
|
|
4033
4777
|
}, children: [
|
|
4034
|
-
/* @__PURE__ */
|
|
4778
|
+
/* @__PURE__ */ jsx7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx7("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" }) }),
|
|
4035
4779
|
errorMessage
|
|
4036
4780
|
] }),
|
|
4037
|
-
/* @__PURE__ */
|
|
4781
|
+
/* @__PURE__ */ jsx7("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
4038
4782
|
] });
|
|
4039
4783
|
}
|
|
4040
4784
|
|
|
4041
4785
|
// src/checkout-form.tsx
|
|
4042
|
-
import { PaymentAPI as
|
|
4043
|
-
import { FloPayError as
|
|
4044
|
-
import { forwardRef as forwardRef2, useCallback as useCallback3, useEffect as
|
|
4045
|
-
import { Fragment as Fragment4, jsx as
|
|
4786
|
+
import { PaymentAPI as PaymentAPI5 } from "@flopay/js";
|
|
4787
|
+
import { FloPayError as FloPayError6 } from "@flopay/shared";
|
|
4788
|
+
import { forwardRef as forwardRef2, useCallback as useCallback3, useEffect as useEffect6, useImperativeHandle as useImperativeHandle2, useState as useState5 } from "react";
|
|
4789
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4046
4790
|
var WALLET_RESUME_KEY2 = "flopay_wallet_resume";
|
|
4047
4791
|
var CheckoutForm = forwardRef2(
|
|
4048
4792
|
function CheckoutForm2(props, ref) {
|
|
4049
|
-
return /* @__PURE__ */
|
|
4793
|
+
return /* @__PURE__ */ jsx8(CheckoutFormInner, { ...props, innerRef: ref });
|
|
4050
4794
|
}
|
|
4051
4795
|
);
|
|
4052
4796
|
function CheckoutFormInner({
|
|
@@ -4075,9 +4819,9 @@ function CheckoutFormInner({
|
|
|
4075
4819
|
const paypalFlopay = usePayPalFloPay();
|
|
4076
4820
|
const elements = useElements();
|
|
4077
4821
|
const contextBillingUrl = useBillingApiUrl();
|
|
4078
|
-
const [processing, setProcessing] =
|
|
4079
|
-
const [error, setError] =
|
|
4080
|
-
const [is3DSActive, setIs3DSActive] =
|
|
4822
|
+
const [processing, setProcessing] = useState5(false);
|
|
4823
|
+
const [error, setError] = useState5(null);
|
|
4824
|
+
const [is3DSActive, setIs3DSActive] = useState5(false);
|
|
4081
4825
|
const displayError = externalError ?? error;
|
|
4082
4826
|
const isSubmitting = externalProcessing ?? processing;
|
|
4083
4827
|
const isSelfContained = !onTokenizedBody;
|
|
@@ -4102,7 +4846,7 @@ function CheckoutFormInner({
|
|
|
4102
4846
|
const resolvedCompletionPaymentMethodId = completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);
|
|
4103
4847
|
const requestTokenizedBody = tokenizedBody.originalPaymentMethodId ? { ...tokenizedBody, originalPaymentMethodId: void 0 } : tokenizedBody;
|
|
4104
4848
|
try {
|
|
4105
|
-
const api = new
|
|
4849
|
+
const api = new PaymentAPI5(baseUrl);
|
|
4106
4850
|
const response = await api.processPayment(userId ?? "", {
|
|
4107
4851
|
sessionId,
|
|
4108
4852
|
tokenizedData: requestTokenizedBody,
|
|
@@ -4243,7 +4987,7 @@ function CheckoutFormInner({
|
|
|
4243
4987
|
}
|
|
4244
4988
|
}
|
|
4245
4989
|
}), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
|
|
4246
|
-
|
|
4990
|
+
useEffect6(() => {
|
|
4247
4991
|
if (typeof window === "undefined") return;
|
|
4248
4992
|
const stored = localStorage.getItem(WALLET_RESUME_KEY2);
|
|
4249
4993
|
if (!stored) return;
|
|
@@ -4285,7 +5029,7 @@ function CheckoutFormInner({
|
|
|
4285
5029
|
return;
|
|
4286
5030
|
}
|
|
4287
5031
|
if (!sessionId || !email) {
|
|
4288
|
-
throw new
|
|
5032
|
+
throw new FloPayError6("Missing sessionId or email", "validation_error");
|
|
4289
5033
|
}
|
|
4290
5034
|
const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
|
|
4291
5035
|
method: "POST",
|
|
@@ -4309,7 +5053,7 @@ function CheckoutFormInner({
|
|
|
4309
5053
|
}
|
|
4310
5054
|
const intentJson = await intentResponse.json();
|
|
4311
5055
|
const intentClientSecret = intentJson.data?.id;
|
|
4312
|
-
if (!intentClientSecret) throw new
|
|
5056
|
+
if (!intentClientSecret) throw new FloPayError6("No client_secret in payment intent response", "api_error");
|
|
4313
5057
|
const confirmResult = await flopay.confirmCardPayment({
|
|
4314
5058
|
clientSecret: intentClientSecret,
|
|
4315
5059
|
paymentMethodId: pmResult.paymentMethodId
|
|
@@ -4328,7 +5072,7 @@ function CheckoutFormInner({
|
|
|
4328
5072
|
const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
|
|
4329
5073
|
const paymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? pmResult.paymentMethodId;
|
|
4330
5074
|
if (!paymentIntentId) {
|
|
4331
|
-
const error2 = new
|
|
5075
|
+
const error2 = new FloPayError6("No payment intent returned after confirmation.", "api_error");
|
|
4332
5076
|
updateError(error2.message);
|
|
4333
5077
|
onError?.(error2);
|
|
4334
5078
|
return;
|
|
@@ -4351,8 +5095,8 @@ function CheckoutFormInner({
|
|
|
4351
5095
|
[flopay, elements, isSubmitting, sessionId, email, baseUrl, isSelfContained, dispatchTokenizedBody, onError, updateError, emitDecline]
|
|
4352
5096
|
);
|
|
4353
5097
|
const isReady = flopay !== null && elements !== null;
|
|
4354
|
-
return /* @__PURE__ */
|
|
4355
|
-
(is3DSActive || isSubmitting) && /* @__PURE__ */
|
|
5098
|
+
return /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
5099
|
+
(is3DSActive || isSubmitting) && /* @__PURE__ */ jsx8("div", { "data-testid": "flopay-overlay", style: {
|
|
4356
5100
|
position: "absolute",
|
|
4357
5101
|
inset: 0,
|
|
4358
5102
|
background: "rgba(255,255,255,0.7)",
|
|
@@ -4361,12 +5105,12 @@ function CheckoutFormInner({
|
|
|
4361
5105
|
justifyContent: "center",
|
|
4362
5106
|
zIndex: 10
|
|
4363
5107
|
}, children: is3DSActive ? "Verifying payment..." : "Processing..." }),
|
|
4364
|
-
!isReady && /* @__PURE__ */
|
|
4365
|
-
isReady && /* @__PURE__ */
|
|
4366
|
-
/* @__PURE__ */
|
|
4367
|
-
showAddress && /* @__PURE__ */
|
|
4368
|
-
displayError && /* @__PURE__ */
|
|
4369
|
-
children ?? /* @__PURE__ */
|
|
5108
|
+
!isReady && /* @__PURE__ */ jsx8("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." }),
|
|
5109
|
+
isReady && /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
5110
|
+
/* @__PURE__ */ jsx8(PaymentElement, { options: { layout } }),
|
|
5111
|
+
showAddress && /* @__PURE__ */ jsx8(AddressElement, { options: { mode: showAddress === true ? "billing" : showAddress } }),
|
|
5112
|
+
displayError && /* @__PURE__ */ jsx8("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0" }, children: displayError }),
|
|
5113
|
+
children ?? /* @__PURE__ */ jsx8(
|
|
4370
5114
|
"button",
|
|
4371
5115
|
{
|
|
4372
5116
|
type: "submit",
|
|
@@ -4380,10 +5124,10 @@ function CheckoutFormInner({
|
|
|
4380
5124
|
}
|
|
4381
5125
|
|
|
4382
5126
|
// src/paypal-button.tsx
|
|
4383
|
-
import { PaymentAPI as
|
|
4384
|
-
import { FloPayError as
|
|
4385
|
-
import { useCallback as useCallback4, useEffect as
|
|
4386
|
-
import { Fragment as Fragment5, jsx as
|
|
5127
|
+
import { PaymentAPI as PaymentAPI6 } from "@flopay/js";
|
|
5128
|
+
import { FloPayError as FloPayError7 } from "@flopay/shared";
|
|
5129
|
+
import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef5, useState as useState6 } from "react";
|
|
5130
|
+
import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4387
5131
|
function PayPalButton({
|
|
4388
5132
|
sessionId,
|
|
4389
5133
|
billingApiUrl,
|
|
@@ -4400,14 +5144,14 @@ function PayPalButton({
|
|
|
4400
5144
|
const flopay = useFloPay();
|
|
4401
5145
|
const elements = useElements();
|
|
4402
5146
|
const contextBillingUrl = useBillingApiUrl();
|
|
4403
|
-
const [ready, setReady] =
|
|
4404
|
-
const [submitting, setSubmitting] =
|
|
4405
|
-
const paypalResumeAttempted =
|
|
5147
|
+
const [ready, setReady] = useState6(false);
|
|
5148
|
+
const [submitting, setSubmitting] = useState6(false);
|
|
5149
|
+
const paypalResumeAttempted = useRef5(false);
|
|
4406
5150
|
const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
|
|
4407
5151
|
const processPaymentInternal = useCallback4(
|
|
4408
5152
|
async (tokenizedBody) => {
|
|
4409
5153
|
try {
|
|
4410
|
-
const api = new
|
|
5154
|
+
const api = new PaymentAPI6(baseUrl);
|
|
4411
5155
|
const response = await api.processPayment(userId ?? "", {
|
|
4412
5156
|
sessionId,
|
|
4413
5157
|
tokenizedData: tokenizedBody,
|
|
@@ -4441,7 +5185,7 @@ function PayPalButton({
|
|
|
4441
5185
|
},
|
|
4442
5186
|
[onTokenizedBody, processPaymentInternal]
|
|
4443
5187
|
);
|
|
4444
|
-
|
|
5188
|
+
useEffect7(() => {
|
|
4445
5189
|
if (!flopay || paypalResumeAttempted.current) return;
|
|
4446
5190
|
const params = new URLSearchParams(window.location.search);
|
|
4447
5191
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -4495,7 +5239,7 @@ function PayPalButton({
|
|
|
4495
5239
|
setSubmitting(true);
|
|
4496
5240
|
onErrorChange?.(null);
|
|
4497
5241
|
if (!sessionId || !email) {
|
|
4498
|
-
throw new
|
|
5242
|
+
throw new FloPayError7("Missing sessionId or email for PayPal payment", "validation_error");
|
|
4499
5243
|
}
|
|
4500
5244
|
const result = await flopay.confirmPayPalPayment({
|
|
4501
5245
|
billingApiUrl: baseUrl,
|
|
@@ -4522,11 +5266,11 @@ function PayPalButton({
|
|
|
4522
5266
|
}
|
|
4523
5267
|
}, [flopay, elements, sessionId, email, baseUrl, dispatchTokenizedBody, onErrorChange]);
|
|
4524
5268
|
if (!flopay || !elements) {
|
|
4525
|
-
return /* @__PURE__ */
|
|
5269
|
+
return /* @__PURE__ */ jsx9("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6, animation: "pulse 1.5s infinite" } });
|
|
4526
5270
|
}
|
|
4527
|
-
return /* @__PURE__ */
|
|
4528
|
-
!ready && /* @__PURE__ */
|
|
4529
|
-
/* @__PURE__ */
|
|
5271
|
+
return /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
5272
|
+
!ready && /* @__PURE__ */ jsx9("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6 } }),
|
|
5273
|
+
/* @__PURE__ */ jsx9("div", { style: ready ? {} : { display: "none" }, children: /* @__PURE__ */ jsx9(
|
|
4530
5274
|
"button",
|
|
4531
5275
|
{
|
|
4532
5276
|
type: "button",
|
|
@@ -4548,7 +5292,7 @@ function PayPalButton({
|
|
|
4548
5292
|
children: submitting ? "Processing..." : "PayPal"
|
|
4549
5293
|
}
|
|
4550
5294
|
) }),
|
|
4551
|
-
(submitting || isProcessing) && /* @__PURE__ */
|
|
5295
|
+
(submitting || isProcessing) && /* @__PURE__ */ jsx9("div", { style: {
|
|
4552
5296
|
position: "fixed",
|
|
4553
5297
|
inset: 0,
|
|
4554
5298
|
background: "rgba(0,0,0,0.4)",
|
|
@@ -4556,7 +5300,7 @@ function PayPalButton({
|
|
|
4556
5300
|
alignItems: "center",
|
|
4557
5301
|
justifyContent: "center",
|
|
4558
5302
|
zIndex: 1e3
|
|
4559
|
-
}, children: /* @__PURE__ */
|
|
5303
|
+
}, children: /* @__PURE__ */ jsx9("div", { style: {
|
|
4560
5304
|
background: "white",
|
|
4561
5305
|
borderRadius: 8,
|
|
4562
5306
|
padding: "1.5rem",
|
|
@@ -4568,20 +5312,20 @@ function PayPalButton({
|
|
|
4568
5312
|
}
|
|
4569
5313
|
|
|
4570
5314
|
// src/automatic-payment-button.tsx
|
|
4571
|
-
import { useCallback as useCallback5, useEffect as
|
|
4572
|
-
import { PaymentAPI as
|
|
4573
|
-
import { FloPayError as
|
|
4574
|
-
import { Fragment as Fragment6, jsx as
|
|
5315
|
+
import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMemo5, useRef as useRef6, useState as useState7 } from "react";
|
|
5316
|
+
import { PaymentAPI as PaymentAPI7 } from "@flopay/js";
|
|
5317
|
+
import { FloPayError as FloPayError8, resolveBillingApiUrl as resolveBillingApiUrl4, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme3 } from "@flopay/shared";
|
|
5318
|
+
import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4575
5319
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3 = 44;
|
|
4576
5320
|
var PAYPAL_RESUME_STORAGE_KEY2 = "flopay_automatic_payment_button_resume";
|
|
4577
5321
|
function sleep2(ms) {
|
|
4578
5322
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4579
5323
|
}
|
|
4580
5324
|
function coerceError(err, fallbackMessage) {
|
|
4581
|
-
if (err instanceof
|
|
5325
|
+
if (err instanceof FloPayError8) {
|
|
4582
5326
|
return err;
|
|
4583
5327
|
}
|
|
4584
|
-
return new
|
|
5328
|
+
return new FloPayError8(
|
|
4585
5329
|
err instanceof Error ? err.message : fallbackMessage,
|
|
4586
5330
|
"api_error"
|
|
4587
5331
|
);
|
|
@@ -4688,11 +5432,11 @@ function FloPayAutomaticPaymentButton({
|
|
|
4688
5432
|
style,
|
|
4689
5433
|
...buttonProps
|
|
4690
5434
|
}) {
|
|
4691
|
-
const resolvedBillingUrl =
|
|
5435
|
+
const resolvedBillingUrl = useMemo5(
|
|
4692
5436
|
() => resolveBillingApiUrl4(billingApiUrl),
|
|
4693
5437
|
[billingApiUrl]
|
|
4694
5438
|
);
|
|
4695
|
-
const createSessionDraft =
|
|
5439
|
+
const createSessionDraft = useMemo5(
|
|
4696
5440
|
() => resolveCreateSessionDraft({
|
|
4697
5441
|
createSession,
|
|
4698
5442
|
clientId,
|
|
@@ -4718,43 +5462,47 @@ function FloPayAutomaticPaymentButton({
|
|
|
4718
5462
|
utmMetadata
|
|
4719
5463
|
]
|
|
4720
5464
|
);
|
|
4721
|
-
const [isProcessing, setIsProcessing] =
|
|
4722
|
-
const [overlayStatus, setOverlayStatus] =
|
|
4723
|
-
const [overlayError, setOverlayError] =
|
|
4724
|
-
const [fallbackSession, setFallbackSession] =
|
|
4725
|
-
const automaticPaymentToken =
|
|
5465
|
+
const [isProcessing, setIsProcessing] = useState7(false);
|
|
5466
|
+
const [overlayStatus, setOverlayStatus] = useState7(null);
|
|
5467
|
+
const [overlayError, setOverlayError] = useState7(null);
|
|
5468
|
+
const [fallbackSession, setFallbackSession] = useState7(null);
|
|
5469
|
+
const automaticPaymentToken = useMemo5(
|
|
4726
5470
|
() => paymentMethodId ? {
|
|
4727
5471
|
id: paymentMethodId,
|
|
4728
|
-
|
|
5472
|
+
// Saved PayPal `user_payment_method` records are submitted with
|
|
5473
|
+
// `type: 'paypal'` so the backend routes the upsell through the
|
|
5474
|
+
// direct PayPal gateway's vaulted-token flow. Card and wallet PMs
|
|
5475
|
+
// continue to use `type: 'card'`.
|
|
5476
|
+
type: checkoutMethod === "paypal" ? "paypal" : "card",
|
|
4729
5477
|
...checkoutMethod === "paypal" ? { isPaypal: true } : {}
|
|
4730
5478
|
} : void 0,
|
|
4731
5479
|
[checkoutMethod, paymentMethodId]
|
|
4732
5480
|
);
|
|
4733
|
-
const isMountedRef =
|
|
4734
|
-
const resumeAttemptedRef =
|
|
4735
|
-
const fallbackSessionRef =
|
|
4736
|
-
const onSuccessRef =
|
|
4737
|
-
const onErrorRef =
|
|
4738
|
-
const onDeclineRef =
|
|
4739
|
-
|
|
5481
|
+
const isMountedRef = useRef6(true);
|
|
5482
|
+
const resumeAttemptedRef = useRef6(false);
|
|
5483
|
+
const fallbackSessionRef = useRef6(fallbackSession);
|
|
5484
|
+
const onSuccessRef = useRef6(onSuccess);
|
|
5485
|
+
const onErrorRef = useRef6(onError);
|
|
5486
|
+
const onDeclineRef = useRef6(onDecline);
|
|
5487
|
+
useEffect8(() => {
|
|
4740
5488
|
fallbackSessionRef.current = fallbackSession;
|
|
4741
5489
|
}, [fallbackSession]);
|
|
4742
|
-
|
|
5490
|
+
useEffect8(() => {
|
|
4743
5491
|
onSuccessRef.current = onSuccess;
|
|
4744
5492
|
}, [onSuccess]);
|
|
4745
|
-
|
|
5493
|
+
useEffect8(() => {
|
|
4746
5494
|
onErrorRef.current = onError;
|
|
4747
5495
|
}, [onError]);
|
|
4748
|
-
|
|
5496
|
+
useEffect8(() => {
|
|
4749
5497
|
onDeclineRef.current = onDecline;
|
|
4750
5498
|
}, [onDecline]);
|
|
4751
|
-
|
|
5499
|
+
useEffect8(() => {
|
|
4752
5500
|
isMountedRef.current = true;
|
|
4753
5501
|
return () => {
|
|
4754
5502
|
isMountedRef.current = false;
|
|
4755
5503
|
};
|
|
4756
5504
|
}, []);
|
|
4757
|
-
|
|
5505
|
+
useEffect8(() => {
|
|
4758
5506
|
if (!fallbackSession || typeof window === "undefined") {
|
|
4759
5507
|
return;
|
|
4760
5508
|
}
|
|
@@ -4795,7 +5543,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
4795
5543
|
const processResolvedSession = useCallback5(async (apiResult, resolvedSessionId, options) => {
|
|
4796
5544
|
const session = apiResult.data.session ?? null;
|
|
4797
5545
|
if (!session) {
|
|
4798
|
-
throw new
|
|
5546
|
+
throw new FloPayError8("No session data returned", "api_error");
|
|
4799
5547
|
}
|
|
4800
5548
|
if (session.status === "complete") {
|
|
4801
5549
|
await showSuccess({
|
|
@@ -4807,7 +5555,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
4807
5555
|
return;
|
|
4808
5556
|
}
|
|
4809
5557
|
if (session.status === "expired") {
|
|
4810
|
-
throw new
|
|
5558
|
+
throw new FloPayError8("Checkout session has expired.", "api_error", {
|
|
4811
5559
|
code: "checkout_session_expired"
|
|
4812
5560
|
});
|
|
4813
5561
|
}
|
|
@@ -4817,13 +5565,13 @@ function FloPayAutomaticPaymentButton({
|
|
|
4817
5565
|
const shouldTreatCreateSessionFlowAsServerAutoAttempt = options?.fromCreateSession && (apiResult.autoProcessingAttempted === true || !!apiResult.autoProcessingError || !!redirectResult);
|
|
4818
5566
|
const shouldRetryPayPalClientSide = checkoutMethod === "paypal" && automaticPaymentToken?.isPaypal === true && options?.fromCreateSession === true;
|
|
4819
5567
|
if (apiResult.autoProcessingPending) {
|
|
4820
|
-
const api = new
|
|
5568
|
+
const api = new PaymentAPI7(resolvedBillingUrl);
|
|
4821
5569
|
const completed = await api.waitForCheckoutSessionCompletion(apiResult.autoProcessingPending.sessionId, {
|
|
4822
5570
|
initialDelayMs: apiResult.autoProcessingPending.retryAfterMs
|
|
4823
5571
|
});
|
|
4824
5572
|
const completedSession = completed.data.session;
|
|
4825
5573
|
if (!completedSession || completedSession.status !== "complete") {
|
|
4826
|
-
throw new
|
|
5574
|
+
throw new FloPayError8("Automatic payment failed. Please try again.", "api_error", {
|
|
4827
5575
|
code: completedSession?.status === "expired" ? "checkout_session_expired" : "checkout_processing_timeout"
|
|
4828
5576
|
});
|
|
4829
5577
|
}
|
|
@@ -5022,7 +5770,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5022
5770
|
}
|
|
5023
5771
|
setFallbackSession(null);
|
|
5024
5772
|
if (sessionId && createSessionDraft) {
|
|
5025
|
-
const error = new
|
|
5773
|
+
const error = new FloPayError8(
|
|
5026
5774
|
"Provide either sessionId or create-session props, not both.",
|
|
5027
5775
|
"validation_error"
|
|
5028
5776
|
);
|
|
@@ -5034,7 +5782,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5034
5782
|
return;
|
|
5035
5783
|
}
|
|
5036
5784
|
if (!sessionId && !createSessionDraft) {
|
|
5037
|
-
const error = new
|
|
5785
|
+
const error = new FloPayError8(
|
|
5038
5786
|
"Provide a sessionId or the props required to create an automatic payment session.",
|
|
5039
5787
|
"validation_error"
|
|
5040
5788
|
);
|
|
@@ -5049,7 +5797,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5049
5797
|
setOverlayError(null);
|
|
5050
5798
|
setOverlayStatus("processing");
|
|
5051
5799
|
try {
|
|
5052
|
-
const api = new
|
|
5800
|
+
const api = new PaymentAPI7(resolvedBillingUrl);
|
|
5053
5801
|
if (sessionId) {
|
|
5054
5802
|
const result = await api.getUnifiedCheckoutSession(sessionId);
|
|
5055
5803
|
await processResolvedSession(result, sessionId);
|
|
@@ -5064,7 +5812,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5064
5812
|
fromCreateSession: true
|
|
5065
5813
|
});
|
|
5066
5814
|
} catch (err) {
|
|
5067
|
-
if (err instanceof
|
|
5815
|
+
if (err instanceof FloPayError8 && err.code === "session_auto_completed") {
|
|
5068
5816
|
await showSuccess({
|
|
5069
5817
|
result: { status: "succeeded" },
|
|
5070
5818
|
session: null,
|
|
@@ -5113,7 +5861,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5113
5861
|
const handleFallbackDecline = useCallback5((decline) => {
|
|
5114
5862
|
onDeclineRef.current?.(decline);
|
|
5115
5863
|
}, []);
|
|
5116
|
-
|
|
5864
|
+
useEffect8(() => {
|
|
5117
5865
|
if (typeof window === "undefined" || resumeAttemptedRef.current) {
|
|
5118
5866
|
return;
|
|
5119
5867
|
}
|
|
@@ -5134,7 +5882,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5134
5882
|
try {
|
|
5135
5883
|
if (params.get("redirect_status") === "failed") {
|
|
5136
5884
|
throw Object.assign(
|
|
5137
|
-
new
|
|
5885
|
+
new FloPayError8("PayPal payment was declined. Please try again.", "api_error"),
|
|
5138
5886
|
{ checkoutMethod: "paypal" }
|
|
5139
5887
|
);
|
|
5140
5888
|
}
|
|
@@ -5150,14 +5898,14 @@ function FloPayAutomaticPaymentButton({
|
|
|
5150
5898
|
const paypalStripe = (paypalFlopay ?? flopay).getRawProvider();
|
|
5151
5899
|
if (!paypalStripe) {
|
|
5152
5900
|
throw Object.assign(
|
|
5153
|
-
new
|
|
5901
|
+
new FloPayError8("PayPal is not available.", "api_error"),
|
|
5154
5902
|
{ checkoutMethod: "paypal" }
|
|
5155
5903
|
);
|
|
5156
5904
|
}
|
|
5157
5905
|
const { paymentIntent, error } = await paypalStripe.retrievePaymentIntent(clientSecret);
|
|
5158
5906
|
if (error) {
|
|
5159
5907
|
throw Object.assign(
|
|
5160
|
-
new
|
|
5908
|
+
new FloPayError8(
|
|
5161
5909
|
error.message ?? "Failed to retrieve PayPal payment status.",
|
|
5162
5910
|
"api_error",
|
|
5163
5911
|
{ code: error.code }
|
|
@@ -5168,23 +5916,23 @@ function FloPayAutomaticPaymentButton({
|
|
|
5168
5916
|
const resultStatus = mapPayPalIntentStatusToPaymentResult(paymentIntent?.status);
|
|
5169
5917
|
if (!paymentIntent || resultStatus === "failed") {
|
|
5170
5918
|
throw Object.assign(
|
|
5171
|
-
new
|
|
5919
|
+
new FloPayError8("PayPal payment was not completed. Please try again.", "api_error"),
|
|
5172
5920
|
{ checkoutMethod: "paypal" }
|
|
5173
5921
|
);
|
|
5174
5922
|
}
|
|
5175
5923
|
const paymentMethodId2 = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
5176
5924
|
if (!resumeState.sessionId) {
|
|
5177
5925
|
throw Object.assign(
|
|
5178
|
-
new
|
|
5926
|
+
new FloPayError8("Missing session id on PayPal resume.", "api_error"),
|
|
5179
5927
|
{ checkoutMethod: "paypal" }
|
|
5180
5928
|
);
|
|
5181
5929
|
}
|
|
5182
|
-
const api = new
|
|
5930
|
+
const api = new PaymentAPI7(resolvedBillingUrl);
|
|
5183
5931
|
const sessionResult = await api.getUnifiedCheckoutSession(resumeState.sessionId);
|
|
5184
5932
|
let resumeSession = sessionResult.data.session;
|
|
5185
5933
|
if (!resumeSession) {
|
|
5186
5934
|
throw Object.assign(
|
|
5187
|
-
new
|
|
5935
|
+
new FloPayError8("Could not load session to capture PayPal payment.", "api_error"),
|
|
5188
5936
|
{ checkoutMethod: "paypal" }
|
|
5189
5937
|
);
|
|
5190
5938
|
}
|
|
@@ -5203,7 +5951,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5203
5951
|
});
|
|
5204
5952
|
if (processResult.type !== "success") {
|
|
5205
5953
|
throw Object.assign(
|
|
5206
|
-
new
|
|
5954
|
+
new FloPayError8("Failed to finalize PayPal payment.", "api_error"),
|
|
5207
5955
|
{ checkoutMethod: "paypal" }
|
|
5208
5956
|
);
|
|
5209
5957
|
}
|
|
@@ -5244,7 +5992,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5244
5992
|
}
|
|
5245
5993
|
})();
|
|
5246
5994
|
}, [locale, resolvedBillingUrl, showError, showSuccess]);
|
|
5247
|
-
const bStyles =
|
|
5995
|
+
const bStyles = useMemo5(() => {
|
|
5248
5996
|
const base = resolveButtonsLayoutTheme3(buttonsTheme);
|
|
5249
5997
|
if (!stylesOverride) return base;
|
|
5250
5998
|
return {
|
|
@@ -5254,8 +6002,8 @@ function FloPayAutomaticPaymentButton({
|
|
|
5254
6002
|
};
|
|
5255
6003
|
}, [buttonsTheme, stylesOverride]);
|
|
5256
6004
|
const cardButtonSizing = children === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
5257
|
-
return /* @__PURE__ */
|
|
5258
|
-
/* @__PURE__ */
|
|
6005
|
+
return /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
6006
|
+
/* @__PURE__ */ jsx10(
|
|
5259
6007
|
"button",
|
|
5260
6008
|
{
|
|
5261
6009
|
...buttonProps,
|
|
@@ -5296,17 +6044,17 @@ function FloPayAutomaticPaymentButton({
|
|
|
5296
6044
|
e.currentTarget.style.transform = "scale(1)";
|
|
5297
6045
|
}
|
|
5298
6046
|
},
|
|
5299
|
-
children: /* @__PURE__ */
|
|
6047
|
+
children: /* @__PURE__ */ jsx10(CardButtonContentSlot, { content: children })
|
|
5300
6048
|
}
|
|
5301
6049
|
),
|
|
5302
|
-
overlayStatus && /* @__PURE__ */
|
|
6050
|
+
overlayStatus && /* @__PURE__ */ jsx10(
|
|
5303
6051
|
ProcessingOverlay,
|
|
5304
6052
|
{
|
|
5305
6053
|
status: overlayStatus,
|
|
5306
6054
|
errorMessage: overlayError
|
|
5307
6055
|
}
|
|
5308
6056
|
),
|
|
5309
|
-
fallbackSession && /* @__PURE__ */
|
|
6057
|
+
fallbackSession && /* @__PURE__ */ jsx10(
|
|
5310
6058
|
"div",
|
|
5311
6059
|
{
|
|
5312
6060
|
"data-testid": "flopay-automatic-payment-fallback",
|
|
@@ -5327,7 +6075,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5327
6075
|
padding: "1.5rem",
|
|
5328
6076
|
zIndex: 1100
|
|
5329
6077
|
},
|
|
5330
|
-
children: /* @__PURE__ */
|
|
6078
|
+
children: /* @__PURE__ */ jsx10(
|
|
5331
6079
|
"div",
|
|
5332
6080
|
{
|
|
5333
6081
|
style: {
|
|
@@ -5343,7 +6091,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5343
6091
|
flexDirection: "column",
|
|
5344
6092
|
gap: "1rem"
|
|
5345
6093
|
},
|
|
5346
|
-
children: /* @__PURE__ */
|
|
6094
|
+
children: /* @__PURE__ */ jsx10(
|
|
5347
6095
|
FloPayCheckout,
|
|
5348
6096
|
{
|
|
5349
6097
|
sessionId: fallbackSession.sessionId,
|
|
@@ -5370,6 +6118,7 @@ export {
|
|
|
5370
6118
|
CardExpiryElement,
|
|
5371
6119
|
CardNumberElement,
|
|
5372
6120
|
CheckoutForm,
|
|
6121
|
+
DirectPayPalButton,
|
|
5373
6122
|
FloPayAutomaticPaymentButton,
|
|
5374
6123
|
FloPayCheckout,
|
|
5375
6124
|
FloPayProvider,
|