@flopay/react 0.5.5 → 0.5.10
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 +91 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +91 -17
- 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,17 @@ function PayPalButtonInner({
|
|
|
756
789
|
const redirectStatus = params.get("redirect_status");
|
|
757
790
|
if (!paymentIntentId || !clientSecret) return;
|
|
758
791
|
paypalResumeAttempted.current = true;
|
|
792
|
+
console.info("[FloPay debug] PayPal resume effect firing", {
|
|
793
|
+
paymentIntentId,
|
|
794
|
+
redirectStatus,
|
|
795
|
+
currentSessionId: sessionId,
|
|
796
|
+
url: window.location.href
|
|
797
|
+
});
|
|
798
|
+
const cleanedUrl = new URL(window.location.href);
|
|
799
|
+
cleanedUrl.searchParams.delete("payment_intent");
|
|
800
|
+
cleanedUrl.searchParams.delete("payment_intent_client_secret");
|
|
801
|
+
cleanedUrl.searchParams.delete("redirect_status");
|
|
802
|
+
window.history.replaceState({}, "", cleanedUrl.toString());
|
|
759
803
|
(async () => {
|
|
760
804
|
try {
|
|
761
805
|
setSubmitting(true);
|
|
@@ -778,11 +822,6 @@ function PayPalButtonInner({
|
|
|
778
822
|
threeDSecureActionResultTokenId: paymentIntent.id,
|
|
779
823
|
isPaypal: true
|
|
780
824
|
});
|
|
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
825
|
} else {
|
|
787
826
|
const message = "PayPal payment was not completed. Please try again.";
|
|
788
827
|
onErrorChange?.(message);
|
|
@@ -810,8 +849,9 @@ function PayPalButtonInner({
|
|
|
810
849
|
accountPatch: beforeClick.accountPatch,
|
|
811
850
|
sessionId: beforeClick.sessionId
|
|
812
851
|
};
|
|
852
|
+
onButtonClick?.("paypal");
|
|
813
853
|
event.resolve();
|
|
814
|
-
}, [isProcessing, runBeforeButtonClick, submitting]);
|
|
854
|
+
}, [isProcessing, onButtonClick, runBeforeButtonClick, submitting]);
|
|
815
855
|
const handlePayPalConfirm = (0, import_react7.useCallback)(async (event) => {
|
|
816
856
|
if (!stripe || !elements) return;
|
|
817
857
|
let prepared = beforeClickRef.current;
|
|
@@ -829,7 +869,6 @@ function PayPalButtonInner({
|
|
|
829
869
|
}
|
|
830
870
|
const effectiveSessionId = prepared?.sessionId ?? sessionId;
|
|
831
871
|
const effectiveEmail = prepared?.accountPatch?.email ?? email;
|
|
832
|
-
onButtonClick?.("paypal");
|
|
833
872
|
try {
|
|
834
873
|
setSubmitting(true);
|
|
835
874
|
onErrorChange?.(null);
|
|
@@ -904,7 +943,7 @@ function PayPalButtonInner({
|
|
|
904
943
|
} finally {
|
|
905
944
|
setSubmitting(false);
|
|
906
945
|
}
|
|
907
|
-
}, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline,
|
|
946
|
+
}, [stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]);
|
|
908
947
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
909
948
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-paypal-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
910
949
|
import_react_stripe_js.ExpressCheckoutElement,
|
|
@@ -975,7 +1014,6 @@ function WalletButtonInner({
|
|
|
975
1014
|
const method = walletType === "apple_pay" ? "apple_pay" : "google_pay";
|
|
976
1015
|
const effectiveSessionId = prepared?.sessionId ?? sessionId;
|
|
977
1016
|
const effectiveEmail = prepared?.accountPatch?.email ?? email;
|
|
978
|
-
onButtonClick?.(walletType === "apple_pay" ? "apple_pay" : "google_pay");
|
|
979
1017
|
try {
|
|
980
1018
|
setSubmitting(true);
|
|
981
1019
|
onErrorChange?.(null);
|
|
@@ -1041,7 +1079,7 @@ function WalletButtonInner({
|
|
|
1041
1079
|
setSubmitting(false);
|
|
1042
1080
|
}
|
|
1043
1081
|
},
|
|
1044
|
-
[stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline,
|
|
1082
|
+
[stripe, elements, sessionId, email, baseUrl, onTokenizedBody, onErrorChange, onDecline, runBeforeButtonClick]
|
|
1045
1083
|
);
|
|
1046
1084
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1047
1085
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpressCheckoutReadySwap, { state: loadState, placeholderTestId: "flopay-wallet-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -1061,6 +1099,7 @@ function WalletButtonInner({
|
|
|
1061
1099
|
accountPatch: beforeClick.accountPatch,
|
|
1062
1100
|
sessionId: beforeClick.sessionId
|
|
1063
1101
|
};
|
|
1102
|
+
onButtonClick?.(lastWalletMethodRef.current);
|
|
1064
1103
|
event.resolve();
|
|
1065
1104
|
},
|
|
1066
1105
|
onConfirm: handleWalletConfirm,
|
|
@@ -1315,6 +1354,11 @@ function SplitCardFormInner({
|
|
|
1315
1354
|
const effectiveAccount = mergeAccountPatch(resolvedAccount, overrides?.accountPatch);
|
|
1316
1355
|
const resolvedCompletionPaymentMethodId = overrides?.completionPaymentMethodId ?? resolveTokenizedPaymentMethodId(tokenizedBody);
|
|
1317
1356
|
const requestTokenizedBody = tokenizedBody.originalPaymentMethodId ? { ...tokenizedBody, originalPaymentMethodId: void 0 } : tokenizedBody;
|
|
1357
|
+
console.info("[FloPay debug] processPaymentInternal -> POST /process", {
|
|
1358
|
+
sessionId: effectiveSessionId,
|
|
1359
|
+
paymentIntentId: tokenizedBody.threeDSecureActionResultTokenId,
|
|
1360
|
+
isPaypal: tokenizedBody.isPaypal
|
|
1361
|
+
});
|
|
1318
1362
|
try {
|
|
1319
1363
|
const response = await fetch(`${baseUrl}/v1/checkouts/sessions/process`, {
|
|
1320
1364
|
method: "POST",
|
|
@@ -1365,6 +1409,7 @@ function SplitCardFormInner({
|
|
|
1365
1409
|
})
|
|
1366
1410
|
});
|
|
1367
1411
|
if (response.ok) {
|
|
1412
|
+
markSessionRecentlyCompleted(effectiveSessionId);
|
|
1368
1413
|
setOverlayStatus("success");
|
|
1369
1414
|
await new Promise((r) => setTimeout(r, PROCESSING_OVERLAY_SUCCESS_DELAY_MS));
|
|
1370
1415
|
onComplete?.({
|
|
@@ -2777,6 +2822,7 @@ async function loadSavedPaymentProviders({
|
|
|
2777
2822
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2778
2823
|
var DEFAULT_BUTTONS_LAYOUT_BUTTON_HEIGHT2 = 44;
|
|
2779
2824
|
var PAYPAL_RESUME_STORAGE_KEY = "flopay_checkout_saved_payment_resume";
|
|
2825
|
+
var sessionInflightMap = /* @__PURE__ */ new Map();
|
|
2780
2826
|
function sleep(ms) {
|
|
2781
2827
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2782
2828
|
}
|
|
@@ -3018,6 +3064,7 @@ function FloPayCheckout({
|
|
|
3018
3064
|
}
|
|
3019
3065
|
}
|
|
3020
3066
|
}
|
|
3067
|
+
if (activeSessionId2) markSessionRecentlyCompleted(activeSessionId2);
|
|
3021
3068
|
setModeOverlayStatus("success");
|
|
3022
3069
|
await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
|
|
3023
3070
|
onCompleteRef.current?.(paymentResult);
|
|
@@ -3114,6 +3161,7 @@ function FloPayCheckout({
|
|
|
3114
3161
|
);
|
|
3115
3162
|
}
|
|
3116
3163
|
const paymentMethodId = typeof paymentIntent.payment_method === "string" ? paymentIntent.payment_method : paymentIntent.payment_method?.id;
|
|
3164
|
+
if (resumeState.sessionId) markSessionRecentlyCompleted(resumeState.sessionId);
|
|
3117
3165
|
setModeOverlayStatus("success");
|
|
3118
3166
|
await sleep(PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
|
|
3119
3167
|
onCompleteRef.current?.({
|
|
@@ -3143,13 +3191,11 @@ function FloPayCheckout({
|
|
|
3143
3191
|
}
|
|
3144
3192
|
})();
|
|
3145
3193
|
}, [emitDecline, locale, normalizeSavedPaymentError, resolvedBillingUrl]);
|
|
3146
|
-
const inflightRef = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
|
|
3147
3194
|
const initializedHashRef = (0, import_react8.useRef)(null);
|
|
3148
3195
|
function hashCreateParams(params) {
|
|
3149
3196
|
const key = JSON.stringify({
|
|
3150
3197
|
c: params?.clientId,
|
|
3151
3198
|
a: {
|
|
3152
|
-
u: params?.account?.userId ?? "",
|
|
3153
3199
|
e: params?.account?.email?.trim().toLowerCase() ?? "",
|
|
3154
3200
|
country: params?.account?.country ?? ""
|
|
3155
3201
|
},
|
|
@@ -3188,20 +3234,42 @@ function FloPayCheckout({
|
|
|
3188
3234
|
const api = new import_js2.PaymentAPI(resolvedBillingUrl);
|
|
3189
3235
|
let sid = typeof window !== "undefined" ? window.sessionStorage.getItem(cacheKey) : null;
|
|
3190
3236
|
let realResult = null;
|
|
3237
|
+
console.info("[FloPay debug] resolveInlineSession enter", {
|
|
3238
|
+
cacheKey,
|
|
3239
|
+
cachedSid: sid,
|
|
3240
|
+
url: typeof window !== "undefined" ? window.location.href : null
|
|
3241
|
+
});
|
|
3191
3242
|
if (sid) {
|
|
3192
3243
|
try {
|
|
3193
3244
|
realResult = await api.getUnifiedCheckoutSession(sid);
|
|
3194
|
-
|
|
3245
|
+
const status = realResult.data.session?.status;
|
|
3246
|
+
console.info("[FloPay debug] resolveInlineSession cache hit", {
|
|
3247
|
+
cacheKey,
|
|
3248
|
+
sid,
|
|
3249
|
+
status,
|
|
3250
|
+
recentlyCompleted: wasSessionRecentlyCompleted(sid)
|
|
3251
|
+
});
|
|
3252
|
+
if (status === "complete") {
|
|
3253
|
+
if (wasSessionRecentlyCompleted(sid)) {
|
|
3254
|
+
console.info("[FloPay debug] resolveInlineSession reuse-completed", { sid });
|
|
3255
|
+
return { sid, result: realResult };
|
|
3256
|
+
}
|
|
3257
|
+
console.warn("[FloPay debug] resolveInlineSession clearing stale complete cache", { sid });
|
|
3195
3258
|
if (typeof window !== "undefined") window.sessionStorage.removeItem(cacheKey);
|
|
3196
3259
|
sid = null;
|
|
3197
3260
|
realResult = null;
|
|
3198
3261
|
}
|
|
3199
|
-
} catch {
|
|
3262
|
+
} catch (err) {
|
|
3263
|
+
console.warn("[FloPay debug] resolveInlineSession getUnifiedCheckoutSession threw", { sid, err });
|
|
3200
3264
|
if (typeof window !== "undefined") window.sessionStorage.removeItem(cacheKey);
|
|
3201
3265
|
sid = null;
|
|
3202
3266
|
}
|
|
3203
3267
|
}
|
|
3204
3268
|
if (!sid) {
|
|
3269
|
+
console.warn("[FloPay debug] resolveInlineSession POSTing /v1/checkouts/sessions", {
|
|
3270
|
+
cacheKey,
|
|
3271
|
+
url: typeof window !== "undefined" ? window.location.href : null
|
|
3272
|
+
});
|
|
3205
3273
|
const paramsWithAnalytics = {
|
|
3206
3274
|
...params,
|
|
3207
3275
|
avsCheck: !!enableAVS,
|
|
@@ -3225,16 +3293,22 @@ function FloPayCheckout({
|
|
|
3225
3293
|
}
|
|
3226
3294
|
const mergedParams = mergeInlineSessionPatch(baseParams, patch);
|
|
3227
3295
|
const cacheKey = hashCreateParams(mergedParams);
|
|
3228
|
-
let promise =
|
|
3296
|
+
let promise = sessionInflightMap.get(cacheKey);
|
|
3297
|
+
const inflightHit = !!promise;
|
|
3229
3298
|
if (!promise) {
|
|
3230
3299
|
promise = resolveInlineSession(mergedParams, cacheKey);
|
|
3231
|
-
|
|
3300
|
+
sessionInflightMap.set(cacheKey, promise);
|
|
3232
3301
|
}
|
|
3302
|
+
console.info("[FloPay debug] bootstrapInlineSession", {
|
|
3303
|
+
cacheKey,
|
|
3304
|
+
inflightHit,
|
|
3305
|
+
url: typeof window !== "undefined" ? window.location.href : null
|
|
3306
|
+
});
|
|
3233
3307
|
let resolved;
|
|
3234
3308
|
try {
|
|
3235
3309
|
resolved = await promise;
|
|
3236
3310
|
} finally {
|
|
3237
|
-
|
|
3311
|
+
sessionInflightMap.delete(cacheKey);
|
|
3238
3312
|
}
|
|
3239
3313
|
initializedHashRef.current = cacheKey;
|
|
3240
3314
|
try {
|