Skip to main content
Use refunds to return funds for payments that have reached P_SETTLED. Refund requests are idempotent and must reference the original payment token.
Create refunds only after the payment reaches P_SETTLED.

Create a refund

curl --request POST "{{base_url}}/v1/aggregators/{{aggregator_id}}/refunds" \
  --header "X-SFPY-AGGREGATOR-SECRET-KEY: {{secret_key}}" \
  --header "Content-Type: application/json" \
  --data '{
    "request_id": "{{request_id}}",
    "payment_id": "{{payment_token}}",
    "amount": 500,
    "reason": "DuplicatePayment",
    "addtl_info": "Duplicate charge on invoice INV-1024",
    "debitor_iban": "PK12ALFH0031001006540005"
  }'

Body fields

FieldTypeRequired?Notes
request_idstringYesUUID to guarantee idempotency.
payment_idstringYesToken from the original payment response.
amountintegerYesAmount in paisa; cannot exceed the settled payment amount.
reasonstringYesOne of TechnicalProblem or DuplicatePayment.
debitor_ibanstringYesIBAN that received the original payment.
addtl_infostringOptionalFree-form text for audit logs.

Statuses

Refunds are asynchronous. The API returns a status field; list filters include R_INITIATED, R_COMPLETED, R_FAILED, and R_CANCELED.

Webhook events to expect

  • refund.created
  • refund.completed
  • refund.failed
  • refund.canceled

Key endpoints

EndpointPurpose
POST /v1/aggregators/{{aggregator_id}}/refundsCreate a refund.
GET /v1/aggregators/{{aggregator_id}}/refundsList refunds with filters and pagination.
GET /v1/aggregators/{{aggregator_id}}/refunds/{{refund_id}}Read a single refund.

See also