refundOrder
Refund the captured payment of an order, in full or in part. refundOrder is the service behind the Refund button on the order page and the POST /api/orders/:id/refunds endpoint. It works for every payment method that registered a refund handler.
Core validates the request, calls the handler (the one step that talks to the payment provider), then hands the result to recordRefund, which saves the refund, sets the payment status and emits order_refunded.
Import
import { refundOrder } from "@evershop/evershop/oms/services";
Syntax
refundOrder(uuid: string, amount: number): Promise<RefundOrderResult>
interface RefundOrderResult {
status: string;
isFullRefund: boolean;
}
Parameters
uuid
Type: string
The order uuid (order.uuid), not the numeric order_id.
amount
Type: number
The amount to refund, in the order currency's major units (49.99, not 4999). It must be greater than zero and no more than what is still refundable: the captured amount minus the refunds already recorded. Amounts are compared in the currency's smallest unit, so rounding noise cannot slip a cent through.
Return Value
Returns Promise<RefundOrderResult>:
status— the new payment status:<payment_method>_refundedwhen the refunds reach the captured amount, otherwise<payment_method>_partial_refunded.isFullRefund—truewhen the refunds recorded so far, including this one, reach the captured amount.
Behavior
- Loads the order by uuid.
- Looks up the payment method's registered
refundhandler. - Checks that the order's payment status is flagged
isRefundable. - Finds the captured payment: the newest payment transaction that is not a refund.
- Checks the amount against what remains refundable.
- Calls the handler with
{ order, transaction, amount, currency }, wheretransactionis the capture. This call runs outside any database transaction. - Calls
recordRefundwith what the handler returned. Core uses the handler'samount, not the requested one.
Errors
refundOrder throws a plain Error. The REST endpoint returns the message in an HTTP 500 response.
| Message | Cause |
|---|---|
Order <uuid> not found | No order has this uuid. |
Order <uuid> has no payment method | The order has no payment method recorded. |
Payment method "<code>" does not support refunds | The method has no refund handler, or it is not registered. |
Order <uuid> is not refundable in its current status (<status>) | The payment status is not flagged isRefundable. |
Order <uuid> has no captured payment to refund | The order has no non-refund payment_transaction row. |
Refund amount must be greater than 0 and at most the remaining captured amount | The amount is zero, negative, not a number, or more than what is left. |
| The handler's error | Passed through unchanged, for example PayPal refund failed (status ...). |
Errors from recordRefund | See recordRefund, for example Invalid status when the method did not register its refund statuses. |
Notes
- Not idempotent per call. Each valid call makes a new refund at the provider. Only the provider's own webhook echo is deduplicated, because it carries the same refund id.
- Emits
order_refundedthroughrecordRefund.refundOrderitself is not wrapped inhookable. - If the provider's webhook reaches
recordRefundfirst, the refund is already recorded whenrefundOrdergets there.recordRefundthen reportsalreadyRecorded, andrefundOrderreturns the order's current payment status withisFullRefund: false. - The
supportsPartialRefundflag on a payment method is not checked.
Examples
import { refundOrder } from "@evershop/evershop/oms/services";
const { status, isFullRefund } = await refundOrder(order.uuid, 25.5);
// status: 'stripe_partial_refunded', isFullRefund: false
An offline method has no provider to call. Cash On Delivery's handler only reports the amount:
refund: async ({ order, amount }) => ({
transactionId: `cod-refund-${order.uuid}-${Date.now()}`,
amount,
offline: true
})
See Also
- recordRefund — Record a refund without calling a provider
- captureOrder — Capture an authorized payment
- Order API: Refund An Order — The REST endpoint
- Payment Method Development — Writing a
refundhandler