iT邦幫忙

2021 iThome 鐵人賽

DAY 2
1
永豐金融APIs

永豐Vue一下-從生活尋找靈感系列 第 7

[day7]呼叫永豐API及流程串接整理

今天先來進行呼叫永豐API

串接永豐API

按照範例測試,主要針對建立訂單進行實作,查詢訂單等API於自建API流程中進行。
前幾天已經完成各項參數的實作
按照各項參數將fuction各自建立起來,最後將各fuction串接後呼叫永豐API及解析回覆後訊息

各參數建置

  • hashID產出
def strToHex(str):
    return int(str,base=16)

def getAESKey():
    A1 = "8XXXXE"
    A2 = "0XXXX5"
    B1 = "9XXXX3"
    B2 = "7XXXX1" 
    # XOR 計算
    OR1 = strToHex(A1) ^ strToHex(A2)
    OR2 = strToHex(B1) ^ strToHex(B2)
    # 結果 轉 hex
    hex_XOR1 = hex(OR1)
    hex_XOR2 = hex(OR2)
    # 將字串合併後,再大寫
    hashID = ( format(OR1, 'X')  +format(OR2, 'X')  )
    print("hashID => ",hashID)
    return hashID
  • Nonce取得
def getNonce(Shop_No):
    URL ="https://apisbx.sinopac.com/funBIZ/QPay.WebAPI/api/Nonce"
    r = requests.post(url = URL, json = Shop_No )
    print('status_code',r.status_code)
    print('r.json()',r.json())
    Nonce=r.json()["Nonce"]
    r.close()
    return Nonce
  • 訊息雜湊組合
def getMessageTextHash(send_message,NonceValue,hashID):
    # {k: type(v) for k, v in send_message.items() if type(v)!=dict }
    send_message={k: v for k, v in send_message.items() if v and type(v)!=dict }
    send_message = {k: send_message[k] for k in sorted ( send_message.keys())}
    send_message_str=json.dumps(send_message, ensure_ascii=False)
    send_message_ContentHash=send_message_str.replace('": "', "=").replace('": ', "=").replace('", "', "&").replace(', "', "&")[2:][:-2]
    send_message_TextHash=send_message_ContentHash+NonceValue+hashID
    return send_message_TextHash
  • Sign取得
def getSignValue(send_message):
    s2 = hashlib.sha256()
    s2.update(send_message.encode('utf-8'))
    Sign = s2.hexdigest().upper()
    return Sign
  • IV值計算
def getSHAValue(Nonce):
    s = hashlib.sha256()
    s.update(Nonce.encode('utf-8'))
    SHAValue = s.hexdigest().upper()
    IVValue=SHAValue[-16:]
    return SHAValue,IVValue
  • AES CBC加密及解密
    上一篇加解密的function搞得太複雜了,參考其他文章及鐵人賽的大大們,程式調整如下:
def AES_CBC_Encrpt(HashID, iv, data):
  key = str.encode(HashID)
  iv = str.encode(iv)
  data = str.encode(data)
  cipher = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)
  ct_bytes = cipher.encrypt(pad(data, AES.block_size))
  return ct_bytes.hex().upper()

def AES_CBC_Decrypt(HashID, iv, data):
  try:
    key = str.encode(HashID)
    iv = str.encode(iv)
    data = bytes.fromhex(data)
    cipher = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)
    pt = unpad(cipher.decrypt(data), AES.block_size)
    return pt.decode("utf-8")
  except (ValueError, KeyError):
    print("Incorrect decryption")

呼叫永豐訂單建置API

終於可以直接對永豐API做支付動作流程了,讓我們繼續看下去~
管理費使用匯款方式較合理,預計未來將匯款方式設為預設,

  • 基本設定如下:
Shop_No = {'ShopNo':"NAXXX_0XX"}
NonceValue=getNonce(Shop_No)
SHAValue ,IVValue= getSHAValue(NonceValue)

hashID = getAESKey()
#付款截止日期,預設五日內要完成匯款
lastDate= datetime.date.today() + datetime.timedelta(days=5)
#使用匯款選項,測試訂單
send_message_ori = {
"ShopNo": Shop_No["ShopNo"],
"OrderNo": "a123q3asrfewrw2",
"Amount": 66600,
"CurrencyID": "TWD",
"PayType": "A", #管理費用匯款方式較合理,目前預設的"A",信用卡繳費模式僅供測試。
"ATMParam": {"ExpireDate":str(lastDate).replace("-","")},
"CardParam": {},
"ConvStoreParam": {},
"PrdtName": "order",
"ReturnURL": "http://10.11.22.113:8803/QPay.ApiClient/Store/Return",
"BackendURL": "http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess",
}
  • 呼叫永豐API建立訂單交易
    程式如下
send_message_TextHash=getMessageTextHash(send_message_ori,NonceValue,hashID)
SignValue = getSignValue(send_message_TextHash)
jsonText=json.dumps(send_message_ori, ensure_ascii=False).replace(' ', "")
aes_encrypt_str = AES_CBC_Encrpt(hashID, IVValue, jsonText)
send_POST_message={
  "Version": "1.0.0",
  "ShopNo": Shop_No["ShopNo"],
  "APIService": "OrderCreate",
  "Sign": SignValue,
  "Nonce": NonceValue,
  "Message": aes_encrypt_str
  }
requests_link = 'https://apisbx.sinopac.com/funBIZ/QPay.WebAPI/api/Order'    
r = requests.post(url = requests_link, json = send_POST_message )
NonceValue=r.json()["Nonce"]
SHAValue ,IVValue= getSHAValue(NonceValue)
hashID = getAESKey()
# cryptor = AESCrypt(hashID,IVValue)
# aes_decrypt_str = cryptor.aes_decrypt(r.json()["Message"])
aes_decrypt_str = AES_CBC_Decrypt(hashID, iv=IVValue, data=r.json()["Message"])
print(f'解密結果為: {aes_decrypt_str}')
r.close()
  • 程式結果
    解密結果為:
{"OrderNo":"a123q3asrfewrw2","ShopNo":"NAXXX_0XX","TSNo":"NA024900000196","Amount":66600,"Status":"S","Description":"S0000 – 處理成功","PayType":"A","ATMParam":{"AtmPayNo":"99922530174530","WebAtmURL":"https://sandbox.sinopac.com/QPay.WebPaySite/Bridge/PayWebATM?TD=NA024900000196&TK=5094342d-d3f6-4c03-ae8e-7e52c7547762","OtpURL":"https://sandbox.sinopac.com/QPay.WebPaySite/Bridge/PayOTP?TD=NA024900000196&TK=5094342d-d3f6-4c03-ae8e-7e52c7547762"}}

雖然已經有點進度了,但30天還蠻遙遠的,同志仍需努力。
明天就是介紹FASTAPI的建制方式以及談談想要建置的API項目有哪些!!


上一篇
[day6]API串接-Message內文加密
下一篇
[day8]FASTAPI建置示範-進度落後了!!
系列文
永豐Vue一下-從生活尋找靈感30

尚未有邦友留言

立即登入留言