点击上方“程序员小惠”,选择关注公众号
有趣又有意义的文章第一时间送出!
介绍
“目前,在大多数互联网应用支付场景中,对接支付宝、微信移动支付产品等需要用户参与支付过程的支付方式已经非常普遍。 同样,还有PC端银行网银支付; 而通过绑定用户银行虽然直接借记卡或连接银行卡快捷支付通道的支付方式在电商、保险、互联网金融、租赁等行业仍被广泛应用,但随着移动互联网支付的兴起微信钱包、支付宝钱包等方式的用户规模快速增长,加上用户银行卡信息安全、银行直销渠道关闭等因素,正在逐渐缩小用户市场份额。”
事实上,这种需要客户参与支付流程的方式,在支付系统流程和订单结构设计上与银行卡快捷支付、直接借记等支付方式有很大不同。 其中,秩序预防非常重要。 失效机制的设计是一个比较困难的问题。
参与过支付系统开发或者在业务系统中开发过支付功能的同学可能会遇到类似这样的业务需求:
用户在外卖网站或应用上购买外卖,并通过微信支付进行支付。 收到用户支付完成的消息后,系统提示用户支付成功,并将订单派发至餐厅?
乍一看,很多同学可能对这个问题有疑问。 这不是一个非常简单的支付流程吗? 大多数支付场景不都是这样吗?
事实上,情况确实如此。 作为正常的支付流程,上述场景是没有问题的。 当整个系统链稳定运行时,大多数参与者可能没有什么感觉; 不过,作为专业人士,对于小型码农来说,还是有很多异常场景需要考虑,否则可能会因为系统流程的设计缺陷,给公司和用户体验造成更大的伤害。
那么上述需求中会出现什么样的异常场景呢? 与支付系统的防复制机制的设计有何联系?
我们可以先看一下上述场景在系统进程中的运行情况(需要放大才能查看):
在上述过程中,虽然从用户的角度来看可能只需要几秒钟的时间,但实际上整个系统链已经经历了一个相对较长的调用过程。 详情如下:
从上面的流程我们可以了解到,其实大家在通过app进行支付时,通常会经历一个非常复杂的流程。 那么,不知道您在支付过程中是否有这样的经历呢?
点外卖付款后,微信也提示支付成功,但外卖APP却始终没有显示订单成功? 即使选择再次付款,也会提示正在付款且不允许重复付款? 或者选择再次支付后,外卖APP会显示订单成功,但是之前支付的钱不见了,只能向客服投诉,各种麻烦?
上述问题是当前支付流程设计中必然会出现的问题。 笔者目前所在的公司也存在类似问题。 虽然出现此类问题的概率可能不是特别高,但肯定会破坏用户体验,增加客服的工作量。 交易量和正确处理是衡量支付系统实力的核心指标之一。
那么什么样的设计才能很好的解决此类问题呢?
从流程上来看,用户选择微信支付并激活微信钱包进行支付后,外卖平台的支付系统实际上已经不再感知系统状态。 也就是说,此时用户是否完成支付,平台无法同步感知,只能依靠微信的主动通知回调,一般来说,主流支付公司都有一套完整的商户通知逻辑,会通知商户支付完成后实时显示。
然而,在很多情况下,有很多因素会导致此类通知延迟。 常见因素包括网络、自有平台系统服务宕机、第三方渠道通知服务故障等。
也就是说,会有用户外卖付款,但系统没有实时显示支付成功,这就是我们常说的短期掉单问题; 或者用户没有及时付款,但还款时会提示“已付款”。 “请不要重新提交”,这就是付款预防的问题。
掉单的处理可以根据业务场景来考虑,但无论采用哪种方案,补偿业务越快,才能有效提升用户体验,减少系统异常处理流程,使防重复机制更加灵敏,并且避免重复付款。 同时提高支付成功率的问题。
此外,是否允许用户重复支付,如何利用冲销机制,在快速保障用户权益的同时,有效提升用户体验,也是整体规划中需要考虑的方面。
根据业务时效性要求,大致有两种选择:
异步补偿机制。
具体来说,支付过程遵循正常流程,采用旁路计时的方式扫描系统中状态在一定时间策略范围内的订单,并通过微信提供的订单查询接口主动轮询。 一旦支付状态查询完成,状态立即触发系统回调,完成支付订单的补偿和业务逻辑;
另一方面,如果状态订单没有通过轮询查询最终状态,则需要设置一定的重复轮询策略,如5分钟、10分钟、20分钟、1小时、3小时、8小时、24小时, 等等。 超过策略规定的时间和轮询次数后,支付流程将更新为无效最终状态,并提供订单查询接口供业务平台完成自身业务订单逻辑的更新。
系统框图如下:
通过侧挂的方式,主要的支付流程会变得相对简单,只需要考虑正常的收单场景。 对于很多业务实时性不高的支付场景,这种方式也足够了。 但对于业务实时性要求非常高、用户体验要求极高的场景,这种方法显然存在明显的问题。
我们以外卖为例。 外卖后台收到用户通过App发送的点餐支付请求后,生成外卖订单,并将支付请求发送至平台支付系统。 一般来说,支付系统首先会防止重复订单。 判断,即已经发起成功的支付/支付请求不允许再次发起,成功的支付交易不允许再次发起。
然而,许多公司的内部支付系统被要求允许对等待支付或支付失败的交易进行二次支付。 在外卖点餐过程中,如果用户点餐后没有立即付款或者由于某种原因付款失败,可以重新付款。 在这种情况下,支付系统就会面临问题。 由于预付费后并不知道用户是否已经完成支付,因此防重复逻辑对于用户是否应该继续发起支付请求会变得缓慢。 如果允许用户付费,可能会出现重复扣费的问题。 如果不允许,就会影响用户体验。 为了使整个机制合理,需要依靠上述系统的补偿机制进行回滚或失效处理。
这里你会遇到以下三种情况:
1、如果用户最终未能支付,系统会安装一定的轮询机制来处理后续订单失效;
2、用户完成支付后,支付系统长时间没有收到微信的回调。 系统还将通过逐步轮询的方式进行后续订单回调补偿; 但这里的问题是,如果异步补偿系统对订单的轮询不够及时(当支付订单量比较大时,定时轮询方式的时效性较差),就会导致比较尴尬的情况。 用户已付款,但外卖订单显示已长时间未付款。 ,订单无法派发,轮询补偿系统完成回调后触发订单派发操作,但往往已经过了用餐时间,很可能是用户触发了申诉流程,外卖平台需要进行退款操作(增加客服工作量);
3、用户当时没有及时付款。 在订单过期前的某个时间,用户可能会选择再次支付,因为此时支付系统订单尚未过期,会处于支付状态,触发防重复机制,无法再次支付。 发起付款;
对于2和3这两种情况,如果需要很好地满足业务需求,就必须提高支付系统的及时性、提高订单防重复失败的处理时间、订单的快速返回。 要实现这样的效果,仅仅依靠并行处理解决方案通常很难。 相反,实时支付流程的设计需要更加智能和灵敏。
实时支付流程优化设计
为了解决上述问题,我们需要在实时支付流程中加入异常优化机制,从整个流程的设计上解决,让整个支付系统更加智能、灵敏。 尽管这种方法似乎使主要支付流程变得复杂。 很多,但从优化用户体验和提高系统灵敏度的角度来看,这种复杂性是值得的,并且可以通过技术细节来屏蔽。
那么我们到底应该如何设计这样一个流程呢?
详情如图(点击放大):
如上图所示,当支付系统收到前端发起的支付请求时,系统首先需要进行防重复判断。 为了有效防止并发请求,采用了锁,即业务支付订单请求发送到支付系统后,首先获取到。 全局锁定。 如果有锁,则表示订单正常处理/未正常处理。 这时候我们就需要判断锁的更新时间。 如果锁的更新时间与当前系统时间相差10s,此时会有两种情况。 一种是指该支付订单未正常支付,应允许重新发起支付。 另一种可能是,用户可能已经支付成功,但支付结果回调过程中通道出现问题,导致系统掉单。 这两种情况混合在一起,系统无法立即识别出属于哪一种情况。
这个问题是一个非常普遍、典型的问题,几乎很多企业都会遇到。
此时支付系统有两种选择。 一种选择是实施严格的防重复策略,要求所有与支付平台对接的业务系统每次调用支付请求时都生成不同的商户订单号。 支付系统必须为同一订单生成不同的商户订单号。 无论支付是否成功,商户的支付订单号均不允许重复发送至支付平台。 该方案与第三方支付公司的接口协议一致。
这种防重复策略是粗暴而简单的。 本质上,它把逻辑的复杂性转移到了业务系统上,这也会让业务感到不舒服。 如果支付平台后期进行了重构,需要推动业务线切换,往往会招致业务系统的反对。
那么支付平台本身如何屏蔽如此复杂的细节,让业务尽可能难以察觉呢?
两个订单号
为了实现上述目标,支付系统内部需要采用1:3(举例)的订单模型,即一个业务订单号可以对应支付系统中的三个支付订单流,并且满足以下条件:每次发起的支付流程是,之前的支付交易数据库中的订单状态是支付未成功,当前支付交易重新生成后,需要将之前的支付交易放入订单动态生效队列中用于快速失效处理。
之所以采用上述方法,是因为如果支付次数超过3次且时间间隔超过30秒(政策可根据业务实践动态调整)未完成,系统基本可以判定为恶意点击行为,可以直接拒绝业务订单并重新发起。 有薪酬的。
之所以需要快速动态设置最后一个支付订单为有效,是因为我们需要在内部设置一个逻辑:“如果支付订单处于有效状态,并且稍后收到第三方支付成功的回调,系统需要自动发起支付订单原有的退款逻辑,并保证该订单不会通知到商户侧。” 之所以会出现这种现象,是因为我们为了提高系统的实时性,允许少量重复扣分的发生,并实现了自动纠错逻辑。
当然,在细节处理上,我们在发起当前交易之前,已经对上一笔交易进行了一轮实时查询。 如果结果是支付成功,请求会直接返回支付成功(也可以提示支付已成功,App主动查询支付系统的订单状态,完成订单返回) 。
如果当前订单再次预付成功,则需要更新订单锁的发起时间和次数,才能同步返回预付结果。 同时,收到第三方正常支付成功回调后,完成订单状态更新和商户通知,解除锁定。
上述策略为防止重复支付和二次支付问题提供了解决方案。 当然,代码逻辑还有很多细节需要考虑和完善,比如实时查询超时策略、退款触发时间、用户提示等。
另外,如果用户不再选择再次发起支付,系统中已有的订单也需要通过本文前面介绍的异步补偿机制逐步作废(具体策略机制可参考图示和前面的概述),但如果在异步补偿机制期间发现掉单,是正常返回订单还是自动退款给用户,需要具体情况具体分析。
以上就是本文的全部内容。 整个支付系统的搭建过程中,还有很多细节逻辑可以优化,需要根据具体业务去实践和处理。鉴于经验和水平有限,有不足的地方还请大家批评指正(可以直接在公众号评论交流)
![]()
)。
最后给大家送个福利
长按图片参与抽奖,先到先得