Available in🇮🇳 India
Refunds are always issued against an existing captured payment, so you create a test payment and then refund it. The refund amount decides the outcome. Specific amounts may fail and all others succeed. Whether a refund is Normal or Instant depends on the Refund Instantly checkbox, not the amount. Everything runs on your test keys and is fully simulated. No real money moves.
1. Test Mode Coverage
2. Test Kit
You need a captured test payment to refund. Payment first, then refund: a refund always acts on an existing captured payment, so your end-to-end flow is to create and capture a test payment, then refund it.- Create a test payment on an order and capture it, see Orders and the method pages, then capture with the Capture Payment API (
POST /v1/payments/:id/capture). - Keep the payment amount greater than the refund amount. Capture more than ₹24.68 so one payment covers every case, including the ₹24.68 failure.
- Refund it with
POST /v1/payments/:id/refund(see the scenarios below).
3. Scenarios to Test Your Integration
Grouped into must-have refund flows, other common refund flows, and error scenarios. Click a Scenario ID for its details.3.1 Must-have refund scenarios
| Scenario ID | Scenario | Trigger creds | Steps to follow |
|---|---|---|---|
| RFND-01 | Create a Normal refund (success) | A captured payment, any refund amount (e.g. amount: 100), at speed: “normal” | POST /v1/payments/:id/refund with test keys, amount: 100 and speed: “normal”. Confirm it moves from pending to processed, with speed_processed: “normal”. Store the refund id against your payment or order. |
| RFND-02 | Normal refund fails (coming soon) | A captured payment above ₹24.68, amount: 2468 (₹24.68) at speed: “normal” | POST /v1/payments/:id/refund with amount: 2468 and speed: “normal”. Confirm it moves from pending to failed. Handle the refund.failed webhook and reconcile. |
3.2 Other common refund scenarios
| Scenario ID | Scenario | Trigger creds | Steps to follow |
|---|---|---|---|
| RFND-03 | Create an Instant refund (success) (coming soon) | A captured payment, any refund amount (e.g. amount: 100), at speed: “optimum” | POST /v1/payments/:id/refund with amount: 100 and speed: “optimum”. Confirm speed_requested: “optimum”, speed_processed: “instant”, and it moves from pending to processed. The per-refund fee is deducted from your test balance. |
| RFND-04 | Instant refund falls back to Normal | A captured payment above ₹14.68, amount: 1468 (₹14.68) at speed: “optimum” | POST /v1/payments/:id/refund with amount: 1468 and speed: “optimum”. Confirm it moves from pending to processed with speed_requested: “optimum” and speed_processed: “normal”. The instant fee is credited back to your test balance. |
Seeing the pending stateWhether you see the
pending refund state depends on your account. It is enabled by default for merchants onboarded on or after 28 April 2026, and for some onboarded earlier. If it isn’t enabled for your account, a refund appears directly as processed (or failed), without a visible pending state.3.3 Refund error scenarios
Trigger each with a bad request and read the error object to handle it.4. Scenario Details
RFND-01: Create a Normal refund (success) Before you start: a captured test payment and your test API keys. How to test:POST /v1/payments/:id/refund with amount: 100 and speed: "normal".
Expected result: HTTP 200 with a refund ID (rfnd_…); it moves from pending to processed, with speed_processed: "normal".
Webhooks: refund.created, then refund.processed.
Your integration should: mark the refund successful on the processed state or the refund.processed webhook, and store the refund ID.
RFND-02: Normal refund fails
Before you start: a captured test payment greater than ₹24.68.
How to test: POST /v1/payments/:id/refund with amount: 2468 (₹24.68) and speed: "normal".
Expected result: the refund moves from pending to failed.
Webhooks: refund.created, then refund.failed.
Your integration should: handle the failed state / refund.failed webhook, and retry or reconcile.
RFND-03: Create an Instant refund (success)
Before you start: a captured test payment, with Instant Refunds enabled on your test account.
How to test: POST /v1/payments/:id/refund with amount: 100 and speed: "optimum".
Expected result: speed_requested: "optimum", speed_processed: "instant"; it moves from pending to processed. The per-refund fee is deducted from your test balance.
Webhooks: refund.created, then refund.processed.
Your integration should: read speed_processed = instant and account for the instant-refund fee.
RFND-04: Instant refund falls back to Normal
Before you start: a captured test payment greater than ₹14.68.
How to test: POST /v1/payments/:id/refund with amount: 1468 (₹14.68) and speed: "optimum".
Expected result: the instant refund cannot be processed instantly, so it falls back to normal speed. It moves from pending to processed with speed_requested: "optimum" and speed_processed: "normal"; the instant fee is credited back.
Webhooks: refund.created, refund.speed_changed, then refund.processed.
Your integration should: not assume instant always succeeds. Listen for refund.speed_changed, read speed_processed, and show the normal 5-7 working day timeline.