Accept payments
Refunds
Refund a payment in full or in part.
Refund a captured payment, in full or in part, with a single server-to-server
call. Refunds are booked into the double-entry ledger and issued at the PSP under
the same cumulative model as inbound payment.refunded webhooks, so the merchant-
initiated path and the webhook path converge without double-booking.
Request
POST /v1/payments/{id}/refunds
Authorization: Bearer sk_...
Content-Type: application/json
Idempotency-Key: a-unique-keyThe body is optional:
| Field | Type | Description |
|---|---|---|
amount | int64 | Amount to refund in minor units. Omit, send 0, or send an empty body to refund the full remaining balance. |
reason | string | Optional merchant-supplied reason, stored with the refund. |
- Full refund — omit
amount(or send an empty body). The gateway refunds the remaining refundable balance (amount − already refunded). - Partial refund — send
amountless than the remaining balance. You can issue multiple partial refunds until the payment is fully refunded.
Amounts are integer minor units (for example 125000 for Rs 1,250.00). Send the
Idempotency-Key header so a retried request does
not double-refund; the key is forwarded to the PSP as well.
Response
201 Created:
{
"payment_id": "pay_3Nf...",
"refunded": 125000,
"status": "refunded",
"connector_ref": "re_1Ofs...",
"refund_status": "succeeded"
}| Field | Description |
|---|---|
payment_id | The refunded payment's public id. |
refunded | The amount booked by this call, in minor units (may be less than requested if a webhook already booked part of it). |
status | The payment's new status: partially_refunded or refunded. |
connector_ref | The PSP's refund reference, for reconciliation. |
refund_status | The PSP's normalized refund status, e.g. succeeded. |
Errors
| HTTP | Code | When |
|---|---|---|
409 | not_refundable | The payment is not in a refundable state (only succeeded and partially_refunded payments can be refunded), or it has no connector reference to refund against. |
409 | already_refunded | The payment is already fully refunded. |
422 | amount_too_large | amount exceeds the remaining refundable balance. |
403 | feature_disabled | Refunds are disabled by the platform kill switch. |
404 | not_found | No such payment under your account. |
Example
# Full refund of the remaining balance.
curl -X POST https://api.lite.shiftxpay.com/v1/payments/pay_3Nf.../refunds \
-H "Authorization: Bearer sk_..." \
-H "Idempotency-Key: $(uuidgen)"
# Partial refund of Rs 500.00 with a reason.
curl -X POST https://api.lite.shiftxpay.com/v1/payments/pay_3Nf.../refunds \
-H "Authorization: Bearer sk_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "amount": 50000, "reason": "partial return" }'See the API reference for the full schema.