@easypayment/medusa-paypal 0.2.3 → 0.2.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.
- package/.medusa/server/src/admin/index.js +1079 -1079
- package/.medusa/server/src/admin/index.mjs +1079 -1079
- package/.medusa/server/src/api/store/paypal/capture-order/route.js +1 -1
- package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/config/route.js +1 -1
- package/.medusa/server/src/api/store/paypal/create-order/route.js +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.js +9 -9
- package/.medusa/server/src/modules/paypal/payment-provider/service.js +10 -10
- package/.medusa/server/src/modules/paypal/service.js +1 -1
- package/.medusa/server/src/modules/paypal/utils/currencies.js +1 -1
- package/package.json +1 -1
- package/src/api/store/paypal/capture-order/route.ts +1 -1
- package/src/api/store/paypal/config/route.ts +1 -1
- package/src/api/store/paypal/create-order/route.ts +1 -1
- package/src/modules/paypal/payment-provider/card-service.ts +9 -9
- package/src/modules/paypal/payment-provider/service.ts +10 -10
- package/src/modules/paypal/service.ts +1 -1
- package/src/modules/paypal/utils/currencies.ts +1 -1
|
@@ -41,17 +41,11 @@ function PayPalTabs() {
|
|
|
41
41
|
}) }) });
|
|
42
42
|
}
|
|
43
43
|
const DEFAULT_FORM$1 = {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
sendItemDetails: true,
|
|
50
|
-
skipOrderReviewPage: true,
|
|
51
|
-
invoicePrefix: "WC-",
|
|
52
|
-
creditCardStatementName: "PayPal",
|
|
53
|
-
enableLogging: true,
|
|
54
|
-
logPath: "/uploads/wc-logs/"
|
|
44
|
+
enabled: true,
|
|
45
|
+
title: "Credit or Debit Card",
|
|
46
|
+
disabledCards: [],
|
|
47
|
+
threeDS: "when_required",
|
|
48
|
+
cardSaveEnabled: false
|
|
55
49
|
};
|
|
56
50
|
function mergeWithDefaults$1(saved) {
|
|
57
51
|
if (!saved) return { ...DEFAULT_FORM$1 };
|
|
@@ -61,6 +55,53 @@ function mergeWithDefaults$1(saved) {
|
|
|
61
55
|
...Object.fromEntries(entries)
|
|
62
56
|
};
|
|
63
57
|
}
|
|
58
|
+
const CARD_BRANDS = [
|
|
59
|
+
{ value: "visa", label: "Visa" },
|
|
60
|
+
{ value: "mastercard", label: "Mastercard" },
|
|
61
|
+
{ value: "amex", label: "American Express" },
|
|
62
|
+
{ value: "discover", label: "Discover" },
|
|
63
|
+
{ value: "diners", label: "Diners Club" },
|
|
64
|
+
{ value: "jcb", label: "JCB" },
|
|
65
|
+
{ value: "unionpay", label: "UnionPay" }
|
|
66
|
+
];
|
|
67
|
+
const THREE_DS_OPTIONS = [
|
|
68
|
+
{
|
|
69
|
+
value: "when_required",
|
|
70
|
+
label: "3D Secure when required",
|
|
71
|
+
hint: "Triggers 3DS only when the card / issuer requires it."
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
value: "sli",
|
|
75
|
+
label: "3D Secure (SCA) / liability shift (recommended)",
|
|
76
|
+
hint: "Attempts to optimize for liability shift while remaining compliant."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
value: "always",
|
|
80
|
+
label: "Always request 3D Secure",
|
|
81
|
+
hint: "Forces 3DS challenge whenever possible (may reduce conversion)."
|
|
82
|
+
}
|
|
83
|
+
];
|
|
84
|
+
function cx$1(...parts) {
|
|
85
|
+
return parts.filter(Boolean).join(" ");
|
|
86
|
+
}
|
|
87
|
+
function Pill$1({
|
|
88
|
+
children,
|
|
89
|
+
onRemove
|
|
90
|
+
}) {
|
|
91
|
+
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: [
|
|
92
|
+
children,
|
|
93
|
+
onRemove ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
94
|
+
"button",
|
|
95
|
+
{
|
|
96
|
+
type: "button",
|
|
97
|
+
onClick: onRemove,
|
|
98
|
+
className: "ml-1 rounded px-1 text-ui-fg-subtle hover:text-ui-fg-base",
|
|
99
|
+
"aria-label": "Remove",
|
|
100
|
+
children: "×"
|
|
101
|
+
}
|
|
102
|
+
) : null
|
|
103
|
+
] });
|
|
104
|
+
}
|
|
64
105
|
function SectionCard$2({
|
|
65
106
|
title,
|
|
66
107
|
description,
|
|
@@ -91,10 +132,12 @@ function FieldRow$2({
|
|
|
91
132
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
|
|
92
133
|
] });
|
|
93
134
|
}
|
|
94
|
-
function
|
|
135
|
+
function AdvancedCardPaymentsTab() {
|
|
136
|
+
var _a, _b;
|
|
95
137
|
const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM$1 }));
|
|
96
138
|
const [loading, setLoading] = react.useState(false);
|
|
97
139
|
const [saving, setSaving] = react.useState(false);
|
|
140
|
+
const [toast, setToast] = react.useState(null);
|
|
98
141
|
const didInit = react.useRef(false);
|
|
99
142
|
react.useEffect(() => {
|
|
100
143
|
if (didInit.current) return;
|
|
@@ -109,7 +152,7 @@ function AdditionalSettingsTab() {
|
|
|
109
152
|
if (!r.ok) return;
|
|
110
153
|
const json = await r.json();
|
|
111
154
|
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
112
|
-
const saved = payload == null ? void 0 : payload.
|
|
155
|
+
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
113
156
|
if (saved && typeof saved === "object") {
|
|
114
157
|
setForm(mergeWithDefaults$1(saved));
|
|
115
158
|
}
|
|
@@ -118,11 +161,9 @@ function AdditionalSettingsTab() {
|
|
|
118
161
|
}
|
|
119
162
|
})();
|
|
120
163
|
}, []);
|
|
121
|
-
const [toast, setToast] = react.useState(null);
|
|
122
164
|
async function onSave() {
|
|
123
165
|
try {
|
|
124
166
|
setSaving(true);
|
|
125
|
-
setToast(null);
|
|
126
167
|
const r = await fetch("/admin/paypal/settings", {
|
|
127
168
|
method: "POST",
|
|
128
169
|
credentials: "include",
|
|
@@ -130,29 +171,42 @@ function AdditionalSettingsTab() {
|
|
|
130
171
|
"Content-Type": "application/json",
|
|
131
172
|
"Accept": "application/json"
|
|
132
173
|
},
|
|
133
|
-
body: JSON.stringify({
|
|
134
|
-
additional_settings: form
|
|
135
|
-
})
|
|
174
|
+
body: JSON.stringify({ advanced_card_payments: form })
|
|
136
175
|
});
|
|
137
176
|
if (!r.ok) {
|
|
138
|
-
const
|
|
139
|
-
|
|
177
|
+
const t = await r.text();
|
|
178
|
+
setToast({ type: "error", message: "Failed to save settings. " + t });
|
|
179
|
+
window.setTimeout(() => setToast(null), 3500);
|
|
180
|
+
return;
|
|
140
181
|
}
|
|
141
|
-
const json = await r.json().catch(() =>
|
|
182
|
+
const json = await r.json().catch(() => null);
|
|
142
183
|
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
143
|
-
const saved = payload == null ? void 0 : payload.
|
|
184
|
+
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
144
185
|
if (saved && typeof saved === "object") {
|
|
145
186
|
setForm(mergeWithDefaults$1(saved));
|
|
146
187
|
}
|
|
147
188
|
setToast({ type: "success", message: "Settings saved" });
|
|
148
189
|
window.setTimeout(() => setToast(null), 2500);
|
|
149
|
-
} catch (e) {
|
|
150
|
-
setToast({ type: "error", message: (e == null ? void 0 : e.message) || "Failed to save settings" });
|
|
151
|
-
window.setTimeout(() => setToast(null), 3500);
|
|
152
190
|
} finally {
|
|
153
191
|
setSaving(false);
|
|
154
192
|
}
|
|
155
193
|
}
|
|
194
|
+
const disabledSet = react.useMemo(() => new Set(form.disabledCards), [form.disabledCards]);
|
|
195
|
+
function toggleDisabledCard(value) {
|
|
196
|
+
setForm((prev) => {
|
|
197
|
+
const exists = prev.disabledCards.includes(value);
|
|
198
|
+
return {
|
|
199
|
+
...prev,
|
|
200
|
+
disabledCards: exists ? prev.disabledCards.filter((v) => v !== value) : [...prev.disabledCards, value]
|
|
201
|
+
};
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function removeDisabledCard(value) {
|
|
205
|
+
setForm((prev) => ({
|
|
206
|
+
...prev,
|
|
207
|
+
disabledCards: prev.disabledCards.filter((v) => v !== value)
|
|
208
|
+
}));
|
|
209
|
+
}
|
|
156
210
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
157
211
|
/* @__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" }) }) }),
|
|
158
212
|
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
@@ -168,8 +222,8 @@ function AdditionalSettingsTab() {
|
|
|
168
222
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
169
223
|
SectionCard$2,
|
|
170
224
|
{
|
|
171
|
-
title: "
|
|
172
|
-
description: "
|
|
225
|
+
title: "Advanced Card Payments",
|
|
226
|
+
description: "Control card checkout settings, 3D Secure behavior, and card saving.",
|
|
173
227
|
right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
174
228
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
175
229
|
"button",
|
|
@@ -184,1035 +238,981 @@ function AdditionalSettingsTab() {
|
|
|
184
238
|
loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading…" }) : null
|
|
185
239
|
] }),
|
|
186
240
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
|
|
187
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "
|
|
188
|
-
"select",
|
|
189
|
-
{
|
|
190
|
-
value: form.paymentAction,
|
|
191
|
-
onChange: (e) => setForm((p) => ({ ...p, paymentAction: e.target.value })),
|
|
192
|
-
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",
|
|
193
|
-
children: [
|
|
194
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "capture", children: "Capture" }),
|
|
195
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorize", children: "Authorize" })
|
|
196
|
-
]
|
|
197
|
-
}
|
|
198
|
-
) }),
|
|
199
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Brand Name", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
200
|
-
"input",
|
|
201
|
-
{
|
|
202
|
-
value: form.brandName,
|
|
203
|
-
onChange: (e) => setForm((p) => ({ ...p, brandName: e.target.value })),
|
|
204
|
-
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",
|
|
205
|
-
placeholder: "PayPal"
|
|
206
|
-
}
|
|
207
|
-
) }),
|
|
208
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Landing Page", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
209
|
-
"select",
|
|
210
|
-
{
|
|
211
|
-
value: form.landingPage,
|
|
212
|
-
onChange: (e) => setForm((p) => ({ ...p, landingPage: e.target.value })),
|
|
213
|
-
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",
|
|
214
|
-
children: [
|
|
215
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "no_preference", children: "No Preference" }),
|
|
216
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "login", children: "Login" }),
|
|
217
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "billing", children: "Billing" })
|
|
218
|
-
]
|
|
219
|
-
}
|
|
220
|
-
) }),
|
|
221
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Instant Payments", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
241
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Enable/Disable", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
222
242
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
223
243
|
"input",
|
|
224
244
|
{
|
|
225
245
|
type: "checkbox",
|
|
226
|
-
checked: form.
|
|
227
|
-
onChange: (e) => setForm((p) => ({ ...p,
|
|
246
|
+
checked: form.enabled,
|
|
247
|
+
onChange: (e) => setForm((p) => ({ ...p, enabled: e.target.checked })),
|
|
228
248
|
className: "h-4 w-4 rounded border-ui-border-base"
|
|
229
249
|
}
|
|
230
250
|
),
|
|
231
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "
|
|
251
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable Advanced Credit/Debit Card" })
|
|
232
252
|
] }) }),
|
|
233
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
234
|
-
|
|
253
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Title", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
254
|
+
"input",
|
|
235
255
|
{
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
"input",
|
|
241
|
-
{
|
|
242
|
-
type: "checkbox",
|
|
243
|
-
checked: form.useShippingAsBilling,
|
|
244
|
-
onChange: (e) => setForm((p) => ({ ...p, useShippingAsBilling: e.target.checked })),
|
|
245
|
-
className: "h-4 w-4 rounded border-ui-border-base"
|
|
246
|
-
}
|
|
247
|
-
),
|
|
248
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Use PayPal Shipping Address as Billing" })
|
|
249
|
-
] })
|
|
256
|
+
value: form.title,
|
|
257
|
+
onChange: (e) => setForm((p) => ({ ...p, title: e.target.value })),
|
|
258
|
+
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",
|
|
259
|
+
placeholder: "Credit or Debit Card"
|
|
250
260
|
}
|
|
251
|
-
),
|
|
261
|
+
) }),
|
|
252
262
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
253
263
|
FieldRow$2,
|
|
254
264
|
{
|
|
255
|
-
label: "
|
|
256
|
-
hint: "
|
|
257
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("
|
|
258
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
265
|
+
label: "Disable specific credit cards",
|
|
266
|
+
hint: "Select card brands to hide from the card form.",
|
|
267
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
268
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: form.disabledCards.length ? form.disabledCards.map((v) => {
|
|
269
|
+
var _a2;
|
|
270
|
+
const label = ((_a2 = CARD_BRANDS.find((b) => b.value === v)) == null ? void 0 : _a2.label) ?? v;
|
|
271
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Pill$1, { onRemove: () => removeDisabledCard(v), children: label }, v);
|
|
272
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "No card brands disabled." }) }),
|
|
273
|
+
/* @__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) => {
|
|
274
|
+
const checked = disabledSet.has(b.value);
|
|
275
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
276
|
+
"label",
|
|
277
|
+
{
|
|
278
|
+
className: cx$1(
|
|
279
|
+
"flex items-center gap-2 rounded-md p-2",
|
|
280
|
+
"hover:bg-ui-bg-subtle"
|
|
281
|
+
),
|
|
282
|
+
children: [
|
|
283
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
284
|
+
"input",
|
|
285
|
+
{
|
|
286
|
+
type: "checkbox",
|
|
287
|
+
checked,
|
|
288
|
+
onChange: () => toggleDisabledCard(b.value),
|
|
289
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
290
|
+
}
|
|
291
|
+
),
|
|
292
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: b.label })
|
|
293
|
+
]
|
|
294
|
+
},
|
|
295
|
+
b.value
|
|
296
|
+
);
|
|
297
|
+
}) }) })
|
|
268
298
|
] })
|
|
269
299
|
}
|
|
270
300
|
),
|
|
271
301
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
272
302
|
FieldRow$2,
|
|
273
303
|
{
|
|
274
|
-
label: "
|
|
275
|
-
hint: "
|
|
276
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("
|
|
304
|
+
label: "Contingency for 3D Secure",
|
|
305
|
+
hint: "Choose when 3D Secure should be triggered during card payments.",
|
|
306
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
277
307
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
278
|
-
"
|
|
308
|
+
"select",
|
|
279
309
|
{
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
310
|
+
value: form.threeDS,
|
|
311
|
+
onChange: (e) => setForm((p) => ({ ...p, threeDS: e.target.value })),
|
|
312
|
+
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",
|
|
313
|
+
children: THREE_DS_OPTIONS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
|
|
284
314
|
}
|
|
285
315
|
),
|
|
286
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
316
|
+
((_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
|
|
287
317
|
] })
|
|
288
318
|
}
|
|
289
319
|
),
|
|
290
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
"
|
|
301
|
-
|
|
302
|
-
value: form.creditCardStatementName,
|
|
303
|
-
onChange: (e) => setForm((p) => ({ ...p, creditCardStatementName: e.target.value })),
|
|
304
|
-
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",
|
|
305
|
-
placeholder: "PayPal"
|
|
306
|
-
}
|
|
307
|
-
) }),
|
|
308
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
309
|
-
FieldRow$2,
|
|
310
|
-
{
|
|
311
|
-
label: "Debug log",
|
|
312
|
-
hint: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
313
|
-
"Log PayPal events such as Webhook, Payment, Refund.",
|
|
314
|
-
" ",
|
|
315
|
-
form.logPath ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
316
|
-
"Log location: ",
|
|
317
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: form.logPath })
|
|
318
|
-
] }) : null
|
|
319
|
-
] }),
|
|
320
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
321
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
322
|
-
"input",
|
|
323
|
-
{
|
|
324
|
-
type: "checkbox",
|
|
325
|
-
checked: form.enableLogging,
|
|
326
|
-
onChange: (e) => setForm((p) => ({ ...p, enableLogging: e.target.checked })),
|
|
327
|
-
className: "h-4 w-4 rounded border-ui-border-base"
|
|
328
|
-
}
|
|
329
|
-
),
|
|
330
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable logging" })
|
|
331
|
-
] })
|
|
332
|
-
}
|
|
333
|
-
)
|
|
320
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$2, { label: "Card Save Enabled", hint: "Allow customers to save a card at checkout for future use.", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
321
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
322
|
+
"input",
|
|
323
|
+
{
|
|
324
|
+
type: "checkbox",
|
|
325
|
+
checked: form.cardSaveEnabled,
|
|
326
|
+
onChange: (e) => setForm((p) => ({ ...p, cardSaveEnabled: e.target.checked })),
|
|
327
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
328
|
+
}
|
|
329
|
+
),
|
|
330
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable card saving at checkout" })
|
|
331
|
+
] }) })
|
|
334
332
|
] })
|
|
335
333
|
}
|
|
336
334
|
)
|
|
337
335
|
] }) });
|
|
338
336
|
}
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const ppScript = document.createElement("script");
|
|
360
|
-
ppScript.id = "paypal-partner-js";
|
|
361
|
-
ppScript.src = preloadHref;
|
|
362
|
-
ppScript.async = true;
|
|
363
|
-
document.head.appendChild(ppScript);
|
|
364
|
-
}
|
|
337
|
+
const DEFAULT_FORM = {
|
|
338
|
+
paymentAction: "capture",
|
|
339
|
+
brandName: "PayPal",
|
|
340
|
+
landingPage: "no_preference",
|
|
341
|
+
requireInstantPayment: false,
|
|
342
|
+
useShippingAsBilling: true,
|
|
343
|
+
sendItemDetails: true,
|
|
344
|
+
skipOrderReviewPage: true,
|
|
345
|
+
invoicePrefix: "WC-",
|
|
346
|
+
creditCardStatementName: "PayPal",
|
|
347
|
+
enableLogging: true,
|
|
348
|
+
logPath: "/uploads/wc-logs/"
|
|
349
|
+
};
|
|
350
|
+
function mergeWithDefaults(saved) {
|
|
351
|
+
if (!saved) return { ...DEFAULT_FORM };
|
|
352
|
+
const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
|
|
353
|
+
return {
|
|
354
|
+
...DEFAULT_FORM,
|
|
355
|
+
...Object.fromEntries(entries)
|
|
356
|
+
};
|
|
365
357
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
} catch (e) {
|
|
385
|
-
console.error("Cache read error:", e);
|
|
386
|
-
}
|
|
358
|
+
function SectionCard$1({
|
|
359
|
+
title,
|
|
360
|
+
description,
|
|
361
|
+
right,
|
|
362
|
+
children
|
|
363
|
+
}) {
|
|
364
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
365
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
|
|
366
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
367
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
|
|
368
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
|
|
369
|
+
] }),
|
|
370
|
+
right
|
|
371
|
+
] }),
|
|
372
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
|
|
373
|
+
] });
|
|
387
374
|
}
|
|
388
|
-
function
|
|
389
|
-
|
|
375
|
+
function FieldRow$1({
|
|
376
|
+
label,
|
|
377
|
+
hint,
|
|
378
|
+
children
|
|
379
|
+
}) {
|
|
380
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
|
|
381
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
|
|
382
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
|
|
383
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
|
|
384
|
+
] }),
|
|
385
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
|
|
386
|
+
] });
|
|
387
|
+
}
|
|
388
|
+
function AdditionalSettingsTab() {
|
|
389
|
+
const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM }));
|
|
390
|
+
const [loading, setLoading] = react.useState(false);
|
|
391
|
+
const [saving, setSaving] = react.useState(false);
|
|
392
|
+
const didInit = react.useRef(false);
|
|
390
393
|
react.useEffect(() => {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
const runIdRef = react.useRef(0);
|
|
410
|
-
const currentRunId = react.useRef(0);
|
|
411
|
-
const ppBtnMeasureRef = react.useRef(null);
|
|
412
|
-
const [ppBtnWidth, setPpBtnWidth] = react.useState(null);
|
|
413
|
-
const canSaveManual = react.useMemo(() => {
|
|
414
|
-
return clientId.trim().length > 0 && secret.trim().length > 0;
|
|
415
|
-
}, [clientId, secret]);
|
|
416
|
-
const maskValue = react.useCallback((value, visibleChars = 4) => {
|
|
417
|
-
if (!value) return "";
|
|
418
|
-
if (value.length <= visibleChars) {
|
|
419
|
-
return "•".repeat(value.length);
|
|
420
|
-
}
|
|
421
|
-
return `${"•".repeat(Math.max(0, value.length - visibleChars))}${value.slice(
|
|
422
|
-
-visibleChars
|
|
423
|
-
)}`;
|
|
424
|
-
}, []);
|
|
425
|
-
const fetchFreshLink = react.useCallback(
|
|
426
|
-
(runId) => {
|
|
427
|
-
if (initLoaderRef.current) {
|
|
428
|
-
const loaderText = initLoaderRef.current.querySelector("#loader-text");
|
|
429
|
-
if (loaderText)
|
|
430
|
-
loaderText.textContent = "Generating onboarding session...";
|
|
394
|
+
if (didInit.current) return;
|
|
395
|
+
didInit.current = true;
|
|
396
|
+
(async () => {
|
|
397
|
+
try {
|
|
398
|
+
setLoading(true);
|
|
399
|
+
const r = await fetch("/admin/paypal/settings", {
|
|
400
|
+
credentials: "include",
|
|
401
|
+
headers: { "Accept": "application/json" }
|
|
402
|
+
});
|
|
403
|
+
if (!r.ok) return;
|
|
404
|
+
const json = await r.json();
|
|
405
|
+
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
406
|
+
const saved = payload == null ? void 0 : payload.additional_settings;
|
|
407
|
+
if (saved && typeof saved === "object") {
|
|
408
|
+
setForm(mergeWithDefaults(saved));
|
|
409
|
+
}
|
|
410
|
+
} finally {
|
|
411
|
+
setLoading(false);
|
|
431
412
|
}
|
|
432
|
-
|
|
413
|
+
})();
|
|
414
|
+
}, []);
|
|
415
|
+
const [toast, setToast] = react.useState(null);
|
|
416
|
+
async function onSave() {
|
|
417
|
+
try {
|
|
418
|
+
setSaving(true);
|
|
419
|
+
setToast(null);
|
|
420
|
+
const r = await fetch("/admin/paypal/settings", {
|
|
433
421
|
method: "POST",
|
|
434
|
-
|
|
422
|
+
credentials: "include",
|
|
423
|
+
headers: {
|
|
424
|
+
"Content-Type": "application/json",
|
|
425
|
+
"Accept": "application/json"
|
|
426
|
+
},
|
|
435
427
|
body: JSON.stringify({
|
|
436
|
-
|
|
428
|
+
additional_settings: form
|
|
437
429
|
})
|
|
438
|
-
}).then((r) => r.json()).then((data) => {
|
|
439
|
-
if (runId !== currentRunId.current) return;
|
|
440
|
-
const href = data == null ? void 0 : data.onboarding_url;
|
|
441
|
-
if (!href) {
|
|
442
|
-
showError("Onboarding URL not returned.");
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
const finalUrl2 = href + (href.includes("?") ? "&" : "?") + "displayMode=minibrowser";
|
|
446
|
-
localStorage.setItem(
|
|
447
|
-
CACHE_KEY,
|
|
448
|
-
JSON.stringify({
|
|
449
|
-
url: finalUrl2,
|
|
450
|
-
ts: Date.now()
|
|
451
|
-
})
|
|
452
|
-
);
|
|
453
|
-
if (!localStorage.getItem(RELOAD_KEY)) {
|
|
454
|
-
localStorage.setItem(RELOAD_KEY, "1");
|
|
455
|
-
window.location.reload();
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
activatePayPal(finalUrl2, runId);
|
|
459
|
-
}).catch(() => {
|
|
460
|
-
if (runId !== currentRunId.current) return;
|
|
461
|
-
showError("Unable to connect to service.");
|
|
462
430
|
});
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
const showUI = react.useCallback(() => {
|
|
467
|
-
var _a, _b, _c, _d;
|
|
468
|
-
const btn = document.querySelector('[data-paypal-button="true"]');
|
|
469
|
-
if (btn && ((_d = (_c = (_b = (_a = window.PAYPAL) == null ? void 0 : _a.apps) == null ? void 0 : _b.Signup) == null ? void 0 : _c.miniBrowser) == null ? void 0 : _d.init)) {
|
|
470
|
-
window.PAYPAL.apps.Signup.miniBrowser.init();
|
|
471
|
-
}
|
|
472
|
-
setConnState("ready");
|
|
473
|
-
}, []);
|
|
474
|
-
const showError = react.useCallback((msg) => {
|
|
475
|
-
setConnState("error");
|
|
476
|
-
setError(msg);
|
|
477
|
-
}, []);
|
|
478
|
-
const activatePayPal = react.useCallback(
|
|
479
|
-
(url, runId) => {
|
|
480
|
-
if (paypalButtonRef.current) {
|
|
481
|
-
paypalButtonRef.current.href = url;
|
|
431
|
+
if (!r.ok) {
|
|
432
|
+
const errText = await r.text().catch(() => "");
|
|
433
|
+
throw new Error(errText || "Failed to save settings");
|
|
482
434
|
}
|
|
483
|
-
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
showUI();
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
setTimeout(tryInit, 50);
|
|
492
|
-
};
|
|
493
|
-
tryInit();
|
|
494
|
-
},
|
|
495
|
-
[showUI]
|
|
496
|
-
);
|
|
497
|
-
react.useEffect(() => {
|
|
498
|
-
currentRunId.current = ++runIdRef.current;
|
|
499
|
-
const runId = currentRunId.current;
|
|
500
|
-
let cancelled = false;
|
|
501
|
-
const run = async () => {
|
|
502
|
-
setConnState("loading");
|
|
503
|
-
setError(null);
|
|
504
|
-
setFinalUrl("");
|
|
505
|
-
try {
|
|
506
|
-
const r = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
507
|
-
method: "GET"
|
|
508
|
-
});
|
|
509
|
-
const st = await r.json().catch(() => ({}));
|
|
510
|
-
if (cancelled || runId !== currentRunId.current) return;
|
|
511
|
-
setStatusInfo(st);
|
|
512
|
-
const isConnected = (st == null ? void 0 : st.status) === "connected" && (st == null ? void 0 : st.seller_client_id_present) === true;
|
|
513
|
-
if (isConnected) {
|
|
514
|
-
setConnState("connected");
|
|
515
|
-
setShowManual(false);
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
} catch (e) {
|
|
519
|
-
console.error(e);
|
|
520
|
-
}
|
|
521
|
-
if (cachedUrl) {
|
|
522
|
-
console.log("Using prioritized cache...");
|
|
523
|
-
activatePayPal(cachedUrl, runId);
|
|
524
|
-
} else {
|
|
525
|
-
fetchFreshLink(runId);
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
run();
|
|
529
|
-
return () => {
|
|
530
|
-
cancelled = true;
|
|
531
|
-
currentRunId.current = 0;
|
|
532
|
-
};
|
|
533
|
-
}, [env, fetchFreshLink, activatePayPal]);
|
|
534
|
-
react.useLayoutEffect(() => {
|
|
535
|
-
window.onboardingCallback = async function(authCode, sharedId) {
|
|
536
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
537
|
-
try {
|
|
538
|
-
;
|
|
539
|
-
window.onbeforeunload = "";
|
|
540
|
-
} catch {
|
|
541
|
-
}
|
|
542
|
-
setOnboardingInProgress(true);
|
|
543
|
-
setConnState("loading");
|
|
544
|
-
setError(null);
|
|
545
|
-
const payload = {
|
|
546
|
-
authCode,
|
|
547
|
-
sharedId,
|
|
548
|
-
env: env === "sandbox" ? "sandbox" : "live"
|
|
549
|
-
};
|
|
550
|
-
try {
|
|
551
|
-
const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
|
|
552
|
-
method: "POST",
|
|
553
|
-
headers: { "content-type": "application/json" },
|
|
554
|
-
body: JSON.stringify(payload)
|
|
555
|
-
});
|
|
556
|
-
if (!res.ok) {
|
|
557
|
-
const txt = await res.text().catch(() => "");
|
|
558
|
-
throw new Error(txt || `Onboarding exchange failed (${res.status})`);
|
|
559
|
-
}
|
|
560
|
-
try {
|
|
561
|
-
const close1 = (_d = (_c = (_b = (_a = window.PAYPAL) == null ? void 0 : _a.apps) == null ? void 0 : _b.Signup) == null ? void 0 : _c.MiniBrowser) == null ? void 0 : _d.closeFlow;
|
|
562
|
-
if (typeof close1 === "function") close1();
|
|
563
|
-
} catch {
|
|
564
|
-
}
|
|
565
|
-
try {
|
|
566
|
-
const close2 = ((_g = (_f = (_e = window.PAYPAL) == null ? void 0 : _e.apps) == null ? void 0 : _f.Signup) == null ? void 0 : _g.miniBrowser) && window.PAYPAL.apps.Signup.miniBrowser.closeFlow;
|
|
567
|
-
if (typeof close2 === "function") close2();
|
|
568
|
-
} catch {
|
|
569
|
-
}
|
|
570
|
-
try {
|
|
571
|
-
localStorage.removeItem(CACHE_KEY);
|
|
572
|
-
localStorage.removeItem(RELOAD_KEY);
|
|
573
|
-
} catch {
|
|
574
|
-
}
|
|
575
|
-
window.location.href = window.location.href;
|
|
576
|
-
} catch (e) {
|
|
577
|
-
console.error(e);
|
|
578
|
-
setConnState("error");
|
|
579
|
-
setError((e == null ? void 0 : e.message) || "Exchange failed while saving credentials.");
|
|
580
|
-
setOnboardingInProgress(false);
|
|
581
|
-
}
|
|
582
|
-
};
|
|
583
|
-
return () => {
|
|
584
|
-
window.onboardingCallback = void 0;
|
|
585
|
-
};
|
|
586
|
-
}, [env]);
|
|
587
|
-
react.useLayoutEffect(() => {
|
|
588
|
-
const el = ppBtnMeasureRef.current;
|
|
589
|
-
if (!el) return;
|
|
590
|
-
const update = () => {
|
|
591
|
-
const w = Math.round(el.getBoundingClientRect().width || 0);
|
|
592
|
-
if (w > 0) setPpBtnWidth(w);
|
|
593
|
-
};
|
|
594
|
-
update();
|
|
595
|
-
let ro = null;
|
|
596
|
-
if (typeof ResizeObserver !== "undefined") {
|
|
597
|
-
ro = new ResizeObserver(() => update());
|
|
598
|
-
ro.observe(el);
|
|
599
|
-
} else {
|
|
600
|
-
window.addEventListener("resize", update);
|
|
601
|
-
}
|
|
602
|
-
return () => {
|
|
603
|
-
if (ro) ro.disconnect();
|
|
604
|
-
else window.removeEventListener("resize", update);
|
|
605
|
-
};
|
|
606
|
-
}, [connState, env, finalUrl]);
|
|
607
|
-
const handleConnectClick = (e) => {
|
|
608
|
-
if (connState !== "ready" || !finalUrl || onboardingInProgress) {
|
|
609
|
-
e.preventDefault();
|
|
610
|
-
}
|
|
611
|
-
};
|
|
612
|
-
const handleSaveManual = async () => {
|
|
613
|
-
if (!canSaveManual || onboardingInProgress) return;
|
|
614
|
-
setOnboardingInProgress(true);
|
|
615
|
-
setConnState("loading");
|
|
616
|
-
setError(null);
|
|
617
|
-
try {
|
|
618
|
-
const res = await fetch(SAVE_CREDENTIALS_ENDPOINT, {
|
|
619
|
-
method: "POST",
|
|
620
|
-
headers: { "content-type": "application/json" },
|
|
621
|
-
body: JSON.stringify({
|
|
622
|
-
clientId: clientId.trim(),
|
|
623
|
-
clientSecret: secret.trim()
|
|
624
|
-
})
|
|
625
|
-
});
|
|
626
|
-
if (!res.ok) {
|
|
627
|
-
const txt = await res.text().catch(() => "");
|
|
628
|
-
throw new Error(txt || `Save credentials failed (${res.status})`);
|
|
629
|
-
}
|
|
630
|
-
setConnState("connected");
|
|
631
|
-
setStatusInfo({
|
|
632
|
-
seller_client_id_masked: maskValue(clientId.trim()),
|
|
633
|
-
seller_client_secret_masked: "••••••••"
|
|
634
|
-
});
|
|
635
|
-
setShowManual(false);
|
|
636
|
-
try {
|
|
637
|
-
localStorage.removeItem(CACHE_KEY);
|
|
638
|
-
localStorage.removeItem(RELOAD_KEY);
|
|
639
|
-
} catch {
|
|
435
|
+
const json = await r.json().catch(() => ({}));
|
|
436
|
+
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
437
|
+
const saved = payload == null ? void 0 : payload.additional_settings;
|
|
438
|
+
if (saved && typeof saved === "object") {
|
|
439
|
+
setForm(mergeWithDefaults(saved));
|
|
640
440
|
}
|
|
441
|
+
setToast({ type: "success", message: "Settings saved" });
|
|
442
|
+
window.setTimeout(() => setToast(null), 2500);
|
|
641
443
|
} catch (e) {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
setError((e == null ? void 0 : e.message) || "Failed to save credentials.");
|
|
444
|
+
setToast({ type: "error", message: (e == null ? void 0 : e.message) || "Failed to save settings" });
|
|
445
|
+
window.setTimeout(() => setToast(null), 3500);
|
|
645
446
|
} finally {
|
|
646
|
-
|
|
447
|
+
setSaving(false);
|
|
647
448
|
}
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
method: "POST",
|
|
660
|
-
headers: { "content-type": "application/json" },
|
|
661
|
-
body: JSON.stringify({ environment: env })
|
|
662
|
-
});
|
|
663
|
-
if (!res.ok) {
|
|
664
|
-
const t = await res.text().catch(() => "");
|
|
665
|
-
throw new Error(t || `Disconnect failed (${res.status})`);
|
|
666
|
-
}
|
|
667
|
-
try {
|
|
668
|
-
localStorage.removeItem(CACHE_KEY);
|
|
669
|
-
localStorage.removeItem(RELOAD_KEY);
|
|
670
|
-
} catch {
|
|
449
|
+
}
|
|
450
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
451
|
+
/* @__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" }) }) }),
|
|
452
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
453
|
+
toast ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
454
|
+
"div",
|
|
455
|
+
{
|
|
456
|
+
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",
|
|
457
|
+
role: "status",
|
|
458
|
+
"aria-live": "polite",
|
|
459
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error", children: toast.message })
|
|
671
460
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
setOnboardingInProgress(false);
|
|
681
|
-
}
|
|
682
|
-
};
|
|
683
|
-
const handleEnvChange = async (e) => {
|
|
684
|
-
const next = e.target.value;
|
|
685
|
-
setEnv(next);
|
|
686
|
-
cachedUrl = null;
|
|
687
|
-
try {
|
|
688
|
-
await fetch("/admin/paypal/environment", {
|
|
689
|
-
method: "POST",
|
|
690
|
-
headers: { "content-type": "application/json" },
|
|
691
|
-
body: JSON.stringify({ environment: next })
|
|
692
|
-
});
|
|
693
|
-
} catch {
|
|
694
|
-
}
|
|
695
|
-
try {
|
|
696
|
-
localStorage.removeItem(CACHE_KEY);
|
|
697
|
-
localStorage.removeItem(RELOAD_KEY);
|
|
698
|
-
} catch {
|
|
699
|
-
}
|
|
700
|
-
};
|
|
701
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6", children: [
|
|
702
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
703
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold", children: "PayPal Gateway By Easy Payment" }),
|
|
704
|
-
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
705
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base p-4 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-y-6 md:grid-cols-[260px_1fr] md:items-start", children: [
|
|
706
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium pt-2", children: "Environment" }),
|
|
707
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-xl", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
708
|
-
"select",
|
|
709
|
-
{
|
|
710
|
-
value: env,
|
|
711
|
-
onChange: handleEnvChange,
|
|
712
|
-
disabled: onboardingInProgress,
|
|
713
|
-
className: "w-full rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm",
|
|
714
|
-
children: [
|
|
715
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "sandbox", children: "Sandbox (Test Mode)" }),
|
|
716
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "live", children: "Live (Production)" })
|
|
717
|
-
]
|
|
718
|
-
}
|
|
719
|
-
) }),
|
|
720
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium pt-2", children: env === "sandbox" ? "Connect to PayPal Sandbox" : "Connect to PayPal Live" }),
|
|
721
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-xl", children: connState === "connected" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
722
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-green-600 bg-green-50 p-3 rounded border border-green-200", children: [
|
|
723
|
-
"✅ Successfully connected to PayPal!",
|
|
724
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
725
|
-
"a",
|
|
726
|
-
{
|
|
727
|
-
"data-paypal-button": "true",
|
|
728
|
-
"data-paypal-onboard-complete": "onboardingCallback",
|
|
729
|
-
href: "#",
|
|
730
|
-
style: { display: "none" },
|
|
731
|
-
children: "PayPal"
|
|
732
|
-
}
|
|
733
|
-
)
|
|
734
|
-
] }),
|
|
735
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 rounded-md border border-ui-border-base bg-ui-bg-subtle p-3 text-xs text-ui-fg-subtle", children: [
|
|
736
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-ui-fg-base", children: "Connected PayPal account" }),
|
|
737
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1", children: [
|
|
738
|
-
"Email:",
|
|
739
|
-
" ",
|
|
740
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-ui-fg-base", children: (statusInfo == null ? void 0 : statusInfo.seller_email) || "Unavailable" })
|
|
741
|
-
] })
|
|
742
|
-
] }),
|
|
743
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
744
|
-
"button",
|
|
745
|
-
{
|
|
746
|
-
type: "button",
|
|
747
|
-
onClick: handleDisconnect,
|
|
748
|
-
disabled: onboardingInProgress,
|
|
749
|
-
className: "rounded-md border border-ui-border-base px-3 py-2 text-sm font-medium hover:bg-ui-bg-subtle disabled:opacity-50 disabled:cursor-not-allowed",
|
|
750
|
-
children: "Disconnect"
|
|
751
|
-
}
|
|
752
|
-
) })
|
|
753
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
754
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
755
|
-
"div",
|
|
756
|
-
{
|
|
757
|
-
ref: initLoaderRef,
|
|
758
|
-
id: "init-loader",
|
|
759
|
-
className: `status-msg mb-4 ${connState !== "loading" ? "hidden" : "block"}`,
|
|
760
|
-
children: [
|
|
761
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "loader inline-block align-middle mr-2" }),
|
|
762
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { id: "loader-text", className: "text-sm", children: onboardingInProgress ? "Configuring connection to PayPal…" : "Checking connection..." })
|
|
763
|
-
]
|
|
764
|
-
}
|
|
765
|
-
),
|
|
766
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${connState === "ready" ? "block" : "hidden"}`, children: [
|
|
767
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
768
|
-
"a",
|
|
769
|
-
{
|
|
770
|
-
ref: (node) => {
|
|
771
|
-
paypalButtonRef.current = node;
|
|
772
|
-
ppBtnMeasureRef.current = node;
|
|
773
|
-
},
|
|
774
|
-
id: "paypal-button",
|
|
775
|
-
"data-paypal-button": "true",
|
|
776
|
-
href: finalUrl || "#",
|
|
777
|
-
"data-paypal-onboard-complete": "onboardingCallback",
|
|
778
|
-
onClick: handleConnectClick,
|
|
779
|
-
className: "btn-paypal",
|
|
780
|
-
style: {
|
|
781
|
-
borderRadius: "50px",
|
|
782
|
-
textDecoration: "none",
|
|
783
|
-
display: "inline-block",
|
|
784
|
-
fontWeight: "bold",
|
|
785
|
-
border: "none",
|
|
786
|
-
cursor: onboardingInProgress ? "not-allowed" : "pointer",
|
|
787
|
-
opacity: onboardingInProgress ? 0.6 : 1,
|
|
788
|
-
pointerEvents: onboardingInProgress ? "none" : "auto"
|
|
789
|
-
},
|
|
790
|
-
children: "Connect to PayPal"
|
|
791
|
-
}
|
|
792
|
-
),
|
|
793
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
794
|
-
"div",
|
|
795
|
-
{
|
|
796
|
-
className: "mt-2",
|
|
797
|
-
style: {
|
|
798
|
-
width: ppBtnWidth ? `${ppBtnWidth}px` : "auto",
|
|
799
|
-
marginTop: "20px",
|
|
800
|
-
marginBottom: "10px"
|
|
801
|
-
},
|
|
802
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] text-ui-fg-muted leading-none", children: "OR" }) })
|
|
803
|
-
}
|
|
804
|
-
),
|
|
805
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
806
|
-
"button",
|
|
807
|
-
{
|
|
808
|
-
type: "button",
|
|
809
|
-
onClick: () => setShowManual(!showManual),
|
|
810
|
-
disabled: onboardingInProgress,
|
|
811
|
-
className: "text-sm text-ui-fg-interactive underline whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed",
|
|
812
|
-
children: "Click here to insert credentials manually"
|
|
813
|
-
}
|
|
814
|
-
) })
|
|
815
|
-
] }),
|
|
816
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `${connState === "ready" ? "hidden" : "block"} mt-3`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
461
|
+
) : null,
|
|
462
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
463
|
+
SectionCard$1,
|
|
464
|
+
{
|
|
465
|
+
title: "Additional Settings",
|
|
466
|
+
description: "These settings control checkout behavior, PayPal experience, and logging.",
|
|
467
|
+
right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
468
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
817
469
|
"button",
|
|
818
470
|
{
|
|
819
471
|
type: "button",
|
|
820
|
-
onClick:
|
|
821
|
-
disabled:
|
|
822
|
-
className: "text-sm text-ui-fg-
|
|
823
|
-
children:
|
|
472
|
+
onClick: onSave,
|
|
473
|
+
disabled: saving || loading,
|
|
474
|
+
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",
|
|
475
|
+
children: saving ? "Saving..." : "Save settings"
|
|
476
|
+
}
|
|
477
|
+
),
|
|
478
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading…" }) : null
|
|
479
|
+
] }),
|
|
480
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
|
|
481
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Payment action", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
482
|
+
"select",
|
|
483
|
+
{
|
|
484
|
+
value: form.paymentAction,
|
|
485
|
+
onChange: (e) => setForm((p) => ({ ...p, paymentAction: e.target.value })),
|
|
486
|
+
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",
|
|
487
|
+
children: [
|
|
488
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "capture", children: "Capture" }),
|
|
489
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorize", children: "Authorize" })
|
|
490
|
+
]
|
|
824
491
|
}
|
|
825
492
|
) }),
|
|
826
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
827
|
-
"
|
|
493
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Brand Name", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
494
|
+
"input",
|
|
828
495
|
{
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
className:
|
|
832
|
-
|
|
496
|
+
value: form.brandName,
|
|
497
|
+
onChange: (e) => setForm((p) => ({ ...p, brandName: e.target.value })),
|
|
498
|
+
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",
|
|
499
|
+
placeholder: "PayPal"
|
|
833
500
|
}
|
|
834
|
-
)
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
"
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
value:
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
)
|
|
850
|
-
] }),
|
|
851
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
852
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Client Secret" }),
|
|
853
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
854
|
-
"input",
|
|
855
|
-
{
|
|
856
|
-
type: "password",
|
|
857
|
-
value: secret,
|
|
858
|
-
onChange: (e) => setSecret(e.target.value),
|
|
859
|
-
disabled: onboardingInProgress,
|
|
860
|
-
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
861
|
-
placeholder: env === "sandbox" ? "Sandbox Secret" : "Live Secret"
|
|
862
|
-
}
|
|
863
|
-
)
|
|
864
|
-
] }),
|
|
865
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:col-span-2", children: [
|
|
866
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Merchant ID (optional)" }),
|
|
501
|
+
) }),
|
|
502
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Landing Page", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
503
|
+
"select",
|
|
504
|
+
{
|
|
505
|
+
value: form.landingPage,
|
|
506
|
+
onChange: (e) => setForm((p) => ({ ...p, landingPage: e.target.value })),
|
|
507
|
+
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",
|
|
508
|
+
children: [
|
|
509
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "no_preference", children: "No Preference" }),
|
|
510
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "login", children: "Login" }),
|
|
511
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "billing", children: "Billing" })
|
|
512
|
+
]
|
|
513
|
+
}
|
|
514
|
+
) }),
|
|
515
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Instant Payments", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
867
516
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
868
517
|
"input",
|
|
869
518
|
{
|
|
870
|
-
type: "
|
|
871
|
-
|
|
872
|
-
onChange: (e) =>
|
|
873
|
-
|
|
874
|
-
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
875
|
-
placeholder: "Merchant ID"
|
|
876
|
-
}
|
|
877
|
-
)
|
|
878
|
-
] }),
|
|
879
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:col-span-2 flex items-center gap-2 mt-2", children: [
|
|
880
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
881
|
-
"button",
|
|
882
|
-
{
|
|
883
|
-
type: "button",
|
|
884
|
-
className: "rounded-md border border-ui-border-base px-3 py-2 text-sm font-medium hover:bg-ui-bg-subtle disabled:opacity-50 disabled:cursor-not-allowed",
|
|
885
|
-
onClick: () => setShowManual(false),
|
|
886
|
-
disabled: onboardingInProgress,
|
|
887
|
-
children: "Cancel"
|
|
519
|
+
type: "checkbox",
|
|
520
|
+
checked: form.requireInstantPayment,
|
|
521
|
+
onChange: (e) => setForm((p) => ({ ...p, requireInstantPayment: e.target.checked })),
|
|
522
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
888
523
|
}
|
|
889
524
|
),
|
|
890
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
525
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Require Instant Payment" })
|
|
526
|
+
] }) }),
|
|
527
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
528
|
+
FieldRow$1,
|
|
529
|
+
{
|
|
530
|
+
label: "Billing Address",
|
|
531
|
+
hint: "If the billing address is empty and PayPal provides a shipping address, the order will use the shipping address as the billing address.",
|
|
532
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
533
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
534
|
+
"input",
|
|
535
|
+
{
|
|
536
|
+
type: "checkbox",
|
|
537
|
+
checked: form.useShippingAsBilling,
|
|
538
|
+
onChange: (e) => setForm((p) => ({ ...p, useShippingAsBilling: e.target.checked })),
|
|
539
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
540
|
+
}
|
|
541
|
+
),
|
|
542
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Use PayPal Shipping Address as Billing" })
|
|
543
|
+
] })
|
|
544
|
+
}
|
|
545
|
+
),
|
|
546
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
547
|
+
FieldRow$1,
|
|
548
|
+
{
|
|
549
|
+
label: "Send Item Details",
|
|
550
|
+
hint: "Include all line item details in the payment request to PayPal so that they can be seen from the PayPal transaction details page.",
|
|
551
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
552
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
553
|
+
"input",
|
|
554
|
+
{
|
|
555
|
+
type: "checkbox",
|
|
556
|
+
checked: form.sendItemDetails,
|
|
557
|
+
onChange: (e) => setForm((p) => ({ ...p, sendItemDetails: e.target.checked })),
|
|
558
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
559
|
+
}
|
|
560
|
+
),
|
|
561
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Send line item details to PayPal" })
|
|
562
|
+
] })
|
|
563
|
+
}
|
|
564
|
+
),
|
|
565
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
566
|
+
FieldRow$1,
|
|
567
|
+
{
|
|
568
|
+
label: "Order Review Page",
|
|
569
|
+
hint: "Payments from the Product or Cart page skip the review step and go straight to the Thank You page.",
|
|
570
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
571
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
572
|
+
"input",
|
|
573
|
+
{
|
|
574
|
+
type: "checkbox",
|
|
575
|
+
checked: form.skipOrderReviewPage,
|
|
576
|
+
onChange: (e) => setForm((p) => ({ ...p, skipOrderReviewPage: e.target.checked })),
|
|
577
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
578
|
+
}
|
|
579
|
+
),
|
|
580
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Skip Order Review Page" })
|
|
581
|
+
] })
|
|
582
|
+
}
|
|
583
|
+
),
|
|
584
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Invoice prefix", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
585
|
+
"input",
|
|
586
|
+
{
|
|
587
|
+
value: form.invoicePrefix,
|
|
588
|
+
onChange: (e) => setForm((p) => ({ ...p, invoicePrefix: e.target.value })),
|
|
589
|
+
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",
|
|
590
|
+
placeholder: "WC-"
|
|
591
|
+
}
|
|
592
|
+
) }),
|
|
593
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Credit Card Statement Name", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
594
|
+
"input",
|
|
595
|
+
{
|
|
596
|
+
value: form.creditCardStatementName,
|
|
597
|
+
onChange: (e) => setForm((p) => ({ ...p, creditCardStatementName: e.target.value })),
|
|
598
|
+
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",
|
|
599
|
+
placeholder: "PayPal"
|
|
600
|
+
}
|
|
601
|
+
) }),
|
|
602
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
603
|
+
FieldRow$1,
|
|
604
|
+
{
|
|
605
|
+
label: "Debug log",
|
|
606
|
+
hint: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
607
|
+
"Log PayPal events such as Webhook, Payment, Refund.",
|
|
608
|
+
" ",
|
|
609
|
+
form.logPath ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
610
|
+
"Log location: ",
|
|
611
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: form.logPath })
|
|
612
|
+
] }) : null
|
|
613
|
+
] }),
|
|
614
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
615
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
616
|
+
"input",
|
|
617
|
+
{
|
|
618
|
+
type: "checkbox",
|
|
619
|
+
checked: form.enableLogging,
|
|
620
|
+
onChange: (e) => setForm((p) => ({ ...p, enableLogging: e.target.checked })),
|
|
621
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
622
|
+
}
|
|
623
|
+
),
|
|
624
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable logging" })
|
|
625
|
+
] })
|
|
626
|
+
}
|
|
627
|
+
)
|
|
628
|
+
] })
|
|
629
|
+
}
|
|
630
|
+
)
|
|
631
|
+
] }) });
|
|
937
632
|
}
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
633
|
+
const config = adminSdk.defineRouteConfig({
|
|
634
|
+
label: "PayPal Connection",
|
|
635
|
+
hide: true
|
|
636
|
+
});
|
|
637
|
+
if (typeof window !== "undefined") {
|
|
638
|
+
const preloadHref = "https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js";
|
|
639
|
+
const existingPreload = document.head.querySelector(
|
|
640
|
+
`link[rel="preload"][href="${preloadHref}"]`
|
|
641
|
+
);
|
|
642
|
+
if (!existingPreload) {
|
|
643
|
+
const preloadLink = document.createElement("link");
|
|
644
|
+
preloadLink.rel = "preload";
|
|
645
|
+
preloadLink.href = preloadHref;
|
|
646
|
+
preloadLink.as = "script";
|
|
647
|
+
document.head.appendChild(preloadLink);
|
|
648
|
+
}
|
|
649
|
+
const existingScript = document.getElementById(
|
|
650
|
+
"paypal-partner-js"
|
|
651
|
+
);
|
|
652
|
+
if (!existingScript) {
|
|
653
|
+
const ppScript = document.createElement("script");
|
|
654
|
+
ppScript.id = "paypal-partner-js";
|
|
655
|
+
ppScript.src = preloadHref;
|
|
656
|
+
ppScript.async = true;
|
|
657
|
+
document.head.appendChild(ppScript);
|
|
962
658
|
}
|
|
963
|
-
];
|
|
964
|
-
function cx$1(...parts) {
|
|
965
|
-
return parts.filter(Boolean).join(" ");
|
|
966
659
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
660
|
+
const SERVICE_URL = "/admin/paypal/onboarding-link";
|
|
661
|
+
const CACHE_KEY = "pp_onboard_cache";
|
|
662
|
+
const RELOAD_KEY = "pp_onboard_reloaded_once";
|
|
663
|
+
const CACHE_EXPIRY = 10 * 60 * 1e3;
|
|
664
|
+
const ONBOARDING_COMPLETE_ENDPOINT = "/admin/paypal/onboard-complete";
|
|
665
|
+
const STATUS_ENDPOINT = "/admin/paypal/status";
|
|
666
|
+
const SAVE_CREDENTIALS_ENDPOINT = "/admin/paypal/save-credentials";
|
|
667
|
+
const DISCONNECT_ENDPOINT = "/admin/paypal/disconnect";
|
|
668
|
+
let cachedUrl = null;
|
|
669
|
+
if (typeof window !== "undefined") {
|
|
670
|
+
try {
|
|
671
|
+
const cached = localStorage.getItem(CACHE_KEY);
|
|
672
|
+
if (cached) {
|
|
673
|
+
const data = JSON.parse(cached);
|
|
674
|
+
if ((/* @__PURE__ */ new Date()).getTime() - data.ts < CACHE_EXPIRY) {
|
|
675
|
+
cachedUrl = data.url;
|
|
981
676
|
}
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
title,
|
|
987
|
-
description,
|
|
988
|
-
right,
|
|
989
|
-
children
|
|
990
|
-
}) {
|
|
991
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
992
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
|
|
993
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
994
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
|
|
995
|
-
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
|
|
996
|
-
] }),
|
|
997
|
-
right
|
|
998
|
-
] }),
|
|
999
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
|
|
1000
|
-
] });
|
|
1001
|
-
}
|
|
1002
|
-
function FieldRow$1({
|
|
1003
|
-
label,
|
|
1004
|
-
hint,
|
|
1005
|
-
children
|
|
1006
|
-
}) {
|
|
1007
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
|
|
1008
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
|
|
1009
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
|
|
1010
|
-
hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
|
|
1011
|
-
] }),
|
|
1012
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
|
|
1013
|
-
] });
|
|
677
|
+
}
|
|
678
|
+
} catch (e) {
|
|
679
|
+
console.error("Cache read error:", e);
|
|
680
|
+
}
|
|
1014
681
|
}
|
|
1015
|
-
function
|
|
1016
|
-
|
|
1017
|
-
const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM }));
|
|
1018
|
-
const [loading, setLoading] = react.useState(false);
|
|
1019
|
-
const [saving, setSaving] = react.useState(false);
|
|
1020
|
-
const [toast, setToast] = react.useState(null);
|
|
1021
|
-
const didInit = react.useRef(false);
|
|
682
|
+
function PayPalConnectionPage() {
|
|
683
|
+
const [env, setEnv] = react.useState("sandbox");
|
|
1022
684
|
react.useEffect(() => {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
685
|
+
fetch("/admin/paypal/environment", { method: "GET" }).then((r) => r.json()).then((d) => {
|
|
686
|
+
const v = (d == null ? void 0 : d.environment) === "live" ? "live" : "sandbox";
|
|
687
|
+
setEnv(v);
|
|
688
|
+
}).catch(() => {
|
|
689
|
+
});
|
|
690
|
+
}, []);
|
|
691
|
+
const [connState, setConnState] = react.useState("loading");
|
|
692
|
+
const [error, setError] = react.useState(null);
|
|
693
|
+
const [finalUrl, setFinalUrl] = react.useState("");
|
|
694
|
+
const [showManual, setShowManual] = react.useState(false);
|
|
695
|
+
const [clientId, setClientId] = react.useState("");
|
|
696
|
+
const [secret, setSecret] = react.useState("");
|
|
697
|
+
const [merchantId, setMerchantId] = react.useState("");
|
|
698
|
+
const [statusInfo, setStatusInfo] = react.useState(null);
|
|
699
|
+
const [onboardingInProgress, setOnboardingInProgress] = react.useState(false);
|
|
700
|
+
const initLoaderRef = react.useRef(null);
|
|
701
|
+
const paypalButtonRef = react.useRef(null);
|
|
702
|
+
const errorLogRef = react.useRef(null);
|
|
703
|
+
const runIdRef = react.useRef(0);
|
|
704
|
+
const currentRunId = react.useRef(0);
|
|
705
|
+
const ppBtnMeasureRef = react.useRef(null);
|
|
706
|
+
const [ppBtnWidth, setPpBtnWidth] = react.useState(null);
|
|
707
|
+
const canSaveManual = react.useMemo(() => {
|
|
708
|
+
return clientId.trim().length > 0 && secret.trim().length > 0;
|
|
709
|
+
}, [clientId, secret]);
|
|
710
|
+
const maskValue = react.useCallback((value, visibleChars = 4) => {
|
|
711
|
+
if (!value) return "";
|
|
712
|
+
if (value.length <= visibleChars) {
|
|
713
|
+
return "•".repeat(value.length);
|
|
714
|
+
}
|
|
715
|
+
return `${"•".repeat(Math.max(0, value.length - visibleChars))}${value.slice(
|
|
716
|
+
-visibleChars
|
|
717
|
+
)}`;
|
|
718
|
+
}, []);
|
|
719
|
+
const fetchFreshLink = react.useCallback(
|
|
720
|
+
(runId) => {
|
|
721
|
+
if (initLoaderRef.current) {
|
|
722
|
+
const loaderText = initLoaderRef.current.querySelector("#loader-text");
|
|
723
|
+
if (loaderText)
|
|
724
|
+
loaderText.textContent = "Generating onboarding session...";
|
|
725
|
+
}
|
|
726
|
+
fetch(SERVICE_URL, {
|
|
727
|
+
method: "POST",
|
|
728
|
+
headers: { "content-type": "application/json" },
|
|
729
|
+
body: JSON.stringify({
|
|
730
|
+
products: ["PPCP"]
|
|
731
|
+
})
|
|
732
|
+
}).then((r) => r.json()).then((data) => {
|
|
733
|
+
if (runId !== currentRunId.current) return;
|
|
734
|
+
const href = data == null ? void 0 : data.onboarding_url;
|
|
735
|
+
if (!href) {
|
|
736
|
+
showError("Onboarding URL not returned.");
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
const finalUrl2 = href + (href.includes("?") ? "&" : "?") + "displayMode=minibrowser";
|
|
740
|
+
localStorage.setItem(
|
|
741
|
+
CACHE_KEY,
|
|
742
|
+
JSON.stringify({
|
|
743
|
+
url: finalUrl2,
|
|
744
|
+
ts: Date.now()
|
|
745
|
+
})
|
|
746
|
+
);
|
|
747
|
+
if (!localStorage.getItem(RELOAD_KEY)) {
|
|
748
|
+
localStorage.setItem(RELOAD_KEY, "1");
|
|
749
|
+
window.location.reload();
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
activatePayPal(finalUrl2, runId);
|
|
753
|
+
}).catch(() => {
|
|
754
|
+
if (runId !== currentRunId.current) return;
|
|
755
|
+
showError("Unable to connect to service.");
|
|
756
|
+
});
|
|
757
|
+
},
|
|
758
|
+
[env]
|
|
759
|
+
);
|
|
760
|
+
const showUI = react.useCallback(() => {
|
|
761
|
+
var _a, _b, _c, _d;
|
|
762
|
+
const btn = document.querySelector('[data-paypal-button="true"]');
|
|
763
|
+
if (btn && ((_d = (_c = (_b = (_a = window.PAYPAL) == null ? void 0 : _a.apps) == null ? void 0 : _b.Signup) == null ? void 0 : _c.miniBrowser) == null ? void 0 : _d.init)) {
|
|
764
|
+
window.PAYPAL.apps.Signup.miniBrowser.init();
|
|
765
|
+
}
|
|
766
|
+
setConnState("ready");
|
|
767
|
+
}, []);
|
|
768
|
+
const showError = react.useCallback((msg) => {
|
|
769
|
+
setConnState("error");
|
|
770
|
+
setError(msg);
|
|
771
|
+
}, []);
|
|
772
|
+
const activatePayPal = react.useCallback(
|
|
773
|
+
(url, runId) => {
|
|
774
|
+
if (paypalButtonRef.current) {
|
|
775
|
+
paypalButtonRef.current.href = url;
|
|
776
|
+
}
|
|
777
|
+
setFinalUrl(url);
|
|
778
|
+
const tryInit = () => {
|
|
779
|
+
var _a, _b;
|
|
780
|
+
if (runId !== currentRunId.current) return;
|
|
781
|
+
if ((_b = (_a = window.PAYPAL) == null ? void 0 : _a.apps) == null ? void 0 : _b.Signup) {
|
|
782
|
+
showUI();
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
setTimeout(tryInit, 50);
|
|
786
|
+
};
|
|
787
|
+
tryInit();
|
|
788
|
+
},
|
|
789
|
+
[showUI]
|
|
790
|
+
);
|
|
791
|
+
react.useEffect(() => {
|
|
792
|
+
currentRunId.current = ++runIdRef.current;
|
|
793
|
+
const runId = currentRunId.current;
|
|
794
|
+
let cancelled = false;
|
|
795
|
+
const run = async () => {
|
|
796
|
+
setConnState("loading");
|
|
797
|
+
setError(null);
|
|
798
|
+
setFinalUrl("");
|
|
799
|
+
try {
|
|
800
|
+
const r = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
801
|
+
method: "GET"
|
|
802
|
+
});
|
|
803
|
+
const st = await r.json().catch(() => ({}));
|
|
804
|
+
if (cancelled || runId !== currentRunId.current) return;
|
|
805
|
+
setStatusInfo(st);
|
|
806
|
+
const isConnected = (st == null ? void 0 : st.status) === "connected" && (st == null ? void 0 : st.seller_client_id_present) === true;
|
|
807
|
+
if (isConnected) {
|
|
808
|
+
setConnState("connected");
|
|
809
|
+
setShowManual(false);
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
} catch (e) {
|
|
813
|
+
console.error(e);
|
|
814
|
+
}
|
|
815
|
+
if (cachedUrl) {
|
|
816
|
+
console.log("Using prioritized cache...");
|
|
817
|
+
activatePayPal(cachedUrl, runId);
|
|
818
|
+
} else {
|
|
819
|
+
fetchFreshLink(runId);
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
run();
|
|
823
|
+
return () => {
|
|
824
|
+
cancelled = true;
|
|
825
|
+
currentRunId.current = 0;
|
|
826
|
+
};
|
|
827
|
+
}, [env, fetchFreshLink, activatePayPal]);
|
|
828
|
+
react.useLayoutEffect(() => {
|
|
829
|
+
window.onboardingCallback = async function(authCode, sharedId) {
|
|
830
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1026
831
|
try {
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
832
|
+
;
|
|
833
|
+
window.onbeforeunload = "";
|
|
834
|
+
} catch {
|
|
835
|
+
}
|
|
836
|
+
setOnboardingInProgress(true);
|
|
837
|
+
setConnState("loading");
|
|
838
|
+
setError(null);
|
|
839
|
+
const payload = {
|
|
840
|
+
authCode,
|
|
841
|
+
sharedId,
|
|
842
|
+
env: env === "sandbox" ? "sandbox" : "live"
|
|
843
|
+
};
|
|
844
|
+
try {
|
|
845
|
+
const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
|
|
846
|
+
method: "POST",
|
|
847
|
+
headers: { "content-type": "application/json" },
|
|
848
|
+
body: JSON.stringify(payload)
|
|
1031
849
|
});
|
|
1032
|
-
if (!
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
1036
|
-
if (saved && typeof saved === "object") {
|
|
1037
|
-
setForm(mergeWithDefaults(saved));
|
|
850
|
+
if (!res.ok) {
|
|
851
|
+
const txt = await res.text().catch(() => "");
|
|
852
|
+
throw new Error(txt || `Onboarding exchange failed (${res.status})`);
|
|
1038
853
|
}
|
|
1039
|
-
|
|
1040
|
-
|
|
854
|
+
try {
|
|
855
|
+
const close1 = (_d = (_c = (_b = (_a = window.PAYPAL) == null ? void 0 : _a.apps) == null ? void 0 : _b.Signup) == null ? void 0 : _c.MiniBrowser) == null ? void 0 : _d.closeFlow;
|
|
856
|
+
if (typeof close1 === "function") close1();
|
|
857
|
+
} catch {
|
|
858
|
+
}
|
|
859
|
+
try {
|
|
860
|
+
const close2 = ((_g = (_f = (_e = window.PAYPAL) == null ? void 0 : _e.apps) == null ? void 0 : _f.Signup) == null ? void 0 : _g.miniBrowser) && window.PAYPAL.apps.Signup.miniBrowser.closeFlow;
|
|
861
|
+
if (typeof close2 === "function") close2();
|
|
862
|
+
} catch {
|
|
863
|
+
}
|
|
864
|
+
try {
|
|
865
|
+
localStorage.removeItem(CACHE_KEY);
|
|
866
|
+
localStorage.removeItem(RELOAD_KEY);
|
|
867
|
+
} catch {
|
|
868
|
+
}
|
|
869
|
+
window.location.href = window.location.href;
|
|
870
|
+
} catch (e) {
|
|
871
|
+
console.error(e);
|
|
872
|
+
setConnState("error");
|
|
873
|
+
setError((e == null ? void 0 : e.message) || "Exchange failed while saving credentials.");
|
|
874
|
+
setOnboardingInProgress(false);
|
|
1041
875
|
}
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
|
|
876
|
+
};
|
|
877
|
+
return () => {
|
|
878
|
+
window.onboardingCallback = void 0;
|
|
879
|
+
};
|
|
880
|
+
}, [env]);
|
|
881
|
+
react.useLayoutEffect(() => {
|
|
882
|
+
const el = ppBtnMeasureRef.current;
|
|
883
|
+
if (!el) return;
|
|
884
|
+
const update = () => {
|
|
885
|
+
const w = Math.round(el.getBoundingClientRect().width || 0);
|
|
886
|
+
if (w > 0) setPpBtnWidth(w);
|
|
887
|
+
};
|
|
888
|
+
update();
|
|
889
|
+
let ro = null;
|
|
890
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
891
|
+
ro = new ResizeObserver(() => update());
|
|
892
|
+
ro.observe(el);
|
|
893
|
+
} else {
|
|
894
|
+
window.addEventListener("resize", update);
|
|
895
|
+
}
|
|
896
|
+
return () => {
|
|
897
|
+
if (ro) ro.disconnect();
|
|
898
|
+
else window.removeEventListener("resize", update);
|
|
899
|
+
};
|
|
900
|
+
}, [connState, env, finalUrl]);
|
|
901
|
+
const handleConnectClick = (e) => {
|
|
902
|
+
if (connState !== "ready" || !finalUrl || onboardingInProgress) {
|
|
903
|
+
e.preventDefault();
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
const handleSaveManual = async () => {
|
|
907
|
+
if (!canSaveManual || onboardingInProgress) return;
|
|
908
|
+
setOnboardingInProgress(true);
|
|
909
|
+
setConnState("loading");
|
|
910
|
+
setError(null);
|
|
1045
911
|
try {
|
|
1046
|
-
|
|
1047
|
-
const r = await fetch("/admin/paypal/settings", {
|
|
912
|
+
const res = await fetch(SAVE_CREDENTIALS_ENDPOINT, {
|
|
1048
913
|
method: "POST",
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
}
|
|
1054
|
-
body: JSON.stringify({ advanced_card_payments: form })
|
|
914
|
+
headers: { "content-type": "application/json" },
|
|
915
|
+
body: JSON.stringify({
|
|
916
|
+
clientId: clientId.trim(),
|
|
917
|
+
clientSecret: secret.trim()
|
|
918
|
+
})
|
|
1055
919
|
});
|
|
1056
|
-
if (!
|
|
1057
|
-
const
|
|
1058
|
-
|
|
1059
|
-
window.setTimeout(() => setToast(null), 3500);
|
|
1060
|
-
return;
|
|
920
|
+
if (!res.ok) {
|
|
921
|
+
const txt = await res.text().catch(() => "");
|
|
922
|
+
throw new Error(txt || `Save credentials failed (${res.status})`);
|
|
1061
923
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
924
|
+
setConnState("connected");
|
|
925
|
+
setStatusInfo({
|
|
926
|
+
seller_client_id_masked: maskValue(clientId.trim()),
|
|
927
|
+
seller_client_secret_masked: "••••••••"
|
|
928
|
+
});
|
|
929
|
+
setShowManual(false);
|
|
930
|
+
try {
|
|
931
|
+
localStorage.removeItem(CACHE_KEY);
|
|
932
|
+
localStorage.removeItem(RELOAD_KEY);
|
|
933
|
+
} catch {
|
|
1067
934
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
935
|
+
} catch (e) {
|
|
936
|
+
console.error(e);
|
|
937
|
+
setConnState("error");
|
|
938
|
+
setError((e == null ? void 0 : e.message) || "Failed to save credentials.");
|
|
1070
939
|
} finally {
|
|
1071
|
-
|
|
940
|
+
setOnboardingInProgress(false);
|
|
1072
941
|
}
|
|
1073
|
-
}
|
|
1074
|
-
const
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
/* @__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" }) }) }),
|
|
1092
|
-
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
1093
|
-
toast ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1094
|
-
"div",
|
|
1095
|
-
{
|
|
1096
|
-
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",
|
|
1097
|
-
role: "status",
|
|
1098
|
-
"aria-live": "polite",
|
|
1099
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error", children: toast.message })
|
|
942
|
+
};
|
|
943
|
+
const handleDisconnect = async () => {
|
|
944
|
+
if (onboardingInProgress) return;
|
|
945
|
+
if (!window.confirm("Disconnect PayPal for this environment?")) return;
|
|
946
|
+
setOnboardingInProgress(true);
|
|
947
|
+
setConnState("loading");
|
|
948
|
+
setError(null);
|
|
949
|
+
setFinalUrl("");
|
|
950
|
+
setShowManual(false);
|
|
951
|
+
try {
|
|
952
|
+
const res = await fetch(DISCONNECT_ENDPOINT, {
|
|
953
|
+
method: "POST",
|
|
954
|
+
headers: { "content-type": "application/json" },
|
|
955
|
+
body: JSON.stringify({ environment: env })
|
|
956
|
+
});
|
|
957
|
+
if (!res.ok) {
|
|
958
|
+
const t = await res.text().catch(() => "");
|
|
959
|
+
throw new Error(t || `Disconnect failed (${res.status})`);
|
|
1100
960
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
{
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
961
|
+
try {
|
|
962
|
+
localStorage.removeItem(CACHE_KEY);
|
|
963
|
+
localStorage.removeItem(RELOAD_KEY);
|
|
964
|
+
} catch {
|
|
965
|
+
}
|
|
966
|
+
currentRunId.current = ++runIdRef.current;
|
|
967
|
+
const runId = currentRunId.current;
|
|
968
|
+
fetchFreshLink(runId);
|
|
969
|
+
} catch (e) {
|
|
970
|
+
console.error(e);
|
|
971
|
+
setConnState("error");
|
|
972
|
+
setError((e == null ? void 0 : e.message) || "Failed to disconnect.");
|
|
973
|
+
} finally {
|
|
974
|
+
setOnboardingInProgress(false);
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
const handleEnvChange = async (e) => {
|
|
978
|
+
const next = e.target.value;
|
|
979
|
+
setEnv(next);
|
|
980
|
+
cachedUrl = null;
|
|
981
|
+
try {
|
|
982
|
+
await fetch("/admin/paypal/environment", {
|
|
983
|
+
method: "POST",
|
|
984
|
+
headers: { "content-type": "application/json" },
|
|
985
|
+
body: JSON.stringify({ environment: next })
|
|
986
|
+
});
|
|
987
|
+
} catch {
|
|
988
|
+
}
|
|
989
|
+
try {
|
|
990
|
+
localStorage.removeItem(CACHE_KEY);
|
|
991
|
+
localStorage.removeItem(RELOAD_KEY);
|
|
992
|
+
} catch {
|
|
993
|
+
}
|
|
994
|
+
};
|
|
995
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6", children: [
|
|
996
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
997
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold", children: "PayPal Gateway By Easy Payment" }),
|
|
998
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
999
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-ui-border-base p-4 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-y-6 md:grid-cols-[260px_1fr] md:items-start", children: [
|
|
1000
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium pt-2", children: "Environment" }),
|
|
1001
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-xl", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1002
|
+
"select",
|
|
1003
|
+
{
|
|
1004
|
+
value: env,
|
|
1005
|
+
onChange: handleEnvChange,
|
|
1006
|
+
disabled: onboardingInProgress,
|
|
1007
|
+
className: "w-full rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm",
|
|
1008
|
+
children: [
|
|
1009
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "sandbox", children: "Sandbox (Test Mode)" }),
|
|
1010
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "live", children: "Live (Production)" })
|
|
1011
|
+
]
|
|
1012
|
+
}
|
|
1013
|
+
) }),
|
|
1014
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium pt-2", children: env === "sandbox" ? "Connect to PayPal Sandbox" : "Connect to PayPal Live" }),
|
|
1015
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-xl", children: connState === "connected" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1016
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-green-600 bg-green-50 p-3 rounded border border-green-200", children: [
|
|
1017
|
+
"✅ Successfully connected to PayPal!",
|
|
1018
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1019
|
+
"a",
|
|
1020
|
+
{
|
|
1021
|
+
"data-paypal-button": "true",
|
|
1022
|
+
"data-paypal-onboard-complete": "onboardingCallback",
|
|
1023
|
+
href: "#",
|
|
1024
|
+
style: { display: "none" },
|
|
1025
|
+
children: "PayPal"
|
|
1026
|
+
}
|
|
1027
|
+
)
|
|
1028
|
+
] }),
|
|
1029
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 rounded-md border border-ui-border-base bg-ui-bg-subtle p-3 text-xs text-ui-fg-subtle", children: [
|
|
1030
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-ui-fg-base", children: "Connected PayPal account" }),
|
|
1031
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1", children: [
|
|
1032
|
+
"Email:",
|
|
1033
|
+
" ",
|
|
1034
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-ui-fg-base", children: (statusInfo == null ? void 0 : statusInfo.seller_email) || "Unavailable" })
|
|
1035
|
+
] })
|
|
1036
|
+
] }),
|
|
1037
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1109
1038
|
"button",
|
|
1110
1039
|
{
|
|
1111
1040
|
type: "button",
|
|
1112
|
-
onClick:
|
|
1113
|
-
disabled:
|
|
1114
|
-
className: "rounded-md
|
|
1115
|
-
children:
|
|
1041
|
+
onClick: handleDisconnect,
|
|
1042
|
+
disabled: onboardingInProgress,
|
|
1043
|
+
className: "rounded-md border border-ui-border-base px-3 py-2 text-sm font-medium hover:bg-ui-bg-subtle disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1044
|
+
children: "Disconnect"
|
|
1045
|
+
}
|
|
1046
|
+
) })
|
|
1047
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1048
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1049
|
+
"div",
|
|
1050
|
+
{
|
|
1051
|
+
ref: initLoaderRef,
|
|
1052
|
+
id: "init-loader",
|
|
1053
|
+
className: `status-msg mb-4 ${connState !== "loading" ? "hidden" : "block"}`,
|
|
1054
|
+
children: [
|
|
1055
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "loader inline-block align-middle mr-2" }),
|
|
1056
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { id: "loader-text", className: "text-sm", children: onboardingInProgress ? "Configuring connection to PayPal…" : "Checking connection..." })
|
|
1057
|
+
]
|
|
1116
1058
|
}
|
|
1117
1059
|
),
|
|
1118
|
-
|
|
1119
|
-
] }),
|
|
1120
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
|
|
1121
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Enable/Disable", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
1060
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${connState === "ready" ? "block" : "hidden"}`, children: [
|
|
1122
1061
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1123
|
-
"
|
|
1062
|
+
"a",
|
|
1124
1063
|
{
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1064
|
+
ref: (node) => {
|
|
1065
|
+
paypalButtonRef.current = node;
|
|
1066
|
+
ppBtnMeasureRef.current = node;
|
|
1067
|
+
},
|
|
1068
|
+
id: "paypal-button",
|
|
1069
|
+
"data-paypal-button": "true",
|
|
1070
|
+
href: finalUrl || "#",
|
|
1071
|
+
"data-paypal-onboard-complete": "onboardingCallback",
|
|
1072
|
+
onClick: handleConnectClick,
|
|
1073
|
+
className: "btn-paypal",
|
|
1074
|
+
style: {
|
|
1075
|
+
borderRadius: "50px",
|
|
1076
|
+
textDecoration: "none",
|
|
1077
|
+
display: "inline-block",
|
|
1078
|
+
fontWeight: "bold",
|
|
1079
|
+
border: "none",
|
|
1080
|
+
cursor: onboardingInProgress ? "not-allowed" : "pointer",
|
|
1081
|
+
opacity: onboardingInProgress ? 0.6 : 1,
|
|
1082
|
+
pointerEvents: onboardingInProgress ? "none" : "auto"
|
|
1083
|
+
},
|
|
1084
|
+
children: "Connect to PayPal"
|
|
1129
1085
|
}
|
|
1130
1086
|
),
|
|
1131
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1087
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1088
|
+
"div",
|
|
1089
|
+
{
|
|
1090
|
+
className: "mt-2",
|
|
1091
|
+
style: {
|
|
1092
|
+
width: ppBtnWidth ? `${ppBtnWidth}px` : "auto",
|
|
1093
|
+
marginTop: "20px",
|
|
1094
|
+
marginBottom: "10px"
|
|
1095
|
+
},
|
|
1096
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] text-ui-fg-muted leading-none", children: "OR" }) })
|
|
1097
|
+
}
|
|
1098
|
+
),
|
|
1099
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1100
|
+
"button",
|
|
1101
|
+
{
|
|
1102
|
+
type: "button",
|
|
1103
|
+
onClick: () => setShowManual(!showManual),
|
|
1104
|
+
disabled: onboardingInProgress,
|
|
1105
|
+
className: "text-sm text-ui-fg-interactive underline whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1106
|
+
children: "Click here to insert credentials manually"
|
|
1107
|
+
}
|
|
1108
|
+
) })
|
|
1109
|
+
] }),
|
|
1110
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `${connState === "ready" ? "hidden" : "block"} mt-3`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1111
|
+
"button",
|
|
1135
1112
|
{
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1113
|
+
type: "button",
|
|
1114
|
+
onClick: () => setShowManual(!showManual),
|
|
1115
|
+
disabled: onboardingInProgress,
|
|
1116
|
+
className: "text-sm text-ui-fg-interactive underline whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1117
|
+
children: "Click here to insert credentials manually"
|
|
1140
1118
|
}
|
|
1141
1119
|
) }),
|
|
1142
1120
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1143
|
-
|
|
1144
|
-
{
|
|
1145
|
-
label: "Disable specific credit cards",
|
|
1146
|
-
hint: "Select card brands to hide from the card form.",
|
|
1147
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
1148
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: form.disabledCards.length ? form.disabledCards.map((v) => {
|
|
1149
|
-
var _a2;
|
|
1150
|
-
const label = ((_a2 = CARD_BRANDS.find((b) => b.value === v)) == null ? void 0 : _a2.label) ?? v;
|
|
1151
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Pill$1, { onRemove: () => removeDisabledCard(v), children: label }, v);
|
|
1152
|
-
}) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "No card brands disabled." }) }),
|
|
1153
|
-
/* @__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) => {
|
|
1154
|
-
const checked = disabledSet.has(b.value);
|
|
1155
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1156
|
-
"label",
|
|
1157
|
-
{
|
|
1158
|
-
className: cx$1(
|
|
1159
|
-
"flex items-center gap-2 rounded-md p-2",
|
|
1160
|
-
"hover:bg-ui-bg-subtle"
|
|
1161
|
-
),
|
|
1162
|
-
children: [
|
|
1163
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1164
|
-
"input",
|
|
1165
|
-
{
|
|
1166
|
-
type: "checkbox",
|
|
1167
|
-
checked,
|
|
1168
|
-
onChange: () => toggleDisabledCard(b.value),
|
|
1169
|
-
className: "h-4 w-4 rounded border-ui-border-base"
|
|
1170
|
-
}
|
|
1171
|
-
),
|
|
1172
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: b.label })
|
|
1173
|
-
]
|
|
1174
|
-
},
|
|
1175
|
-
b.value
|
|
1176
|
-
);
|
|
1177
|
-
}) }) })
|
|
1178
|
-
] })
|
|
1179
|
-
}
|
|
1180
|
-
),
|
|
1181
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1182
|
-
FieldRow$1,
|
|
1121
|
+
"div",
|
|
1183
1122
|
{
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
"select",
|
|
1189
|
-
{
|
|
1190
|
-
value: form.threeDS,
|
|
1191
|
-
onChange: (e) => setForm((p) => ({ ...p, threeDS: e.target.value })),
|
|
1192
|
-
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",
|
|
1193
|
-
children: THREE_DS_OPTIONS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
|
|
1194
|
-
}
|
|
1195
|
-
),
|
|
1196
|
-
((_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
|
|
1197
|
-
] })
|
|
1123
|
+
ref: errorLogRef,
|
|
1124
|
+
id: "error-log",
|
|
1125
|
+
className: `mt-4 text-left text-xs bg-red-50 text-red-600 p-3 border border-red-200 rounded ${connState === "error" && error ? "block" : "hidden"}`,
|
|
1126
|
+
children: error
|
|
1198
1127
|
}
|
|
1199
|
-
)
|
|
1200
|
-
|
|
1128
|
+
)
|
|
1129
|
+
] }) }),
|
|
1130
|
+
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: [
|
|
1131
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1132
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Client ID" }),
|
|
1201
1133
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1202
1134
|
"input",
|
|
1203
1135
|
{
|
|
1204
|
-
type: "
|
|
1205
|
-
|
|
1206
|
-
onChange: (e) =>
|
|
1207
|
-
|
|
1136
|
+
type: "text",
|
|
1137
|
+
value: clientId,
|
|
1138
|
+
onChange: (e) => setClientId(e.target.value),
|
|
1139
|
+
disabled: onboardingInProgress,
|
|
1140
|
+
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
1141
|
+
placeholder: env === "sandbox" ? "Sandbox Client ID" : "Live Client ID"
|
|
1142
|
+
}
|
|
1143
|
+
)
|
|
1144
|
+
] }),
|
|
1145
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1146
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Client Secret" }),
|
|
1147
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1148
|
+
"input",
|
|
1149
|
+
{
|
|
1150
|
+
type: "password",
|
|
1151
|
+
value: secret,
|
|
1152
|
+
onChange: (e) => setSecret(e.target.value),
|
|
1153
|
+
disabled: onboardingInProgress,
|
|
1154
|
+
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
1155
|
+
placeholder: env === "sandbox" ? "Sandbox Secret" : "Live Secret"
|
|
1156
|
+
}
|
|
1157
|
+
)
|
|
1158
|
+
] }),
|
|
1159
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:col-span-2", children: [
|
|
1160
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Merchant ID (optional)" }),
|
|
1161
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1162
|
+
"input",
|
|
1163
|
+
{
|
|
1164
|
+
type: "text",
|
|
1165
|
+
value: merchantId,
|
|
1166
|
+
onChange: (e) => setMerchantId(e.target.value),
|
|
1167
|
+
disabled: onboardingInProgress,
|
|
1168
|
+
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
1169
|
+
placeholder: "Merchant ID"
|
|
1170
|
+
}
|
|
1171
|
+
)
|
|
1172
|
+
] }),
|
|
1173
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:col-span-2 flex items-center gap-2 mt-2", children: [
|
|
1174
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1175
|
+
"button",
|
|
1176
|
+
{
|
|
1177
|
+
type: "button",
|
|
1178
|
+
className: "rounded-md border border-ui-border-base px-3 py-2 text-sm font-medium hover:bg-ui-bg-subtle disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1179
|
+
onClick: () => setShowManual(false),
|
|
1180
|
+
disabled: onboardingInProgress,
|
|
1181
|
+
children: "Cancel"
|
|
1208
1182
|
}
|
|
1209
1183
|
),
|
|
1210
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1184
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1185
|
+
"button",
|
|
1186
|
+
{
|
|
1187
|
+
type: "button",
|
|
1188
|
+
className: "rounded-md border border-ui-border-base px-3 py-2 text-sm font-medium bg-ui-bg-base hover:bg-ui-bg-subtle disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1189
|
+
disabled: !canSaveManual || onboardingInProgress,
|
|
1190
|
+
onClick: handleSaveManual,
|
|
1191
|
+
children: "Save credentials"
|
|
1192
|
+
}
|
|
1193
|
+
)
|
|
1194
|
+
] })
|
|
1195
|
+
] }) })
|
|
1196
|
+
] }) })
|
|
1197
|
+
] }),
|
|
1198
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
1199
|
+
.loader {
|
|
1200
|
+
border: 3px solid #f3f3f3;
|
|
1201
|
+
border-top: 3px solid #0070ba;
|
|
1202
|
+
border-radius: 50%;
|
|
1203
|
+
width: 18px;
|
|
1204
|
+
height: 18px;
|
|
1205
|
+
animation: spin 1s linear infinite;
|
|
1206
|
+
display: inline-block;
|
|
1207
|
+
vertical-align: middle;
|
|
1208
|
+
margin-right: 8px;
|
|
1209
|
+
}
|
|
1210
|
+
@keyframes spin {
|
|
1211
|
+
0% { transform: rotate(0deg); }
|
|
1212
|
+
100% { transform: rotate(360deg); }
|
|
1213
|
+
}
|
|
1214
|
+
` })
|
|
1215
|
+
] });
|
|
1216
1216
|
}
|
|
1217
1217
|
function formatDate$2(value) {
|
|
1218
1218
|
if (!value) {
|
|
@@ -1494,6 +1494,116 @@ function PayPalGooglePayPage() {
|
|
|
1494
1494
|
function PayPalPayLaterMessagingPage() {
|
|
1495
1495
|
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
1496
1496
|
}
|
|
1497
|
+
function formatDate(value) {
|
|
1498
|
+
if (!value) {
|
|
1499
|
+
return "—";
|
|
1500
|
+
}
|
|
1501
|
+
const parsed = new Date(value);
|
|
1502
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
1503
|
+
return value;
|
|
1504
|
+
}
|
|
1505
|
+
return parsed.toLocaleString();
|
|
1506
|
+
}
|
|
1507
|
+
function PayPalReconciliationStatusPage() {
|
|
1508
|
+
const [status, setStatus] = react.useState({});
|
|
1509
|
+
const [loading, setLoading] = react.useState(false);
|
|
1510
|
+
const [error, setError] = react.useState(null);
|
|
1511
|
+
const fetchStatus = react.useCallback(async () => {
|
|
1512
|
+
try {
|
|
1513
|
+
setLoading(true);
|
|
1514
|
+
setError(null);
|
|
1515
|
+
const response = await fetch("/admin/paypal/reconciliation-status", {
|
|
1516
|
+
credentials: "include",
|
|
1517
|
+
headers: {
|
|
1518
|
+
Accept: "application/json"
|
|
1519
|
+
}
|
|
1520
|
+
});
|
|
1521
|
+
if (!response.ok) {
|
|
1522
|
+
const message = await response.text().catch(() => "");
|
|
1523
|
+
throw new Error(message || "Failed to load reconciliation status.");
|
|
1524
|
+
}
|
|
1525
|
+
const data = await response.json().catch(() => ({}));
|
|
1526
|
+
setStatus((data == null ? void 0 : data.status) || {});
|
|
1527
|
+
} catch (fetchError) {
|
|
1528
|
+
setError((fetchError == null ? void 0 : fetchError.message) || "Failed to load reconciliation status.");
|
|
1529
|
+
setStatus({});
|
|
1530
|
+
} finally {
|
|
1531
|
+
setLoading(false);
|
|
1532
|
+
}
|
|
1533
|
+
}, []);
|
|
1534
|
+
react.useEffect(() => {
|
|
1535
|
+
fetchStatus();
|
|
1536
|
+
}, [fetchStatus]);
|
|
1537
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
1538
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1539
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-ui-fg-base", children: "PayPal Reconciliation Status" }),
|
|
1540
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-ui-fg-subtle", children: "Monitor reconciliation health and drift detection for PayPal payment sessions." })
|
|
1541
|
+
] }),
|
|
1542
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
1543
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
1544
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-ui-border-base p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
|
|
1545
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: "Latest reconciliation run" }),
|
|
1546
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1547
|
+
"button",
|
|
1548
|
+
{
|
|
1549
|
+
type: "button",
|
|
1550
|
+
onClick: fetchStatus,
|
|
1551
|
+
className: "rounded-md border border-ui-border-base px-3 py-2 text-sm text-ui-fg-base",
|
|
1552
|
+
disabled: loading,
|
|
1553
|
+
children: loading ? "Refreshing..." : "Refresh"
|
|
1554
|
+
}
|
|
1555
|
+
)
|
|
1556
|
+
] }) }),
|
|
1557
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
|
|
1558
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-600", children: error }) : null,
|
|
1559
|
+
!error && Object.keys(status).length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-ui-fg-subtle", children: loading ? "Loading reconciliation status..." : "No reconciliation data yet." }) : null,
|
|
1560
|
+
Object.keys(status).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 text-sm text-ui-fg-base md:grid-cols-2", children: [
|
|
1561
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
1562
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last run" }),
|
|
1563
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: formatDate(status.last_run_at) })
|
|
1564
|
+
] }),
|
|
1565
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
1566
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last run status" }),
|
|
1567
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium capitalize", children: status.last_run_status || "—" })
|
|
1568
|
+
] }),
|
|
1569
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
1570
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last success" }),
|
|
1571
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: formatDate(status.last_success_at) })
|
|
1572
|
+
] }),
|
|
1573
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
1574
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last failure" }),
|
|
1575
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: formatDate(status.last_failure_at) })
|
|
1576
|
+
] }),
|
|
1577
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
1578
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Sessions checked" }),
|
|
1579
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.sessions_checked ?? 0 })
|
|
1580
|
+
] }),
|
|
1581
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
1582
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Sessions updated" }),
|
|
1583
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.sessions_updated ?? 0 })
|
|
1584
|
+
] }),
|
|
1585
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
1586
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Drift detections" }),
|
|
1587
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.drift_count ?? 0 })
|
|
1588
|
+
] }),
|
|
1589
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
1590
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last drift order" }),
|
|
1591
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.last_drift_order_id || "—" }),
|
|
1592
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: formatDate(status.last_drift_at) })
|
|
1593
|
+
] }),
|
|
1594
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3 md:col-span-2", children: [
|
|
1595
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last error" }),
|
|
1596
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.last_error || "No errors recorded." })
|
|
1597
|
+
] }),
|
|
1598
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3 md:col-span-2", children: [
|
|
1599
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Total runs" }),
|
|
1600
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.runs ?? 0 })
|
|
1601
|
+
] })
|
|
1602
|
+
] }) : null
|
|
1603
|
+
] })
|
|
1604
|
+
] })
|
|
1605
|
+
] }) });
|
|
1606
|
+
}
|
|
1497
1607
|
const DISPLAY_LOCATION_OPTIONS = [
|
|
1498
1608
|
{ value: "product", label: "Product Page" },
|
|
1499
1609
|
{ value: "cart", label: "Cart Page" },
|
|
@@ -1931,116 +2041,6 @@ function PayPalSettingsTab() {
|
|
|
1931
2041
|
)
|
|
1932
2042
|
] }) });
|
|
1933
2043
|
}
|
|
1934
|
-
function formatDate(value) {
|
|
1935
|
-
if (!value) {
|
|
1936
|
-
return "—";
|
|
1937
|
-
}
|
|
1938
|
-
const parsed = new Date(value);
|
|
1939
|
-
if (Number.isNaN(parsed.getTime())) {
|
|
1940
|
-
return value;
|
|
1941
|
-
}
|
|
1942
|
-
return parsed.toLocaleString();
|
|
1943
|
-
}
|
|
1944
|
-
function PayPalReconciliationStatusPage() {
|
|
1945
|
-
const [status, setStatus] = react.useState({});
|
|
1946
|
-
const [loading, setLoading] = react.useState(false);
|
|
1947
|
-
const [error, setError] = react.useState(null);
|
|
1948
|
-
const fetchStatus = react.useCallback(async () => {
|
|
1949
|
-
try {
|
|
1950
|
-
setLoading(true);
|
|
1951
|
-
setError(null);
|
|
1952
|
-
const response = await fetch("/admin/paypal/reconciliation-status", {
|
|
1953
|
-
credentials: "include",
|
|
1954
|
-
headers: {
|
|
1955
|
-
Accept: "application/json"
|
|
1956
|
-
}
|
|
1957
|
-
});
|
|
1958
|
-
if (!response.ok) {
|
|
1959
|
-
const message = await response.text().catch(() => "");
|
|
1960
|
-
throw new Error(message || "Failed to load reconciliation status.");
|
|
1961
|
-
}
|
|
1962
|
-
const data = await response.json().catch(() => ({}));
|
|
1963
|
-
setStatus((data == null ? void 0 : data.status) || {});
|
|
1964
|
-
} catch (fetchError) {
|
|
1965
|
-
setError((fetchError == null ? void 0 : fetchError.message) || "Failed to load reconciliation status.");
|
|
1966
|
-
setStatus({});
|
|
1967
|
-
} finally {
|
|
1968
|
-
setLoading(false);
|
|
1969
|
-
}
|
|
1970
|
-
}, []);
|
|
1971
|
-
react.useEffect(() => {
|
|
1972
|
-
fetchStatus();
|
|
1973
|
-
}, [fetchStatus]);
|
|
1974
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
1975
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1976
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-ui-fg-base", children: "PayPal Reconciliation Status" }),
|
|
1977
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-ui-fg-subtle", children: "Monitor reconciliation health and drift detection for PayPal payment sessions." })
|
|
1978
|
-
] }),
|
|
1979
|
-
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
1980
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
1981
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-ui-border-base p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
|
|
1982
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: "Latest reconciliation run" }),
|
|
1983
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1984
|
-
"button",
|
|
1985
|
-
{
|
|
1986
|
-
type: "button",
|
|
1987
|
-
onClick: fetchStatus,
|
|
1988
|
-
className: "rounded-md border border-ui-border-base px-3 py-2 text-sm text-ui-fg-base",
|
|
1989
|
-
disabled: loading,
|
|
1990
|
-
children: loading ? "Refreshing..." : "Refresh"
|
|
1991
|
-
}
|
|
1992
|
-
)
|
|
1993
|
-
] }) }),
|
|
1994
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
|
|
1995
|
-
error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-600", children: error }) : null,
|
|
1996
|
-
!error && Object.keys(status).length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-ui-fg-subtle", children: loading ? "Loading reconciliation status..." : "No reconciliation data yet." }) : null,
|
|
1997
|
-
Object.keys(status).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 text-sm text-ui-fg-base md:grid-cols-2", children: [
|
|
1998
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
1999
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last run" }),
|
|
2000
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: formatDate(status.last_run_at) })
|
|
2001
|
-
] }),
|
|
2002
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
2003
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last run status" }),
|
|
2004
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium capitalize", children: status.last_run_status || "—" })
|
|
2005
|
-
] }),
|
|
2006
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
2007
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last success" }),
|
|
2008
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: formatDate(status.last_success_at) })
|
|
2009
|
-
] }),
|
|
2010
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
2011
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last failure" }),
|
|
2012
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: formatDate(status.last_failure_at) })
|
|
2013
|
-
] }),
|
|
2014
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
2015
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Sessions checked" }),
|
|
2016
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.sessions_checked ?? 0 })
|
|
2017
|
-
] }),
|
|
2018
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
2019
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Sessions updated" }),
|
|
2020
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.sessions_updated ?? 0 })
|
|
2021
|
-
] }),
|
|
2022
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
2023
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Drift detections" }),
|
|
2024
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.drift_count ?? 0 })
|
|
2025
|
-
] }),
|
|
2026
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3", children: [
|
|
2027
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last drift order" }),
|
|
2028
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.last_drift_order_id || "—" }),
|
|
2029
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: formatDate(status.last_drift_at) })
|
|
2030
|
-
] }),
|
|
2031
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3 md:col-span-2", children: [
|
|
2032
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Last error" }),
|
|
2033
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.last_error || "No errors recorded." })
|
|
2034
|
-
] }),
|
|
2035
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3 md:col-span-2", children: [
|
|
2036
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ui-fg-subtle", children: "Total runs" }),
|
|
2037
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 font-medium", children: status.runs ?? 0 })
|
|
2038
|
-
] })
|
|
2039
|
-
] }) : null
|
|
2040
|
-
] })
|
|
2041
|
-
] })
|
|
2042
|
-
] }) });
|
|
2043
|
-
}
|
|
2044
2044
|
const widgetModule = { widgets: [] };
|
|
2045
2045
|
const routeModule = {
|
|
2046
2046
|
routes: [
|
|
@@ -2048,6 +2048,10 @@ const routeModule = {
|
|
|
2048
2048
|
Component: PayPalSettingsIndexRoute,
|
|
2049
2049
|
path: "/settings/paypal"
|
|
2050
2050
|
},
|
|
2051
|
+
{
|
|
2052
|
+
Component: AdvancedCardPaymentsTab,
|
|
2053
|
+
path: "/settings/paypal/advanced-card-payments"
|
|
2054
|
+
},
|
|
2051
2055
|
{
|
|
2052
2056
|
Component: AdditionalSettingsTab,
|
|
2053
2057
|
path: "/settings/paypal/additional-settings"
|
|
@@ -2056,10 +2060,6 @@ const routeModule = {
|
|
|
2056
2060
|
Component: PayPalConnectionPage,
|
|
2057
2061
|
path: "/settings/paypal/connection"
|
|
2058
2062
|
},
|
|
2059
|
-
{
|
|
2060
|
-
Component: AdvancedCardPaymentsTab,
|
|
2061
|
-
path: "/settings/paypal/advanced-card-payments"
|
|
2062
|
-
},
|
|
2063
2063
|
{
|
|
2064
2064
|
Component: PayPalAuditLogsPage,
|
|
2065
2065
|
path: "/settings/paypal/audit-logs"
|
|
@@ -2080,13 +2080,13 @@ const routeModule = {
|
|
|
2080
2080
|
Component: PayPalPayLaterMessagingPage,
|
|
2081
2081
|
path: "/settings/paypal/pay-later-messaging"
|
|
2082
2082
|
},
|
|
2083
|
-
{
|
|
2084
|
-
Component: PayPalSettingsTab,
|
|
2085
|
-
path: "/settings/paypal/paypal-settings"
|
|
2086
|
-
},
|
|
2087
2083
|
{
|
|
2088
2084
|
Component: PayPalReconciliationStatusPage,
|
|
2089
2085
|
path: "/settings/paypal/reconciliation-status"
|
|
2086
|
+
},
|
|
2087
|
+
{
|
|
2088
|
+
Component: PayPalSettingsTab,
|
|
2089
|
+
path: "/settings/paypal/paypal-settings"
|
|
2090
2090
|
}
|
|
2091
2091
|
]
|
|
2092
2092
|
};
|