@easypayment/medusa-payment-paypal 0.9.25 → 0.9.27
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/.medusa/server/src/admin/index.js +183 -297
- package/.medusa/server/src/admin/index.mjs +183 -297
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.d.ts +0 -1
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.d.ts.map +1 -1
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js +204 -368
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/onboard-return/route.d.ts +11 -9
- package/.medusa/server/src/api/store/paypal/onboard-return/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/onboard-return/route.js +28 -9
- package/.medusa/server/src/api/store/paypal/onboard-return/route.js.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.js +67 -55
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/service.js +15 -5
- package/.medusa/server/src/modules/paypal/payment-provider/service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/service.js +32 -6
- package/.medusa/server/src/modules/paypal/service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/utils/amounts.d.ts +10 -0
- package/.medusa/server/src/modules/paypal/utils/amounts.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/utils/amounts.js +36 -0
- package/.medusa/server/src/modules/paypal/utils/amounts.js.map +1 -1
- package/package.json +1 -1
- package/src/admin/routes/settings/paypal/connection/page.tsx +230 -389
- package/src/api/store/paypal/onboard-return/route.ts +34 -9
- package/src/modules/paypal/payment-provider/card-service.ts +85 -65
- package/src/modules/paypal/payment-provider/service.ts +22 -7
- package/src/modules/paypal/service.ts +34 -7
- package/src/modules/paypal/utils/amounts.ts +36 -0
|
@@ -307,21 +307,11 @@ function AdvancedCardPaymentsTab() {
|
|
|
307
307
|
)
|
|
308
308
|
] }) });
|
|
309
309
|
}
|
|
310
|
-
function PayPalApplePayPage() {
|
|
311
|
-
return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
312
|
-
}
|
|
313
|
-
function PayPalGooglePayPage() {
|
|
314
|
-
return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
315
|
-
}
|
|
316
310
|
const config = defineRouteConfig({
|
|
317
311
|
label: "PayPal Connection"
|
|
318
312
|
});
|
|
319
|
-
const
|
|
320
|
-
sandbox: "https://www.sandbox.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js",
|
|
321
|
-
live: "https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js"
|
|
322
|
-
};
|
|
313
|
+
const PARTNER_JS_URL = "https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js";
|
|
323
314
|
const SERVICE_URL = "/admin/paypal/onboarding-link";
|
|
324
|
-
const POPUP_NAME = "PPFrame";
|
|
325
315
|
const CACHE_PREFIX = "pp_onboard_cache";
|
|
326
316
|
const CACHE_EXPIRY = 6 * 60 * 60 * 1e3;
|
|
327
317
|
const ONBOARDING_COMPLETE_ENDPOINT = "/admin/paypal/onboard-complete";
|
|
@@ -346,9 +336,7 @@ function readCachedUrl(env) {
|
|
|
346
336
|
function writeCachedUrl(env, url) {
|
|
347
337
|
try {
|
|
348
338
|
localStorage.setItem(cacheKeyFor(env), JSON.stringify({ url, ts: Date.now() }));
|
|
349
|
-
return readCachedUrl(env) === url;
|
|
350
339
|
} catch {
|
|
351
|
-
return false;
|
|
352
340
|
}
|
|
353
341
|
}
|
|
354
342
|
function clearCachedUrl(env) {
|
|
@@ -362,62 +350,11 @@ function clearCachedUrl(env) {
|
|
|
362
350
|
} catch {
|
|
363
351
|
}
|
|
364
352
|
}
|
|
365
|
-
function isPayPalOrigin(origin) {
|
|
366
|
-
try {
|
|
367
|
-
const host = new URL(origin).hostname.toLowerCase();
|
|
368
|
-
return host === "www.paypal.com" || host === "www.sandbox.paypal.com" || host.endsWith(".paypal.com") || host.endsWith(".paypalobjects.com");
|
|
369
|
-
} catch {
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
function extractAuth(data) {
|
|
374
|
-
if (!data) return {};
|
|
375
|
-
if (typeof data === "object") {
|
|
376
|
-
const obj = data;
|
|
377
|
-
const authCode = obj.authCode ?? obj.auth_code ?? obj.authcode ?? obj.code;
|
|
378
|
-
const sharedId = obj.sharedId ?? obj.shared_id ?? obj.sharedid;
|
|
379
|
-
if (authCode && sharedId) {
|
|
380
|
-
return { authCode: String(authCode), sharedId: String(sharedId) };
|
|
381
|
-
}
|
|
382
|
-
for (const key of ["data", "payload", "message", "detail", "body", "params"]) {
|
|
383
|
-
if (obj[key] && typeof obj[key] === "object") {
|
|
384
|
-
const inner = extractAuth(obj[key]);
|
|
385
|
-
if (inner.authCode && inner.sharedId) return inner;
|
|
386
|
-
}
|
|
387
|
-
if (typeof obj[key] === "string") {
|
|
388
|
-
const inner = extractAuth(obj[key]);
|
|
389
|
-
if (inner.authCode && inner.sharedId) return inner;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
return {};
|
|
393
|
-
}
|
|
394
|
-
if (typeof data === "string") {
|
|
395
|
-
const s = data.trim();
|
|
396
|
-
if (!s) return {};
|
|
397
|
-
if (s.startsWith("{") || s.startsWith("[")) {
|
|
398
|
-
try {
|
|
399
|
-
return extractAuth(JSON.parse(s));
|
|
400
|
-
} catch {
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (/auth_?code/i.test(s) && /shared_?id/i.test(s)) {
|
|
404
|
-
try {
|
|
405
|
-
const sp = new URLSearchParams(s.replace(/^[?#]/, ""));
|
|
406
|
-
const authCode = sp.get("authCode") || sp.get("auth_code") || void 0;
|
|
407
|
-
const sharedId = sp.get("sharedId") || sp.get("shared_id") || void 0;
|
|
408
|
-
if (authCode && sharedId) return { authCode, sharedId };
|
|
409
|
-
} catch {
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
return {};
|
|
414
|
-
}
|
|
415
353
|
function PayPalConnectionPage() {
|
|
416
354
|
const [env, setEnv] = useState("live");
|
|
417
355
|
const [envReady, setEnvReady] = useState(false);
|
|
418
356
|
const [connState, setConnState] = useState("loading");
|
|
419
357
|
const [error, setError] = useState(null);
|
|
420
|
-
const [popupBlocked, setPopupBlocked] = useState(false);
|
|
421
358
|
const [finalUrl, setFinalUrl] = useState("");
|
|
422
359
|
const [showManual, setShowManual] = useState(false);
|
|
423
360
|
const [clientId, setClientId] = useState("");
|
|
@@ -429,17 +366,11 @@ function PayPalConnectionPage() {
|
|
|
429
366
|
const errorLogRef = useRef(null);
|
|
430
367
|
const runIdRef = useRef(0);
|
|
431
368
|
const currentRunId = useRef(0);
|
|
369
|
+
const completedRef = useRef(false);
|
|
432
370
|
const envRef = useRef(env);
|
|
433
371
|
envRef.current = env;
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
const connStateRef = useRef(connState);
|
|
437
|
-
connStateRef.current = connState;
|
|
438
|
-
const inProgressRef = useRef(onboardingInProgress);
|
|
439
|
-
inProgressRef.current = onboardingInProgress;
|
|
440
|
-
const popupRef = useRef(null);
|
|
441
|
-
const pollRef = useRef(null);
|
|
442
|
-
const completedRef = useRef(false);
|
|
372
|
+
const pollTimerRef = useRef(null);
|
|
373
|
+
const pollAttemptsRef = useRef(0);
|
|
443
374
|
const ppBtnMeasureRef = useRef(null);
|
|
444
375
|
const [ppBtnWidth, setPpBtnWidth] = useState(null);
|
|
445
376
|
const canSaveManual = useMemo(() => {
|
|
@@ -449,44 +380,72 @@ function PayPalConnectionPage() {
|
|
|
449
380
|
setConnState("error");
|
|
450
381
|
setError(msg);
|
|
451
382
|
}, []);
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
383
|
+
const closeMiniBrowser = useCallback(() => {
|
|
384
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
385
|
+
try {
|
|
386
|
+
const close1 = (_d = (_c = (_b = (_a = window.PAYPAL) == null ? void 0 : _a.apps) == null ? void 0 : _b.Signup) == null ? void 0 : _c.MiniBrowser) == null ? void 0 : _d.closeFlow;
|
|
387
|
+
if (typeof close1 === "function") close1();
|
|
388
|
+
} catch {
|
|
456
389
|
}
|
|
457
|
-
}, []);
|
|
458
|
-
const openOnboardingPopup = useCallback((url) => {
|
|
459
|
-
const w = 450;
|
|
460
|
-
const h = 600;
|
|
461
|
-
const baseLeft = typeof window.screenX === "number" ? window.screenX : window.screenLeft || 0;
|
|
462
|
-
const baseTop = typeof window.screenY === "number" ? window.screenY : window.screenTop || 0;
|
|
463
|
-
const outerW = window.outerWidth || document.documentElement.clientWidth || 1024;
|
|
464
|
-
const outerH = window.outerHeight || document.documentElement.clientHeight || 768;
|
|
465
|
-
const left = Math.round(baseLeft + Math.max(0, (outerW - w) / 2));
|
|
466
|
-
const top = Math.round(baseTop + Math.max(0, (outerH - h) / 2));
|
|
467
|
-
const features = `popup=yes,width=${w},height=${h},left=${left},top=${top},scrollbars=yes,resizable=yes`;
|
|
468
|
-
let popup = null;
|
|
469
390
|
try {
|
|
470
|
-
|
|
391
|
+
const close2 = (_h = (_g = (_f = (_e = window.PAYPAL) == null ? void 0 : _e.apps) == null ? void 0 : _f.Signup) == null ? void 0 : _g.miniBrowser) == null ? void 0 : _h.closeFlow;
|
|
392
|
+
if (typeof close2 === "function") close2();
|
|
471
393
|
} catch {
|
|
472
|
-
popup = null;
|
|
473
394
|
}
|
|
474
|
-
|
|
475
|
-
|
|
395
|
+
}, []);
|
|
396
|
+
const stopStatusPolling = useCallback(() => {
|
|
397
|
+
if (pollTimerRef.current) {
|
|
398
|
+
clearTimeout(pollTimerRef.current);
|
|
399
|
+
pollTimerRef.current = null;
|
|
400
|
+
}
|
|
401
|
+
pollAttemptsRef.current = 0;
|
|
402
|
+
}, []);
|
|
403
|
+
const refreshStatusAndMaybeConnect = useCallback(
|
|
404
|
+
async (activeEnv) => {
|
|
476
405
|
try {
|
|
477
|
-
|
|
406
|
+
const res = await fetch(`${STATUS_ENDPOINT}?environment=${activeEnv}`, {
|
|
407
|
+
method: "GET",
|
|
408
|
+
credentials: "include"
|
|
409
|
+
});
|
|
410
|
+
const st = await res.json().catch(() => ({}));
|
|
411
|
+
const connected = (st == null ? void 0 : st.status) === "connected" && (st == null ? void 0 : st.seller_client_id_present) === true;
|
|
412
|
+
if (connected) {
|
|
413
|
+
completedRef.current = true;
|
|
414
|
+
setStatusInfo(st);
|
|
415
|
+
setConnState("connected");
|
|
416
|
+
setShowManual(false);
|
|
417
|
+
setOnboardingInProgress(false);
|
|
418
|
+
clearCachedUrl(activeEnv);
|
|
419
|
+
closeMiniBrowser();
|
|
420
|
+
stopStatusPolling();
|
|
421
|
+
}
|
|
422
|
+
return connected;
|
|
478
423
|
} catch {
|
|
424
|
+
return false;
|
|
479
425
|
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
|
|
426
|
+
},
|
|
427
|
+
[closeMiniBrowser, stopStatusPolling]
|
|
428
|
+
);
|
|
429
|
+
const startStatusPolling = useCallback(() => {
|
|
430
|
+
stopStatusPolling();
|
|
431
|
+
const MAX_ATTEMPTS = 100;
|
|
432
|
+
const tick = async () => {
|
|
433
|
+
pollAttemptsRef.current += 1;
|
|
434
|
+
const connected = await refreshStatusAndMaybeConnect(envRef.current);
|
|
435
|
+
if (connected || completedRef.current) return;
|
|
436
|
+
if (pollAttemptsRef.current >= MAX_ATTEMPTS) {
|
|
437
|
+
stopStatusPolling();
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
pollTimerRef.current = setTimeout(tick, 3e3);
|
|
441
|
+
};
|
|
442
|
+
pollTimerRef.current = setTimeout(tick, 3e3);
|
|
443
|
+
}, [refreshStatusAndMaybeConnect, stopStatusPolling]);
|
|
483
444
|
const completeOnboarding = useCallback(
|
|
484
445
|
async (authCode, sharedId) => {
|
|
485
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
486
446
|
if (!authCode || !sharedId) return;
|
|
487
447
|
if (completedRef.current) return;
|
|
488
448
|
completedRef.current = true;
|
|
489
|
-
stopPoll();
|
|
490
449
|
try {
|
|
491
450
|
window.onbeforeunload = null;
|
|
492
451
|
} catch {
|
|
@@ -495,7 +454,6 @@ function PayPalConnectionPage() {
|
|
|
495
454
|
setOnboardingInProgress(true);
|
|
496
455
|
setConnState("loading");
|
|
497
456
|
setError(null);
|
|
498
|
-
setPopupBlocked(false);
|
|
499
457
|
try {
|
|
500
458
|
const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
|
|
501
459
|
method: "POST",
|
|
@@ -507,32 +465,20 @@ function PayPalConnectionPage() {
|
|
|
507
465
|
const txt = await res.text().catch(() => "");
|
|
508
466
|
throw new Error(txt || `Onboarding exchange failed (${res.status})`);
|
|
509
467
|
}
|
|
510
|
-
|
|
511
|
-
(_a = popupRef.current) == null ? void 0 : _a.close();
|
|
512
|
-
} catch {
|
|
513
|
-
}
|
|
514
|
-
try {
|
|
515
|
-
const close1 = (_e = (_d = (_c = (_b = window.PAYPAL) == null ? void 0 : _b.apps) == null ? void 0 : _c.Signup) == null ? void 0 : _d.MiniBrowser) == null ? void 0 : _e.closeFlow;
|
|
516
|
-
if (typeof close1 === "function") close1();
|
|
517
|
-
} catch {
|
|
518
|
-
}
|
|
519
|
-
try {
|
|
520
|
-
const close2 = ((_h = (_g = (_f = window.PAYPAL) == null ? void 0 : _f.apps) == null ? void 0 : _g.Signup) == null ? void 0 : _h.miniBrowser) && window.PAYPAL.apps.Signup.miniBrowser.closeFlow;
|
|
521
|
-
if (typeof close2 === "function") close2();
|
|
522
|
-
} catch {
|
|
523
|
-
}
|
|
468
|
+
closeMiniBrowser();
|
|
524
469
|
clearCachedUrl(activeEnv);
|
|
525
470
|
try {
|
|
526
|
-
const statusRes = await fetch(
|
|
527
|
-
|
|
528
|
-
credentials: "include"
|
|
529
|
-
|
|
471
|
+
const statusRes = await fetch(
|
|
472
|
+
`${STATUS_ENDPOINT}?environment=${activeEnv}`,
|
|
473
|
+
{ method: "GET", credentials: "include" }
|
|
474
|
+
);
|
|
530
475
|
const refreshedStatus = await statusRes.json().catch(() => ({}));
|
|
531
476
|
setStatusInfo(refreshedStatus || null);
|
|
532
477
|
} catch {
|
|
533
478
|
}
|
|
534
479
|
setConnState("connected");
|
|
535
480
|
setShowManual(false);
|
|
481
|
+
stopStatusPolling();
|
|
536
482
|
} catch (e) {
|
|
537
483
|
completedRef.current = false;
|
|
538
484
|
console.error(e);
|
|
@@ -542,42 +488,72 @@ function PayPalConnectionPage() {
|
|
|
542
488
|
setOnboardingInProgress(false);
|
|
543
489
|
}
|
|
544
490
|
},
|
|
545
|
-
[
|
|
491
|
+
[closeMiniBrowser, stopStatusPolling]
|
|
546
492
|
);
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
ticks += 1;
|
|
553
|
-
if (completedRef.current || ticks > 150) {
|
|
554
|
-
stopPoll();
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
493
|
+
const initPartner = useCallback(() => {
|
|
494
|
+
var _a, _b;
|
|
495
|
+
const signup = (_b = (_a = window.PAYPAL) == null ? void 0 : _a.apps) == null ? void 0 : _b.Signup;
|
|
496
|
+
const init = (signup == null ? void 0 : signup.miniBrowser) && signup.miniBrowser.init || (signup == null ? void 0 : signup.MiniBrowser) && signup.MiniBrowser.init;
|
|
497
|
+
if (typeof init === "function") {
|
|
557
498
|
try {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
499
|
+
init();
|
|
500
|
+
} catch (e) {
|
|
501
|
+
console.error("[paypal] partner.js init failed:", e);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}, []);
|
|
505
|
+
useEffect(() => {
|
|
506
|
+
const existingScript = document.getElementById("paypal-partner-js");
|
|
507
|
+
if (existingScript) return;
|
|
508
|
+
const preloadHref = PARTNER_JS_URL;
|
|
509
|
+
let preloadLink = null;
|
|
510
|
+
if (!document.head.querySelector(`link[rel="preload"][href="${preloadHref}"]`)) {
|
|
511
|
+
preloadLink = document.createElement("link");
|
|
512
|
+
preloadLink.rel = "preload";
|
|
513
|
+
preloadLink.href = preloadHref;
|
|
514
|
+
preloadLink.as = "script";
|
|
515
|
+
document.head.appendChild(preloadLink);
|
|
516
|
+
}
|
|
517
|
+
const ppScript = document.createElement("script");
|
|
518
|
+
ppScript.id = "paypal-partner-js";
|
|
519
|
+
ppScript.src = preloadHref;
|
|
520
|
+
ppScript.async = true;
|
|
521
|
+
document.head.appendChild(ppScript);
|
|
522
|
+
return () => {
|
|
523
|
+
if (preloadLink == null ? void 0 : preloadLink.parentNode) preloadLink.parentNode.removeChild(preloadLink);
|
|
524
|
+
if (ppScript.parentNode) ppScript.parentNode.removeChild(ppScript);
|
|
525
|
+
};
|
|
526
|
+
}, []);
|
|
527
|
+
const activatePayPal = useCallback(
|
|
528
|
+
(url, runId) => {
|
|
529
|
+
if (paypalButtonRef.current) {
|
|
530
|
+
paypalButtonRef.current.href = url;
|
|
577
531
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
532
|
+
setFinalUrl(url);
|
|
533
|
+
let attempts = 0;
|
|
534
|
+
const MAX_ATTEMPTS = 200;
|
|
535
|
+
const tryInit = () => {
|
|
536
|
+
var _a, _b;
|
|
537
|
+
if (runId !== currentRunId.current) return;
|
|
538
|
+
if ((_b = (_a = window.PAYPAL) == null ? void 0 : _a.apps) == null ? void 0 : _b.Signup) {
|
|
539
|
+
initPartner();
|
|
540
|
+
setConnState("ready");
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
attempts++;
|
|
544
|
+
if (attempts >= MAX_ATTEMPTS) {
|
|
545
|
+
showError(
|
|
546
|
+
"PayPal partner script failed to load. Please refresh and try again."
|
|
547
|
+
);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
setTimeout(tryInit, 50);
|
|
551
|
+
};
|
|
552
|
+
tryInit();
|
|
553
|
+
},
|
|
554
|
+
[initPartner, showError]
|
|
555
|
+
);
|
|
556
|
+
const fetchFreshLink = useCallback(
|
|
581
557
|
async (targetEnv, runId) => {
|
|
582
558
|
if (initLoaderRef.current) {
|
|
583
559
|
const loaderText = initLoaderRef.current.querySelector("#loader-text");
|
|
@@ -599,19 +575,14 @@ function PayPalConnectionPage() {
|
|
|
599
575
|
return;
|
|
600
576
|
}
|
|
601
577
|
const url = href + (href.includes("?") ? "&" : "?") + "displayMode=minibrowser";
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
window.location.reload();
|
|
605
|
-
return;
|
|
606
|
-
}
|
|
607
|
-
setFinalUrl(url);
|
|
608
|
-
setConnState("ready");
|
|
578
|
+
writeCachedUrl(targetEnv, url);
|
|
579
|
+
activatePayPal(url, runId);
|
|
609
580
|
} catch {
|
|
610
581
|
if (runId !== currentRunId.current) return;
|
|
611
582
|
showError("Unable to connect to service.");
|
|
612
583
|
}
|
|
613
584
|
},
|
|
614
|
-
[showError]
|
|
585
|
+
[activatePayPal, showError]
|
|
615
586
|
);
|
|
616
587
|
useEffect(() => {
|
|
617
588
|
let alive = true;
|
|
@@ -635,7 +606,6 @@ function PayPalConnectionPage() {
|
|
|
635
606
|
const run = async () => {
|
|
636
607
|
setConnState("loading");
|
|
637
608
|
setError(null);
|
|
638
|
-
setPopupBlocked(false);
|
|
639
609
|
setFinalUrl("");
|
|
640
610
|
try {
|
|
641
611
|
const r = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
@@ -657,149 +627,43 @@ function PayPalConnectionPage() {
|
|
|
657
627
|
if (cancelled || runId !== currentRunId.current) return;
|
|
658
628
|
const cached = readCachedUrl(env);
|
|
659
629
|
if (cached) {
|
|
660
|
-
|
|
661
|
-
setConnState("ready");
|
|
630
|
+
activatePayPal(cached, runId);
|
|
662
631
|
return;
|
|
663
632
|
}
|
|
664
|
-
await
|
|
633
|
+
await fetchFreshLink(env, runId);
|
|
665
634
|
};
|
|
666
635
|
run();
|
|
667
636
|
return () => {
|
|
668
637
|
cancelled = true;
|
|
669
638
|
};
|
|
670
|
-
}, [env, envReady,
|
|
671
|
-
useEffect(() => {
|
|
672
|
-
var _a, _b, _c;
|
|
673
|
-
if (connState !== "ready" || !finalUrl) return;
|
|
674
|
-
const scriptUrl = PARTNER_JS_URLS[env];
|
|
675
|
-
let cancelled = false;
|
|
676
|
-
let pollTimer;
|
|
677
|
-
const initPartner = (attempt = 0) => {
|
|
678
|
-
var _a2, _b2;
|
|
679
|
-
if (cancelled) return;
|
|
680
|
-
const signup = (_b2 = (_a2 = window.PAYPAL) == null ? void 0 : _a2.apps) == null ? void 0 : _b2.Signup;
|
|
681
|
-
const target = (signup == null ? void 0 : signup.miniBrowser) && typeof signup.miniBrowser.init === "function" ? signup.miniBrowser : (signup == null ? void 0 : signup.MiniBrowser) && typeof signup.MiniBrowser.init === "function" ? signup.MiniBrowser : null;
|
|
682
|
-
if (target == null ? void 0 : target.init) {
|
|
683
|
-
try {
|
|
684
|
-
target.init();
|
|
685
|
-
} catch (e) {
|
|
686
|
-
console.error("[paypal] partner.js init failed:", e);
|
|
687
|
-
}
|
|
688
|
-
return;
|
|
689
|
-
}
|
|
690
|
-
if (typeof (signup == null ? void 0 : signup.render) === "function") {
|
|
691
|
-
try {
|
|
692
|
-
signup.render();
|
|
693
|
-
} catch (e) {
|
|
694
|
-
console.error("[paypal] partner.js render failed:", e);
|
|
695
|
-
}
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
if (attempt < 40) {
|
|
699
|
-
pollTimer = setTimeout(() => initPartner(attempt + 1), 50);
|
|
700
|
-
return;
|
|
701
|
-
}
|
|
702
|
-
try {
|
|
703
|
-
document.dispatchEvent(new Event("DOMContentLoaded"));
|
|
704
|
-
} catch {
|
|
705
|
-
}
|
|
706
|
-
};
|
|
707
|
-
const existingScript = document.getElementById("paypal-partner-js");
|
|
708
|
-
if (existingScript) {
|
|
709
|
-
(_a = existingScript.parentNode) == null ? void 0 : _a.removeChild(existingScript);
|
|
710
|
-
}
|
|
711
|
-
if ((_c = (_b = window.PAYPAL) == null ? void 0 : _b.apps) == null ? void 0 : _c.Signup) {
|
|
712
|
-
try {
|
|
713
|
-
delete window.PAYPAL.apps.Signup;
|
|
714
|
-
} catch {
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
const ppScript = document.createElement("script");
|
|
718
|
-
ppScript.id = "paypal-partner-js";
|
|
719
|
-
ppScript.src = scriptUrl;
|
|
720
|
-
ppScript.async = true;
|
|
721
|
-
ppScript.onload = () => initPartner();
|
|
722
|
-
document.body.appendChild(ppScript);
|
|
723
|
-
return () => {
|
|
724
|
-
cancelled = true;
|
|
725
|
-
if (pollTimer) clearTimeout(pollTimer);
|
|
726
|
-
if (ppScript.parentNode) ppScript.parentNode.removeChild(ppScript);
|
|
727
|
-
};
|
|
728
|
-
}, [connState, finalUrl, env]);
|
|
729
|
-
useEffect(() => {
|
|
730
|
-
const onMessage = (ev) => {
|
|
731
|
-
var _a;
|
|
732
|
-
let serialized = "";
|
|
733
|
-
try {
|
|
734
|
-
serialized = typeof ev.data === "string" ? ev.data : JSON.stringify(ev.data);
|
|
735
|
-
} catch {
|
|
736
|
-
serialized = String(ev.data);
|
|
737
|
-
}
|
|
738
|
-
const looksRelevant = isPayPalOrigin(ev.origin) || /auth_?code|shared_?id|onboard|merchantId/i.test(serialized || "");
|
|
739
|
-
if (looksRelevant) {
|
|
740
|
-
console.info(
|
|
741
|
-
"[PayPal onboarding] message from",
|
|
742
|
-
ev.origin,
|
|
743
|
-
"·",
|
|
744
|
-
(serialized || "").slice(0, 500)
|
|
745
|
-
);
|
|
746
|
-
}
|
|
747
|
-
const d = ev.data;
|
|
748
|
-
if (d && typeof d === "object" && d.source === "paypal-onboarding-return") {
|
|
749
|
-
try {
|
|
750
|
-
(_a = popupRef.current) == null ? void 0 : _a.close();
|
|
751
|
-
} catch {
|
|
752
|
-
}
|
|
753
|
-
const fromReturn = extractAuth(d.params);
|
|
754
|
-
if (fromReturn.authCode && fromReturn.sharedId) {
|
|
755
|
-
completeOnboarding(fromReturn.authCode, fromReturn.sharedId);
|
|
756
|
-
} else if (!completedRef.current) {
|
|
757
|
-
startStatusPoll();
|
|
758
|
-
}
|
|
759
|
-
return;
|
|
760
|
-
}
|
|
761
|
-
if (!isPayPalOrigin(ev.origin)) return;
|
|
762
|
-
const { authCode, sharedId } = extractAuth(ev.data);
|
|
763
|
-
if (authCode && sharedId) {
|
|
764
|
-
completeOnboarding(authCode, sharedId);
|
|
765
|
-
}
|
|
766
|
-
};
|
|
767
|
-
window.addEventListener("message", onMessage);
|
|
768
|
-
return () => window.removeEventListener("message", onMessage);
|
|
769
|
-
}, [completeOnboarding, startStatusPoll]);
|
|
639
|
+
}, [env, envReady, fetchFreshLink, activatePayPal]);
|
|
770
640
|
useLayoutEffect(() => {
|
|
771
641
|
window.onboardingCallback = (authCode, sharedId) => {
|
|
772
|
-
completeOnboarding(authCode, sharedId);
|
|
642
|
+
void completeOnboarding(authCode, sharedId);
|
|
773
643
|
};
|
|
774
644
|
return () => {
|
|
775
645
|
window.onboardingCallback = void 0;
|
|
776
646
|
};
|
|
777
647
|
}, [completeOnboarding]);
|
|
778
648
|
useEffect(() => {
|
|
779
|
-
const
|
|
780
|
-
const
|
|
781
|
-
if (!
|
|
782
|
-
const
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
return;
|
|
793
|
-
}
|
|
794
|
-
setPopupBlocked(false);
|
|
795
|
-
startStatusPoll();
|
|
649
|
+
const onMessage = (event) => {
|
|
650
|
+
const data = event == null ? void 0 : event.data;
|
|
651
|
+
if (!data || data.source !== "paypal-onboarding-return") return;
|
|
652
|
+
const params = data.params || {};
|
|
653
|
+
const authCode = params.authCode || params.auth_code;
|
|
654
|
+
const sharedId = params.sharedId || params.shared_id;
|
|
655
|
+
const activeEnv = envRef.current;
|
|
656
|
+
void (async () => {
|
|
657
|
+
const connected = await refreshStatusAndMaybeConnect(activeEnv);
|
|
658
|
+
if (!connected && authCode && sharedId) {
|
|
659
|
+
await completeOnboarding(authCode, sharedId);
|
|
660
|
+
}
|
|
661
|
+
})();
|
|
796
662
|
};
|
|
797
|
-
|
|
798
|
-
return () =>
|
|
799
|
-
}, [
|
|
800
|
-
useEffect(() =>
|
|
801
|
-
return () => stopPoll();
|
|
802
|
-
}, [stopPoll]);
|
|
663
|
+
window.addEventListener("message", onMessage);
|
|
664
|
+
return () => window.removeEventListener("message", onMessage);
|
|
665
|
+
}, [completeOnboarding, refreshStatusAndMaybeConnect]);
|
|
666
|
+
useEffect(() => stopStatusPolling, [stopStatusPolling]);
|
|
803
667
|
useLayoutEffect(() => {
|
|
804
668
|
const el = ppBtnMeasureRef.current;
|
|
805
669
|
if (!el) return;
|
|
@@ -821,7 +685,12 @@ function PayPalConnectionPage() {
|
|
|
821
685
|
};
|
|
822
686
|
}, [connState, env, finalUrl]);
|
|
823
687
|
const handleConnectClick = (e) => {
|
|
824
|
-
|
|
688
|
+
if (connState !== "ready" || !finalUrl || onboardingInProgress) {
|
|
689
|
+
e.preventDefault();
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
completedRef.current = false;
|
|
693
|
+
startStatusPolling();
|
|
825
694
|
};
|
|
826
695
|
const handleSaveManual = async () => {
|
|
827
696
|
if (!canSaveManual || onboardingInProgress) return;
|
|
@@ -863,6 +732,7 @@ function PayPalConnectionPage() {
|
|
|
863
732
|
const handleDisconnect = async () => {
|
|
864
733
|
if (onboardingInProgress) return;
|
|
865
734
|
if (!window.confirm("Disconnect PayPal for this environment?")) return;
|
|
735
|
+
stopStatusPolling();
|
|
866
736
|
setOnboardingInProgress(true);
|
|
867
737
|
setConnState("loading");
|
|
868
738
|
setError(null);
|
|
@@ -883,7 +753,7 @@ function PayPalConnectionPage() {
|
|
|
883
753
|
clearCachedUrl(env);
|
|
884
754
|
completedRef.current = false;
|
|
885
755
|
currentRunId.current = ++runIdRef.current;
|
|
886
|
-
await
|
|
756
|
+
await fetchFreshLink(env, currentRunId.current);
|
|
887
757
|
} catch (e) {
|
|
888
758
|
console.error(e);
|
|
889
759
|
setConnState("error");
|
|
@@ -895,9 +765,9 @@ function PayPalConnectionPage() {
|
|
|
895
765
|
const handleEnvChange = async (e) => {
|
|
896
766
|
const next = e.target.value;
|
|
897
767
|
if (next === env || onboardingInProgress) return;
|
|
768
|
+
stopStatusPolling();
|
|
898
769
|
completedRef.current = false;
|
|
899
770
|
clearCachedUrl();
|
|
900
|
-
setPopupBlocked(false);
|
|
901
771
|
setConnState("loading");
|
|
902
772
|
try {
|
|
903
773
|
await fetch(ENVIRONMENT_ENDPOINT, {
|
|
@@ -931,7 +801,19 @@ function PayPalConnectionPage() {
|
|
|
931
801
|
) }),
|
|
932
802
|
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium pt-2", children: env === "sandbox" ? "Connect to PayPal (Sandbox)" : "Connect to PayPal" }),
|
|
933
803
|
/* @__PURE__ */ jsx("div", { className: "max-w-xl", children: connState === "connected" ? /* @__PURE__ */ jsxs("div", { children: [
|
|
934
|
-
/* @__PURE__ */
|
|
804
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm text-green-600 bg-green-50 p-3 rounded border border-green-200", children: [
|
|
805
|
+
"✅ Successfully connected to PayPal!",
|
|
806
|
+
/* @__PURE__ */ jsx(
|
|
807
|
+
"a",
|
|
808
|
+
{
|
|
809
|
+
"data-paypal-button": "true",
|
|
810
|
+
"data-paypal-onboard-complete": "onboardingCallback",
|
|
811
|
+
href: "#",
|
|
812
|
+
style: { display: "none" },
|
|
813
|
+
children: "PayPal"
|
|
814
|
+
}
|
|
815
|
+
)
|
|
816
|
+
] }),
|
|
935
817
|
/* @__PURE__ */ jsxs("div", { className: "mt-3 rounded-md border border-ui-border-base bg-ui-bg-subtle p-3 text-xs text-ui-fg-subtle", children: [
|
|
936
818
|
/* @__PURE__ */ jsx("div", { className: "font-medium text-ui-fg-base", children: "Connected PayPal account" }),
|
|
937
819
|
/* @__PURE__ */ jsxs("div", { className: "mt-1", children: [
|
|
@@ -972,7 +854,6 @@ function PayPalConnectionPage() {
|
|
|
972
854
|
ppBtnMeasureRef.current = node;
|
|
973
855
|
},
|
|
974
856
|
id: "paypal-button",
|
|
975
|
-
target: POPUP_NAME,
|
|
976
857
|
"data-paypal-button": "true",
|
|
977
858
|
href: finalUrl || "#",
|
|
978
859
|
"data-paypal-onboard-complete": "onboardingCallback",
|
|
@@ -986,7 +867,6 @@ function PayPalConnectionPage() {
|
|
|
986
867
|
children: "Connect to PayPal"
|
|
987
868
|
}
|
|
988
869
|
),
|
|
989
|
-
popupBlocked && /* @__PURE__ */ jsx("div", { className: "mt-3 text-left text-xs bg-amber-50 text-amber-700 p-3 border border-amber-200 rounded", children: "Your browser blocked the PayPal popup. Please allow popups for this site, then click “Connect to PayPal” again." }),
|
|
990
870
|
/* @__PURE__ */ jsx(
|
|
991
871
|
"div",
|
|
992
872
|
{
|
|
@@ -1142,6 +1022,12 @@ function PayPalConnectionPage() {
|
|
|
1142
1022
|
` })
|
|
1143
1023
|
] });
|
|
1144
1024
|
}
|
|
1025
|
+
function PayPalApplePayPage() {
|
|
1026
|
+
return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
1027
|
+
}
|
|
1028
|
+
function PayPalGooglePayPage() {
|
|
1029
|
+
return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
1030
|
+
}
|
|
1145
1031
|
function PayPalPayLaterMessagingPage() {
|
|
1146
1032
|
return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
1147
1033
|
}
|
|
@@ -1367,6 +1253,10 @@ const routeModule = {
|
|
|
1367
1253
|
Component: AdvancedCardPaymentsTab,
|
|
1368
1254
|
path: "/settings/paypal/advanced-card-payments"
|
|
1369
1255
|
},
|
|
1256
|
+
{
|
|
1257
|
+
Component: PayPalConnectionPage,
|
|
1258
|
+
path: "/settings/paypal/connection"
|
|
1259
|
+
},
|
|
1370
1260
|
{
|
|
1371
1261
|
Component: PayPalApplePayPage,
|
|
1372
1262
|
path: "/settings/paypal/apple-pay"
|
|
@@ -1375,10 +1265,6 @@ const routeModule = {
|
|
|
1375
1265
|
Component: PayPalGooglePayPage,
|
|
1376
1266
|
path: "/settings/paypal/google-pay"
|
|
1377
1267
|
},
|
|
1378
|
-
{
|
|
1379
|
-
Component: PayPalConnectionPage,
|
|
1380
|
-
path: "/settings/paypal/connection"
|
|
1381
|
-
},
|
|
1382
1268
|
{
|
|
1383
1269
|
Component: PayPalPayLaterMessagingPage,
|
|
1384
1270
|
path: "/settings/paypal/pay-later-messaging"
|