在我们花了不少时间终於完整的完成ATM付款并成功架设Heroku网站後取回PayToken,更新付款资讯。有了这些基础後,我们在实作信用卡的部份基本上都可以用走到飞的状态来进行。
有兴趣可以参考从Day12开始到Day17的文章,Day17基本上已将完整的流程与架构做了完成度很高的铺垫。
以上为永丰规格书中提供的信用卡刷卡内容,和ATM的流程稍有不同就是在於PayToken的取得方式,下面来说明。
按照先前的ATM付款流程,信用卡的流程差在没有中间的BackendURL的等待呼叫过程,整个流程从我们的电商平台到取得信用卡刷卡位置转址,再转回来,流程是衔接在一起的。
/order/create_card_order
)
create_new_card_order
CreateOrder
)
CreditCardMessage
类别物件 (继承至ApiMessage
)set_shop_data()
设定订单相关资料
ReturnURL
网址,待刷卡完成後导回网页,并处理由永丰回传的PayToken
。create_new_order()
方法进行各种所需流程之资料准备(加密、运算签章等),最後叫用APIResponseCard
类别物件取回回传值,最重要的是CardPayURL
。 (继承至ResponseMessage
)ReturnURL
网址将页面导回/order/card_return
)取回PayToken值
OrderPayQuery
)
QueryByPaytokenMessage
类别物件 (继承至ApiMessage
)set_paytoken_json()
设定PayToken所需相关资料send_query()
方法进行各种所需流程之资料准备(加密、运算签章等),最後叫用APIResponsePayToken
类别物件取回回传值 (继承至ResponseMessage
)和先前流程一样,因为我们已经建立了两套共用的父类别(ApiMessage
、ResponseMessage
),分别可从中继承扩充新的Message呼叫方法以及扩充取回的response内容。
所以我们就新增一个CreditCardMessage
(继承ApiMessage
),以及ResponseCard
(继承ResponseMessage
),因此更新一下我们的物件架构图。
class CreditCardMessage(ApiMessage):
return_url = "https://kummyshop.herokuapp.com/order/card_return"
def __init__(self):
super().__init__("OrderCreate")
self.shop_data = None
def set_shop_data(self, will_paid=True, amount=100, auto_billing="Y"):
self.shop_data = CreditCardMessage.gen_default_shop_data(self.shop_no, will_paid, amount)
self.shop_data["PayType"] = "C"
self.shop_data["CardParam"]["AutoBilling"] = auto_billing
self.shop_data["ReturnURL"] = CreditCardMessage.return_url
self.shop_data["BackendURL"] = SinopacUtil.backend_url
print("- shop_data: {}".format(self.shop_data))
super()._set_plain_msg_to_proc_msg_sign(self.shop_data)
def create_new_order(self):
print("Send API...")
return super()._send_api()
@staticmethod
def gen_default_shop_data(shop_no, will_paid=True, amount=100):
tmp_data = ApiMessage._gen_temp_shop_data()
tmp_data["ShopNo"] = shop_no
tmp_data["OrderNo"] = SinopacUtil.gen_order_no(will_paid)
tmp_data["Amount"] = amount * 100
tmp_data["PrdtName"] = "信用卡订单"
return tmp_data
这边和ATM基本上很像,差异仅在ATMParam与CardParam的部份,至於PrdtName则仅作个注记用途,没有太实际的功能性。主要还是初始化後,设定shop_data後,就可以进行Send API的流程。
另外就是我们需要准备好ReturnURL
给永丰API,届时刷卡完成後会再导回我们的网页。
实际流程当然相当复杂,只是我们先前将Code经过整理後,目前只要有新的作法就可以叠加在已架构好的程序架构上进行叫用,无需每次都要重覆复制贴上一堆八、九成都一样的的程序码,这就是实践程序码的DRY(Don't repeat yourself)精神。
至於其他程序段,请参阅Day17的部份,在此就不再贴过来占版面。
class ResponseCard(ResponseMessage):
def __init__(self, resp_json, hash_id):
super().__init__(resp_json, hash_id)
self.orderno = self.dec_resp_json["OrderNo"]
self.amount = self.dec_resp_json["Amount"]
self.tsno = self.dec_resp_json["TSNo"]
self.status = self.dec_resp_json["Status"]
self.desc = self.dec_resp_json["Description"]
self.card_pay_url = self.dec_resp_json["CardParam"]["CardPayURL"]
这里就是针对CardPayURL
进行处理,简单来说,就是我们既然要提供顾客刷卡服务,且透过永丰API,那我们要作的其实是建立订单後请永丰给我们一个信卡用刷卡的金流网址,我们收到後就可以将客户导入後刷卡,待刷卡完成後会再导回我们的页面 (我们先前提供的ReturnURL
要用在这里)。而导回我们的页面,另一个要点是要处理PayToken
。
待我们将程序码布署上Heroku後,就可以马上来试用。
建立新订单,取回信用卡刷卡位置,点选导入刷卡网址:
进行刷卡,虽然永丰开发规格书上有提供测试用的刷卡卡号,但毕竟不是完全的公开资料,不确定被有心人士拿去乱使用会不会造成相关单位困扰,所以还是马赛克一下。
在刷卡成功後,网页回来是回来了,但却发生了以下的错误。
500 Internal Server Error
原先因为Heroku上面我使用另一组production_settings设定档,上面DEBUG是False,导致看不出原因。
以下是永丰的文件说提到,无论是ReturnURL或BackendURL都是以下面方式将PayToken传入:
後来使用了F12
大法,透过Network方式查看Request的内容,发现如下内容。
於是解读了一下,原先在ATM的BackendURL中,我是使用POST中将JSON内容从Raw Data方法取回,但一样的方式会出现错误。
另外我再将DEBUG Mode打开後,确认他是透过POST Form
的方式回传PayToken,而非JSON。
以此可证实,透过ReturnURL
回传的PayToken值,是需要使用POST Form去抓取的。
(这部份永丰的开发规格书可能要注明一下)
上方的PayToken的值会和我等会儿下面页面截图上的值不同,因为页面是後来全部修正完後重新上版跑过,所以两者值不一样是可想而知。
def card_return(request):
pay_token_dic = {"PayToken": request.POST.get("PayToken"), "ShopNo": request.POST.get("ShopNo")}
print(" --- PayToken: {}, ShopNo: {}".format(pay_token_dic["PayToken"], pay_token_dic["ShopNo"]))
create_new_paytoken(pay_token_dic["PayToken"])
update_order_by_paytoken(pay_token_dic)
return HttpResponse("PayToken: {}<br />ShopNo: {}".format(pay_token_dic["PayToken"], pay_token_dic["ShopNo"]))
首先,我们先直接从POST中取资料,而非先前的request.body
。取得後,一样是需要将PayToken拿去重新经过一连串的加密包装後取回付款状态,并且更新。先前都写好包装好的程序码,这时候就可以1分钟内实作完成。
再看一下页面,果然可以了!
当然,实际的电商页面不会是这样把PayToken印在画面上,一切都是为了测试API的流程与验证而已。真正要做的是将由PayToken问回来的付款结果,更新在画面上,告知顾客他刷卡成功了。这部份就交给各位来实作了。
一样的我们回到pgAdmin中看一下资料的更新状态,也都符合我们的预期。!
这样总算是将丰收款的两大功能:ATM虚拟帐户付款
与信用卡付款服务
完成了!
<<: #17-不用套件让网站Logo动起来~(SVG SMIL)
嗨! 昨天终於结束了语料库模型建置的部分,再来就要建立 API 了。这个系统中我采用了一个比较特别的...
终於来到最後一天最後一篇啦!!!! 真的好感动QQ 成功完赛了 第三次挑战铁人赛成功~ 每一年都是难...
Day 28 - 你们服务项目有 Prototype,通常会位於流程的哪一阶段呢? 在目前短暂的在外...
Last Night in Soho线上 《Soho区惊魂夜》是由埃德加·赖特执导,安雅·泰勒-乔伊...
人脸辨识的技术可使用两种方式搭建云端上或边缘装置上,那要如何选择将系统搭在哪个架构上,就要先了解系统...