开发统一支付平台需要接入多种第三方支付渠道的API

2024-06-23
来源:网络整理

我目前所在的公司在开发统一支付平台,由于公司业务需要,需要对接多个第三方支付平台,为了以后对支付平台有更深入的思考,我整理了一下。

组件模式

由于公司业务在多个地区,需要提供多种支付方式来满足业务的发展。因此设计的支付平台需要接入多个第三方支付渠道,比如:微信支付、支付宝、卡联支付、迅联等等。我们都知道每个第三方支付都有自己的一套对外API,而官方又有一套SDK来实现这些API。那么我们应该如何组织这些API呢?

由于第三方支付渠道会随着业务的发展而变化,这些 SDK 的组织方式需要能够灵活插拔,且不影响支付平台整体架构。这里我利用组件的思想,将支付 API 拆分成各个组件,比如支付组件、退款组件、订单组件、计费组件、订单异常处理组件等,这样在引入第三方支付 SDK 时,可以灵活地将所需的 API 添加到组件中。架构设计如下:

通过模式根据请求参数构建相应的组件对象,将组件与外部分离,隐藏组件构建的实现,组件模式+模式让支付平台具有极强的可扩展性。统一回调与异步分发处理

对接第三方支付有个特点,就是在支付和退款成功之后,都会有一个支付和退款回调功能,这个回调的目的是:1:让商户平台可以自己验证订单的合法性,比如:防止客户端在支付过程中恶意篡改金额等参数。这种情况下,支付成功之后,订单处于支付状态,需要等待第三方的回调,如果回调验证发现支付金额和订单金额不正确,我们可以将订单状态改为失败,防止资金损失。2:通过回调我们可以处理自己系统的业务逻辑,商品的分发等。回调的理念是保证数据的最终一致性,所以我们在发起支付的时候不需要验证参数的正确性,只需要在回调过程中进行验证即可。那么支付平台的回调我们应该如何设置呢?

由于支付平台需要对接多个第三方支付平台,如果每个第三方支付平台都设置一个回调地址,那么就会有多个回调地址。由于回调API必须暴露出来才能接受第三方回调,这样就会存在安全问题。我们必须在API的外层设置安全过滤,因此需要将回调API统一起来,统一进行安全验证,然后再进行一层分发。

我们采用的分发机制是,这里可能会有疑问,如果使用MQ进行分发处理,如何实时的将验证结果返回给第三方呢?下面是一些关于回调的思考:

1、系统基于boot微服务架构,服务之间通过Http进行通信,如果使用Http进行分发,可以保证消息返回的实时性,但是由于网络不稳定,可能会出现请求失败或者超时的情况,接口的稳定性无法保证。2、由于第三方支付在收到响应后,会在接下来的一段时间内再次发起回调请求,这样做的目的是为了保证回调的成功率。对于第三方支付来说,这没问题,但是对于商户支付平台来说,可能是一个比较坑的设计。试想一下,假设一个订单在支付时被恶意篡改金额,回调验证失败,返回给第三方支付,此时第三方支付会再次发送回调,无论发送多少次回调,都会验证失败,增加了不必要的交互。当然这里也可以用到幂等性,下面是微信支付回调的一个应用场景描述:

基于以上两点考虑,我觉得没有必要返回给第三方支付。为了系统的健壮性,我采用消息队列异步分发的方式,支付平台收到回调请求后直接返回 true。这时候你可能会问一个问题,如果此时验证失败,但是此时返回 true,会不会有什么问题?首先如果验证失败,订单肯定是支付失败状态,此时返回 true 的目的是为了减少和第三方支付不必要的远程交互。

笫三方支付平台_游戏第三方支付平台_第三方游戏支付平台

因为MQ是将消息持久化到磁盘,所以使用消息队列进行分发最大的好处就是可以回顾消息队列中的消息来排查问题,同时在业务高峰期消息队列可以缓解流量峰值。

以下是统一回调分发的架构图:

聚合付款

支付平台聚合了多种第三方支付,因此在请求层需要做大量的适配工作才能满足多种支付的需求。你可能会想,为什么不直接在适配中增加几行if else呢?这样也可以,也能满足多种支付的需求,但是如果再增加一个第三方支付,就只能在原有的方法上增加多个else条件,这样就会导致请求层代码随着业务的发展不断变化,变得极其不优雅,不便于维护。这时候我们就可以利用策略模式来消除这些if else代码,当我们增加一个第三方支付的时候,只需要新建一个类就可以了。架构如下:

请求处理

由于支付平台涉及到资金,各种支付请求与退回,以及异常记录在一个支付平台中极其重要,我们需要记录每一条支付请求记录,以便后续排查问题。

基于此,我们在开始请求第三方支付之前设计了一个层,所有的请求都要经过该层处理,核心方法如下:

public K handle(T t) { K k; try { before(t); k = execute(t); after(k); } catch (Exception e) { exception(t, e); } return k; } protected abstract void before(T t); protected abstract void after(K k); protected abstract void exception(T t, Exception exception);

该层采用模板模式,不仅可以实现日志记录,还可以实现多种处理方式,如请求监控,消息推送等,实现了该层的高扩展性

分享