@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.
Files changed (54) hide show
  1. package/.medusa/server/src/admin/index.js +264 -80
  2. package/.medusa/server/src/admin/index.mjs +264 -80
  3. package/.medusa/server/src/admin/routes/settings/paypal/connection/page.d.ts.map +1 -1
  4. package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js +340 -146
  5. package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js.map +1 -1
  6. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -1
  7. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js +6 -8
  8. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js.map +1 -1
  9. package/.medusa/server/src/api/admin/paypal/environment/route.d.ts.map +1 -1
  10. package/.medusa/server/src/api/admin/paypal/environment/route.js +11 -3
  11. package/.medusa/server/src/api/admin/paypal/environment/route.js.map +1 -1
  12. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts +7 -0
  13. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts.map +1 -1
  14. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js +7 -0
  15. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js.map +1 -1
  16. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.d.ts.map +1 -1
  17. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js +4 -1
  18. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js.map +1 -1
  19. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -1
  20. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js +6 -8
  21. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js.map +1 -1
  22. package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts.map +1 -1
  23. package/.medusa/server/src/api/store/paypal/capture-order/route.js +11 -0
  24. package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -1
  25. package/.medusa/server/src/api/store/paypal/onboard-return/route.d.ts +23 -0
  26. package/.medusa/server/src/api/store/paypal/onboard-return/route.d.ts.map +1 -0
  27. package/.medusa/server/src/api/store/paypal/onboard-return/route.js +63 -0
  28. package/.medusa/server/src/api/store/paypal/onboard-return/route.js.map +1 -0
  29. package/.medusa/server/src/api/store/paypal-complete/route.d.ts.map +1 -1
  30. package/.medusa/server/src/api/store/paypal-complete/route.js +2 -4
  31. package/.medusa/server/src/api/store/paypal-complete/route.js.map +1 -1
  32. package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts.map +1 -1
  33. package/.medusa/server/src/modules/paypal/payment-provider/card-service.js +55 -34
  34. package/.medusa/server/src/modules/paypal/payment-provider/card-service.js.map +1 -1
  35. package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -1
  36. package/.medusa/server/src/modules/paypal/service.js +5 -1
  37. package/.medusa/server/src/modules/paypal/service.js.map +1 -1
  38. package/.medusa/server/src/modules/paypal/utils/core-workflow.d.ts +32 -0
  39. package/.medusa/server/src/modules/paypal/utils/core-workflow.d.ts.map +1 -0
  40. package/.medusa/server/src/modules/paypal/utils/core-workflow.js +40 -0
  41. package/.medusa/server/src/modules/paypal/utils/core-workflow.js.map +1 -0
  42. package/package.json +1 -1
  43. package/src/admin/routes/settings/paypal/connection/page.tsx +364 -160
  44. package/src/api/admin/payment-collections/[id]/payment-sessions/route.ts +6 -8
  45. package/src/api/admin/paypal/environment/route.ts +10 -3
  46. package/src/api/admin/paypal/onboard-complete/route.ts +7 -0
  47. package/src/api/admin/paypal/onboarding-status/route.ts +4 -1
  48. package/src/api/store/payment-collections/[id]/payment-sessions/route.ts +6 -8
  49. package/src/api/store/paypal/capture-order/route.ts +15 -0
  50. package/src/api/store/paypal/onboard-return/route.ts +63 -0
  51. package/src/api/store/paypal-complete/route.ts +6 -4
  52. package/src/modules/paypal/payment-provider/card-service.ts +72 -38
  53. package/src/modules/paypal/service.ts +5 -1
  54. 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(readyFallback);
551
- if (pollTimer) {
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
- const completeOnboarding = useCallback(async (authCode, sharedId) => {
560
- var _a, _b, _c, _d, _e, _f, _g;
561
- if (!authCode || !sharedId) return;
562
- if (completedRef.current) return;
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
- 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;
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
- try {
589
- 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;
590
- if (typeof close2 === "function") close2();
591
- } catch {
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
- clearCachedUrl(activeEnv);
594
- try {
595
- const statusRes = await fetch(`${STATUS_ENDPOINT}?environment=${activeEnv}`, {
596
- method: "GET",
597
- credentials: "include"
598
- });
599
- const refreshedStatus = await statusRes.json().catch(() => ({}));
600
- setStatusInfo(refreshedStatus || null);
601
- } catch {
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
- setConnState("connected");
604
- setShowManual(false);
605
- } catch (e) {
606
- completedRef.current = false;
607
- console.error(e);
608
- setConnState("error");
609
- setError((e == null ? void 0 : e.message) || "Exchange failed while saving credentials.");
610
- } finally {
611
- setOnboardingInProgress(false);
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
- "aria-disabled": onboardingInProgress || !partnerReady,
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 || !partnerReady ? "not-allowed" : "pointer",
797
- opacity: onboardingInProgress || !partnerReady ? 0.6 : 1,
798
- // Keep the anchor mounted (partner.js must find it to bind)
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: partnerReady || onboardingInProgress ? "Connect to PayPal" : "Preparing PayPal…"
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;AA0ED,MAAM,CAAC,OAAO,UAAU,oBAAoB,4CAgvB3C"}
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"}