@flopay/react 1.2.8 → 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 +1387 -634
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +104 -4
- package/dist/index.d.ts +104 -4
- package/dist/index.mjs +1187 -437
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
PayPalButton: () => PayPalButton,
|
|
44
44
|
PaymentElement: () => PaymentElement,
|
|
45
45
|
SplitCardForm: () => SplitCardForm,
|
|
46
|
+
VaultCardFields: () => VaultCardFields,
|
|
46
47
|
useCheckout: () => useCheckout,
|
|
47
48
|
useElements: () => useElements,
|
|
48
49
|
useFloPay: () => useFloPay,
|
|
@@ -152,7 +153,7 @@ function FloPayProvider({
|
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
// src/flopay-checkout.tsx
|
|
155
|
-
var
|
|
156
|
+
var import_react10 = __toESM(require("react"), 1);
|
|
156
157
|
var import_js4 = require("@flopay/js");
|
|
157
158
|
var import_shared8 = require("@flopay/shared");
|
|
158
159
|
|
|
@@ -287,41 +288,114 @@ var AddressElement = createElementComponent("address", "AddressElement");
|
|
|
287
288
|
var import_react_stripe_js = require("@stripe/react-stripe-js");
|
|
288
289
|
var import_shared5 = require("@flopay/shared");
|
|
289
290
|
var import_js2 = require("@flopay/js");
|
|
290
|
-
var import_react8 = __toESM(require("react"), 1);
|
|
291
291
|
|
|
292
|
-
// src/
|
|
292
|
+
// src/vault-card-fields.tsx
|
|
293
293
|
var import_react5 = require("react");
|
|
294
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
295
|
+
function VaultCardFields({
|
|
296
|
+
capture,
|
|
297
|
+
html,
|
|
298
|
+
messageToken,
|
|
299
|
+
expectedOrigin,
|
|
300
|
+
theme,
|
|
301
|
+
containerStyle,
|
|
302
|
+
onReady,
|
|
303
|
+
onError,
|
|
304
|
+
onValidation
|
|
305
|
+
}) {
|
|
306
|
+
const containerRef = (0, import_react5.useRef)(null);
|
|
307
|
+
const onReadyRef = (0, import_react5.useRef)(onReady);
|
|
308
|
+
const onErrorRef = (0, import_react5.useRef)(onError);
|
|
309
|
+
const onValidationRef = (0, import_react5.useRef)(onValidation);
|
|
310
|
+
onReadyRef.current = onReady;
|
|
311
|
+
onErrorRef.current = onError;
|
|
312
|
+
onValidationRef.current = onValidation;
|
|
313
|
+
const themeRef = (0, import_react5.useRef)(theme);
|
|
314
|
+
themeRef.current = theme;
|
|
315
|
+
(0, import_react5.useEffect)(() => {
|
|
316
|
+
const el = containerRef.current;
|
|
317
|
+
if (!el) return;
|
|
318
|
+
let active = true;
|
|
319
|
+
let readyEmitted = false;
|
|
320
|
+
const emitReadyOnce = () => {
|
|
321
|
+
if (!active || readyEmitted) return;
|
|
322
|
+
readyEmitted = true;
|
|
323
|
+
onReadyRef.current?.();
|
|
324
|
+
};
|
|
325
|
+
const offReady = capture.on("ready", () => {
|
|
326
|
+
emitReadyOnce();
|
|
327
|
+
});
|
|
328
|
+
const offError = capture.on("error", (event) => {
|
|
329
|
+
onErrorRef.current?.(event.message ?? "There was a problem loading the secure card form.");
|
|
330
|
+
});
|
|
331
|
+
const offValidation = capture.on("validation", (event) => {
|
|
332
|
+
onValidationRef.current?.(event.message ?? null);
|
|
333
|
+
});
|
|
334
|
+
const mountOptions = {
|
|
335
|
+
html,
|
|
336
|
+
...messageToken ? { messageToken } : {},
|
|
337
|
+
...expectedOrigin ? { expectedOrigin } : {},
|
|
338
|
+
...themeRef.current ? { theme: themeRef.current } : {}
|
|
339
|
+
};
|
|
340
|
+
capture.mount(el, mountOptions).then(() => {
|
|
341
|
+
emitReadyOnce();
|
|
342
|
+
}).catch((err) => {
|
|
343
|
+
if (active) {
|
|
344
|
+
onErrorRef.current?.(
|
|
345
|
+
err instanceof Error ? err.message : "Failed to load the secure card form."
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
return () => {
|
|
350
|
+
active = false;
|
|
351
|
+
offReady();
|
|
352
|
+
offError();
|
|
353
|
+
offValidation();
|
|
354
|
+
capture.unmount();
|
|
355
|
+
};
|
|
356
|
+
}, [capture, html, messageToken, expectedOrigin]);
|
|
357
|
+
(0, import_react5.useEffect)(() => {
|
|
358
|
+
if (theme) capture.applyTheme?.(theme);
|
|
359
|
+
}, [capture, theme]);
|
|
360
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref: containerRef, "data-testid": "flopay-vault-card-fields", style: containerStyle });
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// src/split-card-form.tsx
|
|
364
|
+
var import_react9 = __toESM(require("react"), 1);
|
|
365
|
+
|
|
366
|
+
// src/hooks.ts
|
|
367
|
+
var import_react6 = require("react");
|
|
294
368
|
var import_shared2 = require("@flopay/shared");
|
|
295
369
|
function useFloPay() {
|
|
296
|
-
const ctx = (0,
|
|
370
|
+
const ctx = (0, import_react6.useContext)(FloPayContext);
|
|
297
371
|
return ctx.flopay;
|
|
298
372
|
}
|
|
299
373
|
function usePayPalFloPay() {
|
|
300
|
-
const ctx = (0,
|
|
374
|
+
const ctx = (0, import_react6.useContext)(FloPayContext);
|
|
301
375
|
return ctx.paypalFlopay ?? null;
|
|
302
376
|
}
|
|
303
377
|
function useElements() {
|
|
304
|
-
const ctx = (0,
|
|
378
|
+
const ctx = (0, import_react6.useContext)(FloPayContext);
|
|
305
379
|
return ctx.elements;
|
|
306
380
|
}
|
|
307
381
|
function useCheckout() {
|
|
308
|
-
return (0,
|
|
382
|
+
return (0, import_react6.useContext)(CheckoutContext);
|
|
309
383
|
}
|
|
310
384
|
function useBillingApiUrl() {
|
|
311
|
-
const ctx = (0,
|
|
385
|
+
const ctx = (0, import_react6.useContext)(FloPayContext);
|
|
312
386
|
return ctx.billingApiUrl || (0, import_shared2.resolveBillingApiUrl)();
|
|
313
387
|
}
|
|
314
388
|
|
|
315
389
|
// src/processing-overlay.tsx
|
|
316
|
-
var
|
|
317
|
-
var
|
|
390
|
+
var import_react7 = require("react");
|
|
391
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
318
392
|
var PROCESSING_OVERLAY_SUCCESS_DELAY_MS = 1200;
|
|
319
393
|
var PROCESSING_OVERLAY_ERROR_DELAY_MS = 1500;
|
|
320
394
|
function ProcessingOverlay({
|
|
321
395
|
status,
|
|
322
396
|
errorMessage
|
|
323
397
|
}) {
|
|
324
|
-
return /* @__PURE__ */ (0,
|
|
398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
325
399
|
"div",
|
|
326
400
|
{
|
|
327
401
|
"data-testid": "flopay-processing-overlay",
|
|
@@ -338,7 +412,7 @@ function ProcessingOverlay({
|
|
|
338
412
|
zIndex: 1e3,
|
|
339
413
|
backdropFilter: "blur(2px)"
|
|
340
414
|
},
|
|
341
|
-
children: /* @__PURE__ */ (0,
|
|
415
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
342
416
|
"div",
|
|
343
417
|
{
|
|
344
418
|
style: {
|
|
@@ -354,8 +428,8 @@ function ProcessingOverlay({
|
|
|
354
428
|
gap: 16
|
|
355
429
|
},
|
|
356
430
|
children: [
|
|
357
|
-
/* @__PURE__ */ (0,
|
|
358
|
-
status === "processing" && /* @__PURE__ */ (0,
|
|
431
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { width: 48, height: 48, position: "relative" }, children: [
|
|
432
|
+
status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
359
433
|
"svg",
|
|
360
434
|
{
|
|
361
435
|
width: "48",
|
|
@@ -365,14 +439,14 @@ function ProcessingOverlay({
|
|
|
365
439
|
xmlns: "http://www.w3.org/2000/svg",
|
|
366
440
|
style: { animation: "flopay-spin 0.8s linear infinite" },
|
|
367
441
|
children: [
|
|
368
|
-
/* @__PURE__ */ (0,
|
|
369
|
-
/* @__PURE__ */ (0,
|
|
442
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "12", r: "10", stroke: "#e5e7eb", strokeWidth: "3" }),
|
|
443
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z", fill: "#4A49FF" })
|
|
370
444
|
]
|
|
371
445
|
}
|
|
372
446
|
),
|
|
373
|
-
status === "success" && /* @__PURE__ */ (0,
|
|
374
|
-
/* @__PURE__ */ (0,
|
|
375
|
-
/* @__PURE__ */ (0,
|
|
447
|
+
status === "success" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { animation: "flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
448
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "12", r: "11", fill: "#22c55e" }),
|
|
449
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
376
450
|
"path",
|
|
377
451
|
{
|
|
378
452
|
d: "M7 12.5l3 3 7-7",
|
|
@@ -388,9 +462,9 @@ function ProcessingOverlay({
|
|
|
388
462
|
}
|
|
389
463
|
)
|
|
390
464
|
] }) }),
|
|
391
|
-
status === "error" && /* @__PURE__ */ (0,
|
|
392
|
-
/* @__PURE__ */ (0,
|
|
393
|
-
/* @__PURE__ */ (0,
|
|
465
|
+
status === "error" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { animation: "flopay-shake 0.4s ease" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
466
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "12", r: "11", fill: "#ef4444" }),
|
|
467
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
394
468
|
"path",
|
|
395
469
|
{
|
|
396
470
|
d: "M8 8l8 8M16 8l-8 8",
|
|
@@ -406,7 +480,7 @@ function ProcessingOverlay({
|
|
|
406
480
|
)
|
|
407
481
|
] }) })
|
|
408
482
|
] }),
|
|
409
|
-
/* @__PURE__ */ (0,
|
|
483
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
410
484
|
"span",
|
|
411
485
|
{
|
|
412
486
|
style: {
|
|
@@ -422,7 +496,7 @@ function ProcessingOverlay({
|
|
|
422
496
|
]
|
|
423
497
|
}
|
|
424
498
|
),
|
|
425
|
-
status === "success" && /* @__PURE__ */ (0,
|
|
499
|
+
status === "success" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
426
500
|
"p",
|
|
427
501
|
{
|
|
428
502
|
style: {
|
|
@@ -436,7 +510,7 @@ function ProcessingOverlay({
|
|
|
436
510
|
children: "You will be automatically redirected, do not close or navigate away from this window."
|
|
437
511
|
}
|
|
438
512
|
),
|
|
439
|
-
status === "error" && errorMessage && /* @__PURE__ */ (0,
|
|
513
|
+
status === "error" && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
440
514
|
"p",
|
|
441
515
|
{
|
|
442
516
|
style: {
|
|
@@ -450,7 +524,7 @@ function ProcessingOverlay({
|
|
|
450
524
|
children: errorMessage
|
|
451
525
|
}
|
|
452
526
|
),
|
|
453
|
-
/* @__PURE__ */ (0,
|
|
527
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: `
|
|
454
528
|
@keyframes flopay-spin { to { transform: rotate(360deg); } }
|
|
455
529
|
@keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
|
|
456
530
|
@keyframes flopay-draw { to { stroke-dashoffset: 0; } }
|
|
@@ -724,11 +798,11 @@ function isInAppBrowser(userAgent) {
|
|
|
724
798
|
}
|
|
725
799
|
|
|
726
800
|
// src/direct-paypal-button.tsx
|
|
727
|
-
var
|
|
801
|
+
var import_react8 = require("react");
|
|
728
802
|
var import_paypal_js = require("@paypal/paypal-js");
|
|
729
803
|
var import_js = require("@flopay/js");
|
|
730
804
|
var import_shared4 = require("@flopay/shared");
|
|
731
|
-
var
|
|
805
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
732
806
|
var DEFAULT_BUTTON_HEIGHT = 45;
|
|
733
807
|
function DirectPayPalButton({
|
|
734
808
|
sessionId,
|
|
@@ -751,62 +825,62 @@ function DirectPayPalButton({
|
|
|
751
825
|
existingOrderId,
|
|
752
826
|
debug = false
|
|
753
827
|
}) {
|
|
754
|
-
const containerRef = (0,
|
|
755
|
-
const [ready, setReady] = (0,
|
|
756
|
-
const [failed, setFailed] = (0,
|
|
757
|
-
const [submitting, setSubmitting] = (0,
|
|
758
|
-
const baseUrl = (0,
|
|
759
|
-
const [debugLines, setDebugLines] = (0,
|
|
828
|
+
const containerRef = (0, import_react8.useRef)(null);
|
|
829
|
+
const [ready, setReady] = (0, import_react8.useState)(false);
|
|
830
|
+
const [failed, setFailed] = (0, import_react8.useState)(false);
|
|
831
|
+
const [submitting, setSubmitting] = (0, import_react8.useState)(false);
|
|
832
|
+
const baseUrl = (0, import_react8.useMemo)(() => billingApiUrl.replace(/\/+$/, ""), [billingApiUrl]);
|
|
833
|
+
const [debugLines, setDebugLines] = (0, import_react8.useState)([]);
|
|
760
834
|
const appendDebug = (line) => {
|
|
761
835
|
if (!debug) return;
|
|
762
836
|
setDebugLines((prev) => [...prev, `${(/* @__PURE__ */ new Date()).toISOString().slice(11, 23)} ${line}`]);
|
|
763
837
|
};
|
|
764
|
-
const onTokenizedBodyRef = (0,
|
|
765
|
-
const onCompleteRef = (0,
|
|
766
|
-
const onErrorChangeRef = (0,
|
|
767
|
-
const onDeclineRef = (0,
|
|
768
|
-
const onButtonClickRef = (0,
|
|
769
|
-
const onLoadStateChangeRef = (0,
|
|
770
|
-
const runBeforeButtonClickRef = (0,
|
|
771
|
-
const sessionRef = (0,
|
|
772
|
-
const emailRef = (0,
|
|
773
|
-
const nonceRef = (0,
|
|
774
|
-
const beforeClickRef = (0,
|
|
775
|
-
(0,
|
|
838
|
+
const onTokenizedBodyRef = (0, import_react8.useRef)(onTokenizedBody);
|
|
839
|
+
const onCompleteRef = (0, import_react8.useRef)(onComplete);
|
|
840
|
+
const onErrorChangeRef = (0, import_react8.useRef)(onErrorChange);
|
|
841
|
+
const onDeclineRef = (0, import_react8.useRef)(onDecline);
|
|
842
|
+
const onButtonClickRef = (0, import_react8.useRef)(onButtonClick);
|
|
843
|
+
const onLoadStateChangeRef = (0, import_react8.useRef)(onLoadStateChange);
|
|
844
|
+
const runBeforeButtonClickRef = (0, import_react8.useRef)(runBeforeButtonClick);
|
|
845
|
+
const sessionRef = (0, import_react8.useRef)(session);
|
|
846
|
+
const emailRef = (0, import_react8.useRef)(email);
|
|
847
|
+
const nonceRef = (0, import_react8.useRef)(nonce);
|
|
848
|
+
const beforeClickRef = (0, import_react8.useRef)(null);
|
|
849
|
+
(0, import_react8.useEffect)(() => {
|
|
776
850
|
onTokenizedBodyRef.current = onTokenizedBody;
|
|
777
851
|
}, [onTokenizedBody]);
|
|
778
|
-
(0,
|
|
852
|
+
(0, import_react8.useEffect)(() => {
|
|
779
853
|
onCompleteRef.current = onComplete;
|
|
780
854
|
}, [onComplete]);
|
|
781
|
-
(0,
|
|
855
|
+
(0, import_react8.useEffect)(() => {
|
|
782
856
|
onErrorChangeRef.current = onErrorChange;
|
|
783
857
|
}, [onErrorChange]);
|
|
784
|
-
(0,
|
|
858
|
+
(0, import_react8.useEffect)(() => {
|
|
785
859
|
onDeclineRef.current = onDecline;
|
|
786
860
|
}, [onDecline]);
|
|
787
|
-
(0,
|
|
861
|
+
(0, import_react8.useEffect)(() => {
|
|
788
862
|
onButtonClickRef.current = onButtonClick;
|
|
789
863
|
}, [onButtonClick]);
|
|
790
|
-
(0,
|
|
864
|
+
(0, import_react8.useEffect)(() => {
|
|
791
865
|
onLoadStateChangeRef.current = onLoadStateChange;
|
|
792
866
|
}, [onLoadStateChange]);
|
|
793
|
-
(0,
|
|
867
|
+
(0, import_react8.useEffect)(() => {
|
|
794
868
|
runBeforeButtonClickRef.current = runBeforeButtonClick;
|
|
795
869
|
}, [runBeforeButtonClick]);
|
|
796
|
-
(0,
|
|
870
|
+
(0, import_react8.useEffect)(() => {
|
|
797
871
|
sessionRef.current = session;
|
|
798
872
|
}, [session]);
|
|
799
|
-
(0,
|
|
873
|
+
(0, import_react8.useEffect)(() => {
|
|
800
874
|
emailRef.current = email;
|
|
801
875
|
}, [email]);
|
|
802
|
-
(0,
|
|
876
|
+
(0, import_react8.useEffect)(() => {
|
|
803
877
|
nonceRef.current = nonce;
|
|
804
878
|
}, [nonce]);
|
|
805
|
-
(0,
|
|
879
|
+
(0, import_react8.useEffect)(() => {
|
|
806
880
|
onLoadStateChangeRef.current?.(ready && !failed);
|
|
807
881
|
}, [ready, failed]);
|
|
808
882
|
const normalizedEnv = (0, import_shared4.normalizeGatewayEnvironment)(environment);
|
|
809
|
-
(0,
|
|
883
|
+
(0, import_react8.useEffect)(() => {
|
|
810
884
|
const maskedClient = clientId ? `${clientId.slice(0, 6)}\u2026(len ${clientId.length})` : "(empty)";
|
|
811
885
|
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "(no navigator)";
|
|
812
886
|
appendDebug(`mount clientId=${maskedClient} env=${environment ?? "(unset)"}\u2192${normalizedEnv ?? "live"} ccy=${currency} sub=${isSubscription}`);
|
|
@@ -1218,7 +1292,7 @@ function DirectPayPalButton({
|
|
|
1218
1292
|
}
|
|
1219
1293
|
};
|
|
1220
1294
|
}, [baseUrl, clientId, currency, environment, isSubscription, sessionId, existingOrderId]);
|
|
1221
|
-
const debugPanel = debug ? /* @__PURE__ */ (0,
|
|
1295
|
+
const debugPanel = debug ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1222
1296
|
"pre",
|
|
1223
1297
|
{
|
|
1224
1298
|
"data-testid": "flopay-direct-paypal-debug",
|
|
@@ -1243,17 +1317,17 @@ ${debugLines.join("\n")}`
|
|
|
1243
1317
|
}
|
|
1244
1318
|
) : null;
|
|
1245
1319
|
if (failed) {
|
|
1246
|
-
return debug ? /* @__PURE__ */ (0,
|
|
1320
|
+
return debug ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: debugPanel }) : null;
|
|
1247
1321
|
}
|
|
1248
1322
|
return (
|
|
1249
1323
|
// Single wrapper so the parent flex container sees exactly one flex item
|
|
1250
1324
|
// (otherwise the fragment's placeholder + container become two siblings
|
|
1251
1325
|
// and any spacing-sensitive layout has to reason about both). The wrapper
|
|
1252
1326
|
// intentionally has no margin/padding so the parent owns all spacing.
|
|
1253
|
-
/* @__PURE__ */ (0,
|
|
1327
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
|
|
1254
1328
|
debugPanel,
|
|
1255
|
-
/* @__PURE__ */ (0,
|
|
1256
|
-
!ready && /* @__PURE__ */ (0,
|
|
1329
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { position: "relative", minHeight: DEFAULT_BUTTON_HEIGHT }, children: [
|
|
1330
|
+
!ready && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1257
1331
|
"div",
|
|
1258
1332
|
{
|
|
1259
1333
|
"data-testid": "flopay-direct-paypal-placeholder",
|
|
@@ -1267,7 +1341,7 @@ ${debugLines.join("\n")}`
|
|
|
1267
1341
|
}
|
|
1268
1342
|
}
|
|
1269
1343
|
),
|
|
1270
|
-
/* @__PURE__ */ (0,
|
|
1344
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1271
1345
|
"div",
|
|
1272
1346
|
{
|
|
1273
1347
|
ref: containerRef,
|
|
@@ -1287,10 +1361,28 @@ ${debugLines.join("\n")}`
|
|
|
1287
1361
|
|
|
1288
1362
|
// src/split-card-form.tsx
|
|
1289
1363
|
var import_shared6 = require("@flopay/shared");
|
|
1290
|
-
var
|
|
1364
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1291
1365
|
var STRIPE_RESUME_KEY = "flopay_stripe_resume";
|
|
1292
1366
|
var LEGACY_WALLET_RESUME_KEY = "flopay_wallet_resume";
|
|
1293
1367
|
var PAYPAL_RESUME_KEY = "flopay_paypal_resume";
|
|
1368
|
+
function toVaultMount(block) {
|
|
1369
|
+
if (!block?.html) return null;
|
|
1370
|
+
return {
|
|
1371
|
+
html: block.html,
|
|
1372
|
+
...block.messageToken ? { messageToken: block.messageToken } : {},
|
|
1373
|
+
...block.expectedOrigin ? { expectedOrigin: block.expectedOrigin } : {}
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
function darkenHex(hex, amount = 0.12) {
|
|
1377
|
+
const match = /^#?([0-9a-fA-F]{6})$/.exec(hex.trim());
|
|
1378
|
+
if (!match) return hex;
|
|
1379
|
+
const value = parseInt(match[1], 16);
|
|
1380
|
+
const scale = Math.max(0, Math.min(1, 1 - amount));
|
|
1381
|
+
const r = Math.round((value >> 16 & 255) * scale);
|
|
1382
|
+
const g = Math.round((value >> 8 & 255) * scale);
|
|
1383
|
+
const b = Math.round((value & 255) * scale);
|
|
1384
|
+
return `#${(1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1)}`;
|
|
1385
|
+
}
|
|
1294
1386
|
var FLOPAY_KEYFRAMES = `
|
|
1295
1387
|
.paypal-buttons { margin: 0 !important; vertical-align: top !important; }
|
|
1296
1388
|
@keyframes flopay-spin { to { transform: rotate(360deg); } }
|
|
@@ -1315,18 +1407,20 @@ var FLOPAY_KEYFRAMES = `
|
|
|
1315
1407
|
`;
|
|
1316
1408
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;
|
|
1317
1409
|
function derivePrimaryTileStyle(opts) {
|
|
1318
|
-
if (!opts.themeBundle) {
|
|
1410
|
+
if (!opts.themeBundle && !opts.explicitPrimaryColor) {
|
|
1319
1411
|
return {
|
|
1320
1412
|
backgroundColor: "white",
|
|
1321
1413
|
color: "#262833",
|
|
1322
1414
|
border: "1px solid #d1d5db",
|
|
1323
|
-
borderRadius:
|
|
1415
|
+
borderRadius: opts.resolvedBorderRadius,
|
|
1324
1416
|
boxShadow: "0 1px 2px rgba(0,0,0,0.04)"
|
|
1325
1417
|
};
|
|
1326
1418
|
}
|
|
1327
|
-
const submit = opts.submitButtonStyle ?? {};
|
|
1419
|
+
const submit = opts.themeBundle ? opts.submitButtonStyle ?? {} : {};
|
|
1328
1420
|
return {
|
|
1329
|
-
|
|
1421
|
+
// `colorPrimary` wins so a per-checkout override re-skins the card / auto-pay
|
|
1422
|
+
// buttons in lock-step with the submit CTA (which also keys off it).
|
|
1423
|
+
backgroundColor: opts.resolvedPrimaryColor,
|
|
1330
1424
|
color: submit.color ?? "white",
|
|
1331
1425
|
border: submit.border ?? "none",
|
|
1332
1426
|
borderRadius: submit.borderRadius ?? opts.resolvedBorderRadius,
|
|
@@ -1360,7 +1454,7 @@ function normalizeBeforeButtonClickError(method, err) {
|
|
|
1360
1454
|
);
|
|
1361
1455
|
}
|
|
1362
1456
|
function FloPayKeyframes() {
|
|
1363
|
-
return /* @__PURE__ */ (0,
|
|
1457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: FLOPAY_KEYFRAMES });
|
|
1364
1458
|
}
|
|
1365
1459
|
function toCssSize(value) {
|
|
1366
1460
|
if (typeof value === "number") return `${value}px`;
|
|
@@ -1382,8 +1476,8 @@ function ExpressCheckoutReadySwap({
|
|
|
1382
1476
|
children
|
|
1383
1477
|
}) {
|
|
1384
1478
|
if (state === "unavailable" || state === "load_error") return null;
|
|
1385
|
-
return /* @__PURE__ */ (0,
|
|
1386
|
-
/* @__PURE__ */ (0,
|
|
1479
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { position: "relative", minHeight: 44 }, children: [
|
|
1480
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1387
1481
|
"div",
|
|
1388
1482
|
{
|
|
1389
1483
|
"data-testid": placeholderTestId,
|
|
@@ -1402,7 +1496,7 @@ function ExpressCheckoutReadySwap({
|
|
|
1402
1496
|
}
|
|
1403
1497
|
}
|
|
1404
1498
|
),
|
|
1405
|
-
/* @__PURE__ */ (0,
|
|
1499
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1406
1500
|
"div",
|
|
1407
1501
|
{
|
|
1408
1502
|
style: {
|
|
@@ -1420,9 +1514,9 @@ function ExpressCheckoutReadySwap({
|
|
|
1420
1514
|
function isExpressCheckoutRowVisible(state) {
|
|
1421
1515
|
return state !== "unavailable" && state !== "load_error";
|
|
1422
1516
|
}
|
|
1423
|
-
var SplitCardForm = (0,
|
|
1517
|
+
var SplitCardForm = (0, import_react9.forwardRef)(
|
|
1424
1518
|
function SplitCardForm2(props, ref) {
|
|
1425
|
-
return /* @__PURE__ */ (0,
|
|
1519
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SplitCardFormInner, { ...props, innerRef: ref });
|
|
1426
1520
|
}
|
|
1427
1521
|
);
|
|
1428
1522
|
function PayPalButtonInner({
|
|
@@ -1441,15 +1535,15 @@ function PayPalButtonInner({
|
|
|
1441
1535
|
}) {
|
|
1442
1536
|
const stripe = (0, import_react_stripe_js.useStripe)();
|
|
1443
1537
|
const elements = (0, import_react_stripe_js.useElements)();
|
|
1444
|
-
const [loadState, setLoadState] = (0,
|
|
1445
|
-
(0,
|
|
1538
|
+
const [loadState, setLoadState] = (0, import_react9.useState)("loading");
|
|
1539
|
+
(0, import_react9.useEffect)(() => {
|
|
1446
1540
|
onLoadStateChange?.(loadState);
|
|
1447
1541
|
}, [loadState, onLoadStateChange]);
|
|
1448
|
-
const [submitting, setSubmitting] = (0,
|
|
1449
|
-
const paypalResumeAttempted = (0,
|
|
1450
|
-
const beforeClickRef = (0,
|
|
1542
|
+
const [submitting, setSubmitting] = (0, import_react9.useState)(false);
|
|
1543
|
+
const paypalResumeAttempted = (0, import_react9.useRef)(false);
|
|
1544
|
+
const beforeClickRef = (0, import_react9.useRef)(null);
|
|
1451
1545
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
1452
|
-
(0,
|
|
1546
|
+
(0, import_react9.useEffect)(() => {
|
|
1453
1547
|
if (!stripe || paypalResumeAttempted.current) return;
|
|
1454
1548
|
const params = new URLSearchParams(window.location.search);
|
|
1455
1549
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -1515,7 +1609,7 @@ function PayPalButtonInner({
|
|
|
1515
1609
|
}
|
|
1516
1610
|
})();
|
|
1517
1611
|
}, [stripe, onTokenizedBody, onErrorChange, onDecline]);
|
|
1518
|
-
const handlePayPalClick = (0,
|
|
1612
|
+
const handlePayPalClick = (0, import_react9.useCallback)(async (event) => {
|
|
1519
1613
|
if (isProcessing || submitting) {
|
|
1520
1614
|
event.reject();
|
|
1521
1615
|
return;
|
|
@@ -1534,7 +1628,7 @@ function PayPalButtonInner({
|
|
|
1534
1628
|
onButtonClick?.("paypal");
|
|
1535
1629
|
event.resolve();
|
|
1536
1630
|
}, [isProcessing, onButtonClick, runBeforeButtonClick, submitting]);
|
|
1537
|
-
const handlePayPalConfirm = (0,
|
|
1631
|
+
const handlePayPalConfirm = (0, import_react9.useCallback)(async (event) => {
|
|
1538
1632
|
if (!stripe || !elements) return;
|
|
1539
1633
|
let prepared = beforeClickRef.current;
|
|
1540
1634
|
beforeClickRef.current = null;
|
|
@@ -1654,14 +1748,14 @@ function PayPalButtonInner({
|
|
|
1654
1748
|
setSubmitting(false);
|
|
1655
1749
|
}
|
|
1656
1750
|
}, [stripe, elements, sessionId, nonce, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]);
|
|
1657
|
-
return /* @__PURE__ */ (0,
|
|
1658
|
-
/* @__PURE__ */ (0,
|
|
1751
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1752
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1659
1753
|
ExpressCheckoutReadySwap,
|
|
1660
1754
|
{
|
|
1661
1755
|
state: loadState,
|
|
1662
1756
|
placeholderTestId: "flopay-paypal-placeholder",
|
|
1663
1757
|
borderRadius: placeholderBorderRadius,
|
|
1664
|
-
children: /* @__PURE__ */ (0,
|
|
1758
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1665
1759
|
import_react_stripe_js.ExpressCheckoutElement,
|
|
1666
1760
|
{
|
|
1667
1761
|
onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
|
|
@@ -1688,7 +1782,7 @@ function PayPalButtonInner({
|
|
|
1688
1782
|
)
|
|
1689
1783
|
}
|
|
1690
1784
|
),
|
|
1691
|
-
submitting && /* @__PURE__ */ (0,
|
|
1785
|
+
submitting && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProcessingOverlay, { status: "processing" })
|
|
1692
1786
|
] });
|
|
1693
1787
|
}
|
|
1694
1788
|
function WalletButtonInner({
|
|
@@ -1707,15 +1801,15 @@ function WalletButtonInner({
|
|
|
1707
1801
|
}) {
|
|
1708
1802
|
const stripe = (0, import_react_stripe_js.useStripe)();
|
|
1709
1803
|
const elements = (0, import_react_stripe_js.useElements)();
|
|
1710
|
-
const [loadState, setLoadState] = (0,
|
|
1711
|
-
(0,
|
|
1804
|
+
const [loadState, setLoadState] = (0, import_react9.useState)("loading");
|
|
1805
|
+
(0, import_react9.useEffect)(() => {
|
|
1712
1806
|
onLoadStateChange?.(loadState);
|
|
1713
1807
|
}, [loadState, onLoadStateChange]);
|
|
1714
|
-
const [submitting, setSubmitting] = (0,
|
|
1808
|
+
const [submitting, setSubmitting] = (0, import_react9.useState)(false);
|
|
1715
1809
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
1716
|
-
const lastWalletMethodRef = (0,
|
|
1717
|
-
const beforeClickRef = (0,
|
|
1718
|
-
const handleWalletConfirm = (0,
|
|
1810
|
+
const lastWalletMethodRef = (0, import_react9.useRef)("card");
|
|
1811
|
+
const beforeClickRef = (0, import_react9.useRef)(null);
|
|
1812
|
+
const handleWalletConfirm = (0, import_react9.useCallback)(
|
|
1719
1813
|
async (event) => {
|
|
1720
1814
|
if (!stripe || !elements) return;
|
|
1721
1815
|
const walletType = event.expressPaymentType;
|
|
@@ -1805,7 +1899,7 @@ function WalletButtonInner({
|
|
|
1805
1899
|
},
|
|
1806
1900
|
[stripe, elements, sessionId, nonce, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]
|
|
1807
1901
|
);
|
|
1808
|
-
const expressMethodMap = (0,
|
|
1902
|
+
const expressMethodMap = (0, import_react9.useMemo)(() => {
|
|
1809
1903
|
const allKeys = ["applePay", "googlePay", "paypal", "link", "amazonPay", "klarna"];
|
|
1810
1904
|
const alwaysCapable = /* @__PURE__ */ new Set(["applePay", "googlePay"]);
|
|
1811
1905
|
const enabledKeys = new Set(expressMethods.map(import_shared5.stripeExpressMethodToOptionKey));
|
|
@@ -1819,18 +1913,18 @@ function WalletButtonInner({
|
|
|
1819
1913
|
}
|
|
1820
1914
|
return out;
|
|
1821
1915
|
}, [expressMethods]);
|
|
1822
|
-
const availableMethodKeys = (0,
|
|
1916
|
+
const availableMethodKeys = (0, import_react9.useMemo)(
|
|
1823
1917
|
() => expressMethods.map(import_shared5.stripeExpressMethodToOptionKey),
|
|
1824
1918
|
[expressMethods]
|
|
1825
1919
|
);
|
|
1826
|
-
return /* @__PURE__ */ (0,
|
|
1827
|
-
/* @__PURE__ */ (0,
|
|
1920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1828
1922
|
ExpressCheckoutReadySwap,
|
|
1829
1923
|
{
|
|
1830
1924
|
state: loadState,
|
|
1831
1925
|
placeholderTestId: "flopay-wallet-placeholder",
|
|
1832
1926
|
borderRadius: placeholderBorderRadius,
|
|
1833
|
-
children: /* @__PURE__ */ (0,
|
|
1927
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1834
1928
|
import_react_stripe_js.ExpressCheckoutElement,
|
|
1835
1929
|
{
|
|
1836
1930
|
onReady: (event) => {
|
|
@@ -1869,7 +1963,7 @@ function WalletButtonInner({
|
|
|
1869
1963
|
)
|
|
1870
1964
|
}
|
|
1871
1965
|
),
|
|
1872
|
-
submitting && /* @__PURE__ */ (0,
|
|
1966
|
+
submitting && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProcessingOverlay, { status: "processing" })
|
|
1873
1967
|
] });
|
|
1874
1968
|
}
|
|
1875
1969
|
function StripeMethodButton({
|
|
@@ -1890,7 +1984,7 @@ function StripeMethodButton({
|
|
|
1890
1984
|
const resolvedBackground = brand?.backgroundColor ?? backgroundColor ?? "#ffffff";
|
|
1891
1985
|
const resolvedBorder = brand?.borderColor ?? borderColor ?? "#d1d5db";
|
|
1892
1986
|
const resolvedTextColor = brand?.textColor ?? textColor ?? "#262833";
|
|
1893
|
-
return /* @__PURE__ */ (0,
|
|
1987
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1894
1988
|
"button",
|
|
1895
1989
|
{
|
|
1896
1990
|
type: "button",
|
|
@@ -1937,9 +2031,9 @@ function StripeMethodButton({
|
|
|
1937
2031
|
// Pulse-skeleton parity with the wallet ECE: no spinner, just the
|
|
1938
2032
|
// status text on top of the pulsing background. Keeps the loading
|
|
1939
2033
|
// affordance shape-equivalent across both kinds of tile.
|
|
1940
|
-
/* @__PURE__ */ (0,
|
|
1941
|
-
) : /* @__PURE__ */ (0,
|
|
1942
|
-
/* @__PURE__ */ (0,
|
|
2034
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { margin: "0 auto" }, children: `Connecting to ${(0, import_shared5.getStripeMethodDisplayName)(method)}\u2026` })
|
|
2035
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
2036
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1943
2037
|
"span",
|
|
1944
2038
|
{
|
|
1945
2039
|
style: {
|
|
@@ -1952,7 +2046,7 @@ function StripeMethodButton({
|
|
|
1952
2046
|
gap: (0, import_shared5.hasVendoredStripeMethodLogo)(method) ? 8 : 0
|
|
1953
2047
|
},
|
|
1954
2048
|
children: [
|
|
1955
|
-
brand?.logoSvg && /* @__PURE__ */ (0,
|
|
2049
|
+
brand?.logoSvg && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1956
2050
|
"span",
|
|
1957
2051
|
{
|
|
1958
2052
|
"aria-hidden": "true",
|
|
@@ -1971,11 +2065,11 @@ function StripeMethodButton({
|
|
|
1971
2065
|
dangerouslySetInnerHTML: { __html: brand.logoSvg }
|
|
1972
2066
|
}
|
|
1973
2067
|
),
|
|
1974
|
-
/* @__PURE__ */ (0,
|
|
2068
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: (0, import_shared5.getStripeMethodDisplayName)(method) })
|
|
1975
2069
|
]
|
|
1976
2070
|
}
|
|
1977
2071
|
),
|
|
1978
|
-
hasNextStep && /* @__PURE__ */ (0,
|
|
2072
|
+
hasNextStep && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1979
2073
|
"svg",
|
|
1980
2074
|
{
|
|
1981
2075
|
width: "14",
|
|
@@ -1995,7 +2089,7 @@ function StripeMethodButton({
|
|
|
1995
2089
|
opacity: 0.7
|
|
1996
2090
|
},
|
|
1997
2091
|
"aria-hidden": "true",
|
|
1998
|
-
children: /* @__PURE__ */ (0,
|
|
2092
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M9 18l6-6-6-6" })
|
|
1999
2093
|
}
|
|
2000
2094
|
)
|
|
2001
2095
|
] })
|
|
@@ -2018,16 +2112,17 @@ function StripeMethodInlineForm({
|
|
|
2018
2112
|
isProcessing,
|
|
2019
2113
|
submitButtonColor,
|
|
2020
2114
|
submitButtonBorderRadius,
|
|
2021
|
-
submitButtonStyle
|
|
2115
|
+
submitButtonStyle,
|
|
2116
|
+
errorText
|
|
2022
2117
|
}) {
|
|
2023
2118
|
const stripe = (0, import_react_stripe_js.useStripe)();
|
|
2024
2119
|
const elements = (0, import_react_stripe_js.useElements)();
|
|
2025
|
-
const [submitting, setSubmitting] = (0,
|
|
2026
|
-
const submittingRef = (0,
|
|
2027
|
-
const [isMethodComplete, setIsMethodComplete] = (0,
|
|
2028
|
-
const [loadState, setLoadState] = (0,
|
|
2120
|
+
const [submitting, setSubmitting] = (0, import_react9.useState)(false);
|
|
2121
|
+
const submittingRef = (0, import_react9.useRef)(false);
|
|
2122
|
+
const [isMethodComplete, setIsMethodComplete] = (0, import_react9.useState)(false);
|
|
2123
|
+
const [loadState, setLoadState] = (0, import_react9.useState)("loading");
|
|
2029
2124
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
2030
|
-
const handlePay = (0,
|
|
2125
|
+
const handlePay = (0, import_react9.useCallback)(async () => {
|
|
2031
2126
|
if (!stripe || !elements || isProcessing || submittingRef.current || !isMethodComplete) return;
|
|
2032
2127
|
submittingRef.current = true;
|
|
2033
2128
|
setSubmitting(true);
|
|
@@ -2167,8 +2262,8 @@ function StripeMethodInlineForm({
|
|
|
2167
2262
|
onDecline
|
|
2168
2263
|
]);
|
|
2169
2264
|
void onCancel;
|
|
2170
|
-
return /* @__PURE__ */ (0,
|
|
2171
|
-
/* @__PURE__ */ (0,
|
|
2265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-testid": `flopay-stripe-method-form-${method}`, style: { display: "flex", flexDirection: "column" }, children: [
|
|
2266
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2172
2267
|
import_react_stripe_js.PaymentElement,
|
|
2173
2268
|
{
|
|
2174
2269
|
onReady: () => setLoadState("ready"),
|
|
@@ -2188,7 +2283,7 @@ function StripeMethodInlineForm({
|
|
|
2188
2283
|
}
|
|
2189
2284
|
}
|
|
2190
2285
|
),
|
|
2191
|
-
/* @__PURE__ */ (0,
|
|
2286
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2192
2287
|
"button",
|
|
2193
2288
|
{
|
|
2194
2289
|
type: "button",
|
|
@@ -2214,7 +2309,23 @@ function StripeMethodInlineForm({
|
|
|
2214
2309
|
},
|
|
2215
2310
|
children: submitting ? "Processing\u2026" : `Pay with ${(0, import_shared5.getStripeMethodDisplayName)(method)}`
|
|
2216
2311
|
}
|
|
2217
|
-
)
|
|
2312
|
+
),
|
|
2313
|
+
errorText && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
2314
|
+
margin: "0.75rem 0 0",
|
|
2315
|
+
padding: "0.625rem 0.875rem",
|
|
2316
|
+
background: "#FEF2F2",
|
|
2317
|
+
border: "1px solid #FECACA",
|
|
2318
|
+
borderRadius: "8px",
|
|
2319
|
+
color: "#991B1B",
|
|
2320
|
+
fontSize: "0.85rem",
|
|
2321
|
+
fontWeight: 600,
|
|
2322
|
+
display: "flex",
|
|
2323
|
+
alignItems: "center",
|
|
2324
|
+
gap: "0.5rem"
|
|
2325
|
+
}, children: [
|
|
2326
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
2327
|
+
errorText
|
|
2328
|
+
] })
|
|
2218
2329
|
] });
|
|
2219
2330
|
}
|
|
2220
2331
|
function StripePaymentElementInner({
|
|
@@ -2242,17 +2353,17 @@ function StripePaymentElementInner({
|
|
|
2242
2353
|
expandedApmMethod
|
|
2243
2354
|
}) {
|
|
2244
2355
|
const baseUrl = billingApiUrl.replace(/\/+$/, "");
|
|
2245
|
-
const [expandedMethod, setExpandedMethod] = (0,
|
|
2246
|
-
const [submittingMethod, setSubmittingMethod] = (0,
|
|
2247
|
-
const submittingRef = (0,
|
|
2248
|
-
(0,
|
|
2356
|
+
const [expandedMethod, setExpandedMethod] = (0, import_react9.useState)(null);
|
|
2357
|
+
const [submittingMethod, setSubmittingMethod] = (0, import_react9.useState)(null);
|
|
2358
|
+
const submittingRef = (0, import_react9.useRef)(false);
|
|
2359
|
+
(0, import_react9.useEffect)(() => {
|
|
2249
2360
|
if (paymentElementMethods.length > 0 && stripeInstance) {
|
|
2250
2361
|
onLoadStateChange?.("ready");
|
|
2251
2362
|
} else if (!stripeInstance) {
|
|
2252
2363
|
onLoadStateChange?.("loading");
|
|
2253
2364
|
}
|
|
2254
2365
|
}, [paymentElementMethods.length, stripeInstance, onLoadStateChange]);
|
|
2255
|
-
const handleAutoConfirm = (0,
|
|
2366
|
+
const handleAutoConfirm = (0, import_react9.useCallback)(async (method) => {
|
|
2256
2367
|
if (!stripeInstance) return;
|
|
2257
2368
|
if (submittingRef.current || isProcessing) return;
|
|
2258
2369
|
submittingRef.current = true;
|
|
@@ -2391,9 +2502,9 @@ function StripePaymentElementInner({
|
|
|
2391
2502
|
onErrorChange,
|
|
2392
2503
|
onDecline
|
|
2393
2504
|
]);
|
|
2394
|
-
const [localExpandedMethod, setLocalExpandedMethod] = (0,
|
|
2505
|
+
const [localExpandedMethod, setLocalExpandedMethod] = (0, import_react9.useState)(null);
|
|
2395
2506
|
const activeExpandedMethod = onExpandApm ? expandedApmMethod ?? null : localExpandedMethod;
|
|
2396
|
-
const handleMethodClick = (0,
|
|
2507
|
+
const handleMethodClick = (0, import_react9.useCallback)((method) => {
|
|
2397
2508
|
if (submittingRef.current || isProcessing) return;
|
|
2398
2509
|
if (activeExpandedMethod && activeExpandedMethod !== method) return;
|
|
2399
2510
|
if ((0, import_shared5.needsStripeMethodExplicitConfirm)(method)) {
|
|
@@ -2406,14 +2517,14 @@ function StripePaymentElementInner({
|
|
|
2406
2517
|
void handleAutoConfirm(method);
|
|
2407
2518
|
}
|
|
2408
2519
|
}, [activeExpandedMethod, isProcessing, handleAutoConfirm, onExpandApm]);
|
|
2409
|
-
const localInlineElementsOptions = (0,
|
|
2520
|
+
const localInlineElementsOptions = (0, import_react9.useMemo)(() => {
|
|
2410
2521
|
if (!localExpandedMethod) return null;
|
|
2411
2522
|
return {
|
|
2412
2523
|
...paymentElementBaseOptions,
|
|
2413
2524
|
paymentMethodTypes: [localExpandedMethod]
|
|
2414
2525
|
};
|
|
2415
2526
|
}, [localExpandedMethod, paymentElementBaseOptions]);
|
|
2416
|
-
return /* @__PURE__ */ (0,
|
|
2527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2417
2528
|
"div",
|
|
2418
2529
|
{
|
|
2419
2530
|
"data-testid": "flopay-stripe-payment-element-region",
|
|
@@ -2422,8 +2533,8 @@ function StripePaymentElementInner({
|
|
|
2422
2533
|
const isExpanded = expandedApmMethod === method;
|
|
2423
2534
|
const isSubmittingThis = submittingMethod === method;
|
|
2424
2535
|
const otherInProgress = submittingMethod !== null && submittingMethod !== method || expandedApmMethod !== null && expandedApmMethod !== void 0 && expandedApmMethod !== method;
|
|
2425
|
-
return /* @__PURE__ */ (0,
|
|
2426
|
-
/* @__PURE__ */ (0,
|
|
2536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react9.default.Fragment, { children: [
|
|
2537
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2427
2538
|
StripeMethodButton,
|
|
2428
2539
|
{
|
|
2429
2540
|
method,
|
|
@@ -2440,12 +2551,12 @@ function StripePaymentElementInner({
|
|
|
2440
2551
|
fontFamily: buttonAppearance?.fontFamily
|
|
2441
2552
|
}
|
|
2442
2553
|
),
|
|
2443
|
-
!onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && /* @__PURE__ */ (0,
|
|
2554
|
+
!onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2444
2555
|
import_react_stripe_js.Elements,
|
|
2445
2556
|
{
|
|
2446
2557
|
stripe: stripeInstance,
|
|
2447
2558
|
options: localInlineElementsOptions,
|
|
2448
|
-
children: /* @__PURE__ */ (0,
|
|
2559
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2449
2560
|
StripeMethodInlineForm,
|
|
2450
2561
|
{
|
|
2451
2562
|
method,
|
|
@@ -2498,6 +2609,7 @@ function SplitCardFormInner({
|
|
|
2498
2609
|
showPayPal = true,
|
|
2499
2610
|
showStripe = true,
|
|
2500
2611
|
enabledPaymentMethods,
|
|
2612
|
+
enabledPaymentMethodCountries,
|
|
2501
2613
|
showApplePay = true,
|
|
2502
2614
|
showGooglePay = true,
|
|
2503
2615
|
layout = "default",
|
|
@@ -2512,6 +2624,8 @@ function SplitCardFormInner({
|
|
|
2512
2624
|
onButtonClick,
|
|
2513
2625
|
onBeforeButtonClick,
|
|
2514
2626
|
enableAVS: enableAVSProp,
|
|
2627
|
+
cardFieldOrder,
|
|
2628
|
+
cardPreFormSlot,
|
|
2515
2629
|
avsLayout: avsLayoutProp = "row",
|
|
2516
2630
|
country: countryProp,
|
|
2517
2631
|
zip: zipProp,
|
|
@@ -2536,68 +2650,95 @@ function SplitCardFormInner({
|
|
|
2536
2650
|
const flopay = useFloPay();
|
|
2537
2651
|
const paypalFlopay = usePayPalFloPay();
|
|
2538
2652
|
const elements = useElements();
|
|
2539
|
-
const checkout = (0,
|
|
2653
|
+
const checkout = (0, import_react9.useContext)(CheckoutContext);
|
|
2540
2654
|
const contextBillingUrl = useBillingApiUrl();
|
|
2541
|
-
const [processing, setProcessing] = (0,
|
|
2542
|
-
const [error, setError] = (0,
|
|
2543
|
-
const [is3DSActive, setIs3DSActive] = (0,
|
|
2544
|
-
const [selectedCountry, setSelectedCountry] = (0,
|
|
2545
|
-
const [zipCode, setZipCode] = (0,
|
|
2546
|
-
const [addressLine1, setAddressLine1] = (0,
|
|
2547
|
-
const [addressLine2, setAddressLine2] = (0,
|
|
2548
|
-
const [city, setCity] = (0,
|
|
2549
|
-
const [stateValue, setStateValue] = (0,
|
|
2550
|
-
const [accountPatch, setAccountPatch] = (0,
|
|
2551
|
-
const zipCodeRef = (0,
|
|
2552
|
-
const selectedCountryRef = (0,
|
|
2553
|
-
const addressLine1Ref = (0,
|
|
2554
|
-
const addressLine2Ref = (0,
|
|
2555
|
-
const cityRef = (0,
|
|
2556
|
-
const stateRef = (0,
|
|
2557
|
-
const avsConfig = (0,
|
|
2655
|
+
const [processing, setProcessing] = (0, import_react9.useState)(false);
|
|
2656
|
+
const [error, setError] = (0, import_react9.useState)(null);
|
|
2657
|
+
const [is3DSActive, setIs3DSActive] = (0, import_react9.useState)(false);
|
|
2658
|
+
const [selectedCountry, setSelectedCountry] = (0, import_react9.useState)(countryProp ?? "US");
|
|
2659
|
+
const [zipCode, setZipCode] = (0, import_react9.useState)(zipProp ?? "");
|
|
2660
|
+
const [addressLine1, setAddressLine1] = (0, import_react9.useState)(addressLine1Prop ?? "");
|
|
2661
|
+
const [addressLine2, setAddressLine2] = (0, import_react9.useState)(addressLine2Prop ?? "");
|
|
2662
|
+
const [city, setCity] = (0, import_react9.useState)(cityProp ?? "");
|
|
2663
|
+
const [stateValue, setStateValue] = (0, import_react9.useState)(stateProp ?? "");
|
|
2664
|
+
const [accountPatch, setAccountPatch] = (0, import_react9.useState)({});
|
|
2665
|
+
const zipCodeRef = (0, import_react9.useRef)(zipProp ?? "");
|
|
2666
|
+
const selectedCountryRef = (0, import_react9.useRef)(countryProp ?? "US");
|
|
2667
|
+
const addressLine1Ref = (0, import_react9.useRef)(addressLine1Prop ?? "");
|
|
2668
|
+
const addressLine2Ref = (0, import_react9.useRef)(addressLine2Prop ?? "");
|
|
2669
|
+
const cityRef = (0, import_react9.useRef)(cityProp ?? "");
|
|
2670
|
+
const stateRef = (0, import_react9.useRef)(stateProp ?? "");
|
|
2671
|
+
const avsConfig = (0, import_react9.useMemo)(() => (0, import_shared5.resolveAVSConfig)(enableAVSProp), [enableAVSProp]);
|
|
2558
2672
|
const enableAVS = avsConfig !== null;
|
|
2559
|
-
const
|
|
2560
|
-
const
|
|
2673
|
+
const vaultBlockReady = Boolean(session?.vault?.html);
|
|
2674
|
+
const vaultGatewayAdvertised = Boolean(session?.gateways?.pcivault);
|
|
2675
|
+
const vaultActive = Boolean(
|
|
2676
|
+
showStripe && (vaultBlockReady || vaultGatewayAdvertised) && flopay && sessionId
|
|
2677
|
+
);
|
|
2678
|
+
const cardCapture = (0, import_react9.useMemo)(() => {
|
|
2679
|
+
if (!flopay || !vaultActive || !sessionId) return null;
|
|
2680
|
+
return flopay.cardCapture({ sessionId });
|
|
2681
|
+
}, [flopay, vaultActive, sessionId]);
|
|
2682
|
+
const { avsInvalid, invalidAvsFields } = (0, import_react9.useMemo)(() => {
|
|
2683
|
+
const none = { line1: false, city: false, state: false, zip: false };
|
|
2684
|
+
if (!vaultActive || !avsConfig) return { avsInvalid: false, invalidAvsFields: none };
|
|
2685
|
+
const cc = selectedCountry;
|
|
2686
|
+
const isEmpty = (field, value) => (0, import_shared5.isAVSFieldVisible)(field, cc) && !value.trim();
|
|
2687
|
+
const invalidAvsFields2 = {
|
|
2688
|
+
line1: isEmpty(avsConfig.address_line_1, addressLine1),
|
|
2689
|
+
city: isEmpty(avsConfig.city, city),
|
|
2690
|
+
state: isEmpty(avsConfig.state, stateValue),
|
|
2691
|
+
zip: isEmpty(avsConfig.postal_code, zipCode)
|
|
2692
|
+
};
|
|
2693
|
+
const avsInvalid2 = invalidAvsFields2.line1 || invalidAvsFields2.city || invalidAvsFields2.state || invalidAvsFields2.zip;
|
|
2694
|
+
return { avsInvalid: avsInvalid2, invalidAvsFields: invalidAvsFields2 };
|
|
2695
|
+
}, [vaultActive, avsConfig, selectedCountry, addressLine1, city, stateValue, zipCode]);
|
|
2696
|
+
const [hasAttemptedSubmit, setHasAttemptedSubmit] = (0, import_react9.useState)(false);
|
|
2697
|
+
const [vaultMount, setVaultMount] = (0, import_react9.useState)(
|
|
2698
|
+
() => toVaultMount(session?.vault)
|
|
2699
|
+
);
|
|
2700
|
+
const [viewState, setViewState] = (0, import_react9.useState)(initialCardOpen ? "card" : "buttons");
|
|
2701
|
+
const [expandedApmMethod, setExpandedApmMethod] = (0, import_react9.useState)(null);
|
|
2561
2702
|
const showCardForm = viewState === "expanding" || viewState === "card";
|
|
2562
2703
|
const TRANSITION_MS = 280;
|
|
2563
|
-
const expandToCard = (0,
|
|
2704
|
+
const expandToCard = (0, import_react9.useCallback)(() => {
|
|
2564
2705
|
setViewState("expanding");
|
|
2565
2706
|
setTimeout(() => setViewState("card"), TRANSITION_MS);
|
|
2566
2707
|
}, []);
|
|
2567
|
-
const collapseToButtons = (0,
|
|
2708
|
+
const collapseToButtons = (0, import_react9.useCallback)(() => {
|
|
2568
2709
|
setViewState("collapsing");
|
|
2569
2710
|
setTimeout(() => setViewState("buttons"), TRANSITION_MS);
|
|
2570
2711
|
}, []);
|
|
2571
|
-
const expandToApm = (0,
|
|
2712
|
+
const expandToApm = (0, import_react9.useCallback)((method) => {
|
|
2572
2713
|
setExpandedApmMethod(method);
|
|
2573
2714
|
setViewState("apm-expanding");
|
|
2574
2715
|
setTimeout(() => setViewState("apm-form"), TRANSITION_MS);
|
|
2575
2716
|
}, []);
|
|
2576
|
-
const collapseFromApm = (0,
|
|
2717
|
+
const collapseFromApm = (0, import_react9.useCallback)(() => {
|
|
2577
2718
|
setViewState("apm-collapsing");
|
|
2578
2719
|
setTimeout(() => {
|
|
2579
2720
|
setViewState("buttons");
|
|
2580
2721
|
setExpandedApmMethod(null);
|
|
2581
2722
|
}, TRANSITION_MS);
|
|
2582
2723
|
}, []);
|
|
2583
|
-
(0,
|
|
2724
|
+
(0, import_react9.useEffect)(() => {
|
|
2584
2725
|
if (layout === "buttons" && initialCardOpen) {
|
|
2585
2726
|
setViewState("card");
|
|
2586
2727
|
}
|
|
2587
2728
|
}, [layout, initialCardOpen]);
|
|
2588
|
-
const [fullName, setFullName] = (0,
|
|
2589
|
-
const [formReady, setFormReady] = (0,
|
|
2590
|
-
const [overlayStatus, setOverlayStatus] = (0,
|
|
2591
|
-
const processingRef = (0,
|
|
2592
|
-
const [paypalDirectRetry, setPaypalDirectRetry] = (0,
|
|
2593
|
-
const paypalDirectRetryRef = (0,
|
|
2594
|
-
(0,
|
|
2729
|
+
const [fullName, setFullName] = (0, import_react9.useState)("");
|
|
2730
|
+
const [formReady, setFormReady] = (0, import_react9.useState)(false);
|
|
2731
|
+
const [overlayStatus, setOverlayStatus] = (0, import_react9.useState)(null);
|
|
2732
|
+
const processingRef = (0, import_react9.useRef)(false);
|
|
2733
|
+
const [paypalDirectRetry, setPaypalDirectRetry] = (0, import_react9.useState)(null);
|
|
2734
|
+
const paypalDirectRetryRef = (0, import_react9.useRef)(paypalDirectRetry);
|
|
2735
|
+
(0, import_react9.useEffect)(() => {
|
|
2595
2736
|
paypalDirectRetryRef.current = paypalDirectRetry;
|
|
2596
2737
|
}, [paypalDirectRetry]);
|
|
2597
2738
|
const resolvedBillingApiUrl = billingApiUrl || contextBillingUrl;
|
|
2598
2739
|
const displayError = externalError ?? error;
|
|
2599
|
-
const themeBundle = (0,
|
|
2600
|
-
const bStyles = (0,
|
|
2740
|
+
const themeBundle = (0, import_react9.useMemo)(() => (0, import_shared6.resolveTheme)(theme), [theme]);
|
|
2741
|
+
const bStyles = (0, import_react9.useMemo)(() => {
|
|
2601
2742
|
const base = themeBundle?.buttonsLayout ?? (0, import_shared5.resolveButtonsLayoutTheme)(buttonsTheme);
|
|
2602
2743
|
if (!buttonsStylesOverride) return base;
|
|
2603
2744
|
return {
|
|
@@ -2612,11 +2753,36 @@ function SplitCardFormInner({
|
|
|
2612
2753
|
};
|
|
2613
2754
|
}, [themeBundle, buttonsTheme, buttonsStylesOverride]);
|
|
2614
2755
|
const appearance = appearanceOverride ?? themeBundle?.appearance;
|
|
2756
|
+
const vaultThemeColors = (0, import_react9.useMemo)(() => {
|
|
2757
|
+
const vars = appearance?.variables;
|
|
2758
|
+
const asString = (value) => typeof value === "string" && value ? value : void 0;
|
|
2759
|
+
const submitButtonStyle = bStyles.submitButton;
|
|
2760
|
+
const primary = asString(vars?.colorPrimary) ?? asString(submitButtonStyle?.backgroundColor) ?? "#4A49FF";
|
|
2761
|
+
const isButtonsLayout = layout === "buttons";
|
|
2762
|
+
const nameInput = bStyles.nameInput;
|
|
2763
|
+
return {
|
|
2764
|
+
primaryColor: primary,
|
|
2765
|
+
primaryHoverColor: asString(vars?.colorPrimaryHover) ?? darkenHex(primary, 0.12),
|
|
2766
|
+
inputBackgroundColor: asString(bStyles.cardInputBackground) ?? asString(vars?.colorBackground) ?? "#ffffff",
|
|
2767
|
+
textColor: asString(bStyles.cardInputColor) ?? asString(nameInput?.color) ?? asString(vars?.colorText) ?? "#262833",
|
|
2768
|
+
borderColor: asString(bStyles.cardInputBorder) ?? (isButtonsLayout ? "#e5e7eb" : "#A4A4FF"),
|
|
2769
|
+
placeholderColor: asString(bStyles.cardInputPlaceholderColor) ?? "#9ca3af",
|
|
2770
|
+
errorColor: asString(vars?.colorDanger) ?? "#dc2626",
|
|
2771
|
+
successColor: "#16a34a",
|
|
2772
|
+
fontFamily: asString(nameInput?.fontFamily) ?? asString(vars?.fontFamily) ?? "Poppins, sans-serif",
|
|
2773
|
+
fontSize: asString(bStyles.cardInputFontSize) ?? asString(vars?.fontSizeBase) ?? "16px",
|
|
2774
|
+
// `resolvedInputFontWeight` equivalent — sent as a string (the widget's
|
|
2775
|
+
// theme applier only honors string values) so vault inputs/placeholders
|
|
2776
|
+
// match the AVS fields' weight per theme (default 400).
|
|
2777
|
+
fontWeight: String(toCssWeight(nameInput?.fontWeight) ?? 400),
|
|
2778
|
+
borderRadius: asString(vars?.borderRadius) ?? "8px"
|
|
2779
|
+
};
|
|
2780
|
+
}, [appearance, bStyles, layout]);
|
|
2615
2781
|
const isInlineSessionPatchProcessing = checkout.inlineSessionPatchProcessing ?? false;
|
|
2616
2782
|
const isSubmitting = (externalProcessing ?? processing) || isInlineSessionPatchProcessing;
|
|
2617
2783
|
const isSelfContained = !onTokenizedBody;
|
|
2618
2784
|
const baseUrl = resolvedBillingApiUrl.replace(/\/+$/, "");
|
|
2619
|
-
const resolvedAccount = (0,
|
|
2785
|
+
const resolvedAccount = (0, import_react9.useMemo)(() => mergeAccountPatch({
|
|
2620
2786
|
userId,
|
|
2621
2787
|
email,
|
|
2622
2788
|
firstName,
|
|
@@ -2624,17 +2790,17 @@ function SplitCardFormInner({
|
|
|
2624
2790
|
country: countryProp,
|
|
2625
2791
|
zip: zipProp
|
|
2626
2792
|
}, accountPatch), [userId, email, firstName, lastName, countryProp, zipProp, accountPatch]);
|
|
2627
|
-
const stripeInstance = (0,
|
|
2793
|
+
const stripeInstance = (0, import_react9.useMemo)(() => {
|
|
2628
2794
|
if (!flopay) return null;
|
|
2629
2795
|
return flopay.getRawProvider();
|
|
2630
2796
|
}, [flopay]);
|
|
2631
|
-
const paypalStripeInstance = (0,
|
|
2797
|
+
const paypalStripeInstance = (0, import_react9.useMemo)(() => {
|
|
2632
2798
|
if (!paypalFlopay) return null;
|
|
2633
2799
|
return paypalFlopay.getRawProvider();
|
|
2634
2800
|
}, [paypalFlopay]);
|
|
2635
2801
|
const amountInCents = totalAmount || 100;
|
|
2636
2802
|
const stripeAppearanceProp = appearance ? { appearance } : null;
|
|
2637
|
-
const paymentElementAppearance = (0,
|
|
2803
|
+
const paymentElementAppearance = (0, import_react9.useMemo)(() => {
|
|
2638
2804
|
const base = appearance ?? {};
|
|
2639
2805
|
const baseRules = base.rules ?? {};
|
|
2640
2806
|
return {
|
|
@@ -2654,7 +2820,7 @@ function SplitCardFormInner({
|
|
|
2654
2820
|
}
|
|
2655
2821
|
};
|
|
2656
2822
|
}, [appearance]);
|
|
2657
|
-
const walletOptions = (0,
|
|
2823
|
+
const walletOptions = (0, import_react9.useMemo)(() => {
|
|
2658
2824
|
const modeOptions = resolveWalletElementsMode(totalAmount);
|
|
2659
2825
|
return {
|
|
2660
2826
|
...modeOptions,
|
|
@@ -2665,7 +2831,7 @@ function SplitCardFormInner({
|
|
|
2665
2831
|
...stripeAppearanceProp
|
|
2666
2832
|
};
|
|
2667
2833
|
}, [totalAmount, currency, stripeAppearanceProp]);
|
|
2668
|
-
const paypalOptions = (0,
|
|
2834
|
+
const paypalOptions = (0, import_react9.useMemo)(() => ({
|
|
2669
2835
|
mode: "payment",
|
|
2670
2836
|
amount: amountInCents,
|
|
2671
2837
|
currency: currency.toLowerCase(),
|
|
@@ -2673,35 +2839,183 @@ function SplitCardFormInner({
|
|
|
2673
2839
|
setupFutureUsage: "off_session",
|
|
2674
2840
|
...stripeAppearanceProp
|
|
2675
2841
|
}), [amountInCents, currency, stripeAppearanceProp]);
|
|
2676
|
-
const updateError = (0,
|
|
2842
|
+
const updateError = (0, import_react9.useCallback)(
|
|
2677
2843
|
(err) => {
|
|
2678
2844
|
setError(err);
|
|
2679
2845
|
onErrorChange?.(err);
|
|
2680
2846
|
},
|
|
2681
2847
|
[onErrorChange]
|
|
2682
2848
|
);
|
|
2683
|
-
|
|
2849
|
+
(0, import_react9.useEffect)(() => {
|
|
2850
|
+
if (!vaultActive || !cardCapture) return;
|
|
2851
|
+
cardCapture.setSubmitGate?.(avsInvalid);
|
|
2852
|
+
}, [vaultActive, cardCapture, avsInvalid]);
|
|
2853
|
+
(0, import_react9.useEffect)(() => {
|
|
2854
|
+
if (!vaultActive || !cardCapture) return;
|
|
2855
|
+
cardCapture.setCardFieldOrder?.(cardFieldOrder ?? null, avsConfig == null);
|
|
2856
|
+
}, [vaultActive, cardCapture, cardFieldOrder, avsConfig]);
|
|
2857
|
+
(0, import_react9.useEffect)(() => {
|
|
2858
|
+
if (viewState === "expanding" || viewState === "collapsing" || viewState === "apm-expanding" || viewState === "apm-collapsing") {
|
|
2859
|
+
updateError(null);
|
|
2860
|
+
}
|
|
2861
|
+
}, [viewState, updateError]);
|
|
2862
|
+
const emitDecline = (0, import_react9.useCallback)(
|
|
2684
2863
|
(method, input, overrides) => {
|
|
2685
2864
|
onDecline?.(buildDeclineEvent(method, input, overrides));
|
|
2686
2865
|
},
|
|
2687
2866
|
[onDecline]
|
|
2688
2867
|
);
|
|
2868
|
+
(0, import_react9.useEffect)(() => {
|
|
2869
|
+
if (!vaultActive || !sessionId) {
|
|
2870
|
+
setVaultMount(null);
|
|
2871
|
+
return;
|
|
2872
|
+
}
|
|
2873
|
+
const embedded = toVaultMount(session?.vault);
|
|
2874
|
+
if (embedded) {
|
|
2875
|
+
setVaultMount(embedded);
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2878
|
+
setVaultMount(null);
|
|
2879
|
+
let active = true;
|
|
2880
|
+
new import_js2.PaymentAPI(baseUrl).getVaultCapture(sessionId, nonce).then((block) => {
|
|
2881
|
+
if (!active) return;
|
|
2882
|
+
const mount = toVaultMount(block);
|
|
2883
|
+
if (mount) {
|
|
2884
|
+
setVaultMount(mount);
|
|
2885
|
+
} else {
|
|
2886
|
+
updateError("Failed to load the secure card form.");
|
|
2887
|
+
}
|
|
2888
|
+
}).catch((err) => {
|
|
2889
|
+
if (active) {
|
|
2890
|
+
updateError(err instanceof Error ? err.message : "Failed to load the secure card form.");
|
|
2891
|
+
}
|
|
2892
|
+
});
|
|
2893
|
+
return () => {
|
|
2894
|
+
active = false;
|
|
2895
|
+
};
|
|
2896
|
+
}, [
|
|
2897
|
+
vaultActive,
|
|
2898
|
+
sessionId,
|
|
2899
|
+
session?.vault?.html,
|
|
2900
|
+
session?.vault?.messageToken,
|
|
2901
|
+
session?.vault?.expectedOrigin,
|
|
2902
|
+
baseUrl,
|
|
2903
|
+
nonce,
|
|
2904
|
+
updateError
|
|
2905
|
+
]);
|
|
2906
|
+
(0, import_react9.useEffect)(() => {
|
|
2907
|
+
if (!vaultActive || !cardCapture) return;
|
|
2908
|
+
let cancelled = false;
|
|
2909
|
+
const offSubmitting = cardCapture.on("submitting", () => {
|
|
2910
|
+
setHasAttemptedSubmit(true);
|
|
2911
|
+
setOverlayStatus("processing");
|
|
2912
|
+
if (!sessionId || !nonce) return;
|
|
2913
|
+
const cc = selectedCountryRef.current || resolvedAccount.country || "US";
|
|
2914
|
+
const stateVisible = avsConfig ? (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) : false;
|
|
2915
|
+
const line1Visible = avsConfig ? (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, cc) : false;
|
|
2916
|
+
const zipVisible = avsConfig ? (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) : false;
|
|
2917
|
+
const cityVisible = avsConfig ? (0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) : false;
|
|
2918
|
+
const line2Visible = avsConfig ? (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_2, cc) : false;
|
|
2919
|
+
const derivedState = line1Visible && !stateVisible && zipVisible ? (0, import_shared5.getStateFromPostalCode)(cc, zipCodeRef.current ?? "") : null;
|
|
2920
|
+
const stateValue2 = stateVisible ? stateRef.current : derivedState;
|
|
2921
|
+
void new import_js2.PaymentAPI(baseUrl).patchAccountSnapshot(sessionId, nonce, {
|
|
2922
|
+
accountData: {
|
|
2923
|
+
userId: resolvedAccount.userId ?? "",
|
|
2924
|
+
email: resolvedAccount.email ?? "",
|
|
2925
|
+
firstName: resolvedAccount.firstName ?? fullName.trim().split(/\s+/)[0] ?? "",
|
|
2926
|
+
lastName: resolvedAccount.lastName ?? fullName.trim().split(/\s+/).slice(1).join(" ") ?? "",
|
|
2927
|
+
...zipVisible && zipCodeRef.current ? { zip: zipCodeRef.current } : {},
|
|
2928
|
+
...cityVisible && cityRef.current ? { city: cityRef.current } : {},
|
|
2929
|
+
...stateValue2 ? { state: stateValue2 } : {},
|
|
2930
|
+
...line1Visible && addressLine1Ref.current ? { addressLine1: addressLine1Ref.current } : {},
|
|
2931
|
+
...line2Visible && addressLine2Ref.current ? { addressLine2: addressLine2Ref.current } : {},
|
|
2932
|
+
country: cc
|
|
2933
|
+
},
|
|
2934
|
+
...avsCheckProp !== void 0 ? { avsCheck: avsCheckProp } : {},
|
|
2935
|
+
...avsConfig ? {
|
|
2936
|
+
avsConfig: {
|
|
2937
|
+
country: (0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc),
|
|
2938
|
+
postal_code: zipVisible,
|
|
2939
|
+
address_line_1: line1Visible,
|
|
2940
|
+
address_line_2: line2Visible,
|
|
2941
|
+
city: cityVisible,
|
|
2942
|
+
state: stateVisible
|
|
2943
|
+
}
|
|
2944
|
+
} : {}
|
|
2945
|
+
}).catch(() => {
|
|
2946
|
+
});
|
|
2947
|
+
});
|
|
2948
|
+
const offComplete = cardCapture.on("complete", async (event) => {
|
|
2949
|
+
markSessionRecentlyCompleted(event.sessionId ?? sessionId);
|
|
2950
|
+
setOverlayStatus("success");
|
|
2951
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));
|
|
2952
|
+
if (cancelled) return;
|
|
2953
|
+
onComplete?.({
|
|
2954
|
+
status: "succeeded",
|
|
2955
|
+
paymentIntentId: event.intentId,
|
|
2956
|
+
checkoutMethod: "card"
|
|
2957
|
+
});
|
|
2958
|
+
});
|
|
2959
|
+
const offDecline = cardCapture.on("decline", async (event) => {
|
|
2960
|
+
const message = event.message ?? "Your payment was declined. Please try another card or contact your bank.";
|
|
2961
|
+
updateError(message);
|
|
2962
|
+
setOverlayStatus("error");
|
|
2963
|
+
emitDecline("card", message, event.declineReason ? { declineCode: event.declineReason } : void 0);
|
|
2964
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
2965
|
+
if (cancelled) return;
|
|
2966
|
+
setOverlayStatus(null);
|
|
2967
|
+
});
|
|
2968
|
+
const offError = cardCapture.on("error", async (event) => {
|
|
2969
|
+
const message = event.message ?? "There was a problem processing your payment. Please try again.";
|
|
2970
|
+
updateError(message);
|
|
2971
|
+
setOverlayStatus("error");
|
|
2972
|
+
onError?.(new import_shared6.FloPayError(message, "api_error"));
|
|
2973
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
2974
|
+
if (cancelled) return;
|
|
2975
|
+
setOverlayStatus(null);
|
|
2976
|
+
});
|
|
2977
|
+
return () => {
|
|
2978
|
+
cancelled = true;
|
|
2979
|
+
offSubmitting();
|
|
2980
|
+
offComplete();
|
|
2981
|
+
offDecline();
|
|
2982
|
+
offError();
|
|
2983
|
+
};
|
|
2984
|
+
}, [
|
|
2985
|
+
vaultActive,
|
|
2986
|
+
cardCapture,
|
|
2987
|
+
sessionId,
|
|
2988
|
+
nonce,
|
|
2989
|
+
baseUrl,
|
|
2990
|
+
avsConfig,
|
|
2991
|
+
avsCheckProp,
|
|
2992
|
+
resolvedAccount.userId,
|
|
2993
|
+
resolvedAccount.email,
|
|
2994
|
+
resolvedAccount.firstName,
|
|
2995
|
+
resolvedAccount.lastName,
|
|
2996
|
+
resolvedAccount.country,
|
|
2997
|
+
fullName,
|
|
2998
|
+
onComplete,
|
|
2999
|
+
onError,
|
|
3000
|
+
updateError,
|
|
3001
|
+
emitDecline
|
|
3002
|
+
]);
|
|
2689
3003
|
const directPaypalConfigured = !!directPaypal?.clientId;
|
|
2690
3004
|
const hasEnabledMethodsPayload = Array.isArray(enabledPaymentMethods);
|
|
2691
3005
|
const hasEnabledMethods = hasEnabledMethodsPayload && enabledPaymentMethods.length > 0;
|
|
2692
3006
|
const paypalEnabled = hasEnabledMethodsPayload && enabledPaymentMethods.includes("paypal");
|
|
2693
|
-
const { expressMethods, paymentElementMethods } = (0,
|
|
3007
|
+
const { expressMethods, paymentElementMethods } = (0, import_react9.useMemo)(
|
|
2694
3008
|
() => (0, import_shared5.partitionStripeMethods)(enabledPaymentMethods, {
|
|
2695
3009
|
excludePaypal: directPaypalConfigured
|
|
2696
3010
|
}),
|
|
2697
3011
|
[enabledPaymentMethods, directPaypalConfigured]
|
|
2698
3012
|
);
|
|
2699
3013
|
const paypalRenderedSeparately = directPaypalConfigured || !!paypalFlopay;
|
|
2700
|
-
const expressMethodsForWalletRow = (0,
|
|
3014
|
+
const expressMethodsForWalletRow = (0, import_react9.useMemo)(
|
|
2701
3015
|
() => paypalRenderedSeparately ? expressMethods.filter((m) => m !== "paypal") : expressMethods,
|
|
2702
3016
|
[expressMethods, paypalRenderedSeparately]
|
|
2703
3017
|
);
|
|
2704
|
-
const legacyExpressMethods = (0,
|
|
3018
|
+
const legacyExpressMethods = (0, import_react9.useMemo)(() => {
|
|
2705
3019
|
const out = [];
|
|
2706
3020
|
if (showApplePay) out.push("apple_pay");
|
|
2707
3021
|
if (showGooglePay) out.push("google_pay");
|
|
@@ -2709,30 +3023,31 @@ function SplitCardFormInner({
|
|
|
2709
3023
|
}, [showApplePay, showGooglePay]);
|
|
2710
3024
|
const walletExpressMethods = hasEnabledMethodsPayload ? expressMethodsForWalletRow : legacyExpressMethods;
|
|
2711
3025
|
const showWallets = showStripe && walletExpressMethods.length > 0;
|
|
2712
|
-
const
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
),
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
3026
|
+
const apmCountry = enableAVS ? selectedCountry : countryProp;
|
|
3027
|
+
const paymentElementMethodsForCurrency = (0, import_react9.useMemo)(() => {
|
|
3028
|
+
const target = apmCountry?.trim().toUpperCase();
|
|
3029
|
+
if (!target) return paymentElementMethods;
|
|
3030
|
+
if (!enabledPaymentMethodCountries) {
|
|
3031
|
+
return (0, import_shared5.filterStripeMethodsByCountry)(paymentElementMethods, apmCountry);
|
|
3032
|
+
}
|
|
3033
|
+
return paymentElementMethods.filter((method) => {
|
|
3034
|
+
const allowed = enabledPaymentMethodCountries[method];
|
|
3035
|
+
return !allowed || allowed.length === 0 || allowed.includes(target);
|
|
3036
|
+
});
|
|
3037
|
+
}, [paymentElementMethods, apmCountry, enabledPaymentMethodCountries]);
|
|
3038
|
+
const paymentElementBaseOptions = (0, import_react9.useMemo)(() => ({
|
|
2724
3039
|
mode: "payment",
|
|
2725
3040
|
amount: amountInCents,
|
|
2726
3041
|
currency: currency.toLowerCase(),
|
|
2727
3042
|
paymentMethodCreation: "manual",
|
|
2728
3043
|
appearance: paymentElementAppearance
|
|
2729
3044
|
}), [amountInCents, currency, paymentElementAppearance]);
|
|
2730
|
-
const [paypalLoadState, setPaypalLoadState] = (0,
|
|
2731
|
-
const [walletLoadState, setWalletLoadState] = (0,
|
|
2732
|
-
const [paymentElementLoadState, setPaymentElementLoadState] = (0,
|
|
2733
|
-
const [directPaypalReady, setDirectPaypalReady] = (0,
|
|
2734
|
-
const [inAppBrowserDetected, setInAppBrowserDetected] = (0,
|
|
2735
|
-
(0,
|
|
3045
|
+
const [paypalLoadState, setPaypalLoadState] = (0, import_react9.useState)("loading");
|
|
3046
|
+
const [walletLoadState, setWalletLoadState] = (0, import_react9.useState)("loading");
|
|
3047
|
+
const [paymentElementLoadState, setPaymentElementLoadState] = (0, import_react9.useState)("loading");
|
|
3048
|
+
const [directPaypalReady, setDirectPaypalReady] = (0, import_react9.useState)(false);
|
|
3049
|
+
const [inAppBrowserDetected, setInAppBrowserDetected] = (0, import_react9.useState)();
|
|
3050
|
+
(0, import_react9.useEffect)(() => {
|
|
2736
3051
|
setInAppBrowserDetected(isInAppBrowser());
|
|
2737
3052
|
}, []);
|
|
2738
3053
|
const shouldShowPayPal = showPayPal && (directPaypalConfigured || (hasEnabledMethodsPayload ? paypalEnabled : inAppBrowserDetected === false));
|
|
@@ -2744,8 +3059,8 @@ function SplitCardFormInner({
|
|
|
2744
3059
|
const shouldDisplayPayPalRow = shouldRenderDirectPayPal ? directPaypalReady : shouldRenderStripePayPal && isExpressCheckoutRowVisible(paypalLoadState);
|
|
2745
3060
|
const shouldDisplayWalletRow = shouldRenderWallets && isExpressCheckoutRowVisible(walletLoadState);
|
|
2746
3061
|
const shouldDisplayPaymentElementRow = shouldRenderPaymentElement && paymentElementLoadState !== "load_error";
|
|
2747
|
-
const validationFiredRef = (0,
|
|
2748
|
-
(0,
|
|
3062
|
+
const validationFiredRef = (0, import_react9.useRef)(false);
|
|
3063
|
+
(0, import_react9.useEffect)(() => {
|
|
2749
3064
|
if (validationFiredRef.current) return;
|
|
2750
3065
|
if (!showStripe && !showPayPal) {
|
|
2751
3066
|
validationFiredRef.current = true;
|
|
@@ -2765,8 +3080,8 @@ function SplitCardFormInner({
|
|
|
2765
3080
|
updateError(err.message);
|
|
2766
3081
|
}
|
|
2767
3082
|
}, [showStripe, showPayPal, directPaypalConfigured, paypalStripeInstance, onError, updateError]);
|
|
2768
|
-
const deprecationLoggedRef = (0,
|
|
2769
|
-
(0,
|
|
3083
|
+
const deprecationLoggedRef = (0, import_react9.useRef)(false);
|
|
3084
|
+
(0, import_react9.useEffect)(() => {
|
|
2770
3085
|
if (deprecationLoggedRef.current) return;
|
|
2771
3086
|
if (!hasEnabledMethods) return;
|
|
2772
3087
|
const stale = [];
|
|
@@ -2778,14 +3093,14 @@ function SplitCardFormInner({
|
|
|
2778
3093
|
`[FloPay] ${stale.join(" / ")} ${stale.length === 1 ? "is" : "are"} deprecated: the Apple Pay / Google Pay surface is now driven by \`gateways.stripe.enabledPaymentMethods\` on the session response. Remove the legacy prop(s) to silence this warning.`
|
|
2779
3094
|
);
|
|
2780
3095
|
}, [hasEnabledMethods, showApplePay, showGooglePay]);
|
|
2781
|
-
const handleNameChange = (0,
|
|
3096
|
+
const handleNameChange = (0, import_react9.useCallback)((value) => {
|
|
2782
3097
|
setFullName(value);
|
|
2783
3098
|
onFullNameChange?.(value);
|
|
2784
3099
|
const parts = value.trim().split(/\s+/);
|
|
2785
3100
|
onFirstNameChange?.(parts[0] ?? "");
|
|
2786
3101
|
onLastNameChange?.(parts.length > 1 ? parts.slice(1).join(" ") : "");
|
|
2787
3102
|
}, [onFullNameChange, onFirstNameChange, onLastNameChange]);
|
|
2788
|
-
const applyInlineSessionPatch = (0,
|
|
3103
|
+
const applyInlineSessionPatch = (0, import_react9.useCallback)(
|
|
2789
3104
|
(patch, method) => {
|
|
2790
3105
|
if (!checkout.applyInlineSessionPatch) {
|
|
2791
3106
|
return Promise.resolve({ error: null, sessionId, nonce });
|
|
@@ -2807,7 +3122,7 @@ function SplitCardFormInner({
|
|
|
2807
3122
|
},
|
|
2808
3123
|
[checkout.applyInlineSessionPatch, nonce, onError, sessionId, updateError]
|
|
2809
3124
|
);
|
|
2810
|
-
const runBeforeButtonClick = (0,
|
|
3125
|
+
const runBeforeButtonClick = (0, import_react9.useCallback)(async (method) => {
|
|
2811
3126
|
if (!onBeforeButtonClick) return { proceed: true };
|
|
2812
3127
|
try {
|
|
2813
3128
|
const result = await onBeforeButtonClick({
|
|
@@ -2844,7 +3159,7 @@ function SplitCardFormInner({
|
|
|
2844
3159
|
return { proceed: false };
|
|
2845
3160
|
}
|
|
2846
3161
|
}, [applyInlineSessionPatch, checkout.inlineSessionDraft, onBeforeButtonClick, onError, sessionId, updateError]);
|
|
2847
|
-
const processPaymentInternal = (0,
|
|
3162
|
+
const processPaymentInternal = (0, import_react9.useCallback)(
|
|
2848
3163
|
async (tokenizedBody, overrides) => {
|
|
2849
3164
|
if (processingRef.current) return;
|
|
2850
3165
|
processingRef.current = true;
|
|
@@ -3055,7 +3370,7 @@ function SplitCardFormInner({
|
|
|
3055
3370
|
},
|
|
3056
3371
|
[baseUrl, sessionId, nonce, resolvedAccount, fullName, chv, flopay, paypalFlopay, onComplete, onError, updateError, emitDecline]
|
|
3057
3372
|
);
|
|
3058
|
-
const dispatchTokenizedBody = (0,
|
|
3373
|
+
const dispatchTokenizedBody = (0, import_react9.useCallback)(
|
|
3059
3374
|
(tokenizedBody, overrides) => {
|
|
3060
3375
|
if (onTokenizedBody) {
|
|
3061
3376
|
onTokenizedBody(tokenizedBody);
|
|
@@ -3065,7 +3380,7 @@ function SplitCardFormInner({
|
|
|
3065
3380
|
},
|
|
3066
3381
|
[onTokenizedBody, processPaymentInternal]
|
|
3067
3382
|
);
|
|
3068
|
-
(0,
|
|
3383
|
+
(0, import_react9.useImperativeHandle)(innerRef, () => ({
|
|
3069
3384
|
async handleNextAction(secret) {
|
|
3070
3385
|
if (!flopay) return;
|
|
3071
3386
|
setIs3DSActive(true);
|
|
@@ -3092,8 +3407,8 @@ function SplitCardFormInner({
|
|
|
3092
3407
|
}
|
|
3093
3408
|
}
|
|
3094
3409
|
}), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
|
|
3095
|
-
const stripeResumeAttemptedRef = (0,
|
|
3096
|
-
(0,
|
|
3410
|
+
const stripeResumeAttemptedRef = (0, import_react9.useRef)(false);
|
|
3411
|
+
(0, import_react9.useEffect)(() => {
|
|
3097
3412
|
if (typeof window === "undefined" || stripeResumeAttemptedRef.current) return;
|
|
3098
3413
|
const params = new URLSearchParams(window.location.search);
|
|
3099
3414
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -3171,10 +3486,11 @@ function SplitCardFormInner({
|
|
|
3171
3486
|
}, persistedOverrides);
|
|
3172
3487
|
})();
|
|
3173
3488
|
}, [sessionId, dispatchTokenizedBody, flopay, updateError, emitDecline]);
|
|
3174
|
-
const handleSubmit = (0,
|
|
3489
|
+
const handleSubmit = (0, import_react9.useCallback)(
|
|
3175
3490
|
async (e) => {
|
|
3176
3491
|
e.preventDefault();
|
|
3177
3492
|
if (!flopay || !elements || isSubmitting || processingRef.current) return;
|
|
3493
|
+
if (vaultActive) return;
|
|
3178
3494
|
if (layout !== "buttons") {
|
|
3179
3495
|
onButtonClick?.("card");
|
|
3180
3496
|
}
|
|
@@ -3202,11 +3518,13 @@ function SplitCardFormInner({
|
|
|
3202
3518
|
return;
|
|
3203
3519
|
}
|
|
3204
3520
|
}
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3521
|
+
if (!vaultActive) {
|
|
3522
|
+
const submitResult = await flopay.submitElements();
|
|
3523
|
+
if (submitResult.error) {
|
|
3524
|
+
updateError(submitResult.error.message);
|
|
3525
|
+
onError?.(submitResult.error);
|
|
3526
|
+
return;
|
|
3527
|
+
}
|
|
3210
3528
|
}
|
|
3211
3529
|
const billingAddress = {};
|
|
3212
3530
|
const cc = selectedCountryRef.current;
|
|
@@ -3231,75 +3549,77 @@ function SplitCardFormInner({
|
|
|
3231
3549
|
...fullName.trim() ? { name: fullName.trim() } : {},
|
|
3232
3550
|
...Object.keys(billingAddress).length > 0 ? { address: billingAddress } : {}
|
|
3233
3551
|
};
|
|
3234
|
-
const pmResult = await flopay.createPaymentMethod(billingDetails);
|
|
3235
|
-
if (pmResult.error || !pmResult.paymentMethodId) {
|
|
3236
|
-
updateError(pmResult.error?.message ?? "Failed to create payment method.");
|
|
3237
|
-
return;
|
|
3238
|
-
}
|
|
3239
3552
|
if (!sessionId || !resolvedAccount.email) {
|
|
3240
3553
|
throw new import_shared6.FloPayError("Missing sessionId or email", "validation_error");
|
|
3241
3554
|
}
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3555
|
+
{
|
|
3556
|
+
const pmResult = await flopay.createPaymentMethod(billingDetails);
|
|
3557
|
+
if (pmResult.error || !pmResult.paymentMethodId) {
|
|
3558
|
+
updateError(pmResult.error?.message ?? "Failed to create payment method.");
|
|
3559
|
+
return;
|
|
3560
|
+
}
|
|
3561
|
+
const intentHeaders = { "Content-Type": "application/json" };
|
|
3562
|
+
if (nonce) intentHeaders["x-checkout-session-token"] = nonce;
|
|
3563
|
+
const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
|
|
3564
|
+
method: "POST",
|
|
3565
|
+
headers: intentHeaders,
|
|
3566
|
+
body: JSON.stringify({
|
|
3567
|
+
sessionId,
|
|
3568
|
+
email: resolvedAccount.email,
|
|
3569
|
+
paymentMethodType: pmResult.paymentMethodId,
|
|
3570
|
+
isPaypal: false
|
|
3571
|
+
})
|
|
3572
|
+
});
|
|
3573
|
+
if (!intentResponse.ok) {
|
|
3574
|
+
const intentError = await buildFloPayApiErrorFromResponse(
|
|
3575
|
+
intentResponse,
|
|
3576
|
+
"Failed to create payment intent"
|
|
3577
|
+
);
|
|
3578
|
+
setOverlayStatus("error");
|
|
3579
|
+
updateError(intentError.message);
|
|
3580
|
+
onError?.(intentError);
|
|
3581
|
+
emitDecline("card", intentError);
|
|
3582
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3583
|
+
return;
|
|
3584
|
+
}
|
|
3585
|
+
const intentJson = await intentResponse.json();
|
|
3586
|
+
const intentClientSecret = intentJson.data?.id;
|
|
3587
|
+
if (!intentClientSecret) throw new import_shared6.FloPayError("No client_secret in payment intent response", "api_error");
|
|
3588
|
+
const confirmResult = await flopay.confirmCardPayment({
|
|
3589
|
+
clientSecret: intentClientSecret,
|
|
3590
|
+
paymentMethodId: pmResult.paymentMethodId
|
|
3591
|
+
});
|
|
3592
|
+
if (confirmResult.error) {
|
|
3593
|
+
setOverlayStatus("error");
|
|
3594
|
+
updateError(confirmResult.error.message);
|
|
3595
|
+
onError?.(confirmResult.error);
|
|
3596
|
+
emitDecline("card", confirmResult.error);
|
|
3597
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3598
|
+
return;
|
|
3599
|
+
}
|
|
3600
|
+
const rawProvider = typeof flopay.getRawProvider === "function" ? flopay.getRawProvider() : null;
|
|
3601
|
+
const confirmedPaymentIntent = await retrievePaymentIntentFromProvider(
|
|
3602
|
+
rawProvider,
|
|
3603
|
+
intentClientSecret
|
|
3258
3604
|
);
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
onError?.(confirmResult.error);
|
|
3277
|
-
emitDecline("card", confirmResult.error);
|
|
3278
|
-
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3279
|
-
return;
|
|
3280
|
-
}
|
|
3281
|
-
const rawProvider = typeof flopay.getRawProvider === "function" ? flopay.getRawProvider() : null;
|
|
3282
|
-
const confirmedPaymentIntent = await retrievePaymentIntentFromProvider(
|
|
3283
|
-
rawProvider,
|
|
3284
|
-
intentClientSecret
|
|
3285
|
-
);
|
|
3286
|
-
const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
|
|
3287
|
-
const paymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? pmResult.paymentMethodId;
|
|
3288
|
-
if (!paymentIntentId) {
|
|
3289
|
-
const error2 = new import_shared6.FloPayError("No payment intent returned after confirmation.", "api_error");
|
|
3290
|
-
setOverlayStatus("error");
|
|
3291
|
-
updateError(error2.message);
|
|
3292
|
-
onError?.(error2);
|
|
3293
|
-
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3294
|
-
return;
|
|
3605
|
+
const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
|
|
3606
|
+
const paymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? pmResult.paymentMethodId;
|
|
3607
|
+
if (!paymentIntentId) {
|
|
3608
|
+
const error2 = new import_shared6.FloPayError("No payment intent returned after confirmation.", "api_error");
|
|
3609
|
+
setOverlayStatus("error");
|
|
3610
|
+
updateError(error2.message);
|
|
3611
|
+
onError?.(error2);
|
|
3612
|
+
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
|
|
3613
|
+
return;
|
|
3614
|
+
}
|
|
3615
|
+
handedOff = isSelfContained;
|
|
3616
|
+
dispatchTokenizedBody({
|
|
3617
|
+
id: paymentMethodId,
|
|
3618
|
+
type: "card",
|
|
3619
|
+
threeDSecureActionResultTokenId: paymentIntentId,
|
|
3620
|
+
originalPaymentMethodId: pmResult.paymentMethodId
|
|
3621
|
+
});
|
|
3295
3622
|
}
|
|
3296
|
-
handedOff = isSelfContained;
|
|
3297
|
-
dispatchTokenizedBody({
|
|
3298
|
-
id: paymentMethodId,
|
|
3299
|
-
type: "card",
|
|
3300
|
-
threeDSecureActionResultTokenId: paymentIntentId,
|
|
3301
|
-
originalPaymentMethodId: pmResult.paymentMethodId
|
|
3302
|
-
});
|
|
3303
3623
|
} catch (err) {
|
|
3304
3624
|
setOverlayStatus("error");
|
|
3305
3625
|
updateError(err instanceof Error ? err.message : "An unexpected error occurred");
|
|
@@ -3311,11 +3631,11 @@ function SplitCardFormInner({
|
|
|
3311
3631
|
}
|
|
3312
3632
|
}
|
|
3313
3633
|
},
|
|
3314
|
-
[flopay, elements, isSubmitting, sessionId, nonce, resolvedAccount.email, baseUrl, isSelfContained, dispatchTokenizedBody, onButtonClick, onError, updateError, emitDecline, layout]
|
|
3634
|
+
[flopay, elements, isSubmitting, sessionId, nonce, resolvedAccount.email, baseUrl, isSelfContained, vaultActive, dispatchTokenizedBody, onButtonClick, onError, updateError, emitDecline, layout]
|
|
3315
3635
|
);
|
|
3316
|
-
const isReady = flopay !== null && elements !== null;
|
|
3636
|
+
const isReady = flopay !== null && (vaultActive || elements !== null);
|
|
3317
3637
|
if (!isReady) {
|
|
3318
|
-
return /* @__PURE__ */ (0,
|
|
3638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
|
|
3319
3639
|
}
|
|
3320
3640
|
const isButtons = layout === "buttons";
|
|
3321
3641
|
const appearanceVars = appearance?.variables;
|
|
@@ -3323,6 +3643,8 @@ function SplitCardFormInner({
|
|
|
3323
3643
|
const appearanceColorBg = appearanceVars?.colorBackground;
|
|
3324
3644
|
const themedWrapperBg = appearanceColorBg && !SDK_DEFAULT_WHITES.has(appearanceColorBg) ? appearanceColorBg : void 0;
|
|
3325
3645
|
const resolvedBorder = bStyles.cardInputBorder ?? (isButtons ? "#e5e7eb" : "#A4A4FF");
|
|
3646
|
+
const resolvedDangerColor = appearanceVars?.colorDanger ?? "#dc2626";
|
|
3647
|
+
const avsBorderColor = (fieldInvalid) => hasAttemptedSubmit && fieldInvalid ? resolvedDangerColor : resolvedBorder;
|
|
3326
3648
|
const cardBg = bStyles.cardFormContainer?.backgroundColor ?? themedWrapperBg ?? (isButtons ? "white" : "#EDEDFF");
|
|
3327
3649
|
const cardInputBg = bStyles.cardInputBackground ?? appearanceVars?.colorBackground ?? "white";
|
|
3328
3650
|
const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);
|
|
@@ -3334,7 +3656,9 @@ function SplitCardFormInner({
|
|
|
3334
3656
|
const resolvedInputColor = bStyles.cardInputColor ?? (typeof nameInputOverrides?.color === "string" ? nameInputOverrides.color : void 0) ?? appearanceVars?.colorText ?? "#262833";
|
|
3335
3657
|
const resolvedPlaceholderColor = bStyles.cardInputPlaceholderColor ?? "#9ca3af";
|
|
3336
3658
|
const resolvedBorderRadius = appearanceVars?.borderRadius ?? "8px";
|
|
3659
|
+
const buttonBorderRadius = appearanceVars?.borderRadius ?? bStyles.cardButton?.borderRadius ?? resolvedBorderRadius;
|
|
3337
3660
|
const resolvedPrimaryColor = appearanceVars?.colorPrimary ?? "#4A49FF";
|
|
3661
|
+
const resolvedPrimaryHoverColor = appearanceVars?.colorPrimaryHover ?? darkenHex(resolvedPrimaryColor, 0.12);
|
|
3338
3662
|
const resolvedTitleColor = appearanceVars?.colorText ?? "#262833";
|
|
3339
3663
|
const sharedInputTypography = {
|
|
3340
3664
|
fontSize: resolvedInputFontSize,
|
|
@@ -3368,14 +3692,73 @@ function SplitCardFormInner({
|
|
|
3368
3692
|
const containerOverrides = bStyles.cardFormContainer ?? {};
|
|
3369
3693
|
const containerPadding = containerOverrides.padding ?? (isButtons ? "0" : "1rem");
|
|
3370
3694
|
const containerRadius = containerOverrides.borderRadius ?? resolvedBorderRadius;
|
|
3371
|
-
const
|
|
3695
|
+
const vaultCardFieldsNode = cardCapture && vaultMount ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3696
|
+
VaultCardFields,
|
|
3697
|
+
{
|
|
3698
|
+
capture: cardCapture,
|
|
3699
|
+
html: vaultMount.html,
|
|
3700
|
+
messageToken: vaultMount.messageToken,
|
|
3701
|
+
expectedOrigin: vaultMount.expectedOrigin,
|
|
3702
|
+
theme: vaultThemeColors,
|
|
3703
|
+
onReady: () => {
|
|
3704
|
+
setFormReady(true);
|
|
3705
|
+
if (!avsConfig || typeof document === "undefined") return;
|
|
3706
|
+
const focusFirstAvs = () => {
|
|
3707
|
+
const block = document.querySelector('[data-testid="flopay-avs-fields"]');
|
|
3708
|
+
const first = block?.querySelector(
|
|
3709
|
+
"input:not([disabled]), select:not([disabled])"
|
|
3710
|
+
);
|
|
3711
|
+
first?.focus();
|
|
3712
|
+
};
|
|
3713
|
+
focusFirstAvs();
|
|
3714
|
+
let tries = 0;
|
|
3715
|
+
const timer = window.setInterval(() => {
|
|
3716
|
+
tries += 1;
|
|
3717
|
+
const active = document.activeElement;
|
|
3718
|
+
const onIframe = !!active && active.tagName === "IFRAME" && active.id === "flopay_vault_form_iframe";
|
|
3719
|
+
if (onIframe) {
|
|
3720
|
+
focusFirstAvs();
|
|
3721
|
+
window.clearInterval(timer);
|
|
3722
|
+
} else if (tries >= 50) {
|
|
3723
|
+
window.clearInterval(timer);
|
|
3724
|
+
}
|
|
3725
|
+
}, 100);
|
|
3726
|
+
},
|
|
3727
|
+
onError: (message) => updateError(message),
|
|
3728
|
+
onValidation: (message) => {
|
|
3729
|
+
updateError(message);
|
|
3730
|
+
if (message) setOverlayStatus(null);
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3734
|
+
"div",
|
|
3735
|
+
{
|
|
3736
|
+
"data-testid": "flopay-vault-loading",
|
|
3737
|
+
style: {
|
|
3738
|
+
minHeight: 120,
|
|
3739
|
+
display: "flex",
|
|
3740
|
+
alignItems: "center",
|
|
3741
|
+
justifyContent: "center",
|
|
3742
|
+
color: "#6b7280",
|
|
3743
|
+
fontSize: 14
|
|
3744
|
+
},
|
|
3745
|
+
children: "Loading secure card form\u2026"
|
|
3746
|
+
}
|
|
3747
|
+
);
|
|
3748
|
+
const cardFormBlock = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
|
|
3372
3749
|
backgroundColor: cardBg,
|
|
3373
3750
|
borderRadius: containerRadius,
|
|
3374
3751
|
...containerOverrides,
|
|
3375
3752
|
padding: containerPadding,
|
|
3376
|
-
...sharedInputPlaceholderVars
|
|
3753
|
+
...sharedInputPlaceholderVars,
|
|
3754
|
+
// Flex column (BOTH layouts, so default and buttons>card never diverge) so
|
|
3755
|
+
// AVS can be ordered above the vault widget — its submit lives inside the
|
|
3756
|
+
// iframe, so AVS can't sit between fields and button; it goes above the
|
|
3757
|
+
// card form instead of after the button.
|
|
3758
|
+
display: "flex",
|
|
3759
|
+
flexDirection: "column"
|
|
3377
3760
|
}, children: [
|
|
3378
|
-
/* @__PURE__ */ (0,
|
|
3761
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
|
|
3379
3762
|
.flopay-shared-input::placeholder {
|
|
3380
3763
|
color: var(--flopay-input-placeholder-color);
|
|
3381
3764
|
opacity: 1;
|
|
@@ -3384,12 +3767,14 @@ function SplitCardFormInner({
|
|
|
3384
3767
|
font-weight: var(--flopay-input-font-weight);
|
|
3385
3768
|
}
|
|
3386
3769
|
` }),
|
|
3387
|
-
isButtons && showCardForm && /* @__PURE__ */ (0,
|
|
3770
|
+
isButtons && showCardForm && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
|
|
3388
3771
|
display: "flex",
|
|
3389
3772
|
alignItems: "center",
|
|
3390
|
-
padding: "0.75rem 0 0.625rem"
|
|
3773
|
+
padding: "0.75rem 0 0.625rem",
|
|
3774
|
+
// Keep the header on top when AVS is ordered above the card on vault.
|
|
3775
|
+
order: vaultActive ? -2 : 0
|
|
3391
3776
|
}, children: [
|
|
3392
|
-
/* @__PURE__ */ (0,
|
|
3777
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3393
3778
|
"button",
|
|
3394
3779
|
{
|
|
3395
3780
|
type: "button",
|
|
@@ -3411,7 +3796,7 @@ function SplitCardFormInner({
|
|
|
3411
3796
|
},
|
|
3412
3797
|
"aria-label": "Back to payment methods",
|
|
3413
3798
|
children: [
|
|
3414
|
-
/* @__PURE__ */ (0,
|
|
3799
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
|
|
3415
3800
|
display: "inline-flex",
|
|
3416
3801
|
alignItems: "center",
|
|
3417
3802
|
justifyContent: "center",
|
|
@@ -3421,12 +3806,12 @@ function SplitCardFormInner({
|
|
|
3421
3806
|
backgroundColor: "#f3f4f6",
|
|
3422
3807
|
transition: "background-color 0.15s",
|
|
3423
3808
|
...bStyles.backButtonIcon
|
|
3424
|
-
}, children: /* @__PURE__ */ (0,
|
|
3425
|
-
/* @__PURE__ */ (0,
|
|
3809
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
|
|
3810
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
3426
3811
|
]
|
|
3427
3812
|
}
|
|
3428
3813
|
),
|
|
3429
|
-
hideTitle ? /* @__PURE__ */ (0,
|
|
3814
|
+
hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3430
3815
|
flex: 1,
|
|
3431
3816
|
textAlign: "center",
|
|
3432
3817
|
fontWeight: 600,
|
|
@@ -3434,58 +3819,65 @@ function SplitCardFormInner({
|
|
|
3434
3819
|
color: "#262833",
|
|
3435
3820
|
paddingRight: 80,
|
|
3436
3821
|
...bStyles.title
|
|
3437
|
-
}, children: /* @__PURE__ */ (0,
|
|
3822
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TitleContentSlot, { content: cardTitleContent }) })
|
|
3438
3823
|
] }),
|
|
3439
|
-
!isButtons && !hideTitle && /* @__PURE__ */ (0,
|
|
3824
|
+
!isButtons && !hideTitle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3440
3825
|
textAlign: "center",
|
|
3441
3826
|
fontWeight: 600,
|
|
3442
3827
|
fontSize: "1.1rem",
|
|
3443
3828
|
padding: "0.5rem 0",
|
|
3444
3829
|
color: resolvedTitleColor,
|
|
3830
|
+
// Keep the title at the very top on the vault path. The card-form slot
|
|
3831
|
+
// (-2) and AVS block (-1) are ordered below it but above the card form.
|
|
3832
|
+
order: vaultActive ? -3 : 0,
|
|
3445
3833
|
...bStyles.title
|
|
3446
|
-
}, children: /* @__PURE__ */ (0,
|
|
3447
|
-
/* @__PURE__ */ (0,
|
|
3448
|
-
|
|
3449
|
-
border: `1px solid ${resolvedBorder}`,
|
|
3450
|
-
borderTopLeftRadius: "8px",
|
|
3451
|
-
borderTopRightRadius: "8px",
|
|
3452
|
-
padding: "10px"
|
|
3453
|
-
}, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
|
|
3454
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex" }, children: [
|
|
3455
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
|
|
3456
|
-
flex: 1,
|
|
3457
|
-
backgroundColor: cardInputBg,
|
|
3458
|
-
// Longhand only — mixing `border` shorthand with per-side
|
|
3459
|
-
// overrides triggers React's "shorthand vs longhand" warning
|
|
3460
|
-
// because render order isn't deterministic.
|
|
3461
|
-
borderTop: "none",
|
|
3462
|
-
borderRight: "none",
|
|
3463
|
-
borderBottom: `1px solid ${resolvedBorder}`,
|
|
3464
|
-
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3465
|
-
borderBottomLeftRadius: "8px",
|
|
3466
|
-
padding: "10px"
|
|
3467
|
-
}, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardExpiryElement, { options: stripeElementStyle }) }),
|
|
3468
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
|
|
3469
|
-
flex: 1,
|
|
3834
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TitleContentSlot, { content: cardTitleContent }) }),
|
|
3835
|
+
!vaultActive && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
3836
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3470
3837
|
backgroundColor: cardInputBg,
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3475
|
-
borderBottomRightRadius: "8px",
|
|
3838
|
+
border: `1px solid ${resolvedBorder}`,
|
|
3839
|
+
borderTopLeftRadius: resolvedBorderRadius,
|
|
3840
|
+
borderTopRightRadius: resolvedBorderRadius,
|
|
3476
3841
|
padding: "10px"
|
|
3477
|
-
}, children: /* @__PURE__ */ (0,
|
|
3842
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
|
|
3843
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex" }, children: [
|
|
3844
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3845
|
+
flex: 1,
|
|
3846
|
+
backgroundColor: cardInputBg,
|
|
3847
|
+
// Longhand only — mixing `border` shorthand with per-side
|
|
3848
|
+
// overrides triggers React's "shorthand vs longhand" warning
|
|
3849
|
+
// because render order isn't deterministic.
|
|
3850
|
+
borderTop: "none",
|
|
3851
|
+
borderRight: "none",
|
|
3852
|
+
borderBottom: `1px solid ${resolvedBorder}`,
|
|
3853
|
+
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3854
|
+
borderBottomLeftRadius: resolvedBorderRadius,
|
|
3855
|
+
padding: "10px"
|
|
3856
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardExpiryElement, { options: stripeElementStyle }) }),
|
|
3857
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3858
|
+
flex: 1,
|
|
3859
|
+
backgroundColor: cardInputBg,
|
|
3860
|
+
borderTop: "none",
|
|
3861
|
+
borderRight: `1px solid ${resolvedBorder}`,
|
|
3862
|
+
borderBottom: `1px solid ${resolvedBorder}`,
|
|
3863
|
+
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3864
|
+
borderBottomRightRadius: resolvedBorderRadius,
|
|
3865
|
+
padding: "10px"
|
|
3866
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardCvcElement, { options: stripeElementStyle }) })
|
|
3867
|
+
] })
|
|
3478
3868
|
] }),
|
|
3479
|
-
/* @__PURE__ */ (0,
|
|
3869
|
+
!vaultActive && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3480
3870
|
backgroundColor: cardInputBg,
|
|
3481
3871
|
border: `1px solid ${resolvedBorder}`,
|
|
3482
|
-
borderRadius:
|
|
3872
|
+
borderRadius: resolvedBorderRadius,
|
|
3483
3873
|
marginTop: "0.5rem",
|
|
3484
3874
|
padding: "10px"
|
|
3485
|
-
}, children: /* @__PURE__ */ (0,
|
|
3875
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3486
3876
|
"input",
|
|
3487
3877
|
{
|
|
3488
3878
|
className: "flopay-shared-input",
|
|
3879
|
+
id: "flopay-cc-name",
|
|
3880
|
+
name: "cc-name",
|
|
3489
3881
|
placeholder: "Full Name on Card",
|
|
3490
3882
|
autoComplete: "cc-name",
|
|
3491
3883
|
value: fullName,
|
|
@@ -3502,32 +3894,32 @@ function SplitCardFormInner({
|
|
|
3502
3894
|
}
|
|
3503
3895
|
}
|
|
3504
3896
|
) }),
|
|
3505
|
-
avsConfig && (() => {
|
|
3897
|
+
avsConfig && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { order: vaultActive ? -1 : 0 }, "data-testid": "flopay-avs-fields", children: (() => {
|
|
3506
3898
|
const cc = selectedCountry;
|
|
3507
|
-
const inputWrapStyle = (
|
|
3899
|
+
const inputWrapStyle = (invalid = false) => ({
|
|
3508
3900
|
backgroundColor: cardInputBg,
|
|
3509
|
-
border: `1px solid ${
|
|
3510
|
-
borderRadius:
|
|
3901
|
+
border: `1px solid ${avsBorderColor(invalid)}`,
|
|
3902
|
+
borderRadius: resolvedBorderRadius,
|
|
3511
3903
|
marginTop: "0.5rem",
|
|
3512
|
-
padding: "10px"
|
|
3513
|
-
...isButtons && extraStyle ? extraStyle : {}
|
|
3904
|
+
padding: "10px"
|
|
3514
3905
|
});
|
|
3515
3906
|
const inputFieldStyle = () => ({
|
|
3516
3907
|
width: "100%",
|
|
3517
3908
|
border: "none",
|
|
3518
3909
|
outline: "none",
|
|
3519
3910
|
background: "transparent",
|
|
3520
|
-
...sharedInputTypography
|
|
3521
|
-
...isButtons && bStyles.nameInput ? bStyles.nameInput : {}
|
|
3911
|
+
...sharedInputTypography
|
|
3522
3912
|
});
|
|
3523
3913
|
const stateOpts = (0, import_shared5.getStateOptions)(cc);
|
|
3524
|
-
return /* @__PURE__ */ (0,
|
|
3525
|
-
(0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, cc) && /* @__PURE__ */ (0,
|
|
3914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
3915
|
+
(0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: inputWrapStyle(invalidAvsFields.line1), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3526
3916
|
"input",
|
|
3527
3917
|
{
|
|
3528
3918
|
className: "flopay-shared-input",
|
|
3919
|
+
id: "flopay-billing-address-line1",
|
|
3920
|
+
name: "billing-address-line1",
|
|
3529
3921
|
placeholder: "Street Address (e.g. 123 Main St)",
|
|
3530
|
-
autoComplete: "address-line1",
|
|
3922
|
+
autoComplete: "billing address-line1",
|
|
3531
3923
|
value: addressLine1,
|
|
3532
3924
|
onChange: (e) => {
|
|
3533
3925
|
addressLine1Ref.current = e.target.value;
|
|
@@ -3539,12 +3931,14 @@ function SplitCardFormInner({
|
|
|
3539
3931
|
style: inputFieldStyle()
|
|
3540
3932
|
}
|
|
3541
3933
|
) }),
|
|
3542
|
-
(0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_2, cc) && /* @__PURE__ */ (0,
|
|
3934
|
+
(0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_2, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: inputWrapStyle(), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3543
3935
|
"input",
|
|
3544
3936
|
{
|
|
3545
3937
|
className: "flopay-shared-input",
|
|
3938
|
+
id: "flopay-billing-address-line2",
|
|
3939
|
+
name: "billing-address-line2",
|
|
3546
3940
|
placeholder: "Apt, Suite, Unit (optional)",
|
|
3547
|
-
autoComplete: "address-line2",
|
|
3941
|
+
autoComplete: "billing address-line2",
|
|
3548
3942
|
value: addressLine2,
|
|
3549
3943
|
onChange: (e) => {
|
|
3550
3944
|
addressLine2Ref.current = e.target.value;
|
|
@@ -3555,29 +3949,30 @@ function SplitCardFormInner({
|
|
|
3555
3949
|
style: inputFieldStyle()
|
|
3556
3950
|
}
|
|
3557
3951
|
) }),
|
|
3558
|
-
((0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc)) && /* @__PURE__ */ (0,
|
|
3952
|
+
((0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc)) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
|
|
3559
3953
|
display: "flex",
|
|
3560
3954
|
gap: "0",
|
|
3561
3955
|
marginTop: "0.5rem"
|
|
3562
3956
|
}, children: [
|
|
3563
|
-
(0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) && /* @__PURE__ */ (0,
|
|
3957
|
+
(0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3564
3958
|
flex: 1,
|
|
3565
3959
|
backgroundColor: cardInputBg,
|
|
3566
|
-
borderTop: `1px solid ${
|
|
3567
|
-
borderRight: `1px solid ${
|
|
3568
|
-
borderBottom: `1px solid ${
|
|
3569
|
-
borderLeft: `1px solid ${
|
|
3960
|
+
borderTop: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,
|
|
3961
|
+
borderRight: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,
|
|
3962
|
+
borderBottom: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,
|
|
3963
|
+
borderLeft: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,
|
|
3570
3964
|
padding: "10px",
|
|
3571
|
-
borderTopLeftRadius:
|
|
3572
|
-
borderBottomLeftRadius:
|
|
3573
|
-
...(0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) ? { borderRight: "none", borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius:
|
|
3574
|
-
|
|
3575
|
-
}, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
3965
|
+
borderTopLeftRadius: resolvedBorderRadius,
|
|
3966
|
+
borderBottomLeftRadius: resolvedBorderRadius,
|
|
3967
|
+
...(0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) ? { borderRight: "none", borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius: resolvedBorderRadius }
|
|
3968
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3576
3969
|
"input",
|
|
3577
3970
|
{
|
|
3578
3971
|
className: "flopay-shared-input",
|
|
3972
|
+
id: "flopay-billing-city",
|
|
3973
|
+
name: "billing-city",
|
|
3579
3974
|
placeholder: "City",
|
|
3580
|
-
autoComplete: "address-level2",
|
|
3975
|
+
autoComplete: "billing address-level2",
|
|
3581
3976
|
value: city,
|
|
3582
3977
|
onChange: (e) => {
|
|
3583
3978
|
cityRef.current = e.target.value;
|
|
@@ -3589,39 +3984,42 @@ function SplitCardFormInner({
|
|
|
3589
3984
|
style: inputFieldStyle()
|
|
3590
3985
|
}
|
|
3591
3986
|
) }),
|
|
3592
|
-
(0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) && /* @__PURE__ */ (0,
|
|
3987
|
+
(0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3593
3988
|
flex: 1,
|
|
3594
3989
|
backgroundColor: cardInputBg,
|
|
3595
|
-
border: `1px solid ${
|
|
3990
|
+
border: `1px solid ${avsBorderColor(invalidAvsFields.state)}`,
|
|
3596
3991
|
padding: "10px",
|
|
3597
|
-
borderTopRightRadius:
|
|
3598
|
-
borderBottomRightRadius:
|
|
3599
|
-
...(0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius:
|
|
3600
|
-
|
|
3601
|
-
}, children: stateOpts ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
3992
|
+
borderTopRightRadius: resolvedBorderRadius,
|
|
3993
|
+
borderBottomRightRadius: resolvedBorderRadius,
|
|
3994
|
+
...(0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius: resolvedBorderRadius }
|
|
3995
|
+
}, children: stateOpts ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3602
3996
|
"select",
|
|
3603
3997
|
{
|
|
3998
|
+
id: "flopay-billing-state",
|
|
3999
|
+
name: "billing-state",
|
|
3604
4000
|
value: stateValue,
|
|
3605
4001
|
onChange: (e) => {
|
|
3606
4002
|
stateRef.current = e.target.value;
|
|
3607
4003
|
setStateValue(e.target.value);
|
|
3608
4004
|
},
|
|
3609
4005
|
disabled: isSubmitting,
|
|
3610
|
-
autoComplete: "address-level1",
|
|
4006
|
+
autoComplete: "billing address-level1",
|
|
3611
4007
|
required: true,
|
|
3612
4008
|
"data-testid": "flopay-state",
|
|
3613
4009
|
style: { ...inputFieldStyle(), cursor: "pointer" },
|
|
3614
4010
|
children: [
|
|
3615
|
-
/* @__PURE__ */ (0,
|
|
3616
|
-
stateOpts.map((s) => /* @__PURE__ */ (0,
|
|
4011
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", children: (0, import_shared5.getStateLabel)(cc) }),
|
|
4012
|
+
stateOpts.map((s) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: s.code, children: s.name }, s.code))
|
|
3617
4013
|
]
|
|
3618
4014
|
}
|
|
3619
|
-
) : /* @__PURE__ */ (0,
|
|
4015
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3620
4016
|
"input",
|
|
3621
4017
|
{
|
|
3622
4018
|
className: "flopay-shared-input",
|
|
4019
|
+
id: "flopay-billing-state",
|
|
4020
|
+
name: "billing-state",
|
|
3623
4021
|
placeholder: (0, import_shared5.getStateLabel)(cc),
|
|
3624
|
-
autoComplete: "address-level1",
|
|
4022
|
+
autoComplete: "billing address-level1",
|
|
3625
4023
|
value: stateValue,
|
|
3626
4024
|
onChange: (e) => {
|
|
3627
4025
|
stateRef.current = e.target.value;
|
|
@@ -3634,13 +4032,13 @@ function SplitCardFormInner({
|
|
|
3634
4032
|
}
|
|
3635
4033
|
) })
|
|
3636
4034
|
] }),
|
|
3637
|
-
((0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc)) && /* @__PURE__ */ (0,
|
|
4035
|
+
((0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc)) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
|
|
3638
4036
|
display: "flex",
|
|
3639
4037
|
flexDirection: avsLayoutProp === "column" ? "column" : "row",
|
|
3640
4038
|
gap: avsLayoutProp === "column" ? "0.5rem" : "0",
|
|
3641
4039
|
marginTop: "0.5rem"
|
|
3642
4040
|
}, children: [
|
|
3643
|
-
(0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) && /* @__PURE__ */ (0,
|
|
4041
|
+
(0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3644
4042
|
flex: avsLayoutProp === "row" ? 1 : void 0,
|
|
3645
4043
|
backgroundColor: cardInputBg,
|
|
3646
4044
|
borderTop: `1px solid ${resolvedBorder}`,
|
|
@@ -3648,11 +4046,12 @@ function SplitCardFormInner({
|
|
|
3648
4046
|
borderBottom: `1px solid ${resolvedBorder}`,
|
|
3649
4047
|
borderLeft: `1px solid ${resolvedBorder}`,
|
|
3650
4048
|
padding: "10px",
|
|
3651
|
-
...avsLayoutProp === "row" && (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) ? { borderRadius: "0", borderTopLeftRadius:
|
|
3652
|
-
|
|
3653
|
-
}, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4049
|
+
...avsLayoutProp === "row" && (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) ? { borderRadius: "0", borderTopLeftRadius: resolvedBorderRadius, borderBottomLeftRadius: resolvedBorderRadius, borderRight: "none" } : { borderRadius: resolvedBorderRadius }
|
|
4050
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3654
4051
|
"select",
|
|
3655
4052
|
{
|
|
4053
|
+
id: "flopay-billing-country",
|
|
4054
|
+
name: "billing-country",
|
|
3656
4055
|
value: selectedCountry,
|
|
3657
4056
|
onChange: (e) => {
|
|
3658
4057
|
selectedCountryRef.current = e.target.value;
|
|
@@ -3662,29 +4061,30 @@ function SplitCardFormInner({
|
|
|
3662
4061
|
setStateValue("");
|
|
3663
4062
|
},
|
|
3664
4063
|
disabled: isSubmitting,
|
|
3665
|
-
autoComplete: "country",
|
|
4064
|
+
autoComplete: "billing country",
|
|
3666
4065
|
"data-testid": "flopay-country",
|
|
3667
4066
|
style: { ...inputFieldStyle(), cursor: "pointer" },
|
|
3668
|
-
children: import_shared5.COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ (0,
|
|
4067
|
+
children: import_shared5.COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("option", { value: c.code, children: [
|
|
3669
4068
|
c.flag,
|
|
3670
4069
|
" ",
|
|
3671
4070
|
c.name
|
|
3672
4071
|
] }, c.code))
|
|
3673
4072
|
}
|
|
3674
4073
|
) }),
|
|
3675
|
-
(0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) && /* @__PURE__ */ (0,
|
|
4074
|
+
(0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
3676
4075
|
flex: avsLayoutProp === "row" ? 1 : void 0,
|
|
3677
4076
|
backgroundColor: cardInputBg,
|
|
3678
|
-
border: `1px solid ${
|
|
4077
|
+
border: `1px solid ${avsBorderColor(invalidAvsFields.zip)}`,
|
|
3679
4078
|
padding: "10px",
|
|
3680
|
-
...avsLayoutProp === "row" && (0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) ? { borderRadius: "0", borderTopRightRadius:
|
|
3681
|
-
|
|
3682
|
-
}, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4079
|
+
...avsLayoutProp === "row" && (0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) ? { borderRadius: "0", borderTopRightRadius: resolvedBorderRadius, borderBottomRightRadius: resolvedBorderRadius } : { borderRadius: resolvedBorderRadius }
|
|
4080
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3683
4081
|
"input",
|
|
3684
4082
|
{
|
|
3685
4083
|
className: "flopay-shared-input",
|
|
4084
|
+
id: "flopay-billing-postal-code",
|
|
4085
|
+
name: "billing-postal-code",
|
|
3686
4086
|
placeholder: (0, import_shared5.getPostalCodeLabel)(selectedCountry),
|
|
3687
|
-
autoComplete: "postal-code",
|
|
4087
|
+
autoComplete: "billing postal-code",
|
|
3688
4088
|
value: zipCode,
|
|
3689
4089
|
onChange: (e) => {
|
|
3690
4090
|
zipCodeRef.current = e.target.value;
|
|
@@ -3699,8 +4099,10 @@ function SplitCardFormInner({
|
|
|
3699
4099
|
) })
|
|
3700
4100
|
] })
|
|
3701
4101
|
] });
|
|
3702
|
-
})(),
|
|
3703
|
-
|
|
4102
|
+
})() }),
|
|
4103
|
+
vaultActive && cardPreFormSlot && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { order: -2, width: "100%" }, children: cardPreFormSlot }),
|
|
4104
|
+
vaultActive && vaultCardFieldsNode,
|
|
4105
|
+
displayError && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
3704
4106
|
margin: "0.75rem 0",
|
|
3705
4107
|
padding: "0.625rem 0.875rem",
|
|
3706
4108
|
background: "#FEF2F2",
|
|
@@ -3714,15 +4116,21 @@ function SplitCardFormInner({
|
|
|
3714
4116
|
gap: "0.5rem",
|
|
3715
4117
|
...bStyles.errorBanner ? bStyles.errorBanner : {}
|
|
3716
4118
|
}, children: [
|
|
3717
|
-
/* @__PURE__ */ (0,
|
|
4119
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
3718
4120
|
displayError
|
|
3719
4121
|
] }),
|
|
3720
|
-
children ?? /* @__PURE__ */ (0,
|
|
4122
|
+
!vaultActive && (children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3721
4123
|
"button",
|
|
3722
4124
|
{
|
|
3723
4125
|
type: "submit",
|
|
3724
4126
|
disabled: !formReady || isSubmitting,
|
|
3725
4127
|
"data-testid": "flopay-submit",
|
|
4128
|
+
onMouseEnter: (e) => {
|
|
4129
|
+
if (formReady && !isSubmitting) e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;
|
|
4130
|
+
},
|
|
4131
|
+
onMouseLeave: (e) => {
|
|
4132
|
+
e.currentTarget.style.backgroundColor = bStyles.submitButton?.backgroundColor ?? resolvedPrimaryColor;
|
|
4133
|
+
},
|
|
3726
4134
|
style: {
|
|
3727
4135
|
width: "100%",
|
|
3728
4136
|
padding: "0.875rem",
|
|
@@ -3735,11 +4143,12 @@ function SplitCardFormInner({
|
|
|
3735
4143
|
fontWeight: 600,
|
|
3736
4144
|
cursor: !formReady || isSubmitting ? "not-allowed" : "pointer",
|
|
3737
4145
|
opacity: !formReady || isSubmitting ? 0.5 : 1,
|
|
4146
|
+
transition: "background-color 0.15s",
|
|
3738
4147
|
...bStyles.submitButton
|
|
3739
4148
|
},
|
|
3740
4149
|
children: isSubmitting ? "PROCESSING..." : submitLabel
|
|
3741
4150
|
}
|
|
3742
|
-
)
|
|
4151
|
+
))
|
|
3743
4152
|
] });
|
|
3744
4153
|
const gateDebugStyle = {
|
|
3745
4154
|
margin: 0,
|
|
@@ -3755,9 +4164,9 @@ function SplitCardFormInner({
|
|
|
3755
4164
|
const renderDirectPaypalGateDebug = (testId) => {
|
|
3756
4165
|
if (!debug) return null;
|
|
3757
4166
|
if (!showPayPal || !directPaypalConfigured) {
|
|
3758
|
-
return /* @__PURE__ */ (0,
|
|
4167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/DirectPayPal-debug - not enabled" });
|
|
3759
4168
|
}
|
|
3760
|
-
return /* @__PURE__ */ (0,
|
|
4169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: [
|
|
3761
4170
|
"FloPay/DirectPayPal-debug (parent gate)",
|
|
3762
4171
|
` showPayPal=${showPayPal}`,
|
|
3763
4172
|
` directPaypalConfigured=${directPaypalConfigured}`,
|
|
@@ -3770,9 +4179,9 @@ function SplitCardFormInner({
|
|
|
3770
4179
|
const renderStripeGateDebug = (testId) => {
|
|
3771
4180
|
if (!debug) return null;
|
|
3772
4181
|
if (!showStripe || !stripeInstance) {
|
|
3773
|
-
return /* @__PURE__ */ (0,
|
|
4182
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/Stripe-debug - not enabled" });
|
|
3774
4183
|
}
|
|
3775
|
-
return /* @__PURE__ */ (0,
|
|
4184
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: [
|
|
3776
4185
|
"FloPay/Stripe-debug (parent gate)",
|
|
3777
4186
|
` showStripe=${showStripe}`,
|
|
3778
4187
|
` currency=${currency}`,
|
|
@@ -3801,11 +4210,11 @@ function SplitCardFormInner({
|
|
|
3801
4210
|
const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
3802
4211
|
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;
|
|
3803
4212
|
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;
|
|
3804
|
-
return /* @__PURE__ */ (0,
|
|
3805
|
-
/* @__PURE__ */ (0,
|
|
3806
|
-
overlayStatus && /* @__PURE__ */ (0,
|
|
3807
|
-
/* @__PURE__ */ (0,
|
|
3808
|
-
/* @__PURE__ */ (0,
|
|
4213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
4214
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FloPayKeyframes, {}),
|
|
4215
|
+
overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
4216
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "grid" }, children: [
|
|
4217
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3809
4218
|
"div",
|
|
3810
4219
|
{
|
|
3811
4220
|
"data-testid": "flopay-buttons-panel",
|
|
@@ -3822,8 +4231,8 @@ function SplitCardFormInner({
|
|
|
3822
4231
|
children: [
|
|
3823
4232
|
renderDirectPaypalGateDebug("flopay-direct-paypal-gate-debug"),
|
|
3824
4233
|
renderStripeGateDebug("flopay-stripe-gate-debug"),
|
|
3825
|
-
shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0,
|
|
3826
|
-
paypalDirectRetry && /* @__PURE__ */ (0,
|
|
4234
|
+
shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4235
|
+
paypalDirectRetry && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3827
4236
|
"div",
|
|
3828
4237
|
{
|
|
3829
4238
|
"data-testid": "flopay-paypal-direct-retry-notice",
|
|
@@ -3839,7 +4248,7 @@ function SplitCardFormInner({
|
|
|
3839
4248
|
children: "Please confirm your PayPal payment to complete checkout."
|
|
3840
4249
|
}
|
|
3841
4250
|
),
|
|
3842
|
-
/* @__PURE__ */ (0,
|
|
4251
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3843
4252
|
DirectPayPalButton,
|
|
3844
4253
|
{
|
|
3845
4254
|
sessionId,
|
|
@@ -3865,7 +4274,7 @@ function SplitCardFormInner({
|
|
|
3865
4274
|
paypalDirectRetry?.orderId ?? "fresh"
|
|
3866
4275
|
)
|
|
3867
4276
|
] }),
|
|
3868
|
-
shouldRenderStripePayPal && /* @__PURE__ */ (0,
|
|
4277
|
+
shouldRenderStripePayPal && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3869
4278
|
PayPalButtonInner,
|
|
3870
4279
|
{
|
|
3871
4280
|
sessionId,
|
|
@@ -3879,10 +4288,10 @@ function SplitCardFormInner({
|
|
|
3879
4288
|
onDecline,
|
|
3880
4289
|
runBeforeButtonClick,
|
|
3881
4290
|
onLoadStateChange: setPaypalLoadState,
|
|
3882
|
-
placeholderBorderRadius:
|
|
4291
|
+
placeholderBorderRadius: buttonBorderRadius
|
|
3883
4292
|
}
|
|
3884
4293
|
) }),
|
|
3885
|
-
shouldRenderWallets ? /* @__PURE__ */ (0,
|
|
4294
|
+
shouldRenderWallets ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3886
4295
|
WalletButtonInner,
|
|
3887
4296
|
{
|
|
3888
4297
|
sessionId,
|
|
@@ -3896,10 +4305,10 @@ function SplitCardFormInner({
|
|
|
3896
4305
|
onDecline,
|
|
3897
4306
|
runBeforeButtonClick,
|
|
3898
4307
|
onLoadStateChange: setWalletLoadState,
|
|
3899
|
-
placeholderBorderRadius:
|
|
4308
|
+
placeholderBorderRadius: buttonBorderRadius
|
|
3900
4309
|
}
|
|
3901
|
-
) }) : shouldShowWallets ? /* @__PURE__ */ (0,
|
|
3902
|
-
shouldRenderPaymentElement && /* @__PURE__ */ (0,
|
|
4310
|
+
) }) : shouldShowWallets ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: buttonBorderRadius, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
|
|
4311
|
+
shouldRenderPaymentElement && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3903
4312
|
StripePaymentElementInner,
|
|
3904
4313
|
{
|
|
3905
4314
|
sessionId,
|
|
@@ -3927,11 +4336,11 @@ function SplitCardFormInner({
|
|
|
3927
4336
|
backgroundColor: bStyles.cardButton?.backgroundColor,
|
|
3928
4337
|
borderColor: bStyles.cardInputBorder,
|
|
3929
4338
|
textColor: bStyles.cardButton?.color,
|
|
3930
|
-
borderRadius:
|
|
4339
|
+
borderRadius: buttonBorderRadius
|
|
3931
4340
|
}
|
|
3932
4341
|
}
|
|
3933
4342
|
),
|
|
3934
|
-
showStripe && /* @__PURE__ */ (0,
|
|
4343
|
+
showStripe && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3935
4344
|
"button",
|
|
3936
4345
|
{
|
|
3937
4346
|
type: "button",
|
|
@@ -3959,7 +4368,8 @@ function SplitCardFormInner({
|
|
|
3959
4368
|
themeBundle,
|
|
3960
4369
|
resolvedPrimaryColor,
|
|
3961
4370
|
resolvedBorderRadius,
|
|
3962
|
-
submitButtonStyle: bStyles.submitButton
|
|
4371
|
+
submitButtonStyle: bStyles.submitButton,
|
|
4372
|
+
explicitPrimaryColor: appearanceVars?.colorPrimary
|
|
3963
4373
|
}),
|
|
3964
4374
|
fontSize: bStyles.cardButtonFontSize ?? "0.95rem",
|
|
3965
4375
|
fontWeight: 600,
|
|
@@ -3968,20 +4378,28 @@ function SplitCardFormInner({
|
|
|
3968
4378
|
alignItems: "center",
|
|
3969
4379
|
justifyContent: "center",
|
|
3970
4380
|
gap: "0.625rem",
|
|
3971
|
-
transition: "border-color 0.2s, box-shadow 0.2s, transform 0.1s",
|
|
4381
|
+
transition: "background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s",
|
|
3972
4382
|
position: "relative",
|
|
3973
4383
|
opacity: isSubmitting ? 0.6 : 1
|
|
3974
4384
|
},
|
|
4385
|
+
onMouseEnter: (e) => {
|
|
4386
|
+
if (!isSubmitting && (themeBundle || appearanceVars?.colorPrimary)) {
|
|
4387
|
+
e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;
|
|
4388
|
+
}
|
|
4389
|
+
},
|
|
4390
|
+
onMouseLeave: (e) => {
|
|
4391
|
+
if (themeBundle || appearanceVars?.colorPrimary) e.currentTarget.style.backgroundColor = resolvedPrimaryColor;
|
|
4392
|
+
},
|
|
3975
4393
|
onMouseDown: (e) => {
|
|
3976
4394
|
e.currentTarget.style.transform = "scale(0.985)";
|
|
3977
4395
|
},
|
|
3978
4396
|
onMouseUp: (e) => {
|
|
3979
4397
|
e.currentTarget.style.transform = "scale(1)";
|
|
3980
4398
|
},
|
|
3981
|
-
children: /* @__PURE__ */ (0,
|
|
4399
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardButtonContentSlot, { content: cardButtonContent })
|
|
3982
4400
|
}
|
|
3983
4401
|
),
|
|
3984
|
-
displayError && viewState === "buttons" && /* @__PURE__ */ (0,
|
|
4402
|
+
displayError && viewState === "buttons" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
|
|
3985
4403
|
margin: "0.25rem 0",
|
|
3986
4404
|
padding: "0.625rem 0.875rem",
|
|
3987
4405
|
background: "#FEF2F2",
|
|
@@ -3995,33 +4413,33 @@ function SplitCardFormInner({
|
|
|
3995
4413
|
gap: "0.5rem",
|
|
3996
4414
|
...bStyles.errorBanner ? bStyles.errorBanner : {}
|
|
3997
4415
|
}, children: [
|
|
3998
|
-
/* @__PURE__ */ (0,
|
|
4416
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
3999
4417
|
displayError
|
|
4000
4418
|
] })
|
|
4001
4419
|
]
|
|
4002
4420
|
}
|
|
4003
4421
|
),
|
|
4004
|
-
showStripe && isCardView && /* @__PURE__ */ (0,
|
|
4422
|
+
showStripe && isCardView && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
4005
4423
|
gridArea: "1 / 1",
|
|
4006
4424
|
...cardAnim ? { animation: cardAnim } : {},
|
|
4007
4425
|
...viewState === "collapsing" ? { pointerEvents: "none" } : {}
|
|
4008
4426
|
}, children: cardFormBlock }),
|
|
4009
|
-
showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && /* @__PURE__ */ (0,
|
|
4427
|
+
showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
4010
4428
|
gridArea: "1 / 1",
|
|
4011
4429
|
...apmAnim ? { animation: apmAnim } : {},
|
|
4012
4430
|
...viewState === "apm-collapsing" ? { pointerEvents: "none" } : {}
|
|
4013
|
-
}, children: /* @__PURE__ */ (0,
|
|
4431
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
|
|
4014
4432
|
backgroundColor: cardBg,
|
|
4015
4433
|
borderRadius: containerRadius,
|
|
4016
4434
|
...containerOverrides,
|
|
4017
4435
|
padding: containerPadding
|
|
4018
4436
|
}, children: [
|
|
4019
|
-
/* @__PURE__ */ (0,
|
|
4437
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
|
|
4020
4438
|
display: "flex",
|
|
4021
4439
|
alignItems: "center",
|
|
4022
4440
|
padding: "0.75rem 0 0.625rem"
|
|
4023
4441
|
}, children: [
|
|
4024
|
-
/* @__PURE__ */ (0,
|
|
4442
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
4025
4443
|
"button",
|
|
4026
4444
|
{
|
|
4027
4445
|
type: "button",
|
|
@@ -4044,7 +4462,7 @@ function SplitCardFormInner({
|
|
|
4044
4462
|
},
|
|
4045
4463
|
"aria-label": "Back to payment methods",
|
|
4046
4464
|
children: [
|
|
4047
|
-
/* @__PURE__ */ (0,
|
|
4465
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
|
|
4048
4466
|
display: "inline-flex",
|
|
4049
4467
|
alignItems: "center",
|
|
4050
4468
|
justifyContent: "center",
|
|
@@ -4054,12 +4472,12 @@ function SplitCardFormInner({
|
|
|
4054
4472
|
backgroundColor: "#f3f4f6",
|
|
4055
4473
|
transition: "background-color 0.15s",
|
|
4056
4474
|
...bStyles.backButtonIcon
|
|
4057
|
-
}, children: /* @__PURE__ */ (0,
|
|
4058
|
-
/* @__PURE__ */ (0,
|
|
4475
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
|
|
4476
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
4059
4477
|
]
|
|
4060
4478
|
}
|
|
4061
4479
|
),
|
|
4062
|
-
/* @__PURE__ */ (0,
|
|
4480
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
4063
4481
|
flex: 1,
|
|
4064
4482
|
textAlign: "center",
|
|
4065
4483
|
fontWeight: 600,
|
|
@@ -4069,12 +4487,12 @@ function SplitCardFormInner({
|
|
|
4069
4487
|
...bStyles.title
|
|
4070
4488
|
}, children: `Pay with ${(0, import_shared5.getStripeMethodDisplayName)(expandedApmMethod)}` })
|
|
4071
4489
|
] }),
|
|
4072
|
-
/* @__PURE__ */ (0,
|
|
4490
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4073
4491
|
import_react_stripe_js.Elements,
|
|
4074
4492
|
{
|
|
4075
4493
|
stripe: stripeInstance,
|
|
4076
4494
|
options: apmInlineOptions,
|
|
4077
|
-
children: /* @__PURE__ */ (0,
|
|
4495
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4078
4496
|
StripeMethodInlineForm,
|
|
4079
4497
|
{
|
|
4080
4498
|
method: expandedApmMethod,
|
|
@@ -4092,7 +4510,8 @@ function SplitCardFormInner({
|
|
|
4092
4510
|
isProcessing: isSubmitting,
|
|
4093
4511
|
submitButtonColor: resolvedPrimaryColor,
|
|
4094
4512
|
submitButtonBorderRadius: resolvedBorderRadius,
|
|
4095
|
-
submitButtonStyle: bStyles.submitButton
|
|
4513
|
+
submitButtonStyle: bStyles.submitButton,
|
|
4514
|
+
errorText: displayError
|
|
4096
4515
|
}
|
|
4097
4516
|
)
|
|
4098
4517
|
},
|
|
@@ -4103,24 +4522,24 @@ function SplitCardFormInner({
|
|
|
4103
4522
|
] });
|
|
4104
4523
|
}
|
|
4105
4524
|
if (isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && showStripe) {
|
|
4106
|
-
return /* @__PURE__ */ (0,
|
|
4107
|
-
/* @__PURE__ */ (0,
|
|
4108
|
-
overlayStatus && /* @__PURE__ */ (0,
|
|
4109
|
-
/* @__PURE__ */ (0,
|
|
4525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
4526
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FloPayKeyframes, {}),
|
|
4527
|
+
overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
4528
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
4110
4529
|
...apmAnim ? { animation: apmAnim } : {},
|
|
4111
4530
|
...viewState === "apm-collapsing" ? { pointerEvents: "none" } : {}
|
|
4112
|
-
}, children: /* @__PURE__ */ (0,
|
|
4531
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
|
|
4113
4532
|
backgroundColor: cardBg,
|
|
4114
4533
|
borderRadius: containerRadius,
|
|
4115
4534
|
...containerOverrides,
|
|
4116
4535
|
padding: containerPadding
|
|
4117
4536
|
}, children: [
|
|
4118
|
-
/* @__PURE__ */ (0,
|
|
4537
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
|
|
4119
4538
|
display: "flex",
|
|
4120
4539
|
alignItems: "center",
|
|
4121
4540
|
padding: "0.75rem 0 0.625rem"
|
|
4122
4541
|
}, children: [
|
|
4123
|
-
/* @__PURE__ */ (0,
|
|
4542
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
4124
4543
|
"button",
|
|
4125
4544
|
{
|
|
4126
4545
|
type: "button",
|
|
@@ -4143,7 +4562,7 @@ function SplitCardFormInner({
|
|
|
4143
4562
|
},
|
|
4144
4563
|
"aria-label": "Back to payment methods",
|
|
4145
4564
|
children: [
|
|
4146
|
-
/* @__PURE__ */ (0,
|
|
4565
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
|
|
4147
4566
|
display: "inline-flex",
|
|
4148
4567
|
alignItems: "center",
|
|
4149
4568
|
justifyContent: "center",
|
|
@@ -4153,12 +4572,12 @@ function SplitCardFormInner({
|
|
|
4153
4572
|
backgroundColor: "#f3f4f6",
|
|
4154
4573
|
transition: "background-color 0.15s",
|
|
4155
4574
|
...bStyles.backButtonIcon
|
|
4156
|
-
}, children: /* @__PURE__ */ (0,
|
|
4157
|
-
/* @__PURE__ */ (0,
|
|
4575
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
|
|
4576
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
4158
4577
|
]
|
|
4159
4578
|
}
|
|
4160
4579
|
),
|
|
4161
|
-
/* @__PURE__ */ (0,
|
|
4580
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
|
|
4162
4581
|
flex: 1,
|
|
4163
4582
|
textAlign: "center",
|
|
4164
4583
|
fontWeight: 600,
|
|
@@ -4168,12 +4587,12 @@ function SplitCardFormInner({
|
|
|
4168
4587
|
...bStyles.title
|
|
4169
4588
|
}, children: `Pay with ${(0, import_shared5.getStripeMethodDisplayName)(expandedApmMethod)}` })
|
|
4170
4589
|
] }),
|
|
4171
|
-
/* @__PURE__ */ (0,
|
|
4590
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4172
4591
|
import_react_stripe_js.Elements,
|
|
4173
4592
|
{
|
|
4174
4593
|
stripe: stripeInstance,
|
|
4175
4594
|
options: apmInlineOptions,
|
|
4176
|
-
children: /* @__PURE__ */ (0,
|
|
4595
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4177
4596
|
StripeMethodInlineForm,
|
|
4178
4597
|
{
|
|
4179
4598
|
method: expandedApmMethod,
|
|
@@ -4191,7 +4610,8 @@ function SplitCardFormInner({
|
|
|
4191
4610
|
isProcessing: isSubmitting,
|
|
4192
4611
|
submitButtonColor: resolvedPrimaryColor,
|
|
4193
4612
|
submitButtonBorderRadius: resolvedBorderRadius,
|
|
4194
|
-
submitButtonStyle: bStyles.submitButton
|
|
4613
|
+
submitButtonStyle: bStyles.submitButton,
|
|
4614
|
+
errorText: displayError
|
|
4195
4615
|
}
|
|
4196
4616
|
)
|
|
4197
4617
|
},
|
|
@@ -4200,14 +4620,14 @@ function SplitCardFormInner({
|
|
|
4200
4620
|
] }) })
|
|
4201
4621
|
] });
|
|
4202
4622
|
}
|
|
4203
|
-
return /* @__PURE__ */ (0,
|
|
4204
|
-
/* @__PURE__ */ (0,
|
|
4205
|
-
overlayStatus && /* @__PURE__ */ (0,
|
|
4206
|
-
/* @__PURE__ */ (0,
|
|
4623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
4624
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FloPayKeyframes, {}),
|
|
4625
|
+
overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
|
|
4626
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
4207
4627
|
renderDirectPaypalGateDebug("flopay-direct-paypal-gate-debug-default"),
|
|
4208
4628
|
renderStripeGateDebug("flopay-stripe-gate-debug-default"),
|
|
4209
|
-
shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0,
|
|
4210
|
-
paypalDirectRetry && /* @__PURE__ */ (0,
|
|
4629
|
+
shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4630
|
+
paypalDirectRetry && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4211
4631
|
"div",
|
|
4212
4632
|
{
|
|
4213
4633
|
"data-testid": "flopay-paypal-direct-retry-notice-default",
|
|
@@ -4223,7 +4643,7 @@ function SplitCardFormInner({
|
|
|
4223
4643
|
children: "Please confirm your PayPal payment to complete checkout."
|
|
4224
4644
|
}
|
|
4225
4645
|
),
|
|
4226
|
-
/* @__PURE__ */ (0,
|
|
4646
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4227
4647
|
DirectPayPalButton,
|
|
4228
4648
|
{
|
|
4229
4649
|
sessionId,
|
|
@@ -4249,7 +4669,7 @@ function SplitCardFormInner({
|
|
|
4249
4669
|
paypalDirectRetry?.orderId ?? "fresh"
|
|
4250
4670
|
)
|
|
4251
4671
|
] }),
|
|
4252
|
-
shouldRenderStripePayPal && /* @__PURE__ */ (0,
|
|
4672
|
+
shouldRenderStripePayPal && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4253
4673
|
PayPalButtonInner,
|
|
4254
4674
|
{
|
|
4255
4675
|
sessionId,
|
|
@@ -4263,10 +4683,10 @@ function SplitCardFormInner({
|
|
|
4263
4683
|
onDecline,
|
|
4264
4684
|
runBeforeButtonClick,
|
|
4265
4685
|
onLoadStateChange: setPaypalLoadState,
|
|
4266
|
-
placeholderBorderRadius:
|
|
4686
|
+
placeholderBorderRadius: buttonBorderRadius
|
|
4267
4687
|
}
|
|
4268
4688
|
) }),
|
|
4269
|
-
shouldRenderWallets && /* @__PURE__ */ (0,
|
|
4689
|
+
shouldRenderWallets && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4270
4690
|
WalletButtonInner,
|
|
4271
4691
|
{
|
|
4272
4692
|
sessionId,
|
|
@@ -4280,10 +4700,10 @@ function SplitCardFormInner({
|
|
|
4280
4700
|
onDecline,
|
|
4281
4701
|
runBeforeButtonClick,
|
|
4282
4702
|
onLoadStateChange: setWalletLoadState,
|
|
4283
|
-
placeholderBorderRadius:
|
|
4703
|
+
placeholderBorderRadius: buttonBorderRadius
|
|
4284
4704
|
}
|
|
4285
4705
|
) }),
|
|
4286
|
-
shouldRenderPaymentElement && /* @__PURE__ */ (0,
|
|
4706
|
+
shouldRenderPaymentElement && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4287
4707
|
StripePaymentElementInner,
|
|
4288
4708
|
{
|
|
4289
4709
|
sessionId,
|
|
@@ -4311,12 +4731,12 @@ function SplitCardFormInner({
|
|
|
4311
4731
|
backgroundColor: bStyles.cardButton?.backgroundColor,
|
|
4312
4732
|
borderColor: bStyles.cardInputBorder,
|
|
4313
4733
|
textColor: bStyles.cardButton?.color,
|
|
4314
|
-
borderRadius:
|
|
4734
|
+
borderRadius: buttonBorderRadius
|
|
4315
4735
|
}
|
|
4316
4736
|
}
|
|
4317
4737
|
)
|
|
4318
4738
|
] }),
|
|
4319
|
-
showStripe && (shouldDisplayWalletRow || shouldDisplayPayPalRow || shouldDisplayPaymentElementRow) && /* @__PURE__ */ (0,
|
|
4739
|
+
showStripe && (shouldDisplayWalletRow || shouldDisplayPayPalRow || shouldDisplayPaymentElementRow) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
|
|
4320
4740
|
display: "flex",
|
|
4321
4741
|
alignItems: "center",
|
|
4322
4742
|
gap: "0.75rem",
|
|
@@ -4324,9 +4744,9 @@ function SplitCardFormInner({
|
|
|
4324
4744
|
color: "#999",
|
|
4325
4745
|
fontSize: "0.85rem"
|
|
4326
4746
|
}, children: [
|
|
4327
|
-
/* @__PURE__ */ (0,
|
|
4328
|
-
/* @__PURE__ */ (0,
|
|
4329
|
-
/* @__PURE__ */ (0,
|
|
4747
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } }),
|
|
4748
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "or pay with card" }),
|
|
4749
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
|
|
4330
4750
|
] }),
|
|
4331
4751
|
showStripe && cardFormBlock
|
|
4332
4752
|
] });
|
|
@@ -4369,6 +4789,210 @@ function getRedirectResultFromCheckoutProcessError(error) {
|
|
|
4369
4789
|
paymentMethodId: error.paymentMethodId
|
|
4370
4790
|
};
|
|
4371
4791
|
}
|
|
4792
|
+
function isTerminalAutoCheckoutThreeDsOutcome(outcome) {
|
|
4793
|
+
return outcome.status === "succeeded" || outcome.status === "declined";
|
|
4794
|
+
}
|
|
4795
|
+
async function runAutoCheckoutThreeDsChallenge(input) {
|
|
4796
|
+
if (typeof document === "undefined" || typeof window === "undefined") {
|
|
4797
|
+
throw new import_shared7.FloPayError("3DS challenge requires a browser environment.", "api_error", {
|
|
4798
|
+
code: "three_ds_no_window"
|
|
4799
|
+
});
|
|
4800
|
+
}
|
|
4801
|
+
if (input.signal?.aborted) {
|
|
4802
|
+
throw new import_shared7.FloPayError("Card authentication was cancelled.", "api_error", {
|
|
4803
|
+
code: "three_ds_aborted"
|
|
4804
|
+
});
|
|
4805
|
+
}
|
|
4806
|
+
const CHALLENGE_TIMEOUT_MS = 3e5;
|
|
4807
|
+
const CHALLENGE_POLL_INTERVAL_MS = 1e3;
|
|
4808
|
+
const COMPLETE_REQUEST_TIMEOUT_MS = 15e3;
|
|
4809
|
+
const completionEndpoint = `${input.billingApiUrl.replace(/\/$/, "")}/v1/checkouts/sessions/${encodeURIComponent(
|
|
4810
|
+
input.sessionId
|
|
4811
|
+
)}/3ds/complete`;
|
|
4812
|
+
const completeThreeDs = async () => {
|
|
4813
|
+
const controller = new AbortController();
|
|
4814
|
+
const onParentAbort = () => controller.abort();
|
|
4815
|
+
if (input.signal?.aborted) {
|
|
4816
|
+
controller.abort();
|
|
4817
|
+
} else {
|
|
4818
|
+
input.signal?.addEventListener("abort", onParentAbort);
|
|
4819
|
+
}
|
|
4820
|
+
const requestTimeout = window.setTimeout(() => controller.abort(), COMPLETE_REQUEST_TIMEOUT_MS);
|
|
4821
|
+
try {
|
|
4822
|
+
const response = await fetch(completionEndpoint, {
|
|
4823
|
+
method: "POST",
|
|
4824
|
+
headers: {
|
|
4825
|
+
"x-checkout-session-token": input.nonce,
|
|
4826
|
+
"content-type": "application/json"
|
|
4827
|
+
},
|
|
4828
|
+
body: "{}",
|
|
4829
|
+
signal: controller.signal
|
|
4830
|
+
});
|
|
4831
|
+
if (!response.ok) {
|
|
4832
|
+
return { status: "unknown" };
|
|
4833
|
+
}
|
|
4834
|
+
const json = await response.json().catch(() => null);
|
|
4835
|
+
return coerceThreeDsOutcome(json);
|
|
4836
|
+
} catch {
|
|
4837
|
+
return { status: "unknown" };
|
|
4838
|
+
} finally {
|
|
4839
|
+
window.clearTimeout(requestTimeout);
|
|
4840
|
+
input.signal?.removeEventListener("abort", onParentAbort);
|
|
4841
|
+
}
|
|
4842
|
+
};
|
|
4843
|
+
const previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
4844
|
+
const backdrop = document.createElement("div");
|
|
4845
|
+
backdrop.setAttribute("data-flopay-auto-3ds-overlay", "1");
|
|
4846
|
+
backdrop.setAttribute("role", "dialog");
|
|
4847
|
+
backdrop.setAttribute("aria-modal", "true");
|
|
4848
|
+
backdrop.setAttribute("aria-label", "Card authentication");
|
|
4849
|
+
backdrop.style.cssText = [
|
|
4850
|
+
"position:fixed",
|
|
4851
|
+
"inset:0",
|
|
4852
|
+
"z-index:2147483647",
|
|
4853
|
+
"background:rgba(15,23,42,0.6)",
|
|
4854
|
+
"display:flex",
|
|
4855
|
+
"align-items:center",
|
|
4856
|
+
"justify-content:center",
|
|
4857
|
+
"padding:16px"
|
|
4858
|
+
].join(";");
|
|
4859
|
+
const frame = document.createElement("iframe");
|
|
4860
|
+
frame.setAttribute("title", "Card authentication");
|
|
4861
|
+
frame.setAttribute("allow", "payment");
|
|
4862
|
+
frame.tabIndex = 0;
|
|
4863
|
+
frame.style.cssText = [
|
|
4864
|
+
"width:min(100%,460px)",
|
|
4865
|
+
"height:min(100%,640px)",
|
|
4866
|
+
"border:0",
|
|
4867
|
+
"border-radius:12px",
|
|
4868
|
+
"background:#fff",
|
|
4869
|
+
"box-shadow:0 12px 30px rgba(0,0,0,0.35)"
|
|
4870
|
+
].join(";");
|
|
4871
|
+
frame.src = input.nextActionRedirectUrl;
|
|
4872
|
+
backdrop.appendChild(frame);
|
|
4873
|
+
document.body.appendChild(backdrop);
|
|
4874
|
+
frame.focus();
|
|
4875
|
+
let expectedReturnOrigin = null;
|
|
4876
|
+
try {
|
|
4877
|
+
expectedReturnOrigin = new URL(input.billingApiUrl, window.location.href).origin;
|
|
4878
|
+
} catch {
|
|
4879
|
+
expectedReturnOrigin = null;
|
|
4880
|
+
}
|
|
4881
|
+
try {
|
|
4882
|
+
const polledOutcome = await new Promise((resolve, reject) => {
|
|
4883
|
+
let settled = false;
|
|
4884
|
+
let timer = 0;
|
|
4885
|
+
let pollTimer = 0;
|
|
4886
|
+
let loadPollTimer = 0;
|
|
4887
|
+
let pollInFlight = false;
|
|
4888
|
+
const cleanup = () => {
|
|
4889
|
+
window.clearTimeout(timer);
|
|
4890
|
+
window.clearInterval(pollTimer);
|
|
4891
|
+
window.clearTimeout(loadPollTimer);
|
|
4892
|
+
window.removeEventListener("message", listener);
|
|
4893
|
+
frame.removeEventListener("load", onFrameLoad);
|
|
4894
|
+
input.signal?.removeEventListener("abort", onAbort);
|
|
4895
|
+
};
|
|
4896
|
+
const maybeResolveFromBackend = async () => {
|
|
4897
|
+
if (settled || pollInFlight) return;
|
|
4898
|
+
pollInFlight = true;
|
|
4899
|
+
try {
|
|
4900
|
+
const outcome = await completeThreeDs();
|
|
4901
|
+
if (settled || !isTerminalAutoCheckoutThreeDsOutcome(outcome)) return;
|
|
4902
|
+
settled = true;
|
|
4903
|
+
cleanup();
|
|
4904
|
+
resolve(outcome);
|
|
4905
|
+
} finally {
|
|
4906
|
+
pollInFlight = false;
|
|
4907
|
+
}
|
|
4908
|
+
};
|
|
4909
|
+
const onFrameLoad = () => {
|
|
4910
|
+
window.clearTimeout(loadPollTimer);
|
|
4911
|
+
loadPollTimer = window.setTimeout(() => {
|
|
4912
|
+
void maybeResolveFromBackend();
|
|
4913
|
+
}, 250);
|
|
4914
|
+
};
|
|
4915
|
+
const onAbort = () => {
|
|
4916
|
+
if (settled) return;
|
|
4917
|
+
settled = true;
|
|
4918
|
+
cleanup();
|
|
4919
|
+
reject(
|
|
4920
|
+
new import_shared7.FloPayError("Card authentication was cancelled.", "api_error", {
|
|
4921
|
+
code: "three_ds_aborted"
|
|
4922
|
+
})
|
|
4923
|
+
);
|
|
4924
|
+
};
|
|
4925
|
+
const listener = (event) => {
|
|
4926
|
+
if (event.source !== frame.contentWindow) return;
|
|
4927
|
+
if (expectedReturnOrigin && event.origin !== expectedReturnOrigin) return;
|
|
4928
|
+
const data = event.data;
|
|
4929
|
+
if (!data || typeof data !== "object") return;
|
|
4930
|
+
const record = data;
|
|
4931
|
+
if (record["source"] !== "flopay-vault-3ds-return") return;
|
|
4932
|
+
if (settled) return;
|
|
4933
|
+
settled = true;
|
|
4934
|
+
cleanup();
|
|
4935
|
+
resolve(null);
|
|
4936
|
+
};
|
|
4937
|
+
timer = window.setTimeout(() => {
|
|
4938
|
+
if (settled) return;
|
|
4939
|
+
settled = true;
|
|
4940
|
+
cleanup();
|
|
4941
|
+
reject(
|
|
4942
|
+
new import_shared7.FloPayError("Card authentication timed out.", "api_error", {
|
|
4943
|
+
code: "three_ds_timeout"
|
|
4944
|
+
})
|
|
4945
|
+
);
|
|
4946
|
+
}, CHALLENGE_TIMEOUT_MS);
|
|
4947
|
+
pollTimer = window.setInterval(() => {
|
|
4948
|
+
void maybeResolveFromBackend();
|
|
4949
|
+
}, CHALLENGE_POLL_INTERVAL_MS);
|
|
4950
|
+
frame.addEventListener("load", onFrameLoad);
|
|
4951
|
+
window.addEventListener("message", listener);
|
|
4952
|
+
input.signal?.addEventListener("abort", onAbort);
|
|
4953
|
+
if (input.signal?.aborted) onAbort();
|
|
4954
|
+
});
|
|
4955
|
+
if (polledOutcome) {
|
|
4956
|
+
return polledOutcome;
|
|
4957
|
+
}
|
|
4958
|
+
return await completeThreeDs();
|
|
4959
|
+
} finally {
|
|
4960
|
+
backdrop.parentNode?.removeChild(backdrop);
|
|
4961
|
+
if (previousFocus?.isConnected) {
|
|
4962
|
+
previousFocus.focus();
|
|
4963
|
+
}
|
|
4964
|
+
}
|
|
4965
|
+
}
|
|
4966
|
+
function coerceThreeDsOutcome(json) {
|
|
4967
|
+
if (!json || typeof json !== "object") return { status: "unknown" };
|
|
4968
|
+
const status = typeof json["status"] === "string" ? json["status"] : "unknown";
|
|
4969
|
+
const providerIntentId = typeof json["providerIntentId"] === "string" ? json["providerIntentId"] : null;
|
|
4970
|
+
switch (status) {
|
|
4971
|
+
case "succeeded":
|
|
4972
|
+
return { status: "succeeded", providerIntentId };
|
|
4973
|
+
case "declined":
|
|
4974
|
+
return {
|
|
4975
|
+
status: "declined",
|
|
4976
|
+
providerIntentId,
|
|
4977
|
+
declineReason: typeof json["declineReason"] === "string" ? json["declineReason"] : null,
|
|
4978
|
+
gatewayDeclineReason: typeof json["gatewayDeclineReason"] === "string" ? json["gatewayDeclineReason"] : null
|
|
4979
|
+
};
|
|
4980
|
+
case "requires_action":
|
|
4981
|
+
return {
|
|
4982
|
+
status: "requires_action",
|
|
4983
|
+
providerIntentId,
|
|
4984
|
+
nextActionRedirectUrl: typeof json["nextActionRedirectUrl"] === "string" ? json["nextActionRedirectUrl"] : null
|
|
4985
|
+
};
|
|
4986
|
+
case "pending":
|
|
4987
|
+
return { status: "pending", providerIntentId };
|
|
4988
|
+
case "timeout":
|
|
4989
|
+
return { status: "timeout", providerIntentId };
|
|
4990
|
+
case "no_attempt":
|
|
4991
|
+
return { status: "no_attempt" };
|
|
4992
|
+
default:
|
|
4993
|
+
return { status: "unknown" };
|
|
4994
|
+
}
|
|
4995
|
+
}
|
|
4372
4996
|
function checkoutProcessErrorToFloPayError(error, fallbackMessage = "Payment failed. Please try again.", options) {
|
|
4373
4997
|
const checkoutMethod = options?.checkoutMethod ?? error?.checkoutMethod ?? (error?.type === "paypal_redirect_required" ? "paypal" : "card");
|
|
4374
4998
|
const rawMessage = error?.message ?? fallbackMessage;
|
|
@@ -4810,7 +5434,7 @@ async function loadSavedPaymentProviders({
|
|
|
4810
5434
|
}
|
|
4811
5435
|
|
|
4812
5436
|
// src/flopay-checkout.tsx
|
|
4813
|
-
var
|
|
5437
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
4814
5438
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
|
|
4815
5439
|
var PAYPAL_RESUME_STORAGE_KEY = "flopay_checkout_saved_payment_resume";
|
|
4816
5440
|
var sessionInflightMap = /* @__PURE__ */ new Map();
|
|
@@ -4859,6 +5483,36 @@ function clearPayPalResumeState() {
|
|
|
4859
5483
|
console.warn("[FloPayCheckout] Failed to clear PayPal resume state.", error);
|
|
4860
5484
|
}
|
|
4861
5485
|
}
|
|
5486
|
+
function readCachedInlineSession(cacheKey) {
|
|
5487
|
+
if (!canUseStorage()) return null;
|
|
5488
|
+
const raw = window.sessionStorage.getItem(cacheKey);
|
|
5489
|
+
if (!raw) return null;
|
|
5490
|
+
try {
|
|
5491
|
+
const parsed = JSON.parse(raw);
|
|
5492
|
+
if (parsed && typeof parsed.sid === "string" && parsed.sid) {
|
|
5493
|
+
return { sid: parsed.sid, nonce: typeof parsed.nonce === "string" ? parsed.nonce : void 0 };
|
|
5494
|
+
}
|
|
5495
|
+
return null;
|
|
5496
|
+
} catch {
|
|
5497
|
+
return { sid: raw };
|
|
5498
|
+
}
|
|
5499
|
+
}
|
|
5500
|
+
function persistCachedInlineSession(cacheKey, sid, nonce) {
|
|
5501
|
+
if (!canUseStorage()) return;
|
|
5502
|
+
try {
|
|
5503
|
+
window.sessionStorage.setItem(cacheKey, JSON.stringify(nonce ? { sid, nonce } : { sid }));
|
|
5504
|
+
} catch (error) {
|
|
5505
|
+
console.warn("[FloPayCheckout] Failed to persist checkout session cache.", error);
|
|
5506
|
+
}
|
|
5507
|
+
}
|
|
5508
|
+
function clearCachedInlineSession(cacheKey) {
|
|
5509
|
+
if (!canUseStorage()) return;
|
|
5510
|
+
try {
|
|
5511
|
+
window.sessionStorage.removeItem(cacheKey);
|
|
5512
|
+
} catch (error) {
|
|
5513
|
+
console.warn("[FloPayCheckout] Failed to clear checkout session cache.", error);
|
|
5514
|
+
}
|
|
5515
|
+
}
|
|
4862
5516
|
function clearPayPalRedirectParams() {
|
|
4863
5517
|
if (typeof window === "undefined") return;
|
|
4864
5518
|
const url = new URL(window.location.href);
|
|
@@ -4917,6 +5571,8 @@ function FloPayCheckout({
|
|
|
4917
5571
|
onButtonClick,
|
|
4918
5572
|
onBeforeButtonClick,
|
|
4919
5573
|
enableAVS,
|
|
5574
|
+
cardFieldOrder,
|
|
5575
|
+
cardPreFormSlot,
|
|
4920
5576
|
avsLayout,
|
|
4921
5577
|
submitLabel,
|
|
4922
5578
|
className,
|
|
@@ -4928,41 +5584,41 @@ function FloPayCheckout({
|
|
|
4928
5584
|
onSessionCompleted
|
|
4929
5585
|
}) {
|
|
4930
5586
|
const resolvedBillingUrl = (0, import_shared8.resolveBillingApiUrl)(billingApiUrl);
|
|
4931
|
-
const themeBundle = (0,
|
|
5587
|
+
const themeBundle = (0, import_react10.useMemo)(() => (0, import_shared8.resolveTheme)(theme), [theme]);
|
|
4932
5588
|
const appearance = appearanceOverride ?? themeBundle?.appearance;
|
|
4933
5589
|
const checkoutType = createSessionParams ? "embedded_checkout" : "standard_checkout";
|
|
4934
5590
|
const checkoutLayout = children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout";
|
|
4935
|
-
const [unified, setUnified] = (0,
|
|
4936
|
-
const [flopay, setFloPay] = (0,
|
|
4937
|
-
const flopayRef = (0,
|
|
4938
|
-
const [paypalFlopay, setPaypalFloPay] = (0,
|
|
4939
|
-
const paypalFlopayRef = (0,
|
|
4940
|
-
const [session, setSession] = (0,
|
|
4941
|
-
const [resolvedSessionId, setResolvedSessionId] = (0,
|
|
5591
|
+
const [unified, setUnified] = (0, import_react10.useState)(null);
|
|
5592
|
+
const [flopay, setFloPay] = (0, import_react10.useState)(null);
|
|
5593
|
+
const flopayRef = (0, import_react10.useRef)(null);
|
|
5594
|
+
const [paypalFlopay, setPaypalFloPay] = (0, import_react10.useState)(null);
|
|
5595
|
+
const paypalFlopayRef = (0, import_react10.useRef)(null);
|
|
5596
|
+
const [session, setSession] = (0, import_react10.useState)(null);
|
|
5597
|
+
const [resolvedSessionId, setResolvedSessionId] = (0, import_react10.useState)(sessionIdProp ?? "");
|
|
4942
5598
|
const activeSessionId = sessionIdProp ?? resolvedSessionId;
|
|
4943
5599
|
const initSessionDependency = createSessionParams ? "" : activeSessionId;
|
|
4944
|
-
const [isLoading, setIsLoading] = (0,
|
|
4945
|
-
const [loadError, setLoadError] = (0,
|
|
4946
|
-
const [currentMode, setCurrentMode] = (0,
|
|
4947
|
-
const [confirmProcessing, setConfirmProcessing] = (0,
|
|
4948
|
-
const [modeError, setModeError] = (0,
|
|
4949
|
-
const [modeOverlayStatus, setModeOverlayStatus] = (0,
|
|
4950
|
-
const [modeOverlayError, setModeOverlayError] = (0,
|
|
4951
|
-
const [createSessionPatch, setCreateSessionPatch] = (0,
|
|
4952
|
-
const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = (0,
|
|
4953
|
-
const [cardBootstrapPending, setCardBootstrapPending] = (0,
|
|
4954
|
-
const autoCheckoutAttempted = (0,
|
|
4955
|
-
const paypalResumeAttempted = (0,
|
|
4956
|
-
const savedPaymentKeysRef = (0,
|
|
4957
|
-
const onCompleteRef = (0,
|
|
5600
|
+
const [isLoading, setIsLoading] = (0, import_react10.useState)(true);
|
|
5601
|
+
const [loadError, setLoadError] = (0, import_react10.useState)(null);
|
|
5602
|
+
const [currentMode, setCurrentMode] = (0, import_react10.useState)("full");
|
|
5603
|
+
const [confirmProcessing, setConfirmProcessing] = (0, import_react10.useState)(false);
|
|
5604
|
+
const [modeError, setModeError] = (0, import_react10.useState)(initialErrorMessage);
|
|
5605
|
+
const [modeOverlayStatus, setModeOverlayStatus] = (0, import_react10.useState)(null);
|
|
5606
|
+
const [modeOverlayError, setModeOverlayError] = (0, import_react10.useState)(null);
|
|
5607
|
+
const [createSessionPatch, setCreateSessionPatch] = (0, import_react10.useState)(void 0);
|
|
5608
|
+
const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = (0, import_react10.useState)("");
|
|
5609
|
+
const [cardBootstrapPending, setCardBootstrapPending] = (0, import_react10.useState)(false);
|
|
5610
|
+
const autoCheckoutAttempted = (0, import_react10.useRef)(false);
|
|
5611
|
+
const paypalResumeAttempted = (0, import_react10.useRef)(false);
|
|
5612
|
+
const savedPaymentKeysRef = (0, import_react10.useRef)(null);
|
|
5613
|
+
const onCompleteRef = (0, import_react10.useRef)(onComplete);
|
|
4958
5614
|
onCompleteRef.current = onComplete;
|
|
4959
|
-
const onErrorRef = (0,
|
|
5615
|
+
const onErrorRef = (0, import_react10.useRef)(onError);
|
|
4960
5616
|
onErrorRef.current = onError;
|
|
4961
|
-
const onDeclineRef = (0,
|
|
5617
|
+
const onDeclineRef = (0, import_react10.useRef)(onDecline);
|
|
4962
5618
|
onDeclineRef.current = onDecline;
|
|
4963
|
-
const onSessionCompletedRef = (0,
|
|
5619
|
+
const onSessionCompletedRef = (0, import_react10.useRef)(onSessionCompleted);
|
|
4964
5620
|
onSessionCompletedRef.current = onSessionCompleted;
|
|
4965
|
-
(0,
|
|
5621
|
+
(0, import_react10.useEffect)(() => {
|
|
4966
5622
|
console.info("[FloPay] Checkout initialized", {
|
|
4967
5623
|
sdk_version: import_shared8.SDK_VERSION,
|
|
4968
5624
|
checkout_type: checkoutType,
|
|
@@ -4970,40 +5626,40 @@ function FloPayCheckout({
|
|
|
4970
5626
|
billing_api_url: resolvedBillingUrl
|
|
4971
5627
|
});
|
|
4972
5628
|
}, [checkoutLayout, checkoutType, resolvedBillingUrl]);
|
|
4973
|
-
const baseCreateSessionHash = (0,
|
|
5629
|
+
const baseCreateSessionHash = (0, import_react10.useMemo)(
|
|
4974
5630
|
() => createSessionParams ? hashCreateParams(createSessionParams) : "",
|
|
4975
5631
|
[createSessionParams]
|
|
4976
5632
|
);
|
|
4977
|
-
const activeCreateSessionPatch = (0,
|
|
5633
|
+
const activeCreateSessionPatch = (0, import_react10.useMemo)(
|
|
4978
5634
|
() => createSessionPatchBaseHash === baseCreateSessionHash ? createSessionPatch : void 0,
|
|
4979
5635
|
[createSessionPatch, createSessionPatchBaseHash, baseCreateSessionHash]
|
|
4980
5636
|
);
|
|
4981
|
-
const effectiveCreateSessionBase = (0,
|
|
5637
|
+
const effectiveCreateSessionBase = (0, import_react10.useMemo)(
|
|
4982
5638
|
() => createSessionParams ? mergeInlineSessionPatch(createSessionParams, activeCreateSessionPatch) : void 0,
|
|
4983
5639
|
[createSessionParams, activeCreateSessionPatch]
|
|
4984
5640
|
);
|
|
4985
5641
|
const effectiveCreateSessionMode = checkoutModeProp ?? effectiveCreateSessionBase?.checkoutMode ?? "full";
|
|
4986
|
-
const effectiveCreateSession = (0,
|
|
5642
|
+
const effectiveCreateSession = (0, import_react10.useMemo)(
|
|
4987
5643
|
() => effectiveCreateSessionBase ? {
|
|
4988
5644
|
...effectiveCreateSessionBase,
|
|
4989
5645
|
checkoutMode: effectiveCreateSessionMode
|
|
4990
5646
|
} : void 0,
|
|
4991
5647
|
[effectiveCreateSessionBase, effectiveCreateSessionMode]
|
|
4992
5648
|
);
|
|
4993
|
-
(0,
|
|
5649
|
+
(0, import_react10.useEffect)(() => {
|
|
4994
5650
|
setCreateSessionPatch(void 0);
|
|
4995
5651
|
setCreateSessionPatchBaseHash(baseCreateSessionHash);
|
|
4996
5652
|
}, [baseCreateSessionHash]);
|
|
4997
|
-
(0,
|
|
5653
|
+
(0, import_react10.useEffect)(() => {
|
|
4998
5654
|
setModeError(initialErrorMessage);
|
|
4999
5655
|
}, [initialErrorMessage]);
|
|
5000
|
-
const emitDecline = (0,
|
|
5656
|
+
const emitDecline = (0, import_react10.useCallback)(
|
|
5001
5657
|
(method, input, overrides) => {
|
|
5002
5658
|
onDeclineRef.current?.(buildDeclineEvent(method, input, overrides));
|
|
5003
5659
|
},
|
|
5004
5660
|
[]
|
|
5005
5661
|
);
|
|
5006
|
-
const runSavedPaymentFlow = (0,
|
|
5662
|
+
const runSavedPaymentFlow = (0, import_react10.useCallback)(
|
|
5007
5663
|
async (sess, options) => {
|
|
5008
5664
|
setModeError(null);
|
|
5009
5665
|
setModeOverlayError(null);
|
|
@@ -5121,7 +5777,7 @@ function FloPayCheckout({
|
|
|
5121
5777
|
resolvedBillingUrl
|
|
5122
5778
|
]
|
|
5123
5779
|
);
|
|
5124
|
-
(0,
|
|
5780
|
+
(0, import_react10.useEffect)(() => {
|
|
5125
5781
|
if (typeof window === "undefined" || paypalResumeAttempted.current) {
|
|
5126
5782
|
return;
|
|
5127
5783
|
}
|
|
@@ -5238,7 +5894,7 @@ function FloPayCheckout({
|
|
|
5238
5894
|
}
|
|
5239
5895
|
})();
|
|
5240
5896
|
}, [emitDecline, locale, normalizeSavedPaymentError, resolvedBillingUrl]);
|
|
5241
|
-
const initializedHashRef = (0,
|
|
5897
|
+
const initializedHashRef = (0, import_react10.useRef)(null);
|
|
5242
5898
|
function hashCreateParams(params) {
|
|
5243
5899
|
const key = JSON.stringify({
|
|
5244
5900
|
c: params?.clientId,
|
|
@@ -5271,16 +5927,16 @@ function FloPayCheckout({
|
|
|
5271
5927
|
}
|
|
5272
5928
|
return `flopay_session_${Math.abs(h).toString(36)}`;
|
|
5273
5929
|
}
|
|
5274
|
-
const createSessionHash = (0,
|
|
5930
|
+
const createSessionHash = (0, import_react10.useMemo)(
|
|
5275
5931
|
() => effectiveCreateSession ? hashCreateParams(effectiveCreateSession) : "",
|
|
5276
5932
|
[effectiveCreateSession]
|
|
5277
5933
|
);
|
|
5278
|
-
const createSessionParamsRef = (0,
|
|
5934
|
+
const createSessionParamsRef = (0, import_react10.useRef)(effectiveCreateSession);
|
|
5279
5935
|
createSessionParamsRef.current = effectiveCreateSession;
|
|
5280
|
-
(0,
|
|
5936
|
+
(0, import_react10.useEffect)(() => {
|
|
5281
5937
|
setResolvedSessionId(sessionIdProp ?? "");
|
|
5282
5938
|
}, [sessionIdProp]);
|
|
5283
|
-
(0,
|
|
5939
|
+
(0, import_react10.useEffect)(() => {
|
|
5284
5940
|
autoCheckoutAttempted.current = false;
|
|
5285
5941
|
setModeError(initialErrorMessage);
|
|
5286
5942
|
setModeOverlayError(null);
|
|
@@ -5288,22 +5944,23 @@ function FloPayCheckout({
|
|
|
5288
5944
|
}, [createSessionHash, initialErrorMessage, sessionIdProp]);
|
|
5289
5945
|
async function resolveInlineSession(params, cacheKey) {
|
|
5290
5946
|
const api = new import_js4.PaymentAPI(resolvedBillingUrl);
|
|
5291
|
-
|
|
5947
|
+
const cached = readCachedInlineSession(cacheKey);
|
|
5948
|
+
let sid = cached?.sid ?? null;
|
|
5292
5949
|
let realResult = null;
|
|
5293
5950
|
if (sid) {
|
|
5294
5951
|
try {
|
|
5295
|
-
realResult = await api.getUnifiedCheckoutSession(sid);
|
|
5952
|
+
realResult = await api.getUnifiedCheckoutSession(sid, cached?.nonce);
|
|
5296
5953
|
const status = realResult.data.session?.status;
|
|
5297
5954
|
if (status === "complete") {
|
|
5298
5955
|
if (wasSessionRecentlyCompleted(sid)) {
|
|
5299
5956
|
return { sid, result: realResult };
|
|
5300
5957
|
}
|
|
5301
|
-
|
|
5958
|
+
clearCachedInlineSession(cacheKey);
|
|
5302
5959
|
sid = null;
|
|
5303
5960
|
realResult = null;
|
|
5304
5961
|
}
|
|
5305
5962
|
} catch {
|
|
5306
|
-
|
|
5963
|
+
clearCachedInlineSession(cacheKey);
|
|
5307
5964
|
sid = null;
|
|
5308
5965
|
}
|
|
5309
5966
|
}
|
|
@@ -5317,13 +5974,13 @@ function FloPayCheckout({
|
|
|
5317
5974
|
};
|
|
5318
5975
|
realResult = await api.createAndFetchSession(paramsWithAnalytics);
|
|
5319
5976
|
sid = realResult.data.session?.id ?? "";
|
|
5320
|
-
if (sid
|
|
5321
|
-
|
|
5977
|
+
if (sid) {
|
|
5978
|
+
persistCachedInlineSession(cacheKey, sid, realResult.data.session?.clientSecret);
|
|
5322
5979
|
}
|
|
5323
5980
|
}
|
|
5324
5981
|
return { sid: sid ?? "", result: realResult };
|
|
5325
5982
|
}
|
|
5326
|
-
const bootstrapInlineSession = (0,
|
|
5983
|
+
const bootstrapInlineSession = (0, import_react10.useCallback)(
|
|
5327
5984
|
async (patch) => {
|
|
5328
5985
|
const baseParams = createSessionParamsRef.current;
|
|
5329
5986
|
if (!baseParams) {
|
|
@@ -5384,7 +6041,7 @@ function FloPayCheckout({
|
|
|
5384
6041
|
},
|
|
5385
6042
|
[locale, resolvedBillingUrl]
|
|
5386
6043
|
);
|
|
5387
|
-
const handleInlineSessionPatch = (0,
|
|
6044
|
+
const handleInlineSessionPatch = (0, import_react10.useCallback)(async (patch) => {
|
|
5388
6045
|
if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) {
|
|
5389
6046
|
return {
|
|
5390
6047
|
sessionId: resolvedSessionId,
|
|
@@ -5407,7 +6064,7 @@ function FloPayCheckout({
|
|
|
5407
6064
|
resolvedSessionId,
|
|
5408
6065
|
session
|
|
5409
6066
|
]);
|
|
5410
|
-
(0,
|
|
6067
|
+
(0, import_react10.useEffect)(() => {
|
|
5411
6068
|
let cancelled = false;
|
|
5412
6069
|
setLoadError(null);
|
|
5413
6070
|
if (createSessionHash) {
|
|
@@ -5573,7 +6230,7 @@ function FloPayCheckout({
|
|
|
5573
6230
|
nonceProp,
|
|
5574
6231
|
runSavedPaymentFlow
|
|
5575
6232
|
]);
|
|
5576
|
-
const handleConfirmCheckout = (0,
|
|
6233
|
+
const handleConfirmCheckout = (0, import_react10.useCallback)(async () => {
|
|
5577
6234
|
if (confirmProcessing || !session) return;
|
|
5578
6235
|
setConfirmProcessing(true);
|
|
5579
6236
|
setModeError(null);
|
|
@@ -5588,7 +6245,7 @@ function FloPayCheckout({
|
|
|
5588
6245
|
}, [activeSessionId, confirmProcessing, runSavedPaymentFlow, session]);
|
|
5589
6246
|
const directPaypalConfig = resolveDirectPaypalConfig(unified);
|
|
5590
6247
|
const isPaypalOnlySession = isPayPalOnlyUnified(unified);
|
|
5591
|
-
const providerOptions = (0,
|
|
6248
|
+
const providerOptions = (0, import_react10.useMemo)(() => {
|
|
5592
6249
|
if (!unified || !session || !unified.data.stripe?.publishableKey) return void 0;
|
|
5593
6250
|
const opts = {
|
|
5594
6251
|
appearance,
|
|
@@ -5607,7 +6264,7 @@ function FloPayCheckout({
|
|
|
5607
6264
|
const shouldHandleInlineSessionPatch = Boolean(
|
|
5608
6265
|
createSessionParams && !children && layout === "buttons" && onBeforeButtonClick && effectiveCreateSessionMode === "full"
|
|
5609
6266
|
);
|
|
5610
|
-
const checkoutValue = (0,
|
|
6267
|
+
const checkoutValue = (0, import_react10.useMemo)(
|
|
5611
6268
|
() => ({
|
|
5612
6269
|
session,
|
|
5613
6270
|
loading: isLoading,
|
|
@@ -5629,7 +6286,7 @@ function FloPayCheckout({
|
|
|
5629
6286
|
]
|
|
5630
6287
|
);
|
|
5631
6288
|
const shouldShowInterimButtons = Boolean(createSessionParams) && layout === "buttons" && !isPaypalOnlySession && (!flopay || !providerOptions);
|
|
5632
|
-
const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ (0,
|
|
6289
|
+
const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5633
6290
|
ProcessingOverlay,
|
|
5634
6291
|
{
|
|
5635
6292
|
status: modeOverlayStatus,
|
|
@@ -5638,32 +6295,32 @@ function FloPayCheckout({
|
|
|
5638
6295
|
) : null;
|
|
5639
6296
|
if (isLoading) {
|
|
5640
6297
|
if (loadingNode) {
|
|
5641
|
-
return /* @__PURE__ */ (0,
|
|
6298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
5642
6299
|
loadingNode,
|
|
5643
6300
|
modeOverlay
|
|
5644
6301
|
] });
|
|
5645
6302
|
}
|
|
5646
6303
|
if (layout === "buttons") {
|
|
5647
6304
|
const bundleRadius = themeBundle?.buttonsLayout?.cardButton?.borderRadius ?? themeBundle?.appearance.variables?.borderRadius ?? 8;
|
|
5648
|
-
const skeletonBar = (h) => /* @__PURE__ */ (0,
|
|
6305
|
+
const skeletonBar = (h) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
|
|
5649
6306
|
height: h,
|
|
5650
6307
|
borderRadius: bundleRadius,
|
|
5651
6308
|
background: "#e5e7eb",
|
|
5652
6309
|
animation: "flopay-loading-pulse 1.5s ease-in-out infinite"
|
|
5653
6310
|
} });
|
|
5654
|
-
return /* @__PURE__ */ (0,
|
|
5655
|
-
/* @__PURE__ */ (0,
|
|
6311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
6312
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
5656
6313
|
showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
5657
6314
|
showStripe && (showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
5658
6315
|
showStripe && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
5659
|
-
/* @__PURE__ */ (0,
|
|
6316
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
5660
6317
|
] }),
|
|
5661
6318
|
modeOverlay
|
|
5662
6319
|
] });
|
|
5663
6320
|
}
|
|
5664
|
-
return /* @__PURE__ */ (0,
|
|
5665
|
-
/* @__PURE__ */ (0,
|
|
5666
|
-
/* @__PURE__ */ (0,
|
|
6321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
6322
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", justifyContent: "center", padding: 32 }, children: [
|
|
6323
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
|
|
5667
6324
|
width: 24,
|
|
5668
6325
|
height: 24,
|
|
5669
6326
|
border: "2px solid #e5e7eb",
|
|
@@ -5671,16 +6328,16 @@ function FloPayCheckout({
|
|
|
5671
6328
|
borderRadius: "50%",
|
|
5672
6329
|
animation: "spin 0.6s linear infinite"
|
|
5673
6330
|
} }),
|
|
5674
|
-
/* @__PURE__ */ (0,
|
|
6331
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
|
|
5675
6332
|
] }),
|
|
5676
6333
|
modeOverlay
|
|
5677
6334
|
] });
|
|
5678
6335
|
}
|
|
5679
6336
|
if (loadError) {
|
|
5680
6337
|
if (errorNode) {
|
|
5681
|
-
return /* @__PURE__ */ (0,
|
|
6338
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: errorNode(loadError) });
|
|
5682
6339
|
}
|
|
5683
|
-
return /* @__PURE__ */ (0,
|
|
6340
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5684
6341
|
"div",
|
|
5685
6342
|
{
|
|
5686
6343
|
role: "alert",
|
|
@@ -5696,8 +6353,8 @@ function FloPayCheckout({
|
|
|
5696
6353
|
) });
|
|
5697
6354
|
}
|
|
5698
6355
|
if (shouldShowInterimButtons) {
|
|
5699
|
-
return /* @__PURE__ */ (0,
|
|
5700
|
-
/* @__PURE__ */ (0,
|
|
6356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
6357
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5701
6358
|
InterimButtonsView,
|
|
5702
6359
|
{
|
|
5703
6360
|
onButtonClick,
|
|
@@ -5717,9 +6374,9 @@ function FloPayCheckout({
|
|
|
5717
6374
|
] });
|
|
5718
6375
|
}
|
|
5719
6376
|
if (isPaypalOnlySession && session && directPaypalConfig) {
|
|
5720
|
-
return /* @__PURE__ */ (0,
|
|
5721
|
-
/* @__PURE__ */ (0,
|
|
5722
|
-
modeError && /* @__PURE__ */ (0,
|
|
6377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
6378
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className, style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
6379
|
+
modeError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5723
6380
|
"div",
|
|
5724
6381
|
{
|
|
5725
6382
|
role: "alert",
|
|
@@ -5736,7 +6393,7 @@ function FloPayCheckout({
|
|
|
5736
6393
|
children: modeError
|
|
5737
6394
|
}
|
|
5738
6395
|
),
|
|
5739
|
-
/* @__PURE__ */ (0,
|
|
6396
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5740
6397
|
DirectPayPalButton,
|
|
5741
6398
|
{
|
|
5742
6399
|
sessionId: activeSessionId,
|
|
@@ -5760,12 +6417,12 @@ function FloPayCheckout({
|
|
|
5760
6417
|
] });
|
|
5761
6418
|
}
|
|
5762
6419
|
if (!flopay || !providerOptions) {
|
|
5763
|
-
return /* @__PURE__ */ (0,
|
|
6420
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: modeOverlay });
|
|
5764
6421
|
}
|
|
5765
6422
|
if (currentMode === "confirm") {
|
|
5766
|
-
return /* @__PURE__ */ (0,
|
|
5767
|
-
/* @__PURE__ */ (0,
|
|
5768
|
-
modeError && /* @__PURE__ */ (0,
|
|
6423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
6424
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className, children: [
|
|
6425
|
+
modeError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5769
6426
|
"div",
|
|
5770
6427
|
{
|
|
5771
6428
|
style: {
|
|
@@ -5780,7 +6437,7 @@ function FloPayCheckout({
|
|
|
5780
6437
|
renderConfirmButton ? renderConfirmButton({
|
|
5781
6438
|
onConfirm: handleConfirmCheckout,
|
|
5782
6439
|
isProcessing: confirmProcessing
|
|
5783
|
-
}) : /* @__PURE__ */ (0,
|
|
6440
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5784
6441
|
"button",
|
|
5785
6442
|
{
|
|
5786
6443
|
type: "button",
|
|
@@ -5805,9 +6462,9 @@ function FloPayCheckout({
|
|
|
5805
6462
|
modeOverlay
|
|
5806
6463
|
] });
|
|
5807
6464
|
}
|
|
5808
|
-
return /* @__PURE__ */ (0,
|
|
5809
|
-
/* @__PURE__ */ (0,
|
|
5810
|
-
modeError && /* @__PURE__ */ (0,
|
|
6465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
6466
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: children ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
6467
|
+
modeError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5811
6468
|
"div",
|
|
5812
6469
|
{
|
|
5813
6470
|
style: {
|
|
@@ -5822,7 +6479,7 @@ function FloPayCheckout({
|
|
|
5822
6479
|
children: modeError
|
|
5823
6480
|
}
|
|
5824
6481
|
),
|
|
5825
|
-
/* @__PURE__ */ (0,
|
|
6482
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5826
6483
|
SessionInjector,
|
|
5827
6484
|
{
|
|
5828
6485
|
sessionId: activeSessionId,
|
|
@@ -5832,7 +6489,7 @@ function FloPayCheckout({
|
|
|
5832
6489
|
children
|
|
5833
6490
|
}
|
|
5834
6491
|
)
|
|
5835
|
-
] }) : /* @__PURE__ */ (0,
|
|
6492
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5836
6493
|
SplitCardForm,
|
|
5837
6494
|
{
|
|
5838
6495
|
sessionId: activeSessionId,
|
|
@@ -5852,6 +6509,7 @@ function FloPayCheckout({
|
|
|
5852
6509
|
showPayPal,
|
|
5853
6510
|
showStripe,
|
|
5854
6511
|
enabledPaymentMethods: unified?.data.stripe?.enabledPaymentMethods,
|
|
6512
|
+
enabledPaymentMethodCountries: unified?.data.stripe?.enabledPaymentMethodCountries,
|
|
5855
6513
|
showApplePay,
|
|
5856
6514
|
showGooglePay,
|
|
5857
6515
|
layout,
|
|
@@ -5865,6 +6523,8 @@ function FloPayCheckout({
|
|
|
5865
6523
|
onButtonClick,
|
|
5866
6524
|
onBeforeButtonClick,
|
|
5867
6525
|
enableAVS,
|
|
6526
|
+
...cardFieldOrder ? { cardFieldOrder } : {},
|
|
6527
|
+
...cardPreFormSlot ? { cardPreFormSlot } : {},
|
|
5868
6528
|
avsLayout,
|
|
5869
6529
|
country: session?.customer?.country,
|
|
5870
6530
|
city: session?.customer?.city,
|
|
@@ -5892,8 +6552,8 @@ function SessionInjector({
|
|
|
5892
6552
|
session,
|
|
5893
6553
|
children
|
|
5894
6554
|
}) {
|
|
5895
|
-
return /* @__PURE__ */ (0,
|
|
5896
|
-
if (!
|
|
6555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: import_react10.default.Children.map(children, (child) => {
|
|
6556
|
+
if (!import_react10.default.isValidElement(child)) return child;
|
|
5897
6557
|
const existing = child.props;
|
|
5898
6558
|
const injected = {};
|
|
5899
6559
|
if (!existing.sessionId) injected.sessionId = sessionId;
|
|
@@ -5908,7 +6568,7 @@ function SessionInjector({
|
|
|
5908
6568
|
injected.lastName = session.customer.lastName;
|
|
5909
6569
|
}
|
|
5910
6570
|
if (Object.keys(injected).length === 0) return child;
|
|
5911
|
-
return
|
|
6571
|
+
return import_react10.default.cloneElement(child, injected);
|
|
5912
6572
|
}) });
|
|
5913
6573
|
}
|
|
5914
6574
|
function InterimButtonsView({
|
|
@@ -5928,15 +6588,15 @@ function InterimButtonsView({
|
|
|
5928
6588
|
cardBackButtonContent,
|
|
5929
6589
|
cardTitleContent
|
|
5930
6590
|
}) {
|
|
5931
|
-
const [showCardForm, setShowCardForm] = (0,
|
|
6591
|
+
const [showCardForm, setShowCardForm] = (0, import_react10.useState)(false);
|
|
5932
6592
|
const isCardOpenControlled = typeof cardOpen === "boolean";
|
|
5933
|
-
(0,
|
|
6593
|
+
(0, import_react10.useEffect)(() => {
|
|
5934
6594
|
if (isCardOpenControlled) {
|
|
5935
6595
|
setShowCardForm(cardOpen);
|
|
5936
6596
|
}
|
|
5937
6597
|
}, [cardOpen, isCardOpenControlled]);
|
|
5938
|
-
const themeBundle = (0,
|
|
5939
|
-
const bStyles = (0,
|
|
6598
|
+
const themeBundle = (0, import_react10.useMemo)(() => (0, import_shared8.resolveTheme)(theme), [theme]);
|
|
6599
|
+
const bStyles = (0, import_react10.useMemo)(() => {
|
|
5940
6600
|
const base = themeBundle?.buttonsLayout ?? (0, import_shared8.resolveButtonsLayoutTheme)(buttonsTheme);
|
|
5941
6601
|
if (!stylesOverride) return base;
|
|
5942
6602
|
return {
|
|
@@ -5951,7 +6611,7 @@ function InterimButtonsView({
|
|
|
5951
6611
|
};
|
|
5952
6612
|
}, [themeBundle, buttonsTheme, stylesOverride]);
|
|
5953
6613
|
const skeletonRadius = themeBundle?.buttonsLayout?.cardButton?.borderRadius ?? themeBundle?.appearance.variables?.borderRadius ?? 8;
|
|
5954
|
-
const skeleton = (h) => /* @__PURE__ */ (0,
|
|
6614
|
+
const skeleton = (h) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
|
|
5955
6615
|
height: h,
|
|
5956
6616
|
borderRadius: skeletonRadius,
|
|
5957
6617
|
background: "#e5e7eb",
|
|
@@ -5963,15 +6623,15 @@ function InterimButtonsView({
|
|
|
5963
6623
|
const inputBg = bStyles.cardInputBackground ?? "white";
|
|
5964
6624
|
const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);
|
|
5965
6625
|
const hideTitle = isEmptySlotContent(cardTitleContent);
|
|
5966
|
-
return /* @__PURE__ */ (0,
|
|
6626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: {
|
|
5967
6627
|
backgroundColor: bStyles.cardFormContainer?.backgroundColor ?? "white",
|
|
5968
6628
|
borderRadius: "8px",
|
|
5969
6629
|
animation: "flopay-interim-expand 0.35s cubic-bezier(0.4, 0, 0.2, 1) both",
|
|
5970
6630
|
overflow: "hidden",
|
|
5971
6631
|
...bStyles.cardFormContainer
|
|
5972
6632
|
}, children: [
|
|
5973
|
-
/* @__PURE__ */ (0,
|
|
5974
|
-
/* @__PURE__ */ (0,
|
|
6633
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", padding: "0.75rem 0 0.625rem" }, children: [
|
|
6634
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
5975
6635
|
"button",
|
|
5976
6636
|
{
|
|
5977
6637
|
type: "button",
|
|
@@ -5998,7 +6658,7 @@ function InterimButtonsView({
|
|
|
5998
6658
|
...bStyles.backButton
|
|
5999
6659
|
},
|
|
6000
6660
|
children: [
|
|
6001
|
-
/* @__PURE__ */ (0,
|
|
6661
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: {
|
|
6002
6662
|
display: "inline-flex",
|
|
6003
6663
|
alignItems: "center",
|
|
6004
6664
|
justifyContent: "center",
|
|
@@ -6007,12 +6667,12 @@ function InterimButtonsView({
|
|
|
6007
6667
|
borderRadius: "50%",
|
|
6008
6668
|
backgroundColor: "#f3f4f6",
|
|
6009
6669
|
...bStyles.backButtonIcon
|
|
6010
|
-
}, children: /* @__PURE__ */ (0,
|
|
6011
|
-
/* @__PURE__ */ (0,
|
|
6670
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
|
|
6671
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
|
|
6012
6672
|
]
|
|
6013
6673
|
}
|
|
6014
6674
|
),
|
|
6015
|
-
hideTitle ? /* @__PURE__ */ (0,
|
|
6675
|
+
hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
|
|
6016
6676
|
flex: 1,
|
|
6017
6677
|
textAlign: "center",
|
|
6018
6678
|
fontWeight: 600,
|
|
@@ -6020,11 +6680,11 @@ function InterimButtonsView({
|
|
|
6020
6680
|
color: "#262833",
|
|
6021
6681
|
paddingRight: 80,
|
|
6022
6682
|
...bStyles.title
|
|
6023
|
-
}, children: /* @__PURE__ */ (0,
|
|
6683
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TitleContentSlot, { content: cardTitleContent }) })
|
|
6024
6684
|
] }),
|
|
6025
|
-
/* @__PURE__ */ (0,
|
|
6026
|
-
/* @__PURE__ */ (0,
|
|
6027
|
-
/* @__PURE__ */ (0,
|
|
6685
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { width: "60%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
6686
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex" }, children: [
|
|
6687
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
|
|
6028
6688
|
flex: 1,
|
|
6029
6689
|
backgroundColor: inputBg,
|
|
6030
6690
|
borderTop: "none",
|
|
@@ -6034,8 +6694,8 @@ function InterimButtonsView({
|
|
|
6034
6694
|
borderBottomLeftRadius: 8,
|
|
6035
6695
|
padding: 12,
|
|
6036
6696
|
height: 45
|
|
6037
|
-
}, children: /* @__PURE__ */ (0,
|
|
6038
|
-
/* @__PURE__ */ (0,
|
|
6697
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { width: "50%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
6698
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
|
|
6039
6699
|
flex: 1,
|
|
6040
6700
|
backgroundColor: inputBg,
|
|
6041
6701
|
borderTop: "none",
|
|
@@ -6045,10 +6705,10 @@ function InterimButtonsView({
|
|
|
6045
6705
|
borderBottomRightRadius: 8,
|
|
6046
6706
|
padding: 12,
|
|
6047
6707
|
height: 45
|
|
6048
|
-
}, children: /* @__PURE__ */ (0,
|
|
6708
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { width: "40%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) })
|
|
6049
6709
|
] }),
|
|
6050
|
-
/* @__PURE__ */ (0,
|
|
6051
|
-
/* @__PURE__ */ (0,
|
|
6710
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { width: "45%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
|
|
6711
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
|
|
6052
6712
|
height: 50,
|
|
6053
6713
|
borderRadius: 8,
|
|
6054
6714
|
marginTop: 16,
|
|
@@ -6057,7 +6717,7 @@ function InterimButtonsView({
|
|
|
6057
6717
|
...bStyles.submitButton,
|
|
6058
6718
|
opacity: 0.5
|
|
6059
6719
|
} }),
|
|
6060
|
-
/* @__PURE__ */ (0,
|
|
6720
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `
|
|
6061
6721
|
@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
6062
6722
|
@keyframes flopay-interim-expand {
|
|
6063
6723
|
0% { opacity: 0; max-height: 0; transform: translateY(-12px); }
|
|
@@ -6067,10 +6727,10 @@ function InterimButtonsView({
|
|
|
6067
6727
|
` })
|
|
6068
6728
|
] });
|
|
6069
6729
|
}
|
|
6070
|
-
return /* @__PURE__ */ (0,
|
|
6730
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
6071
6731
|
showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
6072
6732
|
showStripe && (showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
|
|
6073
|
-
showStripe && /* @__PURE__ */ (0,
|
|
6733
|
+
showStripe && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
6074
6734
|
"button",
|
|
6075
6735
|
{
|
|
6076
6736
|
type: "button",
|
|
@@ -6110,10 +6770,10 @@ function InterimButtonsView({
|
|
|
6110
6770
|
onMouseUp: (e) => {
|
|
6111
6771
|
e.currentTarget.style.transform = "scale(1)";
|
|
6112
6772
|
},
|
|
6113
|
-
children: /* @__PURE__ */ (0,
|
|
6773
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CardButtonContentSlot, { content: cardButtonContent })
|
|
6114
6774
|
}
|
|
6115
6775
|
),
|
|
6116
|
-
errorMessage && /* @__PURE__ */ (0,
|
|
6776
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: {
|
|
6117
6777
|
margin: "0.25rem 0",
|
|
6118
6778
|
padding: "0.625rem 0.875rem",
|
|
6119
6779
|
background: "#FEF2F2",
|
|
@@ -6127,22 +6787,22 @@ function InterimButtonsView({
|
|
|
6127
6787
|
gap: "0.5rem",
|
|
6128
6788
|
...bStyles.errorBanner
|
|
6129
6789
|
}, children: [
|
|
6130
|
-
/* @__PURE__ */ (0,
|
|
6790
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
6131
6791
|
errorMessage
|
|
6132
6792
|
] }),
|
|
6133
|
-
/* @__PURE__ */ (0,
|
|
6793
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
|
|
6134
6794
|
] });
|
|
6135
6795
|
}
|
|
6136
6796
|
|
|
6137
6797
|
// src/checkout-form.tsx
|
|
6138
6798
|
var import_js5 = require("@flopay/js");
|
|
6139
6799
|
var import_shared9 = require("@flopay/shared");
|
|
6140
|
-
var
|
|
6141
|
-
var
|
|
6800
|
+
var import_react11 = require("react");
|
|
6801
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
6142
6802
|
var WALLET_RESUME_KEY = "flopay_wallet_resume";
|
|
6143
|
-
var CheckoutForm = (0,
|
|
6803
|
+
var CheckoutForm = (0, import_react11.forwardRef)(
|
|
6144
6804
|
function CheckoutForm2(props, ref) {
|
|
6145
|
-
return /* @__PURE__ */ (0,
|
|
6805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CheckoutFormInner, { ...props, innerRef: ref });
|
|
6146
6806
|
}
|
|
6147
6807
|
);
|
|
6148
6808
|
function CheckoutFormInner({
|
|
@@ -6172,27 +6832,27 @@ function CheckoutFormInner({
|
|
|
6172
6832
|
const paypalFlopay = usePayPalFloPay();
|
|
6173
6833
|
const elements = useElements();
|
|
6174
6834
|
const contextBillingUrl = useBillingApiUrl();
|
|
6175
|
-
const [processing, setProcessing] = (0,
|
|
6176
|
-
const [error, setError] = (0,
|
|
6177
|
-
const [is3DSActive, setIs3DSActive] = (0,
|
|
6835
|
+
const [processing, setProcessing] = (0, import_react11.useState)(false);
|
|
6836
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
6837
|
+
const [is3DSActive, setIs3DSActive] = (0, import_react11.useState)(false);
|
|
6178
6838
|
const displayError = externalError ?? error;
|
|
6179
6839
|
const isSubmitting = externalProcessing ?? processing;
|
|
6180
6840
|
const isSelfContained = !onTokenizedBody;
|
|
6181
6841
|
const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
|
|
6182
|
-
const updateError = (0,
|
|
6842
|
+
const updateError = (0, import_react11.useCallback)(
|
|
6183
6843
|
(err) => {
|
|
6184
6844
|
setError(err);
|
|
6185
6845
|
onErrorChange?.(err);
|
|
6186
6846
|
},
|
|
6187
6847
|
[onErrorChange]
|
|
6188
6848
|
);
|
|
6189
|
-
const emitDecline = (0,
|
|
6849
|
+
const emitDecline = (0, import_react11.useCallback)(
|
|
6190
6850
|
(input, overrides) => {
|
|
6191
6851
|
onDecline?.(buildDeclineEvent("card", input, overrides));
|
|
6192
6852
|
},
|
|
6193
6853
|
[onDecline]
|
|
6194
6854
|
);
|
|
6195
|
-
const processPaymentInternal = (0,
|
|
6855
|
+
const processPaymentInternal = (0, import_react11.useCallback)(
|
|
6196
6856
|
async (tokenizedBody, completionPaymentMethodId) => {
|
|
6197
6857
|
setProcessing(true);
|
|
6198
6858
|
updateError(null);
|
|
@@ -6304,7 +6964,7 @@ function CheckoutFormInner({
|
|
|
6304
6964
|
},
|
|
6305
6965
|
[baseUrl, sessionId, nonce, userId, email, firstName, lastName, chv, flopay, paypalFlopay, onComplete, onError, onDecline, updateError, emitDecline]
|
|
6306
6966
|
);
|
|
6307
|
-
const dispatchTokenizedBody = (0,
|
|
6967
|
+
const dispatchTokenizedBody = (0, import_react11.useCallback)(
|
|
6308
6968
|
(tokenizedBody) => {
|
|
6309
6969
|
if (onTokenizedBody) {
|
|
6310
6970
|
onTokenizedBody(tokenizedBody);
|
|
@@ -6314,7 +6974,7 @@ function CheckoutFormInner({
|
|
|
6314
6974
|
},
|
|
6315
6975
|
[onTokenizedBody, processPaymentInternal]
|
|
6316
6976
|
);
|
|
6317
|
-
(0,
|
|
6977
|
+
(0, import_react11.useImperativeHandle)(innerRef, () => ({
|
|
6318
6978
|
async handleNextAction(secret) {
|
|
6319
6979
|
if (!flopay) return;
|
|
6320
6980
|
setIs3DSActive(true);
|
|
@@ -6341,7 +7001,7 @@ function CheckoutFormInner({
|
|
|
6341
7001
|
}
|
|
6342
7002
|
}
|
|
6343
7003
|
}), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
|
|
6344
|
-
(0,
|
|
7004
|
+
(0, import_react11.useEffect)(() => {
|
|
6345
7005
|
if (typeof window === "undefined") return;
|
|
6346
7006
|
const stored = localStorage.getItem(WALLET_RESUME_KEY);
|
|
6347
7007
|
if (!stored) return;
|
|
@@ -6359,7 +7019,7 @@ function CheckoutFormInner({
|
|
|
6359
7019
|
localStorage.removeItem(WALLET_RESUME_KEY);
|
|
6360
7020
|
}
|
|
6361
7021
|
}, [sessionId, dispatchTokenizedBody]);
|
|
6362
|
-
const handleSubmit = (0,
|
|
7022
|
+
const handleSubmit = (0, import_react11.useCallback)(
|
|
6363
7023
|
async (e) => {
|
|
6364
7024
|
e.preventDefault();
|
|
6365
7025
|
if (!flopay || !elements || isSubmitting) return;
|
|
@@ -6451,8 +7111,8 @@ function CheckoutFormInner({
|
|
|
6451
7111
|
[flopay, elements, isSubmitting, sessionId, nonce, email, firstName, lastName, baseUrl, isSelfContained, dispatchTokenizedBody, onError, updateError, emitDecline]
|
|
6452
7112
|
);
|
|
6453
7113
|
const isReady = flopay !== null && elements !== null;
|
|
6454
|
-
return /* @__PURE__ */ (0,
|
|
6455
|
-
(is3DSActive || isSubmitting) && /* @__PURE__ */ (0,
|
|
7114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
|
|
7115
|
+
(is3DSActive || isSubmitting) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { "data-testid": "flopay-overlay", style: {
|
|
6456
7116
|
position: "absolute",
|
|
6457
7117
|
inset: 0,
|
|
6458
7118
|
background: "rgba(255,255,255,0.7)",
|
|
@@ -6461,12 +7121,12 @@ function CheckoutFormInner({
|
|
|
6461
7121
|
justifyContent: "center",
|
|
6462
7122
|
zIndex: 10
|
|
6463
7123
|
}, children: is3DSActive ? "Verifying payment..." : "Processing..." }),
|
|
6464
|
-
!isReady && /* @__PURE__ */ (0,
|
|
6465
|
-
isReady && /* @__PURE__ */ (0,
|
|
6466
|
-
/* @__PURE__ */ (0,
|
|
6467
|
-
showAddress && /* @__PURE__ */ (0,
|
|
6468
|
-
displayError && /* @__PURE__ */ (0,
|
|
6469
|
-
children ?? /* @__PURE__ */ (0,
|
|
7124
|
+
!isReady && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." }),
|
|
7125
|
+
isReady && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
7126
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PaymentElement, { options: { layout } }),
|
|
7127
|
+
showAddress && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AddressElement, { options: { mode: showAddress === true ? "billing" : showAddress } }),
|
|
7128
|
+
displayError && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0" }, children: displayError }),
|
|
7129
|
+
children ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
6470
7130
|
"button",
|
|
6471
7131
|
{
|
|
6472
7132
|
type: "submit",
|
|
@@ -6482,8 +7142,8 @@ function CheckoutFormInner({
|
|
|
6482
7142
|
// src/paypal-button.tsx
|
|
6483
7143
|
var import_js6 = require("@flopay/js");
|
|
6484
7144
|
var import_shared10 = require("@flopay/shared");
|
|
6485
|
-
var
|
|
6486
|
-
var
|
|
7145
|
+
var import_react12 = require("react");
|
|
7146
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
6487
7147
|
function PayPalButton({
|
|
6488
7148
|
sessionId,
|
|
6489
7149
|
nonce,
|
|
@@ -6501,11 +7161,11 @@ function PayPalButton({
|
|
|
6501
7161
|
const flopay = useFloPay();
|
|
6502
7162
|
const elements = useElements();
|
|
6503
7163
|
const contextBillingUrl = useBillingApiUrl();
|
|
6504
|
-
const [ready, setReady] = (0,
|
|
6505
|
-
const [submitting, setSubmitting] = (0,
|
|
6506
|
-
const paypalResumeAttempted = (0,
|
|
7164
|
+
const [ready, setReady] = (0, import_react12.useState)(false);
|
|
7165
|
+
const [submitting, setSubmitting] = (0, import_react12.useState)(false);
|
|
7166
|
+
const paypalResumeAttempted = (0, import_react12.useRef)(false);
|
|
6507
7167
|
const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
|
|
6508
|
-
const processPaymentInternal = (0,
|
|
7168
|
+
const processPaymentInternal = (0, import_react12.useCallback)(
|
|
6509
7169
|
async (tokenizedBody) => {
|
|
6510
7170
|
try {
|
|
6511
7171
|
const api = new import_js6.PaymentAPI(baseUrl);
|
|
@@ -6533,7 +7193,7 @@ function PayPalButton({
|
|
|
6533
7193
|
},
|
|
6534
7194
|
[baseUrl, sessionId, nonce, userId, email, firstName, lastName, chv, onComplete, onErrorChange]
|
|
6535
7195
|
);
|
|
6536
|
-
const dispatchTokenizedBody = (0,
|
|
7196
|
+
const dispatchTokenizedBody = (0, import_react12.useCallback)(
|
|
6537
7197
|
(body) => {
|
|
6538
7198
|
if (onTokenizedBody) {
|
|
6539
7199
|
onTokenizedBody(body);
|
|
@@ -6543,7 +7203,7 @@ function PayPalButton({
|
|
|
6543
7203
|
},
|
|
6544
7204
|
[onTokenizedBody, processPaymentInternal]
|
|
6545
7205
|
);
|
|
6546
|
-
(0,
|
|
7206
|
+
(0, import_react12.useEffect)(() => {
|
|
6547
7207
|
if (!flopay || paypalResumeAttempted.current) return;
|
|
6548
7208
|
const params = new URLSearchParams(window.location.search);
|
|
6549
7209
|
const paymentIntentId = params.get("payment_intent");
|
|
@@ -6591,7 +7251,7 @@ function PayPalButton({
|
|
|
6591
7251
|
}
|
|
6592
7252
|
})();
|
|
6593
7253
|
}, [flopay, dispatchTokenizedBody, onErrorChange]);
|
|
6594
|
-
const handlePayPalConfirm = (0,
|
|
7254
|
+
const handlePayPalConfirm = (0, import_react12.useCallback)(async () => {
|
|
6595
7255
|
if (!flopay || !elements) return;
|
|
6596
7256
|
try {
|
|
6597
7257
|
setSubmitting(true);
|
|
@@ -6625,11 +7285,11 @@ function PayPalButton({
|
|
|
6625
7285
|
}
|
|
6626
7286
|
}, [flopay, elements, sessionId, nonce, email, baseUrl, dispatchTokenizedBody, onErrorChange]);
|
|
6627
7287
|
if (!flopay || !elements) {
|
|
6628
|
-
return /* @__PURE__ */ (0,
|
|
7288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6, animation: "pulse 1.5s infinite" } });
|
|
6629
7289
|
}
|
|
6630
|
-
return /* @__PURE__ */ (0,
|
|
6631
|
-
!ready && /* @__PURE__ */ (0,
|
|
6632
|
-
/* @__PURE__ */ (0,
|
|
7290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
7291
|
+
!ready && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6 } }),
|
|
7292
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: ready ? {} : { display: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
6633
7293
|
"button",
|
|
6634
7294
|
{
|
|
6635
7295
|
type: "button",
|
|
@@ -6651,7 +7311,7 @@ function PayPalButton({
|
|
|
6651
7311
|
children: submitting ? "Processing..." : "PayPal"
|
|
6652
7312
|
}
|
|
6653
7313
|
) }),
|
|
6654
|
-
(submitting || isProcessing) && /* @__PURE__ */ (0,
|
|
7314
|
+
(submitting || isProcessing) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: {
|
|
6655
7315
|
position: "fixed",
|
|
6656
7316
|
inset: 0,
|
|
6657
7317
|
background: "rgba(0,0,0,0.4)",
|
|
@@ -6659,7 +7319,7 @@ function PayPalButton({
|
|
|
6659
7319
|
alignItems: "center",
|
|
6660
7320
|
justifyContent: "center",
|
|
6661
7321
|
zIndex: 1e3
|
|
6662
|
-
}, children: /* @__PURE__ */ (0,
|
|
7322
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: {
|
|
6663
7323
|
background: "white",
|
|
6664
7324
|
borderRadius: 8,
|
|
6665
7325
|
padding: "1.5rem",
|
|
@@ -6671,10 +7331,10 @@ function PayPalButton({
|
|
|
6671
7331
|
}
|
|
6672
7332
|
|
|
6673
7333
|
// src/automatic-payment-button.tsx
|
|
6674
|
-
var
|
|
7334
|
+
var import_react13 = require("react");
|
|
6675
7335
|
var import_js7 = require("@flopay/js");
|
|
6676
7336
|
var import_shared11 = require("@flopay/shared");
|
|
6677
|
-
var
|
|
7337
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
6678
7338
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3 = 44;
|
|
6679
7339
|
function sleep2(ms) {
|
|
6680
7340
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -6742,6 +7402,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
6742
7402
|
billingApiUrl,
|
|
6743
7403
|
locale,
|
|
6744
7404
|
theme,
|
|
7405
|
+
appearance,
|
|
6745
7406
|
buttonsTheme,
|
|
6746
7407
|
buttonsStyles: stylesOverride,
|
|
6747
7408
|
onSuccess,
|
|
@@ -6753,11 +7414,11 @@ function FloPayAutomaticPaymentButton({
|
|
|
6753
7414
|
style,
|
|
6754
7415
|
...buttonProps
|
|
6755
7416
|
}) {
|
|
6756
|
-
const resolvedBillingUrl = (0,
|
|
7417
|
+
const resolvedBillingUrl = (0, import_react13.useMemo)(
|
|
6757
7418
|
() => (0, import_shared11.resolveBillingApiUrl)(billingApiUrl),
|
|
6758
7419
|
[billingApiUrl]
|
|
6759
7420
|
);
|
|
6760
|
-
const createSessionDraft = (0,
|
|
7421
|
+
const createSessionDraft = (0, import_react13.useMemo)(
|
|
6761
7422
|
() => resolveCreateSessionDraft({
|
|
6762
7423
|
createSession,
|
|
6763
7424
|
clientId,
|
|
@@ -6785,34 +7446,36 @@ function FloPayAutomaticPaymentButton({
|
|
|
6785
7446
|
utmMetadata
|
|
6786
7447
|
]
|
|
6787
7448
|
);
|
|
6788
|
-
const [isProcessing, setIsProcessing] = (0,
|
|
6789
|
-
const [overlayStatus, setOverlayStatus] = (0,
|
|
6790
|
-
const [overlayError, setOverlayError] = (0,
|
|
6791
|
-
const [fallbackSession, setFallbackSession] = (0,
|
|
6792
|
-
const isMountedRef = (0,
|
|
6793
|
-
const
|
|
6794
|
-
const
|
|
6795
|
-
const
|
|
6796
|
-
const
|
|
6797
|
-
(0,
|
|
7449
|
+
const [isProcessing, setIsProcessing] = (0, import_react13.useState)(false);
|
|
7450
|
+
const [overlayStatus, setOverlayStatus] = (0, import_react13.useState)(null);
|
|
7451
|
+
const [overlayError, setOverlayError] = (0, import_react13.useState)(null);
|
|
7452
|
+
const [fallbackSession, setFallbackSession] = (0, import_react13.useState)(null);
|
|
7453
|
+
const isMountedRef = (0, import_react13.useRef)(true);
|
|
7454
|
+
const threeDsAbortRef = (0, import_react13.useRef)(null);
|
|
7455
|
+
const fallbackSessionRef = (0, import_react13.useRef)(fallbackSession);
|
|
7456
|
+
const onSuccessRef = (0, import_react13.useRef)(onSuccess);
|
|
7457
|
+
const onErrorRef = (0, import_react13.useRef)(onError);
|
|
7458
|
+
const onDeclineRef = (0, import_react13.useRef)(onDecline);
|
|
7459
|
+
(0, import_react13.useEffect)(() => {
|
|
6798
7460
|
fallbackSessionRef.current = fallbackSession;
|
|
6799
7461
|
}, [fallbackSession]);
|
|
6800
|
-
(0,
|
|
7462
|
+
(0, import_react13.useEffect)(() => {
|
|
6801
7463
|
onSuccessRef.current = onSuccess;
|
|
6802
7464
|
}, [onSuccess]);
|
|
6803
|
-
(0,
|
|
7465
|
+
(0, import_react13.useEffect)(() => {
|
|
6804
7466
|
onErrorRef.current = onError;
|
|
6805
7467
|
}, [onError]);
|
|
6806
|
-
(0,
|
|
7468
|
+
(0, import_react13.useEffect)(() => {
|
|
6807
7469
|
onDeclineRef.current = onDecline;
|
|
6808
7470
|
}, [onDecline]);
|
|
6809
|
-
(0,
|
|
7471
|
+
(0, import_react13.useEffect)(() => {
|
|
6810
7472
|
isMountedRef.current = true;
|
|
6811
7473
|
return () => {
|
|
6812
7474
|
isMountedRef.current = false;
|
|
7475
|
+
threeDsAbortRef.current?.abort();
|
|
6813
7476
|
};
|
|
6814
7477
|
}, []);
|
|
6815
|
-
(0,
|
|
7478
|
+
(0, import_react13.useEffect)(() => {
|
|
6816
7479
|
if (!fallbackSession || typeof window === "undefined") {
|
|
6817
7480
|
return;
|
|
6818
7481
|
}
|
|
@@ -6826,13 +7489,13 @@ function FloPayAutomaticPaymentButton({
|
|
|
6826
7489
|
window.removeEventListener("keydown", handleKeyDown);
|
|
6827
7490
|
};
|
|
6828
7491
|
}, [fallbackSession]);
|
|
6829
|
-
const emitDecline = (0,
|
|
7492
|
+
const emitDecline = (0, import_react13.useCallback)((error, method = DEFAULT_SAVED_PAYMENT_DECLINE_METHOD) => {
|
|
6830
7493
|
onDeclineRef.current?.(buildDeclineEvent(method, error, {
|
|
6831
7494
|
code: error.code,
|
|
6832
7495
|
declineCode: error.declineCode
|
|
6833
7496
|
}));
|
|
6834
7497
|
}, []);
|
|
6835
|
-
const showSuccess = (0,
|
|
7498
|
+
const showSuccess = (0, import_react13.useCallback)(async (event) => {
|
|
6836
7499
|
if (!isMountedRef.current) return;
|
|
6837
7500
|
setOverlayError(null);
|
|
6838
7501
|
setOverlayStatus("success");
|
|
@@ -6840,7 +7503,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
6840
7503
|
if (!isMountedRef.current) return;
|
|
6841
7504
|
onSuccessRef.current?.(event);
|
|
6842
7505
|
}, []);
|
|
6843
|
-
const showError = (0,
|
|
7506
|
+
const showError = (0, import_react13.useCallback)(async (error, options) => {
|
|
6844
7507
|
if (!isMountedRef.current) return;
|
|
6845
7508
|
onErrorRef.current?.(error);
|
|
6846
7509
|
if (options?.emitDecline) {
|
|
@@ -6850,7 +7513,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
6850
7513
|
setOverlayStatus("error");
|
|
6851
7514
|
await sleep2(PROCESSING_OVERLAY_ERROR_DELAY_MS);
|
|
6852
7515
|
}, [emitDecline]);
|
|
6853
|
-
const processResolvedSession = (0,
|
|
7516
|
+
const processResolvedSession = (0, import_react13.useCallback)(async (apiResult, resolvedSessionId, options) => {
|
|
6854
7517
|
const session = apiResult.data.session ?? null;
|
|
6855
7518
|
if (!session) {
|
|
6856
7519
|
throw new import_shared11.FloPayError("No session data returned", "api_error");
|
|
@@ -6891,6 +7554,62 @@ function FloPayAutomaticPaymentButton({
|
|
|
6891
7554
|
return;
|
|
6892
7555
|
}
|
|
6893
7556
|
if (apiResult.autoProcessingError) {
|
|
7557
|
+
if (apiResult.autoProcessingError.type === "3ds_required" && apiResult.autoProcessingError.nextActionRedirectUrl && resolvedSessionId && effectiveNonce) {
|
|
7558
|
+
const threeDsAbort = new AbortController();
|
|
7559
|
+
threeDsAbortRef.current = threeDsAbort;
|
|
7560
|
+
let outcome;
|
|
7561
|
+
try {
|
|
7562
|
+
outcome = await runAutoCheckoutThreeDsChallenge({
|
|
7563
|
+
billingApiUrl: resolvedBillingUrl,
|
|
7564
|
+
sessionId: resolvedSessionId,
|
|
7565
|
+
nonce: effectiveNonce,
|
|
7566
|
+
nextActionRedirectUrl: apiResult.autoProcessingError.nextActionRedirectUrl,
|
|
7567
|
+
signal: threeDsAbort.signal
|
|
7568
|
+
});
|
|
7569
|
+
} finally {
|
|
7570
|
+
if (threeDsAbortRef.current === threeDsAbort) {
|
|
7571
|
+
threeDsAbortRef.current = null;
|
|
7572
|
+
}
|
|
7573
|
+
}
|
|
7574
|
+
if (outcome.status === "declined") {
|
|
7575
|
+
throw checkoutProcessErrorToFloPayError(
|
|
7576
|
+
{
|
|
7577
|
+
type: outcome.declineReason ?? "decline",
|
|
7578
|
+
message: "Card was declined.",
|
|
7579
|
+
gatewayErrorCode: outcome.gatewayDeclineReason ?? void 0
|
|
7580
|
+
},
|
|
7581
|
+
"Card was declined.",
|
|
7582
|
+
{
|
|
7583
|
+
checkoutMethod: apiResult.autoProcessingError.checkoutMethod
|
|
7584
|
+
}
|
|
7585
|
+
);
|
|
7586
|
+
}
|
|
7587
|
+
const api = new import_js7.PaymentAPI(resolvedBillingUrl);
|
|
7588
|
+
const completed = await api.waitForCheckoutSessionCompletion(resolvedSessionId, {
|
|
7589
|
+
initialDelayMs: 0,
|
|
7590
|
+
nonce: effectiveNonce
|
|
7591
|
+
});
|
|
7592
|
+
const completedSession = completed.data.session;
|
|
7593
|
+
if (!completedSession || completedSession.status !== "complete") {
|
|
7594
|
+
throw checkoutProcessErrorToFloPayError(
|
|
7595
|
+
{
|
|
7596
|
+
type: "unknown",
|
|
7597
|
+
message: "Card authentication was not completed."
|
|
7598
|
+
},
|
|
7599
|
+
"Card authentication was not completed.",
|
|
7600
|
+
{
|
|
7601
|
+
checkoutMethod: apiResult.autoProcessingError.checkoutMethod
|
|
7602
|
+
}
|
|
7603
|
+
);
|
|
7604
|
+
}
|
|
7605
|
+
await showSuccess({
|
|
7606
|
+
result: { status: "succeeded" },
|
|
7607
|
+
session: completedSession,
|
|
7608
|
+
sessionId: completedSession.id || resolvedSessionId,
|
|
7609
|
+
autoCompleted: false
|
|
7610
|
+
});
|
|
7611
|
+
return;
|
|
7612
|
+
}
|
|
6894
7613
|
throw checkoutProcessErrorToFloPayError(
|
|
6895
7614
|
apiResult.autoProcessingError,
|
|
6896
7615
|
"Automatic payment failed. Please try again.",
|
|
@@ -6950,7 +7669,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
6950
7669
|
showError,
|
|
6951
7670
|
showSuccess
|
|
6952
7671
|
]);
|
|
6953
|
-
const handleButtonClick = (0,
|
|
7672
|
+
const handleButtonClick = (0, import_react13.useCallback)(async (event) => {
|
|
6954
7673
|
buttonProps.onClick?.(event);
|
|
6955
7674
|
if (event.defaultPrevented || disabled || isProcessing) {
|
|
6956
7675
|
return;
|
|
@@ -7032,7 +7751,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
7032
7751
|
showError,
|
|
7033
7752
|
showSuccess
|
|
7034
7753
|
]);
|
|
7035
|
-
const handleFallbackComplete = (0,
|
|
7754
|
+
const handleFallbackComplete = (0, import_react13.useCallback)((result) => {
|
|
7036
7755
|
const activeFallback = fallbackSessionRef.current;
|
|
7037
7756
|
setFallbackSession(null);
|
|
7038
7757
|
onSuccessRef.current?.({
|
|
@@ -7042,14 +7761,14 @@ function FloPayAutomaticPaymentButton({
|
|
|
7042
7761
|
autoCompleted: false
|
|
7043
7762
|
});
|
|
7044
7763
|
}, []);
|
|
7045
|
-
const handleFallbackError = (0,
|
|
7764
|
+
const handleFallbackError = (0, import_react13.useCallback)((error) => {
|
|
7046
7765
|
onErrorRef.current?.(error);
|
|
7047
7766
|
}, []);
|
|
7048
|
-
const handleFallbackDecline = (0,
|
|
7767
|
+
const handleFallbackDecline = (0, import_react13.useCallback)((decline) => {
|
|
7049
7768
|
onDeclineRef.current?.(decline);
|
|
7050
7769
|
}, []);
|
|
7051
|
-
const themeBundle = (0,
|
|
7052
|
-
const bStyles = (0,
|
|
7770
|
+
const themeBundle = (0, import_react13.useMemo)(() => (0, import_shared11.resolveTheme)(theme), [theme]);
|
|
7771
|
+
const bStyles = (0, import_react13.useMemo)(() => {
|
|
7053
7772
|
const base = themeBundle?.buttonsLayout ?? (0, import_shared11.resolveButtonsLayoutTheme)(buttonsTheme);
|
|
7054
7773
|
if (!stylesOverride) return base;
|
|
7055
7774
|
return {
|
|
@@ -7058,9 +7777,26 @@ function FloPayAutomaticPaymentButton({
|
|
|
7058
7777
|
cardButton: { ...base.cardButton, ...stylesOverride.cardButton }
|
|
7059
7778
|
};
|
|
7060
7779
|
}, [themeBundle, buttonsTheme, stylesOverride]);
|
|
7780
|
+
const resolvedAppearance = (0, import_react13.useMemo)(() => {
|
|
7781
|
+
const bundleAppearance = themeBundle?.appearance;
|
|
7782
|
+
if (!appearance) return bundleAppearance;
|
|
7783
|
+
if (!bundleAppearance) return appearance;
|
|
7784
|
+
return {
|
|
7785
|
+
...bundleAppearance,
|
|
7786
|
+
...appearance,
|
|
7787
|
+
variables: {
|
|
7788
|
+
...bundleAppearance.variables,
|
|
7789
|
+
...appearance.variables
|
|
7790
|
+
}
|
|
7791
|
+
};
|
|
7792
|
+
}, [appearance, themeBundle]);
|
|
7793
|
+
const resolvedAppearanceVars = resolvedAppearance?.variables;
|
|
7794
|
+
const resolvedPrimaryColor = resolvedAppearanceVars?.colorPrimary ?? "#4A49FF";
|
|
7795
|
+
const resolvedPrimaryHoverColor = resolvedAppearanceVars?.colorPrimaryHover ?? darkenHex(resolvedPrimaryColor, 0.12);
|
|
7796
|
+
const resolvedButtonBorderRadius = resolvedAppearanceVars?.borderRadius ?? "8px";
|
|
7061
7797
|
const cardButtonSizing = children === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
7062
|
-
return /* @__PURE__ */ (0,
|
|
7063
|
-
/* @__PURE__ */ (0,
|
|
7798
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
7799
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
7064
7800
|
"button",
|
|
7065
7801
|
{
|
|
7066
7802
|
...buttonProps,
|
|
@@ -7076,14 +7812,17 @@ function FloPayAutomaticPaymentButton({
|
|
|
7076
7812
|
// on top so the auto-pay button carries the *submit* button's
|
|
7077
7813
|
// background and text colours — making it visually identical to
|
|
7078
7814
|
// the "Confirm Payment" / "Pay with X" actions it stands in for.
|
|
7815
|
+
// `resolvedPrimaryColor` is the *merged* appearance value, so a
|
|
7816
|
+
// per-checkout `colorPrimary` override re-skins this button too.
|
|
7079
7817
|
// Inline `style` consumer override stays at the end so explicit
|
|
7080
7818
|
// per-button overrides still win.
|
|
7081
7819
|
...bStyles.cardButton,
|
|
7082
7820
|
...derivePrimaryTileStyle({
|
|
7083
7821
|
themeBundle,
|
|
7084
|
-
resolvedPrimaryColor
|
|
7085
|
-
resolvedBorderRadius:
|
|
7086
|
-
submitButtonStyle: bStyles.submitButton
|
|
7822
|
+
resolvedPrimaryColor,
|
|
7823
|
+
resolvedBorderRadius: resolvedButtonBorderRadius,
|
|
7824
|
+
submitButtonStyle: bStyles.submitButton,
|
|
7825
|
+
explicitPrimaryColor: resolvedAppearanceVars?.colorPrimary
|
|
7087
7826
|
}),
|
|
7088
7827
|
fontSize: bStyles.cardButtonFontSize ?? "0.95rem",
|
|
7089
7828
|
fontWeight: 600,
|
|
@@ -7092,11 +7831,23 @@ function FloPayAutomaticPaymentButton({
|
|
|
7092
7831
|
alignItems: "center",
|
|
7093
7832
|
justifyContent: "center",
|
|
7094
7833
|
gap: "0.625rem",
|
|
7095
|
-
transition: "border-color 0.2s, box-shadow 0.2s, transform 0.1s",
|
|
7834
|
+
transition: "background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s",
|
|
7096
7835
|
position: "relative",
|
|
7097
7836
|
opacity: disabled || isProcessing ? 0.6 : 1,
|
|
7098
7837
|
...style
|
|
7099
7838
|
},
|
|
7839
|
+
onMouseEnter: (e) => {
|
|
7840
|
+
buttonProps.onMouseEnter?.(e);
|
|
7841
|
+
if (!e.defaultPrevented && !disabled && !isProcessing && (themeBundle || resolvedAppearanceVars?.colorPrimary)) {
|
|
7842
|
+
e.currentTarget.style.backgroundColor = resolvedPrimaryHoverColor;
|
|
7843
|
+
}
|
|
7844
|
+
},
|
|
7845
|
+
onMouseLeave: (e) => {
|
|
7846
|
+
buttonProps.onMouseLeave?.(e);
|
|
7847
|
+
if (!e.defaultPrevented && (themeBundle || resolvedAppearanceVars?.colorPrimary)) {
|
|
7848
|
+
e.currentTarget.style.backgroundColor = resolvedPrimaryColor;
|
|
7849
|
+
}
|
|
7850
|
+
},
|
|
7100
7851
|
onMouseDown: (e) => {
|
|
7101
7852
|
buttonProps.onMouseDown?.(e);
|
|
7102
7853
|
if (!e.defaultPrevented) {
|
|
@@ -7109,17 +7860,17 @@ function FloPayAutomaticPaymentButton({
|
|
|
7109
7860
|
e.currentTarget.style.transform = "scale(1)";
|
|
7110
7861
|
}
|
|
7111
7862
|
},
|
|
7112
|
-
children: /* @__PURE__ */ (0,
|
|
7863
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CardButtonContentSlot, { content: children })
|
|
7113
7864
|
}
|
|
7114
7865
|
),
|
|
7115
|
-
overlayStatus && /* @__PURE__ */ (0,
|
|
7866
|
+
overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
7116
7867
|
ProcessingOverlay,
|
|
7117
7868
|
{
|
|
7118
7869
|
status: overlayStatus,
|
|
7119
7870
|
errorMessage: overlayError
|
|
7120
7871
|
}
|
|
7121
7872
|
),
|
|
7122
|
-
fallbackSession && /* @__PURE__ */ (0,
|
|
7873
|
+
fallbackSession && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
7123
7874
|
"div",
|
|
7124
7875
|
{
|
|
7125
7876
|
"data-testid": "flopay-automatic-payment-fallback",
|
|
@@ -7140,7 +7891,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
7140
7891
|
padding: "1.5rem",
|
|
7141
7892
|
zIndex: 1100
|
|
7142
7893
|
},
|
|
7143
|
-
children: /* @__PURE__ */ (0,
|
|
7894
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
7144
7895
|
"div",
|
|
7145
7896
|
{
|
|
7146
7897
|
style: {
|
|
@@ -7156,7 +7907,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
7156
7907
|
flexDirection: "column",
|
|
7157
7908
|
gap: "1rem"
|
|
7158
7909
|
},
|
|
7159
|
-
children: /* @__PURE__ */ (0,
|
|
7910
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
7160
7911
|
FloPayCheckout,
|
|
7161
7912
|
{
|
|
7162
7913
|
sessionId: fallbackSession.sessionId,
|
|
@@ -7165,6 +7916,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
7165
7916
|
billingApiUrl: resolvedBillingUrl,
|
|
7166
7917
|
locale,
|
|
7167
7918
|
theme,
|
|
7919
|
+
...resolvedAppearance ? { appearance: resolvedAppearance } : {},
|
|
7168
7920
|
buttonsTheme,
|
|
7169
7921
|
buttonsStyles: stylesOverride,
|
|
7170
7922
|
initialErrorMessage: fallbackSession.errorMessage,
|
|
@@ -7195,6 +7947,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
7195
7947
|
PayPalButton,
|
|
7196
7948
|
PaymentElement,
|
|
7197
7949
|
SplitCardForm,
|
|
7950
|
+
VaultCardFields,
|
|
7198
7951
|
useCheckout,
|
|
7199
7952
|
useElements,
|
|
7200
7953
|
useFloPay,
|