Integrate Razorpay Payment Gateway with Django: Working Example

In today’s digital world, online payments have become an essential part of e-commerce and web applications. If you’re developing a Django web application and want to accept payments seamlessly, Razorpay is an excellent choice. Razorpay is a popular payment gateway that allows you to integrate payment functionality quickly and securely into your Django project. In this guide, we’ll walk you through the process of integrating Razorpay with Django and provide you with a working example.

Prerequisites

Before we begin, make sure you have the following prerequisites in place:

  1. Django Install: Ensure you have Django installed. You can install it using pip:
   pip install Django
  1. You’ll need to install the razorpay library to interact with Razorpay’s API. Install it using pip:
pip install razorpay
  1. Razorpay Account: Sign up for a Razorpay account and obtain your API key and secret key. You can sign up at Razorpay’s official website.

Step 1: Create a Django Project

If you don’t already have a Django project, create one using the following command:

django-admin startproject yourprojectname

Replace yourprojectname with your project’s name.

Step 2: Create a Django App

Inside your project, create a Django app where you’ll implement the payment functionality:

python manage.py startapp payment_app

Step 3: Configure Django Settings

Add the newly created app and configure your project’s settings:

# yourprojectname/settings.py

INSTALLED_APPS = [
    # ...
    'payment_app',
]

RAZORPAY_API_KEY = 'YOUR_RAZORPAY_API_KEY'
RAZORPAY_API_SECRET = 'YOUR_RAZORPAY_API_SECRET'

# To Enable Popus in Django or else it will block the payment popup
SECURE_CROSS_ORIGIN_OPENER_POLICY = "same-origin-allow-popups"

Replace 'YOUR_RAZORPAY_API_KEY' and 'YOUR_RAZORPAY_API_SECRET' with your actual Razorpay API credentials.

Using SECURE_CROSS_ORIGIN_OPENER_POLICY = "same-origin-allow-popups", you will solve the issue  about:blank#blocked which occassionaly occurs in django pop ups

Step 4: Create Views and Templates

In your payment_app app, create views for initiating payments and handling payment success or failure. You’ll also need to create HTML templates for these views.

Here’s an example implementation of the views:

# payment_app/views.py

import razorpay
from django.conf import settings
from django.http import JsonResponse
from django.shortcuts import render

def initiate_payment(request):
    if request.method == "POST":
        amount = int(request.POST["amount"]) * 100  # Amount in paise

        client = razorpay.Client(auth=(settings.RAZORPAY_API_KEY, settings.RAZORPAY_API_SECRET))

        payment_data = {
            "amount": amount,
            "currency": "INR",
            "receipt": "order_receipt",
            "notes": {
                "email": "[email protected]",
            },
        }

        order = client.order.create(data=payment_data)
        
        # Include key, name, description, and image in the JSON response
        response_data = {
            "id": order["id"],
            "amount": order["amount"],
            "currency": order["currency"],
            "key": settings.RAZORPAY_API_KEY,
            "name": "Your Company Name",
            "description": "Payment for Your Product",
            "image": "https://yourwebsite.com/logo.png",  # Replace with your logo URL
        }
        
        return JsonResponse(response_data)
    
    return render(request, "payment.html")


def payment_success(request):
    return render(request, "payment_success.html")

def payment_failed(request):
    return render(request, "payment_failed.html")

Ensure that you have corresponding HTML templates (payment.html, payment_success.html, and payment_failed.html) in the payment_app/templates/payment_app/ directory.

Step 5: Create Payment Templates

In your payment_app app’s templates directory, create the payment-related HTML templates as mentioned in the views:

  • payment.html: This template displays the payment form to the user. Bellow we have created this in step 6.
  • payment_success.html: Shown to the user when the payment is successful.
<!-- payment_app/templates/payment_success.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Payment Success</title>
</head>
<body>
    <h1>Payment Successful</h1>
    <p>Your payment has been successfully processed.</p>
</body>
</html>
  • payment_failed.html: Displayed if the payment fails or is canceled.
<!-- payment_app/templates/payment_failed.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Payment Failed</title>
</head>
<body>
    <h1>Payment Failed</h1>
    <p>Your payment could not be processed. Please try again later.</p>
</body>
</html>

You can customize the appearance and content of these templates to match your application’s design.

Step 6: Initialize Razorpay Checkout

In the payment.html template, include the Razorpay Checkout.js script and use JavaScript to initiate payments without reloading the page. Here’s an example:

<!-- payment_app/templates/payment.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Razorpay Payment</title>
    <script src="https://checkout.razorpay.com/v1/checkout.js"></script>
</head>
<body>
    <h1>Razorpay Payment Form</h1>
    <form id="payment-form">
        {% csrf_token %}
        <label for="amount">Enter Amount (in INR):</label>
        <input type="number" id="amount" name="amount" required>
        <button type="button" id="pay-button">Pay Now</button>
    </form>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        $(document).ready(function() {
            $("#pay-button").click(function(e) {
                e.preventDefault(); // Prevent the default form submission
                
                // Get the amount entered by the user
                const amount = $("#amount").val();

                // Make an AJAX request to initiate the payment
                $.ajax({
                    type: "POST",
                    url: "/payment/initiate-payment/",
                    data: { amount: amount },
                    dataType: "json",
                    beforeSend: function(xhr) {
                        xhr.setRequestHeader("X-CSRFToken", $("[name=csrfmiddlewaretoken]").val());
                    },
                    success: function(data) {
                        // Initialize Razorpay Checkout with the received values
                        const options = {
                            key: data.key,
                            amount: data.amount,
                            currency: data.currency,
                            order_id: data.id,
                            name: data.name,
                            description: data.description,
                            image: data.image,
                            handler: function(response) {
                                // Handle the payment success or failure and redirect accordingly
                                if (response.razorpay_payment_id) {
                                    // Payment successful, redirect to the success URL
                                    window.location.href = "/payment/payment-success/";
                                } else {
                                    // Payment failed or canceled, redirect to the failure URL
                                    window.location.href = "/payment/payment-failed/";
                                }
                            },
                            prefill: {
                                name: "Customer Name",
                                email: "[email protected]",
                                contact: "customer_contact",
                            },
                        };

                        const rzp = new Razorpay(options);
                        rzp.open();
                    },
                    error: function(error) {
                        console.error("Error initiating payment:", error);
                    }
                });
            });
        });
    </script>
</body>
</html>

Step 7: Define URLs

Define the URLs for your payment-related views in the urls.py file of your app:

# payment_app/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path("initiate-payment/", views.initiate_payment, name="initiate_payment"),
    path("payment-success/", views.payment_success, name="payment_success"),
    path("payment-failed/", views.payment_failed, name="payment_failed"),
]

In yourprojectname urls.py add your app urls:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("payment/", include("payment_app.urls")),
]

Step 8: Run the Development Server

Finally, run the Django development server to test your Razorpay integration:

python manage.py runserver

You can now access the payment initiation form at http://localhost:8000/payment/initiate-payment/. After completing the payment, Razorpay will redirect the user to the appropriate success or failure URL based on the payment status.

Congratulations! You’ve successfully integrated Razorpay with your Django application. This allows you to accept online payments securely and efficiently.

Remember to replace the placeholder values in the code with your actual API credentials, company information, and URLs.

Find this project on Github.

Read our blog on How to Protect Sensitive Data in Python Projects like Django and Flask

As you are using sensitive data in your project, like api keys and secrets. You need protect it.
Blogs You Might to Read!