iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
永豐金融APIs

串接生活與金融 API系列 第 4

計算API所需要的參數: 內文雜湊

嗯 API 所需要的參數內文雜湊 …
依照規格說明書的指示,需要以下的流程

(1) 先移除所有空值的參數,參數值前後不可有空白。
(2) 將剩餘所有參數值依照「參數名稱」由小至大排序。
(3) 如為多節點參數則不參與sign值演算

有點難懂 ?

直接看範例最快,就是把call API時的 JSON 由

{
    "ShopNo": "BA0026_001",
    "OrderNo": "A201804270001",
    "Amount": 50000,
    "CurrencyID": "TWD",
    "PayType": "A",
    "ATMParam": {"ExpireDate": "20180502"},
    "CardParam": {},
    "ConvStoreParam": {},
    "PrdtName": "ThisDummyOrderNo",
    "ReturnURL": "http://10.11.22.113:8803/QPay.ApiClient/Store/Return",
    "BackendURL": "http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess",
}

轉換成如下的字串

'Amount=50000&BackendURL=http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess&CurrencyID=TWD&OrderNo=A201804270001&PayType=A&PrdtName=ThisDummyOrderNo&ReturnURL=http://10.11.22.113:8803/QPay.ApiClient/Store/Return&ShopNo=BA0026_001'

在此我們可以知道需要利用 Python 做到以下幾件事情

(1)移除不必要的參數,像是

    "ATMParam": {"ExpireDate": "20180502"},
    "CardParam": {},
    "ConvStoreParam": {},

(2)送出去的參數需要先依 key 進行排序
雖然規格書中有提到此處的可以不用區分大小寫(例: a > B) ,但傳入參數前就全部依規格書使用首字大寫的參數最單純

# 等一下將 dict 格式轉成 json 時會利到
import json
 
# 將 api 所需要的參數直接以內建的 dict 方式讀入
send_message = {
    "ShopNo": "BA0026_001",
    "OrderNo": "A201804270001",
    "Amount": 50000,
    "CurrencyID": "TWD",
    "PayType": "A",
    "ATMParam": {"ExpireDate": "20180502"},
    "CardParam": {},
    "ConvStoreParam": {},
    "PrdtName": "ThisDummyOrderNo",
    "ReturnURL": "http://10.11.22.113:8803/QPay.ApiClient/Store/Return",
    "BackendURL": "http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess",
}

# 檢查看看 CardParam 所對應的型別是?
print ( type(send_message["CardParam"]) )
## <class 'dict'>
## 由此我們可以知道,等一下要留下來不是 dict 的資料
## 說穿了就是要留下 str 與 int
## 不過為了簡化程式碼的邏輯,等一下就以 != dict 的方式來過濾資料


# 透過 Dictionary comprehension 一行就可以濾掉
send_message_filter = {
    k: send_message[k] for k in send_message if type(send_message[k]) != dict
}
# 上述的程式碼與以下傳統的 for 迴圈是等價的
# 但就稍微冗長了點
send_message_filter = {}
for k in send_message:
    if type(send_message[k]) != dict:
        send_message_filter[k] = send_message[k]
    

# 將 key 進行排序,將此順序存到另外一個 list 中
sorted_key =  sorted ( send_message_filter.keys() )

# 一樣透過 Dictionary comprehension 得到一個排序好的新 dict
send_message_orderby_key = {k: send_message_filter[k] for k in sorted_key}
    
# 將 dict 轉成 json (字串)
app_json = json.dumps(send_message_orderby_key)

# 印出來看看
print(app_json)
# {"Amount": 50000, "BackendURL": "http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess", "CurrencyID": "TWD", "OrderNo": "A201804270001", "PayType": "A", "PrdtName": "ThisDummyOrderNo", "ReturnURL": "http://10.11.22.113:8803/QPay.ApiClient/Store/Return", "ShopNo": "BA0026_001"}

# 透過內建的文字取代函數,就可以拿到最終的成果囉! 
api_json.replace(": ", "=").replace(" ", "").replace(",", "&").replace('"', "").replace("{", "" ).replace("}", "")
    

今天主要是複習 comprehension 的用法與內建 json 函數。

嗯 第四天了,還在 api 參數的準備中 … 真的不是我故意的啊…


上一篇
計算API所需要的參數: IV
下一篇
計算API所需: 以 AES CBC 編碼
系列文
串接生活與金融 API6

尚未有邦友留言

立即登入留言