细数一下之前实作的API功能,有建立订单以及选择支付方式(ATM虚拟帐号、信用卡付款),拿到永丰API透过ReturnURL
或BackendURL
回传给我们的PayToken去问回付款状态,现在即将进入最後一个永丰API的功能:订单交易查询
若是在上面透过ReturnURL
或BackendURL
回传PayToken失效 (任何可能的原因),永丰API还提供了一个主动由电商带时间区间条件来查询订单状态的功能。
开发规格书中提到的使用时机:
收款纪录都可透过此API查询,若有交易迟未收到丰收款的主动通知,您可透过本API介面,利用条件筛选,主动发起查询,减少掉单问题。
而注意事项如下:
A. 订单查询时至少要选择其一条件 (1)订单编号 (2)收款方式 (3)交易起迄 (4)付款状态
B. 每次查询笔数上限为 300 笔,建议条件范围不要设定过大。
参数名称 | 说明 |
---|---|
ShopNo | 商店号码 |
OrderNo | 商户订单编号 |
PayType | 收款方式 |
OrderDateTimeS | 交易日期(起),例如 2017/5/3 00:00 则带 201705030000 |
OrderDateTimeE | 交易日期(迄),例如 2017/5/3 23:59 则带 201705032359 |
PayDateTimeS | 付款日期(起),例如 2017/5/3 00:00 则带 201705030000 |
PayDateTimeE | 付款日期(迄),例如 2017/5/3 23:59 则带 201705032359 |
PayFlag | 依付款状态为条件查询ATM - Y:已转帐/N:未转帐/O:逾期;信用卡 - Y:已请款/N:未请款/O:逾期 |
我们可以提供多种条件组合来查询订单,在查询结果是会出现符合结果的多笔订单内容,因此和先前的response不同之处在於我们需要从OrderList
多性中拿回List的结果。
合理的用法如下:
由於我实际呼叫後,发现铁人赛的参数者都是共用相同的ShopNo,因此用时间区间会把一脱拉库与自己不相关的订单也都取回。所以我主要会以单笔OrderNo进行查询。
class OrderQueryMessage(ApiMessage):
def __init__(self):
super().__init__("OrderQuery")
self.query_cond = None
def set_query_conditions(self, orderno="", pay_type="",
order_date_time_s="", order_date_time_e="",
pay_date_time_s="", pay_date_time_e="", pay_flag=""):
self.query_cond = {
"ShopNo": self.shop_no,
"OrderNo": orderno,
"PayType": pay_type,
"OrderDateTimeS": order_date_time_s,
"OrderDateTimeE": order_date_time_e,
"PayDateTimeS": pay_date_time_s,
"PayDateTimeE": pay_date_time_e,
"PayFlag": pay_flag
}
print("- Query_data: {}".format(self.query_cond))
super()._set_plain_msg_to_proc_msg_sign(self.query_cond)
def query_orders(self):
print("Send API...")
return super()._send_api()
如同先前作法一样,我们会将这个订单查询拆成两个方法叫用,一个是先设定所需要的查询条件set_query_conditions()
,设定完後再呼叫实际叫用API的query_orders()
方法。
这里我们将条件参数都设定了预设值,主要是希望到时使用时可依带明确参数方式传值进来,增加使用的弹性。
class ResponseOrderQuery(ResponseMessage):
def __init__(self, resp_json, hash_id):
super().__init__(resp_json, hash_id)
在这边的回传值不像上次会直接更新Payment资料表,因此暂时留空,我们目标只希望把结果取回就好。这需要商业逻辑先行定义好,是否需要启动连带的更新动作,则可将取回的资料在後续进行订单付款状态更新。
def query_orders_by_conditions(orderno="", pay_type="",
order_date_time_s="", order_date_time_e="",
pay_date_time_s="", pay_date_time_e="", pay_flag=""):
query_api = OrderQueryMessage()
query_api.set_query_conditions(orderno=orderno, pay_type=pay_type,
order_date_time_s=order_date_time_s, order_date_time_e=order_date_time_e,
pay_date_time_s=pay_date_time_s, pay_date_time_e=pay_date_time_e, pay_flag=pay_flag)
resp = ResponseOrderQuery(query_api.query_orders(), query_api.hash_id)
print("-- Response: " + str(resp.dec_resp_json))
return str(resp.dec_resp_json)
def order_query(request):
resp = query_orders_by_conditions(pay_type="A", orderno="A202110507397", pay_flag="Y")
return HttpResponse(resp)
例如,我们以固定的OrderNo进行查询,而且仅希望ATM虚拟帐户,且付款成功的才回传回来。
结果如下:
{
"ShopNo":"NA0249_001",
"Date":"202110032253",
"Status":"S",
"Description":"S0000 – 处理成功",
"OrderList":[
{
"OrderNo":"A202110507397",
"TSNo":"NA024900000369",
"TSDate":"202110012243",
"PayDate":"202110012245",
"Amount":79900,
"PayType":"A",
"PayStatus":"1A400",
"ExpireDate":"202110112359",
"RefundFlag":"N",
"RefundStatus":"",
"RefundDate":"",
"PrdtName":"虚拟帐号订单",
"ATMParam":{
"AtmPayNo":"99922530175613",
"WebAtmURL":"https://sandbox.sinopac.com/QPay.WebPaySite/Bridge/PayWebATM?TD=NA024900000369&TK=3a83b2d6-76d0-4e66-a32b-66d55ceb74f3",
"OtpURL":"https://sandbox.sinopac.com/QPay.WebPaySite/Bridge/PayOTP?TD=NA024900000369&TK=3a83b2d6-76d0-4e66-a32b-66d55ceb74f3",
"BankNo":"807",
"AcctNo":"01700100003411"
},
"RefundAmount":0
}
]
}
虽然仅回传一笔回来,不过一样会放在List型别的OrderList
中,需要再加工将资料取出。
另外最後再提一下,若是在ReturnURL或BackendURL有成功被回传的情况下,基本上我们是可以作到自动化更新付款状态,因此当顾客进到会员後台查询他的订单内容时,是会即时更新。但难免在例如我们提供的服务器有异常时,例如BackendURL有十分钟重新丢一次,至多五次的retry机制。因此如果在永丰API尝试回呼我们的服务器但未果时,而且也超过上限,我们总不会希望订单的付款状态永远无法更新。
在这个状态下,才会使用今天介绍的这支主动询问订单程序。可以写成排程,类似是每几小时进行询问尚未更新的状态,但一样的,我们也是需要有自己的retry上限与逻辑。这部份都是在商务逻辑上需要设计与实作的,不可能永无止尽一直去照三餐询问一个可能永远不会有结果的消息。(如此悲伤)
目前已把所有功能都完成了,接下来看是要作更贴近电商模拟情境的实作,还是用剩下的天数来写Shioaji
证券程序交易呢?就让我们看下去吧。
<<: 【Tableau Desktop入门】免费2小时基础操作体验
>>: 18 - Rest Client - HTTP 请求工具
1. 静态型别 VS. 动态型别 1.1 静态型别的例子 以Java为例: int x 在宣告x变数...
本次要来介绍如何建立Android Studio上的模拟器,以及有哪些优缺点。 首先我认为最大的优点...
该文章同步发布於:我的部落格 利用 Command line 来创建你的 RSpec 资料夹 一样...
嘿嘿 到了第28八天啦 雀跃的心情 就像在京都 看着漫天散落的粉嫩樱花 今天这题超简单 因为我要去补...
工程师太师了: 第2.5话 杂记: 报名的时候没注意到有最低300个字限制阿~~~~(抱头 本来只想...