“生产”模式下 Paytm Django 集成错误

问题描述

我正致力于将 Paytm 集成到我的 Django 项目中。它在演示运行中运行良好,即登台。当我尝试为生产运行它时,它开始抛出错误。校验和在生产中不匹配。

Paytm/Checksum.py

# pip install pycryptodome
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,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,merchant_key)


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


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

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

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

    # Get salt
    paytm_hash = __decode__(checksum,merchant_key)
    salt = paytm_hash[-4:]
    calculated_checksum = generate_checksum_by_str(param_str,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,key):
    # Decode
    to_decode = base64.b64decode(to_decode)
    # Decrypt
    c = AES.new(key.encode('utf-8'),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"))

views.py

def orderproduct(request):
    category = Category.objects.all()
    current_user = request.user
    shopcart = ShopCart.objects.filter(user_id=current_user.id)
    total = 0
    for rs in shopcart:
        total += rs.product.price * rs.quantity

    if request.method == 'POST':  # if there is a post
        form = OrderForm(request.POST)
        # return HttpResponse(request.POST.items())
        if form.is_valid():
            data = Order()
            data.first_name = form.cleaned_data['first_name']
            data.last_name = form.cleaned_data['last_name']
            data.address = form.cleaned_data['address']
            data.city = form.cleaned_data['city']
            data.country = form.cleaned_data['country']
            data.phone = form.cleaned_data['phone']
            data.user_id = current_user.id
            data.total = total
            data.ip = request.META.get('REMOTE_ADDR')
            ordercode = get_random_string(5).upper()  # random cod
            data.code = ordercode
            data.save()

            for rs in shopcart:
                detail = OrderProduct()
                detail.order_id = data.id  # Order Id
                detail.product_id = rs.product_id
                detail.user_id = current_user.id
                detail.quantity = rs.quantity
                detail.price = rs.product.price

                # detail.variant_id   = rs.variant_id
                detail.amount = rs.amount
                detail.save()
                # ***Reduce quantity of sold product from Amount of Product
                product = Product.objects.get(id=rs.product_id)
                product.amount -= rs.quantity
                product.save()

                # ************ <> *****************
            ShopCart.objects.filter(user_id=current_user.id).delete() # Clear & Delete shopcart
            request.session['cart_items']=0
            amount = int(total)

        # Request paytm to transfer the amount to your account after payment by user
            param_dict = {
                'MID': 'MY_MERCHANT_ID','ORDER_ID': str(ordercode),'TXN_AMOUNT': str(amount),'CUST_ID': request.user.email,'INDUSTRY_TYPE_ID': 'Retail','WEBSITE': 'WEBSTAGING','CHANNEL_ID': 'WEB','CALLBACK_URL': 'http://127.0.0.1:8000/order/handlerequest/',}
            param_dict['CHECKSUMHASH'] = Checksum.generate_checksum(
                param_dict,MERCHANT_KEY)
            return render(request,'order/paytm.html',{'param_dict': param_dict})
            # Clear & Delete shopcart
            
            return render(request,'order/order_completed.html',{'ordercode': ordercode,'category': category})
        else:
            messages.warning(request,form.errors)
            return HttpResponseRedirect("/order/orderproduct")

    form = OrderForm()
    profile = UserProfile.objects.filter(user_id=current_user.id)
    context = {'shopcart': shopcart,'category': category,'total': total,'form': form,'profile': profile,}
    return render(request,'order/order_form.html',context)

@csrf_exempt
def handlerequest(request):
    # paytm will send you post request here
    form = request.POST
    # print(form)
    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':
            ShopCart.objects.filter(user_id=request.user.id).delete()
            request.session['cart_items'] = 0
            order = Order.objects.get(code = form['ORDERID'])
            order.paid = True
            order.save()
            messages.success(
                request,"Your Order has been completed. Thank you ")
            print('order successful')
        else:
            print('order was not successful because' + response_dict['RESPMSG'])
    return render(request,'order/paymentstatus.html',{'response': response_dict})

models.py

class Order(models.Model):
    STATUS = (
        ('New','New'),('Accepted','Accepted'),('Preaparing','Preaparing'),('OnShipping','OnShipping'),('Completed','Completed'),('Canceled','Canceled'),)
    user = models.ForeignKey(User,on_delete=models.SET_NULL,null=True)
    code = models.CharField(max_length=5,editable=False )
    first_name = models.CharField(max_length=10)
    last_name = models.CharField(max_length=10)
    phone = models.CharField(blank=True,max_length=20)
    address = models.CharField(blank=True,max_length=150)
    city = models.CharField(blank=True,max_length=20)
    country = models.CharField(blank=True,max_length=20)
    total = models.FloatField()
    status=models.CharField(max_length=10,choices=STATUS,default='New')
    ip = models.CharField(blank=True,max_length=20)
    adminnote = models.CharField(blank=True,max_length=100)
    create_at=models.DateTimeField(auto_now_add=True)
    update_at=models.DateTimeField(auto_now=True)
    paid = models.BooleanField(default=False)

    def __str__(self):
        return self.user.first_name

#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>

演示的表单操作如上所述。但对于生产,我尝试过:“https://securegw-stage.paytm.in/theia/processTransaction”。

当我运行演示时。一切正常。校验和匹配,交易成功。 但是当我尝试运行生产时,弹出的错误是:

UnboundLocalError at /order/handlerequest/
local variable 'checksum' referenced before assignment

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)