【发布时间】:2019-05-17 11:52:49
【问题描述】:
我的问题是在我的电子商务项目中实施支付网关。我使用的支付网关是来自印度国家的“Paytm”。
访问他们的网站后,https://developer.paytm.com/docs/v1/payment-gateway。
我收集了我的测试 ID 和密钥。
我有一个结帐页面,一旦用户输入他/她的详细信息。他被重定向到带有订单 ID 的成功下单页面。 一切正常。
但是,现在当我开始实施支付网关时,我在订单应用程序的 views.py 文件中遇到错误“'DeferredAttribute' 类型的参数不可迭代”。
首先我用 pip3 安装了 pycryptodome
我在我的 src 文件夹下创建了一个名为“payTm”的目录。我制作了一个名为“Checksum.py”的新python文件。(我从paytm的网站复制粘贴)
所以我的问题出现在我的views.py文件下。
views.py(在订单应用中)
from django.shortcuts import render
from .models import OrderItem , Order
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from .forms import OrderCreateForm
from cart.cart import Cart
from payTm import Checksum
from django.http import HttpResponse
MERCHANT_KEY = 'my_merchant_key';
@csrf_exempt
def handlerequest(request):
return HttpResponse('done')
pass
@login_required
def order_create(request):
cart = Cart(request)
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save()
for item in cart:
OrderItem.objects.create(
order=order,
product=item['product'],
price=item['price'],
quantity=item['quantity'],
total_price=item['total_price'],
)
cart.clear()
param_dict = {
'MID': 'my_merchant_id',
'ORDER_ID': str(Order.id),
'TXN_AMOUNT': Order.total_cost,
'CUST_ID': Order.email,
'INDUSTRY_TYPE_ID': 'Retail',
'WEBSITE': 'WENSTAGING',
'CHANNEL_ID': 'WEB',
'CALLBACK_URL': 'http://127.0.0.1:8000/handlerequest',
}
param_dict['CHECKSUMHASH'] =
Checksum.generate_checksum(param_dict, MERCHANT_KEY)
return render(request, 'paytm.html', {'order': order},
{'param_dict': param_dict})
else:
form = OrderCreateForm()
return render(request, 'create.html', {'form': form})
服务器运行没有任何错误。
但是错误输出是:
这是我的 html 页面。 帖子 URL 链接由 paytm 本身从他们的网站提供。 paytm.html
{% extends 'base.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 don't refresh this 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>
校验和.py
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/u
Ym3WBOWHf+sDQAmTyxqUipA7i1nILlxrk="))
# print(generate_checksum(params, "xxxxxxxxxxxxxxxx"))
可能是什么错误?或者我应该做些什么改变?如果我的商家密钥和 ID 凭据有任何错误,我已经交叉检查了很多次,但没有。
【问题讨论】:
-
回溯显示错误发生在
Checksum.__get_param_string。你需要证明这一点。 -
感谢您的评论。我已经添加了我的 Checksum.py
标签: python django payment-gateway