@flopay/react 0.5.6 → 0.5.11
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 +121 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +121 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -625,6 +625,39 @@ function resolveTokenizedPaymentMethodId(tokenizedBody) {
|
|
|
625
625
|
return void 0;
|
|
626
626
|
}
|
|
627
627
|
|
|
628
|
+
// src/recent-completion.ts
|
|
629
|
+
var STORAGE_KEY_PREFIX = "flopay_recent_completion_";
|
|
630
|
+
var RECENT_COMPLETION_TTL_MS = 60 * 1e3;
|
|
631
|
+
function markSessionRecentlyCompleted(sessionId) {
|
|
632
|
+
if (!sessionId || typeof window === "undefined") return;
|
|
633
|
+
try {
|
|
634
|
+
const payload = {
|
|
635
|
+
expiresAt: Date.now() + RECENT_COMPLETION_TTL_MS
|
|
636
|
+
};
|
|
637
|
+
window.sessionStorage.setItem(STORAGE_KEY_PREFIX + sessionId, JSON.stringify(payload));
|
|
638
|
+
} catch {
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
function wasSessionRecentlyCompleted(sessionId) {
|
|
642
|
+
if (!sessionId || typeof window === "undefined") return false;
|
|
643
|
+
try {
|
|
644
|
+
const raw = window.sessionStorage.getItem(STORAGE_KEY_PREFIX + sessionId);
|
|
645
|
+
if (!raw) return false;
|
|
646
|
+
const parsed = JSON.parse(raw);
|
|
647
|
+
if (typeof parsed?.expiresAt !== "number") {
|
|
648
|
+
window.sessionStorage.removeItem(STORAGE_KEY_PREFIX + sessionId);
|
|
649
|
+
return false;
|
|
650
|
+
}
|
|
651
|
+
if (parsed.expiresAt <= Date.now()) {
|
|
652
|
+
window.sessionStorage.removeItem(STORAGE_KEY_PREFIX + sessionId);
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
return true;
|
|
656
|
+
} catch {
|
|
657
|
+
return false;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
628
661
|
// src/split-card-form.tsx
|
|
629
662
|
var import_shared5 = require("@flopay/shared");
|
|
630
663
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
@@ -756,6 +789,11 @@ function PayPalButtonInner({
|
|
|
756
789
|
const redirectStatus = params.get("redirect_status");
|
|
757
790
|
if (!paymentIntentId || !clientSecret) return;
|
|
758
791
|
paypalResumeAttempted.current = true;
|
|
792
|
+
const cleanedUrl = new URL(window.location.href);
|
|
793
|
+
cleanedUrl.searchParams.delete("payment_intent");
|
|
794
|
+
cleanedUrl.searchParams.delete("payment_intent_client_secret");
|
|
795
|
+
cleanedUrl.searchParams.delete("redirect_status");
|
|
796
|
+
window.history.replaceState({}, "", cleanedUrl.toString());
|
|
759
797
|
(async () => {
|
|
760
798
|
try {
|
|
761
799
|
setSubmitting(true);
|
|
@@ -778,11 +816,6 @@ function PayPalButtonInner({
|
|
|
778
816
|
threeDSecureActionResultTokenId: paymentIntent.id,
|
|
779
817
|
isPaypal: true
|
|
780
818
|
});
|
|
781
|
-
const url = new URL(window.location.href);
|
|
782
|
-
url.searchParams.delete("payment_intent");
|
|
783
|
-
url.searchParams.delete("payment_intent_client_secret");
|
|
784
|
-
url.searchParams.delete("redirect_status");
|
|
785
|
-
window.history.replaceState({}, "", url.toString());
|
|
786
819
|
} else {
|
|
787
820
|
const message = "PayPal payment was not completed. Please try again.";
|
|
788
821
|
onErrorChange?.(message);
|
|
@@ -1365,6 +1398,7 @@ function SplitCardFormInner({
|
|
|
1365
1398
|
})
|
|
1366
1399
|
});
|
|
1367
1400
|
if (response.ok) {
|
|
1401
|
+
markSessionRecentlyCompleted(effectiveSessionId);
|
|
1368
1402
|
setOverlayStatus("success");
|
|
1369
1403
|
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));
|
|
1370
1404
|
onComplete?.({
|
|
@@ -3019,6 +3053,7 @@ function FloPayCheckout({
|
|
|
3019
3053
|
}
|
|
3020
3054
|
}
|
|
3021
3055
|
}
|
|
3056
|
+
if (activeSessionId2) markSessionRecentlyCompleted(activeSessionId2);
|
|
3022
3057
|
setModeOverlayStatus("success");
|
|
3023
3058
|
await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
|
|
3024
3059
|
onCompleteRef.current?.(paymentResult);
|
|
@@ -3115,6 +3150,31 @@ function FloPayCheckout({
|
|
|
3115
3150
|
);
|
|
3116
3151
|
}
|
|
3117
3152
|
const paymentMethodId = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
3153
|
+
if (resumeState.sessionId) {
|
|
3154
|
+
const resumeApi = new import_js2.PaymentAPI(resolvedBillingUrl);
|
|
3155
|
+
const resumeSessionResult = await resumeApi.getUnifiedCheckoutSession(resumeState.sessionId);
|
|
3156
|
+
const resumeSession = resumeSessionResult.data.session;
|
|
3157
|
+
if (resumeSession && resumeSession.status !== "complete") {
|
|
3158
|
+
const processResult = await processSavedPaymentForMode({
|
|
3159
|
+
billingApiUrl: resolvedBillingUrl,
|
|
3160
|
+
sessionId: resumeState.sessionId,
|
|
3161
|
+
session: resumeSession,
|
|
3162
|
+
tokenizedData: {
|
|
3163
|
+
id: paymentMethodId ?? paymentIntent.id,
|
|
3164
|
+
type: "card",
|
|
3165
|
+
threeDSecureActionResultTokenId: paymentIntent.id,
|
|
3166
|
+
isPaypal: true
|
|
3167
|
+
}
|
|
3168
|
+
});
|
|
3169
|
+
if (processResult.type !== "success") {
|
|
3170
|
+
throw Object.assign(
|
|
3171
|
+
new import_shared7.FloPayError("Failed to finalize PayPal payment.", "api_error"),
|
|
3172
|
+
{ checkoutMethod: "paypal" }
|
|
3173
|
+
);
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
if (resumeState.sessionId) markSessionRecentlyCompleted(resumeState.sessionId);
|
|
3118
3178
|
setModeOverlayStatus("success");
|
|
3119
3179
|
await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
|
|
3120
3180
|
onCompleteRef.current?.({
|
|
@@ -3149,7 +3209,6 @@ function FloPayCheckout({
|
|
|
3149
3209
|
const key = JSON.stringify({
|
|
3150
3210
|
c: params?.clientId,
|
|
3151
3211
|
a: {
|
|
3152
|
-
u: params?.account?.userId ?? "",
|
|
3153
3212
|
e: params?.account?.email?.trim().toLowerCase() ?? "",
|
|
3154
3213
|
country: params?.account?.country ?? ""
|
|
3155
3214
|
},
|
|
@@ -3191,7 +3250,11 @@ function FloPayCheckout({
|
|
|
3191
3250
|
if (sid) {
|
|
3192
3251
|
try {
|
|
3193
3252
|
realResult = await api.getUnifiedCheckoutSession(sid);
|
|
3194
|
-
|
|
3253
|
+
const status = realResult.data.session?.status;
|
|
3254
|
+
if (status === "complete") {
|
|
3255
|
+
if (wasSessionRecentlyCompleted(sid)) {
|
|
3256
|
+
return { sid, result: realResult };
|
|
3257
|
+
}
|
|
3195
3258
|
if (typeof window !== "undefined") window.sessionStorage.removeItem(cacheKey);
|
|
3196
3259
|
sid = null;
|
|
3197
3260
|
realResult = null;
|
|
@@ -4856,6 +4919,10 @@ function FloPayAutomaticPaymentButton({
|
|
|
4856
4919
|
floPayErr = normalizeSavedPaymentError(intentRecoveryErr);
|
|
4857
4920
|
}
|
|
4858
4921
|
}
|
|
4922
|
+
const inResumeWindow = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("payment_intent_client_secret") && !!readPayPalResumeState2();
|
|
4923
|
+
if (floPayErr.code === "payment_intent_unexpected_state" && inResumeWindow) {
|
|
4924
|
+
return;
|
|
4925
|
+
}
|
|
4859
4926
|
await showError(floPayErr, {
|
|
4860
4927
|
emitDecline: true,
|
|
4861
4928
|
method: floPayErr.checkoutMethod ?? DEFAULT_SAVED_PAYMENT_DECLINE_METHOD
|
|
@@ -5027,25 +5094,58 @@ function FloPayAutomaticPaymentButton({
|
|
|
5027
5094
|
);
|
|
5028
5095
|
}
|
|
5029
5096
|
const resultStatus = mapPayPalIntentStatusToPaymentResult(paymentIntent?.status);
|
|
5030
|
-
if (paymentIntent
|
|
5031
|
-
const paymentMethodId2 = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
5032
|
-
await showSuccess({
|
|
5033
|
-
result: {
|
|
5034
|
-
status: resultStatus,
|
|
5035
|
-
paymentIntentId: paymentIntent.id,
|
|
5036
|
-
paymentMethodId: paymentMethodId2,
|
|
5037
|
-
checkoutMethod: "paypal"
|
|
5038
|
-
},
|
|
5039
|
-
session: null,
|
|
5040
|
-
sessionId: resumeState.sessionId,
|
|
5041
|
-
autoCompleted: false
|
|
5042
|
-
});
|
|
5043
|
-
} else {
|
|
5097
|
+
if (!paymentIntent || resultStatus === "failed") {
|
|
5044
5098
|
throw Object.assign(
|
|
5045
5099
|
new import_shared10.FloPayError("PayPal payment was not completed. Please try again.", "api_error"),
|
|
5046
5100
|
{ checkoutMethod: "paypal" }
|
|
5047
5101
|
);
|
|
5048
5102
|
}
|
|
5103
|
+
const paymentMethodId2 = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
5104
|
+
if (!resumeState.sessionId) {
|
|
5105
|
+
throw Object.assign(
|
|
5106
|
+
new import_shared10.FloPayError("Missing session id on PayPal resume.", "api_error"),
|
|
5107
|
+
{ checkoutMethod: "paypal" }
|
|
5108
|
+
);
|
|
5109
|
+
}
|
|
5110
|
+
const api = new import_js3.PaymentAPI(resolvedBillingUrl);
|
|
5111
|
+
const sessionResult = await api.getUnifiedCheckoutSession(resumeState.sessionId);
|
|
5112
|
+
const resumeSession = sessionResult.data.session;
|
|
5113
|
+
if (!resumeSession) {
|
|
5114
|
+
throw Object.assign(
|
|
5115
|
+
new import_shared10.FloPayError("Could not load session to capture PayPal payment.", "api_error"),
|
|
5116
|
+
{ checkoutMethod: "paypal" }
|
|
5117
|
+
);
|
|
5118
|
+
}
|
|
5119
|
+
if (resumeSession.status !== "complete") {
|
|
5120
|
+
const processResult = await processSavedPaymentForMode({
|
|
5121
|
+
billingApiUrl: resolvedBillingUrl,
|
|
5122
|
+
sessionId: resumeState.sessionId,
|
|
5123
|
+
session: resumeSession,
|
|
5124
|
+
tokenizedData: {
|
|
5125
|
+
id: paymentMethodId2 ?? paymentIntent.id,
|
|
5126
|
+
type: "card",
|
|
5127
|
+
threeDSecureActionResultTokenId: paymentIntent.id,
|
|
5128
|
+
isPaypal: true
|
|
5129
|
+
}
|
|
5130
|
+
});
|
|
5131
|
+
if (processResult.type !== "success") {
|
|
5132
|
+
throw Object.assign(
|
|
5133
|
+
new import_shared10.FloPayError("Failed to finalize PayPal payment.", "api_error"),
|
|
5134
|
+
{ checkoutMethod: "paypal" }
|
|
5135
|
+
);
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
await showSuccess({
|
|
5139
|
+
result: {
|
|
5140
|
+
status: resultStatus,
|
|
5141
|
+
paymentIntentId: paymentIntent.id,
|
|
5142
|
+
paymentMethodId: paymentMethodId2,
|
|
5143
|
+
checkoutMethod: "paypal"
|
|
5144
|
+
},
|
|
5145
|
+
session: resumeSession,
|
|
5146
|
+
sessionId: resumeState.sessionId,
|
|
5147
|
+
autoCompleted: false
|
|
5148
|
+
});
|
|
5049
5149
|
} catch (err) {
|
|
5050
5150
|
const floPayErr = normalizeSavedPaymentError(err);
|
|
5051
5151
|
await showError(floPayErr, {
|