order-management 0.0.95 → 0.0.96

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.
@@ -3,27 +3,39 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.blockRefundUntilReturnReceived = blockRefundUntilReturnReceived;
4
4
  const utils_1 = require("@medusajs/framework/utils");
5
5
  const refund_receive_guard_1 = require("../../helpers/refund-receive-guard");
6
+ function getKnex(req) {
7
+ return req.scope.resolve(utils_1.ContainerRegistrationKeys.PG_CONNECTION);
8
+ }
6
9
  function paymentIdFromRequest(req) {
7
10
  const raw = req.params?.id;
8
- const id = typeof raw === "string" ? raw.trim() : "";
9
- return id || undefined;
11
+ const fromParams = typeof raw === "string" ? raw.trim() : "";
12
+ if (fromParams) {
13
+ return fromParams;
14
+ }
15
+ // Wildcard matchers (/admin/payments/*/refund) do not populate :id
16
+ const path = (typeof req.originalUrl === "string" && req.originalUrl) ||
17
+ (typeof req.url === "string" && req.url) ||
18
+ (typeof req.path === "string" && req.path) ||
19
+ "";
20
+ const match = path.match(/\/admin\/payments\/([^/?#]+)\/refund/i);
21
+ const fromPath = match?.[1]?.trim();
22
+ return fromPath || undefined;
10
23
  }
11
24
  async function resolveOrderIdForPayment(paymentId, req) {
12
25
  const paymentModule = req.scope.resolve(utils_1.Modules.PAYMENT);
13
- const payments = await paymentModule.listPayments({ id: [paymentId] }, { relations: ["payment_session"], take: 1 });
26
+ const payments = await paymentModule.listPayments({ id: [paymentId] }, { take: 1 });
14
27
  const paymentList = Array.isArray(payments) ? payments : [];
15
28
  const paymentRow = paymentList[0];
16
29
  if (!paymentRow) {
17
30
  return null;
18
31
  }
19
- const sessionObj = paymentRow.payment_session;
20
- let collectionId = paymentRow.payment_collection_id?.trim() ||
21
- sessionObj?.payment_collection_id?.trim() ||
22
- null;
32
+ let collectionId = paymentRow.payment_collection_id?.trim() || null;
23
33
  if (!collectionId && typeof paymentRow.payment_session_id === "string") {
24
34
  const sessionId = paymentRow.payment_session_id.trim();
25
35
  if (sessionId) {
26
- const sessions = await paymentModule.listPaymentSessions({ id: [sessionId] }).catch(() => []);
36
+ const sessions = await paymentModule
37
+ .listPaymentSessions({ id: [sessionId] })
38
+ .catch(() => []);
27
39
  const sessionList = Array.isArray(sessions) ? sessions : [];
28
40
  const session = sessionList[0];
29
41
  if (session?.payment_collection_id) {
@@ -34,34 +46,114 @@ async function resolveOrderIdForPayment(paymentId, req) {
34
46
  if (!collectionId) {
35
47
  return null;
36
48
  }
37
- const remoteQuery = req.scope.resolve(utils_1.ContainerRegistrationKeys.REMOTE_QUERY);
38
- const pcQuery = (0, utils_1.remoteQueryObjectFromString)({
39
- entryPoint: "payment_collection",
40
- fields: ["id", "order.id"],
41
- filters: { id: [collectionId] },
49
+ try {
50
+ const knex = getKnex(req);
51
+ const rows = await knex("order_payment_collection")
52
+ .select("order_id")
53
+ .where("payment_collection_id", collectionId)
54
+ .whereNull("deleted_at")
55
+ .limit(1);
56
+ const orderId = rows?.[0]?.order_id;
57
+ if (typeof orderId === "string" && orderId.trim()) {
58
+ return orderId.trim();
59
+ }
60
+ }
61
+ catch {
62
+ // Fall through
63
+ }
64
+ return null;
65
+ }
66
+ async function loadRmaForOrder(orderId, req) {
67
+ const knex = getKnex(req);
68
+ const returnRows = (await knex("return")
69
+ .select(["id", "status", "exchange_id"])
70
+ .where("order_id", orderId)
71
+ .whereNull("deleted_at"));
72
+ const returns = returnRows
73
+ .filter((row) => typeof row.id === "string")
74
+ .map((row) => ({
75
+ id: row.id,
76
+ status: row.status,
77
+ exchange_id: row.exchange_id ?? null,
78
+ }));
79
+ const exchangeRows = (await knex("order_exchange")
80
+ .select(["id", "canceled_at", "return_id"])
81
+ .where("order_id", orderId)
82
+ .whereNull("deleted_at"));
83
+ const exchanges = exchangeRows
84
+ .filter((row) => typeof row.id === "string")
85
+ .map((row) => {
86
+ const returnId = row.return_id ?? null;
87
+ const linked = (returnId ? returns.find((r) => r.id === returnId) : null) ?? null;
88
+ return {
89
+ id: row.id,
90
+ canceled_at: row.canceled_at ?? null,
91
+ return_id: returnId,
92
+ return: linked,
93
+ };
42
94
  });
43
- const pcRows = await remoteQuery(pcQuery);
44
- const pcList = Array.isArray(pcRows) ? pcRows : pcRows ? [pcRows] : [];
45
- const firstPc = pcList[0];
46
- let orderId = firstPc?.order?.id ?? null;
47
- if (!orderId) {
48
- const orderQuery = (0, utils_1.remoteQueryObjectFromString)({
49
- entryPoint: "order",
50
- fields: ["id", "payment_collections.id"],
51
- filters: { payment_collections: { id: [collectionId] } },
52
- });
53
- const orderRows = await remoteQuery(orderQuery).catch(() => []);
54
- const orderList = Array.isArray(orderRows) ? orderRows : orderRows ? [orderRows] : [];
55
- const firstOrder = orderList[0];
56
- orderId = firstOrder?.id ?? null;
95
+ return { returns, exchanges };
96
+ }
97
+ async function loadWalletSettleEvidence(orderId, req) {
98
+ const knex = getKnex(req);
99
+ let orderTransactions = [];
100
+ try {
101
+ const txRows = (await knex("order_transaction")
102
+ .select(["reference", "reference_id"])
103
+ .where("order_id", orderId)
104
+ .whereNull("deleted_at"));
105
+ orderTransactions = txRows
106
+ .filter((row) => (row.reference ?? "").trim() === "refund")
107
+ .map((row) => ({
108
+ reference: row.reference,
109
+ reference_id: row.reference_id,
110
+ }));
57
111
  }
58
- return orderId;
112
+ catch {
113
+ orderTransactions = [];
114
+ }
115
+ const paymentRefunds = [];
116
+ try {
117
+ const result = await knex.raw(`
118
+ SELECT r.created_by, r.note, r.metadata
119
+ FROM refund r
120
+ INNER JOIN payment p ON p.id = r.payment_id AND p.deleted_at IS NULL
121
+ INNER JOIN order_payment_collection opc
122
+ ON opc.payment_collection_id = p.payment_collection_id
123
+ AND opc.deleted_at IS NULL
124
+ WHERE opc.order_id = ?
125
+ AND r.deleted_at IS NULL
126
+ `, [orderId]);
127
+ const rows = (result && typeof result === "object" && "rows" in result
128
+ ? result.rows
129
+ : Array.isArray(result)
130
+ ? result
131
+ : []);
132
+ for (const row of rows) {
133
+ paymentRefunds.push({
134
+ created_by: row.created_by,
135
+ note: row.note,
136
+ metadata: row.metadata ?? null,
137
+ });
138
+ }
139
+ }
140
+ catch {
141
+ // Soft-fail: still enforce return/exchange checks
142
+ }
143
+ return { orderTransactions, paymentRefunds };
59
144
  }
60
145
  /**
61
- * Block Medusa core POST /admin/payments/:id/refund while any return on the order
62
- * is still unreceived. Receive-and-refund inside core workflows is not HTTP and is unaffected.
146
+ * Block Medusa core POST /admin/payments/:id/refund while return/exchange is
147
+ * unreceived, or when the order was already settled to the customer wallet.
63
148
  */
64
149
  async function blockRefundUntilReturnReceived(req, res, next) {
150
+ // Dual matchers can both hit; only evaluate once per request.
151
+ const checkedKey = "__om_refund_rma_checked";
152
+ const reqFlags = req;
153
+ if (reqFlags[checkedKey]) {
154
+ return next();
155
+ }
156
+ reqFlags[checkedKey] = true;
65
157
  const paymentId = paymentIdFromRequest(req);
66
158
  if (!paymentId) {
67
159
  return next();
@@ -69,29 +161,36 @@ async function blockRefundUntilReturnReceived(req, res, next) {
69
161
  try {
70
162
  const orderId = await resolveOrderIdForPayment(paymentId, req);
71
163
  if (!orderId) {
72
- return next();
164
+ res.status(400).json({
165
+ message: (0, refund_receive_guard_1.refundBlockedOrderUnresolvedMessage)(),
166
+ type: "NOT_ALLOWED",
167
+ });
168
+ return;
73
169
  }
74
- const orderModule = req.scope.resolve(utils_1.Modules.ORDER);
75
- const returns = await orderModule.listReturns({ order_id: orderId }, { take: 100 });
76
- const returnList = Array.isArray(returns) ? returns : [];
77
- const blocking = (0, refund_receive_guard_1.getUnreceivedReturnBlockingRefund)(returnList.map((row) => ({
78
- id: row.id,
79
- status: row.status,
80
- })));
81
- if (!blocking) {
170
+ const { returns: returnList, exchanges: exchangeList } = await loadRmaForOrder(orderId, req);
171
+ const { orderTransactions, paymentRefunds } = await loadWalletSettleEvidence(orderId, req);
172
+ const decision = (0, refund_receive_guard_1.shouldBlockRefundForRma)({
173
+ returns: returnList,
174
+ exchanges: exchangeList,
175
+ orderTransactions,
176
+ paymentRefunds,
177
+ });
178
+ if (!decision.blocked) {
82
179
  return next();
83
180
  }
84
181
  res.status(400).json({
85
- message: (0, refund_receive_guard_1.refundBlockedByReturnMessage)(blocking.status ?? "requested"),
182
+ message: decision.message,
86
183
  type: "NOT_ALLOWED",
87
184
  });
88
185
  }
89
186
  catch (err) {
90
- const message = err instanceof Error ? err.message : "Failed to validate refund against return status";
187
+ const message = err instanceof Error
188
+ ? err.message
189
+ : "Failed to validate refund against return status";
91
190
  res.status(500).json({
92
191
  message,
93
192
  type: "INTERNAL_ERROR",
94
193
  });
95
194
  }
96
195
  }
97
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2stcmVmdW5kLXVudGlsLXJldHVybi1yZWNlaXZlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvbWlkZGxld2FyZXMvYmxvY2stcmVmdW5kLXVudGlsLXJldHVybi1yZWNlaXZlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTJGQSx3RUE0Q0M7QUE3SEQscURBQTJHO0FBQzNHLDZFQUcyQztBQUUzQyxTQUFTLG9CQUFvQixDQUFDLEdBQWtCO0lBQzlDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFBO0lBQzFCLE1BQU0sRUFBRSxHQUFHLE9BQU8sR0FBRyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7SUFDcEQsT0FBTyxFQUFFLElBQUksU0FBUyxDQUFBO0FBQ3hCLENBQUM7QUFFRCxLQUFLLFVBQVUsd0JBQXdCLENBQ3JDLFNBQWlCLEVBQ2pCLEdBQWtCO0lBRWxCLE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUF3QixlQUFPLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDL0UsTUFBTSxRQUFRLEdBQUcsTUFBTSxhQUFhLENBQUMsWUFBWSxDQUMvQyxFQUFFLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQ25CLEVBQUUsU0FBUyxFQUFFLENBQUMsaUJBQWlCLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQzVDLENBQUE7SUFDRCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtJQUMzRCxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFtRCxDQUFBO0lBQ25GLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FB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
196
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2stcmVmdW5kLXVudGlsLXJldHVybi1yZWNlaXZlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvbWlkZGxld2FyZXMvYmxvY2stcmVmdW5kLXVudGlsLXJldHVybi1yZWNlaXZlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXNQQSx3RUErREM7QUEvU0QscURBR2tDO0FBQ2xDLDZFQU8yQztBQTBCM0MsU0FBUyxPQUFPLENBQUMsR0FBa0I7SUFDakMsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBVyxpQ0FBeUIsQ0FBQyxhQUFhLENBQUMsQ0FBQTtBQUM3RSxDQUFDO0FBRUQsU0FBUyxvQkFBb0IsQ0FBQyxHQUFrQjtJQUM5QyxNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQTtJQUMxQixNQUFNLFVBQVUsR0FBRyxPQUFPLEdBQUcsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFBO0lBQzVELElBQUksVUFBVSxFQUFFLENBQUM7UUFDZixPQUFPLFVBQVUsQ0FBQTtJQUNuQixDQUFDO0lBQ0QsbUVBQW1FO0lBQ25FLE1BQU0sSUFBSSxHQUNSLENBQUMsT0FBTyxHQUFHLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDO1FBQ3hELENBQUMsT0FBTyxHQUFHLENBQUMsR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDO1FBQ3hDLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQzFDLEVBQUUsQ0FBQTtJQUNKLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQTtJQUNqRSxNQUFNLFFBQVEsR0FBRyxLQUFLLEVBQUUs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
@@ -8,24 +8,30 @@ exports.default = (0, http_1.defineMiddlewares)({
8
8
  routes: [
9
9
  {
10
10
  matcher: "/admin/payments/:id/refund",
11
- method: "POST",
11
+ methods: ["POST"],
12
+ middlewares: [block_refund_until_return_received_1.blockRefundUntilReturnReceived],
13
+ },
14
+ {
15
+ // Wildcard fallback when :id matchers are skipped
16
+ matcher: "/admin/payments/*/refund",
17
+ methods: ["POST"],
12
18
  middlewares: [block_refund_until_return_received_1.blockRefundUntilReturnReceived],
13
19
  },
14
20
  {
15
21
  matcher: "/store/returns",
16
- method: "POST",
22
+ methods: ["POST"],
17
23
  middlewares: [(0, http_1.validateAndTransformBody)(validators_1.StoreCreateReturnSchema)],
18
24
  },
19
25
  {
20
26
  matcher: "/store/orders/cancel/:order_id",
21
- method: "POST",
27
+ methods: ["POST"],
22
28
  middlewares: [(0, http_1.validateAndTransformBody)(cancel_order_1.StoreCancelOrderBodySchema)],
23
29
  },
24
30
  {
25
31
  matcher: "/store/guest-orders/:id/cancel",
26
- method: "POST",
32
+ methods: ["POST"],
27
33
  middlewares: [(0, http_1.validateAndTransformBody)(cancel_order_1.StoreCancelOrderBodySchema)],
28
34
  },
29
35
  ],
30
36
  });
31
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbURBR2lDO0FBQ2pDLHlHQUFpRztBQUNqRywyREFBb0U7QUFDcEUsa0VBQTRFO0FBRTVFLGtCQUFlLElBQUEsd0JBQWlCLEVBQUM7SUFDL0IsTUFBTSxFQUFFO1FBQ047WUFDRSxPQUFPLEVBQUUsNEJBQTRCO1lBQ3JDLE1BQU0sRUFBRSxNQUFNO1lBQ2QsV0FBVyxFQUFFLENBQUMsbUVBQThCLENBQUM7U0FDOUM7UUFDRDtZQUNFLE9BQU8sRUFBRSxnQkFBZ0I7WUFDekIsTUFBTSxFQUFFLE1BQU07WUFDZCxXQUFXLEVBQUUsQ0FBQyxJQUFBLCtCQUF3QixFQUFDLG9DQUF1QixDQUFDLENBQUM7U0FDakU7UUFDRDtZQUNFLE9BQU8sRUFBRSxnQ0FBZ0M7WUFDekMsTUFBTSxFQUFFLE1BQU07WUFDZCxXQUFXLEVBQUUsQ0FBQyxJQUFBLCtCQUF3QixFQUFDLHlDQUEwQixDQUFDLENBQUM7U0FDcEU7UUFDRDtZQUNFLE9BQU8sRUFBRSxnQ0FBZ0M7WUFDekMsTUFBTSxFQUFFLE1BQU07WUFDZCxXQUFXLEVBQUUsQ0FBQyxJQUFBLCtCQUF3QixFQUFDLHlDQUEwQixDQUFDLENBQUM7U0FDcEU7S0FDRjtDQUNGLENBQUMsQ0FBQSJ9
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbURBR2lDO0FBQ2pDLHlHQUFpRztBQUNqRywyREFBb0U7QUFDcEUsa0VBQTRFO0FBRTVFLGtCQUFlLElBQUEsd0JBQWlCLEVBQUM7SUFDL0IsTUFBTSxFQUFFO1FBQ047WUFDRSxPQUFPLEVBQUUsNEJBQTRCO1lBQ3JDLE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQztZQUNqQixXQUFXLEVBQUUsQ0FBQyxtRUFBOEIsQ0FBQztTQUM5QztRQUNEO1lBQ0Usa0RBQWtEO1lBQ2xELE9BQU8sRUFBRSwwQkFBMEI7WUFDbkMsT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDO1lBQ2pCLFdBQVcsRUFBRSxDQUFDLG1FQUE4QixDQUFDO1NBQzlDO1FBQ0Q7WUFDRSxPQUFPLEVBQUUsZ0JBQWdCO1lBQ3pCLE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQztZQUNqQixXQUFXLEVBQUUsQ0FBQyxJQUFBLCtCQUF3QixFQUFDLG9DQUF1QixDQUFDLENBQUM7U0FDakU7UUFDRDtZQUNFLE9BQU8sRUFBRSxnQ0FBZ0M7WUFDekMsT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDO1lBQ2pCLFdBQVcsRUFBRSxDQUFDLElBQUEsK0JBQXdCLEVBQUMseUNBQTBCLENBQUMsQ0FBQztTQUNwRTtRQUNEO1lBQ0UsT0FBTyxFQUFFLGdDQUFnQztZQUN6QyxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUM7WUFDakIsV0FBVyxFQUFFLENBQUMsSUFBQSwrQkFBd0IsRUFBQyx5Q0FBMEIsQ0FBQyxDQUFDO1NBQ3BFO0tBQ0Y7Q0FDRixDQUFDLENBQUEifQ==
@@ -1,17 +1,64 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.refundBlockedByReturnMessage = refundBlockedByReturnMessage;
4
+ exports.refundBlockedByExchangeMessage = refundBlockedByExchangeMessage;
5
+ exports.refundBlockedByWalletSettleMessage = refundBlockedByWalletSettleMessage;
6
+ exports.refundBlockedOrderUnresolvedMessage = refundBlockedOrderUnresolvedMessage;
7
+ exports.isWalletSettleOrderTransaction = isWalletSettleOrderTransaction;
8
+ exports.isWalletSettlePaymentRefund = isWalletSettlePaymentRefund;
9
+ exports.orderHasWalletSettle = orderHasWalletSettle;
4
10
  exports.getUnreceivedReturnBlockingRefund = getUnreceivedReturnBlockingRefund;
11
+ exports.shouldBlockRefundForRma = shouldBlockRefundForRma;
5
12
  exports.assertReturnReceivedForRefund = assertReturnReceivedForRefund;
6
13
  exports.canProcessRefundForReturn = canProcessRefundForReturn;
7
14
  const utils_1 = require("@medusajs/framework/utils");
8
15
  const return_exchange_guard_1 = require("./return-exchange-guard");
16
+ const WALLET_SETTLE_REFERENCE_PREFIXES = [
17
+ "wallet:exchange:",
18
+ "wallet:return:",
19
+ "wallet:payment:",
20
+ ];
9
21
  /**
10
22
  * Message when a refund is attempted before the return is fully received.
11
23
  */
12
24
  function refundBlockedByReturnMessage(status) {
13
25
  return `Cannot process a refund while the return is ${status}. Receive the returned items first.`;
14
26
  }
27
+ function refundBlockedByExchangeMessage() {
28
+ return "Cannot process a refund while an exchange is in progress. Receive the returned items first.";
29
+ }
30
+ function refundBlockedByWalletSettleMessage() {
31
+ return "Cannot process a payment refund; this order was already settled to the customer wallet.";
32
+ }
33
+ function refundBlockedOrderUnresolvedMessage() {
34
+ return "Cannot process a refund: unable to resolve the order for this payment. Verify the payment is linked to an order.";
35
+ }
36
+ function isWalletSettleOrderTransaction(tx) {
37
+ if ((tx.reference ?? "").trim() !== "refund") {
38
+ return false;
39
+ }
40
+ const refId = (tx.reference_id ?? "").trim();
41
+ return WALLET_SETTLE_REFERENCE_PREFIXES.some((prefix) => refId.startsWith(prefix));
42
+ }
43
+ function isWalletSettlePaymentRefund(refund) {
44
+ if (refund.created_by === "wallet_settle") {
45
+ return true;
46
+ }
47
+ if (refund.metadata?.wallet_settle === true) {
48
+ return true;
49
+ }
50
+ const note = refund.note ?? "";
51
+ return note.startsWith("wallet_settle:");
52
+ }
53
+ function orderHasWalletSettle(input) {
54
+ if ((input.orderTransactions ?? []).some(isWalletSettleOrderTransaction)) {
55
+ return true;
56
+ }
57
+ if ((input.paymentRefunds ?? []).some(isWalletSettlePaymentRefund)) {
58
+ return true;
59
+ }
60
+ return false;
61
+ }
15
62
  /**
16
63
  * First unreceived return that must block a refund (`open` | `requested` | `partially_received`).
17
64
  * Exchange-linked returns are included — refunds are blocked until items are received.
@@ -24,6 +71,60 @@ function getUnreceivedReturnBlockingRefund(returns) {
24
71
  }
25
72
  return null;
26
73
  }
74
+ /**
75
+ * Whether admin payment refund should be blocked for open RMA or prior wallet settle.
76
+ */
77
+ function shouldBlockRefundForRma(input) {
78
+ if (orderHasWalletSettle({
79
+ orderTransactions: input.orderTransactions,
80
+ paymentRefunds: input.paymentRefunds,
81
+ })) {
82
+ return {
83
+ blocked: true,
84
+ reason: "wallet_settle",
85
+ message: refundBlockedByWalletSettleMessage(),
86
+ };
87
+ }
88
+ const blockingReturn = getUnreceivedReturnBlockingRefund(input.returns);
89
+ if (blockingReturn) {
90
+ return {
91
+ blocked: true,
92
+ reason: "return",
93
+ message: refundBlockedByReturnMessage(blockingReturn.status ?? "requested"),
94
+ returnId: blockingReturn.id,
95
+ status: blockingReturn.status ?? undefined,
96
+ };
97
+ }
98
+ for (const exchange of input.exchanges) {
99
+ let linked = exchange.return ?? null;
100
+ if (!linked && exchange.return_id) {
101
+ linked =
102
+ input.returns.find((r) => r.id === exchange.return_id) ?? null;
103
+ }
104
+ const linkedForGuard = linked
105
+ ? {
106
+ id: linked.id,
107
+ status: linked.status ?? undefined,
108
+ exchange_id: linked.exchange_id,
109
+ }
110
+ : null;
111
+ if ((0, return_exchange_guard_1.isActiveExchange)({
112
+ id: exchange.id,
113
+ canceled_at: exchange.canceled_at,
114
+ return_id: exchange.return_id,
115
+ return: linkedForGuard,
116
+ }, linkedForGuard)) {
117
+ return {
118
+ blocked: true,
119
+ reason: "exchange",
120
+ message: refundBlockedByExchangeMessage(),
121
+ exchangeId: exchange.id,
122
+ status: linked?.status ?? undefined,
123
+ };
124
+ }
125
+ }
126
+ return { blocked: false };
127
+ }
27
128
  /**
28
129
  * Throw NOT_ALLOWED when this return is still unreceived.
29
130
  * No return / already received / canceled → allow.
@@ -45,4 +146,4 @@ function canProcessRefundForReturn(input) {
45
146
  Boolean(input.has_mapping) &&
46
147
  !input.is_refunded);
47
148
  }
48
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmdW5kLXJlY2VpdmUtZ3VhcmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaGVscGVycy9yZWZ1bmQtcmVjZWl2ZS1ndWFyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVdBLG9FQUVDO0FBTUQsOEVBU0M7QUFNRCxzRUFhQztBQUtELDhEQVVDO0FBOURELHFEQUF1RDtBQUN2RCxtRUFBOEQ7QUFPOUQ7O0dBRUc7QUFDSCxTQUFnQiw0QkFBNEIsQ0FBQyxNQUFjO0lBQ3pELE9BQU8sK0NBQStDLE1BQU0scUNBQXFDLENBQUE7QUFDbkcsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLGlDQUFpQyxDQUMvQyxPQUErQjtJQUUvQixLQUFLLE1BQU0sR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzFCLElBQUksSUFBQSw0Q0FBb0IsRUFBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUNyQyxPQUFPLEdBQUcsQ0FBQTtRQUNaLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUE7QUFDYixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0IsNkJBQTZCLENBQzNDLEdBQTRDO0lBRTVDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNULE9BQU07SUFDUixDQUFDO0lBQ0QsSUFBSSxDQUFDLElBQUEsNENBQW9CLEVBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDdEMsT0FBTTtJQUNSLENBQUM7SUFDRCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUM3Qiw0QkFBNEIsQ0FBQyxHQUFHLENBQUMsTUFBTSxJQUFJLFdBQVcsQ0FBQyxDQUN4RCxDQUFBO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IseUJBQXlCLENBQUMsS0FJekM7SUFDQyxPQUFPLENBQ0wsS0FBSyxDQUFDLE1BQU0sS0FBSyxVQUFVO1FBQzNCLE9BQU8sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO1FBQzFCLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FDbkIsQ0FBQTtBQUNILENBQUMifQ==
149
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmdW5kLXJlY2VpdmUtZ3VhcmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaGVscGVycy9yZWZ1bmQtcmVjZWl2ZS1ndWFyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWtEQSxvRUFFQztBQUVELHdFQUVDO0FBRUQsZ0ZBRUM7QUFFRCxrRkFFQztBQUVELHdFQVVDO0FBRUQsa0VBV0M7QUFFRCxvREFXQztBQU1ELDhFQVNDO0FBS0QsMERBbUVDO0FBTUQsc0VBYUM7QUFLRCw4REFVQztBQS9ORCxxREFBdUQ7QUFDdkQsbUVBR2dDO0FBcUNoQyxNQUFNLGdDQUFnQyxHQUFHO0lBQ3ZDLGtCQUFrQjtJQUNsQixnQkFBZ0I7SUFDaEIsaUJBQWlCO0NBQ1QsQ0FBQTtBQUVWOztHQUVHO0FBQ0gsU0FBZ0IsNEJBQTRCLENBQUMsTUFBYztJQUN6RCxPQUFPLCtDQUErQyxNQUFNLHFDQUFxQyxDQUFBO0FBQ25HLENBQUM7QUFFRCxTQUFnQiw4QkFBOEI7SUFDNUMsT0FBTyw2RkFBNkYsQ0FBQTtBQUN0RyxDQUFDO0FBRUQsU0FBZ0Isa0NBQWtDO0lBQ2hELE9BQU8seUZBQXlGLENBQUE7QUFDbEcsQ0FBQztBQUVELFNBQWdCLG1DQUFtQztJQUNqRCxPQUFPLGtIQUFrSCxDQUFBO0FBQzNILENBQUM7QUFFRCxTQUFnQiw4QkFBOEIsQ0FDNUMsRUFBa0M7SUFFbEMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDN0MsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBQ0QsTUFBTSxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFBO0lBQzVDLE9BQU8sZ0NBQWdDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FDdEQsS0FBSyxDQUFDLFVB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
package/README.md CHANGED
@@ -245,7 +245,6 @@ curl "http://localhost:9000/admin/orders/order_123/refund-context" \
245
245
  | Swaps routes | `/swaps`, `/swaps/:id` | Exchange listing/detail pages | Search, filters, reject/cancel exchange; uses `/admin/swaps*`. |
246
246
  | Payments routes | `/payments`, `/payments/:id` | Transaction list + detail pages | Filter transactions and inspect gateway payload. |
247
247
  | Refunds routes | `/refunds`, `/refunds/:id` | Refund list + detail pages | Filter by status/provider/date/amount; view computed refund context. |
248
- | `order-refund-context-widget` | `order.details.after` | Refund context panel | Order checkout payment method (including guest orders), refund calculation (product amount, return charge, processed final refund), edit refund mode/details/images, upload images, mark refunded. |
249
248
  | `order-gift-items-widget` | `order.details.side.after` | Gift item widget | Reads gift metadata and downloads generated gift card image. |
250
249
 
251
250
  ## Models & Entities
@@ -592,7 +591,7 @@ The plugin includes a `refund_payment_mapping` module: one row per return linkin
592
591
  - `PUT /admin/refund-payment-mapping/:return_id` — update admin-only fields. Body: `{ refund_mode?: "offline" | "online" | null, images?: string[], details?: string | null }` (partial; only provided keys are updated).
593
592
  - `POST /admin/refund-payment-mapping/:return_id/mark-refunded` — set `is_refunded = true` (idempotent). Requires Medusa return status `received`; otherwise `400 NOT_ALLOWED`. Already-refunded mappings still succeed without re-checking receive status.
594
593
  - **Receive-before-refund guard**: Middleware on Medusa core `POST /admin/payments/:id/refund` rejects the request with `400 NOT_ALLOWED` when the order has any return in `open`, `requested`, or `partially_received` (including exchange-linked returns). Message: `Cannot process a refund while the return is {status}. Receive the returned items first.` Orders with no return, or only `received` / `canceled` returns, are not blocked.
595
- - **Order detail integration**: `GET /admin/orders/:order_id/refund-context` — aggregated read returning `return_id`, `return_status`, `can_process_refund` (`true` only when status is `received` and the mapping exists and is not already refunded), `order_payment` (checkout `provider_id`, human-readable `label`, `is_cod` — used for guest orders that have no saved `payment_detail`), `refund_mapping` (id, payment_id, is_refunded, refund_mode, images, details), `payment_detail` (id, type, detail_json, is_default) resolved from the customer's specified or default payment detail, and `refund` (product_amount, return_charge, expected_net_amount, final_refund_amount, currency_code, is_processed, breakdown_matches, destination_label). `final_refund_amount` is the processed payment refund (or COD/offline `return.refund_amount` after mark-refunded), not `product_amount - return_charge`. Returns null blocks when no return or mapping exists. An admin widget at `order.details.after` shows **Order payment method** (the provider used at checkout, including guest orders), **Refund calculation**, refund payment method, **Refund mode** (Offline/Online), **Details**, **Images** (with upload via Medusa `POST /admin/uploads`), and **Mark refunded** only when `can_process_refund` is true. While the return is unreceived the widget tells admins to receive items first and not refund from Payments. Only admin can change refund_mode, images, and details.
594
+ - **Order detail integration**: `GET /admin/orders/:order_id/refund-context` — aggregated read returning `return_id`, `return_status`, `can_process_refund` (`true` only when status is `received` and the mapping exists and is not already refunded), `order_payment` (checkout `provider_id`, human-readable `label`, `is_cod` — used for guest orders that have no saved `payment_detail`), `refund_mapping` (id, payment_id, is_refunded, refund_mode, images, details), `payment_detail` (id, type, detail_json, is_default) resolved from the customer's specified or default payment detail, and `refund` (product_amount, return_charge, expected_net_amount, final_refund_amount, currency_code, is_processed, breakdown_matches, destination_label). `final_refund_amount` is the processed payment refund (or COD/offline `return.refund_amount` after mark-refunded), not `product_amount - return_charge`. Returns null blocks when no return or mapping exists. Used by admin refund/return detail pages; refund_mode, images, and details are admin-only via the mapping APIs above.
596
595
  - **Store return payload**: `GET /store/returns` and `GET /store/returns/:id` attach the same `refund` object so the storefront can render the breakdown. `GET /store/orders/:order_id/refund-payment-mappings` includes `refund` per mapping.
597
596
  - **Registration**: Add the module in `medusa-config.js` (e.g. `orderManagement.modules["refund-payment-mapping"]`) and run migrations.
598
597
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "order-management",
3
- "version": "0.0.95",
3
+ "version": "0.0.96",
4
4
  "description": "A starter for Medusa plugins.",
5
5
  "author": "Medusa (https://medusajs.com)",
6
6
  "license": "MIT",