Razorpay Standard Checkout — live demo
Click Pay, complete the Razorpay test flow, and watch the three-step integration run end-to-end: create-order → Checkout.js modal → verify-payment signature check.
How to test (test mode only)
Don't scan the QR with a real UPI app.Test-mode orders aren't registered on the live UPI network, so GPay / PhonePe / Paytm will say "invalid UPI id." Use the test credentials below inside the Razorpay modal instead.
Card tab
Razorpay test accounts have International Payments disabled by default. The old 4111 1111 1111 1111 number gets classified as international and rejected with "International cards are not supported." Use the domestic test cards below instead.
Card number 5267 3181 8797 5449 (Mastercard, domestic INR)
4386 2894 0766 0153 (Visa, domestic INR)
Expiry any future date (e.g. 12/30)
CVV any 3 digits (e.g. 123)
Name any
OTP 1111 (shown in the modal — NOT a real SMS)If you get a real SMS OTP on your phone during test mode, that's a coincidental Razorpay account notification, not this payment — nothing is actually charged.
UPI tab
Typeone of these into the UPI ID field (don't scan):
success@razorpay → payment.captured failure@razorpay → payment.failed
Nothing is actually charged. See Razorpay test card docs and test UPI IDs.
What happens when you click Pay
- Frontend calls
POST /api/create-orderwith{ amount: 100, currency: "INR", receipt: "..." }. Backend calls Razorpay API, returns{ order_id, amount, currency }. - Frontend opens Razorpay Checkout.js modal with the
order_id+ yourNEXT_PUBLIC_RAZORPAY_KEY_ID. - You complete the test payment. Razorpay calls the Checkout.js
handlerwithrazorpay_order_id,razorpay_payment_id, andrazorpay_signature. - Frontend forwards those three to
POST /api/verify-payment. Backend recomputes HMAC-SHA256(order_id|payment_id,KEY_SECRET) and constant-time compares. Returns{ ok: true, verified: true }or 400. - In parallel, Razorpay fires the async webhook at
/api/webhook(authoritative source for billing state — frontend verification is a UX gate, the webhook flips the DB).