本節將繼續完成的虛擬訂單請求發送
以下是完整程式碼
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import json
import uuid
import requests
import hashlib
def get_hash_id(hash_a1, hash_a2, hash_b1, hash_b2):
hash_a = format((int(hash_a1, 16) ^ int(hash_a2, 16)), 'x')
hash_b = format((int(hash_b1, 16) ^ int(hash_b2, 16)), 'x')
hash_id = hash_a + hash_b
return hash_id.upper()
def get_nonce(shop_no):
nonce_url = "https://sandbox.sinopac.com/QPay.WebAPI/api/Nonce"
req_body = {"ShopNo": shop_no}
r = requests.post(url=nonce_url, json = req_body)
return r.json()["Nonce"]
def get_iv(nonce):
sha_nonce_value = hashlib.sha256(nonce.encode("utf-8")).hexdigest().upper()
return sha_nonce_value[-16:]
def get_message_hash(data):
sorted_key_list = sorted(data.keys())
first = True
result = ""
for key in sorted_key_list:
if type(data[key]) != dict:
if first:
temp = key + "=" + str(data[key])
first = False
else:
temp = "&" + key + "=" + str(data[key])
result += temp
return result
def get_sign(data, nonce, hash_id):
hash_value = data + nonce + hash_id
return hashlib.sha256(hash_value.encode("utf-8")).hexdigest().upper()
def aes_encrypt(key, content, iv):
cipher = AES.new(key.encode("utf8"), AES.MODE_CBC, iv.encode("utf8"))
return cipher.encrypt(pad(content.encode("utf8"), AES.block_size))
def get_message(hash_id, data, iv):
print('IV: ' + iv)
encrypt_data = aes_encrypt(hash_id, data, iv)
return encrypt_data.hex().upper()
def get_order_no(need_pay):
order = str(uuid.uuid4())
if need_pay:
order = order + "1"
else:
order = order + "9"
return order
def get_order(shop_no, need_pay, return_url, backend_url, hash_a1, hash_a2, hash_b1, hash_b2, amount):
url = 'https://sandbox.sinopac.com/QPay.WebAPI/api/Order'
origin_message = {
'ShopNo': shop_no,
'OrderNo': get_order_no(need_pay),
'Amount': amount * 100,
'CurrencyID': 'TWD',
'PayType': 'A',
'ATMParam': {
'ExpireDate': '20210929'
},
'CardParam': {},
'PrdtName': '虛擬帳號訂單',
'ReturnURL': return_url,
'BackendURL': backend_url
}
origin_json_message = json.dumps(origin_message, ensure_ascii=False, separators=(',', ':'))
hash_id = get_hash_id(hash_a1, hash_a2, hash_b1, hash_b2)
nonce = get_nonce(shop_no)
sign = get_sign(get_message_hash(origin_message), nonce, hash_id)
messge = get_message(hash_id, origin_json_message, get_iv(nonce))
reqest_body = {
'Version': '1.0.0',
'ShopNo': shop_no,
'APIService': 'OrderCreate',
'Sign': sign,
'Nonce': nonce,
'Message': messge
}
r = requests.post(url=url, json=reqest_body)
return r.json()
shop_no = 'NA0249_001'
hash_a1 = '86D50DEF3EB7400E'
hash_a2 = '01FD27C09E5549E5'
hash_b1 = '9E004965F4244953'
hash_b2 = '7FB3385F414E4F91'
need_pay = True
order_url = 'https://sandbox.sinopac.com/QPay.WebAPI/api/Order'
return_url = 'http://10.11.22.113:8803/QPay.ApiClient/Store/Return'
backend_url = 'http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess'
print(get_order(shop_no, need_pay, return_url, backend_url, hash_a1, hash_a2, hash_b1, hash_b2, 500))
response為
{
"Version": "1.0.0",
"ShopNo": "NA0249_001",
"APIService": "OrderCreate",
"Sign": "6E185202050FADCF5672F95EE77E96727A77A206B0C12716221E182340BB50B4",
"Nonce": "NjM3Njg3MjA0ODEwNTUuNToxZDMwZTgzZmQ3ZTYxZWI3NTY4ZmQ4NDRiNWY5Njc3YTY3ODgyNTBjYTBmNDY4NWMwYmYzZmNkNTYzYTNjYTZk",
"Message": "CF0BA4B409F546BCDEEEDC58B5C7B49C629D35D561ED81009CD0051011AF18C92F2DDBAB643A7354D175AD2287C558C90EBF43B3BBA6DF6C01DE1FDC8F9D33E3E4D2EE733CA0C1AB5EA1EFF85E4430C10EECF14CCE57ABEE01A02B0F4E9B0DDDA368C75C5DC669DD4E0C1B3ECA79E31896862A4E0F441774CECDF4F95379AA38A3C14622684595052F59049A539CE57ACEF095331646CAD27AB7689D48C6682FA4761BA041A87DE17EB9A63C68BC28E63A9601DADD8FCCA98C481B12E00F51EFC7BB1C9DEF995874F7D885C035764499CF1E6F55A2E4559105CD7686355E0A388868F0A787D7FE53A2426441EDC57EB7"
}
下一節將繼續解析response結果