Paytm payment gateway integration in Django

In this blog, I am going to show how to integrate Paytm payment integration in Django.

In order to integrate payment integration you need to have an ecommerce project, so make sure you have one. If not, then you can get the source code of an ecommerce website from my git repository and clone it.

source code:- https://github.com/devyani21/Ecomm

Let’s begin paytm payment gateway integration!!

First of all, you need to have a paytm merchant account in order to setup paytm payment gateway.So make sure you have one. By having a merchant account , you will get merchant Id and merchant key which you should not share with anyone.Also , you will get the test account credentials.

If you do not have a merchant account then simply go to https://business.paytm.com/blog/now-register-as-a-merchant-in-2-minutes/ and create a merchant account.

Let’s Start

Following are the steps involved in this paytm payment integration :-

  • Sign up and Login with Paytm
  • Created Merchant account and get SandBox creditientials.
  • Download paytm script from paytm documentations.
  • Make some changes as discussed below in your project files.
  • At last, run your project.

After you have performed first two steps , Now, we will create a new directory for Paytm integration. Double click on your project folder and create a new directory named Paytm. Inside this directory, create a new file named “Checksum.py.” You can also see paytm documentation at https://developer.paytm.com/docs/paytm-payouts/

  • Checksum.py
  • response.cgi
  • test.cgi

Copy the code of the Checksum.py file and paste in the Checksum.py file of the Paytm directory. Now, we need to make some changes in the checksum file. Type “.encode(‘utf-8’)” after “key”, “IV” and “to_encode”.  You can make the changes by yourself or you can simply copy the below code :

import base64
import string
import random
import hashlib

from Crypto.Cipher import AES


IV = "@@@@&&&&####$$$$"
BLOCK_SIZE = 16


def generate_checksum(param_dict, merchant_key, salt=None):
    params_string = __get_param_string__(param_dict)
    salt = salt if salt else __id_generator__(4)
    final_string = '%s|%s' % (params_string, salt)

    hasher = hashlib.sha256(final_string.encode())
    hash_string = hasher.hexdigest()

    hash_string += salt

    return __encode__(hash_string, IV, merchant_key)

def generate_refund_checksum(param_dict, merchant_key, salt=None):
    for i in param_dict:
        if("|" in param_dict[i]):
            param_dict = {}
            exit()
    params_string = __get_param_string__(param_dict)
    salt = salt if salt else __id_generator__(4)
    final_string = '%s|%s' % (params_string, salt)

    hasher = hashlib.sha256(final_string.encode())
    hash_string = hasher.hexdigest()

    hash_string += salt

    return __encode__(hash_string, IV, merchant_key)


def generate_checksum_by_str(param_str, merchant_key, salt=None):
    params_string = param_str
    salt = salt if salt else __id_generator__(4)
    final_string = '%s|%s' % (params_string, salt)

    hasher = hashlib.sha256(final_string.encode())
    hash_string = hasher.hexdigest()

    hash_string += salt

    return __encode__(hash_string, IV, merchant_key)


def verify_checksum(param_dict, merchant_key, checksum):
    # Remove checksum
    if 'CHECKSUMHASH' in param_dict:
        param_dict.pop('CHECKSUMHASH')

    # Get salt
    paytm_hash = __decode__(checksum, IV, merchant_key)
    salt = paytm_hash[-4:]
    calculated_checksum = generate_checksum(param_dict, merchant_key, salt=salt)
    return calculated_checksum == checksum

def verify_checksum_by_str(param_str, merchant_key, checksum):
    # Remove checksum
    #if 'CHECKSUMHASH' in param_dict:
        #param_dict.pop('CHECKSUMHASH')

    # Get salt
    paytm_hash = __decode__(checksum, IV, merchant_key)
    salt = paytm_hash[-4:]
    calculated_checksum = generate_checksum_by_str(param_str, merchant_key, salt=salt)
    return calculated_checksum == checksum



def __id_generator__(size=6, chars=string.ascii_uppercase + string.digits + string.ascii_lowercase):
    return ''.join(random.choice(chars) for _ in range(size))


def __get_param_string__(params):
    params_string = []
    for key in sorted(params.keys()):
        if("REFUND" in params[key] or "|" in params[key]):
            respons_dict = {}
            exit()
        value = params[key]
        params_string.append('' if value == 'null' else str(value))
    return '|'.join(params_string)


__pad__ = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
__unpad__ = lambda s: s[0:-ord(s[-1])]


def __encode__(to_encode, iv, key):
    # Pad
    to_encode = __pad__(to_encode)
    # Encrypt
    c = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv.encode('utf-8'))
    to_encode = c.encrypt(to_encode.encode('utf-8'))
    # Encode
    to_encode = base64.b64encode(to_encode)
    return to_encode.decode("UTF-8")


def __decode__(to_decode, iv, key):
    # Decode
    to_decode = base64.b64decode(to_decode)
    # Decrypt
    c = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv.encode('utf-8'))
    to_decode = c.decrypt(to_decode)
    if type(to_decode) == bytes:
        # convert bytes array to str.
        to_decode = to_decode.decode()
    # remove pad
    return __unpad__(to_decode)


if __name__ == "__main__":
    params = {
        "MID": "mid",
        "ORDER_ID": "order_id",
        "CUST_ID": "cust_id",
        "TXN_AMOUNT": "1",
        "CHANNEL_ID": "WEB",
        "INDUSTRY_TYPE_ID": "Retail",
        "WEBSITE": "xxxxxxxxxxx"
    }

    print(verify_checksum(
        params, 'xxxxxxxxxxxxxxxx',
        "CD5ndX8VVjlzjWbbYoAtKQIlvtXPypQYOg0Fi2AUYKXZA5XSHiRF0FDj7vQu66S8MHx9NaDZ/uYm3WBOWHf+sDQAmTyxqUipA7i1nILlxrk="))

    # print(generate_checksum(params, "xxxxxxxxxxxxxxxx"))

Run the Checksum.py file and if you see the output as TRUE then everything is working correctly.

Now, we need to fetch the details of the user so that the Paytm can deduct the billing amount from the user’s account and transfer it to our Paytm merchant account. Open the views.py of the your app and type the below code :-


    #request paytm to transfer the amount to your account after payment by user
    param_dict={

            'MID': 'Your_merchant_id',
            'ORDER_ID': 'order.order_id',
            'TXN_AMOUNT': '1',
            'CUST_ID': 'your_email',
            'INDUSTRY_TYPE_ID': 'Retail',
            'WEBSITE': 'WEBSTAGING',
            'CHANNEL_ID': 'WEB',
            'CALLBACK_URL':'http://127.0.0.1:8000/your_app/handlepayment/',

    }
    return  render(request, 'your_app/paytm.html', {'param_dict': param_dict})
    return render(request, 'your_app/checkout.html')

@csrf_exempt
def handlerequest(request):
    # paytm will send you post request here
    form = request.POST
    response_dict = {}
    for i in form.keys():
        response_dict[i] = form[i]
        if i == 'CHECKSUMHASH':
            checksum = form[i]

    verify = Checksum.verify_checksum(response_dict, MERCHANT_KEY, checksum)
    if verify:
        if response_dict['RESPCODE'] == '01':
            print('order successful')
        else:
            print('order was not successful because' + response_dict['RESPMSG'])
    return render(request, 'your_app/paymentstatus.html', {'response': response_dict})

Let’s understand the arguments passed in the param_dict dictionary in the above code.

  • Merchant id: It is the merchant id given to you by the Paytm while signing up for the Paytm merchant account.
  • Order id: It is the id of the user’s order. In the above code, we are fetching the order id from our database.
  • Customer id: In the above code, we are using the user’s email address as the customer id.
  • Callback URL: It is the URL where you want the Paytm to show you the status of the payment.

Now, we will create a new template to handle the param_dict dictionary that we’ve just created in the above step. Double click on the templates folder and create a new file named “paytm.html.”

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Paytm merchant payment page</title>
</head>
<body>
<h1>Redirecting you to the merchant....</h1>
<h1>Please do not refresh your page....</h1>
<form action="https://securegw-stage.paytm.in/theia/processTransaction" method="post" name="paytm">
    {% for key, value in param_dict.items %}
    <input type="hidden" name="{{key}}" value="{{value}}">
    {% endfor %}

</form>
</body>
<script>
document.paytm.submit()
</script>
</html>

Create another file in the templates folder named as paymentstatus.html so the status of the transaction can be displayed:-

{% extends 'your_app/basic.html' %}
{% block title%} Your App{% endblock %}
{% block body %}
<div class="container">
    {{response}}
    <div class="col my-4">

        <h2>Payment status regarding your order Id {{response.ORDERID}}</h2>
        {% if response.RESPCODE == '01' %}
        ORDER SUCCESS
        {% else %}
        ORDER FAILURE
        {% endif%}

    </div>

</div>
{% endblock %}
{% block js %}
<script>
</script>
{% endblock %}

Now add the url pattern for handlerequest page in the urls of your app:-

from django.urls import path
from . import views

urlpatterns = [
    path("handlerequest/", views.handlerequest, name="HandleRequest"),
    ...
]

So here our paytm payment gateway integration is done!!

Now run your project, it should work fine.