HomeAll GuidesSample AppsDev Studio

linkIntegrate Cashfree Payments' Payment Gateway in Your Django App Effortlessly

In this tutorial, we'll integrate Cashfree Payments' payment gateway into a basic e-commerce application built with Django. This tutorial will walk you through the steps to set up the application, create orders, and handle payments using the Cashfree Python SDK.

We'll use a basic e-commerce app as our example, which you can find in the GitHub repository for your reference.

linkOverview of the E-commerce App

Our e-commerce app has the following features:

  1. Landing Page: Displays a list of products fetched from an API.
  2. Cart Functionality: Allows users to add products to the cart, adjust quantities, and view the cart.
  3. Checkout Process: Uses Cashfree Payments' gateway to handle payments.

ecommerce-demo

Try Cashfree Dev Studio: Cashfree offers an SDK & API playground for developers. You can freely explore, experiment, and play with various APIs and SDKs offered by Cashfree Payments.

linkStep 1: Set Up Your Django Project

First, ensure you have Django installed. If not, install it using pip:

1link$pip install django

Create a new Django project and app:

1link$django-admin startproject ecommerce

2link$cd ecommerce

3link$django-admin startapp shop

linkStep 2: Install Cashfree Python SDK

Install the Cashfree Python SDK using pip:

1link$pip install cashfree_pg

linkStep 3: Configure Cashfree in Your Django Project

Create a file named cashfree_config.py in your Django app directory (shop) and add the following configuration:

1link# shop/cashfree_config.py

2linkfrom cashfree_pg.api_client import Cashfree

3link

4linkCashfree.XClientId = 'YOUR_CLIENT_ID'

5linkCashfree.XClientSecret = 'YOUR_CLIENT_SECRET'

6linkCashfree.XEnvironment = Cashfree.SANDBOX # Use Cashfree.PRODUCTION for live environment

7link

Replace 'YOUR_CLIENT_ID' and 'YOUR_CLIENT_SECRET' with your actual Cashfree credentials. You can find the Client ID and Secret from the Developers section of the Cashfree Payments’ Merchant Dashboard.

linkStep 4: Update Views to Handle Orders and Payments

In views.py, add the necessary imports and views to handle creating orders and processing payments.

1link# shop/views.py

2linkimport requests

3linkfrom django.shortcuts import render, redirect

4linkfrom django.http import JsonResponse

5linkfrom cashfree_pg.models.create_order_request import CreateOrderRequest

6linkfrom cashfree_pg.api_client import Cashfree

7linkfrom cashfree_pg.models.customer_details import CustomerDetails

8linkfrom cashfree_pg.models.order_meta import OrderMeta

9linkfrom django.views.decorators.csrf import csrf_exempt

10linkimport json

11link

12link# Import Cashfree configuration

13linkfrom .cashfree_config import Cashfree

14link

15linkdef landing_page(request):

16link response = requests.get('<https://fakestoreapi.com/products>')

17link products = response.json()

18link return render(request, 'shop/landing_page.html', {'products': products})

19link

20linkdef cart_page(request):

21link cart = request.session.get('cart', {})

22link cart_items = []

23link for product_id, details in cart.items():

24link cart_items.append({

25link 'id': product_id,

26link 'title': details.get('title', 'No Title'),

27link 'description': details.get('description', ''),

28link 'image': details.get('image', '<https://via.placeholder.com/80>'), # Default placeholder image

29link 'price': details.get('price', 0.0),

30link 'quantity': details.get('quantity', 1)

31link })

32link return render(request, 'shop/cart_page.html', {'cart_items': cart_items})

33link

34link@csrf_exempt

35linkdef create_order(request):

36link if request.method == 'POST':

37link cart_data = request.POST.get('cart')

38link if not cart_data:

39link return JsonResponse({'status': 'error', 'message': 'Cart is empty'})

40link

41link try:

42link cart = json.loads(cart_data)

43link except json.JSONDecodeError:

44link return JsonResponse({'status': 'error', 'message': 'Invalid cart data'})

45link

46link total_amount = 0.0

47link for item in cart.values():

48link try:

49link price = float(item['price'])

50link quantity = int(item['quantity'])

51link total_amount += price * quantity

52link except ValueError as e:

53link return JsonResponse({'status': 'error', 'message': f"Error parsing price or quantity for item {item['id']}"})

54link

55link if total_amount < 1:

56link return JsonResponse({'status': 'error', 'message': 'Total amount must be at least 1'})

57link

58link customer_details = CustomerDetails(customer_id="123", customer_phone="9999999999")

59link create_order_request = CreateOrderRequest(order_amount=total_amount, order_currency="INR", customer_details=customer_details)

60link order_meta = OrderMeta(return_url="<http://localhost:8000/successfull/>")

61link create_order_request.order_meta = order_meta

62link

63link try:

64link api_response = Cashfree().PGCreateOrder("2023-08-01", create_order_request, None, None)

65link payment_session_id = api_response.data.payment_session_id

66link return JsonResponse({'status': 'success', 'payment_session_id': payment_session_id})

67link except Exception as e:

68link return JsonResponse({'status': 'error', 'message': f'Error creating order: {str(e)}'})

69link

70link return JsonResponse({'status': 'error', 'message': 'Invalid request method'})

71link

72linkdef success_page(request):

73link cart = request.session.get('cart', {})

74link cart_items = []

75link for product_id, details in cart.items():

76link cart_items.append({

77link 'id': product_id,

78link 'title': details.get('title', 'No Title'),

79link 'price': details.get('price', 0.0),

80link 'quantity': details.get('quantity', 1)

81link })

82link request.session['cart'] = {}

83link return render(request, 'shop/successfull.html', {'cart_items': cart_items})

linkStep 5: Create Templates

Create the necessary HTML templates to handle the cart, payment, and success pages.

link1. landing_page.html

1link<!-- shop/templates/shop/landing_page.html -->

2linkload static %}

3link<!DOCTYPE html>

4link<html lang="en">

5link <head>

6link <meta charset="UTF-8" />

7link <meta name="viewport" content="width=device-width, initial-scale=1.0" />

8link <title>Landing Page</title>

9link <link rel="stylesheet" type="text/css" href=" static 'css/styles.css' %}" />

10link <script src="<https://code.jquery.com/jquery-3.6.0.min.js>"></script>

11link </head>

12link <body>

13link <div class="navbar">

14link <div class="logo">Fakeazon</div>

15link <a href=" url 'cart_page' %}" class="cart">Cart (<span id="cart-count">0</span>)</a>

16link </div>

17link <div class="container">

18link <div class="header">

19link <h1>Get Inspired</h1>

20link <p>

21link Browsing for your next long-haul trip, everyday journey, or just fancy a look at what's new? From community favourites to about-to-sell-out items, see

22link them all here.

23link </p>

24link </div>

25link <div class="filters">

26link <select>

27link <option>All Categories</option>

28link </select>

29link <select>

30link <option>All Colors</option>

31link </select>

32link <select>

33link <option>All Features</option>

34link </select>

35link <select>

36link <option>From ₹0 - ₹1000</option>

37link </select>

38link <select>

39link <option>New In</option>

40link </select>

41link </div>

42link <div class="product-grid">

43link for product in products %}

44link <div class="product-item">

45link <img src="{{ product.image }}" alt="{{ product.title }}" />

46link <h2>{{ product.title }}</h2>

47link <p>₹{{ product.price }}</p>

48link <div class="product-actions">

49link <button

50link class="add-to-cart"

51link data-id="{{ product.id }}"

52link data-title="{{ product.title }}"

53link data-description="{{ product.description }}"

54link data-image="{{ product.image }}"

55link data-price="{{ product.price }}"

56link >

57link Add to cart

58link </button>

59link <div class="quantity-selector" data-id="{{ product.id }}" style="display: none;">

60link <button class="decrease" data-id="{{ product.id }}">-</button>

61link <span class="quantity" data-id="{{ product.id }}">1</span>

62link <button class="increase" data-id="{{ product.id }}">+</button>

63link </div>

64link </div>

65link </div>

66link endfor %}

67link </div>

68link </div>

69link <script>

70link let cart = JSON.parse(localStorage.getItem("cart")) || {};

71link

72link function updateCartCount() {

73link let count = 0;

74link for (let id in cart) {

75link count += cart[id].quantity;

76link }

77link

78link $("#cart-count").text(count);

79link }

80link

81link function updateQuantity(productId, quantity) {

82link if (quantity <= 0) {

83link delete cart[productId];

84link $(`.product-item .add-to-cart[data-id=${productId}]`).show();

85link $(`.product-item .quantity-selector[data-id=${productId}]`).hide();

86link } else {

87link cart[productId].quantity = quantity;

88link $(`.product-item .quantity[data-id=${productId}]`).text(quantity);

89link }

90link localStorage.setItem("cart", JSON.stringify(cart));

91link updateCartCount();

92link }

93link

94link $(document).ready(function () {

95link // Update cart count on page load

96link updateCartCount();

97link

98link $(".add-to-cart").click(function () {

99link const productId = $(this).data("id");

100link const title = $(this).data("title");

101link const description = $(this).data("description");

102link const image = $(this).data("image");

103link const price = $(this).data("price");

104link

105link if (!cart[productId]) {

106link cart[productId] = { id: productId, title, description, image, price, quantity: 1 };

107link }

108link

109link localStorage.setItem("cart", JSON.stringify(cart));

110link updateCartCount();

111link

112link $(this).hide();

113link $(`.product-item .quantity-selector[data-id=${productId}]`).show();

114link });

115link

116link $(".increase").click(function () {

117link const productId = $(this).data("id");

118link const quantity = cart[productId].quantity + 1;

119link updateQuantity(productId, quantity);

120link });

121link

122link $(".decrease").click(function () {

123link const productId = $(this).data("id");

124link const quantity = cart[productId].quantity - 1;

125link updateQuantity(productId, quantity);

126link });

127link });

128link </script>

129link </body>

130link</html>

This template displays a list of products. It handles adding products to the cart and updating quantities.

link2. cart_page.html

1link<!-- shop/templates/shop/cart_page.html -->

2linkload static %}

3link<!DOCTYPE html>

4link<html lang="en">

5link <head>

6link <meta charset="UTF-8" />

7link <meta name="viewport" content="width=device-width, initial-scale=1.0" />

8link <title>Cart Page</title>

9link <link rel="stylesheet" type="text/css" href=" static 'css/styles.css' %}" />

10link <script src="<https://code.jquery.com/jquery-3.6.0.min.js>"></script>

11link <script src="<https://sdk.cashfree.com/js/v3/cashfree.js>"></script>

12link </head>

13link

14link <body>

15link <div class="navbar">

16link <div class="logo">Fakeazon</div>

17link <a href=" url 'cart_page' %}" class="cart">Cart (<span id="cart-count">0</span>)</a>

18link </div>

19link <div class="container">

20link <div class="cart-container">

21link <div class="cart-header">

22link <a href=" url 'landing_page' %}">Continue Shopping</a>

23link <h1>Shopping Cart</h1>

24link </div>

25link <div class="cart-items">

26link <!-- Cart items will be dynamically loaded here -->

27link </div>

28link <form>

29link csrf_token %}

30link <div class="cart-total">

31link <div class="total-amount">Total: ₹<span id="total-amount">0.00</span></div>

32link <button type="button" class="pay-now" disabled>Pay Now</button>

33link </div>

34link </form>

35link </div>

36link </div>

37link <script>

38link const cashfree = Cashfree({

39link mode: "sandbox",

40link });

41link

42link let cart = JSON.parse(localStorage.getItem("cart")) || {};

43link

44link function updateCartCount() {

45link let count = 0;

46link for (let id in cart) {

47link count += cart[id].quantity;

48link }

49link $("#cart-count").text(count);

50link }

51link

52link function updateTotalAmount() {

53link let total = 0;

54link for (let id in cart) {

55link total += parseFloat(cart[id].price) * parseInt(cart[id].quantity);

56link }

57link $("#total-amount").text(total.toFixed(2));

58link if (total > 0) {

59link $(".pay-now").prop("disabled", false);

60link } else {

61link $(".pay-now").prop("disabled", true);

62link }

63link }

64link

65link function updateQuantity(productId, quantity) {

66link if (quantity <= 0) {

67link delete cart[productId];

68link $(`.cart-item[data-id=${productId}]`).remove();

69link } else {

70link cart[productId].quantity = quantity;

71link $(`.cart-item .quantity[data-id=${productId}]`).text(quantity);

72link }

73link localStorage.setItem("cart", JSON.stringify(cart));

74link updateCartCount();

75link updateTotalAmount();

76link }

77link

78link function loadCartItems() {

79link const cartContainer = $(".cart-items");

80link cartContainer.empty();

81link

82link for (let id in cart) {

83link const item = cart[id];

84link const cartItemHtml = `

85link <div class="cart-item" data-id="${item.id}">

86link <img src="${item.image}" alt="${item.title}">

87link <div class="cart-item-details">

88link <h2>${item.title}</h2>

89link <p>${item.description}</p>

90link </div>

91link <div class="cart-item-actions">

92link <button class="decrease" data-id="${item.id}">-</button>

93link <span class="quantity" data-id="${item.id}">${item.quantity}</span>

94link <button class="increase" data-id="${item.id}">+</button>

95link <span class="price">₹${item.price}</span>

96link <button class="delete" data-id="${item.id}">&#128465;</button>

97link </div>

98link </div>

99link `;

100link cartContainer.append(cartItemHtml);

101link }

102link }

103link

104link $(document).ready(function () {

105link // Load cart items on page load

106link loadCartItems();

107link updateCartCount();

108link updateTotalAmount();

109link

110link // Handle increase and decrease buttons

111link $(document).on("click", ".increase", function () {

112link const productId = $(this).data("id");

113link const quantity = cart[productId].quantity + 1;

114link updateQuantity(productId, quantity);

115link });

116link

117link $(document).on("click", ".decrease", function () {

118link const productId = $(this).data("id");

119link const quantity = cart[productId].quantity - 1;

120link updateQuantity(productId, quantity);

121link });

122link

123link // Handle delete button

124link $(document).on("click", ".delete", function () {

125link const productId = $(this).data("id");

126link updateQuantity(productId, 0);

127link });

128link

129link // Handle Pay Now button click

130link $(".pay-now").click(function () {

131link const csrftoken = $('input[name="csrfmiddlewaretoken"]').val();

132link const cartData = JSON.stringify(cart);

133link console.log("Cart data being sent:", cart);

134link $.ajax({

135link url: "/create-order/",

136link method: "POST",

137link headers: { "X-CSRFToken": csrftoken },

138link data: { cart: cartData },

139link success: function (response) {

140link if (response.status === "success") {

141link const paymentSessionId = response.payment_session_id;

142link const checkoutOptions = {

143link paymentSessionId: paymentSessionId,

144link redirectTarget: "_self",

145link };

146link cashfree.checkout(checkoutOptions);

147link } else {

148link alert("Failed to create order: " + response.message);

149link }

150link },

151link error: function () {

152link alert("Failed to create order. Please try again.");

153link },

154link });

155link });

156link });

157link </script>

158link </body>

159link</html>

This template includes the necessary JavaScript to handle cart operations and initiate the payment process. On clicking the "Pay Now" button, it creates an order and opens the Cashfree checkout page.

link3. success_page.html

1link<!-- shop/templates/shop/successfull.html -->

2linkload static %}

3link<!DOCTYPE html>

4link<html lang="en">

5link <head>

6link <meta charset="UTF-8" />

7link <meta name="viewport" content="width=device-width, initial-scale=1.0" />

8link <title>Order Successful</title>

9link <link rel="stylesheet" type="text/css" href=" static 'css/styles.css' %}" />

10link </head>

11link <body>

12link <div class="container">

13link <div class="success-container">

14link <h1>Order Successful</h1>

15link <p>Thank you for your purchase! Here are your order details:</p>

16link <ul>

17link for item in cart_items %}

18link <li>{{ item.title }} - Quantity: {{ item.quantity }} - Price: ₹{{ item.price }}</li>

19link endfor %}

20link </ul>

21link <p>Redirecting to the landing page in <span id="countdown">10</span> seconds...</p>

22link </div>

23link </div>

24link <script>

25link let countdown = 10;

26link const countdownElement = document.getElementById("countdown");

27link

28link setInterval(() => {

29link countdown -= 1;

30link countdownElement.textContent = countdown;

31link if (countdown <= 0) {

32link localStorage.removeItem("cart");

33link window.location.href = "/";

34link }

35link }, 1000);

36link </script>

37link </body>

38link</html>

This template shows the order success details and redirects the user back to the landing page after 10 seconds, clearing the cart.

ecommerce-demo

linkStyling

To style your e-commerce application, you can use the provided CSS file. Ensure you create a styles.css file in your static folder and link it to your HTML templates. Here is how you can do it:

  1. Create a CSS file named styles.css in the static/css directory of your Django project.
  2. Link the CSS file in your HTML templates by adding the following line in the <head> section:
1link<link rel="stylesheet" type="text/css" href="static 'css/styles.css' %}" />

For a detailed CSS styling reference, you can check the styles.css file in the GitHub repository.

This CSS file will include styles for:

Ensure your Django settings are correctly configured to serve static files during development by including STATICFILES_DIRS in your settings.py.

1linkSTATICFILES_DIRS = [

2link os.path.join(BASE_DIR, 'shop/static'),

3link]

linkConclusion

In this tutorial, we've walked through the integration of Cashfree Payments' payment gateway into a Django e-commerce application. By following these steps, you can seamlessly handle payments in your Django projects using the Cashfree Python SDK.

You can find the complete source code for this project in the GitHub repository. Feel free to clone it and use it as a reference for your projects.

If you have any questions or run into issues, refer to the Cashfree Documentation for more details or join the Discord community for developer support.

Integrate Cashfree Payments' Payment Gateway in Your Django App EffortlesslyOverview of the E-commerce AppStep 1: Set Up Your Django ProjectStep 2: Install Cashfree Python SDKStep 3: Configure Cashfree in Your Django ProjectStep 4: Update Views to Handle Orders and PaymentsStep 5: Create Templates1. landing_page.html2. cart_page.html3. success_page.htmlStylingConclusion

Home