@flopay/react 1.2.7 → 1.3.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 +53 -1
- package/dist/index.cjs +1468 -675
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +104 -5
- package/dist/index.d.ts +104 -5
- package/dist/index.mjs +1272 -482
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -11
package/dist/index.mjs
CHANGED
|
@@ -100,7 +100,7 @@ function FloPayProvider({
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
// src/flopay-checkout.tsx
|
|
103
|
-
import
|
|
103
|
+
import React8, { useCallback as useCallback2, useEffect as useEffect6, useMemo as useMemo4, useRef as useRef5, useState as useState4 } from "react";
|
|
104
104
|
import { PaymentAPI as PaymentAPI4 } from "@flopay/js";
|
|
105
105
|
import { SDK_VERSION, FloPayError as FloPayError5, resolveBillingApiUrl as resolveBillingApiUrl3, buildCheckoutDisplayData, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme2, resolveTheme as resolveTheme2 } from "@flopay/shared";
|
|
106
106
|
|
|
@@ -248,9 +248,7 @@ import {
|
|
|
248
248
|
resolveAVSConfig,
|
|
249
249
|
isAVSFieldVisible,
|
|
250
250
|
getStateFromPostalCode,
|
|
251
|
-
filterStripeMethodsByCurrency,
|
|
252
251
|
filterStripeMethodsByCountry,
|
|
253
|
-
filterStripeMethodsByAmount,
|
|
254
252
|
getStripeMethodDisplayName,
|
|
255
253
|
hasVendoredStripeMethodLogo,
|
|
256
254
|
needsStripeMethodExplicitConfirm,
|
|
@@ -259,7 +257,80 @@ import {
|
|
|
259
257
|
stripeExpressMethodToOptionKey
|
|
260
258
|
} from "@flopay/shared";
|
|
261
259
|
import { PaymentAPI as PaymentAPI2 } from "@flopay/js";
|
|
262
|
-
|
|
260
|
+
|
|
261
|
+
// src/vault-card-fields.tsx
|
|
262
|
+
import { useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
263
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
264
|
+
function VaultCardFields({
|
|
265
|
+
capture,
|
|
266
|
+
html,
|
|
267
|
+
messageToken,
|
|
268
|
+
expectedOrigin,
|
|
269
|
+
theme,
|
|
270
|
+
containerStyle,
|
|
271
|
+
onReady,
|
|
272
|
+
onError,
|
|
273
|
+
onValidation
|
|
274
|
+
}) {
|
|
275
|
+
const containerRef = useRef2(null);
|
|
276
|
+
const onReadyRef = useRef2(onReady);
|
|
277
|
+
const onErrorRef = useRef2(onError);
|
|
278
|
+
const onValidationRef = useRef2(onValidation);
|
|
279
|
+
onReadyRef.current = onReady;
|
|
280
|
+
onErrorRef.current = onError;
|
|
281
|
+
onValidationRef.current = onValidation;
|
|
282
|
+
const themeRef = useRef2(theme);
|
|
283
|
+
themeRef.current = theme;
|
|
284
|
+
useEffect3(() => {
|
|
285
|
+
const el = containerRef.current;
|
|
286
|
+
if (!el) return;
|
|
287
|
+
let active = true;
|
|
288
|
+
let readyEmitted = false;
|
|
289
|
+
const emitReadyOnce = () => {
|
|
290
|
+
if (!active || readyEmitted) return;
|
|
291
|
+
readyEmitted = true;
|
|
292
|
+
onReadyRef.current?.();
|
|
293
|
+
};
|
|
294
|
+
const offReady = capture.on("ready", () => {
|
|
295
|
+
emitReadyOnce();
|
|
296
|
+
});
|
|
297
|
+
const offError = capture.on("error", (event) => {
|
|
298
|
+
onErrorRef.current?.(event.message ?? "There was a problem loading the secure card form.");
|
|
299
|
+
});
|
|
300
|
+
const offValidation = capture.on("validation", (event) => {
|
|
301
|
+
onValidationRef.current?.(event.message ?? null);
|
|
302
|
+
});
|
|
303
|
+
const mountOptions = {
|
|
304
|
+
html,
|
|
305
|
+
...messageToken ? { messageToken } : {},
|
|
306
|
+
...expectedOrigin ? { expectedOrigin } : {},
|
|
307
|
+
...themeRef.current ? { theme: themeRef.current } : {}
|
|
308
|
+
};
|
|
309
|
+
capture.mount(el, mountOptions).then(() => {
|
|
310
|
+
emitReadyOnce();
|
|
311
|
+
}).catch((err) => {
|
|
312
|
+
if (active) {
|
|
313
|
+
onErrorRef.current?.(
|
|
314
|
+
err instanceof Error ? err.message : "Failed to load the secure card form."
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
return () => {
|
|
319
|
+
active = false;
|
|
320
|
+
offReady();
|
|
321
|
+
offError();
|
|
322
|
+
offValidation();
|
|
323
|
+
capture.unmount();
|
|
324
|
+
};
|
|
325
|
+
}, [capture, html, messageToken, expectedOrigin]);
|
|
326
|
+
useEffect3(() => {
|
|
327
|
+
if (theme) capture.applyTheme?.(theme);
|
|
328
|
+
}, [capture, theme]);
|
|
329
|
+
return /* @__PURE__ */ jsx4("div", { ref: containerRef, "data-testid": "flopay-vault-card-fields", style: containerStyle });
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// src/split-card-form.tsx
|
|
333
|
+
import React7, { forwardRef, useCallback, useContext as useContext3, useEffect as useEffect5, useImperativeHandle, useMemo as useMemo3, useRef as useRef4, useState as useState3 } from "react";
|
|
263
334
|
|
|
264
335
|
// src/hooks.ts
|
|
265
336
|
import { useContext as useContext2 } from "react";
|
|
@@ -286,14 +357,14 @@ function useBillingApiUrl() {
|
|
|
286
357
|
|
|
287
358
|
// src/processing-overlay.tsx
|
|
288
359
|
import "react";
|
|
289
|
-
import { jsx as
|
|
360
|
+
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
290
361
|
var PROCESSING_OVERLAY_SUCCESS_DELAY_MS = 1200;
|
|
291
362
|
var PROCESSING_OVERLAY_ERROR_DELAY_MS = 1500;
|
|
292
363
|
function ProcessingOverlay({
|
|
293
364
|
status,
|
|
294
365
|
errorMessage
|
|
295
366
|
}) {
|
|
296
|
-
return /* @__PURE__ */
|
|
367
|
+
return /* @__PURE__ */ jsx5(
|
|
297
368
|
"div",
|
|
298
369
|
{
|
|
299
370
|
"data-testid": "flopay-processing-overlay",
|
|
@@ -337,14 +408,14 @@ function ProcessingOverlay({
|
|
|
337
408
|
xmlns: "http://www.w3.org/2000/svg",
|
|
338
409
|
style: { animation: "flopay-spin 0.8s linear infinite" },
|
|
339
410
|
children: [
|
|
340
|
-
/* @__PURE__ */
|
|
341
|
-
/* @__PURE__ */
|
|
411
|
+
/* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "10", stroke: "#e5e7eb", strokeWidth: "3" }),
|
|
412
|
+
/* @__PURE__ */ jsx5("path", { d: "M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z", fill: "#4A49FF" })
|
|
342
413
|
]
|
|
343
414
|
}
|
|
344
415
|
),
|
|
345
|
-
status === "success" && /* @__PURE__ */
|
|
346
|
-
/* @__PURE__ */
|
|
347
|
-
/* @__PURE__ */
|
|
416
|
+
status === "success" && /* @__PURE__ */ jsx5("div", { style: { animation: "flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)" }, children: /* @__PURE__ */ jsxs2("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
417
|
+
/* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "11", fill: "#22c55e" }),
|
|
418
|
+
/* @__PURE__ */ jsx5(
|
|
348
419
|
"path",
|
|
349
420
|
{
|
|
350
421
|
d: "M7 12.5l3 3 7-7",
|
|
@@ -360,9 +431,9 @@ function ProcessingOverlay({
|
|
|
360
431
|
}
|
|
361
432
|
)
|
|
362
433
|
] }) }),
|
|
363
|
-
status === "error" && /* @__PURE__ */
|
|
364
|
-
/* @__PURE__ */
|
|
365
|
-
/* @__PURE__ */
|
|
434
|
+
status === "error" && /* @__PURE__ */ jsx5("div", { style: { animation: "flopay-shake 0.4s ease" }, children: /* @__PURE__ */ jsxs2("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
435
|
+
/* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "11", fill: "#ef4444" }),
|
|
436
|
+
/* @__PURE__ */ jsx5(
|
|
366
437
|
"path",
|
|
367
438
|
{
|
|
368
439
|
d: "M8 8l8 8M16 8l-8 8",
|
|
@@ -394,7 +465,7 @@ function ProcessingOverlay({
|
|
|
394
465
|
]
|
|
395
466
|
}
|
|
396
467
|
),
|
|
397
|
-
status === "success" && /* @__PURE__ */
|
|
468
|
+
status === "success" && /* @__PURE__ */ jsx5(
|
|
398
469
|
"p",
|
|
399
470
|
{
|
|
400
471
|
style: {
|
|
@@ -408,7 +479,7 @@ function ProcessingOverlay({
|
|
|
408
479
|
children: "You will be automatically redirected, do not close or navigate away from this window."
|
|
409
480
|
}
|
|
410
481
|
),
|
|
411
|
-
status === "error" && errorMessage && /* @__PURE__ */
|
|
482
|
+
status === "error" && errorMessage && /* @__PURE__ */ jsx5(
|
|
412
483
|
"p",
|
|
413
484
|
{
|
|
414
485
|
style: {
|
|
@@ -422,7 +493,7 @@ function ProcessingOverlay({
|
|
|
422
493
|
children: errorMessage
|
|
423
494
|
}
|
|
424
495
|
),
|
|
425
|
-
/* @__PURE__ */
|
|
496
|
+
/* @__PURE__ */ jsx5("style", { children: `
|
|
426
497
|
@keyframes flopay-spin { to { transform: rotate(360deg); } }
|
|
427
498
|
@keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
|
|
428
499
|
@keyframes flopay-draw { to { stroke-dashoffset: 0; } }
|
|
@@ -436,7 +507,7 @@ function ProcessingOverlay({
|
|
|
436
507
|
}
|
|
437
508
|
|
|
438
509
|
// src/checkout-utils.ts
|
|
439
|
-
import { FloPayError } from "@flopay/shared";
|
|
510
|
+
import { FloPayError, isSetupIntentClientSecret } from "@flopay/shared";
|
|
440
511
|
function mergeInlineSessionPatches(base, patch) {
|
|
441
512
|
if (!patch) return base;
|
|
442
513
|
if (!base) return patch;
|
|
@@ -605,6 +676,18 @@ function resolvePaymentIntentPaymentMethodId(paymentIntent) {
|
|
|
605
676
|
}
|
|
606
677
|
async function retrievePaymentIntentFromProvider(provider, clientSecret) {
|
|
607
678
|
const retriever = provider;
|
|
679
|
+
if (isSetupIntentClientSecret(clientSecret)) {
|
|
680
|
+
if (!retriever?.retrieveSetupIntent) {
|
|
681
|
+
return null;
|
|
682
|
+
}
|
|
683
|
+
const { setupIntent, error: error2 } = await retriever.retrieveSetupIntent(clientSecret);
|
|
684
|
+
if (error2) {
|
|
685
|
+
throw new FloPayError(error2.message ?? "Failed to retrieve setup intent.", "api_error", {
|
|
686
|
+
...error2.code ? { code: error2.code } : {}
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
return setupIntent ?? null;
|
|
690
|
+
}
|
|
608
691
|
if (!retriever?.retrievePaymentIntent) {
|
|
609
692
|
return null;
|
|
610
693
|
}
|
|
@@ -616,6 +699,12 @@ async function retrievePaymentIntentFromProvider(provider, clientSecret) {
|
|
|
616
699
|
}
|
|
617
700
|
return paymentIntent ?? null;
|
|
618
701
|
}
|
|
702
|
+
function resolveWalletElementsMode(amountInMinorUnits) {
|
|
703
|
+
if (typeof amountInMinorUnits !== "number" || !Number.isFinite(amountInMinorUnits) || amountInMinorUnits <= 0) {
|
|
704
|
+
return { mode: "setup" };
|
|
705
|
+
}
|
|
706
|
+
return { mode: "payment", amount: amountInMinorUnits };
|
|
707
|
+
}
|
|
619
708
|
function resolveTokenizedPaymentMethodId(tokenizedBody) {
|
|
620
709
|
const candidates = [
|
|
621
710
|
tokenizedBody?.id,
|
|
@@ -678,11 +767,11 @@ function isInAppBrowser(userAgent) {
|
|
|
678
767
|
}
|
|
679
768
|
|
|
680
769
|
// src/direct-paypal-button.tsx
|
|
681
|
-
import { useEffect as
|
|
770
|
+
import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState2 } from "react";
|
|
682
771
|
import { loadScript } from "@paypal/paypal-js";
|
|
683
772
|
import { PaymentAPI } from "@flopay/js";
|
|
684
773
|
import { FloPayError as FloPayError2, normalizeGatewayEnvironment } from "@flopay/shared";
|
|
685
|
-
import { jsx as
|
|
774
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
686
775
|
var DEFAULT_BUTTON_HEIGHT = 45;
|
|
687
776
|
function DirectPayPalButton({
|
|
688
777
|
sessionId,
|
|
@@ -705,7 +794,7 @@ function DirectPayPalButton({
|
|
|
705
794
|
existingOrderId,
|
|
706
795
|
debug = false
|
|
707
796
|
}) {
|
|
708
|
-
const containerRef =
|
|
797
|
+
const containerRef = useRef3(null);
|
|
709
798
|
const [ready, setReady] = useState2(false);
|
|
710
799
|
const [failed, setFailed] = useState2(false);
|
|
711
800
|
const [submitting, setSubmitting] = useState2(false);
|
|
@@ -715,52 +804,52 @@ function DirectPayPalButton({
|
|
|
715
804
|
if (!debug) return;
|
|
716
805
|
setDebugLines((prev) => [...prev, `${(/* @__PURE__ */ new Date()).toISOString().slice(11, 23)} ${line}`]);
|
|
717
806
|
};
|
|
718
|
-
const onTokenizedBodyRef =
|
|
719
|
-
const onCompleteRef =
|
|
720
|
-
const onErrorChangeRef =
|
|
721
|
-
const onDeclineRef =
|
|
722
|
-
const onButtonClickRef =
|
|
723
|
-
const onLoadStateChangeRef =
|
|
724
|
-
const runBeforeButtonClickRef =
|
|
725
|
-
const sessionRef =
|
|
726
|
-
const emailRef =
|
|
727
|
-
const nonceRef =
|
|
728
|
-
const beforeClickRef =
|
|
729
|
-
|
|
807
|
+
const onTokenizedBodyRef = useRef3(onTokenizedBody);
|
|
808
|
+
const onCompleteRef = useRef3(onComplete);
|
|
809
|
+
const onErrorChangeRef = useRef3(onErrorChange);
|
|
810
|
+
const onDeclineRef = useRef3(onDecline);
|
|
811
|
+
const onButtonClickRef = useRef3(onButtonClick);
|
|
812
|
+
const onLoadStateChangeRef = useRef3(onLoadStateChange);
|
|
813
|
+
const runBeforeButtonClickRef = useRef3(runBeforeButtonClick);
|
|
814
|
+
const sessionRef = useRef3(session);
|
|
815
|
+
const emailRef = useRef3(email);
|
|
816
|
+
const nonceRef = useRef3(nonce);
|
|
817
|
+
const beforeClickRef = useRef3(null);
|
|
818
|
+
useEffect4(() => {
|
|
730
819
|
onTokenizedBodyRef.current = onTokenizedBody;
|
|
731
820
|
}, [onTokenizedBody]);
|
|
732
|
-
|
|
821
|
+
useEffect4(() => {
|
|
733
822
|
onCompleteRef.current = onComplete;
|
|
734
823
|
}, [onComplete]);
|
|
735
|
-
|
|
824
|
+
useEffect4(() => {
|
|
736
825
|
onErrorChangeRef.current = onErrorChange;
|
|
737
826
|
}, [onErrorChange]);
|
|
738
|
-
|
|
827
|
+
useEffect4(() => {
|
|
739
828
|
onDeclineRef.current = onDecline;
|
|
740
829
|
}, [onDecline]);
|
|
741
|
-
|
|
830
|
+
useEffect4(() => {
|
|
742
831
|
onButtonClickRef.current = onButtonClick;
|
|
743
832
|
}, [onButtonClick]);
|
|
744
|
-
|
|
833
|
+
useEffect4(() => {
|
|
745
834
|
onLoadStateChangeRef.current = onLoadStateChange;
|
|
746
835
|
}, [onLoadStateChange]);
|
|
747
|
-
|
|
836
|
+
useEffect4(() => {
|
|
748
837
|
runBeforeButtonClickRef.current = runBeforeButtonClick;
|
|
749
838
|
}, [runBeforeButtonClick]);
|
|
750
|
-
|
|
839
|
+
useEffect4(() => {
|
|
751
840
|
sessionRef.current = session;
|
|
752
841
|
}, [session]);
|
|
753
|
-
|
|
842
|
+
useEffect4(() => {
|
|
754
843
|
emailRef.current = email;
|
|
755
844
|
}, [email]);
|
|
756
|
-
|
|
845
|
+
useEffect4(() => {
|
|
757
846
|
nonceRef.current = nonce;
|
|
758
847
|
}, [nonce]);
|
|
759
|
-
|
|
848
|
+
useEffect4(() => {
|
|
760
849
|
onLoadStateChangeRef.current?.(ready && !failed);
|
|
761
850
|
}, [ready, failed]);
|
|
762
851
|
const normalizedEnv = normalizeGatewayEnvironment(environment);
|
|
763
|
-
|
|
852
|
+
useEffect4(() => {
|
|
764
853
|
const maskedClient = clientId ? `${clientId.slice(0, 6)}\u2026(len ${clientId.length})` : "(empty)";
|
|
765
854
|
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "(no navigator)";
|
|
766
855
|
appendDebug(`mount clientId=${maskedClient} env=${environment ?? "(unset)"}\u2192${normalizedEnv ?? "live"} ccy=${currency} sub=${isSubscription}`);
|
|
@@ -1197,7 +1286,7 @@ ${debugLines.join("\n")}`
|
|
|
1197
1286
|
}
|
|
1198
1287
|
) : null;
|
|
1199
1288
|
if (failed) {
|
|
1200
|
-
return debug ? /* @__PURE__ */
|
|
1289
|
+
return debug ? /* @__PURE__ */ jsx6("div", { children: debugPanel }) : null;
|
|
1201
1290
|
}
|
|
1202
1291
|
return (
|
|
1203
1292
|
// Single wrapper so the parent flex container sees exactly one flex item
|
|
@@ -1207,7 +1296,7 @@ ${debugLines.join("\n")}`
|
|
|
1207
1296
|
/* @__PURE__ */ jsxs3("div", { children: [
|
|
1208
1297
|
debugPanel,
|
|
1209
1298
|
/* @__PURE__ */ jsxs3("div", { style: { position: "relative", minHeight: DEFAULT_BUTTON_HEIGHT }, children: [
|
|
1210
|
-
!ready && /* @__PURE__ */
|
|
1299
|
+
!ready && /* @__PURE__ */ jsx6(
|
|
1211
1300
|
"div",
|
|
1212
1301
|
{
|
|
1213
1302
|
"data-testid": "flopay-direct-paypal-placeholder",
|
|
@@ -1221,7 +1310,7 @@ ${debugLines.join("\n")}`
|
|
|
1221
1310
|
}
|
|
1222
1311
|
}
|
|
1223
1312
|
),
|
|
1224
|
-
/* @__PURE__ */
|
|
1313
|
+
/* @__PURE__ */ jsx6(
|
|
1225
1314
|
"div",
|
|
1226
1315
|
{
|
|
1227
1316
|
ref: containerRef,
|
|
@@ -1240,11 +1329,29 @@ ${debugLines.join("\n")}`
|
|
|
1240
1329
|
}
|
|
1241
1330
|
|
|
1242
1331
|
// src/split-card-form.tsx
|
|
1243
|
-
import { FloPayError as FloPayError3, resolveTheme } from "@flopay/shared";
|
|
1244
|
-
import { Fragment as Fragment2, jsx as
|
|
1332
|
+
import { FloPayError as FloPayError3, isSetupIntentClientSecret as isSetupIntentClientSecret2, resolveTheme } from "@flopay/shared";
|
|
1333
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1245
1334
|
var STRIPE_RESUME_KEY = "flopay_stripe_resume";
|
|
1246
1335
|
var LEGACY_WALLET_RESUME_KEY = "flopay_wallet_resume";
|
|
1247
1336
|
var PAYPAL_RESUME_KEY = "flopay_paypal_resume";
|
|
1337
|
+
function toVaultMount(block) {
|
|
1338
|
+
if (!block?.html) return null;
|
|
1339
|
+
return {
|
|
1340
|
+
html: block.html,
|
|
1341
|
+
...block.messageToken ? { messageToken: block.messageToken } : {},
|
|
1342
|
+
...block.expectedOrigin ? { expectedOrigin: block.expectedOrigin } : {}
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
function darkenHex(hex, amount = 0.12) {
|
|
1346
|
+
const match = /^#?([0-9a-fA-F]{6})$/.exec(hex.trim());
|
|
1347
|
+
if (!match) return hex;
|
|
1348
|
+
const value = parseInt(match[1], 16);
|
|
1349
|
+
const scale = Math.max(0, Math.min(1, 1 - amount));
|
|
1350
|
+
const r = Math.round((value >> 16 & 255) * scale);
|
|
1351
|
+
const g = Math.round((value >> 8 & 255) * scale);
|
|
1352
|
+
const b = Math.round((value & 255) * scale);
|
|
1353
|
+
return `#${(1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1)}`;
|
|
1354
|
+
}
|
|
1248
1355
|
var FLOPAY_KEYFRAMES = `
|
|
1249
1356
|
.paypal-buttons { margin: 0 !important; vertical-align: top !important; }
|
|
1250
1357
|
@keyframes flopay-spin { to { transform: rotate(360deg); } }
|
|
@@ -1269,18 +1376,20 @@ var FLOPAY_KEYFRAMES = `
|
|
|
1269
1376
|
`;
|
|
1270
1377
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;
|
|
1271
1378
|
function derivePrimaryTileStyle(opts) {
|
|
1272
|
-
if (!opts.themeBundle) {
|
|
1379
|
+
if (!opts.themeBundle && !opts.explicitPrimaryColor) {
|
|
1273
1380
|
return {
|
|
1274
1381
|
backgroundColor: "white",
|
|
1275
1382
|
color: "#262833",
|
|
1276
1383
|
border: "1px solid #d1d5db",
|
|
1277
|
-
borderRadius:
|
|
1384
|
+
borderRadius: opts.resolvedBorderRadius,
|
|
1278
1385
|
boxShadow: "0 1px 2px rgba(0,0,0,0.04)"
|
|
1279
1386
|
};
|
|
1280
1387
|
}
|
|
1281
|
-
const submit = opts.submitButtonStyle ?? {};
|
|
1388
|
+
const submit = opts.themeBundle ? opts.submitButtonStyle ?? {} : {};
|
|
1282
1389
|
return {
|
|
1283
|
-
|
|
1390
|
+
// `colorPrimary` wins so a per-checkout override re-skins the card / auto-pay
|
|
1391
|
+
// buttons in lock-step with the submit CTA (which also keys off it).
|
|
1392
|
+
backgroundColor: opts.resolvedPrimaryColor,
|
|
1284
1393
|
color: submit.color ?? "white",
|
|
1285
1394
|
border: submit.border ?? "none",
|
|
1286
1395
|
borderRadius: submit.borderRadius ?? opts.resolvedBorderRadius,
|
|
@@ -1314,7 +1423,7 @@ function normalizeBeforeButtonClickError(method, err) {
|
|
|
1314
1423
|
);
|
|
1315
1424
|
}
|
|
1316
1425
|
function FloPayKeyframes() {
|
|
1317
|
-
return /* @__PURE__ */
|
|
1426
|
+
return /* @__PURE__ */ jsx7("style", { children: FLOPAY_KEYFRAMES });
|
|
1318
1427
|
}
|
|
1319
1428
|
function toCssSize(value) {
|
|
1320
1429
|
if (typeof value === "number") return `${value}px`;
|
|
@@ -1337,7 +1446,7 @@ function ExpressCheckoutReadySwap({
|
|
|
1337
1446
|
}) {
|
|
1338
1447
|
if (state === "unavailable" || state === "load_error") return null;
|
|
1339
1448
|
return /* @__PURE__ */ jsxs4("div", { style: { position: "relative", minHeight: 44 }, children: [
|
|
1340
|
-
/* @__PURE__ */
|
|
1449
|
+
/* @__PURE__ */ jsx7(
|
|
1341
1450
|
"div",
|
|
1342
1451
|
{
|
|
1343
1452
|
"data-testid": placeholderTestId,
|
|
@@ -1356,7 +1465,7 @@ function ExpressCheckoutReadySwap({
|
|
|
1356
1465
|
}
|
|
1357
1466
|
}
|
|
1358
1467
|
),
|
|
1359
|
-
/* @__PURE__ */
|
|
1468
|
+
/* @__PURE__ */ jsx7(
|
|
1360
1469
|
"div",
|
|
1361
1470
|
{
|
|
1362
1471
|
style: {
|
|
@@ -1376,7 +1485,7 @@ function isExpressCheckoutRowVisible(state) {
|
|
|
1376
1485
|
}
|
|
1377
1486
|
var SplitCardForm = forwardRef(
|
|
1378
1487
|
function SplitCardForm2(props, ref) {
|
|
1379
|
-
return /* @__PURE__ */
|
|
1488
|
+
return /* @__PURE__ */ jsx7(SplitCardFormInner, { ...props, innerRef: ref });
|
|
1380
1489
|
}
|
|
1381
1490
|
);
|
|
1382
1491
|
function PayPalButtonInner({
|
|
@@ -1396,14 +1505,14 @@ function PayPalButtonInner({
|
|
|
1396
1505
|
const stripe = useStripeRaw();
|
|
1397
1506
|
const elements = useStripeElements();
|
|
1398
1507
|
const [loadState, setLoadState] = useState3("loading");
|
|
1399
|
-
|
|
1508
|
+
useEffect5(() => {
|
|
1400
1509
|
onLoadStateChange?.(loadState);
|
|
1401
1510
|
}, [loadState, onLoadStateChange]);
|
|
1402
1511
|
const [submitting, setSubmitting] = useState3(false);
|
|
1403
|
-
const paypalResumeAttempted =
|
|
1404
|
-
const beforeClickRef =
|
|
1512
|
+
const paypalResumeAttempted = useRef4(false);
|
|
1513
|
+
const beforeClickRef = useRef4(null);
|
|
1405
1514
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
1406
|
-
|
|
1515
|
+
useEffect5(() => {
|
|
1407
1516
|
if (!stripe || paypalResumeAttempted.current) return;
|
|
1408
1517
|
const params = new URLSearchParams(window.location.search);
|
|
1409
1518
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -1609,13 +1718,13 @@ function PayPalButtonInner({
|
|
|
1609
1718
|
}
|
|
1610
1719
|
}, [stripe, elements, sessionId, nonce, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]);
|
|
1611
1720
|
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1612
|
-
/* @__PURE__ */
|
|
1721
|
+
/* @__PURE__ */ jsx7(
|
|
1613
1722
|
ExpressCheckoutReadySwap,
|
|
1614
1723
|
{
|
|
1615
1724
|
state: loadState,
|
|
1616
1725
|
placeholderTestId: "flopay-paypal-placeholder",
|
|
1617
1726
|
borderRadius: placeholderBorderRadius,
|
|
1618
|
-
children: /* @__PURE__ */
|
|
1727
|
+
children: /* @__PURE__ */ jsx7(
|
|
1619
1728
|
ExpressCheckoutElement,
|
|
1620
1729
|
{
|
|
1621
1730
|
onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
|
|
@@ -1642,7 +1751,7 @@ function PayPalButtonInner({
|
|
|
1642
1751
|
)
|
|
1643
1752
|
}
|
|
1644
1753
|
),
|
|
1645
|
-
submitting && /* @__PURE__ */
|
|
1754
|
+
submitting && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: "processing" })
|
|
1646
1755
|
] });
|
|
1647
1756
|
}
|
|
1648
1757
|
function WalletButtonInner({
|
|
@@ -1662,13 +1771,13 @@ function WalletButtonInner({
|
|
|
1662
1771
|
const stripe = useStripeRaw();
|
|
1663
1772
|
const elements = useStripeElements();
|
|
1664
1773
|
const [loadState, setLoadState] = useState3("loading");
|
|
1665
|
-
|
|
1774
|
+
useEffect5(() => {
|
|
1666
1775
|
onLoadStateChange?.(loadState);
|
|
1667
1776
|
}, [loadState, onLoadStateChange]);
|
|
1668
1777
|
const [submitting, setSubmitting] = useState3(false);
|
|
1669
1778
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
1670
|
-
const lastWalletMethodRef =
|
|
1671
|
-
const beforeClickRef =
|
|
1779
|
+
const lastWalletMethodRef = useRef4("card");
|
|
1780
|
+
const beforeClickRef = useRef4(null);
|
|
1672
1781
|
const handleWalletConfirm = useCallback(
|
|
1673
1782
|
async (event) => {
|
|
1674
1783
|
if (!stripe || !elements) return;
|
|
@@ -1733,10 +1842,7 @@ function WalletButtonInner({
|
|
|
1733
1842
|
const intentJson = await intentResponse.json();
|
|
1734
1843
|
const intentClientSecret = intentJson.data?.id;
|
|
1735
1844
|
if (!intentClientSecret) throw new Error("No client_secret in payment intent response");
|
|
1736
|
-
const { error: confirmError,
|
|
1737
|
-
intentClientSecret,
|
|
1738
|
-
{ payment_method: paymentMethod.id }
|
|
1739
|
-
);
|
|
1845
|
+
const { error: confirmError, intentId } = isSetupIntentClientSecret2(intentClientSecret) ? await stripe.confirmCardSetup(intentClientSecret, { payment_method: paymentMethod.id }).then((r) => ({ error: r.error, intentId: r.setupIntent?.id })) : await stripe.confirmCardPayment(intentClientSecret, { payment_method: paymentMethod.id }).then((r) => ({ error: r.error, intentId: r.paymentIntent?.id }));
|
|
1740
1846
|
if (confirmError) {
|
|
1741
1847
|
const message = confirmError.message ?? "Wallet payment failed.";
|
|
1742
1848
|
onErrorChange?.(message);
|
|
@@ -1748,7 +1854,7 @@ function WalletButtonInner({
|
|
|
1748
1854
|
onTokenizedBody({
|
|
1749
1855
|
id: paymentMethod.id,
|
|
1750
1856
|
type: "card",
|
|
1751
|
-
threeDSecureActionResultTokenId:
|
|
1857
|
+
threeDSecureActionResultTokenId: intentId
|
|
1752
1858
|
}, {
|
|
1753
1859
|
accountPatch: prepared?.accountPatch,
|
|
1754
1860
|
sessionId: effectiveSessionId,
|
|
@@ -1781,13 +1887,13 @@ function WalletButtonInner({
|
|
|
1781
1887
|
[expressMethods]
|
|
1782
1888
|
);
|
|
1783
1889
|
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1784
|
-
/* @__PURE__ */
|
|
1890
|
+
/* @__PURE__ */ jsx7(
|
|
1785
1891
|
ExpressCheckoutReadySwap,
|
|
1786
1892
|
{
|
|
1787
1893
|
state: loadState,
|
|
1788
1894
|
placeholderTestId: "flopay-wallet-placeholder",
|
|
1789
1895
|
borderRadius: placeholderBorderRadius,
|
|
1790
|
-
children: /* @__PURE__ */
|
|
1896
|
+
children: /* @__PURE__ */ jsx7(
|
|
1791
1897
|
ExpressCheckoutElement,
|
|
1792
1898
|
{
|
|
1793
1899
|
onReady: (event) => {
|
|
@@ -1826,7 +1932,7 @@ function WalletButtonInner({
|
|
|
1826
1932
|
)
|
|
1827
1933
|
}
|
|
1828
1934
|
),
|
|
1829
|
-
submitting && /* @__PURE__ */
|
|
1935
|
+
submitting && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: "processing" })
|
|
1830
1936
|
] });
|
|
1831
1937
|
}
|
|
1832
1938
|
function StripeMethodButton({
|
|
@@ -1847,7 +1953,7 @@ function StripeMethodButton({
|
|
|
1847
1953
|
const resolvedBackground = brand?.backgroundColor ?? backgroundColor ?? "#ffffff";
|
|
1848
1954
|
const resolvedBorder = brand?.borderColor ?? borderColor ?? "#d1d5db";
|
|
1849
1955
|
const resolvedTextColor = brand?.textColor ?? textColor ?? "#262833";
|
|
1850
|
-
return /* @__PURE__ */
|
|
1956
|
+
return /* @__PURE__ */ jsx7(
|
|
1851
1957
|
"button",
|
|
1852
1958
|
{
|
|
1853
1959
|
type: "button",
|
|
@@ -1894,7 +2000,7 @@ function StripeMethodButton({
|
|
|
1894
2000
|
// Pulse-skeleton parity with the wallet ECE: no spinner, just the
|
|
1895
2001
|
// status text on top of the pulsing background. Keeps the loading
|
|
1896
2002
|
// affordance shape-equivalent across both kinds of tile.
|
|
1897
|
-
/* @__PURE__ */
|
|
2003
|
+
/* @__PURE__ */ jsx7("span", { style: { margin: "0 auto" }, children: `Connecting to ${getStripeMethodDisplayName(method)}\u2026` })
|
|
1898
2004
|
) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1899
2005
|
/* @__PURE__ */ jsxs4(
|
|
1900
2006
|
"span",
|
|
@@ -1909,7 +2015,7 @@ function StripeMethodButton({
|
|
|
1909
2015
|
gap: hasVendoredStripeMethodLogo(method) ? 8 : 0
|
|
1910
2016
|
},
|
|
1911
2017
|
children: [
|
|
1912
|
-
brand?.logoSvg && /* @__PURE__ */
|
|
2018
|
+
brand?.logoSvg && /* @__PURE__ */ jsx7(
|
|
1913
2019
|
"span",
|
|
1914
2020
|
{
|
|
1915
2021
|
"aria-hidden": "true",
|
|
@@ -1928,11 +2034,11 @@ function StripeMethodButton({
|
|
|
1928
2034
|
dangerouslySetInnerHTML: { __html: brand.logoSvg }
|
|
1929
2035
|
}
|
|
1930
2036
|
),
|
|
1931
|
-
/* @__PURE__ */
|
|
2037
|
+
/* @__PURE__ */ jsx7("span", { children: getStripeMethodDisplayName(method) })
|
|
1932
2038
|
]
|
|
1933
2039
|
}
|
|
1934
2040
|
),
|
|
1935
|
-
hasNextStep && /* @__PURE__ */
|
|
2041
|
+
hasNextStep && /* @__PURE__ */ jsx7(
|
|
1936
2042
|
"svg",
|
|
1937
2043
|
{
|
|
1938
2044
|
width: "14",
|
|
@@ -1952,7 +2058,7 @@ function StripeMethodButton({
|
|
|
1952
2058
|
opacity: 0.7
|
|
1953
2059
|
},
|
|
1954
2060
|
"aria-hidden": "true",
|
|
1955
|
-
children: /* @__PURE__ */
|
|
2061
|
+
children: /* @__PURE__ */ jsx7("path", { d: "M9 18l6-6-6-6" })
|
|
1956
2062
|
}
|
|
1957
2063
|
)
|
|
1958
2064
|
] })
|
|
@@ -1975,12 +2081,13 @@ function StripeMethodInlineForm({
|
|
|
1975
2081
|
isProcessing,
|
|
1976
2082
|
submitButtonColor,
|
|
1977
2083
|
submitButtonBorderRadius,
|
|
1978
|
-
submitButtonStyle
|
|
2084
|
+
submitButtonStyle,
|
|
2085
|
+
errorText
|
|
1979
2086
|
}) {
|
|
1980
2087
|
const stripe = useStripeRaw();
|
|
1981
2088
|
const elements = useStripeElements();
|
|
1982
2089
|
const [submitting, setSubmitting] = useState3(false);
|
|
1983
|
-
const submittingRef =
|
|
2090
|
+
const submittingRef = useRef4(false);
|
|
1984
2091
|
const [isMethodComplete, setIsMethodComplete] = useState3(false);
|
|
1985
2092
|
const [loadState, setLoadState] = useState3("loading");
|
|
1986
2093
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
@@ -2125,7 +2232,7 @@ function StripeMethodInlineForm({
|
|
|
2125
2232
|
]);
|
|
2126
2233
|
void onCancel;
|
|
2127
2234
|
return /* @__PURE__ */ jsxs4("div", { "data-testid": `flopay-stripe-method-form-${method}`, style: { display: "flex", flexDirection: "column" }, children: [
|
|
2128
|
-
/* @__PURE__ */
|
|
2235
|
+
/* @__PURE__ */ jsx7(
|
|
2129
2236
|
PaymentElement2,
|
|
2130
2237
|
{
|
|
2131
2238
|
onReady: () => setLoadState("ready"),
|
|
@@ -2145,7 +2252,7 @@ function StripeMethodInlineForm({
|
|
|
2145
2252
|
}
|
|
2146
2253
|
}
|
|
2147
2254
|
),
|
|
2148
|
-
/* @__PURE__ */
|
|
2255
|
+
/* @__PURE__ */ jsx7(
|
|
2149
2256
|
"button",
|
|
2150
2257
|
{
|
|
2151
2258
|
type: "button",
|
|
@@ -2171,7 +2278,23 @@ function StripeMethodInlineForm({
|
|
|
2171
2278
|
},
|
|
2172
2279
|
children: submitting ? "Processing\u2026" : `Pay with ${getStripeMethodDisplayName(method)}`
|
|
2173
2280
|
}
|
|
2174
|
-
)
|
|
2281
|
+
),
|
|
2282
|
+
errorText && /* @__PURE__ */ jsxs4("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
2283
|
+
margin: "0.75rem 0 0",
|
|
2284
|
+
padding: "0.625rem 0.875rem",
|
|
2285
|
+
background: "#FEF2F2",
|
|
2286
|
+
border: "1px solid #FECACA",
|
|
2287
|
+
borderRadius: "8px",
|
|
2288
|
+
color: "#991B1B",
|
|
2289
|
+
fontSize: "0.85rem",
|
|
2290
|
+
fontWeight: 600,
|
|
2291
|
+
display: "flex",
|
|
2292
|
+
alignItems: "center",
|
|
2293
|
+
gap: "0.5rem"
|
|
2294
|
+
}, children: [
|
|
2295
|
+
/* @__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" }) }),
|
|
2296
|
+
errorText
|
|
2297
|
+
] })
|
|
2175
2298
|
] });
|
|
2176
2299
|
}
|
|
2177
2300
|
function StripePaymentElementInner({
|
|
@@ -2201,8 +2324,8 @@ function StripePaymentElementInner({
|
|
|
2201
2324
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
2202
2325
|
const [expandedMethod, setExpandedMethod] = useState3(null);
|
|
2203
2326
|
const [submittingMethod, setSubmittingMethod] = useState3(null);
|
|
2204
|
-
const submittingRef =
|
|
2205
|
-
|
|
2327
|
+
const submittingRef = useRef4(false);
|
|
2328
|
+
useEffect5(() => {
|
|
2206
2329
|
if (paymentElementMethods.length > 0 && stripeInstance) {
|
|
2207
2330
|
onLoadStateChange?.("ready");
|
|
2208
2331
|
} else if (!stripeInstance) {
|
|
@@ -2370,7 +2493,7 @@ function StripePaymentElementInner({
|
|
|
2370
2493
|
paymentMethodTypes: [localExpandedMethod]
|
|
2371
2494
|
};
|
|
2372
2495
|
}, [localExpandedMethod, paymentElementBaseOptions]);
|
|
2373
|
-
return /* @__PURE__ */
|
|
2496
|
+
return /* @__PURE__ */ jsx7(
|
|
2374
2497
|
"div",
|
|
2375
2498
|
{
|
|
2376
2499
|
"data-testid": "flopay-stripe-payment-element-region",
|
|
@@ -2379,8 +2502,8 @@ function StripePaymentElementInner({
|
|
|
2379
2502
|
const isExpanded = expandedApmMethod === method;
|
|
2380
2503
|
const isSubmittingThis = submittingMethod === method;
|
|
2381
2504
|
const otherInProgress = submittingMethod !== null && submittingMethod !== method || expandedApmMethod !== null && expandedApmMethod !== void 0 && expandedApmMethod !== method;
|
|
2382
|
-
return /* @__PURE__ */ jsxs4(
|
|
2383
|
-
/* @__PURE__ */
|
|
2505
|
+
return /* @__PURE__ */ jsxs4(React7.Fragment, { children: [
|
|
2506
|
+
/* @__PURE__ */ jsx7(
|
|
2384
2507
|
StripeMethodButton,
|
|
2385
2508
|
{
|
|
2386
2509
|
method,
|
|
@@ -2397,12 +2520,12 @@ function StripePaymentElementInner({
|
|
|
2397
2520
|
fontFamily: buttonAppearance?.fontFamily
|
|
2398
2521
|
}
|
|
2399
2522
|
),
|
|
2400
|
-
!onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && /* @__PURE__ */
|
|
2523
|
+
!onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && /* @__PURE__ */ jsx7(
|
|
2401
2524
|
StripeElements,
|
|
2402
2525
|
{
|
|
2403
2526
|
stripe: stripeInstance,
|
|
2404
2527
|
options: localInlineElementsOptions,
|
|
2405
|
-
children: /* @__PURE__ */
|
|
2528
|
+
children: /* @__PURE__ */ jsx7(
|
|
2406
2529
|
StripeMethodInlineForm,
|
|
2407
2530
|
{
|
|
2408
2531
|
method,
|
|
@@ -2455,6 +2578,7 @@ function SplitCardFormInner({
|
|
|
2455
2578
|
showPayPal = true,
|
|
2456
2579
|
showStripe = true,
|
|
2457
2580
|
enabledPaymentMethods,
|
|
2581
|
+
enabledPaymentMethodCountries,
|
|
2458
2582
|
showApplePay = true,
|
|
2459
2583
|
showGooglePay = true,
|
|
2460
2584
|
layout = "default",
|
|
@@ -2469,6 +2593,8 @@ function SplitCardFormInner({
|
|
|
2469
2593
|
onButtonClick,
|
|
2470
2594
|
onBeforeButtonClick,
|
|
2471
2595
|
enableAVS: enableAVSProp,
|
|
2596
|
+
cardFieldOrder,
|
|
2597
|
+
cardPreFormSlot,
|
|
2472
2598
|
avsLayout: avsLayoutProp = "row",
|
|
2473
2599
|
country: countryProp,
|
|
2474
2600
|
zip: zipProp,
|
|
@@ -2505,14 +2631,41 @@ function SplitCardFormInner({
|
|
|
2505
2631
|
const [city, setCity] = useState3(cityProp ?? "");
|
|
2506
2632
|
const [stateValue, setStateValue] = useState3(stateProp ?? "");
|
|
2507
2633
|
const [accountPatch, setAccountPatch] = useState3({});
|
|
2508
|
-
const zipCodeRef =
|
|
2509
|
-
const selectedCountryRef =
|
|
2510
|
-
const addressLine1Ref =
|
|
2511
|
-
const addressLine2Ref =
|
|
2512
|
-
const cityRef =
|
|
2513
|
-
const stateRef =
|
|
2634
|
+
const zipCodeRef = useRef4(zipProp ?? "");
|
|
2635
|
+
const selectedCountryRef = useRef4(countryProp ?? "US");
|
|
2636
|
+
const addressLine1Ref = useRef4(addressLine1Prop ?? "");
|
|
2637
|
+
const addressLine2Ref = useRef4(addressLine2Prop ?? "");
|
|
2638
|
+
const cityRef = useRef4(cityProp ?? "");
|
|
2639
|
+
const stateRef = useRef4(stateProp ?? "");
|
|
2514
2640
|
const avsConfig = useMemo3(() => resolveAVSConfig(enableAVSProp), [enableAVSProp]);
|
|
2515
2641
|
const enableAVS = avsConfig !== null;
|
|
2642
|
+
const vaultBlockReady = Boolean(session?.vault?.html);
|
|
2643
|
+
const vaultGatewayAdvertised = Boolean(session?.gateways?.pcivault);
|
|
2644
|
+
const vaultActive = Boolean(
|
|
2645
|
+
showStripe && (vaultBlockReady || vaultGatewayAdvertised) && flopay && sessionId
|
|
2646
|
+
);
|
|
2647
|
+
const cardCapture = useMemo3(() => {
|
|
2648
|
+
if (!flopay || !vaultActive || !sessionId) return null;
|
|
2649
|
+
return flopay.cardCapture({ sessionId });
|
|
2650
|
+
}, [flopay, vaultActive, sessionId]);
|
|
2651
|
+
const { avsInvalid, invalidAvsFields } = useMemo3(() => {
|
|
2652
|
+
const none = { line1: false, city: false, state: false, zip: false };
|
|
2653
|
+
if (!vaultActive || !avsConfig) return { avsInvalid: false, invalidAvsFields: none };
|
|
2654
|
+
const cc = selectedCountry;
|
|
2655
|
+
const isEmpty = (field, value) => isAVSFieldVisible(field, cc) && !value.trim();
|
|
2656
|
+
const invalidAvsFields2 = {
|
|
2657
|
+
line1: isEmpty(avsConfig.address_line_1, addressLine1),
|
|
2658
|
+
city: isEmpty(avsConfig.city, city),
|
|
2659
|
+
state: isEmpty(avsConfig.state, stateValue),
|
|
2660
|
+
zip: isEmpty(avsConfig.postal_code, zipCode)
|
|
2661
|
+
};
|
|
2662
|
+
const avsInvalid2 = invalidAvsFields2.line1 || invalidAvsFields2.city || invalidAvsFields2.state || invalidAvsFields2.zip;
|
|
2663
|
+
return { avsInvalid: avsInvalid2, invalidAvsFields: invalidAvsFields2 };
|
|
2664
|
+
}, [vaultActive, avsConfig, selectedCountry, addressLine1, city, stateValue, zipCode]);
|
|
2665
|
+
const [hasAttemptedSubmit, setHasAttemptedSubmit] = useState3(false);
|
|
2666
|
+
const [vaultMount, setVaultMount] = useState3(
|
|
2667
|
+
() => toVaultMount(session?.vault)
|
|
2668
|
+
);
|
|
2516
2669
|
const [viewState, setViewState] = useState3(initialCardOpen ? "card" : "buttons");
|
|
2517
2670
|
const [expandedApmMethod, setExpandedApmMethod] = useState3(null);
|
|
2518
2671
|
const showCardForm = viewState === "expanding" || viewState === "card";
|
|
@@ -2537,7 +2690,7 @@ function SplitCardFormInner({
|
|
|
2537
2690
|
setExpandedApmMethod(null);
|
|
2538
2691
|
}, TRANSITION_MS);
|
|
2539
2692
|
}, []);
|
|
2540
|
-
|
|
2693
|
+
useEffect5(() => {
|
|
2541
2694
|
if (layout === "buttons" && initialCardOpen) {
|
|
2542
2695
|
setViewState("card");
|
|
2543
2696
|
}
|
|
@@ -2545,10 +2698,10 @@ function SplitCardFormInner({
|
|
|
2545
2698
|
const [fullName, setFullName] = useState3("");
|
|
2546
2699
|
const [formReady, setFormReady] = useState3(false);
|
|
2547
2700
|
const [overlayStatus, setOverlayStatus] = useState3(null);
|
|
2548
|
-
const processingRef =
|
|
2701
|
+
const processingRef = useRef4(false);
|
|
2549
2702
|
const [paypalDirectRetry, setPaypalDirectRetry] = useState3(null);
|
|
2550
|
-
const paypalDirectRetryRef =
|
|
2551
|
-
|
|
2703
|
+
const paypalDirectRetryRef = useRef4(paypalDirectRetry);
|
|
2704
|
+
useEffect5(() => {
|
|
2552
2705
|
paypalDirectRetryRef.current = paypalDirectRetry;
|
|
2553
2706
|
}, [paypalDirectRetry]);
|
|
2554
2707
|
const resolvedBillingApiUrl = billingApiUrl || contextBillingUrl;
|
|
@@ -2569,6 +2722,31 @@ function SplitCardFormInner({
|
|
|
2569
2722
|
};
|
|
2570
2723
|
}, [themeBundle, buttonsTheme, buttonsStylesOverride]);
|
|
2571
2724
|
const appearance = appearanceOverride ?? themeBundle?.appearance;
|
|
2725
|
+
const vaultThemeColors = useMemo3(() => {
|
|
2726
|
+
const vars = appearance?.variables;
|
|
2727
|
+
const asString = (value) => typeof value === "string" && value ? value : void 0;
|
|
2728
|
+
const submitButtonStyle = bStyles.submitButton;
|
|
2729
|
+
const primary = asString(vars?.colorPrimary) ?? asString(submitButtonStyle?.backgroundColor) ?? "#4A49FF";
|
|
2730
|
+
const isButtonsLayout = layout === "buttons";
|
|
2731
|
+
const nameInput = bStyles.nameInput;
|
|
2732
|
+
return {
|
|
2733
|
+
primaryColor: primary,
|
|
2734
|
+
primaryHoverColor: asString(vars?.colorPrimaryHover) ?? darkenHex(primary, 0.12),
|
|
2735
|
+
inputBackgroundColor: asString(bStyles.cardInputBackground) ?? asString(vars?.colorBackground) ?? "#ffffff",
|
|
2736
|
+
textColor: asString(bStyles.cardInputColor) ?? asString(nameInput?.color) ?? asString(vars?.colorText) ?? "#262833",
|
|
2737
|
+
borderColor: asString(bStyles.cardInputBorder) ?? (isButtonsLayout ? "#e5e7eb" : "#A4A4FF"),
|
|
2738
|
+
placeholderColor: asString(bStyles.cardInputPlaceholderColor) ?? "#9ca3af",
|
|
2739
|
+
errorColor: asString(vars?.colorDanger) ?? "#dc2626",
|
|
2740
|
+
successColor: "#16a34a",
|
|
2741
|
+
fontFamily: asString(nameInput?.fontFamily) ?? asString(vars?.fontFamily) ?? "Poppins, sans-serif",
|
|
2742
|
+
fontSize: asString(bStyles.cardInputFontSize) ?? asString(vars?.fontSizeBase) ?? "16px",
|
|
2743
|
+
// `resolvedInputFontWeight` equivalent — sent as a string (the widget's
|
|
2744
|
+
// theme applier only honors string values) so vault inputs/placeholders
|
|
2745
|
+
// match the AVS fields' weight per theme (default 400).
|
|
2746
|
+
fontWeight: String(toCssWeight(nameInput?.fontWeight) ?? 400),
|
|
2747
|
+
borderRadius: asString(vars?.borderRadius) ?? "8px"
|
|
2748
|
+
};
|
|
2749
|
+
}, [appearance, bStyles, layout]);
|
|
2572
2750
|
const isInlineSessionPatchProcessing = checkout.inlineSessionPatchProcessing ?? false;
|
|
2573
2751
|
const isSubmitting = (externalProcessing ?? processing) || isInlineSessionPatchProcessing;
|
|
2574
2752
|
const isSelfContained = !onTokenizedBody;
|
|
@@ -2611,14 +2789,17 @@ function SplitCardFormInner({
|
|
|
2611
2789
|
}
|
|
2612
2790
|
};
|
|
2613
2791
|
}, [appearance]);
|
|
2614
|
-
const walletOptions = useMemo3(() =>
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2792
|
+
const walletOptions = useMemo3(() => {
|
|
2793
|
+
const modeOptions = resolveWalletElementsMode(totalAmount);
|
|
2794
|
+
return {
|
|
2795
|
+
...modeOptions,
|
|
2796
|
+
currency: currency.toLowerCase(),
|
|
2797
|
+
paymentMethodCreation: "manual",
|
|
2798
|
+
// captureMethod only applies to payment mode; Stripe rejects it in setup.
|
|
2799
|
+
...modeOptions.mode === "payment" ? { captureMethod: "manual" } : {},
|
|
2800
|
+
...stripeAppearanceProp
|
|
2801
|
+
};
|
|
2802
|
+
}, [totalAmount, currency, stripeAppearanceProp]);
|
|
2622
2803
|
const paypalOptions = useMemo3(() => ({
|
|
2623
2804
|
mode: "payment",
|
|
2624
2805
|
amount: amountInCents,
|
|
@@ -2634,12 +2815,160 @@ function SplitCardFormInner({
|
|
|
2634
2815
|
},
|
|
2635
2816
|
[onErrorChange]
|
|
2636
2817
|
);
|
|
2818
|
+
useEffect5(() => {
|
|
2819
|
+
if (!vaultActive || !cardCapture) return;
|
|
2820
|
+
cardCapture.setSubmitGate?.(avsInvalid);
|
|
2821
|
+
}, [vaultActive, cardCapture, avsInvalid]);
|
|
2822
|
+
useEffect5(() => {
|
|
2823
|
+
if (!vaultActive || !cardCapture) return;
|
|
2824
|
+
cardCapture.setCardFieldOrder?.(cardFieldOrder ?? null, avsConfig == null);
|
|
2825
|
+
}, [vaultActive, cardCapture, cardFieldOrder, avsConfig]);
|
|
2826
|
+
useEffect5(() => {
|
|
2827
|
+
if (viewState === "expanding" || viewState === "collapsing" || viewState === "apm-expanding" || viewState === "apm-collapsing") {
|
|
2828
|
+
updateError(null);
|
|
2829
|
+
}
|
|
2830
|
+
}, [viewState, updateError]);
|
|
2637
2831
|
const emitDecline = useCallback(
|
|
2638
2832
|
(method, input, overrides) => {
|
|
2639
2833
|
onDecline?.(buildDeclineEvent(method, input, overrides));
|
|
2640
2834
|
},
|
|
2641
2835
|
[onDecline]
|
|
2642
2836
|
);
|
|
2837
|
+
useEffect5(() => {
|
|
2838
|
+
if (!vaultActive || !sessionId) {
|
|
2839
|
+
setVaultMount(null);
|
|
2840
|
+
return;
|
|
2841
|
+
}
|
|
2842
|
+
const embedded = toVaultMount(session?.vault);
|
|
2843
|
+
if (embedded) {
|
|
2844
|
+
setVaultMount(embedded);
|
|
2845
|
+
return;
|
|
2846
|
+
}
|
|
2847
|
+
setVaultMount(null);
|
|
2848
|
+
let active = true;
|
|
2849
|
+
new PaymentAPI2(baseUrl).getVaultCapture(sessionId, nonce).then((block) => {
|
|
2850
|
+
if (!active) return;
|
|
2851
|
+
const mount = toVaultMount(block);
|
|
2852
|
+
if (mount) {
|
|
2853
|
+
setVaultMount(mount);
|
|
2854
|
+
} else {
|
|
2855
|
+
updateError("Failed to load the secure card form.");
|
|
2856
|
+
}
|
|
2857
|
+
}).catch((err) => {
|
|
2858
|
+
if (active) {
|
|
2859
|
+
updateError(err instanceof Error ? err.message : "Failed to load the secure card form.");
|
|
2860
|
+
}
|
|
2861
|
+
});
|
|
2862
|
+
return () => {
|
|
2863
|
+
active = false;
|
|
2864
|
+
};
|
|
2865
|
+
}, [
|
|
2866
|
+
vaultActive,
|
|
2867
|
+
sessionId,
|
|
2868
|
+
session?.vault?.html,
|
|
2869
|
+
session?.vault?.messageToken,
|
|
2870
|
+
session?.vault?.expectedOrigin,
|
|
2871
|
+
baseUrl,
|
|
2872
|
+
nonce,
|
|
2873
|
+
updateError
|
|
2874
|
+
]);
|
|
2875
|
+
useEffect5(() => {
|
|
2876
|
+
if (!vaultActive || !cardCapture) return;
|
|
2877
|
+
let cancelled = false;
|
|
2878
|
+
const offSubmitting = cardCapture.on("submitting", () => {
|
|
2879
|
+
setHasAttemptedSubmit(true);
|
|
2880
|
+
setOverlayStatus("processing");
|
|
2881
|
+
if (!sessionId || !nonce) return;
|
|
2882
|
+
const cc = selectedCountryRef.current || resolvedAccount.country || "US";
|
|
2883
|
+
const stateVisible = avsConfig ? isAVSFieldVisible(avsConfig.state, cc) : false;
|
|
2884
|
+
const line1Visible = avsConfig ? isAVSFieldVisible(avsConfig.address_line_1, cc) : false;
|
|
2885
|
+
const zipVisible = avsConfig ? isAVSFieldVisible(avsConfig.postal_code, cc) : false;
|
|
2886
|
+
const cityVisible = avsConfig ? isAVSFieldVisible(avsConfig.city, cc) : false;
|
|
2887
|
+
const line2Visible = avsConfig ? isAVSFieldVisible(avsConfig.address_line_2, cc) : false;
|
|
2888
|
+
const derivedState = line1Visible && !stateVisible && zipVisible ? getStateFromPostalCode(cc, zipCodeRef.current ?? "") : null;
|
|
2889
|
+
const stateValue2 = stateVisible ? stateRef.current : derivedState;
|
|
2890
|
+
void new PaymentAPI2(baseUrl).patchAccountSnapshot(sessionId, nonce, {
|
|
2891
|
+
accountData: {
|
|
2892
|
+
userId: resolvedAccount.userId ?? "",
|
|
2893
|
+
email: resolvedAccount.email ?? "",
|
|
2894
|
+
firstName: resolvedAccount.firstName ?? fullName.trim().split(/\s+/)[0] ?? "",
|
|
2895
|
+
lastName: resolvedAccount.lastName ?? fullName.trim().split(/\s+/).slice(1).join(" ") ?? "",
|
|
2896
|
+
...zipVisible && zipCodeRef.current ? { zip: zipCodeRef.current } : {},
|
|
2897
|
+
...cityVisible && cityRef.current ? { city: cityRef.current } : {},
|
|
2898
|
+
...stateValue2 ? { state: stateValue2 } : {},
|
|
2899
|
+
...line1Visible && addressLine1Ref.current ? { addressLine1: addressLine1Ref.current } : {},
|
|
2900
|
+
...line2Visible && addressLine2Ref.current ? { addressLine2: addressLine2Ref.current } : {},
|
|
2901
|
+
country: cc
|
|
2902
|
+
},
|
|
2903
|
+
...avsCheckProp !== void 0 ? { avsCheck: avsCheckProp } : {},
|
|
2904
|
+
...avsConfig ? {
|
|
2905
|
+
avsConfig: {
|
|
2906
|
+
country: isAVSFieldVisible(avsConfig.country, cc),
|
|
2907
|
+
postal_code: zipVisible,
|
|
2908
|
+
address_line_1: line1Visible,
|
|
2909
|
+
address_line_2: line2Visible,
|
|
2910
|
+
city: cityVisible,
|
|
2911
|
+
state: stateVisible
|
|
2912
|
+
}
|
|
2913
|
+
} : {}
|
|
2914
|
+
}).catch(() => {
|
|
2915
|
+
});
|
|
2916
|
+
});
|
|
2917
|
+
const offComplete = cardCapture.on("complete", async (event) => {
|
|
2918
|
+
markSessionRecentlyCompleted(event.sessionId ?? sessionId);
|
|
2919
|
+
setOverlayStatus("success");
|
|
2920
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));
|
|
2921
|
+
if (cancelled) return;
|
|
2922
|
+
onComplete?.({
|
|
2923
|
+
status: "succeeded",
|
|
2924
|
+
paymentIntentId: event.intentId,
|
|
2925
|
+
checkoutMethod: "card"
|
|
2926
|
+
});
|
|
2927
|
+
});
|
|
2928
|
+
const offDecline = cardCapture.on("decline", async (event) => {
|
|
2929
|
+
const message = event.message ?? "Your payment was declined. Please try another card or contact your bank.";
|
|
2930
|
+
updateError(message);
|
|
2931
|
+
setOverlayStatus("error");
|
|
2932
|
+
emitDecline("card", message, event.declineReason ? { declineCode: event.declineReason } : void 0);
|
|
2933
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
2934
|
+
if (cancelled) return;
|
|
2935
|
+
setOverlayStatus(null);
|
|
2936
|
+
});
|
|
2937
|
+
const offError = cardCapture.on("error", async (event) => {
|
|
2938
|
+
const message = event.message ?? "There was a problem processing your payment. Please try again.";
|
|
2939
|
+
updateError(message);
|
|
2940
|
+
setOverlayStatus("error");
|
|
2941
|
+
onError?.(new FloPayError3(message, "api_error"));
|
|
2942
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
2943
|
+
if (cancelled) return;
|
|
2944
|
+
setOverlayStatus(null);
|
|
2945
|
+
});
|
|
2946
|
+
return () => {
|
|
2947
|
+
cancelled = true;
|
|
2948
|
+
offSubmitting();
|
|
2949
|
+
offComplete();
|
|
2950
|
+
offDecline();
|
|
2951
|
+
offError();
|
|
2952
|
+
};
|
|
2953
|
+
}, [
|
|
2954
|
+
vaultActive,
|
|
2955
|
+
cardCapture,
|
|
2956
|
+
sessionId,
|
|
2957
|
+
nonce,
|
|
2958
|
+
baseUrl,
|
|
2959
|
+
avsConfig,
|
|
2960
|
+
avsCheckProp,
|
|
2961
|
+
resolvedAccount.userId,
|
|
2962
|
+
resolvedAccount.email,
|
|
2963
|
+
resolvedAccount.firstName,
|
|
2964
|
+
resolvedAccount.lastName,
|
|
2965
|
+
resolvedAccount.country,
|
|
2966
|
+
fullName,
|
|
2967
|
+
onComplete,
|
|
2968
|
+
onError,
|
|
2969
|
+
updateError,
|
|
2970
|
+
emitDecline
|
|
2971
|
+
]);
|
|
2643
2972
|
const directPaypalConfigured = !!directPaypal?.clientId;
|
|
2644
2973
|
const hasEnabledMethodsPayload = Array.isArray(enabledPaymentMethods);
|
|
2645
2974
|
const hasEnabledMethods = hasEnabledMethodsPayload && enabledPaymentMethods.length > 0;
|
|
@@ -2663,17 +2992,18 @@ function SplitCardFormInner({
|
|
|
2663
2992
|
}, [showApplePay, showGooglePay]);
|
|
2664
2993
|
const walletExpressMethods = hasEnabledMethodsPayload ? expressMethodsForWalletRow : legacyExpressMethods;
|
|
2665
2994
|
const showWallets = showStripe && walletExpressMethods.length > 0;
|
|
2666
|
-
const
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
)
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2995
|
+
const apmCountry = enableAVS ? selectedCountry : countryProp;
|
|
2996
|
+
const paymentElementMethodsForCurrency = useMemo3(() => {
|
|
2997
|
+
const target = apmCountry?.trim().toUpperCase();
|
|
2998
|
+
if (!target) return paymentElementMethods;
|
|
2999
|
+
if (!enabledPaymentMethodCountries) {
|
|
3000
|
+
return filterStripeMethodsByCountry(paymentElementMethods, apmCountry);
|
|
3001
|
+
}
|
|
3002
|
+
return paymentElementMethods.filter((method) => {
|
|
3003
|
+
const allowed = enabledPaymentMethodCountries[method];
|
|
3004
|
+
return !allowed || allowed.length === 0 || allowed.includes(target);
|
|
3005
|
+
});
|
|
3006
|
+
}, [paymentElementMethods, apmCountry, enabledPaymentMethodCountries]);
|
|
2677
3007
|
const paymentElementBaseOptions = useMemo3(() => ({
|
|
2678
3008
|
mode: "payment",
|
|
2679
3009
|
amount: amountInCents,
|
|
@@ -2686,7 +3016,7 @@ function SplitCardFormInner({
|
|
|
2686
3016
|
const [paymentElementLoadState, setPaymentElementLoadState] = useState3("loading");
|
|
2687
3017
|
const [directPaypalReady, setDirectPaypalReady] = useState3(false);
|
|
2688
3018
|
const [inAppBrowserDetected, setInAppBrowserDetected] = useState3();
|
|
2689
|
-
|
|
3019
|
+
useEffect5(() => {
|
|
2690
3020
|
setInAppBrowserDetected(isInAppBrowser());
|
|
2691
3021
|
}, []);
|
|
2692
3022
|
const shouldShowPayPal = showPayPal && (directPaypalConfigured || (hasEnabledMethodsPayload ? paypalEnabled : inAppBrowserDetected === false));
|
|
@@ -2698,8 +3028,8 @@ function SplitCardFormInner({
|
|
|
2698
3028
|
const shouldDisplayPayPalRow = shouldRenderDirectPayPal ? directPaypalReady : shouldRenderStripePayPal && isExpressCheckoutRowVisible(paypalLoadState);
|
|
2699
3029
|
const shouldDisplayWalletRow = shouldRenderWallets && isExpressCheckoutRowVisible(walletLoadState);
|
|
2700
3030
|
const shouldDisplayPaymentElementRow = shouldRenderPaymentElement && paymentElementLoadState !== "load_error";
|
|
2701
|
-
const validationFiredRef =
|
|
2702
|
-
|
|
3031
|
+
const validationFiredRef = useRef4(false);
|
|
3032
|
+
useEffect5(() => {
|
|
2703
3033
|
if (validationFiredRef.current) return;
|
|
2704
3034
|
if (!showStripe && !showPayPal) {
|
|
2705
3035
|
validationFiredRef.current = true;
|
|
@@ -2719,8 +3049,8 @@ function SplitCardFormInner({
|
|
|
2719
3049
|
updateError(err.message);
|
|
2720
3050
|
}
|
|
2721
3051
|
}, [showStripe, showPayPal, directPaypalConfigured, paypalStripeInstance, onError, updateError]);
|
|
2722
|
-
const deprecationLoggedRef =
|
|
2723
|
-
|
|
3052
|
+
const deprecationLoggedRef = useRef4(false);
|
|
3053
|
+
useEffect5(() => {
|
|
2724
3054
|
if (deprecationLoggedRef.current) return;
|
|
2725
3055
|
if (!hasEnabledMethods) return;
|
|
2726
3056
|
const stale = [];
|
|
@@ -3046,8 +3376,8 @@ function SplitCardFormInner({
|
|
|
3046
3376
|
}
|
|
3047
3377
|
}
|
|
3048
3378
|
}), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
|
|
3049
|
-
const stripeResumeAttemptedRef =
|
|
3050
|
-
|
|
3379
|
+
const stripeResumeAttemptedRef = useRef4(false);
|
|
3380
|
+
useEffect5(() => {
|
|
3051
3381
|
if (typeof window === "undefined" || stripeResumeAttemptedRef.current) return;
|
|
3052
3382
|
const params = new URLSearchParams(window.location.search);
|
|
3053
3383
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -3129,6 +3459,7 @@ function SplitCardFormInner({
|
|
|
3129
3459
|
async (e) => {
|
|
3130
3460
|
e.preventDefault();
|
|
3131
3461
|
if (!flopay || !elements || isSubmitting || processingRef.current) return;
|
|
3462
|
+
if (vaultActive) return;
|
|
3132
3463
|
if (layout !== "buttons") {
|
|
3133
3464
|
onButtonClick?.("card");
|
|
3134
3465
|
}
|
|
@@ -3156,11 +3487,13 @@ function SplitCardFormInner({
|
|
|
3156
3487
|
return;
|
|
3157
3488
|
}
|
|
3158
3489
|
}
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3490
|
+
if (!vaultActive) {
|
|
3491
|
+
const submitResult = await flopay.submitElements();
|
|
3492
|
+
if (submitResult.error) {
|
|
3493
|
+
updateError(submitResult.error.message);
|
|
3494
|
+
onError?.(submitResult.error);
|
|
3495
|
+
return;
|
|
3496
|
+
}
|
|
3164
3497
|
}
|
|
3165
3498
|
const billingAddress = {};
|
|
3166
3499
|
const cc = selectedCountryRef.current;
|
|
@@ -3185,75 +3518,77 @@ function SplitCardFormInner({
|
|
|
3185
3518
|
...fullName.trim() ? { name: fullName.trim() } : {},
|
|
3186
3519
|
...Object.keys(billingAddress).length > 0 ? { address: billingAddress } : {}
|
|
3187
3520
|
};
|
|
3188
|
-
const pmResult = await flopay.createPaymentMethod(billingDetails);
|
|
3189
|
-
if (pmResult.error || !pmResult.paymentMethodId) {
|
|
3190
|
-
updateError(pmResult.error?.message ?? "Failed to create payment method.");
|
|
3191
|
-
return;
|
|
3192
|
-
}
|
|
3193
3521
|
if (!sessionId || !resolvedAccount.email) {
|
|
3194
3522
|
throw new FloPayError3("Missing sessionId or email", "validation_error");
|
|
3195
3523
|
}
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3524
|
+
{
|
|
3525
|
+
const pmResult = await flopay.createPaymentMethod(billingDetails);
|
|
3526
|
+
if (pmResult.error || !pmResult.paymentMethodId) {
|
|
3527
|
+
updateError(pmResult.error?.message ?? "Failed to create payment method.");
|
|
3528
|
+
return;
|
|
3529
|
+
}
|
|
3530
|
+
const intentHeaders = { "Content-Type": "application/json" };
|
|
3531
|
+
if (nonce) intentHeaders["x-checkout-session-token"] = nonce;
|
|
3532
|
+
const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
|
|
3533
|
+
method: "POST",
|
|
3534
|
+
headers: intentHeaders,
|
|
3535
|
+
body: JSON.stringify({
|
|
3536
|
+
sessionId,
|
|
3537
|
+
email: resolvedAccount.email,
|
|
3538
|
+
paymentMethodType: pmResult.paymentMethodId,
|
|
3539
|
+
isPaypal: false
|
|
3540
|
+
})
|
|
3541
|
+
});
|
|
3542
|
+
if (!intentResponse.ok) {
|
|
3543
|
+
const intentError = await buildFloPayApiErrorFromResponse(
|
|
3544
|
+
intentResponse,
|
|
3545
|
+
"Failed to create payment intent"
|
|
3546
|
+
);
|
|
3547
|
+
setOverlayStatus("error");
|
|
3548
|
+
updateError(intentError.message);
|
|
3549
|
+
onError?.(intentError);
|
|
3550
|
+
emitDecline("card", intentError);
|
|
3551
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3552
|
+
return;
|
|
3553
|
+
}
|
|
3554
|
+
const intentJson = await intentResponse.json();
|
|
3555
|
+
const intentClientSecret = intentJson.data?.id;
|
|
3556
|
+
if (!intentClientSecret) throw new FloPayError3("No client_secret in payment intent response", "api_error");
|
|
3557
|
+
const confirmResult = await flopay.confirmCardPayment({
|
|
3558
|
+
clientSecret: intentClientSecret,
|
|
3559
|
+
paymentMethodId: pmResult.paymentMethodId
|
|
3560
|
+
});
|
|
3561
|
+
if (confirmResult.error) {
|
|
3562
|
+
setOverlayStatus("error");
|
|
3563
|
+
updateError(confirmResult.error.message);
|
|
3564
|
+
onError?.(confirmResult.error);
|
|
3565
|
+
emitDecline("card", confirmResult.error);
|
|
3566
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3567
|
+
return;
|
|
3568
|
+
}
|
|
3569
|
+
const rawProvider = typeof flopay.getRawProvider === "function" ? flopay.getRawProvider() : null;
|
|
3570
|
+
const confirmedPaymentIntent = await retrievePaymentIntentFromProvider(
|
|
3571
|
+
rawProvider,
|
|
3572
|
+
intentClientSecret
|
|
3212
3573
|
);
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
onError?.(confirmResult.error);
|
|
3231
|
-
emitDecline("card", confirmResult.error);
|
|
3232
|
-
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3233
|
-
return;
|
|
3234
|
-
}
|
|
3235
|
-
const rawProvider = typeof flopay.getRawProvider === "function" ? flopay.getRawProvider() : null;
|
|
3236
|
-
const confirmedPaymentIntent = await retrievePaymentIntentFromProvider(
|
|
3237
|
-
rawProvider,
|
|
3238
|
-
intentClientSecret
|
|
3239
|
-
);
|
|
3240
|
-
const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
|
|
3241
|
-
const paymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? pmResult.paymentMethodId;
|
|
3242
|
-
if (!paymentIntentId) {
|
|
3243
|
-
const error2 = new FloPayError3("No payment intent returned after confirmation.", "api_error");
|
|
3244
|
-
setOverlayStatus("error");
|
|
3245
|
-
updateError(error2.message);
|
|
3246
|
-
onError?.(error2);
|
|
3247
|
-
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3248
|
-
return;
|
|
3574
|
+
const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
|
|
3575
|
+
const paymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? pmResult.paymentMethodId;
|
|
3576
|
+
if (!paymentIntentId) {
|
|
3577
|
+
const error2 = new FloPayError3("No payment intent returned after confirmation.", "api_error");
|
|
3578
|
+
setOverlayStatus("error");
|
|
3579
|
+
updateError(error2.message);
|
|
3580
|
+
onError?.(error2);
|
|
3581
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3582
|
+
return;
|
|
3583
|
+
}
|
|
3584
|
+
handedOff = isSelfContained;
|
|
3585
|
+
dispatchTokenizedBody({
|
|
3586
|
+
id: paymentMethodId,
|
|
3587
|
+
type: "card",
|
|
3588
|
+
threeDSecureActionResultTokenId: paymentIntentId,
|
|
3589
|
+
originalPaymentMethodId: pmResult.paymentMethodId
|
|
3590
|
+
});
|
|
3249
3591
|
}
|
|
3250
|
-
handedOff = isSelfContained;
|
|
3251
|
-
dispatchTokenizedBody({
|
|
3252
|
-
id: paymentMethodId,
|
|
3253
|
-
type: "card",
|
|
3254
|
-
threeDSecureActionResultTokenId: paymentIntentId,
|
|
3255
|
-
originalPaymentMethodId: pmResult.paymentMethodId
|
|
3256
|
-
});
|
|
3257
3592
|
} catch (err) {
|
|
3258
3593
|
setOverlayStatus("error");
|
|
3259
3594
|
updateError(err instanceof Error ? err.message : "An unexpected error occurred");
|
|
@@ -3265,11 +3600,11 @@ function SplitCardFormInner({
|
|
|
3265
3600
|
}
|
|
3266
3601
|
}
|
|
3267
3602
|
},
|
|
3268
|
-
[flopay, elements, isSubmitting, sessionId, nonce, resolvedAccount.email, baseUrl, isSelfContained, dispatchTokenizedBody, onButtonClick, onError, updateError, emitDecline, layout]
|
|
3603
|
+
[flopay, elements, isSubmitting, sessionId, nonce, resolvedAccount.email, baseUrl, isSelfContained, vaultActive, dispatchTokenizedBody, onButtonClick, onError, updateError, emitDecline, layout]
|
|
3269
3604
|
);
|
|
3270
|
-
const isReady = flopay !== null && elements !== null;
|
|
3605
|
+
const isReady = flopay !== null && (vaultActive || elements !== null);
|
|
3271
3606
|
if (!isReady) {
|
|
3272
|
-
return /* @__PURE__ */
|
|
3607
|
+
return /* @__PURE__ */ jsx7("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
|
|
3273
3608
|
}
|
|
3274
3609
|
const isButtons = layout === "buttons";
|
|
3275
3610
|
const appearanceVars = appearance?.variables;
|
|
@@ -3277,6 +3612,8 @@ function SplitCardFormInner({
|
|
|
3277
3612
|
const appearanceColorBg = appearanceVars?.colorBackground;
|
|
3278
3613
|
const themedWrapperBg = appearanceColorBg && !SDK_DEFAULT_WHITES.has(appearanceColorBg) ? appearanceColorBg : void 0;
|
|
3279
3614
|
const resolvedBorder = bStyles.cardInputBorder ?? (isButtons ? "#e5e7eb" : "#A4A4FF");
|
|
3615
|
+
const resolvedDangerColor = appearanceVars?.colorDanger ?? "#dc2626";
|
|
3616
|
+
const avsBorderColor = (fieldInvalid) => hasAttemptedSubmit && fieldInvalid ? resolvedDangerColor : resolvedBorder;
|
|
3280
3617
|
const cardBg = bStyles.cardFormContainer?.backgroundColor ?? themedWrapperBg ?? (isButtons ? "white" : "#EDEDFF");
|
|
3281
3618
|
const cardInputBg = bStyles.cardInputBackground ?? appearanceVars?.colorBackground ?? "white";
|
|
3282
3619
|
const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);
|
|
@@ -3288,7 +3625,9 @@ function SplitCardFormInner({
|
|
|
3288
3625
|
const resolvedInputColor = bStyles.cardInputColor ?? (typeof nameInputOverrides?.color === "string" ? nameInputOverrides.color : void 0) ?? appearanceVars?.colorText ?? "#262833";
|
|
3289
3626
|
const resolvedPlaceholderColor = bStyles.cardInputPlaceholderColor ?? "#9ca3af";
|
|
3290
3627
|
const resolvedBorderRadius = appearanceVars?.borderRadius ?? "8px";
|
|
3628
|
+
const buttonBorderRadius = appearanceVars?.borderRadius ?? bStyles.cardButton?.borderRadius ?? resolvedBorderRadius;
|
|
3291
3629
|
const resolvedPrimaryColor = appearanceVars?.colorPrimary ?? "#4A49FF";
|
|
3630
|
+
const resolvedPrimaryHoverColor = appearanceVars?.colorPrimaryHover ?? darkenHex(resolvedPrimaryColor, 0.12);
|
|
3292
3631
|
const resolvedTitleColor = appearanceVars?.colorText ?? "#262833";
|
|
3293
3632
|
const sharedInputTypography = {
|
|
3294
3633
|
fontSize: resolvedInputFontSize,
|
|
@@ -3322,14 +3661,73 @@ function SplitCardFormInner({
|
|
|
3322
3661
|
const containerOverrides = bStyles.cardFormContainer ?? {};
|
|
3323
3662
|
const containerPadding = containerOverrides.padding ?? (isButtons ? "0" : "1rem");
|
|
3324
3663
|
const containerRadius = containerOverrides.borderRadius ?? resolvedBorderRadius;
|
|
3664
|
+
const vaultCardFieldsNode = cardCapture && vaultMount ? /* @__PURE__ */ jsx7(
|
|
3665
|
+
VaultCardFields,
|
|
3666
|
+
{
|
|
3667
|
+
capture: cardCapture,
|
|
3668
|
+
html: vaultMount.html,
|
|
3669
|
+
messageToken: vaultMount.messageToken,
|
|
3670
|
+
expectedOrigin: vaultMount.expectedOrigin,
|
|
3671
|
+
theme: vaultThemeColors,
|
|
3672
|
+
onReady: () => {
|
|
3673
|
+
setFormReady(true);
|
|
3674
|
+
if (!avsConfig || typeof document === "undefined") return;
|
|
3675
|
+
const focusFirstAvs = () => {
|
|
3676
|
+
const block = document.querySelector('[data-testid="flopay-avs-fields"]');
|
|
3677
|
+
const first = block?.querySelector(
|
|
3678
|
+
"input:not([disabled]), select:not([disabled])"
|
|
3679
|
+
);
|
|
3680
|
+
first?.focus();
|
|
3681
|
+
};
|
|
3682
|
+
focusFirstAvs();
|
|
3683
|
+
let tries = 0;
|
|
3684
|
+
const timer = window.setInterval(() => {
|
|
3685
|
+
tries += 1;
|
|
3686
|
+
const active = document.activeElement;
|
|
3687
|
+
const onIframe = !!active && active.tagName === "IFRAME" && active.id === "flopay_vault_form_iframe";
|
|
3688
|
+
if (onIframe) {
|
|
3689
|
+
focusFirstAvs();
|
|
3690
|
+
window.clearInterval(timer);
|
|
3691
|
+
} else if (tries >= 50) {
|
|
3692
|
+
window.clearInterval(timer);
|
|
3693
|
+
}
|
|
3694
|
+
}, 100);
|
|
3695
|
+
},
|
|
3696
|
+
onError: (message) => updateError(message),
|
|
3697
|
+
onValidation: (message) => {
|
|
3698
|
+
updateError(message);
|
|
3699
|
+
if (message) setOverlayStatus(null);
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
) : /* @__PURE__ */ jsx7(
|
|
3703
|
+
"div",
|
|
3704
|
+
{
|
|
3705
|
+
"data-testid": "flopay-vault-loading",
|
|
3706
|
+
style: {
|
|
3707
|
+
minHeight: 120,
|
|
3708
|
+
display: "flex",
|
|
3709
|
+
alignItems: "center",
|
|
3710
|
+
justifyContent: "center",
|
|
3711
|
+
color: "#6b7280",
|
|
3712
|
+
fontSize: 14
|
|
3713
|
+
},
|
|
3714
|
+
children: "Loading secure card form\u2026"
|
|
3715
|
+
}
|
|
3716
|
+
);
|
|
3325
3717
|
const cardFormBlock = /* @__PURE__ */ jsxs4("div", { style: {
|
|
3326
3718
|
backgroundColor: cardBg,
|
|
3327
3719
|
borderRadius: containerRadius,
|
|
3328
3720
|
...containerOverrides,
|
|
3329
3721
|
padding: containerPadding,
|
|
3330
|
-
...sharedInputPlaceholderVars
|
|
3722
|
+
...sharedInputPlaceholderVars,
|
|
3723
|
+
// Flex column (BOTH layouts, so default and buttons>card never diverge) so
|
|
3724
|
+
// AVS can be ordered above the vault widget — its submit lives inside the
|
|
3725
|
+
// iframe, so AVS can't sit between fields and button; it goes above the
|
|
3726
|
+
// card form instead of after the button.
|
|
3727
|
+
display: "flex",
|
|
3728
|
+
flexDirection: "column"
|
|
3331
3729
|
}, children: [
|
|
3332
|
-
/* @__PURE__ */
|
|
3730
|
+
/* @__PURE__ */ jsx7("style", { children: `
|
|
3333
3731
|
.flopay-shared-input::placeholder {
|
|
3334
3732
|
color: var(--flopay-input-placeholder-color);
|
|
3335
3733
|
opacity: 1;
|
|
@@ -3341,7 +3739,9 @@ function SplitCardFormInner({
|
|
|
3341
3739
|
isButtons && showCardForm && /* @__PURE__ */ jsxs4("div", { style: {
|
|
3342
3740
|
display: "flex",
|
|
3343
3741
|
alignItems: "center",
|
|
3344
|
-
padding: "0.75rem 0 0.625rem"
|
|
3742
|
+
padding: "0.75rem 0 0.625rem",
|
|
3743
|
+
// Keep the header on top when AVS is ordered above the card on vault.
|
|
3744
|
+
order: vaultActive ? -2 : 0
|
|
3345
3745
|
}, children: [
|
|
3346
3746
|
/* @__PURE__ */ jsxs4(
|
|
3347
3747
|
"button",
|
|
@@ -3365,7 +3765,7 @@ function SplitCardFormInner({
|
|
|
3365
3765
|
},
|
|
3366
3766
|
"aria-label": "Back to payment methods",
|
|
3367
3767
|
children: [
|
|
3368
|
-
/* @__PURE__ */
|
|
3768
|
+
/* @__PURE__ */ jsx7("span", { style: {
|
|
3369
3769
|
display: "inline-flex",
|
|
3370
3770
|
alignItems: "center",
|
|
3371
3771
|
justifyContent: "center",
|
|
@@ -3375,12 +3775,12 @@ function SplitCardFormInner({
|
|
|
3375
3775
|
backgroundColor: "#f3f4f6",
|
|
3376
3776
|
transition: "background-color 0.15s",
|
|
3377
3777
|
...bStyles.backButtonIcon
|
|
3378
|
-
}, children: /* @__PURE__ */
|
|
3379
|
-
/* @__PURE__ */
|
|
3778
|
+
}, 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" }) }) }),
|
|
3779
|
+
/* @__PURE__ */ jsx7(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
3380
3780
|
]
|
|
3381
3781
|
}
|
|
3382
3782
|
),
|
|
3383
|
-
hideTitle ? /* @__PURE__ */
|
|
3783
|
+
hideTitle ? /* @__PURE__ */ jsx7("div", { style: { flex: 1 } }) : /* @__PURE__ */ jsx7("div", { style: {
|
|
3384
3784
|
flex: 1,
|
|
3385
3785
|
textAlign: "center",
|
|
3386
3786
|
fontWeight: 600,
|
|
@@ -3388,58 +3788,65 @@ function SplitCardFormInner({
|
|
|
3388
3788
|
color: "#262833",
|
|
3389
3789
|
paddingRight: 80,
|
|
3390
3790
|
...bStyles.title
|
|
3391
|
-
}, children: /* @__PURE__ */
|
|
3791
|
+
}, children: /* @__PURE__ */ jsx7(TitleContentSlot, { content: cardTitleContent }) })
|
|
3392
3792
|
] }),
|
|
3393
|
-
!isButtons && !hideTitle && /* @__PURE__ */
|
|
3793
|
+
!isButtons && !hideTitle && /* @__PURE__ */ jsx7("div", { style: {
|
|
3394
3794
|
textAlign: "center",
|
|
3395
3795
|
fontWeight: 600,
|
|
3396
3796
|
fontSize: "1.1rem",
|
|
3397
3797
|
padding: "0.5rem 0",
|
|
3398
3798
|
color: resolvedTitleColor,
|
|
3799
|
+
// Keep the title at the very top on the vault path. The card-form slot
|
|
3800
|
+
// (-2) and AVS block (-1) are ordered below it but above the card form.
|
|
3801
|
+
order: vaultActive ? -3 : 0,
|
|
3399
3802
|
...bStyles.title
|
|
3400
|
-
}, children: /* @__PURE__ */
|
|
3401
|
-
/* @__PURE__ */
|
|
3402
|
-
|
|
3403
|
-
border: `1px solid ${resolvedBorder}`,
|
|
3404
|
-
borderTopLeftRadius: "8px",
|
|
3405
|
-
borderTopRightRadius: "8px",
|
|
3406
|
-
padding: "10px"
|
|
3407
|
-
}, children: /* @__PURE__ */ jsx6(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
|
|
3408
|
-
/* @__PURE__ */ jsxs4("div", { style: { display: "flex" }, children: [
|
|
3409
|
-
/* @__PURE__ */ jsx6("div", { style: {
|
|
3410
|
-
flex: 1,
|
|
3411
|
-
backgroundColor: cardInputBg,
|
|
3412
|
-
// Longhand only — mixing `border` shorthand with per-side
|
|
3413
|
-
// overrides triggers React's "shorthand vs longhand" warning
|
|
3414
|
-
// because render order isn't deterministic.
|
|
3415
|
-
borderTop: "none",
|
|
3416
|
-
borderRight: "none",
|
|
3417
|
-
borderBottom: `1px solid ${resolvedBorder}`,
|
|
3418
|
-
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3419
|
-
borderBottomLeftRadius: "8px",
|
|
3420
|
-
padding: "10px"
|
|
3421
|
-
}, children: /* @__PURE__ */ jsx6(CardExpiryElement, { options: stripeElementStyle }) }),
|
|
3422
|
-
/* @__PURE__ */ jsx6("div", { style: {
|
|
3423
|
-
flex: 1,
|
|
3803
|
+
}, children: /* @__PURE__ */ jsx7(TitleContentSlot, { content: cardTitleContent }) }),
|
|
3804
|
+
!vaultActive && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
3805
|
+
/* @__PURE__ */ jsx7("div", { style: {
|
|
3424
3806
|
backgroundColor: cardInputBg,
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3429
|
-
borderBottomRightRadius: "8px",
|
|
3807
|
+
border: `1px solid ${resolvedBorder}`,
|
|
3808
|
+
borderTopLeftRadius: resolvedBorderRadius,
|
|
3809
|
+
borderTopRightRadius: resolvedBorderRadius,
|
|
3430
3810
|
padding: "10px"
|
|
3431
|
-
}, children: /* @__PURE__ */
|
|
3811
|
+
}, children: /* @__PURE__ */ jsx7(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
|
|
3812
|
+
/* @__PURE__ */ jsxs4("div", { style: { display: "flex" }, children: [
|
|
3813
|
+
/* @__PURE__ */ jsx7("div", { style: {
|
|
3814
|
+
flex: 1,
|
|
3815
|
+
backgroundColor: cardInputBg,
|
|
3816
|
+
// Longhand only — mixing `border` shorthand with per-side
|
|
3817
|
+
// overrides triggers React's "shorthand vs longhand" warning
|
|
3818
|
+
// because render order isn't deterministic.
|
|
3819
|
+
borderTop: "none",
|
|
3820
|
+
borderRight: "none",
|
|
3821
|
+
borderBottom: `1px solid ${resolvedBorder}`,
|
|
3822
|
+
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3823
|
+
borderBottomLeftRadius: resolvedBorderRadius,
|
|
3824
|
+
padding: "10px"
|
|
3825
|
+
}, children: /* @__PURE__ */ jsx7(CardExpiryElement, { options: stripeElementStyle }) }),
|
|
3826
|
+
/* @__PURE__ */ jsx7("div", { style: {
|
|
3827
|
+
flex: 1,
|
|
3828
|
+
backgroundColor: cardInputBg,
|
|
3829
|
+
borderTop: "none",
|
|
3830
|
+
borderRight: `1px solid ${resolvedBorder}`,
|
|
3831
|
+
borderBottom: `1px solid ${resolvedBorder}`,
|
|
3832
|
+
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3833
|
+
borderBottomRightRadius: resolvedBorderRadius,
|
|
3834
|
+
padding: "10px"
|
|
3835
|
+
}, children: /* @__PURE__ */ jsx7(CardCvcElement, { options: stripeElementStyle }) })
|
|
3836
|
+
] })
|
|
3432
3837
|
] }),
|
|
3433
|
-
/* @__PURE__ */
|
|
3838
|
+
!vaultActive && /* @__PURE__ */ jsx7("div", { style: {
|
|
3434
3839
|
backgroundColor: cardInputBg,
|
|
3435
3840
|
border: `1px solid ${resolvedBorder}`,
|
|
3436
|
-
borderRadius:
|
|
3841
|
+
borderRadius: resolvedBorderRadius,
|
|
3437
3842
|
marginTop: "0.5rem",
|
|
3438
3843
|
padding: "10px"
|
|
3439
|
-
}, children: /* @__PURE__ */
|
|
3844
|
+
}, children: /* @__PURE__ */ jsx7(
|
|
3440
3845
|
"input",
|
|
3441
3846
|
{
|
|
3442
3847
|
className: "flopay-shared-input",
|
|
3848
|
+
id: "flopay-cc-name",
|
|
3849
|
+
name: "cc-name",
|
|
3443
3850
|
placeholder: "Full Name on Card",
|
|
3444
3851
|
autoComplete: "cc-name",
|
|
3445
3852
|
value: fullName,
|
|
@@ -3456,32 +3863,32 @@ function SplitCardFormInner({
|
|
|
3456
3863
|
}
|
|
3457
3864
|
}
|
|
3458
3865
|
) }),
|
|
3459
|
-
avsConfig && (() => {
|
|
3866
|
+
avsConfig && /* @__PURE__ */ jsx7("div", { style: { order: vaultActive ? -1 : 0 }, "data-testid": "flopay-avs-fields", children: (() => {
|
|
3460
3867
|
const cc = selectedCountry;
|
|
3461
|
-
const inputWrapStyle = (
|
|
3868
|
+
const inputWrapStyle = (invalid = false) => ({
|
|
3462
3869
|
backgroundColor: cardInputBg,
|
|
3463
|
-
border: `1px solid ${
|
|
3464
|
-
borderRadius:
|
|
3870
|
+
border: `1px solid ${avsBorderColor(invalid)}`,
|
|
3871
|
+
borderRadius: resolvedBorderRadius,
|
|
3465
3872
|
marginTop: "0.5rem",
|
|
3466
|
-
padding: "10px"
|
|
3467
|
-
...isButtons && extraStyle ? extraStyle : {}
|
|
3873
|
+
padding: "10px"
|
|
3468
3874
|
});
|
|
3469
3875
|
const inputFieldStyle = () => ({
|
|
3470
3876
|
width: "100%",
|
|
3471
3877
|
border: "none",
|
|
3472
3878
|
outline: "none",
|
|
3473
3879
|
background: "transparent",
|
|
3474
|
-
...sharedInputTypography
|
|
3475
|
-
...isButtons && bStyles.nameInput ? bStyles.nameInput : {}
|
|
3880
|
+
...sharedInputTypography
|
|
3476
3881
|
});
|
|
3477
3882
|
const stateOpts = getStateOptions(cc);
|
|
3478
3883
|
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
3479
|
-
isAVSFieldVisible(avsConfig.address_line_1, cc) && /* @__PURE__ */
|
|
3884
|
+
isAVSFieldVisible(avsConfig.address_line_1, cc) && /* @__PURE__ */ jsx7("div", { style: inputWrapStyle(invalidAvsFields.line1), children: /* @__PURE__ */ jsx7(
|
|
3480
3885
|
"input",
|
|
3481
3886
|
{
|
|
3482
3887
|
className: "flopay-shared-input",
|
|
3888
|
+
id: "flopay-billing-address-line1",
|
|
3889
|
+
name: "billing-address-line1",
|
|
3483
3890
|
placeholder: "Street Address (e.g. 123 Main St)",
|
|
3484
|
-
autoComplete: "address-line1",
|
|
3891
|
+
autoComplete: "billing address-line1",
|
|
3485
3892
|
value: addressLine1,
|
|
3486
3893
|
onChange: (e) => {
|
|
3487
3894
|
addressLine1Ref.current = e.target.value;
|
|
@@ -3493,12 +3900,14 @@ function SplitCardFormInner({
|
|
|
3493
3900
|
style: inputFieldStyle()
|
|
3494
3901
|
}
|
|
3495
3902
|
) }),
|
|
3496
|
-
isAVSFieldVisible(avsConfig.address_line_2, cc) && /* @__PURE__ */
|
|
3903
|
+
isAVSFieldVisible(avsConfig.address_line_2, cc) && /* @__PURE__ */ jsx7("div", { style: inputWrapStyle(), children: /* @__PURE__ */ jsx7(
|
|
3497
3904
|
"input",
|
|
3498
3905
|
{
|
|
3499
3906
|
className: "flopay-shared-input",
|
|
3907
|
+
id: "flopay-billing-address-line2",
|
|
3908
|
+
name: "billing-address-line2",
|
|
3500
3909
|
placeholder: "Apt, Suite, Unit (optional)",
|
|
3501
|
-
autoComplete: "address-line2",
|
|
3910
|
+
autoComplete: "billing address-line2",
|
|
3502
3911
|
value: addressLine2,
|
|
3503
3912
|
onChange: (e) => {
|
|
3504
3913
|
addressLine2Ref.current = e.target.value;
|
|
@@ -3514,24 +3923,25 @@ function SplitCardFormInner({
|
|
|
3514
3923
|
gap: "0",
|
|
3515
3924
|
marginTop: "0.5rem"
|
|
3516
3925
|
}, children: [
|
|
3517
|
-
isAVSFieldVisible(avsConfig.city, cc) && /* @__PURE__ */
|
|
3926
|
+
isAVSFieldVisible(avsConfig.city, cc) && /* @__PURE__ */ jsx7("div", { style: {
|
|
3518
3927
|
flex: 1,
|
|
3519
3928
|
backgroundColor: cardInputBg,
|
|
3520
|
-
borderTop: `1px solid ${
|
|
3521
|
-
borderRight: `1px solid ${
|
|
3522
|
-
borderBottom: `1px solid ${
|
|
3523
|
-
borderLeft: `1px solid ${
|
|
3929
|
+
borderTop: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,
|
|
3930
|
+
borderRight: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,
|
|
3931
|
+
borderBottom: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,
|
|
3932
|
+
borderLeft: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,
|
|
3524
3933
|
padding: "10px",
|
|
3525
|
-
borderTopLeftRadius:
|
|
3526
|
-
borderBottomLeftRadius:
|
|
3527
|
-
...isAVSFieldVisible(avsConfig.state, cc) ? { borderRight: "none", borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius:
|
|
3528
|
-
|
|
3529
|
-
}, children: /* @__PURE__ */ jsx6(
|
|
3934
|
+
borderTopLeftRadius: resolvedBorderRadius,
|
|
3935
|
+
borderBottomLeftRadius: resolvedBorderRadius,
|
|
3936
|
+
...isAVSFieldVisible(avsConfig.state, cc) ? { borderRight: "none", borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius: resolvedBorderRadius }
|
|
3937
|
+
}, children: /* @__PURE__ */ jsx7(
|
|
3530
3938
|
"input",
|
|
3531
3939
|
{
|
|
3532
3940
|
className: "flopay-shared-input",
|
|
3941
|
+
id: "flopay-billing-city",
|
|
3942
|
+
name: "billing-city",
|
|
3533
3943
|
placeholder: "City",
|
|
3534
|
-
autoComplete: "address-level2",
|
|
3944
|
+
autoComplete: "billing address-level2",
|
|
3535
3945
|
value: city,
|
|
3536
3946
|
onChange: (e) => {
|
|
3537
3947
|
cityRef.current = e.target.value;
|
|
@@ -3543,39 +3953,42 @@ function SplitCardFormInner({
|
|
|
3543
3953
|
style: inputFieldStyle()
|
|
3544
3954
|
}
|
|
3545
3955
|
) }),
|
|
3546
|
-
isAVSFieldVisible(avsConfig.state, cc) && /* @__PURE__ */
|
|
3956
|
+
isAVSFieldVisible(avsConfig.state, cc) && /* @__PURE__ */ jsx7("div", { style: {
|
|
3547
3957
|
flex: 1,
|
|
3548
3958
|
backgroundColor: cardInputBg,
|
|
3549
|
-
border: `1px solid ${
|
|
3959
|
+
border: `1px solid ${avsBorderColor(invalidAvsFields.state)}`,
|
|
3550
3960
|
padding: "10px",
|
|
3551
|
-
borderTopRightRadius:
|
|
3552
|
-
borderBottomRightRadius:
|
|
3553
|
-
...isAVSFieldVisible(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius:
|
|
3554
|
-
...isButtons && bStyles.stateInput ? bStyles.stateInput : {}
|
|
3961
|
+
borderTopRightRadius: resolvedBorderRadius,
|
|
3962
|
+
borderBottomRightRadius: resolvedBorderRadius,
|
|
3963
|
+
...isAVSFieldVisible(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius: resolvedBorderRadius }
|
|
3555
3964
|
}, children: stateOpts ? /* @__PURE__ */ jsxs4(
|
|
3556
3965
|
"select",
|
|
3557
3966
|
{
|
|
3967
|
+
id: "flopay-billing-state",
|
|
3968
|
+
name: "billing-state",
|
|
3558
3969
|
value: stateValue,
|
|
3559
3970
|
onChange: (e) => {
|
|
3560
3971
|
stateRef.current = e.target.value;
|
|
3561
3972
|
setStateValue(e.target.value);
|
|
3562
3973
|
},
|
|
3563
3974
|
disabled: isSubmitting,
|
|
3564
|
-
autoComplete: "address-level1",
|
|
3975
|
+
autoComplete: "billing address-level1",
|
|
3565
3976
|
required: true,
|
|
3566
3977
|
"data-testid": "flopay-state",
|
|
3567
3978
|
style: { ...inputFieldStyle(), cursor: "pointer" },
|
|
3568
3979
|
children: [
|
|
3569
|
-
/* @__PURE__ */
|
|
3570
|
-
stateOpts.map((s) => /* @__PURE__ */
|
|
3980
|
+
/* @__PURE__ */ jsx7("option", { value: "", children: getStateLabel(cc) }),
|
|
3981
|
+
stateOpts.map((s) => /* @__PURE__ */ jsx7("option", { value: s.code, children: s.name }, s.code))
|
|
3571
3982
|
]
|
|
3572
3983
|
}
|
|
3573
|
-
) : /* @__PURE__ */
|
|
3984
|
+
) : /* @__PURE__ */ jsx7(
|
|
3574
3985
|
"input",
|
|
3575
3986
|
{
|
|
3576
3987
|
className: "flopay-shared-input",
|
|
3988
|
+
id: "flopay-billing-state",
|
|
3989
|
+
name: "billing-state",
|
|
3577
3990
|
placeholder: getStateLabel(cc),
|
|
3578
|
-
autoComplete: "address-level1",
|
|
3991
|
+
autoComplete: "billing address-level1",
|
|
3579
3992
|
value: stateValue,
|
|
3580
3993
|
onChange: (e) => {
|
|
3581
3994
|
stateRef.current = e.target.value;
|
|
@@ -3594,7 +4007,7 @@ function SplitCardFormInner({
|
|
|
3594
4007
|
gap: avsLayoutProp === "column" ? "0.5rem" : "0",
|
|
3595
4008
|
marginTop: "0.5rem"
|
|
3596
4009
|
}, children: [
|
|
3597
|
-
isAVSFieldVisible(avsConfig.country, cc) && /* @__PURE__ */
|
|
4010
|
+
isAVSFieldVisible(avsConfig.country, cc) && /* @__PURE__ */ jsx7("div", { style: {
|
|
3598
4011
|
flex: avsLayoutProp === "row" ? 1 : void 0,
|
|
3599
4012
|
backgroundColor: cardInputBg,
|
|
3600
4013
|
borderTop: `1px solid ${resolvedBorder}`,
|
|
@@ -3602,11 +4015,12 @@ function SplitCardFormInner({
|
|
|
3602
4015
|
borderBottom: `1px solid ${resolvedBorder}`,
|
|
3603
4016
|
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3604
4017
|
padding: "10px",
|
|
3605
|
-
...avsLayoutProp === "row" && isAVSFieldVisible(avsConfig.postal_code, cc) ? { borderRadius: "0", borderTopLeftRadius:
|
|
3606
|
-
|
|
3607
|
-
}, children: /* @__PURE__ */ jsx6(
|
|
4018
|
+
...avsLayoutProp === "row" && isAVSFieldVisible(avsConfig.postal_code, cc) ? { borderRadius: "0", borderTopLeftRadius: resolvedBorderRadius, borderBottomLeftRadius: resolvedBorderRadius, borderRight: "none" } : { borderRadius: resolvedBorderRadius }
|
|
4019
|
+
}, children: /* @__PURE__ */ jsx7(
|
|
3608
4020
|
"select",
|
|
3609
4021
|
{
|
|
4022
|
+
id: "flopay-billing-country",
|
|
4023
|
+
name: "billing-country",
|
|
3610
4024
|
value: selectedCountry,
|
|
3611
4025
|
onChange: (e) => {
|
|
3612
4026
|
selectedCountryRef.current = e.target.value;
|
|
@@ -3616,7 +4030,7 @@ function SplitCardFormInner({
|
|
|
3616
4030
|
setStateValue("");
|
|
3617
4031
|
},
|
|
3618
4032
|
disabled: isSubmitting,
|
|
3619
|
-
autoComplete: "country",
|
|
4033
|
+
autoComplete: "billing country",
|
|
3620
4034
|
"data-testid": "flopay-country",
|
|
3621
4035
|
style: { ...inputFieldStyle(), cursor: "pointer" },
|
|
3622
4036
|
children: COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ jsxs4("option", { value: c.code, children: [
|
|
@@ -3626,19 +4040,20 @@ function SplitCardFormInner({
|
|
|
3626
4040
|
] }, c.code))
|
|
3627
4041
|
}
|
|
3628
4042
|
) }),
|
|
3629
|
-
isAVSFieldVisible(avsConfig.postal_code, cc) && /* @__PURE__ */
|
|
4043
|
+
isAVSFieldVisible(avsConfig.postal_code, cc) && /* @__PURE__ */ jsx7("div", { style: {
|
|
3630
4044
|
flex: avsLayoutProp === "row" ? 1 : void 0,
|
|
3631
4045
|
backgroundColor: cardInputBg,
|
|
3632
|
-
border: `1px solid ${
|
|
4046
|
+
border: `1px solid ${avsBorderColor(invalidAvsFields.zip)}`,
|
|
3633
4047
|
padding: "10px",
|
|
3634
|
-
...avsLayoutProp === "row" && isAVSFieldVisible(avsConfig.country, cc) ? { borderRadius: "0", borderTopRightRadius:
|
|
3635
|
-
|
|
3636
|
-
}, children: /* @__PURE__ */ jsx6(
|
|
4048
|
+
...avsLayoutProp === "row" && isAVSFieldVisible(avsConfig.country, cc) ? { borderRadius: "0", borderTopRightRadius: resolvedBorderRadius, borderBottomRightRadius: resolvedBorderRadius } : { borderRadius: resolvedBorderRadius }
|
|
4049
|
+
}, children: /* @__PURE__ */ jsx7(
|
|
3637
4050
|
"input",
|
|
3638
4051
|
{
|
|
3639
4052
|
className: "flopay-shared-input",
|
|
4053
|
+
id: "flopay-billing-postal-code",
|
|
4054
|
+
name: "billing-postal-code",
|
|
3640
4055
|
placeholder: getPostalCodeLabel(selectedCountry),
|
|
3641
|
-
autoComplete: "postal-code",
|
|
4056
|
+
autoComplete: "billing postal-code",
|
|
3642
4057
|
value: zipCode,
|
|
3643
4058
|
onChange: (e) => {
|
|
3644
4059
|
zipCodeRef.current = e.target.value;
|
|
@@ -3653,7 +4068,9 @@ function SplitCardFormInner({
|
|
|
3653
4068
|
) })
|
|
3654
4069
|
] })
|
|
3655
4070
|
] });
|
|
3656
|
-
})(),
|
|
4071
|
+
})() }),
|
|
4072
|
+
vaultActive && cardPreFormSlot && /* @__PURE__ */ jsx7("div", { style: { order: -2, width: "100%" }, children: cardPreFormSlot }),
|
|
4073
|
+
vaultActive && vaultCardFieldsNode,
|
|
3657
4074
|
displayError && /* @__PURE__ */ jsxs4("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
3658
4075
|
margin: "0.75rem 0",
|
|
3659
4076
|
padding: "0.625rem 0.875rem",
|
|
@@ -3668,15 +4085,21 @@ function SplitCardFormInner({
|
|
|
3668
4085
|
gap: "0.5rem",
|
|
3669
4086
|
...bStyles.errorBanner ? bStyles.errorBanner : {}
|
|
3670
4087
|
}, children: [
|
|
3671
|
-
/* @__PURE__ */
|
|
4088
|
+
/* @__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" }) }),
|
|
3672
4089
|
displayError
|
|
3673
4090
|
] }),
|
|
3674
|
-
children ?? /* @__PURE__ */
|
|
4091
|
+
!vaultActive && (children ?? /* @__PURE__ */ jsx7(
|
|
3675
4092
|
"button",
|
|
3676
4093
|
{
|
|
3677
4094
|
type: "submit",
|
|
3678
4095
|
disabled: !formReady || isSubmitting,
|
|
3679
4096
|
"data-testid": "flopay-submit",
|
|
4097
|
+
onMouseEnter: (e) => {
|
|
4098
|
+
if (formReady && !isSubmitting) e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;
|
|
4099
|
+
},
|
|
4100
|
+
onMouseLeave: (e) => {
|
|
4101
|
+
e.currentTarget.style.backgroundColor = bStyles.submitButton?.backgroundColor ?? resolvedPrimaryColor;
|
|
4102
|
+
},
|
|
3680
4103
|
style: {
|
|
3681
4104
|
width: "100%",
|
|
3682
4105
|
padding: "0.875rem",
|
|
@@ -3689,11 +4112,12 @@ function SplitCardFormInner({
|
|
|
3689
4112
|
fontWeight: 600,
|
|
3690
4113
|
cursor: !formReady || isSubmitting ? "not-allowed" : "pointer",
|
|
3691
4114
|
opacity: !formReady || isSubmitting ? 0.5 : 1,
|
|
4115
|
+
transition: "background-color 0.15s",
|
|
3692
4116
|
...bStyles.submitButton
|
|
3693
4117
|
},
|
|
3694
4118
|
children: isSubmitting ? "PROCESSING..." : submitLabel
|
|
3695
4119
|
}
|
|
3696
|
-
)
|
|
4120
|
+
))
|
|
3697
4121
|
] });
|
|
3698
4122
|
const gateDebugStyle = {
|
|
3699
4123
|
margin: 0,
|
|
@@ -3709,9 +4133,9 @@ function SplitCardFormInner({
|
|
|
3709
4133
|
const renderDirectPaypalGateDebug = (testId) => {
|
|
3710
4134
|
if (!debug) return null;
|
|
3711
4135
|
if (!showPayPal || !directPaypalConfigured) {
|
|
3712
|
-
return /* @__PURE__ */
|
|
4136
|
+
return /* @__PURE__ */ jsx7("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/DirectPayPal-debug - not enabled" });
|
|
3713
4137
|
}
|
|
3714
|
-
return /* @__PURE__ */
|
|
4138
|
+
return /* @__PURE__ */ jsx7("pre", { "data-testid": testId, style: gateDebugStyle, children: [
|
|
3715
4139
|
"FloPay/DirectPayPal-debug (parent gate)",
|
|
3716
4140
|
` showPayPal=${showPayPal}`,
|
|
3717
4141
|
` directPaypalConfigured=${directPaypalConfigured}`,
|
|
@@ -3724,9 +4148,9 @@ function SplitCardFormInner({
|
|
|
3724
4148
|
const renderStripeGateDebug = (testId) => {
|
|
3725
4149
|
if (!debug) return null;
|
|
3726
4150
|
if (!showStripe || !stripeInstance) {
|
|
3727
|
-
return /* @__PURE__ */
|
|
4151
|
+
return /* @__PURE__ */ jsx7("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/Stripe-debug - not enabled" });
|
|
3728
4152
|
}
|
|
3729
|
-
return /* @__PURE__ */
|
|
4153
|
+
return /* @__PURE__ */ jsx7("pre", { "data-testid": testId, style: gateDebugStyle, children: [
|
|
3730
4154
|
"FloPay/Stripe-debug (parent gate)",
|
|
3731
4155
|
` showStripe=${showStripe}`,
|
|
3732
4156
|
` currency=${currency}`,
|
|
@@ -3756,8 +4180,8 @@ function SplitCardFormInner({
|
|
|
3756
4180
|
const buttonsAnim = viewState === "expanding" || viewState === "apm-expanding" ? `flopay-buttons-exit ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1) both` : viewState === "collapsing" || viewState === "apm-collapsing" ? `flopay-buttons-enter ${TRANSITION_MS}ms cubic-bezier(0, 0, 0.2, 1) both` : void 0;
|
|
3757
4181
|
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;
|
|
3758
4182
|
return /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
3759
|
-
/* @__PURE__ */
|
|
3760
|
-
overlayStatus && /* @__PURE__ */
|
|
4183
|
+
/* @__PURE__ */ jsx7(FloPayKeyframes, {}),
|
|
4184
|
+
overlayStatus && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
3761
4185
|
/* @__PURE__ */ jsxs4("div", { style: { display: "grid" }, children: [
|
|
3762
4186
|
/* @__PURE__ */ jsxs4(
|
|
3763
4187
|
"div",
|
|
@@ -3777,7 +4201,7 @@ function SplitCardFormInner({
|
|
|
3777
4201
|
renderDirectPaypalGateDebug("flopay-direct-paypal-gate-debug"),
|
|
3778
4202
|
renderStripeGateDebug("flopay-stripe-gate-debug"),
|
|
3779
4203
|
shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
3780
|
-
paypalDirectRetry && /* @__PURE__ */
|
|
4204
|
+
paypalDirectRetry && /* @__PURE__ */ jsx7(
|
|
3781
4205
|
"div",
|
|
3782
4206
|
{
|
|
3783
4207
|
"data-testid": "flopay-paypal-direct-retry-notice",
|
|
@@ -3793,7 +4217,7 @@ function SplitCardFormInner({
|
|
|
3793
4217
|
children: "Please confirm your PayPal payment to complete checkout."
|
|
3794
4218
|
}
|
|
3795
4219
|
),
|
|
3796
|
-
/* @__PURE__ */
|
|
4220
|
+
/* @__PURE__ */ jsx7(
|
|
3797
4221
|
DirectPayPalButton,
|
|
3798
4222
|
{
|
|
3799
4223
|
sessionId,
|
|
@@ -3819,7 +4243,7 @@ function SplitCardFormInner({
|
|
|
3819
4243
|
paypalDirectRetry?.orderId ?? "fresh"
|
|
3820
4244
|
)
|
|
3821
4245
|
] }),
|
|
3822
|
-
shouldRenderStripePayPal && /* @__PURE__ */
|
|
4246
|
+
shouldRenderStripePayPal && /* @__PURE__ */ jsx7(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx7(
|
|
3823
4247
|
PayPalButtonInner,
|
|
3824
4248
|
{
|
|
3825
4249
|
sessionId,
|
|
@@ -3833,10 +4257,10 @@ function SplitCardFormInner({
|
|
|
3833
4257
|
onDecline,
|
|
3834
4258
|
runBeforeButtonClick,
|
|
3835
4259
|
onLoadStateChange: setPaypalLoadState,
|
|
3836
|
-
placeholderBorderRadius:
|
|
4260
|
+
placeholderBorderRadius: buttonBorderRadius
|
|
3837
4261
|
}
|
|
3838
4262
|
) }),
|
|
3839
|
-
shouldRenderWallets ? /* @__PURE__ */
|
|
4263
|
+
shouldRenderWallets ? /* @__PURE__ */ jsx7(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx7(
|
|
3840
4264
|
WalletButtonInner,
|
|
3841
4265
|
{
|
|
3842
4266
|
sessionId,
|
|
@@ -3850,10 +4274,10 @@ function SplitCardFormInner({
|
|
|
3850
4274
|
onDecline,
|
|
3851
4275
|
runBeforeButtonClick,
|
|
3852
4276
|
onLoadStateChange: setWalletLoadState,
|
|
3853
|
-
placeholderBorderRadius:
|
|
4277
|
+
placeholderBorderRadius: buttonBorderRadius
|
|
3854
4278
|
}
|
|
3855
|
-
) }) : shouldShowWallets ? /* @__PURE__ */
|
|
3856
|
-
shouldRenderPaymentElement && /* @__PURE__ */
|
|
4279
|
+
) }) : shouldShowWallets ? /* @__PURE__ */ jsx7("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: buttonBorderRadius, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
|
|
4280
|
+
shouldRenderPaymentElement && /* @__PURE__ */ jsx7(
|
|
3857
4281
|
StripePaymentElementInner,
|
|
3858
4282
|
{
|
|
3859
4283
|
sessionId,
|
|
@@ -3881,11 +4305,11 @@ function SplitCardFormInner({
|
|
|
3881
4305
|
backgroundColor: bStyles.cardButton?.backgroundColor,
|
|
3882
4306
|
borderColor: bStyles.cardInputBorder,
|
|
3883
4307
|
textColor: bStyles.cardButton?.color,
|
|
3884
|
-
borderRadius:
|
|
4308
|
+
borderRadius: buttonBorderRadius
|
|
3885
4309
|
}
|
|
3886
4310
|
}
|
|
3887
4311
|
),
|
|
3888
|
-
showStripe && /* @__PURE__ */
|
|
4312
|
+
showStripe && /* @__PURE__ */ jsx7(
|
|
3889
4313
|
"button",
|
|
3890
4314
|
{
|
|
3891
4315
|
type: "button",
|
|
@@ -3913,7 +4337,8 @@ function SplitCardFormInner({
|
|
|
3913
4337
|
themeBundle,
|
|
3914
4338
|
resolvedPrimaryColor,
|
|
3915
4339
|
resolvedBorderRadius,
|
|
3916
|
-
submitButtonStyle: bStyles.submitButton
|
|
4340
|
+
submitButtonStyle: bStyles.submitButton,
|
|
4341
|
+
explicitPrimaryColor: appearanceVars?.colorPrimary
|
|
3917
4342
|
}),
|
|
3918
4343
|
fontSize: bStyles.cardButtonFontSize ?? "0.95rem",
|
|
3919
4344
|
fontWeight: 600,
|
|
@@ -3922,17 +4347,25 @@ function SplitCardFormInner({
|
|
|
3922
4347
|
alignItems: "center",
|
|
3923
4348
|
justifyContent: "center",
|
|
3924
4349
|
gap: "0.625rem",
|
|
3925
|
-
transition: "border-color 0.2s, box-shadow 0.2s, transform 0.1s",
|
|
4350
|
+
transition: "background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s",
|
|
3926
4351
|
position: "relative",
|
|
3927
4352
|
opacity: isSubmitting ? 0.6 : 1
|
|
3928
4353
|
},
|
|
4354
|
+
onMouseEnter: (e) => {
|
|
4355
|
+
if (!isSubmitting && (themeBundle || appearanceVars?.colorPrimary)) {
|
|
4356
|
+
e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;
|
|
4357
|
+
}
|
|
4358
|
+
},
|
|
4359
|
+
onMouseLeave: (e) => {
|
|
4360
|
+
if (themeBundle || appearanceVars?.colorPrimary) e.currentTarget.style.backgroundColor = resolvedPrimaryColor;
|
|
4361
|
+
},
|
|
3929
4362
|
onMouseDown: (e) => {
|
|
3930
4363
|
e.currentTarget.style.transform = "scale(0.985)";
|
|
3931
4364
|
},
|
|
3932
4365
|
onMouseUp: (e) => {
|
|
3933
4366
|
e.currentTarget.style.transform = "scale(1)";
|
|
3934
4367
|
},
|
|
3935
|
-
children: /* @__PURE__ */
|
|
4368
|
+
children: /* @__PURE__ */ jsx7(CardButtonContentSlot, { content: cardButtonContent })
|
|
3936
4369
|
}
|
|
3937
4370
|
),
|
|
3938
4371
|
displayError && viewState === "buttons" && /* @__PURE__ */ jsxs4("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
@@ -3949,18 +4382,18 @@ function SplitCardFormInner({
|
|
|
3949
4382
|
gap: "0.5rem",
|
|
3950
4383
|
...bStyles.errorBanner ? bStyles.errorBanner : {}
|
|
3951
4384
|
}, children: [
|
|
3952
|
-
/* @__PURE__ */
|
|
4385
|
+
/* @__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" }) }),
|
|
3953
4386
|
displayError
|
|
3954
4387
|
] })
|
|
3955
4388
|
]
|
|
3956
4389
|
}
|
|
3957
4390
|
),
|
|
3958
|
-
showStripe && isCardView && /* @__PURE__ */
|
|
4391
|
+
showStripe && isCardView && /* @__PURE__ */ jsx7("div", { style: {
|
|
3959
4392
|
gridArea: "1 / 1",
|
|
3960
4393
|
...cardAnim ? { animation: cardAnim } : {},
|
|
3961
4394
|
...viewState === "collapsing" ? { pointerEvents: "none" } : {}
|
|
3962
4395
|
}, children: cardFormBlock }),
|
|
3963
|
-
showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && /* @__PURE__ */
|
|
4396
|
+
showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && /* @__PURE__ */ jsx7("div", { style: {
|
|
3964
4397
|
gridArea: "1 / 1",
|
|
3965
4398
|
...apmAnim ? { animation: apmAnim } : {},
|
|
3966
4399
|
...viewState === "apm-collapsing" ? { pointerEvents: "none" } : {}
|
|
@@ -3998,7 +4431,7 @@ function SplitCardFormInner({
|
|
|
3998
4431
|
},
|
|
3999
4432
|
"aria-label": "Back to payment methods",
|
|
4000
4433
|
children: [
|
|
4001
|
-
/* @__PURE__ */
|
|
4434
|
+
/* @__PURE__ */ jsx7("span", { style: {
|
|
4002
4435
|
display: "inline-flex",
|
|
4003
4436
|
alignItems: "center",
|
|
4004
4437
|
justifyContent: "center",
|
|
@@ -4008,12 +4441,12 @@ function SplitCardFormInner({
|
|
|
4008
4441
|
backgroundColor: "#f3f4f6",
|
|
4009
4442
|
transition: "background-color 0.15s",
|
|
4010
4443
|
...bStyles.backButtonIcon
|
|
4011
|
-
}, children: /* @__PURE__ */
|
|
4012
|
-
/* @__PURE__ */
|
|
4444
|
+
}, 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" }) }) }),
|
|
4445
|
+
/* @__PURE__ */ jsx7(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
4013
4446
|
]
|
|
4014
4447
|
}
|
|
4015
4448
|
),
|
|
4016
|
-
/* @__PURE__ */
|
|
4449
|
+
/* @__PURE__ */ jsx7("div", { style: {
|
|
4017
4450
|
flex: 1,
|
|
4018
4451
|
textAlign: "center",
|
|
4019
4452
|
fontWeight: 600,
|
|
@@ -4023,12 +4456,12 @@ function SplitCardFormInner({
|
|
|
4023
4456
|
...bStyles.title
|
|
4024
4457
|
}, children: `Pay with ${getStripeMethodDisplayName(expandedApmMethod)}` })
|
|
4025
4458
|
] }),
|
|
4026
|
-
/* @__PURE__ */
|
|
4459
|
+
/* @__PURE__ */ jsx7(
|
|
4027
4460
|
StripeElements,
|
|
4028
4461
|
{
|
|
4029
4462
|
stripe: stripeInstance,
|
|
4030
4463
|
options: apmInlineOptions,
|
|
4031
|
-
children: /* @__PURE__ */
|
|
4464
|
+
children: /* @__PURE__ */ jsx7(
|
|
4032
4465
|
StripeMethodInlineForm,
|
|
4033
4466
|
{
|
|
4034
4467
|
method: expandedApmMethod,
|
|
@@ -4046,7 +4479,8 @@ function SplitCardFormInner({
|
|
|
4046
4479
|
isProcessing: isSubmitting,
|
|
4047
4480
|
submitButtonColor: resolvedPrimaryColor,
|
|
4048
4481
|
submitButtonBorderRadius: resolvedBorderRadius,
|
|
4049
|
-
submitButtonStyle: bStyles.submitButton
|
|
4482
|
+
submitButtonStyle: bStyles.submitButton,
|
|
4483
|
+
errorText: displayError
|
|
4050
4484
|
}
|
|
4051
4485
|
)
|
|
4052
4486
|
},
|
|
@@ -4058,9 +4492,9 @@ function SplitCardFormInner({
|
|
|
4058
4492
|
}
|
|
4059
4493
|
if (isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && showStripe) {
|
|
4060
4494
|
return /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
4061
|
-
/* @__PURE__ */
|
|
4062
|
-
overlayStatus && /* @__PURE__ */
|
|
4063
|
-
/* @__PURE__ */
|
|
4495
|
+
/* @__PURE__ */ jsx7(FloPayKeyframes, {}),
|
|
4496
|
+
overlayStatus && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
4497
|
+
/* @__PURE__ */ jsx7("div", { style: {
|
|
4064
4498
|
...apmAnim ? { animation: apmAnim } : {},
|
|
4065
4499
|
...viewState === "apm-collapsing" ? { pointerEvents: "none" } : {}
|
|
4066
4500
|
}, children: /* @__PURE__ */ jsxs4("div", { style: {
|
|
@@ -4097,7 +4531,7 @@ function SplitCardFormInner({
|
|
|
4097
4531
|
},
|
|
4098
4532
|
"aria-label": "Back to payment methods",
|
|
4099
4533
|
children: [
|
|
4100
|
-
/* @__PURE__ */
|
|
4534
|
+
/* @__PURE__ */ jsx7("span", { style: {
|
|
4101
4535
|
display: "inline-flex",
|
|
4102
4536
|
alignItems: "center",
|
|
4103
4537
|
justifyContent: "center",
|
|
@@ -4107,12 +4541,12 @@ function SplitCardFormInner({
|
|
|
4107
4541
|
backgroundColor: "#f3f4f6",
|
|
4108
4542
|
transition: "background-color 0.15s",
|
|
4109
4543
|
...bStyles.backButtonIcon
|
|
4110
|
-
}, children: /* @__PURE__ */
|
|
4111
|
-
/* @__PURE__ */
|
|
4544
|
+
}, 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" }) }) }),
|
|
4545
|
+
/* @__PURE__ */ jsx7(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
4112
4546
|
]
|
|
4113
4547
|
}
|
|
4114
4548
|
),
|
|
4115
|
-
/* @__PURE__ */
|
|
4549
|
+
/* @__PURE__ */ jsx7("div", { style: {
|
|
4116
4550
|
flex: 1,
|
|
4117
4551
|
textAlign: "center",
|
|
4118
4552
|
fontWeight: 600,
|
|
@@ -4122,12 +4556,12 @@ function SplitCardFormInner({
|
|
|
4122
4556
|
...bStyles.title
|
|
4123
4557
|
}, children: `Pay with ${getStripeMethodDisplayName(expandedApmMethod)}` })
|
|
4124
4558
|
] }),
|
|
4125
|
-
/* @__PURE__ */
|
|
4559
|
+
/* @__PURE__ */ jsx7(
|
|
4126
4560
|
StripeElements,
|
|
4127
4561
|
{
|
|
4128
4562
|
stripe: stripeInstance,
|
|
4129
4563
|
options: apmInlineOptions,
|
|
4130
|
-
children: /* @__PURE__ */
|
|
4564
|
+
children: /* @__PURE__ */ jsx7(
|
|
4131
4565
|
StripeMethodInlineForm,
|
|
4132
4566
|
{
|
|
4133
4567
|
method: expandedApmMethod,
|
|
@@ -4145,7 +4579,8 @@ function SplitCardFormInner({
|
|
|
4145
4579
|
isProcessing: isSubmitting,
|
|
4146
4580
|
submitButtonColor: resolvedPrimaryColor,
|
|
4147
4581
|
submitButtonBorderRadius: resolvedBorderRadius,
|
|
4148
|
-
submitButtonStyle: bStyles.submitButton
|
|
4582
|
+
submitButtonStyle: bStyles.submitButton,
|
|
4583
|
+
errorText: displayError
|
|
4149
4584
|
}
|
|
4150
4585
|
)
|
|
4151
4586
|
},
|
|
@@ -4155,13 +4590,13 @@ function SplitCardFormInner({
|
|
|
4155
4590
|
] });
|
|
4156
4591
|
}
|
|
4157
4592
|
return /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
4158
|
-
/* @__PURE__ */
|
|
4159
|
-
overlayStatus && /* @__PURE__ */
|
|
4593
|
+
/* @__PURE__ */ jsx7(FloPayKeyframes, {}),
|
|
4594
|
+
overlayStatus && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
4160
4595
|
/* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
4161
4596
|
renderDirectPaypalGateDebug("flopay-direct-paypal-gate-debug-default"),
|
|
4162
4597
|
renderStripeGateDebug("flopay-stripe-gate-debug-default"),
|
|
4163
4598
|
shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
4164
|
-
paypalDirectRetry && /* @__PURE__ */
|
|
4599
|
+
paypalDirectRetry && /* @__PURE__ */ jsx7(
|
|
4165
4600
|
"div",
|
|
4166
4601
|
{
|
|
4167
4602
|
"data-testid": "flopay-paypal-direct-retry-notice-default",
|
|
@@ -4177,7 +4612,7 @@ function SplitCardFormInner({
|
|
|
4177
4612
|
children: "Please confirm your PayPal payment to complete checkout."
|
|
4178
4613
|
}
|
|
4179
4614
|
),
|
|
4180
|
-
/* @__PURE__ */
|
|
4615
|
+
/* @__PURE__ */ jsx7(
|
|
4181
4616
|
DirectPayPalButton,
|
|
4182
4617
|
{
|
|
4183
4618
|
sessionId,
|
|
@@ -4203,7 +4638,7 @@ function SplitCardFormInner({
|
|
|
4203
4638
|
paypalDirectRetry?.orderId ?? "fresh"
|
|
4204
4639
|
)
|
|
4205
4640
|
] }),
|
|
4206
|
-
shouldRenderStripePayPal && /* @__PURE__ */
|
|
4641
|
+
shouldRenderStripePayPal && /* @__PURE__ */ jsx7(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx7(
|
|
4207
4642
|
PayPalButtonInner,
|
|
4208
4643
|
{
|
|
4209
4644
|
sessionId,
|
|
@@ -4217,10 +4652,10 @@ function SplitCardFormInner({
|
|
|
4217
4652
|
onDecline,
|
|
4218
4653
|
runBeforeButtonClick,
|
|
4219
4654
|
onLoadStateChange: setPaypalLoadState,
|
|
4220
|
-
placeholderBorderRadius:
|
|
4655
|
+
placeholderBorderRadius: buttonBorderRadius
|
|
4221
4656
|
}
|
|
4222
4657
|
) }),
|
|
4223
|
-
shouldRenderWallets && /* @__PURE__ */
|
|
4658
|
+
shouldRenderWallets && /* @__PURE__ */ jsx7(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx7(
|
|
4224
4659
|
WalletButtonInner,
|
|
4225
4660
|
{
|
|
4226
4661
|
sessionId,
|
|
@@ -4234,10 +4669,10 @@ function SplitCardFormInner({
|
|
|
4234
4669
|
onDecline,
|
|
4235
4670
|
runBeforeButtonClick,
|
|
4236
4671
|
onLoadStateChange: setWalletLoadState,
|
|
4237
|
-
placeholderBorderRadius:
|
|
4672
|
+
placeholderBorderRadius: buttonBorderRadius
|
|
4238
4673
|
}
|
|
4239
4674
|
) }),
|
|
4240
|
-
shouldRenderPaymentElement && /* @__PURE__ */
|
|
4675
|
+
shouldRenderPaymentElement && /* @__PURE__ */ jsx7(
|
|
4241
4676
|
StripePaymentElementInner,
|
|
4242
4677
|
{
|
|
4243
4678
|
sessionId,
|
|
@@ -4265,7 +4700,7 @@ function SplitCardFormInner({
|
|
|
4265
4700
|
backgroundColor: bStyles.cardButton?.backgroundColor,
|
|
4266
4701
|
borderColor: bStyles.cardInputBorder,
|
|
4267
4702
|
textColor: bStyles.cardButton?.color,
|
|
4268
|
-
borderRadius:
|
|
4703
|
+
borderRadius: buttonBorderRadius
|
|
4269
4704
|
}
|
|
4270
4705
|
}
|
|
4271
4706
|
)
|
|
@@ -4278,9 +4713,9 @@ function SplitCardFormInner({
|
|
|
4278
4713
|
color: "#999",
|
|
4279
4714
|
fontSize: "0.85rem"
|
|
4280
4715
|
}, children: [
|
|
4281
|
-
/* @__PURE__ */
|
|
4282
|
-
/* @__PURE__ */
|
|
4283
|
-
/* @__PURE__ */
|
|
4716
|
+
/* @__PURE__ */ jsx7("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } }),
|
|
4717
|
+
/* @__PURE__ */ jsx7("span", { children: "or pay with card" }),
|
|
4718
|
+
/* @__PURE__ */ jsx7("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
|
|
4284
4719
|
] }),
|
|
4285
4720
|
showStripe && cardFormBlock
|
|
4286
4721
|
] });
|
|
@@ -4288,8 +4723,28 @@ function SplitCardFormInner({
|
|
|
4288
4723
|
|
|
4289
4724
|
// src/saved-payment-flow.ts
|
|
4290
4725
|
import { loadFloPay, PaymentAPI as PaymentAPI3 } from "@flopay/js";
|
|
4291
|
-
import { FloPayError as FloPayError4 } from "@flopay/shared";
|
|
4726
|
+
import { FloPayError as FloPayError4, isSetupIntentClientSecret as isSetupIntentClientSecret3 } from "@flopay/shared";
|
|
4292
4727
|
var DEFAULT_SAVED_PAYMENT_DECLINE_METHOD = "card";
|
|
4728
|
+
async function retrieveResumeIntent(stripe, clientSecret, isSetupIntent) {
|
|
4729
|
+
if (isSetupIntent) {
|
|
4730
|
+
if (typeof stripe.retrieveSetupIntent !== "function") return null;
|
|
4731
|
+
const { setupIntent, error: error2 } = await stripe.retrieveSetupIntent(clientSecret);
|
|
4732
|
+
return { error: error2, intent: setupIntent ?? null };
|
|
4733
|
+
}
|
|
4734
|
+
if (typeof stripe.retrievePaymentIntent !== "function") return null;
|
|
4735
|
+
const { paymentIntent, error } = await stripe.retrievePaymentIntent(clientSecret);
|
|
4736
|
+
return { error, intent: paymentIntent ?? null };
|
|
4737
|
+
}
|
|
4738
|
+
async function confirmResumeIntent(stripe, clientSecret, data, isSetupIntent) {
|
|
4739
|
+
if (isSetupIntent) {
|
|
4740
|
+
if (typeof stripe.confirmCardSetup !== "function") return null;
|
|
4741
|
+
const { setupIntent, error: error2 } = await stripe.confirmCardSetup(clientSecret, data);
|
|
4742
|
+
return { error: error2, intent: setupIntent ?? null };
|
|
4743
|
+
}
|
|
4744
|
+
if (typeof stripe.confirmCardPayment !== "function") return null;
|
|
4745
|
+
const { paymentIntent, error } = await stripe.confirmCardPayment(clientSecret, data);
|
|
4746
|
+
return { error, intent: paymentIntent ?? null };
|
|
4747
|
+
}
|
|
4293
4748
|
function getRedirectResultFromCheckoutProcessError(error) {
|
|
4294
4749
|
if (!error?.type || !error.threeDSecureToken) {
|
|
4295
4750
|
return null;
|
|
@@ -4303,6 +4758,210 @@ function getRedirectResultFromCheckoutProcessError(error) {
|
|
|
4303
4758
|
paymentMethodId: error.paymentMethodId
|
|
4304
4759
|
};
|
|
4305
4760
|
}
|
|
4761
|
+
function isTerminalAutoCheckoutThreeDsOutcome(outcome) {
|
|
4762
|
+
return outcome.status === "succeeded" || outcome.status === "declined";
|
|
4763
|
+
}
|
|
4764
|
+
async function runAutoCheckoutThreeDsChallenge(input) {
|
|
4765
|
+
if (typeof document === "undefined" || typeof window === "undefined") {
|
|
4766
|
+
throw new FloPayError4("3DS challenge requires a browser environment.", "api_error", {
|
|
4767
|
+
code: "three_ds_no_window"
|
|
4768
|
+
});
|
|
4769
|
+
}
|
|
4770
|
+
if (input.signal?.aborted) {
|
|
4771
|
+
throw new FloPayError4("Card authentication was cancelled.", "api_error", {
|
|
4772
|
+
code: "three_ds_aborted"
|
|
4773
|
+
});
|
|
4774
|
+
}
|
|
4775
|
+
const CHALLENGE_TIMEOUT_MS = 3e5;
|
|
4776
|
+
const CHALLENGE_POLL_INTERVAL_MS = 1e3;
|
|
4777
|
+
const COMPLETE_REQUEST_TIMEOUT_MS = 15e3;
|
|
4778
|
+
const completionEndpoint = `${input.billingApiUrl.replace(/\/$/, "")}/v1/checkouts/sessions/${encodeURIComponent(
|
|
4779
|
+
input.sessionId
|
|
4780
|
+
)}/3ds/complete`;
|
|
4781
|
+
const completeThreeDs = async () => {
|
|
4782
|
+
const controller = new AbortController();
|
|
4783
|
+
const onParentAbort = () => controller.abort();
|
|
4784
|
+
if (input.signal?.aborted) {
|
|
4785
|
+
controller.abort();
|
|
4786
|
+
} else {
|
|
4787
|
+
input.signal?.addEventListener("abort", onParentAbort);
|
|
4788
|
+
}
|
|
4789
|
+
const requestTimeout = window.setTimeout(() => controller.abort(), COMPLETE_REQUEST_TIMEOUT_MS);
|
|
4790
|
+
try {
|
|
4791
|
+
const response = await fetch(completionEndpoint, {
|
|
4792
|
+
method: "POST",
|
|
4793
|
+
headers: {
|
|
4794
|
+
"x-checkout-session-token": input.nonce,
|
|
4795
|
+
"content-type": "application/json"
|
|
4796
|
+
},
|
|
4797
|
+
body: "{}",
|
|
4798
|
+
signal: controller.signal
|
|
4799
|
+
});
|
|
4800
|
+
if (!response.ok) {
|
|
4801
|
+
return { status: "unknown" };
|
|
4802
|
+
}
|
|
4803
|
+
const json = await response.json().catch(() => null);
|
|
4804
|
+
return coerceThreeDsOutcome(json);
|
|
4805
|
+
} catch {
|
|
4806
|
+
return { status: "unknown" };
|
|
4807
|
+
} finally {
|
|
4808
|
+
window.clearTimeout(requestTimeout);
|
|
4809
|
+
input.signal?.removeEventListener("abort", onParentAbort);
|
|
4810
|
+
}
|
|
4811
|
+
};
|
|
4812
|
+
const previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
4813
|
+
const backdrop = document.createElement("div");
|
|
4814
|
+
backdrop.setAttribute("data-flopay-auto-3ds-overlay", "1");
|
|
4815
|
+
backdrop.setAttribute("role", "dialog");
|
|
4816
|
+
backdrop.setAttribute("aria-modal", "true");
|
|
4817
|
+
backdrop.setAttribute("aria-label", "Card authentication");
|
|
4818
|
+
backdrop.style.cssText = [
|
|
4819
|
+
"position:fixed",
|
|
4820
|
+
"inset:0",
|
|
4821
|
+
"z-index:2147483647",
|
|
4822
|
+
"background:rgba(15,23,42,0.6)",
|
|
4823
|
+
"display:flex",
|
|
4824
|
+
"align-items:center",
|
|
4825
|
+
"justify-content:center",
|
|
4826
|
+
"padding:16px"
|
|
4827
|
+
].join(";");
|
|
4828
|
+
const frame = document.createElement("iframe");
|
|
4829
|
+
frame.setAttribute("title", "Card authentication");
|
|
4830
|
+
frame.setAttribute("allow", "payment");
|
|
4831
|
+
frame.tabIndex = 0;
|
|
4832
|
+
frame.style.cssText = [
|
|
4833
|
+
"width:min(100%,460px)",
|
|
4834
|
+
"height:min(100%,640px)",
|
|
4835
|
+
"border:0",
|
|
4836
|
+
"border-radius:12px",
|
|
4837
|
+
"background:#fff",
|
|
4838
|
+
"box-shadow:0 12px 30px rgba(0,0,0,0.35)"
|
|
4839
|
+
].join(";");
|
|
4840
|
+
frame.src = input.nextActionRedirectUrl;
|
|
4841
|
+
backdrop.appendChild(frame);
|
|
4842
|
+
document.body.appendChild(backdrop);
|
|
4843
|
+
frame.focus();
|
|
4844
|
+
let expectedReturnOrigin = null;
|
|
4845
|
+
try {
|
|
4846
|
+
expectedReturnOrigin = new URL(input.billingApiUrl, window.location.href).origin;
|
|
4847
|
+
} catch {
|
|
4848
|
+
expectedReturnOrigin = null;
|
|
4849
|
+
}
|
|
4850
|
+
try {
|
|
4851
|
+
const polledOutcome = await new Promise((resolve, reject) => {
|
|
4852
|
+
let settled = false;
|
|
4853
|
+
let timer = 0;
|
|
4854
|
+
let pollTimer = 0;
|
|
4855
|
+
let loadPollTimer = 0;
|
|
4856
|
+
let pollInFlight = false;
|
|
4857
|
+
const cleanup = () => {
|
|
4858
|
+
window.clearTimeout(timer);
|
|
4859
|
+
window.clearInterval(pollTimer);
|
|
4860
|
+
window.clearTimeout(loadPollTimer);
|
|
4861
|
+
window.removeEventListener("message", listener);
|
|
4862
|
+
frame.removeEventListener("load", onFrameLoad);
|
|
4863
|
+
input.signal?.removeEventListener("abort", onAbort);
|
|
4864
|
+
};
|
|
4865
|
+
const maybeResolveFromBackend = async () => {
|
|
4866
|
+
if (settled || pollInFlight) return;
|
|
4867
|
+
pollInFlight = true;
|
|
4868
|
+
try {
|
|
4869
|
+
const outcome = await completeThreeDs();
|
|
4870
|
+
if (settled || !isTerminalAutoCheckoutThreeDsOutcome(outcome)) return;
|
|
4871
|
+
settled = true;
|
|
4872
|
+
cleanup();
|
|
4873
|
+
resolve(outcome);
|
|
4874
|
+
} finally {
|
|
4875
|
+
pollInFlight = false;
|
|
4876
|
+
}
|
|
4877
|
+
};
|
|
4878
|
+
const onFrameLoad = () => {
|
|
4879
|
+
window.clearTimeout(loadPollTimer);
|
|
4880
|
+
loadPollTimer = window.setTimeout(() => {
|
|
4881
|
+
void maybeResolveFromBackend();
|
|
4882
|
+
}, 250);
|
|
4883
|
+
};
|
|
4884
|
+
const onAbort = () => {
|
|
4885
|
+
if (settled) return;
|
|
4886
|
+
settled = true;
|
|
4887
|
+
cleanup();
|
|
4888
|
+
reject(
|
|
4889
|
+
new FloPayError4("Card authentication was cancelled.", "api_error", {
|
|
4890
|
+
code: "three_ds_aborted"
|
|
4891
|
+
})
|
|
4892
|
+
);
|
|
4893
|
+
};
|
|
4894
|
+
const listener = (event) => {
|
|
4895
|
+
if (event.source !== frame.contentWindow) return;
|
|
4896
|
+
if (expectedReturnOrigin && event.origin !== expectedReturnOrigin) return;
|
|
4897
|
+
const data = event.data;
|
|
4898
|
+
if (!data || typeof data !== "object") return;
|
|
4899
|
+
const record = data;
|
|
4900
|
+
if (record["source"] !== "flopay-vault-3ds-return") return;
|
|
4901
|
+
if (settled) return;
|
|
4902
|
+
settled = true;
|
|
4903
|
+
cleanup();
|
|
4904
|
+
resolve(null);
|
|
4905
|
+
};
|
|
4906
|
+
timer = window.setTimeout(() => {
|
|
4907
|
+
if (settled) return;
|
|
4908
|
+
settled = true;
|
|
4909
|
+
cleanup();
|
|
4910
|
+
reject(
|
|
4911
|
+
new FloPayError4("Card authentication timed out.", "api_error", {
|
|
4912
|
+
code: "three_ds_timeout"
|
|
4913
|
+
})
|
|
4914
|
+
);
|
|
4915
|
+
}, CHALLENGE_TIMEOUT_MS);
|
|
4916
|
+
pollTimer = window.setInterval(() => {
|
|
4917
|
+
void maybeResolveFromBackend();
|
|
4918
|
+
}, CHALLENGE_POLL_INTERVAL_MS);
|
|
4919
|
+
frame.addEventListener("load", onFrameLoad);
|
|
4920
|
+
window.addEventListener("message", listener);
|
|
4921
|
+
input.signal?.addEventListener("abort", onAbort);
|
|
4922
|
+
if (input.signal?.aborted) onAbort();
|
|
4923
|
+
});
|
|
4924
|
+
if (polledOutcome) {
|
|
4925
|
+
return polledOutcome;
|
|
4926
|
+
}
|
|
4927
|
+
return await completeThreeDs();
|
|
4928
|
+
} finally {
|
|
4929
|
+
backdrop.parentNode?.removeChild(backdrop);
|
|
4930
|
+
if (previousFocus?.isConnected) {
|
|
4931
|
+
previousFocus.focus();
|
|
4932
|
+
}
|
|
4933
|
+
}
|
|
4934
|
+
}
|
|
4935
|
+
function coerceThreeDsOutcome(json) {
|
|
4936
|
+
if (!json || typeof json !== "object") return { status: "unknown" };
|
|
4937
|
+
const status = typeof json["status"] === "string" ? json["status"] : "unknown";
|
|
4938
|
+
const providerIntentId = typeof json["providerIntentId"] === "string" ? json["providerIntentId"] : null;
|
|
4939
|
+
switch (status) {
|
|
4940
|
+
case "succeeded":
|
|
4941
|
+
return { status: "succeeded", providerIntentId };
|
|
4942
|
+
case "declined":
|
|
4943
|
+
return {
|
|
4944
|
+
status: "declined",
|
|
4945
|
+
providerIntentId,
|
|
4946
|
+
declineReason: typeof json["declineReason"] === "string" ? json["declineReason"] : null,
|
|
4947
|
+
gatewayDeclineReason: typeof json["gatewayDeclineReason"] === "string" ? json["gatewayDeclineReason"] : null
|
|
4948
|
+
};
|
|
4949
|
+
case "requires_action":
|
|
4950
|
+
return {
|
|
4951
|
+
status: "requires_action",
|
|
4952
|
+
providerIntentId,
|
|
4953
|
+
nextActionRedirectUrl: typeof json["nextActionRedirectUrl"] === "string" ? json["nextActionRedirectUrl"] : null
|
|
4954
|
+
};
|
|
4955
|
+
case "pending":
|
|
4956
|
+
return { status: "pending", providerIntentId };
|
|
4957
|
+
case "timeout":
|
|
4958
|
+
return { status: "timeout", providerIntentId };
|
|
4959
|
+
case "no_attempt":
|
|
4960
|
+
return { status: "no_attempt" };
|
|
4961
|
+
default:
|
|
4962
|
+
return { status: "unknown" };
|
|
4963
|
+
}
|
|
4964
|
+
}
|
|
4306
4965
|
function checkoutProcessErrorToFloPayError(error, fallbackMessage = "Payment failed. Please try again.", options) {
|
|
4307
4966
|
const checkoutMethod = options?.checkoutMethod ?? error?.checkoutMethod ?? (error?.type === "paypal_redirect_required" ? "paypal" : "card");
|
|
4308
4967
|
const rawMessage = error?.message ?? fallbackMessage;
|
|
@@ -4525,64 +5184,66 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
|
4525
5184
|
{ checkoutMethod: "card" }
|
|
4526
5185
|
);
|
|
4527
5186
|
}
|
|
5187
|
+
const isSetupIntent = isSetupIntentClientSecret3(redirectResult.threeDSecureToken);
|
|
4528
5188
|
let paymentIntent = null;
|
|
4529
5189
|
let savedPaymentMethodId = redirectResult.paymentMethodId;
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
);
|
|
4534
|
-
if (retrieveError) {
|
|
5190
|
+
const retrieved = await retrieveResumeIntent(stripe, redirectResult.threeDSecureToken, isSetupIntent);
|
|
5191
|
+
if (retrieved) {
|
|
5192
|
+
if (retrieved.error) {
|
|
4535
5193
|
throw Object.assign(
|
|
4536
5194
|
new FloPayError4(
|
|
4537
|
-
|
|
5195
|
+
retrieved.error.message ?? `Failed to retrieve 3DS ${isSetupIntent ? "setup" : "payment"} status.`,
|
|
4538
5196
|
"api_error",
|
|
4539
|
-
{ code:
|
|
5197
|
+
{ code: retrieved.error.code }
|
|
4540
5198
|
),
|
|
4541
5199
|
{ checkoutMethod: "card" }
|
|
4542
5200
|
);
|
|
4543
5201
|
}
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
5202
|
+
const existingIntent = retrieved.intent;
|
|
5203
|
+
if (!savedPaymentMethodId && existingIntent?.payment_method) {
|
|
5204
|
+
if (typeof existingIntent.payment_method === "string") {
|
|
5205
|
+
savedPaymentMethodId = existingIntent.payment_method;
|
|
5206
|
+
} else if ("id" in existingIntent.payment_method) {
|
|
5207
|
+
savedPaymentMethodId = existingIntent.payment_method.id ?? void 0;
|
|
4549
5208
|
}
|
|
4550
5209
|
}
|
|
4551
5210
|
}
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
5211
|
+
const confirmed = savedPaymentMethodId ? await confirmResumeIntent(
|
|
5212
|
+
stripe,
|
|
5213
|
+
redirectResult.threeDSecureToken,
|
|
5214
|
+
{
|
|
5215
|
+
payment_method: savedPaymentMethodId,
|
|
5216
|
+
return_url: returnUrl ?? resolveSavedPaymentReturnUrl(session) ?? window.location.href
|
|
5217
|
+
},
|
|
5218
|
+
isSetupIntent
|
|
5219
|
+
) : null;
|
|
5220
|
+
if (confirmed) {
|
|
5221
|
+
if (confirmed.error) {
|
|
4561
5222
|
throw Object.assign(
|
|
4562
5223
|
new FloPayError4(
|
|
4563
|
-
|
|
5224
|
+
confirmed.error.message ?? "3DS authentication failed.",
|
|
4564
5225
|
"api_error",
|
|
4565
|
-
{ code:
|
|
5226
|
+
{ code: confirmed.error.code }
|
|
4566
5227
|
),
|
|
4567
5228
|
{ checkoutMethod: "card" }
|
|
4568
5229
|
);
|
|
4569
5230
|
}
|
|
4570
|
-
paymentIntent =
|
|
5231
|
+
paymentIntent = confirmed.intent;
|
|
4571
5232
|
} else {
|
|
4572
|
-
const
|
|
5233
|
+
const nextAction = await stripe.handleNextAction({
|
|
4573
5234
|
clientSecret: redirectResult.threeDSecureToken
|
|
4574
5235
|
});
|
|
4575
|
-
if (
|
|
5236
|
+
if (nextAction.error) {
|
|
4576
5237
|
throw Object.assign(
|
|
4577
5238
|
new FloPayError4(
|
|
4578
|
-
|
|
5239
|
+
nextAction.error.message ?? "3DS authentication failed.",
|
|
4579
5240
|
"api_error",
|
|
4580
|
-
{ code:
|
|
5241
|
+
{ code: nextAction.error.code }
|
|
4581
5242
|
),
|
|
4582
5243
|
{ checkoutMethod: "card" }
|
|
4583
5244
|
);
|
|
4584
5245
|
}
|
|
4585
|
-
paymentIntent =
|
|
5246
|
+
paymentIntent = (isSetupIntent ? nextAction.setupIntent : nextAction.paymentIntent) ?? null;
|
|
4586
5247
|
}
|
|
4587
5248
|
if (paymentIntent && (paymentIntent.status === "requires_capture" || paymentIntent.status === "succeeded" || paymentIntent.status === "processing")) {
|
|
4588
5249
|
const followUp = await processSavedPaymentForMode({
|
|
@@ -4742,7 +5403,7 @@ async function loadSavedPaymentProviders({
|
|
|
4742
5403
|
}
|
|
4743
5404
|
|
|
4744
5405
|
// src/flopay-checkout.tsx
|
|
4745
|
-
import { Fragment as Fragment3, jsx as
|
|
5406
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4746
5407
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
|
|
4747
5408
|
var PAYPAL_RESUME_STORAGE_KEY = "flopay_checkout_saved_payment_resume";
|
|
4748
5409
|
var sessionInflightMap = /* @__PURE__ */ new Map();
|
|
@@ -4791,6 +5452,36 @@ function clearPayPalResumeState() {
|
|
|
4791
5452
|
console.warn("[FloPayCheckout] Failed to clear PayPal resume state.", error);
|
|
4792
5453
|
}
|
|
4793
5454
|
}
|
|
5455
|
+
function readCachedInlineSession(cacheKey) {
|
|
5456
|
+
if (!canUseStorage()) return null;
|
|
5457
|
+
const raw = window.sessionStorage.getItem(cacheKey);
|
|
5458
|
+
if (!raw) return null;
|
|
5459
|
+
try {
|
|
5460
|
+
const parsed = JSON.parse(raw);
|
|
5461
|
+
if (parsed && typeof parsed.sid === "string" && parsed.sid) {
|
|
5462
|
+
return { sid: parsed.sid, nonce: typeof parsed.nonce === "string" ? parsed.nonce : void 0 };
|
|
5463
|
+
}
|
|
5464
|
+
return null;
|
|
5465
|
+
} catch {
|
|
5466
|
+
return { sid: raw };
|
|
5467
|
+
}
|
|
5468
|
+
}
|
|
5469
|
+
function persistCachedInlineSession(cacheKey, sid, nonce) {
|
|
5470
|
+
if (!canUseStorage()) return;
|
|
5471
|
+
try {
|
|
5472
|
+
window.sessionStorage.setItem(cacheKey, JSON.stringify(nonce ? { sid, nonce } : { sid }));
|
|
5473
|
+
} catch (error) {
|
|
5474
|
+
console.warn("[FloPayCheckout] Failed to persist checkout session cache.", error);
|
|
5475
|
+
}
|
|
5476
|
+
}
|
|
5477
|
+
function clearCachedInlineSession(cacheKey) {
|
|
5478
|
+
if (!canUseStorage()) return;
|
|
5479
|
+
try {
|
|
5480
|
+
window.sessionStorage.removeItem(cacheKey);
|
|
5481
|
+
} catch (error) {
|
|
5482
|
+
console.warn("[FloPayCheckout] Failed to clear checkout session cache.", error);
|
|
5483
|
+
}
|
|
5484
|
+
}
|
|
4794
5485
|
function clearPayPalRedirectParams() {
|
|
4795
5486
|
if (typeof window === "undefined") return;
|
|
4796
5487
|
const url = new URL(window.location.href);
|
|
@@ -4849,6 +5540,8 @@ function FloPayCheckout({
|
|
|
4849
5540
|
onButtonClick,
|
|
4850
5541
|
onBeforeButtonClick,
|
|
4851
5542
|
enableAVS,
|
|
5543
|
+
cardFieldOrder,
|
|
5544
|
+
cardPreFormSlot,
|
|
4852
5545
|
avsLayout,
|
|
4853
5546
|
submitLabel,
|
|
4854
5547
|
className,
|
|
@@ -4866,9 +5559,9 @@ function FloPayCheckout({
|
|
|
4866
5559
|
const checkoutLayout = children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout";
|
|
4867
5560
|
const [unified, setUnified] = useState4(null);
|
|
4868
5561
|
const [flopay, setFloPay] = useState4(null);
|
|
4869
|
-
const flopayRef =
|
|
5562
|
+
const flopayRef = useRef5(null);
|
|
4870
5563
|
const [paypalFlopay, setPaypalFloPay] = useState4(null);
|
|
4871
|
-
const paypalFlopayRef =
|
|
5564
|
+
const paypalFlopayRef = useRef5(null);
|
|
4872
5565
|
const [session, setSession] = useState4(null);
|
|
4873
5566
|
const [resolvedSessionId, setResolvedSessionId] = useState4(sessionIdProp ?? "");
|
|
4874
5567
|
const activeSessionId = sessionIdProp ?? resolvedSessionId;
|
|
@@ -4883,18 +5576,18 @@ function FloPayCheckout({
|
|
|
4883
5576
|
const [createSessionPatch, setCreateSessionPatch] = useState4(void 0);
|
|
4884
5577
|
const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = useState4("");
|
|
4885
5578
|
const [cardBootstrapPending, setCardBootstrapPending] = useState4(false);
|
|
4886
|
-
const autoCheckoutAttempted =
|
|
4887
|
-
const paypalResumeAttempted =
|
|
4888
|
-
const savedPaymentKeysRef =
|
|
4889
|
-
const onCompleteRef =
|
|
5579
|
+
const autoCheckoutAttempted = useRef5(false);
|
|
5580
|
+
const paypalResumeAttempted = useRef5(false);
|
|
5581
|
+
const savedPaymentKeysRef = useRef5(null);
|
|
5582
|
+
const onCompleteRef = useRef5(onComplete);
|
|
4890
5583
|
onCompleteRef.current = onComplete;
|
|
4891
|
-
const onErrorRef =
|
|
5584
|
+
const onErrorRef = useRef5(onError);
|
|
4892
5585
|
onErrorRef.current = onError;
|
|
4893
|
-
const onDeclineRef =
|
|
5586
|
+
const onDeclineRef = useRef5(onDecline);
|
|
4894
5587
|
onDeclineRef.current = onDecline;
|
|
4895
|
-
const onSessionCompletedRef =
|
|
5588
|
+
const onSessionCompletedRef = useRef5(onSessionCompleted);
|
|
4896
5589
|
onSessionCompletedRef.current = onSessionCompleted;
|
|
4897
|
-
|
|
5590
|
+
useEffect6(() => {
|
|
4898
5591
|
console.info("[FloPay] Checkout initialized", {
|
|
4899
5592
|
sdk_version: SDK_VERSION,
|
|
4900
5593
|
checkout_type: checkoutType,
|
|
@@ -4922,11 +5615,11 @@ function FloPayCheckout({
|
|
|
4922
5615
|
} : void 0,
|
|
4923
5616
|
[effectiveCreateSessionBase, effectiveCreateSessionMode]
|
|
4924
5617
|
);
|
|
4925
|
-
|
|
5618
|
+
useEffect6(() => {
|
|
4926
5619
|
setCreateSessionPatch(void 0);
|
|
4927
5620
|
setCreateSessionPatchBaseHash(baseCreateSessionHash);
|
|
4928
5621
|
}, [baseCreateSessionHash]);
|
|
4929
|
-
|
|
5622
|
+
useEffect6(() => {
|
|
4930
5623
|
setModeError(initialErrorMessage);
|
|
4931
5624
|
}, [initialErrorMessage]);
|
|
4932
5625
|
const emitDecline = useCallback2(
|
|
@@ -5053,7 +5746,7 @@ function FloPayCheckout({
|
|
|
5053
5746
|
resolvedBillingUrl
|
|
5054
5747
|
]
|
|
5055
5748
|
);
|
|
5056
|
-
|
|
5749
|
+
useEffect6(() => {
|
|
5057
5750
|
if (typeof window === "undefined" || paypalResumeAttempted.current) {
|
|
5058
5751
|
return;
|
|
5059
5752
|
}
|
|
@@ -5170,7 +5863,7 @@ function FloPayCheckout({
|
|
|
5170
5863
|
}
|
|
5171
5864
|
})();
|
|
5172
5865
|
}, [emitDecline, locale, normalizeSavedPaymentError, resolvedBillingUrl]);
|
|
5173
|
-
const initializedHashRef =
|
|
5866
|
+
const initializedHashRef = useRef5(null);
|
|
5174
5867
|
function hashCreateParams(params) {
|
|
5175
5868
|
const key = JSON.stringify({
|
|
5176
5869
|
c: params?.clientId,
|
|
@@ -5207,12 +5900,12 @@ function FloPayCheckout({
|
|
|
5207
5900
|
() => effectiveCreateSession ? hashCreateParams(effectiveCreateSession) : "",
|
|
5208
5901
|
[effectiveCreateSession]
|
|
5209
5902
|
);
|
|
5210
|
-
const createSessionParamsRef =
|
|
5903
|
+
const createSessionParamsRef = useRef5(effectiveCreateSession);
|
|
5211
5904
|
createSessionParamsRef.current = effectiveCreateSession;
|
|
5212
|
-
|
|
5905
|
+
useEffect6(() => {
|
|
5213
5906
|
setResolvedSessionId(sessionIdProp ?? "");
|
|
5214
5907
|
}, [sessionIdProp]);
|
|
5215
|
-
|
|
5908
|
+
useEffect6(() => {
|
|
5216
5909
|
autoCheckoutAttempted.current = false;
|
|
5217
5910
|
setModeError(initialErrorMessage);
|
|
5218
5911
|
setModeOverlayError(null);
|
|
@@ -5220,22 +5913,23 @@ function FloPayCheckout({
|
|
|
5220
5913
|
}, [createSessionHash, initialErrorMessage, sessionIdProp]);
|
|
5221
5914
|
async function resolveInlineSession(params, cacheKey) {
|
|
5222
5915
|
const api = new PaymentAPI4(resolvedBillingUrl);
|
|
5223
|
-
|
|
5916
|
+
const cached = readCachedInlineSession(cacheKey);
|
|
5917
|
+
let sid = cached?.sid ?? null;
|
|
5224
5918
|
let realResult = null;
|
|
5225
5919
|
if (sid) {
|
|
5226
5920
|
try {
|
|
5227
|
-
realResult = await api.getUnifiedCheckoutSession(sid);
|
|
5921
|
+
realResult = await api.getUnifiedCheckoutSession(sid, cached?.nonce);
|
|
5228
5922
|
const status = realResult.data.session?.status;
|
|
5229
5923
|
if (status === "complete") {
|
|
5230
5924
|
if (wasSessionRecentlyCompleted(sid)) {
|
|
5231
5925
|
return { sid, result: realResult };
|
|
5232
5926
|
}
|
|
5233
|
-
|
|
5927
|
+
clearCachedInlineSession(cacheKey);
|
|
5234
5928
|
sid = null;
|
|
5235
5929
|
realResult = null;
|
|
5236
5930
|
}
|
|
5237
5931
|
} catch {
|
|
5238
|
-
|
|
5932
|
+
clearCachedInlineSession(cacheKey);
|
|
5239
5933
|
sid = null;
|
|
5240
5934
|
}
|
|
5241
5935
|
}
|
|
@@ -5249,8 +5943,8 @@ function FloPayCheckout({
|
|
|
5249
5943
|
};
|
|
5250
5944
|
realResult = await api.createAndFetchSession(paramsWithAnalytics);
|
|
5251
5945
|
sid = realResult.data.session?.id ?? "";
|
|
5252
|
-
if (sid
|
|
5253
|
-
|
|
5946
|
+
if (sid) {
|
|
5947
|
+
persistCachedInlineSession(cacheKey, sid, realResult.data.session?.clientSecret);
|
|
5254
5948
|
}
|
|
5255
5949
|
}
|
|
5256
5950
|
return { sid: sid ?? "", result: realResult };
|
|
@@ -5339,7 +6033,7 @@ function FloPayCheckout({
|
|
|
5339
6033
|
resolvedSessionId,
|
|
5340
6034
|
session
|
|
5341
6035
|
]);
|
|
5342
|
-
|
|
6036
|
+
useEffect6(() => {
|
|
5343
6037
|
let cancelled = false;
|
|
5344
6038
|
setLoadError(null);
|
|
5345
6039
|
if (createSessionHash) {
|
|
@@ -5561,7 +6255,7 @@ function FloPayCheckout({
|
|
|
5561
6255
|
]
|
|
5562
6256
|
);
|
|
5563
6257
|
const shouldShowInterimButtons = Boolean(createSessionParams) && layout === "buttons" && !isPaypalOnlySession && (!flopay || !providerOptions);
|
|
5564
|
-
const modeOverlay = modeOverlayStatus ? /* @__PURE__ */
|
|
6258
|
+
const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ jsx8(
|
|
5565
6259
|
ProcessingOverlay,
|
|
5566
6260
|
{
|
|
5567
6261
|
status: modeOverlayStatus,
|
|
@@ -5577,7 +6271,7 @@ function FloPayCheckout({
|
|
|
5577
6271
|
}
|
|
5578
6272
|
if (layout === "buttons") {
|
|
5579
6273
|
const bundleRadius = themeBundle?.buttonsLayout?.cardButton?.borderRadius ?? themeBundle?.appearance.variables?.borderRadius ?? 8;
|
|
5580
|
-
const skeletonBar = (h) => /* @__PURE__ */
|
|
6274
|
+
const skeletonBar = (h) => /* @__PURE__ */ jsx8("div", { style: {
|
|
5581
6275
|
height: h,
|
|
5582
6276
|
borderRadius: bundleRadius,
|
|
5583
6277
|
background: "#e5e7eb",
|
|
@@ -5588,14 +6282,14 @@ function FloPayCheckout({
|
|
|
5588
6282
|
showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
5589
6283
|
showStripe && (showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
5590
6284
|
showStripe && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
5591
|
-
/* @__PURE__ */
|
|
6285
|
+
/* @__PURE__ */ jsx8("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
5592
6286
|
] }),
|
|
5593
6287
|
modeOverlay
|
|
5594
6288
|
] });
|
|
5595
6289
|
}
|
|
5596
6290
|
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
5597
6291
|
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", justifyContent: "center", padding: 32 }, children: [
|
|
5598
|
-
/* @__PURE__ */
|
|
6292
|
+
/* @__PURE__ */ jsx8("div", { style: {
|
|
5599
6293
|
width: 24,
|
|
5600
6294
|
height: 24,
|
|
5601
6295
|
border: "2px solid #e5e7eb",
|
|
@@ -5603,16 +6297,16 @@ function FloPayCheckout({
|
|
|
5603
6297
|
borderRadius: "50%",
|
|
5604
6298
|
animation: "spin 0.6s linear infinite"
|
|
5605
6299
|
} }),
|
|
5606
|
-
/* @__PURE__ */
|
|
6300
|
+
/* @__PURE__ */ jsx8("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
|
|
5607
6301
|
] }),
|
|
5608
6302
|
modeOverlay
|
|
5609
6303
|
] });
|
|
5610
6304
|
}
|
|
5611
6305
|
if (loadError) {
|
|
5612
6306
|
if (errorNode) {
|
|
5613
|
-
return /* @__PURE__ */
|
|
6307
|
+
return /* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: errorNode(loadError) });
|
|
5614
6308
|
}
|
|
5615
|
-
return /* @__PURE__ */
|
|
6309
|
+
return /* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx8(
|
|
5616
6310
|
"div",
|
|
5617
6311
|
{
|
|
5618
6312
|
role: "alert",
|
|
@@ -5629,7 +6323,7 @@ function FloPayCheckout({
|
|
|
5629
6323
|
}
|
|
5630
6324
|
if (shouldShowInterimButtons) {
|
|
5631
6325
|
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
5632
|
-
/* @__PURE__ */
|
|
6326
|
+
/* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx8(
|
|
5633
6327
|
InterimButtonsView,
|
|
5634
6328
|
{
|
|
5635
6329
|
onButtonClick,
|
|
@@ -5650,8 +6344,8 @@ function FloPayCheckout({
|
|
|
5650
6344
|
}
|
|
5651
6345
|
if (isPaypalOnlySession && session && directPaypalConfig) {
|
|
5652
6346
|
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
5653
|
-
/* @__PURE__ */
|
|
5654
|
-
modeError && /* @__PURE__ */
|
|
6347
|
+
/* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsxs5("div", { className, style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
6348
|
+
modeError && /* @__PURE__ */ jsx8(
|
|
5655
6349
|
"div",
|
|
5656
6350
|
{
|
|
5657
6351
|
role: "alert",
|
|
@@ -5668,7 +6362,7 @@ function FloPayCheckout({
|
|
|
5668
6362
|
children: modeError
|
|
5669
6363
|
}
|
|
5670
6364
|
),
|
|
5671
|
-
/* @__PURE__ */
|
|
6365
|
+
/* @__PURE__ */ jsx8(
|
|
5672
6366
|
DirectPayPalButton,
|
|
5673
6367
|
{
|
|
5674
6368
|
sessionId: activeSessionId,
|
|
@@ -5692,12 +6386,12 @@ function FloPayCheckout({
|
|
|
5692
6386
|
] });
|
|
5693
6387
|
}
|
|
5694
6388
|
if (!flopay || !providerOptions) {
|
|
5695
|
-
return /* @__PURE__ */
|
|
6389
|
+
return /* @__PURE__ */ jsx8(Fragment3, { children: modeOverlay });
|
|
5696
6390
|
}
|
|
5697
6391
|
if (currentMode === "confirm") {
|
|
5698
6392
|
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
5699
|
-
/* @__PURE__ */
|
|
5700
|
-
modeError && /* @__PURE__ */
|
|
6393
|
+
/* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx8(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: /* @__PURE__ */ jsxs5("div", { className, children: [
|
|
6394
|
+
modeError && /* @__PURE__ */ jsx8(
|
|
5701
6395
|
"div",
|
|
5702
6396
|
{
|
|
5703
6397
|
style: {
|
|
@@ -5712,7 +6406,7 @@ function FloPayCheckout({
|
|
|
5712
6406
|
renderConfirmButton ? renderConfirmButton({
|
|
5713
6407
|
onConfirm: handleConfirmCheckout,
|
|
5714
6408
|
isProcessing: confirmProcessing
|
|
5715
|
-
}) : /* @__PURE__ */
|
|
6409
|
+
}) : /* @__PURE__ */ jsx8(
|
|
5716
6410
|
"button",
|
|
5717
6411
|
{
|
|
5718
6412
|
type: "button",
|
|
@@ -5738,8 +6432,8 @@ function FloPayCheckout({
|
|
|
5738
6432
|
] });
|
|
5739
6433
|
}
|
|
5740
6434
|
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
5741
|
-
/* @__PURE__ */
|
|
5742
|
-
modeError && /* @__PURE__ */
|
|
6435
|
+
/* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx8(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: children ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
6436
|
+
modeError && /* @__PURE__ */ jsx8(
|
|
5743
6437
|
"div",
|
|
5744
6438
|
{
|
|
5745
6439
|
style: {
|
|
@@ -5754,7 +6448,7 @@ function FloPayCheckout({
|
|
|
5754
6448
|
children: modeError
|
|
5755
6449
|
}
|
|
5756
6450
|
),
|
|
5757
|
-
/* @__PURE__ */
|
|
6451
|
+
/* @__PURE__ */ jsx8(
|
|
5758
6452
|
SessionInjector,
|
|
5759
6453
|
{
|
|
5760
6454
|
sessionId: activeSessionId,
|
|
@@ -5764,7 +6458,7 @@ function FloPayCheckout({
|
|
|
5764
6458
|
children
|
|
5765
6459
|
}
|
|
5766
6460
|
)
|
|
5767
|
-
] }) : /* @__PURE__ */
|
|
6461
|
+
] }) : /* @__PURE__ */ jsx8(
|
|
5768
6462
|
SplitCardForm,
|
|
5769
6463
|
{
|
|
5770
6464
|
sessionId: activeSessionId,
|
|
@@ -5784,6 +6478,7 @@ function FloPayCheckout({
|
|
|
5784
6478
|
showPayPal,
|
|
5785
6479
|
showStripe,
|
|
5786
6480
|
enabledPaymentMethods: unified?.data.stripe?.enabledPaymentMethods,
|
|
6481
|
+
enabledPaymentMethodCountries: unified?.data.stripe?.enabledPaymentMethodCountries,
|
|
5787
6482
|
showApplePay,
|
|
5788
6483
|
showGooglePay,
|
|
5789
6484
|
layout,
|
|
@@ -5797,6 +6492,8 @@ function FloPayCheckout({
|
|
|
5797
6492
|
onButtonClick,
|
|
5798
6493
|
onBeforeButtonClick,
|
|
5799
6494
|
enableAVS,
|
|
6495
|
+
...cardFieldOrder ? { cardFieldOrder } : {},
|
|
6496
|
+
...cardPreFormSlot ? { cardPreFormSlot } : {},
|
|
5800
6497
|
avsLayout,
|
|
5801
6498
|
country: session?.customer?.country,
|
|
5802
6499
|
city: session?.customer?.city,
|
|
@@ -5824,8 +6521,8 @@ function SessionInjector({
|
|
|
5824
6521
|
session,
|
|
5825
6522
|
children
|
|
5826
6523
|
}) {
|
|
5827
|
-
return /* @__PURE__ */
|
|
5828
|
-
if (!
|
|
6524
|
+
return /* @__PURE__ */ jsx8(Fragment3, { children: React8.Children.map(children, (child) => {
|
|
6525
|
+
if (!React8.isValidElement(child)) return child;
|
|
5829
6526
|
const existing = child.props;
|
|
5830
6527
|
const injected = {};
|
|
5831
6528
|
if (!existing.sessionId) injected.sessionId = sessionId;
|
|
@@ -5840,7 +6537,7 @@ function SessionInjector({
|
|
|
5840
6537
|
injected.lastName = session.customer.lastName;
|
|
5841
6538
|
}
|
|
5842
6539
|
if (Object.keys(injected).length === 0) return child;
|
|
5843
|
-
return
|
|
6540
|
+
return React8.cloneElement(child, injected);
|
|
5844
6541
|
}) });
|
|
5845
6542
|
}
|
|
5846
6543
|
function InterimButtonsView({
|
|
@@ -5862,7 +6559,7 @@ function InterimButtonsView({
|
|
|
5862
6559
|
}) {
|
|
5863
6560
|
const [showCardForm, setShowCardForm] = useState4(false);
|
|
5864
6561
|
const isCardOpenControlled = typeof cardOpen === "boolean";
|
|
5865
|
-
|
|
6562
|
+
useEffect6(() => {
|
|
5866
6563
|
if (isCardOpenControlled) {
|
|
5867
6564
|
setShowCardForm(cardOpen);
|
|
5868
6565
|
}
|
|
@@ -5883,7 +6580,7 @@ function InterimButtonsView({
|
|
|
5883
6580
|
};
|
|
5884
6581
|
}, [themeBundle, buttonsTheme, stylesOverride]);
|
|
5885
6582
|
const skeletonRadius = themeBundle?.buttonsLayout?.cardButton?.borderRadius ?? themeBundle?.appearance.variables?.borderRadius ?? 8;
|
|
5886
|
-
const skeleton = (h) => /* @__PURE__ */
|
|
6583
|
+
const skeleton = (h) => /* @__PURE__ */ jsx8("div", { style: {
|
|
5887
6584
|
height: h,
|
|
5888
6585
|
borderRadius: skeletonRadius,
|
|
5889
6586
|
background: "#e5e7eb",
|
|
@@ -5930,7 +6627,7 @@ function InterimButtonsView({
|
|
|
5930
6627
|
...bStyles.backButton
|
|
5931
6628
|
},
|
|
5932
6629
|
children: [
|
|
5933
|
-
/* @__PURE__ */
|
|
6630
|
+
/* @__PURE__ */ jsx8("span", { style: {
|
|
5934
6631
|
display: "inline-flex",
|
|
5935
6632
|
alignItems: "center",
|
|
5936
6633
|
justifyContent: "center",
|
|
@@ -5939,12 +6636,12 @@ function InterimButtonsView({
|
|
|
5939
6636
|
borderRadius: "50%",
|
|
5940
6637
|
backgroundColor: "#f3f4f6",
|
|
5941
6638
|
...bStyles.backButtonIcon
|
|
5942
|
-
}, children: /* @__PURE__ */
|
|
5943
|
-
/* @__PURE__ */
|
|
6639
|
+
}, children: /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "M15 18l-6-6 6-6" }) }) }),
|
|
6640
|
+
/* @__PURE__ */ jsx8(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
5944
6641
|
]
|
|
5945
6642
|
}
|
|
5946
6643
|
),
|
|
5947
|
-
hideTitle ? /* @__PURE__ */
|
|
6644
|
+
hideTitle ? /* @__PURE__ */ jsx8("div", { style: { flex: 1 } }) : /* @__PURE__ */ jsx8("div", { style: {
|
|
5948
6645
|
flex: 1,
|
|
5949
6646
|
textAlign: "center",
|
|
5950
6647
|
fontWeight: 600,
|
|
@@ -5952,11 +6649,11 @@ function InterimButtonsView({
|
|
|
5952
6649
|
color: "#262833",
|
|
5953
6650
|
paddingRight: 80,
|
|
5954
6651
|
...bStyles.title
|
|
5955
|
-
}, children: /* @__PURE__ */
|
|
6652
|
+
}, children: /* @__PURE__ */ jsx8(TitleContentSlot, { content: cardTitleContent }) })
|
|
5956
6653
|
] }),
|
|
5957
|
-
/* @__PURE__ */
|
|
6654
|
+
/* @__PURE__ */ jsx8("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx8("div", { style: { width: "60%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
5958
6655
|
/* @__PURE__ */ jsxs5("div", { style: { display: "flex" }, children: [
|
|
5959
|
-
/* @__PURE__ */
|
|
6656
|
+
/* @__PURE__ */ jsx8("div", { style: {
|
|
5960
6657
|
flex: 1,
|
|
5961
6658
|
backgroundColor: inputBg,
|
|
5962
6659
|
borderTop: "none",
|
|
@@ -5966,8 +6663,8 @@ function InterimButtonsView({
|
|
|
5966
6663
|
borderBottomLeftRadius: 8,
|
|
5967
6664
|
padding: 12,
|
|
5968
6665
|
height: 45
|
|
5969
|
-
}, children: /* @__PURE__ */
|
|
5970
|
-
/* @__PURE__ */
|
|
6666
|
+
}, children: /* @__PURE__ */ jsx8("div", { style: { width: "50%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
6667
|
+
/* @__PURE__ */ jsx8("div", { style: {
|
|
5971
6668
|
flex: 1,
|
|
5972
6669
|
backgroundColor: inputBg,
|
|
5973
6670
|
borderTop: "none",
|
|
@@ -5977,10 +6674,10 @@ function InterimButtonsView({
|
|
|
5977
6674
|
borderBottomRightRadius: 8,
|
|
5978
6675
|
padding: 12,
|
|
5979
6676
|
height: 45
|
|
5980
|
-
}, children: /* @__PURE__ */
|
|
6677
|
+
}, children: /* @__PURE__ */ jsx8("div", { style: { width: "40%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) })
|
|
5981
6678
|
] }),
|
|
5982
|
-
/* @__PURE__ */
|
|
5983
|
-
/* @__PURE__ */
|
|
6679
|
+
/* @__PURE__ */ jsx8("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx8("div", { style: { width: "45%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
6680
|
+
/* @__PURE__ */ jsx8("div", { style: {
|
|
5984
6681
|
height: 50,
|
|
5985
6682
|
borderRadius: 8,
|
|
5986
6683
|
marginTop: 16,
|
|
@@ -5989,7 +6686,7 @@ function InterimButtonsView({
|
|
|
5989
6686
|
...bStyles.submitButton,
|
|
5990
6687
|
opacity: 0.5
|
|
5991
6688
|
} }),
|
|
5992
|
-
/* @__PURE__ */
|
|
6689
|
+
/* @__PURE__ */ jsx8("style", { children: `
|
|
5993
6690
|
@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
5994
6691
|
@keyframes flopay-interim-expand {
|
|
5995
6692
|
0% { opacity: 0; max-height: 0; transform: translateY(-12px); }
|
|
@@ -6002,7 +6699,7 @@ function InterimButtonsView({
|
|
|
6002
6699
|
return /* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
6003
6700
|
showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
6004
6701
|
showStripe && (showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
6005
|
-
showStripe && /* @__PURE__ */
|
|
6702
|
+
showStripe && /* @__PURE__ */ jsx8(
|
|
6006
6703
|
"button",
|
|
6007
6704
|
{
|
|
6008
6705
|
type: "button",
|
|
@@ -6042,7 +6739,7 @@ function InterimButtonsView({
|
|
|
6042
6739
|
onMouseUp: (e) => {
|
|
6043
6740
|
e.currentTarget.style.transform = "scale(1)";
|
|
6044
6741
|
},
|
|
6045
|
-
children: /* @__PURE__ */
|
|
6742
|
+
children: /* @__PURE__ */ jsx8(CardButtonContentSlot, { content: cardButtonContent })
|
|
6046
6743
|
}
|
|
6047
6744
|
),
|
|
6048
6745
|
errorMessage && /* @__PURE__ */ jsxs5("div", { style: {
|
|
@@ -6059,22 +6756,22 @@ function InterimButtonsView({
|
|
|
6059
6756
|
gap: "0.5rem",
|
|
6060
6757
|
...bStyles.errorBanner
|
|
6061
6758
|
}, children: [
|
|
6062
|
-
/* @__PURE__ */
|
|
6759
|
+
/* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx8("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" }) }),
|
|
6063
6760
|
errorMessage
|
|
6064
6761
|
] }),
|
|
6065
|
-
/* @__PURE__ */
|
|
6762
|
+
/* @__PURE__ */ jsx8("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
6066
6763
|
] });
|
|
6067
6764
|
}
|
|
6068
6765
|
|
|
6069
6766
|
// src/checkout-form.tsx
|
|
6070
6767
|
import { PaymentAPI as PaymentAPI5 } from "@flopay/js";
|
|
6071
6768
|
import { FloPayError as FloPayError6 } from "@flopay/shared";
|
|
6072
|
-
import { forwardRef as forwardRef2, useCallback as useCallback3, useEffect as
|
|
6073
|
-
import { Fragment as Fragment4, jsx as
|
|
6769
|
+
import { forwardRef as forwardRef2, useCallback as useCallback3, useEffect as useEffect7, useImperativeHandle as useImperativeHandle2, useState as useState5 } from "react";
|
|
6770
|
+
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
6074
6771
|
var WALLET_RESUME_KEY = "flopay_wallet_resume";
|
|
6075
6772
|
var CheckoutForm = forwardRef2(
|
|
6076
6773
|
function CheckoutForm2(props, ref) {
|
|
6077
|
-
return /* @__PURE__ */
|
|
6774
|
+
return /* @__PURE__ */ jsx9(CheckoutFormInner, { ...props, innerRef: ref });
|
|
6078
6775
|
}
|
|
6079
6776
|
);
|
|
6080
6777
|
function CheckoutFormInner({
|
|
@@ -6273,7 +6970,7 @@ function CheckoutFormInner({
|
|
|
6273
6970
|
}
|
|
6274
6971
|
}
|
|
6275
6972
|
}), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
|
|
6276
|
-
|
|
6973
|
+
useEffect7(() => {
|
|
6277
6974
|
if (typeof window === "undefined") return;
|
|
6278
6975
|
const stored = localStorage.getItem(WALLET_RESUME_KEY);
|
|
6279
6976
|
if (!stored) return;
|
|
@@ -6384,7 +7081,7 @@ function CheckoutFormInner({
|
|
|
6384
7081
|
);
|
|
6385
7082
|
const isReady = flopay !== null && elements !== null;
|
|
6386
7083
|
return /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
6387
|
-
(is3DSActive || isSubmitting) && /* @__PURE__ */
|
|
7084
|
+
(is3DSActive || isSubmitting) && /* @__PURE__ */ jsx9("div", { "data-testid": "flopay-overlay", style: {
|
|
6388
7085
|
position: "absolute",
|
|
6389
7086
|
inset: 0,
|
|
6390
7087
|
background: "rgba(255,255,255,0.7)",
|
|
@@ -6393,12 +7090,12 @@ function CheckoutFormInner({
|
|
|
6393
7090
|
justifyContent: "center",
|
|
6394
7091
|
zIndex: 10
|
|
6395
7092
|
}, children: is3DSActive ? "Verifying payment..." : "Processing..." }),
|
|
6396
|
-
!isReady && /* @__PURE__ */
|
|
7093
|
+
!isReady && /* @__PURE__ */ jsx9("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." }),
|
|
6397
7094
|
isReady && /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
6398
|
-
/* @__PURE__ */
|
|
6399
|
-
showAddress && /* @__PURE__ */
|
|
6400
|
-
displayError && /* @__PURE__ */
|
|
6401
|
-
children ?? /* @__PURE__ */
|
|
7095
|
+
/* @__PURE__ */ jsx9(PaymentElement, { options: { layout } }),
|
|
7096
|
+
showAddress && /* @__PURE__ */ jsx9(AddressElement, { options: { mode: showAddress === true ? "billing" : showAddress } }),
|
|
7097
|
+
displayError && /* @__PURE__ */ jsx9("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0" }, children: displayError }),
|
|
7098
|
+
children ?? /* @__PURE__ */ jsx9(
|
|
6402
7099
|
"button",
|
|
6403
7100
|
{
|
|
6404
7101
|
type: "submit",
|
|
@@ -6414,8 +7111,8 @@ function CheckoutFormInner({
|
|
|
6414
7111
|
// src/paypal-button.tsx
|
|
6415
7112
|
import { PaymentAPI as PaymentAPI6 } from "@flopay/js";
|
|
6416
7113
|
import { FloPayError as FloPayError7 } from "@flopay/shared";
|
|
6417
|
-
import { useCallback as useCallback4, useEffect as
|
|
6418
|
-
import { Fragment as Fragment5, jsx as
|
|
7114
|
+
import { useCallback as useCallback4, useEffect as useEffect8, useRef as useRef6, useState as useState6 } from "react";
|
|
7115
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
6419
7116
|
function PayPalButton({
|
|
6420
7117
|
sessionId,
|
|
6421
7118
|
nonce,
|
|
@@ -6435,7 +7132,7 @@ function PayPalButton({
|
|
|
6435
7132
|
const contextBillingUrl = useBillingApiUrl();
|
|
6436
7133
|
const [ready, setReady] = useState6(false);
|
|
6437
7134
|
const [submitting, setSubmitting] = useState6(false);
|
|
6438
|
-
const paypalResumeAttempted =
|
|
7135
|
+
const paypalResumeAttempted = useRef6(false);
|
|
6439
7136
|
const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
|
|
6440
7137
|
const processPaymentInternal = useCallback4(
|
|
6441
7138
|
async (tokenizedBody) => {
|
|
@@ -6475,7 +7172,7 @@ function PayPalButton({
|
|
|
6475
7172
|
},
|
|
6476
7173
|
[onTokenizedBody, processPaymentInternal]
|
|
6477
7174
|
);
|
|
6478
|
-
|
|
7175
|
+
useEffect8(() => {
|
|
6479
7176
|
if (!flopay || paypalResumeAttempted.current) return;
|
|
6480
7177
|
const params = new URLSearchParams(window.location.search);
|
|
6481
7178
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -6557,11 +7254,11 @@ function PayPalButton({
|
|
|
6557
7254
|
}
|
|
6558
7255
|
}, [flopay, elements, sessionId, nonce, email, baseUrl, dispatchTokenizedBody, onErrorChange]);
|
|
6559
7256
|
if (!flopay || !elements) {
|
|
6560
|
-
return /* @__PURE__ */
|
|
7257
|
+
return /* @__PURE__ */ jsx10("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6, animation: "pulse 1.5s infinite" } });
|
|
6561
7258
|
}
|
|
6562
7259
|
return /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
6563
|
-
!ready && /* @__PURE__ */
|
|
6564
|
-
/* @__PURE__ */
|
|
7260
|
+
!ready && /* @__PURE__ */ jsx10("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6 } }),
|
|
7261
|
+
/* @__PURE__ */ jsx10("div", { style: ready ? {} : { display: "none" }, children: /* @__PURE__ */ jsx10(
|
|
6565
7262
|
"button",
|
|
6566
7263
|
{
|
|
6567
7264
|
type: "button",
|
|
@@ -6583,7 +7280,7 @@ function PayPalButton({
|
|
|
6583
7280
|
children: submitting ? "Processing..." : "PayPal"
|
|
6584
7281
|
}
|
|
6585
7282
|
) }),
|
|
6586
|
-
(submitting || isProcessing) && /* @__PURE__ */
|
|
7283
|
+
(submitting || isProcessing) && /* @__PURE__ */ jsx10("div", { style: {
|
|
6587
7284
|
position: "fixed",
|
|
6588
7285
|
inset: 0,
|
|
6589
7286
|
background: "rgba(0,0,0,0.4)",
|
|
@@ -6591,7 +7288,7 @@ function PayPalButton({
|
|
|
6591
7288
|
alignItems: "center",
|
|
6592
7289
|
justifyContent: "center",
|
|
6593
7290
|
zIndex: 1e3
|
|
6594
|
-
}, children: /* @__PURE__ */
|
|
7291
|
+
}, children: /* @__PURE__ */ jsx10("div", { style: {
|
|
6595
7292
|
background: "white",
|
|
6596
7293
|
borderRadius: 8,
|
|
6597
7294
|
padding: "1.5rem",
|
|
@@ -6603,10 +7300,10 @@ function PayPalButton({
|
|
|
6603
7300
|
}
|
|
6604
7301
|
|
|
6605
7302
|
// src/automatic-payment-button.tsx
|
|
6606
|
-
import { useCallback as useCallback5, useEffect as
|
|
7303
|
+
import { useCallback as useCallback5, useEffect as useEffect9, useMemo as useMemo5, useRef as useRef7, useState as useState7 } from "react";
|
|
6607
7304
|
import { PaymentAPI as PaymentAPI7 } from "@flopay/js";
|
|
6608
7305
|
import { FloPayError as FloPayError8, resolveBillingApiUrl as resolveBillingApiUrl4, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme3, resolveTheme as resolveTheme3 } from "@flopay/shared";
|
|
6609
|
-
import { Fragment as Fragment6, jsx as
|
|
7306
|
+
import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
6610
7307
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3 = 44;
|
|
6611
7308
|
function sleep2(ms) {
|
|
6612
7309
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -6674,6 +7371,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
6674
7371
|
billingApiUrl,
|
|
6675
7372
|
locale,
|
|
6676
7373
|
theme,
|
|
7374
|
+
appearance,
|
|
6677
7375
|
buttonsTheme,
|
|
6678
7376
|
buttonsStyles: stylesOverride,
|
|
6679
7377
|
onSuccess,
|
|
@@ -6721,30 +7419,32 @@ function FloPayAutomaticPaymentButton({
|
|
|
6721
7419
|
const [overlayStatus, setOverlayStatus] = useState7(null);
|
|
6722
7420
|
const [overlayError, setOverlayError] = useState7(null);
|
|
6723
7421
|
const [fallbackSession, setFallbackSession] = useState7(null);
|
|
6724
|
-
const isMountedRef =
|
|
6725
|
-
const
|
|
6726
|
-
const
|
|
6727
|
-
const
|
|
6728
|
-
const
|
|
6729
|
-
|
|
7422
|
+
const isMountedRef = useRef7(true);
|
|
7423
|
+
const threeDsAbortRef = useRef7(null);
|
|
7424
|
+
const fallbackSessionRef = useRef7(fallbackSession);
|
|
7425
|
+
const onSuccessRef = useRef7(onSuccess);
|
|
7426
|
+
const onErrorRef = useRef7(onError);
|
|
7427
|
+
const onDeclineRef = useRef7(onDecline);
|
|
7428
|
+
useEffect9(() => {
|
|
6730
7429
|
fallbackSessionRef.current = fallbackSession;
|
|
6731
7430
|
}, [fallbackSession]);
|
|
6732
|
-
|
|
7431
|
+
useEffect9(() => {
|
|
6733
7432
|
onSuccessRef.current = onSuccess;
|
|
6734
7433
|
}, [onSuccess]);
|
|
6735
|
-
|
|
7434
|
+
useEffect9(() => {
|
|
6736
7435
|
onErrorRef.current = onError;
|
|
6737
7436
|
}, [onError]);
|
|
6738
|
-
|
|
7437
|
+
useEffect9(() => {
|
|
6739
7438
|
onDeclineRef.current = onDecline;
|
|
6740
7439
|
}, [onDecline]);
|
|
6741
|
-
|
|
7440
|
+
useEffect9(() => {
|
|
6742
7441
|
isMountedRef.current = true;
|
|
6743
7442
|
return () => {
|
|
6744
7443
|
isMountedRef.current = false;
|
|
7444
|
+
threeDsAbortRef.current?.abort();
|
|
6745
7445
|
};
|
|
6746
7446
|
}, []);
|
|
6747
|
-
|
|
7447
|
+
useEffect9(() => {
|
|
6748
7448
|
if (!fallbackSession || typeof window === "undefined") {
|
|
6749
7449
|
return;
|
|
6750
7450
|
}
|
|
@@ -6823,6 +7523,62 @@ function FloPayAutomaticPaymentButton({
|
|
|
6823
7523
|
return;
|
|
6824
7524
|
}
|
|
6825
7525
|
if (apiResult.autoProcessingError) {
|
|
7526
|
+
if (apiResult.autoProcessingError.type === "3ds_required" && apiResult.autoProcessingError.nextActionRedirectUrl && resolvedSessionId && effectiveNonce) {
|
|
7527
|
+
const threeDsAbort = new AbortController();
|
|
7528
|
+
threeDsAbortRef.current = threeDsAbort;
|
|
7529
|
+
let outcome;
|
|
7530
|
+
try {
|
|
7531
|
+
outcome = await runAutoCheckoutThreeDsChallenge({
|
|
7532
|
+
billingApiUrl: resolvedBillingUrl,
|
|
7533
|
+
sessionId: resolvedSessionId,
|
|
7534
|
+
nonce: effectiveNonce,
|
|
7535
|
+
nextActionRedirectUrl: apiResult.autoProcessingError.nextActionRedirectUrl,
|
|
7536
|
+
signal: threeDsAbort.signal
|
|
7537
|
+
});
|
|
7538
|
+
} finally {
|
|
7539
|
+
if (threeDsAbortRef.current === threeDsAbort) {
|
|
7540
|
+
threeDsAbortRef.current = null;
|
|
7541
|
+
}
|
|
7542
|
+
}
|
|
7543
|
+
if (outcome.status === "declined") {
|
|
7544
|
+
throw checkoutProcessErrorToFloPayError(
|
|
7545
|
+
{
|
|
7546
|
+
type: outcome.declineReason ?? "decline",
|
|
7547
|
+
message: "Card was declined.",
|
|
7548
|
+
gatewayErrorCode: outcome.gatewayDeclineReason ?? void 0
|
|
7549
|
+
},
|
|
7550
|
+
"Card was declined.",
|
|
7551
|
+
{
|
|
7552
|
+
checkoutMethod: apiResult.autoProcessingError.checkoutMethod
|
|
7553
|
+
}
|
|
7554
|
+
);
|
|
7555
|
+
}
|
|
7556
|
+
const api = new PaymentAPI7(resolvedBillingUrl);
|
|
7557
|
+
const completed = await api.waitForCheckoutSessionCompletion(resolvedSessionId, {
|
|
7558
|
+
initialDelayMs: 0,
|
|
7559
|
+
nonce: effectiveNonce
|
|
7560
|
+
});
|
|
7561
|
+
const completedSession = completed.data.session;
|
|
7562
|
+
if (!completedSession || completedSession.status !== "complete") {
|
|
7563
|
+
throw checkoutProcessErrorToFloPayError(
|
|
7564
|
+
{
|
|
7565
|
+
type: "unknown",
|
|
7566
|
+
message: "Card authentication was not completed."
|
|
7567
|
+
},
|
|
7568
|
+
"Card authentication was not completed.",
|
|
7569
|
+
{
|
|
7570
|
+
checkoutMethod: apiResult.autoProcessingError.checkoutMethod
|
|
7571
|
+
}
|
|
7572
|
+
);
|
|
7573
|
+
}
|
|
7574
|
+
await showSuccess({
|
|
7575
|
+
result: { status: "succeeded" },
|
|
7576
|
+
session: completedSession,
|
|
7577
|
+
sessionId: completedSession.id || resolvedSessionId,
|
|
7578
|
+
autoCompleted: false
|
|
7579
|
+
});
|
|
7580
|
+
return;
|
|
7581
|
+
}
|
|
6826
7582
|
throw checkoutProcessErrorToFloPayError(
|
|
6827
7583
|
apiResult.autoProcessingError,
|
|
6828
7584
|
"Automatic payment failed. Please try again.",
|
|
@@ -6990,9 +7746,26 @@ function FloPayAutomaticPaymentButton({
|
|
|
6990
7746
|
cardButton: { ...base.cardButton, ...stylesOverride.cardButton }
|
|
6991
7747
|
};
|
|
6992
7748
|
}, [themeBundle, buttonsTheme, stylesOverride]);
|
|
7749
|
+
const resolvedAppearance = useMemo5(() => {
|
|
7750
|
+
const bundleAppearance = themeBundle?.appearance;
|
|
7751
|
+
if (!appearance) return bundleAppearance;
|
|
7752
|
+
if (!bundleAppearance) return appearance;
|
|
7753
|
+
return {
|
|
7754
|
+
...bundleAppearance,
|
|
7755
|
+
...appearance,
|
|
7756
|
+
variables: {
|
|
7757
|
+
...bundleAppearance.variables,
|
|
7758
|
+
...appearance.variables
|
|
7759
|
+
}
|
|
7760
|
+
};
|
|
7761
|
+
}, [appearance, themeBundle]);
|
|
7762
|
+
const resolvedAppearanceVars = resolvedAppearance?.variables;
|
|
7763
|
+
const resolvedPrimaryColor = resolvedAppearanceVars?.colorPrimary ?? "#4A49FF";
|
|
7764
|
+
const resolvedPrimaryHoverColor = resolvedAppearanceVars?.colorPrimaryHover ?? darkenHex(resolvedPrimaryColor, 0.12);
|
|
7765
|
+
const resolvedButtonBorderRadius = resolvedAppearanceVars?.borderRadius ?? "8px";
|
|
6993
7766
|
const cardButtonSizing = children === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
6994
7767
|
return /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
6995
|
-
/* @__PURE__ */
|
|
7768
|
+
/* @__PURE__ */ jsx11(
|
|
6996
7769
|
"button",
|
|
6997
7770
|
{
|
|
6998
7771
|
...buttonProps,
|
|
@@ -7008,14 +7781,17 @@ function FloPayAutomaticPaymentButton({
|
|
|
7008
7781
|
// on top so the auto-pay button carries the *submit* button's
|
|
7009
7782
|
// background and text colours — making it visually identical to
|
|
7010
7783
|
// the "Confirm Payment" / "Pay with X" actions it stands in for.
|
|
7784
|
+
// `resolvedPrimaryColor` is the *merged* appearance value, so a
|
|
7785
|
+
// per-checkout `colorPrimary` override re-skins this button too.
|
|
7011
7786
|
// Inline `style` consumer override stays at the end so explicit
|
|
7012
7787
|
// per-button overrides still win.
|
|
7013
7788
|
...bStyles.cardButton,
|
|
7014
7789
|
...derivePrimaryTileStyle({
|
|
7015
7790
|
themeBundle,
|
|
7016
|
-
resolvedPrimaryColor
|
|
7017
|
-
resolvedBorderRadius:
|
|
7018
|
-
submitButtonStyle: bStyles.submitButton
|
|
7791
|
+
resolvedPrimaryColor,
|
|
7792
|
+
resolvedBorderRadius: resolvedButtonBorderRadius,
|
|
7793
|
+
submitButtonStyle: bStyles.submitButton,
|
|
7794
|
+
explicitPrimaryColor: resolvedAppearanceVars?.colorPrimary
|
|
7019
7795
|
}),
|
|
7020
7796
|
fontSize: bStyles.cardButtonFontSize ?? "0.95rem",
|
|
7021
7797
|
fontWeight: 600,
|
|
@@ -7024,11 +7800,23 @@ function FloPayAutomaticPaymentButton({
|
|
|
7024
7800
|
alignItems: "center",
|
|
7025
7801
|
justifyContent: "center",
|
|
7026
7802
|
gap: "0.625rem",
|
|
7027
|
-
transition: "border-color 0.2s, box-shadow 0.2s, transform 0.1s",
|
|
7803
|
+
transition: "background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s",
|
|
7028
7804
|
position: "relative",
|
|
7029
7805
|
opacity: disabled || isProcessing ? 0.6 : 1,
|
|
7030
7806
|
...style
|
|
7031
7807
|
},
|
|
7808
|
+
onMouseEnter: (e) => {
|
|
7809
|
+
buttonProps.onMouseEnter?.(e);
|
|
7810
|
+
if (!e.defaultPrevented && !disabled && !isProcessing && (themeBundle || resolvedAppearanceVars?.colorPrimary)) {
|
|
7811
|
+
e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;
|
|
7812
|
+
}
|
|
7813
|
+
},
|
|
7814
|
+
onMouseLeave: (e) => {
|
|
7815
|
+
buttonProps.onMouseLeave?.(e);
|
|
7816
|
+
if (!e.defaultPrevented && (themeBundle || resolvedAppearanceVars?.colorPrimary)) {
|
|
7817
|
+
e.currentTarget.style.backgroundColor = resolvedPrimaryColor;
|
|
7818
|
+
}
|
|
7819
|
+
},
|
|
7032
7820
|
onMouseDown: (e) => {
|
|
7033
7821
|
buttonProps.onMouseDown?.(e);
|
|
7034
7822
|
if (!e.defaultPrevented) {
|
|
@@ -7041,17 +7829,17 @@ function FloPayAutomaticPaymentButton({
|
|
|
7041
7829
|
e.currentTarget.style.transform = "scale(1)";
|
|
7042
7830
|
}
|
|
7043
7831
|
},
|
|
7044
|
-
children: /* @__PURE__ */
|
|
7832
|
+
children: /* @__PURE__ */ jsx11(CardButtonContentSlot, { content: children })
|
|
7045
7833
|
}
|
|
7046
7834
|
),
|
|
7047
|
-
overlayStatus && /* @__PURE__ */
|
|
7835
|
+
overlayStatus && /* @__PURE__ */ jsx11(
|
|
7048
7836
|
ProcessingOverlay,
|
|
7049
7837
|
{
|
|
7050
7838
|
status: overlayStatus,
|
|
7051
7839
|
errorMessage: overlayError
|
|
7052
7840
|
}
|
|
7053
7841
|
),
|
|
7054
|
-
fallbackSession && /* @__PURE__ */
|
|
7842
|
+
fallbackSession && /* @__PURE__ */ jsx11(
|
|
7055
7843
|
"div",
|
|
7056
7844
|
{
|
|
7057
7845
|
"data-testid": "flopay-automatic-payment-fallback",
|
|
@@ -7072,7 +7860,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
7072
7860
|
padding: "1.5rem",
|
|
7073
7861
|
zIndex: 1100
|
|
7074
7862
|
},
|
|
7075
|
-
children: /* @__PURE__ */
|
|
7863
|
+
children: /* @__PURE__ */ jsx11(
|
|
7076
7864
|
"div",
|
|
7077
7865
|
{
|
|
7078
7866
|
style: {
|
|
@@ -7088,7 +7876,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
7088
7876
|
flexDirection: "column",
|
|
7089
7877
|
gap: "1rem"
|
|
7090
7878
|
},
|
|
7091
|
-
children: /* @__PURE__ */
|
|
7879
|
+
children: /* @__PURE__ */ jsx11(
|
|
7092
7880
|
FloPayCheckout,
|
|
7093
7881
|
{
|
|
7094
7882
|
sessionId: fallbackSession.sessionId,
|
|
@@ -7097,6 +7885,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
7097
7885
|
billingApiUrl: resolvedBillingUrl,
|
|
7098
7886
|
locale,
|
|
7099
7887
|
theme,
|
|
7888
|
+
...resolvedAppearance ? { appearance: resolvedAppearance } : {},
|
|
7100
7889
|
buttonsTheme,
|
|
7101
7890
|
buttonsStyles: stylesOverride,
|
|
7102
7891
|
initialErrorMessage: fallbackSession.errorMessage,
|
|
@@ -7126,6 +7915,7 @@ export {
|
|
|
7126
7915
|
PayPalButton,
|
|
7127
7916
|
PaymentElement,
|
|
7128
7917
|
SplitCardForm,
|
|
7918
|
+
VaultCardFields,
|
|
7129
7919
|
useCheckout,
|
|
7130
7920
|
useElements,
|
|
7131
7921
|
useFloPay,
|