@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.mjs
CHANGED
|
@@ -588,6 +588,39 @@ function resolveTokenizedPaymentMethodId(tokenizedBody) {
|
|
|
588
588
|
return void 0;
|
|
589
589
|
}
|
|
590
590
|
|
|
591
|
+
// src/recent-completion.ts
|
|
592
|
+
var STORAGE_KEY_PREFIX = "flopay_recent_completion_";
|
|
593
|
+
var RECENT_COMPLETION_TTL_MS = 60 * 1e3;
|
|
594
|
+
function markSessionRecentlyCompleted(sessionId) {
|
|
595
|
+
if (!sessionId || typeof window === "undefined") return;
|
|
596
|
+
try {
|
|
597
|
+
const payload = {
|
|
598
|
+
expiresAt: Date.now() + RECENT_COMPLETION_TTL_MS
|
|
599
|
+
};
|
|
600
|
+
window.sessionStorage.setItem(STORAGE_KEY_PREFIX + sessionId, JSON.stringify(payload));
|
|
601
|
+
} catch {
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
function wasSessionRecentlyCompleted(sessionId) {
|
|
605
|
+
if (!sessionId || typeof window === "undefined") return false;
|
|
606
|
+
try {
|
|
607
|
+
const raw = window.sessionStorage.getItem(STORAGE_KEY_PREFIX + sessionId);
|
|
608
|
+
if (!raw) return false;
|
|
609
|
+
const parsed = JSON.parse(raw);
|
|
610
|
+
if (typeof parsed?.expiresAt !== "number") {
|
|
611
|
+
window.sessionStorage.removeItem(STORAGE_KEY_PREFIX + sessionId);
|
|
612
|
+
return false;
|
|
613
|
+
}
|
|
614
|
+
if (parsed.expiresAt <= Date.now()) {
|
|
615
|
+
window.sessionStorage.removeItem(STORAGE_KEY_PREFIX + sessionId);
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
618
|
+
return true;
|
|
619
|
+
} catch {
|
|
620
|
+
return false;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
591
624
|
// src/split-card-form.tsx
|
|
592
625
|
import { FloPayError as FloPayError2 } from "@flopay/shared";
|
|
593
626
|
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
@@ -719,6 +752,11 @@ function PayPalButtonInner({
|
|
|
719
752
|
const redirectStatus = params.get("redirect_status");
|
|
720
753
|
if (!paymentIntentId || !clientSecret) return;
|
|
721
754
|
paypalResumeAttempted.current = true;
|
|
755
|
+
const cleanedUrl = new URL(window.location.href);
|
|
756
|
+
cleanedUrl.searchParams.delete("payment_intent");
|
|
757
|
+
cleanedUrl.searchParams.delete("payment_intent_client_secret");
|
|
758
|
+
cleanedUrl.searchParams.delete("redirect_status");
|
|
759
|
+
window.history.replaceState({}, "", cleanedUrl.toString());
|
|
722
760
|
(async () => {
|
|
723
761
|
try {
|
|
724
762
|
setSubmitting(true);
|
|
@@ -741,11 +779,6 @@ function PayPalButtonInner({
|
|
|
741
779
|
threeDSecureActionResultTokenId: paymentIntent.id,
|
|
742
780
|
isPaypal: true
|
|
743
781
|
});
|
|
744
|
-
const url = new URL(window.location.href);
|
|
745
|
-
url.searchParams.delete("payment_intent");
|
|
746
|
-
url.searchParams.delete("payment_intent_client_secret");
|
|
747
|
-
url.searchParams.delete("redirect_status");
|
|
748
|
-
window.history.replaceState({}, "", url.toString());
|
|
749
782
|
} else {
|
|
750
783
|
const message = "PayPal payment was not completed. Please try again.";
|
|
751
784
|
onErrorChange?.(message);
|
|
@@ -1328,6 +1361,7 @@ function SplitCardFormInner({
|
|
|
1328
1361
|
})
|
|
1329
1362
|
});
|
|
1330
1363
|
if (response.ok) {
|
|
1364
|
+
markSessionRecentlyCompleted(effectiveSessionId);
|
|
1331
1365
|
setOverlayStatus("success");
|
|
1332
1366
|
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));
|
|
1333
1367
|
onComplete?.({
|
|
@@ -2982,6 +3016,7 @@ function FloPayCheckout({
|
|
|
2982
3016
|
}
|
|
2983
3017
|
}
|
|
2984
3018
|
}
|
|
3019
|
+
if (activeSessionId2) markSessionRecentlyCompleted(activeSessionId2);
|
|
2985
3020
|
setModeOverlayStatus("success");
|
|
2986
3021
|
await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
|
|
2987
3022
|
onCompleteRef.current?.(paymentResult);
|
|
@@ -3078,6 +3113,31 @@ function FloPayCheckout({
|
|
|
3078
3113
|
);
|
|
3079
3114
|
}
|
|
3080
3115
|
const paymentMethodId = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
3116
|
+
if (resumeState.sessionId) {
|
|
3117
|
+
const resumeApi = new PaymentAPI2(resolvedBillingUrl);
|
|
3118
|
+
const resumeSessionResult = await resumeApi.getUnifiedCheckoutSession(resumeState.sessionId);
|
|
3119
|
+
const resumeSession = resumeSessionResult.data.session;
|
|
3120
|
+
if (resumeSession && resumeSession.status !== "complete") {
|
|
3121
|
+
const processResult = await processSavedPaymentForMode({
|
|
3122
|
+
billingApiUrl: resolvedBillingUrl,
|
|
3123
|
+
sessionId: resumeState.sessionId,
|
|
3124
|
+
session: resumeSession,
|
|
3125
|
+
tokenizedData: {
|
|
3126
|
+
id: paymentMethodId ?? paymentIntent.id,
|
|
3127
|
+
type: "card",
|
|
3128
|
+
threeDSecureActionResultTokenId: paymentIntent.id,
|
|
3129
|
+
isPaypal: true
|
|
3130
|
+
}
|
|
3131
|
+
});
|
|
3132
|
+
if (processResult.type !== "success") {
|
|
3133
|
+
throw Object.assign(
|
|
3134
|
+
new FloPayError4("Failed to finalize PayPal payment.", "api_error"),
|
|
3135
|
+
{ checkoutMethod: "paypal" }
|
|
3136
|
+
);
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
if (resumeState.sessionId) markSessionRecentlyCompleted(resumeState.sessionId);
|
|
3081
3141
|
setModeOverlayStatus("success");
|
|
3082
3142
|
await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
|
|
3083
3143
|
onCompleteRef.current?.({
|
|
@@ -3112,7 +3172,6 @@ function FloPayCheckout({
|
|
|
3112
3172
|
const key = JSON.stringify({
|
|
3113
3173
|
c: params?.clientId,
|
|
3114
3174
|
a: {
|
|
3115
|
-
u: params?.account?.userId ?? "",
|
|
3116
3175
|
e: params?.account?.email?.trim().toLowerCase() ?? "",
|
|
3117
3176
|
country: params?.account?.country ?? ""
|
|
3118
3177
|
},
|
|
@@ -3154,7 +3213,11 @@ function FloPayCheckout({
|
|
|
3154
3213
|
if (sid) {
|
|
3155
3214
|
try {
|
|
3156
3215
|
realResult = await api.getUnifiedCheckoutSession(sid);
|
|
3157
|
-
|
|
3216
|
+
const status = realResult.data.session?.status;
|
|
3217
|
+
if (status === "complete") {
|
|
3218
|
+
if (wasSessionRecentlyCompleted(sid)) {
|
|
3219
|
+
return { sid, result: realResult };
|
|
3220
|
+
}
|
|
3158
3221
|
if (typeof window !== "undefined") window.sessionStorage.removeItem(cacheKey);
|
|
3159
3222
|
sid = null;
|
|
3160
3223
|
realResult = null;
|
|
@@ -4819,6 +4882,10 @@ function FloPayAutomaticPaymentButton({
|
|
|
4819
4882
|
floPayErr = normalizeSavedPaymentError(intentRecoveryErr);
|
|
4820
4883
|
}
|
|
4821
4884
|
}
|
|
4885
|
+
const inResumeWindow = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("payment_intent_client_secret") && !!readPayPalResumeState2();
|
|
4886
|
+
if (floPayErr.code === "payment_intent_unexpected_state" && inResumeWindow) {
|
|
4887
|
+
return;
|
|
4888
|
+
}
|
|
4822
4889
|
await showError(floPayErr, {
|
|
4823
4890
|
emitDecline: true,
|
|
4824
4891
|
method: floPayErr.checkoutMethod ?? DEFAULT_SAVED_PAYMENT_DECLINE_METHOD
|
|
@@ -4990,25 +5057,58 @@ function FloPayAutomaticPaymentButton({
|
|
|
4990
5057
|
);
|
|
4991
5058
|
}
|
|
4992
5059
|
const resultStatus = mapPayPalIntentStatusToPaymentResult(paymentIntent?.status);
|
|
4993
|
-
if (paymentIntent
|
|
4994
|
-
const paymentMethodId2 = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
4995
|
-
await showSuccess({
|
|
4996
|
-
result: {
|
|
4997
|
-
status: resultStatus,
|
|
4998
|
-
paymentIntentId: paymentIntent.id,
|
|
4999
|
-
paymentMethodId: paymentMethodId2,
|
|
5000
|
-
checkoutMethod: "paypal"
|
|
5001
|
-
},
|
|
5002
|
-
session: null,
|
|
5003
|
-
sessionId: resumeState.sessionId,
|
|
5004
|
-
autoCompleted: false
|
|
5005
|
-
});
|
|
5006
|
-
} else {
|
|
5060
|
+
if (!paymentIntent || resultStatus === "failed") {
|
|
5007
5061
|
throw Object.assign(
|
|
5008
5062
|
new FloPayError7("PayPal payment was not completed. Please try again.", "api_error"),
|
|
5009
5063
|
{ checkoutMethod: "paypal" }
|
|
5010
5064
|
);
|
|
5011
5065
|
}
|
|
5066
|
+
const paymentMethodId2 = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
5067
|
+
if (!resumeState.sessionId) {
|
|
5068
|
+
throw Object.assign(
|
|
5069
|
+
new FloPayError7("Missing session id on PayPal resume.", "api_error"),
|
|
5070
|
+
{ checkoutMethod: "paypal" }
|
|
5071
|
+
);
|
|
5072
|
+
}
|
|
5073
|
+
const api = new PaymentAPI3(resolvedBillingUrl);
|
|
5074
|
+
const sessionResult = await api.getUnifiedCheckoutSession(resumeState.sessionId);
|
|
5075
|
+
const resumeSession = sessionResult.data.session;
|
|
5076
|
+
if (!resumeSession) {
|
|
5077
|
+
throw Object.assign(
|
|
5078
|
+
new FloPayError7("Could not load session to capture PayPal payment.", "api_error"),
|
|
5079
|
+
{ checkoutMethod: "paypal" }
|
|
5080
|
+
);
|
|
5081
|
+
}
|
|
5082
|
+
if (resumeSession.status !== "complete") {
|
|
5083
|
+
const processResult = await processSavedPaymentForMode({
|
|
5084
|
+
billingApiUrl: resolvedBillingUrl,
|
|
5085
|
+
sessionId: resumeState.sessionId,
|
|
5086
|
+
session: resumeSession,
|
|
5087
|
+
tokenizedData: {
|
|
5088
|
+
id: paymentMethodId2 ?? paymentIntent.id,
|
|
5089
|
+
type: "card",
|
|
5090
|
+
threeDSecureActionResultTokenId: paymentIntent.id,
|
|
5091
|
+
isPaypal: true
|
|
5092
|
+
}
|
|
5093
|
+
});
|
|
5094
|
+
if (processResult.type !== "success") {
|
|
5095
|
+
throw Object.assign(
|
|
5096
|
+
new FloPayError7("Failed to finalize PayPal payment.", "api_error"),
|
|
5097
|
+
{ checkoutMethod: "paypal" }
|
|
5098
|
+
);
|
|
5099
|
+
}
|
|
5100
|
+
}
|
|
5101
|
+
await showSuccess({
|
|
5102
|
+
result: {
|
|
5103
|
+
status: resultStatus,
|
|
5104
|
+
paymentIntentId: paymentIntent.id,
|
|
5105
|
+
paymentMethodId: paymentMethodId2,
|
|
5106
|
+
checkoutMethod: "paypal"
|
|
5107
|
+
},
|
|
5108
|
+
session: resumeSession,
|
|
5109
|
+
sessionId: resumeState.sessionId,
|
|
5110
|
+
autoCompleted: false
|
|
5111
|
+
});
|
|
5012
5112
|
} catch (err) {
|
|
5013
5113
|
const floPayErr = normalizeSavedPaymentError(err);
|
|
5014
5114
|
await showError(floPayErr, {
|