@flopay/react 0.4.4 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +179 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +179 -81
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1407,13 +1407,19 @@ function SplitCardFormInner({
|
|
|
1407
1407
|
onError?.(submitResult.error);
|
|
1408
1408
|
return;
|
|
1409
1409
|
}
|
|
1410
|
-
const
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1410
|
+
const billingAddress = {
|
|
1411
|
+
...(enableAVS ? selectedCountryRef.current : resolvedAccount.country) ? {
|
|
1412
|
+
country: enableAVS ? selectedCountryRef.current : resolvedAccount.country
|
|
1413
|
+
} : {},
|
|
1414
|
+
...(enableAVS ? zipCodeRef.current.trim() : resolvedAccount.zip) || "" ? {
|
|
1415
|
+
postal_code: enableAVS ? zipCodeRef.current.trim() : resolvedAccount.zip
|
|
1416
|
+
} : {}
|
|
1417
|
+
};
|
|
1418
|
+
const billingDetails = {
|
|
1419
|
+
...resolvedAccount.email ? { email: resolvedAccount.email } : {},
|
|
1420
|
+
...fullName.trim() ? { name: fullName.trim() } : {},
|
|
1421
|
+
...Object.keys(billingAddress).length > 0 ? { address: billingAddress } : {}
|
|
1422
|
+
};
|
|
1417
1423
|
const pmResult = await flopay.createPaymentMethod(billingDetails);
|
|
1418
1424
|
if (pmResult.error || !pmResult.paymentMethodId) {
|
|
1419
1425
|
updateError(pmResult.error?.message ?? "Failed to create payment method.");
|
|
@@ -1923,6 +1929,32 @@ function SplitCardFormInner({
|
|
|
1923
1929
|
var import_js = require("@flopay/js");
|
|
1924
1930
|
var import_shared6 = require("@flopay/shared");
|
|
1925
1931
|
var DEFAULT_SAVED_PAYMENT_DECLINE_METHOD = "card";
|
|
1932
|
+
function getRedirectResultFromCheckoutProcessError(error) {
|
|
1933
|
+
if (!error?.type || !error.threeDSecureToken) {
|
|
1934
|
+
return null;
|
|
1935
|
+
}
|
|
1936
|
+
if (error.type !== "3ds_required" && error.type !== "paypal_redirect_required") {
|
|
1937
|
+
return null;
|
|
1938
|
+
}
|
|
1939
|
+
return {
|
|
1940
|
+
type: error.type,
|
|
1941
|
+
threeDSecureToken: error.threeDSecureToken,
|
|
1942
|
+
paymentMethodId: error.paymentMethodId
|
|
1943
|
+
};
|
|
1944
|
+
}
|
|
1945
|
+
function checkoutProcessErrorToFloPayError(error, fallbackMessage = "Payment failed. Please try again.", options) {
|
|
1946
|
+
const checkoutMethod = options?.checkoutMethod ?? error?.checkoutMethod ?? (error?.type === "paypal_redirect_required" ? "paypal" : "card");
|
|
1947
|
+
return Object.assign(
|
|
1948
|
+
new import_shared6.FloPayError(
|
|
1949
|
+
error?.message ?? fallbackMessage,
|
|
1950
|
+
"api_error",
|
|
1951
|
+
{
|
|
1952
|
+
code: error?.gatewayErrorCode
|
|
1953
|
+
}
|
|
1954
|
+
),
|
|
1955
|
+
{ checkoutMethod }
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1926
1958
|
function resolveSavedPaymentReturnUrl(session) {
|
|
1927
1959
|
if (typeof window !== "undefined" && window.location.href) {
|
|
1928
1960
|
return window.location.href;
|
|
@@ -2445,6 +2477,7 @@ function FloPayCheckout({
|
|
|
2445
2477
|
avsLayout,
|
|
2446
2478
|
submitLabel,
|
|
2447
2479
|
className,
|
|
2480
|
+
initialErrorMessage = null,
|
|
2448
2481
|
children,
|
|
2449
2482
|
checkoutMode: checkoutModeProp,
|
|
2450
2483
|
confirmLabel,
|
|
@@ -2467,7 +2500,7 @@ function FloPayCheckout({
|
|
|
2467
2500
|
const [loadError, setLoadError] = (0, import_react8.useState)(null);
|
|
2468
2501
|
const [currentMode, setCurrentMode] = (0, import_react8.useState)("full");
|
|
2469
2502
|
const [confirmProcessing, setConfirmProcessing] = (0, import_react8.useState)(false);
|
|
2470
|
-
const [modeError, setModeError] = (0, import_react8.useState)(
|
|
2503
|
+
const [modeError, setModeError] = (0, import_react8.useState)(initialErrorMessage);
|
|
2471
2504
|
const [modeOverlayStatus, setModeOverlayStatus] = (0, import_react8.useState)(null);
|
|
2472
2505
|
const [modeOverlayError, setModeOverlayError] = (0, import_react8.useState)(null);
|
|
2473
2506
|
const [createSessionPatch, setCreateSessionPatch] = (0, import_react8.useState)(void 0);
|
|
@@ -2514,6 +2547,9 @@ function FloPayCheckout({
|
|
|
2514
2547
|
setCreateSessionPatch(void 0);
|
|
2515
2548
|
setCreateSessionPatchBaseHash(baseCreateSessionHash);
|
|
2516
2549
|
}, [baseCreateSessionHash]);
|
|
2550
|
+
(0, import_react8.useEffect)(() => {
|
|
2551
|
+
setModeError(initialErrorMessage);
|
|
2552
|
+
}, [initialErrorMessage]);
|
|
2517
2553
|
const emitDecline = (0, import_react8.useCallback)(
|
|
2518
2554
|
(method, input, overrides) => {
|
|
2519
2555
|
onDeclineRef.current?.(buildDeclineEvent(method, input, overrides));
|
|
@@ -2527,19 +2563,45 @@ function FloPayCheckout({
|
|
|
2527
2563
|
setModeOverlayStatus("processing");
|
|
2528
2564
|
const activeSessionId2 = options?.sessionId ?? sess.id;
|
|
2529
2565
|
try {
|
|
2530
|
-
const
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2566
|
+
const redirectResult = getRedirectResultFromCheckoutProcessError(options?.initialAutoProcessingError);
|
|
2567
|
+
let paymentResult;
|
|
2568
|
+
if (redirectResult) {
|
|
2569
|
+
paymentResult = await handleSavedPaymentRedirectResult(redirectResult, {
|
|
2570
|
+
flopay: flopayRef.current,
|
|
2571
|
+
paypalFlopay: paypalFlopayRef.current,
|
|
2572
|
+
attempt3DS: options?.attempt3DS,
|
|
2573
|
+
billingApiUrl: resolvedBillingUrl,
|
|
2574
|
+
sessionId: activeSessionId2,
|
|
2575
|
+
session: sess
|
|
2576
|
+
});
|
|
2577
|
+
} else if (options?.initialAutoProcessingError) {
|
|
2578
|
+
throw checkoutProcessErrorToFloPayError(
|
|
2579
|
+
options.initialAutoProcessingError,
|
|
2580
|
+
"Automatic payment failed. Please try again.",
|
|
2581
|
+
{
|
|
2582
|
+
checkoutMethod: options.initialAutoProcessingError.checkoutMethod
|
|
2583
|
+
}
|
|
2584
|
+
);
|
|
2585
|
+
} else if (options?.fromCreateSession) {
|
|
2586
|
+
if (options?.fallbackToFull) {
|
|
2587
|
+
setCurrentMode("full");
|
|
2588
|
+
}
|
|
2589
|
+
return false;
|
|
2590
|
+
} else {
|
|
2591
|
+
const result = await processSavedPaymentForMode({
|
|
2592
|
+
billingApiUrl: resolvedBillingUrl,
|
|
2593
|
+
sessionId: activeSessionId2,
|
|
2594
|
+
session: sess
|
|
2595
|
+
});
|
|
2596
|
+
paymentResult = result.type === "success" ? result.result : await handleSavedPaymentRedirectResult(result, {
|
|
2597
|
+
flopay: flopayRef.current,
|
|
2598
|
+
paypalFlopay: paypalFlopayRef.current,
|
|
2599
|
+
attempt3DS: options?.attempt3DS,
|
|
2600
|
+
billingApiUrl: resolvedBillingUrl,
|
|
2601
|
+
sessionId: activeSessionId2,
|
|
2602
|
+
session: sess
|
|
2603
|
+
});
|
|
2604
|
+
}
|
|
2543
2605
|
setModeOverlayStatus("success");
|
|
2544
2606
|
await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
|
|
2545
2607
|
onCompleteRef.current?.(paymentResult);
|
|
@@ -2606,10 +2668,10 @@ function FloPayCheckout({
|
|
|
2606
2668
|
}, [sessionIdProp]);
|
|
2607
2669
|
(0, import_react8.useEffect)(() => {
|
|
2608
2670
|
autoCheckoutAttempted.current = false;
|
|
2609
|
-
setModeError(
|
|
2671
|
+
setModeError(initialErrorMessage);
|
|
2610
2672
|
setModeOverlayError(null);
|
|
2611
2673
|
setModeOverlayStatus(null);
|
|
2612
|
-
}, [
|
|
2674
|
+
}, [createSessionHash, initialErrorMessage, sessionIdProp]);
|
|
2613
2675
|
async function resolveInlineSession(params, cacheKey) {
|
|
2614
2676
|
const api = new import_js2.PaymentAPI(resolvedBillingUrl);
|
|
2615
2677
|
let sid = typeof window !== "undefined" ? window.sessionStorage.getItem(cacheKey) : null;
|
|
@@ -2748,6 +2810,9 @@ function FloPayCheckout({
|
|
|
2748
2810
|
await runSavedPaymentFlow(resolvedSession, {
|
|
2749
2811
|
attempt3DS: true,
|
|
2750
2812
|
fallbackToFull: true,
|
|
2813
|
+
fromCreateSession: true,
|
|
2814
|
+
initialAutoProcessingError: resolved.result.autoProcessingError,
|
|
2815
|
+
autoProcessingAttempted: resolved.result.autoProcessingAttempted,
|
|
2751
2816
|
sessionId: resolved.sid || resolvedSession.id
|
|
2752
2817
|
});
|
|
2753
2818
|
return;
|
|
@@ -3568,7 +3633,11 @@ function CheckoutFormInner({
|
|
|
3568
3633
|
onError?.(submitResult.error);
|
|
3569
3634
|
return;
|
|
3570
3635
|
}
|
|
3571
|
-
const
|
|
3636
|
+
const fullName = `${firstName ?? ""} ${lastName ?? ""}`.trim();
|
|
3637
|
+
const pmResult = await flopay.createPaymentMethod({
|
|
3638
|
+
...email ? { email } : {},
|
|
3639
|
+
...fullName ? { name: fullName } : {}
|
|
3640
|
+
});
|
|
3572
3641
|
if (pmResult.error || !pmResult.paymentMethodId) {
|
|
3573
3642
|
updateError(pmResult.error?.message ?? "Failed to create payment method.");
|
|
3574
3643
|
return;
|
|
@@ -4071,7 +4140,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
4071
4140
|
setOverlayStatus("error");
|
|
4072
4141
|
await sleep2(PROCESSING_OVERLAY_ERROR_DELAY_MS);
|
|
4073
4142
|
}, [emitDecline]);
|
|
4074
|
-
const processResolvedSession = (0, import_react11.useCallback)(async (apiResult, resolvedSessionId) => {
|
|
4143
|
+
const processResolvedSession = (0, import_react11.useCallback)(async (apiResult, resolvedSessionId, options) => {
|
|
4075
4144
|
const session = apiResult.data.session ?? null;
|
|
4076
4145
|
if (!session) {
|
|
4077
4146
|
throw new import_shared10.FloPayError("No session data returned", "api_error");
|
|
@@ -4086,19 +4155,15 @@ function FloPayAutomaticPaymentButton({
|
|
|
4086
4155
|
return;
|
|
4087
4156
|
}
|
|
4088
4157
|
try {
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
tokenizedData: automaticPaymentToken
|
|
4094
|
-
});
|
|
4095
|
-
let paymentResult = result.type === "success" ? result.result : null;
|
|
4096
|
-
if (result.type !== "success") {
|
|
4158
|
+
let paymentResult = null;
|
|
4159
|
+
const redirectResult = getRedirectResultFromCheckoutProcessError(apiResult.autoProcessingError);
|
|
4160
|
+
const shouldTreatCreateSessionFlowAsServerAutoAttempt = options?.fromCreateSession && (apiResult.autoProcessingAttempted === true || !!apiResult.autoProcessingError || !!redirectResult);
|
|
4161
|
+
if (redirectResult) {
|
|
4097
4162
|
const {
|
|
4098
4163
|
publishableKey,
|
|
4099
4164
|
paypalPublishableKey
|
|
4100
4165
|
} = resolveSavedPaymentPublishableKeys(apiResult, fallbackPublishableKey);
|
|
4101
|
-
if (
|
|
4166
|
+
if (redirectResult.type === "paypal_redirect_required") {
|
|
4102
4167
|
persistPayPalResumeState({
|
|
4103
4168
|
sessionId: session.id || resolvedSessionId,
|
|
4104
4169
|
publishableKey,
|
|
@@ -4114,7 +4179,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
4114
4179
|
billingApiUrl: resolvedBillingUrl,
|
|
4115
4180
|
locale
|
|
4116
4181
|
});
|
|
4117
|
-
paymentResult = await handleSavedPaymentRedirectResult(
|
|
4182
|
+
paymentResult = await handleSavedPaymentRedirectResult(redirectResult, {
|
|
4118
4183
|
flopay,
|
|
4119
4184
|
paypalFlopay,
|
|
4120
4185
|
attempt3DS: true,
|
|
@@ -4122,9 +4187,66 @@ function FloPayAutomaticPaymentButton({
|
|
|
4122
4187
|
sessionId: session.id || resolvedSessionId,
|
|
4123
4188
|
session
|
|
4124
4189
|
});
|
|
4125
|
-
if (
|
|
4190
|
+
if (redirectResult.type === "paypal_redirect_required") {
|
|
4126
4191
|
clearPayPalResumeState();
|
|
4127
4192
|
}
|
|
4193
|
+
} else if (apiResult.autoProcessingError) {
|
|
4194
|
+
throw checkoutProcessErrorToFloPayError(
|
|
4195
|
+
apiResult.autoProcessingError,
|
|
4196
|
+
"Automatic payment failed. Please try again.",
|
|
4197
|
+
{
|
|
4198
|
+
checkoutMethod: apiResult.autoProcessingError.checkoutMethod
|
|
4199
|
+
}
|
|
4200
|
+
);
|
|
4201
|
+
} else if (shouldTreatCreateSessionFlowAsServerAutoAttempt) {
|
|
4202
|
+
throw checkoutProcessErrorToFloPayError(
|
|
4203
|
+
{
|
|
4204
|
+
type: "unknown",
|
|
4205
|
+
message: "Automatic payment failed. Please try again."
|
|
4206
|
+
},
|
|
4207
|
+
"Automatic payment failed. Please try again."
|
|
4208
|
+
);
|
|
4209
|
+
} else {
|
|
4210
|
+
const result = await processSavedPaymentForMode({
|
|
4211
|
+
billingApiUrl: resolvedBillingUrl,
|
|
4212
|
+
sessionId: resolvedSessionId ?? session.id,
|
|
4213
|
+
session,
|
|
4214
|
+
tokenizedData: automaticPaymentToken
|
|
4215
|
+
});
|
|
4216
|
+
paymentResult = result.type === "success" ? result.result : null;
|
|
4217
|
+
if (result.type !== "success") {
|
|
4218
|
+
const {
|
|
4219
|
+
publishableKey,
|
|
4220
|
+
paypalPublishableKey
|
|
4221
|
+
} = resolveSavedPaymentPublishableKeys(apiResult, fallbackPublishableKey);
|
|
4222
|
+
if (result.type === "paypal_redirect_required") {
|
|
4223
|
+
persistPayPalResumeState({
|
|
4224
|
+
sessionId: session.id || resolvedSessionId,
|
|
4225
|
+
publishableKey,
|
|
4226
|
+
paypalPublishableKey
|
|
4227
|
+
});
|
|
4228
|
+
}
|
|
4229
|
+
const {
|
|
4230
|
+
flopay,
|
|
4231
|
+
paypalFlopay
|
|
4232
|
+
} = await loadSavedPaymentProviders({
|
|
4233
|
+
publishableKey,
|
|
4234
|
+
paypalPublishableKey,
|
|
4235
|
+
billingApiUrl: resolvedBillingUrl,
|
|
4236
|
+
locale
|
|
4237
|
+
});
|
|
4238
|
+
paymentResult = await handleSavedPaymentRedirectResult(result, {
|
|
4239
|
+
flopay,
|
|
4240
|
+
paypalFlopay,
|
|
4241
|
+
attempt3DS: true,
|
|
4242
|
+
billingApiUrl: resolvedBillingUrl,
|
|
4243
|
+
sessionId: session.id || resolvedSessionId,
|
|
4244
|
+
session
|
|
4245
|
+
});
|
|
4246
|
+
if (result.type === "paypal_redirect_required") {
|
|
4247
|
+
clearPayPalResumeState();
|
|
4248
|
+
}
|
|
4249
|
+
}
|
|
4128
4250
|
}
|
|
4129
4251
|
await showSuccess({
|
|
4130
4252
|
result: paymentResult ? {
|
|
@@ -4141,7 +4263,8 @@ function FloPayAutomaticPaymentButton({
|
|
|
4141
4263
|
} catch (err) {
|
|
4142
4264
|
let floPayErr = normalizeSavedPaymentError(err);
|
|
4143
4265
|
const fallbackSessionId = session.id || resolvedSessionId;
|
|
4144
|
-
|
|
4266
|
+
const shouldTreatCreateSessionFlowAsServerAutoAttempt = options?.fromCreateSession && apiResult.autoProcessingAttempted === true;
|
|
4267
|
+
if (!shouldTreatCreateSessionFlowAsServerAutoAttempt && floPayErr.code === "authentication_required" && fallbackSessionId && automaticPaymentToken?.id && automaticPaymentToken.id.startsWith("pm_")) {
|
|
4145
4268
|
try {
|
|
4146
4269
|
const {
|
|
4147
4270
|
publishableKey,
|
|
@@ -4238,7 +4361,9 @@ function FloPayAutomaticPaymentButton({
|
|
|
4238
4361
|
}
|
|
4239
4362
|
try {
|
|
4240
4363
|
const result = await api.createAndFetchSession(createSessionDraft);
|
|
4241
|
-
await processResolvedSession(result, result.data.session?.id ?? null
|
|
4364
|
+
await processResolvedSession(result, result.data.session?.id ?? null, {
|
|
4365
|
+
fromCreateSession: true
|
|
4366
|
+
});
|
|
4242
4367
|
} catch (err) {
|
|
4243
4368
|
if (err instanceof import_shared10.FloPayError && err.code === "session_auto_completed") {
|
|
4244
4369
|
await showSuccess({
|
|
@@ -4454,7 +4579,7 @@ function FloPayAutomaticPaymentButton({
|
|
|
4454
4579
|
padding: "1.5rem",
|
|
4455
4580
|
zIndex: 1100
|
|
4456
4581
|
},
|
|
4457
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime9.
|
|
4582
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4458
4583
|
"div",
|
|
4459
4584
|
{
|
|
4460
4585
|
style: {
|
|
@@ -4470,48 +4595,21 @@ function FloPayAutomaticPaymentButton({
|
|
|
4470
4595
|
flexDirection: "column",
|
|
4471
4596
|
gap: "1rem"
|
|
4472
4597
|
},
|
|
4473
|
-
children:
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
color: "#b91c1c",
|
|
4489
|
-
border: "1px solid #fecaca",
|
|
4490
|
-
borderRadius: "12px",
|
|
4491
|
-
padding: "0.75rem 1rem",
|
|
4492
|
-
fontSize: "0.9rem",
|
|
4493
|
-
lineHeight: 1.5
|
|
4494
|
-
},
|
|
4495
|
-
children: fallbackSession.errorMessage
|
|
4496
|
-
}
|
|
4497
|
-
)
|
|
4498
|
-
}
|
|
4499
|
-
),
|
|
4500
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4501
|
-
FloPayCheckout,
|
|
4502
|
-
{
|
|
4503
|
-
sessionId: fallbackSession.sessionId,
|
|
4504
|
-
checkoutMode: "full",
|
|
4505
|
-
billingApiUrl: resolvedBillingUrl,
|
|
4506
|
-
fallbackPublishableKey,
|
|
4507
|
-
cardTitleContent: null,
|
|
4508
|
-
showSecurityFooter: false,
|
|
4509
|
-
onComplete: handleFallbackComplete,
|
|
4510
|
-
onError: handleFallbackError,
|
|
4511
|
-
onDecline: handleFallbackDecline
|
|
4512
|
-
}
|
|
4513
|
-
)
|
|
4514
|
-
]
|
|
4598
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4599
|
+
FloPayCheckout,
|
|
4600
|
+
{
|
|
4601
|
+
sessionId: fallbackSession.sessionId,
|
|
4602
|
+
checkoutMode: "full",
|
|
4603
|
+
billingApiUrl: resolvedBillingUrl,
|
|
4604
|
+
fallbackPublishableKey,
|
|
4605
|
+
initialErrorMessage: fallbackSession.errorMessage,
|
|
4606
|
+
cardTitleContent: null,
|
|
4607
|
+
showSecurityFooter: false,
|
|
4608
|
+
onComplete: handleFallbackComplete,
|
|
4609
|
+
onError: handleFallbackError,
|
|
4610
|
+
onDecline: handleFallbackDecline
|
|
4611
|
+
}
|
|
4612
|
+
)
|
|
4515
4613
|
}
|
|
4516
4614
|
)
|
|
4517
4615
|
}
|