@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.mjs
CHANGED
|
@@ -24,7 +24,24 @@ function createHttpClient(opts) {
|
|
|
24
24
|
if (opts.publishableApiKey) {
|
|
25
25
|
headers["x-publishable-api-key"] = opts.publishableApiKey;
|
|
26
26
|
}
|
|
27
|
-
const
|
|
27
|
+
const timeoutMs = 3e4;
|
|
28
|
+
let timeoutId;
|
|
29
|
+
const controller = new AbortController();
|
|
30
|
+
if (!init?.signal) {
|
|
31
|
+
timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
32
|
+
}
|
|
33
|
+
const effectiveSignal = init?.signal || controller.signal;
|
|
34
|
+
let res;
|
|
35
|
+
try {
|
|
36
|
+
res = await fetch(url, { ...init, headers, credentials: "include", signal: effectiveSignal });
|
|
37
|
+
} catch (err) {
|
|
38
|
+
if (err instanceof Error && err.name === "AbortError" && !init?.signal) {
|
|
39
|
+
throw new Error(`[PayPal] Request to ${path} timed out after ${timeoutMs / 1e3}s`);
|
|
40
|
+
}
|
|
41
|
+
throw err;
|
|
42
|
+
} finally {
|
|
43
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
44
|
+
}
|
|
28
45
|
const text = await res.text().catch(() => "");
|
|
29
46
|
if (!res.ok) {
|
|
30
47
|
if (res.status === 401) {
|
|
@@ -61,22 +78,12 @@ function createHttpClient(opts) {
|
|
|
61
78
|
|
|
62
79
|
// src/client/paypal.ts
|
|
63
80
|
async function markPaymentComplete(baseUrl, cartId, publishableApiKey) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
},
|
|
71
|
-
body: JSON.stringify({ cart_id: cartId }),
|
|
72
|
-
credentials: "include"
|
|
73
|
-
});
|
|
74
|
-
const data = await resp.json().catch(() => ({}));
|
|
75
|
-
return data || {};
|
|
76
|
-
} catch (e) {
|
|
77
|
-
console.warn("[PayPal] paypal-complete call failed:", e);
|
|
78
|
-
return {};
|
|
79
|
-
}
|
|
81
|
+
const http = createHttpClient({ baseUrl, publishableApiKey });
|
|
82
|
+
return http.request(`/store/paypal-complete`, {
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers: { "Content-Type": "application/json" },
|
|
85
|
+
body: JSON.stringify({ cart_id: cartId })
|
|
86
|
+
});
|
|
80
87
|
}
|
|
81
88
|
function createPayPalStoreApi(opts) {
|
|
82
89
|
const http = createHttpClient(opts);
|
|
@@ -107,8 +114,16 @@ function createPayPalStoreApi(opts) {
|
|
|
107
114
|
|
|
108
115
|
// src/hooks/usePayPalConfig.ts
|
|
109
116
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
117
|
+
var MAX_CACHE_ENTRIES = 50;
|
|
110
118
|
var _cache = /* @__PURE__ */ new Map();
|
|
111
119
|
var CACHE_TTL = 5 * 60 * 1e3;
|
|
120
|
+
function cacheSet(key, value) {
|
|
121
|
+
if (_cache.size >= MAX_CACHE_ENTRIES) {
|
|
122
|
+
const oldest = _cache.keys().next().value;
|
|
123
|
+
if (oldest !== void 0) _cache.delete(oldest);
|
|
124
|
+
}
|
|
125
|
+
_cache.set(key, value);
|
|
126
|
+
}
|
|
112
127
|
function cacheKey(baseUrl, cartId) {
|
|
113
128
|
return `${baseUrl}::${cartId ?? ""}`;
|
|
114
129
|
}
|
|
@@ -152,12 +167,12 @@ function usePayPalConfig({
|
|
|
152
167
|
try {
|
|
153
168
|
const cfg = await api.getConfig(cartId, controller.signal);
|
|
154
169
|
if (!mounted || id !== fetchIdRef.current) return;
|
|
155
|
-
|
|
170
|
+
cacheSet(k, { config: cfg, at: Date.now() });
|
|
156
171
|
setConfig(cfg);
|
|
157
172
|
} catch (e) {
|
|
158
|
-
if (e
|
|
173
|
+
if (e instanceof Error && e.name === "AbortError") return;
|
|
159
174
|
if (!mounted || id !== fetchIdRef.current) return;
|
|
160
|
-
setError(e
|
|
175
|
+
setError(e instanceof Error ? e.message : "Failed to load PayPal config");
|
|
161
176
|
} finally {
|
|
162
177
|
if (mounted && id === fetchIdRef.current) setLoading(false);
|
|
163
178
|
}
|
|
@@ -187,7 +202,7 @@ function PayPalProvider(props) {
|
|
|
187
202
|
"disable-funding": disableFunding,
|
|
188
203
|
"data-partner-attribution-id": BN_CODE
|
|
189
204
|
};
|
|
190
|
-
}, [config, intent, disableFunding]);
|
|
205
|
+
}, [config.client_id, config.currency, config.client_token, intent, disableFunding]);
|
|
191
206
|
return /* @__PURE__ */ jsx(
|
|
192
207
|
PayPalScriptProvider,
|
|
193
208
|
{
|
|
@@ -202,17 +217,80 @@ function PayPalProvider(props) {
|
|
|
202
217
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
203
218
|
function PayPalCurrencyNotice({ config }) {
|
|
204
219
|
if (config.currency_supported) return null;
|
|
205
|
-
return /* @__PURE__ */ jsxs("div", { style: { padding: 12, border: "1px solid #ddd", borderRadius: 10 }, children: [
|
|
220
|
+
return /* @__PURE__ */ jsxs("div", { role: "alert", style: { padding: 12, border: "1px solid #ddd", borderRadius: 10 }, children: [
|
|
206
221
|
/* @__PURE__ */ jsx2("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "PayPal currency issue" }),
|
|
207
222
|
/* @__PURE__ */ jsx2("ul", { style: { margin: 0, paddingLeft: 18 }, children: (config.currency_errors || []).map((e) => /* @__PURE__ */ jsx2("li", { children: e }, e)) })
|
|
208
223
|
] });
|
|
209
224
|
}
|
|
210
225
|
|
|
211
226
|
// src/components/PayPalSmartButtons.tsx
|
|
212
|
-
import { useMemo as useMemo3, useState as useState2 } from "react";
|
|
227
|
+
import { useCallback, useMemo as useMemo3, useState as useState2 } from "react";
|
|
213
228
|
import { PayPalButtons, usePayPalScriptReducer } from "@paypal/react-paypal-js";
|
|
229
|
+
|
|
230
|
+
// src/utils/next-errors.ts
|
|
231
|
+
function isNextRouterError(e) {
|
|
232
|
+
if (typeof e !== "object" || e === null || !("digest" in e)) return false;
|
|
233
|
+
const digest = e.digest;
|
|
234
|
+
return typeof digest === "string" && (digest.startsWith("NEXT_REDIRECT") || digest.startsWith("NEXT_NOT_FOUND"));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/utils/processing-overlay.ts
|
|
238
|
+
var OVERLAY_ID = "__pp_processing_overlay";
|
|
239
|
+
function showProcessingOverlay() {
|
|
240
|
+
if (typeof document === "undefined") return;
|
|
241
|
+
if (document.getElementById(OVERLAY_ID)) return;
|
|
242
|
+
const overlay = document.createElement("div");
|
|
243
|
+
overlay.id = OVERLAY_ID;
|
|
244
|
+
overlay.setAttribute("role", "status");
|
|
245
|
+
overlay.setAttribute("aria-label", "Processing payment");
|
|
246
|
+
overlay.innerHTML = `
|
|
247
|
+
<style>
|
|
248
|
+
@keyframes _pp_spin { to { transform: rotate(360deg) } }
|
|
249
|
+
@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }
|
|
250
|
+
</style>
|
|
251
|
+
<div style="position:relative;width:56px;height:56px">
|
|
252
|
+
<div style="position:absolute;inset:0;border-radius:50%;border:3px solid #e5e7eb"></div>
|
|
253
|
+
<div style="position:absolute;inset:0;border-radius:50%;border:3px solid transparent;border-top-color:#0070ba;animation:_pp_spin .8s linear infinite"></div>
|
|
254
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="#0070ba" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"
|
|
255
|
+
style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:24px;height:24px">
|
|
256
|
+
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
|
|
257
|
+
</svg>
|
|
258
|
+
</div>
|
|
259
|
+
<div style="text-align:center">
|
|
260
|
+
<div style="font-size:18px;font-weight:600;color:#111827;letter-spacing:-0.01em">Processing your payment</div>
|
|
261
|
+
<div style="font-size:14px;color:#6b7280;margin-top:6px;line-height:1.5">
|
|
262
|
+
This may take a few moments. Please do not close<br>or refresh this page.
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
<div style="width:200px;height:3px;background:#e5e7eb;border-radius:3px;overflow:hidden;margin-top:4px">
|
|
266
|
+
<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>
|
|
267
|
+
</div>
|
|
268
|
+
`;
|
|
269
|
+
Object.assign(overlay.style, {
|
|
270
|
+
position: "fixed",
|
|
271
|
+
inset: "0",
|
|
272
|
+
zIndex: "99999",
|
|
273
|
+
background: "rgba(255,255,255,0.96)",
|
|
274
|
+
display: "flex",
|
|
275
|
+
flexDirection: "column",
|
|
276
|
+
alignItems: "center",
|
|
277
|
+
justifyContent: "center",
|
|
278
|
+
gap: "20px",
|
|
279
|
+
fontFamily: "-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif"
|
|
280
|
+
});
|
|
281
|
+
document.body.appendChild(overlay);
|
|
282
|
+
}
|
|
283
|
+
function hideProcessingOverlay() {
|
|
284
|
+
if (typeof document === "undefined") return;
|
|
285
|
+
document.getElementById(OVERLAY_ID)?.remove();
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// src/components/PayPalSmartButtons.tsx
|
|
214
289
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
215
|
-
var SPIN_STYLE =
|
|
290
|
+
var SPIN_STYLE = `
|
|
291
|
+
@keyframes _pp_spin { to { transform: rotate(360deg) } }
|
|
292
|
+
@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }
|
|
293
|
+
`;
|
|
216
294
|
var BUTTON_WIDTH_MAP = {
|
|
217
295
|
small: "300px",
|
|
218
296
|
medium: "400px",
|
|
@@ -227,7 +305,12 @@ function PayPalSmartButtons(props) {
|
|
|
227
305
|
);
|
|
228
306
|
const [error, setError] = useState2(null);
|
|
229
307
|
const [processing, setProcessing] = useState2(false);
|
|
230
|
-
const [
|
|
308
|
+
const [buttonsReady, setButtonsReady] = useState2(false);
|
|
309
|
+
const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer();
|
|
310
|
+
const handleInit = useCallback(() => {
|
|
311
|
+
setButtonsReady(true);
|
|
312
|
+
}, []);
|
|
313
|
+
const showSpinner = isPending || isResolved && !buttonsReady;
|
|
231
314
|
if (!config.currency_supported) return null;
|
|
232
315
|
const containerWidth = BUTTON_WIDTH_MAP[config.button_width ?? "responsive"] ?? "100%";
|
|
233
316
|
return /* @__PURE__ */ jsxs2("div", { style: { width: containerWidth, position: "relative" }, children: [
|
|
@@ -235,43 +318,107 @@ function PayPalSmartButtons(props) {
|
|
|
235
318
|
processing && /* @__PURE__ */ jsxs2(
|
|
236
319
|
"div",
|
|
237
320
|
{
|
|
321
|
+
role: "status",
|
|
322
|
+
"aria-label": "Processing payment",
|
|
238
323
|
style: {
|
|
239
|
-
position: "
|
|
324
|
+
position: "fixed",
|
|
240
325
|
inset: 0,
|
|
241
|
-
zIndex:
|
|
242
|
-
background: "rgba(255,255,255,0.
|
|
243
|
-
borderRadius: 8,
|
|
326
|
+
zIndex: 9999,
|
|
327
|
+
background: "rgba(255,255,255,0.96)",
|
|
244
328
|
display: "flex",
|
|
245
329
|
flexDirection: "column",
|
|
246
330
|
alignItems: "center",
|
|
247
331
|
justifyContent: "center",
|
|
248
|
-
gap:
|
|
249
|
-
minHeight: 60
|
|
332
|
+
gap: 20
|
|
250
333
|
},
|
|
251
334
|
children: [
|
|
335
|
+
/* @__PURE__ */ jsxs2("div", { style: { position: "relative", width: 56, height: 56 }, children: [
|
|
336
|
+
/* @__PURE__ */ jsx3(
|
|
337
|
+
"div",
|
|
338
|
+
{
|
|
339
|
+
style: {
|
|
340
|
+
position: "absolute",
|
|
341
|
+
inset: 0,
|
|
342
|
+
borderRadius: "50%",
|
|
343
|
+
border: "3px solid #e5e7eb"
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
),
|
|
347
|
+
/* @__PURE__ */ jsx3(
|
|
348
|
+
"div",
|
|
349
|
+
{
|
|
350
|
+
style: {
|
|
351
|
+
position: "absolute",
|
|
352
|
+
inset: 0,
|
|
353
|
+
borderRadius: "50%",
|
|
354
|
+
border: "3px solid transparent",
|
|
355
|
+
borderTopColor: "#0070ba",
|
|
356
|
+
animation: "_pp_spin .8s linear infinite"
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
),
|
|
360
|
+
/* @__PURE__ */ jsx3(
|
|
361
|
+
"svg",
|
|
362
|
+
{
|
|
363
|
+
viewBox: "0 0 24 24",
|
|
364
|
+
fill: "none",
|
|
365
|
+
stroke: "#0070ba",
|
|
366
|
+
strokeWidth: "1.8",
|
|
367
|
+
strokeLinecap: "round",
|
|
368
|
+
strokeLinejoin: "round",
|
|
369
|
+
style: {
|
|
370
|
+
position: "absolute",
|
|
371
|
+
top: "50%",
|
|
372
|
+
left: "50%",
|
|
373
|
+
transform: "translate(-50%, -50%)",
|
|
374
|
+
width: 24,
|
|
375
|
+
height: 24
|
|
376
|
+
},
|
|
377
|
+
children: /* @__PURE__ */ jsx3("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" })
|
|
378
|
+
}
|
|
379
|
+
)
|
|
380
|
+
] }),
|
|
381
|
+
/* @__PURE__ */ jsxs2("div", { style: { textAlign: "center" }, children: [
|
|
382
|
+
/* @__PURE__ */ jsx3("div", { style: { fontSize: 18, fontWeight: 600, color: "#111827", letterSpacing: "-0.01em" }, children: "Processing your payment" }),
|
|
383
|
+
/* @__PURE__ */ jsxs2("div", { style: { fontSize: 14, color: "#6b7280", marginTop: 6, lineHeight: 1.5 }, children: [
|
|
384
|
+
"This may take a few moments. Please do not close",
|
|
385
|
+
/* @__PURE__ */ jsx3("br", {}),
|
|
386
|
+
"or refresh this page."
|
|
387
|
+
] })
|
|
388
|
+
] }),
|
|
252
389
|
/* @__PURE__ */ jsx3(
|
|
253
390
|
"div",
|
|
254
391
|
{
|
|
255
392
|
style: {
|
|
256
|
-
width:
|
|
257
|
-
height:
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
393
|
+
width: 200,
|
|
394
|
+
height: 3,
|
|
395
|
+
background: "#e5e7eb",
|
|
396
|
+
borderRadius: 3,
|
|
397
|
+
overflow: "hidden",
|
|
398
|
+
marginTop: 4
|
|
399
|
+
},
|
|
400
|
+
children: /* @__PURE__ */ jsx3(
|
|
401
|
+
"div",
|
|
402
|
+
{
|
|
403
|
+
style: {
|
|
404
|
+
width: "40%",
|
|
405
|
+
height: "100%",
|
|
406
|
+
background: "linear-gradient(90deg, #0070ba, #003087)",
|
|
407
|
+
borderRadius: 3,
|
|
408
|
+
animation: "_pp_progress 1.5s ease-in-out infinite"
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
)
|
|
263
412
|
}
|
|
264
|
-
)
|
|
265
|
-
/* @__PURE__ */ jsxs2("div", { style: { textAlign: "center" }, children: [
|
|
266
|
-
/* @__PURE__ */ jsx3("div", { style: { fontSize: 13, color: "#374151", fontWeight: 500 }, children: "Processing your payment\u2026" }),
|
|
267
|
-
/* @__PURE__ */ jsx3("div", { style: { fontSize: 12, color: "#6b7280", marginTop: 4 }, children: "Please do not close or refresh this page" })
|
|
268
|
-
] })
|
|
413
|
+
)
|
|
269
414
|
]
|
|
270
415
|
}
|
|
271
416
|
),
|
|
272
|
-
|
|
417
|
+
showSpinner && /* @__PURE__ */ jsxs2(
|
|
273
418
|
"div",
|
|
274
419
|
{
|
|
420
|
+
role: "status",
|
|
421
|
+
"aria-label": "Loading PayPal",
|
|
275
422
|
style: {
|
|
276
423
|
display: "flex",
|
|
277
424
|
alignItems: "center",
|
|
@@ -302,7 +449,29 @@ function PayPalSmartButtons(props) {
|
|
|
302
449
|
]
|
|
303
450
|
}
|
|
304
451
|
),
|
|
305
|
-
|
|
452
|
+
isRejected && /* @__PURE__ */ jsxs2(
|
|
453
|
+
"div",
|
|
454
|
+
{
|
|
455
|
+
role: "alert",
|
|
456
|
+
style: {
|
|
457
|
+
display: "flex",
|
|
458
|
+
alignItems: "flex-start",
|
|
459
|
+
gap: 8,
|
|
460
|
+
padding: "10px 14px",
|
|
461
|
+
background: "#fef2f2",
|
|
462
|
+
border: "1px solid #fecaca",
|
|
463
|
+
borderRadius: 8,
|
|
464
|
+
fontSize: 13,
|
|
465
|
+
color: "#b91c1c",
|
|
466
|
+
lineHeight: 1.5
|
|
467
|
+
},
|
|
468
|
+
children: [
|
|
469
|
+
/* @__PURE__ */ jsx3("span", { style: { flexShrink: 0, fontSize: 15 }, children: "\u26A0\uFE0F" }),
|
|
470
|
+
/* @__PURE__ */ jsx3("span", { children: "PayPal failed to load. Please refresh the page or try a different payment method." })
|
|
471
|
+
]
|
|
472
|
+
}
|
|
473
|
+
),
|
|
474
|
+
config.environment === "sandbox" && buttonsReady && /* @__PURE__ */ jsxs2(
|
|
306
475
|
"div",
|
|
307
476
|
{
|
|
308
477
|
style: {
|
|
@@ -340,10 +509,11 @@ function PayPalSmartButtons(props) {
|
|
|
340
509
|
]
|
|
341
510
|
}
|
|
342
511
|
),
|
|
343
|
-
isResolved && /* @__PURE__ */ jsx3(
|
|
512
|
+
isResolved && /* @__PURE__ */ jsx3("div", { style: buttonsReady ? void 0 : { position: "absolute", left: -9999, opacity: 0, pointerEvents: "none" }, children: /* @__PURE__ */ jsx3(
|
|
344
513
|
PayPalButtons,
|
|
345
514
|
{
|
|
346
515
|
forceReRender: [config.currency, config.intent, cartId],
|
|
516
|
+
onInit: handleInit,
|
|
347
517
|
style: {
|
|
348
518
|
layout: "vertical",
|
|
349
519
|
color: config.button_color,
|
|
@@ -352,40 +522,53 @@ function PayPalSmartButtons(props) {
|
|
|
352
522
|
height: config.button_height
|
|
353
523
|
},
|
|
354
524
|
createOrder: async () => {
|
|
525
|
+
if (processing) throw new Error("Payment already processing");
|
|
355
526
|
setError(null);
|
|
356
|
-
|
|
357
|
-
|
|
527
|
+
setProcessing(true);
|
|
528
|
+
try {
|
|
529
|
+
const r = await api.createOrder(cartId);
|
|
530
|
+
return r.id;
|
|
531
|
+
} catch (e) {
|
|
532
|
+
setProcessing(false);
|
|
533
|
+
throw e;
|
|
534
|
+
}
|
|
358
535
|
},
|
|
359
536
|
onApprove: async (data) => {
|
|
360
537
|
try {
|
|
361
538
|
setProcessing(true);
|
|
539
|
+
showProcessingOverlay();
|
|
362
540
|
setError(null);
|
|
363
541
|
const orderId = String(data?.orderID || "");
|
|
542
|
+
if (!orderId) throw new Error("PayPal order ID is missing from approval response");
|
|
364
543
|
const result = await api.captureOrder(cartId, orderId);
|
|
365
544
|
const completeResult = await markPaymentComplete(baseUrl, cartId, publishableApiKey);
|
|
366
|
-
onPaid?.({ ...result, ...completeResult });
|
|
545
|
+
await onPaid?.({ ...result, ...completeResult });
|
|
367
546
|
} catch (e) {
|
|
547
|
+
if (isNextRouterError(e)) throw e;
|
|
548
|
+
hideProcessingOverlay();
|
|
549
|
+
setProcessing(false);
|
|
368
550
|
const msg = e instanceof Error ? e.message : "Payment capture failed";
|
|
369
551
|
setError(msg);
|
|
370
552
|
onError?.(msg);
|
|
371
|
-
} finally {
|
|
372
|
-
setProcessing(false);
|
|
373
553
|
}
|
|
374
554
|
},
|
|
375
555
|
onCancel: () => {
|
|
556
|
+
hideProcessingOverlay();
|
|
376
557
|
setProcessing(false);
|
|
377
558
|
},
|
|
378
559
|
onError: (err) => {
|
|
560
|
+
hideProcessingOverlay();
|
|
379
561
|
setProcessing(false);
|
|
380
562
|
const msg = err instanceof Error ? err.message : err?.message || "PayPal error";
|
|
381
563
|
setError(msg);
|
|
382
564
|
onError?.(msg);
|
|
383
565
|
}
|
|
384
566
|
}
|
|
385
|
-
),
|
|
567
|
+
) }),
|
|
386
568
|
error ? /* @__PURE__ */ jsxs2(
|
|
387
569
|
"div",
|
|
388
570
|
{
|
|
571
|
+
role: "alert",
|
|
389
572
|
style: {
|
|
390
573
|
marginTop: 10,
|
|
391
574
|
display: "flex",
|
|
@@ -409,16 +592,20 @@ function PayPalSmartButtons(props) {
|
|
|
409
592
|
}
|
|
410
593
|
|
|
411
594
|
// src/components/PayPalAdvancedCard.tsx
|
|
412
|
-
import { useMemo as useMemo4, useState as useState3 } from "react";
|
|
595
|
+
import { useMemo as useMemo4, useRef as useRef2, useState as useState3 } from "react";
|
|
413
596
|
import {
|
|
414
597
|
PayPalCardFieldsProvider,
|
|
415
598
|
PayPalNumberField,
|
|
416
599
|
PayPalExpiryField,
|
|
417
600
|
PayPalCVVField,
|
|
418
|
-
usePayPalCardFields
|
|
601
|
+
usePayPalCardFields,
|
|
602
|
+
usePayPalScriptReducer as usePayPalScriptReducer2
|
|
419
603
|
} from "@paypal/react-paypal-js";
|
|
420
604
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
421
|
-
var SPIN_STYLE2 =
|
|
605
|
+
var SPIN_STYLE2 = `
|
|
606
|
+
@keyframes _pp_spin { to { transform: rotate(360deg) } }
|
|
607
|
+
@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }
|
|
608
|
+
`;
|
|
422
609
|
var cardStyle = {
|
|
423
610
|
input: {
|
|
424
611
|
"font-size": "15px",
|
|
@@ -473,9 +660,13 @@ function SubmitButton({
|
|
|
473
660
|
{
|
|
474
661
|
type: "button",
|
|
475
662
|
disabled: isDisabled,
|
|
663
|
+
"aria-busy": disabled,
|
|
476
664
|
onClick: () => {
|
|
477
665
|
onSubmit();
|
|
478
|
-
|
|
666
|
+
try {
|
|
667
|
+
cardFieldsForm?.submit();
|
|
668
|
+
} catch {
|
|
669
|
+
}
|
|
479
670
|
},
|
|
480
671
|
style: {
|
|
481
672
|
width: "100%",
|
|
@@ -519,7 +710,34 @@ function PayPalAdvancedCard(props) {
|
|
|
519
710
|
);
|
|
520
711
|
const [error, setError] = useState3(null);
|
|
521
712
|
const [submitting, setSubmitting] = useState3(false);
|
|
713
|
+
const submittingRef = useRef2(false);
|
|
714
|
+
const creatingOrderRef = useRef2(false);
|
|
715
|
+
const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer2();
|
|
522
716
|
if (!config.currency_supported) return null;
|
|
717
|
+
if (isRejected) {
|
|
718
|
+
return /* @__PURE__ */ jsxs3(
|
|
719
|
+
"div",
|
|
720
|
+
{
|
|
721
|
+
role: "alert",
|
|
722
|
+
style: {
|
|
723
|
+
display: "flex",
|
|
724
|
+
alignItems: "flex-start",
|
|
725
|
+
gap: 8,
|
|
726
|
+
padding: "10px 14px",
|
|
727
|
+
background: "#fef2f2",
|
|
728
|
+
border: "1px solid #fecaca",
|
|
729
|
+
borderRadius: 8,
|
|
730
|
+
fontSize: 13,
|
|
731
|
+
color: "#b91c1c",
|
|
732
|
+
lineHeight: 1.5
|
|
733
|
+
},
|
|
734
|
+
children: [
|
|
735
|
+
/* @__PURE__ */ jsx4("span", { style: { flexShrink: 0, fontSize: 15 }, children: "\u26A0\uFE0F" }),
|
|
736
|
+
/* @__PURE__ */ jsx4("span", { children: "PayPal failed to load. Please refresh the page or try a different payment method." })
|
|
737
|
+
]
|
|
738
|
+
}
|
|
739
|
+
);
|
|
740
|
+
}
|
|
523
741
|
if (!config.client_token) {
|
|
524
742
|
return /* @__PURE__ */ jsx4(
|
|
525
743
|
"div",
|
|
@@ -537,42 +755,143 @@ function PayPalAdvancedCard(props) {
|
|
|
537
755
|
);
|
|
538
756
|
}
|
|
539
757
|
const isSandbox = config.environment === "sandbox";
|
|
758
|
+
if (isPending) {
|
|
759
|
+
return /* @__PURE__ */ jsxs3(
|
|
760
|
+
"div",
|
|
761
|
+
{
|
|
762
|
+
role: "status",
|
|
763
|
+
"aria-label": "Loading PayPal",
|
|
764
|
+
style: {
|
|
765
|
+
display: "flex",
|
|
766
|
+
alignItems: "center",
|
|
767
|
+
justifyContent: "center",
|
|
768
|
+
gap: 10,
|
|
769
|
+
padding: "18px 16px",
|
|
770
|
+
background: "#f9fafb",
|
|
771
|
+
border: "1px solid #e5e7eb",
|
|
772
|
+
borderRadius: 8,
|
|
773
|
+
minHeight: 55
|
|
774
|
+
},
|
|
775
|
+
children: [
|
|
776
|
+
/* @__PURE__ */ jsx4("style", { children: SPIN_STYLE2 }),
|
|
777
|
+
/* @__PURE__ */ jsx4(
|
|
778
|
+
"div",
|
|
779
|
+
{
|
|
780
|
+
style: {
|
|
781
|
+
width: 22,
|
|
782
|
+
height: 22,
|
|
783
|
+
borderRadius: "50%",
|
|
784
|
+
border: "2.5px solid #e5e7eb",
|
|
785
|
+
borderTopColor: "#0070ba",
|
|
786
|
+
animation: "_pp_spin .7s linear infinite",
|
|
787
|
+
flexShrink: 0
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
),
|
|
791
|
+
/* @__PURE__ */ jsx4("div", { style: { fontSize: 13, fontWeight: 500, color: "#6b7280" }, children: "Loading card fields\u2026" })
|
|
792
|
+
]
|
|
793
|
+
}
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
if (!isResolved) return null;
|
|
540
797
|
return /* @__PURE__ */ jsxs3("div", { style: { position: "relative" }, children: [
|
|
541
798
|
/* @__PURE__ */ jsx4("style", { children: SPIN_STYLE2 }),
|
|
542
799
|
submitting && /* @__PURE__ */ jsxs3(
|
|
543
800
|
"div",
|
|
544
801
|
{
|
|
802
|
+
role: "status",
|
|
803
|
+
"aria-label": "Processing payment",
|
|
545
804
|
style: {
|
|
546
|
-
position: "
|
|
805
|
+
position: "fixed",
|
|
547
806
|
inset: 0,
|
|
548
|
-
zIndex:
|
|
549
|
-
background: "rgba(255,255,255,0.
|
|
550
|
-
borderRadius: 12,
|
|
807
|
+
zIndex: 9999,
|
|
808
|
+
background: "rgba(255,255,255,0.96)",
|
|
551
809
|
display: "flex",
|
|
552
810
|
flexDirection: "column",
|
|
553
811
|
alignItems: "center",
|
|
554
812
|
justifyContent: "center",
|
|
555
|
-
gap:
|
|
556
|
-
minHeight: 180
|
|
813
|
+
gap: 20
|
|
557
814
|
},
|
|
558
815
|
children: [
|
|
816
|
+
/* @__PURE__ */ jsxs3("div", { style: { position: "relative", width: 56, height: 56 }, children: [
|
|
817
|
+
/* @__PURE__ */ jsx4(
|
|
818
|
+
"div",
|
|
819
|
+
{
|
|
820
|
+
style: {
|
|
821
|
+
position: "absolute",
|
|
822
|
+
inset: 0,
|
|
823
|
+
borderRadius: "50%",
|
|
824
|
+
border: "3px solid #e5e7eb"
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
),
|
|
828
|
+
/* @__PURE__ */ jsx4(
|
|
829
|
+
"div",
|
|
830
|
+
{
|
|
831
|
+
style: {
|
|
832
|
+
position: "absolute",
|
|
833
|
+
inset: 0,
|
|
834
|
+
borderRadius: "50%",
|
|
835
|
+
border: "3px solid transparent",
|
|
836
|
+
borderTopColor: "#2563eb",
|
|
837
|
+
animation: "_pp_spin .8s linear infinite"
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
),
|
|
841
|
+
/* @__PURE__ */ jsx4(
|
|
842
|
+
"svg",
|
|
843
|
+
{
|
|
844
|
+
viewBox: "0 0 24 24",
|
|
845
|
+
fill: "none",
|
|
846
|
+
stroke: "#2563eb",
|
|
847
|
+
strokeWidth: "1.8",
|
|
848
|
+
strokeLinecap: "round",
|
|
849
|
+
strokeLinejoin: "round",
|
|
850
|
+
style: {
|
|
851
|
+
position: "absolute",
|
|
852
|
+
top: "50%",
|
|
853
|
+
left: "50%",
|
|
854
|
+
transform: "translate(-50%, -50%)",
|
|
855
|
+
width: 24,
|
|
856
|
+
height: 24
|
|
857
|
+
},
|
|
858
|
+
children: /* @__PURE__ */ jsx4("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" })
|
|
859
|
+
}
|
|
860
|
+
)
|
|
861
|
+
] }),
|
|
862
|
+
/* @__PURE__ */ jsxs3("div", { style: { textAlign: "center" }, children: [
|
|
863
|
+
/* @__PURE__ */ jsx4("div", { style: { fontSize: 18, fontWeight: 600, color: "#111827", letterSpacing: "-0.01em" }, children: "Processing your payment" }),
|
|
864
|
+
/* @__PURE__ */ jsxs3("div", { style: { fontSize: 14, color: "#6b7280", marginTop: 6, lineHeight: 1.5 }, children: [
|
|
865
|
+
"This may take a few moments. Please do not close",
|
|
866
|
+
/* @__PURE__ */ jsx4("br", {}),
|
|
867
|
+
"or refresh this page."
|
|
868
|
+
] })
|
|
869
|
+
] }),
|
|
559
870
|
/* @__PURE__ */ jsx4(
|
|
560
871
|
"div",
|
|
561
872
|
{
|
|
562
873
|
style: {
|
|
563
|
-
width:
|
|
564
|
-
height:
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
}
|
|
874
|
+
width: 200,
|
|
875
|
+
height: 3,
|
|
876
|
+
background: "#e5e7eb",
|
|
877
|
+
borderRadius: 3,
|
|
878
|
+
overflow: "hidden",
|
|
879
|
+
marginTop: 4
|
|
880
|
+
},
|
|
881
|
+
children: /* @__PURE__ */ jsx4(
|
|
882
|
+
"div",
|
|
883
|
+
{
|
|
884
|
+
style: {
|
|
885
|
+
width: "40%",
|
|
886
|
+
height: "100%",
|
|
887
|
+
background: "linear-gradient(90deg, #2563eb, #1d4ed8)",
|
|
888
|
+
borderRadius: 3,
|
|
889
|
+
animation: "_pp_progress 1.5s ease-in-out infinite"
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
)
|
|
570
893
|
}
|
|
571
|
-
)
|
|
572
|
-
/* @__PURE__ */ jsxs3("div", { style: { textAlign: "center" }, children: [
|
|
573
|
-
/* @__PURE__ */ jsx4("div", { style: { fontSize: 15, fontWeight: 600, color: "#111827" }, children: "Processing your payment\u2026" }),
|
|
574
|
-
/* @__PURE__ */ jsx4("div", { style: { fontSize: 13, color: "#6b7280", marginTop: 4 }, children: "Please do not close or refresh this page" })
|
|
575
|
-
] })
|
|
894
|
+
)
|
|
576
895
|
]
|
|
577
896
|
}
|
|
578
897
|
),
|
|
@@ -581,32 +900,49 @@ function PayPalAdvancedCard(props) {
|
|
|
581
900
|
{
|
|
582
901
|
style: cardStyle,
|
|
583
902
|
createOrder: async () => {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
903
|
+
if (creatingOrderRef.current) throw new Error("Payment already processing");
|
|
904
|
+
creatingOrderRef.current = true;
|
|
905
|
+
try {
|
|
906
|
+
setError(null);
|
|
907
|
+
const r = await api.createOrder(cartId, true);
|
|
908
|
+
return r.id;
|
|
909
|
+
} catch (e) {
|
|
910
|
+
creatingOrderRef.current = false;
|
|
911
|
+
throw e;
|
|
912
|
+
}
|
|
587
913
|
},
|
|
588
914
|
onApprove: async (data) => {
|
|
589
915
|
try {
|
|
590
916
|
setError(null);
|
|
917
|
+
showProcessingOverlay();
|
|
591
918
|
const orderId = String(data?.orderID || "");
|
|
592
919
|
const result = await api.captureOrder(cartId, orderId);
|
|
593
920
|
const completeResult = await markPaymentComplete(baseUrl, cartId, publishableApiKey);
|
|
594
|
-
onPaid?.({ ...result, ...completeResult });
|
|
921
|
+
await onPaid?.({ ...result, ...completeResult });
|
|
595
922
|
} catch (e) {
|
|
923
|
+
if (isNextRouterError(e)) throw e;
|
|
924
|
+
hideProcessingOverlay();
|
|
925
|
+
creatingOrderRef.current = false;
|
|
926
|
+
submittingRef.current = false;
|
|
927
|
+
setSubmitting(false);
|
|
596
928
|
const msg = e instanceof Error ? e.message : "Card payment failed";
|
|
597
929
|
setError(msg);
|
|
598
930
|
onError?.(msg);
|
|
599
|
-
} finally {
|
|
600
|
-
setSubmitting(false);
|
|
601
931
|
}
|
|
602
932
|
},
|
|
603
933
|
onCancel: () => {
|
|
934
|
+
hideProcessingOverlay();
|
|
935
|
+
creatingOrderRef.current = false;
|
|
936
|
+
submittingRef.current = false;
|
|
604
937
|
setSubmitting(false);
|
|
605
938
|
},
|
|
606
939
|
onError: (e) => {
|
|
607
940
|
const msg = e instanceof Error ? e.message : e?.message || "CardFields error";
|
|
608
941
|
setError(msg);
|
|
609
942
|
onError?.(msg);
|
|
943
|
+
hideProcessingOverlay();
|
|
944
|
+
creatingOrderRef.current = false;
|
|
945
|
+
submittingRef.current = false;
|
|
610
946
|
setSubmitting(false);
|
|
611
947
|
},
|
|
612
948
|
children: /* @__PURE__ */ jsxs3(
|
|
@@ -705,14 +1041,18 @@ function PayPalAdvancedCard(props) {
|
|
|
705
1041
|
disabled: submitting,
|
|
706
1042
|
label: submitting ? "Processing\u2026" : "Pay by Card",
|
|
707
1043
|
onSubmit: () => {
|
|
1044
|
+
if (submittingRef.current) return;
|
|
1045
|
+
submittingRef.current = true;
|
|
708
1046
|
setError(null);
|
|
709
1047
|
setSubmitting(true);
|
|
1048
|
+
showProcessingOverlay();
|
|
710
1049
|
}
|
|
711
1050
|
}
|
|
712
1051
|
),
|
|
713
1052
|
error && /* @__PURE__ */ jsxs3(
|
|
714
1053
|
"div",
|
|
715
1054
|
{
|
|
1055
|
+
role: "alert",
|
|
716
1056
|
style: {
|
|
717
1057
|
display: "flex",
|
|
718
1058
|
alignItems: "flex-start",
|
|
@@ -740,7 +1080,7 @@ function PayPalAdvancedCard(props) {
|
|
|
740
1080
|
}
|
|
741
1081
|
|
|
742
1082
|
// src/adapters/MedusaNextPayPalAdapter.tsx
|
|
743
|
-
import { useCallback } from "react";
|
|
1083
|
+
import { useCallback as useCallback2 } from "react";
|
|
744
1084
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
745
1085
|
var DEFAULT_PAYPAL_PROVIDER_ID = "pp_paypal_paypal";
|
|
746
1086
|
var DEFAULT_PAYPAL_CARD_PROVIDER_ID = "pp_paypal_card_paypal_card";
|
|
@@ -749,6 +1089,8 @@ function PayPalLoadingCard() {
|
|
|
749
1089
|
return /* @__PURE__ */ jsxs4(
|
|
750
1090
|
"div",
|
|
751
1091
|
{
|
|
1092
|
+
role: "status",
|
|
1093
|
+
"aria-label": "Connecting to PayPal",
|
|
752
1094
|
style: {
|
|
753
1095
|
display: "flex",
|
|
754
1096
|
alignItems: "center",
|
|
@@ -786,6 +1128,7 @@ function PayPalErrorCard({ message }) {
|
|
|
786
1128
|
return /* @__PURE__ */ jsx5(
|
|
787
1129
|
"div",
|
|
788
1130
|
{
|
|
1131
|
+
role: "alert",
|
|
789
1132
|
style: {
|
|
790
1133
|
padding: "12px 16px",
|
|
791
1134
|
background: "#fef2f2",
|
|
@@ -818,10 +1161,10 @@ function MedusaNextPayPalAdapter(props) {
|
|
|
818
1161
|
cartId,
|
|
819
1162
|
enabled: shouldRender
|
|
820
1163
|
});
|
|
821
|
-
const handlePaid =
|
|
822
|
-
(captureResult) => {
|
|
1164
|
+
const handlePaid = useCallback2(
|
|
1165
|
+
async (captureResult) => {
|
|
823
1166
|
onPaid?.(captureResult);
|
|
824
|
-
onSuccess?.(cartId);
|
|
1167
|
+
await onSuccess?.(cartId);
|
|
825
1168
|
},
|
|
826
1169
|
[cartId, onPaid, onSuccess]
|
|
827
1170
|
);
|
|
@@ -868,7 +1211,7 @@ function MedusaNextPayPalAdapter(props) {
|
|
|
868
1211
|
}
|
|
869
1212
|
|
|
870
1213
|
// src/components/PayPalPaymentSection.tsx
|
|
871
|
-
import { useCallback as
|
|
1214
|
+
import { useCallback as useCallback3 } from "react";
|
|
872
1215
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
873
1216
|
var PAYPAL_WALLET_PROVIDER_ID = "pp_paypal_paypal";
|
|
874
1217
|
var PAYPAL_CARD_PROVIDER_ID = "pp_paypal_card_paypal_card";
|
|
@@ -885,6 +1228,8 @@ function SessionInitCard() {
|
|
|
885
1228
|
return /* @__PURE__ */ jsxs5(
|
|
886
1229
|
"div",
|
|
887
1230
|
{
|
|
1231
|
+
role: "status",
|
|
1232
|
+
"aria-label": "Setting up payment",
|
|
888
1233
|
style: {
|
|
889
1234
|
display: "flex",
|
|
890
1235
|
alignItems: "center",
|
|
@@ -920,6 +1265,8 @@ function ConfigLoadingCard() {
|
|
|
920
1265
|
return /* @__PURE__ */ jsxs5(
|
|
921
1266
|
"div",
|
|
922
1267
|
{
|
|
1268
|
+
role: "status",
|
|
1269
|
+
"aria-label": "Connecting to PayPal",
|
|
923
1270
|
style: {
|
|
924
1271
|
display: "flex",
|
|
925
1272
|
alignItems: "center",
|
|
@@ -957,6 +1304,7 @@ function ErrorCard({ message }) {
|
|
|
957
1304
|
return /* @__PURE__ */ jsx6(
|
|
958
1305
|
"div",
|
|
959
1306
|
{
|
|
1307
|
+
role: "alert",
|
|
960
1308
|
style: {
|
|
961
1309
|
padding: "12px 16px",
|
|
962
1310
|
background: "#fef2f2",
|
|
@@ -986,10 +1334,10 @@ function PayPalPaymentSection({
|
|
|
986
1334
|
cartId,
|
|
987
1335
|
enabled: shouldRender
|
|
988
1336
|
});
|
|
989
|
-
const handlePaid =
|
|
990
|
-
(captureResult) => {
|
|
1337
|
+
const handlePaid = useCallback3(
|
|
1338
|
+
async (captureResult) => {
|
|
991
1339
|
onPaid?.(captureResult);
|
|
992
|
-
onSuccess?.(cartId);
|
|
1340
|
+
await onSuccess?.(cartId);
|
|
993
1341
|
},
|
|
994
1342
|
[cartId, onPaid, onSuccess]
|
|
995
1343
|
);
|
|
@@ -1039,9 +1387,17 @@ function PayPalPaymentSection({
|
|
|
1039
1387
|
}
|
|
1040
1388
|
|
|
1041
1389
|
// src/hooks/usePayPalPaymentMethods.ts
|
|
1042
|
-
import { useEffect as useEffect2, useMemo as useMemo5, useRef as
|
|
1390
|
+
import { useEffect as useEffect2, useMemo as useMemo5, useRef as useRef3, useState as useState4 } from "react";
|
|
1391
|
+
var MAX_CACHE_ENTRIES2 = 50;
|
|
1043
1392
|
var _cache2 = /* @__PURE__ */ new Map();
|
|
1044
1393
|
var CACHE_TTL2 = 5 * 60 * 1e3;
|
|
1394
|
+
function cacheSet2(key, value) {
|
|
1395
|
+
if (_cache2.size >= MAX_CACHE_ENTRIES2) {
|
|
1396
|
+
const oldest = _cache2.keys().next().value;
|
|
1397
|
+
if (oldest !== void 0) _cache2.delete(oldest);
|
|
1398
|
+
}
|
|
1399
|
+
_cache2.set(key, value);
|
|
1400
|
+
}
|
|
1045
1401
|
function cacheKey2(baseUrl, cartId) {
|
|
1046
1402
|
return `ppm::${baseUrl}::${cartId ?? ""}`;
|
|
1047
1403
|
}
|
|
@@ -1066,7 +1422,7 @@ function usePayPalPaymentMethods({
|
|
|
1066
1422
|
const hit = _cache2.get(key);
|
|
1067
1423
|
const seed = hit && Date.now() - hit.at < CACHE_TTL2 ? hit.result : null;
|
|
1068
1424
|
const [result, setResult] = useState4(seed ?? { ...DEFAULT_RESULT, loading: enabled });
|
|
1069
|
-
const fetchIdRef =
|
|
1425
|
+
const fetchIdRef = useRef3(0);
|
|
1070
1426
|
useEffect2(() => {
|
|
1071
1427
|
if (!enabled) {
|
|
1072
1428
|
setResult((prev) => ({ ...prev, loading: false }));
|
|
@@ -1093,12 +1449,13 @@ function usePayPalPaymentMethods({
|
|
|
1093
1449
|
cardTitle: typeof cfg.card_title === "string" && cfg.card_title ? cfg.card_title : "Credit or Debit Card",
|
|
1094
1450
|
loading: false
|
|
1095
1451
|
};
|
|
1096
|
-
|
|
1452
|
+
cacheSet2(k, { result: next, at: Date.now() });
|
|
1097
1453
|
setResult(next);
|
|
1098
1454
|
} catch (e) {
|
|
1099
|
-
|
|
1455
|
+
const msg = e instanceof Error ? e.message : "";
|
|
1456
|
+
if (e instanceof Error && e.name === "AbortError") return;
|
|
1100
1457
|
if (!mounted || id !== fetchIdRef.current) return;
|
|
1101
|
-
if (
|
|
1458
|
+
if (msg.includes("403") || msg.includes("Forbidden")) {
|
|
1102
1459
|
const disabled = {
|
|
1103
1460
|
...DEFAULT_RESULT,
|
|
1104
1461
|
paypalEnabled: false,
|
|
@@ -1128,8 +1485,10 @@ export {
|
|
|
1128
1485
|
PayPalProvider,
|
|
1129
1486
|
PayPalSmartButtons,
|
|
1130
1487
|
createPayPalStoreApi,
|
|
1488
|
+
hideProcessingOverlay,
|
|
1131
1489
|
isPayPalProviderId,
|
|
1132
1490
|
markPaymentComplete,
|
|
1491
|
+
showProcessingOverlay,
|
|
1133
1492
|
usePayPalConfig,
|
|
1134
1493
|
usePayPalPaymentMethods
|
|
1135
1494
|
};
|