> ## Documentation Index
> Fetch the complete documentation index at: https://razorpay.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment States and Late Authorisation

> Keep orders open after payment.failed and accept a later success, with the scenarios, gaps and failures to test.

Available in
🇮🇳 India

Keep the order open after `payment.failed` and accept a later success on it. A payment with no bank response is marked `failed` after about 10 minutes, but Razorpay keeps polling the bank for up to 3 days — it can turn `authorized` later. Capture manually only inside your capture window; an `authorized` payment you do not capture in time is auto-refunded.

**Best way to integrate:**

* Create one order per purchase and store its `order_id` against your cart. Retry payments on the same order.
* Drive fulfilment from the order: fulfil when it is `paid`, on `order.paid` or `payment.captured`.
* Keep the order open after `payment.failed`, so the customer can retry and a late authorisation is caught.
* Move states forward only; accept `failed` → `authorized`.
* Set capture to match how you fulfil: auto-capture for most businesses; manual only if you check stock or risk first.
* Reconcile any order still `created` or `attempted` after 15 minutes.
* Disable the pay button once an order is `paid`.

| Behaviour | Live mode | Test mode |
| - | - | - |
| Late authorisation | Under 0.5% of payments; up to 3 days after a timeout | Not simulated: replay the events |
| Manual capture | Available | Coming soon (cards) |
| Capture failure (merchant balance) | Rare | Live only |
| Second payment on a paid order | Refused or auto-refunded | Same |

## Scenarios to test your integration

| Scenario ID | Order ends | Scenario | Trigger | Steps to follow | Test mode |
| - | - | - | - | - | - |
| BP-24 | `paid` | Customer pays first time | Any success trigger | Pay once. Confirm order `paid`, one captured payment; fulfil on `order.paid`/`payment.captured`. | Available |
| BP-25 | `paid` | First attempt fails, retry succeeds | A failure trigger, then a success trigger | Fail one attempt, then pay. Confirm order `paid` with one failed and one captured payment; fulfil once. See ORD-03. | Available |
| BP-06 | `attempted` → `paid` | Late authorisation, auto-capture on | Replay `payment.failed`, then `payment.authorized` (`late_authorized: true`), `payment.captured`, `order.paid` | Replay the sequence to your endpoint. Confirm the order stays open after `payment.failed` and is fulfilled on `order.paid`. | Available (replay); live only (real) |
| BP-30 | `paid` | Customer closes the browser before the callback | Any success trigger | Same as BP-01: the webhook (or a fetch) still drives fulfilment. | Available |
| BP-31 | Any | Webhook delayed or missed | Unsubscribe from the event | Same as BP-05: fetch `GET /v1/orders/:id/payments` after 15 minutes and act on the result. | Available |
| BP-27 | `attempted` | Attempt fails, customer leaves | A failure trigger | Fail one attempt and stop. Confirm the order stays `attempted` and open, and the reconciler checks it later. | Available |
| BP-14 | `attempted` | Authorised, not captured (manual capture) | Auto-capture off + a success trigger | Confirm order `attempted`, one authorized payment. Capture inside your window (`POST /v1/payments/:id/capture`), or confirm it is auto-refunded. | Coming soon (cards) |
| BP-09 | `paid` | Second payment on an already paid order | A paid order + another payment | Pay a paid order again. Confirm you fulfil once, the extra is refused or auto-refunded, and the pay button is disabled. See ORD-07. | Available |
| BP-26 | `created` | Customer never starts paying | Create an order and stop | Confirm the order stays `created` with no payments. Confirm you expire it on your side after your own timeout. | Available |
| BP-28 | `attempted` | Late authorisation after your capture window | — | Confirm nothing is fulfilled; the payment is refunded automatically. Check in live mode. | Live only |
| BP-29 | `attempted` | Capture fails (for example insufficient merchant balance) | — | Confirm the order stays `attempted` with one authorized payment; Razorpay retries, then auto-refunds after 3 days. Check in live mode. | Live only |

## Scenario details

**BP-06 — Late authorisation, auto-capture on**

*Before you start:* stored events, or hand-written ones that match the live payloads.

*How to test:* send `payment.failed` for a payment on an open order. Send `payment.authorized` for the same payment with `late_authorized: true`. Send `payment.captured` and `order.paid`.

*Expected result:* the order stays open after `payment.failed` and is fulfilled once on `order.paid`.

*Your integration should:* never close the order on `payment.failed`.

*Live mode differs:* real late authorisations cannot be simulated.

> [!WARNING]
>
> **Watch Out!**
>
> Late authorisation depends on delayed bank polling and is **not simulated in Test Mode**. Verify it in a controlled live test. Listen for `payment.authorized` for 3 days, then capture and fulfil or let it auto-refund.

## Webhooks: What Fires, and What It Lets You Decide

Every scenario above delivers a specific set of events, in a specific order. This table is the one place that says which, and — the part that actually matters — what each one entitles you to do. Most integration bugs that reach production are not missing webhooks; they are acting on the wrong one.

| Scenario | What it is | Events, in order | What it lets you decide |
| - | - | - | - |
| BP-24 | Customer pays first time | `order.paid`, `payment.captured` | The order is settled and will not accept another payment. Close the cart and stop any retry loop. Money is yours — this is the event to fulfil on. |
| BP-06 | Late authorisation, auto-capture on | `payment.failed`, `order.paid` | This attempt is over. The error reason tells you whether to offer the same method again or move the customer to another one. The order is settled and will not accept another payment — close the cart and stop any retry loop. |

**Before you trust any of them**

* Verify the signature on every event. Replay one event to your endpoint and send one with a changed body. The replay must be ignored and the tampered event rejected. An endpoint that skips this is an open write to your order state.
* Expect duplicates. The same event can arrive more than once. Key your handler on the event ID and make it idempotent.
* Order is not guaranteed across events. Do not assume `payment.captured` lands before `order.paid`; handle whichever arrives first.
* Webhook first, callback second. The browser callback can be lost, blocked or forged. Fulfil on the webhook.

## Common integration gaps to avoid

| Gap | What goes wrong in production | What to do | Test with |
| - | - | - | - |
| Closing the order on `payment.failed` | A late-authorised payment lands on a closed order, and the customer cannot retry. | Keep the order open. | BP-06, BP-27 |
| Letting customers pay a paid order again | The extra payment is refunded and the customer complains. | Disable the pay button and check the order status. | BP-09 |
| Fulfilling on `authorized` | You ship and the payment is never captured. | Fulfil only when the order is `paid`. | BP-14 |

## Simulate failures

**Available in test mode**

| Failure | How to simulate | Expected handling | Scenario |
| - | - | - | - |
| Late authorisation | Replay the event sequence | Fulfil on `order.paid` | BP-06 |
| Second payment on a paid order | Pay a paid order again | Fulfil once | BP-09 |

**Not available in test mode**

| Failure | Why not | How to cover it |
| - | - | - |
| Real late authorisation | Depends on the bank | Replay (BP-06); check in live |
| Late authorisation after the capture window | Depends on the bank | Check in live (BP-28) |
| Capture failure (merchant balance) | Depends on your balance | Check in live (BP-29) |

### Related Information

* [Best Practices](https://razorpay.com/docs/payments/payment-gateway/s2s-integration/test-s2s/best-practices)
* [Error Handling](https://razorpay.com/docs/payments/payment-gateway/s2s-integration/test-s2s/best-practices/error-handling.md)
* [Orders](https://razorpay.com/docs/payments/payment-gateway/s2s-integration/test-s2s/orders.md)
