Test Razorpay
in paise — not rupees
Razorpay's Orders API works in paise — India's smallest currency unit. ₹1 = 100 paise, ₹500 = 50000 paise, integer only. This mock handles the full order → redirect → signature verification flow without any Razorpay account or dashboard access.
Paise amounts
integer only, no decimals
HMAC sig
mandatory verification
0 credentials
to get started
{
"amount": 50000,
"currency": "INR",
"receipt": "receipt#0042"
}
// ₹500.00 = 50000 paise ← always integer
Razorpay is the dominant payment gateway in India. The integration uses an Orders API: you create an order on your server, open the Razorpay checkout in the browser, and after the customer pays, verify the payment signature before fulfilling. All amounts are in paise — the smallest Indian currency unit. ₹1 = 100 paise. If you send 500 instead of 50000, the customer gets charged ₹5 instead of ₹500.
Signature verification is mandatory and often skipped in tutorials. After payment, Razorpay sends razorpay_order_id, razorpay_payment_id, and razorpay_signature to your frontend. Your server must compute HMAC-SHA256(order_id + '|' + payment_id, key_secret) and compare it against the signature. Skip this check and anyone can send a fake payment callback to your server.
Razorpay supports cards, UPI, netbanking, wallets, and EMI — all from the same checkout. UPI accounts for over 70% of digital transactions in India and is instant 24/7. The payment.captured webhook fires after the payment is finalized — that's the right place to fulfill orders, not the frontend callback. This mock delivers the full Orders API flow with signature verification and webhook events.
The paise system
₹1 = 100 paise
₹500 = 50000
Integer only. No decimals.
Razorpay — like Stripe, Checkout.com, and most modern gateways — works in the smallest indivisible currency unit. For INR, that is paise. Floating point numbers are unreliable for money: 0.1 + 0.2 !== 0.3 in most languages. Integers never have this problem.
Watch out
If you send 500 instead of 50000, the customer pays ₹5 not ₹500. Razorpay applies no conversion — the number you send is interpreted directly as paise.
| Rupees (₹) | Send as (paise) |
|---|---|
| ₹1 | 100 |
| ₹10 | 1,000 |
| ₹100 | 10,000 |
| ₹500 | 50,000 |
| ₹999 | 99,900 |
| ₹1,499 | 1,49,900 |
Conversion is always: rupee_amount × 100. No rounding needed — paise is already the smallest unit.
Signature verification
After the customer pays, Razorpay sends three values back to your callback. You must verify them with HMAC-SHA256 before fulfilling the order.
HMAC-SHA256(
razorpay_order_id + " | " + razorpay_payment_id,
key_secret
)
The resulting hex string must match razorpay_signature exactly. If it does not, reject the callback with a 400.
Without this check, an attacker who knows your order_id can send a fake payment_id to your callback and get their order fulfilled without paying. This has happened to real apps.
razorpay_order_idThe order ID you created in step 1. Starts with order_
razorpay_payment_idThe unique ID for this payment attempt. Starts with pay_
razorpay_signatureHMAC hex string. Verify this against your own calculation. Must match exactly.
Payment methods
Razorpay's checkout supports all major Indian payment methods through a single integration. Every method fires the same payment.captured webhook format.
Cards
Visa, Mastercard, Rupay
UPI
GPay, PhonePe, BHIM
Netbanking
50+ banks supported
Wallets
Paytm, MobiKwik, Freecharge
EMI
Bank and No-cost EMI
Pay Later
Simpl, LazyPay, HDFC PayLater
Unified response: Whether the customer pays with a Visa card, UPI, or a wallet, your webhook handler receives the same payment.captured event shape with method indicating which rail was used. You do not need separate handlers per method.
Integration code
curl -X POST https://mockgateway.dev/api/base/razorpay/v1/orders \
-H "Authorization: Bearer YOUR_MOCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 50000,
"currency": "INR",
"receipt": "receipt#ORD-0042",
"notes": {
"order_id": "ORD-0042",
"customer": "Priya Sharma"
}
}'
// amount = 50000 paise = ₹500.00
// INR is the only supported currency in this mockRequest parameters
Sent to POST /api/base/razorpay/v1/orders
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | integer | required | Amount in smallest currency unit (paise for INR) e.g. 50000 |
currency | string | required | ISO 4217 currency (e.g. INR) e.g. INR |
description | string | optional | Payment description |
order_id | string | optional | Your order reference e.g. ORD-12345 |
Response fields
| Field | Type | Description |
|---|---|---|
id | string | Razorpay payment ID |
status | enum | Payment status |
order_id | string | Razorpay order ID |
created_at | integer | |
payment_link_id | string | Razorpay payment link identifier |
Questions about Razorpay
Other gateway templates
Looking for a different provider?