Short answer: in Razorpay test mode, plug in 4111 1111 1111 1111 with any future expiry date, any three digit CVV, and the OTP 1234. That is the standard success path. The rest of this page covers the variations you need when you are testing declines, OTP failures, and other card networks.
Test mode is a separate world
Before the numbers, the thing that confuses most people. Test mode and live mode are two different systems. Your test key starts with rzp_test_, and the live key does not. A test card only works with a test key. If you paste 4111 1111 1111 1111 into a live checkout, the gateway will reject it, and rightly so. No real money moves in test mode. No bank is contacted. No settlement happens. The whole flow runs inside Razorpay's sandbox.
The test cards worth bookmarking
- 4111 1111 1111 1111 (Visa): success
- 4012 8888 8888 1881 (Visa): success
- 5267 3181 8797 5449 (Mastercard): success
- 5555 5555 5555 4444 (Mastercard): success
- 4000 0000 0000 0002 (Visa): payment declined
- 5104 0600 0000 0008 (Mastercard): success, useful for network checks
Expiry can be any date in the future. CVV can be any three digits. I usually type 123 because it is fast, not because the value matters. If the card form asks for a name, anything works.
The decline card is the one you actually need
Everyone tests the happy path first and forgets the failure path. Then a real user's card gets declined in production and your error state shows a blank screen. Run 4000 0000 0000 0002 through your checkout once. Watch what your code does with the failure response. That five minute test saves a bad support ticket later.
The OTP step trips people up
Razorpay simulates the 3D Secure step in test mode, so a test payment is not finished at the card form. You get an OTP screen. Enter 1234 and the payment succeeds. Enter 1111 and it fails. Any other value also fails. If your test just hangs, check whether your integration is still waiting on that OTP response and never resolving.
Other methods in the sandbox
- UPI:
success@razorpaycompletes,failure@razorpayfails - Netbanking: pick any bank in the test list, the flow is simulated
- Wallets: test balances are fake, no real wallet is touched
Mistakes I see over and over
- Using an expiry date in the past. The form rejects it before it ever reaches the gateway.
- Mixing keys. Test card plus live key equals a confusing error.
- Expecting webhooks to behave exactly like live. They fire in test mode, but the payloads are sandbox events.
- Shipping with the test key still in the build. Grep your config before you deploy.
- Assuming test mode validates your account. It does not. Live payments need an activated account, and some payment methods stay unavailable until then.
Never test with a real card
It is tempting. A live card gives you a real end to end run. Do not do it. Test environments log request bodies, and a card number sitting in a log file is a compliance problem the moment it lands there. Card network rules and PCI DSS both push you toward sandbox numbers for a reason. Keep production card data out of development systems entirely, and if you ever do need live end to end coverage, use your own card in a controlled live transaction with logging turned off.
That is the whole toolkit. One success card, one decline card, OTP 1234 and 1111, and a habit of testing the failure path before you ship.