Skip to main content
Available in🇮🇳 India
Use Test Mode to check your card recurring integration before you go live. Test Mode simulates the card network, mandate hub and bank responses, so you can register mandates, run subsequent debits and handle failures without moving real money. This page covers S2S integrations. See UPI Autopay Intent for the UPI equivalent. Start with the overview for test keys and webhook setup.
Before you startEvery scenario on this page needs an order. Order behaviour has scenarios of its own, all on Orders. The ones that matter for this method: ORD-20 mandate order, ORD-21 mandate order errors, ORD-22 a new order per subsequent debit, ORD-04 signature, ORD-05 idempotent create, ORD-06 fetch. Request errors (ORD-08 to ORD-15) are the same for every method; run them once.

1. Test Mode Coverage

How live mode and test mode differ

What you can test

Endpoint coverage in test mode

Webhooks: what fires, and what it lets you decide

Test Mode webhooks have the same shape as live mode ones and are delivered to the URL set in your Test Mode Dashboard. Which webhooks each scenario fires Before you rely on webhooks
  • 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.

Token states

Charge a token only while it is confirmed.

2. Before You Begin

  • Use your test keys (rzp_test_...). The APIs and requests are the same as in live mode; only the keys change.
  • Configure a webhook URL in your Test Mode Dashboard to receive test events.
  • Test Mode has a mock bank page with Success and Failure buttons. No real money is deducted.
  • In Test Mode, the card number decides the scenario. To use a test card:
    • Create the authorisation payment and pass the card for your scenario in card.number. Use any CVV and any future expiry date.
    • Redirect the customer to the authentication URL returned in the response. A mock bank page is displayed.
    • Choose Success to register the mandate, or Failure for a registration failure card.
  • For subsequent debits, register with the same card number first, then charge the token. The subsequent debit reaches its final state about 5 minutes later.
Registration and subsequent-debit cards

3. Scenarios to Test Your Integration

This section lists the scenarios worth running against your card recurring integration before you go live. They are grouped by what each one proves, so that you can work down the page in order and cover the integration end to end. Must-have. Run these first. They cover registration, the subsequent debit and the outcomes you are almost certain to meet once you are live, including a failed registration and a failed subsequent debit. Other common scenarios. These come up in normal running: Native OTP and bank redirect, eligibility checks, a token rejected after registration, cards that can’t be used for recurring, AFA, token checks and token management. Error scenarios. Failures you bring on deliberately with a test card, so that you can check your error handling without waiting for a real failure. Each row uses one test card. Not available in test mode yet. These are real scenarios your integration has to handle, but they can’t be reproduced in Test Mode today.

3.1 Must-have

#ScenarioTrigger credsSteps to follow
1Register a mandate4100 2800 0000 1007 (Visa), 5305 6200 0006 0000 (Mastercard) or 6527 6589 0000 1005 (RuPay) + SuccessCreate a customer (POST /v1/customers) and store the returned customer_id. Create an order (POST /v1/orders) with method: "card", the customer_id and a token object (max_amount, expire_at, frequency). Create the authorisation payment (POST /v1/payments/create/json, recurring: true) with the trigger card in card.number, any CVV and any future expiry date. Redirect to the authentication URL in the response, and choose Success on the mock bank page. Webhooks received: payment.authorized, payment.captured, order.paid, token.confirmed. Status changes: the payment moves to captured and the token to confirmed. Store the token_id; you need it for every subsequent debit.
2Registration fails: insufficient funds4100 2800 0008 0001 + FailureCreate a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Failure on the mock bank page. Confirm payment.failed with insufficient_funds. The mandate is not registered. Let the customer retry the registration, for example with another card.
3Subsequent debit succeedsSame card as #1Register a mandate (#1). Create a new order (POST /v1/orders) for the subsequent debit, then charge the token (POST /v1/payments/create/recurring), or charge it from the Dashboard. Wait about 5 minutes (poll with a timeout). Confirm payment.captured and order.paid.
4Subsequent debit fails: insufficient funds4718 6000 0007 0021Register a mandate with the trigger card, choosing Success (#1). Create a new order for the subsequent debit, then charge the token, or charge it from the Dashboard. Confirm payment.failed with insufficient_funds. Token stays active.
5Mandate cancelled before the subsequent debit4718 6091 2000 0016Register a mandate with the trigger card, choosing Success (#1). Create a new order for the subsequent debit, then charge the token. Confirm card_mandate_not_active. Confirm you stop scheduling subsequent debits on this token.
6Mandate paused before the subsequent debit4718 6091 2007 0019Register a mandate with the trigger card, choosing Success (#1). Create a new order for the subsequent debit, then charge the token. Confirm card_mandate_paused. Confirm you stop scheduling subsequent debits on this token.

3.2 Other common scenarios

#ScenarioTrigger credsSteps to follow
7Register with a card that supports Native OTP5305 6200 0006 0000Create a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. The customer enters the OTP on the Razorpay page. Confirm the mandate registration succeeds and token.confirmed is sent.
8Register with a card that doesn’t support Native OTP4100 2800 0000 1007Create a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. The customer is redirected to the mock bank page; choose Success. Confirm the mandate registration succeeds and token.confirmed is sent.
9Check recurring eligibility with the IIN APIGET /v1/iins/:iin (on-demand)Call the IIN API with the card’s IIN before you create the registration payment. The IIN API is an on-demand feature; ask Support to enable it on your account. Confirm you block registration when recurring.available is false.
10Registration payment succeeds, token rejected later4100 2800 0005 0012 + SuccessCreate a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Success on the mock bank page. Confirm payment.captured, then token.rejected. The token is rejected at the mandate hub because the card BIN isn’t supported. Confirm you don’t schedule subsequent debits. Treat the mandate as live only after token.confirmed.
11Card not eligible for recurring4100 2800 0006 0011 + FailureCreate a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Failure on the mock bank page. Confirm payment.failed with card_mandate_card_not_supported. Ask the customer to use a different card.
12Card BIN not supported for recurring6527 6500 0007 0022 + FailureCreate a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Failure on the mock bank page. Confirm payment.failed with card_mandate_bin_not_supported. Ask the customer to use a different card.
13Customer doesn’t approve AFA4718 6091 2009 0017Register a mandate with the trigger card, choosing Success (#1). Create a new order for the subsequent debit, then charge the token. Confirm customer_action_required and your customer prompt.
14Subsequent debit on a token that isn’t confirmed4718 6091 2002 0014Register a mandate with the trigger card, choosing Success (#1). Create a new order for the subsequent debit, then charge the token. Confirm the create payment request is rejected with token_not_eligible and no payment is created. Read the error from the API response; no payment webhook is sent.
15Subsequent debit on an expired token4718 6091 2008 0018Register a mandate with the trigger card, choosing Success (#1). Create a new order for the subsequent debit, then charge the token. Confirm the payment is created and then fails with token_expired.
16Fetch and delete tokensA token from scenario 1Fetch the token created by the registration payment: GET /v1/payments/:id (the response contains token_id). Fetch all tokens for the customer: GET /v1/customers/:id/tokens. Delete the token: DELETE /v1/customers/:customer_id/tokens/:token_id. Confirm the status changes to cancelled and token.cancelled is sent. The token is not removed from Razorpay.

3.3 Error scenarios

Registration These happen while the customer is registering the mandate. The registration payment fails, so the mandate is not registered and you can’t create subsequent debits. The customer has to start the registration again.
#ScenarioTrigger credsError objectSteps to follow
17Customer cancels the payment4100 2800 0007 0002 + Failurecode BAD_REQUEST_ERROR
source customer
step payment_authentication
reason payment_cancelled
Create a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Failure on the mock bank page. Confirm payment.failed and the error object. Let the customer retry the registration.
18Payment times out4100 2800 0009 0000 + Failurecode BAD_REQUEST_ERROR
source customer
step payment_authentication
reason payment_timed_out
Create a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Failure on the mock bank page. Confirm payment.failed and the error object. Let the customer retry the registration.
19Incorrect OTP or verification details4100 2800 0000 0009 + Failurecode GATEWAY_ERROR
source customer
step payment_authentication
reason authentication_failed
Create a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Failure on the mock bank page. Confirm payment.failed and the error object. Let the customer retry the registration.
20Card not enabled for online payments4100 2800 0004 0013 + Failurecode GATEWAY_ERROR
source customer
step card_enrollment_check
reason card_not_enrolled
Create a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Failure on the mock bank page. Confirm payment.failed and the error object. Let the customer retry the registration.
21Declined by the issuing bank4100 2800 0005 0004 + Failurecode BAD_REQUEST_ERROR
source issuer_bank
step payment_authorization
reason card_declined
Create a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Failure on the mock bank page. Confirm payment.failed and the error object. Let the customer retry the registration.
22Card disabled for online payments4100 2800 0003 0006 + Failurecode BAD_REQUEST_ERROR
source issuer_bank
step payment_authorization
reason card_disabled_for_online_payments
Create a customer and an order as in #1. Create the authorisation payment with the trigger card, any CVV and any future expiry date. Redirect to the authentication URL, and choose Failure on the mock bank page. Confirm payment.failed and the error object. Let the customer retry the registration.
Subsequent debit These happen on a subsequent debit, after the mandate is registered.
#ScenarioTrigger credsError objectSteps to follow
23Pre-debit notification fails4718 6091 2001 0015code BAD_REQUEST_ERROR
source issuer_bank
step pre_debit_notification_verify
reason pre_debit_notification_failed
Register a mandate with the trigger card, choosing Success (#1). Create a new order for the subsequent debit, then charge the token. Confirm payment.failed with the error object about 5 minutes after you create the payment.
The full list of card recurring error reasons, including the ones no test card reproduces, is on the Error index. These are payment errors; errors from creating the order (bad amount, currency, receipt and so on) are on Orders → Simulate failures.

3.4 Not available in test mode yet

These scenarios can’t be reproduced in Test Mode today, but your integration still has to handle them. Each row gives the behaviour your code has to implement.

4. Common Integration Gaps to Avoid

These are the mistakes that most often cause failed payments, missed subsequent debits or double charges after go-live. “Test with” gives the scenario numbers in section 3 that prove you’ve handled it.

Webhook and token updates

Error handling and messaging to the payer

Fetch API when webhooks are late

5. Best Integration Practices

These apply to every Razorpay integration. “On this method” says what each one means here; “Test it” links to where it is tested once for every method. All best practices: Overview · Webhooks and Fetch APIs · Payment states and late authorisation · Error handling · Downtime handling · Security
Last modified on November 12, 2026