order-management 0.0.90 → 0.0.91
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 +452 -395
- package/.medusa/server/src/admin/index.mjs +454 -397
- package/.medusa/server/src/api/admin/orders/[order_id]/refund-context/route.js +18 -1
- package/.medusa/server/src/api/admin/return/[id]/route.js +9 -2
- package/.medusa/server/src/api/admin/return/route.js +43 -3
- package/.medusa/server/src/api/store/orders/[order_id]/refund-payment-mappings/route.js +4 -2
- package/.medusa/server/src/api/store/returns/[id]/route.js +13 -3
- package/.medusa/server/src/api/store/returns/route.js +36 -3
- package/.medusa/server/src/helpers/index.js +2 -1
- package/.medusa/server/src/helpers/refund-calculation.js +274 -0
- package/.medusa/server/src/helpers/returns.js +2 -1
- package/README.md +29 -11
- package/package.json +1 -1
|
@@ -470,6 +470,48 @@ const OrderGiftItemsWidget = ({ data }) => {
|
|
|
470
470
|
adminSdk.defineWidgetConfig({
|
|
471
471
|
zone: "order.details.side.after"
|
|
472
472
|
});
|
|
473
|
+
function formatRefundCurrency(amount, currencyCode = "inr", options) {
|
|
474
|
+
const formatted = new Intl.NumberFormat("en-IN", {
|
|
475
|
+
style: "currency",
|
|
476
|
+
currency: (currencyCode || "inr").toUpperCase(),
|
|
477
|
+
currencyDisplay: "symbol",
|
|
478
|
+
minimumFractionDigits: 2,
|
|
479
|
+
maximumFractionDigits: 2
|
|
480
|
+
}).format(amount);
|
|
481
|
+
if ((options == null ? void 0 : options.signed) && amount > 0) {
|
|
482
|
+
return `−${formatted}`;
|
|
483
|
+
}
|
|
484
|
+
return formatted;
|
|
485
|
+
}
|
|
486
|
+
const RefundCalculationBlock = ({ refund }) => {
|
|
487
|
+
const currency = refund.currency_code || "inr";
|
|
488
|
+
const finalLabel = refund.is_processed ? formatRefundCurrency(refund.final_refund_amount ?? 0, currency) : "Refund pending";
|
|
489
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
490
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Refund calculation" }),
|
|
491
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
492
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
|
|
493
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Product amount" }),
|
|
494
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: formatRefundCurrency(refund.product_amount, currency) })
|
|
495
|
+
] }),
|
|
496
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
|
|
497
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Return charge" }),
|
|
498
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: formatRefundCurrency(refund.return_charge, currency, { signed: true }) })
|
|
499
|
+
] }),
|
|
500
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4 border-t border-ui-border-base pt-1.5", children: [
|
|
501
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Final refund amount" }),
|
|
502
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: finalLabel })
|
|
503
|
+
] })
|
|
504
|
+
] }),
|
|
505
|
+
refund.is_processed && refund.destination_label ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
506
|
+
formatRefundCurrency(refund.final_refund_amount ?? 0, currency),
|
|
507
|
+
" will be refunded to",
|
|
508
|
+
" ",
|
|
509
|
+
refund.destination_label,
|
|
510
|
+
"."
|
|
511
|
+
] }) : null,
|
|
512
|
+
!refund.is_processed ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: "Refund pending." }) : null
|
|
513
|
+
] });
|
|
514
|
+
};
|
|
473
515
|
const FIELD_LABELS = {
|
|
474
516
|
// UPI
|
|
475
517
|
upi_id: "UPI ID",
|
|
@@ -636,7 +678,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
636
678
|
}
|
|
637
679
|
};
|
|
638
680
|
if (!orderId) return null;
|
|
639
|
-
if (!loading && !error && context && !context.refund_mapping) return null;
|
|
681
|
+
if (!loading && !error && context && !context.refund_mapping && !context.refund) return null;
|
|
640
682
|
if (loading) {
|
|
641
683
|
return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mt-6 divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Loading refund context..." }) }) });
|
|
642
684
|
}
|
|
@@ -659,6 +701,7 @@ const OrderRefundContextWidget = (props) => {
|
|
|
659
701
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: context.return_id }),
|
|
660
702
|
((_d = context.refund_mapping) == null ? void 0 : _d.is_refunded) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "green", children: "Refunded" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "orange", children: "Not refunded" })
|
|
661
703
|
] }),
|
|
704
|
+
context.refund ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 border-t border-ui-border-base pt-3", children: /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: context.refund }) }) : null,
|
|
662
705
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
|
|
663
706
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
664
707
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Payment method (refund destination)" }),
|
|
@@ -851,7 +894,10 @@ const OrderRefundContextWidget = (props) => {
|
|
|
851
894
|
markError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: markError })
|
|
852
895
|
] })
|
|
853
896
|
] }),
|
|
854
|
-
hasReturn && !hasMapping && /* @__PURE__ */ jsxRuntime.
|
|
897
|
+
hasReturn && !hasMapping && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: [
|
|
898
|
+
(context == null ? void 0 : context.refund) ? /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: context.refund }) : null,
|
|
899
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No refund payment mapping for this return. Ensure the refund_payment_mapping module is registered and a mapping was created when the return was created." })
|
|
900
|
+
] })
|
|
855
901
|
] }) });
|
|
856
902
|
};
|
|
857
903
|
adminSdk.defineWidgetConfig({
|
|
@@ -873,16 +919,216 @@ const getStatusBadgeClass$7 = (status) => {
|
|
|
873
919
|
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
874
920
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
875
921
|
};
|
|
876
|
-
const
|
|
922
|
+
const PaymentsPage = () => {
|
|
877
923
|
const navigate = reactRouterDom.useNavigate();
|
|
878
924
|
const [items, setItems] = react.useState([]);
|
|
925
|
+
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
879
926
|
const [orderIdSearch, setOrderIdSearch] = react.useState("");
|
|
880
927
|
const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
|
|
928
|
+
const [isLoading, setIsLoading] = react.useState(true);
|
|
929
|
+
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
930
|
+
const [error, setError] = react.useState(null);
|
|
931
|
+
const [offset, setOffset] = react.useState(0);
|
|
932
|
+
const [count, setCount] = react.useState(0);
|
|
933
|
+
const limit = 50;
|
|
934
|
+
const loadTransactions = react.useCallback(
|
|
935
|
+
async (nextOffset, replace) => {
|
|
936
|
+
try {
|
|
937
|
+
if (replace) setIsLoading(true);
|
|
938
|
+
else setIsFetchingMore(true);
|
|
939
|
+
setError(null);
|
|
940
|
+
const params = new URLSearchParams();
|
|
941
|
+
params.set("limit", String(limit));
|
|
942
|
+
params.set("offset", String(nextOffset));
|
|
943
|
+
if (statusFilter !== "all") params.set("status", statusFilter);
|
|
944
|
+
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
945
|
+
const response = await fetch(
|
|
946
|
+
`/admin/payment-transactions?${params.toString()}`,
|
|
947
|
+
{ credentials: "include" }
|
|
948
|
+
);
|
|
949
|
+
if (!response.ok) {
|
|
950
|
+
const text = await response.text();
|
|
951
|
+
throw new Error(text || "Failed to load payment transactions");
|
|
952
|
+
}
|
|
953
|
+
const payload = await response.json();
|
|
954
|
+
const list = payload.transactions ?? [];
|
|
955
|
+
setCount(payload.count ?? 0);
|
|
956
|
+
setOffset(nextOffset + list.length);
|
|
957
|
+
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
958
|
+
} catch (e) {
|
|
959
|
+
setError(e instanceof Error ? e.message : "Failed to load");
|
|
960
|
+
} finally {
|
|
961
|
+
setIsLoading(false);
|
|
962
|
+
setIsFetchingMore(false);
|
|
963
|
+
}
|
|
964
|
+
},
|
|
965
|
+
[statusFilter, debouncedOrderId]
|
|
966
|
+
);
|
|
967
|
+
react.useEffect(() => {
|
|
968
|
+
void loadTransactions(0, true);
|
|
969
|
+
}, [loadTransactions]);
|
|
970
|
+
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
971
|
+
const displayStatus = (t) => {
|
|
972
|
+
const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
|
|
973
|
+
return s2 !== "" ? s2 : "—";
|
|
974
|
+
};
|
|
975
|
+
const displayAmount = (t) => {
|
|
976
|
+
const code = (t.currency_code ?? "USD").toUpperCase();
|
|
977
|
+
return `${code} ${Number(t.amount)}`;
|
|
978
|
+
};
|
|
979
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
980
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
981
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
982
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payments" }),
|
|
983
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
|
|
984
|
+
] }),
|
|
985
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
|
|
986
|
+
] }),
|
|
987
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
988
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
989
|
+
ui.Input,
|
|
990
|
+
{
|
|
991
|
+
placeholder: "Search by Order ID",
|
|
992
|
+
value: orderIdSearch,
|
|
993
|
+
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
994
|
+
className: "md:max-w-sm",
|
|
995
|
+
"aria-label": "Search by order ID"
|
|
996
|
+
}
|
|
997
|
+
),
|
|
998
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
999
|
+
"select",
|
|
1000
|
+
{
|
|
1001
|
+
value: statusFilter,
|
|
1002
|
+
onChange: (e) => setStatusFilter(e.target.value),
|
|
1003
|
+
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
|
|
1004
|
+
"aria-label": "Filter by status",
|
|
1005
|
+
children: [
|
|
1006
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
|
|
1007
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
|
|
1008
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
|
|
1009
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
|
|
1010
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
|
|
1011
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
|
|
1012
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
|
|
1013
|
+
]
|
|
1014
|
+
}
|
|
1015
|
+
) })
|
|
1016
|
+
] }),
|
|
1017
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1018
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1019
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
|
|
1020
|
+
] }) : null,
|
|
1021
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading payments…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
1022
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
|
|
1023
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
|
|
1024
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
1025
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1026
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
1027
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
1028
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
1029
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
1030
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
|
|
1031
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
1032
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
1033
|
+
] }) }),
|
|
1034
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1035
|
+
"tr",
|
|
1036
|
+
{
|
|
1037
|
+
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1038
|
+
onClick: () => navigate(`/payments/${t.payment_session_id}`),
|
|
1039
|
+
children: [
|
|
1040
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
|
|
1041
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
|
|
1042
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
|
|
1043
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1044
|
+
ui.Badge,
|
|
1045
|
+
{
|
|
1046
|
+
size: "2xsmall",
|
|
1047
|
+
className: `uppercase ${getStatusBadgeClass$7(displayStatus(t))}`,
|
|
1048
|
+
children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
|
|
1049
|
+
}
|
|
1050
|
+
) }),
|
|
1051
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
|
|
1052
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
|
|
1053
|
+
year: "numeric",
|
|
1054
|
+
month: "short",
|
|
1055
|
+
day: "numeric",
|
|
1056
|
+
hour: "numeric",
|
|
1057
|
+
minute: "2-digit",
|
|
1058
|
+
hour12: true
|
|
1059
|
+
}) }),
|
|
1060
|
+
/* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-4", children: [
|
|
1061
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1062
|
+
ui.Button,
|
|
1063
|
+
{
|
|
1064
|
+
variant: "transparent",
|
|
1065
|
+
size: "small",
|
|
1066
|
+
onClick: (e) => {
|
|
1067
|
+
e.stopPropagation();
|
|
1068
|
+
navigate(`/payments/${t.payment_session_id}`);
|
|
1069
|
+
},
|
|
1070
|
+
children: "View details"
|
|
1071
|
+
}
|
|
1072
|
+
),
|
|
1073
|
+
t.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1074
|
+
ui.Button,
|
|
1075
|
+
{
|
|
1076
|
+
variant: "transparent",
|
|
1077
|
+
size: "small",
|
|
1078
|
+
onClick: (e) => {
|
|
1079
|
+
e.stopPropagation();
|
|
1080
|
+
navigate(`/orders/${t.order_id}`);
|
|
1081
|
+
},
|
|
1082
|
+
children: "Order"
|
|
1083
|
+
}
|
|
1084
|
+
) : null
|
|
1085
|
+
] })
|
|
1086
|
+
]
|
|
1087
|
+
},
|
|
1088
|
+
t.payment_session_id
|
|
1089
|
+
)) })
|
|
1090
|
+
] }) }),
|
|
1091
|
+
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1092
|
+
ui.Button,
|
|
1093
|
+
{
|
|
1094
|
+
variant: "secondary",
|
|
1095
|
+
isLoading: isFetchingMore,
|
|
1096
|
+
onClick: () => loadTransactions(offset, false),
|
|
1097
|
+
children: "Load more"
|
|
1098
|
+
}
|
|
1099
|
+
) }) : null
|
|
1100
|
+
] }) });
|
|
1101
|
+
};
|
|
1102
|
+
const config$7 = adminSdk.defineRouteConfig({
|
|
1103
|
+
label: "Payments",
|
|
1104
|
+
icon: icons.CreditCard
|
|
1105
|
+
});
|
|
1106
|
+
const useDebounce$2 = (value, delay) => {
|
|
1107
|
+
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1108
|
+
react.useEffect(() => {
|
|
1109
|
+
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
1110
|
+
return () => clearTimeout(handler);
|
|
1111
|
+
}, [value, delay]);
|
|
1112
|
+
return debouncedValue;
|
|
1113
|
+
};
|
|
1114
|
+
const getStatusBadgeClass$6 = (status) => {
|
|
1115
|
+
const s2 = status.toLowerCase();
|
|
1116
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1117
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1118
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1119
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1120
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1121
|
+
};
|
|
1122
|
+
const RefundsPage = () => {
|
|
1123
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1124
|
+
const [items, setItems] = react.useState([]);
|
|
1125
|
+
const [orderIdSearch, setOrderIdSearch] = react.useState("");
|
|
1126
|
+
const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
|
|
881
1127
|
const [paymentStatusFilter, setPaymentStatusFilter] = react.useState("all");
|
|
882
1128
|
const [providerSearch, setProviderSearch] = react.useState("");
|
|
883
|
-
const debouncedProvider = useDebounce$
|
|
1129
|
+
const debouncedProvider = useDebounce$2(providerSearch, 300);
|
|
884
1130
|
const [currencySearch, setCurrencySearch] = react.useState("");
|
|
885
|
-
const debouncedCurrency = useDebounce$
|
|
1131
|
+
const debouncedCurrency = useDebounce$2(currencySearch, 300);
|
|
886
1132
|
const [dateFrom, setDateFrom] = react.useState("");
|
|
887
1133
|
const [dateTo, setDateTo] = react.useState("");
|
|
888
1134
|
const [amountMin, setAmountMin] = react.useState("");
|
|
@@ -1094,7 +1340,7 @@ const RefundsPage = () => {
|
|
|
1094
1340
|
ui.Badge,
|
|
1095
1341
|
{
|
|
1096
1342
|
size: "2xsmall",
|
|
1097
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1343
|
+
className: `uppercase ${getStatusBadgeClass$6(displayStatus(r))}`,
|
|
1098
1344
|
children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
|
|
1099
1345
|
}
|
|
1100
1346
|
) }),
|
|
@@ -1148,11 +1394,11 @@ const RefundsPage = () => {
|
|
|
1148
1394
|
) }) : null
|
|
1149
1395
|
] }) });
|
|
1150
1396
|
};
|
|
1151
|
-
const config$
|
|
1397
|
+
const config$6 = adminSdk.defineRouteConfig({
|
|
1152
1398
|
label: "Refunds",
|
|
1153
1399
|
icon: icons.Receipt
|
|
1154
1400
|
});
|
|
1155
|
-
const useDebounce$
|
|
1401
|
+
const useDebounce$1 = (value, delay) => {
|
|
1156
1402
|
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1157
1403
|
react.useEffect(() => {
|
|
1158
1404
|
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
@@ -1160,7 +1406,7 @@ const useDebounce$2 = (value, delay) => {
|
|
|
1160
1406
|
}, [value, delay]);
|
|
1161
1407
|
return debouncedValue;
|
|
1162
1408
|
};
|
|
1163
|
-
const getStatusBadgeClass$
|
|
1409
|
+
const getStatusBadgeClass$5 = (status) => {
|
|
1164
1410
|
const statusLower = status.toLowerCase();
|
|
1165
1411
|
if (statusLower === "requested") {
|
|
1166
1412
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -1185,7 +1431,7 @@ const ReturnsPage = () => {
|
|
|
1185
1431
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
1186
1432
|
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
1187
1433
|
const [searchQuery, setSearchQuery] = react.useState("");
|
|
1188
|
-
const debouncedSearchQuery = useDebounce$
|
|
1434
|
+
const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
|
|
1189
1435
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
1190
1436
|
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
1191
1437
|
const [error, setError] = react.useState(null);
|
|
@@ -1331,18 +1577,28 @@ const ReturnsPage = () => {
|
|
|
1331
1577
|
ui.Badge,
|
|
1332
1578
|
{
|
|
1333
1579
|
size: "2xsmall",
|
|
1334
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1580
|
+
className: `uppercase ${getStatusBadgeClass$5(returnOrder.status)}`,
|
|
1335
1581
|
children: returnOrder.status.replace(/_/g, " ")
|
|
1336
1582
|
}
|
|
1337
1583
|
) }),
|
|
1338
1584
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1339
|
-
const
|
|
1340
|
-
if (
|
|
1585
|
+
const calc = returnOrder.refund;
|
|
1586
|
+
if ((calc == null ? void 0 : calc.is_processed) && calc.final_refund_amount != null) {
|
|
1587
|
+
return formatRefundCurrency(
|
|
1588
|
+
calc.final_refund_amount,
|
|
1589
|
+
calc.currency_code || returnOrder.currency_code
|
|
1590
|
+
);
|
|
1591
|
+
}
|
|
1592
|
+
if (calc) {
|
|
1593
|
+
return "Pending";
|
|
1594
|
+
}
|
|
1595
|
+
if (returnOrder.refund_amount == null) {
|
|
1341
1596
|
return "—";
|
|
1342
1597
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1598
|
+
return formatRefundCurrency(
|
|
1599
|
+
Number(returnOrder.refund_amount),
|
|
1600
|
+
returnOrder.currency_code
|
|
1601
|
+
);
|
|
1346
1602
|
})() }),
|
|
1347
1603
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
|
|
1348
1604
|
year: "numeric",
|
|
@@ -1380,11 +1636,11 @@ const ReturnsPage = () => {
|
|
|
1380
1636
|
) }) : null
|
|
1381
1637
|
] }) });
|
|
1382
1638
|
};
|
|
1383
|
-
const config$
|
|
1639
|
+
const config$5 = adminSdk.defineRouteConfig({
|
|
1384
1640
|
label: "Return Orders",
|
|
1385
1641
|
icon: icons.ArrowPath
|
|
1386
1642
|
});
|
|
1387
|
-
const useDebounce
|
|
1643
|
+
const useDebounce = (value, delay) => {
|
|
1388
1644
|
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
1389
1645
|
react.useEffect(() => {
|
|
1390
1646
|
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
@@ -1392,7 +1648,7 @@ const useDebounce$1 = (value, delay) => {
|
|
|
1392
1648
|
}, [value, delay]);
|
|
1393
1649
|
return debouncedValue;
|
|
1394
1650
|
};
|
|
1395
|
-
const getStatusBadgeClass$
|
|
1651
|
+
const getStatusBadgeClass$4 = (status) => {
|
|
1396
1652
|
const statusLower = status.toLowerCase();
|
|
1397
1653
|
if (statusLower === "requested") {
|
|
1398
1654
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -1417,7 +1673,7 @@ const SwapsPage = () => {
|
|
|
1417
1673
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
1418
1674
|
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
1419
1675
|
const [searchQuery, setSearchQuery] = react.useState("");
|
|
1420
|
-
const debouncedSearchQuery = useDebounce
|
|
1676
|
+
const debouncedSearchQuery = useDebounce(searchQuery, 300);
|
|
1421
1677
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
1422
1678
|
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
1423
1679
|
const [error, setError] = react.useState(null);
|
|
@@ -1560,7 +1816,7 @@ const SwapsPage = () => {
|
|
|
1560
1816
|
ui.Badge,
|
|
1561
1817
|
{
|
|
1562
1818
|
size: "2xsmall",
|
|
1563
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
1819
|
+
className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
|
|
1564
1820
|
children: swap.status.replace(/_/g, " ")
|
|
1565
1821
|
}
|
|
1566
1822
|
) }),
|
|
@@ -1610,11 +1866,11 @@ const SwapsPage = () => {
|
|
|
1610
1866
|
) }) : null
|
|
1611
1867
|
] }) });
|
|
1612
1868
|
};
|
|
1613
|
-
const config$
|
|
1869
|
+
const config$4 = adminSdk.defineRouteConfig({
|
|
1614
1870
|
label: "Exchanges",
|
|
1615
1871
|
icon: icons.ArrowPath
|
|
1616
1872
|
});
|
|
1617
|
-
const getStatusBadgeClass$
|
|
1873
|
+
const getStatusBadgeClass$3 = (status) => {
|
|
1618
1874
|
const s2 = status.toLowerCase();
|
|
1619
1875
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1620
1876
|
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
@@ -1622,18 +1878,14 @@ const getStatusBadgeClass$4 = (status) => {
|
|
|
1622
1878
|
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1623
1879
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1624
1880
|
};
|
|
1625
|
-
const
|
|
1626
|
-
|
|
1627
|
-
};
|
|
1628
|
-
const RefundDetailPage = () => {
|
|
1629
|
-
var _a, _b, _c;
|
|
1881
|
+
const PaymentDetailPage = () => {
|
|
1882
|
+
var _a;
|
|
1630
1883
|
const navigate = reactRouterDom.useNavigate();
|
|
1631
1884
|
const params = reactRouterDom.useParams();
|
|
1632
1885
|
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
1633
1886
|
const [detail, setDetail] = react.useState(null);
|
|
1634
1887
|
const [loading, setLoading] = react.useState(!!id);
|
|
1635
1888
|
const [error, setError] = react.useState(null);
|
|
1636
|
-
const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
|
|
1637
1889
|
react.useEffect(() => {
|
|
1638
1890
|
if (!id) {
|
|
1639
1891
|
setLoading(false);
|
|
@@ -1642,7 +1894,7 @@ const RefundDetailPage = () => {
|
|
|
1642
1894
|
let cancelled = false;
|
|
1643
1895
|
setLoading(true);
|
|
1644
1896
|
setError(null);
|
|
1645
|
-
fetch(`/admin/
|
|
1897
|
+
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
1646
1898
|
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
1647
1899
|
return res.json();
|
|
1648
1900
|
}).then((data) => {
|
|
@@ -1656,17 +1908,140 @@ const RefundDetailPage = () => {
|
|
|
1656
1908
|
cancelled = true;
|
|
1657
1909
|
};
|
|
1658
1910
|
}, [id]);
|
|
1659
|
-
const
|
|
1660
|
-
const
|
|
1911
|
+
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
1912
|
+
const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
|
|
1913
|
+
const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
|
|
1914
|
+
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
1661
1915
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
1662
1916
|
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1663
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/
|
|
1664
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
1665
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle
|
|
1917
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
1918
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payment session" }),
|
|
1919
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
1666
1920
|
] }) }),
|
|
1667
1921
|
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
1668
1922
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
1669
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/
|
|
1923
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
1924
|
+
] }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
1925
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
1926
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1927
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
1928
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1929
|
+
ui.Button,
|
|
1930
|
+
{
|
|
1931
|
+
variant: "transparent",
|
|
1932
|
+
size: "small",
|
|
1933
|
+
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
1934
|
+
children: detail.order_id
|
|
1935
|
+
}
|
|
1936
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "—" }) })
|
|
1937
|
+
] }),
|
|
1938
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1939
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
1940
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: displayAmount })
|
|
1941
|
+
] }),
|
|
1942
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1943
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
1944
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.provider_id })
|
|
1945
|
+
] }),
|
|
1946
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1947
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
1948
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1949
|
+
ui.Badge,
|
|
1950
|
+
{
|
|
1951
|
+
size: "2xsmall",
|
|
1952
|
+
className: `uppercase ${getStatusBadgeClass$3(displayStatus)}`,
|
|
1953
|
+
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
1954
|
+
}
|
|
1955
|
+
) })
|
|
1956
|
+
] }),
|
|
1957
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1958
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
1959
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
1960
|
+
] }),
|
|
1961
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1962
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
1963
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
1964
|
+
] }),
|
|
1965
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1966
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
1967
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
1968
|
+
] }),
|
|
1969
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1970
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
1971
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
1972
|
+
year: "numeric",
|
|
1973
|
+
month: "short",
|
|
1974
|
+
day: "numeric",
|
|
1975
|
+
hour: "numeric",
|
|
1976
|
+
minute: "2-digit",
|
|
1977
|
+
hour12: true
|
|
1978
|
+
}) })
|
|
1979
|
+
] })
|
|
1980
|
+
] }) }),
|
|
1981
|
+
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
1982
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
1983
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
|
|
1984
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
|
|
1985
|
+
] }) : null
|
|
1986
|
+
] }) });
|
|
1987
|
+
};
|
|
1988
|
+
const config$3 = adminSdk.defineRouteConfig({
|
|
1989
|
+
label: "Payment details",
|
|
1990
|
+
icon: icons.CreditCard
|
|
1991
|
+
});
|
|
1992
|
+
const getStatusBadgeClass$2 = (status) => {
|
|
1993
|
+
const s2 = status.toLowerCase();
|
|
1994
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1995
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1996
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1997
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1998
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1999
|
+
};
|
|
2000
|
+
const formatAmount = (value) => {
|
|
2001
|
+
return String(value);
|
|
2002
|
+
};
|
|
2003
|
+
const RefundDetailPage = () => {
|
|
2004
|
+
var _a, _b, _c;
|
|
2005
|
+
const navigate = reactRouterDom.useNavigate();
|
|
2006
|
+
const params = reactRouterDom.useParams();
|
|
2007
|
+
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2008
|
+
const [detail, setDetail] = react.useState(null);
|
|
2009
|
+
const [loading, setLoading] = react.useState(!!id);
|
|
2010
|
+
const [error, setError] = react.useState(null);
|
|
2011
|
+
const [gatewayExpanded, setGatewayExpanded] = react.useState(false);
|
|
2012
|
+
react.useEffect(() => {
|
|
2013
|
+
if (!id) {
|
|
2014
|
+
setLoading(false);
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
let cancelled = false;
|
|
2018
|
+
setLoading(true);
|
|
2019
|
+
setError(null);
|
|
2020
|
+
fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
|
|
2021
|
+
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2022
|
+
return res.json();
|
|
2023
|
+
}).then((data) => {
|
|
2024
|
+
if (!cancelled) setDetail(data);
|
|
2025
|
+
}).catch((e) => {
|
|
2026
|
+
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2027
|
+
}).finally(() => {
|
|
2028
|
+
if (!cancelled) setLoading(false);
|
|
2029
|
+
});
|
|
2030
|
+
return () => {
|
|
2031
|
+
cancelled = true;
|
|
2032
|
+
};
|
|
2033
|
+
}, [id]);
|
|
2034
|
+
const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
|
|
2035
|
+
const hasGatewayData = ((_c = detail == null ? void 0 : detail.payment) == null ? void 0 : _c.payment_data) && typeof detail.payment.payment_data === "object" && Object.keys(detail.payment.payment_data).length > 0;
|
|
2036
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
2037
|
+
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2038
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
|
|
2039
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Refund details" }),
|
|
2040
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
|
|
2041
|
+
] }) }),
|
|
2042
|
+
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2043
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2044
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
|
|
1670
2045
|
] }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
1671
2046
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
1672
2047
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
|
|
@@ -1725,7 +2100,7 @@ const RefundDetailPage = () => {
|
|
|
1725
2100
|
ui.Badge,
|
|
1726
2101
|
{
|
|
1727
2102
|
size: "2xsmall",
|
|
1728
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2103
|
+
className: `uppercase ${getStatusBadgeClass$2(paymentStatus)}`,
|
|
1729
2104
|
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
1730
2105
|
}
|
|
1731
2106
|
) })
|
|
@@ -1802,11 +2177,11 @@ const RefundDetailPage = () => {
|
|
|
1802
2177
|
] }) : null
|
|
1803
2178
|
] }) });
|
|
1804
2179
|
};
|
|
1805
|
-
const config$
|
|
2180
|
+
const config$2 = adminSdk.defineRouteConfig({
|
|
1806
2181
|
label: "Refund details",
|
|
1807
2182
|
icon: icons.Receipt
|
|
1808
2183
|
});
|
|
1809
|
-
const getStatusBadgeClass$
|
|
2184
|
+
const getStatusBadgeClass$1 = (status) => {
|
|
1810
2185
|
const statusLower = status.toLowerCase();
|
|
1811
2186
|
if (statusLower === "requested") {
|
|
1812
2187
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -1850,7 +2225,7 @@ const ReturnDetailPage = () => {
|
|
|
1850
2225
|
try {
|
|
1851
2226
|
setIsLoading(true);
|
|
1852
2227
|
setError(null);
|
|
1853
|
-
const response = await fetch(`/admin/
|
|
2228
|
+
const response = await fetch(`/admin/return/${id}`, {
|
|
1854
2229
|
credentials: "include"
|
|
1855
2230
|
});
|
|
1856
2231
|
if (!response.ok) {
|
|
@@ -1876,7 +2251,7 @@ const ReturnDetailPage = () => {
|
|
|
1876
2251
|
setIsRejecting(true);
|
|
1877
2252
|
setUpdateError(null);
|
|
1878
2253
|
setUpdateSuccess(false);
|
|
1879
|
-
const response = await fetch(`/admin/
|
|
2254
|
+
const response = await fetch(`/admin/return/${id}/reject`, {
|
|
1880
2255
|
method: "POST",
|
|
1881
2256
|
headers: {
|
|
1882
2257
|
"Content-Type": "application/json"
|
|
@@ -1892,7 +2267,7 @@ const ReturnDetailPage = () => {
|
|
|
1892
2267
|
setReturnOrder(payload.return);
|
|
1893
2268
|
setUpdateSuccess(true);
|
|
1894
2269
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
1895
|
-
const detailResponse = await fetch(`/admin/
|
|
2270
|
+
const detailResponse = await fetch(`/admin/return/${id}`, {
|
|
1896
2271
|
credentials: "include"
|
|
1897
2272
|
});
|
|
1898
2273
|
if (detailResponse.ok) {
|
|
@@ -1940,7 +2315,7 @@ const ReturnDetailPage = () => {
|
|
|
1940
2315
|
ui.Badge,
|
|
1941
2316
|
{
|
|
1942
2317
|
size: "small",
|
|
1943
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2318
|
+
className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
|
|
1944
2319
|
children: returnOrder.status.replace(/_/g, " ")
|
|
1945
2320
|
}
|
|
1946
2321
|
)
|
|
@@ -1959,6 +2334,7 @@ const ReturnDetailPage = () => {
|
|
|
1959
2334
|
) }),
|
|
1960
2335
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
|
|
1961
2336
|
] }),
|
|
2337
|
+
returnOrder.refund ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(RefundCalculationBlock, { refund: returnOrder.refund }) }) : null,
|
|
1962
2338
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1963
2339
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
1964
2340
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
@@ -2022,7 +2398,7 @@ const ReturnDetailPage = () => {
|
|
|
2022
2398
|
ui.Badge,
|
|
2023
2399
|
{
|
|
2024
2400
|
size: "2xsmall",
|
|
2025
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
2401
|
+
className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
|
|
2026
2402
|
children: entry.status.replace(/_/g, " ")
|
|
2027
2403
|
}
|
|
2028
2404
|
) }),
|
|
@@ -2080,11 +2456,11 @@ const ReturnDetailPage = () => {
|
|
|
2080
2456
|
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
|
|
2081
2457
|
] }) });
|
|
2082
2458
|
};
|
|
2083
|
-
const config$
|
|
2459
|
+
const config$1 = adminSdk.defineRouteConfig({
|
|
2084
2460
|
label: "Return Order Details",
|
|
2085
2461
|
icon: icons.CheckCircle
|
|
2086
2462
|
});
|
|
2087
|
-
const getStatusBadgeClass
|
|
2463
|
+
const getStatusBadgeClass = (status) => {
|
|
2088
2464
|
const statusLower = status.toLowerCase();
|
|
2089
2465
|
if (statusLower === "requested") {
|
|
2090
2466
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
@@ -2222,7 +2598,7 @@ const SwapDetailPage = () => {
|
|
|
2222
2598
|
ui.Badge,
|
|
2223
2599
|
{
|
|
2224
2600
|
size: "small",
|
|
2225
|
-
className: `uppercase ${getStatusBadgeClass
|
|
2601
|
+
className: `uppercase ${getStatusBadgeClass(swap.status)}`,
|
|
2226
2602
|
children: swap.status.replace(/_/g, " ")
|
|
2227
2603
|
}
|
|
2228
2604
|
)
|
|
@@ -2290,7 +2666,7 @@ const SwapDetailPage = () => {
|
|
|
2290
2666
|
ui.Badge,
|
|
2291
2667
|
{
|
|
2292
2668
|
size: "2xsmall",
|
|
2293
|
-
className: `uppercase ${getStatusBadgeClass
|
|
2669
|
+
className: `uppercase ${getStatusBadgeClass(entry.status)}`,
|
|
2294
2670
|
children: entry.status.replace(/_/g, " ")
|
|
2295
2671
|
}
|
|
2296
2672
|
) }),
|
|
@@ -2359,329 +2735,10 @@ const SwapDetailPage = () => {
|
|
|
2359
2735
|
] })
|
|
2360
2736
|
] }) });
|
|
2361
2737
|
};
|
|
2362
|
-
const config
|
|
2738
|
+
const config = adminSdk.defineRouteConfig({
|
|
2363
2739
|
label: "Swap Details",
|
|
2364
2740
|
icon: icons.ArrowPath
|
|
2365
2741
|
});
|
|
2366
|
-
const useDebounce = (value, delay) => {
|
|
2367
|
-
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
2368
|
-
react.useEffect(() => {
|
|
2369
|
-
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
2370
|
-
return () => clearTimeout(handler);
|
|
2371
|
-
}, [value, delay]);
|
|
2372
|
-
return debouncedValue;
|
|
2373
|
-
};
|
|
2374
|
-
const getStatusBadgeClass$1 = (status) => {
|
|
2375
|
-
const s2 = status.toLowerCase();
|
|
2376
|
-
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2377
|
-
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2378
|
-
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2379
|
-
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2380
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2381
|
-
};
|
|
2382
|
-
const PaymentsPage = () => {
|
|
2383
|
-
const navigate = reactRouterDom.useNavigate();
|
|
2384
|
-
const [items, setItems] = react.useState([]);
|
|
2385
|
-
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
2386
|
-
const [orderIdSearch, setOrderIdSearch] = react.useState("");
|
|
2387
|
-
const debouncedOrderId = useDebounce(orderIdSearch, 300);
|
|
2388
|
-
const [isLoading, setIsLoading] = react.useState(true);
|
|
2389
|
-
const [isFetchingMore, setIsFetchingMore] = react.useState(false);
|
|
2390
|
-
const [error, setError] = react.useState(null);
|
|
2391
|
-
const [offset, setOffset] = react.useState(0);
|
|
2392
|
-
const [count, setCount] = react.useState(0);
|
|
2393
|
-
const limit = 50;
|
|
2394
|
-
const loadTransactions = react.useCallback(
|
|
2395
|
-
async (nextOffset, replace) => {
|
|
2396
|
-
try {
|
|
2397
|
-
if (replace) setIsLoading(true);
|
|
2398
|
-
else setIsFetchingMore(true);
|
|
2399
|
-
setError(null);
|
|
2400
|
-
const params = new URLSearchParams();
|
|
2401
|
-
params.set("limit", String(limit));
|
|
2402
|
-
params.set("offset", String(nextOffset));
|
|
2403
|
-
if (statusFilter !== "all") params.set("status", statusFilter);
|
|
2404
|
-
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
2405
|
-
const response = await fetch(
|
|
2406
|
-
`/admin/payment-transactions?${params.toString()}`,
|
|
2407
|
-
{ credentials: "include" }
|
|
2408
|
-
);
|
|
2409
|
-
if (!response.ok) {
|
|
2410
|
-
const text = await response.text();
|
|
2411
|
-
throw new Error(text || "Failed to load payment transactions");
|
|
2412
|
-
}
|
|
2413
|
-
const payload = await response.json();
|
|
2414
|
-
const list = payload.transactions ?? [];
|
|
2415
|
-
setCount(payload.count ?? 0);
|
|
2416
|
-
setOffset(nextOffset + list.length);
|
|
2417
|
-
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
2418
|
-
} catch (e) {
|
|
2419
|
-
setError(e instanceof Error ? e.message : "Failed to load");
|
|
2420
|
-
} finally {
|
|
2421
|
-
setIsLoading(false);
|
|
2422
|
-
setIsFetchingMore(false);
|
|
2423
|
-
}
|
|
2424
|
-
},
|
|
2425
|
-
[statusFilter, debouncedOrderId]
|
|
2426
|
-
);
|
|
2427
|
-
react.useEffect(() => {
|
|
2428
|
-
void loadTransactions(0, true);
|
|
2429
|
-
}, [loadTransactions]);
|
|
2430
|
-
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
2431
|
-
const displayStatus = (t) => {
|
|
2432
|
-
const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
|
|
2433
|
-
return s2 !== "" ? s2 : "—";
|
|
2434
|
-
};
|
|
2435
|
-
const displayAmount = (t) => {
|
|
2436
|
-
const code = (t.currency_code ?? "USD").toUpperCase();
|
|
2437
|
-
return `${code} ${Number(t.amount)}`;
|
|
2438
|
-
};
|
|
2439
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
2440
|
-
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
2441
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2442
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payments" }),
|
|
2443
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
|
|
2444
|
-
] }),
|
|
2445
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
|
|
2446
|
-
] }),
|
|
2447
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
2448
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2449
|
-
ui.Input,
|
|
2450
|
-
{
|
|
2451
|
-
placeholder: "Search by Order ID",
|
|
2452
|
-
value: orderIdSearch,
|
|
2453
|
-
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
2454
|
-
className: "md:max-w-sm",
|
|
2455
|
-
"aria-label": "Search by order ID"
|
|
2456
|
-
}
|
|
2457
|
-
),
|
|
2458
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2459
|
-
"select",
|
|
2460
|
-
{
|
|
2461
|
-
value: statusFilter,
|
|
2462
|
-
onChange: (e) => setStatusFilter(e.target.value),
|
|
2463
|
-
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
|
|
2464
|
-
"aria-label": "Filter by status",
|
|
2465
|
-
children: [
|
|
2466
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All statuses" }),
|
|
2467
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
|
|
2468
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "requires_more", children: "Requires more" }),
|
|
2469
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "error", children: "Error" }),
|
|
2470
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "canceled", children: "Canceled" }),
|
|
2471
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "authorized", children: "Authorized" }),
|
|
2472
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "captured", children: "Captured" })
|
|
2473
|
-
]
|
|
2474
|
-
}
|
|
2475
|
-
) })
|
|
2476
|
-
] }),
|
|
2477
|
-
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2478
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2479
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
|
|
2480
|
-
] }) : null,
|
|
2481
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading payments…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
2482
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
|
|
2483
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
|
|
2484
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
2485
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2486
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
2487
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
2488
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
2489
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
2490
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
|
|
2491
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
2492
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
2493
|
-
] }) }),
|
|
2494
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2495
|
-
"tr",
|
|
2496
|
-
{
|
|
2497
|
-
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
2498
|
-
onClick: () => navigate(`/payments/${t.payment_session_id}`),
|
|
2499
|
-
children: [
|
|
2500
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
|
|
2501
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
|
|
2502
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
|
|
2503
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2504
|
-
ui.Badge,
|
|
2505
|
-
{
|
|
2506
|
-
size: "2xsmall",
|
|
2507
|
-
className: `uppercase ${getStatusBadgeClass$1(displayStatus(t))}`,
|
|
2508
|
-
children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
|
|
2509
|
-
}
|
|
2510
|
-
) }),
|
|
2511
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
|
|
2512
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
|
|
2513
|
-
year: "numeric",
|
|
2514
|
-
month: "short",
|
|
2515
|
-
day: "numeric",
|
|
2516
|
-
hour: "numeric",
|
|
2517
|
-
minute: "2-digit",
|
|
2518
|
-
hour12: true
|
|
2519
|
-
}) }),
|
|
2520
|
-
/* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-4", children: [
|
|
2521
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2522
|
-
ui.Button,
|
|
2523
|
-
{
|
|
2524
|
-
variant: "transparent",
|
|
2525
|
-
size: "small",
|
|
2526
|
-
onClick: (e) => {
|
|
2527
|
-
e.stopPropagation();
|
|
2528
|
-
navigate(`/payments/${t.payment_session_id}`);
|
|
2529
|
-
},
|
|
2530
|
-
children: "View details"
|
|
2531
|
-
}
|
|
2532
|
-
),
|
|
2533
|
-
t.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2534
|
-
ui.Button,
|
|
2535
|
-
{
|
|
2536
|
-
variant: "transparent",
|
|
2537
|
-
size: "small",
|
|
2538
|
-
onClick: (e) => {
|
|
2539
|
-
e.stopPropagation();
|
|
2540
|
-
navigate(`/orders/${t.order_id}`);
|
|
2541
|
-
},
|
|
2542
|
-
children: "Order"
|
|
2543
|
-
}
|
|
2544
|
-
) : null
|
|
2545
|
-
] })
|
|
2546
|
-
]
|
|
2547
|
-
},
|
|
2548
|
-
t.payment_session_id
|
|
2549
|
-
)) })
|
|
2550
|
-
] }) }),
|
|
2551
|
-
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2552
|
-
ui.Button,
|
|
2553
|
-
{
|
|
2554
|
-
variant: "secondary",
|
|
2555
|
-
isLoading: isFetchingMore,
|
|
2556
|
-
onClick: () => loadTransactions(offset, false),
|
|
2557
|
-
children: "Load more"
|
|
2558
|
-
}
|
|
2559
|
-
) }) : null
|
|
2560
|
-
] }) });
|
|
2561
|
-
};
|
|
2562
|
-
const config$1 = adminSdk.defineRouteConfig({
|
|
2563
|
-
label: "Payments",
|
|
2564
|
-
icon: icons.CreditCard
|
|
2565
|
-
});
|
|
2566
|
-
const getStatusBadgeClass = (status) => {
|
|
2567
|
-
const s2 = status.toLowerCase();
|
|
2568
|
-
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
2569
|
-
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
2570
|
-
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
2571
|
-
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2572
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2573
|
-
};
|
|
2574
|
-
const PaymentDetailPage = () => {
|
|
2575
|
-
var _a;
|
|
2576
|
-
const navigate = reactRouterDom.useNavigate();
|
|
2577
|
-
const params = reactRouterDom.useParams();
|
|
2578
|
-
const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
|
|
2579
|
-
const [detail, setDetail] = react.useState(null);
|
|
2580
|
-
const [loading, setLoading] = react.useState(!!id);
|
|
2581
|
-
const [error, setError] = react.useState(null);
|
|
2582
|
-
react.useEffect(() => {
|
|
2583
|
-
if (!id) {
|
|
2584
|
-
setLoading(false);
|
|
2585
|
-
return;
|
|
2586
|
-
}
|
|
2587
|
-
let cancelled = false;
|
|
2588
|
-
setLoading(true);
|
|
2589
|
-
setError(null);
|
|
2590
|
-
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
2591
|
-
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
2592
|
-
return res.json();
|
|
2593
|
-
}).then((data) => {
|
|
2594
|
-
if (!cancelled) setDetail(data);
|
|
2595
|
-
}).catch((e) => {
|
|
2596
|
-
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
2597
|
-
}).finally(() => {
|
|
2598
|
-
if (!cancelled) setLoading(false);
|
|
2599
|
-
});
|
|
2600
|
-
return () => {
|
|
2601
|
-
cancelled = true;
|
|
2602
|
-
};
|
|
2603
|
-
}, [id]);
|
|
2604
|
-
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
2605
|
-
const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
|
|
2606
|
-
const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
|
|
2607
|
-
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
2608
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
2609
|
-
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2610
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
2611
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Payment session" }),
|
|
2612
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
2613
|
-
] }) }),
|
|
2614
|
-
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2615
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2616
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
2617
|
-
] }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
2618
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
2619
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2620
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
2621
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2622
|
-
ui.Button,
|
|
2623
|
-
{
|
|
2624
|
-
variant: "transparent",
|
|
2625
|
-
size: "small",
|
|
2626
|
-
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
2627
|
-
children: detail.order_id
|
|
2628
|
-
}
|
|
2629
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "—" }) })
|
|
2630
|
-
] }),
|
|
2631
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2632
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
2633
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: displayAmount })
|
|
2634
|
-
] }),
|
|
2635
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2636
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
2637
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.provider_id })
|
|
2638
|
-
] }),
|
|
2639
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2640
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
2641
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2642
|
-
ui.Badge,
|
|
2643
|
-
{
|
|
2644
|
-
size: "2xsmall",
|
|
2645
|
-
className: `uppercase ${getStatusBadgeClass(displayStatus)}`,
|
|
2646
|
-
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
2647
|
-
}
|
|
2648
|
-
) })
|
|
2649
|
-
] }),
|
|
2650
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2651
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
2652
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
2653
|
-
] }),
|
|
2654
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2655
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
2656
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
2657
|
-
] }),
|
|
2658
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2659
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
2660
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
2661
|
-
] }),
|
|
2662
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2663
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
2664
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
2665
|
-
year: "numeric",
|
|
2666
|
-
month: "short",
|
|
2667
|
-
day: "numeric",
|
|
2668
|
-
hour: "numeric",
|
|
2669
|
-
minute: "2-digit",
|
|
2670
|
-
hour12: true
|
|
2671
|
-
}) })
|
|
2672
|
-
] })
|
|
2673
|
-
] }) }),
|
|
2674
|
-
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
2675
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
2676
|
-
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
|
|
2677
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
|
|
2678
|
-
] }) : null
|
|
2679
|
-
] }) });
|
|
2680
|
-
};
|
|
2681
|
-
const config = adminSdk.defineRouteConfig({
|
|
2682
|
-
label: "Payment details",
|
|
2683
|
-
icon: icons.CreditCard
|
|
2684
|
-
});
|
|
2685
2742
|
const i18nTranslations0 = {};
|
|
2686
2743
|
const widgetModule = { widgets: [
|
|
2687
2744
|
{
|
|
@@ -2695,6 +2752,10 @@ const widgetModule = { widgets: [
|
|
|
2695
2752
|
] };
|
|
2696
2753
|
const routeModule = {
|
|
2697
2754
|
routes: [
|
|
2755
|
+
{
|
|
2756
|
+
Component: PaymentsPage,
|
|
2757
|
+
path: "/payments"
|
|
2758
|
+
},
|
|
2698
2759
|
{
|
|
2699
2760
|
Component: RefundsPage,
|
|
2700
2761
|
path: "/refunds"
|
|
@@ -2707,6 +2768,10 @@ const routeModule = {
|
|
|
2707
2768
|
Component: SwapsPage,
|
|
2708
2769
|
path: "/swaps"
|
|
2709
2770
|
},
|
|
2771
|
+
{
|
|
2772
|
+
Component: PaymentDetailPage,
|
|
2773
|
+
path: "/payments/:id"
|
|
2774
|
+
},
|
|
2710
2775
|
{
|
|
2711
2776
|
Component: RefundDetailPage,
|
|
2712
2777
|
path: "/refunds/:id"
|
|
@@ -2718,14 +2783,6 @@ const routeModule = {
|
|
|
2718
2783
|
{
|
|
2719
2784
|
Component: SwapDetailPage,
|
|
2720
2785
|
path: "/swaps/:id"
|
|
2721
|
-
},
|
|
2722
|
-
{
|
|
2723
|
-
Component: PaymentsPage,
|
|
2724
|
-
path: "/payments"
|
|
2725
|
-
},
|
|
2726
|
-
{
|
|
2727
|
-
Component: PaymentDetailPage,
|
|
2728
|
-
path: "/payments/:id"
|
|
2729
2786
|
}
|
|
2730
2787
|
]
|
|
2731
2788
|
};
|
|
@@ -2734,49 +2791,49 @@ const menuItemModule = {
|
|
|
2734
2791
|
{
|
|
2735
2792
|
label: config$6.label,
|
|
2736
2793
|
icon: config$6.icon,
|
|
2794
|
+
path: "/refunds",
|
|
2795
|
+
nested: void 0
|
|
2796
|
+
},
|
|
2797
|
+
{
|
|
2798
|
+
label: config$5.label,
|
|
2799
|
+
icon: config$5.icon,
|
|
2737
2800
|
path: "/returns",
|
|
2738
2801
|
nested: void 0
|
|
2739
2802
|
},
|
|
2740
2803
|
{
|
|
2741
|
-
label: config$
|
|
2742
|
-
icon: config$
|
|
2743
|
-
path: "/
|
|
2804
|
+
label: config$4.label,
|
|
2805
|
+
icon: config$4.icon,
|
|
2806
|
+
path: "/swaps",
|
|
2744
2807
|
nested: void 0
|
|
2745
2808
|
},
|
|
2746
2809
|
{
|
|
2747
2810
|
label: config$7.label,
|
|
2748
2811
|
icon: config$7.icon,
|
|
2749
|
-
path: "/
|
|
2812
|
+
path: "/payments",
|
|
2750
2813
|
nested: void 0
|
|
2751
2814
|
},
|
|
2752
2815
|
{
|
|
2753
|
-
label: config$
|
|
2754
|
-
icon: config$
|
|
2755
|
-
path: "/
|
|
2816
|
+
label: config$2.label,
|
|
2817
|
+
icon: config$2.icon,
|
|
2818
|
+
path: "/refunds/:id",
|
|
2756
2819
|
nested: void 0
|
|
2757
2820
|
},
|
|
2758
2821
|
{
|
|
2759
|
-
label: config$
|
|
2760
|
-
icon: config$
|
|
2822
|
+
label: config$1.label,
|
|
2823
|
+
icon: config$1.icon,
|
|
2761
2824
|
path: "/returns/:id",
|
|
2762
2825
|
nested: void 0
|
|
2763
2826
|
},
|
|
2764
|
-
{
|
|
2765
|
-
label: config$4.label,
|
|
2766
|
-
icon: config$4.icon,
|
|
2767
|
-
path: "/refunds/:id",
|
|
2768
|
-
nested: void 0
|
|
2769
|
-
},
|
|
2770
2827
|
{
|
|
2771
2828
|
label: config.label,
|
|
2772
2829
|
icon: config.icon,
|
|
2773
|
-
path: "/
|
|
2830
|
+
path: "/swaps/:id",
|
|
2774
2831
|
nested: void 0
|
|
2775
2832
|
},
|
|
2776
2833
|
{
|
|
2777
|
-
label: config$
|
|
2778
|
-
icon: config$
|
|
2779
|
-
path: "/
|
|
2834
|
+
label: config$3.label,
|
|
2835
|
+
icon: config$3.icon,
|
|
2836
|
+
path: "/payments/:id",
|
|
2780
2837
|
nested: void 0
|
|
2781
2838
|
}
|
|
2782
2839
|
]
|