order-management 0.0.90 → 0.0.92

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.
@@ -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 { Container, Text, Heading, Badge, Button, Label, Select, Textarea, Input } from "@medusajs/ui";
5
- import { CashSolid, PencilSquareSolid, Trash, Receipt, ArrowPath, CheckCircle, ArrowLeft, CreditCard } from "@medusajs/icons";
4
+ import { Text, Container, Heading, Badge, Button, Label, Select, Textarea, Input } from "@medusajs/ui";
5
+ import { CashSolid, PencilSquareSolid, Trash, CreditCard, ArrowPath, Receipt, 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",
@@ -490,7 +532,7 @@ function getOrderIdFromPath() {
490
532
  return m ? m[1] : void 0;
491
533
  }
492
534
  const OrderRefundContextWidget = (props) => {
493
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
535
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
494
536
  const orderId = ((_a = props.order) == null ? void 0 : _a.id) ?? ((_c = (_b = props.data) == null ? void 0 : _b.order) == null ? void 0 : _c.id) ?? getOrderIdFromPath();
495
537
  const [context, setContext] = useState(null);
496
538
  const [loading, setLoading] = useState(!!orderId);
@@ -529,7 +571,9 @@ const OrderRefundContextWidget = (props) => {
529
571
  };
530
572
  }, [orderId]);
531
573
  const handleMarkRefunded = async () => {
532
- if (!(context == null ? void 0 : context.return_id) || !(context == null ? void 0 : context.refund_mapping) || context.refund_mapping.is_refunded) return;
574
+ if (!(context == null ? void 0 : context.return_id) || !(context == null ? void 0 : context.refund_mapping) || context.refund_mapping.is_refunded || !context.can_process_refund) {
575
+ return;
576
+ }
533
577
  setMarking(true);
534
578
  setMarkError(null);
535
579
  try {
@@ -548,6 +592,7 @@ const OrderRefundContextWidget = (props) => {
548
592
  var _a2;
549
593
  return prev && prev.refund_mapping ? {
550
594
  ...prev,
595
+ can_process_refund: false,
551
596
  refund_mapping: {
552
597
  ...prev.refund_mapping,
553
598
  is_refunded: ((_a2 = data.refund_payment_mapping) == null ? void 0 : _a2.is_refunded) ?? true
@@ -635,7 +680,7 @@ const OrderRefundContextWidget = (props) => {
635
680
  }
636
681
  };
637
682
  if (!orderId) return null;
638
- if (!loading && !error && context && !context.refund_mapping) return null;
683
+ if (!loading && !error && context && !context.refund_mapping && !context.refund) return null;
639
684
  if (loading) {
640
685
  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
686
  }
@@ -644,28 +689,47 @@ const OrderRefundContextWidget = (props) => {
644
689
  }
645
690
  const hasReturn = !!(context == null ? void 0 : context.return_id);
646
691
  const hasMapping = !!(context == null ? void 0 : context.refund_mapping);
647
- const canMarkRefunded = hasReturn && hasMapping && !context.refund_mapping.is_refunded;
692
+ const canMarkRefunded = Boolean(context == null ? void 0 : context.can_process_refund);
693
+ const returnStatus = (context == null ? void 0 : context.return_status) ?? null;
694
+ const showReceiveFirstHint = hasReturn && !((_d = context == null ? void 0 : context.refund_mapping) == null ? void 0 : _d.is_refunded) && returnStatus !== "received" && returnStatus !== "canceled";
648
695
  const paymentDetail = context == null ? void 0 : context.payment_detail;
696
+ const orderPayment = context == null ? void 0 : context.order_payment;
649
697
  return /* @__PURE__ */ jsx(Container, { className: "mt-6 divide-y p-0", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 py-4", children: [
650
698
  /* @__PURE__ */ jsxs(Heading, { level: "h2", className: "flex items-center gap-2", children: [
651
699
  /* @__PURE__ */ jsx(CashSolid, { className: "text-ui-fg-subtle" }),
652
700
  "Refund payment"
653
701
  ] }),
654
702
  !hasReturn && /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No return for this order." }),
703
+ showReceiveFirstHint && /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Receive returned items before processing a refund. Do not refund from Payments until items are received." }),
655
704
  hasMapping && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: [
656
705
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
657
706
  /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Return" }),
658
707
  /* @__PURE__ */ jsx(Text, { size: "small", children: context.return_id }),
659
- ((_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" })
708
+ ((_e = context.refund_mapping) == null ? void 0 : _e.is_refunded) ? /* @__PURE__ */ jsx(Badge, { color: "green", children: "Refunded" }) : /* @__PURE__ */ jsx(Badge, { color: "orange", children: "Not refunded" })
709
+ ] }),
710
+ context.refund ? /* @__PURE__ */ jsx("div", { className: "mt-3 border-t border-ui-border-base pt-3", children: /* @__PURE__ */ jsx(RefundCalculationBlock, { refund: context.refund }) }) : null,
711
+ orderPayment && /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
712
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Order payment method" }),
713
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
714
+ /* @__PURE__ */ jsx(Badge, { children: orderPayment.label }),
715
+ orderPayment.is_cod ? /* @__PURE__ */ jsx(Badge, { color: "orange", children: "COD" }) : null
716
+ ] }),
717
+ /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: orderPayment.provider_id })
660
718
  ] }),
661
719
  /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-2 border-t border-ui-border-base pt-3", children: [
662
720
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
663
721
  /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Payment method (refund destination)" }),
664
- ((_e = context.refund_mapping) == null ? void 0 : _e.payment_id) ? /* @__PURE__ */ jsx(Badge, { color: "green", children: "Customer specified" }) : paymentDetail ? /* @__PURE__ */ jsx(Badge, { color: "orange", children: "Customer default" }) : null
722
+ ((_f = context.refund_mapping) == null ? void 0 : _f.payment_id) ? /* @__PURE__ */ jsx(Badge, { color: "green", children: "Customer specified" }) : paymentDetail ? /* @__PURE__ */ jsx(Badge, { color: "orange", children: "Customer default" }) : orderPayment && !orderPayment.is_cod ? /* @__PURE__ */ jsx(Badge, { color: "blue", children: "Original payment method" }) : null
665
723
  ] }),
666
- ((_f = context.refund_mapping) == null ? void 0 : _f.payment_id) && !paymentDetail && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-orange-200 bg-orange-50 px-3 py-2", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer specified a payment method for this return, but that payment method has since been removed from their account. Ask the customer to update their refund payment method." }) }),
667
- !((_g = context.refund_mapping) == null ? void 0 : _g.payment_id) && (paymentDetail == null ? void 0 : paymentDetail.source) === "default" && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer did not specify a payment method for this return. Showing their default payment method." }) }),
668
- !((_h = context.refund_mapping) == null ? void 0 : _h.payment_id) && !paymentDetail && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "No payment method found for this customer." }) }),
724
+ ((_g = context.refund_mapping) == null ? void 0 : _g.payment_id) && !paymentDetail && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-orange-200 bg-orange-50 px-3 py-2", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer specified a payment method for this return, but that payment method has since been removed from their account. Ask the customer to update their refund payment method." }) }),
725
+ !((_h = context.refund_mapping) == null ? void 0 : _h.payment_id) && (paymentDetail == null ? void 0 : paymentDetail.source) === "default" && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "The customer did not specify a payment method for this return. Showing their default payment method." }) }),
726
+ !((_i = context.refund_mapping) == null ? void 0 : _i.payment_id) && !paymentDetail && orderPayment && !orderPayment.is_cod && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsxs(Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
727
+ "Refund will go to the original payment method (",
728
+ orderPayment.label,
729
+ ")."
730
+ ] }) }),
731
+ !((_j = context.refund_mapping) == null ? void 0 : _j.payment_id) && !paymentDetail && (context.is_cod || (orderPayment == null ? void 0 : orderPayment.is_cod)) && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "This order was paid with Cash on Delivery. No stored bank/UPI refund destination." }) }),
732
+ !((_k = context.refund_mapping) == null ? void 0 : _k.payment_id) && !paymentDetail && !orderPayment && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "No payment method found for this customer." }) }),
669
733
  paymentDetail && /* @__PURE__ */ jsxs(Fragment, { children: [
670
734
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
671
735
  /* @__PURE__ */ jsx(Badge, { children: paymentDetail.type.toUpperCase() }),
@@ -819,7 +883,7 @@ const OrderRefundContextWidget = (props) => {
819
883
  ] }),
820
884
  /* @__PURE__ */ jsxs("div", { children: [
821
885
  /* @__PURE__ */ jsx(Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted", children: "Images" }),
822
- ((_i = context.refund_mapping.images) == null ? void 0 : _i.length) ? /* @__PURE__ */ jsx("div", { className: "mt-1 flex flex-wrap gap-2", children: context.refund_mapping.images.map((url, i) => /* @__PURE__ */ jsxs(
886
+ ((_l = context.refund_mapping.images) == null ? void 0 : _l.length) ? /* @__PURE__ */ jsx("div", { className: "mt-1 flex flex-wrap gap-2", children: context.refund_mapping.images.map((url, i) => /* @__PURE__ */ jsxs(
823
887
  "a",
824
888
  {
825
889
  href: url,
@@ -848,9 +912,20 @@ const OrderRefundContextWidget = (props) => {
848
912
  }
849
913
  ),
850
914
  markError && /* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-error", children: markError })
851
- ] })
915
+ ] }),
916
+ hasMapping && !canMarkRefunded && !((_m = context.refund_mapping) == null ? void 0 : _m.is_refunded) && showReceiveFirstHint && /* @__PURE__ */ jsx(Text, { size: "small", className: "mt-4 text-ui-fg-muted", children: "Mark refunded is available after the return is received." })
852
917
  ] }),
853
- hasReturn && !hasMapping && /* @__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." })
918
+ hasReturn && !hasMapping && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: [
919
+ (context == null ? void 0 : context.refund) ? /* @__PURE__ */ jsx(RefundCalculationBlock, { refund: context.refund }) : null,
920
+ orderPayment && /* @__PURE__ */ jsxs("div", { className: "mb-3 space-y-1", children: [
921
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", className: "text-ui-fg-subtle", children: "Order payment method" }),
922
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
923
+ /* @__PURE__ */ jsx(Badge, { children: orderPayment.label }),
924
+ orderPayment.is_cod ? /* @__PURE__ */ jsx(Badge, { color: "orange", children: "COD" }) : null
925
+ ] })
926
+ ] }),
927
+ /* @__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." })
928
+ ] })
854
929
  ] }) });
855
930
  };
856
931
  defineWidgetConfig({
@@ -872,27 +947,19 @@ const getStatusBadgeClass$7 = (status) => {
872
947
  if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
873
948
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
874
949
  };
875
- const RefundsPage = () => {
950
+ const PaymentsPage = () => {
876
951
  const navigate = useNavigate();
877
952
  const [items, setItems] = useState([]);
953
+ const [statusFilter, setStatusFilter] = useState("all");
878
954
  const [orderIdSearch, setOrderIdSearch] = useState("");
879
955
  const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
880
- const [paymentStatusFilter, setPaymentStatusFilter] = useState("all");
881
- const [providerSearch, setProviderSearch] = useState("");
882
- const debouncedProvider = useDebounce$3(providerSearch, 300);
883
- const [currencySearch, setCurrencySearch] = useState("");
884
- const debouncedCurrency = useDebounce$3(currencySearch, 300);
885
- const [dateFrom, setDateFrom] = useState("");
886
- const [dateTo, setDateTo] = useState("");
887
- const [amountMin, setAmountMin] = useState("");
888
- const [amountMax, setAmountMax] = useState("");
889
956
  const [isLoading, setIsLoading] = useState(true);
890
957
  const [isFetchingMore, setIsFetchingMore] = useState(false);
891
958
  const [error, setError] = useState(null);
892
959
  const [offset, setOffset] = useState(0);
893
960
  const [count, setCount] = useState(0);
894
961
  const limit = 50;
895
- const loadRefunds = useCallback(
962
+ const loadTransactions = useCallback(
896
963
  async (nextOffset, replace) => {
897
964
  try {
898
965
  if (replace) setIsLoading(true);
@@ -901,25 +968,18 @@ const RefundsPage = () => {
901
968
  const params = new URLSearchParams();
902
969
  params.set("limit", String(limit));
903
970
  params.set("offset", String(nextOffset));
971
+ if (statusFilter !== "all") params.set("status", statusFilter);
904
972
  if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
905
- if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
906
- if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
907
- if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
908
- if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
909
- if (dateTo.trim()) params.set("date_to", dateTo.trim());
910
- const min = amountMin.trim() ? Number(amountMin) : void 0;
911
- const max = amountMax.trim() ? Number(amountMax) : void 0;
912
- if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
913
- if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
914
- const response = await fetch(`/admin/refunds?${params.toString()}`, {
915
- credentials: "include"
916
- });
973
+ const response = await fetch(
974
+ `/admin/payment-transactions?${params.toString()}`,
975
+ { credentials: "include" }
976
+ );
917
977
  if (!response.ok) {
918
978
  const text = await response.text();
919
- throw new Error(text || "Failed to load refunds");
979
+ throw new Error(text || "Failed to load payment transactions");
920
980
  }
921
981
  const payload = await response.json();
922
- const list = payload.refunds ?? [];
982
+ const list = payload.transactions ?? [];
923
983
  setCount(payload.count ?? 0);
924
984
  setOffset(nextOffset + list.length);
925
985
  setItems((prev) => replace ? list : [...prev, ...list]);
@@ -930,75 +990,46 @@ const RefundsPage = () => {
930
990
  setIsFetchingMore(false);
931
991
  }
932
992
  },
933
- [
934
- debouncedOrderId,
935
- paymentStatusFilter,
936
- debouncedProvider,
937
- debouncedCurrency,
938
- dateFrom,
939
- dateTo,
940
- amountMin,
941
- amountMax
942
- ]
993
+ [statusFilter, debouncedOrderId]
943
994
  );
944
995
  useEffect(() => {
945
- void loadRefunds(0, true);
946
- }, [loadRefunds]);
996
+ void loadTransactions(0, true);
997
+ }, [loadTransactions]);
947
998
  const hasMore = useMemo(() => offset < count, [offset, count]);
948
- const displayAmount = (r) => {
949
- const code = (r.currency_code ?? "USD").toUpperCase();
950
- return `${code} ${Number(r.amount)}`;
951
- };
952
- const displayStatus = (r) => {
953
- const s2 = r.payment_status ?? "";
999
+ const displayStatus = (t) => {
1000
+ const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
954
1001
  return s2 !== "" ? s2 : "—";
955
1002
  };
1003
+ const displayAmount = (t) => {
1004
+ const code = (t.currency_code ?? "USD").toUpperCase();
1005
+ return `${code} ${Number(t.amount)}`;
1006
+ };
956
1007
  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: [
957
1008
  /* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
958
1009
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
959
- /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refunds" }),
960
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
1010
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payments" }),
1011
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
961
1012
  ] }),
962
- /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
1013
+ /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
963
1014
  ] }),
964
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
1015
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
965
1016
  /* @__PURE__ */ jsx(
966
1017
  Input,
967
1018
  {
968
- placeholder: "Order ID",
1019
+ placeholder: "Search by Order ID",
969
1020
  value: orderIdSearch,
970
1021
  onChange: (e) => setOrderIdSearch(e.target.value),
971
- className: "md:max-w-[180px]",
972
- "aria-label": "Filter by order ID"
973
- }
974
- ),
975
- /* @__PURE__ */ jsx(
976
- Input,
977
- {
978
- placeholder: "Provider",
979
- value: providerSearch,
980
- onChange: (e) => setProviderSearch(e.target.value),
981
- className: "md:max-w-[140px]",
982
- "aria-label": "Filter by provider"
983
- }
984
- ),
985
- /* @__PURE__ */ jsx(
986
- Input,
987
- {
988
- placeholder: "Currency",
989
- value: currencySearch,
990
- onChange: (e) => setCurrencySearch(e.target.value),
991
- className: "md:max-w-[100px]",
992
- "aria-label": "Filter by currency"
1022
+ className: "md:max-w-sm",
1023
+ "aria-label": "Search by order ID"
993
1024
  }
994
1025
  ),
995
- /* @__PURE__ */ jsxs(
1026
+ /* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxs(
996
1027
  "select",
997
1028
  {
998
- value: paymentStatusFilter,
999
- onChange: (e) => setPaymentStatusFilter(e.target.value),
1000
- 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-[160px]",
1001
- "aria-label": "Filter by payment status",
1029
+ value: statusFilter,
1030
+ onChange: (e) => setStatusFilter(e.target.value),
1031
+ 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",
1032
+ "aria-label": "Filter by status",
1002
1033
  children: [
1003
1034
  /* @__PURE__ */ jsx("option", { value: "all", children: "All statuses" }),
1004
1035
  /* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
@@ -1009,103 +1040,52 @@ const RefundsPage = () => {
1009
1040
  /* @__PURE__ */ jsx("option", { value: "captured", children: "Captured" })
1010
1041
  ]
1011
1042
  }
1012
- ),
1013
- /* @__PURE__ */ jsx(
1014
- Input,
1015
- {
1016
- type: "date",
1017
- placeholder: "From",
1018
- value: dateFrom,
1019
- onChange: (e) => setDateFrom(e.target.value),
1020
- className: "md:max-w-[140px]",
1021
- "aria-label": "Date from"
1022
- }
1023
- ),
1024
- /* @__PURE__ */ jsx(
1025
- Input,
1026
- {
1027
- type: "date",
1028
- placeholder: "To",
1029
- value: dateTo,
1030
- onChange: (e) => setDateTo(e.target.value),
1031
- className: "md:max-w-[140px]",
1032
- "aria-label": "Date to"
1033
- }
1034
- ),
1035
- /* @__PURE__ */ jsx(
1036
- Input,
1037
- {
1038
- placeholder: "Amount min",
1039
- value: amountMin,
1040
- onChange: (e) => setAmountMin(e.target.value),
1041
- type: "number",
1042
- min: 0,
1043
- className: "md:max-w-[100px]",
1044
- "aria-label": "Refund amount minimum"
1045
- }
1046
- ),
1047
- /* @__PURE__ */ jsx(
1048
- Input,
1049
- {
1050
- placeholder: "Amount max",
1051
- value: amountMax,
1052
- onChange: (e) => setAmountMax(e.target.value),
1053
- type: "number",
1054
- min: 0,
1055
- className: "md:max-w-[100px]",
1056
- "aria-label": "Refund amount maximum"
1057
- }
1058
- )
1059
- ] }) }),
1043
+ ) })
1044
+ ] }),
1060
1045
  error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1061
1046
  /* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1062
- /* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => loadRefunds(0, true), children: "Try again" }) })
1047
+ /* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
1063
1048
  ] }) : null,
1064
- isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading refunds…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
1065
- /* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No refunds yet" }),
1066
- /* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Refund records will appear here." })
1067
- ] }) : /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "w-full table-fixed divide-y divide-ui-border-base", style: { minWidth: 0 }, children: [
1049
+ 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: [
1050
+ /* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
1051
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
1052
+ ] }) : /* @__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: [
1068
1053
  /* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
1069
- /* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund ID" }),
1070
- /* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
1071
- /* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment ID" }),
1072
- /* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
1073
- /* @__PURE__ */ jsx("th", { className: "w-[6%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Currency" }),
1074
- /* @__PURE__ */ jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
1075
- /* @__PURE__ */ jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment Status" }),
1076
- /* @__PURE__ */ jsx("th", { className: "w-[14%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Note" }),
1077
- /* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1078
- /* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1054
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
1055
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
1056
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
1057
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
1058
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
1059
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1060
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1079
1061
  ] }) }),
1080
- /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((r) => /* @__PURE__ */ jsxs(
1062
+ /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxs(
1081
1063
  "tr",
1082
1064
  {
1083
- className: "cursor-pointer hover:bg-ui-bg-subtle/60",
1084
- onClick: () => navigate(`/refunds/${r.refund_id}`),
1065
+ className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
1066
+ onClick: () => navigate(`/payments/${t.payment_session_id}`),
1085
1067
  children: [
1086
- /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-base", title: r.refund_id, children: r.refund_id }),
1087
- /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-medium text-ui-fg-base", title: r.order_id ?? void 0, children: r.order_id ?? "—" }),
1088
- /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-subtle", title: r.payment_id, children: r.payment_id }),
1089
- /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", children: displayAmount(r) }),
1090
- /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
1091
- /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.provider_id || void 0, children: r.provider_id || "—" }),
1092
- /* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsx(
1068
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
1069
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
1070
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
1071
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
1093
1072
  Badge,
1094
1073
  {
1095
1074
  size: "2xsmall",
1096
- className: `uppercase ${getStatusBadgeClass$7(displayStatus(r))}`,
1097
- children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
1075
+ className: `uppercase ${getStatusBadgeClass$7(displayStatus(t))}`,
1076
+ children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
1098
1077
  }
1099
1078
  ) }),
1100
- /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.note ?? void 0, children: r.note ?? "—" }),
1101
- /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle text-xs", children: new Date(r.created_at).toLocaleDateString("en-US", {
1079
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
1080
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
1081
+ year: "numeric",
1102
1082
  month: "short",
1103
1083
  day: "numeric",
1104
1084
  hour: "numeric",
1105
1085
  minute: "2-digit",
1106
1086
  hour12: true
1107
1087
  }) }),
1108
- /* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
1088
+ /* @__PURE__ */ jsxs("td", { className: "px-4 py-4", children: [
1109
1089
  /* @__PURE__ */ jsx(
1110
1090
  Button,
1111
1091
  {
@@ -1113,27 +1093,27 @@ const RefundsPage = () => {
1113
1093
  size: "small",
1114
1094
  onClick: (e) => {
1115
1095
  e.stopPropagation();
1116
- navigate(`/refunds/${r.refund_id}`);
1096
+ navigate(`/payments/${t.payment_session_id}`);
1117
1097
  },
1118
- children: "Details"
1098
+ children: "View details"
1119
1099
  }
1120
1100
  ),
1121
- r.order_id ? /* @__PURE__ */ jsx(
1101
+ t.order_id ? /* @__PURE__ */ jsx(
1122
1102
  Button,
1123
1103
  {
1124
1104
  variant: "transparent",
1125
1105
  size: "small",
1126
1106
  onClick: (e) => {
1127
1107
  e.stopPropagation();
1128
- navigate(`/orders/${r.order_id}`);
1108
+ navigate(`/orders/${t.order_id}`);
1129
1109
  },
1130
1110
  children: "Order"
1131
1111
  }
1132
1112
  ) : null
1133
- ] }) })
1113
+ ] })
1134
1114
  ]
1135
1115
  },
1136
- r.refund_id
1116
+ t.payment_session_id
1137
1117
  )) })
1138
1118
  ] }) }),
1139
1119
  hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
@@ -1141,15 +1121,15 @@ const RefundsPage = () => {
1141
1121
  {
1142
1122
  variant: "secondary",
1143
1123
  isLoading: isFetchingMore,
1144
- onClick: () => loadRefunds(offset, false),
1124
+ onClick: () => loadTransactions(offset, false),
1145
1125
  children: "Load more"
1146
1126
  }
1147
1127
  ) }) : null
1148
1128
  ] }) });
1149
1129
  };
1150
1130
  const config$7 = defineRouteConfig({
1151
- label: "Refunds",
1152
- icon: Receipt
1131
+ label: "Payments",
1132
+ icon: CreditCard
1153
1133
  });
1154
1134
  const useDebounce$2 = (value, delay) => {
1155
1135
  const [debouncedValue, setDebouncedValue] = useState(value);
@@ -1335,13 +1315,23 @@ const ReturnsPage = () => {
1335
1315
  }
1336
1316
  ) }),
1337
1317
  /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
1338
- const amount = returnOrder.refund_amount;
1339
- if (amount == null || amount === void 0) {
1318
+ const calc = returnOrder.refund;
1319
+ if ((calc == null ? void 0 : calc.is_processed) && calc.final_refund_amount != null) {
1320
+ return formatRefundCurrency(
1321
+ calc.final_refund_amount,
1322
+ calc.currency_code || returnOrder.currency_code
1323
+ );
1324
+ }
1325
+ if (calc) {
1326
+ return "Pending";
1327
+ }
1328
+ if (returnOrder.refund_amount == null) {
1340
1329
  return "—";
1341
1330
  }
1342
- const displayAmount = Number(amount) / 100;
1343
- const currency = returnOrder.currency_code || "$";
1344
- return `${currency}${displayAmount.toFixed(2)}`;
1331
+ return formatRefundCurrency(
1332
+ Number(returnOrder.refund_amount),
1333
+ returnOrder.currency_code
1334
+ );
1345
1335
  })() }),
1346
1336
  /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
1347
1337
  year: "numeric",
@@ -1392,13 +1382,308 @@ const useDebounce$1 = (value, delay) => {
1392
1382
  return debouncedValue;
1393
1383
  };
1394
1384
  const getStatusBadgeClass$5 = (status) => {
1395
- const statusLower = status.toLowerCase();
1396
- if (statusLower === "requested") {
1397
- return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1398
- }
1399
- if (statusLower === "approved") {
1400
- return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1401
- }
1385
+ const s2 = status.toLowerCase();
1386
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1387
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1388
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
1389
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1390
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1391
+ };
1392
+ const RefundsPage = () => {
1393
+ const navigate = useNavigate();
1394
+ const [items, setItems] = useState([]);
1395
+ const [orderIdSearch, setOrderIdSearch] = useState("");
1396
+ const debouncedOrderId = useDebounce$1(orderIdSearch, 300);
1397
+ const [paymentStatusFilter, setPaymentStatusFilter] = useState("all");
1398
+ const [providerSearch, setProviderSearch] = useState("");
1399
+ const debouncedProvider = useDebounce$1(providerSearch, 300);
1400
+ const [currencySearch, setCurrencySearch] = useState("");
1401
+ const debouncedCurrency = useDebounce$1(currencySearch, 300);
1402
+ const [dateFrom, setDateFrom] = useState("");
1403
+ const [dateTo, setDateTo] = useState("");
1404
+ const [amountMin, setAmountMin] = useState("");
1405
+ const [amountMax, setAmountMax] = useState("");
1406
+ const [isLoading, setIsLoading] = useState(true);
1407
+ const [isFetchingMore, setIsFetchingMore] = useState(false);
1408
+ const [error, setError] = useState(null);
1409
+ const [offset, setOffset] = useState(0);
1410
+ const [count, setCount] = useState(0);
1411
+ const limit = 50;
1412
+ const loadRefunds = useCallback(
1413
+ async (nextOffset, replace) => {
1414
+ try {
1415
+ if (replace) setIsLoading(true);
1416
+ else setIsFetchingMore(true);
1417
+ setError(null);
1418
+ const params = new URLSearchParams();
1419
+ params.set("limit", String(limit));
1420
+ params.set("offset", String(nextOffset));
1421
+ if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
1422
+ if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
1423
+ if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
1424
+ if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
1425
+ if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
1426
+ if (dateTo.trim()) params.set("date_to", dateTo.trim());
1427
+ const min = amountMin.trim() ? Number(amountMin) : void 0;
1428
+ const max = amountMax.trim() ? Number(amountMax) : void 0;
1429
+ if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
1430
+ if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
1431
+ const response = await fetch(`/admin/refunds?${params.toString()}`, {
1432
+ credentials: "include"
1433
+ });
1434
+ if (!response.ok) {
1435
+ const text = await response.text();
1436
+ throw new Error(text || "Failed to load refunds");
1437
+ }
1438
+ const payload = await response.json();
1439
+ const list = payload.refunds ?? [];
1440
+ setCount(payload.count ?? 0);
1441
+ setOffset(nextOffset + list.length);
1442
+ setItems((prev) => replace ? list : [...prev, ...list]);
1443
+ } catch (e) {
1444
+ setError(e instanceof Error ? e.message : "Failed to load");
1445
+ } finally {
1446
+ setIsLoading(false);
1447
+ setIsFetchingMore(false);
1448
+ }
1449
+ },
1450
+ [
1451
+ debouncedOrderId,
1452
+ paymentStatusFilter,
1453
+ debouncedProvider,
1454
+ debouncedCurrency,
1455
+ dateFrom,
1456
+ dateTo,
1457
+ amountMin,
1458
+ amountMax
1459
+ ]
1460
+ );
1461
+ useEffect(() => {
1462
+ void loadRefunds(0, true);
1463
+ }, [loadRefunds]);
1464
+ const hasMore = useMemo(() => offset < count, [offset, count]);
1465
+ const displayAmount = (r) => {
1466
+ const code = (r.currency_code ?? "USD").toUpperCase();
1467
+ return `${code} ${Number(r.amount)}`;
1468
+ };
1469
+ const displayStatus = (r) => {
1470
+ const s2 = r.payment_status ?? "";
1471
+ return s2 !== "" ? s2 : "—";
1472
+ };
1473
+ 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: [
1474
+ /* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
1475
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
1476
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refunds" }),
1477
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
1478
+ ] }),
1479
+ /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
1480
+ ] }),
1481
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
1482
+ /* @__PURE__ */ jsx(
1483
+ Input,
1484
+ {
1485
+ placeholder: "Order ID",
1486
+ value: orderIdSearch,
1487
+ onChange: (e) => setOrderIdSearch(e.target.value),
1488
+ className: "md:max-w-[180px]",
1489
+ "aria-label": "Filter by order ID"
1490
+ }
1491
+ ),
1492
+ /* @__PURE__ */ jsx(
1493
+ Input,
1494
+ {
1495
+ placeholder: "Provider",
1496
+ value: providerSearch,
1497
+ onChange: (e) => setProviderSearch(e.target.value),
1498
+ className: "md:max-w-[140px]",
1499
+ "aria-label": "Filter by provider"
1500
+ }
1501
+ ),
1502
+ /* @__PURE__ */ jsx(
1503
+ Input,
1504
+ {
1505
+ placeholder: "Currency",
1506
+ value: currencySearch,
1507
+ onChange: (e) => setCurrencySearch(e.target.value),
1508
+ className: "md:max-w-[100px]",
1509
+ "aria-label": "Filter by currency"
1510
+ }
1511
+ ),
1512
+ /* @__PURE__ */ jsxs(
1513
+ "select",
1514
+ {
1515
+ value: paymentStatusFilter,
1516
+ onChange: (e) => setPaymentStatusFilter(e.target.value),
1517
+ 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-[160px]",
1518
+ "aria-label": "Filter by payment status",
1519
+ children: [
1520
+ /* @__PURE__ */ jsx("option", { value: "all", children: "All statuses" }),
1521
+ /* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
1522
+ /* @__PURE__ */ jsx("option", { value: "requires_more", children: "Requires more" }),
1523
+ /* @__PURE__ */ jsx("option", { value: "error", children: "Error" }),
1524
+ /* @__PURE__ */ jsx("option", { value: "canceled", children: "Canceled" }),
1525
+ /* @__PURE__ */ jsx("option", { value: "authorized", children: "Authorized" }),
1526
+ /* @__PURE__ */ jsx("option", { value: "captured", children: "Captured" })
1527
+ ]
1528
+ }
1529
+ ),
1530
+ /* @__PURE__ */ jsx(
1531
+ Input,
1532
+ {
1533
+ type: "date",
1534
+ placeholder: "From",
1535
+ value: dateFrom,
1536
+ onChange: (e) => setDateFrom(e.target.value),
1537
+ className: "md:max-w-[140px]",
1538
+ "aria-label": "Date from"
1539
+ }
1540
+ ),
1541
+ /* @__PURE__ */ jsx(
1542
+ Input,
1543
+ {
1544
+ type: "date",
1545
+ placeholder: "To",
1546
+ value: dateTo,
1547
+ onChange: (e) => setDateTo(e.target.value),
1548
+ className: "md:max-w-[140px]",
1549
+ "aria-label": "Date to"
1550
+ }
1551
+ ),
1552
+ /* @__PURE__ */ jsx(
1553
+ Input,
1554
+ {
1555
+ placeholder: "Amount min",
1556
+ value: amountMin,
1557
+ onChange: (e) => setAmountMin(e.target.value),
1558
+ type: "number",
1559
+ min: 0,
1560
+ className: "md:max-w-[100px]",
1561
+ "aria-label": "Refund amount minimum"
1562
+ }
1563
+ ),
1564
+ /* @__PURE__ */ jsx(
1565
+ Input,
1566
+ {
1567
+ placeholder: "Amount max",
1568
+ value: amountMax,
1569
+ onChange: (e) => setAmountMax(e.target.value),
1570
+ type: "number",
1571
+ min: 0,
1572
+ className: "md:max-w-[100px]",
1573
+ "aria-label": "Refund amount maximum"
1574
+ }
1575
+ )
1576
+ ] }) }),
1577
+ error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1578
+ /* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1579
+ /* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => loadRefunds(0, true), children: "Try again" }) })
1580
+ ] }) : null,
1581
+ isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading refunds…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
1582
+ /* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No refunds yet" }),
1583
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Refund records will appear here." })
1584
+ ] }) : /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "w-full table-fixed divide-y divide-ui-border-base", style: { minWidth: 0 }, children: [
1585
+ /* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
1586
+ /* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund ID" }),
1587
+ /* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
1588
+ /* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment ID" }),
1589
+ /* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
1590
+ /* @__PURE__ */ jsx("th", { className: "w-[6%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Currency" }),
1591
+ /* @__PURE__ */ jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
1592
+ /* @__PURE__ */ jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment Status" }),
1593
+ /* @__PURE__ */ jsx("th", { className: "w-[14%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Note" }),
1594
+ /* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
1595
+ /* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
1596
+ ] }) }),
1597
+ /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((r) => /* @__PURE__ */ jsxs(
1598
+ "tr",
1599
+ {
1600
+ className: "cursor-pointer hover:bg-ui-bg-subtle/60",
1601
+ onClick: () => navigate(`/refunds/${r.refund_id}`),
1602
+ children: [
1603
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-base", title: r.refund_id, children: r.refund_id }),
1604
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-medium text-ui-fg-base", title: r.order_id ?? void 0, children: r.order_id ?? "—" }),
1605
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-subtle", title: r.payment_id, children: r.payment_id }),
1606
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", children: displayAmount(r) }),
1607
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
1608
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.provider_id || void 0, children: r.provider_id || "—" }),
1609
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsx(
1610
+ Badge,
1611
+ {
1612
+ size: "2xsmall",
1613
+ className: `uppercase ${getStatusBadgeClass$5(displayStatus(r))}`,
1614
+ children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
1615
+ }
1616
+ ) }),
1617
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.note ?? void 0, children: r.note ?? "—" }),
1618
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle text-xs", children: new Date(r.created_at).toLocaleDateString("en-US", {
1619
+ month: "short",
1620
+ day: "numeric",
1621
+ hour: "numeric",
1622
+ minute: "2-digit",
1623
+ hour12: true
1624
+ }) }),
1625
+ /* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
1626
+ /* @__PURE__ */ jsx(
1627
+ Button,
1628
+ {
1629
+ variant: "transparent",
1630
+ size: "small",
1631
+ onClick: (e) => {
1632
+ e.stopPropagation();
1633
+ navigate(`/refunds/${r.refund_id}`);
1634
+ },
1635
+ children: "Details"
1636
+ }
1637
+ ),
1638
+ r.order_id ? /* @__PURE__ */ jsx(
1639
+ Button,
1640
+ {
1641
+ variant: "transparent",
1642
+ size: "small",
1643
+ onClick: (e) => {
1644
+ e.stopPropagation();
1645
+ navigate(`/orders/${r.order_id}`);
1646
+ },
1647
+ children: "Order"
1648
+ }
1649
+ ) : null
1650
+ ] }) })
1651
+ ]
1652
+ },
1653
+ r.refund_id
1654
+ )) })
1655
+ ] }) }),
1656
+ hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
1657
+ Button,
1658
+ {
1659
+ variant: "secondary",
1660
+ isLoading: isFetchingMore,
1661
+ onClick: () => loadRefunds(offset, false),
1662
+ children: "Load more"
1663
+ }
1664
+ ) }) : null
1665
+ ] }) });
1666
+ };
1667
+ const config$5 = defineRouteConfig({
1668
+ label: "Refunds",
1669
+ icon: Receipt
1670
+ });
1671
+ const useDebounce = (value, delay) => {
1672
+ const [debouncedValue, setDebouncedValue] = useState(value);
1673
+ useEffect(() => {
1674
+ const handler = setTimeout(() => setDebouncedValue(value), delay);
1675
+ return () => clearTimeout(handler);
1676
+ }, [value, delay]);
1677
+ return debouncedValue;
1678
+ };
1679
+ const getStatusBadgeClass$4 = (status) => {
1680
+ const statusLower = status.toLowerCase();
1681
+ if (statusLower === "requested") {
1682
+ return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1683
+ }
1684
+ if (statusLower === "approved") {
1685
+ return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
1686
+ }
1402
1687
  if (statusLower === "rejected") {
1403
1688
  return "bg-ui-tag-red-bg text-ui-tag-red-text";
1404
1689
  }
@@ -1416,7 +1701,7 @@ const SwapsPage = () => {
1416
1701
  const [statusFilter, setStatusFilter] = useState("all");
1417
1702
  const [createdByFilter, setCreatedByFilter] = useState("all");
1418
1703
  const [searchQuery, setSearchQuery] = useState("");
1419
- const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
1704
+ const debouncedSearchQuery = useDebounce(searchQuery, 300);
1420
1705
  const [isLoading, setIsLoading] = useState(true);
1421
1706
  const [isFetchingMore, setIsFetchingMore] = useState(false);
1422
1707
  const [error, setError] = useState(null);
@@ -1559,7 +1844,7 @@ const SwapsPage = () => {
1559
1844
  Badge,
1560
1845
  {
1561
1846
  size: "2xsmall",
1562
- className: `uppercase ${getStatusBadgeClass$5(swap.status)}`,
1847
+ className: `uppercase ${getStatusBadgeClass$4(swap.status)}`,
1563
1848
  children: swap.status.replace(/_/g, " ")
1564
1849
  }
1565
1850
  ) }),
@@ -1609,11 +1894,11 @@ const SwapsPage = () => {
1609
1894
  ) }) : null
1610
1895
  ] }) });
1611
1896
  };
1612
- const config$5 = defineRouteConfig({
1897
+ const config$4 = defineRouteConfig({
1613
1898
  label: "Exchanges",
1614
1899
  icon: ArrowPath
1615
1900
  });
1616
- const getStatusBadgeClass$4 = (status) => {
1901
+ const getStatusBadgeClass$3 = (status) => {
1617
1902
  const s2 = status.toLowerCase();
1618
1903
  if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
1619
1904
  if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
@@ -1621,18 +1906,14 @@ const getStatusBadgeClass$4 = (status) => {
1621
1906
  if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
1622
1907
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1623
1908
  };
1624
- const formatAmount = (value) => {
1625
- return String(value);
1626
- };
1627
- const RefundDetailPage = () => {
1628
- var _a, _b, _c;
1909
+ const PaymentDetailPage = () => {
1910
+ var _a;
1629
1911
  const navigate = useNavigate();
1630
1912
  const params = useParams();
1631
1913
  const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
1632
1914
  const [detail, setDetail] = useState(null);
1633
1915
  const [loading, setLoading] = useState(!!id);
1634
1916
  const [error, setError] = useState(null);
1635
- const [gatewayExpanded, setGatewayExpanded] = useState(false);
1636
1917
  useEffect(() => {
1637
1918
  if (!id) {
1638
1919
  setLoading(false);
@@ -1641,7 +1922,7 @@ const RefundDetailPage = () => {
1641
1922
  let cancelled = false;
1642
1923
  setLoading(true);
1643
1924
  setError(null);
1644
- fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
1925
+ fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
1645
1926
  if (!res.ok) throw new Error(res.statusText || "Failed to load");
1646
1927
  return res.json();
1647
1928
  }).then((data) => {
@@ -1655,157 +1936,88 @@ const RefundDetailPage = () => {
1655
1936
  cancelled = true;
1656
1937
  };
1657
1938
  }, [id]);
1658
- const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
1659
- 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;
1939
+ const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
1940
+ const sessionStatusRaw = (detail == null ? void 0 : detail.session_status) ?? "—";
1941
+ const paymentStatusRaw = (detail == null ? void 0 : detail.payment_id) != null ? (detail == null ? void 0 : detail.payment_status) ?? "—" : "—";
1942
+ const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
1660
1943
  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
1944
  /* @__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("/refunds"), children: "← Refunds" }),
1663
- /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refund details" }),
1664
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
1945
+ /* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
1946
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payment session" }),
1947
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
1665
1948
  ] }) }),
1666
1949
  error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
1667
1950
  /* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
1668
- /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
1951
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
1669
1952
  ] }) : 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
- /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
1671
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
1672
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
1673
- /* @__PURE__ */ jsxs("div", { children: [
1674
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
1675
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
1676
- ] }),
1677
- /* @__PURE__ */ jsxs("div", { children: [
1678
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
1679
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
1680
- ] }),
1681
- /* @__PURE__ */ jsxs("div", { children: [
1682
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
1683
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
1684
- ] }),
1685
- /* @__PURE__ */ jsxs("div", { children: [
1686
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
1687
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
1688
- year: "numeric",
1689
- month: "short",
1690
- day: "numeric",
1691
- hour: "numeric",
1692
- minute: "2-digit",
1693
- hour12: true
1694
- }) })
1695
- ] }),
1696
- detail.refund.created_by ? /* @__PURE__ */ jsxs("div", { children: [
1697
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
1698
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
1699
- ] }) : null
1700
- ] })
1701
- ] }),
1702
- /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
1703
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
1704
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
1705
- /* @__PURE__ */ jsxs("div", { children: [
1706
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
1707
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
1708
- ] }),
1709
- /* @__PURE__ */ jsxs("div", { children: [
1710
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
1711
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
1712
- ] }),
1713
- /* @__PURE__ */ jsxs("div", { children: [
1714
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
1715
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
1716
- ] }),
1717
- /* @__PURE__ */ jsxs("div", { children: [
1718
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
1719
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
1720
- ] }),
1721
- /* @__PURE__ */ jsxs("div", { children: [
1722
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
1723
- /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
1724
- Badge,
1725
- {
1726
- size: "2xsmall",
1727
- className: `uppercase ${getStatusBadgeClass$4(paymentStatus)}`,
1728
- children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
1729
- }
1730
- ) })
1731
- ] }),
1732
- detail.computed ? /* @__PURE__ */ jsxs(Fragment, { children: [
1733
- /* @__PURE__ */ jsxs("div", { children: [
1734
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
1735
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
1736
- ] }),
1737
- /* @__PURE__ */ jsxs("div", { children: [
1738
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
1739
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
1740
- ] }),
1741
- /* @__PURE__ */ jsxs("div", { children: [
1742
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
1743
- /* @__PURE__ */ jsxs(Text, { className: "mt-1 block", children: [
1744
- detail.computed.refund_percentage.toFixed(1),
1745
- "%"
1746
- ] })
1747
- ] })
1748
- ] }) : null
1953
+ /* @__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: [
1954
+ /* @__PURE__ */ jsxs("div", { children: [
1955
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
1956
+ /* @__PURE__ */ jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsx(
1957
+ Button,
1958
+ {
1959
+ variant: "transparent",
1960
+ size: "small",
1961
+ onClick: () => navigate(`/orders/${detail.order_id}`),
1962
+ children: detail.order_id
1963
+ }
1964
+ ) : /* @__PURE__ */ jsx(Text, { children: "—" }) })
1965
+ ] }),
1966
+ /* @__PURE__ */ jsxs("div", { children: [
1967
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
1968
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: displayAmount })
1969
+ ] }),
1970
+ /* @__PURE__ */ jsxs("div", { children: [
1971
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
1972
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.provider_id })
1973
+ ] }),
1974
+ /* @__PURE__ */ jsxs("div", { children: [
1975
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
1976
+ /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
1977
+ Badge,
1978
+ {
1979
+ size: "2xsmall",
1980
+ className: `uppercase ${getStatusBadgeClass$3(displayStatus)}`,
1981
+ children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
1982
+ }
1983
+ ) })
1984
+ ] }),
1985
+ /* @__PURE__ */ jsxs("div", { children: [
1986
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
1987
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: sessionStatusRaw })
1988
+ ] }),
1989
+ /* @__PURE__ */ jsxs("div", { children: [
1990
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
1991
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: paymentStatusRaw })
1992
+ ] }),
1993
+ /* @__PURE__ */ jsxs("div", { children: [
1994
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
1995
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
1996
+ ] }),
1997
+ /* @__PURE__ */ jsxs("div", { children: [
1998
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
1999
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
2000
+ year: "numeric",
2001
+ month: "short",
2002
+ day: "numeric",
2003
+ hour: "numeric",
2004
+ minute: "2-digit",
2005
+ hour12: true
2006
+ }) })
1749
2007
  ] })
1750
- ] }),
1751
- /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
1752
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
1753
- detail.order ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
1754
- /* @__PURE__ */ jsxs("div", { children: [
1755
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
1756
- /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
1757
- Button,
1758
- {
1759
- variant: "transparent",
1760
- size: "small",
1761
- onClick: () => navigate(`/orders/${detail.order.order_id}`),
1762
- children: detail.order.order_number ?? detail.order.order_id
1763
- }
1764
- ) })
1765
- ] }),
1766
- detail.order.total != null ? /* @__PURE__ */ jsxs("div", { children: [
1767
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
1768
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
1769
- ] }) : null,
1770
- detail.order.customer_id ? /* @__PURE__ */ jsxs("div", { children: [
1771
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
1772
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
1773
- ] }) : null,
1774
- detail.order.region ? /* @__PURE__ */ jsxs("div", { children: [
1775
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
1776
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.region })
1777
- ] }) : null,
1778
- detail.order.fulfillment_status ? /* @__PURE__ */ jsxs("div", { children: [
1779
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
1780
- /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
1781
- ] }) : null
1782
- ] }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
1783
- ] }),
1784
- /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
1785
- /* @__PURE__ */ jsxs(
1786
- "button",
1787
- {
1788
- type: "button",
1789
- className: "flex w-full items-center justify-between text-left",
1790
- onClick: () => setGatewayExpanded((prev) => !prev),
1791
- "aria-expanded": gatewayExpanded,
1792
- "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
1793
- children: [
1794
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
1795
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
1796
- ]
1797
- }
1798
- ),
1799
- gatewayExpanded && /* @__PURE__ */ jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
1800
- ] })
2008
+ ] }) }),
2009
+ Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2010
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
2011
+ /* @__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) })
2012
+ ] }) : /* @__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." }) })
1801
2013
  ] }) : null
1802
2014
  ] }) });
1803
2015
  };
1804
- const config$4 = defineRouteConfig({
1805
- label: "Refund details",
1806
- icon: Receipt
2016
+ const config$3 = defineRouteConfig({
2017
+ label: "Payment details",
2018
+ icon: CreditCard
1807
2019
  });
1808
- const getStatusBadgeClass$3 = (status) => {
2020
+ const getStatusBadgeClass$2 = (status) => {
1809
2021
  const statusLower = status.toLowerCase();
1810
2022
  if (statusLower === "requested") {
1811
2023
  return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
@@ -1831,7 +2043,7 @@ const getStatusBadgeClass$3 = (status) => {
1831
2043
  return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
1832
2044
  };
1833
2045
  const ReturnDetailPage = () => {
1834
- var _a, _b;
2046
+ var _a, _b, _c;
1835
2047
  const navigate = useNavigate();
1836
2048
  const { id } = useParams();
1837
2049
  const [returnOrder, setReturnOrder] = useState(null);
@@ -1849,7 +2061,7 @@ const ReturnDetailPage = () => {
1849
2061
  try {
1850
2062
  setIsLoading(true);
1851
2063
  setError(null);
1852
- const response = await fetch(`/admin/returns/${id}`, {
2064
+ const response = await fetch(`/admin/return/${id}`, {
1853
2065
  credentials: "include"
1854
2066
  });
1855
2067
  if (!response.ok) {
@@ -1875,7 +2087,7 @@ const ReturnDetailPage = () => {
1875
2087
  setIsRejecting(true);
1876
2088
  setUpdateError(null);
1877
2089
  setUpdateSuccess(false);
1878
- const response = await fetch(`/admin/returns/${id}/reject`, {
2090
+ const response = await fetch(`/admin/return/${id}/reject`, {
1879
2091
  method: "POST",
1880
2092
  headers: {
1881
2093
  "Content-Type": "application/json"
@@ -1891,7 +2103,7 @@ const ReturnDetailPage = () => {
1891
2103
  setReturnOrder(payload.return);
1892
2104
  setUpdateSuccess(true);
1893
2105
  setTimeout(() => setUpdateSuccess(false), 3e3);
1894
- const detailResponse = await fetch(`/admin/returns/${id}`, {
2106
+ const detailResponse = await fetch(`/admin/return/${id}`, {
1895
2107
  credentials: "include"
1896
2108
  });
1897
2109
  if (detailResponse.ok) {
@@ -1939,7 +2151,7 @@ const ReturnDetailPage = () => {
1939
2151
  Badge,
1940
2152
  {
1941
2153
  size: "small",
1942
- className: `uppercase ${getStatusBadgeClass$3(returnOrder.status)}`,
2154
+ className: `uppercase ${getStatusBadgeClass$2(returnOrder.status)}`,
1943
2155
  children: returnOrder.status.replace(/_/g, " ")
1944
2156
  }
1945
2157
  )
@@ -1958,6 +2170,7 @@ const ReturnDetailPage = () => {
1958
2170
  ) }),
1959
2171
  /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
1960
2172
  ] }),
2173
+ 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
2174
  /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
1962
2175
  /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
1963
2176
  /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
@@ -2021,7 +2234,7 @@ const ReturnDetailPage = () => {
2021
2234
  Badge,
2022
2235
  {
2023
2236
  size: "2xsmall",
2024
- className: `uppercase ${getStatusBadgeClass$3(entry.status)}`,
2237
+ className: `uppercase ${getStatusBadgeClass$2(entry.status)}`,
2025
2238
  children: entry.status.replace(/_/g, " ")
2026
2239
  }
2027
2240
  ) }),
@@ -2051,6 +2264,10 @@ const ReturnDetailPage = () => {
2051
2264
  /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
2052
2265
  /* @__PURE__ */ jsx(Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
2053
2266
  ] }),
2267
+ /* @__PURE__ */ jsxs("div", { children: [
2268
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Payment method" }),
2269
+ /* @__PURE__ */ jsx(Text, { className: "font-medium", children: ((_c = returnOrder.order.order_payment) == null ? void 0 : _c.label) || "—" })
2270
+ ] }),
2054
2271
  returnOrder.order.total && /* @__PURE__ */ jsxs("div", { children: [
2055
2272
  /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
2056
2273
  /* @__PURE__ */ jsxs(Text, { className: "font-medium", children: [
@@ -2079,11 +2296,203 @@ const ReturnDetailPage = () => {
2079
2296
  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
2297
  ] }) });
2081
2298
  };
2082
- const config$3 = defineRouteConfig({
2299
+ const config$2 = defineRouteConfig({
2083
2300
  label: "Return Order Details",
2084
2301
  icon: CheckCircle
2085
2302
  });
2086
- const getStatusBadgeClass$2 = (status) => {
2303
+ const getStatusBadgeClass$1 = (status) => {
2304
+ const s2 = status.toLowerCase();
2305
+ if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
2306
+ if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
2307
+ if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
2308
+ if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
2309
+ return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
2310
+ };
2311
+ const formatAmount = (value) => {
2312
+ return String(value);
2313
+ };
2314
+ const RefundDetailPage = () => {
2315
+ var _a, _b, _c;
2316
+ const navigate = useNavigate();
2317
+ const params = useParams();
2318
+ const id = (_a = params == null ? void 0 : params.id) == null ? void 0 : _a.trim();
2319
+ const [detail, setDetail] = useState(null);
2320
+ const [loading, setLoading] = useState(!!id);
2321
+ const [error, setError] = useState(null);
2322
+ const [gatewayExpanded, setGatewayExpanded] = useState(false);
2323
+ useEffect(() => {
2324
+ if (!id) {
2325
+ setLoading(false);
2326
+ return;
2327
+ }
2328
+ let cancelled = false;
2329
+ setLoading(true);
2330
+ setError(null);
2331
+ fetch(`/admin/refunds/${id}`, { credentials: "include" }).then((res) => {
2332
+ if (!res.ok) throw new Error(res.statusText || "Failed to load");
2333
+ return res.json();
2334
+ }).then((data) => {
2335
+ if (!cancelled) setDetail(data);
2336
+ }).catch((e) => {
2337
+ if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
2338
+ }).finally(() => {
2339
+ if (!cancelled) setLoading(false);
2340
+ });
2341
+ return () => {
2342
+ cancelled = true;
2343
+ };
2344
+ }, [id]);
2345
+ const paymentStatus = ((_b = detail == null ? void 0 : detail.payment) == null ? void 0 : _b.status) ?? "—";
2346
+ 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;
2347
+ 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: [
2348
+ /* @__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: [
2349
+ /* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/refunds"), children: "← Refunds" }),
2350
+ /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refund details" }),
2351
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle font-mono", children: id ?? "—" })
2352
+ ] }) }),
2353
+ error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
2354
+ /* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
2355
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/refunds"), children: "Back to list" })
2356
+ ] }) : 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: [
2357
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2358
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Refund summary" }),
2359
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2360
+ /* @__PURE__ */ jsxs("div", { children: [
2361
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund ID" }),
2362
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.id })
2363
+ ] }),
2364
+ /* @__PURE__ */ jsxs("div", { children: [
2365
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
2366
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.refund.amount) })
2367
+ ] }),
2368
+ /* @__PURE__ */ jsxs("div", { children: [
2369
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Note" }),
2370
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.refund.note ?? "—" })
2371
+ ] }),
2372
+ /* @__PURE__ */ jsxs("div", { children: [
2373
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created at" }),
2374
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.refund.created_at).toLocaleDateString("en-US", {
2375
+ year: "numeric",
2376
+ month: "short",
2377
+ day: "numeric",
2378
+ hour: "numeric",
2379
+ minute: "2-digit",
2380
+ hour12: true
2381
+ }) })
2382
+ ] }),
2383
+ detail.refund.created_by ? /* @__PURE__ */ jsxs("div", { children: [
2384
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created by" }),
2385
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.refund.created_by })
2386
+ ] }) : null
2387
+ ] })
2388
+ ] }),
2389
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2390
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Payment summary" }),
2391
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2392
+ /* @__PURE__ */ jsxs("div", { children: [
2393
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment amount" }),
2394
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.payment_amount) })
2395
+ ] }),
2396
+ /* @__PURE__ */ jsxs("div", { children: [
2397
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Captured amount" }),
2398
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.captured_amount) })
2399
+ ] }),
2400
+ /* @__PURE__ */ jsxs("div", { children: [
2401
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refunded amount" }),
2402
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.payment.refunded_amount) })
2403
+ ] }),
2404
+ /* @__PURE__ */ jsxs("div", { children: [
2405
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
2406
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment.provider_id || "—" })
2407
+ ] }),
2408
+ /* @__PURE__ */ jsxs("div", { children: [
2409
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
2410
+ /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
2411
+ Badge,
2412
+ {
2413
+ size: "2xsmall",
2414
+ className: `uppercase ${getStatusBadgeClass$1(paymentStatus)}`,
2415
+ children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
2416
+ }
2417
+ ) })
2418
+ ] }),
2419
+ detail.computed ? /* @__PURE__ */ jsxs(Fragment, { children: [
2420
+ /* @__PURE__ */ jsxs("div", { children: [
2421
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Full refund" }),
2422
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.computed.is_full_refund ? "Yes" : "No" })
2423
+ ] }),
2424
+ /* @__PURE__ */ jsxs("div", { children: [
2425
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Remaining refundable" }),
2426
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.computed.remaining_refundable_amount) })
2427
+ ] }),
2428
+ /* @__PURE__ */ jsxs("div", { children: [
2429
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Refund %" }),
2430
+ /* @__PURE__ */ jsxs(Text, { className: "mt-1 block", children: [
2431
+ detail.computed.refund_percentage.toFixed(1),
2432
+ "%"
2433
+ ] })
2434
+ ] })
2435
+ ] }) : null
2436
+ ] })
2437
+ ] }),
2438
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2439
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Order summary" }),
2440
+ detail.order ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
2441
+ /* @__PURE__ */ jsxs("div", { children: [
2442
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order" }),
2443
+ /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
2444
+ Button,
2445
+ {
2446
+ variant: "transparent",
2447
+ size: "small",
2448
+ onClick: () => navigate(`/orders/${detail.order.order_id}`),
2449
+ children: detail.order.order_number ?? detail.order.order_id
2450
+ }
2451
+ ) })
2452
+ ] }),
2453
+ detail.order.total != null ? /* @__PURE__ */ jsxs("div", { children: [
2454
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Total" }),
2455
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: formatAmount(detail.order.total) })
2456
+ ] }) : null,
2457
+ detail.order.customer_id ? /* @__PURE__ */ jsxs("div", { children: [
2458
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Customer ID" }),
2459
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block font-mono text-sm", children: detail.order.customer_id })
2460
+ ] }) : null,
2461
+ detail.order.region ? /* @__PURE__ */ jsxs("div", { children: [
2462
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Region" }),
2463
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.region })
2464
+ ] }) : null,
2465
+ detail.order.fulfillment_status ? /* @__PURE__ */ jsxs("div", { children: [
2466
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Fulfillment status" }),
2467
+ /* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.order.fulfillment_status })
2468
+ ] }) : null
2469
+ ] }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No order linked to this refund." })
2470
+ ] }),
2471
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
2472
+ /* @__PURE__ */ jsxs(
2473
+ "button",
2474
+ {
2475
+ type: "button",
2476
+ className: "flex w-full items-center justify-between text-left",
2477
+ onClick: () => setGatewayExpanded((prev) => !prev),
2478
+ "aria-expanded": gatewayExpanded,
2479
+ "aria-label": gatewayExpanded ? "Collapse gateway data" : "Expand gateway data",
2480
+ children: [
2481
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg", children: "Gateway data" }),
2482
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: gatewayExpanded ? "Collapse" : "Expand" })
2483
+ ]
2484
+ }
2485
+ ),
2486
+ gatewayExpanded && /* @__PURE__ */ jsx("div", { className: "mt-4", children: hasGatewayData ? /* @__PURE__ */ jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.payment.payment_data, null, 2) }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No gateway payload for this payment." }) })
2487
+ ] })
2488
+ ] }) : null
2489
+ ] }) });
2490
+ };
2491
+ const config$1 = defineRouteConfig({
2492
+ label: "Refund details",
2493
+ icon: Receipt
2494
+ });
2495
+ const getStatusBadgeClass = (status) => {
2087
2496
  const statusLower = status.toLowerCase();
2088
2497
  if (statusLower === "requested") {
2089
2498
  return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
@@ -2221,7 +2630,7 @@ const SwapDetailPage = () => {
2221
2630
  Badge,
2222
2631
  {
2223
2632
  size: "small",
2224
- className: `uppercase ${getStatusBadgeClass$2(swap.status)}`,
2633
+ className: `uppercase ${getStatusBadgeClass(swap.status)}`,
2225
2634
  children: swap.status.replace(/_/g, " ")
2226
2635
  }
2227
2636
  )
@@ -2280,406 +2689,87 @@ const SwapDetailPage = () => {
2280
2689
  ] }),
2281
2690
  /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2282
2691
  /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Status History" }),
2283
- statusHistory.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: statusHistory.map((entry, index) => /* @__PURE__ */ jsx(
2284
- "div",
2285
- {
2286
- className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
2287
- children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
2288
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx(
2289
- Badge,
2290
- {
2291
- size: "2xsmall",
2292
- className: `uppercase ${getStatusBadgeClass$2(entry.status)}`,
2293
- children: entry.status.replace(/_/g, " ")
2294
- }
2295
- ) }),
2296
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
2297
- new Date(entry.timestamp).toLocaleString(),
2298
- entry.admin_id && ` by ${entry.admin_id}`,
2299
- entry.reason && ` - ${entry.reason}`
2300
- ] })
2301
- ] })
2302
- },
2303
- index
2304
- )) }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
2305
- ] })
2306
- ] }),
2307
- order && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2308
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
2309
- /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
2310
- /* @__PURE__ */ jsxs("div", { children: [
2311
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
2312
- /* @__PURE__ */ jsx(Text, { className: "font-medium", children: order.id })
2313
- ] }),
2314
- /* @__PURE__ */ jsxs("div", { children: [
2315
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
2316
- /* @__PURE__ */ jsx(Text, { className: "font-medium", children: order.status || "—" })
2317
- ] }),
2318
- /* @__PURE__ */ jsxs("div", { children: [
2319
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
2320
- /* @__PURE__ */ jsx(Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
2321
- ] }),
2322
- order.total && /* @__PURE__ */ jsxs("div", { children: [
2323
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
2324
- /* @__PURE__ */ jsxs(Text, { className: "font-medium", children: [
2325
- order.currency_code || "$",
2326
- (Number(order.total) / 100).toFixed(2)
2327
- ] })
2328
- ] })
2329
- ] })
2330
- ] }),
2331
- swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2332
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
2333
- /* @__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: [
2334
- /* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
2335
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item ID" }),
2336
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
2337
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
2338
- ] }) }),
2339
- /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxs("tr", { children: [
2340
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
2341
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
2342
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
2343
- ] }, item.id || index)) })
2344
- ] }) })
2345
- ] }),
2346
- swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2347
- /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
2348
- /* @__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: [
2349
- /* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
2350
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
2351
- /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
2352
- ] }) }),
2353
- /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxs("tr", { children: [
2354
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
2355
- /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
2356
- ] }, item.variant_id || index)) })
2357
- ] }) })
2358
- ] })
2359
- ] }) });
2360
- };
2361
- const config$2 = defineRouteConfig({
2362
- label: "Swap Details",
2363
- icon: ArrowPath
2364
- });
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,
2692
+ statusHistory.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: statusHistory.map((entry, index) => /* @__PURE__ */ jsx(
2693
+ "div",
2694
+ {
2695
+ className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
2696
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
2697
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx(
2698
+ Badge,
2534
2699
  {
2535
- variant: "transparent",
2536
- size: "small",
2537
- onClick: (e) => {
2538
- e.stopPropagation();
2539
- navigate(`/orders/${t.order_id}`);
2540
- },
2541
- children: "Order"
2700
+ size: "2xsmall",
2701
+ className: `uppercase ${getStatusBadgeClass(entry.status)}`,
2702
+ children: entry.status.replace(/_/g, " ")
2542
2703
  }
2543
- ) : null
2704
+ ) }),
2705
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
2706
+ new Date(entry.timestamp).toLocaleString(),
2707
+ entry.admin_id && ` by ${entry.admin_id}`,
2708
+ entry.reason && ` - ${entry.reason}`
2709
+ ] })
2544
2710
  ] })
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
- ] }),
2711
+ },
2712
+ index
2713
+ )) }) : /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
2714
+ ] })
2715
+ ] }),
2716
+ order && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2717
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
2718
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
2649
2719
  /* @__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 })
2720
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
2721
+ /* @__PURE__ */ jsx(Text, { className: "font-medium", children: order.id })
2652
2722
  ] }),
2653
2723
  /* @__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 })
2724
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
2725
+ /* @__PURE__ */ jsx(Text, { className: "font-medium", children: order.status || "—" })
2656
2726
  ] }),
2657
2727
  /* @__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" })
2728
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
2729
+ /* @__PURE__ */ jsx(Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
2660
2730
  ] }),
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
- }) })
2731
+ order.total && /* @__PURE__ */ jsxs("div", { children: [
2732
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
2733
+ /* @__PURE__ */ jsxs(Text, { className: "font-medium", children: [
2734
+ order.currency_code || "$",
2735
+ (Number(order.total) / 100).toFixed(2)
2736
+ ] })
2671
2737
  ] })
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
2738
+ ] })
2739
+ ] }),
2740
+ swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2741
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
2742
+ /* @__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: [
2743
+ /* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
2744
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item ID" }),
2745
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
2746
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
2747
+ ] }) }),
2748
+ /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxs("tr", { children: [
2749
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
2750
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
2751
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
2752
+ ] }, item.id || index)) })
2753
+ ] }) })
2754
+ ] }),
2755
+ swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
2756
+ /* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
2757
+ /* @__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: [
2758
+ /* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
2759
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
2760
+ /* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
2761
+ ] }) }),
2762
+ /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxs("tr", { children: [
2763
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
2764
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
2765
+ ] }, item.variant_id || index)) })
2766
+ ] }) })
2767
+ ] })
2678
2768
  ] }) });
2679
2769
  };
2680
2770
  const config = defineRouteConfig({
2681
- label: "Payment details",
2682
- icon: CreditCard
2771
+ label: "Swap Details",
2772
+ icon: ArrowPath
2683
2773
  });
2684
2774
  const i18nTranslations0 = {};
2685
2775
  const widgetModule = { widgets: [
@@ -2695,36 +2785,36 @@ const widgetModule = { widgets: [
2695
2785
  const routeModule = {
2696
2786
  routes: [
2697
2787
  {
2698
- Component: RefundsPage,
2699
- path: "/refunds"
2788
+ Component: PaymentsPage,
2789
+ path: "/payments"
2700
2790
  },
2701
2791
  {
2702
2792
  Component: ReturnsPage,
2703
2793
  path: "/returns"
2704
2794
  },
2795
+ {
2796
+ Component: RefundsPage,
2797
+ path: "/refunds"
2798
+ },
2705
2799
  {
2706
2800
  Component: SwapsPage,
2707
2801
  path: "/swaps"
2708
2802
  },
2709
2803
  {
2710
- Component: RefundDetailPage,
2711
- path: "/refunds/:id"
2804
+ Component: PaymentDetailPage,
2805
+ path: "/payments/:id"
2712
2806
  },
2713
2807
  {
2714
2808
  Component: ReturnDetailPage,
2715
2809
  path: "/returns/:id"
2716
2810
  },
2717
2811
  {
2718
- Component: SwapDetailPage,
2719
- path: "/swaps/:id"
2720
- },
2721
- {
2722
- Component: PaymentsPage,
2723
- path: "/payments"
2812
+ Component: RefundDetailPage,
2813
+ path: "/refunds/:id"
2724
2814
  },
2725
2815
  {
2726
- Component: PaymentDetailPage,
2727
- path: "/payments/:id"
2816
+ Component: SwapDetailPage,
2817
+ path: "/swaps/:id"
2728
2818
  }
2729
2819
  ]
2730
2820
  };
@@ -2737,45 +2827,45 @@ const menuItemModule = {
2737
2827
  nested: void 0
2738
2828
  },
2739
2829
  {
2740
- label: config$1.label,
2741
- icon: config$1.icon,
2742
- path: "/payments",
2830
+ label: config$4.label,
2831
+ icon: config$4.icon,
2832
+ path: "/swaps",
2743
2833
  nested: void 0
2744
2834
  },
2745
2835
  {
2746
2836
  label: config$7.label,
2747
2837
  icon: config$7.icon,
2748
- path: "/refunds",
2838
+ path: "/payments",
2749
2839
  nested: void 0
2750
2840
  },
2751
2841
  {
2752
2842
  label: config$5.label,
2753
2843
  icon: config$5.icon,
2754
- path: "/swaps",
2844
+ path: "/refunds",
2755
2845
  nested: void 0
2756
2846
  },
2757
2847
  {
2758
- label: config$3.label,
2759
- icon: config$3.icon,
2848
+ label: config$2.label,
2849
+ icon: config$2.icon,
2760
2850
  path: "/returns/:id",
2761
2851
  nested: void 0
2762
2852
  },
2763
2853
  {
2764
- label: config$4.label,
2765
- icon: config$4.icon,
2766
- path: "/refunds/:id",
2854
+ label: config.label,
2855
+ icon: config.icon,
2856
+ path: "/swaps/:id",
2767
2857
  nested: void 0
2768
2858
  },
2769
2859
  {
2770
- label: config.label,
2771
- icon: config.icon,
2860
+ label: config$3.label,
2861
+ icon: config$3.icon,
2772
2862
  path: "/payments/:id",
2773
2863
  nested: void 0
2774
2864
  },
2775
2865
  {
2776
- label: config$2.label,
2777
- icon: config$2.icon,
2778
- path: "/swaps/:id",
2866
+ label: config$1.label,
2867
+ icon: config$1.icon,
2868
+ path: "/refunds/:id",
2779
2869
  nested: void 0
2780
2870
  }
2781
2871
  ]