Complete Guide: Razorpay Integration with Django and Next.js (Order Creation & Verification)

1. Introduction

Razorpay is a robust and secure payment gateway, ideal for Indian startups and web apps. In this blog, we will walk through how to:

  • Create a Razorpay order from your Django backend
  • Integrate Razorpay Checkout in your Next.js frontend
  • Verify the payment after completion
  • Handle order saving and payment status

2. Razorpay Workflow Overview

Here’s how the flow works:

  1. User clicks “Pay” in frontend (Next.js)
  2. Razorpay order is created via Django API
  3. Razorpay Checkout opens with that order
  4. After payment, Razorpay sends back a razorpay_payment_id, razorpay_order_id, and razorpay_signature
  5. Backend verifies the payment using Razorpay SDK
  6. Order is marked successful and saved

3. Backend Setup with Django

3.1 Install Razorpay SDK
pip install razorpay

3.2 Add Razorpay Keys in settings.py
RAZORPAY_KEY_ID = "your_key_id"
RAZORPAY_KEY_SECRET = "your_key_secret"

3.3 Create Order API (views.py)
# views.py
import razorpay
from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

client = razorpay.Client(auth=(settings.RAZORPAY_KEY_ID, settings.RAZORPAY_KEY_SECRET))

class CreateOrderAPIView(APIView):
    def post(self, request):
        try:
            amount = int(request.data.get("amount")) * 100  # convert to paise
            payment = client.order.create({
                "amount": amount,
                "currency": "INR",
                "payment_capture": "1"
            })
            return Response({
                "order_id": payment['id'],
                "amount": amount,
                "currency": "INR",
                "razorpay_key": settings.RAZORPAY_KEY_ID
            })
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)

3.4 Verify Payment API
# views.py
from rest_framework.decorators import api_view

@api_view(["POST"])
def verify_payment(request):
    from razorpay import Utility

    razorpay_order_id = request.data.get("razorpay_order_id")
    razorpay_payment_id = request.data.get("razorpay_payment_id")
    razorpay_signature = request.data.get("razorpay_signature")

    params_dict = {
        "razorpay_order_id": razorpay_order_id,
        "razorpay_payment_id": razorpay_payment_id,
        "razorpay_signature": razorpay_signature
    }

    try:
        client.utility.verify_payment_signature(params_dict)
        return Response({"success": True})
    except razorpay.errors.SignatureVerificationError:
        return Response({"success": False, "error": "Verification failed"}, status=400)

3.5 Add URLs (urls.py)
from django.urls import path
from .views import CreateOrderAPIView, verify_payment

urlpatterns = [
    path("create-order/", CreateOrderAPIView.as_view()),
    path("verify-payment/", verify_payment),
]

4 Frontend Integration with Next.js

4.1 Load Razorpay Script
useEffect(() => {
  const script = document.createElement("script");
  script.src = "https://checkout.razorpay.com/v1/checkout.js";
  document.body.appendChild(script);
}, []);

4.2 Payment Button Handler
const handlePayment = async () => {
  const res = await axios.post("/api/create-order", { amount: 500 });
  const { razorpay_key, order_id, amount } = res.data;

  const options = {
    key: razorpay_key,
    amount,
    currency: "INR",
    name: "Your Brand",
    description: "Purchase",
    order_id,
    handler: async function (response) {
      const verifyRes = await axios.post("/api/verify-payment", {
        razorpay_order_id: response.razorpay_order_id,
        razorpay_payment_id: response.razorpay_payment_id,
        razorpay_signature: response.razorpay_signature,
      });

      if (verifyRes.data.success) {
        alert("Payment Verified ✅");
      } else {
        alert("Payment Verification Failed ❌");
      }
    },
    prefill: {
      name: "Your Name",
      email: "user@example.com",
      contact: "9876543210",
    },
    theme: {
      color: "#3399cc",
    },
  };

  const rzp = new Razorpay(options);
  rzp.open();
};

5. API Summary

API EndpointMethodPurpose
/api/create-order/POSTCreates Razorpay order
/api/verify-payment/POSTVerifies payment signature

6. Common Issues & Fixes

IssueCauseFix
500 Internal Server ErrorWrong Razorpay key/secretCheck credentials in settings
Signature Verification FailedIncorrect frontend callback or missing paramsEnsure all 3 values are sent correctly
“relation does not exist”Missing DB tableRun makemigrations and migrate

7. Final Thoughts

Integrating Razorpay with Django and React/Next.js gives you full control over secure and scalable payments. Whether you’re running an eCommerce app or a digital product site, this setup provides you a clean and maintainable flow with backend verification.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top