今天预计讲解下面两个 (也就是下图的步骤 5)
在 Spec 第七章有详细列出哪一种 Request 的讯息内文需要哪些东西,像是 Spec 在 OrderCreate 给的例子
{
"ShopNo": "BA0026_001",
"OrderNo": "A201804270001",
"Amount": 50000,
"CurrencyID": "TWD",
"PayType": "A",
"ATMParam": { "ExpireDate": "20180502" },
"CardParam": { },
"ConvStoreParam": { },
"PrdtName": "虚拟帐号订单",
"ReturnURL": "http://10.11.22.113:8803/QPay.ApiClient/Store/Return",
"BackendURL": "http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess"
}
但是实际上在 OrderCreate 必须要有的参数只有下面几项,其他会根据你的参数不同,有不同需求~
Name | Type | Required | Note |
---|---|---|---|
ShopNo | bytes(20) | Y | 商店代号 |
OrderNo | bytes(50) | Y | 订单编号 |
Amount | Int(9) | Y | 订单总金额 |
CurrencyID | bytes(3) | Y | 币别 |
PrdtName | bytes(60) | Y | 产品名称 |
ReturnURL | bytes(255) | Y | 付款完成页面 |
PayType | bytes(1) | Y | 收款方式 |
如果要算出讯息的 Sign,需要注意以下几个事项。
CardParam
、ConvStoreParam
ATMParam
param1=value1¶m2=value2
的字串
Amount=50000&BackendURL=http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess&CurrencyID=TWD&OrderNo=A201804270001&PayType=A&PrdtName=虚拟帐号订单&ReturnURL=http://10.11.22.113:8803/QPay.ApiClient/Store/Return&ShopNo=BA0026_001
下面的程序码是要让我们的讯息内文转换成要加密前的形式 (图中的内文杂凑)
def parseQueryData(msg_param):
if type(msg_param) != dict:
return
## 这里是将传进来的 dict 根据 key 做排序
order_message = dict(sorted(message_content.items(), key = lambda x: x[0]))
message = ''
## 这里是看是否为空值或是多节点,然後转换为要求的字串
for k, v in order_message.items():
if type(v) == dict or v == '':
continue
message += f"{k}={v}&"
return message[:-1]
接着只要把前一天说的 Nonce 以及 Hash ID,将他们接在一起算 SHA256 即可获得 Sign
## msg_content 是 parseQueryData() 传回来 value
def calcSign(msg_content, nonce, hash_id):
sign_msg = msg_content+nonce+hash_id
s = hashlib.sha256()
s.update(sign_msg.encode('utf-8'))
h = s.hexdigest()
return h.upper()
所以到目前为止,会有下面的程序码 (部分程序码有做更改,但基本上功能一样~)
import requests
import json
import hashlib
shop_no = '<shop_no>'
sinopac_hash = {
'a1': '',
'a2': '',
'b1': '',
'b2': ''
}
nonce_url = 'https://apisbx.sinopac.com/funBIZ/QPay.WebAPI/api/Nonce'
def getNonce():
nonce_data = {
'ShopNo': shop_no
}
r = requests.post(nonce_url, json=nonce_data)
return json.loads(r.content)['Nonce']
def calcHashID():
a1 = sinopac_hash['a1']
a2 = sinopac_hash['a2']
b1 = sinopac_hash['b1']
b2 = sinopac_hash['b2']
xor1 = hex(int(a1, base=16)^int(a2, base=16))
xor2 = hex(int(b1, base=16)^int(b2, base=16))
hash_id = xor1[2:]+xor2[2:]
return hash_id.upper()
def calcIV(nonce):
s = hashlib.sha256()
s.update(nonce.encode('utf-8'))
h = s.hexdigest()
return h[-16:].upper()
def calcSign(msg_content, nonce, hash_id):
sign_msg = msg_content+nonce+hash_id
s = hashlib.sha256()
s.update(sign_msg.encode('utf-8'))
h = s.hexdigest()
return h.upper()
order_create = {
"ShopNo": shop_no,
"OrderNo": "A202109120008",
"Amount": 50000,
"CurrencyID": "TWD",
"PayType": "C",
"CardParam": {
"AutoBilling": "Y"
},
"ConvStoreParam": { },
"PrdtName": "信用卡订单",
"ReturnURL": "http://10.11.22.113:8803/QPay.ApiClient-Sandbox/Store/Return",
"BackendURL": "https://10.11.22.113:8803/funBIZ.ApiClient/AutoPush/PushSuccess"
}
nonce = getNonce()
hash_id = calcHashID()
iv = calcIV(nonce)
content = parseQueryData(order_create)
signature = calcSign(content, nonce, hash_id)
预告明天会利用 Python 实作 AES-CBC,敬请期待!
<<: python证照必考题 得票数计算 选举题目 投票问题TQC+ 程序语言 Python 3 _ 409
Template Syntax Vue.js 最主要是基於HTML,在使用JQuery或者Js的时候...
简单架设 x 不失质感 目录 源起 : 开发者网站 开发工具 : Adobe Brackets 基础...
Chart function 身为一个键盘柯南,最重要的技能之一就是储存和下载分析後的结果。另外c...
架构图 前言 Java程序是一系列对象的集合,而对象之间透过彼此之间调用方法来达到开发目的,因此在认...
Laravel 路由 基本路由 首先看到rotues资料夹里的web.php,会看到这些程序码 Ro...