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