Django/Payments/Razorpay/One Time Payment/
2022-10-17T07:05:42.964107Z
Published on
Razorpay is one of the modern payment gateways widely used in India. It is more reliable than its compitors. Also, it is developer-friendly and easy to integrate with any technology stack. Also, they provide so many modes of payment like UPI, Debit cards, Credit cards, Internet banking and digital wallets and QR scanner code.
How it works ( Sequence Diagram ) :
Razorpay public and private keys ( How to get Razorpay public and private keys? )
Basic Django project setup
Basic React.js project setup
In this tutorial the payments are done in Test mode, not in production mode.
The source code for both Django and react are given here: https://github.com/episyche/razorpay_django_reactjs_example
Setup instructions for Django and React.js are given in the Github Readme file.
API keys are a unique identification number used to link your Razorpay account with any development platform like Python, Java, Ruby, Node.js etc.
If you don’t have a Razorpay account click here (How to create a Razorpay account ?)
If you don’t have Razorpay API Keys click here (How to generate Razorpay API keys ?)
Create an empty folder with the project name.
1mkdir <project-name>
2cd <project-name>
3
4For example:
5mkdir cake-shop
6cd project-folder
Inside the folder cake-shop(project-folder) create the Django project
1django-admin startproject core .
a. core: main app name.
b. (.) the dot symbol at the end indicates not to create a new folder. Generate files on the working directory.
c. Once the files are generated, It will be looking like the below screenshot example.
Create a Django app for handling payment logic. The name of the app is “payment_razorpay”.
1cd /<project-folder>
2
3for example :
4cd /cake-shop
1cd /cake-shop python3 manage.py startapp payment_razorpay
a. After executing the above command an app named “payment_razorpay” will be created. An example screenshot is given below:
Add the payment_razorpay app to the INSTALLED_APPS
list in settings.py
cake_shop/core/settings.py (<project-folder>/core/settings.py)
1
2INSTALLED_APPS = [
3 'django.contrib.admin',
4 'django.contrib.auth',
5 'django.contrib.contenttypes',
6 'django.contrib.sessions',
7 'django.contrib.messages',
8 'django.contrib.staticfiles',
9 'payment_razorpay', # <<< newly added line
10]
Sample code for the above use case can be found in the following GitHub URL.
https://github.com/episyche/razorpay_django_reactjs_example/blob/main/backend/core/settings.py
Add a new URL path for the payment_razorpay
app, to the base app ( main app ) urls.py file.
cake_shop/core/urls.py (<project-folder/core/urls.py)
1from django.contrib import admin
2from django.urls import path, include # <<< newly added line
3
4urlpatterns = [
5 path('admin/', admin.site.urls),
6 path('payment/', include('payment_razorpay.urls')), # <<< newly added line
7]
Sample code for the above use case can be found in the following GitHub URL.
https://github.com/episyche/razorpay_django_reactjs_example/blob/main/backend/core/urls.py
Create a new urls.py file under the payment_razorpay app that we just created.
Install Razorpay SDK using pip
1pip install razorpay
<project_folder> payment_razorpay > views.py > new_order (function API)
cake-shop > payment_razorpay > views.py > new_order (function API)
Create a function API “new_order” to handle the new payment requests from the front end.
1from unicodedata import name
2from django.shortcuts import render
3import razorpay
4from django.http import JsonResponse
5from django.views.decorators.csrf import csrf_exempt
6
7
8razorpay_client = razorpay.Client(auth=("rzp_test_dFP2CS0ZMKdXFz", "gaZHYtCOVJ2u2oPcS0RGTZm6"))
9
10@csrf_exempt
11def new_order(request):
12 if request.method == "POST":
13
14 print("", request.POST['price'])
15 amount = int(request.POST['price'])
16 product_name = request.POST['product_name']
17
18 new_order_response = razorpay_client.order.create({
19 "amount": amount*100,
20 "currency": "INR",
21 "payment_capture": "1"
22 })
23
24 response_data = {
25 "callback_url": "http://127.0.0.1:8000/payment/callback",
26 "razorpay_key": "rzp_test_dFP2CS0ZMKdXFz",
27 "order": new_order_response,
28 "product_name": product_name
29 }
30
31 print(response_data)
32
33 return JsonResponse(response_data)
Sample code for the above use case can be found in the following GitHub URL.
Add a new URL path for the “new_order” API in the urls.py file under the payment_razorpay app.
cake_shop/payment_razorpay/urls.py (<project-folder>/payment_razorpay/urls.py)
1from . import views
2from django.urls import path
3
4urlpatterns = [
5 path("new-order", views.new_order)
6]
Sample code for the above use case can be found in the following GitHub URL.
To handle the response from Razorpay payment gateway create a new function API named “order_callback“.
After successful payment, Razorpay sends payment-related information to a backend API that we specified in the callback URL. Using the data we get from Razorpay we can verify the payment status and write business logic according to the payment status.
The data we get from Razorpay is given below:
1{
2 "razorpay_payment_id": "pay_29QQoUBi66xm2f",
3 "razorpay_order_id": "order_9A33XWu170gUtm",
4 "razorpay_signature": "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d"
5}
1@csrf_exempt
2def order_callback(request):
3 if request.method == "POST":
4 if "razorpay_signature" in request.POST:
5 payment_verification = razorpay_client.utility.verify_payment_signature(request.POST)
6 if payment_verification:
7 return JsonResponse({"res":"success"})
8 # Logic to perform is payment is successful
9 else:
10 return JsonResponse({"res":"failed"})
11 # Logic to perform is payment is unsuccessful
Sample code for the above use case can be found in the following GitHub URL.
Set up CROS in Django, In order to avoid CROS problems between the frontend(React.js) and backend (Django).
pip install
1pip install django-cors-headers
Add CROS to MIDDLEWARE in settings.py
cake-shop<project-name>/ core / settings.py
1MIDDLEWARE = [
2 'django.middleware.security.SecurityMiddleware',
3 'django.contrib.sessions.middleware.SessionMiddleware',
4 'django.middleware.common.CommonMiddleware',
5 'django.middleware.csrf.CsrfViewMiddleware',
6 'django.contrib.auth.middleware.AuthenticationMiddleware',
7 'django.contrib.messages.middleware.MessageMiddleware',
8 'django.middleware.clickjacking.XFrameOptionsMiddleware',
9 'corsheaders.middleware.CorsMiddleware', # <<< new line added
10]
Sample code for the above use case can be found in the following GitHub URL.
https://github.com/episyche/razorpay_django_reactjs_example/blob/main/backend/core/settings.py
Add another variable at the end of the setings.py file.
cake-shop<project-name>/ core / settings.py
1CORS_ORIGIN_ALLOW_ALL = True # <<< append to the end of the settings.py
Sample code for the above use case can be found in the following GitHub URL.
https://github.com/episyche/razorpay_django_reactjs_example/blob/main/backend/core/settings.py
In this tutorial, a new component is created “Card.jsx”. Here we write the logic to handle the Razorpay payment gateway process.
There is no package available in npm to install for Razorpay. We have to integrate the Razorpay from CDN using useEffect hook. The example code is given below.
1const loadScript = (src) => {
2 return new Promise((resolve) => {
3 const script = document.createElement("script");
4 script.src = src;
5 script.onload = () => {
6 resolve(true);
7 };
8 script.onerror = () => {
9 resolve(false);
10 };
11 document.body.appendChild(script);
12 });
13 };
14
15 useEffect(() => {
16 loadScript("https://checkout.razorpay.com/v1/checkout.js");
17 });
Sample code for the above use case can be found in the following GitHub URL.
https://github.com/episyche/razorpay_django_reactjs_example/blob/main/frontend-reactjs/src/Card.jsx
In react.js to initialize the Razorpay payment gateway, we need some additional information they are provided from the backend. Here is the list of the information we need :
Razorpay key id
Amount
Product name
currency
callback URL ( Django URL)
order_id
1import Book1Img from './img/book1.png';
2import Book2Img from './img/book2.png';
3import { useEffect } from 'react';
4
5export default function Card(){
6
7 const loadScript = (src) => {
8 return new Promise((resolve) => {
9 const script = document.createElement("script");
10 script.src = src;
11 script.onload = () => {
12 resolve(true);
13 };
14 script.onerror = () => {
15 resolve(false);
16 };
17 document.body.appendChild(script);
18 });
19 };
20
21 useEffect(() => {
22 loadScript("https://checkout.razorpay.com/v1/checkout.js");
23 });
24
25
26 function makePayment(e, price, book_name){
27
28 e.preventDefault();
29
30
31 let formData = new FormData();
32 formData.append('price', price);
33 formData.append('product_name', book_name);
34
35 async function paymentGateway() {
36 const url = 'http://127.0.0.1:8000/payment/new-order' // <<< new-order backend api url path
37 const res = await fetch(url, { method: 'POST', body: formData ,
38 })
39 const jsonRes = await res.json()
40 return jsonRes
41 }
42
43 paymentGateway().then((res) =>{
44 //_________ call razorpay gateway ________
45 var options = {
46 "key": res['razorpay_key'],
47 "amount": res['order']['amount'],
48 "currency": res['order']['currency'],
49 "callback_url": res['callback_url'],
50 prefill: {
51 "email": "nosob88243@xitudy.com",
52 "contact": "1234567890"
53 },
54 "name": res['product_name'],
55 "order_id": res['order']['id'],
56 };
57
58 var rzp1 = new window.Razorpay(options);
59 rzp1.open();
60 })
61
62 }
63
64
65 return(
66 <>
67 <section className='flex justify-center mt-52'>
68 <div className='rounded px-10 py-2 text-center drop-shadow-lg bg-zinc-50'>
69 <h2 className='text-3xl mb-5'>Educated</h2>
70 <img className='w-48' src={Book1Img} alt="" />
71 <button type='button' className="mt-12 inline-flex items-center px-2.5 py-1.5 border border-transparent text-sm font-medium rounded shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
72 onClick={e=>{makePayment(e, 500, "Educated")}}
73 >Buy 500</button>
74 </div>
75 <div className='rounded px-10 py-2 text-center drop-shadow-lg bg-zinc-50 ml-10'>
76 <h2 className='text-3xl mb-5'>Atomic Habit</h2>
77 <img className='w-48' src={Book2Img} alt="" />
78 <button className="mt-12 inline-flex items-center px-2.5 py-1.5 border border-transparent text-sm font-medium rounded shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
79 onClick={e=>{makePayment(e, 800, "Atomic Habit")}}
80 >Buy 800</button>
81 </div>
82 </section>
83 </>
84 )
85
86}
Sample code for the above use case can be found in the following GitHub URL.
https://github.com/episyche/razorpay_django_reactjs_example/blob/main/frontend-reactjs/src/Card.jsx
To run Django development server:
1cd <project-folder>
2
3for example:
4cd cake-shop
1python3 manage.py runserver
To run React.js development server:
1cd <project-folder>
2
3for example:
4cd frontend
1npm start
Select any one product from the web page
Select UPI ID as the payment mode.
Enter the following UPI ID provided by Razorpay for Testing purposes. (success@razorpay)
After successful payment, you will get a success message as a response from the backend (Django).
Comments