ShiftxPay
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-key

The body is optional:

FieldTypeDescription
amountint64Amount to refund in minor units. Omit, send 0, or send an empty body to refund the full remaining balance.
reasonstringOptional 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 amount less 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"
}
FieldDescription
payment_idThe refunded payment's public id.
refundedThe amount booked by this call, in minor units (may be less than requested if a webhook already booked part of it).
statusThe payment's new status: partially_refunded or refunded.
connector_refThe PSP's refund reference, for reconciliation.
refund_statusThe PSP's normalized refund status, e.g. succeeded.

Errors

HTTPCodeWhen
409not_refundableThe 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.
409already_refundedThe payment is already fully refunded.
422amount_too_largeamount exceeds the remaining refundable balance.
403feature_disabledRefunds are disabled by the platform kill switch.
404not_foundNo 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.

On this page