DEV Community

Cover image for Razorpay Integration Guide: 5 Mistakes That Break Payments
Vijay Kumar
Vijay Kumar

Posted on

Razorpay Integration Guide: 5 Mistakes That Break Payments

Integrating Razorpay looks easy — until payments start failing in production.

Many developers successfully open the checkout page but still run into issues like:

  • ❌ Payments not verifying
  • ❌ Incorrect amounts being charged
  • ❌ Successful payments not recorded
  • ❌ Order status not updating

After fixing multiple Razorpay integrations, I noticed something interesting:

Most payment failures happen because of a few small mistakes.

In this guide, you'll learn the 5 most common Razorpay integration mistakes — and how to avoid them.


📚 Table of Contents

  • Razorpay Payment Flow
  • Mistake #1: Creating Orders on the Frontend
  • Mistake #2: Using the Wrong Amount Format
  • Mistake #3: Skipping Payment Verification
  • Mistake #4: Not Implementing Webhooks
  • Mistake #5: Using Test Keys in Production
  • Final Thoughts

Razorpay Payment Flow (Overview)

Before looking at the mistakes, it's important to understand the correct payment flow.

User clicks Pay
↓
Frontend sends request to Backend
↓
Backend creates order using Razorpay API
↓
Order ID returned to Frontend
↓
Frontend opens Razorpay Checkout
↓
User completes payment
↓
Frontend sends payment details to Backend
↓
Backend verifies payment signature
↓
Payment confirmed
Enter fullscreen mode Exit fullscreen mode

Key Principles

✔ Orders should be created on the backend
✔ Checkout runs on the frontend
✔ Payment verification must happen on the backend

This separation ensures security and reliability.


❌ Mistake #1: Creating Orders on the Frontend

A very common mistake is trying to create Razorpay orders directly from the frontend.

❌ Wrong Approach

// frontend
fetch("https://api.razorpay.com/v1/orders")
Enter fullscreen mode Exit fullscreen mode

This exposes your secret API key, which is extremely dangerous.

Anyone could inspect your code and misuse it.


✅ Correct Approach

Orders should always be created on the backend.

const Razorpay = require("razorpay");

const razorpay = new Razorpay({
  key_id: process.env.RAZORPAY_KEY_ID,
  key_secret: process.env.RAZORPAY_KEY_SECRET
});

const order = await razorpay.orders.create({
  amount: 50000,
  currency: "INR",
  receipt: "receipt_123"
});
Enter fullscreen mode Exit fullscreen mode

Secure Order Creation Flow

User clicks Pay
      ↓
Frontend requests backend to create order
      ↓
Backend calls Razorpay API
      ↓
Razorpay returns Order ID
      ↓
Backend sends Order ID to frontend
      ↓
Checkout opens
Enter fullscreen mode Exit fullscreen mode

❌ Mistake #2: Using the Wrong Amount Format

Razorpay expects the amount in paise, not rupees.

This small detail causes many integrations to fail.


❌ Incorrect Example

amount: 500
Enter fullscreen mode Exit fullscreen mode

✅ Correct Example

amount: 500 * 100
Enter fullscreen mode Exit fullscreen mode

If the customer needs to pay ₹500, Razorpay expects:

50000
Enter fullscreen mode Exit fullscreen mode

Amount Conversion Flow

Customer payment: 500 INR
        ↓
Convert to paise
        ↓
500 × 100
        ↓
Send 50000 to Razorpay
Enter fullscreen mode Exit fullscreen mode

💡 Rule to remember

Amount sent to Razorpay = Rupees × 100
Enter fullscreen mode Exit fullscreen mode

❌ Mistake #3: Skipping Payment Verification

Many developers assume that if Razorpay checkout shows:

Payment Successful
Enter fullscreen mode Exit fullscreen mode

then the payment is complete.

That is not enough proof.

You must verify the payment signature on your backend.


Payment Verification Flow

User completes payment
        ↓
Razorpay sends payment response to frontend
        ↓
Frontend sends payment_id, order_id, signature to backend
        ↓
Backend verifies signature using Razorpay secret key
        ↓
Backend confirms payment
Enter fullscreen mode Exit fullscreen mode

Without verification, attackers could fake payment responses.


❌ Mistake #4: Not Implementing Webhooks

Some developers rely only on the frontend response.

This works during testing, but in production payments can be:

  • delayed
  • retried
  • refunded
  • partially captured

Webhooks notify your backend when these events happen.


Webhook Event Flow

Payment event occurs on Razorpay
        ↓
Razorpay sends webhook request
        ↓
Your backend webhook endpoint receives event
        ↓
Backend updates database
        ↓
Order status updated
Enter fullscreen mode Exit fullscreen mode

Common webhook events include:

payment.captured
payment.failed
refund.processed
Enter fullscreen mode Exit fullscreen mode

Without webhooks, your backend won't know the real payment state.


❌ Mistake #5: Using Test Keys in Production

This mistake happens more often than you think.

During development, Razorpay provides test API keys.

If those keys are deployed to production, real payments will fail.


Environment Variables

RAZORPAY_KEY_ID=
RAZORPAY_KEY_SECRET=
Enter fullscreen mode Exit fullscreen mode

Deployment Flow

Development
   ↓
Use Razorpay Test Keys
   ↓
Testing completed
   ↓
Switch to Live Keys
   ↓
Deploy to Production
Enter fullscreen mode Exit fullscreen mode

Always double-check this before deployment.


Final Thoughts

Payment integrations rarely fail because of complex code.

They fail because of small details developers overlook, such as:

  • creating orders on the wrong layer
  • sending incorrect amounts
  • skipping payment verification
  • ignoring webhooks
  • deploying with test keys

Fixing these five mistakes will make your Razorpay integration:

✔ Secure
✔ Reliable
✔ Production-ready


💬 Discussion

Have you faced issues integrating Razorpay in production?

What was the hardest part of the payment integration?

Share your experience in the comments 👇


Top comments (0)