@easypayment/medusa-payment-paypal 0.9.18 → 0.9.20
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 +270 -114
- package/.medusa/server/src/admin/index.mjs +270 -114
- 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 +384 -126
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-link/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js +4 -0
- package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js.map +1 -1
- package/.medusa/server/src/modules/paypal/service.d.ts +1 -0
- 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/package.json +1 -1
- package/src/admin/routes/settings/paypal/connection/page.tsx +420 -131
- package/src/api/admin/paypal/onboarding-link/route.ts +6 -0
- package/src/modules/paypal/service.ts +7 -2
|
@@ -223,6 +223,9 @@ function AdditionalSettingsTab() {
|
|
|
223
223
|
)
|
|
224
224
|
] }) });
|
|
225
225
|
}
|
|
226
|
+
function PayPalApplePayPage() {
|
|
227
|
+
return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
228
|
+
}
|
|
226
229
|
const DEFAULT_FORM = {
|
|
227
230
|
enabled: true,
|
|
228
231
|
title: "Credit or Debit Card",
|
|
@@ -315,37 +318,97 @@ const PARTNER_JS_URLS = {
|
|
|
315
318
|
live: "https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js"
|
|
316
319
|
};
|
|
317
320
|
const SERVICE_URL = "/admin/paypal/onboarding-link";
|
|
318
|
-
const
|
|
321
|
+
const POPUP_NAME = "PPMiniBrowser";
|
|
322
|
+
const CACHE_PREFIX = "pp_onboard_cache";
|
|
319
323
|
const CACHE_EXPIRY = 10 * 60 * 1e3;
|
|
320
324
|
const ONBOARDING_COMPLETE_ENDPOINT = "/admin/paypal/onboard-complete";
|
|
321
325
|
const STATUS_ENDPOINT = "/admin/paypal/status";
|
|
322
326
|
const SAVE_CREDENTIALS_ENDPOINT = "/admin/paypal/save-credentials";
|
|
323
327
|
const DISCONNECT_ENDPOINT = "/admin/paypal/disconnect";
|
|
324
|
-
|
|
325
|
-
|
|
328
|
+
const ENVIRONMENT_ENDPOINT = "/admin/paypal/environment";
|
|
329
|
+
const cacheKeyFor = (env) => `${CACHE_PREFIX}_${env}`;
|
|
330
|
+
function readCachedUrl(env) {
|
|
331
|
+
if (typeof window === "undefined") return null;
|
|
326
332
|
try {
|
|
327
|
-
const
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
333
|
+
const raw = localStorage.getItem(cacheKeyFor(env));
|
|
334
|
+
if (!raw) return null;
|
|
335
|
+
const data = JSON.parse(raw);
|
|
336
|
+
if (data && typeof data.url === "string" && Date.now() - (Number(data.ts) || 0) < CACHE_EXPIRY) {
|
|
337
|
+
return data.url;
|
|
338
|
+
}
|
|
339
|
+
} catch {
|
|
340
|
+
}
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
function writeCachedUrl(env, url) {
|
|
344
|
+
try {
|
|
345
|
+
localStorage.setItem(cacheKeyFor(env), JSON.stringify({ url, ts: Date.now() }));
|
|
346
|
+
} catch {
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function clearCachedUrl(env) {
|
|
350
|
+
try {
|
|
351
|
+
if (env) {
|
|
352
|
+
localStorage.removeItem(cacheKeyFor(env));
|
|
353
|
+
} else {
|
|
354
|
+
localStorage.removeItem(cacheKeyFor("sandbox"));
|
|
355
|
+
localStorage.removeItem(cacheKeyFor("live"));
|
|
356
|
+
}
|
|
357
|
+
} catch {
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
function isPayPalOrigin(origin) {
|
|
361
|
+
try {
|
|
362
|
+
const host = new URL(origin).hostname.toLowerCase();
|
|
363
|
+
return host === "www.paypal.com" || host === "www.sandbox.paypal.com" || host.endsWith(".paypal.com") || host.endsWith(".paypalobjects.com");
|
|
364
|
+
} catch {
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
function extractAuth(data) {
|
|
369
|
+
if (!data) return {};
|
|
370
|
+
if (typeof data === "object") {
|
|
371
|
+
const obj = data;
|
|
372
|
+
const authCode = obj.authCode ?? obj.auth_code ?? obj.authcode;
|
|
373
|
+
const sharedId = obj.sharedId ?? obj.shared_id ?? obj.sharedid;
|
|
374
|
+
if (authCode && sharedId) {
|
|
375
|
+
return { authCode: String(authCode), sharedId: String(sharedId) };
|
|
376
|
+
}
|
|
377
|
+
for (const key of ["data", "payload", "message", "detail", "body"]) {
|
|
378
|
+
if (obj[key] && typeof obj[key] === "object") {
|
|
379
|
+
const inner = extractAuth(obj[key]);
|
|
380
|
+
if (inner.authCode && inner.sharedId) return inner;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return {};
|
|
384
|
+
}
|
|
385
|
+
if (typeof data === "string") {
|
|
386
|
+
const s = data.trim();
|
|
387
|
+
if (!s) return {};
|
|
388
|
+
if (s.startsWith("{")) {
|
|
389
|
+
try {
|
|
390
|
+
return extractAuth(JSON.parse(s));
|
|
391
|
+
} catch {
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (/auth_?code/i.test(s) && /shared_?id/i.test(s)) {
|
|
395
|
+
try {
|
|
396
|
+
const sp = new URLSearchParams(s.replace(/^[?#]/, ""));
|
|
397
|
+
const authCode = sp.get("authCode") || sp.get("auth_code") || void 0;
|
|
398
|
+
const sharedId = sp.get("sharedId") || sp.get("shared_id") || void 0;
|
|
399
|
+
if (authCode && sharedId) return { authCode, sharedId };
|
|
400
|
+
} catch {
|
|
332
401
|
}
|
|
333
402
|
}
|
|
334
|
-
} catch (e) {
|
|
335
|
-
console.error("Cache read error:", e);
|
|
336
403
|
}
|
|
404
|
+
return {};
|
|
337
405
|
}
|
|
338
406
|
function PayPalConnectionPage() {
|
|
339
407
|
const [env, setEnv] = useState("live");
|
|
340
|
-
|
|
341
|
-
fetch("/admin/paypal/environment", { method: "GET", credentials: "include" }).then((r) => r.json()).then((d) => {
|
|
342
|
-
const v = (d == null ? void 0 : d.environment) === "sandbox" ? "sandbox" : "live";
|
|
343
|
-
setEnv(v);
|
|
344
|
-
}).catch(() => {
|
|
345
|
-
});
|
|
346
|
-
}, []);
|
|
408
|
+
const [envReady, setEnvReady] = useState(false);
|
|
347
409
|
const [connState, setConnState] = useState("loading");
|
|
348
410
|
const [error, setError] = useState(null);
|
|
411
|
+
const [popupBlocked, setPopupBlocked] = useState(false);
|
|
349
412
|
const [finalUrl, setFinalUrl] = useState("");
|
|
350
413
|
const [showManual, setShowManual] = useState(false);
|
|
351
414
|
const [clientId, setClientId] = useState("");
|
|
@@ -357,6 +420,18 @@ function PayPalConnectionPage() {
|
|
|
357
420
|
const errorLogRef = useRef(null);
|
|
358
421
|
const runIdRef = useRef(0);
|
|
359
422
|
const currentRunId = useRef(0);
|
|
423
|
+
const finalUrlRef = useRef(finalUrl);
|
|
424
|
+
finalUrlRef.current = finalUrl;
|
|
425
|
+
const connStateRef = useRef(connState);
|
|
426
|
+
connStateRef.current = connState;
|
|
427
|
+
const inProgressRef = useRef(onboardingInProgress);
|
|
428
|
+
inProgressRef.current = onboardingInProgress;
|
|
429
|
+
const envRef = useRef(env);
|
|
430
|
+
envRef.current = env;
|
|
431
|
+
const popupRef = useRef(null);
|
|
432
|
+
const popupPollRef = useRef(null);
|
|
433
|
+
const completedRef = useRef(false);
|
|
434
|
+
const partnerBoundRef = useRef(false);
|
|
360
435
|
const ppBtnMeasureRef = useRef(null);
|
|
361
436
|
const [ppBtnWidth, setPpBtnWidth] = useState(null);
|
|
362
437
|
const canSaveManual = useMemo(() => {
|
|
@@ -366,8 +441,112 @@ function PayPalConnectionPage() {
|
|
|
366
441
|
setConnState("error");
|
|
367
442
|
setError(msg);
|
|
368
443
|
}, []);
|
|
444
|
+
const stopPopupPoll = useCallback(() => {
|
|
445
|
+
if (popupPollRef.current) {
|
|
446
|
+
clearInterval(popupPollRef.current);
|
|
447
|
+
popupPollRef.current = null;
|
|
448
|
+
}
|
|
449
|
+
}, []);
|
|
450
|
+
const openOnboardingPopup = useCallback(
|
|
451
|
+
(url) => {
|
|
452
|
+
const w = 450;
|
|
453
|
+
const h = 600;
|
|
454
|
+
const baseLeft = typeof window.screenX === "number" ? window.screenX : window.screenLeft || 0;
|
|
455
|
+
const baseTop = typeof window.screenY === "number" ? window.screenY : window.screenTop || 0;
|
|
456
|
+
const outerW = window.outerWidth || document.documentElement.clientWidth || 1024;
|
|
457
|
+
const outerH = window.outerHeight || document.documentElement.clientHeight || 768;
|
|
458
|
+
const left = Math.round(baseLeft + Math.max(0, (outerW - w) / 2));
|
|
459
|
+
const top = Math.round(baseTop + Math.max(0, (outerH - h) / 2));
|
|
460
|
+
const features = `popup=yes,width=${w},height=${h},left=${left},top=${top},scrollbars=yes,resizable=yes`;
|
|
461
|
+
let popup = null;
|
|
462
|
+
try {
|
|
463
|
+
popup = window.open(url, POPUP_NAME, features);
|
|
464
|
+
} catch {
|
|
465
|
+
popup = null;
|
|
466
|
+
}
|
|
467
|
+
if (popup) {
|
|
468
|
+
popupRef.current = popup;
|
|
469
|
+
try {
|
|
470
|
+
popup.focus();
|
|
471
|
+
} catch {
|
|
472
|
+
}
|
|
473
|
+
stopPopupPoll();
|
|
474
|
+
popupPollRef.current = setInterval(() => {
|
|
475
|
+
if (!popupRef.current || popupRef.current.closed) {
|
|
476
|
+
stopPopupPoll();
|
|
477
|
+
}
|
|
478
|
+
}, 1e3);
|
|
479
|
+
}
|
|
480
|
+
return popup;
|
|
481
|
+
},
|
|
482
|
+
[stopPopupPoll]
|
|
483
|
+
);
|
|
484
|
+
const completeOnboarding = useCallback(
|
|
485
|
+
async (authCode, sharedId) => {
|
|
486
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
487
|
+
if (!authCode || !sharedId) return;
|
|
488
|
+
if (completedRef.current) return;
|
|
489
|
+
completedRef.current = true;
|
|
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
|
+
stopPopupPoll();
|
|
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
|
+
}
|
|
525
|
+
clearCachedUrl(activeEnv);
|
|
526
|
+
try {
|
|
527
|
+
const statusRes = await fetch(
|
|
528
|
+
`${STATUS_ENDPOINT}?environment=${activeEnv}`,
|
|
529
|
+
{ method: "GET", credentials: "include" }
|
|
530
|
+
);
|
|
531
|
+
const refreshedStatus = await statusRes.json().catch(() => ({}));
|
|
532
|
+
setStatusInfo(refreshedStatus || null);
|
|
533
|
+
} catch {
|
|
534
|
+
}
|
|
535
|
+
setConnState("connected");
|
|
536
|
+
setShowManual(false);
|
|
537
|
+
} catch (e) {
|
|
538
|
+
completedRef.current = false;
|
|
539
|
+
console.error(e);
|
|
540
|
+
setConnState("error");
|
|
541
|
+
setError((e == null ? void 0 : e.message) || "Exchange failed while saving credentials.");
|
|
542
|
+
} finally {
|
|
543
|
+
setOnboardingInProgress(false);
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
[stopPopupPoll]
|
|
547
|
+
);
|
|
369
548
|
const fetchFreshLink = useCallback(
|
|
370
|
-
(runId) => {
|
|
549
|
+
(runId, targetEnv) => {
|
|
371
550
|
if (initLoaderRef.current) {
|
|
372
551
|
const loaderText = initLoaderRef.current.querySelector("#loader-text");
|
|
373
552
|
if (loaderText)
|
|
@@ -378,7 +557,10 @@ function PayPalConnectionPage() {
|
|
|
378
557
|
headers: { "content-type": "application/json" },
|
|
379
558
|
credentials: "include",
|
|
380
559
|
body: JSON.stringify({
|
|
381
|
-
products: ["PPCP"]
|
|
560
|
+
products: ["PPCP"],
|
|
561
|
+
// Generate the link for the explicitly selected environment so it can
|
|
562
|
+
// never depend on a racing POST /environment having landed yet.
|
|
563
|
+
environment: targetEnv
|
|
382
564
|
})
|
|
383
565
|
}).then((r) => {
|
|
384
566
|
if (!r.ok) throw new Error(`Service returned ${r.status}`);
|
|
@@ -391,10 +573,7 @@ function PayPalConnectionPage() {
|
|
|
391
573
|
return;
|
|
392
574
|
}
|
|
393
575
|
const url = href + (href.includes("?") ? "&" : "?") + "displayMode=minibrowser";
|
|
394
|
-
|
|
395
|
-
CACHE_KEY,
|
|
396
|
-
JSON.stringify({ url, ts: Date.now() })
|
|
397
|
-
);
|
|
576
|
+
writeCachedUrl(targetEnv, url);
|
|
398
577
|
setFinalUrl(url);
|
|
399
578
|
setConnState("ready");
|
|
400
579
|
}).catch(() => {
|
|
@@ -402,8 +581,21 @@ function PayPalConnectionPage() {
|
|
|
402
581
|
showError("Unable to connect to service.");
|
|
403
582
|
});
|
|
404
583
|
},
|
|
405
|
-
[
|
|
584
|
+
[showError]
|
|
406
585
|
);
|
|
586
|
+
useEffect(() => {
|
|
587
|
+
let alive = true;
|
|
588
|
+
fetch(ENVIRONMENT_ENDPOINT, { method: "GET", credentials: "include" }).then((r) => r.json()).then((d) => {
|
|
589
|
+
if (!alive) return;
|
|
590
|
+
setEnv((d == null ? void 0 : d.environment) === "sandbox" ? "sandbox" : "live");
|
|
591
|
+
}).catch(() => {
|
|
592
|
+
}).finally(() => {
|
|
593
|
+
if (alive) setEnvReady(true);
|
|
594
|
+
});
|
|
595
|
+
return () => {
|
|
596
|
+
alive = false;
|
|
597
|
+
};
|
|
598
|
+
}, []);
|
|
407
599
|
useEffect(() => {
|
|
408
600
|
var _a, _b, _c;
|
|
409
601
|
if (connState !== "ready" || !finalUrl) return;
|
|
@@ -418,6 +610,7 @@ function PayPalConnectionPage() {
|
|
|
418
610
|
if (target == null ? void 0 : target.init) {
|
|
419
611
|
try {
|
|
420
612
|
target.init();
|
|
613
|
+
partnerBoundRef.current = true;
|
|
421
614
|
} catch (e) {
|
|
422
615
|
console.error("[paypal] partner.js init failed:", e);
|
|
423
616
|
}
|
|
@@ -426,6 +619,7 @@ function PayPalConnectionPage() {
|
|
|
426
619
|
if (typeof (signup == null ? void 0 : signup.render) === "function") {
|
|
427
620
|
try {
|
|
428
621
|
signup.render();
|
|
622
|
+
partnerBoundRef.current = true;
|
|
429
623
|
} catch (e) {
|
|
430
624
|
console.error("[paypal] partner.js render failed:", e);
|
|
431
625
|
}
|
|
@@ -440,6 +634,7 @@ function PayPalConnectionPage() {
|
|
|
440
634
|
} catch {
|
|
441
635
|
}
|
|
442
636
|
};
|
|
637
|
+
partnerBoundRef.current = false;
|
|
443
638
|
const existingScript = document.getElementById("paypal-partner-js");
|
|
444
639
|
if (existingScript) {
|
|
445
640
|
(_a = existingScript.parentNode) == null ? void 0 : _a.removeChild(existingScript);
|
|
@@ -467,12 +662,26 @@ function PayPalConnectionPage() {
|
|
|
467
662
|
};
|
|
468
663
|
}, [connState, finalUrl, env]);
|
|
469
664
|
useEffect(() => {
|
|
665
|
+
const onMessage = (ev) => {
|
|
666
|
+
if (!isPayPalOrigin(ev.origin)) return;
|
|
667
|
+
const { authCode, sharedId } = extractAuth(ev.data);
|
|
668
|
+
if (authCode && sharedId) {
|
|
669
|
+
completeOnboarding(authCode, sharedId);
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
window.addEventListener("message", onMessage);
|
|
673
|
+
return () => window.removeEventListener("message", onMessage);
|
|
674
|
+
}, [completeOnboarding]);
|
|
675
|
+
useEffect(() => {
|
|
676
|
+
if (!envReady) return;
|
|
470
677
|
currentRunId.current = ++runIdRef.current;
|
|
471
678
|
const runId = currentRunId.current;
|
|
472
679
|
let cancelled = false;
|
|
680
|
+
completedRef.current = false;
|
|
473
681
|
const run = async () => {
|
|
474
682
|
setConnState("loading");
|
|
475
683
|
setError(null);
|
|
684
|
+
setPopupBlocked(false);
|
|
476
685
|
setFinalUrl("");
|
|
477
686
|
try {
|
|
478
687
|
const r = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
@@ -491,84 +700,33 @@ function PayPalConnectionPage() {
|
|
|
491
700
|
} catch (e) {
|
|
492
701
|
console.error(e);
|
|
493
702
|
}
|
|
494
|
-
if (
|
|
495
|
-
|
|
703
|
+
if (cancelled || runId !== currentRunId.current) return;
|
|
704
|
+
const cached = readCachedUrl(env);
|
|
705
|
+
if (cached) {
|
|
706
|
+
setFinalUrl(cached);
|
|
496
707
|
setConnState("ready");
|
|
497
708
|
} else {
|
|
498
|
-
fetchFreshLink(runId);
|
|
709
|
+
fetchFreshLink(runId, env);
|
|
499
710
|
}
|
|
500
711
|
};
|
|
501
712
|
run();
|
|
502
713
|
return () => {
|
|
503
714
|
cancelled = true;
|
|
504
|
-
currentRunId.current = 0;
|
|
505
715
|
};
|
|
506
|
-
}, [env, fetchFreshLink]);
|
|
716
|
+
}, [env, envReady, fetchFreshLink]);
|
|
507
717
|
useLayoutEffect(() => {
|
|
508
|
-
window.onboardingCallback =
|
|
509
|
-
|
|
510
|
-
try {
|
|
511
|
-
window.onbeforeunload = null;
|
|
512
|
-
} catch {
|
|
513
|
-
}
|
|
514
|
-
setOnboardingInProgress(true);
|
|
515
|
-
setConnState("loading");
|
|
516
|
-
setError(null);
|
|
517
|
-
const payload = {
|
|
518
|
-
authCode,
|
|
519
|
-
sharedId,
|
|
520
|
-
env: env === "sandbox" ? "sandbox" : "live"
|
|
521
|
-
};
|
|
522
|
-
try {
|
|
523
|
-
const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
|
|
524
|
-
method: "POST",
|
|
525
|
-
headers: { "content-type": "application/json" },
|
|
526
|
-
credentials: "include",
|
|
527
|
-
body: JSON.stringify(payload)
|
|
528
|
-
});
|
|
529
|
-
if (!res.ok) {
|
|
530
|
-
const txt = await res.text().catch(() => "");
|
|
531
|
-
throw new Error(txt || `Onboarding exchange failed (${res.status})`);
|
|
532
|
-
}
|
|
533
|
-
try {
|
|
534
|
-
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;
|
|
535
|
-
if (typeof close1 === "function") close1();
|
|
536
|
-
} catch {
|
|
537
|
-
}
|
|
538
|
-
try {
|
|
539
|
-
const close2 = ((_g = (_f = (_e = window.PAYPAL) == null ? void 0 : _e.apps) == null ? void 0 : _f.Signup) == null ? void 0 : _g.miniBrowser) && window.PAYPAL.apps.Signup.miniBrowser.closeFlow;
|
|
540
|
-
if (typeof close2 === "function") close2();
|
|
541
|
-
} catch {
|
|
542
|
-
}
|
|
543
|
-
try {
|
|
544
|
-
localStorage.removeItem(CACHE_KEY);
|
|
545
|
-
} catch {
|
|
546
|
-
}
|
|
547
|
-
try {
|
|
548
|
-
const statusRes = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
549
|
-
method: "GET",
|
|
550
|
-
credentials: "include"
|
|
551
|
-
});
|
|
552
|
-
const refreshedStatus = await statusRes.json().catch(() => ({}));
|
|
553
|
-
setStatusInfo(refreshedStatus || null);
|
|
554
|
-
setConnState("connected");
|
|
555
|
-
setShowManual(false);
|
|
556
|
-
} catch {
|
|
557
|
-
setConnState("connected");
|
|
558
|
-
setShowManual(false);
|
|
559
|
-
}
|
|
560
|
-
setOnboardingInProgress(false);
|
|
561
|
-
} catch (e) {
|
|
562
|
-
console.error(e);
|
|
563
|
-
setConnState("error");
|
|
564
|
-
setError((e == null ? void 0 : e.message) || "Exchange failed while saving credentials.");
|
|
565
|
-
setOnboardingInProgress(false);
|
|
566
|
-
}
|
|
718
|
+
window.onboardingCallback = (authCode, sharedId) => {
|
|
719
|
+
completeOnboarding(authCode, sharedId);
|
|
567
720
|
};
|
|
568
721
|
return () => {
|
|
569
722
|
window.onboardingCallback = void 0;
|
|
570
723
|
};
|
|
571
|
-
}, [
|
|
724
|
+
}, [completeOnboarding]);
|
|
725
|
+
useEffect(() => {
|
|
726
|
+
return () => {
|
|
727
|
+
stopPopupPoll();
|
|
728
|
+
};
|
|
729
|
+
}, [stopPopupPoll]);
|
|
572
730
|
useLayoutEffect(() => {
|
|
573
731
|
const el = ppBtnMeasureRef.current;
|
|
574
732
|
if (!el) return;
|
|
@@ -590,9 +748,16 @@ function PayPalConnectionPage() {
|
|
|
590
748
|
};
|
|
591
749
|
}, [connState, env, finalUrl]);
|
|
592
750
|
const handleConnectClick = (e) => {
|
|
593
|
-
|
|
594
|
-
|
|
751
|
+
e.preventDefault();
|
|
752
|
+
if (connStateRef.current !== "ready" || !finalUrlRef.current || inProgressRef.current) {
|
|
753
|
+
return;
|
|
595
754
|
}
|
|
755
|
+
if (partnerBoundRef.current) {
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
completedRef.current = false;
|
|
759
|
+
const popup = openOnboardingPopup(finalUrlRef.current);
|
|
760
|
+
setPopupBlocked(!popup);
|
|
596
761
|
};
|
|
597
762
|
const handleSaveManual = async () => {
|
|
598
763
|
if (!canSaveManual || onboardingInProgress) return;
|
|
@@ -622,10 +787,7 @@ function PayPalConnectionPage() {
|
|
|
622
787
|
setConnState("connected");
|
|
623
788
|
setStatusInfo(refreshedStatus || null);
|
|
624
789
|
setShowManual(false);
|
|
625
|
-
|
|
626
|
-
localStorage.removeItem(CACHE_KEY);
|
|
627
|
-
} catch {
|
|
628
|
-
}
|
|
790
|
+
clearCachedUrl(env);
|
|
629
791
|
} catch (e) {
|
|
630
792
|
console.error(e);
|
|
631
793
|
setConnState("error");
|
|
@@ -654,13 +816,11 @@ function PayPalConnectionPage() {
|
|
|
654
816
|
const t = await res.text().catch(() => "");
|
|
655
817
|
throw new Error(t || `Disconnect failed (${res.status})`);
|
|
656
818
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
} catch {
|
|
660
|
-
}
|
|
819
|
+
clearCachedUrl(env);
|
|
820
|
+
completedRef.current = false;
|
|
661
821
|
currentRunId.current = ++runIdRef.current;
|
|
662
822
|
const runId = currentRunId.current;
|
|
663
|
-
fetchFreshLink(runId);
|
|
823
|
+
fetchFreshLink(runId, env);
|
|
664
824
|
} catch (e) {
|
|
665
825
|
console.error(e);
|
|
666
826
|
setConnState("error");
|
|
@@ -671,10 +831,12 @@ function PayPalConnectionPage() {
|
|
|
671
831
|
};
|
|
672
832
|
const handleEnvChange = async (e) => {
|
|
673
833
|
const next = e.target.value;
|
|
834
|
+
completedRef.current = false;
|
|
835
|
+
setPopupBlocked(false);
|
|
836
|
+
clearCachedUrl();
|
|
674
837
|
setEnv(next);
|
|
675
|
-
cachedUrl = null;
|
|
676
838
|
try {
|
|
677
|
-
await fetch(
|
|
839
|
+
await fetch(ENVIRONMENT_ENDPOINT, {
|
|
678
840
|
method: "POST",
|
|
679
841
|
headers: { "content-type": "application/json" },
|
|
680
842
|
credentials: "include",
|
|
@@ -682,10 +844,6 @@ function PayPalConnectionPage() {
|
|
|
682
844
|
});
|
|
683
845
|
} catch {
|
|
684
846
|
}
|
|
685
|
-
try {
|
|
686
|
-
localStorage.removeItem(CACHE_KEY);
|
|
687
|
-
} catch {
|
|
688
|
-
}
|
|
689
847
|
};
|
|
690
848
|
return /* @__PURE__ */ jsxs("div", { className: "p-6", children: [
|
|
691
849
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
@@ -749,7 +907,7 @@ function PayPalConnectionPage() {
|
|
|
749
907
|
ppBtnMeasureRef.current = node;
|
|
750
908
|
},
|
|
751
909
|
id: "paypal-button",
|
|
752
|
-
target:
|
|
910
|
+
target: POPUP_NAME,
|
|
753
911
|
"data-paypal-button": "true",
|
|
754
912
|
href: finalUrl || "#",
|
|
755
913
|
"data-paypal-onboard-complete": "onboardingCallback",
|
|
@@ -763,6 +921,7 @@ function PayPalConnectionPage() {
|
|
|
763
921
|
children: "Connect to PayPal"
|
|
764
922
|
}
|
|
765
923
|
),
|
|
924
|
+
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." }),
|
|
766
925
|
/* @__PURE__ */ jsx(
|
|
767
926
|
"div",
|
|
768
927
|
{
|
|
@@ -918,9 +1077,6 @@ function PayPalConnectionPage() {
|
|
|
918
1077
|
` })
|
|
919
1078
|
] });
|
|
920
1079
|
}
|
|
921
|
-
function PayPalApplePayPage() {
|
|
922
|
-
return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
923
|
-
}
|
|
924
1080
|
function PayPalGooglePayPage() {
|
|
925
1081
|
return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
926
1082
|
}
|
|
@@ -1145,6 +1301,10 @@ const routeModule = {
|
|
|
1145
1301
|
Component: AdditionalSettingsTab,
|
|
1146
1302
|
path: "/settings/paypal/additional-settings"
|
|
1147
1303
|
},
|
|
1304
|
+
{
|
|
1305
|
+
Component: PayPalApplePayPage,
|
|
1306
|
+
path: "/settings/paypal/apple-pay"
|
|
1307
|
+
},
|
|
1148
1308
|
{
|
|
1149
1309
|
Component: AdvancedCardPaymentsTab,
|
|
1150
1310
|
path: "/settings/paypal/advanced-card-payments"
|
|
@@ -1153,10 +1313,6 @@ const routeModule = {
|
|
|
1153
1313
|
Component: PayPalConnectionPage,
|
|
1154
1314
|
path: "/settings/paypal/connection"
|
|
1155
1315
|
},
|
|
1156
|
-
{
|
|
1157
|
-
Component: PayPalApplePayPage,
|
|
1158
|
-
path: "/settings/paypal/apple-pay"
|
|
1159
|
-
},
|
|
1160
1316
|
{
|
|
1161
1317
|
Component: PayPalGooglePayPage,
|
|
1162
1318
|
path: "/settings/paypal/google-pay"
|
|
@@ -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;AAmID,MAAM,CAAC,OAAO,UAAU,oBAAoB,4CA02B3C"}
|