@easypayment/medusa-paypal 0.2.6 → 0.2.7
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 +1066 -1066
- package/.medusa/server/src/admin/index.mjs +1066 -1066
- package/.medusa/server/src/api/store/paypal/capture-order/route.js +3 -2
- package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/config/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/config/route.js +9 -2
- package/.medusa/server/src/api/store/paypal/config/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal-complete/route.d.ts +1 -8
- package/.medusa/server/src/api/store/paypal-complete/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal-complete/route.js +5 -19
- package/.medusa/server/src/api/store/paypal-complete/route.js.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.js +54 -4
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts +4 -1
- package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/service.js +35 -8
- package/.medusa/server/src/modules/paypal/payment-provider/service.js.map +1 -1
- package/package.json +1 -1
- package/src/api/store/paypal/capture-order/route.ts +3 -3
- package/src/api/store/paypal/config/route.ts +12 -8
- package/src/api/store/paypal-complete/route.ts +7 -26
- package/src/modules/paypal/payment-provider/card-service.ts +54 -4
- package/src/modules/paypal/payment-provider/service.ts +47 -20
|
@@ -336,1160 +336,1160 @@ function AdditionalSettingsTab() {
|
|
|
336
336
|
)
|
|
337
337
|
] }) });
|
|
338
338
|
}
|
|
339
|
-
|
|
340
|
-
|
|
339
|
+
const DEFAULT_FORM = {
|
|
340
|
+
enabled: true,
|
|
341
|
+
title: "Credit or Debit Card",
|
|
342
|
+
disabledCards: [],
|
|
343
|
+
threeDS: "when_required",
|
|
344
|
+
cardSaveEnabled: false
|
|
345
|
+
};
|
|
346
|
+
function mergeWithDefaults(saved) {
|
|
347
|
+
if (!saved) return { ...DEFAULT_FORM };
|
|
348
|
+
const entries = Object.entries(saved).filter(([, value]) => value !== void 0);
|
|
349
|
+
return {
|
|
350
|
+
...DEFAULT_FORM,
|
|
351
|
+
...Object.fromEntries(entries)
|
|
352
|
+
};
|
|
341
353
|
}
|
|
342
|
-
const
|
|
343
|
-
label: "
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
"
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
document.head.appendChild(ppScript);
|
|
354
|
+
const CARD_BRANDS = [
|
|
355
|
+
{ value: "visa", label: "Visa" },
|
|
356
|
+
{ value: "mastercard", label: "Mastercard" },
|
|
357
|
+
{ value: "amex", label: "American Express" },
|
|
358
|
+
{ value: "discover", label: "Discover" },
|
|
359
|
+
{ value: "diners", label: "Diners Club" },
|
|
360
|
+
{ value: "jcb", label: "JCB" },
|
|
361
|
+
{ value: "unionpay", label: "UnionPay" }
|
|
362
|
+
];
|
|
363
|
+
const THREE_DS_OPTIONS = [
|
|
364
|
+
{
|
|
365
|
+
value: "when_required",
|
|
366
|
+
label: "3D Secure when required",
|
|
367
|
+
hint: "Triggers 3DS only when the card / issuer requires it."
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
value: "sli",
|
|
371
|
+
label: "3D Secure (SCA) / liability shift (recommended)",
|
|
372
|
+
hint: "Attempts to optimize for liability shift while remaining compliant."
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
value: "always",
|
|
376
|
+
label: "Always request 3D Secure",
|
|
377
|
+
hint: "Forces 3DS challenge whenever possible (may reduce conversion)."
|
|
367
378
|
}
|
|
379
|
+
];
|
|
380
|
+
function cx$1(...parts) {
|
|
381
|
+
return parts.filter(Boolean).join(" ");
|
|
368
382
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
if ((/* @__PURE__ */ new Date()).getTime() - data.ts < CACHE_EXPIRY) {
|
|
384
|
-
cachedUrl = data.url;
|
|
383
|
+
function Pill$1({
|
|
384
|
+
children,
|
|
385
|
+
onRemove
|
|
386
|
+
}) {
|
|
387
|
+
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: [
|
|
388
|
+
children,
|
|
389
|
+
onRemove ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
390
|
+
"button",
|
|
391
|
+
{
|
|
392
|
+
type: "button",
|
|
393
|
+
onClick: onRemove,
|
|
394
|
+
className: "ml-1 rounded px-1 text-ui-fg-subtle hover:text-ui-fg-base",
|
|
395
|
+
"aria-label": "Remove",
|
|
396
|
+
children: "×"
|
|
385
397
|
}
|
|
386
|
-
|
|
387
|
-
}
|
|
388
|
-
console.error("Cache read error:", e);
|
|
389
|
-
}
|
|
398
|
+
) : null
|
|
399
|
+
] });
|
|
390
400
|
}
|
|
391
|
-
function
|
|
392
|
-
|
|
401
|
+
function SectionCard$1({
|
|
402
|
+
title,
|
|
403
|
+
description,
|
|
404
|
+
right,
|
|
405
|
+
children
|
|
406
|
+
}) {
|
|
407
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
408
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
|
|
409
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
410
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
|
|
411
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
|
|
412
|
+
] }),
|
|
413
|
+
right
|
|
414
|
+
] }),
|
|
415
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
|
|
416
|
+
] });
|
|
417
|
+
}
|
|
418
|
+
function FieldRow$1({
|
|
419
|
+
label,
|
|
420
|
+
hint,
|
|
421
|
+
children
|
|
422
|
+
}) {
|
|
423
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
|
|
424
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
|
|
425
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
|
|
426
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
|
|
427
|
+
] }),
|
|
428
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
|
|
429
|
+
] });
|
|
430
|
+
}
|
|
431
|
+
function AdvancedCardPaymentsTab() {
|
|
432
|
+
var _a, _b;
|
|
433
|
+
const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM }));
|
|
434
|
+
const [loading, setLoading] = react.useState(false);
|
|
435
|
+
const [saving, setSaving] = react.useState(false);
|
|
436
|
+
const [toast, setToast] = react.useState(null);
|
|
437
|
+
const didInit = react.useRef(false);
|
|
393
438
|
react.useEffect(() => {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
const runIdRef = react.useRef(0);
|
|
413
|
-
const currentRunId = react.useRef(0);
|
|
414
|
-
const ppBtnMeasureRef = react.useRef(null);
|
|
415
|
-
const [ppBtnWidth, setPpBtnWidth] = react.useState(null);
|
|
416
|
-
const canSaveManual = react.useMemo(() => {
|
|
417
|
-
return clientId.trim().length > 0 && secret.trim().length > 0;
|
|
418
|
-
}, [clientId, secret]);
|
|
419
|
-
const maskValue = react.useCallback((value, visibleChars = 4) => {
|
|
420
|
-
if (!value) return "";
|
|
421
|
-
if (value.length <= visibleChars) {
|
|
422
|
-
return "•".repeat(value.length);
|
|
423
|
-
}
|
|
424
|
-
return `${"•".repeat(Math.max(0, value.length - visibleChars))}${value.slice(
|
|
425
|
-
-visibleChars
|
|
426
|
-
)}`;
|
|
427
|
-
}, []);
|
|
428
|
-
const fetchFreshLink = react.useCallback(
|
|
429
|
-
(runId) => {
|
|
430
|
-
if (initLoaderRef.current) {
|
|
431
|
-
const loaderText = initLoaderRef.current.querySelector("#loader-text");
|
|
432
|
-
if (loaderText)
|
|
433
|
-
loaderText.textContent = "Generating onboarding session...";
|
|
439
|
+
if (didInit.current) return;
|
|
440
|
+
didInit.current = true;
|
|
441
|
+
(async () => {
|
|
442
|
+
try {
|
|
443
|
+
setLoading(true);
|
|
444
|
+
const r = await fetch("/admin/paypal/settings", {
|
|
445
|
+
credentials: "include",
|
|
446
|
+
headers: { "Accept": "application/json" }
|
|
447
|
+
});
|
|
448
|
+
if (!r.ok) return;
|
|
449
|
+
const json = await r.json();
|
|
450
|
+
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
451
|
+
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
452
|
+
if (saved && typeof saved === "object") {
|
|
453
|
+
setForm(mergeWithDefaults(saved));
|
|
454
|
+
}
|
|
455
|
+
} finally {
|
|
456
|
+
setLoading(false);
|
|
434
457
|
}
|
|
435
|
-
|
|
458
|
+
})();
|
|
459
|
+
}, []);
|
|
460
|
+
async function onSave() {
|
|
461
|
+
try {
|
|
462
|
+
setSaving(true);
|
|
463
|
+
const r = await fetch("/admin/paypal/settings", {
|
|
436
464
|
method: "POST",
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const href = data == null ? void 0 : data.onboarding_url;
|
|
444
|
-
if (!href) {
|
|
445
|
-
showError("Onboarding URL not returned.");
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
const finalUrl2 = href + (href.includes("?") ? "&" : "?") + "displayMode=minibrowser";
|
|
449
|
-
localStorage.setItem(
|
|
450
|
-
CACHE_KEY,
|
|
451
|
-
JSON.stringify({
|
|
452
|
-
url: finalUrl2,
|
|
453
|
-
ts: Date.now()
|
|
454
|
-
})
|
|
455
|
-
);
|
|
456
|
-
if (!localStorage.getItem(RELOAD_KEY)) {
|
|
457
|
-
localStorage.setItem(RELOAD_KEY, "1");
|
|
458
|
-
window.location.reload();
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
activatePayPal(finalUrl2, runId);
|
|
462
|
-
}).catch(() => {
|
|
463
|
-
if (runId !== currentRunId.current) return;
|
|
464
|
-
showError("Unable to connect to service.");
|
|
465
|
+
credentials: "include",
|
|
466
|
+
headers: {
|
|
467
|
+
"Content-Type": "application/json",
|
|
468
|
+
"Accept": "application/json"
|
|
469
|
+
},
|
|
470
|
+
body: JSON.stringify({ advanced_card_payments: form })
|
|
465
471
|
});
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
const btn = document.querySelector('[data-paypal-button="true"]');
|
|
472
|
-
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)) {
|
|
473
|
-
window.PAYPAL.apps.Signup.miniBrowser.init();
|
|
474
|
-
}
|
|
475
|
-
setConnState("ready");
|
|
476
|
-
}, []);
|
|
477
|
-
const showError = react.useCallback((msg) => {
|
|
478
|
-
setConnState("error");
|
|
479
|
-
setError(msg);
|
|
480
|
-
}, []);
|
|
481
|
-
const activatePayPal = react.useCallback(
|
|
482
|
-
(url, runId) => {
|
|
483
|
-
if (paypalButtonRef.current) {
|
|
484
|
-
paypalButtonRef.current.href = url;
|
|
472
|
+
if (!r.ok) {
|
|
473
|
+
const t = await r.text();
|
|
474
|
+
setToast({ type: "error", message: "Failed to save settings. " + t });
|
|
475
|
+
window.setTimeout(() => setToast(null), 3500);
|
|
476
|
+
return;
|
|
485
477
|
}
|
|
486
|
-
|
|
487
|
-
const
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
showUI();
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
|
-
setTimeout(tryInit, 50);
|
|
495
|
-
};
|
|
496
|
-
tryInit();
|
|
497
|
-
},
|
|
498
|
-
[showUI]
|
|
499
|
-
);
|
|
500
|
-
react.useEffect(() => {
|
|
501
|
-
currentRunId.current = ++runIdRef.current;
|
|
502
|
-
const runId = currentRunId.current;
|
|
503
|
-
let cancelled = false;
|
|
504
|
-
const run = async () => {
|
|
505
|
-
setConnState("loading");
|
|
506
|
-
setError(null);
|
|
507
|
-
setFinalUrl("");
|
|
508
|
-
try {
|
|
509
|
-
const r = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
510
|
-
method: "GET"
|
|
511
|
-
});
|
|
512
|
-
const st = await r.json().catch(() => ({}));
|
|
513
|
-
if (cancelled || runId !== currentRunId.current) return;
|
|
514
|
-
setStatusInfo(st);
|
|
515
|
-
const isConnected = (st == null ? void 0 : st.status) === "connected" && (st == null ? void 0 : st.seller_client_id_present) === true;
|
|
516
|
-
if (isConnected) {
|
|
517
|
-
setConnState("connected");
|
|
518
|
-
setShowManual(false);
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
} catch (e) {
|
|
522
|
-
console.error(e);
|
|
478
|
+
const json = await r.json().catch(() => null);
|
|
479
|
+
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
480
|
+
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
481
|
+
if (saved && typeof saved === "object") {
|
|
482
|
+
setForm(mergeWithDefaults(saved));
|
|
523
483
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
484
|
+
setToast({ type: "success", message: "Settings saved" });
|
|
485
|
+
window.setTimeout(() => setToast(null), 2500);
|
|
486
|
+
} finally {
|
|
487
|
+
setSaving(false);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
const disabledSet = react.useMemo(() => new Set(form.disabledCards), [form.disabledCards]);
|
|
491
|
+
function toggleDisabledCard(value) {
|
|
492
|
+
setForm((prev) => {
|
|
493
|
+
const exists = prev.disabledCards.includes(value);
|
|
494
|
+
return {
|
|
495
|
+
...prev,
|
|
496
|
+
disabledCards: exists ? prev.disabledCards.filter((v) => v !== value) : [...prev.disabledCards, value]
|
|
497
|
+
};
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
function removeDisabledCard(value) {
|
|
501
|
+
setForm((prev) => ({
|
|
502
|
+
...prev,
|
|
503
|
+
disabledCards: prev.disabledCards.filter((v) => v !== value)
|
|
504
|
+
}));
|
|
505
|
+
}
|
|
506
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
507
|
+
/* @__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" }) }) }),
|
|
508
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
509
|
+
toast ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
510
|
+
"div",
|
|
511
|
+
{
|
|
512
|
+
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",
|
|
513
|
+
role: "status",
|
|
514
|
+
"aria-live": "polite",
|
|
515
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error", children: toast.message })
|
|
529
516
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
517
|
+
) : null,
|
|
518
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
519
|
+
SectionCard$1,
|
|
520
|
+
{
|
|
521
|
+
title: "Advanced Card Payments",
|
|
522
|
+
description: "Control card checkout settings, 3D Secure behavior, and card saving.",
|
|
523
|
+
right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
524
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
525
|
+
"button",
|
|
526
|
+
{
|
|
527
|
+
type: "button",
|
|
528
|
+
onClick: onSave,
|
|
529
|
+
disabled: saving || loading,
|
|
530
|
+
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",
|
|
531
|
+
children: saving ? "Saving..." : "Save settings"
|
|
532
|
+
}
|
|
533
|
+
),
|
|
534
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "Loading…" }) : null
|
|
535
|
+
] }),
|
|
536
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-ui-border-base", children: [
|
|
537
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Enable/Disable", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-2", children: [
|
|
538
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
539
|
+
"input",
|
|
540
|
+
{
|
|
541
|
+
type: "checkbox",
|
|
542
|
+
checked: form.enabled,
|
|
543
|
+
onChange: (e) => setForm((p) => ({ ...p, enabled: e.target.checked })),
|
|
544
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
545
|
+
}
|
|
546
|
+
),
|
|
547
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable Advanced Credit/Debit Card" })
|
|
548
|
+
] }) }),
|
|
549
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { label: "Title", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
550
|
+
"input",
|
|
551
|
+
{
|
|
552
|
+
value: form.title,
|
|
553
|
+
onChange: (e) => setForm((p) => ({ ...p, title: e.target.value })),
|
|
554
|
+
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",
|
|
555
|
+
placeholder: "Credit or Debit Card"
|
|
556
|
+
}
|
|
557
|
+
) }),
|
|
558
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
559
|
+
FieldRow$1,
|
|
560
|
+
{
|
|
561
|
+
label: "Disable specific credit cards",
|
|
562
|
+
hint: "Select card brands to hide from the card form.",
|
|
563
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
564
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: form.disabledCards.length ? form.disabledCards.map((v) => {
|
|
565
|
+
var _a2;
|
|
566
|
+
const label = ((_a2 = CARD_BRANDS.find((b) => b.value === v)) == null ? void 0 : _a2.label) ?? v;
|
|
567
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Pill$1, { onRemove: () => removeDisabledCard(v), children: label }, v);
|
|
568
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "No card brands disabled." }) }),
|
|
569
|
+
/* @__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) => {
|
|
570
|
+
const checked = disabledSet.has(b.value);
|
|
571
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
572
|
+
"label",
|
|
573
|
+
{
|
|
574
|
+
className: cx$1(
|
|
575
|
+
"flex items-center gap-2 rounded-md p-2",
|
|
576
|
+
"hover:bg-ui-bg-subtle"
|
|
577
|
+
),
|
|
578
|
+
children: [
|
|
579
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
580
|
+
"input",
|
|
581
|
+
{
|
|
582
|
+
type: "checkbox",
|
|
583
|
+
checked,
|
|
584
|
+
onChange: () => toggleDisabledCard(b.value),
|
|
585
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
586
|
+
}
|
|
587
|
+
),
|
|
588
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: b.label })
|
|
589
|
+
]
|
|
590
|
+
},
|
|
591
|
+
b.value
|
|
592
|
+
);
|
|
593
|
+
}) }) })
|
|
594
|
+
] })
|
|
595
|
+
}
|
|
596
|
+
),
|
|
597
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
598
|
+
FieldRow$1,
|
|
599
|
+
{
|
|
600
|
+
label: "Contingency for 3D Secure",
|
|
601
|
+
hint: "Choose when 3D Secure should be triggered during card payments.",
|
|
602
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
603
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
604
|
+
"select",
|
|
605
|
+
{
|
|
606
|
+
value: form.threeDS,
|
|
607
|
+
onChange: (e) => setForm((p) => ({ ...p, threeDS: e.target.value })),
|
|
608
|
+
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",
|
|
609
|
+
children: THREE_DS_OPTIONS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
|
|
610
|
+
}
|
|
611
|
+
),
|
|
612
|
+
((_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
|
|
613
|
+
] })
|
|
614
|
+
}
|
|
615
|
+
),
|
|
616
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { 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: [
|
|
617
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
618
|
+
"input",
|
|
619
|
+
{
|
|
620
|
+
type: "checkbox",
|
|
621
|
+
checked: form.cardSaveEnabled,
|
|
622
|
+
onChange: (e) => setForm((p) => ({ ...p, cardSaveEnabled: e.target.checked })),
|
|
623
|
+
className: "h-4 w-4 rounded border-ui-border-base"
|
|
624
|
+
}
|
|
625
|
+
),
|
|
626
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable card saving at checkout" })
|
|
627
|
+
] }) })
|
|
628
|
+
] })
|
|
544
629
|
}
|
|
545
|
-
|
|
546
|
-
|
|
630
|
+
)
|
|
631
|
+
] }) });
|
|
632
|
+
}
|
|
633
|
+
function formatDate$2(value) {
|
|
634
|
+
if (!value) {
|
|
635
|
+
return "";
|
|
636
|
+
}
|
|
637
|
+
const parsed = new Date(value);
|
|
638
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
639
|
+
return value;
|
|
640
|
+
}
|
|
641
|
+
return parsed.toLocaleString();
|
|
642
|
+
}
|
|
643
|
+
function PayPalAuditLogsPage() {
|
|
644
|
+
const [logs, setLogs] = react.useState([]);
|
|
645
|
+
const [loading, setLoading] = react.useState(false);
|
|
646
|
+
const [error, setError] = react.useState(null);
|
|
647
|
+
const fetchLogs = react.useCallback(async () => {
|
|
648
|
+
try {
|
|
649
|
+
setLoading(true);
|
|
547
650
|
setError(null);
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
};
|
|
553
|
-
try {
|
|
554
|
-
const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
|
|
555
|
-
method: "POST",
|
|
556
|
-
headers: { "content-type": "application/json" },
|
|
557
|
-
body: JSON.stringify(payload)
|
|
558
|
-
});
|
|
559
|
-
if (!res.ok) {
|
|
560
|
-
const txt = await res.text().catch(() => "");
|
|
561
|
-
throw new Error(txt || `Onboarding exchange failed (${res.status})`);
|
|
651
|
+
const response = await fetch("/admin/paypal/audit-logs?limit=50", {
|
|
652
|
+
credentials: "include",
|
|
653
|
+
headers: {
|
|
654
|
+
Accept: "application/json"
|
|
562
655
|
}
|
|
563
|
-
try {
|
|
564
|
-
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;
|
|
565
|
-
if (typeof close1 === "function") close1();
|
|
566
|
-
} catch {
|
|
567
|
-
}
|
|
568
|
-
try {
|
|
569
|
-
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;
|
|
570
|
-
if (typeof close2 === "function") close2();
|
|
571
|
-
} catch {
|
|
572
|
-
}
|
|
573
|
-
try {
|
|
574
|
-
localStorage.removeItem(CACHE_KEY);
|
|
575
|
-
localStorage.removeItem(RELOAD_KEY);
|
|
576
|
-
} catch {
|
|
577
|
-
}
|
|
578
|
-
window.location.href = window.location.href;
|
|
579
|
-
} catch (e) {
|
|
580
|
-
console.error(e);
|
|
581
|
-
setConnState("error");
|
|
582
|
-
setError((e == null ? void 0 : e.message) || "Exchange failed while saving credentials.");
|
|
583
|
-
setOnboardingInProgress(false);
|
|
584
|
-
}
|
|
585
|
-
};
|
|
586
|
-
return () => {
|
|
587
|
-
window.onboardingCallback = void 0;
|
|
588
|
-
};
|
|
589
|
-
}, [env]);
|
|
590
|
-
react.useLayoutEffect(() => {
|
|
591
|
-
const el = ppBtnMeasureRef.current;
|
|
592
|
-
if (!el) return;
|
|
593
|
-
const update = () => {
|
|
594
|
-
const w = Math.round(el.getBoundingClientRect().width || 0);
|
|
595
|
-
if (w > 0) setPpBtnWidth(w);
|
|
596
|
-
};
|
|
597
|
-
update();
|
|
598
|
-
let ro = null;
|
|
599
|
-
if (typeof ResizeObserver !== "undefined") {
|
|
600
|
-
ro = new ResizeObserver(() => update());
|
|
601
|
-
ro.observe(el);
|
|
602
|
-
} else {
|
|
603
|
-
window.addEventListener("resize", update);
|
|
604
|
-
}
|
|
605
|
-
return () => {
|
|
606
|
-
if (ro) ro.disconnect();
|
|
607
|
-
else window.removeEventListener("resize", update);
|
|
608
|
-
};
|
|
609
|
-
}, [connState, env, finalUrl]);
|
|
610
|
-
const handleConnectClick = (e) => {
|
|
611
|
-
if (connState !== "ready" || !finalUrl || onboardingInProgress) {
|
|
612
|
-
e.preventDefault();
|
|
613
|
-
}
|
|
614
|
-
};
|
|
615
|
-
const handleSaveManual = async () => {
|
|
616
|
-
if (!canSaveManual || onboardingInProgress) return;
|
|
617
|
-
setOnboardingInProgress(true);
|
|
618
|
-
setConnState("loading");
|
|
619
|
-
setError(null);
|
|
620
|
-
try {
|
|
621
|
-
const res = await fetch(SAVE_CREDENTIALS_ENDPOINT, {
|
|
622
|
-
method: "POST",
|
|
623
|
-
headers: { "content-type": "application/json" },
|
|
624
|
-
body: JSON.stringify({
|
|
625
|
-
clientId: clientId.trim(),
|
|
626
|
-
clientSecret: secret.trim()
|
|
627
|
-
})
|
|
628
656
|
});
|
|
629
|
-
if (!
|
|
630
|
-
const
|
|
631
|
-
throw new Error(
|
|
632
|
-
}
|
|
633
|
-
setConnState("connected");
|
|
634
|
-
setStatusInfo({
|
|
635
|
-
seller_client_id_masked: maskValue(clientId.trim()),
|
|
636
|
-
seller_client_secret_masked: "••••••••"
|
|
637
|
-
});
|
|
638
|
-
setShowManual(false);
|
|
639
|
-
try {
|
|
640
|
-
localStorage.removeItem(CACHE_KEY);
|
|
641
|
-
localStorage.removeItem(RELOAD_KEY);
|
|
642
|
-
} catch {
|
|
657
|
+
if (!response.ok) {
|
|
658
|
+
const message = await response.text().catch(() => "");
|
|
659
|
+
throw new Error(message || "Failed to load audit logs.");
|
|
643
660
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
setError((
|
|
661
|
+
const data = await response.json().catch(() => ({}));
|
|
662
|
+
setLogs((data == null ? void 0 : data.logs) || []);
|
|
663
|
+
} catch (fetchError) {
|
|
664
|
+
setError((fetchError == null ? void 0 : fetchError.message) || "Failed to load audit logs.");
|
|
665
|
+
setLogs([]);
|
|
648
666
|
} finally {
|
|
649
|
-
|
|
667
|
+
setLoading(false);
|
|
650
668
|
}
|
|
651
|
-
};
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
669
|
+
}, []);
|
|
670
|
+
react.useEffect(() => {
|
|
671
|
+
fetchLogs();
|
|
672
|
+
}, [fetchLogs]);
|
|
673
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
674
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
675
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-ui-fg-base", children: "PayPal Audit Logs" }),
|
|
676
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-ui-fg-subtle", children: "Track administrative changes and credential events for PayPal configuration." })
|
|
677
|
+
] }),
|
|
678
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
679
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
680
|
+
/* @__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: [
|
|
681
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: "Latest events" }),
|
|
682
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
683
|
+
"button",
|
|
684
|
+
{
|
|
685
|
+
type: "button",
|
|
686
|
+
onClick: fetchLogs,
|
|
687
|
+
className: "rounded-md border border-ui-border-base px-3 py-2 text-sm text-ui-fg-base",
|
|
688
|
+
disabled: loading,
|
|
689
|
+
children: loading ? "Refreshing..." : "Refresh"
|
|
690
|
+
}
|
|
691
|
+
)
|
|
692
|
+
] }) }),
|
|
693
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
|
|
694
|
+
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,
|
|
695
|
+
!error && logs.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-ui-fg-subtle", children: loading ? "Loading audit logs..." : "No audit log entries found yet." }) : null,
|
|
696
|
+
logs.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full text-left text-sm", children: [
|
|
697
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "text-ui-fg-muted", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
698
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 pr-4 font-medium", children: "Timestamp" }),
|
|
699
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 pr-4 font-medium", children: "Event" }),
|
|
700
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 font-medium", children: "Details" })
|
|
701
|
+
] }) }),
|
|
702
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: logs.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-t border-ui-border-base", children: [
|
|
703
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 pr-4 text-ui-fg-base", children: formatDate$2(entry.created_at) || "—" }),
|
|
704
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 pr-4 text-ui-fg-base", children: entry.event_type || "—" }),
|
|
705
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 text-ui-fg-subtle", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap rounded-md bg-ui-bg-subtle p-2 text-xs text-ui-fg-subtle", children: JSON.stringify(entry.metadata || {}, null, 2) }) })
|
|
706
|
+
] }, entry.id)) })
|
|
707
|
+
] }) }) : null
|
|
708
|
+
] })
|
|
709
|
+
] })
|
|
710
|
+
] }) });
|
|
711
|
+
}
|
|
712
|
+
function PayPalApplePayPage() {
|
|
713
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
714
|
+
}
|
|
715
|
+
const EMPTY_FILTERS = {
|
|
716
|
+
dispute_id: "",
|
|
717
|
+
status: "",
|
|
718
|
+
order_id: "",
|
|
719
|
+
cart_id: ""
|
|
720
|
+
};
|
|
721
|
+
function formatDate$1(value) {
|
|
722
|
+
if (!value) {
|
|
723
|
+
return "";
|
|
724
|
+
}
|
|
725
|
+
const parsed = new Date(value);
|
|
726
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
727
|
+
return value;
|
|
728
|
+
}
|
|
729
|
+
return parsed.toLocaleString();
|
|
730
|
+
}
|
|
731
|
+
function PayPalDisputesPage() {
|
|
732
|
+
const [filters, setFilters] = react.useState({ ...EMPTY_FILTERS });
|
|
733
|
+
const [disputes, setDisputes] = react.useState([]);
|
|
734
|
+
const [loading, setLoading] = react.useState(false);
|
|
735
|
+
const [error, setError] = react.useState(null);
|
|
736
|
+
const queryString = react.useMemo(() => {
|
|
737
|
+
const params = new URLSearchParams();
|
|
738
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
739
|
+
if (value.trim()) {
|
|
740
|
+
params.set(key, value.trim());
|
|
741
|
+
}
|
|
742
|
+
});
|
|
743
|
+
const qs = params.toString();
|
|
744
|
+
return qs ? `?${qs}` : "";
|
|
745
|
+
}, [filters]);
|
|
746
|
+
const fetchDisputes = react.useCallback(async (source) => {
|
|
660
747
|
try {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
748
|
+
setLoading(true);
|
|
749
|
+
setError(null);
|
|
750
|
+
const params = new URLSearchParams();
|
|
751
|
+
Object.entries(source).forEach(([key, value]) => {
|
|
752
|
+
if (value.trim()) {
|
|
753
|
+
params.set(key, value.trim());
|
|
754
|
+
}
|
|
665
755
|
});
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
756
|
+
const qs = params.toString();
|
|
757
|
+
const resp = await fetch(`/admin/paypal/disputes${qs ? `?${qs}` : ""}`, {
|
|
758
|
+
credentials: "include",
|
|
759
|
+
headers: {
|
|
760
|
+
Accept: "application/json"
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
if (!resp.ok) {
|
|
764
|
+
const message = await resp.text().catch(() => "");
|
|
765
|
+
throw new Error(message || "Failed to load disputes");
|
|
674
766
|
}
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
setConnState("error");
|
|
681
|
-
setError((e == null ? void 0 : e.message) || "Failed to disconnect.");
|
|
767
|
+
const json = await resp.json().catch(() => ({}));
|
|
768
|
+
setDisputes((json == null ? void 0 : json.disputes) || []);
|
|
769
|
+
} catch (fetchError) {
|
|
770
|
+
setError((fetchError == null ? void 0 : fetchError.message) || "Failed to load disputes");
|
|
771
|
+
setDisputes([]);
|
|
682
772
|
} finally {
|
|
683
|
-
|
|
773
|
+
setLoading(false);
|
|
684
774
|
}
|
|
775
|
+
}, []);
|
|
776
|
+
react.useEffect(() => {
|
|
777
|
+
fetchDisputes(EMPTY_FILTERS);
|
|
778
|
+
}, [fetchDisputes]);
|
|
779
|
+
const onSubmit = (event) => {
|
|
780
|
+
event.preventDefault();
|
|
781
|
+
fetchDisputes(filters);
|
|
685
782
|
};
|
|
686
|
-
const
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
cachedUrl = null;
|
|
690
|
-
try {
|
|
691
|
-
await fetch("/admin/paypal/environment", {
|
|
692
|
-
method: "POST",
|
|
693
|
-
headers: { "content-type": "application/json" },
|
|
694
|
-
body: JSON.stringify({ environment: next })
|
|
695
|
-
});
|
|
696
|
-
} catch {
|
|
697
|
-
}
|
|
698
|
-
try {
|
|
699
|
-
localStorage.removeItem(CACHE_KEY);
|
|
700
|
-
localStorage.removeItem(RELOAD_KEY);
|
|
701
|
-
} catch {
|
|
702
|
-
}
|
|
783
|
+
const onReset = () => {
|
|
784
|
+
setFilters({ ...EMPTY_FILTERS });
|
|
785
|
+
fetchDisputes(EMPTY_FILTERS);
|
|
703
786
|
};
|
|
704
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
705
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
706
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold", children: "PayPal
|
|
707
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
className: "w-full rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm",
|
|
717
|
-
children: [
|
|
718
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "sandbox", children: "Sandbox (Test Mode)" }),
|
|
719
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "live", children: "Live (Production)" })
|
|
720
|
-
]
|
|
721
|
-
}
|
|
722
|
-
) }),
|
|
723
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium pt-2", children: env === "sandbox" ? "Connect to PayPal Sandbox" : "Connect to PayPal Live" }),
|
|
724
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-xl", children: connState === "connected" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
725
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-green-600 bg-green-50 p-3 rounded border border-green-200", children: [
|
|
726
|
-
"✅ Successfully connected to PayPal!",
|
|
727
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
728
|
-
"a",
|
|
729
|
-
{
|
|
730
|
-
"data-paypal-button": "true",
|
|
731
|
-
"data-paypal-onboard-complete": "onboardingCallback",
|
|
732
|
-
href: "#",
|
|
733
|
-
style: { display: "none" },
|
|
734
|
-
children: "PayPal"
|
|
735
|
-
}
|
|
736
|
-
)
|
|
737
|
-
] }),
|
|
738
|
-
/* @__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: [
|
|
739
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-ui-fg-base", children: "Connected PayPal account" }),
|
|
740
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1", children: [
|
|
741
|
-
"Email:",
|
|
742
|
-
" ",
|
|
743
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-ui-fg-base", children: (statusInfo == null ? void 0 : statusInfo.seller_email) || "Unavailable" })
|
|
744
|
-
] })
|
|
745
|
-
] }),
|
|
746
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
747
|
-
"button",
|
|
748
|
-
{
|
|
749
|
-
type: "button",
|
|
750
|
-
onClick: handleDisconnect,
|
|
751
|
-
disabled: onboardingInProgress,
|
|
752
|
-
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",
|
|
753
|
-
children: "Disconnect"
|
|
754
|
-
}
|
|
755
|
-
) })
|
|
756
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
757
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
758
|
-
"div",
|
|
759
|
-
{
|
|
760
|
-
ref: initLoaderRef,
|
|
761
|
-
id: "init-loader",
|
|
762
|
-
className: `status-msg mb-4 ${connState !== "loading" ? "hidden" : "block"}`,
|
|
763
|
-
children: [
|
|
764
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "loader inline-block align-middle mr-2" }),
|
|
765
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { id: "loader-text", className: "text-sm", children: onboardingInProgress ? "Configuring connection to PayPal…" : "Checking connection..." })
|
|
766
|
-
]
|
|
767
|
-
}
|
|
768
|
-
),
|
|
769
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${connState === "ready" ? "block" : "hidden"}`, children: [
|
|
770
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
771
|
-
"a",
|
|
772
|
-
{
|
|
773
|
-
ref: (node) => {
|
|
774
|
-
paypalButtonRef.current = node;
|
|
775
|
-
ppBtnMeasureRef.current = node;
|
|
776
|
-
},
|
|
777
|
-
id: "paypal-button",
|
|
778
|
-
"data-paypal-button": "true",
|
|
779
|
-
href: finalUrl || "#",
|
|
780
|
-
"data-paypal-onboard-complete": "onboardingCallback",
|
|
781
|
-
onClick: handleConnectClick,
|
|
782
|
-
className: "btn-paypal",
|
|
783
|
-
style: {
|
|
784
|
-
borderRadius: "50px",
|
|
785
|
-
textDecoration: "none",
|
|
786
|
-
display: "inline-block",
|
|
787
|
-
fontWeight: "bold",
|
|
788
|
-
border: "none",
|
|
789
|
-
cursor: onboardingInProgress ? "not-allowed" : "pointer",
|
|
790
|
-
opacity: onboardingInProgress ? 0.6 : 1,
|
|
791
|
-
pointerEvents: onboardingInProgress ? "none" : "auto"
|
|
792
|
-
},
|
|
793
|
-
children: "Connect to PayPal"
|
|
794
|
-
}
|
|
795
|
-
),
|
|
796
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
797
|
-
"div",
|
|
798
|
-
{
|
|
799
|
-
className: "mt-2",
|
|
800
|
-
style: {
|
|
801
|
-
width: ppBtnWidth ? `${ppBtnWidth}px` : "auto",
|
|
802
|
-
marginTop: "20px",
|
|
803
|
-
marginBottom: "10px"
|
|
804
|
-
},
|
|
805
|
-
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" }) })
|
|
806
|
-
}
|
|
807
|
-
),
|
|
808
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
809
|
-
"button",
|
|
810
|
-
{
|
|
811
|
-
type: "button",
|
|
812
|
-
onClick: () => setShowManual(!showManual),
|
|
813
|
-
disabled: onboardingInProgress,
|
|
814
|
-
className: "text-sm text-ui-fg-interactive underline whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed",
|
|
815
|
-
children: "Click here to insert credentials manually"
|
|
816
|
-
}
|
|
817
|
-
) })
|
|
818
|
-
] }),
|
|
819
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `${connState === "ready" ? "hidden" : "block"} mt-3`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
820
|
-
"button",
|
|
821
|
-
{
|
|
822
|
-
type: "button",
|
|
823
|
-
onClick: () => setShowManual(!showManual),
|
|
824
|
-
disabled: onboardingInProgress,
|
|
825
|
-
className: "text-sm text-ui-fg-interactive underline whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed",
|
|
826
|
-
children: "Click here to insert credentials manually"
|
|
827
|
-
}
|
|
828
|
-
) }),
|
|
829
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
830
|
-
"div",
|
|
831
|
-
{
|
|
832
|
-
ref: errorLogRef,
|
|
833
|
-
id: "error-log",
|
|
834
|
-
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"}`,
|
|
835
|
-
children: error
|
|
836
|
-
}
|
|
837
|
-
)
|
|
838
|
-
] }) }),
|
|
839
|
-
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: [
|
|
840
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
841
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Client ID" }),
|
|
787
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
788
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
789
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-ui-fg-base", children: "PayPal Disputes" }),
|
|
790
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-ui-fg-subtle", children: "Review PayPal dispute activity tied to your Medusa orders. This view is read-only." })
|
|
791
|
+
] }),
|
|
792
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
793
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
794
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-ui-border-base p-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: "Filters" }) }),
|
|
795
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit, className: "flex flex-col gap-4", children: [
|
|
796
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-4", children: [
|
|
797
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1 text-sm text-ui-fg-subtle", children: [
|
|
798
|
+
"Dispute ID",
|
|
842
799
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
843
800
|
"input",
|
|
844
801
|
{
|
|
845
|
-
|
|
846
|
-
value:
|
|
847
|
-
onChange: (
|
|
848
|
-
|
|
849
|
-
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
850
|
-
placeholder: env === "sandbox" ? "Sandbox Client ID" : "Live Client ID"
|
|
802
|
+
className: "rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base",
|
|
803
|
+
value: filters.dispute_id,
|
|
804
|
+
onChange: (event) => setFilters((prev) => ({ ...prev, dispute_id: event.target.value })),
|
|
805
|
+
placeholder: "PP-D-123"
|
|
851
806
|
}
|
|
852
807
|
)
|
|
853
808
|
] }),
|
|
854
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
855
|
-
|
|
809
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1 text-sm text-ui-fg-subtle", children: [
|
|
810
|
+
"Status",
|
|
856
811
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
857
812
|
"input",
|
|
858
813
|
{
|
|
859
|
-
|
|
860
|
-
value:
|
|
861
|
-
onChange: (
|
|
862
|
-
|
|
863
|
-
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
864
|
-
placeholder: env === "sandbox" ? "Sandbox Secret" : "Live Secret"
|
|
814
|
+
className: "rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base",
|
|
815
|
+
value: filters.status,
|
|
816
|
+
onChange: (event) => setFilters((prev) => ({ ...prev, status: event.target.value })),
|
|
817
|
+
placeholder: "OPEN"
|
|
865
818
|
}
|
|
866
819
|
)
|
|
867
820
|
] }),
|
|
868
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
869
|
-
|
|
821
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1 text-sm text-ui-fg-subtle", children: [
|
|
822
|
+
"Order ID",
|
|
870
823
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
871
824
|
"input",
|
|
872
825
|
{
|
|
873
|
-
|
|
874
|
-
value:
|
|
875
|
-
onChange: (
|
|
876
|
-
|
|
877
|
-
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
878
|
-
placeholder: "Merchant ID"
|
|
826
|
+
className: "rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base",
|
|
827
|
+
value: filters.order_id,
|
|
828
|
+
onChange: (event) => setFilters((prev) => ({ ...prev, order_id: event.target.value })),
|
|
829
|
+
placeholder: "order_..."
|
|
879
830
|
}
|
|
880
831
|
)
|
|
881
832
|
] }),
|
|
882
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
883
|
-
|
|
884
|
-
"button",
|
|
885
|
-
{
|
|
886
|
-
type: "button",
|
|
887
|
-
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",
|
|
888
|
-
onClick: () => setShowManual(false),
|
|
889
|
-
disabled: onboardingInProgress,
|
|
890
|
-
children: "Cancel"
|
|
891
|
-
}
|
|
892
|
-
),
|
|
833
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1 text-sm text-ui-fg-subtle", children: [
|
|
834
|
+
"Cart ID",
|
|
893
835
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
894
|
-
"
|
|
836
|
+
"input",
|
|
895
837
|
{
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
children: "Save credentials"
|
|
838
|
+
className: "rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base",
|
|
839
|
+
value: filters.cart_id,
|
|
840
|
+
onChange: (event) => setFilters((prev) => ({ ...prev, cart_id: event.target.value })),
|
|
841
|
+
placeholder: "cart_..."
|
|
901
842
|
}
|
|
902
843
|
)
|
|
903
844
|
] })
|
|
904
|
-
] })
|
|
845
|
+
] }),
|
|
846
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-3", children: [
|
|
847
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
848
|
+
"button",
|
|
849
|
+
{
|
|
850
|
+
type: "submit",
|
|
851
|
+
className: "rounded-md bg-ui-fg-base px-4 py-2 text-sm font-medium text-ui-bg-base",
|
|
852
|
+
disabled: loading,
|
|
853
|
+
children: loading ? "Loading..." : "Apply filters"
|
|
854
|
+
}
|
|
855
|
+
),
|
|
856
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
857
|
+
"button",
|
|
858
|
+
{
|
|
859
|
+
type: "button",
|
|
860
|
+
className: "rounded-md border border-ui-border-base px-4 py-2 text-sm text-ui-fg-base",
|
|
861
|
+
onClick: onReset,
|
|
862
|
+
disabled: loading,
|
|
863
|
+
children: "Reset"
|
|
864
|
+
}
|
|
865
|
+
),
|
|
866
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-ui-fg-subtle", children: [
|
|
867
|
+
"Showing ",
|
|
868
|
+
disputes.length,
|
|
869
|
+
" dispute",
|
|
870
|
+
disputes.length === 1 ? "" : "s",
|
|
871
|
+
queryString ? " (filtered)" : ""
|
|
872
|
+
] })
|
|
873
|
+
] })
|
|
905
874
|
] }) })
|
|
906
875
|
] }),
|
|
907
|
-
/* @__PURE__ */ jsxRuntime.
|
|
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
|
-
|
|
937
|
-
...DEFAULT_FORM,
|
|
938
|
-
...Object.fromEntries(entries)
|
|
939
|
-
};
|
|
876
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
877
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-ui-border-base p-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: "Dispute Records" }) }),
|
|
878
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base text-sm", children: [
|
|
879
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-left text-ui-fg-subtle", children: [
|
|
880
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 font-medium", children: "Dispute" }),
|
|
881
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 font-medium", children: "Status" }),
|
|
882
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 font-medium", children: "Reason" }),
|
|
883
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 font-medium", children: "Stage" }),
|
|
884
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 font-medium", children: "Amount" }),
|
|
885
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 font-medium", children: "Order" }),
|
|
886
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 font-medium", children: "Cart" }),
|
|
887
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 font-medium", children: "Updated" })
|
|
888
|
+
] }) }),
|
|
889
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-base text-ui-fg-base", children: disputes.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-6 text-center text-ui-fg-subtle", colSpan: 8, children: loading ? "Loading disputes..." : "No disputes found." }) }) : disputes.map((dispute) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
890
|
+
/* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-3", children: [
|
|
891
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-ui-fg-base", children: dispute.dispute_id }),
|
|
892
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-ui-fg-subtle", children: dispute.transaction_id || "No transaction" })
|
|
893
|
+
] }),
|
|
894
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3", children: dispute.status || "Unknown" }),
|
|
895
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3", children: dispute.reason || "-" }),
|
|
896
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3", children: dispute.stage || "-" }),
|
|
897
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3", children: dispute.amount ? `${dispute.amount} ${dispute.currency_code || ""}` : "-" }),
|
|
898
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3", children: dispute.order_id || "-" }),
|
|
899
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3", children: dispute.cart_id || "-" }),
|
|
900
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-ui-fg-subtle", children: formatDate$1(dispute.updated_at || dispute.created_at) })
|
|
901
|
+
] }, dispute.id)) })
|
|
902
|
+
] }) }),
|
|
903
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-ui-border-base px-4 py-3 text-sm text-ui-fg-error", children: error }) : null
|
|
904
|
+
] })
|
|
905
|
+
] }) });
|
|
940
906
|
}
|
|
941
|
-
const
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
907
|
+
const config = adminSdk.defineRouteConfig({
|
|
908
|
+
label: "PayPal Connection",
|
|
909
|
+
hide: true
|
|
910
|
+
});
|
|
911
|
+
if (typeof window !== "undefined") {
|
|
912
|
+
const preloadHref = "https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js";
|
|
913
|
+
const existingPreload = document.head.querySelector(
|
|
914
|
+
`link[rel="preload"][href="${preloadHref}"]`
|
|
915
|
+
);
|
|
916
|
+
if (!existingPreload) {
|
|
917
|
+
const preloadLink = document.createElement("link");
|
|
918
|
+
preloadLink.rel = "preload";
|
|
919
|
+
preloadLink.href = preloadHref;
|
|
920
|
+
preloadLink.as = "script";
|
|
921
|
+
document.head.appendChild(preloadLink);
|
|
922
|
+
}
|
|
923
|
+
const existingScript = document.getElementById(
|
|
924
|
+
"paypal-partner-js"
|
|
925
|
+
);
|
|
926
|
+
if (!existingScript) {
|
|
927
|
+
const ppScript = document.createElement("script");
|
|
928
|
+
ppScript.id = "paypal-partner-js";
|
|
929
|
+
ppScript.src = preloadHref;
|
|
930
|
+
ppScript.async = true;
|
|
931
|
+
document.head.appendChild(ppScript);
|
|
965
932
|
}
|
|
966
|
-
];
|
|
967
|
-
function cx$1(...parts) {
|
|
968
|
-
return parts.filter(Boolean).join(" ");
|
|
969
933
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
934
|
+
const SERVICE_URL = "/admin/paypal/onboarding-link";
|
|
935
|
+
const CACHE_KEY = "pp_onboard_cache";
|
|
936
|
+
const RELOAD_KEY = "pp_onboard_reloaded_once";
|
|
937
|
+
const CACHE_EXPIRY = 10 * 60 * 1e3;
|
|
938
|
+
const ONBOARDING_COMPLETE_ENDPOINT = "/admin/paypal/onboard-complete";
|
|
939
|
+
const STATUS_ENDPOINT = "/admin/paypal/status";
|
|
940
|
+
const SAVE_CREDENTIALS_ENDPOINT = "/admin/paypal/save-credentials";
|
|
941
|
+
const DISCONNECT_ENDPOINT = "/admin/paypal/disconnect";
|
|
942
|
+
let cachedUrl = null;
|
|
943
|
+
if (typeof window !== "undefined") {
|
|
944
|
+
try {
|
|
945
|
+
const cached = localStorage.getItem(CACHE_KEY);
|
|
946
|
+
if (cached) {
|
|
947
|
+
const data = JSON.parse(cached);
|
|
948
|
+
if ((/* @__PURE__ */ new Date()).getTime() - data.ts < CACHE_EXPIRY) {
|
|
949
|
+
cachedUrl = data.url;
|
|
984
950
|
}
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
title,
|
|
990
|
-
description,
|
|
991
|
-
right,
|
|
992
|
-
children
|
|
993
|
-
}) {
|
|
994
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
995
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-ui-border-base p-4", children: [
|
|
996
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
997
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: title }),
|
|
998
|
-
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm text-ui-fg-subtle", children: description }) : null
|
|
999
|
-
] }),
|
|
1000
|
-
right
|
|
1001
|
-
] }),
|
|
1002
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children })
|
|
1003
|
-
] });
|
|
1004
|
-
}
|
|
1005
|
-
function FieldRow$1({
|
|
1006
|
-
label,
|
|
1007
|
-
hint,
|
|
1008
|
-
children
|
|
1009
|
-
}) {
|
|
1010
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 items-start gap-4 py-3", children: [
|
|
1011
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-12 md:col-span-4", children: [
|
|
1012
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-ui-fg-base", children: label }),
|
|
1013
|
-
hint ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-ui-fg-subtle", children: hint }) : null
|
|
1014
|
-
] }),
|
|
1015
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-12 md:col-span-8", children })
|
|
1016
|
-
] });
|
|
951
|
+
}
|
|
952
|
+
} catch (e) {
|
|
953
|
+
console.error("Cache read error:", e);
|
|
954
|
+
}
|
|
1017
955
|
}
|
|
1018
|
-
function
|
|
1019
|
-
|
|
1020
|
-
const [form, setForm] = react.useState(() => ({ ...DEFAULT_FORM }));
|
|
1021
|
-
const [loading, setLoading] = react.useState(false);
|
|
1022
|
-
const [saving, setSaving] = react.useState(false);
|
|
1023
|
-
const [toast, setToast] = react.useState(null);
|
|
1024
|
-
const didInit = react.useRef(false);
|
|
956
|
+
function PayPalConnectionPage() {
|
|
957
|
+
const [env, setEnv] = react.useState("sandbox");
|
|
1025
958
|
react.useEffect(() => {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
const r = await fetch("/admin/paypal/settings", {
|
|
1032
|
-
credentials: "include",
|
|
1033
|
-
headers: { "Accept": "application/json" }
|
|
1034
|
-
});
|
|
1035
|
-
if (!r.ok) return;
|
|
1036
|
-
const json = await r.json();
|
|
1037
|
-
const payload = (json == null ? void 0 : json.data) ?? json;
|
|
1038
|
-
const saved = payload == null ? void 0 : payload.advanced_card_payments;
|
|
1039
|
-
if (saved && typeof saved === "object") {
|
|
1040
|
-
setForm(mergeWithDefaults(saved));
|
|
1041
|
-
}
|
|
1042
|
-
} finally {
|
|
1043
|
-
setLoading(false);
|
|
1044
|
-
}
|
|
1045
|
-
})();
|
|
959
|
+
fetch("/admin/paypal/environment", { method: "GET" }).then((r) => r.json()).then((d) => {
|
|
960
|
+
const v = (d == null ? void 0 : d.environment) === "live" ? "live" : "sandbox";
|
|
961
|
+
setEnv(v);
|
|
962
|
+
}).catch(() => {
|
|
963
|
+
});
|
|
1046
964
|
}, []);
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
}
|
|
1071
|
-
setToast({ type: "success", message: "Settings saved" });
|
|
1072
|
-
window.setTimeout(() => setToast(null), 2500);
|
|
1073
|
-
} finally {
|
|
1074
|
-
setSaving(false);
|
|
965
|
+
const [connState, setConnState] = react.useState("loading");
|
|
966
|
+
const [error, setError] = react.useState(null);
|
|
967
|
+
const [finalUrl, setFinalUrl] = react.useState("");
|
|
968
|
+
const [showManual, setShowManual] = react.useState(false);
|
|
969
|
+
const [clientId, setClientId] = react.useState("");
|
|
970
|
+
const [secret, setSecret] = react.useState("");
|
|
971
|
+
const [merchantId, setMerchantId] = react.useState("");
|
|
972
|
+
const [statusInfo, setStatusInfo] = react.useState(null);
|
|
973
|
+
const [onboardingInProgress, setOnboardingInProgress] = react.useState(false);
|
|
974
|
+
const initLoaderRef = react.useRef(null);
|
|
975
|
+
const paypalButtonRef = react.useRef(null);
|
|
976
|
+
const errorLogRef = react.useRef(null);
|
|
977
|
+
const runIdRef = react.useRef(0);
|
|
978
|
+
const currentRunId = react.useRef(0);
|
|
979
|
+
const ppBtnMeasureRef = react.useRef(null);
|
|
980
|
+
const [ppBtnWidth, setPpBtnWidth] = react.useState(null);
|
|
981
|
+
const canSaveManual = react.useMemo(() => {
|
|
982
|
+
return clientId.trim().length > 0 && secret.trim().length > 0;
|
|
983
|
+
}, [clientId, secret]);
|
|
984
|
+
const maskValue = react.useCallback((value, visibleChars = 4) => {
|
|
985
|
+
if (!value) return "";
|
|
986
|
+
if (value.length <= visibleChars) {
|
|
987
|
+
return "•".repeat(value.length);
|
|
1075
988
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
}
|
|
1087
|
-
function removeDisabledCard(value) {
|
|
1088
|
-
setForm((prev) => ({
|
|
1089
|
-
...prev,
|
|
1090
|
-
disabledCards: prev.disabledCards.filter((v) => v !== value)
|
|
1091
|
-
}));
|
|
1092
|
-
}
|
|
1093
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
1094
|
-
/* @__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" }) }) }),
|
|
1095
|
-
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
1096
|
-
toast ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1097
|
-
"div",
|
|
1098
|
-
{
|
|
1099
|
-
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",
|
|
1100
|
-
role: "status",
|
|
1101
|
-
"aria-live": "polite",
|
|
1102
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error", children: toast.message })
|
|
989
|
+
return `${"•".repeat(Math.max(0, value.length - visibleChars))}${value.slice(
|
|
990
|
+
-visibleChars
|
|
991
|
+
)}`;
|
|
992
|
+
}, []);
|
|
993
|
+
const fetchFreshLink = react.useCallback(
|
|
994
|
+
(runId) => {
|
|
995
|
+
if (initLoaderRef.current) {
|
|
996
|
+
const loaderText = initLoaderRef.current.querySelector("#loader-text");
|
|
997
|
+
if (loaderText)
|
|
998
|
+
loaderText.textContent = "Generating onboarding session...";
|
|
1103
999
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Pill$1, { onRemove: () => removeDisabledCard(v), children: label }, v);
|
|
1155
|
-
}) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-subtle", children: "No card brands disabled." }) }),
|
|
1156
|
-
/* @__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) => {
|
|
1157
|
-
const checked = disabledSet.has(b.value);
|
|
1158
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1159
|
-
"label",
|
|
1160
|
-
{
|
|
1161
|
-
className: cx$1(
|
|
1162
|
-
"flex items-center gap-2 rounded-md p-2",
|
|
1163
|
-
"hover:bg-ui-bg-subtle"
|
|
1164
|
-
),
|
|
1165
|
-
children: [
|
|
1166
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1167
|
-
"input",
|
|
1168
|
-
{
|
|
1169
|
-
type: "checkbox",
|
|
1170
|
-
checked,
|
|
1171
|
-
onChange: () => toggleDisabledCard(b.value),
|
|
1172
|
-
className: "h-4 w-4 rounded border-ui-border-base"
|
|
1173
|
-
}
|
|
1174
|
-
),
|
|
1175
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: b.label })
|
|
1176
|
-
]
|
|
1177
|
-
},
|
|
1178
|
-
b.value
|
|
1179
|
-
);
|
|
1180
|
-
}) }) })
|
|
1181
|
-
] })
|
|
1182
|
-
}
|
|
1183
|
-
),
|
|
1184
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1185
|
-
FieldRow$1,
|
|
1186
|
-
{
|
|
1187
|
-
label: "Contingency for 3D Secure",
|
|
1188
|
-
hint: "Choose when 3D Secure should be triggered during card payments.",
|
|
1189
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
1190
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1191
|
-
"select",
|
|
1192
|
-
{
|
|
1193
|
-
value: form.threeDS,
|
|
1194
|
-
onChange: (e) => setForm((p) => ({ ...p, threeDS: e.target.value })),
|
|
1195
|
-
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",
|
|
1196
|
-
children: THREE_DS_OPTIONS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
|
|
1197
|
-
}
|
|
1198
|
-
),
|
|
1199
|
-
((_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
|
|
1200
|
-
] })
|
|
1201
|
-
}
|
|
1202
|
-
),
|
|
1203
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow$1, { 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: [
|
|
1204
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1205
|
-
"input",
|
|
1206
|
-
{
|
|
1207
|
-
type: "checkbox",
|
|
1208
|
-
checked: form.cardSaveEnabled,
|
|
1209
|
-
onChange: (e) => setForm((p) => ({ ...p, cardSaveEnabled: e.target.checked })),
|
|
1210
|
-
className: "h-4 w-4 rounded border-ui-border-base"
|
|
1211
|
-
}
|
|
1212
|
-
),
|
|
1213
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-ui-fg-base", children: "Enable card saving at checkout" })
|
|
1214
|
-
] }) })
|
|
1215
|
-
] })
|
|
1000
|
+
fetch(SERVICE_URL, {
|
|
1001
|
+
method: "POST",
|
|
1002
|
+
headers: { "content-type": "application/json" },
|
|
1003
|
+
body: JSON.stringify({
|
|
1004
|
+
products: ["PPCP"]
|
|
1005
|
+
})
|
|
1006
|
+
}).then((r) => r.json()).then((data) => {
|
|
1007
|
+
if (runId !== currentRunId.current) return;
|
|
1008
|
+
const href = data == null ? void 0 : data.onboarding_url;
|
|
1009
|
+
if (!href) {
|
|
1010
|
+
showError("Onboarding URL not returned.");
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
const finalUrl2 = href + (href.includes("?") ? "&" : "?") + "displayMode=minibrowser";
|
|
1014
|
+
localStorage.setItem(
|
|
1015
|
+
CACHE_KEY,
|
|
1016
|
+
JSON.stringify({
|
|
1017
|
+
url: finalUrl2,
|
|
1018
|
+
ts: Date.now()
|
|
1019
|
+
})
|
|
1020
|
+
);
|
|
1021
|
+
if (!localStorage.getItem(RELOAD_KEY)) {
|
|
1022
|
+
localStorage.setItem(RELOAD_KEY, "1");
|
|
1023
|
+
window.location.reload();
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
activatePayPal(finalUrl2, runId);
|
|
1027
|
+
}).catch(() => {
|
|
1028
|
+
if (runId !== currentRunId.current) return;
|
|
1029
|
+
showError("Unable to connect to service.");
|
|
1030
|
+
});
|
|
1031
|
+
},
|
|
1032
|
+
[env]
|
|
1033
|
+
);
|
|
1034
|
+
const showUI = react.useCallback(() => {
|
|
1035
|
+
var _a, _b, _c, _d;
|
|
1036
|
+
const btn = document.querySelector('[data-paypal-button="true"]');
|
|
1037
|
+
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)) {
|
|
1038
|
+
window.PAYPAL.apps.Signup.miniBrowser.init();
|
|
1039
|
+
}
|
|
1040
|
+
setConnState("ready");
|
|
1041
|
+
}, []);
|
|
1042
|
+
const showError = react.useCallback((msg) => {
|
|
1043
|
+
setConnState("error");
|
|
1044
|
+
setError(msg);
|
|
1045
|
+
}, []);
|
|
1046
|
+
const activatePayPal = react.useCallback(
|
|
1047
|
+
(url, runId) => {
|
|
1048
|
+
if (paypalButtonRef.current) {
|
|
1049
|
+
paypalButtonRef.current.href = url;
|
|
1216
1050
|
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1051
|
+
setFinalUrl(url);
|
|
1052
|
+
const tryInit = () => {
|
|
1053
|
+
var _a, _b;
|
|
1054
|
+
if (runId !== currentRunId.current) return;
|
|
1055
|
+
if ((_b = (_a = window.PAYPAL) == null ? void 0 : _a.apps) == null ? void 0 : _b.Signup) {
|
|
1056
|
+
showUI();
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
setTimeout(tryInit, 50);
|
|
1060
|
+
};
|
|
1061
|
+
tryInit();
|
|
1062
|
+
},
|
|
1063
|
+
[showUI]
|
|
1064
|
+
);
|
|
1065
|
+
react.useEffect(() => {
|
|
1066
|
+
currentRunId.current = ++runIdRef.current;
|
|
1067
|
+
const runId = currentRunId.current;
|
|
1068
|
+
let cancelled = false;
|
|
1069
|
+
const run = async () => {
|
|
1070
|
+
setConnState("loading");
|
|
1071
|
+
setError(null);
|
|
1072
|
+
setFinalUrl("");
|
|
1073
|
+
try {
|
|
1074
|
+
const r = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
1075
|
+
method: "GET"
|
|
1076
|
+
});
|
|
1077
|
+
const st = await r.json().catch(() => ({}));
|
|
1078
|
+
if (cancelled || runId !== currentRunId.current) return;
|
|
1079
|
+
setStatusInfo(st);
|
|
1080
|
+
const isConnected = (st == null ? void 0 : st.status) === "connected" && (st == null ? void 0 : st.seller_client_id_present) === true;
|
|
1081
|
+
if (isConnected) {
|
|
1082
|
+
setConnState("connected");
|
|
1083
|
+
setShowManual(false);
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
} catch (e) {
|
|
1087
|
+
console.error(e);
|
|
1088
|
+
}
|
|
1089
|
+
if (cachedUrl) {
|
|
1090
|
+
console.log("Using prioritized cache...");
|
|
1091
|
+
activatePayPal(cachedUrl, runId);
|
|
1092
|
+
} else {
|
|
1093
|
+
fetchFreshLink(runId);
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
run();
|
|
1097
|
+
return () => {
|
|
1098
|
+
cancelled = true;
|
|
1099
|
+
currentRunId.current = 0;
|
|
1100
|
+
};
|
|
1101
|
+
}, [env, fetchFreshLink, activatePayPal]);
|
|
1102
|
+
react.useLayoutEffect(() => {
|
|
1103
|
+
window.onboardingCallback = async function(authCode, sharedId) {
|
|
1104
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1105
|
+
try {
|
|
1106
|
+
;
|
|
1107
|
+
window.onbeforeunload = "";
|
|
1108
|
+
} catch {
|
|
1109
|
+
}
|
|
1110
|
+
setOnboardingInProgress(true);
|
|
1111
|
+
setConnState("loading");
|
|
1112
|
+
setError(null);
|
|
1113
|
+
const payload = {
|
|
1114
|
+
authCode,
|
|
1115
|
+
sharedId,
|
|
1116
|
+
env: env === "sandbox" ? "sandbox" : "live"
|
|
1117
|
+
};
|
|
1118
|
+
try {
|
|
1119
|
+
const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
|
|
1120
|
+
method: "POST",
|
|
1121
|
+
headers: { "content-type": "application/json" },
|
|
1122
|
+
body: JSON.stringify(payload)
|
|
1123
|
+
});
|
|
1124
|
+
if (!res.ok) {
|
|
1125
|
+
const txt = await res.text().catch(() => "");
|
|
1126
|
+
throw new Error(txt || `Onboarding exchange failed (${res.status})`);
|
|
1127
|
+
}
|
|
1128
|
+
try {
|
|
1129
|
+
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;
|
|
1130
|
+
if (typeof close1 === "function") close1();
|
|
1131
|
+
} catch {
|
|
1132
|
+
}
|
|
1133
|
+
try {
|
|
1134
|
+
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;
|
|
1135
|
+
if (typeof close2 === "function") close2();
|
|
1136
|
+
} catch {
|
|
1137
|
+
}
|
|
1138
|
+
try {
|
|
1139
|
+
localStorage.removeItem(CACHE_KEY);
|
|
1140
|
+
localStorage.removeItem(RELOAD_KEY);
|
|
1141
|
+
} catch {
|
|
1142
|
+
}
|
|
1143
|
+
window.location.href = window.location.href;
|
|
1144
|
+
} catch (e) {
|
|
1145
|
+
console.error(e);
|
|
1146
|
+
setConnState("error");
|
|
1147
|
+
setError((e == null ? void 0 : e.message) || "Exchange failed while saving credentials.");
|
|
1148
|
+
setOnboardingInProgress(false);
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
return () => {
|
|
1152
|
+
window.onboardingCallback = void 0;
|
|
1153
|
+
};
|
|
1154
|
+
}, [env]);
|
|
1155
|
+
react.useLayoutEffect(() => {
|
|
1156
|
+
const el = ppBtnMeasureRef.current;
|
|
1157
|
+
if (!el) return;
|
|
1158
|
+
const update = () => {
|
|
1159
|
+
const w = Math.round(el.getBoundingClientRect().width || 0);
|
|
1160
|
+
if (w > 0) setPpBtnWidth(w);
|
|
1161
|
+
};
|
|
1162
|
+
update();
|
|
1163
|
+
let ro = null;
|
|
1164
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
1165
|
+
ro = new ResizeObserver(() => update());
|
|
1166
|
+
ro.observe(el);
|
|
1167
|
+
} else {
|
|
1168
|
+
window.addEventListener("resize", update);
|
|
1169
|
+
}
|
|
1170
|
+
return () => {
|
|
1171
|
+
if (ro) ro.disconnect();
|
|
1172
|
+
else window.removeEventListener("resize", update);
|
|
1173
|
+
};
|
|
1174
|
+
}, [connState, env, finalUrl]);
|
|
1175
|
+
const handleConnectClick = (e) => {
|
|
1176
|
+
if (connState !== "ready" || !finalUrl || onboardingInProgress) {
|
|
1177
|
+
e.preventDefault();
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
const handleSaveManual = async () => {
|
|
1181
|
+
if (!canSaveManual || onboardingInProgress) return;
|
|
1182
|
+
setOnboardingInProgress(true);
|
|
1183
|
+
setConnState("loading");
|
|
1184
|
+
setError(null);
|
|
1235
1185
|
try {
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
}
|
|
1186
|
+
const res = await fetch(SAVE_CREDENTIALS_ENDPOINT, {
|
|
1187
|
+
method: "POST",
|
|
1188
|
+
headers: { "content-type": "application/json" },
|
|
1189
|
+
body: JSON.stringify({
|
|
1190
|
+
clientId: clientId.trim(),
|
|
1191
|
+
clientSecret: secret.trim()
|
|
1192
|
+
})
|
|
1243
1193
|
});
|
|
1244
|
-
if (!
|
|
1245
|
-
const
|
|
1246
|
-
throw new Error(
|
|
1194
|
+
if (!res.ok) {
|
|
1195
|
+
const txt = await res.text().catch(() => "");
|
|
1196
|
+
throw new Error(txt || `Save credentials failed (${res.status})`);
|
|
1247
1197
|
}
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1198
|
+
setConnState("connected");
|
|
1199
|
+
setStatusInfo({
|
|
1200
|
+
seller_client_id_masked: maskValue(clientId.trim()),
|
|
1201
|
+
seller_client_secret_masked: "••••••••"
|
|
1202
|
+
});
|
|
1203
|
+
setShowManual(false);
|
|
1204
|
+
try {
|
|
1205
|
+
localStorage.removeItem(CACHE_KEY);
|
|
1206
|
+
localStorage.removeItem(RELOAD_KEY);
|
|
1207
|
+
} catch {
|
|
1208
|
+
}
|
|
1209
|
+
} catch (e) {
|
|
1210
|
+
console.error(e);
|
|
1211
|
+
setConnState("error");
|
|
1212
|
+
setError((e == null ? void 0 : e.message) || "Failed to save credentials.");
|
|
1253
1213
|
} finally {
|
|
1254
|
-
|
|
1214
|
+
setOnboardingInProgress(false);
|
|
1255
1215
|
}
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
1266
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm", children: [
|
|
1267
|
-
/* @__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: [
|
|
1268
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-ui-fg-base", children: "Latest events" }),
|
|
1269
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1270
|
-
"button",
|
|
1271
|
-
{
|
|
1272
|
-
type: "button",
|
|
1273
|
-
onClick: fetchLogs,
|
|
1274
|
-
className: "rounded-md border border-ui-border-base px-3 py-2 text-sm text-ui-fg-base",
|
|
1275
|
-
disabled: loading,
|
|
1276
|
-
children: loading ? "Refreshing..." : "Refresh"
|
|
1277
|
-
}
|
|
1278
|
-
)
|
|
1279
|
-
] }) }),
|
|
1280
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
|
|
1281
|
-
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,
|
|
1282
|
-
!error && logs.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-ui-fg-subtle", children: loading ? "Loading audit logs..." : "No audit log entries found yet." }) : null,
|
|
1283
|
-
logs.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full text-left text-sm", children: [
|
|
1284
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "text-ui-fg-muted", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1285
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 pr-4 font-medium", children: "Timestamp" }),
|
|
1286
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 pr-4 font-medium", children: "Event" }),
|
|
1287
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 font-medium", children: "Details" })
|
|
1288
|
-
] }) }),
|
|
1289
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: logs.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-t border-ui-border-base", children: [
|
|
1290
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 pr-4 text-ui-fg-base", children: formatDate$2(entry.created_at) || "—" }),
|
|
1291
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 pr-4 text-ui-fg-base", children: entry.event_type || "—" }),
|
|
1292
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 text-ui-fg-subtle", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap rounded-md bg-ui-bg-subtle p-2 text-xs text-ui-fg-subtle", children: JSON.stringify(entry.metadata || {}, null, 2) }) })
|
|
1293
|
-
] }, entry.id)) })
|
|
1294
|
-
] }) }) : null
|
|
1295
|
-
] })
|
|
1296
|
-
] })
|
|
1297
|
-
] }) });
|
|
1298
|
-
}
|
|
1299
|
-
function PayPalGooglePayPage() {
|
|
1300
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
1301
|
-
}
|
|
1302
|
-
const EMPTY_FILTERS = {
|
|
1303
|
-
dispute_id: "",
|
|
1304
|
-
status: "",
|
|
1305
|
-
order_id: "",
|
|
1306
|
-
cart_id: ""
|
|
1307
|
-
};
|
|
1308
|
-
function formatDate$1(value) {
|
|
1309
|
-
if (!value) {
|
|
1310
|
-
return "";
|
|
1311
|
-
}
|
|
1312
|
-
const parsed = new Date(value);
|
|
1313
|
-
if (Number.isNaN(parsed.getTime())) {
|
|
1314
|
-
return value;
|
|
1315
|
-
}
|
|
1316
|
-
return parsed.toLocaleString();
|
|
1317
|
-
}
|
|
1318
|
-
function PayPalDisputesPage() {
|
|
1319
|
-
const [filters, setFilters] = react.useState({ ...EMPTY_FILTERS });
|
|
1320
|
-
const [disputes, setDisputes] = react.useState([]);
|
|
1321
|
-
const [loading, setLoading] = react.useState(false);
|
|
1322
|
-
const [error, setError] = react.useState(null);
|
|
1323
|
-
const queryString = react.useMemo(() => {
|
|
1324
|
-
const params = new URLSearchParams();
|
|
1325
|
-
Object.entries(filters).forEach(([key, value]) => {
|
|
1326
|
-
if (value.trim()) {
|
|
1327
|
-
params.set(key, value.trim());
|
|
1328
|
-
}
|
|
1329
|
-
});
|
|
1330
|
-
const qs = params.toString();
|
|
1331
|
-
return qs ? `?${qs}` : "";
|
|
1332
|
-
}, [filters]);
|
|
1333
|
-
const fetchDisputes = react.useCallback(async (source) => {
|
|
1216
|
+
};
|
|
1217
|
+
const handleDisconnect = async () => {
|
|
1218
|
+
if (onboardingInProgress) return;
|
|
1219
|
+
if (!window.confirm("Disconnect PayPal for this environment?")) return;
|
|
1220
|
+
setOnboardingInProgress(true);
|
|
1221
|
+
setConnState("loading");
|
|
1222
|
+
setError(null);
|
|
1223
|
+
setFinalUrl("");
|
|
1224
|
+
setShowManual(false);
|
|
1334
1225
|
try {
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
if (value.trim()) {
|
|
1340
|
-
params.set(key, value.trim());
|
|
1341
|
-
}
|
|
1342
|
-
});
|
|
1343
|
-
const qs = params.toString();
|
|
1344
|
-
const resp = await fetch(`/admin/paypal/disputes${qs ? `?${qs}` : ""}`, {
|
|
1345
|
-
credentials: "include",
|
|
1346
|
-
headers: {
|
|
1347
|
-
Accept: "application/json"
|
|
1348
|
-
}
|
|
1226
|
+
const res = await fetch(DISCONNECT_ENDPOINT, {
|
|
1227
|
+
method: "POST",
|
|
1228
|
+
headers: { "content-type": "application/json" },
|
|
1229
|
+
body: JSON.stringify({ environment: env })
|
|
1349
1230
|
});
|
|
1350
|
-
if (!
|
|
1351
|
-
const
|
|
1352
|
-
throw new Error(
|
|
1231
|
+
if (!res.ok) {
|
|
1232
|
+
const t = await res.text().catch(() => "");
|
|
1233
|
+
throw new Error(t || `Disconnect failed (${res.status})`);
|
|
1353
1234
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1235
|
+
try {
|
|
1236
|
+
localStorage.removeItem(CACHE_KEY);
|
|
1237
|
+
localStorage.removeItem(RELOAD_KEY);
|
|
1238
|
+
} catch {
|
|
1239
|
+
}
|
|
1240
|
+
currentRunId.current = ++runIdRef.current;
|
|
1241
|
+
const runId = currentRunId.current;
|
|
1242
|
+
fetchFreshLink(runId);
|
|
1243
|
+
} catch (e) {
|
|
1244
|
+
console.error(e);
|
|
1245
|
+
setConnState("error");
|
|
1246
|
+
setError((e == null ? void 0 : e.message) || "Failed to disconnect.");
|
|
1359
1247
|
} finally {
|
|
1360
|
-
|
|
1248
|
+
setOnboardingInProgress(false);
|
|
1361
1249
|
}
|
|
1362
|
-
}, []);
|
|
1363
|
-
react.useEffect(() => {
|
|
1364
|
-
fetchDisputes(EMPTY_FILTERS);
|
|
1365
|
-
}, [fetchDisputes]);
|
|
1366
|
-
const onSubmit = (event) => {
|
|
1367
|
-
event.preventDefault();
|
|
1368
|
-
fetchDisputes(filters);
|
|
1369
1250
|
};
|
|
1370
|
-
const
|
|
1371
|
-
|
|
1372
|
-
|
|
1251
|
+
const handleEnvChange = async (e) => {
|
|
1252
|
+
const next = e.target.value;
|
|
1253
|
+
setEnv(next);
|
|
1254
|
+
cachedUrl = null;
|
|
1255
|
+
try {
|
|
1256
|
+
await fetch("/admin/paypal/environment", {
|
|
1257
|
+
method: "POST",
|
|
1258
|
+
headers: { "content-type": "application/json" },
|
|
1259
|
+
body: JSON.stringify({ environment: next })
|
|
1260
|
+
});
|
|
1261
|
+
} catch {
|
|
1262
|
+
}
|
|
1263
|
+
try {
|
|
1264
|
+
localStorage.removeItem(CACHE_KEY);
|
|
1265
|
+
localStorage.removeItem(RELOAD_KEY);
|
|
1266
|
+
} catch {
|
|
1267
|
+
}
|
|
1373
1268
|
};
|
|
1374
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
1375
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1376
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold
|
|
1377
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1269
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6", children: [
|
|
1270
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
1271
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold", children: "PayPal Gateway By Easy Payment" }),
|
|
1272
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalTabs, {}),
|
|
1273
|
+
/* @__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: [
|
|
1274
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium pt-2", children: "Environment" }),
|
|
1275
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-xl", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1276
|
+
"select",
|
|
1277
|
+
{
|
|
1278
|
+
value: env,
|
|
1279
|
+
onChange: handleEnvChange,
|
|
1280
|
+
disabled: onboardingInProgress,
|
|
1281
|
+
className: "w-full rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm",
|
|
1282
|
+
children: [
|
|
1283
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "sandbox", children: "Sandbox (Test Mode)" }),
|
|
1284
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "live", children: "Live (Production)" })
|
|
1285
|
+
]
|
|
1286
|
+
}
|
|
1287
|
+
) }),
|
|
1288
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium pt-2", children: env === "sandbox" ? "Connect to PayPal Sandbox" : "Connect to PayPal Live" }),
|
|
1289
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-xl", children: connState === "connected" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1290
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-green-600 bg-green-50 p-3 rounded border border-green-200", children: [
|
|
1291
|
+
"✅ Successfully connected to PayPal!",
|
|
1292
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1293
|
+
"a",
|
|
1294
|
+
{
|
|
1295
|
+
"data-paypal-button": "true",
|
|
1296
|
+
"data-paypal-onboard-complete": "onboardingCallback",
|
|
1297
|
+
href: "#",
|
|
1298
|
+
style: { display: "none" },
|
|
1299
|
+
children: "PayPal"
|
|
1300
|
+
}
|
|
1301
|
+
)
|
|
1302
|
+
] }),
|
|
1303
|
+
/* @__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: [
|
|
1304
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-ui-fg-base", children: "Connected PayPal account" }),
|
|
1305
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1", children: [
|
|
1306
|
+
"Email:",
|
|
1307
|
+
" ",
|
|
1308
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-ui-fg-base", children: (statusInfo == null ? void 0 : statusInfo.seller_email) || "Unavailable" })
|
|
1309
|
+
] })
|
|
1310
|
+
] }),
|
|
1311
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1312
|
+
"button",
|
|
1313
|
+
{
|
|
1314
|
+
type: "button",
|
|
1315
|
+
onClick: handleDisconnect,
|
|
1316
|
+
disabled: onboardingInProgress,
|
|
1317
|
+
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",
|
|
1318
|
+
children: "Disconnect"
|
|
1319
|
+
}
|
|
1320
|
+
) })
|
|
1321
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1322
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1323
|
+
"div",
|
|
1324
|
+
{
|
|
1325
|
+
ref: initLoaderRef,
|
|
1326
|
+
id: "init-loader",
|
|
1327
|
+
className: `status-msg mb-4 ${connState !== "loading" ? "hidden" : "block"}`,
|
|
1328
|
+
children: [
|
|
1329
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "loader inline-block align-middle mr-2" }),
|
|
1330
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { id: "loader-text", className: "text-sm", children: onboardingInProgress ? "Configuring connection to PayPal…" : "Checking connection..." })
|
|
1331
|
+
]
|
|
1332
|
+
}
|
|
1333
|
+
),
|
|
1334
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${connState === "ready" ? "block" : "hidden"}`, children: [
|
|
1335
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1336
|
+
"a",
|
|
1337
|
+
{
|
|
1338
|
+
ref: (node) => {
|
|
1339
|
+
paypalButtonRef.current = node;
|
|
1340
|
+
ppBtnMeasureRef.current = node;
|
|
1341
|
+
},
|
|
1342
|
+
id: "paypal-button",
|
|
1343
|
+
"data-paypal-button": "true",
|
|
1344
|
+
href: finalUrl || "#",
|
|
1345
|
+
"data-paypal-onboard-complete": "onboardingCallback",
|
|
1346
|
+
onClick: handleConnectClick,
|
|
1347
|
+
className: "btn-paypal",
|
|
1348
|
+
style: {
|
|
1349
|
+
borderRadius: "50px",
|
|
1350
|
+
textDecoration: "none",
|
|
1351
|
+
display: "inline-block",
|
|
1352
|
+
fontWeight: "bold",
|
|
1353
|
+
border: "none",
|
|
1354
|
+
cursor: onboardingInProgress ? "not-allowed" : "pointer",
|
|
1355
|
+
opacity: onboardingInProgress ? 0.6 : 1,
|
|
1356
|
+
pointerEvents: onboardingInProgress ? "none" : "auto"
|
|
1357
|
+
},
|
|
1358
|
+
children: "Connect to PayPal"
|
|
1359
|
+
}
|
|
1360
|
+
),
|
|
1361
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1362
|
+
"div",
|
|
1363
|
+
{
|
|
1364
|
+
className: "mt-2",
|
|
1365
|
+
style: {
|
|
1366
|
+
width: ppBtnWidth ? `${ppBtnWidth}px` : "auto",
|
|
1367
|
+
marginTop: "20px",
|
|
1368
|
+
marginBottom: "10px"
|
|
1369
|
+
},
|
|
1370
|
+
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" }) })
|
|
1371
|
+
}
|
|
1372
|
+
),
|
|
1373
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1374
|
+
"button",
|
|
1375
|
+
{
|
|
1376
|
+
type: "button",
|
|
1377
|
+
onClick: () => setShowManual(!showManual),
|
|
1378
|
+
disabled: onboardingInProgress,
|
|
1379
|
+
className: "text-sm text-ui-fg-interactive underline whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1380
|
+
children: "Click here to insert credentials manually"
|
|
1381
|
+
}
|
|
1382
|
+
) })
|
|
1383
|
+
] }),
|
|
1384
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `${connState === "ready" ? "hidden" : "block"} mt-3`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1385
|
+
"button",
|
|
1386
|
+
{
|
|
1387
|
+
type: "button",
|
|
1388
|
+
onClick: () => setShowManual(!showManual),
|
|
1389
|
+
disabled: onboardingInProgress,
|
|
1390
|
+
className: "text-sm text-ui-fg-interactive underline whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1391
|
+
children: "Click here to insert credentials manually"
|
|
1392
|
+
}
|
|
1393
|
+
) }),
|
|
1394
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1395
|
+
"div",
|
|
1396
|
+
{
|
|
1397
|
+
ref: errorLogRef,
|
|
1398
|
+
id: "error-log",
|
|
1399
|
+
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"}`,
|
|
1400
|
+
children: error
|
|
1401
|
+
}
|
|
1402
|
+
)
|
|
1403
|
+
] }) }),
|
|
1404
|
+
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: [
|
|
1405
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1406
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Client ID" }),
|
|
1386
1407
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1387
1408
|
"input",
|
|
1388
1409
|
{
|
|
1389
|
-
|
|
1390
|
-
value:
|
|
1391
|
-
onChange: (
|
|
1392
|
-
|
|
1410
|
+
type: "text",
|
|
1411
|
+
value: clientId,
|
|
1412
|
+
onChange: (e) => setClientId(e.target.value),
|
|
1413
|
+
disabled: onboardingInProgress,
|
|
1414
|
+
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
1415
|
+
placeholder: env === "sandbox" ? "Sandbox Client ID" : "Live Client ID"
|
|
1393
1416
|
}
|
|
1394
1417
|
)
|
|
1395
1418
|
] }),
|
|
1396
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
1397
|
-
"
|
|
1419
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1420
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Client Secret" }),
|
|
1398
1421
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1399
1422
|
"input",
|
|
1400
1423
|
{
|
|
1401
|
-
|
|
1402
|
-
value:
|
|
1403
|
-
onChange: (
|
|
1404
|
-
|
|
1424
|
+
type: "password",
|
|
1425
|
+
value: secret,
|
|
1426
|
+
onChange: (e) => setSecret(e.target.value),
|
|
1427
|
+
disabled: onboardingInProgress,
|
|
1428
|
+
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
1429
|
+
placeholder: env === "sandbox" ? "Sandbox Secret" : "Live Secret"
|
|
1405
1430
|
}
|
|
1406
1431
|
)
|
|
1407
1432
|
] }),
|
|
1408
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
1409
|
-
"
|
|
1433
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:col-span-2", children: [
|
|
1434
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Merchant ID (optional)" }),
|
|
1410
1435
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1411
1436
|
"input",
|
|
1412
1437
|
{
|
|
1413
|
-
|
|
1414
|
-
value:
|
|
1415
|
-
onChange: (
|
|
1416
|
-
|
|
1438
|
+
type: "text",
|
|
1439
|
+
value: merchantId,
|
|
1440
|
+
onChange: (e) => setMerchantId(e.target.value),
|
|
1441
|
+
disabled: onboardingInProgress,
|
|
1442
|
+
className: "rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50",
|
|
1443
|
+
placeholder: "Merchant ID"
|
|
1417
1444
|
}
|
|
1418
1445
|
)
|
|
1419
1446
|
] }),
|
|
1420
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
1421
|
-
"Cart ID",
|
|
1447
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:col-span-2 flex items-center gap-2 mt-2", children: [
|
|
1422
1448
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1423
|
-
"
|
|
1449
|
+
"button",
|
|
1424
1450
|
{
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1451
|
+
type: "button",
|
|
1452
|
+
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",
|
|
1453
|
+
onClick: () => setShowManual(false),
|
|
1454
|
+
disabled: onboardingInProgress,
|
|
1455
|
+
children: "Cancel"
|
|
1456
|
+
}
|
|
1457
|
+
),
|
|
1458
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1459
|
+
"button",
|
|
1460
|
+
{
|
|
1461
|
+
type: "button",
|
|
1462
|
+
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",
|
|
1463
|
+
disabled: !canSaveManual || onboardingInProgress,
|
|
1464
|
+
onClick: handleSaveManual,
|
|
1465
|
+
children: "Save credentials"
|
|
1429
1466
|
}
|
|
1430
1467
|
)
|
|
1431
1468
|
] })
|
|
1432
|
-
] })
|
|
1433
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-3", children: [
|
|
1434
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1435
|
-
"button",
|
|
1436
|
-
{
|
|
1437
|
-
type: "submit",
|
|
1438
|
-
className: "rounded-md bg-ui-fg-base px-4 py-2 text-sm font-medium text-ui-bg-base",
|
|
1439
|
-
disabled: loading,
|
|
1440
|
-
children: loading ? "Loading..." : "Apply filters"
|
|
1441
|
-
}
|
|
1442
|
-
),
|
|
1443
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1444
|
-
"button",
|
|
1445
|
-
{
|
|
1446
|
-
type: "button",
|
|
1447
|
-
className: "rounded-md border border-ui-border-base px-4 py-2 text-sm text-ui-fg-base",
|
|
1448
|
-
onClick: onReset,
|
|
1449
|
-
disabled: loading,
|
|
1450
|
-
children: "Reset"
|
|
1451
|
-
}
|
|
1452
|
-
),
|
|
1453
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-ui-fg-subtle", children: [
|
|
1454
|
-
"Showing ",
|
|
1455
|
-
disputes.length,
|
|
1456
|
-
" dispute",
|
|
1457
|
-
disputes.length === 1 ? "" : "s",
|
|
1458
|
-
queryString ? " (filtered)" : ""
|
|
1459
|
-
] })
|
|
1460
|
-
] })
|
|
1469
|
+
] }) })
|
|
1461
1470
|
] }) })
|
|
1462
1471
|
] }),
|
|
1463
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3", children: dispute.amount ? `${dispute.amount} ${dispute.currency_code || ""}` : "-" }),
|
|
1485
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3", children: dispute.order_id || "-" }),
|
|
1486
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3", children: dispute.cart_id || "-" }),
|
|
1487
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-ui-fg-subtle", children: formatDate$1(dispute.updated_at || dispute.created_at) })
|
|
1488
|
-
] }, dispute.id)) })
|
|
1489
|
-
] }) }),
|
|
1490
|
-
error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-ui-border-base px-4 py-3 text-sm text-ui-fg-error", children: error }) : null
|
|
1491
|
-
] })
|
|
1492
|
-
] }) });
|
|
1472
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
1473
|
+
.loader {
|
|
1474
|
+
border: 3px solid #f3f3f3;
|
|
1475
|
+
border-top: 3px solid #0070ba;
|
|
1476
|
+
border-radius: 50%;
|
|
1477
|
+
width: 18px;
|
|
1478
|
+
height: 18px;
|
|
1479
|
+
animation: spin 1s linear infinite;
|
|
1480
|
+
display: inline-block;
|
|
1481
|
+
vertical-align: middle;
|
|
1482
|
+
margin-right: 8px;
|
|
1483
|
+
}
|
|
1484
|
+
@keyframes spin {
|
|
1485
|
+
0% { transform: rotate(0deg); }
|
|
1486
|
+
100% { transform: rotate(360deg); }
|
|
1487
|
+
}
|
|
1488
|
+
` })
|
|
1489
|
+
] });
|
|
1490
|
+
}
|
|
1491
|
+
function PayPalGooglePayPage() {
|
|
1492
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
1493
1493
|
}
|
|
1494
1494
|
function PayPalPayLaterMessagingPage() {
|
|
1495
1495
|
return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
|
|
@@ -2052,14 +2052,6 @@ const routeModule = {
|
|
|
2052
2052
|
Component: AdditionalSettingsTab,
|
|
2053
2053
|
path: "/settings/paypal/additional-settings"
|
|
2054
2054
|
},
|
|
2055
|
-
{
|
|
2056
|
-
Component: PayPalApplePayPage,
|
|
2057
|
-
path: "/settings/paypal/apple-pay"
|
|
2058
|
-
},
|
|
2059
|
-
{
|
|
2060
|
-
Component: PayPalConnectionPage,
|
|
2061
|
-
path: "/settings/paypal/connection"
|
|
2062
|
-
},
|
|
2063
2055
|
{
|
|
2064
2056
|
Component: AdvancedCardPaymentsTab,
|
|
2065
2057
|
path: "/settings/paypal/advanced-card-payments"
|
|
@@ -2069,13 +2061,21 @@ const routeModule = {
|
|
|
2069
2061
|
path: "/settings/paypal/audit-logs"
|
|
2070
2062
|
},
|
|
2071
2063
|
{
|
|
2072
|
-
Component:
|
|
2073
|
-
path: "/settings/paypal/
|
|
2064
|
+
Component: PayPalApplePayPage,
|
|
2065
|
+
path: "/settings/paypal/apple-pay"
|
|
2074
2066
|
},
|
|
2075
2067
|
{
|
|
2076
2068
|
Component: PayPalDisputesPage,
|
|
2077
2069
|
path: "/settings/paypal/disputes"
|
|
2078
2070
|
},
|
|
2071
|
+
{
|
|
2072
|
+
Component: PayPalConnectionPage,
|
|
2073
|
+
path: "/settings/paypal/connection"
|
|
2074
|
+
},
|
|
2075
|
+
{
|
|
2076
|
+
Component: PayPalGooglePayPage,
|
|
2077
|
+
path: "/settings/paypal/google-pay"
|
|
2078
|
+
},
|
|
2079
2079
|
{
|
|
2080
2080
|
Component: PayPalPayLaterMessagingPage,
|
|
2081
2081
|
path: "/settings/paypal/pay-later-messaging"
|