Refunds
Card charges can be refunded in full or in steps, up to the amount charged. PIX charges cannot be refunded through the API.
Create a refund
POST /wallet/card/refund
curl -X POST https://dominipay.com/api/wallet/card/refund \
-H "Content-Type: application/json" \
-H "Idempotency-Key: refund-order-1042-1" \
-d '{
"token": "YOUR_TOKEN",
"secret": "YOUR_SECRET",
"idTransaction": "3f2b8c1e-7a4d-4e3b-9c2a-1d5e6f7a8b9c",
"amount": 12.79
}'| Field | Required | Description |
|---|---|---|
idTransaction | Yes | The card charge id. |
amount | No | USD. Omit to refund everything still refundable. |
reason | No | Free text, up to 255 characters. Accepted but not forwarded to the processor. |
idempotency_key | No | Same as the Idempotency-Key header. |
Rules:
- Only charges in
paidorpartially_refundedstate can be refunded. - Sandbox credentials only find sandbox charges, and live credentials only find live charges.
- Accounts limited to refunds (
REFUND_ONLY) can still use this endpoint and the refund status endpoint.
Response (200)
{
"status": "ok",
"idTransaction": "3f2b8c1e-7a4d-4e3b-9c2a-1d5e6f7a8b9c",
"refund_id": "re_3TestExample0000000001",
"refund_status": "succeeded",
"refunded_amount": 12.79,
"total_refunded": 12.79,
"remaining_refundable": 87.21,
"currency": "USD",
"transaction_status": "partially_refunded",
"arn": null,
"arn_status": "pending"
}| Field | Meaning |
|---|---|
refund_id | Store it to check the refund later. |
refund_status | State right now: pending, requires_action, succeeded, failed or canceled. pending is not final. |
refunded_amount | Amount refunded by this call. |
total_refunded | Total refunded on the charge so far. |
remaining_refundable | What can still be refunded. Zero means fully refunded. |
transaction_status | refunded or partially_refunded. |
arn | Acquirer Reference Number, the number the cardholder bank uses to find the refund. Often null at first. |
Idempotency
A refund cannot be undone, so a duplicated refund is real money lost. Send an Idempotency-Key per refund you intend to make.
Without a key, the API derives one from the transaction and the amount (or full when amount is omitted). That makes an identical retry safe, but it also means two separate partial refunds of the same amount on the same charge within 24 hours collapse into one. Use your own key if you refund the same amount more than once.
Balance
Your USD balance is debited when the processor reports the refund on the charge (the same moment the refunded or partially_refunded callback is sent), not when this call returns. If a refund later ends as failed or canceled, contact support so the balance can be reconciled.
Track a refund
A refund can return pending and settle later. Two ways to follow it:
Poll: GET /wallet/card/refund/{refundId} with credentials in the token and secret headers.
curl https://dominipay.com/api/wallet/card/refund/re_3TestExample0000000001 \
-H "token: YOUR_TOKEN" \
-H "secret: YOUR_SECRET"{
"status": "ok",
"refund_id": "re_3TestExample0000000001",
"refund_status": "succeeded",
"idTransaction": "3f2b8c1e-7a4d-4e3b-9c2a-1d5e6f7a8b9c",
"amount": 12.79,
"currency": "USD",
"created_at": "2026-10-01T14:03:11+00:00",
"failure_reason": null,
"arn": "74987500000000000000000",
"arn_status": "available"
}refund_status | Meaning |
|---|---|
pending | Waiting on the bank. Not final. |
succeeded | Settled. The money is on its way to the cardholder. |
failed | The bank rejected it. failure_reason has the reason. The money stays with you. |
canceled | Cancelled before settling. |
requires_action | Extra steps needed. Contact support. |
Callbacks: you receive two kinds at your postback:
- Charge level,
typeTransaction: CARD,status: refundedorpartially_refunded, withrefund_amount,total_refundedandnet_amount. - Refund level,
typeTransaction: CARD_REFUND, whenever an individual refund changes state:
{
"status": "succeeded",
"idTransaction": "3f2b8c1e-7a4d-4e3b-9c2a-1d5e6f7a8b9c",
"typeTransaction": "CARD_REFUND",
"refund_id": "re_3TestExample0000000001",
"refund_status": "succeeded",
"amount": 12.79,
"currency": "USD",
"failure_reason": null,
"arn": "74987500000000000000000"
}On CARD_REFUND, status is the refund state, not the charge state. Always branch on typeTransaction first.
Errors
| HTTP | error_code | When |
|---|---|---|
| 404 | TRANSACTION_NOT_FOUND | No charge with that id under your credentials and environment. |
| 422 | NOT_REFUNDABLE | The charge is not paid or partially_refunded. |
| 422 | ALREADY_REFUNDED | Nothing left to refund. |
| 422 | AMOUNT_EXCEEDS_REFUNDABLE | amount is larger than what is left. The body includes remaining_refundable. |
| 422 | REFUND_FAILED | The processor rejected the refund. message has the reason. |
| 404 | REFUND_NOT_FOUND | Status endpoint: malformed id, unknown refund, or a refund of another account or environment. |
Updated about 2 hours ago
