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.