feat(core-flows,types): Refunds can only be performed when order is imbalanced (#8944)
* feat(core-flows,types): Refunds can only be performed when order is imbalanced * Apply suggestions from code review Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com> * chore: fix tests --------- Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
co-authored by
Oli Juhl
parent
9a34e03ae1
commit
230acb700b
@@ -1,8 +1,9 @@
|
||||
import { BigNumberInput } from "@medusajs/types"
|
||||
import { MathBN, PaymentEvents } from "@medusajs/utils"
|
||||
import { BigNumberInput, OrderDTO, PaymentDTO } from "@medusajs/types"
|
||||
import { MathBN, MedusaError, PaymentEvents } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
@@ -11,6 +12,41 @@ import { emitEventStep, useRemoteQueryStep } from "../../common"
|
||||
import { addOrderTransactionStep } from "../../order/steps/add-order-transaction"
|
||||
import { refundPaymentStep } from "../steps/refund-payment"
|
||||
|
||||
/**
|
||||
* This step validates that the refund is valid for the order
|
||||
*/
|
||||
export const validateRefundStep = createStep(
|
||||
"validate-refund-step",
|
||||
async function ({
|
||||
order,
|
||||
payment,
|
||||
amount,
|
||||
}: {
|
||||
order: OrderDTO
|
||||
payment: PaymentDTO
|
||||
amount?: BigNumberInput
|
||||
}) {
|
||||
const pendingDifference = order.summary?.raw_pending_difference!
|
||||
|
||||
if (MathBN.gte(pendingDifference, 0)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Order does not have an outstanding balance to refund`
|
||||
)
|
||||
}
|
||||
|
||||
const amountPending = MathBN.mult(pendingDifference, -1)
|
||||
const amountToRefund = amount ?? payment.raw_amount ?? payment.amount
|
||||
|
||||
if (MathBN.gt(amountToRefund, amountPending)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot refund more than pending difference - ${amountPending}`
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const refundPaymentWorkflowId = "refund-payment-workflow"
|
||||
/**
|
||||
* This workflow refunds a payment.
|
||||
@@ -24,28 +60,52 @@ export const refundPaymentWorkflow = createWorkflow(
|
||||
amount?: BigNumberInput
|
||||
}>
|
||||
) => {
|
||||
const payment = refundPaymentStep(input)
|
||||
const payment = useRemoteQueryStep({
|
||||
entry_point: "payment",
|
||||
fields: [
|
||||
"id",
|
||||
"payment_collection_id",
|
||||
"currency_code",
|
||||
"amount",
|
||||
"raw_amount",
|
||||
],
|
||||
variables: { id: input.payment_id },
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const orderPayment = useRemoteQueryStep({
|
||||
const orderPaymentCollection = useRemoteQueryStep({
|
||||
entry_point: "order_payment_collection",
|
||||
fields: ["order.id"],
|
||||
variables: { payment_collection_id: payment.payment_collection_id },
|
||||
list: false,
|
||||
})
|
||||
throw_if_key_not_found: true,
|
||||
}).config({ name: "order-payment-collection" })
|
||||
|
||||
when({ orderPayment }, ({ orderPayment }) => {
|
||||
return !!orderPayment?.order?.id
|
||||
const order = useRemoteQueryStep({
|
||||
entry_point: "order",
|
||||
fields: ["id", "summary", "currency_code", "region_id"],
|
||||
variables: { id: orderPaymentCollection.order.id },
|
||||
throw_if_key_not_found: true,
|
||||
list: false,
|
||||
}).config({ name: "order" })
|
||||
|
||||
validateRefundStep({ order, payment, amount: input.amount })
|
||||
refundPaymentStep(input)
|
||||
|
||||
when({ orderPaymentCollection }, ({ orderPaymentCollection }) => {
|
||||
return !!orderPaymentCollection?.order?.id
|
||||
}).then(() => {
|
||||
const orderTransactionData = transform(
|
||||
{ input, payment, orderPayment },
|
||||
({ input, payment, orderPayment }) => {
|
||||
{ input, payment, orderPaymentCollection },
|
||||
({ input, payment, orderPaymentCollection }) => {
|
||||
return {
|
||||
order_id: orderPayment.order.id,
|
||||
order_id: orderPaymentCollection.order.id,
|
||||
amount: MathBN.mult(
|
||||
input.amount ?? payment.raw_amount ?? payment.amount,
|
||||
-1
|
||||
),
|
||||
currency_code: payment.currency_code,
|
||||
currency_code: payment.currency_code ?? order.currency_code,
|
||||
reference_id: payment.id,
|
||||
reference: "refund",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user