@easypayment/medusa-payment-paypal 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/admin/index.js +316 -316
- package/.medusa/server/src/admin/index.mjs +317 -317
- package/package.json +1 -1
|
@@ -9,6 +9,9 @@ const config$1 = adminSdk.defineRouteConfig({
|
|
|
9
9
|
const PayPalSettingsIndexRoute = () => {
|
|
10
10
|
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "connection", replace: true });
|
|
11
11
|
};
|
|
12
|
+
function PayPalApplePayPage() {
|
|
13
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
14
|
+
}
|
|
12
15
|
const BASE = "/settings/paypal";
|
|
13
16
|
const TABS = [
|
|
14
17
|
{ label: "PayPal Connection", to: `${BASE}/connection` },
|
|
@@ -34,297 +37,6 @@ function PayPalTabs() {
|
|
|
34
37
|
);
|
|
35
38
|
}) }) });
|
|
36
39
|
}
|
|
37
|
-
async function adminFetch$2(path, opts = {}) {
|
|
38
|
-
var _a;
|
|
39
|
-
const { method = "GET", body, query } = opts;
|
|
40
|
-
let url = path;
|
|
41
|
-
if (query && Object.keys(query).length > 0) {
|
|
42
|
-
const params = new URLSearchParams(query);
|
|
43
|
-
url = `${path}?${params.toString()}`;
|
|
44
|
-
}
|
|
45
|
-
const headers = { Accept: "application/json" };
|
|
46
|
-
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
47
|
-
if (typeof window !== "undefined") {
|
|
48
|
-
const token = (_a = window.__medusa__) == null ? void 0 : _a.token;
|
|
49
|
-
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
50
|
-
}
|
|
51
|
-
const res = await fetch(url, {
|
|
52
|
-
method,
|
|
53
|
-
headers,
|
|
54
|
-
credentials: "include",
|
|
55
|
-
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
56
|
-
});
|
|
57
|
-
const text = await res.text().catch(() => "");
|
|
58
|
-
if (!res.ok) {
|
|
59
|
-
if (res.status === 401) throw new Error("Unauthorized (401) - session may have expired. Please reload and log in again.");
|
|
60
|
-
if (res.status === 403) throw new Error("Forbidden (403) - you do not have permission to perform this action.");
|
|
61
|
-
throw new Error(text || `Request failed with status ${res.status}`);
|
|
62
|
-
}
|
|
63
|
-
if (!text) return {};
|
|
64
|
-
try {
|
|
65
|
-
return JSON.parse(text);
|
|
66
|
-
} catch {
|
|
67
|
-
return {};
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
const DEFAULT_FORM$1 = {
|
|
71
|
-
paymentAction: "capture",
|
|
72
|
-
brandName: "PayPal",
|
|
73
|
-
landingPage: "no_preference",
|
|
74
|
-
requireInstantPayment: false,
|
|
75
|
-
sendItemDetails: true,
|
|
76
|
-
invoicePrefix: "WC-",
|
|
77
|
-
creditCardStatementName: "PayPal"
|
|
78
|
-
};
|
|
79
|
-
function mergeWithDefaults$1(saved) {
|
|
80
|
-
if (!saved) return { ...DEFAULT_FORM$1 };
|
|
81
|
-
const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
|
|
82
|
-
return { ...DEFAULT_FORM$1, ...Object.fromEntries(entries) };
|
|
83
|
-
}
|
|
84
|
-
function SectionCard$2({ title, description, right, children }) {
|
|
85
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
86
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
|
|
87
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
88
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
|
|
89
|
-
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
|
|
90
|
-
] }),
|
|
91
|
-
right
|
|
92
|
-
] }),
|
|
93
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
|
|
94
|
-
] });
|
|
95
|
-
}
|
|
96
|
-
function FieldRow$2({ label, hint, children }) {
|
|
97
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
|
|
98
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
|
|
99
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
|
|
100
|
-
hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
|
|
101
|
-
] }),
|
|
102
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
|
|
103
|
-
] });
|
|
104
|
-
}
|
|
105
|
-
function AdditionalSettingsTab() {
|
|
106
|
-
const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM$1 }));
|
|
107
|
-
const [loading, setLoading] = react.useState(false);
|
|
108
|
-
const [saving, setSaving] = react.useState(false);
|
|
109
|
-
const [toast, setToast] = react.useState(null);
|
|
110
|
-
const didInit = react.useRef(false);
|
|
111
|
-
react.useEffect(() => {
|
|
112
|
-
if (didInit.current) return;
|
|
113
|
-
didInit.current = true;
|
|
114
|
-
(async () => {
|
|
115
|
-
try {
|
|
116
|
-
setLoading(true);
|
|
117
|
-
const json = await adminFetch$2("/admin/paypal/settings");
|
|
118
|
-
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
119
|
-
const saved = payload == null ? void 0 : payload.additional_settings;
|
|
120
|
-
if (saved && typeof saved === "object") setForm(mergeWithDefaults$1(saved));
|
|
121
|
-
} catch {
|
|
122
|
-
} finally {
|
|
123
|
-
setLoading(false);
|
|
124
|
-
}
|
|
125
|
-
})();
|
|
126
|
-
}, []);
|
|
127
|
-
async function onSave() {
|
|
128
|
-
try {
|
|
129
|
-
setSaving(true);
|
|
130
|
-
setToast(null);
|
|
131
|
-
const json = await adminFetch$2("/admin/paypal/settings", { method: "POST", body: { additional_settings: form } });
|
|
132
|
-
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
133
|
-
const saved = payload == null ? void 0 : payload.additional_settings;
|
|
134
|
-
if (saved && typeof saved === "object") setForm(mergeWithDefaults$1(saved));
|
|
135
|
-
setToast({ type: "success", message: "Settings saved" });
|
|
136
|
-
window.setTimeout(() => setToast(null), 2500);
|
|
137
|
-
} catch (e) {
|
|
138
|
-
setToast({ type: "error", message: e instanceof Error ? e.message : "Failed to save settings" });
|
|
139
|
-
window.setTimeout(() => setToast(null), 3500);
|
|
140
|
-
} finally {
|
|
141
|
-
setSaving(false);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
145
|
-
/* @__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" }) }) }),
|
|
146
|
-
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
147
|
-
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,
|
|
148
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
149
|
-
SectionCard$2,
|
|
150
|
-
{
|
|
151
|
-
title: "Additional Settings",
|
|
152
|
-
description: "These settings control checkout behavior and PayPal experience.",
|
|
153
|
-
right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
154
|
-
/* @__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" }),
|
|
155
|
-
loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading..." }) : null
|
|
156
|
-
] }),
|
|
157
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
|
|
158
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { 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: [
|
|
159
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "capture", children: "Capture" }),
|
|
160
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorize", children: "Authorize" })
|
|
161
|
-
] }) }),
|
|
162
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { 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" }) }),
|
|
163
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { 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: [
|
|
164
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "no_preference", children: "No Preference" }),
|
|
165
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "login", children: "Login" }),
|
|
166
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "billing", children: "Billing" })
|
|
167
|
-
] }) }),
|
|
168
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Instant Payments", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
169
|
-
/* @__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" }),
|
|
170
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Require Instant Payment" })
|
|
171
|
-
] }) }),
|
|
172
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { 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: [
|
|
173
|
-
/* @__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" }),
|
|
174
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Send line item details to PayPal" })
|
|
175
|
-
] }) }),
|
|
176
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { 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-" }) }),
|
|
177
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { 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" }) })
|
|
178
|
-
] })
|
|
179
|
-
}
|
|
180
|
-
)
|
|
181
|
-
] }) });
|
|
182
|
-
}
|
|
183
|
-
function PayPalApplePayPage() {
|
|
184
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
185
|
-
}
|
|
186
|
-
function PayPalGooglePayPage() {
|
|
187
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
188
|
-
}
|
|
189
|
-
async function adminFetch$1(path, opts = {}) {
|
|
190
|
-
var _a;
|
|
191
|
-
const { method = "GET", body, query } = opts;
|
|
192
|
-
let url = path;
|
|
193
|
-
if (query && Object.keys(query).length > 0) {
|
|
194
|
-
const params = new URLSearchParams(query);
|
|
195
|
-
url = `${path}?${params.toString()}`;
|
|
196
|
-
}
|
|
197
|
-
const headers = { Accept: "application/json" };
|
|
198
|
-
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
199
|
-
if (typeof window !== "undefined") {
|
|
200
|
-
const token = (_a = window.__medusa__) == null ? void 0 : _a.token;
|
|
201
|
-
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
202
|
-
}
|
|
203
|
-
const res = await fetch(url, {
|
|
204
|
-
method,
|
|
205
|
-
headers,
|
|
206
|
-
credentials: "include",
|
|
207
|
-
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
208
|
-
});
|
|
209
|
-
const text = await res.text().catch(() => "");
|
|
210
|
-
if (!res.ok) {
|
|
211
|
-
if (res.status === 401) throw new Error("Unauthorized (401) - session may have expired. Please reload and log in again.");
|
|
212
|
-
if (res.status === 403) throw new Error("Forbidden (403) - you do not have permission to perform this action.");
|
|
213
|
-
throw new Error(text || `Request failed with status ${res.status}`);
|
|
214
|
-
}
|
|
215
|
-
if (!text) return {};
|
|
216
|
-
try {
|
|
217
|
-
return JSON.parse(text);
|
|
218
|
-
} catch {
|
|
219
|
-
return {};
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
const DEFAULT_FORM = {
|
|
223
|
-
enabled: true,
|
|
224
|
-
title: "Credit or Debit Card",
|
|
225
|
-
threeDS: "when_required"
|
|
226
|
-
};
|
|
227
|
-
function mergeWithDefaults(saved) {
|
|
228
|
-
if (!saved) return { ...DEFAULT_FORM };
|
|
229
|
-
const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
|
|
230
|
-
return { ...DEFAULT_FORM, ...Object.fromEntries(entries) };
|
|
231
|
-
}
|
|
232
|
-
const THREE_DS_OPTIONS = [
|
|
233
|
-
{ value: "when_required", label: "3D Secure when required", hint: "Triggers 3DS only when the card / issuer requires it." },
|
|
234
|
-
{ value: "sli", label: "3D Secure (SCA) / liability shift (recommended)", hint: "Attempts to optimize for liability shift while remaining compliant." },
|
|
235
|
-
{ value: "always", label: "Always request 3D Secure", hint: "Forces 3DS challenge whenever possible (may reduce conversion)." }
|
|
236
|
-
];
|
|
237
|
-
function SectionCard$1({ title, description, right, children }) {
|
|
238
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
239
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
|
|
240
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
241
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
|
|
242
|
-
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
|
|
243
|
-
] }),
|
|
244
|
-
right
|
|
245
|
-
] }),
|
|
246
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
|
|
247
|
-
] });
|
|
248
|
-
}
|
|
249
|
-
function FieldRow$1({ label, hint, children }) {
|
|
250
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
|
|
251
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
|
|
252
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
|
|
253
|
-
hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
|
|
254
|
-
] }),
|
|
255
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
|
|
256
|
-
] });
|
|
257
|
-
}
|
|
258
|
-
function AdvancedCardPaymentsTab() {
|
|
259
|
-
var _a, _b;
|
|
260
|
-
const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM }));
|
|
261
|
-
const [loading, setLoading] = react.useState(false);
|
|
262
|
-
const [saving, setSaving] = react.useState(false);
|
|
263
|
-
const [toast, setToast] = react.useState(null);
|
|
264
|
-
const didInit = react.useRef(false);
|
|
265
|
-
react.useEffect(() => {
|
|
266
|
-
if (didInit.current) return;
|
|
267
|
-
didInit.current = true;
|
|
268
|
-
(async () => {
|
|
269
|
-
try {
|
|
270
|
-
setLoading(true);
|
|
271
|
-
const json = await adminFetch$1("/admin/paypal/settings");
|
|
272
|
-
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
273
|
-
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
274
|
-
if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved));
|
|
275
|
-
} catch {
|
|
276
|
-
} finally {
|
|
277
|
-
setLoading(false);
|
|
278
|
-
}
|
|
279
|
-
})();
|
|
280
|
-
}, []);
|
|
281
|
-
async function onSave() {
|
|
282
|
-
try {
|
|
283
|
-
setSaving(true);
|
|
284
|
-
const json = await adminFetch$1("/admin/paypal/settings", {
|
|
285
|
-
method: "POST",
|
|
286
|
-
body: { advanced_card_payments: form }
|
|
287
|
-
});
|
|
288
|
-
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
289
|
-
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
290
|
-
if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved));
|
|
291
|
-
setToast({ type: "success", message: "Settings saved" });
|
|
292
|
-
window.setTimeout(() => setToast(null), 2500);
|
|
293
|
-
} catch (e) {
|
|
294
|
-
setToast({ type: "error", message: (e instanceof Error ? e.message : "") || "Failed to save settings." });
|
|
295
|
-
window.setTimeout(() => setToast(null), 3500);
|
|
296
|
-
} finally {
|
|
297
|
-
setSaving(false);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
301
|
-
/* @__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" }) }) }),
|
|
302
|
-
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
303
|
-
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,
|
|
304
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
305
|
-
SectionCard$1,
|
|
306
|
-
{
|
|
307
|
-
title: "Advanced Card Payments",
|
|
308
|
-
description: "Control card checkout settings and 3D Secure behavior.",
|
|
309
|
-
right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
310
|
-
/* @__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" }),
|
|
311
|
-
loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading..." }) : null
|
|
312
|
-
] }),
|
|
313
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
|
|
314
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Enable/Disable", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
315
|
-
/* @__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" }),
|
|
316
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable Advanced Credit/Debit Card" })
|
|
317
|
-
] }) }),
|
|
318
|
-
/* @__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" }) }),
|
|
319
|
-
/* @__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: [
|
|
320
|
-
/* @__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)) }),
|
|
321
|
-
((_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
|
|
322
|
-
] }) })
|
|
323
|
-
] })
|
|
324
|
-
}
|
|
325
|
-
)
|
|
326
|
-
] }) });
|
|
327
|
-
}
|
|
328
40
|
const config = adminSdk.defineRouteConfig({
|
|
329
41
|
label: "PayPal Connection",
|
|
330
42
|
hide: true
|
|
@@ -899,25 +611,313 @@ function PayPalConnectionPage() {
|
|
|
899
611
|
] }) })
|
|
900
612
|
] }) })
|
|
901
613
|
] }),
|
|
902
|
-
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
903
|
-
.loader {
|
|
904
|
-
border: 3px solid #f3f3f3;
|
|
905
|
-
border-top: 3px solid #0070ba;
|
|
906
|
-
border-radius: 50%;
|
|
907
|
-
width: 18px;
|
|
908
|
-
height: 18px;
|
|
909
|
-
animation: spin 1s linear infinite;
|
|
910
|
-
display: inline-block;
|
|
911
|
-
vertical-align: middle;
|
|
912
|
-
margin-right: 8px;
|
|
913
|
-
}
|
|
914
|
-
@keyframes spin {
|
|
915
|
-
0% { transform: rotate(0deg); }
|
|
916
|
-
100% { transform: rotate(360deg); }
|
|
917
|
-
}
|
|
918
|
-
` })
|
|
614
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
615
|
+
.loader {
|
|
616
|
+
border: 3px solid #f3f3f3;
|
|
617
|
+
border-top: 3px solid #0070ba;
|
|
618
|
+
border-radius: 50%;
|
|
619
|
+
width: 18px;
|
|
620
|
+
height: 18px;
|
|
621
|
+
animation: spin 1s linear infinite;
|
|
622
|
+
display: inline-block;
|
|
623
|
+
vertical-align: middle;
|
|
624
|
+
margin-right: 8px;
|
|
625
|
+
}
|
|
626
|
+
@keyframes spin {
|
|
627
|
+
0% { transform: rotate(0deg); }
|
|
628
|
+
100% { transform: rotate(360deg); }
|
|
629
|
+
}
|
|
630
|
+
` })
|
|
631
|
+
] });
|
|
632
|
+
}
|
|
633
|
+
async function adminFetch$2(path, opts = {}) {
|
|
634
|
+
var _a;
|
|
635
|
+
const { method = "GET", body, query } = opts;
|
|
636
|
+
let url = path;
|
|
637
|
+
if (query && Object.keys(query).length > 0) {
|
|
638
|
+
const params = new URLSearchParams(query);
|
|
639
|
+
url = `${path}?${params.toString()}`;
|
|
640
|
+
}
|
|
641
|
+
const headers = { Accept: "application/json" };
|
|
642
|
+
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
643
|
+
if (typeof window !== "undefined") {
|
|
644
|
+
const token = (_a = window.__medusa__) == null ? void 0 : _a.token;
|
|
645
|
+
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
646
|
+
}
|
|
647
|
+
const res = await fetch(url, {
|
|
648
|
+
method,
|
|
649
|
+
headers,
|
|
650
|
+
credentials: "include",
|
|
651
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
652
|
+
});
|
|
653
|
+
const text = await res.text().catch(() => "");
|
|
654
|
+
if (!res.ok) {
|
|
655
|
+
if (res.status === 401) throw new Error("Unauthorized (401) - session may have expired. Please reload and log in again.");
|
|
656
|
+
if (res.status === 403) throw new Error("Forbidden (403) - you do not have permission to perform this action.");
|
|
657
|
+
throw new Error(text || `Request failed with status ${res.status}`);
|
|
658
|
+
}
|
|
659
|
+
if (!text) return {};
|
|
660
|
+
try {
|
|
661
|
+
return JSON.parse(text);
|
|
662
|
+
} catch {
|
|
663
|
+
return {};
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
const DEFAULT_FORM$1 = {
|
|
667
|
+
enabled: true,
|
|
668
|
+
title: "Credit or Debit Card",
|
|
669
|
+
threeDS: "when_required"
|
|
670
|
+
};
|
|
671
|
+
function mergeWithDefaults$1(saved) {
|
|
672
|
+
if (!saved) return { ...DEFAULT_FORM$1 };
|
|
673
|
+
const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
|
|
674
|
+
return { ...DEFAULT_FORM$1, ...Object.fromEntries(entries) };
|
|
675
|
+
}
|
|
676
|
+
const THREE_DS_OPTIONS = [
|
|
677
|
+
{ value: "when_required", label: "3D Secure when required", hint: "Triggers 3DS only when the card / issuer requires it." },
|
|
678
|
+
{ value: "sli", label: "3D Secure (SCA) / liability shift (recommended)", hint: "Attempts to optimize for liability shift while remaining compliant." },
|
|
679
|
+
{ value: "always", label: "Always request 3D Secure", hint: "Forces 3DS challenge whenever possible (may reduce conversion)." }
|
|
680
|
+
];
|
|
681
|
+
function SectionCard$2({ title, description, right, children }) {
|
|
682
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
683
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
|
|
684
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
685
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
|
|
686
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
|
|
687
|
+
] }),
|
|
688
|
+
right
|
|
689
|
+
] }),
|
|
690
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
|
|
691
|
+
] });
|
|
692
|
+
}
|
|
693
|
+
function FieldRow$2({ label, hint, children }) {
|
|
694
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
|
|
695
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
|
|
696
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
|
|
697
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
|
|
698
|
+
] }),
|
|
699
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
|
|
700
|
+
] });
|
|
701
|
+
}
|
|
702
|
+
function AdvancedCardPaymentsTab() {
|
|
703
|
+
var _a, _b;
|
|
704
|
+
const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM$1 }));
|
|
705
|
+
const [loading, setLoading] = react.useState(false);
|
|
706
|
+
const [saving, setSaving] = react.useState(false);
|
|
707
|
+
const [toast, setToast] = react.useState(null);
|
|
708
|
+
const didInit = react.useRef(false);
|
|
709
|
+
react.useEffect(() => {
|
|
710
|
+
if (didInit.current) return;
|
|
711
|
+
didInit.current = true;
|
|
712
|
+
(async () => {
|
|
713
|
+
try {
|
|
714
|
+
setLoading(true);
|
|
715
|
+
const json = await adminFetch$2("/admin/paypal/settings");
|
|
716
|
+
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
717
|
+
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
718
|
+
if (saved && typeof saved === "object") setForm(mergeWithDefaults$1(saved));
|
|
719
|
+
} catch {
|
|
720
|
+
} finally {
|
|
721
|
+
setLoading(false);
|
|
722
|
+
}
|
|
723
|
+
})();
|
|
724
|
+
}, []);
|
|
725
|
+
async function onSave() {
|
|
726
|
+
try {
|
|
727
|
+
setSaving(true);
|
|
728
|
+
const json = await adminFetch$2("/admin/paypal/settings", {
|
|
729
|
+
method: "POST",
|
|
730
|
+
body: { advanced_card_payments: form }
|
|
731
|
+
});
|
|
732
|
+
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
733
|
+
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
734
|
+
if (saved && typeof saved === "object") setForm(mergeWithDefaults$1(saved));
|
|
735
|
+
setToast({ type: "success", message: "Settings saved" });
|
|
736
|
+
window.setTimeout(() => setToast(null), 2500);
|
|
737
|
+
} catch (e) {
|
|
738
|
+
setToast({ type: "error", message: (e instanceof Error ? e.message : "") || "Failed to save settings." });
|
|
739
|
+
window.setTimeout(() => setToast(null), 3500);
|
|
740
|
+
} finally {
|
|
741
|
+
setSaving(false);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
745
|
+
/* @__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" }) }) }),
|
|
746
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
747
|
+
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,
|
|
748
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
749
|
+
SectionCard$2,
|
|
750
|
+
{
|
|
751
|
+
title: "Advanced Card Payments",
|
|
752
|
+
description: "Control card checkout settings and 3D Secure behavior.",
|
|
753
|
+
right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
754
|
+
/* @__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" }),
|
|
755
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading..." }) : null
|
|
756
|
+
] }),
|
|
757
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
|
|
758
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Enable/Disable", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
759
|
+
/* @__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" }),
|
|
760
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable Advanced Credit/Debit Card" })
|
|
761
|
+
] }) }),
|
|
762
|
+
/* @__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" }) }),
|
|
763
|
+
/* @__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: [
|
|
764
|
+
/* @__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)) }),
|
|
765
|
+
((_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
|
|
766
|
+
] }) })
|
|
767
|
+
] })
|
|
768
|
+
}
|
|
769
|
+
)
|
|
770
|
+
] }) });
|
|
771
|
+
}
|
|
772
|
+
async function adminFetch$1(path, opts = {}) {
|
|
773
|
+
var _a;
|
|
774
|
+
const { method = "GET", body, query } = opts;
|
|
775
|
+
let url = path;
|
|
776
|
+
if (query && Object.keys(query).length > 0) {
|
|
777
|
+
const params = new URLSearchParams(query);
|
|
778
|
+
url = `${path}?${params.toString()}`;
|
|
779
|
+
}
|
|
780
|
+
const headers = { Accept: "application/json" };
|
|
781
|
+
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
782
|
+
if (typeof window !== "undefined") {
|
|
783
|
+
const token = (_a = window.__medusa__) == null ? void 0 : _a.token;
|
|
784
|
+
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
785
|
+
}
|
|
786
|
+
const res = await fetch(url, {
|
|
787
|
+
method,
|
|
788
|
+
headers,
|
|
789
|
+
credentials: "include",
|
|
790
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
791
|
+
});
|
|
792
|
+
const text = await res.text().catch(() => "");
|
|
793
|
+
if (!res.ok) {
|
|
794
|
+
if (res.status === 401) throw new Error("Unauthorized (401) - session may have expired. Please reload and log in again.");
|
|
795
|
+
if (res.status === 403) throw new Error("Forbidden (403) - you do not have permission to perform this action.");
|
|
796
|
+
throw new Error(text || `Request failed with status ${res.status}`);
|
|
797
|
+
}
|
|
798
|
+
if (!text) return {};
|
|
799
|
+
try {
|
|
800
|
+
return JSON.parse(text);
|
|
801
|
+
} catch {
|
|
802
|
+
return {};
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
const DEFAULT_FORM = {
|
|
806
|
+
paymentAction: "capture",
|
|
807
|
+
brandName: "PayPal",
|
|
808
|
+
landingPage: "no_preference",
|
|
809
|
+
requireInstantPayment: false,
|
|
810
|
+
sendItemDetails: true,
|
|
811
|
+
invoicePrefix: "WC-",
|
|
812
|
+
creditCardStatementName: "PayPal"
|
|
813
|
+
};
|
|
814
|
+
function mergeWithDefaults(saved) {
|
|
815
|
+
if (!saved) return { ...DEFAULT_FORM };
|
|
816
|
+
const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
|
|
817
|
+
return { ...DEFAULT_FORM, ...Object.fromEntries(entries) };
|
|
818
|
+
}
|
|
819
|
+
function SectionCard$1({ title, description, right, children }) {
|
|
820
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
821
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
|
|
822
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
823
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
|
|
824
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
|
|
825
|
+
] }),
|
|
826
|
+
right
|
|
827
|
+
] }),
|
|
828
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
|
|
829
|
+
] });
|
|
830
|
+
}
|
|
831
|
+
function FieldRow$1({ label, hint, children }) {
|
|
832
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
|
|
833
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
|
|
834
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
|
|
835
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
|
|
836
|
+
] }),
|
|
837
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
|
|
919
838
|
] });
|
|
920
839
|
}
|
|
840
|
+
function AdditionalSettingsTab() {
|
|
841
|
+
const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM }));
|
|
842
|
+
const [loading, setLoading] = react.useState(false);
|
|
843
|
+
const [saving, setSaving] = react.useState(false);
|
|
844
|
+
const [toast, setToast] = react.useState(null);
|
|
845
|
+
const didInit = react.useRef(false);
|
|
846
|
+
react.useEffect(() => {
|
|
847
|
+
if (didInit.current) return;
|
|
848
|
+
didInit.current = true;
|
|
849
|
+
(async () => {
|
|
850
|
+
try {
|
|
851
|
+
setLoading(true);
|
|
852
|
+
const json = await adminFetch$1("/admin/paypal/settings");
|
|
853
|
+
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
854
|
+
const saved = payload == null ? void 0 : payload.additional_settings;
|
|
855
|
+
if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved));
|
|
856
|
+
} catch {
|
|
857
|
+
} finally {
|
|
858
|
+
setLoading(false);
|
|
859
|
+
}
|
|
860
|
+
})();
|
|
861
|
+
}, []);
|
|
862
|
+
async function onSave() {
|
|
863
|
+
try {
|
|
864
|
+
setSaving(true);
|
|
865
|
+
setToast(null);
|
|
866
|
+
const json = await adminFetch$1("/admin/paypal/settings", { method: "POST", body: { additional_settings: form } });
|
|
867
|
+
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
868
|
+
const saved = payload == null ? void 0 : payload.additional_settings;
|
|
869
|
+
if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved));
|
|
870
|
+
setToast({ type: "success", message: "Settings saved" });
|
|
871
|
+
window.setTimeout(() => setToast(null), 2500);
|
|
872
|
+
} catch (e) {
|
|
873
|
+
setToast({ type: "error", message: e instanceof Error ? e.message : "Failed to save settings" });
|
|
874
|
+
window.setTimeout(() => setToast(null), 3500);
|
|
875
|
+
} finally {
|
|
876
|
+
setSaving(false);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
880
|
+
/* @__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" }) }) }),
|
|
881
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
882
|
+
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,
|
|
883
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
884
|
+
SectionCard$1,
|
|
885
|
+
{
|
|
886
|
+
title: "Additional Settings",
|
|
887
|
+
description: "These settings control checkout behavior and PayPal experience.",
|
|
888
|
+
right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
889
|
+
/* @__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" }),
|
|
890
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading..." }) : null
|
|
891
|
+
] }),
|
|
892
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
|
|
893
|
+
/* @__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: [
|
|
894
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "capture", children: "Capture" }),
|
|
895
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorize", children: "Authorize" })
|
|
896
|
+
] }) }),
|
|
897
|
+
/* @__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" }) }),
|
|
898
|
+
/* @__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: [
|
|
899
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "no_preference", children: "No Preference" }),
|
|
900
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "login", children: "Login" }),
|
|
901
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "billing", children: "Billing" })
|
|
902
|
+
] }) }),
|
|
903
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Instant Payments", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
904
|
+
/* @__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" }),
|
|
905
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Require Instant Payment" })
|
|
906
|
+
] }) }),
|
|
907
|
+
/* @__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: [
|
|
908
|
+
/* @__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" }),
|
|
909
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Send line item details to PayPal" })
|
|
910
|
+
] }) }),
|
|
911
|
+
/* @__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-" }) }),
|
|
912
|
+
/* @__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" }) })
|
|
913
|
+
] })
|
|
914
|
+
}
|
|
915
|
+
)
|
|
916
|
+
] }) });
|
|
917
|
+
}
|
|
918
|
+
function PayPalGooglePayPage() {
|
|
919
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
920
|
+
}
|
|
921
921
|
function PayPalPayLaterMessagingPage() {
|
|
922
922
|
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
923
923
|
}
|
|
@@ -1201,25 +1201,25 @@ const routeModule = {
|
|
|
1201
1201
|
Component: PayPalSettingsIndexRoute,
|
|
1202
1202
|
path: "/settings/paypal"
|
|
1203
1203
|
},
|
|
1204
|
-
{
|
|
1205
|
-
Component: AdditionalSettingsTab,
|
|
1206
|
-
path: "/settings/paypal/additional-settings"
|
|
1207
|
-
},
|
|
1208
1204
|
{
|
|
1209
1205
|
Component: PayPalApplePayPage,
|
|
1210
1206
|
path: "/settings/paypal/apple-pay"
|
|
1211
1207
|
},
|
|
1212
1208
|
{
|
|
1213
|
-
Component:
|
|
1214
|
-
path: "/settings/paypal/
|
|
1209
|
+
Component: PayPalConnectionPage,
|
|
1210
|
+
path: "/settings/paypal/connection"
|
|
1215
1211
|
},
|
|
1216
1212
|
{
|
|
1217
1213
|
Component: AdvancedCardPaymentsTab,
|
|
1218
1214
|
path: "/settings/paypal/advanced-card-payments"
|
|
1219
1215
|
},
|
|
1220
1216
|
{
|
|
1221
|
-
Component:
|
|
1222
|
-
path: "/settings/paypal/
|
|
1217
|
+
Component: AdditionalSettingsTab,
|
|
1218
|
+
path: "/settings/paypal/additional-settings"
|
|
1219
|
+
},
|
|
1220
|
+
{
|
|
1221
|
+
Component: PayPalGooglePayPage,
|
|
1222
|
+
path: "/settings/paypal/google-pay"
|
|
1223
1223
|
},
|
|
1224
1224
|
{
|
|
1225
1225
|
Component: PayPalPayLaterMessagingPage,
|