Refunds and Voids
Use the POST /payments/{id}/reverse endpoint to refund a captured payment or void an uncaptured authorization. The same endpoint handles both operations — Odus decides which action to perform based on the current state of the payment.
Prerequisites
- You need a Secret API Key to call the reverse endpoint.
- The payment must have
status: "succeeded"and must not be fully reversed (isFullyReversed: false).
Full refund
To refund the entire captured amount, send a POST /payments/{id}/reverse request with an empty body.
{}
Odus will refund the remaining unreversed amount (amountCaptured - amountReversed) to the customer.
From the Dashboard
- Open the payment details page.
- Click Refund.
- Enter the full amount and click Refund.
Partial refund
To refund a specific amount, include the amount field in minor currency units (for example, 500 for $5.00 USD).
{
"amount": 500
}
You can issue multiple partial refunds against the same payment. The total refunded amount cannot exceed amountCaptured.
From the Dashboard
- Open the payment details page.
- Click Refund.
- Enter the amount you want to refund and click Refund.
Voiding an uncaptured payment
A void cancels an authorization that has not yet been captured. It releases the reserved funds without charging the customer and does not incur a refund fee.
To void a payment, send POST /payments/{id}/reverse with an empty body, exactly as you would for a full refund. Odus automatically issues a void instead of a refund when the payment has not been captured (isCaptured: false).
{}
You cannot void a payment after it has been captured. Once isCaptured is true, only a refund is possible.
Recording an external refund
If you have already processed a refund directly at the gateway — outside of Odus — you can record it in Odus without sending a new refund request by setting isExternal: true.
{
"amount": 1500,
"isExternal": true
}
Odus will update the payment record and the reversal amounts, but will not contact the gateway. Omit amount to record a full external refund.
Response
The response is the full Payment object. After a reversal, check amountReversed for the total reversed amount, isReversed to confirm at least one reversal was applied, and isFullyReversed to check whether further refunds are possible. See the POST /payments/{id}/reverse reference for the full response schema.
Constraints
- The
amountmust not exceedamountCaptured - amountReversed. Attempting to refund more than the remaining capturable amount will return a400error. - A void is only possible when
isCapturedisfalse. Sending a reverse request on a captured payment always triggers a refund. isExternal: truecan be combined with a partialamount. It follows the same amount constraints as a regular refund.