@easypayment/medusa-payment-paypal 0.9.22 → 0.9.25
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 +264 -80
- package/.medusa/server/src/admin/index.mjs +264 -80
- 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 +340 -146
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js.map +1 -1
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js +6 -8
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/environment/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/paypal/environment/route.js +11 -3
- package/.medusa/server/src/api/admin/paypal/environment/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts +7 -0
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js +7 -0
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js +4 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js.map +1 -1
- package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js +6 -8
- package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/capture-order/route.js +11 -0
- package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/onboard-return/route.d.ts +23 -0
- package/.medusa/server/src/api/store/paypal/onboard-return/route.d.ts.map +1 -0
- package/.medusa/server/src/api/store/paypal/onboard-return/route.js +63 -0
- package/.medusa/server/src/api/store/paypal/onboard-return/route.js.map +1 -0
- package/.medusa/server/src/api/store/paypal-complete/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal-complete/route.js +2 -4
- package/.medusa/server/src/api/store/paypal-complete/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 +55 -34
- package/.medusa/server/src/modules/paypal/payment-provider/card-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 +5 -1
- package/.medusa/server/src/modules/paypal/service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/utils/core-workflow.d.ts +32 -0
- package/.medusa/server/src/modules/paypal/utils/core-workflow.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/utils/core-workflow.js +40 -0
- package/.medusa/server/src/modules/paypal/utils/core-workflow.js.map +1 -0
- package/package.json +1 -1
- package/src/admin/routes/settings/paypal/connection/page.tsx +364 -160
- package/src/api/admin/payment-collections/[id]/payment-sessions/route.ts +6 -8
- package/src/api/admin/paypal/environment/route.ts +10 -3
- package/src/api/admin/paypal/onboard-complete/route.ts +7 -0
- package/src/api/admin/paypal/onboarding-status/route.ts +4 -1
- package/src/api/store/payment-collections/[id]/payment-sessions/route.ts +6 -8
- package/src/api/store/paypal/capture-order/route.ts +15 -0
- package/src/api/store/paypal/onboard-return/route.ts +63 -0
- package/src/api/store/paypal-complete/route.ts +6 -4
- package/src/modules/paypal/payment-provider/card-service.ts +72 -38
- package/src/modules/paypal/service.ts +5 -1
- package/src/modules/paypal/utils/core-workflow.ts +46 -0
|
@@ -362,12 +362,62 @@ function clearCachedUrl(env) {
|
|
|
362
362
|
} catch {
|
|
363
363
|
}
|
|
364
364
|
}
|
|
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
|
+
}
|
|
365
415
|
function PayPalConnectionPage() {
|
|
366
416
|
const [env, setEnv] = useState("live");
|
|
367
417
|
const [envReady, setEnvReady] = useState(false);
|
|
368
418
|
const [connState, setConnState] = useState("loading");
|
|
369
|
-
const [partnerReady, setPartnerReady] = useState(false);
|
|
370
419
|
const [error, setError] = useState(null);
|
|
420
|
+
const [popupBlocked, setPopupBlocked] = useState(false);
|
|
371
421
|
const [finalUrl, setFinalUrl] = useState("");
|
|
372
422
|
const [showManual, setShowManual] = useState(false);
|
|
373
423
|
const [clientId, setClientId] = useState("");
|
|
@@ -375,11 +425,20 @@ function PayPalConnectionPage() {
|
|
|
375
425
|
const [statusInfo, setStatusInfo] = useState(null);
|
|
376
426
|
const [onboardingInProgress, setOnboardingInProgress] = useState(false);
|
|
377
427
|
const initLoaderRef = useRef(null);
|
|
428
|
+
const paypalButtonRef = useRef(null);
|
|
378
429
|
const errorLogRef = useRef(null);
|
|
379
430
|
const runIdRef = useRef(0);
|
|
380
431
|
const currentRunId = useRef(0);
|
|
381
432
|
const envRef = useRef(env);
|
|
382
433
|
envRef.current = env;
|
|
434
|
+
const finalUrlRef = useRef(finalUrl);
|
|
435
|
+
finalUrlRef.current = finalUrl;
|
|
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);
|
|
383
442
|
const completedRef = useRef(false);
|
|
384
443
|
const ppBtnMeasureRef = useRef(null);
|
|
385
444
|
const [ppBtnWidth, setPpBtnWidth] = useState(null);
|
|
@@ -390,13 +449,139 @@ function PayPalConnectionPage() {
|
|
|
390
449
|
setConnState("error");
|
|
391
450
|
setError(msg);
|
|
392
451
|
}, []);
|
|
452
|
+
const stopPoll = useCallback(() => {
|
|
453
|
+
if (pollRef.current) {
|
|
454
|
+
clearInterval(pollRef.current);
|
|
455
|
+
pollRef.current = null;
|
|
456
|
+
}
|
|
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
|
+
try {
|
|
470
|
+
popup = window.open(url, POPUP_NAME, features);
|
|
471
|
+
} catch {
|
|
472
|
+
popup = null;
|
|
473
|
+
}
|
|
474
|
+
if (popup) {
|
|
475
|
+
popupRef.current = popup;
|
|
476
|
+
try {
|
|
477
|
+
popup.focus();
|
|
478
|
+
} catch {
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return popup;
|
|
482
|
+
}, []);
|
|
483
|
+
const completeOnboarding = useCallback(
|
|
484
|
+
async (authCode, sharedId) => {
|
|
485
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
486
|
+
if (!authCode || !sharedId) return;
|
|
487
|
+
if (completedRef.current) return;
|
|
488
|
+
completedRef.current = true;
|
|
489
|
+
stopPoll();
|
|
490
|
+
try {
|
|
491
|
+
window.onbeforeunload = null;
|
|
492
|
+
} catch {
|
|
493
|
+
}
|
|
494
|
+
const activeEnv = envRef.current === "sandbox" ? "sandbox" : "live";
|
|
495
|
+
setOnboardingInProgress(true);
|
|
496
|
+
setConnState("loading");
|
|
497
|
+
setError(null);
|
|
498
|
+
setPopupBlocked(false);
|
|
499
|
+
try {
|
|
500
|
+
const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
|
|
501
|
+
method: "POST",
|
|
502
|
+
headers: { "content-type": "application/json" },
|
|
503
|
+
credentials: "include",
|
|
504
|
+
body: JSON.stringify({ authCode, sharedId, env: activeEnv })
|
|
505
|
+
});
|
|
506
|
+
if (!res.ok) {
|
|
507
|
+
const txt = await res.text().catch(() => "");
|
|
508
|
+
throw new Error(txt || `Onboarding exchange failed (${res.status})`);
|
|
509
|
+
}
|
|
510
|
+
try {
|
|
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
|
+
}
|
|
524
|
+
clearCachedUrl(activeEnv);
|
|
525
|
+
try {
|
|
526
|
+
const statusRes = await fetch(`${STATUS_ENDPOINT}?environment=${activeEnv}`, {
|
|
527
|
+
method: "GET",
|
|
528
|
+
credentials: "include"
|
|
529
|
+
});
|
|
530
|
+
const refreshedStatus = await statusRes.json().catch(() => ({}));
|
|
531
|
+
setStatusInfo(refreshedStatus || null);
|
|
532
|
+
} catch {
|
|
533
|
+
}
|
|
534
|
+
setConnState("connected");
|
|
535
|
+
setShowManual(false);
|
|
536
|
+
} catch (e) {
|
|
537
|
+
completedRef.current = false;
|
|
538
|
+
console.error(e);
|
|
539
|
+
setConnState("error");
|
|
540
|
+
setError((e == null ? void 0 : e.message) || "Exchange failed while saving credentials.");
|
|
541
|
+
} finally {
|
|
542
|
+
setOnboardingInProgress(false);
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
[stopPoll]
|
|
546
|
+
);
|
|
547
|
+
const startStatusPoll = useCallback(() => {
|
|
548
|
+
stopPoll();
|
|
549
|
+
let ticks = 0;
|
|
550
|
+
pollRef.current = setInterval(async () => {
|
|
551
|
+
var _a;
|
|
552
|
+
ticks += 1;
|
|
553
|
+
if (completedRef.current || ticks > 150) {
|
|
554
|
+
stopPoll();
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
try {
|
|
558
|
+
const r = await fetch(`${STATUS_ENDPOINT}?environment=${envRef.current}`, {
|
|
559
|
+
method: "GET",
|
|
560
|
+
credentials: "include"
|
|
561
|
+
});
|
|
562
|
+
const st = await r.json().catch(() => ({}));
|
|
563
|
+
if ((st == null ? void 0 : st.status) === "connected" && (st == null ? void 0 : st.seller_client_id_present) === true) {
|
|
564
|
+
completedRef.current = true;
|
|
565
|
+
stopPoll();
|
|
566
|
+
try {
|
|
567
|
+
(_a = popupRef.current) == null ? void 0 : _a.close();
|
|
568
|
+
} catch {
|
|
569
|
+
}
|
|
570
|
+
clearCachedUrl(envRef.current);
|
|
571
|
+
setStatusInfo(st);
|
|
572
|
+
setConnState("connected");
|
|
573
|
+
setShowManual(false);
|
|
574
|
+
setOnboardingInProgress(false);
|
|
575
|
+
}
|
|
576
|
+
} catch {
|
|
577
|
+
}
|
|
578
|
+
}, 2e3);
|
|
579
|
+
}, [stopPoll]);
|
|
393
580
|
const generateLinkAndReload = useCallback(
|
|
394
581
|
async (targetEnv, runId) => {
|
|
395
582
|
if (initLoaderRef.current) {
|
|
396
583
|
const loaderText = initLoaderRef.current.querySelector("#loader-text");
|
|
397
|
-
if (loaderText)
|
|
398
|
-
loaderText.textContent = "Generating onboarding session...";
|
|
399
|
-
}
|
|
584
|
+
if (loaderText) loaderText.textContent = "Generating onboarding session...";
|
|
400
585
|
}
|
|
401
586
|
try {
|
|
402
587
|
const res = await fetch(SERVICE_URL, {
|
|
@@ -450,6 +635,7 @@ function PayPalConnectionPage() {
|
|
|
450
635
|
const run = async () => {
|
|
451
636
|
setConnState("loading");
|
|
452
637
|
setError(null);
|
|
638
|
+
setPopupBlocked(false);
|
|
453
639
|
setFinalUrl("");
|
|
454
640
|
try {
|
|
455
641
|
const r = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
@@ -488,13 +674,6 @@ function PayPalConnectionPage() {
|
|
|
488
674
|
const scriptUrl = PARTNER_JS_URLS[env];
|
|
489
675
|
let cancelled = false;
|
|
490
676
|
let pollTimer;
|
|
491
|
-
setPartnerReady(false);
|
|
492
|
-
const readyFallback = setTimeout(() => {
|
|
493
|
-
if (!cancelled) setPartnerReady(true);
|
|
494
|
-
}, 6e3);
|
|
495
|
-
const markReady = () => {
|
|
496
|
-
if (!cancelled) setPartnerReady(true);
|
|
497
|
-
};
|
|
498
677
|
const initPartner = (attempt = 0) => {
|
|
499
678
|
var _a2, _b2;
|
|
500
679
|
if (cancelled) return;
|
|
@@ -506,7 +685,6 @@ function PayPalConnectionPage() {
|
|
|
506
685
|
} catch (e) {
|
|
507
686
|
console.error("[paypal] partner.js init failed:", e);
|
|
508
687
|
}
|
|
509
|
-
markReady();
|
|
510
688
|
return;
|
|
511
689
|
}
|
|
512
690
|
if (typeof (signup == null ? void 0 : signup.render) === "function") {
|
|
@@ -515,7 +693,6 @@ function PayPalConnectionPage() {
|
|
|
515
693
|
} catch (e) {
|
|
516
694
|
console.error("[paypal] partner.js render failed:", e);
|
|
517
695
|
}
|
|
518
|
-
markReady();
|
|
519
696
|
return;
|
|
520
697
|
}
|
|
521
698
|
if (attempt < 40) {
|
|
@@ -526,7 +703,6 @@ function PayPalConnectionPage() {
|
|
|
526
703
|
document.dispatchEvent(new Event("DOMContentLoaded"));
|
|
527
704
|
} catch {
|
|
528
705
|
}
|
|
529
|
-
markReady();
|
|
530
706
|
};
|
|
531
707
|
const existingScript = document.getElementById("paypal-partner-js");
|
|
532
708
|
if (existingScript) {
|
|
@@ -543,74 +719,54 @@ function PayPalConnectionPage() {
|
|
|
543
719
|
ppScript.src = scriptUrl;
|
|
544
720
|
ppScript.async = true;
|
|
545
721
|
ppScript.onload = () => initPartner();
|
|
546
|
-
ppScript.onerror = () => markReady();
|
|
547
722
|
document.body.appendChild(ppScript);
|
|
548
723
|
return () => {
|
|
549
724
|
cancelled = true;
|
|
550
|
-
clearTimeout(
|
|
551
|
-
if (
|
|
552
|
-
clearTimeout(pollTimer);
|
|
553
|
-
}
|
|
554
|
-
if (ppScript.parentNode) {
|
|
555
|
-
ppScript.parentNode.removeChild(ppScript);
|
|
556
|
-
}
|
|
725
|
+
if (pollTimer) clearTimeout(pollTimer);
|
|
726
|
+
if (ppScript.parentNode) ppScript.parentNode.removeChild(ppScript);
|
|
557
727
|
};
|
|
558
728
|
}, [connState, finalUrl, env]);
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
completedRef.current = true;
|
|
564
|
-
try {
|
|
565
|
-
window.onbeforeunload = null;
|
|
566
|
-
} catch {
|
|
567
|
-
}
|
|
568
|
-
const activeEnv = envRef.current === "sandbox" ? "sandbox" : "live";
|
|
569
|
-
setOnboardingInProgress(true);
|
|
570
|
-
setConnState("loading");
|
|
571
|
-
setError(null);
|
|
572
|
-
try {
|
|
573
|
-
const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
|
|
574
|
-
method: "POST",
|
|
575
|
-
headers: { "content-type": "application/json" },
|
|
576
|
-
credentials: "include",
|
|
577
|
-
body: JSON.stringify({ authCode, sharedId, env: activeEnv })
|
|
578
|
-
});
|
|
579
|
-
if (!res.ok) {
|
|
580
|
-
const txt = await res.text().catch(() => "");
|
|
581
|
-
throw new Error(txt || `Onboarding exchange failed (${res.status})`);
|
|
582
|
-
}
|
|
729
|
+
useEffect(() => {
|
|
730
|
+
const onMessage = (ev) => {
|
|
731
|
+
var _a;
|
|
732
|
+
let serialized = "";
|
|
583
733
|
try {
|
|
584
|
-
|
|
585
|
-
if (typeof close1 === "function") close1();
|
|
734
|
+
serialized = typeof ev.data === "string" ? ev.data : JSON.stringify(ev.data);
|
|
586
735
|
} catch {
|
|
736
|
+
serialized = String(ev.data);
|
|
587
737
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
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
|
+
);
|
|
592
746
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
}
|
|
599
|
-
const
|
|
600
|
-
|
|
601
|
-
|
|
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;
|
|
602
760
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
613
|
-
}, []);
|
|
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]);
|
|
614
770
|
useLayoutEffect(() => {
|
|
615
771
|
window.onboardingCallback = (authCode, sharedId) => {
|
|
616
772
|
completeOnboarding(authCode, sharedId);
|
|
@@ -619,6 +775,31 @@ function PayPalConnectionPage() {
|
|
|
619
775
|
window.onboardingCallback = void 0;
|
|
620
776
|
};
|
|
621
777
|
}, [completeOnboarding]);
|
|
778
|
+
useEffect(() => {
|
|
779
|
+
const onCaptureClick = (e) => {
|
|
780
|
+
const btn = paypalButtonRef.current;
|
|
781
|
+
if (!btn) return;
|
|
782
|
+
const target = e.target;
|
|
783
|
+
if (!target || !btn.contains(target)) return;
|
|
784
|
+
e.preventDefault();
|
|
785
|
+
if (connStateRef.current !== "ready" || !finalUrlRef.current || inProgressRef.current) {
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
completedRef.current = false;
|
|
789
|
+
const popup = openOnboardingPopup(finalUrlRef.current);
|
|
790
|
+
if (!popup) {
|
|
791
|
+
setPopupBlocked(true);
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
setPopupBlocked(false);
|
|
795
|
+
startStatusPoll();
|
|
796
|
+
};
|
|
797
|
+
document.addEventListener("click", onCaptureClick, true);
|
|
798
|
+
return () => document.removeEventListener("click", onCaptureClick, true);
|
|
799
|
+
}, [openOnboardingPopup, startStatusPoll]);
|
|
800
|
+
useEffect(() => {
|
|
801
|
+
return () => stopPoll();
|
|
802
|
+
}, [stopPoll]);
|
|
622
803
|
useLayoutEffect(() => {
|
|
623
804
|
const el = ppBtnMeasureRef.current;
|
|
624
805
|
if (!el) return;
|
|
@@ -639,6 +820,9 @@ function PayPalConnectionPage() {
|
|
|
639
820
|
else window.removeEventListener("resize", update);
|
|
640
821
|
};
|
|
641
822
|
}, [connState, env, finalUrl]);
|
|
823
|
+
const handleConnectClick = (e) => {
|
|
824
|
+
e.preventDefault();
|
|
825
|
+
};
|
|
642
826
|
const handleSaveManual = async () => {
|
|
643
827
|
if (!canSaveManual || onboardingInProgress) return;
|
|
644
828
|
setOnboardingInProgress(true);
|
|
@@ -713,6 +897,7 @@ function PayPalConnectionPage() {
|
|
|
713
897
|
if (next === env || onboardingInProgress) return;
|
|
714
898
|
completedRef.current = false;
|
|
715
899
|
clearCachedUrl();
|
|
900
|
+
setPopupBlocked(false);
|
|
716
901
|
setConnState("loading");
|
|
717
902
|
try {
|
|
718
903
|
await fetch(ENVIRONMENT_ENDPOINT, {
|
|
@@ -783,6 +968,7 @@ function PayPalConnectionPage() {
|
|
|
783
968
|
"a",
|
|
784
969
|
{
|
|
785
970
|
ref: (node) => {
|
|
971
|
+
paypalButtonRef.current = node;
|
|
786
972
|
ppBtnMeasureRef.current = node;
|
|
787
973
|
},
|
|
788
974
|
id: "paypal-button",
|
|
@@ -790,19 +976,17 @@ function PayPalConnectionPage() {
|
|
|
790
976
|
"data-paypal-button": "true",
|
|
791
977
|
href: finalUrl || "#",
|
|
792
978
|
"data-paypal-onboard-complete": "onboardingCallback",
|
|
793
|
-
|
|
979
|
+
onClick: handleConnectClick,
|
|
794
980
|
className: "transition-fg relative inline-flex w-fit items-center justify-center overflow-hidden rounded-md outline-none no-underline shadow-buttons-neutral text-ui-fg-base bg-ui-button-neutral after:transition-fg after:absolute after:inset-0 after:content-[''] after:button-neutral-gradient hover:bg-ui-button-neutral-hover hover:after:button-neutral-hover-gradient active:bg-ui-button-neutral-pressed active:after:button-neutral-pressed-gradient focus-visible:shadow-buttons-neutral-focus disabled:bg-ui-bg-disabled disabled:border-ui-border-base disabled:text-ui-fg-disabled disabled:shadow-buttons-neutral disabled:after:hidden txt-compact-small-plus px-3 py-1.5",
|
|
795
981
|
style: {
|
|
796
|
-
cursor: onboardingInProgress
|
|
797
|
-
opacity: onboardingInProgress
|
|
798
|
-
|
|
799
|
-
// but un-clickable until partner.js has taken over the
|
|
800
|
-
// click — so it can never open a tab via the native href.
|
|
801
|
-
pointerEvents: onboardingInProgress || !partnerReady ? "none" : "auto"
|
|
982
|
+
cursor: onboardingInProgress ? "not-allowed" : "pointer",
|
|
983
|
+
opacity: onboardingInProgress ? 0.6 : 1,
|
|
984
|
+
pointerEvents: onboardingInProgress ? "none" : "auto"
|
|
802
985
|
},
|
|
803
|
-
children:
|
|
986
|
+
children: "Connect to PayPal"
|
|
804
987
|
}
|
|
805
988
|
),
|
|
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." }),
|
|
806
990
|
/* @__PURE__ */ jsx(
|
|
807
991
|
"div",
|
|
808
992
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../../../src/admin/routes/settings/paypal/connection/page.tsx"],"names":[],"mappings":"AAWA,eAAO,MAAM,MAAM,2CAEjB,CAAA;AAQF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,MAAM,CAAC,EAAE;YACP,IAAI,CAAC,EAAE;gBACL,MAAM,CAAC,EAAE;oBACP,WAAW,CAAC,EAAE;wBAAE,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;wBAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;qBAAE,CAAA;oBAC3D,WAAW,CAAC,EAAE;wBAAE,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;wBAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;qBAAE,CAAA;oBAC3D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;iBACpB,CAAA;aACF,CAAA;SACF,CAAA;QACD,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;KAClE;CACF;
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../../../src/admin/routes/settings/paypal/connection/page.tsx"],"names":[],"mappings":"AAWA,eAAO,MAAM,MAAM,2CAEjB,CAAA;AAQF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,MAAM,CAAC,EAAE;YACP,IAAI,CAAC,EAAE;gBACL,MAAM,CAAC,EAAE;oBACP,WAAW,CAAC,EAAE;wBAAE,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;wBAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;qBAAE,CAAA;oBAC3D,WAAW,CAAC,EAAE;wBAAE,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;wBAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;qBAAE,CAAA;oBAC3D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;iBACpB,CAAA;aACF,CAAA;SACF,CAAA;QACD,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;KAClE;CACF;AAkID,MAAM,CAAC,OAAO,UAAU,oBAAoB,4CAo4B3C"}
|