@flopay/react 1.3.4 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/provider.tsx
2
- import { useEffect, useState, useMemo } from "react";
2
+ import { useCallback, useEffect, useState, useMemo, useRef } from "react";
3
3
  import { resolveBillingApiUrl } from "@flopay/shared";
4
4
 
5
5
  // src/context.ts
@@ -16,6 +16,59 @@ var CheckoutContext = createContext({
16
16
  error: null
17
17
  });
18
18
 
19
+ // src/telemetry-bridge.ts
20
+ var FLOPAY_TELEMETRY_BRIDGE = /* @__PURE__ */ Symbol.for("@flopay/js.telemetry.bridge.v1");
21
+ var TELEMETRY_REPORTER_FACTORY = /* @__PURE__ */ Symbol.for("@flopay/js.telemetry.reporter-factory.v1");
22
+ function noopTelemetryBridge() {
23
+ return {
24
+ error: () => {
25
+ },
26
+ log: () => {
27
+ },
28
+ performance: () => {
29
+ },
30
+ terminal: () => {
31
+ },
32
+ now: () => globalThis.performance?.now() ?? 0,
33
+ elapsed: (startedAt) => Math.max(0, (globalThis.performance?.now() ?? startedAt) - startedAt),
34
+ setCheckoutContext: () => {
35
+ },
36
+ beginCheckout: () => globalThis.performance?.now() ?? 0,
37
+ disable: () => {
38
+ },
39
+ flush: async () => {
40
+ },
41
+ destroy: () => {
42
+ }
43
+ };
44
+ }
45
+ function normalizeTelemetryBridge(source) {
46
+ const fallback = noopTelemetryBridge();
47
+ const bind = (candidate, defaultValue) => candidate ? candidate.bind(source) : defaultValue;
48
+ const now = bind(source.now, fallback.now);
49
+ return {
50
+ error: bind(source.error, fallback.error),
51
+ log: bind(source.log, fallback.log),
52
+ performance: bind(source.performance, fallback.performance),
53
+ terminal: bind(source.terminal, fallback.terminal),
54
+ now,
55
+ elapsed: source.elapsed ? source.elapsed.bind(source) : (startedAt) => Math.max(0, now() - startedAt),
56
+ setCheckoutContext: bind(source.setCheckoutContext, fallback.setCheckoutContext),
57
+ beginCheckout: bind(source.beginCheckout, fallback.beginCheckout),
58
+ disable: bind(source.disable, fallback.disable),
59
+ flush: bind(source.flush, fallback.flush),
60
+ destroy: bind(source.destroy, fallback.destroy)
61
+ };
62
+ }
63
+ function createTelemetryBridge(options) {
64
+ const factory = globalThis[TELEMETRY_REPORTER_FACTORY];
65
+ return normalizeTelemetryBridge(factory?.(options) ?? {});
66
+ }
67
+ function getFloPayTelemetryBridge(floPay) {
68
+ if (!floPay) return void 0;
69
+ return floPay[FLOPAY_TELEMETRY_BRIDGE];
70
+ }
71
+
19
72
  // src/provider.tsx
20
73
  import { jsx } from "react/jsx-runtime";
21
74
  function FloPayProvider({
@@ -31,6 +84,18 @@ function FloPayProvider({
31
84
  paypalFloPayProp instanceof Promise || !paypalFloPayProp ? null : paypalFloPayProp
32
85
  );
33
86
  const [elements, setElements] = useState(null);
87
+ const mountedAt = useRef(null);
88
+ const renderedElements = useRef(null);
89
+ const interactiveElements = useRef(null);
90
+ useEffect(() => {
91
+ if (!flopay) return;
92
+ const telemetry = getFloPayTelemetryBridge(flopay);
93
+ mountedAt.current = telemetry?.beginCheckout() ?? telemetry?.now() ?? 0;
94
+ telemetry?.log({ name: "checkout.mount", stage: "checkout_mount" });
95
+ return () => {
96
+ telemetry?.log({ name: "checkout.unmount", stage: "unmount" });
97
+ };
98
+ }, [flopay]);
34
99
  useEffect(() => {
35
100
  let cancelled = false;
36
101
  if (floPayProp instanceof Promise) {
@@ -91,18 +156,46 @@ function FloPayProvider({
91
156
  options?.paymentMethodCreation,
92
157
  options?.setupFutureUsage
93
158
  ]);
159
+ useEffect(() => {
160
+ if (!flopay || !elements || renderedElements.current === elements) return;
161
+ renderedElements.current = elements;
162
+ const telemetry = getFloPayTelemetryBridge(flopay);
163
+ telemetry?.log({ name: "checkout.rendered", stage: "checkout_render" });
164
+ telemetry?.performance({
165
+ stage: "checkout_render",
166
+ durationMs: telemetry.elapsed(mountedAt.current ?? 0),
167
+ durationMode: "machine"
168
+ });
169
+ }, [elements, flopay]);
170
+ const reportInteractive = useCallback(() => {
171
+ if (!flopay || !elements || interactiveElements.current === elements) return;
172
+ interactiveElements.current = elements;
173
+ const telemetry = getFloPayTelemetryBridge(flopay);
174
+ telemetry?.log({ name: "checkout.interactive", stage: "checkout_interactive" });
175
+ telemetry?.performance({
176
+ stage: "checkout_interactive",
177
+ durationMs: telemetry.elapsed(mountedAt.current ?? 0),
178
+ durationMode: "machine"
179
+ });
180
+ }, [elements, flopay]);
94
181
  const resolvedBillingApiUrl = resolveBillingApiUrl(options?.billingApiUrl);
95
182
  const value = useMemo(
96
- () => ({ flopay, paypalFlopay, elements, billingApiUrl: resolvedBillingApiUrl }),
97
- [flopay, paypalFlopay, elements, resolvedBillingApiUrl]
183
+ () => ({
184
+ flopay,
185
+ paypalFlopay,
186
+ elements,
187
+ billingApiUrl: resolvedBillingApiUrl,
188
+ reportInteractive
189
+ }),
190
+ [flopay, paypalFlopay, elements, resolvedBillingApiUrl, reportInteractive]
98
191
  );
99
192
  return /* @__PURE__ */ jsx(FloPayContext.Provider, { value, children });
100
193
  }
101
194
 
102
195
  // src/flopay-checkout.tsx
103
- import React8, { useCallback as useCallback3, useEffect as useEffect6, useMemo as useMemo4, useRef as useRef5, useState as useState4 } from "react";
196
+ import React9, { useCallback as useCallback4, useEffect as useEffect6, useMemo as useMemo4, useRef as useRef6, useState as useState4 } from "react";
104
197
  import { PaymentAPI as PaymentAPI4 } from "@flopay/js";
105
- import { SDK_VERSION, FloPayError as FloPayError5, resolveBillingApiUrl as resolveBillingApiUrl3, buildCheckoutDisplayData, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme2, resolveTheme as resolveTheme2 } from "@flopay/shared";
198
+ import { SDK_VERSION as SDK_VERSION2, FloPayError as FloPayError5, resolveBillingApiUrl as resolveBillingApiUrl3, buildCheckoutDisplayData, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme2, resolveTheme as resolveTheme2 } from "@flopay/shared";
106
199
 
107
200
  // src/card-button-content.tsx
108
201
  import "react";
@@ -172,7 +265,7 @@ function TitleContentSlot({
172
265
  }
173
266
 
174
267
  // src/elements.tsx
175
- import { useEffect as useEffect2, useRef, useContext } from "react";
268
+ import { useEffect as useEffect2, useRef as useRef2, useContext } from "react";
176
269
  import { jsx as jsx3 } from "react/jsx-runtime";
177
270
  function createElementComponent(elementType, displayName) {
178
271
  function ElementComponent({
@@ -186,9 +279,9 @@ function createElementComponent(elementType, displayName) {
186
279
  onBlur,
187
280
  onEscape
188
281
  }) {
189
- const containerRef = useRef(null);
190
- const elementRef = useRef(null);
191
- const { elements } = useContext(FloPayContext);
282
+ const containerRef = useRef2(null);
283
+ const elementRef = useRef2(null);
284
+ const { elements, reportInteractive } = useContext(FloPayContext);
192
285
  useEffect2(() => {
193
286
  if (!elements || !containerRef.current) return;
194
287
  let mounted = true;
@@ -203,7 +296,10 @@ function createElementComponent(elementType, displayName) {
203
296
  element.mount(containerRef.current);
204
297
  elementRef.current = element;
205
298
  if (onChange) element.on("change", onChange);
206
- if (onReady) element.on("ready", onReady);
299
+ element.on("ready", () => {
300
+ reportInteractive?.();
301
+ onReady?.();
302
+ });
207
303
  if (onFocus) element.on("focus", onFocus);
208
304
  if (onBlur) element.on("blur", onBlur);
209
305
  if (onEscape) element.on("escape", onEscape);
@@ -218,7 +314,7 @@ function createElementComponent(elementType, displayName) {
218
314
  elementRef.current = null;
219
315
  }
220
316
  };
221
- }, [elements]);
317
+ }, [elements, reportInteractive]);
222
318
  return /* @__PURE__ */ jsx3("div", { ref: containerRef, className, id, style });
223
319
  }
224
320
  ElementComponent.displayName = displayName;
@@ -262,7 +358,7 @@ import {
262
358
  import { PaymentAPI as PaymentAPI2 } from "@flopay/js";
263
359
 
264
360
  // src/vault-card-fields.tsx
265
- import { useEffect as useEffect3, useRef as useRef2 } from "react";
361
+ import { useEffect as useEffect3, useRef as useRef3 } from "react";
266
362
  import { jsx as jsx4 } from "react/jsx-runtime";
267
363
  function VaultCardFields({
268
364
  capture,
@@ -275,14 +371,14 @@ function VaultCardFields({
275
371
  onError,
276
372
  onValidation
277
373
  }) {
278
- const containerRef = useRef2(null);
279
- const onReadyRef = useRef2(onReady);
280
- const onErrorRef = useRef2(onError);
281
- const onValidationRef = useRef2(onValidation);
374
+ const containerRef = useRef3(null);
375
+ const onReadyRef = useRef3(onReady);
376
+ const onErrorRef = useRef3(onError);
377
+ const onValidationRef = useRef3(onValidation);
282
378
  onReadyRef.current = onReady;
283
379
  onErrorRef.current = onError;
284
380
  onValidationRef.current = onValidation;
285
- const themeRef = useRef2(theme);
381
+ const themeRef = useRef3(theme);
286
382
  themeRef.current = theme;
287
383
  useEffect3(() => {
288
384
  const el = containerRef.current;
@@ -332,8 +428,65 @@ function VaultCardFields({
332
428
  return /* @__PURE__ */ jsx4("div", { ref: containerRef, "data-testid": "flopay-vault-card-fields", style: containerStyle });
333
429
  }
334
430
 
431
+ // src/error-banner.tsx
432
+ import "react";
433
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
434
+ function ErrorBanner({
435
+ children,
436
+ margin,
437
+ icon = true,
438
+ styleOverride
439
+ }) {
440
+ return /* @__PURE__ */ jsxs2(
441
+ "div",
442
+ {
443
+ role: "alert",
444
+ "data-testid": "flopay-error",
445
+ style: {
446
+ margin,
447
+ padding: "0.625rem 0.875rem",
448
+ background: "#FEF2F2",
449
+ border: "1px solid #FECACA",
450
+ borderRadius: "8px",
451
+ color: "#991B1B",
452
+ fontSize: "0.85rem",
453
+ fontWeight: 600,
454
+ ...icon ? { display: "flex", alignItems: "center", gap: "0.5rem" } : {},
455
+ ...styleOverride ?? {}
456
+ },
457
+ children: [
458
+ icon && /* @__PURE__ */ jsx5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx5(
459
+ "path",
460
+ {
461
+ d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z",
462
+ stroke: "#DC2626",
463
+ strokeWidth: "2",
464
+ strokeLinecap: "round",
465
+ strokeLinejoin: "round"
466
+ }
467
+ ) }),
468
+ children
469
+ ]
470
+ }
471
+ );
472
+ }
473
+
474
+ // src/payment-logos.generated.ts
475
+ var PAYMENT_METHOD_LOGO_URLS = {
476
+ "alipay": new URL("./payment-logos/alipay.svg", import.meta.url).href,
477
+ "bancontact": new URL("./payment-logos/bancontact.svg", import.meta.url).href,
478
+ "blik": new URL("./payment-logos/blik.svg", import.meta.url).href,
479
+ "eps": new URL("./payment-logos/eps.svg", import.meta.url).href,
480
+ "giropay": new URL("./payment-logos/giropay.svg", import.meta.url).href,
481
+ "ideal": new URL("./payment-logos/ideal.svg", import.meta.url).href,
482
+ "klarna": new URL("./payment-logos/klarna.svg", import.meta.url).href,
483
+ "p24": new URL("./payment-logos/p24.svg", import.meta.url).href,
484
+ "sepa_debit": new URL("./payment-logos/sepa_debit.svg", import.meta.url).href,
485
+ "wechat_pay": new URL("./payment-logos/wechat_pay.svg", import.meta.url).href
486
+ };
487
+
335
488
  // src/split-card-form.tsx
336
- import React7, { forwardRef, useCallback as useCallback2, useContext as useContext3, useEffect as useEffect5, useImperativeHandle, useMemo as useMemo3, useRef as useRef4, useState as useState3 } from "react";
489
+ import React8, { forwardRef, useCallback as useCallback3, useContext as useContext3, useEffect as useEffect5, useImperativeHandle, useMemo as useMemo3, useRef as useRef5, useState as useState3 } from "react";
337
490
 
338
491
  // src/hooks.ts
339
492
  import { useContext as useContext2 } from "react";
@@ -360,14 +513,14 @@ function useBillingApiUrl() {
360
513
 
361
514
  // src/processing-overlay.tsx
362
515
  import "react";
363
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
516
+ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
364
517
  var PROCESSING_OVERLAY_SUCCESS_DELAY_MS = 1200;
365
518
  var PROCESSING_OVERLAY_ERROR_DELAY_MS = 1500;
366
519
  function ProcessingOverlay({
367
520
  status,
368
521
  errorMessage
369
522
  }) {
370
- return /* @__PURE__ */ jsx5(
523
+ return /* @__PURE__ */ jsx6(
371
524
  "div",
372
525
  {
373
526
  "data-testid": "flopay-processing-overlay",
@@ -384,7 +537,7 @@ function ProcessingOverlay({
384
537
  zIndex: 1e3,
385
538
  backdropFilter: "blur(2px)"
386
539
  },
387
- children: /* @__PURE__ */ jsxs2(
540
+ children: /* @__PURE__ */ jsxs3(
388
541
  "div",
389
542
  {
390
543
  style: {
@@ -400,8 +553,8 @@ function ProcessingOverlay({
400
553
  gap: 16
401
554
  },
402
555
  children: [
403
- /* @__PURE__ */ jsxs2("div", { style: { width: 48, height: 48, position: "relative" }, children: [
404
- status === "processing" && /* @__PURE__ */ jsxs2(
556
+ /* @__PURE__ */ jsxs3("div", { style: { width: 48, height: 48, position: "relative" }, children: [
557
+ status === "processing" && /* @__PURE__ */ jsxs3(
405
558
  "svg",
406
559
  {
407
560
  width: "48",
@@ -411,14 +564,14 @@ function ProcessingOverlay({
411
564
  xmlns: "http://www.w3.org/2000/svg",
412
565
  style: { animation: "flopay-spin 0.8s linear infinite" },
413
566
  children: [
414
- /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "10", stroke: "#e5e7eb", strokeWidth: "3" }),
415
- /* @__PURE__ */ jsx5("path", { d: "M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z", fill: "#4A49FF" })
567
+ /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "10", stroke: "#e5e7eb", strokeWidth: "3" }),
568
+ /* @__PURE__ */ jsx6("path", { d: "M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z", fill: "#4A49FF" })
416
569
  ]
417
570
  }
418
571
  ),
419
- status === "success" && /* @__PURE__ */ jsx5("div", { style: { animation: "flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)" }, children: /* @__PURE__ */ jsxs2("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
420
- /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "11", fill: "#22c55e" }),
421
- /* @__PURE__ */ jsx5(
572
+ status === "success" && /* @__PURE__ */ jsx6("div", { style: { animation: "flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)" }, children: /* @__PURE__ */ jsxs3("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
573
+ /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "11", fill: "#22c55e" }),
574
+ /* @__PURE__ */ jsx6(
422
575
  "path",
423
576
  {
424
577
  d: "M7 12.5l3 3 7-7",
@@ -434,9 +587,9 @@ function ProcessingOverlay({
434
587
  }
435
588
  )
436
589
  ] }) }),
437
- status === "error" && /* @__PURE__ */ jsx5("div", { style: { animation: "flopay-shake 0.4s ease" }, children: /* @__PURE__ */ jsxs2("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
438
- /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "11", fill: "#ef4444" }),
439
- /* @__PURE__ */ jsx5(
590
+ status === "error" && /* @__PURE__ */ jsx6("div", { style: { animation: "flopay-shake 0.4s ease" }, children: /* @__PURE__ */ jsxs3("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
591
+ /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "11", fill: "#ef4444" }),
592
+ /* @__PURE__ */ jsx6(
440
593
  "path",
441
594
  {
442
595
  d: "M8 8l8 8M16 8l-8 8",
@@ -452,7 +605,7 @@ function ProcessingOverlay({
452
605
  )
453
606
  ] }) })
454
607
  ] }),
455
- /* @__PURE__ */ jsxs2(
608
+ /* @__PURE__ */ jsxs3(
456
609
  "span",
457
610
  {
458
611
  style: {
@@ -468,7 +621,7 @@ function ProcessingOverlay({
468
621
  ]
469
622
  }
470
623
  ),
471
- status === "success" && /* @__PURE__ */ jsx5(
624
+ status === "success" && /* @__PURE__ */ jsx6(
472
625
  "p",
473
626
  {
474
627
  style: {
@@ -482,7 +635,7 @@ function ProcessingOverlay({
482
635
  children: "You will be automatically redirected, do not close or navigate away from this window."
483
636
  }
484
637
  ),
485
- status === "error" && errorMessage && /* @__PURE__ */ jsx5(
638
+ status === "error" && errorMessage && /* @__PURE__ */ jsx6(
486
639
  "p",
487
640
  {
488
641
  style: {
@@ -496,7 +649,7 @@ function ProcessingOverlay({
496
649
  children: errorMessage
497
650
  }
498
651
  ),
499
- /* @__PURE__ */ jsx5("style", { children: `
652
+ /* @__PURE__ */ jsx6("style", { children: `
500
653
  @keyframes flopay-spin { to { transform: rotate(360deg); } }
501
654
  @keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
502
655
  @keyframes flopay-draw { to { stroke-dashoffset: 0; } }
@@ -658,6 +811,14 @@ async function buildFloPayApiErrorFromResponse(response, fallbackMessage) {
658
811
  const payload = await response.json().catch(() => null);
659
812
  return buildFloPayApiError(payload, fallbackMessage);
660
813
  }
814
+ function intentRequestHeaders(nonce) {
815
+ const headers = { "Content-Type": "application/json" };
816
+ if (nonce) headers["x-checkout-session-token"] = nonce;
817
+ return headers;
818
+ }
819
+ function isSuccessfulPaymentIntentStatus(status) {
820
+ return status === "succeeded" || status === "requires_capture" || status === "processing";
821
+ }
661
822
  function mapPayPalIntentStatusToPaymentResult(status) {
662
823
  if (status === "succeeded") {
663
824
  return "succeeded";
@@ -770,10 +931,23 @@ function isInAppBrowser(userAgent) {
770
931
  }
771
932
 
772
933
  // src/direct-paypal-button.tsx
773
- import { useCallback, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState2 } from "react";
934
+ import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState2 } from "react";
774
935
  import { loadScript } from "@paypal/paypal-js";
775
936
  import { PaymentAPI } from "@flopay/js";
776
- import { FloPayError as FloPayError2, normalizeGatewayEnvironment } from "@flopay/shared";
937
+ import { FloPayError as FloPayError2, SDK_VERSION, normalizeGatewayEnvironment } from "@flopay/shared";
938
+
939
+ // src/merchant-callback.ts
940
+ function invokeMerchantCallback(callback) {
941
+ if (!callback) return;
942
+ const reportFailure = (error) => {
943
+ console.error("[FloPay] Merchant callback failed; checkout continued.", error);
944
+ };
945
+ try {
946
+ void Promise.resolve(callback()).catch(reportFailure);
947
+ } catch (error) {
948
+ reportFailure(error);
949
+ }
950
+ }
777
951
 
778
952
  // src/external-method-recovery.ts
779
953
  var EXTERNAL_METHOD_CALLBACK_GRACE_MS = 600;
@@ -812,7 +986,7 @@ function isPopupBlockedError(err) {
812
986
  }
813
987
 
814
988
  // src/direct-paypal-button.tsx
815
- import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
989
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
816
990
  var DEFAULT_BUTTON_HEIGHT = 45;
817
991
  var DIRECT_PAYPAL_RECOVERY_MESSAGE = "We couldn't open PayPal. Try again or choose another payment method.";
818
992
  var DIRECT_PAYPAL_RECOVERY_ACTION_STYLE = {
@@ -831,7 +1005,7 @@ var DIRECT_PAYPAL_RECOVERY_ACTION_STYLE = {
831
1005
  function buildDirectPayPalRecoveryMessage(popupBlocked) {
832
1006
  return popupBlocked ? `${DIRECT_PAYPAL_RECOVERY_MESSAGE} Allow pop-ups for this site, then try again.` : DIRECT_PAYPAL_RECOVERY_MESSAGE;
833
1007
  }
834
- function DirectPayPalButton({
1008
+ function DirectPayPalButtonImplementation({
835
1009
  sessionId,
836
1010
  nonce,
837
1011
  billingApiUrl,
@@ -851,14 +1025,62 @@ function DirectPayPalButton({
851
1025
  runBeforeButtonClick,
852
1026
  session,
853
1027
  existingOrderId,
1028
+ telemetry,
1029
+ telemetryContext,
854
1030
  debug = false
855
1031
  }) {
856
- const containerRef = useRef3(null);
857
- const focusTargetRef = useRef3(null);
858
- const pendingProviderFocusRef = useRef3(false);
1032
+ const flopay = useFloPay();
1033
+ const standaloneTelemetry = useMemo2(() => {
1034
+ if (flopay) return null;
1035
+ const reporter = createTelemetryBridge({
1036
+ billingApiUrl,
1037
+ sdkPackage: "@flopay/react",
1038
+ sdkVersion: SDK_VERSION,
1039
+ enabled: telemetry !== false
1040
+ });
1041
+ reporter.setCheckoutContext(telemetryContext ?? {});
1042
+ reporter.beginCheckout(telemetryContext ?? {});
1043
+ return reporter;
1044
+ }, [
1045
+ billingApiUrl,
1046
+ flopay,
1047
+ telemetry,
1048
+ telemetryContext?.checkoutMode,
1049
+ telemetryContext?.layout
1050
+ ]);
1051
+ const floPayTelemetry = useMemo2(() => getFloPayTelemetryBridge(flopay), [flopay]);
1052
+ useEffect4(() => () => {
1053
+ if (!standaloneTelemetry) return;
1054
+ void standaloneTelemetry.flush().catch(() => {
1055
+ }).finally(() => standaloneTelemetry.destroy());
1056
+ }, [standaloneTelemetry]);
1057
+ const telemetrySource = useMemo2(() => ({
1058
+ error: (input) => {
1059
+ if (floPayTelemetry) floPayTelemetry.error(input);
1060
+ else standaloneTelemetry?.error(input);
1061
+ },
1062
+ log: (input) => {
1063
+ if (floPayTelemetry) floPayTelemetry.log(input);
1064
+ else standaloneTelemetry?.log(input);
1065
+ },
1066
+ performance: (input) => {
1067
+ if (floPayTelemetry) floPayTelemetry.performance(input);
1068
+ else standaloneTelemetry?.performance(input);
1069
+ },
1070
+ terminal: (input) => {
1071
+ if (floPayTelemetry) floPayTelemetry.terminal(input);
1072
+ else standaloneTelemetry?.terminal(input);
1073
+ },
1074
+ startTiming: () => floPayTelemetry?.now() ?? standaloneTelemetry?.now() ?? 0,
1075
+ elapsed: (startedAt) => floPayTelemetry?.elapsed(startedAt) ?? Math.max(0, (standaloneTelemetry?.now() ?? startedAt) - startedAt)
1076
+ }), [floPayTelemetry, standaloneTelemetry]);
1077
+ const containerRef = useRef4(null);
1078
+ const providerStartedAt = useRef4(0);
1079
+ const focusTargetRef = useRef4(null);
1080
+ const pendingProviderFocusRef = useRef4(false);
859
1081
  const [ready, setReady] = useState2(false);
860
1082
  const [renderGeneration, setRenderGeneration] = useState2(0);
861
- const activeRenderGenerationRef = useRef3(0);
1083
+ const activeRenderGenerationRef = useRef4(0);
862
1084
  const [showRetryFocusTarget, setShowRetryFocusTarget] = useState2(false);
863
1085
  const [failed, setFailed] = useState2(false);
864
1086
  const [submitting, setSubmitting] = useState2(false);
@@ -868,23 +1090,23 @@ function DirectPayPalButton({
868
1090
  if (!debug) return;
869
1091
  setDebugLines((prev) => [...prev, `${(/* @__PURE__ */ new Date()).toISOString().slice(11, 23)} ${line}`]);
870
1092
  };
871
- const onTokenizedBodyRef = useRef3(onTokenizedBody);
872
- const onCompleteRef = useRef3(onComplete);
873
- const onErrorChangeRef = useRef3(onErrorChange);
874
- const onDeclineRef = useRef3(onDecline);
875
- const onTechnicalFailureRef = useRef3(onTechnicalFailure);
876
- const onButtonClickRef = useRef3(onButtonClick);
877
- const onLoadStateChangeRef = useRef3(onLoadStateChange);
878
- const runBeforeButtonClickRef = useRef3(runBeforeButtonClick);
879
- const sessionRef = useRef3(session);
880
- const emailRef = useRef3(email);
881
- const nonceRef = useRef3(nonce);
882
- const beforeClickRef = useRef3(null);
883
- const attemptGenerationRef = useRef3(0);
884
- const attemptRef = useRef3(null);
885
- const invalidatedAttemptGenerationRef = useRef3(null);
886
- const attemptContextBySurfaceRef = useRef3(/* @__PURE__ */ new Map());
887
- const approvalContextByTokenRef = useRef3(/* @__PURE__ */ new Map());
1093
+ const onTokenizedBodyRef = useRef4(onTokenizedBody);
1094
+ const onCompleteRef = useRef4(onComplete);
1095
+ const onErrorChangeRef = useRef4(onErrorChange);
1096
+ const onDeclineRef = useRef4(onDecline);
1097
+ const onTechnicalFailureRef = useRef4(onTechnicalFailure);
1098
+ const onButtonClickRef = useRef4(onButtonClick);
1099
+ const onLoadStateChangeRef = useRef4(onLoadStateChange);
1100
+ const runBeforeButtonClickRef = useRef4(runBeforeButtonClick);
1101
+ const sessionRef = useRef4(session);
1102
+ const emailRef = useRef4(email);
1103
+ const nonceRef = useRef4(nonce);
1104
+ const beforeClickRef = useRef4(null);
1105
+ const attemptGenerationRef = useRef4(0);
1106
+ const attemptRef = useRef4(null);
1107
+ const invalidatedAttemptGenerationRef = useRef4(null);
1108
+ const attemptContextBySurfaceRef = useRef4(/* @__PURE__ */ new Map());
1109
+ const approvalContextByTokenRef = useRef4(/* @__PURE__ */ new Map());
888
1110
  useEffect4(() => {
889
1111
  onTokenizedBodyRef.current = onTokenizedBody;
890
1112
  }, [onTokenizedBody]);
@@ -924,16 +1146,16 @@ function DirectPayPalButton({
924
1146
  useEffect4(() => {
925
1147
  if (showRetryFocusTarget) focusTargetRef.current?.focus();
926
1148
  }, [showRetryFocusTarget, renderGeneration]);
927
- const focusRetryTarget = useCallback(() => {
1149
+ const focusRetryTarget = useCallback2(() => {
928
1150
  window.setTimeout(() => {
929
1151
  focusTargetRef.current?.focus();
930
1152
  }, 0);
931
1153
  }, []);
932
- const remountPayPalButtons = useCallback(() => {
1154
+ const remountPayPalButtons = useCallback2(() => {
933
1155
  setReady(false);
934
1156
  setRenderGeneration((current) => current + 1);
935
1157
  }, []);
936
- const focusPayPalSurface = useCallback(() => {
1158
+ const focusPayPalSurface = useCallback2(() => {
937
1159
  setShowRetryFocusTarget(false);
938
1160
  const target = containerRef.current?.querySelector(
939
1161
  'iframe, button, [tabindex]:not([tabindex="-1"])'
@@ -945,7 +1167,7 @@ function DirectPayPalButton({
945
1167
  pendingProviderFocusRef.current = false;
946
1168
  focusPayPalSurface();
947
1169
  }, [focusPayPalSurface, ready, renderGeneration]);
948
- const notifyTechnicalFailure = useCallback((err, options) => {
1170
+ const notifyTechnicalFailure = useCallback2((err, options) => {
949
1171
  const handler = onTechnicalFailureRef.current;
950
1172
  if (handler) {
951
1173
  handler("paypal", err, options);
@@ -1042,7 +1264,7 @@ function DirectPayPalButton({
1042
1264
  };
1043
1265
  }, []);
1044
1266
  useEffect4(() => {
1045
- onLoadStateChangeRef.current?.(ready && !failed);
1267
+ invokeMerchantCallback(() => onLoadStateChangeRef.current?.(ready && !failed));
1046
1268
  }, [ready, failed]);
1047
1269
  const normalizedEnv = normalizeGatewayEnvironment(environment);
1048
1270
  useEffect4(() => {
@@ -1053,6 +1275,13 @@ function DirectPayPalButton({
1053
1275
  if (!clientId) {
1054
1276
  appendDebug("FAIL: clientId empty \u2014 gateway misconfigured");
1055
1277
  setFailed(true);
1278
+ telemetrySource.error({
1279
+ errorCode: "CONFIGURATION_INVALID",
1280
+ stage: "provider_load",
1281
+ provider: "paypal",
1282
+ paymentMethodCategory: "paypal",
1283
+ requestCategory: "provider_sdk"
1284
+ });
1056
1285
  console.error("[FloPay] DirectPayPal: clientId empty \u2014 gateway misconfigured");
1057
1286
  return;
1058
1287
  }
@@ -1060,8 +1289,33 @@ function DirectPayPalButton({
1060
1289
  appendDebug("FAIL: containerRef not attached");
1061
1290
  return;
1062
1291
  }
1292
+ providerStartedAt.current = telemetrySource.startTiming();
1293
+ telemetrySource.log({
1294
+ name: "provider.load.started",
1295
+ stage: "provider_load",
1296
+ provider: "paypal",
1297
+ paymentMethodCategory: "paypal"
1298
+ });
1063
1299
  let cancelled = false;
1064
1300
  let activeButtons = null;
1301
+ let overlayStartedAt = null;
1302
+ const finishOverlay = () => {
1303
+ if (overlayStartedAt === null) return;
1304
+ telemetrySource.log({
1305
+ name: "provider.overlay.returned",
1306
+ stage: "overlay_return",
1307
+ provider: "paypal",
1308
+ paymentMethodCategory: "paypal"
1309
+ });
1310
+ telemetrySource.performance({
1311
+ stage: "overlay_return",
1312
+ durationMs: telemetrySource.elapsed(overlayStartedAt),
1313
+ durationMode: "buyer",
1314
+ provider: "paypal",
1315
+ paymentMethodCategory: "paypal"
1316
+ });
1317
+ overlayStartedAt = null;
1318
+ };
1065
1319
  let rendered = false;
1066
1320
  const container = containerRef.current;
1067
1321
  let containerObserver = null;
@@ -1165,7 +1419,7 @@ function DirectPayPalButton({
1165
1419
  if (cancelled) return;
1166
1420
  if (isZoidLifecycleMessage(message)) return;
1167
1421
  const friendly = applyFriendlyMessageOverride(message) ?? message;
1168
- onErrorChangeRef.current?.(friendly);
1422
+ invokeMerchantCallback(() => onErrorChangeRef.current?.(friendly));
1169
1423
  };
1170
1424
  const markRenderFailed = (message) => {
1171
1425
  if (cancelled) return;
@@ -1174,24 +1428,55 @@ function DirectPayPalButton({
1174
1428
  return;
1175
1429
  }
1176
1430
  setFailed(true);
1431
+ if (!message.includes("paypal_ineligible")) {
1432
+ telemetrySource.error({
1433
+ errorCode: "PROVIDER_LOAD_FAILED",
1434
+ stage: "provider_load",
1435
+ provider: "paypal",
1436
+ paymentMethodCategory: "paypal",
1437
+ requestCategory: "provider_sdk"
1438
+ });
1439
+ }
1177
1440
  console.error("[FloPay] DirectPayPal load/render failure:", message);
1178
1441
  };
1179
1442
  setFailed(false);
1180
1443
  const dispatchTokenizedBody = async (body, prepared = beforeClickRef.current) => {
1181
1444
  const effectiveSessionId = prepared?.sessionId ?? sessionId;
1182
1445
  if (onTokenizedBodyRef.current) {
1183
- onTokenizedBodyRef.current(body, {
1446
+ await onTokenizedBodyRef.current(body, {
1184
1447
  sessionId: effectiveSessionId,
1185
1448
  accountPatch: prepared?.accountPatch,
1186
1449
  nonce: prepared?.nonce
1187
1450
  });
1188
1451
  return;
1189
1452
  }
1453
+ const processingStartedAt = telemetrySource.startTiming();
1454
+ telemetrySource.log({
1455
+ name: "payment.processing.started",
1456
+ stage: "processing",
1457
+ provider: "paypal",
1458
+ paymentMethodCategory: "paypal"
1459
+ });
1460
+ const finishProcessing = () => {
1461
+ telemetrySource.log({
1462
+ name: "payment.processing.completed",
1463
+ stage: "processing",
1464
+ provider: "paypal",
1465
+ paymentMethodCategory: "paypal"
1466
+ });
1467
+ telemetrySource.performance({
1468
+ stage: "processing",
1469
+ durationMs: telemetrySource.elapsed(processingStartedAt),
1470
+ durationMode: "machine",
1471
+ provider: "paypal",
1472
+ paymentMethodCategory: "paypal"
1473
+ });
1474
+ };
1190
1475
  try {
1191
1476
  const currentSession = sessionRef.current;
1192
1477
  const currentEmail = prepared?.accountPatch?.email ?? emailRef.current;
1193
1478
  const effectiveUserId = prepared?.accountPatch?.userId ?? currentSession?.customer?.id ?? currentSession?.accountData?.userId ?? "";
1194
- const api = new PaymentAPI(baseUrl);
1479
+ const api = new PaymentAPI(baseUrl, { telemetry: false });
1195
1480
  const response = await api.processPayment(
1196
1481
  effectiveUserId,
1197
1482
  {
@@ -1209,31 +1494,71 @@ function DirectPayPalButton({
1209
1494
  }
1210
1495
  );
1211
1496
  if (response.ok) {
1212
- onCompleteRef.current?.({ status: "succeeded", checkoutMethod: "paypal" });
1497
+ finishProcessing();
1498
+ telemetrySource.terminal({
1499
+ outcome: "payment_succeeded",
1500
+ provider: "paypal",
1501
+ paymentMethodCategory: "paypal"
1502
+ });
1503
+ } else {
1504
+ const json = await response.json().catch(() => null);
1505
+ const rawMessage = json?.["message"] ?? "PayPal payment failed.";
1506
+ const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;
1507
+ finishProcessing();
1508
+ if (typeof json?.["declineCode"] === "string") {
1509
+ telemetrySource.terminal({
1510
+ outcome: "payment_declined",
1511
+ provider: "paypal",
1512
+ paymentMethodCategory: "paypal"
1513
+ });
1514
+ } else {
1515
+ telemetrySource.error({
1516
+ errorCode: "PAYMENT_PROCESSING_FAILED",
1517
+ stage: "processing",
1518
+ provider: "paypal",
1519
+ paymentMethodCategory: "paypal",
1520
+ requestCategory: "process_payment",
1521
+ statusClass: response.status >= 500 ? "5xx" : response.status >= 400 ? "4xx" : response.status >= 300 ? "3xx" : "unknown"
1522
+ });
1523
+ }
1524
+ forwardError(message);
1525
+ invokeMerchantCallback(() => onDeclineRef.current?.(buildDeclineEvent("paypal", message, {
1526
+ code: json?.["code"],
1527
+ declineCode: json?.["declineCode"]
1528
+ })));
1213
1529
  return;
1214
1530
  }
1215
- const json = await response.json().catch(() => null);
1216
- const rawMessage = json?.["message"] ?? "PayPal payment failed.";
1217
- const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;
1218
- forwardError(message);
1219
- onDeclineRef.current?.(buildDeclineEvent("paypal", message, {
1220
- code: json?.["code"],
1221
- declineCode: json?.["declineCode"]
1222
- }));
1223
1531
  } catch (err) {
1532
+ finishProcessing();
1533
+ telemetrySource.error({
1534
+ errorCode: "NETWORK_REQUEST_FAILED",
1535
+ stage: "processing",
1536
+ provider: "paypal",
1537
+ paymentMethodCategory: "paypal",
1538
+ requestCategory: "process_payment",
1539
+ statusClass: "network_error"
1540
+ });
1224
1541
  const rawMessage = err instanceof Error ? err.message : "PayPal payment failed.";
1225
1542
  const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;
1226
1543
  forwardError(message);
1227
- onDeclineRef.current?.(buildDeclineEvent("paypal", message));
1544
+ invokeMerchantCallback(() => onDeclineRef.current?.(buildDeclineEvent("paypal", message)));
1545
+ return;
1228
1546
  }
1547
+ invokeMerchantCallback(() => onCompleteRef.current?.({ status: "succeeded", checkoutMethod: "paypal" }));
1229
1548
  };
1230
1549
  const createPaypalIntent = async (fallbackMessage) => {
1231
1550
  const prepared = beforeClickRef.current;
1232
1551
  const effectiveSessionId = prepared?.sessionId ?? sessionId;
1233
1552
  const effectiveEmail = prepared?.accountPatch?.email ?? emailRef.current;
1234
- const intentHeaders = { "Content-Type": "application/json" };
1235
1553
  const currentNonce = prepared?.nonce ?? nonceRef.current;
1236
- if (currentNonce) intentHeaders["x-checkout-session-token"] = currentNonce;
1554
+ const intentHeaders = intentRequestHeaders(currentNonce);
1555
+ telemetrySource.log({
1556
+ name: "payment.intent.started",
1557
+ stage: "processing",
1558
+ provider: "paypal",
1559
+ paymentMethodCategory: "paypal",
1560
+ requestCategory: "intent_create"
1561
+ });
1237
1562
  const response = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
1238
1563
  method: "POST",
1239
1564
  headers: intentHeaders,
@@ -1252,6 +1577,14 @@ function DirectPayPalButton({
1252
1577
  if (!id) {
1253
1578
  throw new Error(fallbackMessage);
1254
1579
  }
1580
+ telemetrySource.log({
1581
+ name: "payment.intent.completed",
1582
+ stage: "processing",
1583
+ provider: "paypal",
1584
+ paymentMethodCategory: "paypal",
1585
+ requestCategory: "intent_create",
1586
+ statusClass: "2xx"
1587
+ });
1255
1588
  return id;
1256
1589
  };
1257
1590
  const effectRenderGeneration = renderGeneration;
@@ -1286,6 +1619,12 @@ function DirectPayPalButton({
1286
1619
  if (!cancelled && !paypal?.Buttons) appendDebug("FAIL: namespace missing Buttons factory");
1287
1620
  return;
1288
1621
  }
1622
+ telemetrySource.log({
1623
+ name: "provider.availability.checked",
1624
+ stage: "provider_ready",
1625
+ provider: "paypal",
1626
+ paymentMethodCategory: "paypal"
1627
+ });
1289
1628
  const handleApprove = async (data) => {
1290
1629
  if (cancelled || activeRenderGenerationRef.current !== effectRenderGeneration) return;
1291
1630
  const token = data.subscriptionID ?? data.orderID ?? "";
@@ -1294,9 +1633,10 @@ function DirectPayPalButton({
1294
1633
  if (!finishAttempt(context.generation)) return;
1295
1634
  approvalContextByTokenRef.current.delete(token);
1296
1635
  attemptContextBySurfaceRef.current.delete(context.surfaceKey);
1636
+ finishOverlay();
1297
1637
  try {
1298
1638
  setSubmitting(true);
1299
- onErrorChangeRef.current?.(null);
1639
+ invokeMerchantCallback(() => onErrorChangeRef.current?.(null));
1300
1640
  if (!token) {
1301
1641
  throw new FloPayError2(
1302
1642
  "PayPal did not return an approval token.",
@@ -1346,7 +1686,7 @@ function DirectPayPalButton({
1346
1686
  return;
1347
1687
  }
1348
1688
  }
1349
- onButtonClickRef.current?.("paypal");
1689
+ invokeMerchantCallback(() => onButtonClickRef.current?.("paypal"));
1350
1690
  const generation = startAttempt();
1351
1691
  const context = {
1352
1692
  generation,
@@ -1356,6 +1696,25 @@ function DirectPayPalButton({
1356
1696
  beforeClickRef.current = context;
1357
1697
  attemptContextBySurfaceRef.current.set(effectRenderGeneration, context);
1358
1698
  await actions.resolve();
1699
+ telemetrySource.log({
1700
+ name: "payment.method.selected",
1701
+ stage: "processing",
1702
+ provider: "paypal",
1703
+ paymentMethodCategory: "paypal"
1704
+ });
1705
+ telemetrySource.log({
1706
+ name: "provider.popup.opened",
1707
+ stage: "overlay_open",
1708
+ provider: "paypal",
1709
+ paymentMethodCategory: "paypal"
1710
+ });
1711
+ telemetrySource.log({
1712
+ name: "provider.overlay.opened",
1713
+ stage: "overlay_open",
1714
+ provider: "paypal",
1715
+ paymentMethodCategory: "paypal"
1716
+ });
1717
+ overlayStartedAt = telemetrySource.startTiming();
1359
1718
  },
1360
1719
  // When the SDK is already holding an order/subscription id from a
1361
1720
  // prior backend round-trip (the `paypal_direct_required` retry
@@ -1368,6 +1727,12 @@ function DirectPayPalButton({
1368
1727
  const context = attemptContextBySurfaceRef.current.get(effectRenderGeneration) ?? beforeClickRef.current;
1369
1728
  if (context) attemptContextBySurfaceRef.current.delete(context.surfaceKey);
1370
1729
  beforeClickRef.current = null;
1730
+ finishOverlay();
1731
+ telemetrySource.terminal({
1732
+ outcome: "payment_cancelled",
1733
+ provider: "paypal",
1734
+ paymentMethodCategory: "paypal"
1735
+ });
1371
1736
  pendingProviderFocusRef.current = true;
1372
1737
  invalidateAttempt({ generation: context?.generation, remount: true, focus: false });
1373
1738
  },
@@ -1383,6 +1748,15 @@ function DirectPayPalButton({
1383
1748
  finishAttempt(context?.generation);
1384
1749
  return;
1385
1750
  }
1751
+ finishOverlay();
1752
+ const lower = message.toLowerCase();
1753
+ telemetrySource.error({
1754
+ errorCode: lower.includes("popup") && lower.includes("block") ? "POPUP_BLOCKED" : "PROVIDER_RUNTIME_FAILED",
1755
+ stage: "provider_ready",
1756
+ provider: "paypal",
1757
+ paymentMethodCategory: "paypal",
1758
+ requestCategory: "provider_sdk"
1759
+ });
1386
1760
  if (context) attemptContextBySurfaceRef.current.delete(context.surfaceKey);
1387
1761
  beforeClickRef.current = null;
1388
1762
  invalidateAttempt({ generation: context?.generation, remount: true, showRetry: true, focus: true });
@@ -1394,6 +1768,12 @@ function DirectPayPalButton({
1394
1768
  });
1395
1769
  const eligible = buttons.isEligible();
1396
1770
  appendDebug(`isEligible=${eligible}`);
1771
+ telemetrySource.log({
1772
+ name: "provider.eligibility.checked",
1773
+ stage: "provider_ready",
1774
+ provider: "paypal",
1775
+ paymentMethodCategory: "paypal"
1776
+ });
1397
1777
  if (!eligible) {
1398
1778
  setReady(false);
1399
1779
  markRenderFailed(
@@ -1465,6 +1845,19 @@ function DirectPayPalButton({
1465
1845
  activeButtons = typedButtons;
1466
1846
  rendered = true;
1467
1847
  setReady(true);
1848
+ telemetrySource.log({
1849
+ name: "provider.ready",
1850
+ stage: "provider_ready",
1851
+ provider: "paypal",
1852
+ paymentMethodCategory: "paypal"
1853
+ });
1854
+ telemetrySource.performance({
1855
+ stage: "provider_ready",
1856
+ durationMs: telemetrySource.elapsed(providerStartedAt.current),
1857
+ durationMode: "machine",
1858
+ provider: "paypal",
1859
+ paymentMethodCategory: "paypal"
1860
+ });
1468
1861
  }).catch((err) => {
1469
1862
  const message = err instanceof Error ? err.message : "PayPal failed to render.";
1470
1863
  appendDebug(`render:rejected msg=${message.slice(0, 120)}`);
@@ -1486,8 +1879,8 @@ function DirectPayPalButton({
1486
1879
  });
1487
1880
  }
1488
1881
  };
1489
- }, [baseUrl, clientId, currency, environment, isSubscription, sessionId, existingOrderId, renderGeneration]);
1490
- const debugPanel = debug ? /* @__PURE__ */ jsxs3(
1882
+ }, [baseUrl, clientId, currency, environment, isSubscription, sessionId, existingOrderId, renderGeneration, telemetrySource]);
1883
+ const debugPanel = debug ? /* @__PURE__ */ jsxs4(
1491
1884
  "pre",
1492
1885
  {
1493
1886
  "data-testid": "flopay-direct-paypal-debug",
@@ -1512,17 +1905,17 @@ ${debugLines.join("\n")}`
1512
1905
  }
1513
1906
  ) : null;
1514
1907
  if (failed) {
1515
- return debug ? /* @__PURE__ */ jsx6("div", { children: debugPanel }) : null;
1908
+ return debug ? /* @__PURE__ */ jsx7("div", { children: debugPanel }) : null;
1516
1909
  }
1517
1910
  return (
1518
1911
  // Single wrapper so the parent flex container sees exactly one flex item
1519
1912
  // (otherwise the fragment's placeholder + container become two siblings
1520
1913
  // and any spacing-sensitive layout has to reason about both). The wrapper
1521
1914
  // intentionally has no margin/padding so the parent owns all spacing.
1522
- /* @__PURE__ */ jsxs3("div", { children: [
1915
+ /* @__PURE__ */ jsxs4("div", { children: [
1523
1916
  debugPanel,
1524
- /* @__PURE__ */ jsxs3("div", { style: { position: "relative", minHeight: DEFAULT_BUTTON_HEIGHT }, children: [
1525
- !ready && /* @__PURE__ */ jsx6(
1917
+ /* @__PURE__ */ jsxs4("div", { style: { position: "relative", minHeight: DEFAULT_BUTTON_HEIGHT }, children: [
1918
+ !ready && /* @__PURE__ */ jsx7(
1526
1919
  "div",
1527
1920
  {
1528
1921
  "data-testid": "flopay-direct-paypal-placeholder",
@@ -1536,7 +1929,7 @@ ${debugLines.join("\n")}`
1536
1929
  }
1537
1930
  }
1538
1931
  ),
1539
- /* @__PURE__ */ jsx6(
1932
+ /* @__PURE__ */ jsx7(
1540
1933
  "div",
1541
1934
  {
1542
1935
  ref: containerRef,
@@ -1553,7 +1946,7 @@ ${debugLines.join("\n")}`
1553
1946
  renderGeneration
1554
1947
  )
1555
1948
  ] }),
1556
- showRetryFocusTarget && /* @__PURE__ */ jsx6(
1949
+ showRetryFocusTarget && /* @__PURE__ */ jsx7(
1557
1950
  "button",
1558
1951
  {
1559
1952
  ref: focusTargetRef,
@@ -1567,10 +1960,16 @@ ${debugLines.join("\n")}`
1567
1960
  ] })
1568
1961
  );
1569
1962
  }
1963
+ function DirectPayPalButton(props) {
1964
+ return /* @__PURE__ */ jsx7(DirectPayPalButtonImplementation, { ...props });
1965
+ }
1966
+ function InstrumentedDirectPayPalButton(props) {
1967
+ return /* @__PURE__ */ jsx7(DirectPayPalButtonImplementation, { ...props });
1968
+ }
1570
1969
 
1571
1970
  // src/split-card-form.tsx
1572
1971
  import { FloPayError as FloPayError3, isSetupIntentClientSecret as isSetupIntentClientSecret2, resolveTheme } from "@flopay/shared";
1573
- import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
1972
+ import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1574
1973
  var STRIPE_RESUME_KEY = "flopay_stripe_resume";
1575
1974
  var LEGACY_WALLET_RESUME_KEY = "flopay_wallet_resume";
1576
1975
  var PAYPAL_RESUME_KEY = "flopay_paypal_resume";
@@ -1685,17 +2084,17 @@ function buildExternalMethodRecoveryMessage(method, popupBlocked) {
1685
2084
  return popupBlocked ? `${base} Allow pop-ups for this site, then try again.` : base;
1686
2085
  }
1687
2086
  function useExternalAttemptReconciliation(onMissingTerminal) {
1688
- const generationRef = useRef4(0);
1689
- const invalidatedGenerationRef = useRef4(null);
1690
- const attemptRef = useRef4(null);
1691
- const clearAttemptTimer = useCallback2((targetAttempt = attemptRef.current) => {
2087
+ const generationRef = useRef5(0);
2088
+ const invalidatedGenerationRef = useRef5(null);
2089
+ const attemptRef = useRef5(null);
2090
+ const clearAttemptTimer = useCallback3((targetAttempt = attemptRef.current) => {
1692
2091
  const attempt = targetAttempt;
1693
2092
  if (attempt?.timer) {
1694
2093
  clearTimeout(attempt.timer);
1695
2094
  attempt.timer = null;
1696
2095
  }
1697
2096
  }, []);
1698
- const armAttemptTimer = useCallback2((attempt, delayMs) => {
2097
+ const armAttemptTimer = useCallback3((attempt, delayMs) => {
1699
2098
  if (typeof document !== "undefined" && document.visibilityState !== "visible") return;
1700
2099
  clearAttemptTimer(attempt);
1701
2100
  attempt.timer = setTimeout(() => {
@@ -1710,11 +2109,11 @@ function useExternalAttemptReconciliation(onMissingTerminal) {
1710
2109
  );
1711
2110
  }, delayMs);
1712
2111
  }, [clearAttemptTimer, onMissingTerminal]);
1713
- const armRecoveryTimer = useCallback2((attempt) => {
2112
+ const armRecoveryTimer = useCallback3((attempt) => {
1714
2113
  if (!attempt.yieldedControl) return;
1715
2114
  armAttemptTimer(attempt, EXTERNAL_METHOD_CALLBACK_GRACE_MS);
1716
2115
  }, [armAttemptTimer]);
1717
- const startAttempt = useCallback2((method) => {
2116
+ const startAttempt = useCallback3((method) => {
1718
2117
  clearAttemptTimer();
1719
2118
  const generation = generationRef.current + 1;
1720
2119
  generationRef.current = generation;
@@ -1723,7 +2122,7 @@ function useExternalAttemptReconciliation(onMissingTerminal) {
1723
2122
  attemptRef.current = attempt;
1724
2123
  return generation;
1725
2124
  }, [clearAttemptTimer]);
1726
- const finishAttempt = useCallback2((generation) => {
2125
+ const finishAttempt = useCallback3((generation) => {
1727
2126
  const attempt = attemptRef.current;
1728
2127
  if (typeof generation === "number" && attempt?.generation !== generation) return false;
1729
2128
  clearAttemptTimer(attempt);
@@ -1733,7 +2132,7 @@ function useExternalAttemptReconciliation(onMissingTerminal) {
1733
2132
  }
1734
2133
  return true;
1735
2134
  }, [clearAttemptTimer]);
1736
- const invalidateAttempt = useCallback2((generation) => {
2135
+ const invalidateAttempt = useCallback3((generation) => {
1737
2136
  const attempt = attemptRef.current;
1738
2137
  const targetGeneration = generation ?? attempt?.generation ?? generationRef.current;
1739
2138
  if (!generation || attempt?.generation === generation) {
@@ -1742,20 +2141,20 @@ function useExternalAttemptReconciliation(onMissingTerminal) {
1742
2141
  }
1743
2142
  invalidatedGenerationRef.current = targetGeneration;
1744
2143
  }, [clearAttemptTimer]);
1745
- const isAttemptInvalidated = useCallback2(
2144
+ const isAttemptInvalidated = useCallback3(
1746
2145
  (generation) => invalidatedGenerationRef.current === (generation ?? generationRef.current),
1747
2146
  []
1748
2147
  );
1749
- const isAttemptCurrent = useCallback2(
2148
+ const isAttemptCurrent = useCallback3(
1750
2149
  (generation) => attemptRef.current?.generation === generation && invalidatedGenerationRef.current !== generation,
1751
2150
  []
1752
2151
  );
1753
- const scheduleRecoveryIfReturned = useCallback2(() => {
2152
+ const scheduleRecoveryIfReturned = useCallback3(() => {
1754
2153
  const attempt = attemptRef.current;
1755
2154
  if (!attempt) return;
1756
2155
  armRecoveryTimer(attempt);
1757
2156
  }, [armRecoveryTimer]);
1758
- const markAttemptYieldedControl = useCallback2(() => {
2157
+ const markAttemptYieldedControl = useCallback3(() => {
1759
2158
  const attempt = attemptRef.current;
1760
2159
  if (!attempt) return;
1761
2160
  attempt.yieldedControl = true;
@@ -1803,7 +2202,7 @@ function normalizeBeforeButtonClickError(method, err) {
1803
2202
  );
1804
2203
  }
1805
2204
  function FloPayKeyframes() {
1806
- return /* @__PURE__ */ jsx7("style", { children: FLOPAY_KEYFRAMES });
2205
+ return /* @__PURE__ */ jsx8("style", { children: FLOPAY_KEYFRAMES });
1807
2206
  }
1808
2207
  function toCssSize(value) {
1809
2208
  if (typeof value === "number") return `${value}px`;
@@ -1825,8 +2224,8 @@ function ExpressCheckoutReadySwap({
1825
2224
  children
1826
2225
  }) {
1827
2226
  if (state === "unavailable" || state === "load_error") return null;
1828
- return /* @__PURE__ */ jsxs4("div", { style: { position: "relative", minHeight: 44 }, children: [
1829
- /* @__PURE__ */ jsx7(
2227
+ return /* @__PURE__ */ jsxs5("div", { style: { position: "relative", minHeight: 44 }, children: [
2228
+ /* @__PURE__ */ jsx8(
1830
2229
  "div",
1831
2230
  {
1832
2231
  "data-testid": placeholderTestId,
@@ -1845,7 +2244,7 @@ function ExpressCheckoutReadySwap({
1845
2244
  }
1846
2245
  }
1847
2246
  ),
1848
- /* @__PURE__ */ jsx7(
2247
+ /* @__PURE__ */ jsx8(
1849
2248
  "div",
1850
2249
  {
1851
2250
  style: {
@@ -1865,7 +2264,7 @@ function isExpressCheckoutRowVisible(state) {
1865
2264
  }
1866
2265
  var SplitCardForm = forwardRef(
1867
2266
  function SplitCardForm2(props, ref) {
1868
- return /* @__PURE__ */ jsx7(SplitCardFormInner, { ...props, innerRef: ref });
2267
+ return /* @__PURE__ */ jsx8(SplitCardFormInner, { ...props, innerRef: ref });
1869
2268
  }
1870
2269
  );
1871
2270
  function PayPalButtonInner({
@@ -1883,6 +2282,7 @@ function PayPalButtonInner({
1883
2282
  onLoadStateChange,
1884
2283
  placeholderBorderRadius
1885
2284
  }) {
2285
+ const flopay = useFloPay();
1886
2286
  const stripe = useStripeRaw();
1887
2287
  const elements = useStripeElements();
1888
2288
  const [loadState, setLoadState] = useState3("loading");
@@ -1890,13 +2290,13 @@ function PayPalButtonInner({
1890
2290
  onLoadStateChange?.(loadState);
1891
2291
  }, [loadState, onLoadStateChange]);
1892
2292
  const [submitting, setSubmitting] = useState3(false);
1893
- const paypalResumeAttempted = useRef4(false);
1894
- const focusTargetRef = useRef4(null);
1895
- const recoveryActionRef = useRef4(null);
2293
+ const paypalResumeAttempted = useRef5(false);
2294
+ const focusTargetRef = useRef5(null);
2295
+ const recoveryActionRef = useRef5(null);
1896
2296
  const [surfaceKey, setSurfaceKey] = useState3(0);
1897
2297
  const [showRecoveryAction, setShowRecoveryAction] = useState3(false);
1898
- const pendingProviderFocusRef = useRef4(false);
1899
- const attemptContextBySurfaceRef = useRef4(/* @__PURE__ */ new Map());
2298
+ const pendingProviderFocusRef = useRef5(false);
2299
+ const attemptContextBySurfaceRef = useRef5(/* @__PURE__ */ new Map());
1900
2300
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
1901
2301
  const {
1902
2302
  startAttempt,
@@ -1915,16 +2315,16 @@ function PayPalButtonInner({
1915
2315
  useEffect5(() => {
1916
2316
  if (showRecoveryAction) recoveryActionRef.current?.focus();
1917
2317
  }, [showRecoveryAction, surfaceKey]);
1918
- const resetSurface = useCallback2(() => {
2318
+ const resetSurface = useCallback3(() => {
1919
2319
  setSurfaceKey((key) => key + 1);
1920
2320
  }, []);
1921
- const recoverTechnicalFailure = useCallback2((err, code, generation) => {
2321
+ const recoverTechnicalFailure = useCallback3((err, code, generation) => {
1922
2322
  invalidateAttempt(generation);
1923
2323
  onTechnicalFailure?.("paypal", err, { code, popupBlocked: isPopupBlockedError(err) });
1924
2324
  setShowRecoveryAction(true);
1925
2325
  resetSurface();
1926
2326
  }, [invalidateAttempt, onTechnicalFailure, resetSurface]);
1927
- const focusProviderSurface = useCallback2(() => {
2327
+ const focusProviderSurface = useCallback3(() => {
1928
2328
  window.setTimeout(() => {
1929
2329
  const target = focusTargetRef.current?.querySelector("iframe");
1930
2330
  (target ?? focusTargetRef.current)?.focus();
@@ -1935,7 +2335,7 @@ function PayPalButtonInner({
1935
2335
  pendingProviderFocusRef.current = false;
1936
2336
  focusProviderSurface();
1937
2337
  }, [focusProviderSurface, surfaceKey]);
1938
- const handleRecoveryActionClick = useCallback2(() => {
2338
+ const handleRecoveryActionClick = useCallback3(() => {
1939
2339
  setShowRecoveryAction(false);
1940
2340
  onErrorChange?.(null);
1941
2341
  focusProviderSurface();
@@ -2006,7 +2406,7 @@ function PayPalButtonInner({
2006
2406
  }
2007
2407
  })();
2008
2408
  }, [stripe, onTokenizedBody, onErrorChange, onDecline]);
2009
- const handlePayPalClick = useCallback2(async (event) => {
2409
+ const handlePayPalClick = useCallback3(async (event) => {
2010
2410
  if (isProcessing || submitting) {
2011
2411
  event.reject();
2012
2412
  return;
@@ -2028,7 +2428,7 @@ function PayPalButtonInner({
2028
2428
  onButtonClick?.("paypal");
2029
2429
  event.resolve();
2030
2430
  }, [attemptContextBySurfaceRef, isProcessing, onButtonClick, runBeforeButtonClick, startAttempt, submitting, surfaceKey]);
2031
- const handlePayPalConfirm = useCallback2(async (event) => {
2431
+ const handlePayPalConfirm = useCallback3(async (event) => {
2032
2432
  if (!stripe || !elements) return;
2033
2433
  const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);
2034
2434
  if (attemptContext && !isAttemptCurrent(attemptContext.generation)) {
@@ -2068,8 +2468,7 @@ function PayPalButtonInner({
2068
2468
  event.paymentFailed({ reason: "fail" });
2069
2469
  return;
2070
2470
  }
2071
- const intentHeaders = { "Content-Type": "application/json" };
2072
- if (effectiveNonce) intentHeaders["x-checkout-session-token"] = effectiveNonce;
2471
+ const intentHeaders = intentRequestHeaders(effectiveNonce);
2073
2472
  const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
2074
2473
  method: "POST",
2075
2474
  headers: intentHeaders,
@@ -2160,14 +2559,14 @@ function PayPalButtonInner({
2160
2559
  setSubmitting(false);
2161
2560
  }
2162
2561
  }, [stripe, elements, sessionId, nonce, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick, recoverTechnicalFailure, finishAttempt, isAttemptCurrent, isAttemptInvalidated, surfaceKey]);
2163
- return /* @__PURE__ */ jsxs4(Fragment2, { children: [
2164
- /* @__PURE__ */ jsx7(
2562
+ return /* @__PURE__ */ jsxs5(Fragment2, { children: [
2563
+ /* @__PURE__ */ jsx8(
2165
2564
  ExpressCheckoutReadySwap,
2166
2565
  {
2167
2566
  state: loadState,
2168
2567
  placeholderTestId: "flopay-paypal-placeholder",
2169
2568
  borderRadius: placeholderBorderRadius,
2170
- children: /* @__PURE__ */ jsxs4(
2569
+ children: /* @__PURE__ */ jsxs5(
2171
2570
  "div",
2172
2571
  {
2173
2572
  ref: focusTargetRef,
@@ -2176,7 +2575,7 @@ function PayPalButtonInner({
2176
2575
  "aria-label": "PayPal payment method",
2177
2576
  style: { borderRadius: 8, outlineOffset: 4 },
2178
2577
  children: [
2179
- showRecoveryAction && /* @__PURE__ */ jsx7(
2578
+ showRecoveryAction && /* @__PURE__ */ jsx8(
2180
2579
  "button",
2181
2580
  {
2182
2581
  ref: recoveryActionRef,
@@ -2187,7 +2586,7 @@ function PayPalButtonInner({
2187
2586
  children: "Try PayPal again"
2188
2587
  }
2189
2588
  ),
2190
- /* @__PURE__ */ jsx7(
2589
+ /* @__PURE__ */ jsx8(
2191
2590
  ExpressCheckoutElement,
2192
2591
  {
2193
2592
  onReady: (event) => setLoadState(resolveExpressCheckoutLoadState(event, ["paypal"])),
@@ -2197,6 +2596,11 @@ function PayPalButtonInner({
2197
2596
  onCancel: () => {
2198
2597
  const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);
2199
2598
  attemptContextBySurfaceRef.current.delete(surfaceKey);
2599
+ getFloPayTelemetryBridge(flopay)?.terminal({
2600
+ outcome: "payment_cancelled",
2601
+ provider: "paypal",
2602
+ paymentMethodCategory: "paypal"
2603
+ });
2200
2604
  invalidateAttempt(attemptContext?.generation);
2201
2605
  setShowRecoveryAction(false);
2202
2606
  pendingProviderFocusRef.current = true;
@@ -2222,7 +2626,7 @@ function PayPalButtonInner({
2222
2626
  )
2223
2627
  }
2224
2628
  ),
2225
- submitting && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: "processing" })
2629
+ submitting && /* @__PURE__ */ jsx8(ProcessingOverlay, { status: "processing" })
2226
2630
  ] });
2227
2631
  }
2228
2632
  function WalletButtonInner({
@@ -2240,6 +2644,7 @@ function WalletButtonInner({
2240
2644
  onLoadStateChange,
2241
2645
  placeholderBorderRadius
2242
2646
  }) {
2647
+ const flopay = useFloPay();
2243
2648
  const stripe = useStripeRaw();
2244
2649
  const elements = useStripeElements();
2245
2650
  const [loadState, setLoadState] = useState3("loading");
@@ -2248,15 +2653,15 @@ function WalletButtonInner({
2248
2653
  }, [loadState, onLoadStateChange]);
2249
2654
  const [submitting, setSubmitting] = useState3(false);
2250
2655
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
2251
- const focusTargetRef = useRef4(null);
2252
- const recoveryActionRef = useRef4(null);
2656
+ const focusTargetRef = useRef5(null);
2657
+ const recoveryActionRef = useRef5(null);
2253
2658
  const [surfaceKey, setSurfaceKey] = useState3(0);
2254
2659
  const [showRecoveryAction, setShowRecoveryAction] = useState3(false);
2255
2660
  const [recoveryActionMethod, setRecoveryActionMethod] = useState3("google_pay");
2256
- const pendingProviderFocusRef = useRef4(false);
2257
- const lastWalletProviderMethodRef = useRef4("google_pay");
2258
- const lastWalletMethodRef = useRef4("google_pay");
2259
- const attemptContextBySurfaceRef = useRef4(/* @__PURE__ */ new Map());
2661
+ const pendingProviderFocusRef = useRef5(false);
2662
+ const lastWalletProviderMethodRef = useRef5("google_pay");
2663
+ const lastWalletMethodRef = useRef5("google_pay");
2664
+ const attemptContextBySurfaceRef = useRef5(/* @__PURE__ */ new Map());
2260
2665
  const {
2261
2666
  startAttempt,
2262
2667
  finishAttempt,
@@ -2275,17 +2680,17 @@ function WalletButtonInner({
2275
2680
  useEffect5(() => {
2276
2681
  if (showRecoveryAction) recoveryActionRef.current?.focus();
2277
2682
  }, [showRecoveryAction, surfaceKey]);
2278
- const resetSurface = useCallback2(() => {
2683
+ const resetSurface = useCallback3(() => {
2279
2684
  setSurfaceKey((key) => key + 1);
2280
2685
  }, []);
2281
- const recoverTechnicalFailure = useCallback2((method, err, code, generation) => {
2686
+ const recoverTechnicalFailure = useCallback3((method, err, code, generation) => {
2282
2687
  invalidateAttempt(generation);
2283
2688
  onTechnicalFailure?.(method, err, { code, popupBlocked: isPopupBlockedError(err) });
2284
2689
  setRecoveryActionMethod(method);
2285
2690
  setShowRecoveryAction(true);
2286
2691
  resetSurface();
2287
2692
  }, [invalidateAttempt, onTechnicalFailure, resetSurface]);
2288
- const focusProviderSurface = useCallback2(() => {
2693
+ const focusProviderSurface = useCallback3(() => {
2289
2694
  window.setTimeout(() => {
2290
2695
  const target = focusTargetRef.current?.querySelector("iframe");
2291
2696
  (target ?? focusTargetRef.current)?.focus();
@@ -2296,12 +2701,12 @@ function WalletButtonInner({
2296
2701
  pendingProviderFocusRef.current = false;
2297
2702
  focusProviderSurface();
2298
2703
  }, [focusProviderSurface, surfaceKey]);
2299
- const handleRecoveryActionClick = useCallback2(() => {
2704
+ const handleRecoveryActionClick = useCallback3(() => {
2300
2705
  setShowRecoveryAction(false);
2301
2706
  onErrorChange?.(null);
2302
2707
  focusProviderSurface();
2303
2708
  }, [focusProviderSurface, onErrorChange]);
2304
- const handleWalletConfirm = useCallback2(
2709
+ const handleWalletConfirm = useCallback3(
2305
2710
  async (event) => {
2306
2711
  if (!stripe || !elements) return;
2307
2712
  const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);
@@ -2348,8 +2753,7 @@ function WalletButtonInner({
2348
2753
  if (!effectiveSessionId || !effectiveEmail) {
2349
2754
  throw new Error("Missing sessionId or email for wallet payment");
2350
2755
  }
2351
- const intentHeaders = { "Content-Type": "application/json" };
2352
- if (effectiveNonce) intentHeaders["x-checkout-session-token"] = effectiveNonce;
2756
+ const intentHeaders = intentRequestHeaders(effectiveNonce);
2353
2757
  const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
2354
2758
  method: "POST",
2355
2759
  headers: intentHeaders,
@@ -2422,14 +2826,14 @@ function WalletButtonInner({
2422
2826
  () => expressMethods.map(stripeExpressMethodToOptionKey),
2423
2827
  [expressMethods]
2424
2828
  );
2425
- return /* @__PURE__ */ jsxs4(Fragment2, { children: [
2426
- /* @__PURE__ */ jsx7(
2829
+ return /* @__PURE__ */ jsxs5(Fragment2, { children: [
2830
+ /* @__PURE__ */ jsx8(
2427
2831
  ExpressCheckoutReadySwap,
2428
2832
  {
2429
2833
  state: loadState,
2430
2834
  placeholderTestId: "flopay-wallet-placeholder",
2431
2835
  borderRadius: placeholderBorderRadius,
2432
- children: /* @__PURE__ */ jsxs4(
2836
+ children: /* @__PURE__ */ jsxs5(
2433
2837
  "div",
2434
2838
  {
2435
2839
  ref: focusTargetRef,
@@ -2438,7 +2842,7 @@ function WalletButtonInner({
2438
2842
  "aria-label": "Wallet payment methods",
2439
2843
  style: { borderRadius: 8, outlineOffset: 4 },
2440
2844
  children: [
2441
- showRecoveryAction && /* @__PURE__ */ jsxs4(
2845
+ showRecoveryAction && /* @__PURE__ */ jsxs5(
2442
2846
  "button",
2443
2847
  {
2444
2848
  ref: recoveryActionRef,
@@ -2453,7 +2857,7 @@ function WalletButtonInner({
2453
2857
  ]
2454
2858
  }
2455
2859
  ),
2456
- /* @__PURE__ */ jsx7(
2860
+ /* @__PURE__ */ jsx8(
2457
2861
  ExpressCheckoutElement,
2458
2862
  {
2459
2863
  onReady: (event) => {
@@ -2461,6 +2865,13 @@ function WalletButtonInner({
2461
2865
  },
2462
2866
  onLoadError: (_event) => {
2463
2867
  setLoadState("load_error");
2868
+ getFloPayTelemetryBridge(flopay)?.error({
2869
+ errorCode: "PROVIDER_LOAD_FAILED",
2870
+ stage: "provider_load",
2871
+ provider: "stripe",
2872
+ paymentMethodCategory: "wallet",
2873
+ requestCategory: "provider_sdk"
2874
+ });
2464
2875
  },
2465
2876
  onClick: async (event) => {
2466
2877
  lastWalletProviderMethodRef.current = event.expressPaymentType;
@@ -2487,6 +2898,11 @@ function WalletButtonInner({
2487
2898
  onCancel: () => {
2488
2899
  const attemptContext = attemptContextBySurfaceRef.current.get(surfaceKey);
2489
2900
  attemptContextBySurfaceRef.current.delete(surfaceKey);
2901
+ getFloPayTelemetryBridge(flopay)?.terminal({
2902
+ outcome: "payment_cancelled",
2903
+ provider: "stripe",
2904
+ paymentMethodCategory: "wallet"
2905
+ });
2490
2906
  invalidateAttempt(attemptContext?.generation);
2491
2907
  setShowRecoveryAction(false);
2492
2908
  pendingProviderFocusRef.current = true;
@@ -2505,7 +2921,7 @@ function WalletButtonInner({
2505
2921
  )
2506
2922
  }
2507
2923
  ),
2508
- submitting && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: "processing" })
2924
+ submitting && /* @__PURE__ */ jsx8(ProcessingOverlay, { status: "processing" })
2509
2925
  ] });
2510
2926
  }
2511
2927
  function StripeMethodButton({
@@ -2523,10 +2939,11 @@ function StripeMethodButton({
2523
2939
  fontFamily
2524
2940
  }) {
2525
2941
  const brand = resolveStripeMethodBrandVariant(method, themeId);
2942
+ const vendoredLogoUrl = PAYMENT_METHOD_LOGO_URLS[method];
2526
2943
  const resolvedBackground = brand?.backgroundColor ?? backgroundColor ?? "#ffffff";
2527
2944
  const resolvedBorder = brand?.borderColor ?? borderColor ?? "#d1d5db";
2528
2945
  const resolvedTextColor = brand?.textColor ?? textColor ?? "#262833";
2529
- return /* @__PURE__ */ jsx7(
2946
+ return /* @__PURE__ */ jsx8(
2530
2947
  "button",
2531
2948
  {
2532
2949
  type: "button",
@@ -2573,9 +2990,9 @@ function StripeMethodButton({
2573
2990
  // Pulse-skeleton parity with the wallet ECE: no spinner, just the
2574
2991
  // status text on top of the pulsing background. Keeps the loading
2575
2992
  // affordance shape-equivalent across both kinds of tile.
2576
- /* @__PURE__ */ jsx7("span", { style: { margin: "0 auto" }, children: `Connecting to ${getStripeMethodDisplayName(method)}\u2026` })
2577
- ) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
2578
- /* @__PURE__ */ jsxs4(
2993
+ /* @__PURE__ */ jsx8("span", { style: { margin: "0 auto" }, children: `Connecting to ${getStripeMethodDisplayName(method)}\u2026` })
2994
+ ) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2995
+ /* @__PURE__ */ jsxs5(
2579
2996
  "span",
2580
2997
  {
2581
2998
  style: {
@@ -2588,15 +3005,36 @@ function StripeMethodButton({
2588
3005
  gap: hasVendoredStripeMethodLogo(method) ? 8 : 0
2589
3006
  },
2590
3007
  children: [
2591
- brand?.logoSvg && /* @__PURE__ */ jsx7(
3008
+ vendoredLogoUrl ? (
3009
+ // Vendored brand logo — an <img> asset (not inline SVG) so its
3010
+ // bytes ship as a sibling file, out of the JS bundle. 3:2 box
3011
+ // matching the datatrans logos' 120×80 viewBox; each ships its own
3012
+ // white rounded-rect background so it stays legible on any tile.
3013
+ /* @__PURE__ */ jsx8(
3014
+ "img",
3015
+ {
3016
+ src: vendoredLogoUrl,
3017
+ alt: "",
3018
+ "aria-hidden": "true",
3019
+ loading: "lazy",
3020
+ decoding: "async",
3021
+ width: 30,
3022
+ height: 20,
3023
+ style: {
3024
+ width: 30,
3025
+ height: 20,
3026
+ flexShrink: 0,
3027
+ borderRadius: 3,
3028
+ objectFit: "contain",
3029
+ display: "inline-flex"
3030
+ }
3031
+ }
3032
+ )
3033
+ ) : brand?.logoSvg ? /* @__PURE__ */ jsx8(
2592
3034
  "span",
2593
3035
  {
2594
3036
  "aria-hidden": "true",
2595
3037
  style: {
2596
- // 3:2 box matching the vendored datatrans logos' 120×80
2597
- // viewBox. Each logo ships with its own white rounded-rect
2598
- // background baked in, so the mark stays legible on any
2599
- // brand-coloured tile without an extra chip wrapper here.
2600
3038
  width: 30,
2601
3039
  height: 20,
2602
3040
  flexShrink: 0,
@@ -2606,12 +3044,12 @@ function StripeMethodButton({
2606
3044
  },
2607
3045
  dangerouslySetInnerHTML: { __html: brand.logoSvg }
2608
3046
  }
2609
- ),
2610
- /* @__PURE__ */ jsx7("span", { children: getStripeMethodDisplayName(method) })
3047
+ ) : null,
3048
+ /* @__PURE__ */ jsx8("span", { children: getStripeMethodDisplayName(method) })
2611
3049
  ]
2612
3050
  }
2613
3051
  ),
2614
- hasNextStep && /* @__PURE__ */ jsx7(
3052
+ hasNextStep && /* @__PURE__ */ jsx8(
2615
3053
  "svg",
2616
3054
  {
2617
3055
  width: "14",
@@ -2631,7 +3069,7 @@ function StripeMethodButton({
2631
3069
  opacity: 0.7
2632
3070
  },
2633
3071
  "aria-hidden": "true",
2634
- children: /* @__PURE__ */ jsx7("path", { d: "M9 18l6-6-6-6" })
3072
+ children: /* @__PURE__ */ jsx8("path", { d: "M9 18l6-6-6-6" })
2635
3073
  }
2636
3074
  )
2637
3075
  ] })
@@ -2657,14 +3095,15 @@ function StripeMethodInlineForm({
2657
3095
  submitButtonStyle,
2658
3096
  errorText
2659
3097
  }) {
3098
+ const flopay = useFloPay();
2660
3099
  const stripe = useStripeRaw();
2661
3100
  const elements = useStripeElements();
2662
3101
  const [submitting, setSubmitting] = useState3(false);
2663
- const submittingRef = useRef4(false);
3102
+ const submittingRef = useRef5(false);
2664
3103
  const [isMethodComplete, setIsMethodComplete] = useState3(false);
2665
3104
  const [loadState, setLoadState] = useState3("loading");
2666
3105
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
2667
- const handlePay = useCallback2(async () => {
3106
+ const handlePay = useCallback3(async () => {
2668
3107
  if (!stripe || !elements || isProcessing || submittingRef.current || !isMethodComplete) return;
2669
3108
  submittingRef.current = true;
2670
3109
  setSubmitting(true);
@@ -2694,8 +3133,7 @@ function StripeMethodInlineForm({
2694
3133
  if (!effectiveSessionId || !effectiveEmail) {
2695
3134
  throw new Error("Missing sessionId or email for payment.");
2696
3135
  }
2697
- const intentHeaders = { "Content-Type": "application/json" };
2698
- if (effectiveNonce) intentHeaders["x-checkout-session-token"] = effectiveNonce;
3136
+ const intentHeaders = intentRequestHeaders(effectiveNonce);
2699
3137
  const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
2700
3138
  method: "POST",
2701
3139
  headers: intentHeaders,
@@ -2749,9 +3187,8 @@ function StripeMethodInlineForm({
2749
3187
  onDecline?.(buildDeclineEvent("card", message, { code: confirmError.code }));
2750
3188
  return;
2751
3189
  }
2752
- const SUCCESSFUL_PI_STATUSES = /* @__PURE__ */ new Set(["succeeded", "requires_capture", "processing"]);
2753
3190
  const piStatus = paymentIntent?.status;
2754
- if (!piStatus || !SUCCESSFUL_PI_STATUSES.has(piStatus)) {
3191
+ if (!isSuccessfulPaymentIntentStatus(piStatus)) {
2755
3192
  if (typeof window !== "undefined") {
2756
3193
  try {
2757
3194
  localStorage.removeItem(STRIPE_RESUME_KEY);
@@ -2804,12 +3241,21 @@ function StripeMethodInlineForm({
2804
3241
  onDecline
2805
3242
  ]);
2806
3243
  void onCancel;
2807
- return /* @__PURE__ */ jsxs4("div", { "data-testid": `flopay-stripe-method-form-${method}`, style: { display: "flex", flexDirection: "column" }, children: [
2808
- /* @__PURE__ */ jsx7(
3244
+ return /* @__PURE__ */ jsxs5("div", { "data-testid": `flopay-stripe-method-form-${method}`, style: { display: "flex", flexDirection: "column" }, children: [
3245
+ /* @__PURE__ */ jsx8(
2809
3246
  PaymentElement2,
2810
3247
  {
2811
3248
  onReady: () => setLoadState("ready"),
2812
- onLoadError: () => setLoadState("load_error"),
3249
+ onLoadError: () => {
3250
+ setLoadState("load_error");
3251
+ getFloPayTelemetryBridge(flopay)?.error({
3252
+ errorCode: "PROVIDER_LOAD_FAILED",
3253
+ stage: "provider_load",
3254
+ provider: "stripe",
3255
+ paymentMethodCategory: "apm",
3256
+ requestCategory: "provider_sdk"
3257
+ });
3258
+ },
2813
3259
  onChange: (event) => {
2814
3260
  const evRecord = event;
2815
3261
  setIsMethodComplete(!!evRecord.complete);
@@ -2825,7 +3271,7 @@ function StripeMethodInlineForm({
2825
3271
  }
2826
3272
  }
2827
3273
  ),
2828
- /* @__PURE__ */ jsx7(
3274
+ /* @__PURE__ */ jsx8(
2829
3275
  "button",
2830
3276
  {
2831
3277
  type: "button",
@@ -2852,22 +3298,7 @@ function StripeMethodInlineForm({
2852
3298
  children: submitting ? "Processing\u2026" : `Pay with ${getStripeMethodDisplayName(method)}`
2853
3299
  }
2854
3300
  ),
2855
- errorText && /* @__PURE__ */ jsxs4("div", { role: "alert", "data-testid": "flopay-error", style: {
2856
- margin: "0.75rem 0 0",
2857
- padding: "0.625rem 0.875rem",
2858
- background: "#FEF2F2",
2859
- border: "1px solid #FECACA",
2860
- borderRadius: "8px",
2861
- color: "#991B1B",
2862
- fontSize: "0.85rem",
2863
- fontWeight: 600,
2864
- display: "flex",
2865
- alignItems: "center",
2866
- gap: "0.5rem"
2867
- }, children: [
2868
- /* @__PURE__ */ jsx7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx7("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
2869
- errorText
2870
- ] })
3301
+ errorText && /* @__PURE__ */ jsx8(ErrorBanner, { margin: "0.75rem 0 0", children: errorText })
2871
3302
  ] });
2872
3303
  }
2873
3304
  function StripePaymentElementInner({
@@ -2897,7 +3328,7 @@ function StripePaymentElementInner({
2897
3328
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
2898
3329
  const [expandedMethod, setExpandedMethod] = useState3(null);
2899
3330
  const [submittingMethod, setSubmittingMethod] = useState3(null);
2900
- const submittingRef = useRef4(false);
3331
+ const submittingRef = useRef5(false);
2901
3332
  useEffect5(() => {
2902
3333
  if (paymentElementMethods.length > 0 && stripeInstance) {
2903
3334
  onLoadStateChange?.("ready");
@@ -2905,7 +3336,7 @@ function StripePaymentElementInner({
2905
3336
  onLoadStateChange?.("loading");
2906
3337
  }
2907
3338
  }, [paymentElementMethods.length, stripeInstance, onLoadStateChange]);
2908
- const handleAutoConfirm = useCallback2(async (method) => {
3339
+ const handleAutoConfirm = useCallback3(async (method) => {
2909
3340
  if (!stripeInstance) return;
2910
3341
  if (submittingRef.current || isProcessing) return;
2911
3342
  submittingRef.current = true;
@@ -2925,8 +3356,7 @@ function StripePaymentElementInner({
2925
3356
  if (!effectiveSessionId || !effectiveEmail) {
2926
3357
  throw new Error("Missing sessionId or email for payment.");
2927
3358
  }
2928
- const intentHeaders = { "Content-Type": "application/json" };
2929
- if (effectiveNonce) intentHeaders["x-checkout-session-token"] = effectiveNonce;
3359
+ const intentHeaders = intentRequestHeaders(effectiveNonce);
2930
3360
  const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
2931
3361
  method: "POST",
2932
3362
  headers: intentHeaders,
@@ -2992,9 +3422,8 @@ function StripePaymentElementInner({
2992
3422
  onDecline?.(buildDeclineEvent("card", message, { code: confirmError.code }));
2993
3423
  return;
2994
3424
  }
2995
- const SUCCESSFUL_PI_STATUSES = /* @__PURE__ */ new Set(["succeeded", "requires_capture", "processing"]);
2996
3425
  const piStatus = paymentIntent?.status;
2997
- if (!piStatus || !SUCCESSFUL_PI_STATUSES.has(piStatus)) {
3426
+ if (!isSuccessfulPaymentIntentStatus(piStatus)) {
2998
3427
  if (typeof window !== "undefined") {
2999
3428
  try {
3000
3429
  localStorage.removeItem(STRIPE_RESUME_KEY);
@@ -3046,7 +3475,7 @@ function StripePaymentElementInner({
3046
3475
  ]);
3047
3476
  const [localExpandedMethod, setLocalExpandedMethod] = useState3(null);
3048
3477
  const activeExpandedMethod = onExpandApm ? expandedApmMethod ?? null : localExpandedMethod;
3049
- const handleMethodClick = useCallback2((method) => {
3478
+ const handleMethodClick = useCallback3((method) => {
3050
3479
  if (submittingRef.current || isProcessing) return;
3051
3480
  if (activeExpandedMethod && activeExpandedMethod !== method) return;
3052
3481
  if (needsStripeMethodExplicitConfirm(method)) {
@@ -3066,7 +3495,7 @@ function StripePaymentElementInner({
3066
3495
  paymentMethodTypes: [localExpandedMethod]
3067
3496
  };
3068
3497
  }, [localExpandedMethod, paymentElementBaseOptions]);
3069
- return /* @__PURE__ */ jsx7(
3498
+ return /* @__PURE__ */ jsx8(
3070
3499
  "div",
3071
3500
  {
3072
3501
  "data-testid": "flopay-stripe-payment-element-region",
@@ -3075,8 +3504,8 @@ function StripePaymentElementInner({
3075
3504
  const isExpanded = expandedApmMethod === method;
3076
3505
  const isSubmittingThis = submittingMethod === method;
3077
3506
  const otherInProgress = submittingMethod !== null && submittingMethod !== method || expandedApmMethod !== null && expandedApmMethod !== void 0 && expandedApmMethod !== method;
3078
- return /* @__PURE__ */ jsxs4(React7.Fragment, { children: [
3079
- /* @__PURE__ */ jsx7(
3507
+ return /* @__PURE__ */ jsxs5(React8.Fragment, { children: [
3508
+ /* @__PURE__ */ jsx8(
3080
3509
  StripeMethodButton,
3081
3510
  {
3082
3511
  method,
@@ -3093,12 +3522,12 @@ function StripePaymentElementInner({
3093
3522
  fontFamily: buttonAppearance?.fontFamily
3094
3523
  }
3095
3524
  ),
3096
- !onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && /* @__PURE__ */ jsx7(
3525
+ !onExpandApm && localExpandedMethod === method && localInlineElementsOptions && stripeInstance && /* @__PURE__ */ jsx8(
3097
3526
  StripeElements,
3098
3527
  {
3099
3528
  stripe: stripeInstance,
3100
3529
  options: localInlineElementsOptions,
3101
- children: /* @__PURE__ */ jsx7(
3530
+ children: /* @__PURE__ */ jsx8(
3102
3531
  StripeMethodInlineForm,
3103
3532
  {
3104
3533
  method,
@@ -3204,12 +3633,12 @@ function SplitCardFormInner({
3204
3633
  const [city, setCity] = useState3(cityProp ?? "");
3205
3634
  const [stateValue, setStateValue] = useState3(stateProp ?? "");
3206
3635
  const [accountPatch, setAccountPatch] = useState3({});
3207
- const zipCodeRef = useRef4(zipProp ?? "");
3208
- const selectedCountryRef = useRef4(countryProp ?? "US");
3209
- const addressLine1Ref = useRef4(addressLine1Prop ?? "");
3210
- const addressLine2Ref = useRef4(addressLine2Prop ?? "");
3211
- const cityRef = useRef4(cityProp ?? "");
3212
- const stateRef = useRef4(stateProp ?? "");
3636
+ const zipCodeRef = useRef5(zipProp ?? "");
3637
+ const selectedCountryRef = useRef5(countryProp ?? "US");
3638
+ const addressLine1Ref = useRef5(addressLine1Prop ?? "");
3639
+ const addressLine2Ref = useRef5(addressLine2Prop ?? "");
3640
+ const cityRef = useRef5(cityProp ?? "");
3641
+ const stateRef = useRef5(stateProp ?? "");
3213
3642
  const avsConfig = useMemo3(() => resolveAVSConfig(enableAVSProp), [enableAVSProp]);
3214
3643
  const enableAVS = avsConfig !== null;
3215
3644
  const vaultBlockReady = Boolean(session?.vault?.html);
@@ -3251,20 +3680,20 @@ function SplitCardFormInner({
3251
3680
  const [expandedApmMethod, setExpandedApmMethod] = useState3(null);
3252
3681
  const showCardForm = viewState === "expanding" || viewState === "card";
3253
3682
  const TRANSITION_MS = 280;
3254
- const expandToCard = useCallback2(() => {
3683
+ const expandToCard = useCallback3(() => {
3255
3684
  setViewState("expanding");
3256
3685
  setTimeout(() => setViewState("card"), TRANSITION_MS);
3257
3686
  }, []);
3258
- const collapseToButtons = useCallback2(() => {
3687
+ const collapseToButtons = useCallback3(() => {
3259
3688
  setViewState("collapsing");
3260
3689
  setTimeout(() => setViewState("buttons"), TRANSITION_MS);
3261
3690
  }, []);
3262
- const expandToApm = useCallback2((method) => {
3691
+ const expandToApm = useCallback3((method) => {
3263
3692
  setExpandedApmMethod(method);
3264
3693
  setViewState("apm-expanding");
3265
3694
  setTimeout(() => setViewState("apm-form"), TRANSITION_MS);
3266
3695
  }, []);
3267
- const collapseFromApm = useCallback2(() => {
3696
+ const collapseFromApm = useCallback3(() => {
3268
3697
  setViewState("apm-collapsing");
3269
3698
  setTimeout(() => {
3270
3699
  setViewState("buttons");
@@ -3279,9 +3708,9 @@ function SplitCardFormInner({
3279
3708
  const [fullName, setFullName] = useState3("");
3280
3709
  const [formReady, setFormReady] = useState3(false);
3281
3710
  const [overlayStatus, setOverlayStatus] = useState3(null);
3282
- const processingRef = useRef4(false);
3711
+ const processingRef = useRef5(false);
3283
3712
  const [paypalDirectRetry, setPaypalDirectRetry] = useState3(null);
3284
- const paypalDirectRetryRef = useRef4(paypalDirectRetry);
3713
+ const paypalDirectRetryRef = useRef5(paypalDirectRetry);
3285
3714
  useEffect5(() => {
3286
3715
  paypalDirectRetryRef.current = paypalDirectRetry;
3287
3716
  }, [paypalDirectRetry]);
@@ -3389,7 +3818,7 @@ function SplitCardFormInner({
3389
3818
  setupFutureUsage: "off_session",
3390
3819
  ...stripeAppearanceProp
3391
3820
  }), [amountInCents, currency, stripeAppearanceProp]);
3392
- const updateError = useCallback2(
3821
+ const updateError = useCallback3(
3393
3822
  (err) => {
3394
3823
  setError(err);
3395
3824
  onErrorChange?.(err);
@@ -3405,13 +3834,13 @@ function SplitCardFormInner({
3405
3834
  updateError(null);
3406
3835
  }
3407
3836
  }, [viewState, updateError]);
3408
- const emitDecline = useCallback2(
3837
+ const emitDecline = useCallback3(
3409
3838
  (method, input, overrides) => {
3410
3839
  onDecline?.(buildDeclineEvent(method, input, overrides));
3411
3840
  },
3412
3841
  [onDecline]
3413
3842
  );
3414
- const recoverExternalMethodTechnicalFailure = useCallback2(
3843
+ const recoverExternalMethodTechnicalFailure = useCallback3(
3415
3844
  (method, err, options) => {
3416
3845
  const popupBlocked = options?.popupBlocked ?? isPopupBlockedError(err);
3417
3846
  const message = buildExternalMethodRecoveryMessage(method, popupBlocked);
@@ -3473,7 +3902,7 @@ function SplitCardFormInner({
3473
3902
  nonce,
3474
3903
  updateError
3475
3904
  ]);
3476
- const vaultOutcomeRef = useRef4({
3905
+ const vaultOutcomeRef = useRef5({
3477
3906
  onComplete,
3478
3907
  onError,
3479
3908
  updateError,
@@ -3499,8 +3928,8 @@ function SplitCardFormInner({
3499
3928
  nonce,
3500
3929
  baseUrl
3501
3930
  };
3502
- const vaultCompletedRef = useRef4(false);
3503
- const buildVaultAccountSnapshot = useCallback2(() => {
3931
+ const vaultCompletedRef = useRef5(false);
3932
+ const buildVaultAccountSnapshot = useCallback3(() => {
3504
3933
  const { resolvedAccount: resolvedAccount2, avsConfig: avsConfig2, fullName: fullName2, avsCheckProp: avsCheckProp2 } = vaultOutcomeRef.current;
3505
3934
  const cc = selectedCountryRef.current || resolvedAccount2.country || "US";
3506
3935
  const stateVisible = avsConfig2 ? isAVSFieldVisible(avsConfig2.state, cc) : false;
@@ -3656,7 +4085,7 @@ function SplitCardFormInner({
3656
4085
  const shouldDisplayPayPalRow = shouldRenderDirectPayPal ? directPaypalReady : shouldRenderStripePayPal && isExpressCheckoutRowVisible(paypalLoadState);
3657
4086
  const shouldDisplayWalletRow = shouldRenderWallets && isExpressCheckoutRowVisible(walletLoadState);
3658
4087
  const shouldDisplayPaymentElementRow = shouldRenderPaymentElement && paymentElementLoadState !== "load_error";
3659
- const validationFiredRef = useRef4(false);
4088
+ const validationFiredRef = useRef5(false);
3660
4089
  useEffect5(() => {
3661
4090
  if (validationFiredRef.current) return;
3662
4091
  if (!showStripe && !showPayPal) {
@@ -3677,7 +4106,7 @@ function SplitCardFormInner({
3677
4106
  updateError(err.message);
3678
4107
  }
3679
4108
  }, [showStripe, showPayPal, directPaypalConfigured, paypalStripeInstance, onError, updateError]);
3680
- const deprecationLoggedRef = useRef4(false);
4109
+ const deprecationLoggedRef = useRef5(false);
3681
4110
  useEffect5(() => {
3682
4111
  if (deprecationLoggedRef.current) return;
3683
4112
  if (!hasEnabledMethods) return;
@@ -3690,14 +4119,14 @@ function SplitCardFormInner({
3690
4119
  `[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.`
3691
4120
  );
3692
4121
  }, [hasEnabledMethods, showApplePay, showGooglePay]);
3693
- const handleNameChange = useCallback2((value) => {
4122
+ const handleNameChange = useCallback3((value) => {
3694
4123
  setFullName(value);
3695
4124
  onFullNameChange?.(value);
3696
4125
  const parts = value.trim().split(/\s+/);
3697
4126
  onFirstNameChange?.(parts[0] ?? "");
3698
4127
  onLastNameChange?.(parts.length > 1 ? parts.slice(1).join(" ") : "");
3699
4128
  }, [onFullNameChange, onFirstNameChange, onLastNameChange]);
3700
- const applyInlineSessionPatch = useCallback2(
4129
+ const applyInlineSessionPatch = useCallback3(
3701
4130
  (patch, method) => {
3702
4131
  if (!checkout.applyInlineSessionPatch) {
3703
4132
  return Promise.resolve({ error: null, sessionId, nonce });
@@ -3719,7 +4148,7 @@ function SplitCardFormInner({
3719
4148
  },
3720
4149
  [checkout.applyInlineSessionPatch, nonce, onError, sessionId, updateError]
3721
4150
  );
3722
- const runBeforeButtonClick = useCallback2(async (method) => {
4151
+ const runBeforeButtonClick = useCallback3(async (method) => {
3723
4152
  if (!onBeforeButtonClick) return { proceed: true };
3724
4153
  try {
3725
4154
  const result = await onBeforeButtonClick({
@@ -3756,7 +4185,7 @@ function SplitCardFormInner({
3756
4185
  return { proceed: false };
3757
4186
  }
3758
4187
  }, [applyInlineSessionPatch, checkout.inlineSessionDraft, onBeforeButtonClick, onError, sessionId, updateError]);
3759
- const processPaymentInternal = useCallback2(
4188
+ const processPaymentInternal = useCallback3(
3760
4189
  async (tokenizedBody, overrides) => {
3761
4190
  if (processingRef.current) return;
3762
4191
  processingRef.current = true;
@@ -3967,7 +4396,7 @@ function SplitCardFormInner({
3967
4396
  },
3968
4397
  [baseUrl, sessionId, nonce, resolvedAccount, fullName, chv, flopay, paypalFlopay, onComplete, onError, updateError, emitDecline]
3969
4398
  );
3970
- const dispatchTokenizedBody = useCallback2(
4399
+ const dispatchTokenizedBody = useCallback3(
3971
4400
  (tokenizedBody, overrides) => {
3972
4401
  if (onTokenizedBody) {
3973
4402
  onTokenizedBody(tokenizedBody);
@@ -4004,7 +4433,7 @@ function SplitCardFormInner({
4004
4433
  }
4005
4434
  }
4006
4435
  }), [flopay, dispatchTokenizedBody, onError, updateError, emitDecline]);
4007
- const stripeResumeAttemptedRef = useRef4(false);
4436
+ const stripeResumeAttemptedRef = useRef5(false);
4008
4437
  useEffect5(() => {
4009
4438
  if (typeof window === "undefined" || stripeResumeAttemptedRef.current) return;
4010
4439
  const params = new URLSearchParams(window.location.search);
@@ -4066,7 +4495,7 @@ function SplitCardFormInner({
4066
4495
  return;
4067
4496
  }
4068
4497
  const piStatus = paymentIntent?.status;
4069
- const successful = piStatus === "succeeded" || piStatus === "requires_capture" || piStatus === "processing";
4498
+ const successful = isSuccessfulPaymentIntentStatus(piStatus);
4070
4499
  if (!paymentIntent || !successful) {
4071
4500
  const message = piStatus === "canceled" ? "Payment was canceled." : "Payment was not completed. Please try again.";
4072
4501
  updateError(message);
@@ -4083,7 +4512,7 @@ function SplitCardFormInner({
4083
4512
  }, persistedOverrides);
4084
4513
  })();
4085
4514
  }, [sessionId, dispatchTokenizedBody, flopay, updateError, emitDecline]);
4086
- const handleSubmit = useCallback2(
4515
+ const handleSubmit = useCallback3(
4087
4516
  async (e) => {
4088
4517
  e.preventDefault();
4089
4518
  if (!flopay || !elements || isSubmitting || processingRef.current) return;
@@ -4166,8 +4595,7 @@ function SplitCardFormInner({
4166
4595
  updateError(pmResult.error?.message ?? "Failed to create payment method.");
4167
4596
  return;
4168
4597
  }
4169
- const intentHeaders = { "Content-Type": "application/json" };
4170
- if (nonce) intentHeaders["x-checkout-session-token"] = nonce;
4598
+ const intentHeaders = intentRequestHeaders(nonce);
4171
4599
  const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
4172
4600
  method: "POST",
4173
4601
  headers: intentHeaders,
@@ -4243,7 +4671,7 @@ function SplitCardFormInner({
4243
4671
  );
4244
4672
  const isReady = flopay !== null && (vaultActive || elements !== null);
4245
4673
  if (!isReady) {
4246
- return /* @__PURE__ */ jsx7("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
4674
+ return /* @__PURE__ */ jsx8("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
4247
4675
  }
4248
4676
  const isButtons = layout === "buttons";
4249
4677
  const appearanceVars = appearance?.variables;
@@ -4302,7 +4730,7 @@ function SplitCardFormInner({
4302
4730
  const containerOverrides = bStyles.cardFormContainer ?? {};
4303
4731
  const containerPadding = containerOverrides.padding ?? (isButtons ? "0" : "1rem");
4304
4732
  const containerRadius = containerOverrides.borderRadius ?? resolvedBorderRadius;
4305
- const vaultCardFieldsNode = cardCapture && vaultMount ? /* @__PURE__ */ jsx7(
4733
+ const vaultCardFieldsNode = cardCapture && vaultMount ? /* @__PURE__ */ jsx8(
4306
4734
  VaultCardFields,
4307
4735
  {
4308
4736
  capture: cardCapture,
@@ -4340,7 +4768,7 @@ function SplitCardFormInner({
4340
4768
  if (message) setOverlayStatus(null);
4341
4769
  }
4342
4770
  }
4343
- ) : /* @__PURE__ */ jsx7(
4771
+ ) : /* @__PURE__ */ jsx8(
4344
4772
  "div",
4345
4773
  {
4346
4774
  "data-testid": "flopay-vault-loading",
@@ -4355,7 +4783,7 @@ function SplitCardFormInner({
4355
4783
  children: "Loading secure card form\u2026"
4356
4784
  }
4357
4785
  );
4358
- const cardFormBlock = /* @__PURE__ */ jsxs4("div", { style: {
4786
+ const cardFormBlock = /* @__PURE__ */ jsxs5("div", { style: {
4359
4787
  backgroundColor: cardBg,
4360
4788
  borderRadius: containerRadius,
4361
4789
  ...containerOverrides,
@@ -4368,7 +4796,7 @@ function SplitCardFormInner({
4368
4796
  display: "flex",
4369
4797
  flexDirection: "column"
4370
4798
  }, children: [
4371
- /* @__PURE__ */ jsx7("style", { children: `
4799
+ /* @__PURE__ */ jsx8("style", { children: `
4372
4800
  .flopay-shared-input::placeholder {
4373
4801
  color: var(--flopay-input-placeholder-color);
4374
4802
  opacity: 1;
@@ -4377,14 +4805,14 @@ function SplitCardFormInner({
4377
4805
  font-weight: var(--flopay-input-font-weight);
4378
4806
  }
4379
4807
  ` }),
4380
- isButtons && showCardForm && /* @__PURE__ */ jsxs4("div", { style: {
4808
+ isButtons && showCardForm && /* @__PURE__ */ jsxs5("div", { style: {
4381
4809
  display: "flex",
4382
4810
  alignItems: "center",
4383
4811
  padding: "0.75rem 0 0.625rem",
4384
4812
  // Keep the header on top when AVS is ordered above the card on vault.
4385
4813
  order: vaultActive ? -2 : 0
4386
4814
  }, children: [
4387
- /* @__PURE__ */ jsxs4(
4815
+ /* @__PURE__ */ jsxs5(
4388
4816
  "button",
4389
4817
  {
4390
4818
  type: "button",
@@ -4406,7 +4834,7 @@ function SplitCardFormInner({
4406
4834
  },
4407
4835
  "aria-label": "Back to payment methods",
4408
4836
  children: [
4409
- /* @__PURE__ */ jsx7("span", { style: {
4837
+ /* @__PURE__ */ jsx8("span", { style: {
4410
4838
  display: "inline-flex",
4411
4839
  alignItems: "center",
4412
4840
  justifyContent: "center",
@@ -4416,12 +4844,12 @@ function SplitCardFormInner({
4416
4844
  backgroundColor: "#f3f4f6",
4417
4845
  transition: "background-color 0.15s",
4418
4846
  ...bStyles.backButtonIcon
4419
- }, children: /* @__PURE__ */ jsx7("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx7("path", { d: "M15 18l-6-6 6-6" }) }) }),
4420
- /* @__PURE__ */ jsx7(BackButtonContentSlot, { content: cardBackButtonContent })
4847
+ }, children: /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "M15 18l-6-6 6-6" }) }) }),
4848
+ /* @__PURE__ */ jsx8(BackButtonContentSlot, { content: cardBackButtonContent })
4421
4849
  ]
4422
4850
  }
4423
4851
  ),
4424
- hideTitle ? /* @__PURE__ */ jsx7("div", { style: { flex: 1 } }) : /* @__PURE__ */ jsx7("div", { style: {
4852
+ hideTitle ? /* @__PURE__ */ jsx8("div", { style: { flex: 1 } }) : /* @__PURE__ */ jsx8("div", { style: {
4425
4853
  flex: 1,
4426
4854
  textAlign: "center",
4427
4855
  fontWeight: 600,
@@ -4429,9 +4857,9 @@ function SplitCardFormInner({
4429
4857
  color: "#262833",
4430
4858
  paddingRight: 80,
4431
4859
  ...bStyles.title
4432
- }, children: /* @__PURE__ */ jsx7(TitleContentSlot, { content: cardTitleContent }) })
4860
+ }, children: /* @__PURE__ */ jsx8(TitleContentSlot, { content: cardTitleContent }) })
4433
4861
  ] }),
4434
- !isButtons && !hideTitle && /* @__PURE__ */ jsx7("div", { style: {
4862
+ !isButtons && !hideTitle && /* @__PURE__ */ jsx8("div", { style: {
4435
4863
  textAlign: "center",
4436
4864
  fontWeight: 600,
4437
4865
  fontSize: "1.1rem",
@@ -4441,17 +4869,17 @@ function SplitCardFormInner({
4441
4869
  // (-2) and AVS block (-1) are ordered below it but above the card form.
4442
4870
  order: vaultActive ? -3 : 0,
4443
4871
  ...bStyles.title
4444
- }, children: /* @__PURE__ */ jsx7(TitleContentSlot, { content: cardTitleContent }) }),
4445
- !vaultActive && /* @__PURE__ */ jsxs4(Fragment2, { children: [
4446
- /* @__PURE__ */ jsx7("div", { style: {
4872
+ }, children: /* @__PURE__ */ jsx8(TitleContentSlot, { content: cardTitleContent }) }),
4873
+ !vaultActive && /* @__PURE__ */ jsxs5(Fragment2, { children: [
4874
+ /* @__PURE__ */ jsx8("div", { style: {
4447
4875
  backgroundColor: cardInputBg,
4448
4876
  border: `1px solid ${resolvedBorder}`,
4449
4877
  borderTopLeftRadius: resolvedBorderRadius,
4450
4878
  borderTopRightRadius: resolvedBorderRadius,
4451
4879
  padding: "10px"
4452
- }, children: /* @__PURE__ */ jsx7(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
4453
- /* @__PURE__ */ jsxs4("div", { style: { display: "flex" }, children: [
4454
- /* @__PURE__ */ jsx7("div", { style: {
4880
+ }, children: /* @__PURE__ */ jsx8(CardNumberElement, { onReady: () => setFormReady(true), options: stripeElementStyle }) }),
4881
+ /* @__PURE__ */ jsxs5("div", { style: { display: "flex" }, children: [
4882
+ /* @__PURE__ */ jsx8("div", { style: {
4455
4883
  flex: 1,
4456
4884
  backgroundColor: cardInputBg,
4457
4885
  // Longhand only — mixing `border` shorthand with per-side
@@ -4463,8 +4891,8 @@ function SplitCardFormInner({
4463
4891
  borderLeft: `1px solid ${resolvedBorder}`,
4464
4892
  borderBottomLeftRadius: resolvedBorderRadius,
4465
4893
  padding: "10px"
4466
- }, children: /* @__PURE__ */ jsx7(CardExpiryElement, { options: stripeElementStyle }) }),
4467
- /* @__PURE__ */ jsx7("div", { style: {
4894
+ }, children: /* @__PURE__ */ jsx8(CardExpiryElement, { options: stripeElementStyle }) }),
4895
+ /* @__PURE__ */ jsx8("div", { style: {
4468
4896
  flex: 1,
4469
4897
  backgroundColor: cardInputBg,
4470
4898
  borderTop: "none",
@@ -4473,16 +4901,16 @@ function SplitCardFormInner({
4473
4901
  borderLeft: `1px solid ${resolvedBorder}`,
4474
4902
  borderBottomRightRadius: resolvedBorderRadius,
4475
4903
  padding: "10px"
4476
- }, children: /* @__PURE__ */ jsx7(CardCvcElement, { options: stripeElementStyle }) })
4904
+ }, children: /* @__PURE__ */ jsx8(CardCvcElement, { options: stripeElementStyle }) })
4477
4905
  ] })
4478
4906
  ] }),
4479
- !vaultActive && /* @__PURE__ */ jsx7("div", { style: {
4907
+ !vaultActive && /* @__PURE__ */ jsx8("div", { style: {
4480
4908
  backgroundColor: cardInputBg,
4481
4909
  border: `1px solid ${resolvedBorder}`,
4482
4910
  borderRadius: resolvedBorderRadius,
4483
4911
  marginTop: "0.5rem",
4484
4912
  padding: "10px"
4485
- }, children: /* @__PURE__ */ jsx7(
4913
+ }, children: /* @__PURE__ */ jsx8(
4486
4914
  "input",
4487
4915
  {
4488
4916
  className: "flopay-shared-input",
@@ -4504,7 +4932,7 @@ function SplitCardFormInner({
4504
4932
  }
4505
4933
  }
4506
4934
  ) }),
4507
- avsConfig && /* @__PURE__ */ jsx7("div", { style: { order: vaultActive ? -1 : 0 }, "data-testid": "flopay-avs-fields", children: (() => {
4935
+ avsConfig && /* @__PURE__ */ jsx8("div", { style: { order: vaultActive ? -1 : 0 }, "data-testid": "flopay-avs-fields", children: (() => {
4508
4936
  const cc = selectedCountry;
4509
4937
  const inputWrapStyle = (invalid = false) => ({
4510
4938
  backgroundColor: cardInputBg,
@@ -4521,8 +4949,8 @@ function SplitCardFormInner({
4521
4949
  ...sharedInputTypography
4522
4950
  });
4523
4951
  const stateOpts = getStateOptions(cc);
4524
- return /* @__PURE__ */ jsxs4(Fragment2, { children: [
4525
- isAVSFieldVisible(avsConfig.address_line_1, cc) && /* @__PURE__ */ jsx7("div", { style: inputWrapStyle(invalidAvsFields.line1), children: /* @__PURE__ */ jsx7(
4952
+ return /* @__PURE__ */ jsxs5(Fragment2, { children: [
4953
+ isAVSFieldVisible(avsConfig.address_line_1, cc) && /* @__PURE__ */ jsx8("div", { style: inputWrapStyle(invalidAvsFields.line1), children: /* @__PURE__ */ jsx8(
4526
4954
  "input",
4527
4955
  {
4528
4956
  className: "flopay-shared-input",
@@ -4541,7 +4969,7 @@ function SplitCardFormInner({
4541
4969
  style: inputFieldStyle()
4542
4970
  }
4543
4971
  ) }),
4544
- isAVSFieldVisible(avsConfig.address_line_2, cc) && /* @__PURE__ */ jsx7("div", { style: inputWrapStyle(), children: /* @__PURE__ */ jsx7(
4972
+ isAVSFieldVisible(avsConfig.address_line_2, cc) && /* @__PURE__ */ jsx8("div", { style: inputWrapStyle(), children: /* @__PURE__ */ jsx8(
4545
4973
  "input",
4546
4974
  {
4547
4975
  className: "flopay-shared-input",
@@ -4559,12 +4987,12 @@ function SplitCardFormInner({
4559
4987
  style: inputFieldStyle()
4560
4988
  }
4561
4989
  ) }),
4562
- (isAVSFieldVisible(avsConfig.city, cc) || isAVSFieldVisible(avsConfig.state, cc)) && /* @__PURE__ */ jsxs4("div", { style: {
4990
+ (isAVSFieldVisible(avsConfig.city, cc) || isAVSFieldVisible(avsConfig.state, cc)) && /* @__PURE__ */ jsxs5("div", { style: {
4563
4991
  display: "flex",
4564
4992
  gap: "0",
4565
4993
  marginTop: "0.5rem"
4566
4994
  }, children: [
4567
- isAVSFieldVisible(avsConfig.city, cc) && /* @__PURE__ */ jsx7("div", { style: {
4995
+ isAVSFieldVisible(avsConfig.city, cc) && /* @__PURE__ */ jsx8("div", { style: {
4568
4996
  flex: 1,
4569
4997
  backgroundColor: cardInputBg,
4570
4998
  borderTop: `1px solid ${avsBorderColor(invalidAvsFields.city)}`,
@@ -4575,7 +5003,7 @@ function SplitCardFormInner({
4575
5003
  borderTopLeftRadius: resolvedBorderRadius,
4576
5004
  borderBottomLeftRadius: resolvedBorderRadius,
4577
5005
  ...isAVSFieldVisible(avsConfig.state, cc) ? { borderRight: "none", borderTopRightRadius: 0, borderBottomRightRadius: 0 } : { borderRadius: resolvedBorderRadius }
4578
- }, children: /* @__PURE__ */ jsx7(
5006
+ }, children: /* @__PURE__ */ jsx8(
4579
5007
  "input",
4580
5008
  {
4581
5009
  className: "flopay-shared-input",
@@ -4594,7 +5022,7 @@ function SplitCardFormInner({
4594
5022
  style: inputFieldStyle()
4595
5023
  }
4596
5024
  ) }),
4597
- isAVSFieldVisible(avsConfig.state, cc) && /* @__PURE__ */ jsx7("div", { style: {
5025
+ isAVSFieldVisible(avsConfig.state, cc) && /* @__PURE__ */ jsx8("div", { style: {
4598
5026
  flex: 1,
4599
5027
  backgroundColor: cardInputBg,
4600
5028
  border: `1px solid ${avsBorderColor(invalidAvsFields.state)}`,
@@ -4602,7 +5030,7 @@ function SplitCardFormInner({
4602
5030
  borderTopRightRadius: resolvedBorderRadius,
4603
5031
  borderBottomRightRadius: resolvedBorderRadius,
4604
5032
  ...isAVSFieldVisible(avsConfig.city, cc) ? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } : { borderRadius: resolvedBorderRadius }
4605
- }, children: stateOpts ? /* @__PURE__ */ jsxs4(
5033
+ }, children: stateOpts ? /* @__PURE__ */ jsxs5(
4606
5034
  "select",
4607
5035
  {
4608
5036
  id: "flopay-billing-state",
@@ -4618,11 +5046,11 @@ function SplitCardFormInner({
4618
5046
  "data-testid": "flopay-state",
4619
5047
  style: { ...inputFieldStyle(), cursor: "pointer" },
4620
5048
  children: [
4621
- /* @__PURE__ */ jsx7("option", { value: "", children: getStateLabel(cc) }),
4622
- stateOpts.map((s) => /* @__PURE__ */ jsx7("option", { value: s.code, children: s.name }, s.code))
5049
+ /* @__PURE__ */ jsx8("option", { value: "", children: getStateLabel(cc) }),
5050
+ stateOpts.map((s) => /* @__PURE__ */ jsx8("option", { value: s.code, children: s.name }, s.code))
4623
5051
  ]
4624
5052
  }
4625
- ) : /* @__PURE__ */ jsx7(
5053
+ ) : /* @__PURE__ */ jsx8(
4626
5054
  "input",
4627
5055
  {
4628
5056
  className: "flopay-shared-input",
@@ -4642,13 +5070,13 @@ function SplitCardFormInner({
4642
5070
  }
4643
5071
  ) })
4644
5072
  ] }),
4645
- (isAVSFieldVisible(avsConfig.country, cc) || isAVSFieldVisible(avsConfig.postal_code, cc)) && /* @__PURE__ */ jsxs4("div", { style: {
5073
+ (isAVSFieldVisible(avsConfig.country, cc) || isAVSFieldVisible(avsConfig.postal_code, cc)) && /* @__PURE__ */ jsxs5("div", { style: {
4646
5074
  display: "flex",
4647
5075
  flexDirection: avsLayoutProp === "column" ? "column" : "row",
4648
5076
  gap: avsLayoutProp === "column" ? "0.5rem" : "0",
4649
5077
  marginTop: "0.5rem"
4650
5078
  }, children: [
4651
- isAVSFieldVisible(avsConfig.country, cc) && /* @__PURE__ */ jsx7("div", { style: {
5079
+ isAVSFieldVisible(avsConfig.country, cc) && /* @__PURE__ */ jsx8("div", { style: {
4652
5080
  flex: avsLayoutProp === "row" ? 1 : void 0,
4653
5081
  backgroundColor: cardInputBg,
4654
5082
  borderTop: `1px solid ${resolvedBorder}`,
@@ -4657,7 +5085,7 @@ function SplitCardFormInner({
4657
5085
  borderLeft: `1px solid ${resolvedBorder}`,
4658
5086
  padding: "10px",
4659
5087
  ...avsLayoutProp === "row" && isAVSFieldVisible(avsConfig.postal_code, cc) ? { borderRadius: "0", borderTopLeftRadius: resolvedBorderRadius, borderBottomLeftRadius: resolvedBorderRadius, borderRight: "none" } : { borderRadius: resolvedBorderRadius }
4660
- }, children: /* @__PURE__ */ jsx7(
5088
+ }, children: /* @__PURE__ */ jsx8(
4661
5089
  "select",
4662
5090
  {
4663
5091
  id: "flopay-billing-country",
@@ -4674,20 +5102,20 @@ function SplitCardFormInner({
4674
5102
  autoComplete: "billing country",
4675
5103
  "data-testid": "flopay-country",
4676
5104
  style: { ...inputFieldStyle(), cursor: "pointer" },
4677
- children: COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ jsxs4("option", { value: c.code, children: [
5105
+ children: COUNTRY_OPTIONS.map((c) => /* @__PURE__ */ jsxs5("option", { value: c.code, children: [
4678
5106
  c.flag,
4679
5107
  " ",
4680
5108
  c.name
4681
5109
  ] }, c.code))
4682
5110
  }
4683
5111
  ) }),
4684
- isAVSFieldVisible(avsConfig.postal_code, cc) && /* @__PURE__ */ jsx7("div", { style: {
5112
+ isAVSFieldVisible(avsConfig.postal_code, cc) && /* @__PURE__ */ jsx8("div", { style: {
4685
5113
  flex: avsLayoutProp === "row" ? 1 : void 0,
4686
5114
  backgroundColor: cardInputBg,
4687
5115
  border: `1px solid ${zipBorderColor}`,
4688
5116
  padding: "10px",
4689
5117
  ...avsLayoutProp === "row" && isAVSFieldVisible(avsConfig.country, cc) ? { borderRadius: "0", borderTopRightRadius: resolvedBorderRadius, borderBottomRightRadius: resolvedBorderRadius } : { borderRadius: resolvedBorderRadius }
4690
- }, children: /* @__PURE__ */ jsx7(
5118
+ }, children: /* @__PURE__ */ jsx8(
4691
5119
  "input",
4692
5120
  {
4693
5121
  className: "flopay-shared-input",
@@ -4711,7 +5139,7 @@ function SplitCardFormInner({
4711
5139
  }
4712
5140
  ) })
4713
5141
  ] }),
4714
- showPostcodeError && /* @__PURE__ */ jsx7(
5142
+ showPostcodeError && /* @__PURE__ */ jsx8(
4715
5143
  "div",
4716
5144
  {
4717
5145
  id: "flopay-billing-postal-code-error",
@@ -4728,26 +5156,10 @@ function SplitCardFormInner({
4728
5156
  )
4729
5157
  ] });
4730
5158
  })() }),
4731
- vaultActive && cardPreFormSlot && /* @__PURE__ */ jsx7("div", { style: { order: -2, width: "100%" }, children: cardPreFormSlot }),
5159
+ vaultActive && cardPreFormSlot && /* @__PURE__ */ jsx8("div", { style: { order: -2, width: "100%" }, children: cardPreFormSlot }),
4732
5160
  vaultActive && vaultCardFieldsNode,
4733
- displayError && /* @__PURE__ */ jsxs4("div", { role: "alert", "data-testid": "flopay-error", style: {
4734
- margin: "0.75rem 0",
4735
- padding: "0.625rem 0.875rem",
4736
- background: "#FEF2F2",
4737
- border: "1px solid #FECACA",
4738
- borderRadius: "8px",
4739
- color: "#991B1B",
4740
- fontSize: "0.85rem",
4741
- fontWeight: 600,
4742
- display: "flex",
4743
- alignItems: "center",
4744
- gap: "0.5rem",
4745
- ...bStyles.errorBanner ? bStyles.errorBanner : {}
4746
- }, children: [
4747
- /* @__PURE__ */ jsx7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx7("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
4748
- displayError
4749
- ] }),
4750
- !vaultActive && (children ?? /* @__PURE__ */ jsx7(
5161
+ displayError && /* @__PURE__ */ jsx8(ErrorBanner, { margin: "0.75rem 0", styleOverride: bStyles.errorBanner, children: displayError }),
5162
+ !vaultActive && (children ?? /* @__PURE__ */ jsx8(
4751
5163
  "button",
4752
5164
  {
4753
5165
  type: "submit",
@@ -4792,9 +5204,9 @@ function SplitCardFormInner({
4792
5204
  const renderDirectPaypalGateDebug = (testId) => {
4793
5205
  if (!debug) return null;
4794
5206
  if (!showPayPal || !directPaypalConfigured) {
4795
- return /* @__PURE__ */ jsx7("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/DirectPayPal-debug - not enabled" });
5207
+ return /* @__PURE__ */ jsx8("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/DirectPayPal-debug - not enabled" });
4796
5208
  }
4797
- return /* @__PURE__ */ jsx7("pre", { "data-testid": testId, style: gateDebugStyle, children: [
5209
+ return /* @__PURE__ */ jsx8("pre", { "data-testid": testId, style: gateDebugStyle, children: [
4798
5210
  "FloPay/DirectPayPal-debug (parent gate)",
4799
5211
  ` showPayPal=${showPayPal}`,
4800
5212
  ` directPaypalConfigured=${directPaypalConfigured}`,
@@ -4807,9 +5219,9 @@ function SplitCardFormInner({
4807
5219
  const renderStripeGateDebug = (testId) => {
4808
5220
  if (!debug) return null;
4809
5221
  if (!showStripe || !stripeInstance) {
4810
- return /* @__PURE__ */ jsx7("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/Stripe-debug - not enabled" });
5222
+ return /* @__PURE__ */ jsx8("pre", { "data-testid": testId, style: gateDebugStyle, children: "FloPay/Stripe-debug - not enabled" });
4811
5223
  }
4812
- return /* @__PURE__ */ jsx7("pre", { "data-testid": testId, style: gateDebugStyle, children: [
5224
+ return /* @__PURE__ */ jsx8("pre", { "data-testid": testId, style: gateDebugStyle, children: [
4813
5225
  "FloPay/Stripe-debug (parent gate)",
4814
5226
  ` showStripe=${showStripe}`,
4815
5227
  ` currency=${currency}`,
@@ -4838,11 +5250,11 @@ function SplitCardFormInner({
4838
5250
  const cardButtonSizing = cardButtonContent === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
4839
5251
  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;
4840
5252
  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;
4841
- return /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
4842
- /* @__PURE__ */ jsx7(FloPayKeyframes, {}),
4843
- overlayStatus && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
4844
- /* @__PURE__ */ jsxs4("div", { style: { display: "grid" }, children: [
4845
- /* @__PURE__ */ jsxs4(
5253
+ return /* @__PURE__ */ jsxs5("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
5254
+ /* @__PURE__ */ jsx8(FloPayKeyframes, {}),
5255
+ overlayStatus && /* @__PURE__ */ jsx8(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
5256
+ /* @__PURE__ */ jsxs5("div", { style: { display: "grid" }, children: [
5257
+ /* @__PURE__ */ jsxs5(
4846
5258
  "div",
4847
5259
  {
4848
5260
  "data-testid": "flopay-buttons-panel",
@@ -4859,8 +5271,8 @@ function SplitCardFormInner({
4859
5271
  children: [
4860
5272
  renderDirectPaypalGateDebug("flopay-direct-paypal-gate-debug"),
4861
5273
  renderStripeGateDebug("flopay-stripe-gate-debug"),
4862
- shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ jsxs4(Fragment2, { children: [
4863
- paypalDirectRetry && /* @__PURE__ */ jsx7(
5274
+ shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ jsxs5(Fragment2, { children: [
5275
+ paypalDirectRetry && /* @__PURE__ */ jsx8(
4864
5276
  "div",
4865
5277
  {
4866
5278
  "data-testid": "flopay-paypal-direct-retry-notice",
@@ -4876,7 +5288,7 @@ function SplitCardFormInner({
4876
5288
  children: "Please confirm your PayPal payment to complete checkout."
4877
5289
  }
4878
5290
  ),
4879
- /* @__PURE__ */ jsx7(
5291
+ /* @__PURE__ */ jsx8(
4880
5292
  DirectPayPalButton,
4881
5293
  {
4882
5294
  sessionId,
@@ -4903,7 +5315,7 @@ function SplitCardFormInner({
4903
5315
  paypalDirectRetry?.orderId ?? "fresh"
4904
5316
  )
4905
5317
  ] }),
4906
- shouldRenderStripePayPal && /* @__PURE__ */ jsx7(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx7(
5318
+ shouldRenderStripePayPal && /* @__PURE__ */ jsx8(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx8(
4907
5319
  PayPalButtonInner,
4908
5320
  {
4909
5321
  sessionId,
@@ -4921,7 +5333,7 @@ function SplitCardFormInner({
4921
5333
  placeholderBorderRadius: buttonBorderRadius
4922
5334
  }
4923
5335
  ) }),
4924
- shouldRenderWallets ? /* @__PURE__ */ jsx7(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx7(
5336
+ shouldRenderWallets ? /* @__PURE__ */ jsx8(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx8(
4925
5337
  WalletButtonInner,
4926
5338
  {
4927
5339
  sessionId,
@@ -4938,8 +5350,8 @@ function SplitCardFormInner({
4938
5350
  onLoadStateChange: setWalletLoadState,
4939
5351
  placeholderBorderRadius: buttonBorderRadius
4940
5352
  }
4941
- ) }) : shouldShowWallets ? /* @__PURE__ */ jsx7("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: buttonBorderRadius, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
4942
- shouldRenderPaymentElement && /* @__PURE__ */ jsx7(
5353
+ ) }) : shouldShowWallets ? /* @__PURE__ */ jsx8("div", { style: { height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT, borderRadius: buttonBorderRadius, background: "#e5e7eb", animation: "flopay-pulse 1.5s ease-in-out infinite" } }) : null,
5354
+ shouldRenderPaymentElement && /* @__PURE__ */ jsx8(
4943
5355
  StripePaymentElementInner,
4944
5356
  {
4945
5357
  sessionId,
@@ -4971,7 +5383,7 @@ function SplitCardFormInner({
4971
5383
  }
4972
5384
  }
4973
5385
  ),
4974
- showStripe && /* @__PURE__ */ jsx7(
5386
+ showStripe && /* @__PURE__ */ jsx8(
4975
5387
  "button",
4976
5388
  {
4977
5389
  type: "button",
@@ -5027,50 +5439,34 @@ function SplitCardFormInner({
5027
5439
  onMouseUp: (e) => {
5028
5440
  e.currentTarget.style.transform = "scale(1)";
5029
5441
  },
5030
- children: /* @__PURE__ */ jsx7(CardButtonContentSlot, { content: cardButtonContent })
5442
+ children: /* @__PURE__ */ jsx8(CardButtonContentSlot, { content: cardButtonContent })
5031
5443
  }
5032
5444
  ),
5033
- displayError && viewState === "buttons" && /* @__PURE__ */ jsxs4("div", { role: "alert", "data-testid": "flopay-error", style: {
5034
- margin: "0.25rem 0",
5035
- padding: "0.625rem 0.875rem",
5036
- background: "#FEF2F2",
5037
- border: "1px solid #FECACA",
5038
- borderRadius: "8px",
5039
- color: "#991B1B",
5040
- fontSize: "0.85rem",
5041
- fontWeight: 600,
5042
- display: "flex",
5043
- alignItems: "center",
5044
- gap: "0.5rem",
5045
- ...bStyles.errorBanner ? bStyles.errorBanner : {}
5046
- }, children: [
5047
- /* @__PURE__ */ jsx7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx7("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
5048
- displayError
5049
- ] })
5445
+ displayError && viewState === "buttons" && /* @__PURE__ */ jsx8(ErrorBanner, { margin: "0.25rem 0", styleOverride: bStyles.errorBanner, children: displayError })
5050
5446
  ]
5051
5447
  }
5052
5448
  ),
5053
- showStripe && isCardView && /* @__PURE__ */ jsx7("div", { style: {
5449
+ showStripe && isCardView && /* @__PURE__ */ jsx8("div", { style: {
5054
5450
  gridArea: "1 / 1",
5055
5451
  ...cardAnim ? { animation: cardAnim } : {},
5056
5452
  ...viewState === "collapsing" ? { pointerEvents: "none" } : {}
5057
5453
  }, children: cardFormBlock }),
5058
- showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && /* @__PURE__ */ jsx7("div", { style: {
5454
+ showStripe && isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && /* @__PURE__ */ jsx8("div", { style: {
5059
5455
  gridArea: "1 / 1",
5060
5456
  ...apmAnim ? { animation: apmAnim } : {},
5061
5457
  ...viewState === "apm-collapsing" ? { pointerEvents: "none" } : {}
5062
- }, children: /* @__PURE__ */ jsxs4("div", { style: {
5458
+ }, children: /* @__PURE__ */ jsxs5("div", { style: {
5063
5459
  backgroundColor: cardBg,
5064
5460
  borderRadius: containerRadius,
5065
5461
  ...containerOverrides,
5066
5462
  padding: containerPadding
5067
5463
  }, children: [
5068
- /* @__PURE__ */ jsxs4("div", { style: {
5464
+ /* @__PURE__ */ jsxs5("div", { style: {
5069
5465
  display: "flex",
5070
5466
  alignItems: "center",
5071
5467
  padding: "0.75rem 0 0.625rem"
5072
5468
  }, children: [
5073
- /* @__PURE__ */ jsxs4(
5469
+ /* @__PURE__ */ jsxs5(
5074
5470
  "button",
5075
5471
  {
5076
5472
  type: "button",
@@ -5093,7 +5489,7 @@ function SplitCardFormInner({
5093
5489
  },
5094
5490
  "aria-label": "Back to payment methods",
5095
5491
  children: [
5096
- /* @__PURE__ */ jsx7("span", { style: {
5492
+ /* @__PURE__ */ jsx8("span", { style: {
5097
5493
  display: "inline-flex",
5098
5494
  alignItems: "center",
5099
5495
  justifyContent: "center",
@@ -5103,12 +5499,12 @@ function SplitCardFormInner({
5103
5499
  backgroundColor: "#f3f4f6",
5104
5500
  transition: "background-color 0.15s",
5105
5501
  ...bStyles.backButtonIcon
5106
- }, children: /* @__PURE__ */ jsx7("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx7("path", { d: "M15 18l-6-6 6-6" }) }) }),
5107
- /* @__PURE__ */ jsx7(BackButtonContentSlot, { content: cardBackButtonContent })
5502
+ }, children: /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "M15 18l-6-6 6-6" }) }) }),
5503
+ /* @__PURE__ */ jsx8(BackButtonContentSlot, { content: cardBackButtonContent })
5108
5504
  ]
5109
5505
  }
5110
5506
  ),
5111
- /* @__PURE__ */ jsx7("div", { style: {
5507
+ /* @__PURE__ */ jsx8("div", { style: {
5112
5508
  flex: 1,
5113
5509
  textAlign: "center",
5114
5510
  fontWeight: 600,
@@ -5118,12 +5514,12 @@ function SplitCardFormInner({
5118
5514
  ...bStyles.title
5119
5515
  }, children: `Pay with ${getStripeMethodDisplayName(expandedApmMethod)}` })
5120
5516
  ] }),
5121
- /* @__PURE__ */ jsx7(
5517
+ /* @__PURE__ */ jsx8(
5122
5518
  StripeElements,
5123
5519
  {
5124
5520
  stripe: stripeInstance,
5125
5521
  options: apmInlineOptions,
5126
- children: /* @__PURE__ */ jsx7(
5522
+ children: /* @__PURE__ */ jsx8(
5127
5523
  StripeMethodInlineForm,
5128
5524
  {
5129
5525
  method: expandedApmMethod,
@@ -5153,24 +5549,24 @@ function SplitCardFormInner({
5153
5549
  ] });
5154
5550
  }
5155
5551
  if (isApmView && expandedApmMethod && apmInlineOptions && stripeInstance && showStripe) {
5156
- return /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
5157
- /* @__PURE__ */ jsx7(FloPayKeyframes, {}),
5158
- overlayStatus && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
5159
- /* @__PURE__ */ jsx7("div", { style: {
5552
+ return /* @__PURE__ */ jsxs5("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
5553
+ /* @__PURE__ */ jsx8(FloPayKeyframes, {}),
5554
+ overlayStatus && /* @__PURE__ */ jsx8(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
5555
+ /* @__PURE__ */ jsx8("div", { style: {
5160
5556
  ...apmAnim ? { animation: apmAnim } : {},
5161
5557
  ...viewState === "apm-collapsing" ? { pointerEvents: "none" } : {}
5162
- }, children: /* @__PURE__ */ jsxs4("div", { style: {
5558
+ }, children: /* @__PURE__ */ jsxs5("div", { style: {
5163
5559
  backgroundColor: cardBg,
5164
5560
  borderRadius: containerRadius,
5165
5561
  ...containerOverrides,
5166
5562
  padding: containerPadding
5167
5563
  }, children: [
5168
- /* @__PURE__ */ jsxs4("div", { style: {
5564
+ /* @__PURE__ */ jsxs5("div", { style: {
5169
5565
  display: "flex",
5170
5566
  alignItems: "center",
5171
5567
  padding: "0.75rem 0 0.625rem"
5172
5568
  }, children: [
5173
- /* @__PURE__ */ jsxs4(
5569
+ /* @__PURE__ */ jsxs5(
5174
5570
  "button",
5175
5571
  {
5176
5572
  type: "button",
@@ -5193,7 +5589,7 @@ function SplitCardFormInner({
5193
5589
  },
5194
5590
  "aria-label": "Back to payment methods",
5195
5591
  children: [
5196
- /* @__PURE__ */ jsx7("span", { style: {
5592
+ /* @__PURE__ */ jsx8("span", { style: {
5197
5593
  display: "inline-flex",
5198
5594
  alignItems: "center",
5199
5595
  justifyContent: "center",
@@ -5203,12 +5599,12 @@ function SplitCardFormInner({
5203
5599
  backgroundColor: "#f3f4f6",
5204
5600
  transition: "background-color 0.15s",
5205
5601
  ...bStyles.backButtonIcon
5206
- }, children: /* @__PURE__ */ jsx7("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx7("path", { d: "M15 18l-6-6 6-6" }) }) }),
5207
- /* @__PURE__ */ jsx7(BackButtonContentSlot, { content: cardBackButtonContent })
5602
+ }, children: /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "M15 18l-6-6 6-6" }) }) }),
5603
+ /* @__PURE__ */ jsx8(BackButtonContentSlot, { content: cardBackButtonContent })
5208
5604
  ]
5209
5605
  }
5210
5606
  ),
5211
- /* @__PURE__ */ jsx7("div", { style: {
5607
+ /* @__PURE__ */ jsx8("div", { style: {
5212
5608
  flex: 1,
5213
5609
  textAlign: "center",
5214
5610
  fontWeight: 600,
@@ -5218,12 +5614,12 @@ function SplitCardFormInner({
5218
5614
  ...bStyles.title
5219
5615
  }, children: `Pay with ${getStripeMethodDisplayName(expandedApmMethod)}` })
5220
5616
  ] }),
5221
- /* @__PURE__ */ jsx7(
5617
+ /* @__PURE__ */ jsx8(
5222
5618
  StripeElements,
5223
5619
  {
5224
5620
  stripe: stripeInstance,
5225
5621
  options: apmInlineOptions,
5226
- children: /* @__PURE__ */ jsx7(
5622
+ children: /* @__PURE__ */ jsx8(
5227
5623
  StripeMethodInlineForm,
5228
5624
  {
5229
5625
  method: expandedApmMethod,
@@ -5251,14 +5647,14 @@ function SplitCardFormInner({
5251
5647
  ] }) })
5252
5648
  ] });
5253
5649
  }
5254
- return /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
5255
- /* @__PURE__ */ jsx7(FloPayKeyframes, {}),
5256
- overlayStatus && /* @__PURE__ */ jsx7(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
5257
- /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
5650
+ return /* @__PURE__ */ jsxs5("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
5651
+ /* @__PURE__ */ jsx8(FloPayKeyframes, {}),
5652
+ overlayStatus && /* @__PURE__ */ jsx8(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
5653
+ /* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
5258
5654
  renderDirectPaypalGateDebug("flopay-direct-paypal-gate-debug-default"),
5259
5655
  renderStripeGateDebug("flopay-stripe-gate-debug-default"),
5260
- shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ jsxs4(Fragment2, { children: [
5261
- paypalDirectRetry && /* @__PURE__ */ jsx7(
5656
+ shouldRenderDirectPayPal && directPaypal && /* @__PURE__ */ jsxs5(Fragment2, { children: [
5657
+ paypalDirectRetry && /* @__PURE__ */ jsx8(
5262
5658
  "div",
5263
5659
  {
5264
5660
  "data-testid": "flopay-paypal-direct-retry-notice-default",
@@ -5274,7 +5670,7 @@ function SplitCardFormInner({
5274
5670
  children: "Please confirm your PayPal payment to complete checkout."
5275
5671
  }
5276
5672
  ),
5277
- /* @__PURE__ */ jsx7(
5673
+ /* @__PURE__ */ jsx8(
5278
5674
  DirectPayPalButton,
5279
5675
  {
5280
5676
  sessionId,
@@ -5301,7 +5697,7 @@ function SplitCardFormInner({
5301
5697
  paypalDirectRetry?.orderId ?? "fresh"
5302
5698
  )
5303
5699
  ] }),
5304
- shouldRenderStripePayPal && /* @__PURE__ */ jsx7(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx7(
5700
+ shouldRenderStripePayPal && /* @__PURE__ */ jsx8(StripeElements, { stripe: paypalStripeInstance, options: paypalOptions, children: /* @__PURE__ */ jsx8(
5305
5701
  PayPalButtonInner,
5306
5702
  {
5307
5703
  sessionId,
@@ -5319,7 +5715,7 @@ function SplitCardFormInner({
5319
5715
  placeholderBorderRadius: buttonBorderRadius
5320
5716
  }
5321
5717
  ) }),
5322
- shouldRenderWallets && /* @__PURE__ */ jsx7(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx7(
5718
+ shouldRenderWallets && /* @__PURE__ */ jsx8(StripeElements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ jsx8(
5323
5719
  WalletButtonInner,
5324
5720
  {
5325
5721
  sessionId,
@@ -5337,7 +5733,7 @@ function SplitCardFormInner({
5337
5733
  placeholderBorderRadius: buttonBorderRadius
5338
5734
  }
5339
5735
  ) }),
5340
- shouldRenderPaymentElement && /* @__PURE__ */ jsx7(
5736
+ shouldRenderPaymentElement && /* @__PURE__ */ jsx8(
5341
5737
  StripePaymentElementInner,
5342
5738
  {
5343
5739
  sessionId,
@@ -5370,7 +5766,7 @@ function SplitCardFormInner({
5370
5766
  }
5371
5767
  )
5372
5768
  ] }),
5373
- showStripe && (shouldDisplayWalletRow || shouldDisplayPayPalRow || shouldDisplayPaymentElementRow) && /* @__PURE__ */ jsxs4("div", { style: {
5769
+ showStripe && (shouldDisplayWalletRow || shouldDisplayPayPalRow || shouldDisplayPaymentElementRow) && /* @__PURE__ */ jsxs5("div", { style: {
5374
5770
  display: "flex",
5375
5771
  alignItems: "center",
5376
5772
  gap: "0.75rem",
@@ -5378,9 +5774,9 @@ function SplitCardFormInner({
5378
5774
  color: "#999",
5379
5775
  fontSize: "0.85rem"
5380
5776
  }, children: [
5381
- /* @__PURE__ */ jsx7("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } }),
5382
- /* @__PURE__ */ jsx7("span", { children: "or pay with card" }),
5383
- /* @__PURE__ */ jsx7("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
5777
+ /* @__PURE__ */ jsx8("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } }),
5778
+ /* @__PURE__ */ jsx8("span", { children: "or pay with card" }),
5779
+ /* @__PURE__ */ jsx8("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
5384
5780
  ] }),
5385
5781
  showStripe && cardFormBlock
5386
5782
  ] });
@@ -5410,6 +5806,9 @@ async function confirmResumeIntent(stripe, clientSecret, data, isSetupIntent) {
5410
5806
  const { paymentIntent, error } = await stripe.confirmCardPayment(clientSecret, data);
5411
5807
  return { error, intent: paymentIntent ?? null };
5412
5808
  }
5809
+ function withCheckoutMethod(error, checkoutMethod) {
5810
+ return Object.assign(error, { checkoutMethod });
5811
+ }
5413
5812
  function getRedirectResultFromCheckoutProcessError(error) {
5414
5813
  if (!error?.type || !error.threeDSecureToken) {
5415
5814
  return null;
@@ -5631,7 +6030,7 @@ function checkoutProcessErrorToFloPayError(error, fallbackMessage = "Payment fai
5631
6030
  const checkoutMethod = options?.checkoutMethod ?? error?.checkoutMethod ?? (error?.type === "paypal_redirect_required" ? "paypal" : "card");
5632
6031
  const rawMessage = error?.message ?? fallbackMessage;
5633
6032
  const message = applyFriendlyMessageOverride(rawMessage) ?? rawMessage;
5634
- return Object.assign(
6033
+ return withCheckoutMethod(
5635
6034
  new FloPayError4(
5636
6035
  message,
5637
6036
  "api_error",
@@ -5639,7 +6038,7 @@ function checkoutProcessErrorToFloPayError(error, fallbackMessage = "Payment fai
5639
6038
  code: error?.gatewayErrorCode
5640
6039
  }
5641
6040
  ),
5642
- { checkoutMethod }
6041
+ checkoutMethod
5643
6042
  );
5644
6043
  }
5645
6044
  function resolveSavedPaymentReturnUrl(session) {
@@ -5725,7 +6124,7 @@ async function recover3DSRedirectResult({
5725
6124
  return null;
5726
6125
  }
5727
6126
  try {
5728
- const api = new PaymentAPI3(billingApiUrl);
6127
+ const api = new PaymentAPI3(billingApiUrl, { telemetry: false });
5729
6128
  const unified = await api.getUnifiedCheckoutSession(sessionId, nonce);
5730
6129
  const refreshedToken = unified.data.stripe?.clientSecret;
5731
6130
  if (isStripePaymentIntentClientSecret(refreshedToken)) {
@@ -5744,7 +6143,8 @@ async function processSavedPaymentForMode({
5744
6143
  session,
5745
6144
  nonce,
5746
6145
  tokenizedData,
5747
- returnUrl
6146
+ returnUrl,
6147
+ telemetry
5748
6148
  }) {
5749
6149
  const baseUrl = billingApiUrl.replace(/\/+$/, "");
5750
6150
  const resolvedSessionId = sessionId ?? session.id;
@@ -5755,7 +6155,10 @@ async function processSavedPaymentForMode({
5755
6155
  const lastName = session.customer?.lastName ?? session.accountData?.lastName ?? "";
5756
6156
  const country = session.customer?.country ?? session.accountData?.country ?? void 0;
5757
6157
  const zip = session.customer?.zip ?? session.accountData?.zip ?? void 0;
5758
- const api = new PaymentAPI3(baseUrl);
6158
+ const api = new PaymentAPI3(
6159
+ baseUrl,
6160
+ telemetry === false ? { telemetry: false } : void 0
6161
+ );
5759
6162
  const response = await retryOnceOnFetchFailure(() => api.processPayment(customerId, {
5760
6163
  sessionId: resolvedSessionId,
5761
6164
  nonce: resolvedNonce,
@@ -5807,13 +6210,13 @@ async function processSavedPaymentForMode({
5807
6210
  if (recoveredRedirect) {
5808
6211
  return recoveredRedirect;
5809
6212
  }
5810
- throw Object.assign(
6213
+ throw withCheckoutMethod(
5811
6214
  new FloPayError4(
5812
6215
  "Your card requires authentication. Please enter your payment details below.",
5813
6216
  "api_error",
5814
6217
  { code: "authentication_required" }
5815
6218
  ),
5816
- { checkoutMethod: "card" }
6219
+ "card"
5817
6220
  );
5818
6221
  }
5819
6222
  throw new FloPayError4(
@@ -5832,7 +6235,8 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
5832
6235
  billingApiUrl,
5833
6236
  sessionId,
5834
6237
  session,
5835
- returnUrl
6238
+ returnUrl,
6239
+ telemetry
5836
6240
  }) {
5837
6241
  const stripe = flopay?.getRawProvider();
5838
6242
  if (!stripe) {
@@ -5840,13 +6244,13 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
5840
6244
  }
5841
6245
  if (redirectResult.type === "3ds_required") {
5842
6246
  if (!attempt3DS || !redirectResult.threeDSecureToken) {
5843
- throw Object.assign(
6247
+ throw withCheckoutMethod(
5844
6248
  new FloPayError4(
5845
6249
  "Your card requires authentication. Please enter your payment details below.",
5846
6250
  "api_error",
5847
6251
  { code: "authentication_required" }
5848
6252
  ),
5849
- { checkoutMethod: "card" }
6253
+ "card"
5850
6254
  );
5851
6255
  }
5852
6256
  const isSetupIntent = isSetupIntentClientSecret3(redirectResult.threeDSecureToken);
@@ -5855,13 +6259,13 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
5855
6259
  const retrieved = await retrieveResumeIntent(stripe, redirectResult.threeDSecureToken, isSetupIntent);
5856
6260
  if (retrieved) {
5857
6261
  if (retrieved.error) {
5858
- throw Object.assign(
6262
+ throw withCheckoutMethod(
5859
6263
  new FloPayError4(
5860
6264
  retrieved.error.message ?? `Failed to retrieve 3DS ${isSetupIntent ? "setup" : "payment"} status.`,
5861
6265
  "api_error",
5862
6266
  { code: retrieved.error.code }
5863
6267
  ),
5864
- { checkoutMethod: "card" }
6268
+ "card"
5865
6269
  );
5866
6270
  }
5867
6271
  const existingIntent = retrieved.intent;
@@ -5884,13 +6288,13 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
5884
6288
  ) : null;
5885
6289
  if (confirmed) {
5886
6290
  if (confirmed.error) {
5887
- throw Object.assign(
6291
+ throw withCheckoutMethod(
5888
6292
  new FloPayError4(
5889
6293
  confirmed.error.message ?? "3DS authentication failed.",
5890
6294
  "api_error",
5891
6295
  { code: confirmed.error.code }
5892
6296
  ),
5893
- { checkoutMethod: "card" }
6297
+ "card"
5894
6298
  );
5895
6299
  }
5896
6300
  paymentIntent = confirmed.intent;
@@ -5899,13 +6303,13 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
5899
6303
  clientSecret: redirectResult.threeDSecureToken
5900
6304
  });
5901
6305
  if (nextAction.error) {
5902
- throw Object.assign(
6306
+ throw withCheckoutMethod(
5903
6307
  new FloPayError4(
5904
6308
  nextAction.error.message ?? "3DS authentication failed.",
5905
6309
  "api_error",
5906
6310
  { code: nextAction.error.code }
5907
6311
  ),
5908
- { checkoutMethod: "card" }
6312
+ "card"
5909
6313
  );
5910
6314
  }
5911
6315
  paymentIntent = (isSetupIntent ? nextAction.setupIntent : nextAction.paymentIntent) ?? null;
@@ -5915,6 +6319,7 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
5915
6319
  billingApiUrl,
5916
6320
  sessionId,
5917
6321
  session,
6322
+ telemetry,
5918
6323
  tokenizedData: {
5919
6324
  id: paymentIntent.id,
5920
6325
  type: "card",
@@ -5936,20 +6341,21 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
5936
6341
  billingApiUrl,
5937
6342
  sessionId,
5938
6343
  session,
5939
- returnUrl
6344
+ returnUrl,
6345
+ telemetry
5940
6346
  });
5941
6347
  }
5942
- throw Object.assign(
6348
+ throw withCheckoutMethod(
5943
6349
  new FloPayError4("3DS authentication did not complete successfully.", "api_error"),
5944
- { checkoutMethod: "card" }
6350
+ "card"
5945
6351
  );
5946
6352
  }
5947
6353
  if (redirectResult.type === "paypal_redirect_required") {
5948
6354
  const paypalStripe = (paypalFlopay ?? flopay)?.getRawProvider();
5949
6355
  if (!paypalStripe) {
5950
- throw Object.assign(
6356
+ throw withCheckoutMethod(
5951
6357
  new FloPayError4("PayPal is not available.", "api_error"),
5952
- { checkoutMethod: "paypal" }
6358
+ "paypal"
5953
6359
  );
5954
6360
  }
5955
6361
  if (redirectResult.paymentMethodId) {
@@ -5957,13 +6363,13 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
5957
6363
  clientSecret: redirectResult.threeDSecureToken
5958
6364
  });
5959
6365
  if (error2) {
5960
- throw Object.assign(
6366
+ throw withCheckoutMethod(
5961
6367
  new FloPayError4(
5962
6368
  error2.message ?? "PayPal authorization failed.",
5963
6369
  "api_error",
5964
6370
  { code: error2.code }
5965
6371
  ),
5966
- { checkoutMethod: "paypal" }
6372
+ "paypal"
5967
6373
  );
5968
6374
  }
5969
6375
  return {
@@ -5980,13 +6386,13 @@ async function handleSavedPaymentRedirectResult(redirectResult, {
5980
6386
  redirect: "if_required"
5981
6387
  });
5982
6388
  if (error) {
5983
- throw Object.assign(
6389
+ throw withCheckoutMethod(
5984
6390
  new FloPayError4(
5985
6391
  error.message ?? "PayPal authorization failed.",
5986
6392
  "api_error",
5987
6393
  { code: error.code }
5988
6394
  ),
5989
- { checkoutMethod: "paypal" }
6395
+ "paypal"
5990
6396
  );
5991
6397
  }
5992
6398
  return {
@@ -6042,7 +6448,8 @@ async function loadSavedPaymentProviders({
6042
6448
  publishableKey,
6043
6449
  paypalPublishableKey,
6044
6450
  billingApiUrl,
6045
- locale
6451
+ locale,
6452
+ telemetry
6046
6453
  }) {
6047
6454
  if (!publishableKey) {
6048
6455
  return { flopay: null, paypalFlopay: null };
@@ -6051,11 +6458,13 @@ async function loadSavedPaymentProviders({
6051
6458
  const [instance, paypalInstanceOrError] = await Promise.all([
6052
6459
  loadFloPay(publishableKey, {
6053
6460
  billingApiUrl,
6054
- locale
6461
+ locale,
6462
+ telemetry
6055
6463
  }),
6056
6464
  needsSeparatePaypal ? loadFloPay(paypalPublishableKey, {
6057
6465
  billingApiUrl,
6058
- locale
6466
+ locale,
6467
+ telemetry
6059
6468
  }).catch((err) => {
6060
6469
  console.warn("[FloPay] Failed to load PayPal Stripe instance:", err);
6061
6470
  return null;
@@ -6068,13 +6477,40 @@ async function loadSavedPaymentProviders({
6068
6477
  }
6069
6478
 
6070
6479
  // src/flopay-checkout.tsx
6071
- import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
6480
+ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
6072
6481
  var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
6073
6482
  var PAYPAL_RESUME_STORAGE_KEY = "flopay_checkout_saved_payment_resume";
6074
6483
  var sessionInflightMap = /* @__PURE__ */ new Map();
6075
6484
  function sleep(ms) {
6076
6485
  return new Promise((resolve) => setTimeout(resolve, ms));
6077
6486
  }
6487
+ function createStandaloneTelemetryReporter(billingApiUrl, enabled, context) {
6488
+ const reporter = createTelemetryBridge({
6489
+ billingApiUrl,
6490
+ sdkPackage: "@flopay/react",
6491
+ sdkVersion: SDK_VERSION2,
6492
+ enabled: enabled !== false
6493
+ });
6494
+ reporter.beginCheckout(context);
6495
+ return reporter;
6496
+ }
6497
+ function finishStandaloneTelemetry(reporter) {
6498
+ void reporter.flush().catch(() => {
6499
+ }).finally(() => reporter.destroy());
6500
+ }
6501
+ function reportStandaloneTelemetryError(billingApiUrl, enabled, context, errorCode, stage) {
6502
+ const reporter = createStandaloneTelemetryReporter(billingApiUrl, enabled, context);
6503
+ reporter.error({
6504
+ errorCode,
6505
+ stage,
6506
+ paymentMethodCategory: "unknown",
6507
+ ...stage === "session_read" ? { requestCategory: "session_read" } : {}
6508
+ });
6509
+ finishStandaloneTelemetry(reporter);
6510
+ }
6511
+ function isExpectedExistingSessionError(error) {
6512
+ return error.type === "validation_error" || error.code === "checkout_session_not_found" || error.code === "checkout_session_expired" || error.code === "checkout_session_completed" || error.code === "session_auto_completed";
6513
+ }
6078
6514
  function resolveDirectPaypalConfig(unified) {
6079
6515
  const clientId = unified?.data.paypal?.publishableKey;
6080
6516
  if (!clientId) return void 0;
@@ -6179,6 +6615,7 @@ function FloPayCheckout({
6179
6615
  nonce: nonceProp,
6180
6616
  createSession: createSessionParams,
6181
6617
  billingApiUrl,
6618
+ telemetry,
6182
6619
  appearance: appearanceOverride,
6183
6620
  locale,
6184
6621
  loading: loadingNode,
@@ -6224,9 +6661,9 @@ function FloPayCheckout({
6224
6661
  const checkoutLayout = children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout";
6225
6662
  const [unified, setUnified] = useState4(null);
6226
6663
  const [flopay, setFloPay] = useState4(null);
6227
- const flopayRef = useRef5(null);
6664
+ const flopayRef = useRef6(null);
6228
6665
  const [paypalFlopay, setPaypalFloPay] = useState4(null);
6229
- const paypalFlopayRef = useRef5(null);
6666
+ const paypalFlopayRef = useRef6(null);
6230
6667
  const [session, setSession] = useState4(null);
6231
6668
  const [resolvedSessionId, setResolvedSessionId] = useState4(sessionIdProp ?? "");
6232
6669
  const activeSessionId = sessionIdProp ?? resolvedSessionId;
@@ -6241,20 +6678,30 @@ function FloPayCheckout({
6241
6678
  const [createSessionPatch, setCreateSessionPatch] = useState4(void 0);
6242
6679
  const [createSessionPatchBaseHash, setCreateSessionPatchBaseHash] = useState4("");
6243
6680
  const [cardBootstrapPending, setCardBootstrapPending] = useState4(false);
6244
- const autoCheckoutAttempted = useRef5(false);
6245
- const paypalResumeAttempted = useRef5(false);
6246
- const savedPaymentKeysRef = useRef5(null);
6247
- const onCompleteRef = useRef5(onComplete);
6681
+ const autoCheckoutAttempted = useRef6(false);
6682
+ const paypalResumeAttempted = useRef6(false);
6683
+ const savedPaymentKeysRef = useRef6(null);
6684
+ const telemetryCheckoutContext = useMemo4(() => ({
6685
+ checkoutMode: checkoutModeProp ?? currentMode,
6686
+ layout: children ? "unknown" : layout === "buttons" ? "buttons" : "embedded"
6687
+ }), [checkoutModeProp, children, currentMode, layout]);
6688
+ const onCompleteRef = useRef6(onComplete);
6248
6689
  onCompleteRef.current = onComplete;
6249
- const onErrorRef = useRef5(onError);
6690
+ const onErrorRef = useRef6(onError);
6250
6691
  onErrorRef.current = onError;
6251
- const onDeclineRef = useRef5(onDecline);
6692
+ const onDeclineRef = useRef6(onDecline);
6252
6693
  onDeclineRef.current = onDecline;
6253
- const onSessionCompletedRef = useRef5(onSessionCompleted);
6694
+ useEffect6(() => {
6695
+ getFloPayTelemetryBridge(flopay)?.setCheckoutContext(telemetryCheckoutContext);
6696
+ if (paypalFlopay && paypalFlopay !== flopay) {
6697
+ getFloPayTelemetryBridge(paypalFlopay)?.setCheckoutContext(telemetryCheckoutContext);
6698
+ }
6699
+ }, [flopay, paypalFlopay, telemetryCheckoutContext]);
6700
+ const onSessionCompletedRef = useRef6(onSessionCompleted);
6254
6701
  onSessionCompletedRef.current = onSessionCompleted;
6255
6702
  useEffect6(() => {
6256
6703
  console.info("[FloPay] Checkout initialized", {
6257
- sdk_version: SDK_VERSION,
6704
+ sdk_version: SDK_VERSION2,
6258
6705
  checkout_type: checkoutType,
6259
6706
  checkout_layout: checkoutLayout,
6260
6707
  billing_api_url: resolvedBillingUrl
@@ -6287,22 +6734,112 @@ function FloPayCheckout({
6287
6734
  useEffect6(() => {
6288
6735
  setModeError(initialErrorMessage);
6289
6736
  }, [initialErrorMessage]);
6290
- const emitDecline = useCallback3(
6737
+ const emitDecline = useCallback4(
6291
6738
  (method, input, overrides) => {
6292
- onDeclineRef.current?.(buildDeclineEvent(method, input, overrides));
6739
+ invokeMerchantCallback(() => {
6740
+ onDeclineRef.current?.(buildDeclineEvent(method, input, overrides));
6741
+ });
6293
6742
  },
6294
- []
6743
+ [invokeMerchantCallback]
6295
6744
  );
6296
- const runSavedPaymentFlow = useCallback3(
6745
+ const runSavedPaymentFlow = useCallback4(
6297
6746
  async (sess, options) => {
6298
6747
  setModeError(null);
6299
6748
  setModeOverlayError(null);
6300
6749
  setModeOverlayStatus("processing");
6301
6750
  const activeSessionId2 = options?.sessionId ?? sess.id;
6751
+ const activeFloPay = flopayRef.current ?? paypalFlopayRef.current;
6752
+ const activeTelemetry = getFloPayTelemetryBridge(activeFloPay);
6753
+ const standaloneTelemetry = activeFloPay ? null : createStandaloneTelemetryReporter(
6754
+ resolvedBillingUrl,
6755
+ telemetry,
6756
+ telemetryCheckoutContext
6757
+ );
6758
+ const telemetrySource = {
6759
+ log: (input) => {
6760
+ if (activeTelemetry) activeTelemetry.log(input);
6761
+ else standaloneTelemetry?.log(input);
6762
+ },
6763
+ error: (input) => {
6764
+ if (activeTelemetry) activeTelemetry.error(input);
6765
+ else standaloneTelemetry?.error(input);
6766
+ },
6767
+ terminal: (input) => {
6768
+ if (activeTelemetry) activeTelemetry.terminal(input);
6769
+ else standaloneTelemetry?.terminal(input);
6770
+ },
6771
+ performance: (input) => {
6772
+ if (activeTelemetry) activeTelemetry.performance(input);
6773
+ else standaloneTelemetry?.performance(input);
6774
+ },
6775
+ now: () => activeTelemetry?.now() ?? standaloneTelemetry?.now() ?? 0,
6776
+ elapsed: (startedAt) => activeTelemetry?.elapsed(startedAt) ?? Math.max(0, (standaloneTelemetry?.now() ?? startedAt) - startedAt)
6777
+ };
6778
+ const processingStartedAt = telemetrySource.now();
6779
+ let recoveryFlow = Boolean(
6780
+ options?.initialAutoProcessingError || options?.initialAutoProcessingPending
6781
+ );
6782
+ let recoveryStarted = false;
6783
+ let recoveryStartedAt;
6784
+ const startRecovery = () => {
6785
+ if (recoveryStarted) return;
6786
+ recoveryStarted = true;
6787
+ recoveryFlow = true;
6788
+ recoveryStartedAt = telemetrySource.now();
6789
+ telemetrySource.log({
6790
+ name: "checkout.recovery.started",
6791
+ stage: "recovery",
6792
+ paymentMethodCategory: "saved"
6793
+ });
6794
+ telemetrySource.log({
6795
+ name: "operation.recovery.started",
6796
+ stage: "recovery",
6797
+ paymentMethodCategory: "saved"
6798
+ });
6799
+ };
6800
+ let processingFinished = false;
6801
+ const finishProcessing = () => {
6802
+ if (processingFinished) return;
6803
+ processingFinished = true;
6804
+ telemetrySource.log({
6805
+ name: "payment.processing.completed",
6806
+ stage: "processing",
6807
+ paymentMethodCategory: "saved"
6808
+ });
6809
+ telemetrySource.performance({
6810
+ stage: "processing",
6811
+ durationMs: telemetrySource.elapsed(processingStartedAt),
6812
+ durationMode: "machine",
6813
+ paymentMethodCategory: "saved"
6814
+ });
6815
+ if (recoveryStartedAt !== void 0) {
6816
+ telemetrySource.performance({
6817
+ stage: "recovery",
6818
+ durationMs: telemetrySource.elapsed(recoveryStartedAt),
6819
+ durationMode: "machine",
6820
+ paymentMethodCategory: "saved"
6821
+ });
6822
+ }
6823
+ };
6824
+ telemetrySource.log({
6825
+ name: "payment.method.selected",
6826
+ stage: "processing",
6827
+ paymentMethodCategory: "saved"
6828
+ });
6829
+ telemetrySource.log({
6830
+ name: "payment.processing.started",
6831
+ stage: "processing",
6832
+ paymentMethodCategory: "saved"
6833
+ });
6834
+ if (recoveryFlow) {
6835
+ startRecovery();
6836
+ }
6837
+ let completionCallback;
6302
6838
  try {
6303
6839
  const redirectResult = getRedirectResultFromCheckoutProcessError(options?.initialAutoProcessingError);
6304
6840
  let paymentResult;
6305
6841
  if (redirectResult) {
6842
+ startRecovery();
6306
6843
  if (redirectResult.type === "paypal_redirect_required" && savedPaymentKeysRef.current?.publishableKey) {
6307
6844
  persistPayPalResumeState({
6308
6845
  sessionId: activeSessionId2,
@@ -6316,13 +6853,14 @@ function FloPayCheckout({
6316
6853
  attempt3DS: options?.attempt3DS,
6317
6854
  billingApiUrl: resolvedBillingUrl,
6318
6855
  sessionId: activeSessionId2,
6319
- session: sess
6856
+ session: sess,
6857
+ telemetry: false
6320
6858
  });
6321
6859
  if (redirectResult.type === "paypal_redirect_required") {
6322
6860
  clearPayPalResumeState();
6323
6861
  }
6324
6862
  } else if (options?.initialAutoProcessingPending) {
6325
- const api = new PaymentAPI4(resolvedBillingUrl);
6863
+ const api = new PaymentAPI4(resolvedBillingUrl, { telemetry: false });
6326
6864
  const completed = await api.waitForCheckoutSessionCompletion(options.initialAutoProcessingPending.sessionId, {
6327
6865
  initialDelayMs: options.initialAutoProcessingPending.retryAfterMs
6328
6866
  });
@@ -6350,11 +6888,13 @@ function FloPayCheckout({
6350
6888
  const result = await processSavedPaymentForMode({
6351
6889
  billingApiUrl: resolvedBillingUrl,
6352
6890
  sessionId: activeSessionId2,
6353
- session: sess
6891
+ session: sess,
6892
+ telemetry: false
6354
6893
  });
6355
6894
  if (result.type === "success") {
6356
6895
  paymentResult = result.result;
6357
6896
  } else {
6897
+ startRecovery();
6358
6898
  if (result.type === "paypal_redirect_required" && savedPaymentKeysRef.current?.publishableKey) {
6359
6899
  persistPayPalResumeState({
6360
6900
  sessionId: activeSessionId2,
@@ -6368,7 +6908,8 @@ function FloPayCheckout({
6368
6908
  attempt3DS: options?.attempt3DS,
6369
6909
  billingApiUrl: resolvedBillingUrl,
6370
6910
  sessionId: activeSessionId2,
6371
- session: sess
6911
+ session: sess,
6912
+ telemetry: false
6372
6913
  });
6373
6914
  if (result.type === "paypal_redirect_required") {
6374
6915
  clearPayPalResumeState();
@@ -6376,20 +6917,57 @@ function FloPayCheckout({
6376
6917
  }
6377
6918
  }
6378
6919
  if (activeSessionId2) markSessionRecentlyCompleted(activeSessionId2);
6920
+ finishProcessing();
6921
+ if (recoveryFlow) {
6922
+ telemetrySource.log({
6923
+ name: "checkout.recovery.completed",
6924
+ stage: "recovery",
6925
+ paymentMethodCategory: "saved"
6926
+ });
6927
+ telemetrySource.log({
6928
+ name: "operation.recovery.completed",
6929
+ stage: "recovery",
6930
+ paymentMethodCategory: "saved"
6931
+ });
6932
+ }
6933
+ telemetrySource.terminal({
6934
+ outcome: "payment_succeeded",
6935
+ paymentMethodCategory: "saved"
6936
+ });
6379
6937
  setModeOverlayStatus("success");
6380
6938
  await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
6381
- onCompleteRef.current?.(paymentResult);
6382
- return true;
6939
+ completionCallback = () => onCompleteRef.current?.(paymentResult);
6383
6940
  } catch (err) {
6384
6941
  const floPayErr = normalizeSavedPaymentError(err);
6385
6942
  const method = floPayErr.checkoutMethod ?? DEFAULT_SAVED_PAYMENT_DECLINE_METHOD;
6386
6943
  setModeError(floPayErr.message);
6387
6944
  setModeOverlayError(floPayErr.message);
6388
6945
  if (options?.fallbackToFull) {
6946
+ telemetrySource.log({
6947
+ name: "operation.fallback",
6948
+ stage: "recovery",
6949
+ paymentMethodCategory: "saved"
6950
+ });
6389
6951
  setCurrentMode("full");
6390
6952
  replaceCheckoutModeQueryParam("full");
6391
6953
  }
6392
- onErrorRef.current?.(floPayErr);
6954
+ finishProcessing();
6955
+ const expectedDecline = Boolean(
6956
+ floPayErr.declineCode || floPayErr.code?.toLowerCase().includes("declin")
6957
+ );
6958
+ if (expectedDecline) {
6959
+ telemetrySource.terminal({
6960
+ outcome: "payment_declined",
6961
+ paymentMethodCategory: "saved"
6962
+ });
6963
+ } else {
6964
+ telemetrySource.error({
6965
+ errorCode: recoveryFlow ? "RECOVERY_FAILED" : "PAYMENT_PROCESSING_FAILED",
6966
+ stage: recoveryFlow ? "recovery" : "processing",
6967
+ paymentMethodCategory: "saved"
6968
+ });
6969
+ }
6970
+ invokeMerchantCallback(() => onErrorRef.current?.(floPayErr));
6393
6971
  emitDecline(method, floPayErr, {
6394
6972
  code: floPayErr.code,
6395
6973
  declineCode: floPayErr.declineCode
@@ -6399,16 +6977,35 @@ function FloPayCheckout({
6399
6977
  sleep(PROCESSING_OVERLAY_ERROR_DELAY_MS),
6400
6978
  options?.ensureProvidersReady ? options.ensureProvidersReady() : Promise.resolve()
6401
6979
  ]);
6980
+ if (recoveryFlow) {
6981
+ telemetrySource.log({
6982
+ name: "checkout.recovery.completed",
6983
+ stage: "recovery",
6984
+ paymentMethodCategory: "saved"
6985
+ });
6986
+ telemetrySource.log({
6987
+ name: "operation.recovery.completed",
6988
+ stage: "recovery",
6989
+ paymentMethodCategory: "saved"
6990
+ });
6991
+ }
6402
6992
  return false;
6403
6993
  } finally {
6994
+ finishProcessing();
6995
+ if (standaloneTelemetry) finishStandaloneTelemetry(standaloneTelemetry);
6404
6996
  setModeOverlayStatus(null);
6405
6997
  setModeOverlayError(null);
6406
6998
  }
6999
+ invokeMerchantCallback(completionCallback);
7000
+ return true;
6407
7001
  },
6408
7002
  [
6409
7003
  emitDecline,
7004
+ invokeMerchantCallback,
6410
7005
  normalizeSavedPaymentError,
6411
- resolvedBillingUrl
7006
+ resolvedBillingUrl,
7007
+ telemetry,
7008
+ telemetryCheckoutContext
6412
7009
  ]
6413
7010
  );
6414
7011
  useEffect6(() => {
@@ -6426,6 +7023,8 @@ function FloPayCheckout({
6426
7023
  }
6427
7024
  paypalResumeAttempted.current = true;
6428
7025
  void (async () => {
7026
+ let resumeTelemetry;
7027
+ let redirectResumeStartedAt = 0;
6429
7028
  setModeError(null);
6430
7029
  setModeOverlayError(null);
6431
7030
  setModeOverlayStatus("processing");
@@ -6433,7 +7032,11 @@ function FloPayCheckout({
6433
7032
  try {
6434
7033
  if (params.get("redirect_status") === "failed") {
6435
7034
  throw Object.assign(
6436
- new FloPayError5("PayPal payment was declined. Please try again.", "api_error"),
7035
+ new FloPayError5(
7036
+ "PayPal payment was declined. Please try again.",
7037
+ "api_error",
7038
+ { declineCode: "paypal_redirect_failed" }
7039
+ ),
6437
7040
  { checkoutMethod: "paypal" }
6438
7041
  );
6439
7042
  }
@@ -6444,7 +7047,22 @@ function FloPayCheckout({
6444
7047
  publishableKey: resumeState.publishableKey,
6445
7048
  paypalPublishableKey: resumeState.paypalPublishableKey,
6446
7049
  billingApiUrl: resolvedBillingUrl,
6447
- locale
7050
+ locale,
7051
+ telemetry
7052
+ });
7053
+ resumeTelemetry = getFloPayTelemetryBridge(resumePaypalFlopay ?? resumeFlopay);
7054
+ redirectResumeStartedAt = resumeTelemetry?.now() ?? 0;
7055
+ resumeTelemetry?.log({
7056
+ name: "provider.redirect.resumed",
7057
+ stage: "redirect_resume",
7058
+ provider: "paypal",
7059
+ paymentMethodCategory: "paypal"
7060
+ });
7061
+ resumeTelemetry?.log({
7062
+ name: "operation.recovery.started",
7063
+ stage: "recovery",
7064
+ provider: "paypal",
7065
+ paymentMethodCategory: "paypal"
6448
7066
  });
6449
7067
  const paypalStripe = (resumePaypalFlopay ?? resumeFlopay)?.getRawProvider();
6450
7068
  if (!paypalStripe) {
@@ -6474,7 +7092,7 @@ function FloPayCheckout({
6474
7092
  const paymentMethodId = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
6475
7093
  let finalResultStatus = resultStatus;
6476
7094
  if (resumeState.sessionId) {
6477
- const resumeApi = new PaymentAPI4(resolvedBillingUrl);
7095
+ const resumeApi = new PaymentAPI4(resolvedBillingUrl, { telemetry: false });
6478
7096
  const resumeSessionResult = await resumeApi.getUnifiedCheckoutSession(resumeState.sessionId);
6479
7097
  const resumeSession = resumeSessionResult.data.session;
6480
7098
  if (resumeSession && resumeSession.status !== "complete") {
@@ -6482,6 +7100,7 @@ function FloPayCheckout({
6482
7100
  billingApiUrl: resolvedBillingUrl,
6483
7101
  sessionId: resumeState.sessionId,
6484
7102
  session: resumeSession,
7103
+ telemetry: false,
6485
7104
  tokenizedData: {
6486
7105
  id: paymentMethodId ?? paymentIntent.id,
6487
7106
  type: "card",
@@ -6499,20 +7118,84 @@ function FloPayCheckout({
6499
7118
  }
6500
7119
  }
6501
7120
  if (resumeState.sessionId) markSessionRecentlyCompleted(resumeState.sessionId);
7121
+ resumeTelemetry?.log({
7122
+ name: "operation.recovery.completed",
7123
+ stage: "recovery",
7124
+ provider: "paypal",
7125
+ paymentMethodCategory: "paypal"
7126
+ });
7127
+ resumeTelemetry?.performance({
7128
+ stage: "redirect_resume",
7129
+ durationMs: resumeTelemetry.elapsed(redirectResumeStartedAt),
7130
+ durationMode: "machine",
7131
+ provider: "paypal",
7132
+ paymentMethodCategory: "paypal"
7133
+ });
7134
+ resumeTelemetry?.terminal({
7135
+ outcome: "payment_succeeded",
7136
+ provider: "paypal",
7137
+ paymentMethodCategory: "paypal"
7138
+ });
6502
7139
  setModeOverlayStatus("success");
6503
7140
  await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
6504
- onCompleteRef.current?.({
7141
+ invokeMerchantCallback(() => onCompleteRef.current?.({
6505
7142
  status: finalResultStatus,
6506
7143
  paymentIntentId: paymentIntent.id,
6507
7144
  paymentMethodId,
6508
7145
  checkoutMethod: "paypal"
6509
- });
7146
+ }));
6510
7147
  } catch (err) {
6511
7148
  const floPayErr = normalizeSavedPaymentError(err);
6512
7149
  const method = floPayErr.checkoutMethod ?? "paypal";
7150
+ const expectedDecline = Boolean(
7151
+ floPayErr.declineCode || floPayErr.code?.toLowerCase().includes("declin")
7152
+ );
7153
+ if (resumeTelemetry) {
7154
+ resumeTelemetry.performance({
7155
+ stage: "redirect_resume",
7156
+ durationMs: resumeTelemetry.elapsed(redirectResumeStartedAt),
7157
+ durationMode: "machine",
7158
+ provider: "paypal",
7159
+ paymentMethodCategory: "paypal"
7160
+ });
7161
+ if (expectedDecline) {
7162
+ resumeTelemetry.terminal({
7163
+ outcome: "payment_declined",
7164
+ provider: "paypal",
7165
+ paymentMethodCategory: "paypal"
7166
+ });
7167
+ } else {
7168
+ resumeTelemetry.error({
7169
+ errorCode: "REDIRECT_RESUME_FAILED",
7170
+ stage: "redirect_resume",
7171
+ provider: "paypal",
7172
+ paymentMethodCategory: "paypal"
7173
+ });
7174
+ }
7175
+ } else if (expectedDecline) {
7176
+ const reporter = createStandaloneTelemetryReporter(
7177
+ resolvedBillingUrl,
7178
+ telemetry,
7179
+ telemetryCheckoutContext
7180
+ );
7181
+ reporter.terminal({
7182
+ outcome: "payment_declined",
7183
+ provider: "paypal",
7184
+ paymentMethodCategory: "paypal"
7185
+ });
7186
+ finishStandaloneTelemetry(reporter);
7187
+ } else {
7188
+ reportStandaloneTelemetryError(
7189
+ resolvedBillingUrl,
7190
+ telemetry,
7191
+ telemetryCheckoutContext,
7192
+ "REDIRECT_RESUME_FAILED",
7193
+ "redirect_resume"
7194
+ );
7195
+ }
6513
7196
  setModeError(floPayErr.message);
6514
7197
  setModeOverlayError(floPayErr.message);
6515
- onErrorRef.current?.(floPayErr);
7198
+ invokeMerchantCallback(() => onErrorRef.current?.(floPayErr));
6516
7199
  emitDecline(method, floPayErr, {
6517
7200
  code: floPayErr.code,
6518
7201
  declineCode: floPayErr.declineCode
@@ -6527,8 +7210,8 @@ function FloPayCheckout({
6527
7210
  setConfirmProcessing(false);
6528
7211
  }
6529
7212
  })();
6530
- }, [emitDecline, locale, normalizeSavedPaymentError, resolvedBillingUrl]);
6531
- const initializedHashRef = useRef5(null);
7213
+ }, [emitDecline, invokeMerchantCallback, locale, normalizeSavedPaymentError, resolvedBillingUrl, telemetry]);
7214
+ const initializedHashRef = useRef6(null);
6532
7215
  function hashCreateParams(params) {
6533
7216
  const key = JSON.stringify({
6534
7217
  c: params?.clientId,
@@ -6565,7 +7248,7 @@ function FloPayCheckout({
6565
7248
  () => effectiveCreateSession ? hashCreateParams(effectiveCreateSession) : "",
6566
7249
  [effectiveCreateSession]
6567
7250
  );
6568
- const createSessionParamsRef = useRef5(effectiveCreateSession);
7251
+ const createSessionParamsRef = useRef6(effectiveCreateSession);
6569
7252
  createSessionParamsRef.current = effectiveCreateSession;
6570
7253
  useEffect6(() => {
6571
7254
  setResolvedSessionId(sessionIdProp ?? "");
@@ -6577,44 +7260,107 @@ function FloPayCheckout({
6577
7260
  setModeOverlayStatus(null);
6578
7261
  }, [createSessionHash, initialErrorMessage, sessionIdProp]);
6579
7262
  async function resolveInlineSession(params, cacheKey) {
6580
- const api = new PaymentAPI4(resolvedBillingUrl);
6581
- const cached = readCachedInlineSession(cacheKey);
6582
- let sid = cached?.sid ?? null;
6583
- let realResult = null;
6584
- if (sid) {
6585
- try {
6586
- realResult = await api.getUnifiedCheckoutSession(sid, cached?.nonce);
6587
- const status = realResult.data.session?.status;
6588
- if (status === "complete") {
6589
- if (wasSessionRecentlyCompleted(sid)) {
6590
- return { sid, result: realResult };
7263
+ const reporter = createStandaloneTelemetryReporter(
7264
+ resolvedBillingUrl,
7265
+ telemetry,
7266
+ telemetryCheckoutContext
7267
+ );
7268
+ const api = new PaymentAPI4(resolvedBillingUrl, { telemetry: false });
7269
+ try {
7270
+ const cached = readCachedInlineSession(cacheKey);
7271
+ reporter.log({
7272
+ name: cached ? "operation.cache.hit" : "operation.cache.miss",
7273
+ stage: "session_create",
7274
+ requestCategory: "session_create"
7275
+ });
7276
+ let sid = cached?.sid ?? null;
7277
+ let realResult = null;
7278
+ if (sid) {
7279
+ try {
7280
+ realResult = await api.getUnifiedCheckoutSession(sid, cached?.nonce);
7281
+ const status = realResult.data.session?.status;
7282
+ if (status === "complete") {
7283
+ if (wasSessionRecentlyCompleted(sid)) {
7284
+ return { sid, result: realResult };
7285
+ }
7286
+ clearCachedInlineSession(cacheKey);
7287
+ sid = null;
7288
+ realResult = null;
6591
7289
  }
7290
+ } catch {
7291
+ reporter.log({
7292
+ name: "operation.fallback",
7293
+ stage: "session_read",
7294
+ requestCategory: "session_read"
7295
+ });
6592
7296
  clearCachedInlineSession(cacheKey);
6593
7297
  sid = null;
6594
- realResult = null;
6595
7298
  }
6596
- } catch {
6597
- clearCachedInlineSession(cacheKey);
6598
- sid = null;
6599
7299
  }
6600
- }
6601
- if (!sid) {
6602
- const paramsWithAnalytics = {
6603
- ...params,
6604
- avsCheck: !!enableAVS,
6605
- avsConfig: typeof enableAVS === "object" ? enableAVS : void 0,
6606
- checkoutType: "embedded_checkout",
6607
- checkoutLayout: children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout"
6608
- };
6609
- realResult = await api.createAndFetchSession(paramsWithAnalytics);
6610
- sid = realResult.data.session?.id ?? "";
6611
- if (sid) {
6612
- persistCachedInlineSession(cacheKey, sid, realResult.data.session?.clientSecret);
7300
+ if (!sid) {
7301
+ const sessionCreateStartedAt = reporter.now();
7302
+ reporter.log({
7303
+ name: "session.create.started",
7304
+ stage: "session_create",
7305
+ requestCategory: "session_create"
7306
+ });
7307
+ const paramsWithAnalytics = {
7308
+ ...params,
7309
+ avsCheck: !!enableAVS,
7310
+ avsConfig: typeof enableAVS === "object" ? enableAVS : void 0,
7311
+ checkoutType: "embedded_checkout",
7312
+ checkoutLayout: children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout"
7313
+ };
7314
+ try {
7315
+ realResult = await api.createAndFetchSession(paramsWithAnalytics);
7316
+ reporter.log({
7317
+ name: "session.request.completed",
7318
+ stage: "session_complete",
7319
+ requestCategory: "session_create",
7320
+ statusClass: "2xx"
7321
+ });
7322
+ reporter.performance({
7323
+ stage: "session_create",
7324
+ durationMs: reporter.now() - sessionCreateStartedAt,
7325
+ durationMode: "machine",
7326
+ requestCategory: "session_create",
7327
+ statusClass: "2xx"
7328
+ });
7329
+ } catch (error) {
7330
+ reporter.performance({
7331
+ stage: "session_create",
7332
+ durationMs: reporter.now() - sessionCreateStartedAt,
7333
+ durationMode: "machine",
7334
+ requestCategory: "session_create",
7335
+ statusClass: "network_error"
7336
+ });
7337
+ if (error instanceof FloPayError5 && error.type === "validation_error") {
7338
+ reporter.terminal({
7339
+ outcome: "validation_rejected",
7340
+ stage: "session_create",
7341
+ paymentMethodCategory: "unknown"
7342
+ });
7343
+ } else {
7344
+ reporter.error({
7345
+ errorCode: "CHECKOUT_SESSION_CREATE_FAILED",
7346
+ stage: "session_create",
7347
+ paymentMethodCategory: "unknown",
7348
+ requestCategory: "session_create"
7349
+ });
7350
+ }
7351
+ throw error;
7352
+ }
7353
+ sid = realResult.data.session?.id ?? "";
7354
+ if (sid) {
7355
+ persistCachedInlineSession(cacheKey, sid, realResult.data.session?.clientSecret);
7356
+ }
6613
7357
  }
7358
+ return { sid: sid ?? "", result: realResult };
7359
+ } finally {
7360
+ finishStandaloneTelemetry(reporter);
6614
7361
  }
6615
- return { sid: sid ?? "", result: realResult };
6616
7362
  }
6617
- const bootstrapInlineSession = useCallback3(
7363
+ const bootstrapInlineSession = useCallback4(
6618
7364
  async (patch) => {
6619
7365
  const baseParams = createSessionParamsRef.current;
6620
7366
  if (!baseParams) {
@@ -6658,7 +7404,8 @@ function FloPayCheckout({
6658
7404
  publishableKey,
6659
7405
  paypalPublishableKey,
6660
7406
  billingApiUrl: resolvedBillingUrl,
6661
- locale
7407
+ locale,
7408
+ telemetry
6662
7409
  });
6663
7410
  flopayRef.current = instance;
6664
7411
  setFloPay(instance);
@@ -6673,9 +7420,9 @@ function FloPayCheckout({
6673
7420
  }
6674
7421
  return resolved;
6675
7422
  },
6676
- [locale, resolvedBillingUrl]
7423
+ [locale, resolvedBillingUrl, telemetry, telemetryCheckoutContext]
6677
7424
  );
6678
- const handleInlineSessionPatch = useCallback3(async (patch) => {
7425
+ const handleInlineSessionPatch = useCallback4(async (patch) => {
6679
7426
  if (!hasInlineSessionPatchData(patch) || cardBootstrapPending) {
6680
7427
  return {
6681
7428
  sessionId: resolvedSessionId,
@@ -6752,7 +7499,9 @@ function FloPayCheckout({
6752
7499
  setModeOverlayStatus("success");
6753
7500
  await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
6754
7501
  if (!cancelled) {
6755
- onCompleteRef.current?.({ status: "succeeded" });
7502
+ invokeMerchantCallback(() => {
7503
+ onCompleteRef.current?.({ status: "succeeded" });
7504
+ });
6756
7505
  setModeOverlayStatus(null);
6757
7506
  setModeOverlayError(null);
6758
7507
  }
@@ -6772,8 +7521,9 @@ function FloPayCheckout({
6772
7521
  }
6773
7522
  setIsLoading(true);
6774
7523
  async function init() {
7524
+ let sessionReadCompleted = false;
6775
7525
  try {
6776
- const api = new PaymentAPI4(resolvedBillingUrl);
7526
+ const api = new PaymentAPI4(resolvedBillingUrl, { telemetry: false });
6777
7527
  const result = await api.getUnifiedCheckoutSession(activeSessionId, nonceProp);
6778
7528
  if (cancelled) return;
6779
7529
  setUnified(result);
@@ -6784,7 +7534,9 @@ function FloPayCheckout({
6784
7534
  }
6785
7535
  if (sess.status === "complete") {
6786
7536
  setIsLoading(false);
6787
- onSessionCompletedRef.current?.(sess.successUrl ?? "");
7537
+ invokeMerchantCallback(() => {
7538
+ onSessionCompletedRef.current?.(sess.successUrl ?? "");
7539
+ });
6788
7540
  return;
6789
7541
  }
6790
7542
  if (sess.status === "expired") {
@@ -6792,6 +7544,7 @@ function FloPayCheckout({
6792
7544
  code: "checkout_session_expired"
6793
7545
  });
6794
7546
  }
7547
+ sessionReadCompleted = true;
6795
7548
  const effectiveMode = checkoutModeProp ?? sess.checkoutMode ?? "full";
6796
7549
  setCurrentMode(effectiveMode);
6797
7550
  const hasPayPalRedirectParams = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("payment_intent");
@@ -6823,6 +7576,23 @@ function FloPayCheckout({
6823
7576
  if (!cancelled) setIsLoading(false);
6824
7577
  } catch (err) {
6825
7578
  if (cancelled) return;
7579
+ if (!(err instanceof FloPayError5)) {
7580
+ reportStandaloneTelemetryError(
7581
+ resolvedBillingUrl,
7582
+ telemetry,
7583
+ telemetryCheckoutContext,
7584
+ "INTERNAL_SDK_ERROR",
7585
+ "checkout_mount"
7586
+ );
7587
+ } else if (!sessionReadCompleted && !isExpectedExistingSessionError(err)) {
7588
+ reportStandaloneTelemetryError(
7589
+ resolvedBillingUrl,
7590
+ telemetry,
7591
+ telemetryCheckoutContext,
7592
+ "NETWORK_REQUEST_FAILED",
7593
+ "session_read"
7594
+ );
7595
+ }
6826
7596
  const floPayErr = err instanceof FloPayError5 ? err : new FloPayError5(err instanceof Error ? err.message : "Failed to initialize checkout", "api_error");
6827
7597
  setLoadError(floPayErr);
6828
7598
  setIsLoading(false);
@@ -6844,7 +7614,8 @@ function FloPayCheckout({
6844
7614
  publishableKey,
6845
7615
  paypalPublishableKey,
6846
7616
  billingApiUrl: resolvedBillingUrl,
6847
- locale
7617
+ locale,
7618
+ telemetry
6848
7619
  });
6849
7620
  flopayRef.current = instance;
6850
7621
  setFloPay(instance);
@@ -6861,10 +7632,11 @@ function FloPayCheckout({
6861
7632
  createSessionHash,
6862
7633
  effectiveCreateSessionMode,
6863
7634
  initSessionDependency,
7635
+ invokeMerchantCallback,
6864
7636
  nonceProp,
6865
7637
  runSavedPaymentFlow
6866
7638
  ]);
6867
- const handleConfirmCheckout = useCallback3(async () => {
7639
+ const handleConfirmCheckout = useCallback4(async () => {
6868
7640
  if (confirmProcessing || !session) return;
6869
7641
  setConfirmProcessing(true);
6870
7642
  setModeError(null);
@@ -6920,7 +7692,7 @@ function FloPayCheckout({
6920
7692
  ]
6921
7693
  );
6922
7694
  const shouldShowInterimButtons = Boolean(createSessionParams) && layout === "buttons" && !isPaypalOnlySession && (!flopay || !providerOptions);
6923
- const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ jsx8(
7695
+ const modeOverlay = modeOverlayStatus ? /* @__PURE__ */ jsx9(
6924
7696
  ProcessingOverlay,
6925
7697
  {
6926
7698
  status: modeOverlayStatus,
@@ -6929,32 +7701,32 @@ function FloPayCheckout({
6929
7701
  ) : null;
6930
7702
  if (isLoading) {
6931
7703
  if (loadingNode) {
6932
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
7704
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
6933
7705
  loadingNode,
6934
7706
  modeOverlay
6935
7707
  ] });
6936
7708
  }
6937
7709
  if (layout === "buttons") {
6938
7710
  const bundleRadius = themeBundle?.buttonsLayout?.cardButton?.borderRadius ?? themeBundle?.appearance.variables?.borderRadius ?? 8;
6939
- const skeletonBar = (h) => /* @__PURE__ */ jsx8("div", { style: {
7711
+ const skeletonBar = (h) => /* @__PURE__ */ jsx9("div", { style: {
6940
7712
  height: h,
6941
7713
  borderRadius: bundleRadius,
6942
7714
  background: "#e5e7eb",
6943
7715
  animation: "flopay-loading-pulse 1.5s ease-in-out infinite"
6944
7716
  } });
6945
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
6946
- /* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
7717
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
7718
+ /* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
6947
7719
  showPayPal && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
6948
7720
  showStripe && (showApplePay || showGooglePay) && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
6949
7721
  showStripe && skeletonBar(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
6950
- /* @__PURE__ */ jsx8("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
7722
+ /* @__PURE__ */ jsx9("style", { children: `@keyframes flopay-loading-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
6951
7723
  ] }),
6952
7724
  modeOverlay
6953
7725
  ] });
6954
7726
  }
6955
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
6956
- /* @__PURE__ */ jsxs5("div", { style: { display: "flex", justifyContent: "center", padding: 32 }, children: [
6957
- /* @__PURE__ */ jsx8("div", { style: {
7727
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
7728
+ /* @__PURE__ */ jsxs6("div", { style: { display: "flex", justifyContent: "center", padding: 32 }, children: [
7729
+ /* @__PURE__ */ jsx9("div", { style: {
6958
7730
  width: 24,
6959
7731
  height: 24,
6960
7732
  border: "2px solid #e5e7eb",
@@ -6962,16 +7734,16 @@ function FloPayCheckout({
6962
7734
  borderRadius: "50%",
6963
7735
  animation: "spin 0.6s linear infinite"
6964
7736
  } }),
6965
- /* @__PURE__ */ jsx8("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
7737
+ /* @__PURE__ */ jsx9("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
6966
7738
  ] }),
6967
7739
  modeOverlay
6968
7740
  ] });
6969
7741
  }
6970
7742
  if (loadError) {
6971
7743
  if (errorNode) {
6972
- return /* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: errorNode(loadError) });
7744
+ return /* @__PURE__ */ jsx9(CheckoutContext.Provider, { value: checkoutValue, children: errorNode(loadError) });
6973
7745
  }
6974
- return /* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx8(
7746
+ return /* @__PURE__ */ jsx9(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx9(
6975
7747
  "div",
6976
7748
  {
6977
7749
  role: "alert",
@@ -6987,8 +7759,8 @@ function FloPayCheckout({
6987
7759
  ) });
6988
7760
  }
6989
7761
  if (shouldShowInterimButtons) {
6990
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
6991
- /* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx8(
7762
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
7763
+ /* @__PURE__ */ jsx9(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx9(
6992
7764
  InterimButtonsView,
6993
7765
  {
6994
7766
  onButtonClick,
@@ -7008,27 +7780,11 @@ function FloPayCheckout({
7008
7780
  ] });
7009
7781
  }
7010
7782
  if (isPaypalOnlySession && session && directPaypalConfig) {
7011
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
7012
- /* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsxs5("div", { className, style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
7013
- modeError && /* @__PURE__ */ jsx8(
7014
- "div",
7015
- {
7016
- role: "alert",
7017
- "data-testid": "flopay-error",
7018
- style: {
7019
- padding: "0.625rem 0.875rem",
7020
- background: "#FEF2F2",
7021
- border: "1px solid #FECACA",
7022
- borderRadius: "8px",
7023
- color: "#991B1B",
7024
- fontSize: "0.85rem",
7025
- fontWeight: 600
7026
- },
7027
- children: modeError
7028
- }
7029
- ),
7030
- /* @__PURE__ */ jsx8(
7031
- DirectPayPalButton,
7783
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
7784
+ /* @__PURE__ */ jsx9(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsxs6("div", { className, style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
7785
+ modeError && /* @__PURE__ */ jsx9(ErrorBanner, { icon: false, children: modeError }),
7786
+ /* @__PURE__ */ jsx9(
7787
+ InstrumentedDirectPayPalButton,
7032
7788
  {
7033
7789
  sessionId: activeSessionId,
7034
7790
  nonce: session.clientSecret || void 0,
@@ -7043,6 +7799,8 @@ function FloPayCheckout({
7043
7799
  onDecline,
7044
7800
  onButtonClick,
7045
7801
  session,
7802
+ telemetry,
7803
+ telemetryContext: telemetryCheckoutContext,
7046
7804
  debug
7047
7805
  }
7048
7806
  )
@@ -7051,12 +7809,12 @@ function FloPayCheckout({
7051
7809
  ] });
7052
7810
  }
7053
7811
  if (!flopay || !providerOptions) {
7054
- return /* @__PURE__ */ jsx8(Fragment3, { children: modeOverlay });
7812
+ return /* @__PURE__ */ jsx9(Fragment3, { children: modeOverlay });
7055
7813
  }
7056
7814
  if (currentMode === "confirm") {
7057
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
7058
- /* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx8(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: /* @__PURE__ */ jsxs5("div", { className, children: [
7059
- modeError && /* @__PURE__ */ jsx8(
7815
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
7816
+ /* @__PURE__ */ jsx9(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx9(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: /* @__PURE__ */ jsxs6("div", { className, children: [
7817
+ modeError && /* @__PURE__ */ jsx9(
7060
7818
  "div",
7061
7819
  {
7062
7820
  style: {
@@ -7071,7 +7829,7 @@ function FloPayCheckout({
7071
7829
  renderConfirmButton ? renderConfirmButton({
7072
7830
  onConfirm: handleConfirmCheckout,
7073
7831
  isProcessing: confirmProcessing
7074
- }) : /* @__PURE__ */ jsx8(
7832
+ }) : /* @__PURE__ */ jsx9(
7075
7833
  "button",
7076
7834
  {
7077
7835
  type: "button",
@@ -7096,9 +7854,9 @@ function FloPayCheckout({
7096
7854
  modeOverlay
7097
7855
  ] });
7098
7856
  }
7099
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
7100
- /* @__PURE__ */ jsx8(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx8(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: children ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
7101
- modeError && /* @__PURE__ */ jsx8(
7857
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
7858
+ /* @__PURE__ */ jsx9(CheckoutContext.Provider, { value: checkoutValue, children: /* @__PURE__ */ jsx9(FloPayProvider, { flopay, paypalFlopay, options: providerOptions, children: children ? /* @__PURE__ */ jsxs6(Fragment3, { children: [
7859
+ modeError && /* @__PURE__ */ jsx9(
7102
7860
  "div",
7103
7861
  {
7104
7862
  style: {
@@ -7113,7 +7871,7 @@ function FloPayCheckout({
7113
7871
  children: modeError
7114
7872
  }
7115
7873
  ),
7116
- /* @__PURE__ */ jsx8(
7874
+ /* @__PURE__ */ jsx9(
7117
7875
  SessionInjector,
7118
7876
  {
7119
7877
  sessionId: activeSessionId,
@@ -7123,7 +7881,7 @@ function FloPayCheckout({
7123
7881
  children
7124
7882
  }
7125
7883
  )
7126
- ] }) : /* @__PURE__ */ jsx8(
7884
+ ] }) : /* @__PURE__ */ jsx9(
7127
7885
  SplitCardForm,
7128
7886
  {
7129
7887
  sessionId: activeSessionId,
@@ -7186,8 +7944,8 @@ function SessionInjector({
7186
7944
  session,
7187
7945
  children
7188
7946
  }) {
7189
- return /* @__PURE__ */ jsx8(Fragment3, { children: React8.Children.map(children, (child) => {
7190
- if (!React8.isValidElement(child)) return child;
7947
+ return /* @__PURE__ */ jsx9(Fragment3, { children: React9.Children.map(children, (child) => {
7948
+ if (!React9.isValidElement(child)) return child;
7191
7949
  const existing = child.props;
7192
7950
  const injected = {};
7193
7951
  if (!existing.sessionId) injected.sessionId = sessionId;
@@ -7202,15 +7960,11 @@ function SessionInjector({
7202
7960
  injected.lastName = session.customer.lastName;
7203
7961
  }
7204
7962
  if (Object.keys(injected).length === 0) return child;
7205
- return React8.cloneElement(child, injected);
7963
+ return React9.cloneElement(child, injected);
7206
7964
  }) });
7207
7965
  }
7208
7966
  function InterimButtonsView({
7209
7967
  onButtonClick,
7210
- onCardButtonClick,
7211
- cardLoading = false,
7212
- cardOpen,
7213
- errorMessage,
7214
7968
  showPayPal,
7215
7969
  showStripe = true,
7216
7970
  showApplePay,
@@ -7223,12 +7977,6 @@ function InterimButtonsView({
7223
7977
  cardTitleContent
7224
7978
  }) {
7225
7979
  const [showCardForm, setShowCardForm] = useState4(false);
7226
- const isCardOpenControlled = typeof cardOpen === "boolean";
7227
- useEffect6(() => {
7228
- if (isCardOpenControlled) {
7229
- setShowCardForm(cardOpen);
7230
- }
7231
- }, [cardOpen, isCardOpenControlled]);
7232
7980
  const themeBundle = useMemo4(() => resolveTheme2(theme), [theme]);
7233
7981
  const bStyles = useMemo4(() => {
7234
7982
  const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme2(buttonsTheme);
@@ -7245,7 +7993,7 @@ function InterimButtonsView({
7245
7993
  };
7246
7994
  }, [themeBundle, buttonsTheme, stylesOverride]);
7247
7995
  const skeletonRadius = themeBundle?.buttonsLayout?.cardButton?.borderRadius ?? themeBundle?.appearance.variables?.borderRadius ?? 8;
7248
- const skeleton = (h) => /* @__PURE__ */ jsx8("div", { style: {
7996
+ const skeleton = (h) => /* @__PURE__ */ jsx9("div", { style: {
7249
7997
  height: h,
7250
7998
  borderRadius: skeletonRadius,
7251
7999
  background: "#e5e7eb",
@@ -7257,25 +8005,20 @@ function InterimButtonsView({
7257
8005
  const inputBg = bStyles.cardInputBackground ?? "white";
7258
8006
  const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);
7259
8007
  const hideTitle = isEmptySlotContent(cardTitleContent);
7260
- return /* @__PURE__ */ jsxs5("div", { style: {
8008
+ return /* @__PURE__ */ jsxs6("div", { style: {
7261
8009
  backgroundColor: bStyles.cardFormContainer?.backgroundColor ?? "white",
7262
8010
  borderRadius: "8px",
7263
8011
  animation: "flopay-interim-expand 0.35s cubic-bezier(0.4, 0, 0.2, 1) both",
7264
8012
  overflow: "hidden",
7265
8013
  ...bStyles.cardFormContainer
7266
8014
  }, children: [
7267
- /* @__PURE__ */ jsxs5("div", { style: { display: "flex", alignItems: "center", padding: "0.75rem 0 0.625rem" }, children: [
7268
- /* @__PURE__ */ jsxs5(
8015
+ /* @__PURE__ */ jsxs6("div", { style: { display: "flex", alignItems: "center", padding: "0.75rem 0 0.625rem" }, children: [
8016
+ /* @__PURE__ */ jsxs6(
7269
8017
  "button",
7270
8018
  {
7271
8019
  type: "button",
7272
- onClick: () => {
7273
- if (!isCardOpenControlled) {
7274
- setShowCardForm(false);
7275
- }
7276
- },
8020
+ onClick: () => setShowCardForm(false),
7277
8021
  "aria-label": "Back to payment methods",
7278
- disabled: isCardOpenControlled || cardLoading,
7279
8022
  style: {
7280
8023
  display: "inline-flex",
7281
8024
  alignItems: "center",
@@ -7287,12 +8030,12 @@ function InterimButtonsView({
7287
8030
  fontWeight: 500,
7288
8031
  padding: 0,
7289
8032
  flexShrink: 0,
7290
- opacity: isCardOpenControlled || cardLoading ? 0.6 : 1,
7291
- cursor: isCardOpenControlled || cardLoading ? "not-allowed" : "pointer",
8033
+ opacity: 1,
8034
+ cursor: "pointer",
7292
8035
  ...bStyles.backButton
7293
8036
  },
7294
8037
  children: [
7295
- /* @__PURE__ */ jsx8("span", { style: {
8038
+ /* @__PURE__ */ jsx9("span", { style: {
7296
8039
  display: "inline-flex",
7297
8040
  alignItems: "center",
7298
8041
  justifyContent: "center",
@@ -7301,12 +8044,12 @@ function InterimButtonsView({
7301
8044
  borderRadius: "50%",
7302
8045
  backgroundColor: "#f3f4f6",
7303
8046
  ...bStyles.backButtonIcon
7304
- }, children: /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "M15 18l-6-6 6-6" }) }) }),
7305
- /* @__PURE__ */ jsx8(BackButtonContentSlot, { content: cardBackButtonContent })
8047
+ }, children: /* @__PURE__ */ jsx9("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx9("path", { d: "M15 18l-6-6 6-6" }) }) }),
8048
+ /* @__PURE__ */ jsx9(BackButtonContentSlot, { content: cardBackButtonContent })
7306
8049
  ]
7307
8050
  }
7308
8051
  ),
7309
- hideTitle ? /* @__PURE__ */ jsx8("div", { style: { flex: 1 } }) : /* @__PURE__ */ jsx8("div", { style: {
8052
+ hideTitle ? /* @__PURE__ */ jsx9("div", { style: { flex: 1 } }) : /* @__PURE__ */ jsx9("div", { style: {
7310
8053
  flex: 1,
7311
8054
  textAlign: "center",
7312
8055
  fontWeight: 600,
@@ -7314,11 +8057,11 @@ function InterimButtonsView({
7314
8057
  color: "#262833",
7315
8058
  paddingRight: 80,
7316
8059
  ...bStyles.title
7317
- }, children: /* @__PURE__ */ jsx8(TitleContentSlot, { content: cardTitleContent }) })
8060
+ }, children: /* @__PURE__ */ jsx9(TitleContentSlot, { content: cardTitleContent }) })
7318
8061
  ] }),
7319
- /* @__PURE__ */ jsx8("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx8("div", { style: { width: "60%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
7320
- /* @__PURE__ */ jsxs5("div", { style: { display: "flex" }, children: [
7321
- /* @__PURE__ */ jsx8("div", { style: {
8062
+ /* @__PURE__ */ jsx9("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderTopLeftRadius: 8, borderTopRightRadius: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx9("div", { style: { width: "60%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
8063
+ /* @__PURE__ */ jsxs6("div", { style: { display: "flex" }, children: [
8064
+ /* @__PURE__ */ jsx9("div", { style: {
7322
8065
  flex: 1,
7323
8066
  backgroundColor: inputBg,
7324
8067
  borderTop: "none",
@@ -7328,8 +8071,8 @@ function InterimButtonsView({
7328
8071
  borderBottomLeftRadius: 8,
7329
8072
  padding: 12,
7330
8073
  height: 45
7331
- }, children: /* @__PURE__ */ jsx8("div", { style: { width: "50%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
7332
- /* @__PURE__ */ jsx8("div", { style: {
8074
+ }, children: /* @__PURE__ */ jsx9("div", { style: { width: "50%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
8075
+ /* @__PURE__ */ jsx9("div", { style: {
7333
8076
  flex: 1,
7334
8077
  backgroundColor: inputBg,
7335
8078
  borderTop: "none",
@@ -7339,10 +8082,10 @@ function InterimButtonsView({
7339
8082
  borderBottomRightRadius: 8,
7340
8083
  padding: 12,
7341
8084
  height: 45
7342
- }, children: /* @__PURE__ */ jsx8("div", { style: { width: "40%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) })
8085
+ }, children: /* @__PURE__ */ jsx9("div", { style: { width: "40%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) })
7343
8086
  ] }),
7344
- /* @__PURE__ */ jsx8("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx8("div", { style: { width: "45%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
7345
- /* @__PURE__ */ jsx8("div", { style: {
8087
+ /* @__PURE__ */ jsx9("div", { style: { backgroundColor: inputBg, border: `1px solid ${inputBorder}`, borderRadius: 8, marginTop: 8, padding: 12, height: 45 }, children: /* @__PURE__ */ jsx9("div", { style: { width: "45%", height: 14, borderRadius: 4, background: "#e5e7eb", animation: "flopay-interim-pulse 1.5s ease-in-out infinite" } }) }),
8088
+ /* @__PURE__ */ jsx9("div", { style: {
7346
8089
  height: 50,
7347
8090
  borderRadius: 8,
7348
8091
  marginTop: 16,
@@ -7351,7 +8094,7 @@ function InterimButtonsView({
7351
8094
  ...bStyles.submitButton,
7352
8095
  opacity: 0.5
7353
8096
  } }),
7354
- /* @__PURE__ */ jsx8("style", { children: `
8097
+ /* @__PURE__ */ jsx9("style", { children: `
7355
8098
  @keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
7356
8099
  @keyframes flopay-interim-expand {
7357
8100
  0% { opacity: 0; max-height: 0; transform: translateY(-12px); }
@@ -7361,23 +8104,17 @@ function InterimButtonsView({
7361
8104
  ` })
7362
8105
  ] });
7363
8106
  }
7364
- return /* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
8107
+ return /* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
7365
8108
  showPayPal && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
7366
8109
  showStripe && (showApplePay || showGooglePay) && skeleton(DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2),
7367
- showStripe && /* @__PURE__ */ jsx8(
8110
+ showStripe && /* @__PURE__ */ jsx9(
7368
8111
  "button",
7369
8112
  {
7370
8113
  type: "button",
7371
- onClick: async () => {
7372
- if (cardLoading) return;
7373
- if (onCardButtonClick) {
7374
- await onCardButtonClick();
7375
- return;
7376
- }
8114
+ onClick: () => {
7377
8115
  onButtonClick?.("card");
7378
8116
  setShowCardForm(true);
7379
8117
  },
7380
- disabled: cardLoading,
7381
8118
  style: {
7382
8119
  width: "100%",
7383
8120
  ...cardButtonSizing,
@@ -7387,7 +8124,7 @@ function InterimButtonsView({
7387
8124
  borderRadius: "8px",
7388
8125
  fontSize: bStyles.cardButtonFontSize ?? "0.95rem",
7389
8126
  fontWeight: 600,
7390
- cursor: cardLoading ? "not-allowed" : "pointer",
8127
+ cursor: "pointer",
7391
8128
  display: "flex",
7392
8129
  alignItems: "center",
7393
8130
  justifyContent: "center",
@@ -7395,7 +8132,7 @@ function InterimButtonsView({
7395
8132
  boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
7396
8133
  transition: "transform 0.1s",
7397
8134
  position: "relative",
7398
- opacity: cardLoading ? 0.6 : 1,
8135
+ opacity: 1,
7399
8136
  ...bStyles.cardButton
7400
8137
  },
7401
8138
  onMouseDown: (e) => {
@@ -7404,39 +8141,22 @@ function InterimButtonsView({
7404
8141
  onMouseUp: (e) => {
7405
8142
  e.currentTarget.style.transform = "scale(1)";
7406
8143
  },
7407
- children: /* @__PURE__ */ jsx8(CardButtonContentSlot, { content: cardButtonContent })
8144
+ children: /* @__PURE__ */ jsx9(CardButtonContentSlot, { content: cardButtonContent })
7408
8145
  }
7409
8146
  ),
7410
- errorMessage && /* @__PURE__ */ jsxs5("div", { style: {
7411
- margin: "0.25rem 0",
7412
- padding: "0.625rem 0.875rem",
7413
- background: "#FEF2F2",
7414
- border: "1px solid #FECACA",
7415
- borderRadius: "8px",
7416
- color: "#991B1B",
7417
- fontSize: "0.85rem",
7418
- fontWeight: 600,
7419
- display: "flex",
7420
- alignItems: "center",
7421
- gap: "0.5rem",
7422
- ...bStyles.errorBanner
7423
- }, children: [
7424
- /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx8("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
7425
- errorMessage
7426
- ] }),
7427
- /* @__PURE__ */ jsx8("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
8147
+ /* @__PURE__ */ jsx9("style", { children: `@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }` })
7428
8148
  ] });
7429
8149
  }
7430
8150
 
7431
8151
  // src/checkout-form.tsx
7432
8152
  import { PaymentAPI as PaymentAPI5 } from "@flopay/js";
7433
8153
  import { FloPayError as FloPayError6 } from "@flopay/shared";
7434
- import { forwardRef as forwardRef2, useCallback as useCallback4, useEffect as useEffect7, useImperativeHandle as useImperativeHandle2, useState as useState5 } from "react";
7435
- import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
8154
+ import { forwardRef as forwardRef2, useCallback as useCallback5, useEffect as useEffect7, useImperativeHandle as useImperativeHandle2, useState as useState5 } from "react";
8155
+ import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
7436
8156
  var WALLET_RESUME_KEY = "flopay_wallet_resume";
7437
8157
  var CheckoutForm = forwardRef2(
7438
8158
  function CheckoutForm2(props, ref) {
7439
- return /* @__PURE__ */ jsx9(CheckoutFormInner, { ...props, innerRef: ref });
8159
+ return /* @__PURE__ */ jsx10(CheckoutFormInner, { ...props, innerRef: ref });
7440
8160
  }
7441
8161
  );
7442
8162
  function CheckoutFormInner({
@@ -7473,20 +8193,20 @@ function CheckoutFormInner({
7473
8193
  const isSubmitting = externalProcessing ?? processing;
7474
8194
  const isSelfContained = !onTokenizedBody;
7475
8195
  const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
7476
- const updateError = useCallback4(
8196
+ const updateError = useCallback5(
7477
8197
  (err) => {
7478
8198
  setError(err);
7479
8199
  onErrorChange?.(err);
7480
8200
  },
7481
8201
  [onErrorChange]
7482
8202
  );
7483
- const emitDecline = useCallback4(
8203
+ const emitDecline = useCallback5(
7484
8204
  (input, overrides) => {
7485
8205
  onDecline?.(buildDeclineEvent("card", input, overrides));
7486
8206
  },
7487
8207
  [onDecline]
7488
8208
  );
7489
- const processPaymentInternal = useCallback4(
8209
+ const processPaymentInternal = useCallback5(
7490
8210
  async (tokenizedBody, completionPaymentMethodId) => {
7491
8211
  setProcessing(true);
7492
8212
  updateError(null);
@@ -7598,7 +8318,7 @@ function CheckoutFormInner({
7598
8318
  },
7599
8319
  [baseUrl, sessionId, nonce, userId, email, firstName, lastName, chv, flopay, paypalFlopay, onComplete, onError, onDecline, updateError, emitDecline]
7600
8320
  );
7601
- const dispatchTokenizedBody = useCallback4(
8321
+ const dispatchTokenizedBody = useCallback5(
7602
8322
  (tokenizedBody) => {
7603
8323
  if (onTokenizedBody) {
7604
8324
  onTokenizedBody(tokenizedBody);
@@ -7653,7 +8373,7 @@ function CheckoutFormInner({
7653
8373
  localStorage.removeItem(WALLET_RESUME_KEY);
7654
8374
  }
7655
8375
  }, [sessionId, dispatchTokenizedBody]);
7656
- const handleSubmit = useCallback4(
8376
+ const handleSubmit = useCallback5(
7657
8377
  async (e) => {
7658
8378
  e.preventDefault();
7659
8379
  if (!flopay || !elements || isSubmitting) return;
@@ -7679,8 +8399,7 @@ function CheckoutFormInner({
7679
8399
  if (!sessionId || !email) {
7680
8400
  throw new FloPayError6("Missing sessionId or email", "validation_error");
7681
8401
  }
7682
- const intentHeaders = { "Content-Type": "application/json" };
7683
- if (nonce) intentHeaders["x-checkout-session-token"] = nonce;
8402
+ const intentHeaders = intentRequestHeaders(nonce);
7684
8403
  const intentResponse = await fetch(`${baseUrl}/v1/checkouts/payments/intents`, {
7685
8404
  method: "POST",
7686
8405
  headers: intentHeaders,
@@ -7745,8 +8464,8 @@ function CheckoutFormInner({
7745
8464
  [flopay, elements, isSubmitting, sessionId, nonce, email, firstName, lastName, baseUrl, isSelfContained, dispatchTokenizedBody, onError, updateError, emitDecline]
7746
8465
  );
7747
8466
  const isReady = flopay !== null && elements !== null;
7748
- return /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
7749
- (is3DSActive || isSubmitting) && /* @__PURE__ */ jsx9("div", { "data-testid": "flopay-overlay", style: {
8467
+ return /* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
8468
+ (is3DSActive || isSubmitting) && /* @__PURE__ */ jsx10("div", { "data-testid": "flopay-overlay", style: {
7750
8469
  position: "absolute",
7751
8470
  inset: 0,
7752
8471
  background: "rgba(255,255,255,0.7)",
@@ -7755,12 +8474,12 @@ function CheckoutFormInner({
7755
8474
  justifyContent: "center",
7756
8475
  zIndex: 10
7757
8476
  }, children: is3DSActive ? "Verifying payment..." : "Processing..." }),
7758
- !isReady && /* @__PURE__ */ jsx9("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." }),
7759
- isReady && /* @__PURE__ */ jsxs6(Fragment4, { children: [
7760
- /* @__PURE__ */ jsx9(PaymentElement, { options: { layout } }),
7761
- showAddress && /* @__PURE__ */ jsx9(AddressElement, { options: { mode: showAddress === true ? "billing" : showAddress } }),
7762
- displayError && /* @__PURE__ */ jsx9("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0" }, children: displayError }),
7763
- children ?? /* @__PURE__ */ jsx9(
8477
+ !isReady && /* @__PURE__ */ jsx10("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." }),
8478
+ isReady && /* @__PURE__ */ jsxs7(Fragment4, { children: [
8479
+ /* @__PURE__ */ jsx10(PaymentElement, { options: { layout } }),
8480
+ showAddress && /* @__PURE__ */ jsx10(AddressElement, { options: { mode: showAddress === true ? "billing" : showAddress } }),
8481
+ displayError && /* @__PURE__ */ jsx10("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0" }, children: displayError }),
8482
+ children ?? /* @__PURE__ */ jsx10(
7764
8483
  "button",
7765
8484
  {
7766
8485
  type: "submit",
@@ -7776,8 +8495,8 @@ function CheckoutFormInner({
7776
8495
  // src/paypal-button.tsx
7777
8496
  import { PaymentAPI as PaymentAPI6 } from "@flopay/js";
7778
8497
  import { FloPayError as FloPayError7 } from "@flopay/shared";
7779
- import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef6, useState as useState6 } from "react";
7780
- import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
8498
+ import { useCallback as useCallback6, useEffect as useEffect8, useRef as useRef7, useState as useState6 } from "react";
8499
+ import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
7781
8500
  function PayPalButton({
7782
8501
  sessionId,
7783
8502
  nonce,
@@ -7797,9 +8516,9 @@ function PayPalButton({
7797
8516
  const contextBillingUrl = useBillingApiUrl();
7798
8517
  const [ready, setReady] = useState6(false);
7799
8518
  const [submitting, setSubmitting] = useState6(false);
7800
- const paypalResumeAttempted = useRef6(false);
8519
+ const paypalResumeAttempted = useRef7(false);
7801
8520
  const baseUrl = (billingApiUrl || contextBillingUrl).replace(/\/+$/, "");
7802
- const processPaymentInternal = useCallback5(
8521
+ const processPaymentInternal = useCallback6(
7803
8522
  async (tokenizedBody) => {
7804
8523
  try {
7805
8524
  const api = new PaymentAPI6(baseUrl);
@@ -7827,7 +8546,7 @@ function PayPalButton({
7827
8546
  },
7828
8547
  [baseUrl, sessionId, nonce, userId, email, firstName, lastName, chv, onComplete, onErrorChange]
7829
8548
  );
7830
- const dispatchTokenizedBody = useCallback5(
8549
+ const dispatchTokenizedBody = useCallback6(
7831
8550
  (body) => {
7832
8551
  if (onTokenizedBody) {
7833
8552
  onTokenizedBody(body);
@@ -7885,7 +8604,7 @@ function PayPalButton({
7885
8604
  }
7886
8605
  })();
7887
8606
  }, [flopay, dispatchTokenizedBody, onErrorChange]);
7888
- const handlePayPalConfirm = useCallback5(async () => {
8607
+ const handlePayPalConfirm = useCallback6(async () => {
7889
8608
  if (!flopay || !elements) return;
7890
8609
  try {
7891
8610
  setSubmitting(true);
@@ -7919,11 +8638,11 @@ function PayPalButton({
7919
8638
  }
7920
8639
  }, [flopay, elements, sessionId, nonce, email, baseUrl, dispatchTokenizedBody, onErrorChange]);
7921
8640
  if (!flopay || !elements) {
7922
- return /* @__PURE__ */ jsx10("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6, animation: "pulse 1.5s infinite" } });
8641
+ return /* @__PURE__ */ jsx11("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6, animation: "pulse 1.5s infinite" } });
7923
8642
  }
7924
- return /* @__PURE__ */ jsxs7(Fragment5, { children: [
7925
- !ready && /* @__PURE__ */ jsx10("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6 } }),
7926
- /* @__PURE__ */ jsx10("div", { style: ready ? {} : { display: "none" }, children: /* @__PURE__ */ jsx10(
8643
+ return /* @__PURE__ */ jsxs8(Fragment5, { children: [
8644
+ !ready && /* @__PURE__ */ jsx11("div", { style: { height: 45, background: "#f0f0f0", borderRadius: 6 } }),
8645
+ /* @__PURE__ */ jsx11("div", { style: ready ? {} : { display: "none" }, children: /* @__PURE__ */ jsx11(
7927
8646
  "button",
7928
8647
  {
7929
8648
  type: "button",
@@ -7945,7 +8664,7 @@ function PayPalButton({
7945
8664
  children: submitting ? "Processing..." : "PayPal"
7946
8665
  }
7947
8666
  ) }),
7948
- (submitting || isProcessing) && /* @__PURE__ */ jsx10("div", { style: {
8667
+ (submitting || isProcessing) && /* @__PURE__ */ jsx11("div", { style: {
7949
8668
  position: "fixed",
7950
8669
  inset: 0,
7951
8670
  background: "rgba(0,0,0,0.4)",
@@ -7953,7 +8672,7 @@ function PayPalButton({
7953
8672
  alignItems: "center",
7954
8673
  justifyContent: "center",
7955
8674
  zIndex: 1e3
7956
- }, children: /* @__PURE__ */ jsx10("div", { style: {
8675
+ }, children: /* @__PURE__ */ jsx11("div", { style: {
7957
8676
  background: "white",
7958
8677
  borderRadius: 8,
7959
8678
  padding: "1.5rem",
@@ -7965,10 +8684,10 @@ function PayPalButton({
7965
8684
  }
7966
8685
 
7967
8686
  // src/automatic-payment-button.tsx
7968
- import { useCallback as useCallback6, useEffect as useEffect9, useMemo as useMemo5, useRef as useRef7, useState as useState7 } from "react";
8687
+ import { useCallback as useCallback7, useEffect as useEffect9, useMemo as useMemo5, useRef as useRef8, useState as useState7 } from "react";
7969
8688
  import { PaymentAPI as PaymentAPI7 } from "@flopay/js";
7970
8689
  import { FloPayError as FloPayError8, resolveBillingApiUrl as resolveBillingApiUrl4, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme3, resolveTheme as resolveTheme3 } from "@flopay/shared";
7971
- import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
8690
+ import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
7972
8691
  var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3 = 44;
7973
8692
  function sleep2(ms) {
7974
8693
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -8084,12 +8803,12 @@ function FloPayAutomaticPaymentButton({
8084
8803
  const [overlayStatus, setOverlayStatus] = useState7(null);
8085
8804
  const [overlayError, setOverlayError] = useState7(null);
8086
8805
  const [fallbackSession, setFallbackSession] = useState7(null);
8087
- const isMountedRef = useRef7(true);
8088
- const threeDsAbortRef = useRef7(null);
8089
- const fallbackSessionRef = useRef7(fallbackSession);
8090
- const onSuccessRef = useRef7(onSuccess);
8091
- const onErrorRef = useRef7(onError);
8092
- const onDeclineRef = useRef7(onDecline);
8806
+ const isMountedRef = useRef8(true);
8807
+ const threeDsAbortRef = useRef8(null);
8808
+ const fallbackSessionRef = useRef8(fallbackSession);
8809
+ const onSuccessRef = useRef8(onSuccess);
8810
+ const onErrorRef = useRef8(onError);
8811
+ const onDeclineRef = useRef8(onDecline);
8093
8812
  useEffect9(() => {
8094
8813
  fallbackSessionRef.current = fallbackSession;
8095
8814
  }, [fallbackSession]);
@@ -8110,7 +8829,7 @@ function FloPayAutomaticPaymentButton({
8110
8829
  };
8111
8830
  }, []);
8112
8831
  useEffect9(() => {
8113
- if (!fallbackSession || typeof window === "undefined") {
8832
+ if (typeof window === "undefined") {
8114
8833
  return;
8115
8834
  }
8116
8835
  const handleKeyDown = (event) => {
@@ -8122,14 +8841,14 @@ function FloPayAutomaticPaymentButton({
8122
8841
  return () => {
8123
8842
  window.removeEventListener("keydown", handleKeyDown);
8124
8843
  };
8125
- }, [fallbackSession]);
8126
- const emitDecline = useCallback6((error, method = DEFAULT_SAVED_PAYMENT_DECLINE_METHOD) => {
8844
+ }, []);
8845
+ const emitDecline = useCallback7((error, method = DEFAULT_SAVED_PAYMENT_DECLINE_METHOD) => {
8127
8846
  onDeclineRef.current?.(buildDeclineEvent(method, error, {
8128
8847
  code: error.code,
8129
8848
  declineCode: error.declineCode
8130
8849
  }));
8131
8850
  }, []);
8132
- const showSuccess = useCallback6(async (event) => {
8851
+ const showSuccess = useCallback7(async (event) => {
8133
8852
  if (!isMountedRef.current) return;
8134
8853
  setOverlayError(null);
8135
8854
  setOverlayStatus("success");
@@ -8137,7 +8856,7 @@ function FloPayAutomaticPaymentButton({
8137
8856
  if (!isMountedRef.current) return;
8138
8857
  onSuccessRef.current?.(event);
8139
8858
  }, []);
8140
- const showError = useCallback6(async (error, options) => {
8859
+ const showError = useCallback7(async (error, options) => {
8141
8860
  if (!isMountedRef.current) return;
8142
8861
  onErrorRef.current?.(error);
8143
8862
  if (options?.emitDecline) {
@@ -8147,7 +8866,7 @@ function FloPayAutomaticPaymentButton({
8147
8866
  setOverlayStatus("error");
8148
8867
  await sleep2(PROCESSING_OVERLAY_ERROR_DELAY_MS);
8149
8868
  }, [emitDecline]);
8150
- const processResolvedSession = useCallback6(async (apiResult, resolvedSessionId, options) => {
8869
+ const processResolvedSession = useCallback7(async (apiResult, resolvedSessionId, options) => {
8151
8870
  const session = apiResult.data.session ?? null;
8152
8871
  if (!session) {
8153
8872
  throw new FloPayError8("No session data returned", "api_error");
@@ -8303,7 +9022,7 @@ function FloPayAutomaticPaymentButton({
8303
9022
  showError,
8304
9023
  showSuccess
8305
9024
  ]);
8306
- const handleButtonClick = useCallback6(async (event) => {
9025
+ const handleButtonClick = useCallback7(async (event) => {
8307
9026
  buttonProps.onClick?.(event);
8308
9027
  if (event.defaultPrevented || disabled || isProcessing) {
8309
9028
  return;
@@ -8385,7 +9104,7 @@ function FloPayAutomaticPaymentButton({
8385
9104
  showError,
8386
9105
  showSuccess
8387
9106
  ]);
8388
- const handleFallbackComplete = useCallback6((result) => {
9107
+ const handleFallbackComplete = useCallback7((result) => {
8389
9108
  const activeFallback = fallbackSessionRef.current;
8390
9109
  setFallbackSession(null);
8391
9110
  onSuccessRef.current?.({
@@ -8395,10 +9114,10 @@ function FloPayAutomaticPaymentButton({
8395
9114
  autoCompleted: false
8396
9115
  });
8397
9116
  }, []);
8398
- const handleFallbackError = useCallback6((error) => {
9117
+ const handleFallbackError = useCallback7((error) => {
8399
9118
  onErrorRef.current?.(error);
8400
9119
  }, []);
8401
- const handleFallbackDecline = useCallback6((decline) => {
9120
+ const handleFallbackDecline = useCallback7((decline) => {
8402
9121
  onDeclineRef.current?.(decline);
8403
9122
  }, []);
8404
9123
  const themeBundle = useMemo5(() => resolveTheme3(theme), [theme]);
@@ -8429,8 +9148,8 @@ function FloPayAutomaticPaymentButton({
8429
9148
  const resolvedPrimaryHoverColor = resolvedAppearanceVars?.colorPrimaryHover ?? darkenHex(resolvedPrimaryColor, 0.12);
8430
9149
  const resolvedButtonBorderRadius = resolvedAppearanceVars?.borderRadius ?? "8px";
8431
9150
  const cardButtonSizing = children === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
8432
- return /* @__PURE__ */ jsxs8(Fragment6, { children: [
8433
- /* @__PURE__ */ jsx11(
9151
+ return /* @__PURE__ */ jsxs9(Fragment6, { children: [
9152
+ /* @__PURE__ */ jsx12(
8434
9153
  "button",
8435
9154
  {
8436
9155
  ...buttonProps,
@@ -8494,17 +9213,17 @@ function FloPayAutomaticPaymentButton({
8494
9213
  e.currentTarget.style.transform = "scale(1)";
8495
9214
  }
8496
9215
  },
8497
- children: /* @__PURE__ */ jsx11(CardButtonContentSlot, { content: children })
9216
+ children: /* @__PURE__ */ jsx12(CardButtonContentSlot, { content: children })
8498
9217
  }
8499
9218
  ),
8500
- overlayStatus && /* @__PURE__ */ jsx11(
9219
+ overlayStatus && /* @__PURE__ */ jsx12(
8501
9220
  ProcessingOverlay,
8502
9221
  {
8503
9222
  status: overlayStatus,
8504
9223
  errorMessage: overlayError
8505
9224
  }
8506
9225
  ),
8507
- fallbackSession && /* @__PURE__ */ jsx11(
9226
+ fallbackSession && /* @__PURE__ */ jsx12(
8508
9227
  "div",
8509
9228
  {
8510
9229
  "data-testid": "flopay-automatic-payment-fallback",
@@ -8525,7 +9244,7 @@ function FloPayAutomaticPaymentButton({
8525
9244
  padding: "1.5rem",
8526
9245
  zIndex: 1100
8527
9246
  },
8528
- children: /* @__PURE__ */ jsx11(
9247
+ children: /* @__PURE__ */ jsx12(
8529
9248
  "div",
8530
9249
  {
8531
9250
  style: {
@@ -8541,7 +9260,7 @@ function FloPayAutomaticPaymentButton({
8541
9260
  flexDirection: "column",
8542
9261
  gap: "1rem"
8543
9262
  },
8544
- children: /* @__PURE__ */ jsx11(
9263
+ children: /* @__PURE__ */ jsx12(
8545
9264
  FloPayCheckout,
8546
9265
  {
8547
9266
  sessionId: fallbackSession.sessionId,