@flopay/react 0.1.5 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -0
- package/dist/index.cjs +762 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -4
- package/dist/index.d.ts +48 -4
- package/dist/index.mjs +743 -142
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -69,7 +69,7 @@ function FloPayProvider({
|
|
|
69
69
|
// src/flopay-checkout.tsx
|
|
70
70
|
import React4, { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
|
|
71
71
|
import { loadFloPay, PaymentAPI } from "@flopay/js";
|
|
72
|
-
import { FloPayError as FloPayError2, resolveBillingApiUrl as resolveBillingApiUrl3, buildCheckoutDisplayData } from "@flopay/shared";
|
|
72
|
+
import { FloPayError as FloPayError2, resolveBillingApiUrl as resolveBillingApiUrl3, buildCheckoutDisplayData, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme2 } from "@flopay/shared";
|
|
73
73
|
|
|
74
74
|
// src/elements.tsx
|
|
75
75
|
import { useEffect as useEffect2, useRef, useContext } from "react";
|
|
@@ -138,6 +138,7 @@ import {
|
|
|
138
138
|
useElements as useStripeElements,
|
|
139
139
|
useStripe as useStripeRaw
|
|
140
140
|
} from "@stripe/react-stripe-js";
|
|
141
|
+
import { resolveButtonsLayoutTheme } from "@flopay/shared";
|
|
141
142
|
import { forwardRef, useCallback, useEffect as useEffect3, useImperativeHandle, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
142
143
|
|
|
143
144
|
// src/hooks.ts
|
|
@@ -163,7 +164,30 @@ function useBillingApiUrl() {
|
|
|
163
164
|
import { FloPayError } from "@flopay/shared";
|
|
164
165
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
165
166
|
var WALLET_RESUME_KEY = "flopay_wallet_resume";
|
|
166
|
-
|
|
167
|
+
var FLOPAY_KEYFRAMES = `
|
|
168
|
+
@keyframes flopay-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
169
|
+
@keyframes flopay-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
|
|
170
|
+
@keyframes flopay-buttons-enter {
|
|
171
|
+
0% { opacity: 0; transform: translateX(-16px) scale(0.97); }
|
|
172
|
+
100% { opacity: 1; transform: translateX(0) scale(1); }
|
|
173
|
+
}
|
|
174
|
+
@keyframes flopay-buttons-exit {
|
|
175
|
+
0% { opacity: 1; transform: translateX(0) scale(1); }
|
|
176
|
+
100% { opacity: 0; transform: translateX(-16px) scale(0.97); }
|
|
177
|
+
}
|
|
178
|
+
@keyframes flopay-card-enter {
|
|
179
|
+
0% { opacity: 0; transform: translateX(16px) scale(0.97); }
|
|
180
|
+
100% { opacity: 1; transform: translateX(0) scale(1); }
|
|
181
|
+
}
|
|
182
|
+
@keyframes flopay-card-exit {
|
|
183
|
+
0% { opacity: 1; transform: translateX(0) scale(1); }
|
|
184
|
+
100% { opacity: 0; transform: translateX(16px) scale(0.97); }
|
|
185
|
+
}
|
|
186
|
+
`;
|
|
187
|
+
function FloPayKeyframes() {
|
|
188
|
+
return /* @__PURE__ */ jsx3("style", { children: FLOPAY_KEYFRAMES });
|
|
189
|
+
}
|
|
190
|
+
function ProcessingOverlay({ status, errorMessage }) {
|
|
167
191
|
return /* @__PURE__ */ jsx3("div", { style: {
|
|
168
192
|
position: "fixed",
|
|
169
193
|
inset: 0,
|
|
@@ -239,6 +263,14 @@ function ProcessingOverlay({ status }) {
|
|
|
239
263
|
status === "success" && "PAYMENT SUCCESSFUL",
|
|
240
264
|
status === "error" && "PAYMENT FAILED"
|
|
241
265
|
] }),
|
|
266
|
+
status === "error" && errorMessage && /* @__PURE__ */ jsx3("p", { style: {
|
|
267
|
+
fontSize: 13,
|
|
268
|
+
color: "#6b7280",
|
|
269
|
+
fontWeight: 400,
|
|
270
|
+
maxWidth: 260,
|
|
271
|
+
lineHeight: 1.4,
|
|
272
|
+
margin: 0
|
|
273
|
+
}, children: errorMessage }),
|
|
242
274
|
/* @__PURE__ */ jsx3("style", { children: `
|
|
243
275
|
@keyframes flopay-spin { to { transform: rotate(360deg); } }
|
|
244
276
|
@keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
|
|
@@ -258,7 +290,8 @@ function PayPalButtonInner({
|
|
|
258
290
|
billingApiUrl,
|
|
259
291
|
onTokenizedBody,
|
|
260
292
|
onErrorChange,
|
|
261
|
-
isProcessing = false
|
|
293
|
+
isProcessing = false,
|
|
294
|
+
onButtonClick
|
|
262
295
|
}) {
|
|
263
296
|
const stripe = useStripeRaw();
|
|
264
297
|
const elements = useStripeElements();
|
|
@@ -311,6 +344,7 @@ function PayPalButtonInner({
|
|
|
311
344
|
}, [stripe, onTokenizedBody, onErrorChange]);
|
|
312
345
|
const handlePayPalConfirm = useCallback(async (_event) => {
|
|
313
346
|
if (!stripe || !elements) return;
|
|
347
|
+
onButtonClick?.("paypal");
|
|
314
348
|
try {
|
|
315
349
|
setSubmitting(true);
|
|
316
350
|
onErrorChange?.(null);
|
|
@@ -365,7 +399,7 @@ function PayPalButtonInner({
|
|
|
365
399
|
}
|
|
366
400
|
}, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange]);
|
|
367
401
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
368
|
-
/* @__PURE__ */ jsx3("div", {
|
|
402
|
+
/* @__PURE__ */ jsx3("div", { children: /* @__PURE__ */ jsx3(
|
|
369
403
|
ExpressCheckoutElement,
|
|
370
404
|
{
|
|
371
405
|
onReady: () => setReady(true),
|
|
@@ -393,7 +427,8 @@ function WalletButtonInner({
|
|
|
393
427
|
showApplePay = true,
|
|
394
428
|
showGooglePay = true,
|
|
395
429
|
onTokenizedBody,
|
|
396
|
-
onErrorChange
|
|
430
|
+
onErrorChange,
|
|
431
|
+
onButtonClick
|
|
397
432
|
}) {
|
|
398
433
|
const stripe = useStripeRaw();
|
|
399
434
|
const elements = useStripeElements();
|
|
@@ -403,6 +438,8 @@ function WalletButtonInner({
|
|
|
403
438
|
const handleWalletConfirm = useCallback(
|
|
404
439
|
async (_event) => {
|
|
405
440
|
if (!stripe || !elements) return;
|
|
441
|
+
const walletType = _event.expressPaymentType;
|
|
442
|
+
onButtonClick?.(walletType === "apple_pay" ? "apple_pay" : "google_pay");
|
|
406
443
|
try {
|
|
407
444
|
setSubmitting(true);
|
|
408
445
|
onErrorChange?.(null);
|
|
@@ -455,7 +492,7 @@ function WalletButtonInner({
|
|
|
455
492
|
[stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange]
|
|
456
493
|
);
|
|
457
494
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
458
|
-
/* @__PURE__ */ jsx3("div", {
|
|
495
|
+
/* @__PURE__ */ jsx3("div", { children: /* @__PURE__ */ jsx3(
|
|
459
496
|
ExpressCheckoutElement,
|
|
460
497
|
{
|
|
461
498
|
onReady: () => setReady(true),
|
|
@@ -465,10 +502,12 @@ function WalletButtonInner({
|
|
|
465
502
|
options: {
|
|
466
503
|
buttonType: { applePay: "plain", googlePay: "plain" },
|
|
467
504
|
paymentMethods: {
|
|
468
|
-
applePay: showApplePay ? "
|
|
469
|
-
googlePay: showGooglePay ? "
|
|
505
|
+
applePay: showApplePay ? "always" : "never",
|
|
506
|
+
googlePay: showGooglePay ? "always" : "never",
|
|
470
507
|
paypal: "never",
|
|
471
|
-
link: "never"
|
|
508
|
+
link: "never",
|
|
509
|
+
amazonPay: "never",
|
|
510
|
+
klarna: "never"
|
|
472
511
|
},
|
|
473
512
|
layout: { overflow: "never" }
|
|
474
513
|
}
|
|
@@ -499,6 +538,10 @@ function SplitCardFormInner({
|
|
|
499
538
|
showPayPal = true,
|
|
500
539
|
showApplePay = true,
|
|
501
540
|
showGooglePay = true,
|
|
541
|
+
layout = "default",
|
|
542
|
+
buttonsTheme,
|
|
543
|
+
buttonsStyles: buttonsStylesOverride,
|
|
544
|
+
onButtonClick,
|
|
502
545
|
totalAmount = 0,
|
|
503
546
|
currency = "usd",
|
|
504
547
|
innerRef
|
|
@@ -509,12 +552,37 @@ function SplitCardFormInner({
|
|
|
509
552
|
const [processing, setProcessing] = useState2(false);
|
|
510
553
|
const [error, setError] = useState2(null);
|
|
511
554
|
const [is3DSActive, setIs3DSActive] = useState2(false);
|
|
555
|
+
const [viewState, setViewState] = useState2("buttons");
|
|
556
|
+
const showCardForm = viewState === "expanding" || viewState === "card";
|
|
557
|
+
const TRANSITION_MS = 280;
|
|
558
|
+
const expandToCard = useCallback(() => {
|
|
559
|
+
setViewState("expanding");
|
|
560
|
+
setTimeout(() => setViewState("card"), TRANSITION_MS);
|
|
561
|
+
}, []);
|
|
562
|
+
const collapseToButtons = useCallback(() => {
|
|
563
|
+
setViewState("collapsing");
|
|
564
|
+
setTimeout(() => setViewState("buttons"), TRANSITION_MS);
|
|
565
|
+
}, []);
|
|
512
566
|
const [fullName, setFullName] = useState2("");
|
|
513
567
|
const [formReady, setFormReady] = useState2(false);
|
|
514
568
|
const [overlayStatus, setOverlayStatus] = useState2(null);
|
|
515
569
|
const processingRef = useRef2(false);
|
|
516
570
|
const resolvedBillingApiUrl = billingApiUrl || contextBillingUrl;
|
|
517
571
|
const displayError = externalError ?? error;
|
|
572
|
+
const bStyles = useMemo2(() => {
|
|
573
|
+
const base = resolveButtonsLayoutTheme(buttonsTheme);
|
|
574
|
+
if (!buttonsStylesOverride) return base;
|
|
575
|
+
return {
|
|
576
|
+
...base,
|
|
577
|
+
...buttonsStylesOverride,
|
|
578
|
+
cardButton: { ...base.cardButton, ...buttonsStylesOverride.cardButton },
|
|
579
|
+
cardFormContainer: { ...base.cardFormContainer, ...buttonsStylesOverride.cardFormContainer },
|
|
580
|
+
backButton: { ...base.backButton, ...buttonsStylesOverride.backButton },
|
|
581
|
+
backButtonIcon: { ...base.backButtonIcon, ...buttonsStylesOverride.backButtonIcon },
|
|
582
|
+
submitButton: { ...base.submitButton, ...buttonsStylesOverride.submitButton },
|
|
583
|
+
title: { ...base.title, ...buttonsStylesOverride.title }
|
|
584
|
+
};
|
|
585
|
+
}, [buttonsTheme, buttonsStylesOverride]);
|
|
518
586
|
const isSubmitting = externalProcessing ?? processing;
|
|
519
587
|
const isSelfContained = !onTokenizedBody;
|
|
520
588
|
const baseUrl = resolvedBillingApiUrl.replace(/\/+$/, "");
|
|
@@ -726,6 +794,7 @@ function SplitCardFormInner({
|
|
|
726
794
|
async (e) => {
|
|
727
795
|
e.preventDefault();
|
|
728
796
|
if (!flopay || !elements || isSubmitting || processingRef.current) return;
|
|
797
|
+
onButtonClick?.("card");
|
|
729
798
|
setProcessing(true);
|
|
730
799
|
setOverlayStatus("processing");
|
|
731
800
|
updateError(null);
|
|
@@ -792,8 +861,299 @@ function SplitCardFormInner({
|
|
|
792
861
|
if (!isReady) {
|
|
793
862
|
return /* @__PURE__ */ jsx3("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
|
|
794
863
|
}
|
|
864
|
+
const isButtons = layout === "buttons";
|
|
865
|
+
const resolvedBorder = isButtons ? bStyles.cardInputBorder ?? "#e5e7eb" : "#A4A4FF";
|
|
866
|
+
const cardBg = isButtons ? bStyles.cardFormContainer?.backgroundColor ?? "white" : "#EDEDFF";
|
|
867
|
+
const cardInputBg = isButtons ? bStyles.cardInputBackground ?? "white" : "white";
|
|
868
|
+
const stripeElementStyle = isButtons && (bStyles.cardInputColor || bStyles.cardInputPlaceholderColor || bStyles.cardInputFontSize) ? {
|
|
869
|
+
style: {
|
|
870
|
+
base: {
|
|
871
|
+
...bStyles.cardInputColor ? { color: bStyles.cardInputColor } : {},
|
|
872
|
+
...bStyles.cardInputFontSize ? { fontSize: bStyles.cardInputFontSize } : {},
|
|
873
|
+
...bStyles.cardInputPlaceholderColor ? { "::placeholder": { color: bStyles.cardInputPlaceholderColor } } : {}
|
|
874
|
+
},
|
|
875
|
+
invalid: { color: "#ef4444" }
|
|
876
|
+
}
|
|
877
|
+
} : {};
|
|
878
|
+
const cardFormBlock = /* @__PURE__ */ jsxs("div", { style: {
|
|
879
|
+
backgroundColor: cardBg,
|
|
880
|
+
borderRadius: "8px",
|
|
881
|
+
padding: isButtons ? "0" : "1rem",
|
|
882
|
+
...isButtons ? bStyles.cardFormContainer : {},
|
|
883
|
+
...isButtons ? { padding: bStyles.cardFormContainer?.padding ?? "0" } : {}
|
|
884
|
+
}, children: [
|
|
885
|
+
isButtons && showCardForm && /* @__PURE__ */ jsxs("div", { style: {
|
|
886
|
+
display: "flex",
|
|
887
|
+
alignItems: "center",
|
|
888
|
+
padding: "0.75rem 0 0.625rem"
|
|
889
|
+
}, children: [
|
|
890
|
+
/* @__PURE__ */ jsxs(
|
|
891
|
+
"button",
|
|
892
|
+
{
|
|
893
|
+
type: "button",
|
|
894
|
+
onClick: collapseToButtons,
|
|
895
|
+
style: {
|
|
896
|
+
display: "inline-flex",
|
|
897
|
+
alignItems: "center",
|
|
898
|
+
gap: "0.5rem",
|
|
899
|
+
background: "none",
|
|
900
|
+
border: "none",
|
|
901
|
+
cursor: "pointer",
|
|
902
|
+
color: "#4b5563",
|
|
903
|
+
fontSize: bStyles.backButtonFontSize ?? "0.85rem",
|
|
904
|
+
fontWeight: 500,
|
|
905
|
+
padding: 0,
|
|
906
|
+
transition: "color 0.15s",
|
|
907
|
+
flexShrink: 0,
|
|
908
|
+
...bStyles.backButton
|
|
909
|
+
},
|
|
910
|
+
"aria-label": "Back to payment methods",
|
|
911
|
+
children: [
|
|
912
|
+
/* @__PURE__ */ jsx3("span", { style: {
|
|
913
|
+
display: "inline-flex",
|
|
914
|
+
alignItems: "center",
|
|
915
|
+
justifyContent: "center",
|
|
916
|
+
width: 28,
|
|
917
|
+
height: 28,
|
|
918
|
+
borderRadius: "50%",
|
|
919
|
+
backgroundColor: "#f3f4f6",
|
|
920
|
+
transition: "background-color 0.15s",
|
|
921
|
+
...bStyles.backButtonIcon
|
|
922
|
+
}, children: /* @__PURE__ */ jsx3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx3("path", { d: "M15 18l-6-6 6-6" }) }) }),
|
|
923
|
+
"Go back"
|
|
924
|
+
]
|
|
925
|
+
}
|
|
926
|
+
),
|
|
927
|
+
/* @__PURE__ */ jsx3("div", { style: {
|
|
928
|
+
flex: 1,
|
|
929
|
+
textAlign: "center",
|
|
930
|
+
fontWeight: 600,
|
|
931
|
+
fontSize: bStyles.titleFontSize ?? "1.05rem",
|
|
932
|
+
color: "#262833",
|
|
933
|
+
paddingRight: 80,
|
|
934
|
+
...bStyles.title
|
|
935
|
+
}, children: "Secure card checkout" })
|
|
936
|
+
] }),
|
|
937
|
+
!isButtons && /* @__PURE__ */ jsx3("div", { style: { textAlign: "center", fontWeight: 600, fontSize: "1.1rem", padding: "0.5rem 0", color: "#262833" }, children: "Secure card checkout" }),
|
|
938
|
+
/* @__PURE__ */ jsx3("div", { style: {
|
|
939
|
+
backgroundColor: cardInputBg,
|
|
940
|
+
border: `1px solid ${resolvedBorder}`,
|
|
941
|
+
borderTopLeftRadius: "8px",
|
|
942
|
+
borderTopRightRadius: "8px",
|
|
943
|
+
padding: "10px"
|
|
944
|
+
}, children: /* @__PURE__ */ jsx3(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
|
|
945
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex" }, children: [
|
|
946
|
+
/* @__PURE__ */ jsx3("div", { style: {
|
|
947
|
+
flex: 1,
|
|
948
|
+
backgroundColor: cardInputBg,
|
|
949
|
+
border: `1px solid ${resolvedBorder}`,
|
|
950
|
+
borderTop: "none",
|
|
951
|
+
borderRight: "none",
|
|
952
|
+
borderBottomLeftRadius: "8px",
|
|
953
|
+
padding: "10px"
|
|
954
|
+
}, children: /* @__PURE__ */ jsx3(CardExpiryElement, { options: stripeElementStyle }) }),
|
|
955
|
+
/* @__PURE__ */ jsx3("div", { style: {
|
|
956
|
+
flex: 1,
|
|
957
|
+
backgroundColor: cardInputBg,
|
|
958
|
+
border: `1px solid ${resolvedBorder}`,
|
|
959
|
+
borderTop: "none",
|
|
960
|
+
borderBottomRightRadius: "8px",
|
|
961
|
+
padding: "10px"
|
|
962
|
+
}, children: /* @__PURE__ */ jsx3(CardCvcElement, { options: stripeElementStyle }) })
|
|
963
|
+
] }),
|
|
964
|
+
/* @__PURE__ */ jsx3("div", { style: {
|
|
965
|
+
backgroundColor: cardInputBg,
|
|
966
|
+
border: `1px solid ${resolvedBorder}`,
|
|
967
|
+
borderRadius: "8px",
|
|
968
|
+
marginTop: "0.5rem",
|
|
969
|
+
padding: "10px"
|
|
970
|
+
}, children: /* @__PURE__ */ jsx3(
|
|
971
|
+
"input",
|
|
972
|
+
{
|
|
973
|
+
placeholder: "Full Name on Card",
|
|
974
|
+
autoComplete: "cc-name",
|
|
975
|
+
value: fullName,
|
|
976
|
+
onChange: (e) => handleNameChange(e.target.value),
|
|
977
|
+
disabled: isSubmitting,
|
|
978
|
+
required: true,
|
|
979
|
+
style: {
|
|
980
|
+
width: "100%",
|
|
981
|
+
border: "none",
|
|
982
|
+
outline: "none",
|
|
983
|
+
background: "transparent",
|
|
984
|
+
fontSize: bStyles.cardInputFontSize ?? "16px",
|
|
985
|
+
fontFamily: "Poppins, sans-serif",
|
|
986
|
+
color: bStyles.cardInputColor ?? "#262833",
|
|
987
|
+
...isButtons && bStyles.nameInput ? bStyles.nameInput : {}
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
) }),
|
|
991
|
+
displayError && /* @__PURE__ */ jsxs("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
992
|
+
margin: "0.75rem 0",
|
|
993
|
+
padding: "0.625rem 0.875rem",
|
|
994
|
+
background: "#FEF2F2",
|
|
995
|
+
border: "1px solid #FECACA",
|
|
996
|
+
borderRadius: "8px",
|
|
997
|
+
color: "#991B1B",
|
|
998
|
+
fontSize: "0.85rem",
|
|
999
|
+
fontWeight: 600,
|
|
1000
|
+
display: "flex",
|
|
1001
|
+
alignItems: "center",
|
|
1002
|
+
gap: "0.5rem",
|
|
1003
|
+
...isButtons && bStyles.errorBanner ? bStyles.errorBanner : {}
|
|
1004
|
+
}, children: [
|
|
1005
|
+
/* @__PURE__ */ jsx3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx3("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" }) }),
|
|
1006
|
+
displayError
|
|
1007
|
+
] }),
|
|
1008
|
+
children ?? /* @__PURE__ */ jsx3(
|
|
1009
|
+
"button",
|
|
1010
|
+
{
|
|
1011
|
+
type: "submit",
|
|
1012
|
+
disabled: !formReady || isSubmitting,
|
|
1013
|
+
"data-testid": "flopay-submit",
|
|
1014
|
+
style: {
|
|
1015
|
+
width: "100%",
|
|
1016
|
+
padding: "0.875rem",
|
|
1017
|
+
marginTop: "1rem",
|
|
1018
|
+
backgroundColor: "#4A49FF",
|
|
1019
|
+
color: "white",
|
|
1020
|
+
border: "none",
|
|
1021
|
+
borderRadius: "8px",
|
|
1022
|
+
fontSize: isButtons && bStyles.submitButtonFontSize ? bStyles.submitButtonFontSize : "1rem",
|
|
1023
|
+
fontWeight: 600,
|
|
1024
|
+
cursor: !formReady || isSubmitting ? "not-allowed" : "pointer",
|
|
1025
|
+
opacity: !formReady || isSubmitting ? 0.5 : 1,
|
|
1026
|
+
...isButtons ? bStyles.submitButton : {}
|
|
1027
|
+
},
|
|
1028
|
+
children: isSubmitting ? "PROCESSING..." : submitLabel
|
|
1029
|
+
}
|
|
1030
|
+
),
|
|
1031
|
+
!isButtons && /* @__PURE__ */ jsx3("div", { style: {
|
|
1032
|
+
backgroundColor: "#EFF9F0",
|
|
1033
|
+
borderRadius: "8px",
|
|
1034
|
+
padding: "0.75rem",
|
|
1035
|
+
marginTop: "0.75rem",
|
|
1036
|
+
textAlign: "center",
|
|
1037
|
+
fontSize: "0.85rem",
|
|
1038
|
+
fontWeight: 600,
|
|
1039
|
+
color: "#7DAD3A"
|
|
1040
|
+
}, children: "Secure Card Checkout" })
|
|
1041
|
+
] });
|
|
1042
|
+
if (layout === "buttons") {
|
|
1043
|
+
const isButtonsView = viewState === "buttons" || viewState === "expanding";
|
|
1044
|
+
const isCardView = viewState === "expanding" || viewState === "card" || viewState === "collapsing";
|
|
1045
|
+
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;
|
|
1046
|
+
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;
|
|
1047
|
+
return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
1048
|
+
/* @__PURE__ */ jsx3(FloPayKeyframes, {}),
|
|
1049
|
+
overlayStatus && /* @__PURE__ */ jsx3(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
1050
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "grid" }, children: [
|
|
1051
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
1052
|
+
gridArea: "1 / 1",
|
|
1053
|
+
display: "flex",
|
|
1054
|
+
flexDirection: "column",
|
|
1055
|
+
gap: "0.5rem",
|
|
1056
|
+
// When card form is showing (and not transitioning), hide but keep mounted
|
|
1057
|
+
...!isButtonsView && !buttonsAnim ? { visibility: "hidden", position: "absolute", pointerEvents: "none", width: "100%" } : {},
|
|
1058
|
+
...buttonsAnim ? { animation: buttonsAnim, pointerEvents: "none" } : {}
|
|
1059
|
+
}, children: [
|
|
1060
|
+
showPayPal && stripeInstance ? /* @__PURE__ */ jsx3(StripeElements, { stripe: stripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx3(
|
|
1061
|
+
PayPalButtonInner,
|
|
1062
|
+
{
|
|
1063
|
+
sessionId,
|
|
1064
|
+
email,
|
|
1065
|
+
billingApiUrl: resolvedBillingApiUrl,
|
|
1066
|
+
onTokenizedBody: dispatchTokenizedBody,
|
|
1067
|
+
onErrorChange: updateError,
|
|
1068
|
+
isProcessing: isSubmitting,
|
|
1069
|
+
onButtonClick
|
|
1070
|
+
}
|
|
1071
|
+
) }) : showPayPal ? /* @__PURE__ */ jsx3("div", { style: { height: 44, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
|
|
1072
|
+
showWallets && stripeInstance ? /* @__PURE__ */ jsx3(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx3(
|
|
1073
|
+
WalletButtonInner,
|
|
1074
|
+
{
|
|
1075
|
+
sessionId,
|
|
1076
|
+
email,
|
|
1077
|
+
billingApiUrl: resolvedBillingApiUrl,
|
|
1078
|
+
showApplePay,
|
|
1079
|
+
showGooglePay,
|
|
1080
|
+
onTokenizedBody: dispatchTokenizedBody,
|
|
1081
|
+
onErrorChange: updateError,
|
|
1082
|
+
onButtonClick
|
|
1083
|
+
}
|
|
1084
|
+
) }) : showWallets ? /* @__PURE__ */ jsx3("div", { style: { height: 44, borderRadius: 8, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
|
|
1085
|
+
/* @__PURE__ */ jsxs(
|
|
1086
|
+
"button",
|
|
1087
|
+
{
|
|
1088
|
+
type: "button",
|
|
1089
|
+
onClick: () => {
|
|
1090
|
+
onButtonClick?.("card");
|
|
1091
|
+
expandToCard();
|
|
1092
|
+
},
|
|
1093
|
+
style: {
|
|
1094
|
+
width: "100%",
|
|
1095
|
+
padding: "0.9rem 1rem",
|
|
1096
|
+
backgroundColor: "white",
|
|
1097
|
+
color: "#262833",
|
|
1098
|
+
border: "1px solid #d1d5db",
|
|
1099
|
+
borderRadius: "8px",
|
|
1100
|
+
fontSize: bStyles.cardButtonFontSize ?? "0.95rem",
|
|
1101
|
+
fontWeight: 600,
|
|
1102
|
+
cursor: "pointer",
|
|
1103
|
+
display: "flex",
|
|
1104
|
+
alignItems: "center",
|
|
1105
|
+
justifyContent: "center",
|
|
1106
|
+
gap: "0.625rem",
|
|
1107
|
+
transition: "border-color 0.2s, box-shadow 0.2s, transform 0.1s",
|
|
1108
|
+
boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
|
|
1109
|
+
position: "relative",
|
|
1110
|
+
...bStyles.cardButton
|
|
1111
|
+
},
|
|
1112
|
+
onMouseDown: (e) => {
|
|
1113
|
+
e.currentTarget.style.transform = "scale(0.985)";
|
|
1114
|
+
},
|
|
1115
|
+
onMouseUp: (e) => {
|
|
1116
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
1117
|
+
},
|
|
1118
|
+
children: [
|
|
1119
|
+
/* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1120
|
+
/* @__PURE__ */ jsx3("rect", { width: "20", height: "14", x: "2", y: "5", rx: "2" }),
|
|
1121
|
+
/* @__PURE__ */ jsx3("line", { x1: "2", x2: "22", y1: "10", y2: "10" })
|
|
1122
|
+
] }),
|
|
1123
|
+
"Credit / Debit Card",
|
|
1124
|
+
/* @__PURE__ */ jsx3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#9ca3af", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { position: "absolute", right: "1rem" }, children: /* @__PURE__ */ jsx3("path", { d: "M9 18l6-6-6-6" }) })
|
|
1125
|
+
]
|
|
1126
|
+
}
|
|
1127
|
+
),
|
|
1128
|
+
displayError && viewState === "buttons" && /* @__PURE__ */ jsxs("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
1129
|
+
margin: "0.25rem 0",
|
|
1130
|
+
padding: "0.625rem 0.875rem",
|
|
1131
|
+
background: "#FEF2F2",
|
|
1132
|
+
border: "1px solid #FECACA",
|
|
1133
|
+
borderRadius: "8px",
|
|
1134
|
+
color: "#991B1B",
|
|
1135
|
+
fontSize: "0.85rem",
|
|
1136
|
+
fontWeight: 600,
|
|
1137
|
+
display: "flex",
|
|
1138
|
+
alignItems: "center",
|
|
1139
|
+
gap: "0.5rem",
|
|
1140
|
+
...bStyles.errorBanner ? bStyles.errorBanner : {}
|
|
1141
|
+
}, children: [
|
|
1142
|
+
/* @__PURE__ */ jsx3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx3("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" }) }),
|
|
1143
|
+
displayError
|
|
1144
|
+
] })
|
|
1145
|
+
] }),
|
|
1146
|
+
isCardView && /* @__PURE__ */ jsx3("div", { style: {
|
|
1147
|
+
gridArea: "1 / 1",
|
|
1148
|
+
...cardAnim ? { animation: cardAnim } : {},
|
|
1149
|
+
...viewState === "collapsing" ? { pointerEvents: "none" } : {}
|
|
1150
|
+
}, children: cardFormBlock })
|
|
1151
|
+
] })
|
|
1152
|
+
] });
|
|
1153
|
+
}
|
|
795
1154
|
return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
796
|
-
|
|
1155
|
+
/* @__PURE__ */ jsx3(FloPayKeyframes, {}),
|
|
1156
|
+
overlayStatus && /* @__PURE__ */ jsx3(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
797
1157
|
showWallets && stripeInstance && /* @__PURE__ */ jsx3(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx3(
|
|
798
1158
|
WalletButtonInner,
|
|
799
1159
|
{
|
|
@@ -829,100 +1189,15 @@ function SplitCardFormInner({
|
|
|
829
1189
|
/* @__PURE__ */ jsx3("span", { children: "or pay with card" }),
|
|
830
1190
|
/* @__PURE__ */ jsx3("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
|
|
831
1191
|
] }),
|
|
832
|
-
|
|
833
|
-
/* @__PURE__ */ jsx3("div", { style: { textAlign: "center", fontWeight: 600, fontSize: "1.1rem", padding: "0.5rem 0", color: "#262833" }, children: "Secure card checkout" }),
|
|
834
|
-
/* @__PURE__ */ jsx3("div", { style: {
|
|
835
|
-
backgroundColor: "white",
|
|
836
|
-
border: "1px solid #A4A4FF",
|
|
837
|
-
borderTopLeftRadius: "8px",
|
|
838
|
-
borderTopRightRadius: "8px",
|
|
839
|
-
padding: "10px"
|
|
840
|
-
}, children: /* @__PURE__ */ jsx3(CardNumberElement, { onReady: () => setFormReady(true) }) }),
|
|
841
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex" }, children: [
|
|
842
|
-
/* @__PURE__ */ jsx3("div", { style: {
|
|
843
|
-
flex: 1,
|
|
844
|
-
backgroundColor: "white",
|
|
845
|
-
border: "1px solid #A4A4FF",
|
|
846
|
-
borderTop: "none",
|
|
847
|
-
borderRight: "none",
|
|
848
|
-
borderBottomLeftRadius: "8px",
|
|
849
|
-
padding: "10px"
|
|
850
|
-
}, children: /* @__PURE__ */ jsx3(CardExpiryElement, {}) }),
|
|
851
|
-
/* @__PURE__ */ jsx3("div", { style: {
|
|
852
|
-
flex: 1,
|
|
853
|
-
backgroundColor: "white",
|
|
854
|
-
border: "1px solid #A4A4FF",
|
|
855
|
-
borderTop: "none",
|
|
856
|
-
borderBottomRightRadius: "8px",
|
|
857
|
-
padding: "10px"
|
|
858
|
-
}, children: /* @__PURE__ */ jsx3(CardCvcElement, {}) })
|
|
859
|
-
] }),
|
|
860
|
-
/* @__PURE__ */ jsx3("div", { style: {
|
|
861
|
-
backgroundColor: "white",
|
|
862
|
-
border: "1px solid #A4A4FF",
|
|
863
|
-
borderRadius: "8px",
|
|
864
|
-
marginTop: "0.5rem",
|
|
865
|
-
padding: "10px"
|
|
866
|
-
}, children: /* @__PURE__ */ jsx3(
|
|
867
|
-
"input",
|
|
868
|
-
{
|
|
869
|
-
placeholder: "Full Name on Card",
|
|
870
|
-
autoComplete: "cc-name",
|
|
871
|
-
value: fullName,
|
|
872
|
-
onChange: (e) => handleNameChange(e.target.value),
|
|
873
|
-
disabled: isSubmitting,
|
|
874
|
-
required: true,
|
|
875
|
-
style: {
|
|
876
|
-
width: "100%",
|
|
877
|
-
border: "none",
|
|
878
|
-
outline: "none",
|
|
879
|
-
fontSize: "16px",
|
|
880
|
-
fontFamily: "Poppins, sans-serif",
|
|
881
|
-
color: "#262833"
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
) }),
|
|
885
|
-
displayError && /* @__PURE__ */ jsx3("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0", fontSize: "0.9rem" }, children: displayError }),
|
|
886
|
-
children ?? /* @__PURE__ */ jsx3(
|
|
887
|
-
"button",
|
|
888
|
-
{
|
|
889
|
-
type: "submit",
|
|
890
|
-
disabled: !formReady || isSubmitting,
|
|
891
|
-
"data-testid": "flopay-submit",
|
|
892
|
-
style: {
|
|
893
|
-
width: "100%",
|
|
894
|
-
padding: "0.875rem",
|
|
895
|
-
marginTop: "1rem",
|
|
896
|
-
backgroundColor: "#4A49FF",
|
|
897
|
-
color: "white",
|
|
898
|
-
border: "none",
|
|
899
|
-
borderRadius: "8px",
|
|
900
|
-
fontSize: "1rem",
|
|
901
|
-
fontWeight: 600,
|
|
902
|
-
cursor: !formReady || isSubmitting ? "not-allowed" : "pointer",
|
|
903
|
-
opacity: !formReady || isSubmitting ? 0.5 : 1
|
|
904
|
-
},
|
|
905
|
-
children: isSubmitting ? "PROCESSING..." : submitLabel
|
|
906
|
-
}
|
|
907
|
-
),
|
|
908
|
-
/* @__PURE__ */ jsx3("div", { style: {
|
|
909
|
-
backgroundColor: "#EFF9F0",
|
|
910
|
-
borderRadius: "8px",
|
|
911
|
-
padding: "0.75rem",
|
|
912
|
-
marginTop: "0.75rem",
|
|
913
|
-
textAlign: "center",
|
|
914
|
-
fontSize: "0.85rem",
|
|
915
|
-
fontWeight: 600,
|
|
916
|
-
color: "#7DAD3A"
|
|
917
|
-
}, children: "Secure Card Checkout" })
|
|
918
|
-
] })
|
|
1192
|
+
cardFormBlock
|
|
919
1193
|
] });
|
|
920
1194
|
}
|
|
921
1195
|
|
|
922
1196
|
// src/flopay-checkout.tsx
|
|
923
1197
|
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
924
1198
|
function FloPayCheckout({
|
|
925
|
-
sessionId,
|
|
1199
|
+
sessionId: sessionIdProp,
|
|
1200
|
+
createSession: createSessionParams,
|
|
926
1201
|
billingApiUrl,
|
|
927
1202
|
appearance,
|
|
928
1203
|
locale,
|
|
@@ -934,6 +1209,10 @@ function FloPayCheckout({
|
|
|
934
1209
|
showPayPal = true,
|
|
935
1210
|
showApplePay = true,
|
|
936
1211
|
showGooglePay = true,
|
|
1212
|
+
layout,
|
|
1213
|
+
buttonsTheme,
|
|
1214
|
+
buttonsStyles,
|
|
1215
|
+
onButtonClick,
|
|
937
1216
|
submitLabel,
|
|
938
1217
|
className,
|
|
939
1218
|
children,
|
|
@@ -947,6 +1226,7 @@ function FloPayCheckout({
|
|
|
947
1226
|
const [flopay, setFloPay] = useState3(null);
|
|
948
1227
|
const flopayRef = useRef3(null);
|
|
949
1228
|
const [session, setSession] = useState3(null);
|
|
1229
|
+
const [resolvedSessionId, setResolvedSessionId] = useState3(sessionIdProp ?? "");
|
|
950
1230
|
const [isLoading, setIsLoading] = useState3(true);
|
|
951
1231
|
const [loadError, setLoadError] = useState3(null);
|
|
952
1232
|
const [currentMode, setCurrentMode] = useState3("full");
|
|
@@ -969,7 +1249,7 @@ function FloPayCheckout({
|
|
|
969
1249
|
"x-user-id": sess.customer?.id ?? ""
|
|
970
1250
|
},
|
|
971
1251
|
body: JSON.stringify({
|
|
972
|
-
sessionId,
|
|
1252
|
+
sessionId: resolvedSessionId,
|
|
973
1253
|
tokenizedData: { id: void 0 },
|
|
974
1254
|
accountData: {
|
|
975
1255
|
userId: sess.customer?.id ?? "",
|
|
@@ -1003,7 +1283,7 @@ function FloPayCheckout({
|
|
|
1003
1283
|
"api_error"
|
|
1004
1284
|
);
|
|
1005
1285
|
},
|
|
1006
|
-
[resolvedBillingUrl,
|
|
1286
|
+
[resolvedBillingUrl, resolvedSessionId]
|
|
1007
1287
|
);
|
|
1008
1288
|
const handleRedirectResult = useCallback2(
|
|
1009
1289
|
async (redirectResult, sess, options) => {
|
|
@@ -1048,16 +1328,169 @@ function FloPayCheckout({
|
|
|
1048
1328
|
}
|
|
1049
1329
|
return false;
|
|
1050
1330
|
},
|
|
1051
|
-
[resolvedBillingUrl,
|
|
1331
|
+
[resolvedBillingUrl, resolvedSessionId]
|
|
1332
|
+
);
|
|
1333
|
+
const inflightRef = useRef3(/* @__PURE__ */ new Map());
|
|
1334
|
+
const initializedHashRef = useRef3(null);
|
|
1335
|
+
function hashCreateParams(params) {
|
|
1336
|
+
const key = JSON.stringify({
|
|
1337
|
+
c: params?.clientId,
|
|
1338
|
+
i: params?.items?.map((x) => `${x.providerItemId}:${x.totalAmount}:${x.overrideAmount ?? ""}:${x.quantity ?? 1}`).sort(),
|
|
1339
|
+
s: params?.subscriptions?.map((x) => `${x.providerPlanId}:${x.totalAmount}:${x.overrideAmount ?? ""}:${x.quantity ?? 1}`).sort(),
|
|
1340
|
+
e: params?.account.email,
|
|
1341
|
+
m: params?.checkoutMode ?? "full"
|
|
1342
|
+
});
|
|
1343
|
+
let h = 0;
|
|
1344
|
+
for (let i = 0; i < key.length; i++) {
|
|
1345
|
+
h = (h << 5) - h + key.charCodeAt(i) | 0;
|
|
1346
|
+
}
|
|
1347
|
+
return `flopay_session_${Math.abs(h).toString(36)}`;
|
|
1348
|
+
}
|
|
1349
|
+
const createSessionHash = useMemo3(
|
|
1350
|
+
() => createSessionParams ? hashCreateParams(createSessionParams) : "",
|
|
1351
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1352
|
+
[
|
|
1353
|
+
createSessionParams?.clientId,
|
|
1354
|
+
createSessionParams?.account?.email,
|
|
1355
|
+
createSessionParams?.checkoutMode,
|
|
1356
|
+
JSON.stringify(createSessionParams?.items),
|
|
1357
|
+
JSON.stringify(createSessionParams?.subscriptions)
|
|
1358
|
+
]
|
|
1052
1359
|
);
|
|
1360
|
+
const createSessionParamsRef = useRef3(createSessionParams);
|
|
1361
|
+
createSessionParamsRef.current = createSessionParams;
|
|
1053
1362
|
useEffect4(() => {
|
|
1054
1363
|
let cancelled = false;
|
|
1055
|
-
setIsLoading(true);
|
|
1056
1364
|
setLoadError(null);
|
|
1365
|
+
if (createSessionHash) {
|
|
1366
|
+
if (initializedHashRef.current === createSessionHash) return;
|
|
1367
|
+
const params = createSessionParamsRef.current;
|
|
1368
|
+
const totalAmount = [
|
|
1369
|
+
...(params.items ?? []).map((i) => i.overrideAmount ?? i.totalAmount ?? 0),
|
|
1370
|
+
...(params.subscriptions ?? []).map((s) => s.overrideAmount ?? s.totalAmount ?? 0)
|
|
1371
|
+
].reduce((sum, v) => sum + v, 0);
|
|
1372
|
+
const currency = params.items?.[0]?.currency ?? params.subscriptions?.[0]?.currency ?? "USD";
|
|
1373
|
+
const syntheticSession = {
|
|
1374
|
+
id: "",
|
|
1375
|
+
clientSecret: "",
|
|
1376
|
+
mode: "payment",
|
|
1377
|
+
amount: Math.round(totalAmount * 100),
|
|
1378
|
+
currency,
|
|
1379
|
+
status: "open",
|
|
1380
|
+
customer: {
|
|
1381
|
+
id: params.account.userId,
|
|
1382
|
+
email: params.account.email,
|
|
1383
|
+
firstName: params.account.firstName,
|
|
1384
|
+
lastName: params.account.lastName
|
|
1385
|
+
},
|
|
1386
|
+
successUrl: params.successUrl,
|
|
1387
|
+
cancelUrl: params.cancelUrl,
|
|
1388
|
+
checkoutMode: params.checkoutMode ?? "full",
|
|
1389
|
+
items: (params.items ?? []).map((i, idx) => ({
|
|
1390
|
+
uuid: `synthetic-item-${idx}`,
|
|
1391
|
+
checkoutSessionId: "",
|
|
1392
|
+
providerItemId: i.providerItemId,
|
|
1393
|
+
providerItemName: i.providerItemName ?? i.providerItemId,
|
|
1394
|
+
quantity: i.quantity ?? 1,
|
|
1395
|
+
totalAmount: i.totalAmount,
|
|
1396
|
+
overrideAmount: i.overrideAmount ?? null,
|
|
1397
|
+
currency: i.currency ?? currency
|
|
1398
|
+
})),
|
|
1399
|
+
subscriptions: (params.subscriptions ?? []).map((s, idx) => ({
|
|
1400
|
+
uuid: `synthetic-sub-${idx}`,
|
|
1401
|
+
checkoutSessionId: "",
|
|
1402
|
+
providerPlanId: s.providerPlanId,
|
|
1403
|
+
providerPlanName: s.providerPlanName ?? s.providerPlanId,
|
|
1404
|
+
quantity: s.quantity ?? 1,
|
|
1405
|
+
totalAmount: s.totalAmount,
|
|
1406
|
+
overrideAmount: s.overrideAmount ?? null,
|
|
1407
|
+
currency: s.currency ?? currency
|
|
1408
|
+
}))
|
|
1409
|
+
};
|
|
1410
|
+
setSession(syntheticSession);
|
|
1411
|
+
setCurrentMode(params.checkoutMode ?? checkoutModeProp ?? "full");
|
|
1412
|
+
setIsLoading(false);
|
|
1413
|
+
const cacheKey = createSessionHash;
|
|
1414
|
+
async function resolveSession() {
|
|
1415
|
+
const api = new PaymentAPI(resolvedBillingUrl);
|
|
1416
|
+
let sid = typeof window !== "undefined" ? window.sessionStorage.getItem(cacheKey) : null;
|
|
1417
|
+
let realResult = null;
|
|
1418
|
+
if (sid) {
|
|
1419
|
+
try {
|
|
1420
|
+
realResult = await api.getUnifiedCheckoutSession(sid);
|
|
1421
|
+
if (realResult.data.session?.status === "complete") {
|
|
1422
|
+
if (typeof window !== "undefined") window.sessionStorage.removeItem(cacheKey);
|
|
1423
|
+
sid = null;
|
|
1424
|
+
realResult = null;
|
|
1425
|
+
}
|
|
1426
|
+
} catch {
|
|
1427
|
+
if (typeof window !== "undefined") window.sessionStorage.removeItem(cacheKey);
|
|
1428
|
+
sid = null;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
if (!sid) {
|
|
1432
|
+
realResult = await api.createAndFetchSession(createSessionParamsRef.current);
|
|
1433
|
+
sid = realResult.data.session?.id ?? "";
|
|
1434
|
+
if (sid && typeof window !== "undefined") {
|
|
1435
|
+
window.sessionStorage.setItem(cacheKey, sid);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
return { sid: sid ?? "", result: realResult };
|
|
1439
|
+
}
|
|
1440
|
+
(async () => {
|
|
1441
|
+
try {
|
|
1442
|
+
let promise = inflightRef.current.get(cacheKey);
|
|
1443
|
+
if (!promise) {
|
|
1444
|
+
promise = resolveSession();
|
|
1445
|
+
inflightRef.current.set(cacheKey, promise);
|
|
1446
|
+
}
|
|
1447
|
+
let resolved;
|
|
1448
|
+
try {
|
|
1449
|
+
resolved = await promise;
|
|
1450
|
+
} finally {
|
|
1451
|
+
inflightRef.current.delete(cacheKey);
|
|
1452
|
+
}
|
|
1453
|
+
if (cancelled) return;
|
|
1454
|
+
const { sid, result: realResult } = resolved;
|
|
1455
|
+
if (realResult) {
|
|
1456
|
+
setUnified(realResult);
|
|
1457
|
+
if (realResult.data.session) setSession(realResult.data.session);
|
|
1458
|
+
}
|
|
1459
|
+
if (sid) {
|
|
1460
|
+
setResolvedSessionId(sid);
|
|
1461
|
+
}
|
|
1462
|
+
let pk;
|
|
1463
|
+
if (realResult?.provider === "stripe") {
|
|
1464
|
+
pk = realResult.data.stripe?.publishableKey;
|
|
1465
|
+
}
|
|
1466
|
+
if (!pk) pk = fallbackPublishableKey;
|
|
1467
|
+
if (!pk) {
|
|
1468
|
+
throw new FloPayError2(
|
|
1469
|
+
"No publishable key found. Provide fallbackPublishableKey or ensure the session includes gatewayData.publishableKey.",
|
|
1470
|
+
"validation_error"
|
|
1471
|
+
);
|
|
1472
|
+
}
|
|
1473
|
+
const instance = await loadFloPay(pk, { billingApiUrl: resolvedBillingUrl, locale });
|
|
1474
|
+
if (!cancelled) {
|
|
1475
|
+
flopayRef.current = instance;
|
|
1476
|
+
setFloPay(instance);
|
|
1477
|
+
initializedHashRef.current = cacheKey;
|
|
1478
|
+
}
|
|
1479
|
+
} catch (err) {
|
|
1480
|
+
if (cancelled) return;
|
|
1481
|
+
const floPayErr = err instanceof FloPayError2 ? err : new FloPayError2(err instanceof Error ? err.message : "Failed to create session", "api_error");
|
|
1482
|
+
setLoadError(floPayErr);
|
|
1483
|
+
}
|
|
1484
|
+
})();
|
|
1485
|
+
return () => {
|
|
1486
|
+
cancelled = true;
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
setIsLoading(true);
|
|
1057
1490
|
async function init() {
|
|
1058
1491
|
try {
|
|
1059
1492
|
const api = new PaymentAPI(resolvedBillingUrl);
|
|
1060
|
-
const result = await api.getUnifiedCheckoutSession(
|
|
1493
|
+
const result = await api.getUnifiedCheckoutSession(resolvedSessionId);
|
|
1061
1494
|
if (cancelled) return;
|
|
1062
1495
|
setUnified(result);
|
|
1063
1496
|
const sess = result.data.session ?? null;
|
|
@@ -1075,7 +1508,7 @@ function FloPayCheckout({
|
|
|
1075
1508
|
const hasPayPalRedirectParams = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("payment_intent");
|
|
1076
1509
|
if (effectiveMode === "auto" && !autoCheckoutAttempted.current && !hasPayPalRedirectParams) {
|
|
1077
1510
|
autoCheckoutAttempted.current = true;
|
|
1078
|
-
const stripeInitPromise = initStripe(result
|
|
1511
|
+
const stripeInitPromise = initStripe(result);
|
|
1079
1512
|
try {
|
|
1080
1513
|
const redirectResult = await processPaymentForMode(sess);
|
|
1081
1514
|
if (!redirectResult) {
|
|
@@ -1086,9 +1519,7 @@ function FloPayCheckout({
|
|
|
1086
1519
|
await stripeInitPromise;
|
|
1087
1520
|
const handled = await handleRedirectResult(redirectResult, sess, { attempt3DS: true });
|
|
1088
1521
|
if (!cancelled) {
|
|
1089
|
-
if (!handled)
|
|
1090
|
-
setCurrentMode("full");
|
|
1091
|
-
}
|
|
1522
|
+
if (!handled) setCurrentMode("full");
|
|
1092
1523
|
setIsLoading(false);
|
|
1093
1524
|
}
|
|
1094
1525
|
return;
|
|
@@ -1100,19 +1531,16 @@ function FloPayCheckout({
|
|
|
1100
1531
|
return;
|
|
1101
1532
|
}
|
|
1102
1533
|
}
|
|
1103
|
-
await initStripe(result
|
|
1534
|
+
await initStripe(result);
|
|
1104
1535
|
if (!cancelled) setIsLoading(false);
|
|
1105
1536
|
} catch (err) {
|
|
1106
1537
|
if (cancelled) return;
|
|
1107
|
-
const floPayErr = err instanceof FloPayError2 ? err : new FloPayError2(
|
|
1108
|
-
err instanceof Error ? err.message : "Failed to initialize checkout",
|
|
1109
|
-
"api_error"
|
|
1110
|
-
);
|
|
1538
|
+
const floPayErr = err instanceof FloPayError2 ? err : new FloPayError2(err instanceof Error ? err.message : "Failed to initialize checkout", "api_error");
|
|
1111
1539
|
setLoadError(floPayErr);
|
|
1112
1540
|
setIsLoading(false);
|
|
1113
1541
|
}
|
|
1114
1542
|
}
|
|
1115
|
-
async function initStripe(result
|
|
1543
|
+
async function initStripe(result) {
|
|
1116
1544
|
let publishableKey;
|
|
1117
1545
|
if (result.provider === "stripe") {
|
|
1118
1546
|
publishableKey = result.data.stripe?.publishableKey;
|
|
@@ -1135,7 +1563,7 @@ function FloPayCheckout({
|
|
|
1135
1563
|
return () => {
|
|
1136
1564
|
cancelled = true;
|
|
1137
1565
|
};
|
|
1138
|
-
}, [
|
|
1566
|
+
}, [resolvedSessionId, createSessionHash, resolvedBillingUrl, fallbackPublishableKey, locale, checkoutModeProp]);
|
|
1139
1567
|
const handleConfirmCheckout = useCallback2(async () => {
|
|
1140
1568
|
if (confirmProcessing || !session) return;
|
|
1141
1569
|
setConfirmProcessing(true);
|
|
@@ -1187,32 +1615,32 @@ function FloPayCheckout({
|
|
|
1187
1615
|
[session, isLoading, loadError, currentMode]
|
|
1188
1616
|
);
|
|
1189
1617
|
if (isLoading) {
|
|
1190
|
-
return /* @__PURE__ */ jsx4(Fragment2, { children: loadingNode
|
|
1191
|
-
|
|
1192
|
-
{
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1618
|
+
if (loadingNode) return /* @__PURE__ */ jsx4(Fragment2, { children: loadingNode });
|
|
1619
|
+
if (layout === "buttons") {
|
|
1620
|
+
const skeletonBar = (h) => /* @__PURE__ */ jsx4("div", { style: {
|
|
1621
|
+
height: h,
|
|
1622
|
+
borderRadius: 8,
|
|
1623
|
+
background: "#e5e7eb",
|
|
1624
|
+
animation: "flopay-loading-pulse 1.5s ease-in-out infinite"
|
|
1625
|
+
} });
|
|
1626
|
+
return /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
1627
|
+
showPayPal && skeletonBar(44),
|
|
1628
|
+
(showApplePay || showGooglePay) && skeletonBar(44),
|
|
1629
|
+
skeletonBar(48),
|
|
1630
|
+
/* @__PURE__ */ jsx4("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
1631
|
+
] });
|
|
1632
|
+
}
|
|
1633
|
+
return /* @__PURE__ */ jsxs2("div", { style: { display: "flex", justifyContent: "center", padding: 32 }, children: [
|
|
1634
|
+
/* @__PURE__ */ jsx4("div", { style: {
|
|
1635
|
+
width: 24,
|
|
1636
|
+
height: 24,
|
|
1637
|
+
border: "2px solid #e5e7eb",
|
|
1638
|
+
borderTopColor: "#6b7280",
|
|
1639
|
+
borderRadius: "50%",
|
|
1640
|
+
animation: "spin 0.6s linear infinite"
|
|
1641
|
+
} }),
|
|
1642
|
+
/* @__PURE__ */ jsx4("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
|
|
1643
|
+
] });
|
|
1216
1644
|
}
|
|
1217
1645
|
if (loadError) {
|
|
1218
1646
|
if (errorNode) return /* @__PURE__ */ jsx4(Fragment2, { children: errorNode(loadError) });
|
|
@@ -1229,6 +1657,19 @@ function FloPayCheckout({
|
|
|
1229
1657
|
}
|
|
1230
1658
|
);
|
|
1231
1659
|
}
|
|
1660
|
+
if ((!flopay || !providerOptions) && createSessionParams && layout === "buttons") {
|
|
1661
|
+
return /* @__PURE__ */ jsx4(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx4(
|
|
1662
|
+
InterimButtonsView,
|
|
1663
|
+
{
|
|
1664
|
+
onButtonClick,
|
|
1665
|
+
showPayPal,
|
|
1666
|
+
showApplePay,
|
|
1667
|
+
showGooglePay,
|
|
1668
|
+
buttonsTheme,
|
|
1669
|
+
buttonsStyles
|
|
1670
|
+
}
|
|
1671
|
+
) });
|
|
1672
|
+
}
|
|
1232
1673
|
if (!flopay || !providerOptions) return /* @__PURE__ */ jsx4(Fragment2, {});
|
|
1233
1674
|
if (currentMode === "confirm") {
|
|
1234
1675
|
return /* @__PURE__ */ jsx4(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx4(FloPayProvider, { flopay, options: providerOptions, children: /* @__PURE__ */ jsxs2("div", { className, children: [
|
|
@@ -1289,7 +1730,7 @@ function FloPayCheckout({
|
|
|
1289
1730
|
children ? /* @__PURE__ */ jsx4(
|
|
1290
1731
|
SessionInjector,
|
|
1291
1732
|
{
|
|
1292
|
-
sessionId,
|
|
1733
|
+
sessionId: resolvedSessionId,
|
|
1293
1734
|
billingApiUrl: resolvedBillingUrl,
|
|
1294
1735
|
session,
|
|
1295
1736
|
children
|
|
@@ -1297,7 +1738,7 @@ function FloPayCheckout({
|
|
|
1297
1738
|
) : /* @__PURE__ */ jsx4(
|
|
1298
1739
|
SplitCardForm,
|
|
1299
1740
|
{
|
|
1300
|
-
sessionId,
|
|
1741
|
+
sessionId: resolvedSessionId,
|
|
1301
1742
|
email: session?.customer?.email,
|
|
1302
1743
|
userId: session?.customer?.id,
|
|
1303
1744
|
firstName: session?.customer?.firstName,
|
|
@@ -1309,6 +1750,10 @@ function FloPayCheckout({
|
|
|
1309
1750
|
showPayPal,
|
|
1310
1751
|
showApplePay,
|
|
1311
1752
|
showGooglePay,
|
|
1753
|
+
layout,
|
|
1754
|
+
buttonsTheme,
|
|
1755
|
+
buttonsStyles,
|
|
1756
|
+
onButtonClick,
|
|
1312
1757
|
submitLabel,
|
|
1313
1758
|
className
|
|
1314
1759
|
}
|
|
@@ -1339,6 +1784,162 @@ function SessionInjector({
|
|
|
1339
1784
|
return React4.cloneElement(child, injected);
|
|
1340
1785
|
}) });
|
|
1341
1786
|
}
|
|
1787
|
+
function InterimButtonsView({
|
|
1788
|
+
onButtonClick,
|
|
1789
|
+
showPayPal,
|
|
1790
|
+
showApplePay,
|
|
1791
|
+
showGooglePay,
|
|
1792
|
+
buttonsTheme,
|
|
1793
|
+
buttonsStyles: stylesOverride
|
|
1794
|
+
}) {
|
|
1795
|
+
const [showCardForm, setShowCardForm] = useState3(false);
|
|
1796
|
+
const bStyles = useMemo3(() => {
|
|
1797
|
+
const base = resolveButtonsLayoutTheme2(buttonsTheme);
|
|
1798
|
+
if (!stylesOverride) return base;
|
|
1799
|
+
return {
|
|
1800
|
+
...base,
|
|
1801
|
+
...stylesOverride,
|
|
1802
|
+
cardButton: { ...base.cardButton, ...stylesOverride.cardButton },
|
|
1803
|
+
cardFormContainer: { ...base.cardFormContainer, ...stylesOverride.cardFormContainer },
|
|
1804
|
+
submitButton: { ...base.submitButton, ...stylesOverride.submitButton },
|
|
1805
|
+
title: { ...base.title, ...stylesOverride.title }
|
|
1806
|
+
};
|
|
1807
|
+
}, [buttonsTheme, stylesOverride]);
|
|
1808
|
+
const skeleton = (h) => /* @__PURE__ */ jsx4("div", { style: {
|
|
1809
|
+
height: h,
|
|
1810
|
+
borderRadius: 8,
|
|
1811
|
+
background: "#e5e7eb",
|
|
1812
|
+
animation: "flopay-interim-pulse 1.5s ease-in-out infinite"
|
|
1813
|
+
} });
|
|
1814
|
+
if (showCardForm) {
|
|
1815
|
+
const inputBorder = bStyles.cardInputBorder ?? "#e5e7eb";
|
|
1816
|
+
const inputBg = bStyles.cardInputBackground ?? "white";
|
|
1817
|
+
return /* @__PURE__ */ jsxs2("div", { style: {
|
|
1818
|
+
backgroundColor: bStyles.cardFormContainer?.backgroundColor ?? "white",
|
|
1819
|
+
borderRadius: "8px",
|
|
1820
|
+
animation: "flopay-interim-expand 0.35s cubic-bezier(0.4, 0, 0.2, 1) both",
|
|
1821
|
+
overflow: "hidden",
|
|
1822
|
+
...bStyles.cardFormContainer
|
|
1823
|
+
}, children: [
|
|
1824
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", padding: "0.75rem 0 0.625rem" }, children: [
|
|
1825
|
+
/* @__PURE__ */ jsxs2(
|
|
1826
|
+
"button",
|
|
1827
|
+
{
|
|
1828
|
+
type: "button",
|
|
1829
|
+
onClick: () => setShowCardForm(false),
|
|
1830
|
+
style: {
|
|
1831
|
+
display: "inline-flex",
|
|
1832
|
+
alignItems: "center",
|
|
1833
|
+
gap: "0.5rem",
|
|
1834
|
+
background: "none",
|
|
1835
|
+
border: "none",
|
|
1836
|
+
cursor: "pointer",
|
|
1837
|
+
color: "#4b5563",
|
|
1838
|
+
fontSize: "0.85rem",
|
|
1839
|
+
fontWeight: 500,
|
|
1840
|
+
padding: 0,
|
|
1841
|
+
flexShrink: 0,
|
|
1842
|
+
...bStyles.backButton
|
|
1843
|
+
},
|
|
1844
|
+
children: [
|
|
1845
|
+
/* @__PURE__ */ jsx4("span", { style: {
|
|
1846
|
+
display: "inline-flex",
|
|
1847
|
+
alignItems: "center",
|
|
1848
|
+
justifyContent: "center",
|
|
1849
|
+
width: 28,
|
|
1850
|
+
height: 28,
|
|
1851
|
+
borderRadius: "50%",
|
|
1852
|
+
backgroundColor: "#f3f4f6",
|
|
1853
|
+
...bStyles.backButtonIcon
|
|
1854
|
+
}, children: /* @__PURE__ */ jsx4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx4("path", { d: "M15 18l-6-6 6-6" }) }) }),
|
|
1855
|
+
"Go back"
|
|
1856
|
+
]
|
|
1857
|
+
}
|
|
1858
|
+
),
|
|
1859
|
+
/* @__PURE__ */ jsx4("div", { style: {
|
|
1860
|
+
flex: 1,
|
|
1861
|
+
textAlign: "center",
|
|
1862
|
+
fontWeight: 600,
|
|
1863
|
+
fontSize: "1.05rem",
|
|
1864
|
+
color: "#262833",
|
|
1865
|
+
paddingRight: 80,
|
|
1866
|
+
...bStyles.title
|
|
1867
|
+
}, children: "Secure card checkout" })
|
|
1868
|
+
] }),
|
|
1869
|
+
/* @__PURE__ */ jsx4("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx4("div", { style: { width: "60%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
1870
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex" }, children: [
|
|
1871
|
+
/* @__PURE__ */ jsx4("div", { style: { flex: 1, backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTop: "none", borderRight: "none", borderBottomLeftRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx4("div", { style: { width: "50%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
1872
|
+
/* @__PURE__ */ jsx4("div", { style: { flex: 1, backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTop: "none", borderBottomRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx4("div", { style: { width: "40%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) })
|
|
1873
|
+
] }),
|
|
1874
|
+
/* @__PURE__ */ jsx4("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx4("div", { style: { width: "45%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
1875
|
+
/* @__PURE__ */ jsx4("div", { style: {
|
|
1876
|
+
height: 50,
|
|
1877
|
+
borderRadius: 8,
|
|
1878
|
+
marginTop: 16,
|
|
1879
|
+
background: "#c8c8ff",
|
|
1880
|
+
animation: "flopay-interim-pulse 1.5s ease-in-out infinite",
|
|
1881
|
+
...bStyles.submitButton,
|
|
1882
|
+
opacity: 0.5
|
|
1883
|
+
} }),
|
|
1884
|
+
/* @__PURE__ */ jsx4("style", { children: `
|
|
1885
|
+
@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
1886
|
+
@keyframes flopay-interim-expand {
|
|
1887
|
+
0% { opacity: 0; max-height: 0; transform: translateY(-12px); }
|
|
1888
|
+
40% { opacity: 1; }
|
|
1889
|
+
100% { opacity: 1; max-height: 600px; transform: translateY(0); }
|
|
1890
|
+
}
|
|
1891
|
+
` })
|
|
1892
|
+
] });
|
|
1893
|
+
}
|
|
1894
|
+
return /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
1895
|
+
showPayPal && skeleton(44),
|
|
1896
|
+
(showApplePay || showGooglePay) && skeleton(44),
|
|
1897
|
+
/* @__PURE__ */ jsxs2(
|
|
1898
|
+
"button",
|
|
1899
|
+
{
|
|
1900
|
+
type: "button",
|
|
1901
|
+
onClick: () => {
|
|
1902
|
+
onButtonClick?.("card");
|
|
1903
|
+
setShowCardForm(true);
|
|
1904
|
+
},
|
|
1905
|
+
style: {
|
|
1906
|
+
width: "100%",
|
|
1907
|
+
padding: "0.9rem 1rem",
|
|
1908
|
+
backgroundColor: "white",
|
|
1909
|
+
color: "#262833",
|
|
1910
|
+
border: "1px solid #d1d5db",
|
|
1911
|
+
borderRadius: "8px",
|
|
1912
|
+
fontSize: bStyles.cardButtonFontSize ?? "0.95rem",
|
|
1913
|
+
fontWeight: 600,
|
|
1914
|
+
cursor: "pointer",
|
|
1915
|
+
display: "flex",
|
|
1916
|
+
alignItems: "center",
|
|
1917
|
+
justifyContent: "center",
|
|
1918
|
+
gap: "0.625rem",
|
|
1919
|
+
boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
|
|
1920
|
+
transition: "transform 0.1s",
|
|
1921
|
+
position: "relative",
|
|
1922
|
+
...bStyles.cardButton
|
|
1923
|
+
},
|
|
1924
|
+
onMouseDown: (e) => {
|
|
1925
|
+
e.currentTarget.style.transform = "scale(0.985)";
|
|
1926
|
+
},
|
|
1927
|
+
onMouseUp: (e) => {
|
|
1928
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
1929
|
+
},
|
|
1930
|
+
children: [
|
|
1931
|
+
/* @__PURE__ */ jsxs2("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1932
|
+
/* @__PURE__ */ jsx4("rect", { width: "20", height: "14", x: "2", y: "5", rx: "2" }),
|
|
1933
|
+
/* @__PURE__ */ jsx4("line", { x1: "2", x2: "22", y1: "10", y2: "10" })
|
|
1934
|
+
] }),
|
|
1935
|
+
"Credit / Debit Card",
|
|
1936
|
+
/* @__PURE__ */ jsx4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#9ca3af", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { position: "absolute", right: "1rem" }, children: /* @__PURE__ */ jsx4("path", { d: "M9 18l6-6-6-6" }) })
|
|
1937
|
+
]
|
|
1938
|
+
}
|
|
1939
|
+
),
|
|
1940
|
+
/* @__PURE__ */ jsx4("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
1941
|
+
] });
|
|
1942
|
+
}
|
|
1342
1943
|
|
|
1343
1944
|
// src/checkout-form.tsx
|
|
1344
1945
|
import { FloPayError as FloPayError3 } from "@flopay/shared";
|