@easypayment/medusa-payment-paypal 0.9.3 → 0.9.5

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 (190) hide show
  1. package/.medusa/server/src/admin/index.d.ts +2 -0
  2. package/.medusa/server/src/admin/index.d.ts.map +1 -0
  3. package/.medusa/server/src/admin/index.js +242 -287
  4. package/.medusa/server/src/admin/index.js.map +1 -0
  5. package/.medusa/server/src/admin/index.mjs +243 -288
  6. package/.medusa/server/src/admin/routes/settings/paypal/_components/FieldRow.d.ts +8 -0
  7. package/.medusa/server/src/admin/routes/settings/paypal/_components/FieldRow.d.ts.map +1 -0
  8. package/.medusa/server/src/admin/routes/settings/paypal/_components/FieldRow.js +8 -0
  9. package/.medusa/server/src/admin/routes/settings/paypal/_components/FieldRow.js.map +1 -0
  10. package/.medusa/server/src/admin/routes/settings/paypal/_components/SectionCard.d.ts +8 -0
  11. package/.medusa/server/src/admin/routes/settings/paypal/_components/SectionCard.d.ts.map +1 -0
  12. package/.medusa/server/src/admin/routes/settings/paypal/_components/SectionCard.js +8 -0
  13. package/.medusa/server/src/admin/routes/settings/paypal/_components/SectionCard.js.map +1 -0
  14. package/.medusa/server/src/admin/routes/settings/paypal/_components/Tabs.d.ts +2 -0
  15. package/.medusa/server/src/admin/routes/settings/paypal/_components/Tabs.d.ts.map +1 -0
  16. package/.medusa/server/src/admin/routes/settings/paypal/_components/Tabs.js +25 -0
  17. package/.medusa/server/src/admin/routes/settings/paypal/_components/Tabs.js.map +1 -0
  18. package/.medusa/server/src/admin/routes/settings/paypal/_components/Toast.d.ts +12 -0
  19. package/.medusa/server/src/admin/routes/settings/paypal/_components/Toast.d.ts.map +1 -0
  20. package/.medusa/server/src/admin/routes/settings/paypal/_components/Toast.js +22 -0
  21. package/.medusa/server/src/admin/routes/settings/paypal/_components/Toast.js.map +1 -0
  22. package/.medusa/server/src/admin/routes/settings/paypal/_utils/adminFetch.d.ts +7 -0
  23. package/.medusa/server/src/admin/routes/settings/paypal/_utils/adminFetch.d.ts.map +1 -0
  24. package/.medusa/server/src/admin/routes/settings/paypal/_utils/adminFetch.js +40 -0
  25. package/.medusa/server/src/admin/routes/settings/paypal/_utils/adminFetch.js.map +1 -0
  26. package/.medusa/server/src/admin/routes/settings/paypal/additional-settings/page.d.ts +2 -0
  27. package/.medusa/server/src/admin/routes/settings/paypal/additional-settings/page.d.ts.map +1 -0
  28. package/.medusa/server/src/admin/routes/settings/paypal/additional-settings/page.js +76 -0
  29. package/.medusa/server/src/admin/routes/settings/paypal/additional-settings/page.js.map +1 -0
  30. package/.medusa/server/src/admin/routes/settings/paypal/advanced-card-payments/page.d.ts +2 -0
  31. package/.medusa/server/src/admin/routes/settings/paypal/advanced-card-payments/page.d.ts.map +1 -0
  32. package/.medusa/server/src/admin/routes/settings/paypal/advanced-card-payments/page.js +81 -0
  33. package/.medusa/server/src/admin/routes/settings/paypal/advanced-card-payments/page.js.map +1 -0
  34. package/.medusa/server/src/admin/routes/settings/paypal/apple-pay/page.d.ts +2 -0
  35. package/.medusa/server/src/admin/routes/settings/paypal/apple-pay/page.d.ts.map +1 -0
  36. package/.medusa/server/src/admin/routes/settings/paypal/apple-pay/page.js +9 -0
  37. package/.medusa/server/src/admin/routes/settings/paypal/apple-pay/page.js.map +1 -0
  38. package/.medusa/server/src/admin/routes/settings/paypal/connection/page.d.ts +20 -0
  39. package/.medusa/server/src/admin/routes/settings/paypal/connection/page.d.ts.map +1 -0
  40. package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js +440 -0
  41. package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js.map +1 -0
  42. package/.medusa/server/src/admin/routes/settings/paypal/google-pay/page.d.ts +2 -0
  43. package/.medusa/server/src/admin/routes/settings/paypal/google-pay/page.d.ts.map +1 -0
  44. package/.medusa/server/src/admin/routes/settings/paypal/google-pay/page.js +9 -0
  45. package/.medusa/server/src/admin/routes/settings/paypal/google-pay/page.js.map +1 -0
  46. package/.medusa/server/src/admin/routes/settings/paypal/page.d.ts +4 -0
  47. package/.medusa/server/src/admin/routes/settings/paypal/page.d.ts.map +1 -0
  48. package/.medusa/server/src/admin/routes/settings/paypal/page.js +14 -0
  49. package/.medusa/server/src/admin/routes/settings/paypal/page.js.map +1 -0
  50. package/.medusa/server/src/admin/routes/settings/paypal/pay-later-messaging/page.d.ts +2 -0
  51. package/.medusa/server/src/admin/routes/settings/paypal/pay-later-messaging/page.d.ts.map +1 -0
  52. package/.medusa/server/src/admin/routes/settings/paypal/pay-later-messaging/page.js +9 -0
  53. package/.medusa/server/src/admin/routes/settings/paypal/pay-later-messaging/page.js.map +1 -0
  54. package/.medusa/server/src/admin/routes/settings/paypal/paypal-settings/page.d.ts +2 -0
  55. package/.medusa/server/src/admin/routes/settings/paypal/paypal-settings/page.d.ts.map +1 -0
  56. package/.medusa/server/src/admin/routes/settings/paypal/paypal-settings/page.js +109 -0
  57. package/.medusa/server/src/admin/routes/settings/paypal/paypal-settings/page.js.map +1 -0
  58. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts +1 -1
  59. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -1
  60. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js +24 -9
  61. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js.map +1 -1
  62. package/.medusa/server/src/api/admin/paypal/disconnect/route.d.ts.map +1 -1
  63. package/.medusa/server/src/api/admin/paypal/disconnect/route.js +10 -3
  64. package/.medusa/server/src/api/admin/paypal/disconnect/route.js.map +1 -1
  65. package/.medusa/server/src/api/admin/paypal/environment/route.js +2 -2
  66. package/.medusa/server/src/api/admin/paypal/environment/route.js.map +1 -1
  67. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts.map +1 -1
  68. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js +3 -2
  69. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js.map +1 -1
  70. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js +1 -1
  71. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js.map +1 -1
  72. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js +4 -4
  73. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js.map +1 -1
  74. package/.medusa/server/src/api/admin/paypal/save-credentials/route.d.ts.map +1 -1
  75. package/.medusa/server/src/api/admin/paypal/save-credentials/route.js +21 -8
  76. package/.medusa/server/src/api/admin/paypal/save-credentials/route.js.map +1 -1
  77. package/.medusa/server/src/api/admin/paypal/settings/route.d.ts.map +1 -1
  78. package/.medusa/server/src/api/admin/paypal/settings/route.js +34 -4
  79. package/.medusa/server/src/api/admin/paypal/settings/route.js.map +1 -1
  80. package/.medusa/server/src/api/admin/paypal/status/route.d.ts.map +1 -1
  81. package/.medusa/server/src/api/admin/paypal/status/route.js +11 -5
  82. package/.medusa/server/src/api/admin/paypal/status/route.js.map +1 -1
  83. package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts.map +1 -1
  84. package/.medusa/server/src/api/store/paypal/capture-order/route.js +21 -3
  85. package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -1
  86. package/.medusa/server/src/api/store/paypal/config/route.js +2 -2
  87. package/.medusa/server/src/api/store/paypal/config/route.js.map +1 -1
  88. package/.medusa/server/src/api/store/paypal/create-order/route.d.ts.map +1 -1
  89. package/.medusa/server/src/api/store/paypal/create-order/route.js +13 -9
  90. package/.medusa/server/src/api/store/paypal/create-order/route.js.map +1 -1
  91. package/.medusa/server/src/api/store/paypal/settings/route.js +3 -3
  92. package/.medusa/server/src/api/store/paypal/settings/route.js.map +1 -1
  93. package/.medusa/server/src/api/store/paypal/webhook/route.d.ts.map +1 -1
  94. package/.medusa/server/src/api/store/paypal/webhook/route.js +10 -3
  95. package/.medusa/server/src/api/store/paypal/webhook/route.js.map +1 -1
  96. package/.medusa/server/src/api/store/paypal-complete/route.d.ts.map +1 -1
  97. package/.medusa/server/src/api/store/paypal-complete/route.js +7 -4
  98. package/.medusa/server/src/api/store/paypal-complete/route.js.map +1 -1
  99. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js +3 -3
  100. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js.map +1 -1
  101. package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts +1 -1
  102. package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts.map +1 -1
  103. package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js +1 -1
  104. package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js.map +1 -1
  105. package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.d.ts +1 -1
  106. package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.d.ts.map +1 -1
  107. package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.js +1 -1
  108. package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.js.map +1 -1
  109. package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.d.ts +1 -1
  110. package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.d.ts.map +1 -1
  111. package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.js +1 -1
  112. package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.js.map +1 -1
  113. package/.medusa/server/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.d.ts +6 -0
  114. package/.medusa/server/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.d.ts.map +1 -0
  115. package/.medusa/server/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.js +25 -0
  116. package/.medusa/server/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.js.map +1 -0
  117. package/.medusa/server/src/modules/paypal/models/paypal_connection.d.ts +1 -1
  118. package/.medusa/server/src/modules/paypal/models/paypal_connection.js +3 -3
  119. package/.medusa/server/src/modules/paypal/models/paypal_connection.js.map +1 -1
  120. package/.medusa/server/src/modules/paypal/models/paypal_metric.d.ts +1 -1
  121. package/.medusa/server/src/modules/paypal/models/paypal_metric.js +1 -1
  122. package/.medusa/server/src/modules/paypal/models/paypal_metric.js.map +1 -1
  123. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.d.ts +1 -1
  124. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js +1 -1
  125. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js.map +1 -1
  126. package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts.map +1 -1
  127. package/.medusa/server/src/modules/paypal/payment-provider/card-service.js +95 -76
  128. package/.medusa/server/src/modules/paypal/payment-provider/card-service.js.map +1 -1
  129. package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts.map +1 -1
  130. package/.medusa/server/src/modules/paypal/payment-provider/service.js +39 -89
  131. package/.medusa/server/src/modules/paypal/payment-provider/service.js.map +1 -1
  132. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.d.ts.map +1 -1
  133. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js +7 -0
  134. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js.map +1 -1
  135. package/.medusa/server/src/modules/paypal/service.d.ts +10 -8
  136. package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -1
  137. package/.medusa/server/src/modules/paypal/service.js +56 -51
  138. package/.medusa/server/src/modules/paypal/service.js.map +1 -1
  139. package/.medusa/server/src/modules/paypal/types/config.d.ts.map +1 -1
  140. package/.medusa/server/src/modules/paypal/types/config.js +11 -2
  141. package/.medusa/server/src/modules/paypal/types/config.js.map +1 -1
  142. package/.medusa/server/src/modules/paypal/utils/paypal-auth.d.ts.map +1 -1
  143. package/.medusa/server/src/modules/paypal/utils/paypal-auth.js +1 -0
  144. package/.medusa/server/src/modules/paypal/utils/paypal-auth.js.map +1 -1
  145. package/.medusa/server/src/modules/paypal/webhook-processor.d.ts.map +1 -1
  146. package/.medusa/server/src/modules/paypal/webhook-processor.js +1 -1
  147. package/.medusa/server/src/modules/paypal/webhook-processor.js.map +1 -1
  148. package/.medusa/server/src/subscribers/paypal-order-invoice.js +4 -4
  149. package/.medusa/server/src/subscribers/paypal-order-invoice.js.map +1 -1
  150. package/package.json +1 -1
  151. package/src/admin/index.ts +1 -7
  152. package/src/admin/routes/settings/paypal/_components/FieldRow.tsx +29 -0
  153. package/src/admin/routes/settings/paypal/_components/SectionCard.tsx +26 -0
  154. package/src/admin/routes/settings/paypal/_components/Toast.tsx +4 -3
  155. package/src/admin/routes/settings/paypal/_utils/adminFetch.ts +32 -0
  156. package/src/admin/routes/settings/paypal/additional-settings/page.tsx +23 -83
  157. package/src/admin/routes/settings/paypal/advanced-card-payments/page.tsx +17 -77
  158. package/src/admin/routes/settings/paypal/connection/page.tsx +86 -45
  159. package/src/admin/routes/settings/paypal/paypal-settings/page.tsx +23 -101
  160. package/src/api/admin/payment-collections/[id]/payment-sessions/route.ts +26 -9
  161. package/src/api/admin/paypal/disconnect/route.ts +9 -3
  162. package/src/api/admin/paypal/environment/route.ts +2 -2
  163. package/src/api/admin/paypal/onboard-complete/route.ts +4 -3
  164. package/src/api/admin/paypal/onboarding-link/route.ts +1 -1
  165. package/src/api/admin/paypal/onboarding-status/route.ts +5 -5
  166. package/src/api/admin/paypal/save-credentials/route.ts +24 -9
  167. package/src/api/admin/paypal/settings/route.ts +35 -4
  168. package/src/api/admin/paypal/status/route.ts +10 -5
  169. package/src/api/store/paypal/capture-order/route.ts +27 -3
  170. package/src/api/store/paypal/config/route.ts +2 -2
  171. package/src/api/store/paypal/create-order/route.ts +16 -10
  172. package/src/api/store/paypal/settings/route.ts +3 -3
  173. package/src/api/store/paypal/webhook/route.ts +13 -3
  174. package/src/api/store/paypal-complete/route.ts +8 -4
  175. package/src/modules/paypal/clients/paypal-seller.client.ts +3 -3
  176. package/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.ts +1 -1
  177. package/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.ts +1 -1
  178. package/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.ts +1 -1
  179. package/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.ts +44 -0
  180. package/src/modules/paypal/models/paypal_connection.ts +3 -3
  181. package/src/modules/paypal/models/paypal_metric.ts +1 -1
  182. package/src/modules/paypal/models/paypal_webhook_event.ts +1 -1
  183. package/src/modules/paypal/payment-provider/card-service.ts +120 -80
  184. package/src/modules/paypal/payment-provider/service.ts +44 -93
  185. package/src/modules/paypal/payment-provider/webhook-utils.ts +9 -0
  186. package/src/modules/paypal/service.ts +79 -66
  187. package/src/modules/paypal/types/config.ts +18 -2
  188. package/src/modules/paypal/utils/paypal-auth.ts +1 -0
  189. package/src/modules/paypal/webhook-processor.ts +8 -5
  190. package/src/subscribers/paypal-order-invoice.ts +4 -4
@@ -34,7 +34,73 @@ function PayPalTabs() {
34
34
  );
35
35
  }) }) });
36
36
  }
37
- async function adminFetch$2(path, opts = {}) {
37
+ function SectionCard({
38
+ title,
39
+ description,
40
+ children,
41
+ right
42
+ }) {
43
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
44
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
45
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
46
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
47
+ description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
48
+ ] }),
49
+ right
50
+ ] }),
51
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
52
+ ] });
53
+ }
54
+ function FieldRow({
55
+ label,
56
+ hint,
57
+ htmlFor,
58
+ children
59
+ }) {
60
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
61
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
62
+ htmlFor ? /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor, className: "text-sm font-medium text-ui-fg-base", children: label }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
63
+ hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
64
+ ] }),
65
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
66
+ ] });
67
+ }
68
+ function Toast({ toast, onClose }) {
69
+ react.useEffect(() => {
70
+ if (!toast) return;
71
+ const duration = toast.kind === "error" ? 5e3 : 2500;
72
+ const t = setTimeout(() => onClose(), duration);
73
+ return () => clearTimeout(t);
74
+ }, [toast, onClose]);
75
+ if (!toast) return null;
76
+ const isSuccess = toast.kind === "success";
77
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed right-6 top-6 z-[9999]", children: /* @__PURE__ */ jsxRuntime.jsx(
78
+ "div",
79
+ {
80
+ className: [
81
+ "min-w-[280px] max-w-[420px] rounded-lg border px-4 py-3 shadow-md",
82
+ isSuccess ? "border-emerald-500/30 bg-emerald-500/10" : "border-rose-500/30 bg-rose-500/10"
83
+ ].join(" "),
84
+ role: isSuccess ? "status" : "alert",
85
+ "aria-live": isSuccess ? "polite" : "assertive",
86
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
87
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["mt-0.5 h-2.5 w-2.5 rounded-full", isSuccess ? "bg-emerald-500" : "bg-rose-500"].join(" ") }),
88
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 text-sm text-ui-fg-base", children: toast.message }),
89
+ /* @__PURE__ */ jsxRuntime.jsx(
90
+ "button",
91
+ {
92
+ type: "button",
93
+ onClick: onClose,
94
+ className: "text-ui-fg-subtle hover:text-ui-fg-base",
95
+ "aria-label": "Close",
96
+ children: "×"
97
+ }
98
+ )
99
+ ] })
100
+ }
101
+ ) });
102
+ }
103
+ async function adminFetch(path, opts = {}) {
38
104
  var _a;
39
105
  const { method = "GET", body, query } = opts;
40
106
  let url = path;
@@ -68,57 +134,35 @@ async function adminFetch$2(path, opts = {}) {
68
134
  }
69
135
  }
70
136
  const DEFAULT_FORM$1 = {
71
- enabled: true,
72
- title: "Credit or Debit Card",
73
- threeDS: "when_required"
137
+ paymentAction: "capture",
138
+ brandName: "PayPal",
139
+ landingPage: "no_preference",
140
+ requireInstantPayment: false,
141
+ sendItemDetails: true,
142
+ invoicePrefix: "PP-",
143
+ creditCardStatementName: "PayPal"
74
144
  };
75
145
  function mergeWithDefaults$1(saved) {
76
146
  if (!saved) return { ...DEFAULT_FORM$1 };
77
147
  const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
78
148
  return { ...DEFAULT_FORM$1, ...Object.fromEntries(entries) };
79
149
  }
80
- const THREE_DS_OPTIONS = [
81
- { value: "when_required", label: "3D Secure when required", hint: "Triggers 3DS only when the card / issuer requires it." },
82
- { value: "sli", label: "3D Secure (SCA) / liability shift (recommended)", hint: "Attempts to optimize for liability shift while remaining compliant." },
83
- { value: "always", label: "Always request 3D Secure", hint: "Forces 3DS challenge whenever possible (may reduce conversion)." }
84
- ];
85
- function SectionCard$2({ title, description, right, children }) {
86
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
87
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
88
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
89
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
90
- description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
91
- ] }),
92
- right
93
- ] }),
94
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
95
- ] });
96
- }
97
- function FieldRow$2({ label, hint, children }) {
98
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
99
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
100
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
101
- hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
102
- ] }),
103
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
104
- ] });
105
- }
106
- function AdvancedCardPaymentsTab() {
107
- var _a, _b;
150
+ function AdditionalSettingsTab() {
108
151
  const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM$1 }));
109
152
  const [loading, setLoading] = react.useState(false);
110
153
  const [saving, setSaving] = react.useState(false);
111
154
  const [toast, setToast] = react.useState(null);
112
155
  const didInit = react.useRef(false);
156
+ const dismissToast = react.useCallback(() => setToast(null), []);
113
157
  react.useEffect(() => {
114
158
  if (didInit.current) return;
115
159
  didInit.current = true;
116
160
  (async () => {
117
161
  try {
118
162
  setLoading(true);
119
- const json = await adminFetch$2("/admin/paypal/settings");
163
+ const json = await adminFetch("/admin/paypal/settings");
120
164
  const payload = (json == null ? void 0 : json.data) ?? json;
121
- const saved = payload == null ? void 0 : payload.advanced_card_payments;
165
+ const saved = payload == null ? void 0 : payload.additional_settings;
122
166
  if (saved && typeof saved === "object") setForm(mergeWithDefaults$1(saved));
123
167
  } catch {
124
168
  } finally {
@@ -129,18 +173,14 @@ function AdvancedCardPaymentsTab() {
129
173
  async function onSave() {
130
174
  try {
131
175
  setSaving(true);
132
- const json = await adminFetch$2("/admin/paypal/settings", {
133
- method: "POST",
134
- body: { advanced_card_payments: form }
135
- });
176
+ setToast(null);
177
+ const json = await adminFetch("/admin/paypal/settings", { method: "POST", body: { additional_settings: form } });
136
178
  const payload = (json == null ? void 0 : json.data) ?? json;
137
- const saved = payload == null ? void 0 : payload.advanced_card_payments;
179
+ const saved = payload == null ? void 0 : payload.additional_settings;
138
180
  if (saved && typeof saved === "object") setForm(mergeWithDefaults$1(saved));
139
- setToast({ type: "success", message: "Settings saved" });
140
- window.setTimeout(() => setToast(null), 2500);
181
+ setToast({ kind: "success", message: "Settings saved" });
141
182
  } catch (e) {
142
- setToast({ type: "error", message: (e instanceof Error ? e.message : "") || "Failed to save settings." });
143
- window.setTimeout(() => setToast(null), 3500);
183
+ setToast({ kind: "error", message: e instanceof Error ? e.message : "Failed to save settings" });
144
184
  } finally {
145
185
  setSaving(false);
146
186
  }
@@ -148,114 +188,77 @@ function AdvancedCardPaymentsTab() {
148
188
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
149
189
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-ui-fg-base", children: "PayPal Gateway By Easy Payment" }) }) }),
150
190
  /* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
151
- toast ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed right-6 top-6 z-50 rounded-md border border-ui-border-base bg-ui-bg-base px-4 py-3 text-sm shadow-lg", role: "status", "aria-live": "polite", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error", children: toast.message }) }) : null,
191
+ /* @__PURE__ */ jsxRuntime.jsx(Toast, { toast, onClose: dismissToast }),
152
192
  /* @__PURE__ */ jsxRuntime.jsx(
153
- SectionCard$2,
193
+ SectionCard,
154
194
  {
155
- title: "Advanced Card Payments",
156
- description: "Control card checkout settings and 3D Secure behavior.",
195
+ title: "Additional Settings",
196
+ description: "These settings control checkout behavior and PayPal experience.",
157
197
  right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
158
198
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onSave, disabled: saving || loading, className: "transition-fg relative inline-flex w-fit items-center justify-center overflow-hidden rounded-md outline-none 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", children: saving ? "Saving..." : "Save settings" }),
159
- loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading..." }) : null
199
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading" }) : null
160
200
  ] }),
161
201
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
162
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Enable/Disable", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
163
- /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", checked: form.enabled, onChange: (e) => setForm((p) => ({ ...p, enabled: e.target.checked })), className: "h-4 w-4 rounded border-ui-border-base" }),
164
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable Advanced Credit/Debit Card" })
202
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Payment action", htmlFor: "as-payment-action", children: /* @__PURE__ */ jsxRuntime.jsxs("select", { id: "as-payment-action", value: form.paymentAction, onChange: (e) => setForm((p) => ({ ...p, paymentAction: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", children: [
203
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "capture", children: "Capture" }),
204
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorize", children: "Authorize" })
165
205
  ] }) }),
166
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Title", children: /* @__PURE__ */ jsxRuntime.jsx("input", { value: form.title, onChange: (e) => setForm((p) => ({ ...p, title: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", placeholder: "Credit or Debit Card" }) }),
167
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Contingency for 3D Secure", hint: "Choose when 3D Secure should be triggered during card payments.", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
168
- /* @__PURE__ */ jsxRuntime.jsx("select", { value: form.threeDS, onChange: (e) => setForm((p) => ({ ...p, threeDS: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", children: THREE_DS_OPTIONS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value)) }),
169
- ((_a = THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)) == null ? void 0 : _a.hint) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-ui-fg-subtle", children: (_b = THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)) == null ? void 0 : _b.hint }) : null
170
- ] }) })
206
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Brand Name", htmlFor: "as-brand-name", children: /* @__PURE__ */ jsxRuntime.jsx("input", { id: "as-brand-name", value: form.brandName, onChange: (e) => setForm((p) => ({ ...p, brandName: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", placeholder: "PayPal" }) }),
207
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Landing Page", htmlFor: "as-landing-page", children: /* @__PURE__ */ jsxRuntime.jsxs("select", { id: "as-landing-page", value: form.landingPage, onChange: (e) => setForm((p) => ({ ...p, landingPage: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", children: [
208
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "no_preference", children: "No Preference" }),
209
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "login", children: "Login" }),
210
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "billing", children: "Billing" })
211
+ ] }) }),
212
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Instant Payments", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
213
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", checked: form.requireInstantPayment, onChange: (e) => setForm((p) => ({ ...p, requireInstantPayment: e.target.checked })), className: "h-4 w-4 rounded border-ui-border-base" }),
214
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Require Instant Payment" })
215
+ ] }) }),
216
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Send Item Details", hint: "Include all line item details in the payment request to PayPal so that they can be seen from the PayPal transaction details page.", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
217
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", checked: form.sendItemDetails, onChange: (e) => setForm((p) => ({ ...p, sendItemDetails: e.target.checked })), className: "h-4 w-4 rounded border-ui-border-base" }),
218
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Send line item details to PayPal" })
219
+ ] }) }),
220
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Invoice prefix", htmlFor: "as-invoice-prefix", children: /* @__PURE__ */ jsxRuntime.jsx("input", { id: "as-invoice-prefix", value: form.invoicePrefix, onChange: (e) => setForm((p) => ({ ...p, invoicePrefix: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", placeholder: "PP-" }) }),
221
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Credit Card Statement Name", htmlFor: "as-cc-statement", children: /* @__PURE__ */ jsxRuntime.jsx("input", { id: "as-cc-statement", value: form.creditCardStatementName, onChange: (e) => setForm((p) => ({ ...p, creditCardStatementName: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", placeholder: "PayPal" }) })
171
222
  ] })
172
223
  }
173
224
  )
174
225
  ] }) });
175
226
  }
176
- async function adminFetch$1(path, opts = {}) {
177
- var _a;
178
- const { method = "GET", body, query } = opts;
179
- let url = path;
180
- if (query && Object.keys(query).length > 0) {
181
- const params = new URLSearchParams(query);
182
- url = `${path}?${params.toString()}`;
183
- }
184
- const headers = { Accept: "application/json" };
185
- if (body !== void 0) headers["Content-Type"] = "application/json";
186
- if (typeof window !== "undefined") {
187
- const token = (_a = window.__medusa__) == null ? void 0 : _a.token;
188
- if (token) headers["Authorization"] = `Bearer ${token}`;
189
- }
190
- const res = await fetch(url, {
191
- method,
192
- headers,
193
- credentials: "include",
194
- body: body !== void 0 ? JSON.stringify(body) : void 0
195
- });
196
- const text = await res.text().catch(() => "");
197
- if (!res.ok) {
198
- if (res.status === 401) throw new Error("Unauthorized (401) - session may have expired. Please reload and log in again.");
199
- if (res.status === 403) throw new Error("Forbidden (403) - you do not have permission to perform this action.");
200
- throw new Error(text || `Request failed with status ${res.status}`);
201
- }
202
- if (!text) return {};
203
- try {
204
- return JSON.parse(text);
205
- } catch {
206
- return {};
207
- }
227
+ function PayPalApplePayPage() {
228
+ return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
208
229
  }
209
230
  const DEFAULT_FORM = {
210
- paymentAction: "capture",
211
- brandName: "PayPal",
212
- landingPage: "no_preference",
213
- requireInstantPayment: false,
214
- sendItemDetails: true,
215
- invoicePrefix: "WC-",
216
- creditCardStatementName: "PayPal"
231
+ enabled: true,
232
+ title: "Credit or Debit Card",
233
+ threeDS: "when_required"
217
234
  };
218
235
  function mergeWithDefaults(saved) {
219
236
  if (!saved) return { ...DEFAULT_FORM };
220
237
  const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
221
238
  return { ...DEFAULT_FORM, ...Object.fromEntries(entries) };
222
239
  }
223
- function SectionCard$1({ title, description, right, children }) {
224
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
225
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
226
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
227
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
228
- description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
229
- ] }),
230
- right
231
- ] }),
232
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
233
- ] });
234
- }
235
- function FieldRow$1({ label, hint, children }) {
236
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
237
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
238
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
239
- hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
240
- ] }),
241
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
242
- ] });
243
- }
244
- function AdditionalSettingsTab() {
240
+ const THREE_DS_OPTIONS = [
241
+ { value: "when_required", label: "3D Secure when required", hint: "Triggers 3DS only when the card / issuer requires it." },
242
+ { value: "sli", label: "3D Secure (SCA) / liability shift (recommended)", hint: "Attempts to optimize for liability shift while remaining compliant." },
243
+ { value: "always", label: "Always request 3D Secure", hint: "Forces 3DS challenge whenever possible (may reduce conversion)." }
244
+ ];
245
+ function AdvancedCardPaymentsTab() {
246
+ var _a, _b;
245
247
  const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM }));
246
248
  const [loading, setLoading] = react.useState(false);
247
249
  const [saving, setSaving] = react.useState(false);
248
250
  const [toast, setToast] = react.useState(null);
249
251
  const didInit = react.useRef(false);
252
+ const dismissToast = react.useCallback(() => setToast(null), []);
250
253
  react.useEffect(() => {
251
254
  if (didInit.current) return;
252
255
  didInit.current = true;
253
256
  (async () => {
254
257
  try {
255
258
  setLoading(true);
256
- const json = await adminFetch$1("/admin/paypal/settings");
259
+ const json = await adminFetch("/admin/paypal/settings");
257
260
  const payload = (json == null ? void 0 : json.data) ?? json;
258
- const saved = payload == null ? void 0 : payload.additional_settings;
261
+ const saved = payload == null ? void 0 : payload.advanced_card_payments;
259
262
  if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved));
260
263
  } catch {
261
264
  } finally {
@@ -266,16 +269,16 @@ function AdditionalSettingsTab() {
266
269
  async function onSave() {
267
270
  try {
268
271
  setSaving(true);
269
- setToast(null);
270
- const json = await adminFetch$1("/admin/paypal/settings", { method: "POST", body: { additional_settings: form } });
272
+ const json = await adminFetch("/admin/paypal/settings", {
273
+ method: "POST",
274
+ body: { advanced_card_payments: form }
275
+ });
271
276
  const payload = (json == null ? void 0 : json.data) ?? json;
272
- const saved = payload == null ? void 0 : payload.additional_settings;
277
+ const saved = payload == null ? void 0 : payload.advanced_card_payments;
273
278
  if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved));
274
- setToast({ type: "success", message: "Settings saved" });
275
- window.setTimeout(() => setToast(null), 2500);
279
+ setToast({ kind: "success", message: "Settings saved" });
276
280
  } catch (e) {
277
- setToast({ type: "error", message: e instanceof Error ? e.message : "Failed to save settings" });
278
- window.setTimeout(() => setToast(null), 3500);
281
+ setToast({ kind: "error", message: (e instanceof Error ? e.message : "") || "Failed to save settings." });
279
282
  } finally {
280
283
  setSaving(false);
281
284
  }
@@ -283,75 +286,40 @@ function AdditionalSettingsTab() {
283
286
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
284
287
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-ui-fg-base", children: "PayPal Gateway By Easy Payment" }) }) }),
285
288
  /* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
286
- toast ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed right-6 top-6 z-50 rounded-md border border-ui-border-base bg-ui-bg-base px-4 py-3 text-sm shadow-lg", role: "status", "aria-live": "polite", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error", children: toast.message }) }) : null,
289
+ /* @__PURE__ */ jsxRuntime.jsx(Toast, { toast, onClose: dismissToast }),
287
290
  /* @__PURE__ */ jsxRuntime.jsx(
288
- SectionCard$1,
291
+ SectionCard,
289
292
  {
290
- title: "Additional Settings",
291
- description: "These settings control checkout behavior and PayPal experience.",
293
+ title: "Advanced Card Payments",
294
+ description: "Control card checkout settings and 3D Secure behavior.",
292
295
  right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
293
296
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onSave, disabled: saving || loading, className: "transition-fg relative inline-flex w-fit items-center justify-center overflow-hidden rounded-md outline-none 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", children: saving ? "Saving..." : "Save settings" }),
294
- loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading..." }) : null
297
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading" }) : null
295
298
  ] }),
296
299
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
297
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Payment action", children: /* @__PURE__ */ jsxRuntime.jsxs("select", { value: form.paymentAction, onChange: (e) => setForm((p) => ({ ...p, paymentAction: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", children: [
298
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "capture", children: "Capture" }),
299
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorize", children: "Authorize" })
300
- ] }) }),
301
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Brand Name", children: /* @__PURE__ */ jsxRuntime.jsx("input", { value: form.brandName, onChange: (e) => setForm((p) => ({ ...p, brandName: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", placeholder: "PayPal" }) }),
302
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Landing Page", children: /* @__PURE__ */ jsxRuntime.jsxs("select", { value: form.landingPage, onChange: (e) => setForm((p) => ({ ...p, landingPage: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", children: [
303
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "no_preference", children: "No Preference" }),
304
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "login", children: "Login" }),
305
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "billing", children: "Billing" })
306
- ] }) }),
307
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Instant Payments", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
308
- /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", checked: form.requireInstantPayment, onChange: (e) => setForm((p) => ({ ...p, requireInstantPayment: e.target.checked })), className: "h-4 w-4 rounded border-ui-border-base" }),
309
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Require Instant Payment" })
310
- ] }) }),
311
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Send Item Details", hint: "Include all line item details in the payment request to PayPal so that they can be seen from the PayPal transaction details page.", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
312
- /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", checked: form.sendItemDetails, onChange: (e) => setForm((p) => ({ ...p, sendItemDetails: e.target.checked })), className: "h-4 w-4 rounded border-ui-border-base" }),
313
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Send line item details to PayPal" })
300
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Enable/Disable", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
301
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", checked: form.enabled, onChange: (e) => setForm((p) => ({ ...p, enabled: e.target.checked })), className: "h-4 w-4 rounded border-ui-border-base" }),
302
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable Advanced Credit/Debit Card" })
314
303
  ] }) }),
315
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Invoice prefix", children: /* @__PURE__ */ jsxRuntime.jsx("input", { value: form.invoicePrefix, onChange: (e) => setForm((p) => ({ ...p, invoicePrefix: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", placeholder: "WC-" }) }),
316
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Credit Card Statement Name", children: /* @__PURE__ */ jsxRuntime.jsx("input", { value: form.creditCardStatementName, onChange: (e) => setForm((p) => ({ ...p, creditCardStatementName: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", placeholder: "PayPal" }) })
304
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Title", htmlFor: "acp-title", children: /* @__PURE__ */ jsxRuntime.jsx("input", { id: "acp-title", value: form.title, onChange: (e) => setForm((p) => ({ ...p, title: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", placeholder: "Credit or Debit Card" }) }),
305
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Contingency for 3D Secure", hint: "Choose when 3D Secure should be triggered during card payments.", htmlFor: "acp-threeds", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
306
+ /* @__PURE__ */ jsxRuntime.jsx("select", { id: "acp-threeds", value: form.threeDS, onChange: (e) => setForm((p) => ({ ...p, threeDS: e.target.value })), className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive", children: THREE_DS_OPTIONS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value)) }),
307
+ ((_a = THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)) == null ? void 0 : _a.hint) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-ui-fg-subtle", children: (_b = THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)) == null ? void 0 : _b.hint }) : null
308
+ ] }) })
317
309
  ] })
318
310
  }
319
311
  )
320
312
  ] }) });
321
313
  }
322
- function PayPalApplePayPage() {
314
+ function PayPalGooglePayPage() {
323
315
  return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
324
316
  }
325
317
  const config = adminSdk.defineRouteConfig({
326
- label: "PayPal Connection",
327
- hide: true
318
+ label: "PayPal Connection"
328
319
  });
329
- if (typeof window !== "undefined") {
330
- const preloadHref = "https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js";
331
- const existingPreload = document.head.querySelector(
332
- `link[rel="preload"][href="${preloadHref}"]`
333
- );
334
- if (!existingPreload) {
335
- const preloadLink = document.createElement("link");
336
- preloadLink.rel = "preload";
337
- preloadLink.href = preloadHref;
338
- preloadLink.as = "script";
339
- document.head.appendChild(preloadLink);
340
- }
341
- const existingScript = document.getElementById(
342
- "paypal-partner-js"
343
- );
344
- if (!existingScript) {
345
- const ppScript = document.createElement("script");
346
- ppScript.id = "paypal-partner-js";
347
- ppScript.src = preloadHref;
348
- ppScript.async = true;
349
- document.head.appendChild(ppScript);
350
- }
351
- }
320
+ const PARTNER_JS_URL = "https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js";
352
321
  const SERVICE_URL = "/admin/paypal/onboarding-link";
353
322
  const CACHE_KEY = "pp_onboard_cache";
354
- const RELOAD_KEY = "pp_onboard_reloaded_once";
355
323
  const CACHE_EXPIRY = 10 * 60 * 1e3;
356
324
  const ONBOARDING_COMPLETE_ENDPOINT = "/admin/paypal/onboard-complete";
357
325
  const STATUS_ENDPOINT = "/admin/paypal/status";
@@ -374,12 +342,45 @@ if (typeof window !== "undefined") {
374
342
  function PayPalConnectionPage() {
375
343
  const [env, setEnv] = react.useState("live");
376
344
  react.useEffect(() => {
377
- fetch("/admin/paypal/environment", { method: "GET" }).then((r) => r.json()).then((d) => {
345
+ fetch("/admin/paypal/environment", { method: "GET", credentials: "include" }).then((r) => r.json()).then((d) => {
378
346
  const v = (d == null ? void 0 : d.environment) === "sandbox" ? "sandbox" : "live";
379
347
  setEnv(v);
380
348
  }).catch(() => {
381
349
  });
382
350
  }, []);
351
+ react.useEffect(() => {
352
+ const preloadHref = PARTNER_JS_URL;
353
+ let preloadLink = null;
354
+ const existingPreload = document.head.querySelector(
355
+ `link[rel="preload"][href="${preloadHref}"]`
356
+ );
357
+ if (!existingPreload) {
358
+ preloadLink = document.createElement("link");
359
+ preloadLink.rel = "preload";
360
+ preloadLink.href = preloadHref;
361
+ preloadLink.as = "script";
362
+ document.head.appendChild(preloadLink);
363
+ }
364
+ let ppScript = null;
365
+ const existingScript = document.getElementById(
366
+ "paypal-partner-js"
367
+ );
368
+ if (!existingScript) {
369
+ ppScript = document.createElement("script");
370
+ ppScript.id = "paypal-partner-js";
371
+ ppScript.src = preloadHref;
372
+ ppScript.async = true;
373
+ document.head.appendChild(ppScript);
374
+ }
375
+ return () => {
376
+ if (preloadLink && preloadLink.parentNode) {
377
+ preloadLink.parentNode.removeChild(preloadLink);
378
+ }
379
+ if (ppScript && ppScript.parentNode) {
380
+ ppScript.parentNode.removeChild(ppScript);
381
+ }
382
+ };
383
+ }, []);
383
384
  const [connState, setConnState] = react.useState("loading");
384
385
  const [error, setError] = react.useState(null);
385
386
  const [finalUrl, setFinalUrl] = react.useState("");
@@ -408,10 +409,14 @@ function PayPalConnectionPage() {
408
409
  fetch(SERVICE_URL, {
409
410
  method: "POST",
410
411
  headers: { "content-type": "application/json" },
412
+ credentials: "include",
411
413
  body: JSON.stringify({
412
414
  products: ["PPCP"]
413
415
  })
414
- }).then((r) => r.json()).then((data) => {
416
+ }).then((r) => {
417
+ if (!r.ok) throw new Error(`Service returned ${r.status}`);
418
+ return r.json();
419
+ }).then((data) => {
415
420
  if (runId !== currentRunId.current) return;
416
421
  const href = data == null ? void 0 : data.onboarding_url;
417
422
  if (!href) {
@@ -426,11 +431,6 @@ function PayPalConnectionPage() {
426
431
  ts: Date.now()
427
432
  })
428
433
  );
429
- if (!localStorage.getItem(RELOAD_KEY)) {
430
- localStorage.setItem(RELOAD_KEY, "1");
431
- window.location.reload();
432
- return;
433
- }
434
434
  activatePayPal(finalUrl2, runId);
435
435
  }).catch(() => {
436
436
  if (runId !== currentRunId.current) return;
@@ -457,6 +457,8 @@ function PayPalConnectionPage() {
457
457
  paypalButtonRef.current.href = url;
458
458
  }
459
459
  setFinalUrl(url);
460
+ let attempts = 0;
461
+ const MAX_ATTEMPTS = 200;
460
462
  const tryInit = () => {
461
463
  var _a, _b;
462
464
  if (runId !== currentRunId.current) return;
@@ -464,6 +466,11 @@ function PayPalConnectionPage() {
464
466
  showUI();
465
467
  return;
466
468
  }
469
+ attempts++;
470
+ if (attempts >= MAX_ATTEMPTS) {
471
+ showError("PayPal partner script failed to load. Please refresh and try again.");
472
+ return;
473
+ }
467
474
  setTimeout(tryInit, 50);
468
475
  };
469
476
  tryInit();
@@ -480,7 +487,8 @@ function PayPalConnectionPage() {
480
487
  setFinalUrl("");
481
488
  try {
482
489
  const r = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
483
- method: "GET"
490
+ method: "GET",
491
+ credentials: "include"
484
492
  });
485
493
  const st = await r.json().catch(() => ({}));
486
494
  if (cancelled || runId !== currentRunId.current) return;
@@ -510,8 +518,7 @@ function PayPalConnectionPage() {
510
518
  window.onboardingCallback = async function(authCode, sharedId) {
511
519
  var _a, _b, _c, _d, _e, _f, _g;
512
520
  try {
513
- ;
514
- window.onbeforeunload = "";
521
+ window.onbeforeunload = null;
515
522
  } catch {
516
523
  }
517
524
  setOnboardingInProgress(true);
@@ -526,6 +533,7 @@ function PayPalConnectionPage() {
526
533
  const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
527
534
  method: "POST",
528
535
  headers: { "content-type": "application/json" },
536
+ credentials: "include",
529
537
  body: JSON.stringify(payload)
530
538
  });
531
539
  if (!res.ok) {
@@ -544,10 +552,22 @@ function PayPalConnectionPage() {
544
552
  }
545
553
  try {
546
554
  localStorage.removeItem(CACHE_KEY);
547
- localStorage.removeItem(RELOAD_KEY);
548
555
  } catch {
549
556
  }
550
- window.location.href = window.location.href;
557
+ try {
558
+ const statusRes = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
559
+ method: "GET",
560
+ credentials: "include"
561
+ });
562
+ const refreshedStatus = await statusRes.json().catch(() => ({}));
563
+ setStatusInfo(refreshedStatus || null);
564
+ setConnState("connected");
565
+ setShowManual(false);
566
+ } catch {
567
+ setConnState("connected");
568
+ setShowManual(false);
569
+ }
570
+ setOnboardingInProgress(false);
551
571
  } catch (e) {
552
572
  console.error(e);
553
573
  setConnState("error");
@@ -593,6 +613,7 @@ function PayPalConnectionPage() {
593
613
  const res = await fetch(SAVE_CREDENTIALS_ENDPOINT, {
594
614
  method: "POST",
595
615
  headers: { "content-type": "application/json" },
616
+ credentials: "include",
596
617
  body: JSON.stringify({
597
618
  clientId: clientId.trim(),
598
619
  clientSecret: secret.trim(),
@@ -604,7 +625,8 @@ function PayPalConnectionPage() {
604
625
  throw new Error(txt || `Save credentials failed (${res.status})`);
605
626
  }
606
627
  const statusRes = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
607
- method: "GET"
628
+ method: "GET",
629
+ credentials: "include"
608
630
  });
609
631
  const refreshedStatus = await statusRes.json().catch(() => ({}));
610
632
  setConnState("connected");
@@ -612,7 +634,6 @@ function PayPalConnectionPage() {
612
634
  setShowManual(false);
613
635
  try {
614
636
  localStorage.removeItem(CACHE_KEY);
615
- localStorage.removeItem(RELOAD_KEY);
616
637
  } catch {
617
638
  }
618
639
  } catch (e) {
@@ -631,10 +652,12 @@ function PayPalConnectionPage() {
631
652
  setError(null);
632
653
  setFinalUrl("");
633
654
  setShowManual(false);
655
+ setStatusInfo(null);
634
656
  try {
635
657
  const res = await fetch(DISCONNECT_ENDPOINT, {
636
658
  method: "POST",
637
659
  headers: { "content-type": "application/json" },
660
+ credentials: "include",
638
661
  body: JSON.stringify({ environment: env })
639
662
  });
640
663
  if (!res.ok) {
@@ -643,7 +666,6 @@ function PayPalConnectionPage() {
643
666
  }
644
667
  try {
645
668
  localStorage.removeItem(CACHE_KEY);
646
- localStorage.removeItem(RELOAD_KEY);
647
669
  } catch {
648
670
  }
649
671
  currentRunId.current = ++runIdRef.current;
@@ -665,19 +687,19 @@ function PayPalConnectionPage() {
665
687
  await fetch("/admin/paypal/environment", {
666
688
  method: "POST",
667
689
  headers: { "content-type": "application/json" },
690
+ credentials: "include",
668
691
  body: JSON.stringify({ environment: next })
669
692
  });
670
693
  } catch {
671
694
  }
672
695
  try {
673
696
  localStorage.removeItem(CACHE_KEY);
674
- localStorage.removeItem(RELOAD_KEY);
675
697
  } catch {
676
698
  }
677
699
  };
678
700
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6", children: [
679
701
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
680
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold", children: "PayPal Gateway By Easy Payment" }),
702
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-ui-fg-base", children: "PayPal Gateway By Easy Payment" }) }) }),
681
703
  /* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
682
704
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-y-6 p-4 md:grid-cols-[260px_1fr] md:items-start", children: [
683
705
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium pt-2", children: "Environment" }),
@@ -807,10 +829,11 @@ function PayPalConnectionPage() {
807
829
  ] }) }),
808
830
  showManual && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:col-span-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-[260px] max-w-xl mt-4 grid grid-cols-1 gap-3 md:grid-cols-2", children: [
809
831
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
810
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Client ID" }),
832
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "pp-manual-client-id", className: "text-sm font-medium", children: "Client ID" }),
811
833
  /* @__PURE__ */ jsxRuntime.jsx(
812
834
  "input",
813
835
  {
836
+ id: "pp-manual-client-id",
814
837
  type: "text",
815
838
  value: clientId,
816
839
  onChange: (e) => setClientId(e.target.value),
@@ -821,10 +844,11 @@ function PayPalConnectionPage() {
821
844
  )
822
845
  ] }),
823
846
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
824
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Secret" }),
847
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "pp-manual-secret", className: "text-sm font-medium", children: "Secret" }),
825
848
  /* @__PURE__ */ jsxRuntime.jsx(
826
849
  "input",
827
850
  {
851
+ id: "pp-manual-secret",
828
852
  type: "password",
829
853
  value: secret,
830
854
  onChange: (e) => setSecret(e.target.value),
@@ -915,45 +939,9 @@ function PayPalConnectionPage() {
915
939
  ` })
916
940
  ] });
917
941
  }
918
- function PayPalGooglePayPage() {
919
- return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
920
- }
921
942
  function PayPalPayLaterMessagingPage() {
922
943
  return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
923
944
  }
924
- async function adminFetch(path, opts = {}) {
925
- var _a;
926
- const { method = "GET", body, query } = opts;
927
- let url = path;
928
- if (query && Object.keys(query).length > 0) {
929
- const params = new URLSearchParams(query);
930
- url = `${path}?${params.toString()}`;
931
- }
932
- const headers = { Accept: "application/json" };
933
- if (body !== void 0) headers["Content-Type"] = "application/json";
934
- if (typeof window !== "undefined") {
935
- const token = (_a = window.__medusa__) == null ? void 0 : _a.token;
936
- if (token) headers["Authorization"] = `Bearer ${token}`;
937
- }
938
- const res = await fetch(url, {
939
- method,
940
- headers,
941
- credentials: "include",
942
- body: body !== void 0 ? JSON.stringify(body) : void 0
943
- });
944
- const text = await res.text().catch(() => "");
945
- if (!res.ok) {
946
- if (res.status === 401) throw new Error("Unauthorized (401) - session may have expired. Please reload and log in again.");
947
- if (res.status === 403) throw new Error("Forbidden (403) - you do not have permission to perform this action.");
948
- throw new Error(text || `Request failed with status ${res.status}`);
949
- }
950
- if (!text) return {};
951
- try {
952
- return JSON.parse(text);
953
- } catch {
954
- return {};
955
- }
956
- }
957
945
  const COLOR_OPTIONS = [
958
946
  { value: "gold", label: "Gold (Recommended)" },
959
947
  { value: "blue", label: "Blue" },
@@ -978,36 +966,6 @@ const LABEL_OPTIONS = [
978
966
  { value: "buynow", label: "Buy Now" },
979
967
  { value: "pay", label: "Pay" }
980
968
  ];
981
- function SectionCard({
982
- title,
983
- description,
984
- children,
985
- right
986
- }) {
987
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
988
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
989
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
990
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
991
- description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
992
- ] }),
993
- right
994
- ] }),
995
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
996
- ] });
997
- }
998
- function FieldRow({
999
- label,
1000
- hint,
1001
- children
1002
- }) {
1003
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
1004
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
1005
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
1006
- hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
1007
- ] }),
1008
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
1009
- ] });
1010
- }
1011
969
  function PayPalSettingsTab() {
1012
970
  const [form, setForm] = react.useState({
1013
971
  enabled: true,
@@ -1023,6 +981,7 @@ function PayPalSettingsTab() {
1023
981
  const [saving, setSaving] = react.useState(false);
1024
982
  const [toast, setToast] = react.useState(null);
1025
983
  const didInit = react.useRef(false);
984
+ const dismissToast = react.useCallback(() => setToast(null), []);
1026
985
  react.useEffect(() => {
1027
986
  if (didInit.current) return;
1028
987
  didInit.current = true;
@@ -1065,14 +1024,12 @@ function PayPalSettingsTab() {
1065
1024
  ...saved
1066
1025
  }));
1067
1026
  }
1068
- setToast({ type: "success", message: "Settings saved" });
1069
- window.setTimeout(() => setToast(null), 2500);
1027
+ setToast({ kind: "success", message: "Settings saved" });
1070
1028
  } catch (e) {
1071
1029
  setToast({
1072
- type: "error",
1030
+ kind: "error",
1073
1031
  message: (e instanceof Error ? e.message : "") || "Failed to save settings."
1074
1032
  });
1075
- window.setTimeout(() => setToast(null), 3500);
1076
1033
  } finally {
1077
1034
  setSaving(false);
1078
1035
  }
@@ -1083,15 +1040,7 @@ function PayPalSettingsTab() {
1083
1040
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2" })
1084
1041
  ] }),
1085
1042
  /* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
1086
- toast ? /* @__PURE__ */ jsxRuntime.jsx(
1087
- "div",
1088
- {
1089
- className: "fixed right-6 top-6 z-50 rounded-md border border-ui-border-base bg-ui-bg-base px-4 py-3 text-sm shadow-lg",
1090
- role: "status",
1091
- "aria-live": "polite",
1092
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error", children: toast.message })
1093
- }
1094
- ) : null,
1043
+ /* @__PURE__ */ jsxRuntime.jsx(Toast, { toast, onClose: dismissToast }),
1095
1044
  /* @__PURE__ */ jsxRuntime.jsx(
1096
1045
  SectionCard,
1097
1046
  {
@@ -1123,9 +1072,10 @@ function PayPalSettingsTab() {
1123
1072
  ),
1124
1073
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable PayPal" })
1125
1074
  ] }) }),
1126
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Title", children: /* @__PURE__ */ jsxRuntime.jsx(
1075
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Title", htmlFor: "pp-title", children: /* @__PURE__ */ jsxRuntime.jsx(
1127
1076
  "input",
1128
1077
  {
1078
+ id: "pp-title",
1129
1079
  value: form.title,
1130
1080
  onChange: (e) => setForm((p) => ({ ...p, title: e.target.value })),
1131
1081
  className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive",
@@ -1141,36 +1091,40 @@ function PayPalSettingsTab() {
1141
1091
  title: "Button Appearance",
1142
1092
  description: "Control PayPal Smart Button styling (color/shape/size/label).",
1143
1093
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
1144
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Color", children: /* @__PURE__ */ jsxRuntime.jsx(
1094
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Color", htmlFor: "pp-btn-color", children: /* @__PURE__ */ jsxRuntime.jsx(
1145
1095
  "select",
1146
1096
  {
1097
+ id: "pp-btn-color",
1147
1098
  value: form.buttonColor,
1148
1099
  onChange: (e) => setForm((p) => ({ ...p, buttonColor: e.target.value })),
1149
1100
  className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive",
1150
1101
  children: COLOR_OPTIONS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
1151
1102
  }
1152
1103
  ) }),
1153
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Shape", children: /* @__PURE__ */ jsxRuntime.jsx(
1104
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Shape", htmlFor: "pp-btn-shape", children: /* @__PURE__ */ jsxRuntime.jsx(
1154
1105
  "select",
1155
1106
  {
1107
+ id: "pp-btn-shape",
1156
1108
  value: form.buttonShape,
1157
1109
  onChange: (e) => setForm((p) => ({ ...p, buttonShape: e.target.value })),
1158
1110
  className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive",
1159
1111
  children: SHAPE_OPTIONS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
1160
1112
  }
1161
1113
  ) }),
1162
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Width", children: /* @__PURE__ */ jsxRuntime.jsx(
1114
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Width", htmlFor: "pp-btn-width", children: /* @__PURE__ */ jsxRuntime.jsx(
1163
1115
  "select",
1164
1116
  {
1117
+ id: "pp-btn-width",
1165
1118
  value: form.buttonWidth,
1166
1119
  onChange: (e) => setForm((p) => ({ ...p, buttonWidth: e.target.value })),
1167
1120
  className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive",
1168
1121
  children: WIDTH_OPTIONS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
1169
1122
  }
1170
1123
  ) }),
1171
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Height", children: /* @__PURE__ */ jsxRuntime.jsx(
1124
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Height", htmlFor: "pp-btn-height", children: /* @__PURE__ */ jsxRuntime.jsx(
1172
1125
  "select",
1173
1126
  {
1127
+ id: "pp-btn-height",
1174
1128
  value: String(form.buttonHeight),
1175
1129
  onChange: (e) => setForm((p) => ({ ...p, buttonHeight: Number(e.target.value) })),
1176
1130
  className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive",
@@ -1180,9 +1134,10 @@ function PayPalSettingsTab() {
1180
1134
  ] }, h))
1181
1135
  }
1182
1136
  ) }),
1183
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Label", children: /* @__PURE__ */ jsxRuntime.jsx(
1137
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Button Label", htmlFor: "pp-btn-label", children: /* @__PURE__ */ jsxRuntime.jsx(
1184
1138
  "select",
1185
1139
  {
1140
+ id: "pp-btn-label",
1186
1141
  value: form.buttonLabel,
1187
1142
  onChange: (e) => setForm((p) => ({ ...p, buttonLabel: e.target.value })),
1188
1143
  className: "w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive",
@@ -1201,10 +1156,6 @@ const routeModule = {
1201
1156
  Component: PayPalSettingsIndexRoute,
1202
1157
  path: "/settings/paypal"
1203
1158
  },
1204
- {
1205
- Component: AdvancedCardPaymentsTab,
1206
- path: "/settings/paypal/advanced-card-payments"
1207
- },
1208
1159
  {
1209
1160
  Component: AdditionalSettingsTab,
1210
1161
  path: "/settings/paypal/additional-settings"
@@ -1214,13 +1165,17 @@ const routeModule = {
1214
1165
  path: "/settings/paypal/apple-pay"
1215
1166
  },
1216
1167
  {
1217
- Component: PayPalConnectionPage,
1218
- path: "/settings/paypal/connection"
1168
+ Component: AdvancedCardPaymentsTab,
1169
+ path: "/settings/paypal/advanced-card-payments"
1219
1170
  },
1220
1171
  {
1221
1172
  Component: PayPalGooglePayPage,
1222
1173
  path: "/settings/paypal/google-pay"
1223
1174
  },
1175
+ {
1176
+ Component: PayPalConnectionPage,
1177
+ path: "/settings/paypal/connection"
1178
+ },
1224
1179
  {
1225
1180
  Component: PayPalPayLaterMessagingPage,
1226
1181
  path: "/settings/paypal/pay-later-messaging"