API
Refunds API
Refund a captured payment. The refund uses the currency of the original payment. There is no currency field on this request.
Refund
POST /merchant/refund-payment
X-API-KEY: <secret key>
Content-Type: application/json
{
"track_id": "11111111-2222-3333-4444-555555555555",
"amount": 1.5
}
| Field | Type | Required | Notes |
|---|---|---|---|
track_id | string | Yes | VenPays track id returned when the payment was created. Not the acquirer transaction id. |
amount | number | No | Amount to refund, in the original payment currency. |
There is no currency field. A payment taken in USD is refunded in USD. A payment taken in BHD is refunded in BHD. Send amount in that same currency.
If you omit amount, VenPays refunds the original payment amount. That succeeds only when nothing has been refunded yet. If part of the payment was already refunded, omit amount and the call is rejected. Send refundable_balance from the balance call instead.
The payment must belong to the same profile as the API key. Use a secret key. A publishable key is rejected.
Confirmed refund
HTTP 200
{
"success": true,
"refund_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}
success: true means the provider confirmed the refund. Check POST /merchant/payment-status for the same track_id:
| Payment status after a confirmed refund | Meaning |
|---|---|
refunded | The full original amount has been refunded |
partial_refund | A portion has been refunded. refundable_balance is what you can still refund |
refund_id identifies this refund attempt. There is no separate refund-status endpoint. Use payment status and the balance call.
Provider did not confirm
HTTP 200
{
"success": false,
"refund_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}
success: false means the provider did not confirm the refund. The payment status is left unchanged. A following payment-status call still shows success or partial_refund, not refunded.
Do not treat that 200 as a completed refund. Read refundable_balance and the payment status before you try again. If the status is already refunded, the money was refunded on an earlier confirmed call.
Request errors
These are HTTP errors. The body is { "detail": "<message>" }.
| HTTP | detail | What to check |
|---|---|---|
400 | Transaction not found | track_id is not a payment for this API key. An acquirer transaction id will not match. |
400 | Transaction not refundable | Payment status is not success or partial_refund. Includes a payment that is already refunded, still in progress, or failed. |
400 | Refund amount exceeds transaction amount | amount is larger than the original payment. |
400 | Refund would exceed original transaction amount. Already refunded: … | This amount plus earlier refunds is more than the original payment. The message includes the amount already refunded and the max still allowed. |
400 | Invalid payment provider | This payment method cannot be refunded. benefit_web_checkout returns this. |
401 | X-API-KEY header is required or Invalid API key | Send a secret key for the profile that created the payment. |
403 | Publishable keys cannot call this endpoint | Do not use a pk_ key. |
500 | Internal server error, track_id: … | The refund did not finish. Check payment status before retrying. |
Refundable balance
POST /merchant/get-refundable-balance
X-API-KEY: <secret key>
Content-Type: application/json
{ "track_id": "11111111-2222-3333-4444-555555555555" }
Response
HTTP 200
{
"track_id": "11111111-2222-3333-4444-555555555555",
"total_amount": 10.0,
"total_refunded": 1.5,
"refundable_balance": 8.5,
"currency": "USD",
"status": "partial_refund"
}
currency is the original payment currency. Refund amount must be in that currency. status is the same payment status as POST /merchant/payment-status.
The same 400 Transaction not found and not-refundable errors apply when the payment cannot be refunded.
How to diagnose a refund
- Call
POST /merchant/payment-statuswith the VenPaystrack_id. - Call
POST /merchant/get-refundable-balanceand readcurrency,refundable_balance, andstatus. - If the refund response was
success: true, expectrefundedorpartial_refund. - If the refund response was
success: false, expect the previous status to be unchanged. Comparecurrencywith the currency you charged. The refund is sent in that currency, not in a currency you choose on the refund call. - If the response was
400, use thedetailstring in the table above. Do not retry arefundedpayment.