@easypayment/medusa-paypal 0.3.7 → 0.3.9

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.
@@ -217,32 +217,21 @@ async function adminFetch$1(path, opts = {}) {
217
217
  return {};
218
218
  }
219
219
  }
220
- const DEFAULT_FORM = { enabled: true, title: "Credit or Debit Card", disabledCards: [], threeDS: "when_required" };
220
+ const DEFAULT_FORM = {
221
+ enabled: true,
222
+ title: "Credit or Debit Card",
223
+ threeDS: "when_required"
224
+ };
221
225
  function mergeWithDefaults(saved) {
222
226
  if (!saved) return { ...DEFAULT_FORM };
223
227
  const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
224
228
  return { ...DEFAULT_FORM, ...Object.fromEntries(entries) };
225
229
  }
226
- const CARD_BRANDS = [
227
- { value: "visa", label: "Visa" },
228
- { value: "mastercard", label: "Mastercard" },
229
- { value: "amex", label: "American Express" },
230
- { value: "discover", label: "Discover" },
231
- { value: "diners", label: "Diners Club" },
232
- { value: "jcb", label: "JCB" },
233
- { value: "unionpay", label: "UnionPay" }
234
- ];
235
230
  const THREE_DS_OPTIONS = [
236
231
  { value: "when_required", label: "3D Secure when required", hint: "Triggers 3DS only when the card / issuer requires it." },
237
232
  { value: "sli", label: "3D Secure (SCA) / liability shift (recommended)", hint: "Attempts to optimize for liability shift while remaining compliant." },
238
233
  { value: "always", label: "Always request 3D Secure", hint: "Forces 3DS challenge whenever possible (may reduce conversion)." }
239
234
  ];
240
- function Pill$1({ children, onRemove }) {
241
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 rounded-md border border-ui-border-base bg-ui-bg-base px-2 py-1 text-sm text-ui-fg-base", children: [
242
- children,
243
- onRemove ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onRemove, className: "ml-1 rounded px-1 text-ui-fg-subtle hover:text-ui-fg-base", "aria-label": "Remove", children: "x" }) : null
244
- ] });
245
- }
246
235
  function SectionCard$1({ title, description, right, children }) {
247
236
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
248
237
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
@@ -290,7 +279,10 @@ function AdvancedCardPaymentsTab() {
290
279
  async function onSave() {
291
280
  try {
292
281
  setSaving(true);
293
- const json = await adminFetch$1("/admin/paypal/settings", { method: "POST", body: { advanced_card_payments: form } });
282
+ const json = await adminFetch$1("/admin/paypal/settings", {
283
+ method: "POST",
284
+ body: { advanced_card_payments: form }
285
+ });
294
286
  const payload = (json == null ? void 0 : json.data) ?? json;
295
287
  const saved = payload == null ? void 0 : payload.advanced_card_payments;
296
288
  if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved));
@@ -303,16 +295,6 @@ function AdvancedCardPaymentsTab() {
303
295
  setSaving(false);
304
296
  }
305
297
  }
306
- const disabledSet = react.useMemo(() => new Set(form.disabledCards), [form.disabledCards]);
307
- function toggleDisabledCard(value) {
308
- setForm((prev) => {
309
- const exists = prev.disabledCards.includes(value);
310
- return { ...prev, disabledCards: exists ? prev.disabledCards.filter((v) => v !== value) : [...prev.disabledCards, value] };
311
- });
312
- }
313
- function removeDisabledCard(value) {
314
- setForm((prev) => ({ ...prev, disabledCards: prev.disabledCards.filter((v) => v !== value) }));
315
- }
316
298
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
317
299
  /* @__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" }) }) }),
318
300
  /* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
@@ -332,16 +314,6 @@ function AdvancedCardPaymentsTab() {
332
314
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable Advanced Credit/Debit Card" })
333
315
  ] }) }),
334
316
  /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { 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" }) }),
335
- /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Disable specific credit cards", hint: "Select card brands to hide from the card form.", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
336
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: form.disabledCards.length ? form.disabledCards.map((v) => {
337
- var _a2;
338
- return /* @__PURE__ */ jsxRuntime.jsx(Pill$1, { onRemove: () => removeDisabledCard(v), children: ((_a2 = CARD_BRANDS.find((b) => b.value === v)) == null ? void 0 : _a2.label) ?? v }, v);
339
- }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "No card brands disabled." }) }),
340
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base p-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-2 md:grid-cols-2", children: CARD_BRANDS.map((b) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 rounded-md p-2 hover:bg-ui-bg-subtle", children: [
341
- /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", checked: disabledSet.has(b.value), onChange: () => toggleDisabledCard(b.value), className: "h-4 w-4 rounded border-ui-border-base" }),
342
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: b.label })
343
- ] }, b.value)) }) })
344
- ] }) }),
345
317
  /* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { 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: [
346
318
  /* @__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)) }),
347
319
  ((_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
@@ -935,10 +907,10 @@ function PayPalConnectionPage() {
935
907
  ` })
936
908
  ] });
937
909
  }
938
- function PayPalGooglePayPage() {
910
+ function PayPalApplePayPage() {
939
911
  return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
940
912
  }
941
- function PayPalApplePayPage() {
913
+ function PayPalGooglePayPage() {
942
914
  return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
943
915
  }
944
916
  function PayPalPayLaterMessagingPage() {
@@ -1355,14 +1327,14 @@ const routeModule = {
1355
1327
  Component: PayPalConnectionPage,
1356
1328
  path: "/settings/paypal/connection"
1357
1329
  },
1358
- {
1359
- Component: PayPalGooglePayPage,
1360
- path: "/settings/paypal/google-pay"
1361
- },
1362
1330
  {
1363
1331
  Component: PayPalApplePayPage,
1364
1332
  path: "/settings/paypal/apple-pay"
1365
1333
  },
1334
+ {
1335
+ Component: PayPalGooglePayPage,
1336
+ path: "/settings/paypal/google-pay"
1337
+ },
1366
1338
  {
1367
1339
  Component: PayPalPayLaterMessagingPage,
1368
1340
  path: "/settings/paypal/pay-later-messaging"
@@ -216,32 +216,21 @@ async function adminFetch$1(path, opts = {}) {
216
216
  return {};
217
217
  }
218
218
  }
219
- const DEFAULT_FORM = { enabled: true, title: "Credit or Debit Card", disabledCards: [], threeDS: "when_required" };
219
+ const DEFAULT_FORM = {
220
+ enabled: true,
221
+ title: "Credit or Debit Card",
222
+ threeDS: "when_required"
223
+ };
220
224
  function mergeWithDefaults(saved) {
221
225
  if (!saved) return { ...DEFAULT_FORM };
222
226
  const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
223
227
  return { ...DEFAULT_FORM, ...Object.fromEntries(entries) };
224
228
  }
225
- const CARD_BRANDS = [
226
- { value: "visa", label: "Visa" },
227
- { value: "mastercard", label: "Mastercard" },
228
- { value: "amex", label: "American Express" },
229
- { value: "discover", label: "Discover" },
230
- { value: "diners", label: "Diners Club" },
231
- { value: "jcb", label: "JCB" },
232
- { value: "unionpay", label: "UnionPay" }
233
- ];
234
229
  const THREE_DS_OPTIONS = [
235
230
  { value: "when_required", label: "3D Secure when required", hint: "Triggers 3DS only when the card / issuer requires it." },
236
231
  { value: "sli", label: "3D Secure (SCA) / liability shift (recommended)", hint: "Attempts to optimize for liability shift while remaining compliant." },
237
232
  { value: "always", label: "Always request 3D Secure", hint: "Forces 3DS challenge whenever possible (may reduce conversion)." }
238
233
  ];
239
- function Pill$1({ children, onRemove }) {
240
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-md border border-ui-border-base bg-ui-bg-base px-2 py-1 text-sm text-ui-fg-base", children: [
241
- children,
242
- onRemove ? /* @__PURE__ */ jsx("button", { type: "button", onClick: onRemove, className: "ml-1 rounded px-1 text-ui-fg-subtle hover:text-ui-fg-base", "aria-label": "Remove", children: "x" }) : null
243
- ] });
244
- }
245
234
  function SectionCard$1({ title, description, right, children }) {
246
235
  return /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
247
236
  /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
@@ -289,7 +278,10 @@ function AdvancedCardPaymentsTab() {
289
278
  async function onSave() {
290
279
  try {
291
280
  setSaving(true);
292
- const json = await adminFetch$1("/admin/paypal/settings", { method: "POST", body: { advanced_card_payments: form } });
281
+ const json = await adminFetch$1("/admin/paypal/settings", {
282
+ method: "POST",
283
+ body: { advanced_card_payments: form }
284
+ });
293
285
  const payload = (json == null ? void 0 : json.data) ?? json;
294
286
  const saved = payload == null ? void 0 : payload.advanced_card_payments;
295
287
  if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved));
@@ -302,16 +294,6 @@ function AdvancedCardPaymentsTab() {
302
294
  setSaving(false);
303
295
  }
304
296
  }
305
- const disabledSet = useMemo(() => new Set(form.disabledCards), [form.disabledCards]);
306
- function toggleDisabledCard(value) {
307
- setForm((prev) => {
308
- const exists = prev.disabledCards.includes(value);
309
- return { ...prev, disabledCards: exists ? prev.disabledCards.filter((v) => v !== value) : [...prev.disabledCards, value] };
310
- });
311
- }
312
- function removeDisabledCard(value) {
313
- setForm((prev) => ({ ...prev, disabledCards: prev.disabledCards.filter((v) => v !== value) }));
314
- }
315
297
  return /* @__PURE__ */ jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
316
298
  /* @__PURE__ */ jsx("div", { className: "flex items-start justify-between gap-4", children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold text-ui-fg-base", children: "PayPal Gateway By Easy Payment" }) }) }),
317
299
  /* @__PURE__ */ jsx(PayPalTabs, {}),
@@ -331,16 +313,6 @@ function AdvancedCardPaymentsTab() {
331
313
  /* @__PURE__ */ jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable Advanced Credit/Debit Card" })
332
314
  ] }) }),
333
315
  /* @__PURE__ */ jsx(FieldRow$1, { label: "Title", children: /* @__PURE__ */ 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" }) }),
334
- /* @__PURE__ */ jsx(FieldRow$1, { label: "Disable specific credit cards", hint: "Select card brands to hide from the card form.", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
335
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: form.disabledCards.length ? form.disabledCards.map((v) => {
336
- var _a2;
337
- return /* @__PURE__ */ jsx(Pill$1, { onRemove: () => removeDisabledCard(v), children: ((_a2 = CARD_BRANDS.find((b) => b.value === v)) == null ? void 0 : _a2.label) ?? v }, v);
338
- }) : /* @__PURE__ */ jsx("span", { className: "text-sm text-ui-fg-subtle", children: "No card brands disabled." }) }),
339
- /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base p-3", children: /* @__PURE__ */ jsx("div", { className: "grid gap-2 md:grid-cols-2", children: CARD_BRANDS.map((b) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 rounded-md p-2 hover:bg-ui-bg-subtle", children: [
340
- /* @__PURE__ */ jsx("input", { type: "checkbox", checked: disabledSet.has(b.value), onChange: () => toggleDisabledCard(b.value), className: "h-4 w-4 rounded border-ui-border-base" }),
341
- /* @__PURE__ */ jsx("span", { className: "text-sm text-ui-fg-base", children: b.label })
342
- ] }, b.value)) }) })
343
- ] }) }),
344
316
  /* @__PURE__ */ jsx(FieldRow$1, { label: "Contingency for 3D Secure", hint: "Choose when 3D Secure should be triggered during card payments.", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
345
317
  /* @__PURE__ */ 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__ */ jsx("option", { value: o.value, children: o.label }, o.value)) }),
346
318
  ((_a = THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)) == null ? void 0 : _a.hint) ? /* @__PURE__ */ 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
@@ -934,10 +906,10 @@ function PayPalConnectionPage() {
934
906
  ` })
935
907
  ] });
936
908
  }
937
- function PayPalGooglePayPage() {
909
+ function PayPalApplePayPage() {
938
910
  return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
939
911
  }
940
- function PayPalApplePayPage() {
912
+ function PayPalGooglePayPage() {
941
913
  return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
942
914
  }
943
915
  function PayPalPayLaterMessagingPage() {
@@ -1354,14 +1326,14 @@ const routeModule = {
1354
1326
  Component: PayPalConnectionPage,
1355
1327
  path: "/settings/paypal/connection"
1356
1328
  },
1357
- {
1358
- Component: PayPalGooglePayPage,
1359
- path: "/settings/paypal/google-pay"
1360
- },
1361
1329
  {
1362
1330
  Component: PayPalApplePayPage,
1363
1331
  path: "/settings/paypal/apple-pay"
1364
1332
  },
1333
+ {
1334
+ Component: PayPalGooglePayPage,
1335
+ path: "/settings/paypal/google-pay"
1336
+ },
1365
1337
  {
1366
1338
  Component: PayPalPayLaterMessagingPage,
1367
1339
  path: "/settings/paypal/pay-later-messaging"
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/config/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAQ7E,wBAAsB,GAAG,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,2BA0FhE"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/config/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAQ7E,wBAAsB,GAAG,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,2BAkGhE"}
@@ -47,11 +47,14 @@ async function GET(req, res) {
47
47
  const disableButtons = Array.isArray(paypalSettings.disableButtons)
48
48
  ? paypalSettings.disableButtons.filter((value) => typeof value === "string")
49
49
  : [];
50
- // P2 — read advanced card payments enabled setting
50
+ // P2 — read advanced card payments settings
51
51
  const advancedCardSettings = data && typeof data === "object"
52
52
  ? (data.advanced_card_payments || {})
53
53
  : {};
54
54
  const cardEnabled = advancedCardSettings.enabled !== false;
55
+ const cardThreeDS = typeof advancedCardSettings.threeDS === "string"
56
+ ? advancedCardSettings.threeDS
57
+ : "when_required";
55
58
  return res.json({
56
59
  environment: creds.environment,
57
60
  client_id: creds.client_id,
@@ -63,10 +66,12 @@ async function GET(req, res) {
63
66
  intent: paymentAction,
64
67
  paypal_enabled: paypalSettings.enabled ?? true,
65
68
  paypal_title: paypalSettings.title || "PayPal",
66
- card_enabled: cardEnabled, // P2
69
+ card_enabled: cardEnabled,
70
+ card_title: advancedCardSettings.title || "Credit or Debit Card",
71
+ card_three_ds: cardThreeDS, // ← added
67
72
  button_color: paypalSettings.buttonColor || "gold",
68
73
  button_shape: paypalSettings.buttonShape || "rect",
69
- button_width: paypalSettings.buttonWidth || "auto",
74
+ button_width: paypalSettings.buttonWidth || "responsive",
70
75
  button_height: paypalSettings.buttonHeight ?? 45,
71
76
  button_label: paypalSettings.buttonLabel || "paypal",
72
77
  disable_buttons: disableButtons,
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/config/route.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/config/route.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easypayment/medusa-paypal",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "Industry-standard PayPal integration for Medusa v2",
5
5
  "license": "MIT",
6
6
  "main": "./.medusa/server/src/index.js",
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useRef, useState } from "react"
1
+ import React, { useEffect, useRef, useState } from "react"
2
2
  import PayPalTabs from "../_components/Tabs"
3
3
 
4
4
  type AdminFetchOptions = {
@@ -34,17 +34,19 @@ async function adminFetch<T = unknown>(path: string, opts: AdminFetchOptions = {
34
34
  try { return JSON.parse(text) as T } catch { return {} as T }
35
35
  }
36
36
 
37
- type DisabledCardBrand = "visa" | "mastercard" | "amex" | "discover" | "diners" | "jcb" | "unionpay"
38
37
  type ThreeDSContingency = "sli" | "when_required" | "always"
39
38
 
40
39
  type AdvancedCardPaymentsForm = {
41
40
  enabled: boolean
42
41
  title: string
43
- disabledCards: DisabledCardBrand[]
44
42
  threeDS: ThreeDSContingency
45
43
  }
46
44
 
47
- const DEFAULT_FORM: AdvancedCardPaymentsForm = { enabled: true, title: "Credit or Debit Card", disabledCards: [], threeDS: "when_required" }
45
+ const DEFAULT_FORM: AdvancedCardPaymentsForm = {
46
+ enabled: true,
47
+ title: "Credit or Debit Card",
48
+ threeDS: "when_required",
49
+ }
48
50
 
49
51
  function mergeWithDefaults(saved?: Partial<AdvancedCardPaymentsForm> | null) {
50
52
  if (!saved) return { ...DEFAULT_FORM }
@@ -52,27 +54,12 @@ function mergeWithDefaults(saved?: Partial<AdvancedCardPaymentsForm> | null) {
52
54
  return { ...DEFAULT_FORM, ...(Object.fromEntries(entries) as Partial<AdvancedCardPaymentsForm>) }
53
55
  }
54
56
 
55
- const CARD_BRANDS: { value: DisabledCardBrand; label: string }[] = [
56
- { value: "visa", label: "Visa" }, { value: "mastercard", label: "Mastercard" },
57
- { value: "amex", label: "American Express" }, { value: "discover", label: "Discover" },
58
- { value: "diners", label: "Diners Club" }, { value: "jcb", label: "JCB" }, { value: "unionpay", label: "UnionPay" },
59
- ]
60
-
61
57
  const THREE_DS_OPTIONS: { value: ThreeDSContingency; label: string; hint?: string }[] = [
62
58
  { value: "when_required", label: "3D Secure when required", hint: "Triggers 3DS only when the card / issuer requires it." },
63
59
  { value: "sli", label: "3D Secure (SCA) / liability shift (recommended)", hint: "Attempts to optimize for liability shift while remaining compliant." },
64
60
  { value: "always", label: "Always request 3D Secure", hint: "Forces 3DS challenge whenever possible (may reduce conversion)." },
65
61
  ]
66
62
 
67
- function Pill({ children, onRemove }: { children: React.ReactNode; onRemove?: () => void }) {
68
- return (
69
- <span className="inline-flex items-center gap-1 rounded-md border border-ui-border-base bg-ui-bg-base px-2 py-1 text-sm text-ui-fg-base">
70
- {children}
71
- {onRemove ? <button type="button" onClick={onRemove} className="ml-1 rounded px-1 text-ui-fg-subtle hover:text-ui-fg-base" aria-label="Remove">x</button> : null}
72
- </span>
73
- )
74
- }
75
-
76
63
  function SectionCard({ title, description, right, children }: { title: string; description?: string; right?: React.ReactNode; children: React.ReactNode }) {
77
64
  return (
78
65
  <div className="rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm">
@@ -128,7 +115,10 @@ export default function AdvancedCardPaymentsTab() {
128
115
  async function onSave() {
129
116
  try {
130
117
  setSaving(true)
131
- const json = await adminFetch<any>("/admin/paypal/settings", { method: "POST", body: { advanced_card_payments: form as unknown as Record<string, unknown> } })
118
+ const json = await adminFetch<any>("/admin/paypal/settings", {
119
+ method: "POST",
120
+ body: { advanced_card_payments: form as unknown as Record<string, unknown> },
121
+ })
132
122
  const payload = json?.data ?? json
133
123
  const saved = payload?.advanced_card_payments
134
124
  if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved))
@@ -142,19 +132,6 @@ export default function AdvancedCardPaymentsTab() {
142
132
  }
143
133
  }
144
134
 
145
- const disabledSet = useMemo(() => new Set(form.disabledCards), [form.disabledCards])
146
-
147
- function toggleDisabledCard(value: DisabledCardBrand) {
148
- setForm((prev) => {
149
- const exists = prev.disabledCards.includes(value)
150
- return { ...prev, disabledCards: exists ? prev.disabledCards.filter((v) => v !== value) : [...prev.disabledCards, value] }
151
- })
152
- }
153
-
154
- function removeDisabledCard(value: DisabledCardBrand) {
155
- setForm((prev) => ({ ...prev, disabledCards: prev.disabledCards.filter((v) => v !== value) }))
156
- }
157
-
158
135
  return (
159
136
  <div className="p-6">
160
137
  <div className="flex flex-col gap-6">
@@ -167,7 +144,9 @@ export default function AdvancedCardPaymentsTab() {
167
144
  <span className={toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error"}>{toast.message}</span>
168
145
  </div>
169
146
  ) : null}
170
- <SectionCard title="Advanced Card Payments" description="Control card checkout settings and 3D Secure behavior."
147
+ <SectionCard
148
+ title="Advanced Card Payments"
149
+ description="Control card checkout settings and 3D Secure behavior."
171
150
  right={(
172
151
  <div className="flex items-center gap-3">
173
152
  <button type="button" onClick={onSave} disabled={saving || loading} className="rounded-md bg-ui-button-neutral px-4 py-2 text-sm font-medium text-ui-fg-on-color shadow-sm hover:opacity-90 disabled:opacity-60">
@@ -187,29 +166,14 @@ export default function AdvancedCardPaymentsTab() {
187
166
  <FieldRow label="Title">
188
167
  <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" />
189
168
  </FieldRow>
190
- <FieldRow label="Disable specific credit cards" hint="Select card brands to hide from the card form.">
191
- <div className="flex flex-col gap-2">
192
- <div className="flex flex-wrap gap-2">
193
- {form.disabledCards.length ? form.disabledCards.map((v) => <Pill key={v} onRemove={() => removeDisabledCard(v)}>{CARD_BRANDS.find((b) => b.value === v)?.label ?? v}</Pill>) : <span className="text-sm text-ui-fg-subtle">No card brands disabled.</span>}
194
- </div>
195
- <div className="rounded-md border border-ui-border-base p-3">
196
- <div className="grid gap-2 md:grid-cols-2">
197
- {CARD_BRANDS.map((b) => (
198
- <label key={b.value} className="flex items-center gap-2 rounded-md p-2 hover:bg-ui-bg-subtle">
199
- <input type="checkbox" checked={disabledSet.has(b.value)} onChange={() => toggleDisabledCard(b.value)} className="h-4 w-4 rounded border-ui-border-base" />
200
- <span className="text-sm text-ui-fg-base">{b.label}</span>
201
- </label>
202
- ))}
203
- </div>
204
- </div>
205
- </div>
206
- </FieldRow>
207
169
  <FieldRow label="Contingency for 3D Secure" hint="Choose when 3D Secure should be triggered during card payments.">
208
170
  <div className="flex flex-col gap-2">
209
171
  <select value={form.threeDS} onChange={(e) => setForm((p) => ({ ...p, threeDS: e.target.value as ThreeDSContingency }))} 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">
210
172
  {THREE_DS_OPTIONS.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
211
173
  </select>
212
- {THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)?.hint ? <div className="text-xs text-ui-fg-subtle">{THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)?.hint}</div> : null}
174
+ {THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)?.hint
175
+ ? <div className="text-xs text-ui-fg-subtle">{THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)?.hint}</div>
176
+ : null}
213
177
  </div>
214
178
  </FieldRow>
215
179
  </div>
@@ -217,4 +181,4 @@ export default function AdvancedCardPaymentsTab() {
217
181
  </div>
218
182
  </div>
219
183
  )
220
- }
184
+ }
@@ -67,13 +67,19 @@ export async function GET(req: MedusaRequest, res: MedusaResponse) {
67
67
  ? paypalSettings.disableButtons.filter((value: unknown): value is string => typeof value === "string")
68
68
  : []
69
69
 
70
- // P2 — read advanced card payments enabled setting
70
+ // P2 — read advanced card payments settings
71
71
  const advancedCardSettings =
72
72
  data && typeof data === "object"
73
73
  ? ((data as Record<string, any>).advanced_card_payments || {})
74
74
  : {}
75
+
75
76
  const cardEnabled: boolean = advancedCardSettings.enabled !== false
76
77
 
78
+ const cardThreeDS =
79
+ typeof advancedCardSettings.threeDS === "string"
80
+ ? advancedCardSettings.threeDS
81
+ : "when_required"
82
+
77
83
  return res.json({
78
84
  environment: creds.environment,
79
85
  client_id: creds.client_id,
@@ -85,10 +91,12 @@ export async function GET(req: MedusaRequest, res: MedusaResponse) {
85
91
  intent: paymentAction,
86
92
  paypal_enabled: paypalSettings.enabled ?? true,
87
93
  paypal_title: paypalSettings.title || "PayPal",
88
- card_enabled: cardEnabled, // P2
94
+ card_enabled: cardEnabled,
95
+ card_title: advancedCardSettings.title || "Credit or Debit Card",
96
+ card_three_ds: cardThreeDS, // ← added
89
97
  button_color: paypalSettings.buttonColor || "gold",
90
98
  button_shape: paypalSettings.buttonShape || "rect",
91
- button_width: paypalSettings.buttonWidth || "auto",
99
+ button_width: paypalSettings.buttonWidth || "responsive",
92
100
  button_height: paypalSettings.buttonHeight ?? 45,
93
101
  button_label: paypalSettings.buttonLabel || "paypal",
94
102
  disable_buttons: disableButtons,
@@ -96,4 +104,4 @@ export async function GET(req: MedusaRequest, res: MedusaResponse) {
96
104
  } catch (e: any) {
97
105
  return res.status(500).json({ message: e?.message || "Failed to load PayPal config" })
98
106
  }
99
- }
107
+ }