order-management 0.0.2 → 0.0.3

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.
Files changed (33) hide show
  1. package/.medusa/server/src/admin/index.js +4 -639
  2. package/.medusa/server/src/admin/index.mjs +4 -639
  3. package/.medusa/server/src/api/store/orders/reorder/[order_id]/route.js +52 -0
  4. package/.medusa/server/src/workflows/index.js +4 -9
  5. package/.medusa/server/src/workflows/{types.js → reorder/types.js} +1 -1
  6. package/.medusa/server/src/workflows/reorder-workflow.js +27 -0
  7. package/.medusa/server/src/workflows/steps/create-cart-from-order-step.js +26 -0
  8. package/.medusa/server/src/workflows/steps/index.js +10 -0
  9. package/.medusa/server/src/workflows/steps/retrieve-order-step.js +52 -0
  10. package/.medusa/server/src/workflows/steps/transform-order-to-cart-step.js +53 -0
  11. package/README.md +59 -73
  12. package/package.json +1 -1
  13. package/.medusa/server/src/api/admin/returns/[id]/retry-refund/route.js +0 -84
  14. package/.medusa/server/src/api/admin/returns/failed-refunds/route.js +0 -137
  15. package/.medusa/server/src/api/store/returns/[id]/payment-details/route.js +0 -326
  16. package/.medusa/server/src/config/plugin-options.js +0 -61
  17. package/.medusa/server/src/providers/refund-payment/base-refund-provider.js +0 -80
  18. package/.medusa/server/src/providers/refund-payment/index.js +0 -38
  19. package/.medusa/server/src/providers/refund-payment/razorpay-provider.js +0 -96
  20. package/.medusa/server/src/providers/refund-payment/stripe-provider.js +0 -82
  21. package/.medusa/server/src/subscribers/return-received.js +0 -103
  22. package/.medusa/server/src/types/plugin-options.js +0 -3
  23. package/.medusa/server/src/types/refund-payment.js +0 -3
  24. package/.medusa/server/src/workflows/process-cod-refund-workflow.js +0 -99
  25. package/.medusa/server/src/workflows/steps/calculate-refund-amount-step.js +0 -51
  26. package/.medusa/server/src/workflows/steps/create-refund-record-step.js +0 -243
  27. package/.medusa/server/src/workflows/steps/process-refund-payment-step.js +0 -86
  28. package/.medusa/server/src/workflows/steps/retrieve-order-and-payment-step.js +0 -44
  29. package/.medusa/server/src/workflows/steps/retrieve-return-payment-details-step.js +0 -56
  30. package/.medusa/server/src/workflows/steps/select-payment-method-step.js +0 -61
  31. package/.medusa/server/src/workflows/steps/update-payment-status-step.js +0 -45
  32. package/.medusa/server/src/workflows/steps/validate-payment-details-step.js +0 -90
  33. package/.medusa/server/src/workflows/steps/verify-cod-order-step.js +0 -39
@@ -1,646 +1,11 @@
1
1
  "use strict";
2
- const jsxRuntime = require("react/jsx-runtime");
3
- const adminSdk = require("@medusajs/admin-sdk");
4
- const ui = require("@medusajs/ui");
5
- const icons = require("@medusajs/icons");
6
- const react = require("react");
7
- const reactRouterDom = require("react-router-dom");
8
- const FailedRefundsSummaryWidget = () => {
9
- var _a;
10
- const navigate = reactRouterDom.useNavigate();
11
- const [failedRefunds, setFailedRefunds] = react.useState([]);
12
- const [isLoading, setIsLoading] = react.useState(true);
13
- const [error, setError] = react.useState(null);
14
- const fetchFailedRefunds = async () => {
15
- try {
16
- setIsLoading(true);
17
- setError(null);
18
- const response = await fetch(
19
- `/admin/returns/failed-refunds?limit=10`,
20
- {
21
- credentials: "include"
22
- }
23
- );
24
- if (!response.ok) {
25
- throw new Error("Failed to fetch failed refunds");
26
- }
27
- const data = await response.json();
28
- setFailedRefunds(data.failed_refunds || []);
29
- } catch (err) {
30
- const errorMessage = err instanceof Error ? err.message : "Failed to load failed refunds";
31
- setError(errorMessage);
32
- console.error("Error fetching failed refunds:", err);
33
- } finally {
34
- setIsLoading(false);
35
- }
36
- };
37
- react.useEffect(() => {
38
- void fetchFailedRefunds();
39
- const interval = setInterval(() => {
40
- void fetchFailedRefunds();
41
- }, 3e4);
42
- return () => clearInterval(interval);
43
- }, []);
44
- const totalAmount = failedRefunds.reduce((sum, refund) => {
45
- return sum + (refund.amount || 0);
46
- }, 0);
47
- const count = failedRefunds.length;
48
- if (error) {
49
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
50
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Failed Refunds" }) }),
51
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
52
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: error }),
53
- /* @__PURE__ */ jsxRuntime.jsx(
54
- ui.Button,
55
- {
56
- variant: "secondary",
57
- size: "small",
58
- onClick: () => void fetchFailedRefunds(),
59
- className: "mt-2",
60
- children: "Retry"
61
- }
62
- )
63
- ] })
64
- ] });
65
- }
66
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
67
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
68
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Failed Refunds" }),
69
- /* @__PURE__ */ jsxRuntime.jsxs(
70
- ui.Button,
71
- {
72
- variant: "transparent",
73
- size: "small",
74
- onClick: () => navigate("/failed-refunds"),
75
- children: [
76
- "View All",
77
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowRight, { className: "ml-2 h-4 w-4" })
78
- ]
79
- }
80
- )
81
- ] }),
82
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Loading..." }) }) : count === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
83
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 rounded-full bg-ui-tag-green-bg p-2", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationTriangle, { className: "h-5 w-5 text-ui-tag-green-text" }) }),
84
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "No failed refunds" }),
85
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-1 text-ui-fg-muted", children: "All refunds are processing successfully" })
86
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
87
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
88
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base p-4", children: [
89
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Failed Count" }),
90
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "mt-1 text-2xl", children: count })
91
- ] }),
92
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base p-4", children: [
93
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Total Amount" }),
94
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Heading, { level: "h3", className: "mt-1 text-2xl", children: [
95
- ((_a = failedRefunds[0]) == null ? void 0 : _a.currency_code) || "",
96
- " ",
97
- totalAmount.toLocaleString()
98
- ] })
99
- ] })
100
- ] }),
101
- /* @__PURE__ */ jsxRuntime.jsx(
102
- ui.Button,
103
- {
104
- variant: "secondary",
105
- size: "small",
106
- onClick: () => navigate("/failed-refunds"),
107
- className: "w-full",
108
- children: "Manage Failed Refunds"
109
- }
110
- )
111
- ] }) })
112
- ] });
113
- };
114
- adminSdk.defineWidgetConfig({
115
- zone: "order.details.after"
116
- });
117
- function RefundStatusBadge({
118
- status,
119
- size = "2xsmall"
120
- }) {
121
- if (!status) {
122
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size, className: "bg-ui-tag-grey-bg text-ui-tag-grey-text", children: [
123
- /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, { className: "mr-1 h-3 w-3" }),
124
- "Not Started"
125
- ] });
126
- }
127
- const statusLower = status.toLowerCase();
128
- if (statusLower === "succeeded") {
129
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size, className: "bg-ui-tag-green-bg text-ui-tag-green-text", children: [
130
- /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { className: "mr-1 h-3 w-3" }),
131
- "Succeeded"
132
- ] });
133
- }
134
- if (statusLower === "failed") {
135
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size, className: "bg-ui-tag-red-bg text-ui-tag-red-text", children: [
136
- /* @__PURE__ */ jsxRuntime.jsx(icons.XCircle, { className: "mr-1 h-3 w-3" }),
137
- "Failed"
138
- ] });
139
- }
140
- if (statusLower === "pending") {
141
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size, className: "bg-ui-tag-orange-bg text-ui-tag-orange-text", children: [
142
- /* @__PURE__ */ jsxRuntime.jsx(icons.Clock, { className: "mr-1 h-3 w-3" }),
143
- "Pending"
144
- ] });
145
- }
146
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size, className: "bg-ui-tag-grey-bg text-ui-tag-grey-text", children: status });
147
- }
148
- function RetryRefundButton({
149
- returnId,
150
- onSuccess,
151
- variant = "primary",
152
- size = "base"
153
- }) {
154
- const [isRetrying, setIsRetrying] = react.useState(false);
155
- const handleRetry = async () => {
156
- if (isRetrying) return;
157
- setIsRetrying(true);
158
- try {
159
- const response = await fetch(`/admin/returns/${returnId}/retry-refund`, {
160
- method: "POST",
161
- credentials: "include",
162
- headers: {
163
- "Content-Type": "application/json"
164
- }
165
- });
166
- const data = await response.json();
167
- if (!response.ok) {
168
- throw new Error(data.error || data.message || "Failed to retry refund");
169
- }
170
- if (data.success) {
171
- ui.toast.success("Refund retry initiated successfully");
172
- onSuccess == null ? void 0 : onSuccess();
173
- } else {
174
- throw new Error(data.message || "Refund retry failed");
175
- }
176
- } catch (error) {
177
- const errorMessage = error instanceof Error ? error.message : "Failed to retry refund";
178
- ui.toast.error(errorMessage);
179
- console.error("Error retrying refund:", error);
180
- } finally {
181
- setIsRetrying(false);
182
- }
183
- };
184
- return /* @__PURE__ */ jsxRuntime.jsxs(
185
- ui.Button,
186
- {
187
- variant,
188
- size,
189
- onClick: handleRetry,
190
- disabled: isRetrying,
191
- isLoading: isRetrying,
192
- children: [
193
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, { className: "mr-2 h-4 w-4" }),
194
- isRetrying ? "Retrying..." : "Retry Refund"
195
- ]
196
- }
197
- );
198
- }
199
- const ReturnRefundStatusWidget = () => {
200
- var _a, _b, _c, _d, _e, _f, _g, _h;
201
- const [returnData, setReturnData] = react.useState(null);
202
- const [isLoading, setIsLoading] = react.useState(true);
203
- const [error, setError] = react.useState(null);
204
- const [returnId, setReturnId] = react.useState(null);
205
- react.useEffect(() => {
206
- const pathSegments = window.location.pathname.split("/");
207
- const returnIndex = pathSegments.indexOf("returns");
208
- if (returnIndex !== -1 && pathSegments[returnIndex + 1]) {
209
- const id = pathSegments[returnIndex + 1];
210
- setReturnId(id);
211
- fetchReturnData(id);
212
- }
213
- }, []);
214
- const fetchReturnData = async (id) => {
215
- try {
216
- setIsLoading(true);
217
- setError(null);
218
- const response = await fetch(`/admin/returns/${id}`, {
219
- credentials: "include"
220
- });
221
- if (!response.ok) {
222
- throw new Error("Return API not available");
223
- }
224
- const data = await response.json();
225
- setReturnData(data.return || data);
226
- } catch (err) {
227
- try {
228
- const ordersResponse = await fetch(`/admin/orders?limit=1000`, {
229
- credentials: "include"
230
- });
231
- if (ordersResponse.ok) {
232
- const ordersData = await ordersResponse.json();
233
- const orders = ordersData.orders || [];
234
- for (const order of orders) {
235
- const returns = order.returns || [];
236
- const returnRecord = returns.find(
237
- (ret) => ret.id === id
238
- );
239
- if (returnRecord) {
240
- setReturnData(returnRecord);
241
- break;
242
- }
243
- }
244
- }
245
- } catch (fallbackErr) {
246
- const errorMessage = err instanceof Error ? err.message : "Failed to load return data";
247
- setError(errorMessage);
248
- console.error("Error fetching return data:", err);
249
- }
250
- } finally {
251
- setIsLoading(false);
252
- }
253
- };
254
- const handleRetrySuccess = () => {
255
- if (returnId) {
256
- void fetchReturnData(returnId);
257
- }
258
- };
259
- if (isLoading) {
260
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
261
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Refund Status" }) }),
262
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Loading refund status..." }) })
263
- ] });
264
- }
265
- if (error) {
266
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
267
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Refund Status" }) }),
268
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: error }) })
269
- ] });
270
- }
271
- if (!returnData) {
272
- return null;
273
- }
274
- const refundStatus = ((_a = returnData.metadata) == null ? void 0 : _a.refund_status) || null;
275
- const paymentError = (_b = returnData.metadata) == null ? void 0 : _b.payment_error;
276
- const paymentErrorCode = (_c = returnData.metadata) == null ? void 0 : _c.payment_error_code;
277
- const failedAt = (_d = returnData.metadata) == null ? void 0 : _d.failed_at;
278
- const retryCount = ((_e = returnData.metadata) == null ? void 0 : _e.retry_count) || 0;
279
- const transactionId = (_f = returnData.metadata) == null ? void 0 : _f.transaction_id;
280
- const paymentDetails = (_g = returnData.metadata) == null ? void 0 : _g.refund_payment_details;
281
- if (!refundStatus && !paymentError && !transactionId && !paymentDetails) {
282
- return null;
283
- }
284
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
285
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
286
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Refund Status" }),
287
- refundStatus === "failed" && returnId && /* @__PURE__ */ jsxRuntime.jsx(
288
- RetryRefundButton,
289
- {
290
- returnId,
291
- onSuccess: handleRetrySuccess,
292
- size: "small"
293
- }
294
- )
295
- ] }),
296
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
297
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
298
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle mb-2 block", children: "Status" }),
299
- /* @__PURE__ */ jsxRuntime.jsx(RefundStatusBadge, { status: refundStatus })
300
- ] }),
301
- transactionId && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
302
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle mb-1 block", children: "Transaction ID" }),
303
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-mono text-sm", children: transactionId })
304
- ] }),
305
- paymentError && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-3", children: [
306
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-error font-semibold mb-1 block", children: "Error" }),
307
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-error", children: paymentError }),
308
- paymentErrorCode && /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-error mt-1", children: [
309
- "Code: ",
310
- paymentErrorCode
311
- ] }),
312
- failedAt && /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-error mt-1", children: [
313
- "Failed at: ",
314
- new Date(failedAt).toLocaleString()
315
- ] })
316
- ] }),
317
- retryCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
318
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle mb-1 block", children: "Retry Count" }),
319
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: retryCount })
320
- ] }),
321
- paymentDetails && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
322
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle mb-2 block", children: "Payment Details" }),
323
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base p-3 space-y-2", children: [
324
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
325
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Method:" }),
326
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "font-medium", children: paymentDetails.method || "N/A" })
327
- ] }),
328
- paymentDetails.currency_code && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
329
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Currency:" }),
330
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "font-medium", children: paymentDetails.currency_code })
331
- ] }),
332
- paymentDetails.upi_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
333
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "UPI ID:" }),
334
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "font-medium", children: paymentDetails.upi_id })
335
- ] }),
336
- ((_h = paymentDetails.bank_account) == null ? void 0 : _h.account_number) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
337
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Account:" }),
338
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "font-medium", children: [
339
- "****",
340
- paymentDetails.bank_account.account_number.slice(-4)
341
- ] })
342
- ] })
343
- ] })
344
- ] })
345
- ] }) })
346
- ] });
347
- };
348
- adminSdk.defineWidgetConfig({
349
- zone: "order.details.after"
350
- });
351
- const useDebounce = (value, delay) => {
352
- const [debouncedValue, setDebouncedValue] = react.useState(value);
353
- react.useEffect(() => {
354
- const handler = setTimeout(() => setDebouncedValue(value), delay);
355
- return () => clearTimeout(handler);
356
- }, [value, delay]);
357
- return debouncedValue;
358
- };
359
- const FailedRefundsPage = () => {
360
- const navigate = reactRouterDom.useNavigate();
361
- const [failedRefunds, setFailedRefunds] = react.useState([]);
362
- const [isLoading, setIsLoading] = react.useState(true);
363
- const [error, setError] = react.useState(null);
364
- const [offset, setOffset] = react.useState(0);
365
- const [count, setCount] = react.useState(0);
366
- const limit = 50;
367
- const [currencyFilter, setCurrencyFilter] = react.useState("all");
368
- const [errorCodeFilter, setErrorCodeFilter] = react.useState("all");
369
- const [searchQuery, setSearchQuery] = react.useState("");
370
- const debouncedSearchQuery = useDebounce(searchQuery, 300);
371
- const loadFailedRefunds = react.useCallback(
372
- async (nextOffset, replace = false) => {
373
- var _a;
374
- try {
375
- if (replace) {
376
- setIsLoading(true);
377
- }
378
- setError(null);
379
- const params = new URLSearchParams();
380
- params.set("limit", String(limit));
381
- params.set("offset", String(nextOffset));
382
- if (currencyFilter !== "all") {
383
- params.set("currency_code", currencyFilter);
384
- }
385
- if (errorCodeFilter !== "all") {
386
- params.set("error_code", errorCodeFilter);
387
- }
388
- if (debouncedSearchQuery.trim()) {
389
- params.set("return_id", debouncedSearchQuery.trim());
390
- }
391
- const response = await fetch(
392
- `/admin/returns/failed-refunds?${params.toString()}`,
393
- { credentials: "include" }
394
- );
395
- if (!response.ok) {
396
- const message = await response.text();
397
- throw new Error(message || "Unable to load failed refunds");
398
- }
399
- const payload = await response.json();
400
- setCount(payload.count ?? 0);
401
- setOffset(nextOffset + (((_a = payload.failed_refunds) == null ? void 0 : _a.length) ?? 0));
402
- setFailedRefunds(
403
- (prev) => replace ? payload.failed_refunds ?? [] : [...prev, ...payload.failed_refunds ?? []]
404
- );
405
- } catch (loadError) {
406
- const message = loadError instanceof Error ? loadError.message : "Unable to load failed refunds";
407
- setError(message);
408
- } finally {
409
- setIsLoading(false);
410
- }
411
- },
412
- [currencyFilter, errorCodeFilter, debouncedSearchQuery]
413
- );
414
- react.useEffect(() => {
415
- void loadFailedRefunds(0, true);
416
- }, [currencyFilter, errorCodeFilter, debouncedSearchQuery, loadFailedRefunds]);
417
- const hasMore = react.useMemo(() => offset < count, [offset, count]);
418
- const availableCurrencies = react.useMemo(() => {
419
- const currencies = /* @__PURE__ */ new Set();
420
- failedRefunds.forEach((refund) => {
421
- if (refund.currency_code) {
422
- currencies.add(refund.currency_code);
423
- }
424
- });
425
- return Array.from(currencies).sort();
426
- }, [failedRefunds]);
427
- const availableErrorCodes = react.useMemo(() => {
428
- const codes = /* @__PURE__ */ new Set();
429
- failedRefunds.forEach((refund) => {
430
- if (refund.payment_error_code) {
431
- codes.add(refund.payment_error_code);
432
- }
433
- });
434
- return Array.from(codes).sort();
435
- }, [failedRefunds]);
436
- const handleRetrySuccess = () => {
437
- void loadFailedRefunds(0, true);
438
- };
439
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
440
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
441
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
442
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Failed Refunds" }),
443
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and retry failed refund transactions" })
444
- ] }),
445
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadFailedRefunds(0, true), children: "Refresh" })
446
- ] }),
447
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
448
- /* @__PURE__ */ jsxRuntime.jsx(
449
- ui.Input,
450
- {
451
- placeholder: "Search by Return ID or Order ID",
452
- value: searchQuery,
453
- onChange: (event) => setSearchQuery(event.target.value),
454
- className: "md:max-w-sm"
455
- }
456
- ),
457
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
458
- /* @__PURE__ */ jsxRuntime.jsxs(
459
- "select",
460
- {
461
- value: currencyFilter,
462
- onChange: (event) => setCurrencyFilter(event.target.value),
463
- 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",
464
- children: [
465
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Currencies" }),
466
- availableCurrencies.map((currency) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: currency, children: currency }, currency))
467
- ]
468
- }
469
- ),
470
- /* @__PURE__ */ jsxRuntime.jsxs(
471
- "select",
472
- {
473
- value: errorCodeFilter,
474
- onChange: (event) => setErrorCodeFilter(event.target.value),
475
- 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",
476
- children: [
477
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Error Codes" }),
478
- availableErrorCodes.map((code) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: code, children: code }, code))
479
- ]
480
- }
481
- )
482
- ] })
483
- ] }),
484
- error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
485
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
486
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
487
- ui.Button,
488
- {
489
- variant: "secondary",
490
- onClick: () => loadFailedRefunds(0, true),
491
- children: "Try again"
492
- }
493
- ) })
494
- ] }) : null,
495
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading failed refunds..." }) }) : failedRefunds.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
496
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-full bg-ui-tag-green-bg p-3", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ExclamationTriangle, { className: "h-6 w-6 text-ui-tag-green-text" }) }) }),
497
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No failed refunds" }),
498
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "All refunds are processing successfully." })
499
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
500
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
501
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
502
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
503
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
504
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Error" }),
505
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Failed At" }),
506
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Retries" }),
507
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
508
- ] }) }),
509
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: failedRefunds.map((refund) => {
510
- var _a;
511
- return /* @__PURE__ */ jsxRuntime.jsxs(
512
- "tr",
513
- {
514
- className: "hover:bg-ui-bg-subtle/60",
515
- children: [
516
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: refund.return_id ? /* @__PURE__ */ jsxRuntime.jsx(
517
- "button",
518
- {
519
- onClick: () => navigate(`/returns/${refund.return_id}`),
520
- className: "text-left font-medium text-ui-fg-interactive hover:underline",
521
- children: refund.return_id
522
- }
523
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "N/A" }) }) }),
524
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: refund.order_id ? /* @__PURE__ */ jsxRuntime.jsx(
525
- "button",
526
- {
527
- onClick: () => navigate(`/orders/${refund.order_id}`),
528
- className: "text-left font-medium text-ui-fg-interactive hover:underline",
529
- children: refund.order_id
530
- }
531
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "N/A" }) }),
532
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
533
- refund.currency_code || "",
534
- " ",
535
- ((_a = refund.amount) == null ? void 0 : _a.toLocaleString()) || "0"
536
- ] }) }),
537
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-xs", children: [
538
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-error truncate", children: refund.payment_error || "Unknown error" }),
539
- refund.payment_error_code && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-subtle", children: refund.payment_error_code })
540
- ] }) }),
541
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: refund.failed_at ? new Date(refund.failed_at).toLocaleString() : refund.created_at ? new Date(refund.created_at).toLocaleString() : "N/A" }),
542
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", children: refund.retry_count || 0 }) }),
543
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: refund.return_id && /* @__PURE__ */ jsxRuntime.jsx(
544
- RetryRefundButton,
545
- {
546
- returnId: refund.return_id,
547
- onSuccess: handleRetrySuccess,
548
- variant: "secondary",
549
- size: "small"
550
- }
551
- ) })
552
- ]
553
- },
554
- refund.refund_id || refund.return_id
555
- );
556
- }) })
557
- ] }) }),
558
- hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
559
- ui.Button,
560
- {
561
- variant: "secondary",
562
- onClick: () => loadFailedRefunds(offset, false),
563
- children: "Load more"
564
- }
565
- ) }) : null
566
- ] }) });
567
- };
568
- const config = adminSdk.defineRouteConfig({
569
- label: "Failed Refunds",
570
- icon: icons.ExclamationTriangle
571
- });
572
- const i18nTranslations0 = {
573
- translations: {
574
- en: {
575
- "order-management": {
576
- "failed-refunds": {
577
- title: "Failed Refunds",
578
- description: "View and retry failed refund transactions",
579
- "no-failed-refunds": "No failed refunds",
580
- "all-refunds-successful": "All refunds are processing successfully",
581
- "failed-count": "Failed Count",
582
- "total-amount": "Total Amount",
583
- "manage-failed-refunds": "Manage Failed Refunds",
584
- "refund-status": "Refund Status",
585
- "transaction-id": "Transaction ID",
586
- "error": "Error",
587
- "retry-count": "Retry Count",
588
- "payment-details": "Payment Details",
589
- "method": "Method",
590
- "currency": "Currency",
591
- "upi-id": "UPI ID",
592
- "account": "Account",
593
- "retry-refund": "Retry Refund",
594
- "retrying": "Retrying...",
595
- "search-placeholder": "Search by Return ID or Order ID",
596
- "all-currencies": "All Currencies",
597
- "all-error-codes": "All Error Codes",
598
- "return-id": "Return ID",
599
- "order-id": "Order ID",
600
- "amount": "Amount",
601
- "failed-at": "Failed At",
602
- "retries": "Retries",
603
- "actions": "Actions",
604
- "refresh": "Refresh",
605
- "load-more": "Load more",
606
- "loading": "Loading...",
607
- "try-again": "Try again",
608
- "not-started": "Not Started",
609
- "succeeded": "Succeeded",
610
- "failed": "Failed",
611
- "pending": "Pending"
612
- }
613
- }
614
- }
615
- }
616
- };
617
- const widgetModule = { widgets: [
618
- {
619
- Component: FailedRefundsSummaryWidget,
620
- zone: ["order.details.after"]
621
- },
622
- {
623
- Component: ReturnRefundStatusWidget,
624
- zone: ["order.details.after"]
625
- }
626
- ] };
2
+ const i18nTranslations0 = {};
3
+ const widgetModule = { widgets: [] };
627
4
  const routeModule = {
628
- routes: [
629
- {
630
- Component: FailedRefundsPage,
631
- path: "/failed-refunds"
632
- }
633
- ]
5
+ routes: []
634
6
  };
635
7
  const menuItemModule = {
636
- menuItems: [
637
- {
638
- label: config.label,
639
- icon: config.icon,
640
- path: "/failed-refunds",
641
- nested: void 0
642
- }
643
- ]
8
+ menuItems: []
644
9
  };
645
10
  const formModule = { customFields: {} };
646
11
  const displayModule = {