Razorpay Python SDK
raw JSON → 2.0.1 verified Tue May 12 auth: no python install: verified quickstart: stale
Official Python SDK for Razorpay — India's leading payment gateway. Current version: 2.0.1 (Mar 2026). Auth uses API key + secret tuple. All amounts in paise (1 INR = 100 paise) — not rupees. Payment flow: create order server-side → collect payment client-side → verify signature server-side. Signature verification is mandatory — skipping it is a security vulnerability. Test keys start with 'rzp_test_', live keys with 'rzp_live_'.
pip install razorpay Warnings
breaking All amounts are in paise (smallest currency unit) — NOT rupees. 500 INR must be passed as 50000. Passing 500 charges 5 paise (₹0.05). No error is raised — silent wrong charge. ↓
fix amount_in_paise = amount_in_inr * 100. Always multiply INR by 100.
breaking Signature verification is mandatory after payment. Skipping it allows fraudulent payment_id injection. Never fulfill orders without calling verify_payment_signature(). ↓
fix Always call client.utility.verify_payment_signature(params) with razorpay_order_id, razorpay_payment_id, razorpay_signature.
gotcha Test keys (rzp_test_) and live keys (rzp_live_) are different. Test payments don't transfer real money. Accidentally using live keys in development charges real users. ↓
fix Use environment variables: RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET. Verify key starts with 'rzp_test_' in development.
gotcha Webhook signature uses a separate webhook secret — not the API secret. Using API secret for webhook verification raises SignatureVerificationError. ↓
fix client.utility.verify_webhook_signature(payload, signature, WEBHOOK_SECRET) — get WEBHOOK_SECRET from Razorpay dashboard under Webhooks settings.
gotcha payment_capture=1 in order.create auto-captures payment. Without it, payment is authorized but not captured — must manually call client.payment.capture(payment_id, amount). ↓
fix Add 'payment_capture': 1 to order creation for automatic capture.
gotcha SDK method naming: client.payment (singular) not client.payments. client.order (singular) not client.orders. Common LLM error. ↓
fix client.payment.fetch(), client.order.create(), client.refund.fetch(), client.customer.create()
gotcha Razorpay only supports INR for domestic payments. International currencies require Razorpay's international payment product with separate activation. ↓
fix Use currency='INR' for standard integration. Contact Razorpay for international payment activation.
breaking The 'Authentication failed' error means your API Key ID or Secret is incorrect or missing. Verify that both RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET are accurately set and passed to the Razorpay client. ↓
fix Ensure that RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET are correctly obtained from your Razorpay dashboard and properly configured in your application (e.g., via environment variables or direct instantiation of razorpay.Client).
breaking The API keys (RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET) are either incorrect, missing, or have insufficient permissions, leading to an 'Authentication failed' error. This is a fundamental issue preventing any API interaction. ↓
fix Ensure RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET environment variables are set correctly with valid API keys. Double-check for typos and confirm the keys are active and have the necessary permissions in your Razorpay dashboard.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.59s 21.8M
3.10 slim (glibc) - - 0.42s 22M
3.11 alpine (musl) - - 0.78s 23.9M
3.11 slim (glibc) - - 0.63s 24M
3.12 alpine (musl) - - 0.70s 15.6M
3.12 slim (glibc) - - 0.69s 16M
3.13 alpine (musl) - - 0.67s 15.3M
3.13 slim (glibc) - - 0.67s 16M
3.9 alpine (musl) - - 0.54s 21.0M
3.9 slim (glibc) - - 0.47s 22M
Imports
- Client + order creation wrong
import razorpay client = razorpay.Client(auth=('KEY', 'SECRET')) # Wrong: amount in rupees order = client.order.create({ 'amount': 500, # treated as 5 paise, not 500 INR 'currency': 'INR' })correctimport razorpay client = razorpay.Client(auth=('rzp_test_KEY', 'SECRET')) # Amount MUST be in paise — 500 INR = 50000 paise order = client.order.create({ 'amount': 50000, # 500 INR in paise 'currency': 'INR', 'receipt': 'order_rcpt_001', 'payment_capture': 1 # auto-capture payment }) print(order['id']) # pass this to frontend - verify_payment_signature wrong
# Skipping signature verification — security vulnerability # Never trust payment_id from frontend without verifying payment = client.payment.fetch(payment_id) if payment['status'] == 'captured': fulfill_order() # could be spoofedcorrectimport razorpay client = razorpay.Client(auth=('rzp_test_KEY', 'SECRET')) # After frontend payment — MUST verify signature params = { 'razorpay_order_id': order_id, # from order creation 'razorpay_payment_id': payment_id, # from frontend callback 'razorpay_signature': signature # from frontend callback } try: client.utility.verify_payment_signature(params) # Signature valid — payment confirmed print('Payment verified') except razorpay.errors.SignatureVerificationError: # Signature invalid — do NOT fulfill order print('Payment verification failed')
Quickstart stale last tested: 2026-04-23
# pip install razorpay
import razorpay
# Use test keys from dashboard.razorpay.com
client = razorpay.Client(auth=('rzp_test_YOUR_KEY', 'YOUR_SECRET'))
client.enable_retry(True) # retry on transient failures
# Step 1: Create order server-side
order = client.order.create({
'amount': 50000, # 500 INR in paise
'currency': 'INR',
'receipt': 'receipt_001',
'notes': {
'product': 'Widget',
'user_id': '123'
}
})
print('Order ID:', order['id'])
# Pass order['id'], key_id, amount to frontend Razorpay checkout
# Step 2: After frontend payment, verify signature
params = {
'razorpay_order_id': order['id'],
'razorpay_payment_id': 'pay_XXXX', # from frontend
'razorpay_signature': 'SIG_XXXX' # from frontend
}
try:
client.utility.verify_payment_signature(params)
print('Payment confirmed')
except razorpay.errors.SignatureVerificationError:
print('Invalid signature — reject payment')
# Fetch payment details
payment = client.payment.fetch('pay_XXXX')
print(payment['status'], payment['amount'])
# Refund
refund = client.payment.refund('pay_XXXX', {'amount': 50000})
print(refund['id'])