@burdenoff/microfe-billing 2026.912.2 → 2026.912.4

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.
@@ -2,3 +2,4 @@ import "./useInvoices.js";
2
2
  import "./usePayments.js";
3
3
  import "./useTransactions.js";
4
4
  import "./useRefunds.js";
5
+ import "./useOrderCallbacks.js";
@@ -0,0 +1,41 @@
1
+ import { useGetBillingOrderCallbacksQuery as e, useRetryBillingOrderCallbackMutation as t } from "../../../../generated/global-operations.js";
2
+ import { useCallback as n } from "react";
3
+ //#region src/billing/modules/billing/hooks/useOrderCallbacks.ts
4
+ function r(t, r, i) {
5
+ let { data: a, loading: o, error: s, refetch: c } = e({
6
+ variables: {
7
+ limit: i,
8
+ offset: r * i,
9
+ callbackStatus: t.callbackStatus,
10
+ externalService: t.externalService,
11
+ hasError: t.hasError
12
+ },
13
+ fetchPolicy: "cache-and-network"
14
+ }), l = n(async () => {
15
+ await c();
16
+ }, [c]);
17
+ return {
18
+ orders: a?.getBillingOrderCallbacks.orders ?? [],
19
+ totalCount: a?.getBillingOrderCallbacks.totalCount ?? 0,
20
+ isLoading: o,
21
+ error: s,
22
+ refetch: l
23
+ };
24
+ }
25
+ function i() {
26
+ let [e, { loading: r }] = t();
27
+ return {
28
+ retryOrderCallback: n(async (t, n) => {
29
+ let { data: r } = await e({ variables: {
30
+ orderId: t,
31
+ billingAccountId: n
32
+ } });
33
+ if (!r?.retryBillingOrderCallback.success) throw Error(r?.retryBillingOrderCallback.error || "Failed to retry callback");
34
+ }, [e]),
35
+ isRetrying: r
36
+ };
37
+ }
38
+ //#endregion
39
+ export { i as useOrderCallbackMutations, r as useOrderCallbacks };
40
+
41
+ //# sourceMappingURL=useOrderCallbacks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOrderCallbacks.js","names":[],"sources":["../../../../../src/billing/modules/billing/hooks/useOrderCallbacks.ts"],"sourcesContent":["/**\n * Billing Module - useOrderCallbacks Hook\n * Admin visibility into the billing→external-service (store, etc.) order\n * completion callback — the outbound counterpart to useBillingWebhookLogs'\n * inbound Stripe/Razorpay webhook log. Backs the admin order-callback log\n * viewer so ops can see and retry ANY billing→store handoff without direct\n * DB access (BOFF-7192).\n */\n\nimport { useCallback } from 'react';\n\nimport {\n useGetBillingOrderCallbacksQuery,\n useRetryBillingOrderCallbackMutation,\n} from '../../../../generated/global-operations';\n\nexport interface OrderCallback {\n id: string;\n externalService: string;\n orgId: string;\n billingAccountId: string | null;\n currency: string;\n subtotal: number;\n status: string;\n paymentId: string | null;\n transactionId: string | null;\n callbackStatus: string | null;\n callbackAttempts: number | null;\n callbackLastError: string | null;\n callbackLastAttemptAt: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface OrderCallbackFilters {\n callbackStatus?: string;\n externalService?: string;\n hasError?: boolean;\n}\n\ninterface UseOrderCallbacksResult {\n orders: OrderCallback[];\n totalCount: number;\n isLoading: boolean;\n error: Error | undefined;\n refetch: () => Promise<void>;\n}\n\n/**\n * Hook for the admin order-callback log viewer — paginated, filterable view\n * over ALL BillingOrder callback deliveries (not just FAILED ones).\n */\nexport function useOrderCallbacks(\n filters: OrderCallbackFilters,\n page: number,\n pageSize: number\n): UseOrderCallbacksResult {\n const { data, loading, error, refetch } = useGetBillingOrderCallbacksQuery({\n variables: {\n limit: pageSize,\n offset: page * pageSize,\n callbackStatus: filters.callbackStatus,\n externalService: filters.externalService,\n hasError: filters.hasError,\n },\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n return {\n orders: (data?.getBillingOrderCallbacks.orders ?? []) as OrderCallback[],\n totalCount: data?.getBillingOrderCallbacks.totalCount ?? 0,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\ninterface UseOrderCallbackMutationsResult {\n /** Resolves once the retry attempt completes; throws on failure. Callers\n * should refetch the list afterward rather than trust a stale row. */\n retryOrderCallback: (orderId: string, billingAccountId: string) => Promise<void>;\n isRetrying: boolean;\n}\n\n/**\n * Manual retry for a stuck/failed order callback — reuses the same\n * retryBillingOrderCallback mutation checkout already exposes to a billing\n * account owner; a super_admin bypasses the billing-account ownership check\n * server-side, so this page can retry any org's order.\n */\nexport function useOrderCallbackMutations(): UseOrderCallbackMutationsResult {\n const [retryMutation, { loading: isRetrying }] = useRetryBillingOrderCallbackMutation();\n\n const retryOrderCallback = useCallback(\n async (orderId: string, billingAccountId: string): Promise<void> => {\n const { data } = await retryMutation({ variables: { orderId, billingAccountId } });\n if (!data?.retryBillingOrderCallback.success) {\n throw new Error(data?.retryBillingOrderCallback.error || 'Failed to retry callback');\n }\n },\n [retryMutation]\n );\n\n return { retryOrderCallback, isRetrying };\n}\n"],"mappings":";;;AAoDA,SAAgB,EACd,GACA,GACA,GACyB;CACzB,IAAM,EAAE,SAAM,YAAS,UAAO,eAAY,EAAiC;EACzE,WAAW;GACT,OAAO;GACP,QAAQ,IAAO;GACf,gBAAgB,EAAQ;GACxB,iBAAiB,EAAQ;GACzB,UAAU,EAAQ;EACpB;EACA,aAAa;CACf,CAAC,GAEK,IAAgB,EAAY,YAAY;EAC5C,MAAM,EAAQ;CAChB,GAAG,CAAC,CAAO,CAAC;CAEZ,OAAO;EACL,QAAS,GAAM,yBAAyB,UAAU,CAAC;EACnD,YAAY,GAAM,yBAAyB,cAAc;EACzD,WAAW;EACJ;EACP,SAAS;CACX;AACF;AAeA,SAAgB,IAA6D;CAC3E,IAAM,CAAC,GAAe,EAAE,SAAS,OAAgB,EAAqC;CAYtF,OAAO;EAAE,oBAVkB,EACzB,OAAO,GAAiB,MAA4C;GAClE,IAAM,EAAE,YAAS,MAAM,EAAc,EAAE,WAAW;IAAE;IAAS;GAAiB,EAAE,CAAC;GACjF,IAAI,CAAC,GAAM,0BAA0B,SACnC,MAAU,MAAM,GAAM,0BAA0B,SAAS,0BAA0B;EAEvF,GACA,CAAC,CAAa,CAGP;EAAoB;CAAW;AAC1C"}
@@ -3,11 +3,13 @@ import { InvoicesListPage as e } from "./pages/InvoicesListPage.js";
3
3
  import { InvoiceDetailPage as t } from "./pages/InvoiceDetailPage.js";
4
4
  import "./hooks/useTransactions.js";
5
5
  import "./hooks/useRefunds.js";
6
+ import "./hooks/useOrderCallbacks.js";
6
7
  import "./hooks/index.js";
7
8
  import { TransactionsPage as n } from "./pages/TransactionsPage.js";
8
9
  import { PaymentMethodsPage as r } from "./pages/PaymentMethodsPage.js";
9
10
  import { RefundsPage as i } from "./pages/RefundsPage.js";
10
11
  import { UserRefundsPage as a } from "./pages/UserRefundsPage.js";
11
12
  import { BillingWebhookLogsPage as o } from "./pages/BillingWebhookLogsPage.js";
13
+ import { OrderCallbackLogsPage as s } from "./pages/OrderCallbackLogsPage.js";
12
14
  import "./pages/index.js";
13
- export { o as BillingWebhookLogsPage, t as InvoiceDetailPage, e as InvoicesListPage, r as PaymentMethodsPage, i as RefundsPage, n as TransactionsPage, a as UserRefundsPage };
15
+ export { o as BillingWebhookLogsPage, t as InvoiceDetailPage, e as InvoicesListPage, s as OrderCallbackLogsPage, r as PaymentMethodsPage, i as RefundsPage, n as TransactionsPage, a as UserRefundsPage };
@@ -0,0 +1,427 @@
1
+ import { AccessDenied as e } from "../../../shared/components/AccessDenied.js";
2
+ import { PageHeader as t } from "../../../shared/components/PageHeader.js";
3
+ import { statusTokens as n } from "../../../shared/utils/tokens.js";
4
+ import { ServerError as r } from "../../../shared/components/ServerError.js";
5
+ import "../../../shared/components/index.js";
6
+ import { formatDateTime as i } from "../../../shared/utils/format.js";
7
+ import { isServerError as a } from "../../../shared/utils/error.js";
8
+ import "../../../shared/utils/index.js";
9
+ import { useBillingPermissions as o } from "../../../hooks/useBillingPermissions.js";
10
+ import { useOrderCallbackMutations as s, useOrderCallbacks as c } from "../hooks/useOrderCallbacks.js";
11
+ import "../hooks/index.js";
12
+ import { useState as l } from "react";
13
+ import { AlertTriangle as u, CheckCircle as d, ChevronLeft as f, ChevronRight as p, Clock as m, Eye as h, Loader2 as g, RefreshCw as _, RotateCw as v, X as y } from "lucide-react";
14
+ import { jsx as b, jsxs as x } from "react/jsx-runtime";
15
+ import { IllustratedEmptyState as S, ResponsiveTable as C } from "@burdenoff/fe-libs/ui";
16
+ //#region src/billing/modules/billing/pages/OrderCallbackLogsPage.tsx
17
+ var w = 25, T = [
18
+ "PENDING",
19
+ "SUCCESS",
20
+ "FAILED"
21
+ ], E = (e) => e.callbackStatus === "FAILED" ? {
22
+ label: "Failed",
23
+ className: `${n.error.bg} ${n.error.text}`,
24
+ icon: u
25
+ } : e.callbackStatus === "SUCCESS" ? {
26
+ label: "Delivered",
27
+ className: `${n.success.bg} ${n.success.text}`,
28
+ icon: d
29
+ } : {
30
+ label: e.callbackStatus || "Pending",
31
+ className: `${n.warning.bg} ${n.warning.text}`,
32
+ icon: m
33
+ }, D = ({ order: e, onClose: t, onRetry: n, isRetrying: r }) => {
34
+ if (!e) return null;
35
+ let a = e.callbackStatus === "FAILED" && !!e.billingAccountId;
36
+ return /* @__PURE__ */ b("div", {
37
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay p-4",
38
+ children: /* @__PURE__ */ x("div", {
39
+ className: "w-full max-w-2xl max-h-[85vh] overflow-y-auto rounded-lg bg-bg-surface border border-border-subtle shadow-[var(--shadow-elevation-2)]",
40
+ children: [/* @__PURE__ */ x("div", {
41
+ className: "flex items-center justify-between p-4 border-b border-border-subtle",
42
+ children: [/* @__PURE__ */ b("h3", {
43
+ className: "text-base font-semibold text-text-primary",
44
+ children: "Order callback details"
45
+ }), /* @__PURE__ */ b("button", {
46
+ type: "button",
47
+ onClick: t,
48
+ className: "p-1 rounded text-text-muted hover:text-text-primary hover:bg-bg-sunken/50",
49
+ children: /* @__PURE__ */ b(y, { className: "size-4" })
50
+ })]
51
+ }), /* @__PURE__ */ x("div", {
52
+ className: "p-4 space-y-4",
53
+ children: [
54
+ /* @__PURE__ */ x("div", {
55
+ className: "grid grid-cols-2 gap-4 text-sm",
56
+ children: [
57
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
58
+ className: "text-text-muted",
59
+ children: "Order ID"
60
+ }), /* @__PURE__ */ b("p", {
61
+ className: "text-text-primary font-mono text-xs break-all",
62
+ children: e.id
63
+ })] }),
64
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
65
+ className: "text-text-muted",
66
+ children: "Service"
67
+ }), /* @__PURE__ */ b("p", {
68
+ className: "text-text-primary",
69
+ children: e.externalService
70
+ })] }),
71
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
72
+ className: "text-text-muted",
73
+ children: "Order status"
74
+ }), /* @__PURE__ */ b("p", {
75
+ className: "text-text-primary",
76
+ children: e.status
77
+ })] }),
78
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
79
+ className: "text-text-muted",
80
+ children: "Amount"
81
+ }), /* @__PURE__ */ x("p", {
82
+ className: "text-text-primary",
83
+ children: [
84
+ e.subtotal,
85
+ " ",
86
+ e.currency
87
+ ]
88
+ })] }),
89
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
90
+ className: "text-text-muted",
91
+ children: "Billing account"
92
+ }), /* @__PURE__ */ b("p", {
93
+ className: "text-text-primary font-mono text-xs break-all",
94
+ children: e.billingAccountId || "—"
95
+ })] }),
96
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
97
+ className: "text-text-muted",
98
+ children: "Payment / Transaction"
99
+ }), /* @__PURE__ */ x("p", {
100
+ className: "text-text-primary font-mono text-xs break-all",
101
+ children: [
102
+ e.paymentId || "—",
103
+ " / ",
104
+ e.transactionId || "—"
105
+ ]
106
+ })] }),
107
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
108
+ className: "text-text-muted",
109
+ children: "Created"
110
+ }), /* @__PURE__ */ b("p", {
111
+ className: "text-text-primary",
112
+ children: i(e.createdAt)
113
+ })] }),
114
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
115
+ className: "text-text-muted",
116
+ children: "Last callback attempt"
117
+ }), /* @__PURE__ */ b("p", {
118
+ className: "text-text-primary",
119
+ children: e.callbackLastAttemptAt ? i(e.callbackLastAttemptAt) : "—"
120
+ })] }),
121
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
122
+ className: "text-text-muted",
123
+ children: "Callback attempts"
124
+ }), /* @__PURE__ */ b("p", {
125
+ className: "text-text-primary",
126
+ children: e.callbackAttempts ?? 0
127
+ })] }),
128
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
129
+ className: "text-text-muted",
130
+ children: "Callback status"
131
+ }), /* @__PURE__ */ b("p", {
132
+ className: "text-text-primary",
133
+ children: e.callbackStatus || "PENDING"
134
+ })] })
135
+ ]
136
+ }),
137
+ e.callbackLastError && /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
138
+ className: "text-sm text-text-muted mb-1",
139
+ children: "Last error"
140
+ }), /* @__PURE__ */ b("pre", {
141
+ className: "text-xs whitespace-pre-wrap p-3 rounded-md bg-status-error-bg-subtle text-status-error-text border border-status-error-border",
142
+ children: e.callbackLastError
143
+ })] }),
144
+ e.callbackStatus === "FAILED" && !e.billingAccountId && /* @__PURE__ */ b("p", {
145
+ className: "text-xs text-text-muted",
146
+ children: "No billing account was resolved on this order, so it can't be retried from here — the callback was never able to identify who paid."
147
+ }),
148
+ e.callbackStatus === "FAILED" && /* @__PURE__ */ x("button", {
149
+ type: "button",
150
+ onClick: () => n(e),
151
+ disabled: !a || r,
152
+ className: "inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bgHover disabled:opacity-50",
153
+ children: [r ? /* @__PURE__ */ b(g, { className: "size-4 animate-spin" }) : /* @__PURE__ */ b(v, { className: "size-4" }), "Retry callback"]
154
+ })
155
+ ]
156
+ })]
157
+ })
158
+ });
159
+ }, O = () => {
160
+ let n = o(), [u, d] = l(0), [m, g] = l({}), [v, y] = l(null), [O, k] = l(null), { orders: A, totalCount: j, isLoading: M, error: N, refetch: P } = c(m, u, w), { retryOrderCallback: F, isRetrying: I } = s();
161
+ if (!n.isBillingAdmin) return /* @__PURE__ */ b(e, { message: "You don't have permission to view order callback logs." });
162
+ if (N && a(N)) return /* @__PURE__ */ b("div", {
163
+ className: "p-6",
164
+ children: /* @__PURE__ */ b(r, {
165
+ title: "Server Unavailable",
166
+ message: "Unable to load order callback logs. The server might be down or experiencing issues.",
167
+ onRetry: () => P(),
168
+ showRetry: !0
169
+ })
170
+ });
171
+ let L = (e, t) => {
172
+ g((n) => ({
173
+ ...n,
174
+ [e]: t
175
+ })), d(0);
176
+ }, R = async (e) => {
177
+ if (e.billingAccountId) {
178
+ k(null);
179
+ try {
180
+ await F(e.id, e.billingAccountId), await P(), y(null);
181
+ } catch (e) {
182
+ k(e instanceof Error ? e.message : "Failed to retry callback");
183
+ }
184
+ }
185
+ }, z = [
186
+ {
187
+ key: "date",
188
+ header: "Created",
189
+ priority: "primary",
190
+ cellClassName: "whitespace-nowrap",
191
+ cell: (e) => /* @__PURE__ */ x("div", {
192
+ className: "flex flex-col",
193
+ children: [/* @__PURE__ */ b("span", {
194
+ className: "text-sm text-text-primary",
195
+ children: i(e.createdAt).split(" ")[0]
196
+ }), /* @__PURE__ */ b("span", {
197
+ className: "text-xs text-text-muted",
198
+ children: i(e.createdAt).split(" ")[1]
199
+ })]
200
+ })
201
+ },
202
+ {
203
+ key: "callbackStatus",
204
+ header: "Callback",
205
+ cellClassName: "whitespace-nowrap",
206
+ cell: (e) => {
207
+ let t = E(e), n = t.icon;
208
+ return /* @__PURE__ */ x("span", {
209
+ className: `inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded ${t.className}`,
210
+ children: [/* @__PURE__ */ b(n, { className: "size-3" }), t.label]
211
+ });
212
+ }
213
+ },
214
+ {
215
+ key: "service",
216
+ header: "Service",
217
+ priority: "hidden-on-mobile",
218
+ cellClassName: "whitespace-nowrap",
219
+ cell: (e) => /* @__PURE__ */ b("span", {
220
+ className: "text-sm text-text-primary",
221
+ children: e.externalService
222
+ })
223
+ },
224
+ {
225
+ key: "orderId",
226
+ header: "Order ID",
227
+ cellClassName: "whitespace-nowrap max-w-[220px] truncate",
228
+ cell: (e) => /* @__PURE__ */ b("span", {
229
+ className: "text-sm font-mono text-text-muted",
230
+ title: e.id,
231
+ children: e.id
232
+ })
233
+ },
234
+ {
235
+ key: "attempts",
236
+ header: "Attempts",
237
+ priority: "hidden-on-mobile",
238
+ cellClassName: "whitespace-nowrap",
239
+ cell: (e) => /* @__PURE__ */ b("span", {
240
+ className: "text-sm text-text-secondary",
241
+ children: e.callbackAttempts ?? 0
242
+ })
243
+ },
244
+ {
245
+ key: "error",
246
+ header: "Error",
247
+ priority: "hidden-on-mobile",
248
+ cellClassName: "max-w-[280px] truncate",
249
+ cell: (e) => /* @__PURE__ */ b("span", {
250
+ className: "text-sm text-status-error-text",
251
+ children: e.callbackLastError || "-"
252
+ })
253
+ }
254
+ ], B = Math.max(1, Math.ceil(j / w));
255
+ return /* @__PURE__ */ x("div", {
256
+ className: "space-y-6 p-6",
257
+ children: [
258
+ /* @__PURE__ */ b(t, {
259
+ title: "Order Callback Logs",
260
+ description: "Every billing→store (and other external service) order-completion callback — investigate a stuck handoff directly.",
261
+ actions: /* @__PURE__ */ x("button", {
262
+ type: "button",
263
+ onClick: () => P(),
264
+ className: "inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md border border-border-subtle bg-bg-surface hover:bg-bg-sunken/50",
265
+ children: [/* @__PURE__ */ b(_, { className: "size-4" }), "Refresh"]
266
+ })
267
+ }),
268
+ O && /* @__PURE__ */ b("div", {
269
+ className: "p-3 rounded-md bg-status-error-bg-subtle text-status-error-text border border-status-error-border text-sm",
270
+ children: O
271
+ }),
272
+ /* @__PURE__ */ x("div", {
273
+ className: "p-4 border border-border-subtle rounded-lg bg-bg-sunken/30 grid grid-cols-1 sm:grid-cols-3 gap-4",
274
+ children: [
275
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
276
+ className: "block text-sm font-medium mb-1",
277
+ children: "Callback status"
278
+ }), /* @__PURE__ */ x("select", {
279
+ value: m.callbackStatus || "",
280
+ onChange: (e) => L("callbackStatus", e.target.value || void 0),
281
+ className: "w-full px-3 py-2 border border-border-subtle rounded-md bg-bg-surface",
282
+ children: [/* @__PURE__ */ b("option", {
283
+ value: "",
284
+ children: "All"
285
+ }), T.map((e) => /* @__PURE__ */ b("option", {
286
+ value: e,
287
+ children: e
288
+ }, e))]
289
+ })] }),
290
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
291
+ className: "block text-sm font-medium mb-1",
292
+ children: "Service"
293
+ }), /* @__PURE__ */ b("input", {
294
+ type: "text",
295
+ value: m.externalService || "",
296
+ onChange: (e) => L("externalService", e.target.value || void 0),
297
+ placeholder: "e.g. STORE",
298
+ className: "w-full px-3 py-2 border border-border-subtle rounded-md bg-bg-surface"
299
+ })] }),
300
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
301
+ className: "block text-sm font-medium mb-1",
302
+ children: "Has Error"
303
+ }), /* @__PURE__ */ x("select", {
304
+ value: m.hasError === void 0 ? "" : String(m.hasError),
305
+ onChange: (e) => L("hasError", e.target.value === "" ? void 0 : e.target.value === "true"),
306
+ className: "w-full px-3 py-2 border border-border-subtle rounded-md bg-bg-surface",
307
+ children: [
308
+ /* @__PURE__ */ b("option", {
309
+ value: "",
310
+ children: "All"
311
+ }),
312
+ /* @__PURE__ */ b("option", {
313
+ value: "true",
314
+ children: "Has error"
315
+ }),
316
+ /* @__PURE__ */ b("option", {
317
+ value: "false",
318
+ children: "No error"
319
+ })
320
+ ]
321
+ })] })
322
+ ]
323
+ }),
324
+ M && A.length === 0 ? /* @__PURE__ */ b("div", {
325
+ className: "space-y-2",
326
+ children: [
327
+ 1,
328
+ 2,
329
+ 3,
330
+ 4,
331
+ 5
332
+ ].map((e) => /* @__PURE__ */ b("div", { className: "h-16 bg-bg-sunken animate-pulse rounded" }, e))
333
+ }) : A.length === 0 ? /* @__PURE__ */ b(S, {
334
+ illustration: "empty-data",
335
+ title: "No order callbacks found",
336
+ description: "Nothing matches these filters — try widening them, or check back after the next store purchase."
337
+ }) : /* @__PURE__ */ b("div", {
338
+ className: "border border-border-subtle rounded-lg overflow-hidden",
339
+ children: /* @__PURE__ */ b(C, {
340
+ columns: z,
341
+ data: A,
342
+ rowKey: (e) => e.id,
343
+ rowActions: (e) => /* @__PURE__ */ x("button", {
344
+ type: "button",
345
+ onClick: () => y(e),
346
+ className: "inline-flex items-center gap-1.5 px-2 py-1 text-sm font-medium rounded-button text-text-secondary hover:text-text-primary hover:bg-bg-sunken/60 transition-colors",
347
+ children: [/* @__PURE__ */ b(h, { className: "size-4" }), /* @__PURE__ */ b("span", {
348
+ className: "hidden sm:inline",
349
+ children: "View"
350
+ })]
351
+ })
352
+ })
353
+ }),
354
+ j > 0 && /* @__PURE__ */ x("div", {
355
+ className: "flex flex-col sm:flex-row items-center justify-between gap-4 border-t border-border-subtle pt-4",
356
+ children: [/* @__PURE__ */ x("p", {
357
+ className: "text-sm text-text-muted text-center sm:text-left",
358
+ children: [
359
+ "Showing ",
360
+ u * w + 1,
361
+ " to ",
362
+ Math.min((u + 1) * w, j),
363
+ " of",
364
+ " ",
365
+ j,
366
+ " orders"
367
+ ]
368
+ }), /* @__PURE__ */ x("div", {
369
+ className: "flex items-center gap-2",
370
+ children: [
371
+ /* @__PURE__ */ x("button", {
372
+ type: "button",
373
+ onClick: () => d((e) => Math.max(0, e - 1)),
374
+ disabled: u === 0,
375
+ className: "inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-button border border-border-subtle bg-bg-surface hover:bg-bg-sunken/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
376
+ children: [/* @__PURE__ */ b(f, { className: "size-4" }), /* @__PURE__ */ b("span", {
377
+ className: "hidden sm:inline",
378
+ children: "Previous"
379
+ })]
380
+ }),
381
+ /* @__PURE__ */ x("span", {
382
+ className: "text-sm text-text-muted px-2",
383
+ children: [
384
+ /* @__PURE__ */ b("span", {
385
+ className: "hidden sm:inline",
386
+ children: "Page "
387
+ }),
388
+ u + 1,
389
+ " ",
390
+ /* @__PURE__ */ b("span", {
391
+ className: "hidden sm:inline",
392
+ children: "of"
393
+ }),
394
+ /* @__PURE__ */ b("span", {
395
+ className: "sm:hidden",
396
+ children: "/"
397
+ }),
398
+ " ",
399
+ B
400
+ ]
401
+ }),
402
+ /* @__PURE__ */ x("button", {
403
+ type: "button",
404
+ onClick: () => d((e) => e + 1 < B ? e + 1 : e),
405
+ disabled: u + 1 >= B,
406
+ className: "inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-button border border-border-subtle bg-bg-surface hover:bg-bg-sunken/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
407
+ children: [/* @__PURE__ */ b("span", {
408
+ className: "hidden sm:inline",
409
+ children: "Next"
410
+ }), /* @__PURE__ */ b(p, { className: "size-4" })]
411
+ })
412
+ ]
413
+ })]
414
+ }),
415
+ /* @__PURE__ */ b(D, {
416
+ order: v,
417
+ onClose: () => y(null),
418
+ onRetry: R,
419
+ isRetrying: I
420
+ })
421
+ ]
422
+ });
423
+ };
424
+ //#endregion
425
+ export { O as OrderCallbackLogsPage };
426
+
427
+ //# sourceMappingURL=OrderCallbackLogsPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrderCallbackLogsPage.js","names":[],"sources":["../../../../../src/billing/modules/billing/pages/OrderCallbackLogsPage.tsx"],"sourcesContent":["/**\n * Billing Module - Order Callback Logs Page\n * Admin visibility into the billing→external-service (store, etc.) order\n * completion callback — every BillingOrder's callback delivery attempt, not\n * just the ones currently FAILED. The outbound counterpart to\n * BillingWebhookLogsPage's inbound Stripe/Razorpay webhook view: lets\n * whoever owns billing ops see and retry a stuck billing→store handoff\n * without needing direct DB access (BOFF-7192).\n */\n\nimport { useState, type FC } from 'react';\nimport {\n RefreshCw,\n ChevronLeft,\n ChevronRight,\n CheckCircle,\n AlertTriangle,\n Clock,\n X,\n RotateCw,\n Loader2,\n Eye,\n} from 'lucide-react';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport {\n useOrderCallbacks,\n useOrderCallbackMutations,\n type OrderCallbackFilters,\n type OrderCallback,\n} from '../hooks';\nimport { AccessDenied, PageHeader, ServerError } from '../../../shared/components';\nimport { formatDateTime, isServerError } from '../../../shared/utils';\nimport { statusTokens } from '../../../shared/utils/tokens';\nimport {\n ResponsiveTable,\n type ResponsiveTableColumn,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\n\nconst PAGE_SIZE = 25;\nconst CALLBACK_STATUS_OPTIONS = ['PENDING', 'SUCCESS', 'FAILED'];\n\nconst getBadge = (\n order: OrderCallback\n): { label: string; className: string; icon: FC<{ className?: string }> } => {\n if (order.callbackStatus === 'FAILED') {\n return {\n label: 'Failed',\n className: `${statusTokens.error.bg} ${statusTokens.error.text}`,\n icon: AlertTriangle,\n };\n }\n if (order.callbackStatus === 'SUCCESS') {\n return {\n label: 'Delivered',\n className: `${statusTokens.success.bg} ${statusTokens.success.text}`,\n icon: CheckCircle,\n };\n }\n return {\n label: order.callbackStatus || 'Pending',\n className: `${statusTokens.warning.bg} ${statusTokens.warning.text}`,\n icon: Clock,\n };\n};\n\nconst OrderCallbackDetailModal: FC<{\n order: OrderCallback | null;\n onClose: () => void;\n onRetry: (order: OrderCallback) => void;\n isRetrying: boolean;\n}> = ({ order, onClose, onRetry, isRetrying }) => {\n if (!order) return null;\n\n const canRetry = order.callbackStatus === 'FAILED' && Boolean(order.billingAccountId);\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay p-4\">\n <div className=\"w-full max-w-2xl max-h-[85vh] overflow-y-auto rounded-lg bg-bg-surface border border-border-subtle shadow-[var(--shadow-elevation-2)]\">\n <div className=\"flex items-center justify-between p-4 border-b border-border-subtle\">\n <h3 className=\"text-base font-semibold text-text-primary\">Order callback details</h3>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"p-1 rounded text-text-muted hover:text-text-primary hover:bg-bg-sunken/50\"\n >\n <X className=\"size-4\" />\n </button>\n </div>\n <div className=\"p-4 space-y-4\">\n <div className=\"grid grid-cols-2 gap-4 text-sm\">\n <div>\n <p className=\"text-text-muted\">Order ID</p>\n <p className=\"text-text-primary font-mono text-xs break-all\">{order.id}</p>\n </div>\n <div>\n <p className=\"text-text-muted\">Service</p>\n <p className=\"text-text-primary\">{order.externalService}</p>\n </div>\n <div>\n <p className=\"text-text-muted\">Order status</p>\n <p className=\"text-text-primary\">{order.status}</p>\n </div>\n <div>\n <p className=\"text-text-muted\">Amount</p>\n <p className=\"text-text-primary\">\n {order.subtotal} {order.currency}\n </p>\n </div>\n <div>\n <p className=\"text-text-muted\">Billing account</p>\n <p className=\"text-text-primary font-mono text-xs break-all\">\n {order.billingAccountId || '—'}\n </p>\n </div>\n <div>\n <p className=\"text-text-muted\">Payment / Transaction</p>\n <p className=\"text-text-primary font-mono text-xs break-all\">\n {order.paymentId || '—'} / {order.transactionId || '—'}\n </p>\n </div>\n <div>\n <p className=\"text-text-muted\">Created</p>\n <p className=\"text-text-primary\">{formatDateTime(order.createdAt)}</p>\n </div>\n <div>\n <p className=\"text-text-muted\">Last callback attempt</p>\n <p className=\"text-text-primary\">\n {order.callbackLastAttemptAt ? formatDateTime(order.callbackLastAttemptAt) : '—'}\n </p>\n </div>\n <div>\n <p className=\"text-text-muted\">Callback attempts</p>\n <p className=\"text-text-primary\">{order.callbackAttempts ?? 0}</p>\n </div>\n <div>\n <p className=\"text-text-muted\">Callback status</p>\n <p className=\"text-text-primary\">{order.callbackStatus || 'PENDING'}</p>\n </div>\n </div>\n {order.callbackLastError && (\n <div>\n <p className=\"text-sm text-text-muted mb-1\">Last error</p>\n <pre className=\"text-xs whitespace-pre-wrap p-3 rounded-md bg-status-error-bg-subtle text-status-error-text border border-status-error-border\">\n {order.callbackLastError}\n </pre>\n </div>\n )}\n {order.callbackStatus === 'FAILED' && !order.billingAccountId && (\n <p className=\"text-xs text-text-muted\">\n No billing account was resolved on this order, so it can&apos;t be retried from here —\n the callback was never able to identify who paid.\n </p>\n )}\n {order.callbackStatus === 'FAILED' && (\n <button\n type=\"button\"\n onClick={() => onRetry(order)}\n disabled={!canRetry || isRetrying}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bgHover disabled:opacity-50\"\n >\n {isRetrying ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <RotateCw className=\"size-4\" />\n )}\n Retry callback\n </button>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport const OrderCallbackLogsPage: FC = () => {\n const permissions = useBillingPermissions();\n const [page, setPage] = useState(0);\n const [filters, setFilters] = useState<OrderCallbackFilters>({});\n const [selectedOrder, setSelectedOrder] = useState<OrderCallback | null>(null);\n const [retryError, setRetryError] = useState<string | null>(null);\n\n const { orders, totalCount, isLoading, error, refetch } = useOrderCallbacks(\n filters,\n page,\n PAGE_SIZE\n );\n const { retryOrderCallback, isRetrying } = useOrderCallbackMutations();\n\n if (!permissions.isBillingAdmin) {\n return <AccessDenied message=\"You don't have permission to view order callback logs.\" />;\n }\n\n if (error && isServerError(error)) {\n return (\n <div className=\"p-6\">\n <ServerError\n title=\"Server Unavailable\"\n message=\"Unable to load order callback logs. The server might be down or experiencing issues.\"\n onRetry={() => refetch()}\n showRetry\n />\n </div>\n );\n }\n\n const handleFilterChange = <K extends keyof OrderCallbackFilters>(\n key: K,\n value: OrderCallbackFilters[K]\n ) => {\n setFilters((prev) => ({ ...prev, [key]: value }));\n setPage(0);\n };\n\n const handleRetry = async (order: OrderCallback) => {\n if (!order.billingAccountId) return;\n setRetryError(null);\n try {\n await retryOrderCallback(order.id, order.billingAccountId);\n await refetch();\n setSelectedOrder(null);\n } catch (err) {\n setRetryError(err instanceof Error ? err.message : 'Failed to retry callback');\n }\n };\n\n const columns: ResponsiveTableColumn<OrderCallback>[] = [\n {\n key: 'date',\n header: 'Created',\n priority: 'primary',\n cellClassName: 'whitespace-nowrap',\n cell: (order) => (\n <div className=\"flex flex-col\">\n <span className=\"text-sm text-text-primary\">\n {formatDateTime(order.createdAt).split(' ')[0]}\n </span>\n <span className=\"text-xs text-text-muted\">\n {formatDateTime(order.createdAt).split(' ')[1]}\n </span>\n </div>\n ),\n },\n {\n key: 'callbackStatus',\n header: 'Callback',\n cellClassName: 'whitespace-nowrap',\n cell: (order) => {\n const badge = getBadge(order);\n const BadgeIcon = badge.icon;\n return (\n <span\n className={`inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded ${badge.className}`}\n >\n <BadgeIcon className=\"size-3\" />\n {badge.label}\n </span>\n );\n },\n },\n {\n key: 'service',\n header: 'Service',\n priority: 'hidden-on-mobile',\n cellClassName: 'whitespace-nowrap',\n cell: (order) => <span className=\"text-sm text-text-primary\">{order.externalService}</span>,\n },\n {\n key: 'orderId',\n header: 'Order ID',\n cellClassName: 'whitespace-nowrap max-w-[220px] truncate',\n cell: (order) => (\n <span className=\"text-sm font-mono text-text-muted\" title={order.id}>\n {order.id}\n </span>\n ),\n },\n {\n key: 'attempts',\n header: 'Attempts',\n priority: 'hidden-on-mobile',\n cellClassName: 'whitespace-nowrap',\n cell: (order) => (\n <span className=\"text-sm text-text-secondary\">{order.callbackAttempts ?? 0}</span>\n ),\n },\n {\n key: 'error',\n header: 'Error',\n priority: 'hidden-on-mobile',\n cellClassName: 'max-w-[280px] truncate',\n cell: (order) => (\n <span className=\"text-sm text-status-error-text\">{order.callbackLastError || '-'}</span>\n ),\n },\n ];\n\n const totalPages = Math.max(1, Math.ceil(totalCount / PAGE_SIZE));\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title=\"Order Callback Logs\"\n description=\"Every billing→store (and other external service) order-completion callback — investigate a stuck handoff directly.\"\n actions={\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md border border-border-subtle bg-bg-surface hover:bg-bg-sunken/50\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n }\n />\n\n {retryError && (\n <div className=\"p-3 rounded-md bg-status-error-bg-subtle text-status-error-text border border-status-error-border text-sm\">\n {retryError}\n </div>\n )}\n\n {/* Filters */}\n <div className=\"p-4 border border-border-subtle rounded-lg bg-bg-sunken/30 grid grid-cols-1 sm:grid-cols-3 gap-4\">\n <div>\n <label className=\"block text-sm font-medium mb-1\">Callback status</label>\n <select\n value={filters.callbackStatus || ''}\n onChange={(e) => handleFilterChange('callbackStatus', e.target.value || undefined)}\n className=\"w-full px-3 py-2 border border-border-subtle rounded-md bg-bg-surface\"\n >\n <option value=\"\">All</option>\n {CALLBACK_STATUS_OPTIONS.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium mb-1\">Service</label>\n <input\n type=\"text\"\n value={filters.externalService || ''}\n onChange={(e) => handleFilterChange('externalService', e.target.value || undefined)}\n placeholder=\"e.g. STORE\"\n className=\"w-full px-3 py-2 border border-border-subtle rounded-md bg-bg-surface\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium mb-1\">Has Error</label>\n <select\n value={filters.hasError === undefined ? '' : String(filters.hasError)}\n onChange={(e) =>\n handleFilterChange(\n 'hasError',\n e.target.value === '' ? undefined : e.target.value === 'true'\n )\n }\n className=\"w-full px-3 py-2 border border-border-subtle rounded-md bg-bg-surface\"\n >\n <option value=\"\">All</option>\n <option value=\"true\">Has error</option>\n <option value=\"false\">No error</option>\n </select>\n </div>\n </div>\n\n {/* Table */}\n {isLoading && orders.length === 0 ? (\n <div className=\"space-y-2\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className=\"h-16 bg-bg-sunken animate-pulse rounded\" />\n ))}\n </div>\n ) : orders.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No order callbacks found\"\n description=\"Nothing matches these filters — try widening them, or check back after the next store purchase.\"\n />\n ) : (\n <div className=\"border border-border-subtle rounded-lg overflow-hidden\">\n <ResponsiveTable<OrderCallback>\n columns={columns}\n data={orders}\n rowKey={(order) => order.id}\n rowActions={(order) => (\n <button\n type=\"button\"\n onClick={() => setSelectedOrder(order)}\n className=\"inline-flex items-center gap-1.5 px-2 py-1 text-sm font-medium rounded-button text-text-secondary hover:text-text-primary hover:bg-bg-sunken/60 transition-colors\"\n >\n <Eye className=\"size-4\" />\n <span className=\"hidden sm:inline\">View</span>\n </button>\n )}\n />\n </div>\n )}\n\n {/* Pagination */}\n {totalCount > 0 && (\n <div className=\"flex flex-col sm:flex-row items-center justify-between gap-4 border-t border-border-subtle pt-4\">\n <p className=\"text-sm text-text-muted text-center sm:text-left\">\n Showing {page * PAGE_SIZE + 1} to {Math.min((page + 1) * PAGE_SIZE, totalCount)} of{' '}\n {totalCount} orders\n </p>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setPage((p) => Math.max(0, p - 1))}\n disabled={page === 0}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-button border border-border-subtle bg-bg-surface hover:bg-bg-sunken/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n <ChevronLeft className=\"size-4\" />\n <span className=\"hidden sm:inline\">Previous</span>\n </button>\n <span className=\"text-sm text-text-muted px-2\">\n <span className=\"hidden sm:inline\">Page </span>\n {page + 1} <span className=\"hidden sm:inline\">of</span>\n <span className=\"sm:hidden\">/</span> {totalPages}\n </span>\n <button\n type=\"button\"\n onClick={() => setPage((p) => (p + 1 < totalPages ? p + 1 : p))}\n disabled={page + 1 >= totalPages}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-button border border-border-subtle bg-bg-surface hover:bg-bg-sunken/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n <span className=\"hidden sm:inline\">Next</span>\n <ChevronRight className=\"size-4\" />\n </button>\n </div>\n </div>\n )}\n\n <OrderCallbackDetailModal\n order={selectedOrder}\n onClose={() => setSelectedOrder(null)}\n onRetry={handleRetry}\n isRetrying={isRetrying}\n />\n </div>\n );\n};\n"],"mappings":"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"}
@@ -5,3 +5,4 @@ import "./PaymentMethodsPage.js";
5
5
  import "./RefundsPage.js";
6
6
  import "./UserRefundsPage.js";
7
7
  import "./BillingWebhookLogsPage.js";
8
+ import "./OrderCallbackLogsPage.js";
@@ -285,20 +285,21 @@ function u(u = {}) {
285
285
  }
286
286
  }
287
287
  if (a === "CREDITS") {
288
- let e = _.filter((e) => e.type === "ADDON"), t = _.find((e) => e.type === "PLAN"), { data: n } = await fe({ variables: { input: {
288
+ let e = _.filter((e) => e.type === "ADDON"), n = _.find((e) => e.type === "PLAN"), { data: a } = await fe({ variables: { input: {
289
289
  billingAccountId: y.id,
290
- planId: t ? t.metadata?.planId || t.id : void 0,
290
+ orderId: t === "ORDER" ? r : void 0,
291
+ planId: n ? n.metadata?.planId || n.id : void 0,
291
292
  addOnIds: e.length > 0 ? e.map((e) => ({
292
293
  id: e.metadata?.addonId || e.id,
293
294
  quantity: e.quantity
294
295
  })) : void 0,
295
- isAnnual: t?.metadata?.duration === "yearly",
296
+ isAnnual: n?.metadata?.duration === "yearly",
296
297
  upgradeFromSubscriptionId: m || void 0,
297
298
  downgradeFromSubscriptionId: h || void 0,
298
299
  subscriptionId: e.length > 0 ? W : void 0,
299
- seatCount: t?.metadata?.seatCount
300
- } } }), r = n?.spendCredits;
301
- return r?.creditTransactionID ? (P("success"), {
300
+ seatCount: n?.metadata?.seatCount
301
+ } } }), o = a?.spendCredits;
302
+ return o?.creditTransactionID ? (P("success"), {
302
303
  success: !0,
303
304
  provider: "CREDITS",
304
305
  subtotal: i,
@@ -308,7 +309,7 @@ function u(u = {}) {
308
309
  taxType: "NONE",
309
310
  jurisdiction: "UNKNOWN",
310
311
  currency: S,
311
- orderId: r.creditTransactionID
312
+ orderId: o.creditTransactionID
312
313
  }) : (P("error"), F("Failed to process credit payment"), {
313
314
  success: !1,
314
315
  provider: "CREDITS",