支付架构调用流程以及常见支付问题解决方案

目录

支付服务特点

流程图

支付中一般都会遇到什么问题以及解决方案?

用户恶意下单(刷单)怎么办?

如何防止重复下单?

支付回调并发怎么办?

如何做到幂等性?

回调延时,如何解决?

如何保证数据一致性?

mq通知失败怎么办?

mq重复消费怎么办?

如果用户支付成功了,但是自己的订单超时了,而回调在超时之后才回调如何处理?


支付在业务中很重要,这里我根据自己做过支付模块的一些理解和大家讨论一下支付的那些事

支付服务有什么特点

  1. 安全性:幂等

  2. 健壮性:商户通知系统若挂掉,影响发货,所以通知系统要保证其可用性

  3. 及时性:及时通知,对商户的发货和订单扭转至关重要

流程图

下面我画了一种方案的时序图大家可以借鉴,还有其他方案暂不深说

支付架构调用流程以及常见支付问题解决方案_第1张图片

时序图如上

  1. 客户端下单(下单的时候可以锁定库存,锁券,计算价格生成订单),跳转到支付页面,这时候已经有待支付的订单了,各种优惠已经算好,即使返回在待支付栏中也可以找到该订单进行支付
  2. 支付:点击支付,可以根据订单号查到此订单,进行一些简单的验证,(其中支付需要的金额一定要从该订单中取,不可信任前端的金额)
  3. 验证后请求支付服务,支付服务接口根据一系列参数封装,请求第三方支付的API,第三方返回对应的预支付标识,如微信的prepay_id,再根据标识等参数进行签名得到sign,最后封装签名后的参数封装返回客户端,客户端调起第三方支付。支付成功后,同步返回客户端,异步回调返回支付服务
  4. 支付服务接受回调,验签,记录回调过来的请求信息,一般都会有支付单号,订单号,商户号等,(可以针对订单号做个uk,如果第三方支付重复回调了就不用处理了),最后发送mq给业务方
  5. 业务方消费mq处理业务
  6. 客户端跳转到支付成功页面

方案2:有一些企业由于业务场景的不同,下单和支付也可以做在一起,选品后跳到下一个页面并没有下单, 因为退出后在待支付中没有看到待支付订单;在去结算的时候才下单,调起支付,这中间没有其他人为操作,如果不支付去待支付页面可以看到待支付订单继续支付即可

一般来说不用后续的主动查询,如果要保证及时性可以采取这个方案,因为第三方可能会回调延时,这会导致我们自己的服务接不到回调,处理不了业务,下面继续说

支付中一般都会遇到什么问题以及解决方案?

用户恶意下单(刷单)怎么办?

对userid进行限制,比如一单购买商品的数量限制、1h内未支付订单的数量限制、ip限制

如何防止重复下单?

1. 前端按钮灰度

2. 下单重定向跳转页面

3. 后端分布式锁防止并发

4. 同一笔订单生成一个唯一号,存在后端UK,作为重复判断

支付回调并发怎么办?

添加回调记录时,数据库orderSn设置uk

服务解耦

支付服务和业务方的服务解耦,防止并发量大的时候通知阻塞

使用rocketmq:解耦,削峰

如何做幂等?

对于回调可能有多次,对于消费方可能网络抖动等原因导致消费两次

回调时,orderSn设置UK即可

业务方消费时验证订单是否处理过,若可以用uk控制最好不过

业务逻辑幂等:如果已处理则消息做成功处理

回调延时,如何解决?

1.起一个定时任务定时检查订单状态做主动查询进行业务处理

缺点:不及时

2.前端跳转时检查订单状态,未支付则触发主动查询更新订单状态

缺点:不论是否延时都要调用接口查询订单状态,一定程度上影响性能,而大多数情况都是回调成功的。

注意:回调通知和主动查询都需要更新订单状态,可加分布式锁控制,防止并发

刚刚说过大多数都是回调成功的,如果采用2方案,有一个问题:主动查询和回调同时进行也就是并发怎么办?在可能有影响的点上加上分布式锁保证安全

回调通知业务方消费时处理完业务可以在redis中对订单号打一个标记,客户端主动查询若查到这个标记证明已经有回调在处理过了,那么订单一定是成功/失败,直接返回跳转即可,不用查询数据库订单,性能会好一点,极端情况下会存在回调和查询并发的情况,注意是否影响订单幂等性

如何保证数据一致性?

最大努力通知方案:对于支付服务来说已经有结果了,要尽自己最大努力告诉业务方结果,业务方处理的成功失败不关心

支付回调验证订单是否处理过:处理过则给第三方回复确认;如果处理失败了则可以有个定时任务扫描(已处理,发送失败的订单)重新发送,如果最终通知失败则通知人工处理(这种情况不多)

支付回调延时的情况如上,现在只讨论正常回调的情况

回调成功,验签成功,记录回调信息(可用于UK去重)失败(此处可能是bug哈哈,可以不处理,依赖下次回调,也可以往下走,不记录也可以发送mq,处理业务要紧),成功则发送mq,发送失败则记录失败记录,定时任务扫描发送

mq通知失败怎么办?

通知失败则1.重复通知,或者2.持久化,或者不用担心,3.web跳转可以主动查询,反查订单处理订单状态,具体方案可以灵活选择

mq重复消费怎么办?

要幂等,验证订单是否被处理过

如果用户支付成功了,但是自己的订单超时了,而回调在超时之后才回调如何处理?

1.设置支付订单的时间与支付宝交易单号的自动关闭时间一致;

2.支付宝有主动查询交易状态接口;一般我们都采取主动查询的方案

3.支付宝可通过接口主动关闭订单;

4.回调时检查订单状态,若订单已关闭则直接向支付宝发起退款请求,交易结束。

希望可以帮到大家,后面有时间我再完善一下,大家有好的想法也可以私我一起讨论

你可能感兴趣的:(【解决方案】,支付,server,后端,微服务,java)