Accept payments

Refund a payment

Issue a full or partial refund through the provider that processed the payment.

Markdown

Create the refund

Use a server key with refunds:write. Omit amount for the remaining refundable balance, or supply an integer in minor units for a partial refund. Persist a distinct idempotency key for the refund operation. Provider support and payment state determine whether the refund can be made.

curl https://api.veyqo.org/api/v1/payments/pay_example/refunds \
  -H "Authorization: Bearer $VEYQO_SECRET_KEY" \
  -H "Idempotency-Key: $REFUND_ATTEMPT_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 25000, "reason": "requested_by_customer" }'

Track the result

Save the returned refund ID and inspect its status. Retrieve it with GET /refunds/{id} using refunds:read. Do not tell the customer a refund is complete until its status confirms completion.

Refund response and constraints

A successful create response is HTTP 201. The returned refund may still be pending; track it with GET /refunds/{id} and refund events. Only succeeded, partially_refunded payments with a positive remaining amount can be refunded, and the provider must support refunds.

Omit amount for the remaining balance. Do not send null; send a positive integer for a partial refund. A fully refunded payment returns PAYMENT_ALREADY_REFUNDED; an excessive or invalid amount is VALIDATION_FAILED.

A refund remains tied to the provider account that took the original payment, even after the project switches or disconnects its current assignment. Keep that original external account and credentials valid until reconciliation is complete.

{
  "success": true,
  "data": {
    "id": "ref_01M6EB66SC61Q3RQYAN0693DGM",
    "object": "refund",
    "payment": "pay_01M6EB66SC61Q3RQYAN0693DGM",
    "amount": 25000,
    "currency": "NGN",
    "status": "pending",
    "reason": "requested_by_customer",
    "failure_message": null,
    "created_at": "2026-11-02T12:00:00+00:00"
  }
}