说起支付,每个人可能想到的是微信、支付宝,其实他们都是后来者,属于第三方支付,论历史还得属银行久远。在中国银行不仅代表了最正确和最前沿的支付的方向,更代表了社会主义的最先进的生产力。尤其是在“互联网+”潮流下,各个银行每年在互联网信息化方面投入上百亿,争当时代的引领者。鄙人有幸对接了中国农行的支付方式,
下面分享一些学到的设计理念,文档入口:https://bank.u51.com/ebus-two/docs
-
暴露状态码。
当
RetunCode
为EUNKWN
或PR0000
或EOSCUNKWN
或AP5168
时,不代表交易失败,仅代表交易结果不明确,交易结果需要进行查证确认。-
只需要告诉用户不明确结果和成功,明确的失败不需要告诉用户,让他们自己猜或者主动测试。
-
不用解释每个错误码具体含义,以免增加对接方心智负担。
-
不需要提供一个错误码和对应业务场景的语义列表,以免带来更多的维护成本。
-
-
提供Java版本的Demo
https://bank.u51.com/ebus-two/docs/#/quick-start/brefore-start
给对接方提供一个java版本的demo有助于业务方快速了解业务,同时给demo文件一定要包含两种以上的不同的字符集编码格式,
不要用UTF8
,要给打开demo的人一些想象空间和惊喜,让他们自己去猜到底应该用哪种字符集解析。
![](https://img.haomeiwen.com/i2747346/498243cadaa1b49a.png)
![](https://img.haomeiwen.com/i2747346/da76f2372acdef69.png)
![](https://img.haomeiwen.com/i2747346/223224cd1b9f72e2.png)
-
不同字符集体现了内部多样化的开发环境,也是向对接方展示自己软实力的一个窗口。
-
虽然有些中文是乱码,但是很多都是代码注释信息,俗话说
代码即注释
,这也是代码质量的一种自信。 -
不要提供其他的语言的包
-
java才是主流,用其他语言比如php、go的公司肯定做不大,要直接在编程语言上帮公司过滤没有价值的客户,这也是
技术要理解和支持业务
发展的表现。 -
不懂java、不会运行java-demo的对接方不是目标用户群。
-
-
不要提供清晰的加签、验签流程说明
-
不要用自然语言清晰的描述加签验签流程或者提供非java语言的代码案例,要让对接方看demo或者自己猜,这也是判断是否是目标用户群的一个方式。
-
一定不要用UTF8编码,比如可以用GBK或者其他编码,同时把编码和加签验签结合起来,一来可以凸显自己的特色,同时也能帮对接方回忆一下字符集相关的知识。
-
采用多样的数据格式,比如提供http请求接口要采用json数据格式,给用户的回调采用xml格式,xml格式拥有悠久的历史,这也是校验对接方技术人员工作经验和技术水平的一种方式。
-
-
只提供错误的案例
{ "MSG": { "Message": { "Version": "V3.0.0", "Format": "JSON", "Common": { "Channel": "" }, "Merchant": { "ECMerchantType": "EBUS", "MerchantID": "103882200000958" }, "ReturnCode": "AP7745", "ErrorMessage": "该终端号未在当前商户维护,请联系银行工作人员前往网络金融运营管理平台进行维护", "TrxType": "ScanPayOrderReq", "OrderNo": "No20220909100002751953", "OrderAmount": "1.00", "ScanPayQRURL": "" }, "Signature-Algorithm": "SHA1withRSA", "Signature": "dSlArjRftdC3uXVtA4mwDppnSbgDa1gOQMnZ4ZYluk5hlXGtW0b2OqCjuqrX2Oxwt5obszuWXk2qkzWcSiyvp64hP7cC7Ps+5FKM3SQwVbnvXLTVM2ODYtH6lG1s3ogSTzEWyvb+Tukqm8SupnlI8ycsfayRvd80qGUAMn9Msj0=" } }
给用户提供接口只提供错误的案例,帮助用户加深错误的印象。比如上面案例中ScanPayQRURL
在成功场景下返回的格式是什么,要让对接方自己测试。
-
接口升级要具备一定不兼容性。
比如旧接口和新接口的返回值:
https://pay.abchina.com/ebusperbank/PaymentModeNewAct.ebf?TOKEN=15753560246988869886
token和TOKEN,对接方需要取到对应的值进行处理。在设计的时候一定要采用不同的字段,显示的向对接方传达内部接口升级的事实,要让他们感知到自己的存在。
不要让对接方以为仅仅换一个接口名,参数返回值完全都完全相同,要让他们对自己的改动做check,养成良好的习惯
。 -
返回结构多样化
比如:下面的请求结果,一个采用平铺、一个采用嵌套,甚至可以更加不拘一格写出更加多样的结构.
![](https://img.haomeiwen.com/i2747346/04e2ddd44598fb09.png)
![](https://img.haomeiwen.com/i2747346/2cfcccc43967b187.png)
-
这样可以向对接方展示自己包容开放多样化的代码风格。
-
给对接方留下疑问:是文档写错了?还是真是这样设计的?这样是不是就不能复用了?
-
参数和字段命名
- 要让文档发挥不可替代的作用,否则文档编写意义就没有那么大了,比如
NewOrderNo: 退款单号,用于查询退款状态。
OrderNo:支付单号。
这样没有对应的文档说明,很难知道对应字段的含义。
- 要传一些没有看起来没有必要的参数
退款接口让业务方必传日期和时间
OrderDate String
是
10 退款日期 2019/12/23 OrderTime String
是
8 退款时间 11:55:30
这样可以用自己服务器的时间和对接方请求的时间做一个对比,以便计算网络延迟。
-
内部的常识就是业界的常识
下面的事情是没有必要告知对接方的
-
采用了post请求,但是选用了
urlencoded form
格式。 -
字符集是非UTF8编码。
-
数据真正格式是XML,验签的简短的案例是JSON,其实不完全适用,甚至会有一些误导。
比如:交易相关的请求的url是https://pay.abchina.com/ebus/ReceiveMerchantTrxReqServlet,你也不需要写在对应的接口文档上,你只需要写
com.abc.pay.client.ebus.common.EBusMerchantCommonRequest
,懂的自然懂,不懂的说明你没有看java版的demo。 -
-
节约成本
降本增效是未来发展的主旋律,在一些服务器资源相关方面也是应该有所考量。
-
用户超时未支付以后
不要主动关闭支付单
,要始终保持支付单的状态是未支付。-
超时关单一般用异步消息,订单量大的时候发消息也是一种浪费,所以超时未支付不更改状态。
-
对接方在支付超时后查询支付单状态依然要保持未支付的状态,千万不要结合“status = 未支付 && exipre_time < 当前时间” 给对接方转换成一个closed状态,要最原始的状态暴漏给对接方。
-
-
回调通知尽可能的少
-
只回调业务方一次,不论对方是否成功处理,不做重试。
-
最多回调3次。
-
- 实践是检验真理的唯一标准
-
不需要整理对接方常见的问题,并回答。
-
不需要画流程图,不需要对异常情况进行总结。
如果对接方对流程有疑问让业务方自己做实验尝试,这个可以保证最新最准确的结果。
银行系统设计博大精深,个人能力有限只能略微学到一些皮毛,不过在网上看到过一些其他人也有不同的收获:
网友评论