Ver a proveniência

fix: update the checksum logic

pull/2/head
Mangesh-Khairnar há 5 anos
ascendente
cometimento
7fc4702bcd
3 ficheiros alterados com 92 adições e 142 eliminações
  1. +62
    -124
      payments/payment_gateways/doctype/paytm_settings/checksum.py
  2. +26
    -14
      payments/payment_gateways/doctype/paytm_settings/paytm_settings.json
  3. +4
    -4
      payments/payment_gateways/doctype/paytm_settings/paytm_settings.py

+ 62
- 124
payments/payment_gateways/doctype/paytm_settings/checksum.py Ver ficheiro

@@ -2,141 +2,79 @@ import base64
import string import string
import random import random
import hashlib import hashlib
import sys


from Crypto.Cipher import AES from Crypto.Cipher import AES




IV = "@@@@&&&&####$$$$"
iv = '@@@@&&&&####$$$$'
BLOCK_SIZE = 16 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)
if (sys.version_info > (3, 0)):
__pad__ = lambda s: bytes(s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE), 'utf-8')
else:
__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 encrypt(input, key):
input = __pad__(input)
c = AES.new(key.encode("utf8"), AES.MODE_CBC, iv.encode("utf8"))
input = c.encrypt(input)
input = base64.b64encode(input)
return input.decode("UTF-8")

def decrypt(encrypted, key):
encrypted = base64.b64decode(encrypted)
c = AES.new(key.encode("utf8"), AES.MODE_CBC, iv.encode("utf8"))
param = c.decrypt(encrypted)
if type(param) == bytes:
param = param.decode()
return __unpad__(param)

def generateSignature(params, key):
if not type(params) is dict and not type(params) is str:
raise Exception("string or dict expected, " + str(type(params)) + " given")
if type(params) is dict:
params = getStringByParams(params)
return generateSignatureByString(params, key)

def verifySignature(params, key, checksum):
if not type(params) is dict and not type(params) is str:
raise Exception("string or dict expected, " + str(type(params)) + " given")
if "CHECKSUMHASH" in params:
del params["CHECKSUMHASH"]
if type(params) is dict:
params = getStringByParams(params)
return verifySignatureByString(params, key, checksum)

def generateSignatureByString(params, key):
salt = generateRandomString(4)
return calculateChecksum(params, key, salt)

def verifySignatureByString(params, key, checksum):
paytm_hash = decrypt(checksum, key)
salt = paytm_hash[-4:] salt = paytm_hash[-4:]
calculated_checksum = generate_checksum(
param_dict, merchant_key, salt=salt)
return calculated_checksum == checksum
return paytm_hash == calculateHash(params, salt)


def generateRandomString(length):
chars = string.ascii_uppercase + string.digits + string.ascii_lowercase
return ''.join(random.choice(chars) for _ in range(length))


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):
def getStringByParams(params):
params_string = [] params_string = []
for key in sorted(params.keys()): for key in sorted(params.keys()):
if("REFUND" in params[key] or "|" in params[key]):
exit()
value = params[key]
params_string.append('' if value == 'null' else str(value))
value = params[key] if params[key] is not None and params[key].lower() != "null" else ""
params_string.append(str(value))
return '|'.join(params_string) return '|'.join(params_string)


def calculateHash(params, salt):
finalString = '%s|%s' % (params, salt)
hasher = hashlib.sha256(finalString.encode())
hashString = hasher.hexdigest() + salt
return hashString


def __pad__(s): return s + (BLOCK_SIZE - len(s) %
BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)


def __unpad__(s): return s[0:-ord(s[-1])]


def __encode__(to_encode, iv, key):
# Pad
to_encode = __pad__(to_encode)
# Encrypt
c = AES.new(key, AES.MODE_CBC, iv)
to_encode = c.encrypt(to_encode)
# 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, AES.MODE_CBC, iv)
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"))
def calculateChecksum(params, key, salt):
hashString = calculateHash(params, salt)
return encrypt(hashString, key)

+ 26
- 14
payments/payment_gateways/doctype/paytm_settings/paytm_settings.json Ver ficheiro

@@ -9,7 +9,7 @@
"merchant_key", "merchant_key",
"staging", "staging",
"column_break_4", "column_break_4",
"industry_type",
"industry_type_id",
"website" "website"
], ],
"fields": [ "fields": [
@@ -18,43 +18,55 @@
"fieldtype": "Data", "fieldtype": "Data",
"in_list_view": 1, "in_list_view": 1,
"label": "Merchant ID", "label": "Merchant ID",
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
}, },
{ {
"fieldname": "merchant_key", "fieldname": "merchant_key",
"fieldtype": "Password", "fieldtype": "Password",
"in_list_view": 1, "in_list_view": 1,
"label": "Merchant Key", "label": "Merchant Key",
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
}, },
{ {
"default": "0", "default": "0",
"fieldname": "staging", "fieldname": "staging",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Staging"
},
{
"depends_on": "eval: !doc.staging",
"fieldname": "industry_type",
"fieldtype": "Data",
"label": "Industry Type",
"mandatory_depends_on": "eval: !doc.staging"
"label": "Staging",
"show_days": 1,
"show_seconds": 1
}, },
{ {
"depends_on": "eval: !doc.staging", "depends_on": "eval: !doc.staging",
"fieldname": "website", "fieldname": "website",
"fieldtype": "Data", "fieldtype": "Data",
"label": "Website", "label": "Website",
"mandatory_depends_on": "eval: !doc.staging"
"mandatory_depends_on": "eval: !doc.staging",
"show_days": 1,
"show_seconds": 1
}, },
{ {
"fieldname": "column_break_4", "fieldname": "column_break_4",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval: !doc.staging",
"fieldname": "industry_type_id",
"fieldtype": "Data",
"label": "Industry Type ID",
"mandatory_depends_on": "eval: !doc.staging",
"show_days": 1,
"show_seconds": 1
} }
], ],
"issingle": 1, "issingle": 1,
"links": [], "links": [],
"modified": "2020-04-16 14:16:19.687449",
"modified": "2020-06-08 13:36:09.703143",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Integrations", "module": "Integrations",
"name": "Paytm Settings", "name": "Paytm Settings",


+ 4
- 4
payments/payment_gateways/doctype/paytm_settings/paytm_settings.py Ver ficheiro

@@ -13,7 +13,7 @@ from frappe import _
from frappe.utils import get_url, call_hook_method, cint, flt, cstr from frappe.utils import get_url, call_hook_method, cint, flt, cstr
from frappe.integrations.utils import create_request_log, create_payment_gateway from frappe.integrations.utils import create_request_log, create_payment_gateway
from frappe.utils import get_request_site_address from frappe.utils import get_request_site_address
from frappe.integrations.doctype.paytm_settings.checksum import generate_checksum, verify_checksum
from frappe.integrations.doctype.paytm_settings.checksum import generateSignature, verifySignature
from frappe.utils.password import get_decrypted_password from frappe.utils.password import get_decrypted_password


class PaytmSettings(Document): class PaytmSettings(Document):
@@ -75,7 +75,7 @@ def get_paytm_params(payment_details, order_id, paytm_config):
"CALLBACK_URL" : redirect_uri, "CALLBACK_URL" : redirect_uri,
}) })


checksum = generate_checksum(paytm_params, paytm_config.merchant_key)
checksum = generateSignature(paytm_params, paytm_config.merchant_key)


paytm_params.update({ paytm_params.update({
"CHECKSUMHASH" : checksum "CHECKSUMHASH" : checksum
@@ -101,7 +101,7 @@ def verify_transaction(**kwargs):


if paytm_params and paytm_config and paytm_checksum: if paytm_params and paytm_config and paytm_checksum:
# Verify checksum # Verify checksum
is_valid_checksum = verify_checksum(paytm_params, paytm_config.merchant_key, paytm_checksum)
is_valid_checksum = verifySignature(paytm_params, paytm_config.merchant_key, paytm_checksum)


if is_valid_checksum and received_data['RESPCODE'] == '01': if is_valid_checksum and received_data['RESPCODE'] == '01':
verify_transaction_status(paytm_config, received_data['ORDERID']) verify_transaction_status(paytm_config, received_data['ORDERID'])
@@ -118,7 +118,7 @@ def verify_transaction_status(paytm_config, order_id):
ORDERID= order_id ORDERID= order_id
) )


checksum = generate_checksum(paytm_params, paytm_config.merchant_key)
checksum = generateSignature(paytm_params, paytm_config.merchant_key)
paytm_params["CHECKSUMHASH"] = checksum paytm_params["CHECKSUMHASH"] = checksum


post_data = json.dumps(paytm_params) post_data = json.dumps(paytm_params)


Carregando…
Cancelar
Guardar