Skip to main content
Available in🇮🇳 India
Register mandates, run auto-debits, simulate failures and manage tokens in Test Mode, then work through the pre-launch checklist before you go live. Use Test Mode to check your UPI Autopay integration before you go live. Test Mode simulates the responses from NPCI and the customer’s bank, so you can register mandates, run auto-debits and handle failures without moving real money or using a UPI app. This page describes how to test the request and response payload across each API call, and what error scenarios to expect. UPI Autopay flows: Intent · QR · Collect Start with the overview for test keys and webhook setup.

1. Test Mode Coverage

Collect is deprecated from 28 February 2026. Exemptions: specific MCCs, iOS and mobile web, UPI mandates, eRupi vouchers and PACB businesses. For new registrations, everyone else should use Intent (mobile) or QR (desktop).

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

Every webhook UPI Autopay fires in live mode is listed below, along with whether it also fires in test mode. 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
Watch out. Note the order. prefix. The pre-debit notification events are named order.notification.delivered and order.notification.failed, not notification.delivered and notification.failed. We recommend subscribing to them and verifying them against live traffic, since neither fires in Test Mode yet.
Handy tip. A webhook can be delivered more than once. Use the event ID to make sure you process each event only once. This applies in live mode as well.

Token states

Charge a token only while it is confirmed.

2. Before you begin

  • Generate your test mode API keys from the Dashboard. Keys that start with rzp_test_ send all requests to test mode. You do not need to enable any separate flag.
  • Use the same APIs and request formats you use in live mode. Only the API keys change.
  • Pass every amount in paise, as you do in live mode. For example, send 201 for ₹2.01 and 100 for ₹1.
  • Configure a webhook URL in your test mode Dashboard to receive test events. Test mode webhooks are separate from live mode ones and do not carry over.
In test mode the amount you send decides the outcome, because there is no real bank on the other end. Send 100 (₹1) and the payment succeeds. Send one of the reserved amounts and the payment fails with the error mapped to that amount.
  • Send 100 (₹1) on both the order and the payment to succeed.
  • Send a reserved amount from 3.3 Autopay error scenarios on both calls to fail. For debits, keep it below the mandate’s max_amount.
  • No collect request reaches a UPI app, so there is nothing to approve.
  • Any amount that is not in the reserved list succeeds.
Coupled or decoupled? Both debit flows are covered below as scenarios — scenario 2 (coupled) and scenario 4 (decoupled). The flows themselves, the notification object and who owns the retries are defined in the published integration doc: Subsequent Payments. This page does not redefine them.

3. Scenarios to Test Your Integration

This section lists every scenario we think is worth running against your UPI Autopay Collect integration before you go live. They are grouped by what each one proves, rather than by how urgent they are, so that you can work down the page in order and know that you have covered the integration end to end. Must-have. We highly recommend running these scenarios first. They cover the successful path and the handful of outcomes you are almost certain to meet once you are live, so getting through them is the shortest route to an integration you can trust. Other common scenarios. These come up in normal day-to-day running and are shared across one-time UPI and UPI Autopay, so the same handling has to work on both. They are not errors as such, but your integration still needs to recognise them and respond correctly, so we recommend covering them before launch. Error scenarios. These are failures you can bring on deliberately, using a reserved trigger, so that you can check your error handling without waiting for a real failure to happen. Most rows use a single trigger, which keeps the error you get back unambiguous. Not available in test mode yet. These scenarios are real and your integration still has to handle them, but they cannot be reproduced in test mode today. We recommend reading through them and checking your handling on live traffic or in a controlled live test before you ship.

3.1 Must-build Autopay scenarios

#ScenarioTrigger credsSteps to follow
1Register a mandateamount: 100Create a customer (POST /v1/customers) and store the returned customer_id. Create an order (POST /v1/orders) with method: "upi", the customer_id and a token object, using the trigger amount. Create the authorisation payment (POST /v1/payments/create/upi, recurring: 1) with the same amount. upi.flow: "collect" and upi.vpa (any well-formed VPA). Show an “approve the mandate in your UPI app” state. Confirm token.confirmed. Store the token ID from payment.authorized. On the order and the payment.
2Subsequent debit succeedsamount: 100Register a mandate (#1). Create a debit order without the notification object, which is what places the payment on the coupled flow, and a recurring payment (POST /v1/payments/create/recurring) with the trigger amount. Confirm payment.captured and order.paid. Token stays confirmed.
3Debit fails: insufficient fundsamount: 201Register a mandate (#1). Create a debit order and a recurring payment (POST /v1/payments/create/recurring) with the trigger amount. Confirm payment.failed with insufficient_funds. Token stays active.

3.2 Common scenarios in UPI

#ScenarioTrigger credsSteps to follow
4Debit with your own pre-debit notificationamount: 100Register a mandate (#1). Create the debit order (POST /v1/orders) with the notification object, setting notification.token_id and notification.payment_after. Create the recurring payment (POST /v1/payments/create/recurring) with the same amount, passing order_id, customer_id, token and recurring: true. Confirm payment.captured.
5Fetch tokensA sample token IDTake a sample token ID from a mandate you registered earlier. GET /v1/customers/:customer_id/tokens/:token_id and GET /v1/customers/:customer_id/tokens. Confirm status, max_amount, expire_at, frequency.
6Fetch a payment and reconcile (also on one-time UPI)A payment ID from the registration in scenario 1 and one from any row in 3.3Poll GET /v1/payments/:payment_id for each payment. Confirm the status your reconciler reads matches the status the webhook carried. Confirm a payment still in created is never treated as final.
7Full and partial refund (also on one-time UPI)A captured debit payment from scenario 2Refund in full with POST /v1/payments/:payment_id/refund, and refund another captured debit in part. Webhooks received: refund.processed. Confirm the mandate is untouched. A refund does not cancel the token, and the next debit still runs.
8API validation errors (also on one-time UPI)Missing amount, amount: 0, wrong key secretSend each bad request to the order and the payment endpoints. Confirm HTTP 4xx, no payment created and no webhook. Read the API error response rather than waiting for an event, because none fires.

3.3 Autopay error scenarios

Registration These happen while the customer is setting the mandate up, so the token never reaches confirmed and no debit is possible. In each case the customer has to start the registration again.
#ScenarioTrigger credsError objectSteps to follow
9Customer cancels the mandate request — mandate_cancelled_by_user, source: internalamount: 302code BAD_REQUEST_ERROR
source internal
step payment_response
reason mandate_cancelled_by_user
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Show an “approve the mandate in your UPI app” state. Confirm payment.failed and token.rejected. Let the customer restart.
10Customer declines the mandate request — mandate_cancelled_by_user, source: customeramount: 304code GATEWAY_ERROR
source customer
step payment_authentication
reason mandate_cancelled_by_user
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Show an “approve the mandate in your UPI app” state. Confirm payment.failed and token.rejected. Let the customer restart.
11Customer never approves it and the request expires — mandate_collect_request_expiredamount: 301code GATEWAY_ERROR
source customer
step payment_authentication
reason mandate_collect_request_expired
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Show an “approve the mandate in your UPI app” state. Confirm payment.failed and token.rejected. Let the customer restart.
12Registration fails: insufficient fundsamount: 201code GATEWAY_ERROR
source remitter_bank
step payment_response
reason insufficient_funds
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Show an “approve the mandate in your UPI app” state. Confirm insufficient_funds.
13Account not allowed for Autopayamount: 203code GATEWAY_ERROR
source remitter_bank
step payment_authentication
reason account_state_forbidden
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Show an “approve the mandate in your UPI app” state. Confirm remitter_account_dormant (source: customer, step: payment_debit_request).
14Invalid UPI IDamount: 401code GATEWAY_ERROR
source customer
step payment_debit_request
reason invalid_vpa
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Show an “approve the mandate in your UPI app” state. Confirm invalid_vpa and ask the customer to re-enter their UPI ID.
15Duplicate registration request — duplicate_requestamount: 406code BAD_REQUEST_ERROR
source internal
step payment_request
reason duplicate_request
Register as above with the trigger amount, sending it on both the order and the authorisation payment. Confirm 400 Bad Request with duplicate_request (source: internal, step: payment_request) and the description “The request is duplicate”. Do not retry the same request. If the earlier payment succeeded no action is needed, otherwise start a fresh registration.
16Bank technical error — “Your bank is temporarily unavailable. Please try again later or use a different account.”amount: 102code GATEWAY_ERROR
source remitter_bank
step payment_response
reason bank_technical_error
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
17Timeout at remitter bank — “Your bank took too long to respond. Please try again.”amount: 104code GATEWAY_ERROR
source remitter_bank
step payment_response
reason timeout_at_remitter_bank
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
18Bank technical error — “UPI Autopay setup couldn’t be completed due to a temporary issue. Any debited amount will be refunded in 4-5 business days.”amount: 107code GATEWAY_ERROR
source remitter_bank
step payment_authentication
reason bank_technical_error
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
19Customer invalid mobile number — “Your mobile number has been changed or removed from this account. Please update your details or use a different account.”amount: 202code GATEWAY_ERROR
source remitter_bank
step payment_debit_response
reason customer_invalid_mobile_number
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
20Incorrect pin entered — “Payment authorisation failed due to incorrect MPIN. Please retry with the correct MPIN.”amount: 204code GATEWAY_ERROR
source customer
step payment_initiation
reason incorrect_pin_entered
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
21Customer mpin not set — “UPI PIN is not set for this account. Please set up your UPI PIN and try again.”amount: 205code GATEWAY_ERROR
source customer
step payment_debit_response
reason customer_mpin_not_set
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
22Incorrect pin entered — “You’ve exceeded the number of PIN attempts. Please wait and try again later, or contact your bank if you’ve forgotten your PIN.”amount: 206code GATEWAY_ERROR
source customer
step payment_response
reason incorrect_pin_entered
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
23Transaction amount limit exceeded — “This amount is above your transaction limit. Please try a lower amount or contact your bank for assistance.”amount: 208code GATEWAY_ERROR
source remitter_bank
step payment_initiation
reason transaction_amount_limit_exceeded
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
24Transaction amount limit exceeded — “This amount is above your transaction limit. Please try a lower amount or contact your bank for assistance.”amount: 209code GATEWAY_ERROR
source remitter_bank
step payment_authentication
reason transaction_amount_limit_exceeded
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
25Transaction frequency limit exceeded — “You’ve exceeded the number of allowed transactions on this account. Please try again later or contact your bank.”amount: 210code GATEWAY_ERROR
source remitter_bank
step payment_response
reason transaction_frequency_limit_exceeded
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
26Account state blocked — “Your account is blocked or frozen. Please contact your bank to resolve this.”amount: 212code GATEWAY_ERROR
source remitter_bank
step payment_status_request
reason account_state_blocked
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
27Beneficiary account not found — “Payment authorisation failed due to a technical issue. Please try again or contact your bank if this continues.”amount: 213code BAD_REQUEST_ERROR
source business
step payment_response
reason beneficiary_account_not_found
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
28Risk declined by remitter bank — “Autopay setup was blocked for security reasons. Please contact your bank or use a different account.”amount: 404code GATEWAY_ERROR
source remitter_bank
step payment_response
reason risk_declined_by_remitter_bank
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
29Risk declined by remitter bank — “Autopay setup was declined for security reasons. Please contact your bank for assistance.”amount: 405code GATEWAY_ERROR
source remitter_bank
step payment_initiation
reason risk_declined_by_remitter_bank
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
30Customer PSP fingerprint mismatch — “Payment was declined for security reasons. Please contact your bank for more details.”amount: 407code GATEWAY_ERROR
source customer
step payment_response
reason customer_psp_fingerprint_mismatch
Create a customer, an order and the authorisation payment as in #1, using the trigger amount. Confirm the error object above, and that the token ends at rejected.
Auto-debit A debit on a live mandate can run on either of two flows. On the coupled flow you create the order and the payment together and Razorpay raises the pre-debit notification, schedules the debit and runs the retries for you. On the decoupled flow you send the notification object on the order, raise the notification yourself and create the payment separately once the window has passed, and no retries are run on your behalf. For the full description of both, see Subsequent Payments. These happen on a mandate that is already live. The token stays usable, so the right response is to handle the failed charge rather than to ask the customer to register again.
#ScenarioTrigger credsError objectSteps to follow
31Debit above max_amountamount above the token’s max_amount—Create a debit order and a recurring payment (POST /v1/payments/create/recurring) for an amount higher than the token’s max_amount. Confirm you get 400 Bad Request with transaction_limit_exceeded (source: remitter_bank), and that no payment object is created.
32Debit fails: bank error — remitter_bank_erroramount: 101code GATEWAY_ERROR
source remitter_bank
step payment_response
reason remitter_bank_error
Register a mandate (#1). Create a debit order and a recurring payment with the trigger amount. Confirm the failure and that your retry logic treats it as temporary.
33Debit fails: unmapped gateway error — gateway_technical_erroramount: 103code GATEWAY_ERROR
source gateway
step payment_response
reason gateway_technical_error
Register a mandate (#1). Create a debit order and a recurring payment with the trigger amount. Confirm gateway_technical_error (source: gateway, step: payment_response). This is the simulator’s catch-all for an error it has no mapping for, so treat it as a temporary failure and retry.
34Remitter bank unavailable — “Your bank is temporarily unavailable. Please try again in a few moments.”amount: 102code GATEWAY_ERROR
source remitter_bank
step payment_debit_request
reason remitter_bank_unavailable
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
35Timeout at remitter bank — “Your bank took too long to respond. Please try again.”amount: 104code GATEWAY_ERROR
source remitter_bank
step payment_debit_response
reason timeout_at_remitter_bank
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
36Remitter bank unavailable — “Your bank is temporarily unavailable. Please try again in a few moments.”amount: 107code GATEWAY_ERROR
source remitter_bank
step payment_request
reason remitter_bank_unavailable
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
37Customer mobile changed — “Your registered mobile number has been updated. Please update your UPI profile or contact your bank.”amount: 202code GATEWAY_ERROR
source remitter_bank
step payment_request
reason customer_mobile_changed
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
38Customer mpin not set — “UPI PIN is not set for this account. Please set up your UPI PIN and try again.”amount: 205code GATEWAY_ERROR
source customer
step payment_authentication
reason customer_mpin_not_set
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
39Incorrect pin entered — “You’ve exceeded the number of PIN attempts. Please wait and try again later, or contact your bank if you’ve forgotten your PIN.”amount: 206code GATEWAY_ERROR
source customer
step payment_authentication
reason incorrect_pin_entered
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
40Transaction limit exceeded — “Payment amount exceeds your bank’s limit. Please try with a lower amount or contact your bank to increase the limit.”amount: 208code GATEWAY_ERROR
source remitter_bank
step payment_debit_response
reason transaction_limit_exceeded
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
41Spending limit exceeded — “You’ve exceeded your total UPI spending limit. Please try again later or contact your bank to increase the limit.”amount: 209code GATEWAY_ERROR
source remitter_bank
step payment_debit_response
reason spending_limit_exceeded
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
42Frequency limit exceeded — “You’ve exceeded the number of allowed transactions. Please try again later or contact your bank.”amount: 210code GATEWAY_ERROR
source remitter_bank
step payment_initiation
reason frequency_limit_exceeded
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
43Account blocked — “Your account is blocked or frozen. Please contact your bank to resolve this.”amount: 212code GATEWAY_ERROR
source remitter_bank
step payment_debit_request
reason account_blocked
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
44Risk declined — “Payment was declined for security reasons. Please contact your bank for assistance.”amount: 404code BAD_REQUEST_ERROR
source business
step payment_debit_response
reason risk_declined
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
45Risk declined — “Payment was declined for security reasons. Please contact your bank for assistance.”amount: 405code GATEWAY_ERROR
source remitter_bank
step payment_debit_response
reason risk_declined
Register a mandate first. Create a debit order and a recurring payment with the trigger amount. Confirm the error object above, and that the token stays confirmed so the mandate can be charged again.
If you are on the decoupled flow Everything above assumes the coupled flow, which is where most integrations start and which Razorpay recommends. If you send the notification object on the debit order you are on the decoupled flow, and four things change. Run the cases above first, then these. If you integrate against coupled behaviour and later move to decoupled without building the retry loop, every failed debit is silently lost. That is the single most expensive mistake on this flow. The full list of UPI Autopay error reasons, including the ones no trigger reproduces in test mode, is on the Error index.

3.4 Not available in test mode yet

Not being able to trigger a scenario is not a reason to leave it out of your test suite. Each row below gives the behaviour your code has to implement and the assertion worth writing now, so that the test is already in place when the trigger arrives and so that you can run it against live traffic in the meantime.

4. Common Integration Gaps to Avoid

These are the mistakes that most often cause failed payments, missed debits or double charges after go-live. 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