Skip to main content

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.

Full refund — request body
{}

Odus will refund the remaining unreversed amount (amountCaptured - amountReversed) to the customer.

From the Dashboard

  1. Open the payment details page.
  2. Click Refund.
  3. 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).

Partial refund — request body
{
"amount": 500
}

You can issue multiple partial refunds against the same payment. The total refunded amount cannot exceed amountCaptured.

From the Dashboard

  1. Open the payment details page.
  2. Click Refund.
  3. 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).

Void — request body
{}
warning

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.

External refund — request body
{
"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 amount must not exceed amountCaptured - amountReversed. Attempting to refund more than the remaining capturable amount will return a 400 error.
  • A void is only possible when isCaptured is false. Sending a reverse request on a captured payment always triggers a refund.
  • isExternal: true can be combined with a partial amount. It follows the same amount constraints as a regular refund.