@easypayment/medusa-paypal-ui 1.0.51 → 1.0.53
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 +444 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.mjs +452 -93
- package/dist/index.mjs.map +1 -1
- package/dist/order.cjs +20 -7
- package/dist/order.cjs.map +1 -1
- package/dist/order.mjs +20 -7
- package/dist/order.mjs.map +1 -1
- package/package.json +11 -1
- package/src/adapters/MedusaNextPayPalAdapter.tsx +5 -2
- package/src/client/http.ts +18 -1
- package/src/client/paypal.ts +7 -17
- package/src/components/PayPalAdvancedCard.tsx +177 -29
- package/src/components/PayPalCurrencyNotice.tsx +1 -1
- package/src/components/PayPalPaymentSection.tsx +7 -2
- package/src/components/PayPalProvider.tsx +1 -1
- package/src/components/PayPalSmartButtons.tsx +133 -30
- package/src/hooks/usePayPalConfig.ts +13 -4
- package/src/hooks/usePayPalPaymentMethods.ts +14 -4
- package/src/index.ts +1 -0
- package/src/order.ts +20 -7
- package/src/utils/next-errors.ts +17 -0
- package/src/utils/processing-overlay.ts +55 -0
package/dist/index.cjs
CHANGED
|
@@ -30,8 +30,10 @@ __export(index_exports, {
|
|
|
30
30
|
PayPalProvider: () => PayPalProvider,
|
|
31
31
|
PayPalSmartButtons: () => PayPalSmartButtons,
|
|
32
32
|
createPayPalStoreApi: () => createPayPalStoreApi,
|
|
33
|
+
hideProcessingOverlay: () => hideProcessingOverlay,
|
|
33
34
|
isPayPalProviderId: () => isPayPalProviderId,
|
|
34
35
|
markPaymentComplete: () => markPaymentComplete,
|
|
36
|
+
showProcessingOverlay: () => showProcessingOverlay,
|
|
35
37
|
usePayPalConfig: () => usePayPalConfig,
|
|
36
38
|
usePayPalPaymentMethods: () => usePayPalPaymentMethods
|
|
37
39
|
});
|
|
@@ -61,7 +63,24 @@ function createHttpClient(opts) {
|
|
|
61
63
|
if (opts.publishableApiKey) {
|
|
62
64
|
headers["x-publishable-api-key"] = opts.publishableApiKey;
|
|
63
65
|
}
|
|
64
|
-
const
|
|
66
|
+
const timeoutMs = 3e4;
|
|
67
|
+
let timeoutId;
|
|
68
|
+
const controller = new AbortController();
|
|
69
|
+
if (!init?.signal) {
|
|
70
|
+
timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
71
|
+
}
|
|
72
|
+
const effectiveSignal = init?.signal || controller.signal;
|
|
73
|
+
let res;
|
|
74
|
+
try {
|
|
75
|
+
res = await fetch(url, { ...init, headers, credentials: "include", signal: effectiveSignal });
|
|
76
|
+
} catch (err) {
|
|
77
|
+
if (err instanceof Error && err.name === "AbortError" && !init?.signal) {
|
|
78
|
+
throw new Error(`[PayPal] Request to ${path} timed out after ${timeoutMs / 1e3}s`);
|
|
79
|
+
}
|
|
80
|
+
throw err;
|
|
81
|
+
} finally {
|
|
82
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
83
|
+
}
|
|
65
84
|
const text = await res.text().catch(() => "");
|
|
66
85
|
if (!res.ok) {
|
|
67
86
|
if (res.status === 401) {
|
|
@@ -98,22 +117,12 @@ function createHttpClient(opts) {
|
|
|
98
117
|
|
|
99
118
|
// src/client/paypal.ts
|
|
100
119
|
async function markPaymentComplete(baseUrl, cartId, publishableApiKey) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
},
|
|
108
|
-
body: JSON.stringify({ cart_id: cartId }),
|
|
109
|
-
credentials: "include"
|
|
110
|
-
});
|
|
111
|
-
const data = await resp.json().catch(() => ({}));
|
|
112
|
-
return data || {};
|
|
113
|
-
} catch (e) {
|
|
114
|
-
console.warn("[PayPal] paypal-complete call failed:", e);
|
|
115
|
-
return {};
|
|
116
|
-
}
|
|
120
|
+
const http = createHttpClient({ baseUrl, publishableApiKey });
|
|
121
|
+
return http.request(`/store/paypal-complete`, {
|
|
122
|
+
method: "POST",
|
|
123
|
+
headers: { "Content-Type": "application/json" },
|
|
124
|
+
body: JSON.stringify({ cart_id: cartId })
|
|
125
|
+
});
|
|
117
126
|
}
|
|
118
127
|
function createPayPalStoreApi(opts) {
|
|
119
128
|
const http = createHttpClient(opts);
|
|
@@ -144,8 +153,16 @@ function createPayPalStoreApi(opts) {
|
|
|
144
153
|
|
|
145
154
|
// src/hooks/usePayPalConfig.ts
|
|
146
155
|
var import_react = require("react");
|
|
156
|
+
var MAX_CACHE_ENTRIES = 50;
|
|
147
157
|
var _cache = /* @__PURE__ */ new Map();
|
|
148
158
|
var CACHE_TTL = 5 * 60 * 1e3;
|
|
159
|
+
function cacheSet(key, value) {
|
|
160
|
+
if (_cache.size >= MAX_CACHE_ENTRIES) {
|
|
161
|
+
const oldest = _cache.keys().next().value;
|
|
162
|
+
if (oldest !== void 0) _cache.delete(oldest);
|
|
163
|
+
}
|
|
164
|
+
_cache.set(key, value);
|
|
165
|
+
}
|
|
149
166
|
function cacheKey(baseUrl, cartId) {
|
|
150
167
|
return `${baseUrl}::${cartId ?? ""}`;
|
|
151
168
|
}
|
|
@@ -189,12 +206,12 @@ function usePayPalConfig({
|
|
|
189
206
|
try {
|
|
190
207
|
const cfg = await api.getConfig(cartId, controller.signal);
|
|
191
208
|
if (!mounted || id !== fetchIdRef.current) return;
|
|
192
|
-
|
|
209
|
+
cacheSet(k, { config: cfg, at: Date.now() });
|
|
193
210
|
setConfig(cfg);
|
|
194
211
|
} catch (e) {
|
|
195
|
-
if (e
|
|
212
|
+
if (e instanceof Error && e.name === "AbortError") return;
|
|
196
213
|
if (!mounted || id !== fetchIdRef.current) return;
|
|
197
|
-
setError(e
|
|
214
|
+
setError(e instanceof Error ? e.message : "Failed to load PayPal config");
|
|
198
215
|
} finally {
|
|
199
216
|
if (mounted && id === fetchIdRef.current) setLoading(false);
|
|
200
217
|
}
|
|
@@ -224,7 +241,7 @@ function PayPalProvider(props) {
|
|
|
224
241
|
"disable-funding": disableFunding,
|
|
225
242
|
"data-partner-attribution-id": BN_CODE
|
|
226
243
|
};
|
|
227
|
-
}, [config, intent, disableFunding]);
|
|
244
|
+
}, [config.client_id, config.currency, config.client_token, intent, disableFunding]);
|
|
228
245
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
229
246
|
import_react_paypal_js.PayPalScriptProvider,
|
|
230
247
|
{
|
|
@@ -239,7 +256,7 @@ function PayPalProvider(props) {
|
|
|
239
256
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
240
257
|
function PayPalCurrencyNotice({ config }) {
|
|
241
258
|
if (config.currency_supported) return null;
|
|
242
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { padding: 12, border: "1px solid #ddd", borderRadius: 10 }, children: [
|
|
259
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { role: "alert", style: { padding: 12, border: "1px solid #ddd", borderRadius: 10 }, children: [
|
|
243
260
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "PayPal currency issue" }),
|
|
244
261
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { style: { margin: 0, paddingLeft: 18 }, children: (config.currency_errors || []).map((e) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: e }, e)) })
|
|
245
262
|
] });
|
|
@@ -248,8 +265,71 @@ function PayPalCurrencyNotice({ config }) {
|
|
|
248
265
|
// src/components/PayPalSmartButtons.tsx
|
|
249
266
|
var import_react3 = require("react");
|
|
250
267
|
var import_react_paypal_js2 = require("@paypal/react-paypal-js");
|
|
268
|
+
|
|
269
|
+
// src/utils/next-errors.ts
|
|
270
|
+
function isNextRouterError(e) {
|
|
271
|
+
if (typeof e !== "object" || e === null || !("digest" in e)) return false;
|
|
272
|
+
const digest = e.digest;
|
|
273
|
+
return typeof digest === "string" && (digest.startsWith("NEXT_REDIRECT") || digest.startsWith("NEXT_NOT_FOUND"));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// src/utils/processing-overlay.ts
|
|
277
|
+
var OVERLAY_ID = "__pp_processing_overlay";
|
|
278
|
+
function showProcessingOverlay() {
|
|
279
|
+
if (typeof document === "undefined") return;
|
|
280
|
+
if (document.getElementById(OVERLAY_ID)) return;
|
|
281
|
+
const overlay = document.createElement("div");
|
|
282
|
+
overlay.id = OVERLAY_ID;
|
|
283
|
+
overlay.setAttribute("role", "status");
|
|
284
|
+
overlay.setAttribute("aria-label", "Processing payment");
|
|
285
|
+
overlay.innerHTML = `
|
|
286
|
+
<style>
|
|
287
|
+
@keyframes _pp_spin { to { transform: rotate(360deg) } }
|
|
288
|
+
@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }
|
|
289
|
+
</style>
|
|
290
|
+
<div style="position:relative;width:56px;height:56px">
|
|
291
|
+
<div style="position:absolute;inset:0;border-radius:50%;border:3px solid #e5e7eb"></div>
|
|
292
|
+
<div style="position:absolute;inset:0;border-radius:50%;border:3px solid transparent;border-top-color:#0070ba;animation:_pp_spin .8s linear infinite"></div>
|
|
293
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="#0070ba" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"
|
|
294
|
+
style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:24px;height:24px">
|
|
295
|
+
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
|
|
296
|
+
</svg>
|
|
297
|
+
</div>
|
|
298
|
+
<div style="text-align:center">
|
|
299
|
+
<div style="font-size:18px;font-weight:600;color:#111827;letter-spacing:-0.01em">Processing your payment</div>
|
|
300
|
+
<div style="font-size:14px;color:#6b7280;margin-top:6px;line-height:1.5">
|
|
301
|
+
This may take a few moments. Please do not close<br>or refresh this page.
|
|
302
|
+
</div>
|
|
303
|
+
</div>
|
|
304
|
+
<div style="width:200px;height:3px;background:#e5e7eb;border-radius:3px;overflow:hidden;margin-top:4px">
|
|
305
|
+
<div style="width:40%;height:100%;background:linear-gradient(90deg,#0070ba,#003087);border-radius:3px;animation:_pp_progress 1.5s ease-in-out infinite"></div>
|
|
306
|
+
</div>
|
|
307
|
+
`;
|
|
308
|
+
Object.assign(overlay.style, {
|
|
309
|
+
position: "fixed",
|
|
310
|
+
inset: "0",
|
|
311
|
+
zIndex: "99999",
|
|
312
|
+
background: "rgba(255,255,255,0.96)",
|
|
313
|
+
display: "flex",
|
|
314
|
+
flexDirection: "column",
|
|
315
|
+
alignItems: "center",
|
|
316
|
+
justifyContent: "center",
|
|
317
|
+
gap: "20px",
|
|
318
|
+
fontFamily: "-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif"
|
|
319
|
+
});
|
|
320
|
+
document.body.appendChild(overlay);
|
|
321
|
+
}
|
|
322
|
+
function hideProcessingOverlay() {
|
|
323
|
+
if (typeof document === "undefined") return;
|
|
324
|
+
document.getElementById(OVERLAY_ID)?.remove();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// src/components/PayPalSmartButtons.tsx
|
|
251
328
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
252
|
-
var SPIN_STYLE =
|
|
329
|
+
var SPIN_STYLE = `
|
|
330
|
+
@keyframes _pp_spin { to { transform: rotate(360deg) } }
|
|
331
|
+
@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }
|
|
332
|
+
`;
|
|
253
333
|
var BUTTON_WIDTH_MAP = {
|
|
254
334
|
small: "300px",
|
|
255
335
|
medium: "400px",
|
|
@@ -264,7 +344,12 @@ function PayPalSmartButtons(props) {
|
|
|
264
344
|
);
|
|
265
345
|
const [error, setError] = (0, import_react3.useState)(null);
|
|
266
346
|
const [processing, setProcessing] = (0, import_react3.useState)(false);
|
|
267
|
-
const [
|
|
347
|
+
const [buttonsReady, setButtonsReady] = (0, import_react3.useState)(false);
|
|
348
|
+
const [{ isPending, isResolved, isRejected }] = (0, import_react_paypal_js2.usePayPalScriptReducer)();
|
|
349
|
+
const handleInit = (0, import_react3.useCallback)(() => {
|
|
350
|
+
setButtonsReady(true);
|
|
351
|
+
}, []);
|
|
352
|
+
const showSpinner = isPending || isResolved && !buttonsReady;
|
|
268
353
|
if (!config.currency_supported) return null;
|
|
269
354
|
const containerWidth = BUTTON_WIDTH_MAP[config.button_width ?? "responsive"] ?? "100%";
|
|
270
355
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { width: containerWidth, position: "relative" }, children: [
|
|
@@ -272,43 +357,107 @@ function PayPalSmartButtons(props) {
|
|
|
272
357
|
processing && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
273
358
|
"div",
|
|
274
359
|
{
|
|
360
|
+
role: "status",
|
|
361
|
+
"aria-label": "Processing payment",
|
|
275
362
|
style: {
|
|
276
|
-
position: "
|
|
363
|
+
position: "fixed",
|
|
277
364
|
inset: 0,
|
|
278
|
-
zIndex:
|
|
279
|
-
background: "rgba(255,255,255,0.
|
|
280
|
-
borderRadius: 8,
|
|
365
|
+
zIndex: 9999,
|
|
366
|
+
background: "rgba(255,255,255,0.96)",
|
|
281
367
|
display: "flex",
|
|
282
368
|
flexDirection: "column",
|
|
283
369
|
alignItems: "center",
|
|
284
370
|
justifyContent: "center",
|
|
285
|
-
gap:
|
|
286
|
-
minHeight: 60
|
|
371
|
+
gap: 20
|
|
287
372
|
},
|
|
288
373
|
children: [
|
|
374
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { position: "relative", width: 56, height: 56 }, children: [
|
|
375
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
376
|
+
"div",
|
|
377
|
+
{
|
|
378
|
+
style: {
|
|
379
|
+
position: "absolute",
|
|
380
|
+
inset: 0,
|
|
381
|
+
borderRadius: "50%",
|
|
382
|
+
border: "3px solid #e5e7eb"
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
),
|
|
386
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
387
|
+
"div",
|
|
388
|
+
{
|
|
389
|
+
style: {
|
|
390
|
+
position: "absolute",
|
|
391
|
+
inset: 0,
|
|
392
|
+
borderRadius: "50%",
|
|
393
|
+
border: "3px solid transparent",
|
|
394
|
+
borderTopColor: "#0070ba",
|
|
395
|
+
animation: "_pp_spin .8s linear infinite"
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
),
|
|
399
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
400
|
+
"svg",
|
|
401
|
+
{
|
|
402
|
+
viewBox: "0 0 24 24",
|
|
403
|
+
fill: "none",
|
|
404
|
+
stroke: "#0070ba",
|
|
405
|
+
strokeWidth: "1.8",
|
|
406
|
+
strokeLinecap: "round",
|
|
407
|
+
strokeLinejoin: "round",
|
|
408
|
+
style: {
|
|
409
|
+
position: "absolute",
|
|
410
|
+
top: "50%",
|
|
411
|
+
left: "50%",
|
|
412
|
+
transform: "translate(-50%, -50%)",
|
|
413
|
+
width: 24,
|
|
414
|
+
height: 24
|
|
415
|
+
},
|
|
416
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" })
|
|
417
|
+
}
|
|
418
|
+
)
|
|
419
|
+
] }),
|
|
420
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { textAlign: "center" }, children: [
|
|
421
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 18, fontWeight: 600, color: "#111827", letterSpacing: "-0.01em" }, children: "Processing your payment" }),
|
|
422
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { fontSize: 14, color: "#6b7280", marginTop: 6, lineHeight: 1.5 }, children: [
|
|
423
|
+
"This may take a few moments. Please do not close",
|
|
424
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("br", {}),
|
|
425
|
+
"or refresh this page."
|
|
426
|
+
] })
|
|
427
|
+
] }),
|
|
289
428
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
290
429
|
"div",
|
|
291
430
|
{
|
|
292
431
|
style: {
|
|
293
|
-
width:
|
|
294
|
-
height:
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
432
|
+
width: 200,
|
|
433
|
+
height: 3,
|
|
434
|
+
background: "#e5e7eb",
|
|
435
|
+
borderRadius: 3,
|
|
436
|
+
overflow: "hidden",
|
|
437
|
+
marginTop: 4
|
|
438
|
+
},
|
|
439
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
440
|
+
"div",
|
|
441
|
+
{
|
|
442
|
+
style: {
|
|
443
|
+
width: "40%",
|
|
444
|
+
height: "100%",
|
|
445
|
+
background: "linear-gradient(90deg, #0070ba, #003087)",
|
|
446
|
+
borderRadius: 3,
|
|
447
|
+
animation: "_pp_progress 1.5s ease-in-out infinite"
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
)
|
|
300
451
|
}
|
|
301
|
-
)
|
|
302
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { textAlign: "center" }, children: [
|
|
303
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 13, color: "#374151", fontWeight: 500 }, children: "Processing your payment\u2026" }),
|
|
304
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 12, color: "#6b7280", marginTop: 4 }, children: "Please do not close or refresh this page" })
|
|
305
|
-
] })
|
|
452
|
+
)
|
|
306
453
|
]
|
|
307
454
|
}
|
|
308
455
|
),
|
|
309
|
-
|
|
456
|
+
showSpinner && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
310
457
|
"div",
|
|
311
458
|
{
|
|
459
|
+
role: "status",
|
|
460
|
+
"aria-label": "Loading PayPal",
|
|
312
461
|
style: {
|
|
313
462
|
display: "flex",
|
|
314
463
|
alignItems: "center",
|
|
@@ -339,7 +488,29 @@ function PayPalSmartButtons(props) {
|
|
|
339
488
|
]
|
|
340
489
|
}
|
|
341
490
|
),
|
|
342
|
-
|
|
491
|
+
isRejected && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
492
|
+
"div",
|
|
493
|
+
{
|
|
494
|
+
role: "alert",
|
|
495
|
+
style: {
|
|
496
|
+
display: "flex",
|
|
497
|
+
alignItems: "flex-start",
|
|
498
|
+
gap: 8,
|
|
499
|
+
padding: "10px 14px",
|
|
500
|
+
background: "#fef2f2",
|
|
501
|
+
border: "1px solid #fecaca",
|
|
502
|
+
borderRadius: 8,
|
|
503
|
+
fontSize: 13,
|
|
504
|
+
color: "#b91c1c",
|
|
505
|
+
lineHeight: 1.5
|
|
506
|
+
},
|
|
507
|
+
children: [
|
|
508
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { flexShrink: 0, fontSize: 15 }, children: "\u26A0\uFE0F" }),
|
|
509
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "PayPal failed to load. Please refresh the page or try a different payment method." })
|
|
510
|
+
]
|
|
511
|
+
}
|
|
512
|
+
),
|
|
513
|
+
config.environment === "sandbox" && buttonsReady && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
343
514
|
"div",
|
|
344
515
|
{
|
|
345
516
|
style: {
|
|
@@ -377,10 +548,11 @@ function PayPalSmartButtons(props) {
|
|
|
377
548
|
]
|
|
378
549
|
}
|
|
379
550
|
),
|
|
380
|
-
isResolved && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
551
|
+
isResolved && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: buttonsReady ? void 0 : { position: "absolute", left: -9999, opacity: 0, pointerEvents: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
381
552
|
import_react_paypal_js2.PayPalButtons,
|
|
382
553
|
{
|
|
383
554
|
forceReRender: [config.currency, config.intent, cartId],
|
|
555
|
+
onInit: handleInit,
|
|
384
556
|
style: {
|
|
385
557
|
layout: "vertical",
|
|
386
558
|
color: config.button_color,
|
|
@@ -389,40 +561,53 @@ function PayPalSmartButtons(props) {
|
|
|
389
561
|
height: config.button_height
|
|
390
562
|
},
|
|
391
563
|
createOrder: async () => {
|
|
564
|
+
if (processing) throw new Error("Payment already processing");
|
|
392
565
|
setError(null);
|
|
393
|
-
|
|
394
|
-
|
|
566
|
+
setProcessing(true);
|
|
567
|
+
try {
|
|
568
|
+
const r = await api.createOrder(cartId);
|
|
569
|
+
return r.id;
|
|
570
|
+
} catch (e) {
|
|
571
|
+
setProcessing(false);
|
|
572
|
+
throw e;
|
|
573
|
+
}
|
|
395
574
|
},
|
|
396
575
|
onApprove: async (data) => {
|
|
397
576
|
try {
|
|
398
577
|
setProcessing(true);
|
|
578
|
+
showProcessingOverlay();
|
|
399
579
|
setError(null);
|
|
400
580
|
const orderId = String(data?.orderID || "");
|
|
581
|
+
if (!orderId) throw new Error("PayPal order ID is missing from approval response");
|
|
401
582
|
const result = await api.captureOrder(cartId, orderId);
|
|
402
583
|
const completeResult = await markPaymentComplete(baseUrl, cartId, publishableApiKey);
|
|
403
|
-
onPaid?.({ ...result, ...completeResult });
|
|
584
|
+
await onPaid?.({ ...result, ...completeResult });
|
|
404
585
|
} catch (e) {
|
|
586
|
+
if (isNextRouterError(e)) throw e;
|
|
587
|
+
hideProcessingOverlay();
|
|
588
|
+
setProcessing(false);
|
|
405
589
|
const msg = e instanceof Error ? e.message : "Payment capture failed";
|
|
406
590
|
setError(msg);
|
|
407
591
|
onError?.(msg);
|
|
408
|
-
} finally {
|
|
409
|
-
setProcessing(false);
|
|
410
592
|
}
|
|
411
593
|
},
|
|
412
594
|
onCancel: () => {
|
|
595
|
+
hideProcessingOverlay();
|
|
413
596
|
setProcessing(false);
|
|
414
597
|
},
|
|
415
598
|
onError: (err) => {
|
|
599
|
+
hideProcessingOverlay();
|
|
416
600
|
setProcessing(false);
|
|
417
601
|
const msg = err instanceof Error ? err.message : err?.message || "PayPal error";
|
|
418
602
|
setError(msg);
|
|
419
603
|
onError?.(msg);
|
|
420
604
|
}
|
|
421
605
|
}
|
|
422
|
-
),
|
|
606
|
+
) }),
|
|
423
607
|
error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
424
608
|
"div",
|
|
425
609
|
{
|
|
610
|
+
role: "alert",
|
|
426
611
|
style: {
|
|
427
612
|
marginTop: 10,
|
|
428
613
|
display: "flex",
|
|
@@ -449,7 +634,10 @@ function PayPalSmartButtons(props) {
|
|
|
449
634
|
var import_react4 = require("react");
|
|
450
635
|
var import_react_paypal_js3 = require("@paypal/react-paypal-js");
|
|
451
636
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
452
|
-
var SPIN_STYLE2 =
|
|
637
|
+
var SPIN_STYLE2 = `
|
|
638
|
+
@keyframes _pp_spin { to { transform: rotate(360deg) } }
|
|
639
|
+
@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }
|
|
640
|
+
`;
|
|
453
641
|
var cardStyle = {
|
|
454
642
|
input: {
|
|
455
643
|
"font-size": "15px",
|
|
@@ -504,9 +692,13 @@ function SubmitButton({
|
|
|
504
692
|
{
|
|
505
693
|
type: "button",
|
|
506
694
|
disabled: isDisabled,
|
|
695
|
+
"aria-busy": disabled,
|
|
507
696
|
onClick: () => {
|
|
508
697
|
onSubmit();
|
|
509
|
-
|
|
698
|
+
try {
|
|
699
|
+
cardFieldsForm?.submit();
|
|
700
|
+
} catch {
|
|
701
|
+
}
|
|
510
702
|
},
|
|
511
703
|
style: {
|
|
512
704
|
width: "100%",
|
|
@@ -550,7 +742,34 @@ function PayPalAdvancedCard(props) {
|
|
|
550
742
|
);
|
|
551
743
|
const [error, setError] = (0, import_react4.useState)(null);
|
|
552
744
|
const [submitting, setSubmitting] = (0, import_react4.useState)(false);
|
|
745
|
+
const submittingRef = (0, import_react4.useRef)(false);
|
|
746
|
+
const creatingOrderRef = (0, import_react4.useRef)(false);
|
|
747
|
+
const [{ isPending, isResolved, isRejected }] = (0, import_react_paypal_js3.usePayPalScriptReducer)();
|
|
553
748
|
if (!config.currency_supported) return null;
|
|
749
|
+
if (isRejected) {
|
|
750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
751
|
+
"div",
|
|
752
|
+
{
|
|
753
|
+
role: "alert",
|
|
754
|
+
style: {
|
|
755
|
+
display: "flex",
|
|
756
|
+
alignItems: "flex-start",
|
|
757
|
+
gap: 8,
|
|
758
|
+
padding: "10px 14px",
|
|
759
|
+
background: "#fef2f2",
|
|
760
|
+
border: "1px solid #fecaca",
|
|
761
|
+
borderRadius: 8,
|
|
762
|
+
fontSize: 13,
|
|
763
|
+
color: "#b91c1c",
|
|
764
|
+
lineHeight: 1.5
|
|
765
|
+
},
|
|
766
|
+
children: [
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { flexShrink: 0, fontSize: 15 }, children: "\u26A0\uFE0F" }),
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "PayPal failed to load. Please refresh the page or try a different payment method." })
|
|
769
|
+
]
|
|
770
|
+
}
|
|
771
|
+
);
|
|
772
|
+
}
|
|
554
773
|
if (!config.client_token) {
|
|
555
774
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
556
775
|
"div",
|
|
@@ -568,42 +787,143 @@ function PayPalAdvancedCard(props) {
|
|
|
568
787
|
);
|
|
569
788
|
}
|
|
570
789
|
const isSandbox = config.environment === "sandbox";
|
|
790
|
+
if (isPending) {
|
|
791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
792
|
+
"div",
|
|
793
|
+
{
|
|
794
|
+
role: "status",
|
|
795
|
+
"aria-label": "Loading PayPal",
|
|
796
|
+
style: {
|
|
797
|
+
display: "flex",
|
|
798
|
+
alignItems: "center",
|
|
799
|
+
justifyContent: "center",
|
|
800
|
+
gap: 10,
|
|
801
|
+
padding: "18px 16px",
|
|
802
|
+
background: "#f9fafb",
|
|
803
|
+
border: "1px solid #e5e7eb",
|
|
804
|
+
borderRadius: 8,
|
|
805
|
+
minHeight: 55
|
|
806
|
+
},
|
|
807
|
+
children: [
|
|
808
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: SPIN_STYLE2 }),
|
|
809
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
810
|
+
"div",
|
|
811
|
+
{
|
|
812
|
+
style: {
|
|
813
|
+
width: 22,
|
|
814
|
+
height: 22,
|
|
815
|
+
borderRadius: "50%",
|
|
816
|
+
border: "2.5px solid #e5e7eb",
|
|
817
|
+
borderTopColor: "#0070ba",
|
|
818
|
+
animation: "_pp_spin .7s linear infinite",
|
|
819
|
+
flexShrink: 0
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
),
|
|
823
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 13, fontWeight: 500, color: "#6b7280" }, children: "Loading card fields\u2026" })
|
|
824
|
+
]
|
|
825
|
+
}
|
|
826
|
+
);
|
|
827
|
+
}
|
|
828
|
+
if (!isResolved) return null;
|
|
571
829
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { position: "relative" }, children: [
|
|
572
830
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: SPIN_STYLE2 }),
|
|
573
831
|
submitting && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
574
832
|
"div",
|
|
575
833
|
{
|
|
834
|
+
role: "status",
|
|
835
|
+
"aria-label": "Processing payment",
|
|
576
836
|
style: {
|
|
577
|
-
position: "
|
|
837
|
+
position: "fixed",
|
|
578
838
|
inset: 0,
|
|
579
|
-
zIndex:
|
|
580
|
-
background: "rgba(255,255,255,0.
|
|
581
|
-
borderRadius: 12,
|
|
839
|
+
zIndex: 9999,
|
|
840
|
+
background: "rgba(255,255,255,0.96)",
|
|
582
841
|
display: "flex",
|
|
583
842
|
flexDirection: "column",
|
|
584
843
|
alignItems: "center",
|
|
585
844
|
justifyContent: "center",
|
|
586
|
-
gap:
|
|
587
|
-
minHeight: 180
|
|
845
|
+
gap: 20
|
|
588
846
|
},
|
|
589
847
|
children: [
|
|
848
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { position: "relative", width: 56, height: 56 }, children: [
|
|
849
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
850
|
+
"div",
|
|
851
|
+
{
|
|
852
|
+
style: {
|
|
853
|
+
position: "absolute",
|
|
854
|
+
inset: 0,
|
|
855
|
+
borderRadius: "50%",
|
|
856
|
+
border: "3px solid #e5e7eb"
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
),
|
|
860
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
861
|
+
"div",
|
|
862
|
+
{
|
|
863
|
+
style: {
|
|
864
|
+
position: "absolute",
|
|
865
|
+
inset: 0,
|
|
866
|
+
borderRadius: "50%",
|
|
867
|
+
border: "3px solid transparent",
|
|
868
|
+
borderTopColor: "#2563eb",
|
|
869
|
+
animation: "_pp_spin .8s linear infinite"
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
),
|
|
873
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
874
|
+
"svg",
|
|
875
|
+
{
|
|
876
|
+
viewBox: "0 0 24 24",
|
|
877
|
+
fill: "none",
|
|
878
|
+
stroke: "#2563eb",
|
|
879
|
+
strokeWidth: "1.8",
|
|
880
|
+
strokeLinecap: "round",
|
|
881
|
+
strokeLinejoin: "round",
|
|
882
|
+
style: {
|
|
883
|
+
position: "absolute",
|
|
884
|
+
top: "50%",
|
|
885
|
+
left: "50%",
|
|
886
|
+
transform: "translate(-50%, -50%)",
|
|
887
|
+
width: 24,
|
|
888
|
+
height: 24
|
|
889
|
+
},
|
|
890
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" })
|
|
891
|
+
}
|
|
892
|
+
)
|
|
893
|
+
] }),
|
|
894
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { textAlign: "center" }, children: [
|
|
895
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 18, fontWeight: 600, color: "#111827", letterSpacing: "-0.01em" }, children: "Processing your payment" }),
|
|
896
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { fontSize: 14, color: "#6b7280", marginTop: 6, lineHeight: 1.5 }, children: [
|
|
897
|
+
"This may take a few moments. Please do not close",
|
|
898
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("br", {}),
|
|
899
|
+
"or refresh this page."
|
|
900
|
+
] })
|
|
901
|
+
] }),
|
|
590
902
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
591
903
|
"div",
|
|
592
904
|
{
|
|
593
905
|
style: {
|
|
594
|
-
width:
|
|
595
|
-
height:
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
}
|
|
906
|
+
width: 200,
|
|
907
|
+
height: 3,
|
|
908
|
+
background: "#e5e7eb",
|
|
909
|
+
borderRadius: 3,
|
|
910
|
+
overflow: "hidden",
|
|
911
|
+
marginTop: 4
|
|
912
|
+
},
|
|
913
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
914
|
+
"div",
|
|
915
|
+
{
|
|
916
|
+
style: {
|
|
917
|
+
width: "40%",
|
|
918
|
+
height: "100%",
|
|
919
|
+
background: "linear-gradient(90deg, #2563eb, #1d4ed8)",
|
|
920
|
+
borderRadius: 3,
|
|
921
|
+
animation: "_pp_progress 1.5s ease-in-out infinite"
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
)
|
|
601
925
|
}
|
|
602
|
-
)
|
|
603
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { textAlign: "center" }, children: [
|
|
604
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 15, fontWeight: 600, color: "#111827" }, children: "Processing your payment\u2026" }),
|
|
605
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 13, color: "#6b7280", marginTop: 4 }, children: "Please do not close or refresh this page" })
|
|
606
|
-
] })
|
|
926
|
+
)
|
|
607
927
|
]
|
|
608
928
|
}
|
|
609
929
|
),
|
|
@@ -612,32 +932,49 @@ function PayPalAdvancedCard(props) {
|
|
|
612
932
|
{
|
|
613
933
|
style: cardStyle,
|
|
614
934
|
createOrder: async () => {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
935
|
+
if (creatingOrderRef.current) throw new Error("Payment already processing");
|
|
936
|
+
creatingOrderRef.current = true;
|
|
937
|
+
try {
|
|
938
|
+
setError(null);
|
|
939
|
+
const r = await api.createOrder(cartId, true);
|
|
940
|
+
return r.id;
|
|
941
|
+
} catch (e) {
|
|
942
|
+
creatingOrderRef.current = false;
|
|
943
|
+
throw e;
|
|
944
|
+
}
|
|
618
945
|
},
|
|
619
946
|
onApprove: async (data) => {
|
|
620
947
|
try {
|
|
621
948
|
setError(null);
|
|
949
|
+
showProcessingOverlay();
|
|
622
950
|
const orderId = String(data?.orderID || "");
|
|
623
951
|
const result = await api.captureOrder(cartId, orderId);
|
|
624
952
|
const completeResult = await markPaymentComplete(baseUrl, cartId, publishableApiKey);
|
|
625
|
-
onPaid?.({ ...result, ...completeResult });
|
|
953
|
+
await onPaid?.({ ...result, ...completeResult });
|
|
626
954
|
} catch (e) {
|
|
955
|
+
if (isNextRouterError(e)) throw e;
|
|
956
|
+
hideProcessingOverlay();
|
|
957
|
+
creatingOrderRef.current = false;
|
|
958
|
+
submittingRef.current = false;
|
|
959
|
+
setSubmitting(false);
|
|
627
960
|
const msg = e instanceof Error ? e.message : "Card payment failed";
|
|
628
961
|
setError(msg);
|
|
629
962
|
onError?.(msg);
|
|
630
|
-
} finally {
|
|
631
|
-
setSubmitting(false);
|
|
632
963
|
}
|
|
633
964
|
},
|
|
634
965
|
onCancel: () => {
|
|
966
|
+
hideProcessingOverlay();
|
|
967
|
+
creatingOrderRef.current = false;
|
|
968
|
+
submittingRef.current = false;
|
|
635
969
|
setSubmitting(false);
|
|
636
970
|
},
|
|
637
971
|
onError: (e) => {
|
|
638
972
|
const msg = e instanceof Error ? e.message : e?.message || "CardFields error";
|
|
639
973
|
setError(msg);
|
|
640
974
|
onError?.(msg);
|
|
975
|
+
hideProcessingOverlay();
|
|
976
|
+
creatingOrderRef.current = false;
|
|
977
|
+
submittingRef.current = false;
|
|
641
978
|
setSubmitting(false);
|
|
642
979
|
},
|
|
643
980
|
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
@@ -736,14 +1073,18 @@ function PayPalAdvancedCard(props) {
|
|
|
736
1073
|
disabled: submitting,
|
|
737
1074
|
label: submitting ? "Processing\u2026" : "Pay by Card",
|
|
738
1075
|
onSubmit: () => {
|
|
1076
|
+
if (submittingRef.current) return;
|
|
1077
|
+
submittingRef.current = true;
|
|
739
1078
|
setError(null);
|
|
740
1079
|
setSubmitting(true);
|
|
1080
|
+
showProcessingOverlay();
|
|
741
1081
|
}
|
|
742
1082
|
}
|
|
743
1083
|
),
|
|
744
1084
|
error && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
745
1085
|
"div",
|
|
746
1086
|
{
|
|
1087
|
+
role: "alert",
|
|
747
1088
|
style: {
|
|
748
1089
|
display: "flex",
|
|
749
1090
|
alignItems: "flex-start",
|
|
@@ -780,6 +1121,8 @@ function PayPalLoadingCard() {
|
|
|
780
1121
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
781
1122
|
"div",
|
|
782
1123
|
{
|
|
1124
|
+
role: "status",
|
|
1125
|
+
"aria-label": "Connecting to PayPal",
|
|
783
1126
|
style: {
|
|
784
1127
|
display: "flex",
|
|
785
1128
|
alignItems: "center",
|
|
@@ -817,6 +1160,7 @@ function PayPalErrorCard({ message }) {
|
|
|
817
1160
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
818
1161
|
"div",
|
|
819
1162
|
{
|
|
1163
|
+
role: "alert",
|
|
820
1164
|
style: {
|
|
821
1165
|
padding: "12px 16px",
|
|
822
1166
|
background: "#fef2f2",
|
|
@@ -850,9 +1194,9 @@ function MedusaNextPayPalAdapter(props) {
|
|
|
850
1194
|
enabled: shouldRender
|
|
851
1195
|
});
|
|
852
1196
|
const handlePaid = (0, import_react5.useCallback)(
|
|
853
|
-
(captureResult) => {
|
|
1197
|
+
async (captureResult) => {
|
|
854
1198
|
onPaid?.(captureResult);
|
|
855
|
-
onSuccess?.(cartId);
|
|
1199
|
+
await onSuccess?.(cartId);
|
|
856
1200
|
},
|
|
857
1201
|
[cartId, onPaid, onSuccess]
|
|
858
1202
|
);
|
|
@@ -916,6 +1260,8 @@ function SessionInitCard() {
|
|
|
916
1260
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
917
1261
|
"div",
|
|
918
1262
|
{
|
|
1263
|
+
role: "status",
|
|
1264
|
+
"aria-label": "Setting up payment",
|
|
919
1265
|
style: {
|
|
920
1266
|
display: "flex",
|
|
921
1267
|
alignItems: "center",
|
|
@@ -951,6 +1297,8 @@ function ConfigLoadingCard() {
|
|
|
951
1297
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
952
1298
|
"div",
|
|
953
1299
|
{
|
|
1300
|
+
role: "status",
|
|
1301
|
+
"aria-label": "Connecting to PayPal",
|
|
954
1302
|
style: {
|
|
955
1303
|
display: "flex",
|
|
956
1304
|
alignItems: "center",
|
|
@@ -988,6 +1336,7 @@ function ErrorCard({ message }) {
|
|
|
988
1336
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
989
1337
|
"div",
|
|
990
1338
|
{
|
|
1339
|
+
role: "alert",
|
|
991
1340
|
style: {
|
|
992
1341
|
padding: "12px 16px",
|
|
993
1342
|
background: "#fef2f2",
|
|
@@ -1018,9 +1367,9 @@ function PayPalPaymentSection({
|
|
|
1018
1367
|
enabled: shouldRender
|
|
1019
1368
|
});
|
|
1020
1369
|
const handlePaid = (0, import_react6.useCallback)(
|
|
1021
|
-
(captureResult) => {
|
|
1370
|
+
async (captureResult) => {
|
|
1022
1371
|
onPaid?.(captureResult);
|
|
1023
|
-
onSuccess?.(cartId);
|
|
1372
|
+
await onSuccess?.(cartId);
|
|
1024
1373
|
},
|
|
1025
1374
|
[cartId, onPaid, onSuccess]
|
|
1026
1375
|
);
|
|
@@ -1071,8 +1420,16 @@ function PayPalPaymentSection({
|
|
|
1071
1420
|
|
|
1072
1421
|
// src/hooks/usePayPalPaymentMethods.ts
|
|
1073
1422
|
var import_react7 = require("react");
|
|
1423
|
+
var MAX_CACHE_ENTRIES2 = 50;
|
|
1074
1424
|
var _cache2 = /* @__PURE__ */ new Map();
|
|
1075
1425
|
var CACHE_TTL2 = 5 * 60 * 1e3;
|
|
1426
|
+
function cacheSet2(key, value) {
|
|
1427
|
+
if (_cache2.size >= MAX_CACHE_ENTRIES2) {
|
|
1428
|
+
const oldest = _cache2.keys().next().value;
|
|
1429
|
+
if (oldest !== void 0) _cache2.delete(oldest);
|
|
1430
|
+
}
|
|
1431
|
+
_cache2.set(key, value);
|
|
1432
|
+
}
|
|
1076
1433
|
function cacheKey2(baseUrl, cartId) {
|
|
1077
1434
|
return `ppm::${baseUrl}::${cartId ?? ""}`;
|
|
1078
1435
|
}
|
|
@@ -1124,12 +1481,13 @@ function usePayPalPaymentMethods({
|
|
|
1124
1481
|
cardTitle: typeof cfg.card_title === "string" && cfg.card_title ? cfg.card_title : "Credit or Debit Card",
|
|
1125
1482
|
loading: false
|
|
1126
1483
|
};
|
|
1127
|
-
|
|
1484
|
+
cacheSet2(k, { result: next, at: Date.now() });
|
|
1128
1485
|
setResult(next);
|
|
1129
1486
|
} catch (e) {
|
|
1130
|
-
|
|
1487
|
+
const msg = e instanceof Error ? e.message : "";
|
|
1488
|
+
if (e instanceof Error && e.name === "AbortError") return;
|
|
1131
1489
|
if (!mounted || id !== fetchIdRef.current) return;
|
|
1132
|
-
if (
|
|
1490
|
+
if (msg.includes("403") || msg.includes("Forbidden")) {
|
|
1133
1491
|
const disabled = {
|
|
1134
1492
|
...DEFAULT_RESULT,
|
|
1135
1493
|
paypalEnabled: false,
|
|
@@ -1160,8 +1518,10 @@ function usePayPalPaymentMethods({
|
|
|
1160
1518
|
PayPalProvider,
|
|
1161
1519
|
PayPalSmartButtons,
|
|
1162
1520
|
createPayPalStoreApi,
|
|
1521
|
+
hideProcessingOverlay,
|
|
1163
1522
|
isPayPalProviderId,
|
|
1164
1523
|
markPaymentComplete,
|
|
1524
|
+
showProcessingOverlay,
|
|
1165
1525
|
usePayPalConfig,
|
|
1166
1526
|
usePayPalPaymentMethods
|
|
1167
1527
|
});
|