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