@flopay/react 1.1.4 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -11
- package/dist/index.cjs +86 -485
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -13
- package/dist/index.d.ts +75 -13
- package/dist/index.mjs +89 -488
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -102,7 +102,7 @@ function FloPayProvider({
|
|
|
102
102
|
// src/flopay-checkout.tsx
|
|
103
103
|
import React7, { useCallback as useCallback2, useEffect as useEffect5, useMemo as useMemo4, useRef as useRef4, useState as useState4 } from "react";
|
|
104
104
|
import { PaymentAPI as PaymentAPI4 } from "@flopay/js";
|
|
105
|
-
import { SDK_VERSION, FloPayError as FloPayError5, resolveBillingApiUrl as resolveBillingApiUrl3, buildCheckoutDisplayData, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme2 } from "@flopay/shared";
|
|
105
|
+
import { SDK_VERSION, FloPayError as FloPayError5, resolveBillingApiUrl as resolveBillingApiUrl3, buildCheckoutDisplayData, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme2, resolveTheme as resolveTheme2 } from "@flopay/shared";
|
|
106
106
|
|
|
107
107
|
// src/card-button-content.tsx
|
|
108
108
|
import "react";
|
|
@@ -1221,7 +1221,7 @@ ${debugLines.join("\n")}`
|
|
|
1221
1221
|
}
|
|
1222
1222
|
|
|
1223
1223
|
// src/split-card-form.tsx
|
|
1224
|
-
import { FloPayError as FloPayError3 } from "@flopay/shared";
|
|
1224
|
+
import { FloPayError as FloPayError3, resolveTheme } from "@flopay/shared";
|
|
1225
1225
|
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1226
1226
|
var WALLET_RESUME_KEY = "flopay_wallet_resume";
|
|
1227
1227
|
var FLOPAY_KEYFRAMES = `
|
|
@@ -1721,12 +1721,14 @@ function SplitCardFormInner({
|
|
|
1721
1721
|
showApplePay = true,
|
|
1722
1722
|
showGooglePay = true,
|
|
1723
1723
|
layout = "default",
|
|
1724
|
+
theme,
|
|
1724
1725
|
buttonsTheme,
|
|
1725
1726
|
buttonsStyles: buttonsStylesOverride,
|
|
1727
|
+
appearance: appearanceOverride,
|
|
1726
1728
|
cardButtonContent,
|
|
1727
1729
|
cardBackButtonContent,
|
|
1728
1730
|
cardTitleContent,
|
|
1729
|
-
showSecurityFooter
|
|
1731
|
+
showSecurityFooter: _showSecurityFooter,
|
|
1730
1732
|
onButtonClick,
|
|
1731
1733
|
onBeforeButtonClick,
|
|
1732
1734
|
enableAVS: enableAVSProp,
|
|
@@ -1801,8 +1803,9 @@ function SplitCardFormInner({
|
|
|
1801
1803
|
}, [paypalDirectRetry]);
|
|
1802
1804
|
const resolvedBillingApiUrl = billingApiUrl || contextBillingUrl;
|
|
1803
1805
|
const displayError = externalError ?? error;
|
|
1806
|
+
const themeBundle = useMemo3(() => resolveTheme(theme), [theme]);
|
|
1804
1807
|
const bStyles = useMemo3(() => {
|
|
1805
|
-
const base = resolveButtonsLayoutTheme(buttonsTheme);
|
|
1808
|
+
const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme(buttonsTheme);
|
|
1806
1809
|
if (!buttonsStylesOverride) return base;
|
|
1807
1810
|
return {
|
|
1808
1811
|
...base,
|
|
@@ -1814,7 +1817,8 @@ function SplitCardFormInner({
|
|
|
1814
1817
|
submitButton: { ...base.submitButton, ...buttonsStylesOverride.submitButton },
|
|
1815
1818
|
title: { ...base.title, ...buttonsStylesOverride.title }
|
|
1816
1819
|
};
|
|
1817
|
-
}, [buttonsTheme, buttonsStylesOverride]);
|
|
1820
|
+
}, [themeBundle, buttonsTheme, buttonsStylesOverride]);
|
|
1821
|
+
const appearance = appearanceOverride ?? themeBundle?.appearance;
|
|
1818
1822
|
const isInlineSessionPatchProcessing = checkout.inlineSessionPatchProcessing ?? false;
|
|
1819
1823
|
const isSubmitting = (externalProcessing ?? processing) || isInlineSessionPatchProcessing;
|
|
1820
1824
|
const isSelfContained = !onTokenizedBody;
|
|
@@ -2342,17 +2346,24 @@ function SplitCardFormInner({
|
|
|
2342
2346
|
return /* @__PURE__ */ jsx6("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
|
|
2343
2347
|
}
|
|
2344
2348
|
const isButtons = layout === "buttons";
|
|
2345
|
-
const
|
|
2346
|
-
const
|
|
2347
|
-
const
|
|
2349
|
+
const appearanceVars = appearance?.variables;
|
|
2350
|
+
const SDK_DEFAULT_WHITES = /* @__PURE__ */ new Set(["#FFFFFF", "#ffffff", "#fff", "#FFF", "white"]);
|
|
2351
|
+
const appearanceColorBg = appearanceVars?.colorBackground;
|
|
2352
|
+
const themedWrapperBg = appearanceColorBg && !SDK_DEFAULT_WHITES.has(appearanceColorBg) ? appearanceColorBg : void 0;
|
|
2353
|
+
const resolvedBorder = bStyles.cardInputBorder ?? (isButtons ? "#e5e7eb" : "#A4A4FF");
|
|
2354
|
+
const cardBg = bStyles.cardFormContainer?.backgroundColor ?? themedWrapperBg ?? (isButtons ? "white" : "#EDEDFF");
|
|
2355
|
+
const cardInputBg = bStyles.cardInputBackground ?? appearanceVars?.colorBackground ?? "white";
|
|
2348
2356
|
const hideBackButtonLabel = isEmptySlotContent(cardBackButtonContent);
|
|
2349
2357
|
const hideTitle = isEmptySlotContent(cardTitleContent);
|
|
2350
|
-
const nameInputOverrides =
|
|
2351
|
-
const resolvedInputFontSize = bStyles.cardInputFontSize ?? toCssSize(nameInputOverrides?.fontSize) ?? "16px";
|
|
2352
|
-
const resolvedInputFontFamily = typeof nameInputOverrides?.fontFamily === "string" ? nameInputOverrides.fontFamily : "Poppins, sans-serif";
|
|
2358
|
+
const nameInputOverrides = bStyles.nameInput;
|
|
2359
|
+
const resolvedInputFontSize = bStyles.cardInputFontSize ?? toCssSize(nameInputOverrides?.fontSize) ?? appearanceVars?.fontSizeBase ?? "16px";
|
|
2360
|
+
const resolvedInputFontFamily = typeof nameInputOverrides?.fontFamily === "string" ? nameInputOverrides.fontFamily : appearanceVars?.fontFamily ?? "Poppins, sans-serif";
|
|
2353
2361
|
const resolvedInputFontWeight = toCssWeight(nameInputOverrides?.fontWeight) ?? 400;
|
|
2354
|
-
const resolvedInputColor = bStyles.cardInputColor ?? (typeof nameInputOverrides?.color === "string" ? nameInputOverrides.color : void 0) ?? "#262833";
|
|
2362
|
+
const resolvedInputColor = bStyles.cardInputColor ?? (typeof nameInputOverrides?.color === "string" ? nameInputOverrides.color : void 0) ?? appearanceVars?.colorText ?? "#262833";
|
|
2355
2363
|
const resolvedPlaceholderColor = bStyles.cardInputPlaceholderColor ?? "#9ca3af";
|
|
2364
|
+
const resolvedBorderRadius = appearanceVars?.borderRadius ?? "8px";
|
|
2365
|
+
const resolvedPrimaryColor = appearanceVars?.colorPrimary ?? "#4A49FF";
|
|
2366
|
+
const resolvedTitleColor = appearanceVars?.colorText ?? "#262833";
|
|
2356
2367
|
const sharedInputTypography = {
|
|
2357
2368
|
fontSize: resolvedInputFontSize,
|
|
2358
2369
|
fontFamily: resolvedInputFontFamily,
|
|
@@ -2382,12 +2393,14 @@ function SplitCardFormInner({
|
|
|
2382
2393
|
invalid: { color: "#ef4444" }
|
|
2383
2394
|
}
|
|
2384
2395
|
};
|
|
2396
|
+
const containerOverrides = bStyles.cardFormContainer ?? {};
|
|
2397
|
+
const containerPadding = containerOverrides.padding ?? (isButtons ? "0" : "1rem");
|
|
2398
|
+
const containerRadius = containerOverrides.borderRadius ?? resolvedBorderRadius;
|
|
2385
2399
|
const cardFormBlock = /* @__PURE__ */ jsxs4("div", { style: {
|
|
2386
2400
|
backgroundColor: cardBg,
|
|
2387
|
-
borderRadius:
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
...isButtons ? { padding: bStyles.cardFormContainer?.padding ?? "0" } : {},
|
|
2401
|
+
borderRadius: containerRadius,
|
|
2402
|
+
...containerOverrides,
|
|
2403
|
+
padding: containerPadding,
|
|
2391
2404
|
...sharedInputPlaceholderVars
|
|
2392
2405
|
}, children: [
|
|
2393
2406
|
/* @__PURE__ */ jsx6("style", { children: `
|
|
@@ -2451,7 +2464,14 @@ function SplitCardFormInner({
|
|
|
2451
2464
|
...bStyles.title
|
|
2452
2465
|
}, children: /* @__PURE__ */ jsx6(TitleContentSlot, { content: cardTitleContent }) })
|
|
2453
2466
|
] }),
|
|
2454
|
-
!isButtons && !hideTitle && /* @__PURE__ */ jsx6("div", { style: {
|
|
2467
|
+
!isButtons && !hideTitle && /* @__PURE__ */ jsx6("div", { style: {
|
|
2468
|
+
textAlign: "center",
|
|
2469
|
+
fontWeight: 600,
|
|
2470
|
+
fontSize: "1.1rem",
|
|
2471
|
+
padding: "0.5rem 0",
|
|
2472
|
+
color: resolvedTitleColor,
|
|
2473
|
+
...bStyles.title
|
|
2474
|
+
}, children: /* @__PURE__ */ jsx6(TitleContentSlot, { content: cardTitleContent }) }),
|
|
2455
2475
|
/* @__PURE__ */ jsx6("div", { style: {
|
|
2456
2476
|
backgroundColor: cardInputBg,
|
|
2457
2477
|
border: `1px solid ${resolvedBorder}`,
|
|
@@ -2708,7 +2728,7 @@ function SplitCardFormInner({
|
|
|
2708
2728
|
display: "flex",
|
|
2709
2729
|
alignItems: "center",
|
|
2710
2730
|
gap: "0.5rem",
|
|
2711
|
-
...
|
|
2731
|
+
...bStyles.errorBanner ? bStyles.errorBanner : {}
|
|
2712
2732
|
}, children: [
|
|
2713
2733
|
/* @__PURE__ */ jsx6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx6("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" }) }),
|
|
2714
2734
|
displayError
|
|
@@ -2723,29 +2743,19 @@ function SplitCardFormInner({
|
|
|
2723
2743
|
width: "100%",
|
|
2724
2744
|
padding: "0.875rem",
|
|
2725
2745
|
marginTop: "1rem",
|
|
2726
|
-
backgroundColor:
|
|
2746
|
+
backgroundColor: resolvedPrimaryColor,
|
|
2727
2747
|
color: "white",
|
|
2728
2748
|
border: "none",
|
|
2729
|
-
borderRadius:
|
|
2730
|
-
fontSize:
|
|
2749
|
+
borderRadius: resolvedBorderRadius,
|
|
2750
|
+
fontSize: bStyles.submitButtonFontSize ?? "1rem",
|
|
2731
2751
|
fontWeight: 600,
|
|
2732
2752
|
cursor: !formReady || isSubmitting ? "not-allowed" : "pointer",
|
|
2733
2753
|
opacity: !formReady || isSubmitting ? 0.5 : 1,
|
|
2734
|
-
...
|
|
2754
|
+
...bStyles.submitButton
|
|
2735
2755
|
},
|
|
2736
2756
|
children: isSubmitting ? "PROCESSING..." : submitLabel
|
|
2737
2757
|
}
|
|
2738
|
-
)
|
|
2739
|
-
!isButtons && showSecurityFooter && /* @__PURE__ */ jsx6("div", { style: {
|
|
2740
|
-
backgroundColor: "#EFF9F0",
|
|
2741
|
-
borderRadius: "8px",
|
|
2742
|
-
padding: "0.75rem",
|
|
2743
|
-
marginTop: "0.75rem",
|
|
2744
|
-
textAlign: "center",
|
|
2745
|
-
fontSize: "0.85rem",
|
|
2746
|
-
fontWeight: 600,
|
|
2747
|
-
color: "#7DAD3A"
|
|
2748
|
-
}, children: "Secure Card Checkout" })
|
|
2758
|
+
)
|
|
2749
2759
|
] });
|
|
2750
2760
|
if (layout === "buttons") {
|
|
2751
2761
|
const isButtonsView = viewState === "buttons" || viewState === "expanding";
|
|
@@ -3262,105 +3272,6 @@ async function processSavedPaymentForMode({
|
|
|
3262
3272
|
}
|
|
3263
3273
|
);
|
|
3264
3274
|
}
|
|
3265
|
-
async function processSavedPaymentWithIntent({
|
|
3266
|
-
billingApiUrl,
|
|
3267
|
-
sessionId,
|
|
3268
|
-
session,
|
|
3269
|
-
paymentMethodId,
|
|
3270
|
-
flopay,
|
|
3271
|
-
returnUrl
|
|
3272
|
-
}) {
|
|
3273
|
-
const customerEmail = session.customer?.email ?? session.accountData?.email ?? "";
|
|
3274
|
-
if (!customerEmail) {
|
|
3275
|
-
throw Object.assign(
|
|
3276
|
-
new FloPayError4("Customer email is required to create a payment intent.", "validation_error", {
|
|
3277
|
-
param: "email"
|
|
3278
|
-
}),
|
|
3279
|
-
{ checkoutMethod: "card" }
|
|
3280
|
-
);
|
|
3281
|
-
}
|
|
3282
|
-
const api = new PaymentAPI3(billingApiUrl);
|
|
3283
|
-
const intentResponse = await retryOnceOnFetchFailure(() => api.createPaymentIntent(
|
|
3284
|
-
sessionId,
|
|
3285
|
-
customerEmail,
|
|
3286
|
-
paymentMethodId
|
|
3287
|
-
));
|
|
3288
|
-
const intentJson = await intentResponse.json().catch(() => null);
|
|
3289
|
-
if (!intentResponse.ok) {
|
|
3290
|
-
const intentError = buildFloPayApiError(
|
|
3291
|
-
intentJson,
|
|
3292
|
-
"Failed to create payment intent."
|
|
3293
|
-
);
|
|
3294
|
-
throw Object.assign(
|
|
3295
|
-
intentError,
|
|
3296
|
-
{ checkoutMethod: "card" }
|
|
3297
|
-
);
|
|
3298
|
-
}
|
|
3299
|
-
const intentClientSecret = getRedirectTokenFromProcessResponse(intentJson, {
|
|
3300
|
-
requirePaymentIntentClientSecret: true
|
|
3301
|
-
});
|
|
3302
|
-
if (!intentClientSecret) {
|
|
3303
|
-
throw Object.assign(
|
|
3304
|
-
new FloPayError4("No client secret in payment intent response.", "api_error"),
|
|
3305
|
-
{ checkoutMethod: "card" }
|
|
3306
|
-
);
|
|
3307
|
-
}
|
|
3308
|
-
const confirmResult = await flopay.confirmCardPayment({
|
|
3309
|
-
clientSecret: intentClientSecret,
|
|
3310
|
-
paymentMethodId
|
|
3311
|
-
});
|
|
3312
|
-
if (confirmResult.error) {
|
|
3313
|
-
throw Object.assign(
|
|
3314
|
-
confirmResult.error,
|
|
3315
|
-
{ checkoutMethod: "card" }
|
|
3316
|
-
);
|
|
3317
|
-
}
|
|
3318
|
-
const rawProvider = typeof flopay.getRawProvider === "function" ? flopay.getRawProvider() : null;
|
|
3319
|
-
const confirmedPaymentIntent = await retrievePaymentIntentFromProvider(
|
|
3320
|
-
rawProvider,
|
|
3321
|
-
intentClientSecret
|
|
3322
|
-
);
|
|
3323
|
-
const confirmedPaymentIntentId = confirmResult.paymentIntentId ?? confirmedPaymentIntent?.id;
|
|
3324
|
-
const confirmedPaymentMethodId = confirmResult.paymentMethodId ?? resolvePaymentIntentPaymentMethodId(confirmedPaymentIntent) ?? paymentMethodId;
|
|
3325
|
-
if (!confirmedPaymentIntentId || confirmResult.status !== "succeeded" && confirmResult.status !== "processing" && confirmResult.status !== "requires_capture") {
|
|
3326
|
-
throw Object.assign(
|
|
3327
|
-
new FloPayError4(
|
|
3328
|
-
`Unfortunately, your payment could not be processed. Please try again using a different payment method or contact your bank for assistance. If the issue persists, feel free to reach out to us for support.`,
|
|
3329
|
-
"api_error",
|
|
3330
|
-
{
|
|
3331
|
-
code: confirmResult.status === "requires_action" ? "authentication_required" : void 0
|
|
3332
|
-
}
|
|
3333
|
-
),
|
|
3334
|
-
{ checkoutMethod: "card" }
|
|
3335
|
-
);
|
|
3336
|
-
}
|
|
3337
|
-
const followUp = await processSavedPaymentForMode({
|
|
3338
|
-
billingApiUrl,
|
|
3339
|
-
sessionId,
|
|
3340
|
-
session,
|
|
3341
|
-
tokenizedData: {
|
|
3342
|
-
id: confirmedPaymentMethodId,
|
|
3343
|
-
type: "card",
|
|
3344
|
-
threeDSecureActionResultTokenId: confirmedPaymentIntentId
|
|
3345
|
-
},
|
|
3346
|
-
returnUrl
|
|
3347
|
-
});
|
|
3348
|
-
const finalResult = followUp.type === "success" ? followUp.result : await handleSavedPaymentRedirectResult(followUp, {
|
|
3349
|
-
flopay,
|
|
3350
|
-
paypalFlopay: null,
|
|
3351
|
-
attempt3DS: true,
|
|
3352
|
-
billingApiUrl,
|
|
3353
|
-
sessionId,
|
|
3354
|
-
session,
|
|
3355
|
-
returnUrl
|
|
3356
|
-
});
|
|
3357
|
-
return {
|
|
3358
|
-
...finalResult,
|
|
3359
|
-
paymentIntentId: finalResult.paymentIntentId ?? confirmedPaymentIntentId,
|
|
3360
|
-
paymentMethodId: finalResult.paymentMethodId ?? confirmedPaymentMethodId,
|
|
3361
|
-
checkoutMethod: finalResult.checkoutMethod ?? "card"
|
|
3362
|
-
};
|
|
3363
|
-
}
|
|
3364
3275
|
async function handleSavedPaymentRedirectResult(redirectResult, {
|
|
3365
3276
|
flopay,
|
|
3366
3277
|
paypalFlopay,
|
|
@@ -3682,7 +3593,7 @@ function FloPayCheckout({
|
|
|
3682
3593
|
sessionId: sessionIdProp,
|
|
3683
3594
|
createSession: createSessionParams,
|
|
3684
3595
|
billingApiUrl,
|
|
3685
|
-
appearance,
|
|
3596
|
+
appearance: appearanceOverride,
|
|
3686
3597
|
locale,
|
|
3687
3598
|
loading: loadingNode,
|
|
3688
3599
|
error: errorNode,
|
|
@@ -3697,12 +3608,13 @@ function FloPayCheckout({
|
|
|
3697
3608
|
showGooglePay = true,
|
|
3698
3609
|
debug = false,
|
|
3699
3610
|
layout,
|
|
3611
|
+
theme,
|
|
3700
3612
|
buttonsTheme,
|
|
3701
3613
|
buttonsStyles,
|
|
3702
3614
|
cardButtonContent,
|
|
3703
3615
|
cardBackButtonContent,
|
|
3704
3616
|
cardTitleContent,
|
|
3705
|
-
showSecurityFooter
|
|
3617
|
+
showSecurityFooter: _showSecurityFooter,
|
|
3706
3618
|
onButtonClick,
|
|
3707
3619
|
onBeforeButtonClick,
|
|
3708
3620
|
enableAVS,
|
|
@@ -3717,6 +3629,8 @@ function FloPayCheckout({
|
|
|
3717
3629
|
onSessionCompleted
|
|
3718
3630
|
}) {
|
|
3719
3631
|
const resolvedBillingUrl = resolveBillingApiUrl3(billingApiUrl);
|
|
3632
|
+
const themeBundle = useMemo4(() => resolveTheme2(theme), [theme]);
|
|
3633
|
+
const appearance = appearanceOverride ?? themeBundle?.appearance;
|
|
3720
3634
|
const checkoutType = createSessionParams ? "embedded_checkout" : "standard_checkout";
|
|
3721
3635
|
const checkoutLayout = children ? "custom_layout" : layout === "buttons" ? "buttons_layout" : "default_layout";
|
|
3722
3636
|
const [unified, setUnified] = useState4(null);
|
|
@@ -4479,6 +4393,7 @@ function FloPayCheckout({
|
|
|
4479
4393
|
showPayPal,
|
|
4480
4394
|
showApplePay,
|
|
4481
4395
|
showGooglePay,
|
|
4396
|
+
theme,
|
|
4482
4397
|
buttonsTheme,
|
|
4483
4398
|
buttonsStyles,
|
|
4484
4399
|
cardButtonContent,
|
|
@@ -4623,12 +4538,13 @@ function FloPayCheckout({
|
|
|
4623
4538
|
showApplePay,
|
|
4624
4539
|
showGooglePay,
|
|
4625
4540
|
layout,
|
|
4541
|
+
theme,
|
|
4626
4542
|
buttonsTheme,
|
|
4627
4543
|
buttonsStyles,
|
|
4544
|
+
appearance,
|
|
4628
4545
|
cardButtonContent,
|
|
4629
4546
|
cardBackButtonContent,
|
|
4630
4547
|
cardTitleContent,
|
|
4631
|
-
showSecurityFooter,
|
|
4632
4548
|
onButtonClick,
|
|
4633
4549
|
onBeforeButtonClick,
|
|
4634
4550
|
enableAVS,
|
|
@@ -4685,6 +4601,7 @@ function InterimButtonsView({
|
|
|
4685
4601
|
showPayPal,
|
|
4686
4602
|
showApplePay,
|
|
4687
4603
|
showGooglePay,
|
|
4604
|
+
theme,
|
|
4688
4605
|
buttonsTheme,
|
|
4689
4606
|
buttonsStyles: stylesOverride,
|
|
4690
4607
|
cardButtonContent,
|
|
@@ -4698,8 +4615,9 @@ function InterimButtonsView({
|
|
|
4698
4615
|
setShowCardForm(cardOpen);
|
|
4699
4616
|
}
|
|
4700
4617
|
}, [cardOpen, isCardOpenControlled]);
|
|
4618
|
+
const themeBundle = useMemo4(() => resolveTheme2(theme), [theme]);
|
|
4701
4619
|
const bStyles = useMemo4(() => {
|
|
4702
|
-
const base = resolveButtonsLayoutTheme2(buttonsTheme);
|
|
4620
|
+
const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme2(buttonsTheme);
|
|
4703
4621
|
if (!stylesOverride) return base;
|
|
4704
4622
|
return {
|
|
4705
4623
|
...base,
|
|
@@ -4711,7 +4629,7 @@ function InterimButtonsView({
|
|
|
4711
4629
|
submitButton: { ...base.submitButton, ...stylesOverride.submitButton },
|
|
4712
4630
|
title: { ...base.title, ...stylesOverride.title }
|
|
4713
4631
|
};
|
|
4714
|
-
}, [buttonsTheme, stylesOverride]);
|
|
4632
|
+
}, [themeBundle, buttonsTheme, stylesOverride]);
|
|
4715
4633
|
const skeleton = (h) => /* @__PURE__ */ jsx7("div", { style: {
|
|
4716
4634
|
height: h,
|
|
4717
4635
|
borderRadius: 8,
|
|
@@ -5407,10 +5325,9 @@ function PayPalButton({
|
|
|
5407
5325
|
// src/automatic-payment-button.tsx
|
|
5408
5326
|
import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMemo5, useRef as useRef6, useState as useState7 } from "react";
|
|
5409
5327
|
import { PaymentAPI as PaymentAPI7 } from "@flopay/js";
|
|
5410
|
-
import { FloPayError as FloPayError8, resolveBillingApiUrl as resolveBillingApiUrl4, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme3 } from "@flopay/shared";
|
|
5328
|
+
import { FloPayError as FloPayError8, resolveBillingApiUrl as resolveBillingApiUrl4, resolveButtonsLayoutTheme as resolveButtonsLayoutTheme3, resolveTheme as resolveTheme3 } from "@flopay/shared";
|
|
5411
5329
|
import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5412
5330
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3 = 44;
|
|
5413
|
-
var PAYPAL_RESUME_STORAGE_KEY2 = "flopay_automatic_payment_button_resume";
|
|
5414
5331
|
function sleep2(ms) {
|
|
5415
5332
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5416
5333
|
}
|
|
@@ -5423,9 +5340,6 @@ function coerceError(err, fallbackMessage) {
|
|
|
5423
5340
|
"api_error"
|
|
5424
5341
|
);
|
|
5425
5342
|
}
|
|
5426
|
-
function canUseStorage2() {
|
|
5427
|
-
return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
|
|
5428
|
-
}
|
|
5429
5343
|
function shouldShowFallbackCheckout(error, sessionId) {
|
|
5430
5344
|
if (!sessionId) return false;
|
|
5431
5345
|
if (error.type === "validation_error") return false;
|
|
@@ -5434,47 +5348,6 @@ function shouldShowFallbackCheckout(error, sessionId) {
|
|
|
5434
5348
|
}
|
|
5435
5349
|
return true;
|
|
5436
5350
|
}
|
|
5437
|
-
function readPayPalResumeState2() {
|
|
5438
|
-
if (!canUseStorage2()) return null;
|
|
5439
|
-
try {
|
|
5440
|
-
const raw = window.sessionStorage.getItem(PAYPAL_RESUME_STORAGE_KEY2);
|
|
5441
|
-
if (!raw) return null;
|
|
5442
|
-
return JSON.parse(raw);
|
|
5443
|
-
} catch {
|
|
5444
|
-
return null;
|
|
5445
|
-
}
|
|
5446
|
-
}
|
|
5447
|
-
function persistPayPalResumeState2(state) {
|
|
5448
|
-
if (!canUseStorage2()) return;
|
|
5449
|
-
try {
|
|
5450
|
-
window.sessionStorage.setItem(PAYPAL_RESUME_STORAGE_KEY2, JSON.stringify(state));
|
|
5451
|
-
} catch (error) {
|
|
5452
|
-
console.warn("[FloPayAutomaticPaymentButton] Failed to persist PayPal resume state.", error);
|
|
5453
|
-
}
|
|
5454
|
-
}
|
|
5455
|
-
function clearPayPalResumeState2() {
|
|
5456
|
-
if (!canUseStorage2()) return;
|
|
5457
|
-
try {
|
|
5458
|
-
window.sessionStorage.removeItem(PAYPAL_RESUME_STORAGE_KEY2);
|
|
5459
|
-
} catch (error) {
|
|
5460
|
-
console.warn("[FloPayAutomaticPaymentButton] Failed to clear PayPal resume state.", error);
|
|
5461
|
-
}
|
|
5462
|
-
}
|
|
5463
|
-
function clearPayPalRedirectParams2() {
|
|
5464
|
-
if (typeof window === "undefined") return;
|
|
5465
|
-
const url = new URL(window.location.href);
|
|
5466
|
-
const keys = ["payment_intent", "payment_intent_client_secret", "redirect_status"];
|
|
5467
|
-
let changed = false;
|
|
5468
|
-
for (const key of keys) {
|
|
5469
|
-
if (url.searchParams.has(key)) {
|
|
5470
|
-
url.searchParams.delete(key);
|
|
5471
|
-
changed = true;
|
|
5472
|
-
}
|
|
5473
|
-
}
|
|
5474
|
-
if (changed) {
|
|
5475
|
-
window.history.replaceState({}, "", url.toString());
|
|
5476
|
-
}
|
|
5477
|
-
}
|
|
5478
5351
|
function resolveCreateSessionDraft(props) {
|
|
5479
5352
|
if (props.createSession) {
|
|
5480
5353
|
return {
|
|
@@ -5501,8 +5374,10 @@ function resolveCreateSessionDraft(props) {
|
|
|
5501
5374
|
function FloPayAutomaticPaymentButton({
|
|
5502
5375
|
sessionId,
|
|
5503
5376
|
createSession,
|
|
5504
|
-
|
|
5505
|
-
|
|
5377
|
+
// Deprecated — accepted for back-compat and silently ignored. Backend
|
|
5378
|
+
// resolves the customer's latest payment method server-side.
|
|
5379
|
+
paymentMethodId: _deprecatedPaymentMethodId,
|
|
5380
|
+
checkoutMethod: _deprecatedCheckoutMethod,
|
|
5506
5381
|
clientId,
|
|
5507
5382
|
items,
|
|
5508
5383
|
subscriptions,
|
|
@@ -5514,6 +5389,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5514
5389
|
utmMetadata,
|
|
5515
5390
|
billingApiUrl,
|
|
5516
5391
|
locale,
|
|
5392
|
+
theme,
|
|
5517
5393
|
buttonsTheme,
|
|
5518
5394
|
buttonsStyles: stylesOverride,
|
|
5519
5395
|
onSuccess,
|
|
@@ -5559,20 +5435,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5559
5435
|
const [overlayStatus, setOverlayStatus] = useState7(null);
|
|
5560
5436
|
const [overlayError, setOverlayError] = useState7(null);
|
|
5561
5437
|
const [fallbackSession, setFallbackSession] = useState7(null);
|
|
5562
|
-
const automaticPaymentToken = useMemo5(
|
|
5563
|
-
() => paymentMethodId ? {
|
|
5564
|
-
id: paymentMethodId,
|
|
5565
|
-
// Saved PayPal `user_payment_method` records are submitted with
|
|
5566
|
-
// `type: 'paypal'` so the backend routes the upsell through the
|
|
5567
|
-
// direct PayPal gateway's vaulted-token flow. Card and wallet PMs
|
|
5568
|
-
// continue to use `type: 'card'`.
|
|
5569
|
-
type: checkoutMethod === "paypal" ? "paypal" : "card",
|
|
5570
|
-
...checkoutMethod === "paypal" ? { isPaypal: true } : {}
|
|
5571
|
-
} : void 0,
|
|
5572
|
-
[checkoutMethod, paymentMethodId]
|
|
5573
|
-
);
|
|
5574
5438
|
const isMountedRef = useRef6(true);
|
|
5575
|
-
const resumeAttemptedRef = useRef6(false);
|
|
5576
5439
|
const fallbackSessionRef = useRef6(fallbackSession);
|
|
5577
5440
|
const onSuccessRef = useRef6(onSuccess);
|
|
5578
5441
|
const onErrorRef = useRef6(onError);
|
|
@@ -5653,10 +5516,6 @@ function FloPayAutomaticPaymentButton({
|
|
|
5653
5516
|
});
|
|
5654
5517
|
}
|
|
5655
5518
|
try {
|
|
5656
|
-
let paymentResult = null;
|
|
5657
|
-
const redirectResult = getRedirectResultFromCheckoutProcessError(apiResult.autoProcessingError);
|
|
5658
|
-
const shouldTreatCreateSessionFlowAsServerAutoAttempt = options?.fromCreateSession && (apiResult.autoProcessingAttempted === true || !!apiResult.autoProcessingError || !!redirectResult);
|
|
5659
|
-
const shouldRetryPayPalClientSide = checkoutMethod === "paypal" && automaticPaymentToken?.isPaypal === true && options?.fromCreateSession === true;
|
|
5660
5519
|
if (apiResult.autoProcessingPending) {
|
|
5661
5520
|
const api = new PaymentAPI7(resolvedBillingUrl);
|
|
5662
5521
|
const completed = await api.waitForCheckoutSessionCompletion(apiResult.autoProcessingPending.sessionId, {
|
|
@@ -5669,50 +5528,14 @@ function FloPayAutomaticPaymentButton({
|
|
|
5669
5528
|
});
|
|
5670
5529
|
}
|
|
5671
5530
|
await showSuccess({
|
|
5672
|
-
result: {
|
|
5673
|
-
status: "succeeded",
|
|
5674
|
-
paymentMethodId: paymentMethodId ?? void 0,
|
|
5675
|
-
checkoutMethod
|
|
5676
|
-
},
|
|
5531
|
+
result: { status: "succeeded" },
|
|
5677
5532
|
session: completedSession,
|
|
5678
5533
|
sessionId: completedSession.id || resolvedSessionId,
|
|
5679
5534
|
autoCompleted: false
|
|
5680
5535
|
});
|
|
5681
5536
|
return;
|
|
5682
5537
|
}
|
|
5683
|
-
if (
|
|
5684
|
-
const {
|
|
5685
|
-
publishableKey,
|
|
5686
|
-
paypalPublishableKey
|
|
5687
|
-
} = resolveSavedPaymentPublishableKeys(apiResult);
|
|
5688
|
-
if (redirectResult.type === "paypal_redirect_required" && publishableKey) {
|
|
5689
|
-
persistPayPalResumeState2({
|
|
5690
|
-
sessionId: session.id || resolvedSessionId,
|
|
5691
|
-
publishableKey,
|
|
5692
|
-
paypalPublishableKey
|
|
5693
|
-
});
|
|
5694
|
-
}
|
|
5695
|
-
const {
|
|
5696
|
-
flopay,
|
|
5697
|
-
paypalFlopay
|
|
5698
|
-
} = await loadSavedPaymentProviders({
|
|
5699
|
-
publishableKey,
|
|
5700
|
-
paypalPublishableKey,
|
|
5701
|
-
billingApiUrl: resolvedBillingUrl,
|
|
5702
|
-
locale
|
|
5703
|
-
});
|
|
5704
|
-
paymentResult = await handleSavedPaymentRedirectResult(redirectResult, {
|
|
5705
|
-
flopay,
|
|
5706
|
-
paypalFlopay,
|
|
5707
|
-
attempt3DS: true,
|
|
5708
|
-
billingApiUrl: resolvedBillingUrl,
|
|
5709
|
-
sessionId: session.id || resolvedSessionId,
|
|
5710
|
-
session
|
|
5711
|
-
});
|
|
5712
|
-
if (redirectResult.type === "paypal_redirect_required") {
|
|
5713
|
-
clearPayPalResumeState2();
|
|
5714
|
-
}
|
|
5715
|
-
} else if (apiResult.autoProcessingError && !shouldRetryPayPalClientSide) {
|
|
5538
|
+
if (apiResult.autoProcessingError) {
|
|
5716
5539
|
throw checkoutProcessErrorToFloPayError(
|
|
5717
5540
|
apiResult.autoProcessingError,
|
|
5718
5541
|
"Automatic payment failed. Please try again.",
|
|
@@ -5720,7 +5543,22 @@ function FloPayAutomaticPaymentButton({
|
|
|
5720
5543
|
checkoutMethod: apiResult.autoProcessingError.checkoutMethod
|
|
5721
5544
|
}
|
|
5722
5545
|
);
|
|
5723
|
-
}
|
|
5546
|
+
}
|
|
5547
|
+
if (options?.fromCreateSession && apiResult.autoProcessingAttempted === true) {
|
|
5548
|
+
throw checkoutProcessErrorToFloPayError(
|
|
5549
|
+
{
|
|
5550
|
+
type: "unknown",
|
|
5551
|
+
message: "Automatic payment failed. Please try again."
|
|
5552
|
+
},
|
|
5553
|
+
"Automatic payment failed. Please try again."
|
|
5554
|
+
);
|
|
5555
|
+
}
|
|
5556
|
+
const result = await processSavedPaymentForMode({
|
|
5557
|
+
billingApiUrl: resolvedBillingUrl,
|
|
5558
|
+
sessionId: resolvedSessionId ?? session.id,
|
|
5559
|
+
session
|
|
5560
|
+
});
|
|
5561
|
+
if (result.type !== "success") {
|
|
5724
5562
|
throw checkoutProcessErrorToFloPayError(
|
|
5725
5563
|
{
|
|
5726
5564
|
type: "unknown",
|
|
@@ -5728,121 +5566,16 @@ function FloPayAutomaticPaymentButton({
|
|
|
5728
5566
|
},
|
|
5729
5567
|
"Automatic payment failed. Please try again."
|
|
5730
5568
|
);
|
|
5731
|
-
} else {
|
|
5732
|
-
const result = await processSavedPaymentForMode({
|
|
5733
|
-
billingApiUrl: resolvedBillingUrl,
|
|
5734
|
-
sessionId: resolvedSessionId ?? session.id,
|
|
5735
|
-
session,
|
|
5736
|
-
tokenizedData: automaticPaymentToken
|
|
5737
|
-
});
|
|
5738
|
-
paymentResult = result.type === "success" ? result.result : null;
|
|
5739
|
-
if (result.type !== "success") {
|
|
5740
|
-
const {
|
|
5741
|
-
publishableKey,
|
|
5742
|
-
paypalPublishableKey
|
|
5743
|
-
} = resolveSavedPaymentPublishableKeys(apiResult);
|
|
5744
|
-
if (result.type === "paypal_redirect_required" && publishableKey) {
|
|
5745
|
-
persistPayPalResumeState2({
|
|
5746
|
-
sessionId: session.id || resolvedSessionId,
|
|
5747
|
-
publishableKey,
|
|
5748
|
-
paypalPublishableKey
|
|
5749
|
-
});
|
|
5750
|
-
}
|
|
5751
|
-
const {
|
|
5752
|
-
flopay,
|
|
5753
|
-
paypalFlopay
|
|
5754
|
-
} = await loadSavedPaymentProviders({
|
|
5755
|
-
publishableKey,
|
|
5756
|
-
paypalPublishableKey,
|
|
5757
|
-
billingApiUrl: resolvedBillingUrl,
|
|
5758
|
-
locale
|
|
5759
|
-
});
|
|
5760
|
-
paymentResult = await handleSavedPaymentRedirectResult(result, {
|
|
5761
|
-
flopay,
|
|
5762
|
-
paypalFlopay,
|
|
5763
|
-
attempt3DS: true,
|
|
5764
|
-
billingApiUrl: resolvedBillingUrl,
|
|
5765
|
-
sessionId: session.id || resolvedSessionId,
|
|
5766
|
-
session
|
|
5767
|
-
});
|
|
5768
|
-
if (result.type === "paypal_redirect_required") {
|
|
5769
|
-
clearPayPalResumeState2();
|
|
5770
|
-
}
|
|
5771
|
-
}
|
|
5772
5569
|
}
|
|
5773
5570
|
await showSuccess({
|
|
5774
|
-
result:
|
|
5775
|
-
...paymentResult,
|
|
5776
|
-
paymentMethodId: paymentResult.paymentMethodId ?? paymentMethodId,
|
|
5777
|
-
checkoutMethod: paymentResult.checkoutMethod ?? checkoutMethod
|
|
5778
|
-
} : {
|
|
5779
|
-
status: "succeeded",
|
|
5780
|
-
paymentMethodId: paymentMethodId ?? void 0,
|
|
5781
|
-
checkoutMethod
|
|
5782
|
-
},
|
|
5571
|
+
result: result.result,
|
|
5783
5572
|
session,
|
|
5784
5573
|
sessionId: session.id || resolvedSessionId,
|
|
5785
5574
|
autoCompleted: false
|
|
5786
5575
|
});
|
|
5787
5576
|
} catch (err) {
|
|
5788
|
-
|
|
5577
|
+
const floPayErr = normalizeSavedPaymentError(err);
|
|
5789
5578
|
const fallbackSessionId = session.id || resolvedSessionId;
|
|
5790
|
-
const shouldTreatCreateSessionFlowAsServerAutoAttempt = options?.fromCreateSession && apiResult.autoProcessingAttempted === true;
|
|
5791
|
-
if (!shouldTreatCreateSessionFlowAsServerAutoAttempt && floPayErr.code === "authentication_required" && fallbackSessionId && automaticPaymentToken?.id && automaticPaymentToken.id.startsWith("pm_")) {
|
|
5792
|
-
try {
|
|
5793
|
-
const {
|
|
5794
|
-
publishableKey,
|
|
5795
|
-
paypalPublishableKey
|
|
5796
|
-
} = resolveSavedPaymentPublishableKeys(apiResult);
|
|
5797
|
-
const {
|
|
5798
|
-
flopay
|
|
5799
|
-
} = await loadSavedPaymentProviders({
|
|
5800
|
-
publishableKey,
|
|
5801
|
-
paypalPublishableKey,
|
|
5802
|
-
billingApiUrl: resolvedBillingUrl,
|
|
5803
|
-
locale
|
|
5804
|
-
});
|
|
5805
|
-
if (!flopay) {
|
|
5806
|
-
throw new FloPayError8(
|
|
5807
|
-
"Stripe is not available for 3DS authentication.",
|
|
5808
|
-
"api_error",
|
|
5809
|
-
{ code: "authentication_required" }
|
|
5810
|
-
);
|
|
5811
|
-
}
|
|
5812
|
-
const paymentResult = await processSavedPaymentWithIntent({
|
|
5813
|
-
billingApiUrl: resolvedBillingUrl,
|
|
5814
|
-
sessionId: fallbackSessionId,
|
|
5815
|
-
session,
|
|
5816
|
-
paymentMethodId: automaticPaymentToken.id,
|
|
5817
|
-
flopay
|
|
5818
|
-
});
|
|
5819
|
-
await showSuccess({
|
|
5820
|
-
result: {
|
|
5821
|
-
...paymentResult,
|
|
5822
|
-
paymentMethodId: paymentResult.paymentMethodId ?? paymentMethodId,
|
|
5823
|
-
checkoutMethod: paymentResult.checkoutMethod ?? checkoutMethod
|
|
5824
|
-
},
|
|
5825
|
-
session,
|
|
5826
|
-
sessionId: fallbackSessionId,
|
|
5827
|
-
autoCompleted: false
|
|
5828
|
-
});
|
|
5829
|
-
return;
|
|
5830
|
-
} catch (intentRecoveryErr) {
|
|
5831
|
-
floPayErr = normalizeSavedPaymentError(intentRecoveryErr);
|
|
5832
|
-
}
|
|
5833
|
-
}
|
|
5834
|
-
const inResumeWindow = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("payment_intent_client_secret") && !!readPayPalResumeState2();
|
|
5835
|
-
if (floPayErr.code === "payment_intent_unexpected_state" && inResumeWindow) {
|
|
5836
|
-
return;
|
|
5837
|
-
}
|
|
5838
|
-
const isSilentFallbackCase = (floPayErr.code === "paypal_requires_user_interaction" || floPayErr.code === "payment_intent_unexpected_state") && shouldShowFallbackCheckout(floPayErr, fallbackSessionId) && !!fallbackSessionId && isMountedRef.current;
|
|
5839
|
-
if (isSilentFallbackCase) {
|
|
5840
|
-
setFallbackSession({
|
|
5841
|
-
sessionId: fallbackSessionId,
|
|
5842
|
-
errorMessage: ""
|
|
5843
|
-
});
|
|
5844
|
-
return;
|
|
5845
|
-
}
|
|
5846
5579
|
await showError(floPayErr, {
|
|
5847
5580
|
emitDecline: true,
|
|
5848
5581
|
method: floPayErr.checkoutMethod ?? DEFAULT_SAVED_PAYMENT_DECLINE_METHOD
|
|
@@ -5855,10 +5588,6 @@ function FloPayAutomaticPaymentButton({
|
|
|
5855
5588
|
}
|
|
5856
5589
|
}
|
|
5857
5590
|
}, [
|
|
5858
|
-
checkoutMethod,
|
|
5859
|
-
locale,
|
|
5860
|
-
automaticPaymentToken,
|
|
5861
|
-
paymentMethodId,
|
|
5862
5591
|
resolvedBillingUrl,
|
|
5863
5592
|
showError,
|
|
5864
5593
|
showSuccess
|
|
@@ -5905,8 +5634,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
5905
5634
|
}
|
|
5906
5635
|
try {
|
|
5907
5636
|
const result = await api.createAndFetchSession({
|
|
5908
|
-
...createSessionDraft
|
|
5909
|
-
...automaticPaymentToken ? { tokenizedData: automaticPaymentToken } : {}
|
|
5637
|
+
...createSessionDraft
|
|
5910
5638
|
});
|
|
5911
5639
|
await processResolvedSession(result, result.data.session?.id ?? null, {
|
|
5912
5640
|
fromCreateSession: true
|
|
@@ -5961,146 +5689,16 @@ function FloPayAutomaticPaymentButton({
|
|
|
5961
5689
|
const handleFallbackDecline = useCallback5((decline) => {
|
|
5962
5690
|
onDeclineRef.current?.(decline);
|
|
5963
5691
|
}, []);
|
|
5964
|
-
|
|
5965
|
-
if (typeof window === "undefined" || resumeAttemptedRef.current) {
|
|
5966
|
-
return;
|
|
5967
|
-
}
|
|
5968
|
-
const params = new URLSearchParams(window.location.search);
|
|
5969
|
-
const clientSecret = params.get("payment_intent_client_secret");
|
|
5970
|
-
if (!clientSecret) {
|
|
5971
|
-
return;
|
|
5972
|
-
}
|
|
5973
|
-
const resumeState = readPayPalResumeState2();
|
|
5974
|
-
if (!resumeState) {
|
|
5975
|
-
return;
|
|
5976
|
-
}
|
|
5977
|
-
resumeAttemptedRef.current = true;
|
|
5978
|
-
void (async () => {
|
|
5979
|
-
setIsProcessing(true);
|
|
5980
|
-
setOverlayError(null);
|
|
5981
|
-
setOverlayStatus("processing");
|
|
5982
|
-
try {
|
|
5983
|
-
if (params.get("redirect_status") === "failed") {
|
|
5984
|
-
throw Object.assign(
|
|
5985
|
-
new FloPayError8("PayPal payment was declined. Please try again.", "api_error"),
|
|
5986
|
-
{ checkoutMethod: "paypal" }
|
|
5987
|
-
);
|
|
5988
|
-
}
|
|
5989
|
-
const {
|
|
5990
|
-
flopay,
|
|
5991
|
-
paypalFlopay
|
|
5992
|
-
} = await loadSavedPaymentProviders({
|
|
5993
|
-
publishableKey: resumeState.publishableKey,
|
|
5994
|
-
paypalPublishableKey: resumeState.paypalPublishableKey,
|
|
5995
|
-
billingApiUrl: resolvedBillingUrl,
|
|
5996
|
-
locale
|
|
5997
|
-
});
|
|
5998
|
-
const paypalStripe = (paypalFlopay ?? flopay)?.getRawProvider();
|
|
5999
|
-
if (!paypalStripe) {
|
|
6000
|
-
throw Object.assign(
|
|
6001
|
-
new FloPayError8("PayPal is not available.", "api_error"),
|
|
6002
|
-
{ checkoutMethod: "paypal" }
|
|
6003
|
-
);
|
|
6004
|
-
}
|
|
6005
|
-
const { paymentIntent, error } = await paypalStripe.retrievePaymentIntent(clientSecret);
|
|
6006
|
-
if (error) {
|
|
6007
|
-
throw Object.assign(
|
|
6008
|
-
new FloPayError8(
|
|
6009
|
-
error.message ?? "Failed to retrieve PayPal payment status.",
|
|
6010
|
-
"api_error",
|
|
6011
|
-
{ code: error.code }
|
|
6012
|
-
),
|
|
6013
|
-
{ checkoutMethod: "paypal" }
|
|
6014
|
-
);
|
|
6015
|
-
}
|
|
6016
|
-
const resultStatus = mapPayPalIntentStatusToPaymentResult(paymentIntent?.status);
|
|
6017
|
-
if (!paymentIntent || resultStatus === "failed") {
|
|
6018
|
-
throw Object.assign(
|
|
6019
|
-
new FloPayError8("PayPal payment was not completed. Please try again.", "api_error"),
|
|
6020
|
-
{ checkoutMethod: "paypal" }
|
|
6021
|
-
);
|
|
6022
|
-
}
|
|
6023
|
-
const paymentMethodId2 = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
6024
|
-
if (!resumeState.sessionId) {
|
|
6025
|
-
throw Object.assign(
|
|
6026
|
-
new FloPayError8("Missing session id on PayPal resume.", "api_error"),
|
|
6027
|
-
{ checkoutMethod: "paypal" }
|
|
6028
|
-
);
|
|
6029
|
-
}
|
|
6030
|
-
const api = new PaymentAPI7(resolvedBillingUrl);
|
|
6031
|
-
const sessionResult = await api.getUnifiedCheckoutSession(resumeState.sessionId);
|
|
6032
|
-
let resumeSession = sessionResult.data.session;
|
|
6033
|
-
if (!resumeSession) {
|
|
6034
|
-
throw Object.assign(
|
|
6035
|
-
new FloPayError8("Could not load session to capture PayPal payment.", "api_error"),
|
|
6036
|
-
{ checkoutMethod: "paypal" }
|
|
6037
|
-
);
|
|
6038
|
-
}
|
|
6039
|
-
let finalResultStatus = resultStatus;
|
|
6040
|
-
if (resumeSession.status !== "complete") {
|
|
6041
|
-
const processResult = await processSavedPaymentForMode({
|
|
6042
|
-
billingApiUrl: resolvedBillingUrl,
|
|
6043
|
-
sessionId: resumeState.sessionId,
|
|
6044
|
-
session: resumeSession,
|
|
6045
|
-
tokenizedData: {
|
|
6046
|
-
id: paymentMethodId2 ?? paymentIntent.id,
|
|
6047
|
-
type: "card",
|
|
6048
|
-
threeDSecureActionResultTokenId: paymentIntent.id,
|
|
6049
|
-
isPaypal: true
|
|
6050
|
-
}
|
|
6051
|
-
});
|
|
6052
|
-
if (processResult.type !== "success") {
|
|
6053
|
-
throw Object.assign(
|
|
6054
|
-
new FloPayError8("Failed to finalize PayPal payment.", "api_error"),
|
|
6055
|
-
{ checkoutMethod: "paypal" }
|
|
6056
|
-
);
|
|
6057
|
-
}
|
|
6058
|
-
finalResultStatus = processResult.result.status;
|
|
6059
|
-
try {
|
|
6060
|
-
const refreshed = await api.getUnifiedCheckoutSession(resumeState.sessionId);
|
|
6061
|
-
if (refreshed.data.session) {
|
|
6062
|
-
resumeSession = refreshed.data.session;
|
|
6063
|
-
}
|
|
6064
|
-
} catch {
|
|
6065
|
-
}
|
|
6066
|
-
}
|
|
6067
|
-
await showSuccess({
|
|
6068
|
-
result: {
|
|
6069
|
-
status: finalResultStatus,
|
|
6070
|
-
paymentIntentId: paymentIntent.id,
|
|
6071
|
-
paymentMethodId: paymentMethodId2,
|
|
6072
|
-
checkoutMethod: "paypal"
|
|
6073
|
-
},
|
|
6074
|
-
session: resumeSession,
|
|
6075
|
-
sessionId: resumeState.sessionId,
|
|
6076
|
-
autoCompleted: false
|
|
6077
|
-
});
|
|
6078
|
-
} catch (err) {
|
|
6079
|
-
const floPayErr = normalizeSavedPaymentError(err);
|
|
6080
|
-
await showError(floPayErr, {
|
|
6081
|
-
emitDecline: true,
|
|
6082
|
-
method: floPayErr.checkoutMethod ?? "paypal"
|
|
6083
|
-
});
|
|
6084
|
-
} finally {
|
|
6085
|
-
clearPayPalResumeState2();
|
|
6086
|
-
clearPayPalRedirectParams2();
|
|
6087
|
-
if (isMountedRef.current) {
|
|
6088
|
-
setOverlayStatus(null);
|
|
6089
|
-
setOverlayError(null);
|
|
6090
|
-
setIsProcessing(false);
|
|
6091
|
-
}
|
|
6092
|
-
}
|
|
6093
|
-
})();
|
|
6094
|
-
}, [locale, resolvedBillingUrl, showError, showSuccess]);
|
|
5692
|
+
const themeBundle = useMemo5(() => resolveTheme3(theme), [theme]);
|
|
6095
5693
|
const bStyles = useMemo5(() => {
|
|
6096
|
-
const base = resolveButtonsLayoutTheme3(buttonsTheme);
|
|
5694
|
+
const base = themeBundle?.buttonsLayout ?? resolveButtonsLayoutTheme3(buttonsTheme);
|
|
6097
5695
|
if (!stylesOverride) return base;
|
|
6098
5696
|
return {
|
|
6099
5697
|
...base,
|
|
6100
5698
|
...stylesOverride,
|
|
6101
5699
|
cardButton: { ...base.cardButton, ...stylesOverride.cardButton }
|
|
6102
5700
|
};
|
|
6103
|
-
}, [buttonsTheme, stylesOverride]);
|
|
5701
|
+
}, [themeBundle, buttonsTheme, stylesOverride]);
|
|
6104
5702
|
const cardButtonSizing = children === void 0 ? { boxSizing: "border-box", height: DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT3, padding: "0 1rem" } : { padding: "0.9rem 1rem" };
|
|
6105
5703
|
return /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
6106
5704
|
/* @__PURE__ */ jsx10(
|
|
@@ -6197,9 +5795,12 @@ function FloPayAutomaticPaymentButton({
|
|
|
6197
5795
|
sessionId: fallbackSession.sessionId,
|
|
6198
5796
|
checkoutMode: "full",
|
|
6199
5797
|
billingApiUrl: resolvedBillingUrl,
|
|
5798
|
+
locale,
|
|
5799
|
+
theme,
|
|
5800
|
+
buttonsTheme,
|
|
5801
|
+
buttonsStyles: stylesOverride,
|
|
6200
5802
|
initialErrorMessage: fallbackSession.errorMessage,
|
|
6201
5803
|
cardTitleContent: null,
|
|
6202
|
-
showSecurityFooter: false,
|
|
6203
5804
|
onComplete: handleFallbackComplete,
|
|
6204
5805
|
onError: handleFallbackError,
|
|
6205
5806
|
onDecline: handleFallbackDecline
|