@flopay/react 1.2.7 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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 import_react9 = __toESM(require("react"), 1);
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/hooks.ts
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, import_react5.useContext)(FloPayContext);
370
+ const ctx = (0, import_react6.useContext)(FloPayContext);
297
371
  return ctx.flopay;
298
372
  }
299
373
  function usePayPalFloPay() {
300
- const ctx = (0, import_react5.useContext)(FloPayContext);
374
+ const ctx = (0, import_react6.useContext)(FloPayContext);
301
375
  return ctx.paypalFlopay ?? null;
302
376
  }
303
377
  function useElements() {
304
- const ctx = (0, import_react5.useContext)(FloPayContext);
378
+ const ctx = (0, import_react6.useContext)(FloPayContext);
305
379
  return ctx.elements;
306
380
  }
307
381
  function useCheckout() {
308
- return (0, import_react5.useContext)(CheckoutContext);
382
+ return (0, import_react6.useContext)(CheckoutContext);
309
383
  }
310
384
  function useBillingApiUrl() {
311
- const ctx = (0, import_react5.useContext)(FloPayContext);
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 import_react6 = require("react");
317
- var import_jsx_runtime4 = require("react/jsx-runtime");
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, import_jsx_runtime4.jsx)(
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, import_jsx_runtime4.jsxs)(
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, import_jsx_runtime4.jsxs)("div", { style: { width: 48, height: 48, position: "relative" }, children: [
358
- status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
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, import_jsx_runtime4.jsx)("circle", { cx: "12", cy: "12", r: "10", stroke: "#e5e7eb", strokeWidth: "3" }),
369
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z", fill: "#4A49FF" })
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, import_jsx_runtime4.jsx)("div", { style: { animation: "flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
374
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "12", cy: "12", r: "11", fill: "#22c55e" }),
375
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
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, import_jsx_runtime4.jsx)("div", { style: { animation: "flopay-shake 0.4s ease" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
392
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "12", cy: "12", r: "11", fill: "#ef4444" }),
393
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
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, import_jsx_runtime4.jsxs)(
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, import_jsx_runtime4.jsx)(
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, import_jsx_runtime4.jsx)(
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, import_jsx_runtime4.jsx)("style", { children: `
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; } }
@@ -633,6 +707,18 @@ function resolvePaymentIntentPaymentMethodId(paymentIntent) {
633
707
  }
634
708
  async function retrievePaymentIntentFromProvider(provider, clientSecret) {
635
709
  const retriever = provider;
710
+ if ((0, import_shared3.isSetupIntentClientSecret)(clientSecret)) {
711
+ if (!retriever?.retrieveSetupIntent) {
712
+ return null;
713
+ }
714
+ const { setupIntent, error: error2 } = await retriever.retrieveSetupIntent(clientSecret);
715
+ if (error2) {
716
+ throw new import_shared3.FloPayError(error2.message ?? "Failed to retrieve setup intent.", "api_error", {
717
+ ...error2.code ? { code: error2.code } : {}
718
+ });
719
+ }
720
+ return setupIntent ?? null;
721
+ }
636
722
  if (!retriever?.retrievePaymentIntent) {
637
723
  return null;
638
724
  }
@@ -644,6 +730,12 @@ async function retrievePaymentIntentFromProvider(provider, clientSecret) {
644
730
  }
645
731
  return paymentIntent ?? null;
646
732
  }
733
+ function resolveWalletElementsMode(amountInMinorUnits) {
734
+ if (typeof amountInMinorUnits !== "number" || !Number.isFinite(amountInMinorUnits) || amountInMinorUnits <= 0) {
735
+ return { mode: "setup" };
736
+ }
737
+ return { mode: "payment", amount: amountInMinorUnits };
738
+ }
647
739
  function resolveTokenizedPaymentMethodId(tokenizedBody) {
648
740
  const candidates = [
649
741
  tokenizedBody?.id,
@@ -706,11 +798,11 @@ function isInAppBrowser(userAgent) {
706
798
  }
707
799
 
708
800
  // src/direct-paypal-button.tsx
709
- var import_react7 = require("react");
801
+ var import_react8 = require("react");
710
802
  var import_paypal_js = require("@paypal/paypal-js");
711
803
  var import_js = require("@flopay/js");
712
804
  var import_shared4 = require("@flopay/shared");
713
- var import_jsx_runtime5 = require("react/jsx-runtime");
805
+ var import_jsx_runtime6 = require("react/jsx-runtime");
714
806
  var DEFAULT_BUTTON_HEIGHT = 45;
715
807
  function DirectPayPalButton({
716
808
  sessionId,
@@ -733,62 +825,62 @@ function DirectPayPalButton({
733
825
  existingOrderId,
734
826
  debug = false
735
827
  }) {
736
- const containerRef = (0, import_react7.useRef)(null);
737
- const [ready, setReady] = (0, import_react7.useState)(false);
738
- const [failed, setFailed] = (0, import_react7.useState)(false);
739
- const [submitting, setSubmitting] = (0, import_react7.useState)(false);
740
- const baseUrl = (0, import_react7.useMemo)(() => billingApiUrl.replace(/\/+$/, ""), [billingApiUrl]);
741
- const [debugLines, setDebugLines] = (0, import_react7.useState)([]);
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)([]);
742
834
  const appendDebug = (line) => {
743
835
  if (!debug) return;
744
836
  setDebugLines((prev) => [...prev, `${(/* @__PURE__ */ new Date()).toISOString().slice(11, 23)} ${line}`]);
745
837
  };
746
- const onTokenizedBodyRef = (0, import_react7.useRef)(onTokenizedBody);
747
- const onCompleteRef = (0, import_react7.useRef)(onComplete);
748
- const onErrorChangeRef = (0, import_react7.useRef)(onErrorChange);
749
- const onDeclineRef = (0, import_react7.useRef)(onDecline);
750
- const onButtonClickRef = (0, import_react7.useRef)(onButtonClick);
751
- const onLoadStateChangeRef = (0, import_react7.useRef)(onLoadStateChange);
752
- const runBeforeButtonClickRef = (0, import_react7.useRef)(runBeforeButtonClick);
753
- const sessionRef = (0, import_react7.useRef)(session);
754
- const emailRef = (0, import_react7.useRef)(email);
755
- const nonceRef = (0, import_react7.useRef)(nonce);
756
- const beforeClickRef = (0, import_react7.useRef)(null);
757
- (0, import_react7.useEffect)(() => {
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)(() => {
758
850
  onTokenizedBodyRef.current = onTokenizedBody;
759
851
  }, [onTokenizedBody]);
760
- (0, import_react7.useEffect)(() => {
852
+ (0, import_react8.useEffect)(() => {
761
853
  onCompleteRef.current = onComplete;
762
854
  }, [onComplete]);
763
- (0, import_react7.useEffect)(() => {
855
+ (0, import_react8.useEffect)(() => {
764
856
  onErrorChangeRef.current = onErrorChange;
765
857
  }, [onErrorChange]);
766
- (0, import_react7.useEffect)(() => {
858
+ (0, import_react8.useEffect)(() => {
767
859
  onDeclineRef.current = onDecline;
768
860
  }, [onDecline]);
769
- (0, import_react7.useEffect)(() => {
861
+ (0, import_react8.useEffect)(() => {
770
862
  onButtonClickRef.current = onButtonClick;
771
863
  }, [onButtonClick]);
772
- (0, import_react7.useEffect)(() => {
864
+ (0, import_react8.useEffect)(() => {
773
865
  onLoadStateChangeRef.current = onLoadStateChange;
774
866
  }, [onLoadStateChange]);
775
- (0, import_react7.useEffect)(() => {
867
+ (0, import_react8.useEffect)(() => {
776
868
  runBeforeButtonClickRef.current = runBeforeButtonClick;
777
869
  }, [runBeforeButtonClick]);
778
- (0, import_react7.useEffect)(() => {
870
+ (0, import_react8.useEffect)(() => {
779
871
  sessionRef.current = session;
780
872
  }, [session]);
781
- (0, import_react7.useEffect)(() => {
873
+ (0, import_react8.useEffect)(() => {
782
874
  emailRef.current = email;
783
875
  }, [email]);
784
- (0, import_react7.useEffect)(() => {
876
+ (0, import_react8.useEffect)(() => {
785
877
  nonceRef.current = nonce;
786
878
  }, [nonce]);
787
- (0, import_react7.useEffect)(() => {
879
+ (0, import_react8.useEffect)(() => {
788
880
  onLoadStateChangeRef.current?.(ready && !failed);
789
881
  }, [ready, failed]);
790
882
  const normalizedEnv = (0, import_shared4.normalizeGatewayEnvironment)(environment);
791
- (0, import_react7.useEffect)(() => {
883
+ (0, import_react8.useEffect)(() => {
792
884
  const maskedClient = clientId ? `${clientId.slice(0, 6)}\u2026(len ${clientId.length})` : "(empty)";
793
885
  const ua = typeof navigator !== "undefined" ? navigator.userAgent : "(no navigator)";
794
886
  appendDebug(`mount clientId=${maskedClient} env=${environment ?? "(unset)"}\u2192${normalizedEnv ?? "live"} ccy=${currency} sub=${isSubscription}`);
@@ -1200,7 +1292,7 @@ function DirectPayPalButton({
1200
1292
  }
1201
1293
  };
1202
1294
  }, [baseUrl, clientId, currency, environment, isSubscription, sessionId, existingOrderId]);
1203
- const debugPanel = debug ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1295
+ const debugPanel = debug ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1204
1296
  "pre",
1205
1297
  {
1206
1298
  "data-testid": "flopay-direct-paypal-debug",
@@ -1225,17 +1317,17 @@ ${debugLines.join("\n")}`
1225
1317
  }
1226
1318
  ) : null;
1227
1319
  if (failed) {
1228
- return debug ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: debugPanel }) : null;
1320
+ return debug ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: debugPanel }) : null;
1229
1321
  }
1230
1322
  return (
1231
1323
  // Single wrapper so the parent flex container sees exactly one flex item
1232
1324
  // (otherwise the fragment's placeholder + container become two siblings
1233
1325
  // and any spacing-sensitive layout has to reason about both). The wrapper
1234
1326
  // intentionally has no margin/padding so the parent owns all spacing.
1235
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1327
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1236
1328
  debugPanel,
1237
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { position: "relative", minHeight: DEFAULT_BUTTON_HEIGHT }, children: [
1238
- !ready && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1329
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { position: "relative", minHeight: DEFAULT_BUTTON_HEIGHT }, children: [
1330
+ !ready && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1239
1331
  "div",
1240
1332
  {
1241
1333
  "data-testid": "flopay-direct-paypal-placeholder",
@@ -1249,7 +1341,7 @@ ${debugLines.join("\n")}`
1249
1341
  }
1250
1342
  }
1251
1343
  ),
1252
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1344
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1253
1345
  "div",
1254
1346
  {
1255
1347
  ref: containerRef,
@@ -1269,10 +1361,28 @@ ${debugLines.join("\n")}`
1269
1361
 
1270
1362
  // src/split-card-form.tsx
1271
1363
  var import_shared6 = require("@flopay/shared");
1272
- var import_jsx_runtime6 = require("react/jsx-runtime");
1364
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1273
1365
  var STRIPE_RESUME_KEY = "flopay_stripe_resume";
1274
1366
  var LEGACY_WALLET_RESUME_KEY = "flopay_wallet_resume";
1275
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
+ }
1276
1386
  var FLOPAY_KEYFRAMES = `
1277
1387
  .paypal-buttons { margin: 0 !important; vertical-align: top !important; }
1278
1388
  @keyframes flopay-spin { to { transform: rotate(360deg); } }
@@ -1297,18 +1407,20 @@ var FLOPAY_KEYFRAMES = `
1297
1407
  `;
1298
1408
  var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT = 44;
1299
1409
  function derivePrimaryTileStyle(opts) {
1300
- if (!opts.themeBundle) {
1410
+ if (!opts.themeBundle && !opts.explicitPrimaryColor) {
1301
1411
  return {
1302
1412
  backgroundColor: "white",
1303
1413
  color: "#262833",
1304
1414
  border: "1px solid #d1d5db",
1305
- borderRadius: "8px",
1415
+ borderRadius: opts.resolvedBorderRadius,
1306
1416
  boxShadow: "0 1px 2px rgba(0,0,0,0.04)"
1307
1417
  };
1308
1418
  }
1309
- const submit = opts.submitButtonStyle ?? {};
1419
+ const submit = opts.themeBundle ? opts.submitButtonStyle ?? {} : {};
1310
1420
  return {
1311
- backgroundColor: submit.backgroundColor ?? opts.resolvedPrimaryColor,
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,
1312
1424
  color: submit.color ?? "white",
1313
1425
  border: submit.border ?? "none",
1314
1426
  borderRadius: submit.borderRadius ?? opts.resolvedBorderRadius,
@@ -1342,7 +1454,7 @@ function normalizeBeforeButtonClickError(method, err) {
1342
1454
  );
1343
1455
  }
1344
1456
  function FloPayKeyframes() {
1345
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: FLOPAY_KEYFRAMES });
1457
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: FLOPAY_KEYFRAMES });
1346
1458
  }
1347
1459
  function toCssSize(value) {
1348
1460
  if (typeof value === "number") return `${value}px`;
@@ -1364,8 +1476,8 @@ function ExpressCheckoutReadySwap({
1364
1476
  children
1365
1477
  }) {
1366
1478
  if (state === "unavailable" || state === "load_error") return null;
1367
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { position: "relative", minHeight: 44 }, children: [
1368
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1479
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { position: "relative", minHeight: 44 }, children: [
1480
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1369
1481
  "div",
1370
1482
  {
1371
1483
  "data-testid": placeholderTestId,
@@ -1384,7 +1496,7 @@ function ExpressCheckoutReadySwap({
1384
1496
  }
1385
1497
  }
1386
1498
  ),
1387
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1499
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1388
1500
  "div",
1389
1501
  {
1390
1502
  style: {
@@ -1402,9 +1514,9 @@ function ExpressCheckoutReadySwap({
1402
1514
  function isExpressCheckoutRowVisible(state) {
1403
1515
  return state !== "unavailable" && state !== "load_error";
1404
1516
  }
1405
- var SplitCardForm = (0, import_react8.forwardRef)(
1517
+ var SplitCardForm = (0, import_react9.forwardRef)(
1406
1518
  function SplitCardForm2(props, ref) {
1407
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SplitCardFormInner, { ...props, innerRef: ref });
1519
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SplitCardFormInner, { ...props, innerRef: ref });
1408
1520
  }
1409
1521
  );
1410
1522
  function PayPalButtonInner({
@@ -1423,15 +1535,15 @@ function PayPalButtonInner({
1423
1535
  }) {
1424
1536
  const stripe = (0, import_react_stripe_js.useStripe)();
1425
1537
  const elements = (0, import_react_stripe_js.useElements)();
1426
- const [loadState, setLoadState] = (0, import_react8.useState)("loading");
1427
- (0, import_react8.useEffect)(() => {
1538
+ const [loadState, setLoadState] = (0, import_react9.useState)("loading");
1539
+ (0, import_react9.useEffect)(() => {
1428
1540
  onLoadStateChange?.(loadState);
1429
1541
  }, [loadState, onLoadStateChange]);
1430
- const [submitting, setSubmitting] = (0, import_react8.useState)(false);
1431
- const paypalResumeAttempted = (0, import_react8.useRef)(false);
1432
- const beforeClickRef = (0, import_react8.useRef)(null);
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);
1433
1545
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
1434
- (0, import_react8.useEffect)(() => {
1546
+ (0, import_react9.useEffect)(() => {
1435
1547
  if (!stripe || paypalResumeAttempted.current) return;
1436
1548
  const params = new URLSearchParams(window.location.search);
1437
1549
  const paymentIntentId = params.get("payment_intent");
@@ -1497,7 +1609,7 @@ function PayPalButtonInner({
1497
1609
  }
1498
1610
  })();
1499
1611
  }, [stripe, onTokenizedBody, onErrorChange, onDecline]);
1500
- const handlePayPalClick = (0, import_react8.useCallback)(async (event) => {
1612
+ const handlePayPalClick = (0, import_react9.useCallback)(async (event) => {
1501
1613
  if (isProcessing || submitting) {
1502
1614
  event.reject();
1503
1615
  return;
@@ -1516,7 +1628,7 @@ function PayPalButtonInner({
1516
1628
  onButtonClick?.("paypal");
1517
1629
  event.resolve();
1518
1630
  }, [isProcessing, onButtonClick, runBeforeButtonClick, submitting]);
1519
- const handlePayPalConfirm = (0, import_react8.useCallback)(async (event) => {
1631
+ const handlePayPalConfirm = (0, import_react9.useCallback)(async (event) => {
1520
1632
  if (!stripe || !elements) return;
1521
1633
  let prepared = beforeClickRef.current;
1522
1634
  beforeClickRef.current = null;
@@ -1636,14 +1748,14 @@ function PayPalButtonInner({
1636
1748
  setSubmitting(false);
1637
1749
  }
1638
1750
  }, [stripe, elements, sessionId, nonce, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]);
1639
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1640
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1751
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1752
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1641
1753
  ExpressCheckoutReadySwap,
1642
1754
  {
1643
1755
  state: loadState,
1644
1756
  placeholderTestId: "flopay-paypal-placeholder",
1645
1757
  borderRadius: placeholderBorderRadius,
1646
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1758
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1647
1759
  import_react_stripe_js.ExpressCheckoutElement,
1648
1760
  {
1649
1761
  onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
@@ -1670,7 +1782,7 @@ function PayPalButtonInner({
1670
1782
  )
1671
1783
  }
1672
1784
  ),
1673
- submitting && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingOverlay, { status: "processing" })
1785
+ submitting && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProcessingOverlay, { status: "processing" })
1674
1786
  ] });
1675
1787
  }
1676
1788
  function WalletButtonInner({
@@ -1689,15 +1801,15 @@ function WalletButtonInner({
1689
1801
  }) {
1690
1802
  const stripe = (0, import_react_stripe_js.useStripe)();
1691
1803
  const elements = (0, import_react_stripe_js.useElements)();
1692
- const [loadState, setLoadState] = (0, import_react8.useState)("loading");
1693
- (0, import_react8.useEffect)(() => {
1804
+ const [loadState, setLoadState] = (0, import_react9.useState)("loading");
1805
+ (0, import_react9.useEffect)(() => {
1694
1806
  onLoadStateChange?.(loadState);
1695
1807
  }, [loadState, onLoadStateChange]);
1696
- const [submitting, setSubmitting] = (0, import_react8.useState)(false);
1808
+ const [submitting, setSubmitting] = (0, import_react9.useState)(false);
1697
1809
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
1698
- const lastWalletMethodRef = (0, import_react8.useRef)("card");
1699
- const beforeClickRef = (0, import_react8.useRef)(null);
1700
- const handleWalletConfirm = (0, import_react8.useCallback)(
1810
+ const lastWalletMethodRef = (0, import_react9.useRef)("card");
1811
+ const beforeClickRef = (0, import_react9.useRef)(null);
1812
+ const handleWalletConfirm = (0, import_react9.useCallback)(
1701
1813
  async (event) => {
1702
1814
  if (!stripe || !elements) return;
1703
1815
  const walletType = event.expressPaymentType;
@@ -1761,10 +1873,7 @@ function WalletButtonInner({
1761
1873
  const intentJson = await intentResponse.json();
1762
1874
  const intentClientSecret = intentJson.data?.id;
1763
1875
  if (!intentClientSecret) throw new Error("No client_secret in payment intent response");
1764
- const { error: confirmError, paymentIntent } = await stripe.confirmCardPayment(
1765
- intentClientSecret,
1766
- { payment_method: paymentMethod.id }
1767
- );
1876
+ const { error: confirmError, intentId } = (0, import_shared6.isSetupIntentClientSecret)(intentClientSecret) ? await stripe.confirmCardSetup(intentClientSecret, { payment_method: paymentMethod.id }).then((r) => ({ error: r.error, intentId: r.setupIntent?.id })) : await stripe.confirmCardPayment(intentClientSecret, { payment_method: paymentMethod.id }).then((r) => ({ error: r.error, intentId: r.paymentIntent?.id }));
1768
1877
  if (confirmError) {
1769
1878
  const message = confirmError.message ?? "Wallet payment failed.";
1770
1879
  onErrorChange?.(message);
@@ -1776,7 +1885,7 @@ function WalletButtonInner({
1776
1885
  onTokenizedBody({
1777
1886
  id: paymentMethod.id,
1778
1887
  type: "card",
1779
- threeDSecureActionResultTokenId: paymentIntent?.id
1888
+ threeDSecureActionResultTokenId: intentId
1780
1889
  }, {
1781
1890
  accountPatch: prepared?.accountPatch,
1782
1891
  sessionId: effectiveSessionId,
@@ -1790,7 +1899,7 @@ function WalletButtonInner({
1790
1899
  },
1791
1900
  [stripe, elements, sessionId, nonce, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]
1792
1901
  );
1793
- const expressMethodMap = (0, import_react8.useMemo)(() => {
1902
+ const expressMethodMap = (0, import_react9.useMemo)(() => {
1794
1903
  const allKeys = ["applePay", "googlePay", "paypal", "link", "amazonPay", "klarna"];
1795
1904
  const alwaysCapable = /* @__PURE__ */ new Set(["applePay", "googlePay"]);
1796
1905
  const enabledKeys = new Set(expressMethods.map(import_shared5.stripeExpressMethodToOptionKey));
@@ -1804,18 +1913,18 @@ function WalletButtonInner({
1804
1913
  }
1805
1914
  return out;
1806
1915
  }, [expressMethods]);
1807
- const availableMethodKeys = (0, import_react8.useMemo)(
1916
+ const availableMethodKeys = (0, import_react9.useMemo)(
1808
1917
  () => expressMethods.map(import_shared5.stripeExpressMethodToOptionKey),
1809
1918
  [expressMethods]
1810
1919
  );
1811
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1812
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1920
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1921
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1813
1922
  ExpressCheckoutReadySwap,
1814
1923
  {
1815
1924
  state: loadState,
1816
1925
  placeholderTestId: "flopay-wallet-placeholder",
1817
1926
  borderRadius: placeholderBorderRadius,
1818
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1927
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1819
1928
  import_react_stripe_js.ExpressCheckoutElement,
1820
1929
  {
1821
1930
  onReady: (event) => {
@@ -1854,7 +1963,7 @@ function WalletButtonInner({
1854
1963
  )
1855
1964
  }
1856
1965
  ),
1857
- submitting && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingOverlay, { status: "processing" })
1966
+ submitting && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProcessingOverlay, { status: "processing" })
1858
1967
  ] });
1859
1968
  }
1860
1969
  function StripeMethodButton({
@@ -1875,7 +1984,7 @@ function StripeMethodButton({
1875
1984
  const resolvedBackground = brand?.backgroundColor ?? backgroundColor ?? "#ffffff";
1876
1985
  const resolvedBorder = brand?.borderColor ?? borderColor ?? "#d1d5db";
1877
1986
  const resolvedTextColor = brand?.textColor ?? textColor ?? "#262833";
1878
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1987
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1879
1988
  "button",
1880
1989
  {
1881
1990
  type: "button",
@@ -1922,9 +2031,9 @@ function StripeMethodButton({
1922
2031
  // Pulse-skeleton parity with the wallet ECE: no spinner, just the
1923
2032
  // status text on top of the pulsing background. Keeps the loading
1924
2033
  // affordance shape-equivalent across both kinds of tile.
1925
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { margin: "0 auto" }, children: `Connecting to ${(0, import_shared5.getStripeMethodDisplayName)(method)}\u2026` })
1926
- ) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1927
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
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)(
1928
2037
  "span",
1929
2038
  {
1930
2039
  style: {
@@ -1937,7 +2046,7 @@ function StripeMethodButton({
1937
2046
  gap: (0, import_shared5.hasVendoredStripeMethodLogo)(method) ? 8 : 0
1938
2047
  },
1939
2048
  children: [
1940
- brand?.logoSvg && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2049
+ brand?.logoSvg && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1941
2050
  "span",
1942
2051
  {
1943
2052
  "aria-hidden": "true",
@@ -1956,11 +2065,11 @@ function StripeMethodButton({
1956
2065
  dangerouslySetInnerHTML: { __html: brand.logoSvg }
1957
2066
  }
1958
2067
  ),
1959
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: (0, import_shared5.getStripeMethodDisplayName)(method) })
2068
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: (0, import_shared5.getStripeMethodDisplayName)(method) })
1960
2069
  ]
1961
2070
  }
1962
2071
  ),
1963
- hasNextStep && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2072
+ hasNextStep && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1964
2073
  "svg",
1965
2074
  {
1966
2075
  width: "14",
@@ -1980,7 +2089,7 @@ function StripeMethodButton({
1980
2089
  opacity: 0.7
1981
2090
  },
1982
2091
  "aria-hidden": "true",
1983
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M9 18l6-6-6-6" })
2092
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M9 18l6-6-6-6" })
1984
2093
  }
1985
2094
  )
1986
2095
  ] })
@@ -2003,16 +2112,17 @@ function StripeMethodInlineForm({
2003
2112
  isProcessing,
2004
2113
  submitButtonColor,
2005
2114
  submitButtonBorderRadius,
2006
- submitButtonStyle
2115
+ submitButtonStyle,
2116
+ errorText
2007
2117
  }) {
2008
2118
  const stripe = (0, import_react_stripe_js.useStripe)();
2009
2119
  const elements = (0, import_react_stripe_js.useElements)();
2010
- const [submitting, setSubmitting] = (0, import_react8.useState)(false);
2011
- const submittingRef = (0, import_react8.useRef)(false);
2012
- const [isMethodComplete, setIsMethodComplete] = (0, import_react8.useState)(false);
2013
- const [loadState, setLoadState] = (0, import_react8.useState)("loading");
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");
2014
2124
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
2015
- const handlePay = (0, import_react8.useCallback)(async () => {
2125
+ const handlePay = (0, import_react9.useCallback)(async () => {
2016
2126
  if (!stripe || !elements || isProcessing || submittingRef.current || !isMethodComplete) return;
2017
2127
  submittingRef.current = true;
2018
2128
  setSubmitting(true);
@@ -2152,8 +2262,8 @@ function StripeMethodInlineForm({
2152
2262
  onDecline
2153
2263
  ]);
2154
2264
  void onCancel;
2155
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-testid": `flopay-stripe-method-form-${method}`, style: { display: "flex", flexDirection: "column" }, children: [
2156
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
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)(
2157
2267
  import_react_stripe_js.PaymentElement,
2158
2268
  {
2159
2269
  onReady: () => setLoadState("ready"),
@@ -2173,7 +2283,7 @@ function StripeMethodInlineForm({
2173
2283
  }
2174
2284
  }
2175
2285
  ),
2176
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2286
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2177
2287
  "button",
2178
2288
  {
2179
2289
  type: "button",
@@ -2199,7 +2309,23 @@ function StripeMethodInlineForm({
2199
2309
  },
2200
2310
  children: submitting ? "Processing\u2026" : `Pay with ${(0, import_shared5.getStripeMethodDisplayName)(method)}`
2201
2311
  }
2202
- )
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
+ ] })
2203
2329
  ] });
2204
2330
  }
2205
2331
  function StripePaymentElementInner({
@@ -2227,17 +2353,17 @@ function StripePaymentElementInner({
2227
2353
  expandedApmMethod
2228
2354
  }) {
2229
2355
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
2230
- const [expandedMethod, setExpandedMethod] = (0, import_react8.useState)(null);
2231
- const [submittingMethod, setSubmittingMethod] = (0, import_react8.useState)(null);
2232
- const submittingRef = (0, import_react8.useRef)(false);
2233
- (0, import_react8.useEffect)(() => {
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)(() => {
2234
2360
  if (paymentElementMethods.length > 0 && stripeInstance) {
2235
2361
  onLoadStateChange?.("ready");
2236
2362
  } else if (!stripeInstance) {
2237
2363
  onLoadStateChange?.("loading");
2238
2364
  }
2239
2365
  }, [paymentElementMethods.length, stripeInstance, onLoadStateChange]);
2240
- const handleAutoConfirm = (0, import_react8.useCallback)(async (method) => {
2366
+ const handleAutoConfirm = (0, import_react9.useCallback)(async (method) => {
2241
2367
  if (!stripeInstance) return;
2242
2368
  if (submittingRef.current || isProcessing) return;
2243
2369
  submittingRef.current = true;
@@ -2376,9 +2502,9 @@ function StripePaymentElementInner({
2376
2502
  onErrorChange,
2377
2503
  onDecline
2378
2504
  ]);
2379
- const [localExpandedMethod, setLocalExpandedMethod] = (0, import_react8.useState)(null);
2505
+ const [localExpandedMethod, setLocalExpandedMethod] = (0, import_react9.useState)(null);
2380
2506
  const activeExpandedMethod = onExpandApm ? expandedApmMethod ?? null : localExpandedMethod;
2381
- const handleMethodClick = (0, import_react8.useCallback)((method) => {
2507
+ const handleMethodClick = (0, import_react9.useCallback)((method) => {
2382
2508
  if (submittingRef.current || isProcessing) return;
2383
2509
  if (activeExpandedMethod && activeExpandedMethod !== method) return;
2384
2510
  if ((0, import_shared5.needsStripeMethodExplicitConfirm)(method)) {
@@ -2391,14 +2517,14 @@ function StripePaymentElementInner({
2391
2517
  void handleAutoConfirm(method);
2392
2518
  }
2393
2519
  }, [activeExpandedMethod, isProcessing, handleAutoConfirm, onExpandApm]);
2394
- const localInlineElementsOptions = (0, import_react8.useMemo)(() => {
2520
+ const localInlineElementsOptions = (0, import_react9.useMemo)(() => {
2395
2521
  if (!localExpandedMethod) return null;
2396
2522
  return {
2397
2523
  ...paymentElementBaseOptions,
2398
2524
  paymentMethodTypes: [localExpandedMethod]
2399
2525
  };
2400
2526
  }, [localExpandedMethod, paymentElementBaseOptions]);
2401
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2527
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2402
2528
  "div",
2403
2529
  {
2404
2530
  "data-testid": "flopay-stripe-payment-element-region",
@@ -2407,8 +2533,8 @@ function StripePaymentElementInner({
2407
2533
  const isExpanded = expandedApmMethod === method;
2408
2534
  const isSubmittingThis = submittingMethod === method;
2409
2535
  const otherInProgress = submittingMethod !== null && submittingMethod !== method || expandedApmMethod !== null && expandedApmMethod !== void 0 && expandedApmMethod !== method;
2410
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react8.default.Fragment, { children: [
2411
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2536
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react9.default.Fragment, { children: [
2537
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2412
2538
  StripeMethodButton,
2413
2539
  {
2414
2540
  method,
@@ -2425,12 +2551,12 @@ function StripePaymentElementInner({
2425
2551
  fontFamily: buttonAppearance?.fontFamily
2426
2552
  }
2427
2553
  ),
2428
- !onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2554
+ !onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2429
2555
  import_react_stripe_js.Elements,
2430
2556
  {
2431
2557
  stripe: stripeInstance,
2432
2558
  options: localInlineElementsOptions,
2433
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2559
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2434
2560
  StripeMethodInlineForm,
2435
2561
  {
2436
2562
  method,
@@ -2483,6 +2609,7 @@ function SplitCardFormInner({
2483
2609
  showPayPal = true,
2484
2610
  showStripe = true,
2485
2611
  enabledPaymentMethods,
2612
+ enabledPaymentMethodCountries,
2486
2613
  showApplePay = true,
2487
2614
  showGooglePay = true,
2488
2615
  layout = "default",
@@ -2497,6 +2624,8 @@ function SplitCardFormInner({
2497
2624
  onButtonClick,
2498
2625
  onBeforeButtonClick,
2499
2626
  enableAVS: enableAVSProp,
2627
+ cardFieldOrder,
2628
+ cardPreFormSlot,
2500
2629
  avsLayout: avsLayoutProp = "row",
2501
2630
  country: countryProp,
2502
2631
  zip: zipProp,
@@ -2521,68 +2650,95 @@ function SplitCardFormInner({
2521
2650
  const flopay = useFloPay();
2522
2651
  const paypalFlopay = usePayPalFloPay();
2523
2652
  const elements = useElements();
2524
- const checkout = (0, import_react8.useContext)(CheckoutContext);
2653
+ const checkout = (0, import_react9.useContext)(CheckoutContext);
2525
2654
  const contextBillingUrl = useBillingApiUrl();
2526
- const [processing, setProcessing] = (0, import_react8.useState)(false);
2527
- const [error, setError] = (0, import_react8.useState)(null);
2528
- const [is3DSActive, setIs3DSActive] = (0, import_react8.useState)(false);
2529
- const [selectedCountry, setSelectedCountry] = (0, import_react8.useState)(countryProp ?? "US");
2530
- const [zipCode, setZipCode] = (0, import_react8.useState)(zipProp ?? "");
2531
- const [addressLine1, setAddressLine1] = (0, import_react8.useState)(addressLine1Prop ?? "");
2532
- const [addressLine2, setAddressLine2] = (0, import_react8.useState)(addressLine2Prop ?? "");
2533
- const [city, setCity] = (0, import_react8.useState)(cityProp ?? "");
2534
- const [stateValue, setStateValue] = (0, import_react8.useState)(stateProp ?? "");
2535
- const [accountPatch, setAccountPatch] = (0, import_react8.useState)({});
2536
- const zipCodeRef = (0, import_react8.useRef)(zipProp ?? "");
2537
- const selectedCountryRef = (0, import_react8.useRef)(countryProp ?? "US");
2538
- const addressLine1Ref = (0, import_react8.useRef)(addressLine1Prop ?? "");
2539
- const addressLine2Ref = (0, import_react8.useRef)(addressLine2Prop ?? "");
2540
- const cityRef = (0, import_react8.useRef)(cityProp ?? "");
2541
- const stateRef = (0, import_react8.useRef)(stateProp ?? "");
2542
- const avsConfig = (0, import_react8.useMemo)(() => (0, import_shared5.resolveAVSConfig)(enableAVSProp), [enableAVSProp]);
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]);
2543
2672
  const enableAVS = avsConfig !== null;
2544
- const [viewState, setViewState] = (0, import_react8.useState)(initialCardOpen ? "card" : "buttons");
2545
- const [expandedApmMethod, setExpandedApmMethod] = (0, import_react8.useState)(null);
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);
2546
2702
  const showCardForm = viewState === "expanding" || viewState === "card";
2547
2703
  const TRANSITION_MS = 280;
2548
- const expandToCard = (0, import_react8.useCallback)(() => {
2704
+ const expandToCard = (0, import_react9.useCallback)(() => {
2549
2705
  setViewState("expanding");
2550
2706
  setTimeout(() => setViewState("card"), TRANSITION_MS);
2551
2707
  }, []);
2552
- const collapseToButtons = (0, import_react8.useCallback)(() => {
2708
+ const collapseToButtons = (0, import_react9.useCallback)(() => {
2553
2709
  setViewState("collapsing");
2554
2710
  setTimeout(() => setViewState("buttons"), TRANSITION_MS);
2555
2711
  }, []);
2556
- const expandToApm = (0, import_react8.useCallback)((method) => {
2712
+ const expandToApm = (0, import_react9.useCallback)((method) => {
2557
2713
  setExpandedApmMethod(method);
2558
2714
  setViewState("apm-expanding");
2559
2715
  setTimeout(() => setViewState("apm-form"), TRANSITION_MS);
2560
2716
  }, []);
2561
- const collapseFromApm = (0, import_react8.useCallback)(() => {
2717
+ const collapseFromApm = (0, import_react9.useCallback)(() => {
2562
2718
  setViewState("apm-collapsing");
2563
2719
  setTimeout(() => {
2564
2720
  setViewState("buttons");
2565
2721
  setExpandedApmMethod(null);
2566
2722
  }, TRANSITION_MS);
2567
2723
  }, []);
2568
- (0, import_react8.useEffect)(() => {
2724
+ (0, import_react9.useEffect)(() => {
2569
2725
  if (layout === "buttons" && initialCardOpen) {
2570
2726
  setViewState("card");
2571
2727
  }
2572
2728
  }, [layout, initialCardOpen]);
2573
- const [fullName, setFullName] = (0, import_react8.useState)("");
2574
- const [formReady, setFormReady] = (0, import_react8.useState)(false);
2575
- const [overlayStatus, setOverlayStatus] = (0, import_react8.useState)(null);
2576
- const processingRef = (0, import_react8.useRef)(false);
2577
- const [paypalDirectRetry, setPaypalDirectRetry] = (0, import_react8.useState)(null);
2578
- const paypalDirectRetryRef = (0, import_react8.useRef)(paypalDirectRetry);
2579
- (0, import_react8.useEffect)(() => {
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)(() => {
2580
2736
  paypalDirectRetryRef.current = paypalDirectRetry;
2581
2737
  }, [paypalDirectRetry]);
2582
2738
  const resolvedBillingApiUrl = billingApiUrl || contextBillingUrl;
2583
2739
  const displayError = externalError ?? error;
2584
- const themeBundle = (0, import_react8.useMemo)(() => (0, import_shared6.resolveTheme)(theme), [theme]);
2585
- const bStyles = (0, import_react8.useMemo)(() => {
2740
+ const themeBundle = (0, import_react9.useMemo)(() => (0, import_shared6.resolveTheme)(theme), [theme]);
2741
+ const bStyles = (0, import_react9.useMemo)(() => {
2586
2742
  const base = themeBundle?.buttonsLayout ?? (0, import_shared5.resolveButtonsLayoutTheme)(buttonsTheme);
2587
2743
  if (!buttonsStylesOverride) return base;
2588
2744
  return {
@@ -2597,11 +2753,36 @@ function SplitCardFormInner({
2597
2753
  };
2598
2754
  }, [themeBundle, buttonsTheme, buttonsStylesOverride]);
2599
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]);
2600
2781
  const isInlineSessionPatchProcessing = checkout.inlineSessionPatchProcessing ?? false;
2601
2782
  const isSubmitting = (externalProcessing ?? processing) || isInlineSessionPatchProcessing;
2602
2783
  const isSelfContained = !onTokenizedBody;
2603
2784
  const baseUrl = resolvedBillingApiUrl.replace(/\/+$/, "");
2604
- const resolvedAccount = (0, import_react8.useMemo)(() => mergeAccountPatch({
2785
+ const resolvedAccount = (0, import_react9.useMemo)(() => mergeAccountPatch({
2605
2786
  userId,
2606
2787
  email,
2607
2788
  firstName,
@@ -2609,17 +2790,17 @@ function SplitCardFormInner({
2609
2790
  country: countryProp,
2610
2791
  zip: zipProp
2611
2792
  }, accountPatch), [userId, email, firstName, lastName, countryProp, zipProp, accountPatch]);
2612
- const stripeInstance = (0, import_react8.useMemo)(() => {
2793
+ const stripeInstance = (0, import_react9.useMemo)(() => {
2613
2794
  if (!flopay) return null;
2614
2795
  return flopay.getRawProvider();
2615
2796
  }, [flopay]);
2616
- const paypalStripeInstance = (0, import_react8.useMemo)(() => {
2797
+ const paypalStripeInstance = (0, import_react9.useMemo)(() => {
2617
2798
  if (!paypalFlopay) return null;
2618
2799
  return paypalFlopay.getRawProvider();
2619
2800
  }, [paypalFlopay]);
2620
2801
  const amountInCents = totalAmount || 100;
2621
2802
  const stripeAppearanceProp = appearance ? { appearance } : null;
2622
- const paymentElementAppearance = (0, import_react8.useMemo)(() => {
2803
+ const paymentElementAppearance = (0, import_react9.useMemo)(() => {
2623
2804
  const base = appearance ?? {};
2624
2805
  const baseRules = base.rules ?? {};
2625
2806
  return {
@@ -2639,15 +2820,18 @@ function SplitCardFormInner({
2639
2820
  }
2640
2821
  };
2641
2822
  }, [appearance]);
2642
- const walletOptions = (0, import_react8.useMemo)(() => ({
2643
- mode: "payment",
2644
- amount: amountInCents,
2645
- currency: currency.toLowerCase(),
2646
- paymentMethodCreation: "manual",
2647
- captureMethod: "manual",
2648
- ...stripeAppearanceProp
2649
- }), [amountInCents, currency, stripeAppearanceProp]);
2650
- const paypalOptions = (0, import_react8.useMemo)(() => ({
2823
+ const walletOptions = (0, import_react9.useMemo)(() => {
2824
+ const modeOptions = resolveWalletElementsMode(totalAmount);
2825
+ return {
2826
+ ...modeOptions,
2827
+ currency: currency.toLowerCase(),
2828
+ paymentMethodCreation: "manual",
2829
+ // captureMethod only applies to payment mode; Stripe rejects it in setup.
2830
+ ...modeOptions.mode === "payment" ? { captureMethod: "manual" } : {},
2831
+ ...stripeAppearanceProp
2832
+ };
2833
+ }, [totalAmount, currency, stripeAppearanceProp]);
2834
+ const paypalOptions = (0, import_react9.useMemo)(() => ({
2651
2835
  mode: "payment",
2652
2836
  amount: amountInCents,
2653
2837
  currency: currency.toLowerCase(),
@@ -2655,35 +2839,183 @@ function SplitCardFormInner({
2655
2839
  setupFutureUsage: "off_session",
2656
2840
  ...stripeAppearanceProp
2657
2841
  }), [amountInCents, currency, stripeAppearanceProp]);
2658
- const updateError = (0, import_react8.useCallback)(
2842
+ const updateError = (0, import_react9.useCallback)(
2659
2843
  (err) => {
2660
2844
  setError(err);
2661
2845
  onErrorChange?.(err);
2662
2846
  },
2663
2847
  [onErrorChange]
2664
2848
  );
2665
- const emitDecline = (0, import_react8.useCallback)(
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)(
2666
2863
  (method, input, overrides) => {
2667
2864
  onDecline?.(buildDeclineEvent(method, input, overrides));
2668
2865
  },
2669
2866
  [onDecline]
2670
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
+ ]);
2671
3003
  const directPaypalConfigured = !!directPaypal?.clientId;
2672
3004
  const hasEnabledMethodsPayload = Array.isArray(enabledPaymentMethods);
2673
3005
  const hasEnabledMethods = hasEnabledMethodsPayload && enabledPaymentMethods.length > 0;
2674
3006
  const paypalEnabled = hasEnabledMethodsPayload && enabledPaymentMethods.includes("paypal");
2675
- const { expressMethods, paymentElementMethods } = (0, import_react8.useMemo)(
3007
+ const { expressMethods, paymentElementMethods } = (0, import_react9.useMemo)(
2676
3008
  () => (0, import_shared5.partitionStripeMethods)(enabledPaymentMethods, {
2677
3009
  excludePaypal: directPaypalConfigured
2678
3010
  }),
2679
3011
  [enabledPaymentMethods, directPaypalConfigured]
2680
3012
  );
2681
3013
  const paypalRenderedSeparately = directPaypalConfigured || !!paypalFlopay;
2682
- const expressMethodsForWalletRow = (0, import_react8.useMemo)(
3014
+ const expressMethodsForWalletRow = (0, import_react9.useMemo)(
2683
3015
  () => paypalRenderedSeparately ? expressMethods.filter((m) => m !== "paypal") : expressMethods,
2684
3016
  [expressMethods, paypalRenderedSeparately]
2685
3017
  );
2686
- const legacyExpressMethods = (0, import_react8.useMemo)(() => {
3018
+ const legacyExpressMethods = (0, import_react9.useMemo)(() => {
2687
3019
  const out = [];
2688
3020
  if (showApplePay) out.push("apple_pay");
2689
3021
  if (showGooglePay) out.push("google_pay");
@@ -2691,30 +3023,31 @@ function SplitCardFormInner({
2691
3023
  }, [showApplePay, showGooglePay]);
2692
3024
  const walletExpressMethods = hasEnabledMethodsPayload ? expressMethodsForWalletRow : legacyExpressMethods;
2693
3025
  const showWallets = showStripe && walletExpressMethods.length > 0;
2694
- const paymentElementMethodsForCurrency = (0, import_react8.useMemo)(
2695
- () => (0, import_shared5.filterStripeMethodsByAmount)(
2696
- (0, import_shared5.filterStripeMethodsByCountry)(
2697
- (0, import_shared5.filterStripeMethodsByCurrency)(paymentElementMethods, currency),
2698
- countryProp
2699
- ),
2700
- currency,
2701
- amountInCents
2702
- ),
2703
- [paymentElementMethods, currency, countryProp, amountInCents]
2704
- );
2705
- const paymentElementBaseOptions = (0, import_react8.useMemo)(() => ({
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)(() => ({
2706
3039
  mode: "payment",
2707
3040
  amount: amountInCents,
2708
3041
  currency: currency.toLowerCase(),
2709
3042
  paymentMethodCreation: "manual",
2710
3043
  appearance: paymentElementAppearance
2711
3044
  }), [amountInCents, currency, paymentElementAppearance]);
2712
- const [paypalLoadState, setPaypalLoadState] = (0, import_react8.useState)("loading");
2713
- const [walletLoadState, setWalletLoadState] = (0, import_react8.useState)("loading");
2714
- const [paymentElementLoadState, setPaymentElementLoadState] = (0, import_react8.useState)("loading");
2715
- const [directPaypalReady, setDirectPaypalReady] = (0, import_react8.useState)(false);
2716
- const [inAppBrowserDetected, setInAppBrowserDetected] = (0, import_react8.useState)();
2717
- (0, import_react8.useEffect)(() => {
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)(() => {
2718
3051
  setInAppBrowserDetected(isInAppBrowser());
2719
3052
  }, []);
2720
3053
  const shouldShowPayPal = showPayPal && (directPaypalConfigured || (hasEnabledMethodsPayload ? paypalEnabled : inAppBrowserDetected === false));
@@ -2726,8 +3059,8 @@ function SplitCardFormInner({
2726
3059
  const shouldDisplayPayPalRow = shouldRenderDirectPayPal ? directPaypalReady : shouldRenderStripePayPal && isExpressCheckoutRowVisible(paypalLoadState);
2727
3060
  const shouldDisplayWalletRow = shouldRenderWallets && isExpressCheckoutRowVisible(walletLoadState);
2728
3061
  const shouldDisplayPaymentElementRow = shouldRenderPaymentElement && paymentElementLoadState !== "load_error";
2729
- const validationFiredRef = (0, import_react8.useRef)(false);
2730
- (0, import_react8.useEffect)(() => {
3062
+ const validationFiredRef = (0, import_react9.useRef)(false);
3063
+ (0, import_react9.useEffect)(() => {
2731
3064
  if (validationFiredRef.current) return;
2732
3065
  if (!showStripe && !showPayPal) {
2733
3066
  validationFiredRef.current = true;
@@ -2747,8 +3080,8 @@ function SplitCardFormInner({
2747
3080
  updateError(err.message);
2748
3081
  }
2749
3082
  }, [showStripe, showPayPal, directPaypalConfigured, paypalStripeInstance, onError, updateError]);
2750
- const deprecationLoggedRef = (0, import_react8.useRef)(false);
2751
- (0, import_react8.useEffect)(() => {
3083
+ const deprecationLoggedRef = (0, import_react9.useRef)(false);
3084
+ (0, import_react9.useEffect)(() => {
2752
3085
  if (deprecationLoggedRef.current) return;
2753
3086
  if (!hasEnabledMethods) return;
2754
3087
  const stale = [];
@@ -2760,14 +3093,14 @@ function SplitCardFormInner({
2760
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.`
2761
3094
  );
2762
3095
  }, [hasEnabledMethods, showApplePay, showGooglePay]);
2763
- const handleNameChange = (0, import_react8.useCallback)((value) => {
3096
+ const handleNameChange = (0, import_react9.useCallback)((value) => {
2764
3097
  setFullName(value);
2765
3098
  onFullNameChange?.(value);
2766
3099
  const parts = value.trim().split(/\s+/);
2767
3100
  onFirstNameChange?.(parts[0] ?? "");
2768
3101
  onLastNameChange?.(parts.length > 1 ? parts.slice(1).join(" ") : "");
2769
3102
  }, [onFullNameChange, onFirstNameChange, onLastNameChange]);
2770
- const applyInlineSessionPatch = (0, import_react8.useCallback)(
3103
+ const applyInlineSessionPatch = (0, import_react9.useCallback)(
2771
3104
  (patch, method) => {
2772
3105
  if (!checkout.applyInlineSessionPatch) {
2773
3106
  return Promise.resolve({ error: null, sessionId, nonce });
@@ -2789,7 +3122,7 @@ function SplitCardFormInner({
2789
3122
  },
2790
3123
  [checkout.applyInlineSessionPatch, nonce, onError, sessionId, updateError]
2791
3124
  );
2792
- const runBeforeButtonClick = (0, import_react8.useCallback)(async (method) => {
3125
+ const runBeforeButtonClick = (0, import_react9.useCallback)(async (method) => {
2793
3126
  if (!onBeforeButtonClick) return { proceed: true };
2794
3127
  try {
2795
3128
  const result = await onBeforeButtonClick({
@@ -2826,7 +3159,7 @@ function SplitCardFormInner({
2826
3159
  return { proceed: false };
2827
3160
  }
2828
3161
  }, [applyInlineSessionPatch, checkout.inlineSessionDraft, onBeforeButtonClick, onError, sessionId, updateError]);
2829
- const processPaymentInternal = (0, import_react8.useCallback)(
3162
+ const processPaymentInternal = (0, import_react9.useCallback)(
2830
3163
  async (tokenizedBody, overrides) => {
2831
3164
  if (processingRef.current) return;
2832
3165
  processingRef.current = true;
@@ -3037,7 +3370,7 @@ function SplitCardFormInner({
3037
3370
  },
3038
3371
  [baseUrl, sessionId, nonce, resolvedAccount, fullName, chv, flopay, paypalFlopay, onComplete, onError, updateError, emitDecline]
3039
3372
  );
3040
- const dispatchTokenizedBody = (0, import_react8.useCallback)(
3373
+ const dispatchTokenizedBody = (0, import_react9.useCallback)(
3041
3374
  (tokenizedBody, overrides) => {
3042
3375
  if (onTokenizedBody) {
3043
3376
  onTokenizedBody(tokenizedBody);
@@ -3047,7 +3380,7 @@ function SplitCardFormInner({
3047
3380
  },
3048
3381
  [onTokenizedBody, processPaymentInternal]
3049
3382
  );
3050
- (0, import_react8.useImperativeHandle)(innerRef, () => ({
3383
+ (0, import_react9.useImperativeHandle)(innerRef, () => ({
3051
3384
  async handleNextAction(secret) {
3052
3385
  if (!flopay) return;
3053
3386
  setIs3DSActive(true);
@@ -3074,8 +3407,8 @@ function SplitCardFormInner({
3074
3407
  }
3075
3408
  }
3076
3409
  }), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
3077
- const stripeResumeAttemptedRef = (0, import_react8.useRef)(false);
3078
- (0, import_react8.useEffect)(() => {
3410
+ const stripeResumeAttemptedRef = (0, import_react9.useRef)(false);
3411
+ (0, import_react9.useEffect)(() => {
3079
3412
  if (typeof window === "undefined" || stripeResumeAttemptedRef.current) return;
3080
3413
  const params = new URLSearchParams(window.location.search);
3081
3414
  const paymentIntentId = params.get("payment_intent");
@@ -3153,10 +3486,11 @@ function SplitCardFormInner({
3153
3486
  }, persistedOverrides);
3154
3487
  })();
3155
3488
  }, [sessionId, dispatchTokenizedBody, flopay, updateError, emitDecline]);
3156
- const handleSubmit = (0, import_react8.useCallback)(
3489
+ const handleSubmit = (0, import_react9.useCallback)(
3157
3490
  async (e) => {
3158
3491
  e.preventDefault();
3159
3492
  if (!flopay || !elements || isSubmitting || processingRef.current) return;
3493
+ if (vaultActive) return;
3160
3494
  if (layout !== "buttons") {
3161
3495
  onButtonClick?.("card");
3162
3496
  }
@@ -3184,11 +3518,13 @@ function SplitCardFormInner({
3184
3518
  return;
3185
3519
  }
3186
3520
  }
3187
- const submitResult = await flopay.submitElements();
3188
- if (submitResult.error) {
3189
- updateError(submitResult.error.message);
3190
- onError?.(submitResult.error);
3191
- return;
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
+ }
3192
3528
  }
3193
3529
  const billingAddress = {};
3194
3530
  const cc = selectedCountryRef.current;
@@ -3213,75 +3549,77 @@ function SplitCardFormInner({
3213
3549
  ...fullName.trim() ? { name: fullName.trim() } : {},
3214
3550
  ...Object.keys(billingAddress).length > 0 ? { address: billingAddress } : {}
3215
3551
  };
3216
- const pmResult = await flopay.createPaymentMethod(billingDetails);
3217
- if (pmResult.error || !pmResult.paymentMethodId) {
3218
- updateError(pmResult.error?.message ?? "Failed to create payment method.");
3219
- return;
3220
- }
3221
3552
  if (!sessionId || !resolvedAccount.email) {
3222
3553
  throw new import_shared6.FloPayError("Missing sessionId or email", "validation_error");
3223
3554
  }
3224
- const intentHeaders = { "Content-Type": "application/json" };
3225
- if (nonce) intentHeaders["x-checkout-session-token"] = nonce;
3226
- const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
3227
- method: "POST",
3228
- headers: intentHeaders,
3229
- body: JSON.stringify({
3230
- sessionId,
3231
- email: resolvedAccount.email,
3232
- paymentMethodType: pmResult.paymentMethodId,
3233
- isPaypal: false
3234
- })
3235
- });
3236
- if (!intentResponse.ok) {
3237
- const intentError = await buildFloPayApiErrorFromResponse(
3238
- intentResponse,
3239
- "Failed to create payment intent"
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
3240
3604
  );
3241
- setOverlayStatus("error");
3242
- updateError(intentError.message);
3243
- onError?.(intentError);
3244
- emitDecline("card", intentError);
3245
- await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
3246
- return;
3247
- }
3248
- const intentJson = await intentResponse.json();
3249
- const intentClientSecret = intentJson.data?.id;
3250
- if (!intentClientSecret) throw new import_shared6.FloPayError("No client_secret in payment intent response", "api_error");
3251
- const confirmResult = await flopay.confirmCardPayment({
3252
- clientSecret: intentClientSecret,
3253
- paymentMethodId: pmResult.paymentMethodId
3254
- });
3255
- if (confirmResult.error) {
3256
- setOverlayStatus("error");
3257
- updateError(confirmResult.error.message);
3258
- onError?.(confirmResult.error);
3259
- emitDecline("card", confirmResult.error);
3260
- await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
3261
- return;
3262
- }
3263
- const rawProvider = typeof flopay.getRawProvider === "function" ? flopay.getRawProvider() : null;
3264
- const confirmedPaymentIntent = await retrievePaymentIntentFromProvider(
3265
- rawProvider,
3266
- intentClientSecret
3267
- );
3268
- const paymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
3269
- const paymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? pmResult.paymentMethodId;
3270
- if (!paymentIntentId) {
3271
- const error2 = new import_shared6.FloPayError("No payment intent returned after confirmation.", "api_error");
3272
- setOverlayStatus("error");
3273
- updateError(error2.message);
3274
- onError?.(error2);
3275
- await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_ERROR_DELAY_MS));
3276
- 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
+ });
3277
3622
  }
3278
- handedOff = isSelfContained;
3279
- dispatchTokenizedBody({
3280
- id: paymentMethodId,
3281
- type: "card",
3282
- threeDSecureActionResultTokenId: paymentIntentId,
3283
- originalPaymentMethodId: pmResult.paymentMethodId
3284
- });
3285
3623
  } catch (err) {
3286
3624
  setOverlayStatus("error");
3287
3625
  updateError(err instanceof Error ? err.message : "An unexpected error occurred");
@@ -3293,11 +3631,11 @@ function SplitCardFormInner({
3293
3631
  }
3294
3632
  }
3295
3633
  },
3296
- [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]
3297
3635
  );
3298
- const isReady = flopay !== null && elements !== null;
3636
+ const isReady = flopay !== null && (vaultActive || elements !== null);
3299
3637
  if (!isReady) {
3300
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
3638
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
3301
3639
  }
3302
3640
  const isButtons = layout === "buttons";
3303
3641
  const appearanceVars = appearance?.variables;
@@ -3305,6 +3643,8 @@ function SplitCardFormInner({
3305
3643
  const appearanceColorBg = appearanceVars?.colorBackground;
3306
3644
  const themedWrapperBg = appearanceColorBg && !SDK_DEFAULT_WHITES.has(appearanceColorBg) ? appearanceColorBg : void 0;
3307
3645
  const resolvedBorder = bStyles.cardInputBorder ?? (isButtons ? "#e5e7eb" : "#A4A4FF");
3646
+ const resolvedDangerColor = appearanceVars?.colorDanger ?? "#dc2626";
3647
+ const avsBorderColor = (fieldInvalid) => hasAttemptedSubmit && fieldInvalid ? resolvedDangerColor : resolvedBorder;
3308
3648
  const cardBg = bStyles.cardFormContainer?.backgroundColor ?? themedWrapperBg ?? (isButtons ? "white" : "#EDEDFF");
3309
3649
  const cardInputBg = bStyles.cardInputBackground ?? appearanceVars?.colorBackground ?? "white";
3310
3650
  const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);
@@ -3316,7 +3656,9 @@ function SplitCardFormInner({
3316
3656
  const resolvedInputColor = bStyles.cardInputColor ?? (typeof nameInputOverrides?.color === "string" ? nameInputOverrides.color : void 0) ?? appearanceVars?.colorText ?? "#262833";
3317
3657
  const resolvedPlaceholderColor = bStyles.cardInputPlaceholderColor ?? "#9ca3af";
3318
3658
  const resolvedBorderRadius = appearanceVars?.borderRadius ?? "8px";
3659
+ const buttonBorderRadius = appearanceVars?.borderRadius ?? bStyles.cardButton?.borderRadius ?? resolvedBorderRadius;
3319
3660
  const resolvedPrimaryColor = appearanceVars?.colorPrimary ?? "#4A49FF";
3661
+ const resolvedPrimaryHoverColor = appearanceVars?.colorPrimaryHover ?? darkenHex(resolvedPrimaryColor, 0.12);
3320
3662
  const resolvedTitleColor = appearanceVars?.colorText ?? "#262833";
3321
3663
  const sharedInputTypography = {
3322
3664
  fontSize: resolvedInputFontSize,
@@ -3350,14 +3692,73 @@ function SplitCardFormInner({
3350
3692
  const containerOverrides = bStyles.cardFormContainer ?? {};
3351
3693
  const containerPadding = containerOverrides.padding ?? (isButtons ? "0" : "1rem");
3352
3694
  const containerRadius = containerOverrides.borderRadius ?? resolvedBorderRadius;
3353
- const cardFormBlock = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
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: {
3354
3749
  backgroundColor: cardBg,
3355
3750
  borderRadius: containerRadius,
3356
3751
  ...containerOverrides,
3357
3752
  padding: containerPadding,
3358
- ...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"
3359
3760
  }, children: [
3360
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `
3761
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
3361
3762
  .flopay-shared-input::placeholder {
3362
3763
  color: var(--flopay-input-placeholder-color);
3363
3764
  opacity: 1;
@@ -3366,12 +3767,14 @@ function SplitCardFormInner({
3366
3767
  font-weight: var(--flopay-input-font-weight);
3367
3768
  }
3368
3769
  ` }),
3369
- isButtons && showCardForm && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
3770
+ isButtons && showCardForm && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
3370
3771
  display: "flex",
3371
3772
  alignItems: "center",
3372
- 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
3373
3776
  }, children: [
3374
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3777
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3375
3778
  "button",
3376
3779
  {
3377
3780
  type: "button",
@@ -3393,7 +3796,7 @@ function SplitCardFormInner({
3393
3796
  },
3394
3797
  "aria-label": "Back to payment methods",
3395
3798
  children: [
3396
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: {
3799
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
3397
3800
  display: "inline-flex",
3398
3801
  alignItems: "center",
3399
3802
  justifyContent: "center",
@@ -3403,12 +3806,12 @@ function SplitCardFormInner({
3403
3806
  backgroundColor: "#f3f4f6",
3404
3807
  transition: "background-color 0.15s",
3405
3808
  ...bStyles.backButtonIcon
3406
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
3407
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
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 })
3408
3811
  ]
3409
3812
  }
3410
3813
  ),
3411
- hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
3814
+ hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3412
3815
  flex: 1,
3413
3816
  textAlign: "center",
3414
3817
  fontWeight: 600,
@@ -3416,58 +3819,65 @@ function SplitCardFormInner({
3416
3819
  color: "#262833",
3417
3820
  paddingRight: 80,
3418
3821
  ...bStyles.title
3419
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TitleContentSlot, { content: cardTitleContent }) })
3822
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TitleContentSlot, { content: cardTitleContent }) })
3420
3823
  ] }),
3421
- !isButtons && !hideTitle && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
3824
+ !isButtons && !hideTitle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3422
3825
  textAlign: "center",
3423
3826
  fontWeight: 600,
3424
3827
  fontSize: "1.1rem",
3425
3828
  padding: "0.5rem 0",
3426
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,
3427
3833
  ...bStyles.title
3428
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TitleContentSlot, { content: cardTitleContent }) }),
3429
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
3430
- backgroundColor: cardInputBg,
3431
- border: `1px solid ${resolvedBorder}`,
3432
- borderTopLeftRadius: "8px",
3433
- borderTopRightRadius: "8px",
3434
- padding: "10px"
3435
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
3436
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex" }, children: [
3437
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
3438
- flex: 1,
3439
- backgroundColor: cardInputBg,
3440
- // Longhand only — mixing `border` shorthand with per-side
3441
- // overrides triggers React's "shorthand vs longhand" warning
3442
- // because render order isn't deterministic.
3443
- borderTop: "none",
3444
- borderRight: "none",
3445
- borderBottom: `1px solid ${resolvedBorder}`,
3446
- borderLeft: `1px solid ${resolvedBorder}`,
3447
- borderBottomLeftRadius: "8px",
3448
- padding: "10px"
3449
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardExpiryElement, { options: stripeElementStyle }) }),
3450
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
3451
- 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: {
3452
3837
  backgroundColor: cardInputBg,
3453
- borderTop: "none",
3454
- borderRight: `1px solid ${resolvedBorder}`,
3455
- borderBottom: `1px solid ${resolvedBorder}`,
3456
- borderLeft: `1px solid ${resolvedBorder}`,
3457
- borderBottomRightRadius: "8px",
3838
+ border: `1px solid ${resolvedBorder}`,
3839
+ borderTopLeftRadius: resolvedBorderRadius,
3840
+ borderTopRightRadius: resolvedBorderRadius,
3458
3841
  padding: "10px"
3459
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardCvcElement, { options: stripeElementStyle }) })
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
+ ] })
3460
3868
  ] }),
3461
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
3869
+ !vaultActive && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3462
3870
  backgroundColor: cardInputBg,
3463
3871
  border: `1px solid ${resolvedBorder}`,
3464
- borderRadius: "8px",
3872
+ borderRadius: resolvedBorderRadius,
3465
3873
  marginTop: "0.5rem",
3466
3874
  padding: "10px"
3467
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3875
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3468
3876
  "input",
3469
3877
  {
3470
3878
  className: "flopay-shared-input",
3879
+ id: "flopay-cc-name",
3880
+ name: "cc-name",
3471
3881
  placeholder: "Full Name on Card",
3472
3882
  autoComplete: "cc-name",
3473
3883
  value: fullName,
@@ -3484,32 +3894,32 @@ function SplitCardFormInner({
3484
3894
  }
3485
3895
  }
3486
3896
  ) }),
3487
- avsConfig && (() => {
3897
+ avsConfig && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { order: vaultActive ? -1 : 0 }, "data-testid": "flopay-avs-fields", children: (() => {
3488
3898
  const cc = selectedCountry;
3489
- const inputWrapStyle = (extraStyle) => ({
3899
+ const inputWrapStyle = (invalid = false) => ({
3490
3900
  backgroundColor: cardInputBg,
3491
- border: `1px solid ${resolvedBorder}`,
3492
- borderRadius: "8px",
3901
+ border: `1px solid ${avsBorderColor(invalid)}`,
3902
+ borderRadius: resolvedBorderRadius,
3493
3903
  marginTop: "0.5rem",
3494
- padding: "10px",
3495
- ...isButtons && extraStyle ? extraStyle : {}
3904
+ padding: "10px"
3496
3905
  });
3497
3906
  const inputFieldStyle = () => ({
3498
3907
  width: "100%",
3499
3908
  border: "none",
3500
3909
  outline: "none",
3501
3910
  background: "transparent",
3502
- ...sharedInputTypography,
3503
- ...isButtons && bStyles.nameInput ? bStyles.nameInput : {}
3911
+ ...sharedInputTypography
3504
3912
  });
3505
3913
  const stateOpts = (0, import_shared5.getStateOptions)(cc);
3506
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3507
- (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_1, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: inputWrapStyle(bStyles.addressLine1Input), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
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)(
3508
3916
  "input",
3509
3917
  {
3510
3918
  className: "flopay-shared-input",
3919
+ id: "flopay-billing-address-line1",
3920
+ name: "billing-address-line1",
3511
3921
  placeholder: "Street Address (e.g. 123 Main St)",
3512
- autoComplete: "address-line1",
3922
+ autoComplete: "billing address-line1",
3513
3923
  value: addressLine1,
3514
3924
  onChange: (e) => {
3515
3925
  addressLine1Ref.current = e.target.value;
@@ -3521,12 +3931,14 @@ function SplitCardFormInner({
3521
3931
  style: inputFieldStyle()
3522
3932
  }
3523
3933
  ) }),
3524
- (0, import_shared5.isAVSFieldVisible)(avsConfig.address_line_2, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: inputWrapStyle(bStyles.addressLine2Input), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
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)(
3525
3935
  "input",
3526
3936
  {
3527
3937
  className: "flopay-shared-input",
3938
+ id: "flopay-billing-address-line2",
3939
+ name: "billing-address-line2",
3528
3940
  placeholder: "Apt, Suite, Unit (optional)",
3529
- autoComplete: "address-line2",
3941
+ autoComplete: "billing address-line2",
3530
3942
  value: addressLine2,
3531
3943
  onChange: (e) => {
3532
3944
  addressLine2Ref.current = e.target.value;
@@ -3537,29 +3949,30 @@ function SplitCardFormInner({
3537
3949
  style: inputFieldStyle()
3538
3950
  }
3539
3951
  ) }),
3540
- ((0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc)) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
3952
+ ((0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc)) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
3541
3953
  display: "flex",
3542
3954
  gap: "0",
3543
3955
  marginTop: "0.5rem"
3544
3956
  }, children: [
3545
- (0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
3957
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3546
3958
  flex: 1,
3547
3959
  backgroundColor: cardInputBg,
3548
- borderTop: `1px solid ${resolvedBorder}`,
3549
- borderRight: `1px solid ${resolvedBorder}`,
3550
- borderBottom: `1px solid ${resolvedBorder}`,
3551
- borderLeft: `1px solid ${resolvedBorder}`,
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)}`,
3552
3964
  padding: "10px",
3553
- borderTopLeftRadius: "8px",
3554
- borderBottomLeftRadius: "8px",
3555
- ...(0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) ? { borderRight: "none", borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius: "8px" },
3556
- ...isButtons && bStyles.cityInput ? bStyles.cityInput : {}
3557
- }, 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)(
3558
3969
  "input",
3559
3970
  {
3560
3971
  className: "flopay-shared-input",
3972
+ id: "flopay-billing-city",
3973
+ name: "billing-city",
3561
3974
  placeholder: "City",
3562
- autoComplete: "address-level2",
3975
+ autoComplete: "billing address-level2",
3563
3976
  value: city,
3564
3977
  onChange: (e) => {
3565
3978
  cityRef.current = e.target.value;
@@ -3571,39 +3984,42 @@ function SplitCardFormInner({
3571
3984
  style: inputFieldStyle()
3572
3985
  }
3573
3986
  ) }),
3574
- (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
3987
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.state, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3575
3988
  flex: 1,
3576
3989
  backgroundColor: cardInputBg,
3577
- border: `1px solid ${resolvedBorder}`,
3990
+ border: `1px solid ${avsBorderColor(invalidAvsFields.state)}`,
3578
3991
  padding: "10px",
3579
- borderTopRightRadius: "8px",
3580
- borderBottomRightRadius: "8px",
3581
- ...(0, import_shared5.isAVSFieldVisible)(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius: "8px" },
3582
- ...isButtons && bStyles.stateInput ? bStyles.stateInput : {}
3583
- }, 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)(
3584
3996
  "select",
3585
3997
  {
3998
+ id: "flopay-billing-state",
3999
+ name: "billing-state",
3586
4000
  value: stateValue,
3587
4001
  onChange: (e) => {
3588
4002
  stateRef.current = e.target.value;
3589
4003
  setStateValue(e.target.value);
3590
4004
  },
3591
4005
  disabled: isSubmitting,
3592
- autoComplete: "address-level1",
4006
+ autoComplete: "billing address-level1",
3593
4007
  required: true,
3594
4008
  "data-testid": "flopay-state",
3595
4009
  style: { ...inputFieldStyle(), cursor: "pointer" },
3596
4010
  children: [
3597
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", children: (0, import_shared5.getStateLabel)(cc) }),
3598
- stateOpts.map((s) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: s.code, children: s.name }, s.code))
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))
3599
4013
  ]
3600
4014
  }
3601
- ) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4015
+ ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3602
4016
  "input",
3603
4017
  {
3604
4018
  className: "flopay-shared-input",
4019
+ id: "flopay-billing-state",
4020
+ name: "billing-state",
3605
4021
  placeholder: (0, import_shared5.getStateLabel)(cc),
3606
- autoComplete: "address-level1",
4022
+ autoComplete: "billing address-level1",
3607
4023
  value: stateValue,
3608
4024
  onChange: (e) => {
3609
4025
  stateRef.current = e.target.value;
@@ -3616,13 +4032,13 @@ function SplitCardFormInner({
3616
4032
  }
3617
4033
  ) })
3618
4034
  ] }),
3619
- ((0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc)) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
4035
+ ((0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) || (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc)) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
3620
4036
  display: "flex",
3621
4037
  flexDirection: avsLayoutProp === "column" ? "column" : "row",
3622
4038
  gap: avsLayoutProp === "column" ? "0.5rem" : "0",
3623
4039
  marginTop: "0.5rem"
3624
4040
  }, children: [
3625
- (0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4041
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3626
4042
  flex: avsLayoutProp === "row" ? 1 : void 0,
3627
4043
  backgroundColor: cardInputBg,
3628
4044
  borderTop: `1px solid ${resolvedBorder}`,
@@ -3630,11 +4046,12 @@ function SplitCardFormInner({
3630
4046
  borderBottom: `1px solid ${resolvedBorder}`,
3631
4047
  borderLeft: `1px solid ${resolvedBorder}`,
3632
4048
  padding: "10px",
3633
- ...avsLayoutProp === "row" && (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) ? { borderRadius: "0", borderTopLeftRadius: "8px", borderBottomLeftRadius: "8px", borderRight: "none" } : { borderRadius: "8px" },
3634
- ...isButtons && bStyles.countrySelect ? bStyles.countrySelect : {}
3635
- }, 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)(
3636
4051
  "select",
3637
4052
  {
4053
+ id: "flopay-billing-country",
4054
+ name: "billing-country",
3638
4055
  value: selectedCountry,
3639
4056
  onChange: (e) => {
3640
4057
  selectedCountryRef.current = e.target.value;
@@ -3644,29 +4061,30 @@ function SplitCardFormInner({
3644
4061
  setStateValue("");
3645
4062
  },
3646
4063
  disabled: isSubmitting,
3647
- autoComplete: "country",
4064
+ autoComplete: "billing country",
3648
4065
  "data-testid": "flopay-country",
3649
4066
  style: { ...inputFieldStyle(), cursor: "pointer" },
3650
- children: import_shared5.COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("option", { value: c.code, children: [
4067
+ children: import_shared5.COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("option", { value: c.code, children: [
3651
4068
  c.flag,
3652
4069
  " ",
3653
4070
  c.name
3654
4071
  ] }, c.code))
3655
4072
  }
3656
4073
  ) }),
3657
- (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4074
+ (0, import_shared5.isAVSFieldVisible)(avsConfig.postal_code, cc) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3658
4075
  flex: avsLayoutProp === "row" ? 1 : void 0,
3659
4076
  backgroundColor: cardInputBg,
3660
- border: `1px solid ${resolvedBorder}`,
4077
+ border: `1px solid ${avsBorderColor(invalidAvsFields.zip)}`,
3661
4078
  padding: "10px",
3662
- ...avsLayoutProp === "row" && (0, import_shared5.isAVSFieldVisible)(avsConfig.country, cc) ? { borderRadius: "0", borderTopRightRadius: "8px", borderBottomRightRadius: "8px" } : { borderRadius: "8px" },
3663
- ...isButtons && bStyles.zipInput ? bStyles.zipInput : {}
3664
- }, 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)(
3665
4081
  "input",
3666
4082
  {
3667
4083
  className: "flopay-shared-input",
4084
+ id: "flopay-billing-postal-code",
4085
+ name: "billing-postal-code",
3668
4086
  placeholder: (0, import_shared5.getPostalCodeLabel)(selectedCountry),
3669
- autoComplete: "postal-code",
4087
+ autoComplete: "billing postal-code",
3670
4088
  value: zipCode,
3671
4089
  onChange: (e) => {
3672
4090
  zipCodeRef.current = e.target.value;
@@ -3681,8 +4099,10 @@ function SplitCardFormInner({
3681
4099
  ) })
3682
4100
  ] })
3683
4101
  ] });
3684
- })(),
3685
- displayError && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
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: {
3686
4106
  margin: "0.75rem 0",
3687
4107
  padding: "0.625rem 0.875rem",
3688
4108
  background: "#FEF2F2",
@@ -3696,15 +4116,21 @@ function SplitCardFormInner({
3696
4116
  gap: "0.5rem",
3697
4117
  ...bStyles.errorBanner ? bStyles.errorBanner : {}
3698
4118
  }, children: [
3699
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
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" }) }),
3700
4120
  displayError
3701
4121
  ] }),
3702
- children ?? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4122
+ !vaultActive && (children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3703
4123
  "button",
3704
4124
  {
3705
4125
  type: "submit",
3706
4126
  disabled: !formReady || isSubmitting,
3707
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
+ },
3708
4134
  style: {
3709
4135
  width: "100%",
3710
4136
  padding: "0.875rem",
@@ -3717,11 +4143,12 @@ function SplitCardFormInner({
3717
4143
  fontWeight: 600,
3718
4144
  cursor: !formReady || isSubmitting ? "not-allowed" : "pointer",
3719
4145
  opacity: !formReady || isSubmitting ? 0.5 : 1,
4146
+ transition: "background-color 0.15s",
3720
4147
  ...bStyles.submitButton
3721
4148
  },
3722
4149
  children: isSubmitting ? "PROCESSING..." : submitLabel
3723
4150
  }
3724
- )
4151
+ ))
3725
4152
  ] });
3726
4153
  const gateDebugStyle = {
3727
4154
  margin: 0,
@@ -3737,9 +4164,9 @@ function SplitCardFormInner({
3737
4164
  const renderDirectPaypalGateDebug = (testId) => {
3738
4165
  if (!debug) return null;
3739
4166
  if (!showPayPal || !directPaypalConfigured) {
3740
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/DirectPayPal-debug - not enabled" });
4167
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/DirectPayPal-debug - not enabled" });
3741
4168
  }
3742
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: [
4169
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: [
3743
4170
  "FloPay/DirectPayPal-debug (parent gate)",
3744
4171
  ` showPayPal=${showPayPal}`,
3745
4172
  ` directPaypalConfigured=${directPaypalConfigured}`,
@@ -3752,9 +4179,9 @@ function SplitCardFormInner({
3752
4179
  const renderStripeGateDebug = (testId) => {
3753
4180
  if (!debug) return null;
3754
4181
  if (!showStripe || !stripeInstance) {
3755
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/Stripe-debug - not enabled" });
4182
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/Stripe-debug - not enabled" });
3756
4183
  }
3757
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: [
4184
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { "data-testid": testId, style: gateDebugStyle, children: [
3758
4185
  "FloPay/Stripe-debug (parent gate)",
3759
4186
  ` showStripe=${showStripe}`,
3760
4187
  ` currency=${currency}`,
@@ -3783,11 +4210,11 @@ function SplitCardFormInner({
3783
4210
  const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
3784
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;
3785
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;
3786
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
3787
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FloPayKeyframes, {}),
3788
- overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
3789
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "grid" }, children: [
3790
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
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)(
3791
4218
  "div",
3792
4219
  {
3793
4220
  "data-testid": "flopay-buttons-panel",
@@ -3804,8 +4231,8 @@ function SplitCardFormInner({
3804
4231
  children: [
3805
4232
  renderDirectPaypalGateDebug("flopay-direct-paypal-gate-debug"),
3806
4233
  renderStripeGateDebug("flopay-stripe-gate-debug"),
3807
- shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3808
- paypalDirectRetry && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4234
+ shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
4235
+ paypalDirectRetry && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3809
4236
  "div",
3810
4237
  {
3811
4238
  "data-testid": "flopay-paypal-direct-retry-notice",
@@ -3821,7 +4248,7 @@ function SplitCardFormInner({
3821
4248
  children: "Please confirm your PayPal payment to complete checkout."
3822
4249
  }
3823
4250
  ),
3824
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4251
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3825
4252
  DirectPayPalButton,
3826
4253
  {
3827
4254
  sessionId,
@@ -3847,7 +4274,7 @@ function SplitCardFormInner({
3847
4274
  paypalDirectRetry?.orderId ?? "fresh"
3848
4275
  )
3849
4276
  ] }),
3850
- shouldRenderStripePayPal && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4277
+ shouldRenderStripePayPal && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3851
4278
  PayPalButtonInner,
3852
4279
  {
3853
4280
  sessionId,
@@ -3861,10 +4288,10 @@ function SplitCardFormInner({
3861
4288
  onDecline,
3862
4289
  runBeforeButtonClick,
3863
4290
  onLoadStateChange: setPaypalLoadState,
3864
- placeholderBorderRadius: bStyles.cardButton?.borderRadius ?? resolvedBorderRadius
4291
+ placeholderBorderRadius: buttonBorderRadius
3865
4292
  }
3866
4293
  ) }),
3867
- shouldRenderWallets ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4294
+ shouldRenderWallets ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3868
4295
  WalletButtonInner,
3869
4296
  {
3870
4297
  sessionId,
@@ -3878,10 +4305,10 @@ function SplitCardFormInner({
3878
4305
  onDecline,
3879
4306
  runBeforeButtonClick,
3880
4307
  onLoadStateChange: setWalletLoadState,
3881
- placeholderBorderRadius: bStyles.cardButton?.borderRadius ?? resolvedBorderRadius
4308
+ placeholderBorderRadius: buttonBorderRadius
3882
4309
  }
3883
- ) }) : shouldShowWallets ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: bStyles.cardButton?.borderRadius ?? resolvedBorderRadius, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
3884
- shouldRenderPaymentElement && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
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)(
3885
4312
  StripePaymentElementInner,
3886
4313
  {
3887
4314
  sessionId,
@@ -3909,11 +4336,11 @@ function SplitCardFormInner({
3909
4336
  backgroundColor: bStyles.cardButton?.backgroundColor,
3910
4337
  borderColor: bStyles.cardInputBorder,
3911
4338
  textColor: bStyles.cardButton?.color,
3912
- borderRadius: bStyles.cardButton?.borderRadius
4339
+ borderRadius: buttonBorderRadius
3913
4340
  }
3914
4341
  }
3915
4342
  ),
3916
- showStripe && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4343
+ showStripe && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3917
4344
  "button",
3918
4345
  {
3919
4346
  type: "button",
@@ -3941,7 +4368,8 @@ function SplitCardFormInner({
3941
4368
  themeBundle,
3942
4369
  resolvedPrimaryColor,
3943
4370
  resolvedBorderRadius,
3944
- submitButtonStyle: bStyles.submitButton
4371
+ submitButtonStyle: bStyles.submitButton,
4372
+ explicitPrimaryColor: appearanceVars?.colorPrimary
3945
4373
  }),
3946
4374
  fontSize: bStyles.cardButtonFontSize ?? "0.95rem",
3947
4375
  fontWeight: 600,
@@ -3950,20 +4378,28 @@ function SplitCardFormInner({
3950
4378
  alignItems: "center",
3951
4379
  justifyContent: "center",
3952
4380
  gap: "0.625rem",
3953
- 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",
3954
4382
  position: "relative",
3955
4383
  opacity: isSubmitting ? 0.6 : 1
3956
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
+ },
3957
4393
  onMouseDown: (e) => {
3958
4394
  e.currentTarget.style.transform = "scale(0.985)";
3959
4395
  },
3960
4396
  onMouseUp: (e) => {
3961
4397
  e.currentTarget.style.transform = "scale(1)";
3962
4398
  },
3963
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardButtonContentSlot, { content: cardButtonContent })
4399
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardButtonContentSlot, { content: cardButtonContent })
3964
4400
  }
3965
4401
  ),
3966
- displayError && viewState === "buttons" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
4402
+ displayError && viewState === "buttons" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
3967
4403
  margin: "0.25rem 0",
3968
4404
  padding: "0.625rem 0.875rem",
3969
4405
  background: "#FEF2F2",
@@ -3977,33 +4413,33 @@ function SplitCardFormInner({
3977
4413
  gap: "0.5rem",
3978
4414
  ...bStyles.errorBanner ? bStyles.errorBanner : {}
3979
4415
  }, children: [
3980
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
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" }) }),
3981
4417
  displayError
3982
4418
  ] })
3983
4419
  ]
3984
4420
  }
3985
4421
  ),
3986
- showStripe && isCardView && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4422
+ showStripe && isCardView && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3987
4423
  gridArea: "1 / 1",
3988
4424
  ...cardAnim ? { animation: cardAnim } : {},
3989
4425
  ...viewState === "collapsing" ? { pointerEvents: "none" } : {}
3990
4426
  }, children: cardFormBlock }),
3991
- showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4427
+ showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
3992
4428
  gridArea: "1 / 1",
3993
4429
  ...apmAnim ? { animation: apmAnim } : {},
3994
4430
  ...viewState === "apm-collapsing" ? { pointerEvents: "none" } : {}
3995
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
4431
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
3996
4432
  backgroundColor: cardBg,
3997
4433
  borderRadius: containerRadius,
3998
4434
  ...containerOverrides,
3999
4435
  padding: containerPadding
4000
4436
  }, children: [
4001
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
4437
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
4002
4438
  display: "flex",
4003
4439
  alignItems: "center",
4004
4440
  padding: "0.75rem 0 0.625rem"
4005
4441
  }, children: [
4006
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4442
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4007
4443
  "button",
4008
4444
  {
4009
4445
  type: "button",
@@ -4026,7 +4462,7 @@ function SplitCardFormInner({
4026
4462
  },
4027
4463
  "aria-label": "Back to payment methods",
4028
4464
  children: [
4029
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: {
4465
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
4030
4466
  display: "inline-flex",
4031
4467
  alignItems: "center",
4032
4468
  justifyContent: "center",
@@ -4036,12 +4472,12 @@ function SplitCardFormInner({
4036
4472
  backgroundColor: "#f3f4f6",
4037
4473
  transition: "background-color 0.15s",
4038
4474
  ...bStyles.backButtonIcon
4039
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
4040
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
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 })
4041
4477
  ]
4042
4478
  }
4043
4479
  ),
4044
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4480
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
4045
4481
  flex: 1,
4046
4482
  textAlign: "center",
4047
4483
  fontWeight: 600,
@@ -4051,12 +4487,12 @@ function SplitCardFormInner({
4051
4487
  ...bStyles.title
4052
4488
  }, children: `Pay with ${(0, import_shared5.getStripeMethodDisplayName)(expandedApmMethod)}` })
4053
4489
  ] }),
4054
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4490
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4055
4491
  import_react_stripe_js.Elements,
4056
4492
  {
4057
4493
  stripe: stripeInstance,
4058
4494
  options: apmInlineOptions,
4059
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4495
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4060
4496
  StripeMethodInlineForm,
4061
4497
  {
4062
4498
  method: expandedApmMethod,
@@ -4074,7 +4510,8 @@ function SplitCardFormInner({
4074
4510
  isProcessing: isSubmitting,
4075
4511
  submitButtonColor: resolvedPrimaryColor,
4076
4512
  submitButtonBorderRadius: resolvedBorderRadius,
4077
- submitButtonStyle: bStyles.submitButton
4513
+ submitButtonStyle: bStyles.submitButton,
4514
+ errorText: displayError
4078
4515
  }
4079
4516
  )
4080
4517
  },
@@ -4085,24 +4522,24 @@ function SplitCardFormInner({
4085
4522
  ] });
4086
4523
  }
4087
4524
  if (isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && showStripe) {
4088
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
4089
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FloPayKeyframes, {}),
4090
- overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
4091
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
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: {
4092
4529
  ...apmAnim ? { animation: apmAnim } : {},
4093
4530
  ...viewState === "apm-collapsing" ? { pointerEvents: "none" } : {}
4094
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
4531
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
4095
4532
  backgroundColor: cardBg,
4096
4533
  borderRadius: containerRadius,
4097
4534
  ...containerOverrides,
4098
4535
  padding: containerPadding
4099
4536
  }, children: [
4100
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
4537
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
4101
4538
  display: "flex",
4102
4539
  alignItems: "center",
4103
4540
  padding: "0.75rem 0 0.625rem"
4104
4541
  }, children: [
4105
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4542
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4106
4543
  "button",
4107
4544
  {
4108
4545
  type: "button",
@@ -4125,7 +4562,7 @@ function SplitCardFormInner({
4125
4562
  },
4126
4563
  "aria-label": "Back to payment methods",
4127
4564
  children: [
4128
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: {
4565
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
4129
4566
  display: "inline-flex",
4130
4567
  alignItems: "center",
4131
4568
  justifyContent: "center",
@@ -4135,12 +4572,12 @@ function SplitCardFormInner({
4135
4572
  backgroundColor: "#f3f4f6",
4136
4573
  transition: "background-color 0.15s",
4137
4574
  ...bStyles.backButtonIcon
4138
- }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
4139
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
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 })
4140
4577
  ]
4141
4578
  }
4142
4579
  ),
4143
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
4580
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
4144
4581
  flex: 1,
4145
4582
  textAlign: "center",
4146
4583
  fontWeight: 600,
@@ -4150,12 +4587,12 @@ function SplitCardFormInner({
4150
4587
  ...bStyles.title
4151
4588
  }, children: `Pay with ${(0, import_shared5.getStripeMethodDisplayName)(expandedApmMethod)}` })
4152
4589
  ] }),
4153
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4590
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4154
4591
  import_react_stripe_js.Elements,
4155
4592
  {
4156
4593
  stripe: stripeInstance,
4157
4594
  options: apmInlineOptions,
4158
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4595
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4159
4596
  StripeMethodInlineForm,
4160
4597
  {
4161
4598
  method: expandedApmMethod,
@@ -4173,7 +4610,8 @@ function SplitCardFormInner({
4173
4610
  isProcessing: isSubmitting,
4174
4611
  submitButtonColor: resolvedPrimaryColor,
4175
4612
  submitButtonBorderRadius: resolvedBorderRadius,
4176
- submitButtonStyle: bStyles.submitButton
4613
+ submitButtonStyle: bStyles.submitButton,
4614
+ errorText: displayError
4177
4615
  }
4178
4616
  )
4179
4617
  },
@@ -4182,14 +4620,14 @@ function SplitCardFormInner({
4182
4620
  ] }) })
4183
4621
  ] });
4184
4622
  }
4185
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
4186
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FloPayKeyframes, {}),
4187
- overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
4188
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
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: [
4189
4627
  renderDirectPaypalGateDebug("flopay-direct-paypal-gate-debug-default"),
4190
4628
  renderStripeGateDebug("flopay-stripe-gate-debug-default"),
4191
- shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
4192
- paypalDirectRetry && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4629
+ shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
4630
+ paypalDirectRetry && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4193
4631
  "div",
4194
4632
  {
4195
4633
  "data-testid": "flopay-paypal-direct-retry-notice-default",
@@ -4205,7 +4643,7 @@ function SplitCardFormInner({
4205
4643
  children: "Please confirm your PayPal payment to complete checkout."
4206
4644
  }
4207
4645
  ),
4208
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4646
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4209
4647
  DirectPayPalButton,
4210
4648
  {
4211
4649
  sessionId,
@@ -4231,7 +4669,7 @@ function SplitCardFormInner({
4231
4669
  paypalDirectRetry?.orderId ?? "fresh"
4232
4670
  )
4233
4671
  ] }),
4234
- shouldRenderStripePayPal && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4672
+ shouldRenderStripePayPal && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_stripe_js.Elements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4235
4673
  PayPalButtonInner,
4236
4674
  {
4237
4675
  sessionId,
@@ -4245,10 +4683,10 @@ function SplitCardFormInner({
4245
4683
  onDecline,
4246
4684
  runBeforeButtonClick,
4247
4685
  onLoadStateChange: setPaypalLoadState,
4248
- placeholderBorderRadius: bStyles.cardButton?.borderRadius ?? resolvedBorderRadius
4686
+ placeholderBorderRadius: buttonBorderRadius
4249
4687
  }
4250
4688
  ) }),
4251
- shouldRenderWallets && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4689
+ shouldRenderWallets && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4252
4690
  WalletButtonInner,
4253
4691
  {
4254
4692
  sessionId,
@@ -4262,10 +4700,10 @@ function SplitCardFormInner({
4262
4700
  onDecline,
4263
4701
  runBeforeButtonClick,
4264
4702
  onLoadStateChange: setWalletLoadState,
4265
- placeholderBorderRadius: bStyles.cardButton?.borderRadius ?? resolvedBorderRadius
4703
+ placeholderBorderRadius: buttonBorderRadius
4266
4704
  }
4267
4705
  ) }),
4268
- shouldRenderPaymentElement && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4706
+ shouldRenderPaymentElement && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4269
4707
  StripePaymentElementInner,
4270
4708
  {
4271
4709
  sessionId,
@@ -4293,12 +4731,12 @@ function SplitCardFormInner({
4293
4731
  backgroundColor: bStyles.cardButton?.backgroundColor,
4294
4732
  borderColor: bStyles.cardInputBorder,
4295
4733
  textColor: bStyles.cardButton?.color,
4296
- borderRadius: bStyles.cardButton?.borderRadius
4734
+ borderRadius: buttonBorderRadius
4297
4735
  }
4298
4736
  }
4299
4737
  )
4300
4738
  ] }),
4301
- showStripe && (shouldDisplayWalletRow || shouldDisplayPayPalRow || shouldDisplayPaymentElementRow) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: {
4739
+ showStripe && (shouldDisplayWalletRow || shouldDisplayPayPalRow || shouldDisplayPaymentElementRow) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
4302
4740
  display: "flex",
4303
4741
  alignItems: "center",
4304
4742
  gap: "0.75rem",
@@ -4306,9 +4744,9 @@ function SplitCardFormInner({
4306
4744
  color: "#999",
4307
4745
  fontSize: "0.85rem"
4308
4746
  }, children: [
4309
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } }),
4310
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "or pay with card" }),
4311
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
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" } })
4312
4750
  ] }),
4313
4751
  showStripe && cardFormBlock
4314
4752
  ] });
@@ -4318,6 +4756,26 @@ function SplitCardFormInner({
4318
4756
  var import_js3 = require("@flopay/js");
4319
4757
  var import_shared7 = require("@flopay/shared");
4320
4758
  var DEFAULT_SAVED_PAYMENT_DECLINE_METHOD = "card";
4759
+ async function retrieveResumeIntent(stripe, clientSecret, isSetupIntent) {
4760
+ if (isSetupIntent) {
4761
+ if (typeof stripe.retrieveSetupIntent !== "function") return null;
4762
+ const { setupIntent, error: error2 } = await stripe.retrieveSetupIntent(clientSecret);
4763
+ return { error: error2, intent: setupIntent ?? null };
4764
+ }
4765
+ if (typeof stripe.retrievePaymentIntent !== "function") return null;
4766
+ const { paymentIntent, error } = await stripe.retrievePaymentIntent(clientSecret);
4767
+ return { error, intent: paymentIntent ?? null };
4768
+ }
4769
+ async function confirmResumeIntent(stripe, clientSecret, data, isSetupIntent) {
4770
+ if (isSetupIntent) {
4771
+ if (typeof stripe.confirmCardSetup !== "function") return null;
4772
+ const { setupIntent, error: error2 } = await stripe.confirmCardSetup(clientSecret, data);
4773
+ return { error: error2, intent: setupIntent ?? null };
4774
+ }
4775
+ if (typeof stripe.confirmCardPayment !== "function") return null;
4776
+ const { paymentIntent, error } = await stripe.confirmCardPayment(clientSecret, data);
4777
+ return { error, intent: paymentIntent ?? null };
4778
+ }
4321
4779
  function getRedirectResultFromCheckoutProcessError(error) {
4322
4780
  if (!error?.type || !error.threeDSecureToken) {
4323
4781
  return null;
@@ -4331,6 +4789,210 @@ function getRedirectResultFromCheckoutProcessError(error) {
4331
4789
  paymentMethodId: error.paymentMethodId
4332
4790
  };
4333
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
+ }
4334
4996
  function checkoutProcessErrorToFloPayError(error, fallbackMessage = "Payment failed. Please try again.", options) {
4335
4997
  const checkoutMethod = options?.checkoutMethod ?? error?.checkoutMethod ?? (error?.type === "paypal_redirect_required" ? "paypal" : "card");
4336
4998
  const rawMessage = error?.message ?? fallbackMessage;
@@ -4553,64 +5215,66 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
4553
5215
  { checkoutMethod: "card" }
4554
5216
  );
4555
5217
  }
5218
+ const isSetupIntent = (0, import_shared7.isSetupIntentClientSecret)(redirectResult.threeDSecureToken);
4556
5219
  let paymentIntent = null;
4557
5220
  let savedPaymentMethodId = redirectResult.paymentMethodId;
4558
- if (typeof stripe.retrievePaymentIntent === "function") {
4559
- const { paymentIntent: existingPaymentIntent, error: retrieveError } = await stripe.retrievePaymentIntent(
4560
- redirectResult.threeDSecureToken
4561
- );
4562
- if (retrieveError) {
5221
+ const retrieved = await retrieveResumeIntent(stripe, redirectResult.threeDSecureToken, isSetupIntent);
5222
+ if (retrieved) {
5223
+ if (retrieved.error) {
4563
5224
  throw Object.assign(
4564
5225
  new import_shared7.FloPayError(
4565
- retrieveError.message ?? "Failed to retrieve 3DS payment status.",
5226
+ retrieved.error.message ?? `Failed to retrieve 3DS ${isSetupIntent ? "setup" : "payment"} status.`,
4566
5227
  "api_error",
4567
- { code: retrieveError.code }
5228
+ { code: retrieved.error.code }
4568
5229
  ),
4569
5230
  { checkoutMethod: "card" }
4570
5231
  );
4571
5232
  }
4572
- if (!savedPaymentMethodId && existingPaymentIntent?.payment_method) {
4573
- if (typeof existingPaymentIntent.payment_method === "string") {
4574
- savedPaymentMethodId = existingPaymentIntent.payment_method;
4575
- } else if ("id" in existingPaymentIntent.payment_method) {
4576
- savedPaymentMethodId = existingPaymentIntent.payment_method.id;
5233
+ const existingIntent = retrieved.intent;
5234
+ if (!savedPaymentMethodId && existingIntent?.payment_method) {
5235
+ if (typeof existingIntent.payment_method === "string") {
5236
+ savedPaymentMethodId = existingIntent.payment_method;
5237
+ } else if ("id" in existingIntent.payment_method) {
5238
+ savedPaymentMethodId = existingIntent.payment_method.id ?? void 0;
4577
5239
  }
4578
5240
  }
4579
5241
  }
4580
- if (savedPaymentMethodId && typeof stripe.confirmCardPayment === "function") {
4581
- const { error: confirmError, paymentIntent: confirmedPaymentIntent } = await stripe.confirmCardPayment(
4582
- redirectResult.threeDSecureToken,
4583
- {
4584
- payment_method: savedPaymentMethodId,
4585
- return_url: returnUrl ?? resolveSavedPaymentReturnUrl(session) ?? window.location.href
4586
- }
4587
- );
4588
- if (confirmError) {
5242
+ const confirmed = savedPaymentMethodId ? await confirmResumeIntent(
5243
+ stripe,
5244
+ redirectResult.threeDSecureToken,
5245
+ {
5246
+ payment_method: savedPaymentMethodId,
5247
+ return_url: returnUrl ?? resolveSavedPaymentReturnUrl(session) ?? window.location.href
5248
+ },
5249
+ isSetupIntent
5250
+ ) : null;
5251
+ if (confirmed) {
5252
+ if (confirmed.error) {
4589
5253
  throw Object.assign(
4590
5254
  new import_shared7.FloPayError(
4591
- confirmError.message ?? "3DS authentication failed.",
5255
+ confirmed.error.message ?? "3DS authentication failed.",
4592
5256
  "api_error",
4593
- { code: confirmError.code }
5257
+ { code: confirmed.error.code }
4594
5258
  ),
4595
5259
  { checkoutMethod: "card" }
4596
5260
  );
4597
5261
  }
4598
- paymentIntent = confirmedPaymentIntent ?? null;
5262
+ paymentIntent = confirmed.intent;
4599
5263
  } else {
4600
- const { error: nextActionError, paymentIntent: nextActionPaymentIntent } = await stripe.handleNextAction({
5264
+ const nextAction = await stripe.handleNextAction({
4601
5265
  clientSecret: redirectResult.threeDSecureToken
4602
5266
  });
4603
- if (nextActionError) {
5267
+ if (nextAction.error) {
4604
5268
  throw Object.assign(
4605
5269
  new import_shared7.FloPayError(
4606
- nextActionError.message ?? "3DS authentication failed.",
5270
+ nextAction.error.message ?? "3DS authentication failed.",
4607
5271
  "api_error",
4608
- { code: nextActionError.code }
5272
+ { code: nextAction.error.code }
4609
5273
  ),
4610
5274
  { checkoutMethod: "card" }
4611
5275
  );
4612
5276
  }
4613
- paymentIntent = nextActionPaymentIntent ?? null;
5277
+ paymentIntent = (isSetupIntent ? nextAction.setupIntent : nextAction.paymentIntent) ?? null;
4614
5278
  }
4615
5279
  if (paymentIntent && (paymentIntent.status === "requires_capture" || paymentIntent.status === "succeeded" || paymentIntent.status === "processing")) {
4616
5280
  const followUp = await processSavedPaymentForMode({
@@ -4770,7 +5434,7 @@ async function loadSavedPaymentProviders({
4770
5434
  }
4771
5435
 
4772
5436
  // src/flopay-checkout.tsx
4773
- var import_jsx_runtime7 = require("react/jsx-runtime");
5437
+ var import_jsx_runtime8 = require("react/jsx-runtime");
4774
5438
  var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
4775
5439
  var PAYPAL_RESUME_STORAGE_KEY = "flopay_checkout_saved_payment_resume";
4776
5440
  var sessionInflightMap = /* @__PURE__ */ new Map();
@@ -4819,6 +5483,36 @@ function clearPayPalResumeState() {
4819
5483
  console.warn("[FloPayCheckout] Failed to clear PayPal resume state.", error);
4820
5484
  }
4821
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
+ }
4822
5516
  function clearPayPalRedirectParams() {
4823
5517
  if (typeof window === "undefined") return;
4824
5518
  const url = new URL(window.location.href);
@@ -4877,6 +5571,8 @@ function FloPayCheckout({
4877
5571
  onButtonClick,
4878
5572
  onBeforeButtonClick,
4879
5573
  enableAVS,
5574
+ cardFieldOrder,
5575
+ cardPreFormSlot,
4880
5576
  avsLayout,
4881
5577
  submitLabel,
4882
5578
  className,
@@ -4888,41 +5584,41 @@ function FloPayCheckout({
4888
5584
  onSessionCompleted
4889
5585
  }) {
4890
5586
  const resolvedBillingUrl = (0, import_shared8.resolveBillingApiUrl)(billingApiUrl);
4891
- const themeBundle = (0, import_react9.useMemo)(() => (0, import_shared8.resolveTheme)(theme), [theme]);
5587
+ const themeBundle = (0, import_react10.useMemo)(() => (0, import_shared8.resolveTheme)(theme), [theme]);
4892
5588
  const appearance = appearanceOverride ?? themeBundle?.appearance;
4893
5589
  const checkoutType = createSessionParams ? "embedded_checkout" : "standard_checkout";
4894
5590
  const checkoutLayout = children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout";
4895
- const [unified, setUnified] = (0, import_react9.useState)(null);
4896
- const [flopay, setFloPay] = (0, import_react9.useState)(null);
4897
- const flopayRef = (0, import_react9.useRef)(null);
4898
- const [paypalFlopay, setPaypalFloPay] = (0, import_react9.useState)(null);
4899
- const paypalFlopayRef = (0, import_react9.useRef)(null);
4900
- const [session, setSession] = (0, import_react9.useState)(null);
4901
- const [resolvedSessionId, setResolvedSessionId] = (0, import_react9.useState)(sessionIdProp ?? "");
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 ?? "");
4902
5598
  const activeSessionId = sessionIdProp ?? resolvedSessionId;
4903
5599
  const initSessionDependency = createSessionParams ? "" : activeSessionId;
4904
- const [isLoading, setIsLoading] = (0, import_react9.useState)(true);
4905
- const [loadError, setLoadError] = (0, import_react9.useState)(null);
4906
- const [currentMode, setCurrentMode] = (0, import_react9.useState)("full");
4907
- const [confirmProcessing, setConfirmProcessing] = (0, import_react9.useState)(false);
4908
- const [modeError, setModeError] = (0, import_react9.useState)(initialErrorMessage);
4909
- const [modeOverlayStatus, setModeOverlayStatus] = (0, import_react9.useState)(null);
4910
- const [modeOverlayError, setModeOverlayError] = (0, import_react9.useState)(null);
4911
- const [createSessionPatch, setCreateSessionPatch] = (0, import_react9.useState)(void 0);
4912
- const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = (0, import_react9.useState)("");
4913
- const [cardBootstrapPending, setCardBootstrapPending] = (0, import_react9.useState)(false);
4914
- const autoCheckoutAttempted = (0, import_react9.useRef)(false);
4915
- const paypalResumeAttempted = (0, import_react9.useRef)(false);
4916
- const savedPaymentKeysRef = (0, import_react9.useRef)(null);
4917
- const onCompleteRef = (0, import_react9.useRef)(onComplete);
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);
4918
5614
  onCompleteRef.current = onComplete;
4919
- const onErrorRef = (0, import_react9.useRef)(onError);
5615
+ const onErrorRef = (0, import_react10.useRef)(onError);
4920
5616
  onErrorRef.current = onError;
4921
- const onDeclineRef = (0, import_react9.useRef)(onDecline);
5617
+ const onDeclineRef = (0, import_react10.useRef)(onDecline);
4922
5618
  onDeclineRef.current = onDecline;
4923
- const onSessionCompletedRef = (0, import_react9.useRef)(onSessionCompleted);
5619
+ const onSessionCompletedRef = (0, import_react10.useRef)(onSessionCompleted);
4924
5620
  onSessionCompletedRef.current = onSessionCompleted;
4925
- (0, import_react9.useEffect)(() => {
5621
+ (0, import_react10.useEffect)(() => {
4926
5622
  console.info("[FloPay] Checkout initialized", {
4927
5623
  sdk_version: import_shared8.SDK_VERSION,
4928
5624
  checkout_type: checkoutType,
@@ -4930,40 +5626,40 @@ function FloPayCheckout({
4930
5626
  billing_api_url: resolvedBillingUrl
4931
5627
  });
4932
5628
  }, [checkoutLayout, checkoutType, resolvedBillingUrl]);
4933
- const baseCreateSessionHash = (0, import_react9.useMemo)(
5629
+ const baseCreateSessionHash = (0, import_react10.useMemo)(
4934
5630
  () => createSessionParams ? hashCreateParams(createSessionParams) : "",
4935
5631
  [createSessionParams]
4936
5632
  );
4937
- const activeCreateSessionPatch = (0, import_react9.useMemo)(
5633
+ const activeCreateSessionPatch = (0, import_react10.useMemo)(
4938
5634
  () => createSessionPatchBaseHash === baseCreateSessionHash ? createSessionPatch : void 0,
4939
5635
  [createSessionPatch, createSessionPatchBaseHash, baseCreateSessionHash]
4940
5636
  );
4941
- const effectiveCreateSessionBase = (0, import_react9.useMemo)(
5637
+ const effectiveCreateSessionBase = (0, import_react10.useMemo)(
4942
5638
  () => createSessionParams ? mergeInlineSessionPatch(createSessionParams, activeCreateSessionPatch) : void 0,
4943
5639
  [createSessionParams, activeCreateSessionPatch]
4944
5640
  );
4945
5641
  const effectiveCreateSessionMode = checkoutModeProp ?? effectiveCreateSessionBase?.checkoutMode ?? "full";
4946
- const effectiveCreateSession = (0, import_react9.useMemo)(
5642
+ const effectiveCreateSession = (0, import_react10.useMemo)(
4947
5643
  () => effectiveCreateSessionBase ? {
4948
5644
  ...effectiveCreateSessionBase,
4949
5645
  checkoutMode: effectiveCreateSessionMode
4950
5646
  } : void 0,
4951
5647
  [effectiveCreateSessionBase, effectiveCreateSessionMode]
4952
5648
  );
4953
- (0, import_react9.useEffect)(() => {
5649
+ (0, import_react10.useEffect)(() => {
4954
5650
  setCreateSessionPatch(void 0);
4955
5651
  setCreateSessionPatchBaseHash(baseCreateSessionHash);
4956
5652
  }, [baseCreateSessionHash]);
4957
- (0, import_react9.useEffect)(() => {
5653
+ (0, import_react10.useEffect)(() => {
4958
5654
  setModeError(initialErrorMessage);
4959
5655
  }, [initialErrorMessage]);
4960
- const emitDecline = (0, import_react9.useCallback)(
5656
+ const emitDecline = (0, import_react10.useCallback)(
4961
5657
  (method, input, overrides) => {
4962
5658
  onDeclineRef.current?.(buildDeclineEvent(method, input, overrides));
4963
5659
  },
4964
5660
  []
4965
5661
  );
4966
- const runSavedPaymentFlow = (0, import_react9.useCallback)(
5662
+ const runSavedPaymentFlow = (0, import_react10.useCallback)(
4967
5663
  async (sess, options) => {
4968
5664
  setModeError(null);
4969
5665
  setModeOverlayError(null);
@@ -5081,7 +5777,7 @@ function FloPayCheckout({
5081
5777
  resolvedBillingUrl
5082
5778
  ]
5083
5779
  );
5084
- (0, import_react9.useEffect)(() => {
5780
+ (0, import_react10.useEffect)(() => {
5085
5781
  if (typeof window === "undefined" || paypalResumeAttempted.current) {
5086
5782
  return;
5087
5783
  }
@@ -5198,7 +5894,7 @@ function FloPayCheckout({
5198
5894
  }
5199
5895
  })();
5200
5896
  }, [emitDecline, locale, normalizeSavedPaymentError, resolvedBillingUrl]);
5201
- const initializedHashRef = (0, import_react9.useRef)(null);
5897
+ const initializedHashRef = (0, import_react10.useRef)(null);
5202
5898
  function hashCreateParams(params) {
5203
5899
  const key = JSON.stringify({
5204
5900
  c: params?.clientId,
@@ -5231,16 +5927,16 @@ function FloPayCheckout({
5231
5927
  }
5232
5928
  return `flopay_session_${Math.abs(h).toString(36)}`;
5233
5929
  }
5234
- const createSessionHash = (0, import_react9.useMemo)(
5930
+ const createSessionHash = (0, import_react10.useMemo)(
5235
5931
  () => effectiveCreateSession ? hashCreateParams(effectiveCreateSession) : "",
5236
5932
  [effectiveCreateSession]
5237
5933
  );
5238
- const createSessionParamsRef = (0, import_react9.useRef)(effectiveCreateSession);
5934
+ const createSessionParamsRef = (0, import_react10.useRef)(effectiveCreateSession);
5239
5935
  createSessionParamsRef.current = effectiveCreateSession;
5240
- (0, import_react9.useEffect)(() => {
5936
+ (0, import_react10.useEffect)(() => {
5241
5937
  setResolvedSessionId(sessionIdProp ?? "");
5242
5938
  }, [sessionIdProp]);
5243
- (0, import_react9.useEffect)(() => {
5939
+ (0, import_react10.useEffect)(() => {
5244
5940
  autoCheckoutAttempted.current = false;
5245
5941
  setModeError(initialErrorMessage);
5246
5942
  setModeOverlayError(null);
@@ -5248,22 +5944,23 @@ function FloPayCheckout({
5248
5944
  }, [createSessionHash, initialErrorMessage, sessionIdProp]);
5249
5945
  async function resolveInlineSession(params, cacheKey) {
5250
5946
  const api = new import_js4.PaymentAPI(resolvedBillingUrl);
5251
- let sid = typeof window !== "undefined" ? window.sessionStorage.getItem(cacheKey) : null;
5947
+ const cached = readCachedInlineSession(cacheKey);
5948
+ let sid = cached?.sid ?? null;
5252
5949
  let realResult = null;
5253
5950
  if (sid) {
5254
5951
  try {
5255
- realResult = await api.getUnifiedCheckoutSession(sid);
5952
+ realResult = await api.getUnifiedCheckoutSession(sid, cached?.nonce);
5256
5953
  const status = realResult.data.session?.status;
5257
5954
  if (status === "complete") {
5258
5955
  if (wasSessionRecentlyCompleted(sid)) {
5259
5956
  return { sid, result: realResult };
5260
5957
  }
5261
- if (typeof window !== "undefined") window.sessionStorage.removeItem(cacheKey);
5958
+ clearCachedInlineSession(cacheKey);
5262
5959
  sid = null;
5263
5960
  realResult = null;
5264
5961
  }
5265
5962
  } catch {
5266
- if (typeof window !== "undefined") window.sessionStorage.removeItem(cacheKey);
5963
+ clearCachedInlineSession(cacheKey);
5267
5964
  sid = null;
5268
5965
  }
5269
5966
  }
@@ -5277,13 +5974,13 @@ function FloPayCheckout({
5277
5974
  };
5278
5975
  realResult = await api.createAndFetchSession(paramsWithAnalytics);
5279
5976
  sid = realResult.data.session?.id ?? "";
5280
- if (sid && typeof window !== "undefined") {
5281
- window.sessionStorage.setItem(cacheKey, sid);
5977
+ if (sid) {
5978
+ persistCachedInlineSession(cacheKey, sid, realResult.data.session?.clientSecret);
5282
5979
  }
5283
5980
  }
5284
5981
  return { sid: sid ?? "", result: realResult };
5285
5982
  }
5286
- const bootstrapInlineSession = (0, import_react9.useCallback)(
5983
+ const bootstrapInlineSession = (0, import_react10.useCallback)(
5287
5984
  async (patch) => {
5288
5985
  const baseParams = createSessionParamsRef.current;
5289
5986
  if (!baseParams) {
@@ -5344,7 +6041,7 @@ function FloPayCheckout({
5344
6041
  },
5345
6042
  [locale, resolvedBillingUrl]
5346
6043
  );
5347
- const handleInlineSessionPatch = (0, import_react9.useCallback)(async (patch) => {
6044
+ const handleInlineSessionPatch = (0, import_react10.useCallback)(async (patch) => {
5348
6045
  if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) {
5349
6046
  return {
5350
6047
  sessionId: resolvedSessionId,
@@ -5367,7 +6064,7 @@ function FloPayCheckout({
5367
6064
  resolvedSessionId,
5368
6065
  session
5369
6066
  ]);
5370
- (0, import_react9.useEffect)(() => {
6067
+ (0, import_react10.useEffect)(() => {
5371
6068
  let cancelled = false;
5372
6069
  setLoadError(null);
5373
6070
  if (createSessionHash) {
@@ -5533,7 +6230,7 @@ function FloPayCheckout({
5533
6230
  nonceProp,
5534
6231
  runSavedPaymentFlow
5535
6232
  ]);
5536
- const handleConfirmCheckout = (0, import_react9.useCallback)(async () => {
6233
+ const handleConfirmCheckout = (0, import_react10.useCallback)(async () => {
5537
6234
  if (confirmProcessing || !session) return;
5538
6235
  setConfirmProcessing(true);
5539
6236
  setModeError(null);
@@ -5548,7 +6245,7 @@ function FloPayCheckout({
5548
6245
  }, [activeSessionId, confirmProcessing, runSavedPaymentFlow, session]);
5549
6246
  const directPaypalConfig = resolveDirectPaypalConfig(unified);
5550
6247
  const isPaypalOnlySession = isPayPalOnlyUnified(unified);
5551
- const providerOptions = (0, import_react9.useMemo)(() => {
6248
+ const providerOptions = (0, import_react10.useMemo)(() => {
5552
6249
  if (!unified || !session || !unified.data.stripe?.publishableKey) return void 0;
5553
6250
  const opts = {
5554
6251
  appearance,
@@ -5567,7 +6264,7 @@ function FloPayCheckout({
5567
6264
  const shouldHandleInlineSessionPatch = Boolean(
5568
6265
  createSessionParams && !children && layout === "buttons" && onBeforeButtonClick && effectiveCreateSessionMode === "full"
5569
6266
  );
5570
- const checkoutValue = (0, import_react9.useMemo)(
6267
+ const checkoutValue = (0, import_react10.useMemo)(
5571
6268
  () => ({
5572
6269
  session,
5573
6270
  loading: isLoading,
@@ -5589,7 +6286,7 @@ function FloPayCheckout({
5589
6286
  ]
5590
6287
  );
5591
6288
  const shouldShowInterimButtons = Boolean(createSessionParams) && layout === "buttons" && !isPaypalOnlySession && (!flopay || !providerOptions);
5592
- const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6289
+ const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5593
6290
  ProcessingOverlay,
5594
6291
  {
5595
6292
  status: modeOverlayStatus,
@@ -5598,32 +6295,32 @@ function FloPayCheckout({
5598
6295
  ) : null;
5599
6296
  if (isLoading) {
5600
6297
  if (loadingNode) {
5601
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
6298
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
5602
6299
  loadingNode,
5603
6300
  modeOverlay
5604
6301
  ] });
5605
6302
  }
5606
6303
  if (layout === "buttons") {
5607
6304
  const bundleRadius = themeBundle?.buttonsLayout?.cardButton?.borderRadius ?? themeBundle?.appearance.variables?.borderRadius ?? 8;
5608
- const skeletonBar = (h) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
6305
+ const skeletonBar = (h) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
5609
6306
  height: h,
5610
6307
  borderRadius: bundleRadius,
5611
6308
  background: "#e5e7eb",
5612
6309
  animation: "flopay-loading-pulse 1.5s ease-in-out infinite"
5613
6310
  } });
5614
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5615
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
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: [
5616
6313
  showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
5617
6314
  showStripe && (showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
5618
6315
  showStripe && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
5619
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
6316
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
5620
6317
  ] }),
5621
6318
  modeOverlay
5622
6319
  ] });
5623
6320
  }
5624
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5625
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", justifyContent: "center", padding: 32 }, children: [
5626
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
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: {
5627
6324
  width: 24,
5628
6325
  height: 24,
5629
6326
  border: "2px solid #e5e7eb",
@@ -5631,16 +6328,16 @@ function FloPayCheckout({
5631
6328
  borderRadius: "50%",
5632
6329
  animation: "spin 0.6s linear infinite"
5633
6330
  } }),
5634
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
6331
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
5635
6332
  ] }),
5636
6333
  modeOverlay
5637
6334
  ] });
5638
6335
  }
5639
6336
  if (loadError) {
5640
6337
  if (errorNode) {
5641
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: errorNode(loadError) });
6338
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: errorNode(loadError) });
5642
6339
  }
5643
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6340
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5644
6341
  "div",
5645
6342
  {
5646
6343
  role: "alert",
@@ -5656,8 +6353,8 @@ function FloPayCheckout({
5656
6353
  ) });
5657
6354
  }
5658
6355
  if (shouldShowInterimButtons) {
5659
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5660
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
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)(
5661
6358
  InterimButtonsView,
5662
6359
  {
5663
6360
  onButtonClick,
@@ -5677,9 +6374,9 @@ function FloPayCheckout({
5677
6374
  ] });
5678
6375
  }
5679
6376
  if (isPaypalOnlySession && session && directPaypalConfig) {
5680
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5681
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className, style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
5682
- modeError && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
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)(
5683
6380
  "div",
5684
6381
  {
5685
6382
  role: "alert",
@@ -5696,7 +6393,7 @@ function FloPayCheckout({
5696
6393
  children: modeError
5697
6394
  }
5698
6395
  ),
5699
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6396
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5700
6397
  DirectPayPalButton,
5701
6398
  {
5702
6399
  sessionId: activeSessionId,
@@ -5720,12 +6417,12 @@ function FloPayCheckout({
5720
6417
  ] });
5721
6418
  }
5722
6419
  if (!flopay || !providerOptions) {
5723
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: modeOverlay });
6420
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: modeOverlay });
5724
6421
  }
5725
6422
  if (currentMode === "confirm") {
5726
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5727
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className, children: [
5728
- modeError && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
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)(
5729
6426
  "div",
5730
6427
  {
5731
6428
  style: {
@@ -5740,7 +6437,7 @@ function FloPayCheckout({
5740
6437
  renderConfirmButton ? renderConfirmButton({
5741
6438
  onConfirm: handleConfirmCheckout,
5742
6439
  isProcessing: confirmProcessing
5743
- }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6440
+ }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5744
6441
  "button",
5745
6442
  {
5746
6443
  type: "button",
@@ -5765,9 +6462,9 @@ function FloPayCheckout({
5765
6462
  modeOverlay
5766
6463
  ] });
5767
6464
  }
5768
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5769
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: children ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5770
- modeError && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
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)(
5771
6468
  "div",
5772
6469
  {
5773
6470
  style: {
@@ -5782,7 +6479,7 @@ function FloPayCheckout({
5782
6479
  children: modeError
5783
6480
  }
5784
6481
  ),
5785
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6482
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5786
6483
  SessionInjector,
5787
6484
  {
5788
6485
  sessionId: activeSessionId,
@@ -5792,7 +6489,7 @@ function FloPayCheckout({
5792
6489
  children
5793
6490
  }
5794
6491
  )
5795
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6492
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5796
6493
  SplitCardForm,
5797
6494
  {
5798
6495
  sessionId: activeSessionId,
@@ -5812,6 +6509,7 @@ function FloPayCheckout({
5812
6509
  showPayPal,
5813
6510
  showStripe,
5814
6511
  enabledPaymentMethods: unified?.data.stripe?.enabledPaymentMethods,
6512
+ enabledPaymentMethodCountries: unified?.data.stripe?.enabledPaymentMethodCountries,
5815
6513
  showApplePay,
5816
6514
  showGooglePay,
5817
6515
  layout,
@@ -5825,6 +6523,8 @@ function FloPayCheckout({
5825
6523
  onButtonClick,
5826
6524
  onBeforeButtonClick,
5827
6525
  enableAVS,
6526
+ ...cardFieldOrder ? { cardFieldOrder } : {},
6527
+ ...cardPreFormSlot ? { cardPreFormSlot } : {},
5828
6528
  avsLayout,
5829
6529
  country: session?.customer?.country,
5830
6530
  city: session?.customer?.city,
@@ -5852,8 +6552,8 @@ function SessionInjector({
5852
6552
  session,
5853
6553
  children
5854
6554
  }) {
5855
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: import_react9.default.Children.map(children, (child) => {
5856
- if (!import_react9.default.isValidElement(child)) return child;
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;
5857
6557
  const existing = child.props;
5858
6558
  const injected = {};
5859
6559
  if (!existing.sessionId) injected.sessionId = sessionId;
@@ -5868,7 +6568,7 @@ function SessionInjector({
5868
6568
  injected.lastName = session.customer.lastName;
5869
6569
  }
5870
6570
  if (Object.keys(injected).length === 0) return child;
5871
- return import_react9.default.cloneElement(child, injected);
6571
+ return import_react10.default.cloneElement(child, injected);
5872
6572
  }) });
5873
6573
  }
5874
6574
  function InterimButtonsView({
@@ -5888,15 +6588,15 @@ function InterimButtonsView({
5888
6588
  cardBackButtonContent,
5889
6589
  cardTitleContent
5890
6590
  }) {
5891
- const [showCardForm, setShowCardForm] = (0, import_react9.useState)(false);
6591
+ const [showCardForm, setShowCardForm] = (0, import_react10.useState)(false);
5892
6592
  const isCardOpenControlled = typeof cardOpen === "boolean";
5893
- (0, import_react9.useEffect)(() => {
6593
+ (0, import_react10.useEffect)(() => {
5894
6594
  if (isCardOpenControlled) {
5895
6595
  setShowCardForm(cardOpen);
5896
6596
  }
5897
6597
  }, [cardOpen, isCardOpenControlled]);
5898
- const themeBundle = (0, import_react9.useMemo)(() => (0, import_shared8.resolveTheme)(theme), [theme]);
5899
- const bStyles = (0, import_react9.useMemo)(() => {
6598
+ const themeBundle = (0, import_react10.useMemo)(() => (0, import_shared8.resolveTheme)(theme), [theme]);
6599
+ const bStyles = (0, import_react10.useMemo)(() => {
5900
6600
  const base = themeBundle?.buttonsLayout ?? (0, import_shared8.resolveButtonsLayoutTheme)(buttonsTheme);
5901
6601
  if (!stylesOverride) return base;
5902
6602
  return {
@@ -5911,7 +6611,7 @@ function InterimButtonsView({
5911
6611
  };
5912
6612
  }, [themeBundle, buttonsTheme, stylesOverride]);
5913
6613
  const skeletonRadius = themeBundle?.buttonsLayout?.cardButton?.borderRadius ?? themeBundle?.appearance.variables?.borderRadius ?? 8;
5914
- const skeleton = (h) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
6614
+ const skeleton = (h) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
5915
6615
  height: h,
5916
6616
  borderRadius: skeletonRadius,
5917
6617
  background: "#e5e7eb",
@@ -5923,15 +6623,15 @@ function InterimButtonsView({
5923
6623
  const inputBg = bStyles.cardInputBackground ?? "white";
5924
6624
  const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);
5925
6625
  const hideTitle = isEmptySlotContent(cardTitleContent);
5926
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
6626
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: {
5927
6627
  backgroundColor: bStyles.cardFormContainer?.backgroundColor ?? "white",
5928
6628
  borderRadius: "8px",
5929
6629
  animation: "flopay-interim-expand 0.35s cubic-bezier(0.4, 0, 0.2, 1) both",
5930
6630
  overflow: "hidden",
5931
6631
  ...bStyles.cardFormContainer
5932
6632
  }, children: [
5933
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", padding: "0.75rem 0 0.625rem" }, children: [
5934
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
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)(
5935
6635
  "button",
5936
6636
  {
5937
6637
  type: "button",
@@ -5958,7 +6658,7 @@ function InterimButtonsView({
5958
6658
  ...bStyles.backButton
5959
6659
  },
5960
6660
  children: [
5961
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
6661
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: {
5962
6662
  display: "inline-flex",
5963
6663
  alignItems: "center",
5964
6664
  justifyContent: "center",
@@ -5967,12 +6667,12 @@ function InterimButtonsView({
5967
6667
  borderRadius: "50%",
5968
6668
  backgroundColor: "#f3f4f6",
5969
6669
  ...bStyles.backButtonIcon
5970
- }, 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" }) }) }),
5971
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BackButtonContentSlot, { content: cardBackButtonContent })
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 })
5972
6672
  ]
5973
6673
  }
5974
6674
  ),
5975
- hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
6675
+ hideTitle ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { flex: 1 } }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: {
5976
6676
  flex: 1,
5977
6677
  textAlign: "center",
5978
6678
  fontWeight: 600,
@@ -5980,11 +6680,11 @@ function InterimButtonsView({
5980
6680
  color: "#262833",
5981
6681
  paddingRight: 80,
5982
6682
  ...bStyles.title
5983
- }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TitleContentSlot, { content: cardTitleContent }) })
6683
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TitleContentSlot, { content: cardTitleContent }) })
5984
6684
  ] }),
5985
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { width: "60%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
5986
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex" }, children: [
5987
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
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: {
5988
6688
  flex: 1,
5989
6689
  backgroundColor: inputBg,
5990
6690
  borderTop: "none",
@@ -5994,8 +6694,8 @@ function InterimButtonsView({
5994
6694
  borderBottomLeftRadius: 8,
5995
6695
  padding: 12,
5996
6696
  height: 45
5997
- }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { width: "50%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
5998
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
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: {
5999
6699
  flex: 1,
6000
6700
  backgroundColor: inputBg,
6001
6701
  borderTop: "none",
@@ -6005,10 +6705,10 @@ function InterimButtonsView({
6005
6705
  borderBottomRightRadius: 8,
6006
6706
  padding: 12,
6007
6707
  height: 45
6008
- }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { width: "40%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) })
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" } }) })
6009
6709
  ] }),
6010
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { width: "45%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
6011
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
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: {
6012
6712
  height: 50,
6013
6713
  borderRadius: 8,
6014
6714
  marginTop: 16,
@@ -6017,7 +6717,7 @@ function InterimButtonsView({
6017
6717
  ...bStyles.submitButton,
6018
6718
  opacity: 0.5
6019
6719
  } }),
6020
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
6720
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `
6021
6721
  @keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
6022
6722
  @keyframes flopay-interim-expand {
6023
6723
  0% { opacity: 0; max-height: 0; transform: translateY(-12px); }
@@ -6027,10 +6727,10 @@ function InterimButtonsView({
6027
6727
  ` })
6028
6728
  ] });
6029
6729
  }
6030
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
6730
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
6031
6731
  showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
6032
6732
  showStripe && (showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
6033
- showStripe && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6733
+ showStripe && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6034
6734
  "button",
6035
6735
  {
6036
6736
  type: "button",
@@ -6070,10 +6770,10 @@ function InterimButtonsView({
6070
6770
  onMouseUp: (e) => {
6071
6771
  e.currentTarget.style.transform = "scale(1)";
6072
6772
  },
6073
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardButtonContentSlot, { content: cardButtonContent })
6773
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CardButtonContentSlot, { content: cardButtonContent })
6074
6774
  }
6075
6775
  ),
6076
- errorMessage && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
6776
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: {
6077
6777
  margin: "0.25rem 0",
6078
6778
  padding: "0.625rem 0.875rem",
6079
6779
  background: "#FEF2F2",
@@ -6087,22 +6787,22 @@ function InterimButtonsView({
6087
6787
  gap: "0.5rem",
6088
6788
  ...bStyles.errorBanner
6089
6789
  }, children: [
6090
- /* @__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" }) }),
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" }) }),
6091
6791
  errorMessage
6092
6792
  ] }),
6093
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
6793
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
6094
6794
  ] });
6095
6795
  }
6096
6796
 
6097
6797
  // src/checkout-form.tsx
6098
6798
  var import_js5 = require("@flopay/js");
6099
6799
  var import_shared9 = require("@flopay/shared");
6100
- var import_react10 = require("react");
6101
- var import_jsx_runtime8 = require("react/jsx-runtime");
6800
+ var import_react11 = require("react");
6801
+ var import_jsx_runtime9 = require("react/jsx-runtime");
6102
6802
  var WALLET_RESUME_KEY = "flopay_wallet_resume";
6103
- var CheckoutForm = (0, import_react10.forwardRef)(
6803
+ var CheckoutForm = (0, import_react11.forwardRef)(
6104
6804
  function CheckoutForm2(props, ref) {
6105
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckoutFormInner, { ...props, innerRef: ref });
6805
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CheckoutFormInner, { ...props, innerRef: ref });
6106
6806
  }
6107
6807
  );
6108
6808
  function CheckoutFormInner({
@@ -6132,27 +6832,27 @@ function CheckoutFormInner({
6132
6832
  const paypalFlopay = usePayPalFloPay();
6133
6833
  const elements = useElements();
6134
6834
  const contextBillingUrl = useBillingApiUrl();
6135
- const [processing, setProcessing] = (0, import_react10.useState)(false);
6136
- const [error, setError] = (0, import_react10.useState)(null);
6137
- const [is3DSActive, setIs3DSActive] = (0, import_react10.useState)(false);
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);
6138
6838
  const displayError = externalError ?? error;
6139
6839
  const isSubmitting = externalProcessing ?? processing;
6140
6840
  const isSelfContained = !onTokenizedBody;
6141
6841
  const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
6142
- const updateError = (0, import_react10.useCallback)(
6842
+ const updateError = (0, import_react11.useCallback)(
6143
6843
  (err) => {
6144
6844
  setError(err);
6145
6845
  onErrorChange?.(err);
6146
6846
  },
6147
6847
  [onErrorChange]
6148
6848
  );
6149
- const emitDecline = (0, import_react10.useCallback)(
6849
+ const emitDecline = (0, import_react11.useCallback)(
6150
6850
  (input, overrides) => {
6151
6851
  onDecline?.(buildDeclineEvent("card", input, overrides));
6152
6852
  },
6153
6853
  [onDecline]
6154
6854
  );
6155
- const processPaymentInternal = (0, import_react10.useCallback)(
6855
+ const processPaymentInternal = (0, import_react11.useCallback)(
6156
6856
  async (tokenizedBody, completionPaymentMethodId) => {
6157
6857
  setProcessing(true);
6158
6858
  updateError(null);
@@ -6264,7 +6964,7 @@ function CheckoutFormInner({
6264
6964
  },
6265
6965
  [baseUrl, sessionId, nonce, userId, email, firstName, lastName, chv, flopay, paypalFlopay, onComplete, onError, onDecline, updateError, emitDecline]
6266
6966
  );
6267
- const dispatchTokenizedBody = (0, import_react10.useCallback)(
6967
+ const dispatchTokenizedBody = (0, import_react11.useCallback)(
6268
6968
  (tokenizedBody) => {
6269
6969
  if (onTokenizedBody) {
6270
6970
  onTokenizedBody(tokenizedBody);
@@ -6274,7 +6974,7 @@ function CheckoutFormInner({
6274
6974
  },
6275
6975
  [onTokenizedBody, processPaymentInternal]
6276
6976
  );
6277
- (0, import_react10.useImperativeHandle)(innerRef, () => ({
6977
+ (0, import_react11.useImperativeHandle)(innerRef, () => ({
6278
6978
  async handleNextAction(secret) {
6279
6979
  if (!flopay) return;
6280
6980
  setIs3DSActive(true);
@@ -6301,7 +7001,7 @@ function CheckoutFormInner({
6301
7001
  }
6302
7002
  }
6303
7003
  }), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
6304
- (0, import_react10.useEffect)(() => {
7004
+ (0, import_react11.useEffect)(() => {
6305
7005
  if (typeof window === "undefined") return;
6306
7006
  const stored = localStorage.getItem(WALLET_RESUME_KEY);
6307
7007
  if (!stored) return;
@@ -6319,7 +7019,7 @@ function CheckoutFormInner({
6319
7019
  localStorage.removeItem(WALLET_RESUME_KEY);
6320
7020
  }
6321
7021
  }, [sessionId, dispatchTokenizedBody]);
6322
- const handleSubmit = (0, import_react10.useCallback)(
7022
+ const handleSubmit = (0, import_react11.useCallback)(
6323
7023
  async (e) => {
6324
7024
  e.preventDefault();
6325
7025
  if (!flopay || !elements || isSubmitting) return;
@@ -6411,8 +7111,8 @@ function CheckoutFormInner({
6411
7111
  [flopay, elements, isSubmitting, sessionId, nonce, email, firstName, lastName, baseUrl, isSelfContained, dispatchTokenizedBody, onError, updateError, emitDecline]
6412
7112
  );
6413
7113
  const isReady = flopay !== null && elements !== null;
6414
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
6415
- (is3DSActive || isSubmitting) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { "data-testid": "flopay-overlay", style: {
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: {
6416
7116
  position: "absolute",
6417
7117
  inset: 0,
6418
7118
  background: "rgba(255,255,255,0.7)",
@@ -6421,12 +7121,12 @@ function CheckoutFormInner({
6421
7121
  justifyContent: "center",
6422
7122
  zIndex: 10
6423
7123
  }, children: is3DSActive ? "Verifying payment..." : "Processing..." }),
6424
- !isReady && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." }),
6425
- isReady && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
6426
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaymentElement, { options: { layout } }),
6427
- showAddress && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AddressElement, { options: { mode: showAddress === true ? "billing" : showAddress } }),
6428
- displayError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0" }, children: displayError }),
6429
- children ?? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
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)(
6430
7130
  "button",
6431
7131
  {
6432
7132
  type: "submit",
@@ -6442,8 +7142,8 @@ function CheckoutFormInner({
6442
7142
  // src/paypal-button.tsx
6443
7143
  var import_js6 = require("@flopay/js");
6444
7144
  var import_shared10 = require("@flopay/shared");
6445
- var import_react11 = require("react");
6446
- var import_jsx_runtime9 = require("react/jsx-runtime");
7145
+ var import_react12 = require("react");
7146
+ var import_jsx_runtime10 = require("react/jsx-runtime");
6447
7147
  function PayPalButton({
6448
7148
  sessionId,
6449
7149
  nonce,
@@ -6461,11 +7161,11 @@ function PayPalButton({
6461
7161
  const flopay = useFloPay();
6462
7162
  const elements = useElements();
6463
7163
  const contextBillingUrl = useBillingApiUrl();
6464
- const [ready, setReady] = (0, import_react11.useState)(false);
6465
- const [submitting, setSubmitting] = (0, import_react11.useState)(false);
6466
- const paypalResumeAttempted = (0, import_react11.useRef)(false);
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);
6467
7167
  const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
6468
- const processPaymentInternal = (0, import_react11.useCallback)(
7168
+ const processPaymentInternal = (0, import_react12.useCallback)(
6469
7169
  async (tokenizedBody) => {
6470
7170
  try {
6471
7171
  const api = new import_js6.PaymentAPI(baseUrl);
@@ -6493,7 +7193,7 @@ function PayPalButton({
6493
7193
  },
6494
7194
  [baseUrl, sessionId, nonce, userId, email, firstName, lastName, chv, onComplete, onErrorChange]
6495
7195
  );
6496
- const dispatchTokenizedBody = (0, import_react11.useCallback)(
7196
+ const dispatchTokenizedBody = (0, import_react12.useCallback)(
6497
7197
  (body) => {
6498
7198
  if (onTokenizedBody) {
6499
7199
  onTokenizedBody(body);
@@ -6503,7 +7203,7 @@ function PayPalButton({
6503
7203
  },
6504
7204
  [onTokenizedBody, processPaymentInternal]
6505
7205
  );
6506
- (0, import_react11.useEffect)(() => {
7206
+ (0, import_react12.useEffect)(() => {
6507
7207
  if (!flopay || paypalResumeAttempted.current) return;
6508
7208
  const params = new URLSearchParams(window.location.search);
6509
7209
  const paymentIntentId = params.get("payment_intent");
@@ -6551,7 +7251,7 @@ function PayPalButton({
6551
7251
  }
6552
7252
  })();
6553
7253
  }, [flopay, dispatchTokenizedBody, onErrorChange]);
6554
- const handlePayPalConfirm = (0, import_react11.useCallback)(async () => {
7254
+ const handlePayPalConfirm = (0, import_react12.useCallback)(async () => {
6555
7255
  if (!flopay || !elements) return;
6556
7256
  try {
6557
7257
  setSubmitting(true);
@@ -6585,11 +7285,11 @@ function PayPalButton({
6585
7285
  }
6586
7286
  }, [flopay, elements, sessionId, nonce, email, baseUrl, dispatchTokenizedBody, onErrorChange]);
6587
7287
  if (!flopay || !elements) {
6588
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6, animation: "pulse 1.5s infinite" } });
7288
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6, animation: "pulse 1.5s infinite" } });
6589
7289
  }
6590
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
6591
- !ready && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6 } }),
6592
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: ready ? {} : { display: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
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)(
6593
7293
  "button",
6594
7294
  {
6595
7295
  type: "button",
@@ -6611,7 +7311,7 @@ function PayPalButton({
6611
7311
  children: submitting ? "Processing..." : "PayPal"
6612
7312
  }
6613
7313
  ) }),
6614
- (submitting || isProcessing) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: {
7314
+ (submitting || isProcessing) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: {
6615
7315
  position: "fixed",
6616
7316
  inset: 0,
6617
7317
  background: "rgba(0,0,0,0.4)",
@@ -6619,7 +7319,7 @@ function PayPalButton({
6619
7319
  alignItems: "center",
6620
7320
  justifyContent: "center",
6621
7321
  zIndex: 1e3
6622
- }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: {
7322
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: {
6623
7323
  background: "white",
6624
7324
  borderRadius: 8,
6625
7325
  padding: "1.5rem",
@@ -6631,10 +7331,10 @@ function PayPalButton({
6631
7331
  }
6632
7332
 
6633
7333
  // src/automatic-payment-button.tsx
6634
- var import_react12 = require("react");
7334
+ var import_react13 = require("react");
6635
7335
  var import_js7 = require("@flopay/js");
6636
7336
  var import_shared11 = require("@flopay/shared");
6637
- var import_jsx_runtime10 = require("react/jsx-runtime");
7337
+ var import_jsx_runtime11 = require("react/jsx-runtime");
6638
7338
  var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3 = 44;
6639
7339
  function sleep2(ms) {
6640
7340
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -6702,6 +7402,7 @@ function FloPayAutomaticPaymentButton({
6702
7402
  billingApiUrl,
6703
7403
  locale,
6704
7404
  theme,
7405
+ appearance,
6705
7406
  buttonsTheme,
6706
7407
  buttonsStyles: stylesOverride,
6707
7408
  onSuccess,
@@ -6713,11 +7414,11 @@ function FloPayAutomaticPaymentButton({
6713
7414
  style,
6714
7415
  ...buttonProps
6715
7416
  }) {
6716
- const resolvedBillingUrl = (0, import_react12.useMemo)(
7417
+ const resolvedBillingUrl = (0, import_react13.useMemo)(
6717
7418
  () => (0, import_shared11.resolveBillingApiUrl)(billingApiUrl),
6718
7419
  [billingApiUrl]
6719
7420
  );
6720
- const createSessionDraft = (0, import_react12.useMemo)(
7421
+ const createSessionDraft = (0, import_react13.useMemo)(
6721
7422
  () => resolveCreateSessionDraft({
6722
7423
  createSession,
6723
7424
  clientId,
@@ -6745,34 +7446,36 @@ function FloPayAutomaticPaymentButton({
6745
7446
  utmMetadata
6746
7447
  ]
6747
7448
  );
6748
- const [isProcessing, setIsProcessing] = (0, import_react12.useState)(false);
6749
- const [overlayStatus, setOverlayStatus] = (0, import_react12.useState)(null);
6750
- const [overlayError, setOverlayError] = (0, import_react12.useState)(null);
6751
- const [fallbackSession, setFallbackSession] = (0, import_react12.useState)(null);
6752
- const isMountedRef = (0, import_react12.useRef)(true);
6753
- const fallbackSessionRef = (0, import_react12.useRef)(fallbackSession);
6754
- const onSuccessRef = (0, import_react12.useRef)(onSuccess);
6755
- const onErrorRef = (0, import_react12.useRef)(onError);
6756
- const onDeclineRef = (0, import_react12.useRef)(onDecline);
6757
- (0, import_react12.useEffect)(() => {
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)(() => {
6758
7460
  fallbackSessionRef.current = fallbackSession;
6759
7461
  }, [fallbackSession]);
6760
- (0, import_react12.useEffect)(() => {
7462
+ (0, import_react13.useEffect)(() => {
6761
7463
  onSuccessRef.current = onSuccess;
6762
7464
  }, [onSuccess]);
6763
- (0, import_react12.useEffect)(() => {
7465
+ (0, import_react13.useEffect)(() => {
6764
7466
  onErrorRef.current = onError;
6765
7467
  }, [onError]);
6766
- (0, import_react12.useEffect)(() => {
7468
+ (0, import_react13.useEffect)(() => {
6767
7469
  onDeclineRef.current = onDecline;
6768
7470
  }, [onDecline]);
6769
- (0, import_react12.useEffect)(() => {
7471
+ (0, import_react13.useEffect)(() => {
6770
7472
  isMountedRef.current = true;
6771
7473
  return () => {
6772
7474
  isMountedRef.current = false;
7475
+ threeDsAbortRef.current?.abort();
6773
7476
  };
6774
7477
  }, []);
6775
- (0, import_react12.useEffect)(() => {
7478
+ (0, import_react13.useEffect)(() => {
6776
7479
  if (!fallbackSession || typeof window === "undefined") {
6777
7480
  return;
6778
7481
  }
@@ -6786,13 +7489,13 @@ function FloPayAutomaticPaymentButton({
6786
7489
  window.removeEventListener("keydown", handleKeyDown);
6787
7490
  };
6788
7491
  }, [fallbackSession]);
6789
- const emitDecline = (0, import_react12.useCallback)((error, method = DEFAULT_SAVED_PAYMENT_DECLINE_METHOD) => {
7492
+ const emitDecline = (0, import_react13.useCallback)((error, method = DEFAULT_SAVED_PAYMENT_DECLINE_METHOD) => {
6790
7493
  onDeclineRef.current?.(buildDeclineEvent(method, error, {
6791
7494
  code: error.code,
6792
7495
  declineCode: error.declineCode
6793
7496
  }));
6794
7497
  }, []);
6795
- const showSuccess = (0, import_react12.useCallback)(async (event) => {
7498
+ const showSuccess = (0, import_react13.useCallback)(async (event) => {
6796
7499
  if (!isMountedRef.current) return;
6797
7500
  setOverlayError(null);
6798
7501
  setOverlayStatus("success");
@@ -6800,7 +7503,7 @@ function FloPayAutomaticPaymentButton({
6800
7503
  if (!isMountedRef.current) return;
6801
7504
  onSuccessRef.current?.(event);
6802
7505
  }, []);
6803
- const showError = (0, import_react12.useCallback)(async (error, options) => {
7506
+ const showError = (0, import_react13.useCallback)(async (error, options) => {
6804
7507
  if (!isMountedRef.current) return;
6805
7508
  onErrorRef.current?.(error);
6806
7509
  if (options?.emitDecline) {
@@ -6810,7 +7513,7 @@ function FloPayAutomaticPaymentButton({
6810
7513
  setOverlayStatus("error");
6811
7514
  await sleep2(PROCESSING_OVERLAY_ERROR_DELAY_MS);
6812
7515
  }, [emitDecline]);
6813
- const processResolvedSession = (0, import_react12.useCallback)(async (apiResult, resolvedSessionId, options) => {
7516
+ const processResolvedSession = (0, import_react13.useCallback)(async (apiResult, resolvedSessionId, options) => {
6814
7517
  const session = apiResult.data.session ?? null;
6815
7518
  if (!session) {
6816
7519
  throw new import_shared11.FloPayError("No session data returned", "api_error");
@@ -6851,6 +7554,62 @@ function FloPayAutomaticPaymentButton({
6851
7554
  return;
6852
7555
  }
6853
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
+ }
6854
7613
  throw checkoutProcessErrorToFloPayError(
6855
7614
  apiResult.autoProcessingError,
6856
7615
  "Automatic payment failed. Please try again.",
@@ -6910,7 +7669,7 @@ function FloPayAutomaticPaymentButton({
6910
7669
  showError,
6911
7670
  showSuccess
6912
7671
  ]);
6913
- const handleButtonClick = (0, import_react12.useCallback)(async (event) => {
7672
+ const handleButtonClick = (0, import_react13.useCallback)(async (event) => {
6914
7673
  buttonProps.onClick?.(event);
6915
7674
  if (event.defaultPrevented || disabled || isProcessing) {
6916
7675
  return;
@@ -6992,7 +7751,7 @@ function FloPayAutomaticPaymentButton({
6992
7751
  showError,
6993
7752
  showSuccess
6994
7753
  ]);
6995
- const handleFallbackComplete = (0, import_react12.useCallback)((result) => {
7754
+ const handleFallbackComplete = (0, import_react13.useCallback)((result) => {
6996
7755
  const activeFallback = fallbackSessionRef.current;
6997
7756
  setFallbackSession(null);
6998
7757
  onSuccessRef.current?.({
@@ -7002,14 +7761,14 @@ function FloPayAutomaticPaymentButton({
7002
7761
  autoCompleted: false
7003
7762
  });
7004
7763
  }, []);
7005
- const handleFallbackError = (0, import_react12.useCallback)((error) => {
7764
+ const handleFallbackError = (0, import_react13.useCallback)((error) => {
7006
7765
  onErrorRef.current?.(error);
7007
7766
  }, []);
7008
- const handleFallbackDecline = (0, import_react12.useCallback)((decline) => {
7767
+ const handleFallbackDecline = (0, import_react13.useCallback)((decline) => {
7009
7768
  onDeclineRef.current?.(decline);
7010
7769
  }, []);
7011
- const themeBundle = (0, import_react12.useMemo)(() => (0, import_shared11.resolveTheme)(theme), [theme]);
7012
- const bStyles = (0, import_react12.useMemo)(() => {
7770
+ const themeBundle = (0, import_react13.useMemo)(() => (0, import_shared11.resolveTheme)(theme), [theme]);
7771
+ const bStyles = (0, import_react13.useMemo)(() => {
7013
7772
  const base = themeBundle?.buttonsLayout ?? (0, import_shared11.resolveButtonsLayoutTheme)(buttonsTheme);
7014
7773
  if (!stylesOverride) return base;
7015
7774
  return {
@@ -7018,9 +7777,26 @@ function FloPayAutomaticPaymentButton({
7018
7777
  cardButton: { ...base.cardButton, ...stylesOverride.cardButton }
7019
7778
  };
7020
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";
7021
7797
  const cardButtonSizing = children === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
7022
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
7023
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
7798
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
7799
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
7024
7800
  "button",
7025
7801
  {
7026
7802
  ...buttonProps,
@@ -7036,14 +7812,17 @@ function FloPayAutomaticPaymentButton({
7036
7812
  // on top so the auto-pay button carries the *submit* button's
7037
7813
  // background and text colours — making it visually identical to
7038
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.
7039
7817
  // Inline `style` consumer override stays at the end so explicit
7040
7818
  // per-button overrides still win.
7041
7819
  ...bStyles.cardButton,
7042
7820
  ...derivePrimaryTileStyle({
7043
7821
  themeBundle,
7044
- resolvedPrimaryColor: themeBundle?.appearance.variables?.colorPrimary ?? "#4A49FF",
7045
- resolvedBorderRadius: themeBundle?.appearance.variables?.borderRadius ?? "8px",
7046
- submitButtonStyle: bStyles.submitButton
7822
+ resolvedPrimaryColor,
7823
+ resolvedBorderRadius: resolvedButtonBorderRadius,
7824
+ submitButtonStyle: bStyles.submitButton,
7825
+ explicitPrimaryColor: resolvedAppearanceVars?.colorPrimary
7047
7826
  }),
7048
7827
  fontSize: bStyles.cardButtonFontSize ?? "0.95rem",
7049
7828
  fontWeight: 600,
@@ -7052,11 +7831,23 @@ function FloPayAutomaticPaymentButton({
7052
7831
  alignItems: "center",
7053
7832
  justifyContent: "center",
7054
7833
  gap: "0.625rem",
7055
- 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",
7056
7835
  position: "relative",
7057
7836
  opacity: disabled || isProcessing ? 0.6 : 1,
7058
7837
  ...style
7059
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
+ },
7060
7851
  onMouseDown: (e) => {
7061
7852
  buttonProps.onMouseDown?.(e);
7062
7853
  if (!e.defaultPrevented) {
@@ -7069,17 +7860,17 @@ function FloPayAutomaticPaymentButton({
7069
7860
  e.currentTarget.style.transform = "scale(1)";
7070
7861
  }
7071
7862
  },
7072
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CardButtonContentSlot, { content: children })
7863
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CardButtonContentSlot, { content: children })
7073
7864
  }
7074
7865
  ),
7075
- overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
7866
+ overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
7076
7867
  ProcessingOverlay,
7077
7868
  {
7078
7869
  status: overlayStatus,
7079
7870
  errorMessage: overlayError
7080
7871
  }
7081
7872
  ),
7082
- fallbackSession && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
7873
+ fallbackSession && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
7083
7874
  "div",
7084
7875
  {
7085
7876
  "data-testid": "flopay-automatic-payment-fallback",
@@ -7100,7 +7891,7 @@ function FloPayAutomaticPaymentButton({
7100
7891
  padding: "1.5rem",
7101
7892
  zIndex: 1100
7102
7893
  },
7103
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
7894
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
7104
7895
  "div",
7105
7896
  {
7106
7897
  style: {
@@ -7116,7 +7907,7 @@ function FloPayAutomaticPaymentButton({
7116
7907
  flexDirection: "column",
7117
7908
  gap: "1rem"
7118
7909
  },
7119
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
7910
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
7120
7911
  FloPayCheckout,
7121
7912
  {
7122
7913
  sessionId: fallbackSession.sessionId,
@@ -7125,6 +7916,7 @@ function FloPayAutomaticPaymentButton({
7125
7916
  billingApiUrl: resolvedBillingUrl,
7126
7917
  locale,
7127
7918
  theme,
7919
+ ...resolvedAppearance ? { appearance: resolvedAppearance } : {},
7128
7920
  buttonsTheme,
7129
7921
  buttonsStyles: stylesOverride,
7130
7922
  initialErrorMessage: fallbackSession.errorMessage,
@@ -7155,6 +7947,7 @@ function FloPayAutomaticPaymentButton({
7155
7947
  PayPalButton,
7156
7948
  PaymentElement,
7157
7949
  SplitCardForm,
7950
+ VaultCardFields,
7158
7951
  useCheckout,
7159
7952
  useElements,
7160
7953
  useFloPay,