[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项目有哪些!!


<<:  Day17:Flow,一个非同步的资料流。 First Look

>>:  从 IT 技术面细说 Search Console 的 27 组数字 KPI (22) :KPI 总表,项目流程次序

Day 26 权限宝石:IAM User 建立与使用(下)

今天我们要来介绍多种 IAM User 的创建,那我们开始吧! 透过 Admin 帐号创造 IAM...

补充: 建立 Todo list 画面

发现昨天的介绍中漏掉新增 Todo 的画面是怎麽来的,补充一下。 安装 React Material...

Day 04 HTML/JavaScript Attribute vs Property

Attribute vs Property attribute:属性在 HTML 会被称为 attr...

JS Library 学习笔记:Three.js 初见面,在2D画面创造三维世界 (五)

渲染回圈建立动画效果 之前利用PixiJS建立动画时,运用PIXI.Ticker设定运算逻辑,定时变...

JavaScript入门 Day04_变数宣告

嘿各位,今天要说的是 JavaScript 的变数宣告 为什麽昨天说像变魔法呢~ 因为只要使用变数宣...