Skip to content
Open
6 changes: 6 additions & 0 deletions .changeset/grumpy-moles-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@medusajs/core-flows": patch
"@medusajs/payment": patch
---

Fix rounding issue on refund creation
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BigNumberInput, PaymentDTO } from "@medusajs/framework/types"
import {
BigNumber,
defaultCurrencies,
getEpsilonFromDecimalPrecision,
MathBN,
MedusaError,
PaymentEvents,
Expand Down Expand Up @@ -78,7 +80,17 @@ export const validateRefundPaymentExceedsCapturedAmountStep = createStep(

const totalRefundedAmount = MathBN.add(refundedAmount, refundAmount)

if (MathBN.lt(capturedAmount, totalRefundedAmount)) {
const upperCurCode = payment.currency_code?.toUpperCase() as string
const currencyEpsilon = getEpsilonFromDecimalPrecision(
defaultCurrencies[upperCurCode]?.decimal_digits
)

if (
MathBN.gte(
MathBN.sub(totalRefundedAmount, capturedAmount),
currencyEpsilon
)
Comment on lines +89 to +92
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @pepijn-vanvlaanderen,
even though this is correct, would you mind invert the check to make it easier to read?

MathBN.lt( MathBN.sub(captured, refund), epsilon )

) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`You are not allowed to refund more than the captured amount`
Expand Down
15 changes: 14 additions & 1 deletion packages/modules/payment/src/services/payment-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ import {
} from "@medusajs/framework/types"
import {
BigNumber,
defaultCurrencies,
EmitEvents,
getEpsilonFromDecimalPrecision,
InjectManager,
InjectTransactionManager,
isPresent,
Expand Down Expand Up @@ -827,6 +829,7 @@ export default class PaymentModuleService
{
select: [
"id",
"currency_code",
"data",
"provider_id",
"payment_collection_id",
Expand Down Expand Up @@ -878,7 +881,17 @@ export default class PaymentModuleService

const totalRefundedAmount = MathBN.add(refundedAmount, data.amount)

if (MathBN.lt(capturedAmount, totalRefundedAmount)) {
const upperCurCode = payment.currency_code?.toUpperCase() as string
const currencyEpsilon = getEpsilonFromDecimalPrecision(
defaultCurrencies[upperCurCode]?.decimal_digits
)

if (
MathBN.gte(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

MathBN.sub(totalRefundedAmount, capturedAmount),
currencyEpsilon
)
) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`You cannot refund more than what is captured on the payment.`
Expand Down
Loading