图解报文网关:一种低代码报文网关的创新设计

所有的支付系统都对接了很多的外部支付、流出、外汇等各种类型的渠道,这些渠道的接口和报文格式各异。今天和大家一起聊聊如何实现一种简洁高效的低代码报文网关设计,主要包括:报文网关的定位,三种形态,低代码报文网关的设计思路,系统架构,核心代码实现。

如果你做过支付系统并写过脚本或代码对接过渠道,或者你好奇如何通过低代码来对接外部千奇百怪的渠道,欢迎一起探索。

1. 前言

在数字支付领域的深处,存在着一个关键的、却往往被忽视的英雄——报文网关。作为支付系统与外部世界沟通的桥梁,报文网关承担着参数转换、报文组装与解析、安全加密、签名验签等多重重要任务。

一般来说,小型公司可能根本就没有报文网关这一说法,直接引入HttpClient包,手撸几个类,就把一个渠道对接搞定。稍大的公司,可能做一些模板方法的抽象,或者一些组件的抽象,也能实现一定的高效接入及复用。但对于更大型跨国公司,如果接入的渠道有几百条,这样手写接入渠道,往往伴随着代码高复杂性和高维护成本。因应这一挑战,"低代码报文网关"的概念应运而生。

在本文中,我们将一起探索这种低代码报文网关的创新设计。我们会从报文网关在支付系统中的角色和重要性入手,然后深入探讨低代码报文网关的工作原理、产品架构、系统架构以及核心代码实现。我们的目标不仅是理解其技术细节,更是领悟其背后的设计哲学——如何在保证系统强大功能的同时,实现更高的接入效率和可维护性。

这篇文章旨在为广大支付技术从业者、软件开发者以及对支付系统感兴趣的读者们,提供一个全新视角来理解和应用低代码报文网关。

2. 报文网关在支付系统中的定位

报文网关最核心的职责就是对接外部渠道的API接口,把内部的请求发出去,把渠道返回的数据转成内部的参数。

这里面还涉及到很多技术细节,比如参数转换、签名验签、加密解密、报文组装解析,发送接收等。

在前面的两篇文章中,我们介绍了渠道网关,两者的区别在于:

渠道网关:是一个更大范围的网关,还包括渠道路由、渠道开关、渠道咨询等能力。

报文网关:是渠道网关的一部分,只负责对接渠道的接口,小团队可能只是一个小模块,大团队可能会独立出应用。

3. 报文网关的几种形态

一般来说,从简单到复杂、从固定到灵活,报文网关会存在四种形态:

  1. 纯手撸代码
  • 在这种最初级的形态中,每个外部渠道都需要单独的代码实现。这意味着为每个新接入的银行或支付服务,开发团队需要编写一套新的接口逻辑。
  • 优点:针对性强,可以精确控制每个渠道的交互细节。
  • 缺点:随着接入渠道的增多,代码变得越来越复杂,维护和扩展的成本急剧上升。

  1. 模板方法报文网关
  • 这种形态通过引入模板方法模式,将报文处理流程的共通部分抽象出来,为各个渠道提供统一的处理框架,同时留有接口供具体渠道实现其特定逻辑。
  • 优点:提高了代码的重用性,降低了维护成本。
  • 缺点:对于一些特殊需求,模板方法可能仍然不够灵活,需要额外的定制。

  1. 低代码报文网关
    • 低代码报文网关把所有核心的代码逻辑实现后,只需要写几个配置文件,就可以完成渠道的接入。
    • 优点:极大地提高了灵活性和易用性,加快了新渠道的接入速度,核心代码由有经验的资深员工编写,减少出错可能性。
    • 缺点:复杂场景下可能需要写一些内联函数,造成了一定复杂度。

  1. 产品化配置报文网关
    • 在低代码报文网关基础上,提供图形化配置界面,进一步降低使用难度。
    • 优点:极大地提高了易用性,加快了新渠道的接入速度,以前写代码可能需要4、5天才接一个接口,变成可能0.5天就能接一个接口。
    • 缺点:平台的初始研发成本很高,如果总体接入的渠道不多,ROI可能不高。

每种形态都反映了各公司在特定时期的技术水平和方案造型,但总体来说,对于中大型公司来说,低代码报文网关和产品化配置报文网关是一个比较不错的选择。一方面可以提高效率,另一方面也有足够的研发资源来建平台。

4. 一种低代码报文网关设计思路

首先我们要知道报文网关核心只做这么几件事:

  1. 接收内部应用的请求。
  2. 内部标准参数转成外部渠道的参数。比如内部叫mobileNo,渠道可能叫:mobile_id。
  3. 特定字段加密(可选,由渠道定)。
  4. 组装需要签名的明文字符串并签名。
  5. 组装发送报文,比如有json,kv,xml等。
  6. 对报文整体加密(可选,由渠道定)。
  7. 发送请求,并接收请求。
  8. 对报文整体解密(可选,由渠道定)。
  9. 解析报文。
  10. 组装验签明文字符串并验签。
  11. 特定字段解密(可选,由渠道定)。
  12. 外部返回参数转成内部标准参数。
  13. 返回给内部应用。

通过上面的流程分析,我们很容易想到流程引擎或责任链处理,再加一个上下文,就可以实现全部的操作。

具体包括

  1. 可视化配置:提供直观的用户界面,允许用户通过图形化方式配置报文的处理流程,无需编写复杂的代码。
  2. 模块化处理逻辑:将报文处理的各个步骤模块化,如报文解析、加密/解密、数据映射等,用户可以根据需要组合这些模块来构建完整的处理流程。
  3. 灵活的适配能力:支持灵活地适配不同的支付渠道,包括但不限于银行接口、电子钱包、第三方支付平台等。
  4. 动态配置管理:所有配置信息动态管理,支持实时更新,无需重启系统或重新部署。

5. 低代码报文网关的系统架构

说明:

  1. 最上层是API:核心服务和管理服务分离。
  2. 核心上下文:主要是用于保存接口配置,原始请求,中间处理结果等。
  3. 核心处理Handler:参数转换、加密、解密等全部基础功能全部组件化。
  4. 流程引擎:负责串起所有的Handler依次运行。
  5. 内联函数:解决特殊场景下的报文转换。
  6. 配置中心:配置内部接口,外部接口,参数映射等。
  7. 流程管控:发布、回滚、权限管理等能力。

通过这种系统架构,低代码报文网关不仅能够提供强大灵活的配置能力,还能确保处理流程的稳定执行,同时保持高度的可维护性。这样的架构使得报文网关能够适应不断变化的业务需求,同时降低了总体的维护成本和技术复杂性。

6. 低代码报文网关的核心代码实现

代码实现有很多种方式,且报文网关也是一个独立的应用,把所有的代码展示出来也不太现实。这里给出上面系统架构图中的核心代码示例。读者可以扩展实现细节,有兴趣的同学也可以私信我。

整体思路如下:

  1. 设计数据库表结构:用于存储内部接口定义,外部接口定义,接口映射关系,外部渠道参数等。这部分在这里略过。
  2. 设计运行上下文:GatewayContext(保存处理的上下文信息,包括接口配置、内部请求参数、加解密临时数据、加验签临时数据、发送渠道报文、渠道返回原始报文、解析后报文等)。
  3. 设计各种处理Handler:内部参数转外部参数Handler,加密Handler,签名Handler,报文组装Handler,发送Handler,报文解析Handler,验签Handler,解密Handler,外部参数转内部参数Handler等。
  4. 设计Handler工厂类:GatewayHandlerFactory(通过getHandlers()获取处理的责任链)。
  5. 设计内联函数:用于处理一些复杂操作。比如外部渠道返回的币种和金额两个字段转成内部的一个Money类。这部分在这里略过。

下面是核心代码组件包括GatewayContextGatewayHandlerFactory 和一系列的 GatewayHandler 基本实现:

GatewayContext 类用于保存处理过程中的上下文信息,包括临时参数、报文信息等。

public class GatewayContext {
    // 接口配置信息
    private InterfaceInfo interfaceInfo;
    // 原始请求
    private Map<String, Object> originalRequestParam;
    // 转换后参数
    private String requestParam;
    // 签名明文
    private String signPlanContext;

    // 省略部分参数,以及getter和setter方法
    ... ...
}

GatewayHandlerFactory 是一个工厂类,用于构建处理责任链。

public class GatewayHandlerFactory {
	private static final List<GatewayHandler> handlers = new ArrayList<>();

    static {
		handlers.add(new ParameterTransformHandler());
        handlers.add(new EncryptionHandler());
        handlers.add(new SignatureHandler());
        // 添加其他handler
        ... ...
    }
    
    public List<GatewayHandler> 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<GatewayHandler> handlers = GatewayHandlerFactory.getHandlers();
        for(GatewayHandler hander : handlers) {
            hander.execute(context);
        }

        // 转换返回
        return convertResponse(context.getResponseParam);
    }

    // 其它代码略
    ... ...
}

这些组件和处理器共同构成了低代码报文网关的核心功能,允许系统灵活地配置和处理支付系统与外部渠道之间的报文交换。通过这种设计,报文网关可以轻松适应不同支付渠道的接入和业务流程的变更,同时大大减少了传统编码方式所需的开发和维护工作。

7. 结束语

在本文中,我们深入探讨了报文网关在支付系统中的重要性,从其在支付系统中的定位、不同形态的发展,到一种具体的低代码设计思路,以及详细的系统架构。我们还看到了核心代码的实现,展示了如何通过灵活的处理器和上下文管理,实现报文网关的关键功能。

产品化配置的低代码报文网关通过提供直观的配置界面和强大的后端处理能力,使得支付系统更加灵活,能够快速适应新的支付渠道和业务模型。同时,它也降低了技术门槛,使得初始技术人员能够更容易地参与到支付渠道的对接中,而不用担心技术太菜可能导致的各种各样的问题。

这是《百图解码支付系统设计与实现》专栏系列文章中的第(23)篇。点击上方关注,和墨哥一起深入解码支付系统的方方面面。

前一篇:《图解渠道网关(二):模型、状态机与流程编排》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/372387.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ClickHouse时区

clickhouse数据库的时间是UTC时间。服务器默认的是上海时间。 sudo vim /etc/clickhouse-server/config.xml clickhouse默认的时区是注释的就是UTC时间 %F 表示日期&#xff0c;格式为 YYYY-MM-DD。%T 表示时间&#xff0c;格式为 HH:MM:SS。 因此&#xff0c;formatDateT…

uniapp设置不显示顶部返回按钮

一、pages文件中&#xff0c;在相应的页面中设置 "titleNView": {"autoBackButton": false} 二、对应的页面文件设置隐藏元素 document.querySelector(.uni-page-head-hd).style.display none

leetcode(滑动窗口)3.无重复字符的最长字串(C++详细题解)DAY2

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示…

开发大佬为什么都不喜欢关电脑?

引言 在平时工作中&#xff0c;咱们程序员这一群体往往展现出一些特有的行为习惯&#xff0c;其中之一便是不喜欢频繁地关闭电脑、拒绝关机、长久待机、特别是苹果的机器。 下面从技术分析与用户行为研究的角度出发&#xff0c;将深入探讨程序员倾向于保持电脑开机状态的原因…

Git的一些基本操作

初始git 我们给出下面的一个场景&#xff0c;在大学里&#xff0c;一些老师在我们做完实验之后喜欢让我们交实验报告&#xff0c;假设我们有一个比较追求完美的老师和一个勤奋的学生&#xff0c;这个学生叫做小帅&#xff0c;那天小帅桑勤奋的完成实验报告&#xff0c;在第二天…

关于函数接口的认识和学习

1.复习拷贝文件的流程&#xff1a; a.打开文件&#xff1a;fopen b.文件的读写&#xff1a;fgetc/fputc/fgets/fputs c.关闭文件&#xff1a;fclose 注意&#xff1a;全缓存的缓存区大小为4k&#xff0c;所以定义了一个4096字节的char数组。打开两个目标文件和源文件&#xff0…

大厂设计师亲授:PS 中文设置技巧

Photoshop是Adobe开发的图像处理软件&#xff0c;也是市场上最受欢迎的图像处理软件之一。然而&#xff0c;对于一些不熟悉英语的用户来说&#xff0c;Photoshop的默认语言设置可能会成为使用的障碍。那么&#xff0c;如何将Photoshop设置为中文呢&#xff1f;以下是多个角度的…

day21 图像标签、链接标签

文章目录 图像标签链接标签1.文本超链接2.图像超链接3.页面间链接4.锚链接5.功能性链接 图像标签 常见的图像格式 JPGGIFPNGBMP… <img src"path" alt"text" title"text" width"x" height"y"/>src【必填】&#xff…

前端使用pdf.js进行pdf文件预览的第二种方式:Viewer.html

背景 最近需要实现一个PDF文档预览的功能&#xff0c;按理说&#xff0c;如果只是简单的预览&#xff0c;使用<embed>、<object>等就可以实现。 但是&#xff0c;我们的需求要实现搜索&#xff01;而且&#xff0c;文档还都超大&#xff0c;均300页以上。那<e…

###C语言程序设计-----C语言学习(9)#函数基础

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 一. 基础知识的学习 1.函数的定义 函数是一个完成特定工作的独立程序模块&…

Stable Diffusion 模型下载:国风3 GuoFeng3

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十推荐提示词下载地址模型介绍 欢迎使用GuoFeng3模型 - 这是一个中国华丽古风风格模型,也可以说是一个古风游戏角色模型,具有2.5D的质感。 条目内

Tauri:相比Electron,还有很长路要走的。

一、Tauri是什么 Tauri是一个开源的框架&#xff0c;用于构建跨平台的桌面应用程序。它允许开发者使用Web技术&#xff08;如HTML、CSS和JavaScript&#xff09;来构建高性能的本地应用程序&#xff0c;同时提供了访问底层操作系统功能的能力。 Tauri的设计目标是提供一种简单…

js改善轮播图(transform)时内部文本上下闪动问题

前些天绘制轮播图时&#xff0c;发现轮播图中不同span标签内&#xff08;样式不同&#xff09;文字上下跳动。 为了防止眩晕在岗位上&#xff0c;需要对其进行改善&#xff0c;试了很多种方法&#xff0c;最后来总结一下&#xff1a; 我的轮播图template代码片段&#xff1a; …

DBeaver连接人大金仓数据库

人大金仓的驱动 1. 打开DBeaver软件&#xff0c;点击“数据库”&#xff0c;选择“驱动管理器” 2. 点击“新建”进行达人大金仓驱动管理器配置。 3、创建驱动-设置&#xff1a;驱动名称、类名、url 驱动名称&#xff1a;人大金仓&#xff1b; 类名&#xff1a;com.kingbas…

2024美赛数学建模A题思路分析 - 资源可用性和性别比例(2)

# 1 赛题 问题A&#xff1a;资源可用性和性别比例 虽然一些动物物种存在于通常的雄性或雌性性别之外&#xff0c;但大多数物种实质上是雄性或雌性。虽然许多物种在出生时的性别比例为1&#xff1a;1&#xff0c;但其他物种的性别比例并不均匀。这被称为适应性性别比例的变化。…

UE中对象创建方法示例和类的理解

对象创建方法示例集 创建Actor示例 //创建一个护甲道具 AProp* armor GetWorld()->SpawnActor<AProp>(pos, rotator); 创建Component示例 UCapsuleComponent* CapsuleComponent CreateDefaultSubobject<UCapsuleComponent>(TEXT("CapsuleComponent&qu…

C++多线程学习[六]: 多线程之间的同步

一、同步问题 实际开发场景中有很多需要同步的情况&#xff0c;例如&#xff0c;音频和视频的同步输出、或者通讯能够第一时间同步接受处理… 二、多线程同步demo 可以看到cond可以阻塞等待&#xff08;wait&#xff09;可以通知一个线程(notify_one)也可以通知所有的线程&am…

Mysql的BufferPool

Mysql的BufferPool Mysql是一个存储数据到磁盘的进程&#xff0c;但是磁盘的速度难以与CPU相比&#xff0c;所以InnoDB存储引擎在处理客户端的请求时&#xff0c;当需要访问某个页的数据时&#xff0c;就会把完整的页的数据全部加载到内存中。将整个页加载到内存中后就可以进行…

2 月 5 日算法练习- 字符串

人物相关性分析 思路&#xff1a;枚举前缀和。枚举字符串中的 Bob 位置利用前缀和来记录&#xff0c;然后枚举 Alice 的位置&#xff0c;通过判断 Bob 在 Alice 前面还是后面来进行不同的前缀和差值计算距离 k 距离中 Bob 的个数求和就是答案&#xff0c;复杂度是 On。注意 Bob…

力扣刷题之旅:进阶篇(一)

力扣&#xff08;LeetCode&#xff09;是一个在线编程平台&#xff0c;主要用于帮助程序员提升算法和数据结构方面的能力。以下是一些力扣上的入门题目&#xff0c;以及它们的解题代码。 --点击进入刷题地址 题目1&#xff1a;三数之和 题目描述&#xff1a; 给定一个包含n个…
最新文章