支付流程中的猜的几个坑。
1.熟读支付渠道的的文档
2.支付金额的传递到底是元还是分(支付宝和微信貌似是分,银联貌似元)
3.同一订单重复提交数据或者是重复请求,在微信获取时已经申请预付单的订单再次发起请求。
返回的预付,注意处理,支付失败后,再次支付需要重新申请还是去上一次的返回值。注意区别。
微信应该是 继续获取上次的prepareid
4.异步通知时,修改订单的状态,注意。通知失败和成功时,都要记录日志,尤其注意通知失败时,发送短信报警的功能。
5.异步通知,必须校验签名的正确性,才能修改订单的装填。
年初开始对公司的支付系统进行微服务架构改造。 之前有一系列文章介绍了改造的背景。
从这一篇开始,进入重构工作的正题了。 在支付系统中,支付网关和支付渠道的对接是最核心的功能。其中支付网关是对外提供服务的接口,所有需要渠道支持的资金操作都需要通过网关分发到对应的渠道模块上。一旦定型,后续就很少,也很难调整。而支付渠道模块是接收网关的请求,调用渠道接口执行真正的资金操作。每个渠道的接口,传输方式都不尽相同,所以在这里,支付渠道模块的作用,类似设计模式中的wrapper,封装各个渠道的差异,对网关呈现统一的接口。而网关的功能是为业务提供通用接口,一些和渠道交互的公共操作,也会放置到网关中。
早期启动的时候,对接的渠道不多,所有渠道和网关都实现在一个项目中,部署在一起。采用SSH架构,支付网关实现为一个大Apache Struts Action类,在我们重构前,这个类有2000多行代码。实现时提炼了一个支付渠道对接的抽象类,用来封装渠道的差异。最终在这个系统中对接了有30多个渠道,类规模达到2000个。随着业务发展,问题越来越多。高峰期同时有5个渠道在并行开发,还有大量的其他渠道对接问题需要修复。多个人同时修改一个项目代码导致版本控制的工作骤增。上线频发引起服务中断也让业务方很不满。诸多问题,在前面的文章中都有描述。
相对来说,支付渠道拆分微服务还是比较容易的,按照渠道来拆分即可。不过前几天拜读了大众点评支付渠道网关系统的实践之路的文章,才知道居然还有人按照服务来拆分。
表面上看起来没有区别,可是还是怀疑他们接的银行还是少,应该着看这篇文章支付渠道那些事。当然,大众点评折腾了一通后,最终也是调整为按照渠道来拆分系统。原因有:
这样整体软件架构如下所示:
支付网关前置是对接业务系统的模块。它是所有支付功能的集成前置,将不同支付渠道提供的接口通过统一的方式呈现给业务方。 支付网关前置的设计对整个支付系统的稳定性、功能、性能以及其他非功能性需求有着直接的影响。
每一笔交易都需要记录流水,并登记到个人和机构的分户账户上,统计和分析也需要根据交易流水来更新相关数据。 而个人和机构账户总额更新、交易流水记录以及库存的处理,更是需要事务处理机制的支持。 从性能角度, 我们弱化了事务处理的要求,采用消息机制来异步化和交易相关的数据处理。
风控对支付的重要性怎么强调都不过分。有些系统在风控出问题时可以旁路风控,但是在支付系统中,风控出问题必须停止交易。 整体上,风控可以分为数据采集,数据分析,实时计算,规则配置,实时拦截等模块。风控本身是个大话题,以后专门讨论。又欠一个债。 但风控和交易的接口比较简单。对每一次交易,风控一般返回四个结果:拦截,增强验证,人工核实和通过。通过指交易没有问题,可以直接放行。拦截则是阻止本次交易。增强验证则是交易存疑,需要用户进一步核实身份才能继续,比如输入手机号或者身份证号,一般用于身份被盗用的场景。而人工核实则是对交易有疑问,一般用于个人恶意消费满场景。
支付路由是一个复杂的话题。对支付系统来说,能支持的支付方式越多越好,不能由于支付方式的不支持断了财路。现实中的支付方式多得难以置信。用户随时甩出一张你听都没听说过的卡。如果一个银行卡只有几个用户在用,那针对这个卡开发个对接有点得不尝失。现在第三方支付的爆发,确实给开发支付系统省了不少事。但是公司不可能只对接一个第三方支付,如果这个渠道出问题了,或者闹矛盾了,把链接给掐了,老板还不欲哭无泪。总之,得对接多个渠道。对于交易量大的银行,还得考虑直联。支付路由的作用是定义对用户选用的银行卡或者其他支付方式,使用什么渠道来完成支付。一般来说,银行会提供两种支付途径:无跳转的快捷支付接口和带跳转的网银接口。前者在绑卡,支付的时候,不需要跳到银行页面上去处理,后者则需要在银行的网银页面上完成。显然前者对用户来说体验要好多了,用户流程不会被打断。快捷支付要求支付系统在本地保存用户的支付信息,如卡号,登记手机。系统要确保这些信息不被泄漏。风险非常好,所以大部分银行要求接入方必须经过ADSS检验才能够接入快捷支付。 这种固定方式的接入有单点故障的问题,一旦某个渠道出问题,绑定的支付方式就无法使用。改进策略是为每个支付方式定义多个渠道,第一个渠道出问题即选择第二个,以此类推。 当然,更进一步,可以为候选渠道定义权重,按照权重来选择支付方式。当渠道出问题,自动调整权重。 路由实现上还会更复杂,对同一张银行卡,运营上会要求在不同的系统上,比如android,iOS,windows上,或者不同地区,如中国大陆,中国台湾,中国香港,北美等,甚至不同业务上,采用不同渠道来支付。
对于支付渠道,首先考虑的是接入哪些渠道。要对接的渠道按优先级有: - 第三方支付,对大部分应用来说,支付宝和微信支付都是必须的,一般来说,这两者可以占到90%以上的交易量。用户不需要绑卡,授权后直接支付就行。各种平台都支持,性能和稳定性都不错。对于一些特殊业务,比如游戏,企业支付,可以查看一些专用的第三方支付平台。
这篇文章对支付系统整体设计做一个概要描述,其实每个模块都是一个大坑,有很多的技术细节。 欢迎大家提提意见,一起探讨。
转发别人的链接
http://blog.lixf.cn/essay/2016/09/01/microservice-4/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
https://yq.aliyun.com/articles/10 分布式事物
https://www.zhihu.com/question/49084296