fix(medusa): Payment status on refunds (#2770)
This commit is contained in:
1 parent
b2ea8b7d45
commit
3464617553
4 files changed
+127
-2
No files matched your search
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Properly setting "refunded" and "partially refunded" statuses on orders
|
||||||
@@ -6,6 +6,7 @@ const {
|
|||||||
CustomShippingOption,
|
CustomShippingOption,
|
||||||
ShippingMethod,
|
ShippingMethod,
|
||||||
} = require("@medusajs/medusa")
|
} = require("@medusajs/medusa")
|
||||||
|
const idMap = require("medusa-test-utils/src/id-map").default
|
||||||
|
|
||||||
const setupServer = require("../../../../helpers/setup-server")
|
const setupServer = require("../../../../helpers/setup-server")
|
||||||
const { useApi } = require("../../../../helpers/use-api")
|
const { useApi } = require("../../../../helpers/use-api")
|
||||||
@@ -22,7 +23,18 @@ const {
|
|||||||
callGet,
|
callGet,
|
||||||
partial,
|
partial,
|
||||||
} = require("../../../helpers/call-helpers")
|
} = require("../../../helpers/call-helpers")
|
||||||
const { simpleShippingOptionFactory } = require("../../../factories")
|
const {
|
||||||
|
simpleShippingOptionFactory,
|
||||||
|
simpleOrderFactory,
|
||||||
|
simplePaymentFactory,
|
||||||
|
simpleProductFactory,
|
||||||
|
} = require("../../../factories")
|
||||||
|
|
||||||
|
const adminReqConfig = {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer test_token",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
jest.setTimeout(30000)
|
jest.setTimeout(30000)
|
||||||
|
|
||||||
@@ -2360,4 +2372,94 @@ describe("/admin/orders", () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("POST /orders/:id/refund", () => {
|
||||||
|
const orderId = idMap.getId("refund-order-1")
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
await orderSeeder(dbConnection)
|
||||||
|
|
||||||
|
const product1 = await simpleProductFactory(dbConnection, {})
|
||||||
|
|
||||||
|
await simpleOrderFactory(dbConnection, {
|
||||||
|
id: orderId,
|
||||||
|
tax_rate: null,
|
||||||
|
email: "test@testson.com",
|
||||||
|
fulfillment_status: "fulfilled",
|
||||||
|
payment_status: "captured",
|
||||||
|
line_items: [
|
||||||
|
{
|
||||||
|
variant_id: product1.variants[0].id,
|
||||||
|
id: idMap.getId("item-1"),
|
||||||
|
quantity: 1,
|
||||||
|
fulfilled_quantity: 1,
|
||||||
|
shipped_quantity: 1,
|
||||||
|
unit_price: 1000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
await simplePaymentFactory(dbConnection, {
|
||||||
|
provider_id: "test-pay",
|
||||||
|
order: orderId,
|
||||||
|
amount: 300,
|
||||||
|
captured: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
await simplePaymentFactory(dbConnection, {
|
||||||
|
provider_id: "test-pay",
|
||||||
|
order: orderId,
|
||||||
|
amount: 700,
|
||||||
|
captured: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("set status on refunded order", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const response = await api.post(
|
||||||
|
`/admin/orders/${orderId}/refund`,
|
||||||
|
{ amount: 1000, reason: "other" },
|
||||||
|
adminReqConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.data.order).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
payment_status: "refunded",
|
||||||
|
refunded_total: 1000,
|
||||||
|
subtotal: 1000,
|
||||||
|
total: 1000,
|
||||||
|
paid_total: 1000,
|
||||||
|
refundable_amount: 0,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("set correct status on partially refunded order", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const response = await api.post(
|
||||||
|
`/admin/orders/${orderId}/refund`,
|
||||||
|
{ amount: 500, reason: "other" },
|
||||||
|
adminReqConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.data.order).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
payment_status: "partially_refunded",
|
||||||
|
refunded_total: 500,
|
||||||
|
subtotal: 1000,
|
||||||
|
total: 1000,
|
||||||
|
paid_total: 1000,
|
||||||
|
refundable_amount: 500,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -1461,6 +1461,8 @@ class OrderService extends TransactionBaseService {
|
|||||||
const { no_notification } = config
|
const { no_notification } = config
|
||||||
|
|
||||||
return await this.atomicPhase_(async (manager) => {
|
return await this.atomicPhase_(async (manager) => {
|
||||||
|
const orderRepo = manager.getCustomRepository(this.orderRepository_)
|
||||||
|
|
||||||
const order = await this.retrieve(orderId, {
|
const order = await this.retrieve(orderId, {
|
||||||
select: ["refundable_amount", "total", "refunded_total"],
|
select: ["refundable_amount", "total", "refunded_total"],
|
||||||
relations: ["payments"],
|
relations: ["payments"],
|
||||||
@@ -1484,7 +1486,22 @@ class OrderService extends TransactionBaseService {
|
|||||||
.withTransaction(manager)
|
.withTransaction(manager)
|
||||||
.refundPayment(order.payments, refundAmount, reason, note)
|
.refundPayment(order.payments, refundAmount, reason, note)
|
||||||
|
|
||||||
const result = await this.retrieve(orderId)
|
let result = await this.retrieveWithTotals(orderId, {
|
||||||
|
relations: ["payments"],
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result.refunded_total > 0 && result.refundable_amount > 0) {
|
||||||
|
result.payment_status = PaymentStatus.PARTIALLY_REFUNDED
|
||||||
|
result = await orderRepo.save(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
result.paid_total > 0 &&
|
||||||
|
result.refunded_total === result.paid_total
|
||||||
|
) {
|
||||||
|
result.payment_status = PaymentStatus.REFUNDED
|
||||||
|
result = await orderRepo.save(result)
|
||||||
|
}
|
||||||
|
|
||||||
const evaluatedNoNotification =
|
const evaluatedNoNotification =
|
||||||
no_notification !== undefined ? no_notification : order.no_notification
|
no_notification !== undefined ? no_notification : order.no_notification
|
||||||
|
|||||||
@@ -589,6 +589,7 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
const paymentRepo = transactionManager.getCustomRepository(
|
const paymentRepo = transactionManager.getCustomRepository(
|
||||||
this.paymentRepository_
|
this.paymentRepository_
|
||||||
)
|
)
|
||||||
|
|
||||||
let paymentToRefund = payments.find(
|
let paymentToRefund = payments.find(
|
||||||
(payment) => payment.amount - payment.amount_refunded > 0
|
(payment) => payment.amount - payment.amount_refunded > 0
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in new issue
Block a user