支付系统就该这么设计,稳的一批!!

本文介绍了支付系统的设计,包括支付流程、支付中心系统的问题及解决方案。支付流程涉及唤起商户收银台、用户确认支付和处理结果。支付中心面临订单超时、实时性保障和通知容错等问题,解决方案包括使用RocketMQ延时队列和设计模式如模板方法和策略模式。
摘要由CSDN通过智能技术生成

支付中心系统对内为各个业务线提供统一的支付、退款等服务,对外对接三方支付或银行服务实现资金的流转。如下图:
在这里插入图片描述
大部分公司基本都是这样的架构,主要有以下几方面的优点:

  1. 形成统一支付服务,降低业务线接入成本及重复研发成本。
  2. 更好更快的支持创新业务,为公司业务快速发展提供条件。
  3. 更利于构建安全,稳定,可扩展的支付系统。
  4. 利于核心支付数据的沉淀和统一利用。

支付流程

在这里插入图片描述
上图展示了用户支付的主要流程,分为三个步骤:

  1. 用户在业务订单确认页,唤起收银台页面。
  2. 用户在收银台页面选择支付方式,确认支付,显示第三方支付页面,输入密码,进行真实支付行为。
  3. 系统处理用户支付结果,并通知给用户及各个相关系统。

下面详细说下这三个步骤:

1. 唤起商户收银台

用户在订单确认页点击“去支付“按钮,调用收银台支付下单接口。
收银台将订单信息缓存并入库,然后将订单标识拼装到收银台URL上返回给订单系统。
订单系统接收到收银台地址跳转到收银台页面。
在这里插入图片描述
在这里插入图片描述
上图展示了两个业务线(景区业务线,酒店业务线)唤起的收银台页面,大概可以分为三个区域:

页面上部分显示的是支付剩余时间和应付金额;

中间部分是订单信息,根据收银台定义的数据格式,业务线动态传递过来的;

剩余部分展示的是支付渠道,支付渠道也是业务线根据自己的需求在支付后台管理系统配置的,想要哪些支付方式以及它们的顺序都可以自定义。

2. 用户确认支付

  1. 用户在收银台页面选择支付方式(支付宝支付,微信支付,银行卡支付等),点击立即支付按钮,
  2. 调用支付中心创单接口,支付中心调用三方支付创单接口,同步返回支付信息,支付中心对返回参数进行处理,返回给收银台,
  3. 收银台携带支付中心返回的参数,调用三方接口,唤起三方收银台, 用户输入密码,立即支付。
    在这里插入图片描述
    在这里插入图片描述

3. 支付结果处理

  1. 三方系统进行扣款处理,返回收银台结果(目前微信支付返回支付中,支付宝返回支付终态(支付成功或支付失败))

以下几个步骤是异步执行的,不分先后。

  1. 收银台拿到三方返回的结果,确认用户已经支付,则分配定时任务轮询查询(注意超时时间)后台支付结果,拿到终态之后跳转到相应页面,
  2. 三方系统支付成功后会通知支付中心结果,支付中心做好自身逻辑处理,异步通知订单系统,然后返回三方系统通知结果,
  3. 如果长时间未收到三方支付结果的通知,为了防止掉单,支付中心会发起主动查询来获取支付最终结果,以保证支付结果的及时更新。
  4. 当然业务线订单系统为了防止支付系统出现异步通知问题,也可以定时轮询支付中心的支付状态,防止掉单。(图中未画)

支付中心系统一些问题及解决方案

1. 支付订单超时关闭问题

如果用户长时间没有支付,一般都会有一个超时时间(如上图商户收银台的支付剩余时间),到达这个超时时间支付单会自动关闭。实现此需求有很多方式,比如:

  1. 轮询 DB

    定时轮询DB,取出达到超时时间且在支付中的数据,然后执行关闭逻辑。

    缺点:1. 存在延迟,取决于定时任务的频率。2. 影响数据库性能。

  2. JDK 延时队列(DelayQueue)和时间轮算法. 这两种的算法的实现方式自行搜索。

    共同的缺点是 1. 数据易丢失,由于数据存储在内存中,服务重启后数据全部消失。2. 有内存限制,如果数据量过大,会出现OOM异常。

  3. RocketMQ 延时队列
    RocketMQ 支持消息延时发送,社区版不支持任意等级的延迟,目前默认支持18个延时等级:

    1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

    比如支付单30分钟过期,在支付单创建成功后发送延迟消息(延时等级为 16),消费者在30分钟后会拉取到该消息然后执行关闭逻辑。
    在这里插入图片描述
    RocketMQ 延时队列,无论在数据安全性和及时性都有明显的优势,但是目前社区版没有支持任意级别的延迟。

    目前我们使用的是 RocketMQ 延时队列实现的订单关闭。

2. 保证支付结果实时性

三方支付系统支付成功后99.9%的情况下都会回调通知我们,但也难免有意外,比如三方延迟回调或者三方系统宕机,为了保证支付结果的实时性,三方支付也要求我们不能完全依赖于回调接口,所以我们需要定时的调用主动查询接口来查询三方的支付结果。这里我们也是使用的 RocketMQ 延时队列实现的:
在这里插入图片描述

  1. 调用三方支付创单成功后,发送<支付主动查询>延时MQ消息。
  2. 消费消息,判断支付状态是否到达终态,如果到达终态,则返回处理成功,否则调用三方支付查询接口,如果支付成功则处理成功业务,返回处理成功。
  3. 如果客户未支付则判断是否达到最大的重试次数,如果达到最大重试次数则停止<支付主动查询>的重试,否则解析重试规则,发送下一轮的延时消息。

有三个重要参数,这些参数可以放到配置中心或者配置库中,

// 初始延迟级别,对应RocketMQ延时等级,比如3对应的延时时间就是10s
private 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cyufeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值