所有的支付系统都对接了很多的外部支付、流出、外汇等各种类型的渠道,这些渠道的接口和报文格式各异。今天和大家一起聊聊如何实现一种简洁高效的低代码报文网关设计,主要包括:报文网关的定位,三种形态,低代码报文网关的设计思路,系统架构,核心代码实现。
如果你做过支付系统并写过脚本或代码对接过渠道,或者你好奇如何通过低代码来对接外部千奇百怪的渠道,欢迎一起探索。
在数字支付领域的深处,存在着一个关键的、却往往被忽视的英雄——报文网关。作为支付系统与外部世界沟通的桥梁,报文网关承担着参数转换、报文组装与解析、安全加密、签名验签等多重重要任务。
一般来说,小型公司可能根本就没有报文网关这一说法,直接引入HttpClient包,手撸几个类,就把一个渠道对接搞定。稍大的公司,可能做一些模板方法的抽象,或者一些组件的抽象,也能实现一定的高效接入及复用。但对于更大型跨国公司,如果接入的渠道有几百条,这样手写接入渠道,往往伴随着代码高复杂性和高维护成本。因应这一挑战,"低代码报文网关"的概念应运而生。
在本文中,我们将一起探索这种低代码报文网关的创新设计。我们会从报文网关在支付系统中的角色和重要性入手,然后深入探讨低代码报文网关的工作原理、产品架构、系统架构以及核心代码实现。我们的目标不仅是理解其技术细节,更是领悟其背后的设计哲学——如何在保证系统强大功能的同时,实现更高的接入效率和可维护性。
这篇文章旨在为广大支付技术从业者、软件开发者以及对支付系统感兴趣的读者们,提供一个全新视角来理解和应用低代码报文网关。
报文网关最核心的职责就是对接外部渠道的API接口,把内部的请求发出去,把渠道返回的数据转成内部的参数。
这里面还涉及到很多技术细节,比如参数转换、签名验签、加密解密、报文组装解析,发送接收等。
在前面的两篇文章中,我们介绍了渠道网关,两者的区别在于:
渠道网关:是一个更大范围的网关,还包括渠道路由、渠道开关、渠道咨询等能力。
报文网关:是渠道网关的一部分,只负责对接渠道的接口,小团队可能只是一个小模块,大团队可能会独立出应用。
一般来说,从简单到复杂、从固定到灵活,报文网关会存在四种形态:
每种形态都反映了各公司在特定时期的技术水平和方案造型,但总体来说,对于中大型公司来说,低代码报文网关和产品化配置报文网关是一个比较不错的选择。一方面可以提高效率,另一方面也有足够的研发资源来建平台。
首先我们要知道报文网关核心只做这么几件事:
通过上面的流程分析,我们很容易想到流程引擎或责任链处理,再加一个上下文,就可以实现全部的操作。
具体包括:
说明:
通过这种系统架构,低代码报文网关不仅能够提供强大灵活的配置能力,还能确保处理流程的稳定执行,同时保持高度的可维护性。这样的架构使得报文网关能够适应不断变化的业务需求,同时降低了总体的维护成本和技术复杂性。
代码实现有很多种方式,且报文网关也是一个独立的应用,把所有的代码展示出来也不太现实。这里给出上面系统架构图中的核心代码示例。读者可以扩展实现细节,有兴趣的同学也可以私信我。
整体思路如下:
下面是核心代码组件包括GatewayContext
、GatewayHandlerFactory
和一系列的 GatewayHandler
基本实现:
GatewayContext
类用于保存处理过程中的上下文信息,包括临时参数、报文信息等。
public class GatewayContext {
// 接口配置信息
private InterfaceInfo interfaceInfo;
// 原始请求
private Map originalRequestParam;
// 转换后参数
private String requestParam;
// 签名明文
private String signPlanContext;
// 省略部分参数,以及getter和setter方法
... ...
}
GatewayHandlerFactory
是一个工厂类,用于构建处理责任链。
public class GatewayHandlerFactory {
private static final List handlers = new ArrayList<>();
static {
handlers.add(new ParameterTransformHandler());
handlers.add(new EncryptionHandler());
handlers.add(new SignatureHandler());
// 添加其他handler
... ...
}
public List getHandlers() {
// 添加其他handler
return handlers;
}
}
GatewayHandler
接口定义了处理逻辑的执行方法。
public interface GatewayHandler {
void execute(GatewayContext context);
}
具体的 Handler 实现:
内部参数转外部参数Handler
public class ParameterTransformHandler implements GatewayHandler {
@Override
public void execute(GatewayContext context) {
// 实现内部参数到外部参数的转换逻辑
}
}
签名Handler
public class SignatureHandler implements GatewayHandler {
@Override
public void execute(GatewayContext context) {
// 不需要签名
if (!context.isNeedSign()) {
return;
}
context.setSignMessage(sign(context.getSignPlainContext(),
context.getInterfaceInfo().getSignConfig()));
}
// 签名方法略
}
其它Handler的实现略。
执行Service
public class GatewayServiceImpl implements GatewayService {
@Override
public GatewayResponse execute(GatewayRequest request) {
// 转成网关的上下文
GatewayContext context = buildGatewayContext(request);
// 获取责任链,依次执行
List handlers = GatewayHandlerFactory.getHandlers();
for(GatewayHandler hander : handlers) {
hander.execute(context);
}
// 转换返回
return convertResponse(context.getResponseParam);
}
// 其它代码略
... ...
}
这些组件和处理器共同构成了低代码报文网关的核心功能,允许系统灵活地配置和处理支付系统与外部渠道之间的报文交换。通过这种设计,报文网关可以轻松适应不同支付渠道的接入和业务流程的变更,同时大大减少了传统编码方式所需的开发和维护工作。
在本文中,我们深入探讨了报文网关在支付系统中的重要性,从其在支付系统中的定位、不同形态的发展,到一种具体的低代码设计思路,以及详细的系统架构。我们还看到了核心代码的实现,展示了如何通过灵活的处理器和上下文管理,实现报文网关的关键功能。
产品化配置的低代码报文网关通过提供直观的配置界面和强大的后端处理能力,使得支付系统更加灵活,能够快速适应新的支付渠道和业务模型。同时,它也降低了技术门槛,使得初始技术人员能够更容易地参与到支付渠道的对接中,而不用担心技术太菜可能导致的各种各样的问题。
这是《百图解码支付系统设计与实现》专栏系列文章中的第(23)篇。点击上方关注,和墨哥一起深入解码支付系统的方方面面。
前一篇:《图解渠道网关(二):模型、状态机与流程编排》