当前位置: 首页 > article >正文

虚拟电商-话费充值业务(二)话费充值对接供应商模块开发

一、对接供应商模块开发

供应商对接模块chongba_recharge_supplier主要负责的就是调用外部的供应商系统进行充值下单,这种调用是一种基于HTTP协议的调用。

此外在供应商对接模块中主要是实现的业务逻辑有:

1:余额或押金不足情况下的失败轮转

2:网络故障/充值失败重试,需要添加一个重试任务

3:重试次数到达阈值后停止供应商对接

4:供应商异步回调,订单状态修改

二、对接供应商服务接口定义

chongba_recharge_supplier监听到支付成功消息之后,接收到的消息:RechargeRequest,具体对接的不直接写在监听类中,单独定义一个对接供应商服务接口

步骤1:在chongba_recharge_supplier模块下创建包:com.chongba.supplier.inf,在该包下创建充吧系统对接供应商接口:SupplierService,接口中定义一个对接方法:void recharge(RechargeRequest rechargeRequest);

public interface SupplierService {/*** 对接供应商下单* @param rechargeRequest*/public void recharge(RechargeRequest rechargeRequest);
}

步骤2:在chongba_recharge_supplier模块下创建包:com.chongba.supplier.service,在该包下创建一个接口的实现类:SupplierServiceImpl

@Slf4j
@Service
public class SupplierServiceImpl implements SupplierService{    @Overridepublic void recharge(RechargeRequest rechargeRequest) {}
}

步骤3:配置供应商系统的接口地址,在实际业务中调用第三方系统接口大都基于HTTP协议调用,充吧系统在模块中模拟了两个供应商,注意这个模块并没有在充吧的注册中心去注册,因为我们模拟的是外部系统,所以我们要调用外部系统必须得知道系统接口的调用地址;

在application-dev.yml中配置如下:

supplier:apis: {"jisuapi": "http://127.0.0.1:8090/jisuapi/mobilerecharge/recharge","juheapi": "http://127.0.0.1:8090/juheapi/recharge"}

步骤4:编写配置类读取配置,在chongba_recharge_supplier模块下创建包:com.chongba.supplier.conf,在该包下创建配置类:SupplierConfig

@Data
@Component
@ConfigurationProperties(prefix = "supplier")
public class SupplierConfig {private Map<String,String> apis; //加载供应商api地址
}

步骤5:在对接服务实现类:SupplierServiceImpl中注入配置类SupplierConfig,并测试配置能否正常读取

@Slf4j
@Service
public class SupplierServiceImpl implements SupplierService{@Autowiredprivate SupplierConfig supplierConfig;@PostConstructpublic void init(){System.out.println("加载到的配置如下:"+supplierConfig.getApis());}@Overridepublic void recharge(RechargeRequest rechargeRequest) {}
}

运行启动类:SupplierApplication,查看控制台输出:

三、对接供应商逻辑编写

配置正常加载之后需要编写对接供应商的处理逻辑,先将代码结构实现,然后补充细节

1).编写对接逻辑分发方法:doDispatchSupplier(RechargeRequest rechargeRequest),根据供应商编号进行分发
2).编写对接聚合的方法:doPostJuhe(RechargeRequest rechargeRequest)
3).编写对接极速的方法:doPostJisu(RechargeRequest rechargeRequest)

对接第三方其实就是向第三方系统接口地址发起HTTP请求,我们可以使用HttpClient等工具。

步骤1:在启动类SupplierApplication中向容器注入RestTemplate

@Bean
public RestTemplate restTemplate(){return new RestTemplate();
}

步骤2:整体对接代码结构如下:

@Autowiredprivate RestTemplate restTemplate;@Overridepublic void recharge(RechargeRequest rechargeRequest) {doDispatchSupplier(rechargeRequest);}/*** 对接逻辑分发* @param rechargeRequest*/private void doDispatchSupplier(RechargeRequest rechargeRequest) {//设置供应商的调用地址:String url = supplierConfig.getApis().get(rechargeRequest.getSupply());rechargeRequest.setRechargeUrl(url);//根据需要对接的供应商的编号确定不同的对接方式---不同的api需要传递的参数类型和参数名称等各不相同if(Constants.juheapi.equals(rechargeRequest.getSupply())){//对接聚合doPostJuhe(rechargeRequest);}else if(Constants.jisuapi.equals(rechargeRequest.getSupply())) {//对接极速doPostJisu(rechargeRequest);}}private void doPostJuhe(RechargeRequest rechargeRequest) {//聚合要求传递的是json格式的数据//创建并设置请求头HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);//创建请求实体HttpEntity httpEntity = new HttpEntity(JSON.toJSONString(rechargeRequest),headers);//发送请求ResponseEntity<String> responseEntity = restTemplate.postForEntity(rechargeRequest.getRechargeUrl(), httpEntity, String.class);//获得结果String body = responseEntity.getBody();System.out.println(body);}private void doPostJisu(RechargeRequest rechargeRequest) {}

然后注意:在我们监听类中监听到消息之后,要去调用我们供应商对接服务接口方法:

@Component
@Slf4j
@RocketMQMessageListener(topic = "pay",consumerGroup = "order-paid-consumer")
public class PayRocketListener implements RocketMQListener<RechargeRequest>{@Autowiredprivate SupplierService supplierService;/*** 监听消息:* @param rechargeRequest*/@Overridepublic void onMessage(RechargeRequest rechargeRequest) {log.info("PayRocketListener 监听到了消息,{}",rechargeRequest);supplierService.recharge(rechargeRequest);}
}

启动测试:

启动chongba_recharge_web工程,chongba_recharge_mock工程,chongba_recharge_supplier工程

访问:http://localhost:191/ 进行充值,查看结果

步骤3:供应商返回结果封装处理:对于供应商的返回结果数据我们可以统一封装处理

对进行泛型的反序列化,使用TypeReference可以明确的指定反序列化的类型

@Overridepublic void recharge(RechargeRequest rechargeRequest) {Result<RechargeResponse> result = doDispatchSupplier(rechargeRequest);if(result !=null){           }}/*** 对接逻辑分发* @param rechargeRequest*/private Result<RechargeResponse> doDispatchSupplier(RechargeRequest rechargeRequest) {//设置供应商的调用地址:String url = supplierConfig.getApis().get(rechargeRequest.getSupply());rechargeRequest.setRechargeUrl(url);//根据需要对接的供应商的编号确定不同的对接方式---不同的api需要传递的参数类型和参数名称等各不相同if(Constants.juheapi.equals(rechargeRequest.getSupply())){//对接聚合return  doPostJuhe(rechargeRequest);}else if(Constants.jisuapi.equals(rechargeRequest.getSupply())) {//对接极速return  doPostJisu(rechargeRequest);}return null;}private Result<RechargeResponse> doPostJuhe(RechargeRequest rechargeRequest) {//聚合要求传递的是json格式的数据//创建并设置请求头HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);//创建请求实体HttpEntity httpEntity = new HttpEntity(JSON.toJSONString(rechargeRequest),headers);//发送请求ResponseEntity<String> responseEntity = restTemplate.postForEntity(rechargeRequest.getRechargeUrl(), httpEntity, String.class);//获得结果/*String body = responseEntity.getBody();// Result<RechargeResponse>Result result = JSON.parseObject(body, Result.class);//因为泛型的问题可能会导致出现问题System.out.println(body);*/Result<RechargeResponse> result = JSON.parseObject(responseEntity.getBody(), new TypeReference<Result<RechargeResponse>>(){});return result;}// 对接极速private Result<RechargeResponse> doPostJisu(RechargeRequest rechargeRequest) {return null;}

四、对接供应商测试

业务逻辑:

选择 手机充值进行话费充值。进行充值,然后支付成功。支付成功后,对接供应商模块,发送消息到供应商平台,然后接收聚合供应商返回的消息。进行处理。

选择充值:
在这里插入图片描述

进行充值:
在这里插入图片描述
充值话费成功:
在这里插入图片描述
对接供应商模块,发送消息到供应商平台,然后接收聚合供应商返回的消息(余额不足)。对接成功。

相关文章:

虚拟电商-话费充值业务(二)话费充值对接供应商模块开发

一、对接供应商模块开发 供应商对接模块chongba_recharge_supplier主要负责的就是调用外部的供应商系统进行充值下单&#xff0c;这种调用是一种基于HTTP协议的调用。 此外在供应商对接模块中主要是实现的业务逻辑有&#xff1a; 1&#xff1a;余额或押金不足情况下的失败轮…...

练习题:110

目录 Python题目 题目 题目分析 需求理解 关键知识点 实现思路分析 代码实现 代码解释 函数定义&#xff1a; 计算值的总和&#xff1a; 测试函数&#xff1a; 运行思路 结束语 Python题目 题目 定义一个函数&#xff0c;接受一个字典作为参数&#xff0c;返回字…...

c#winform,倒鸭子字幕效果,typemonkey字幕效果,抖音瀑布流字幕效果

不废话 直接上效果图 C# winform 开发抖音的瀑布流字幕。 也是typemonkey插件字幕效果 或者咱再网上常说的倒鸭子字幕效果 主要功能 1&#xff0c;软件可以自定义添加字幕内容 2&#xff0c;软件可以添加字幕显示的时间区间 3&#xff0c;可以自定义字幕颜色&#xff0c;可以随…...

游戏被外挂攻破?金融数据遭篡改?AI反作弊系统实战方案(代码+详细步骤)

一、背景与需求分析 随着游戏行业与金融领域的数字化进程加速,作弊行为(如游戏外挂、金融数据篡改)日益复杂化。传统基于规则的防御手段已难以应对新型攻击,而AI技术通过动态行为分析、异常检测等能力,为安全领域提供了革命性解决方案。本文以游戏反作弊系统和金融数据安…...

晶晨S905L3A(B)-安卓9.0-开启ADB和ROOT-支持IPTV6-支持外置游戏系统-支持多种无线芯片-支持救砖-完美通刷线刷固件包

晶晨S905L3A(B)-安卓9.0-开启ADB和ROOT-支持IPTV6-支持外置游戏系统-支持多种无线芯片-支持救砖-完美通刷线刷固件包 适用型号&#xff1a;M401A、CM311-1a、CM311-1sa、B863AV3.1-M2、B863AV3.2-M、UNT403A、UNT413A、M411A、E900V22C、E900V22D、IP112H等等晶晨S905L3A(B)处…...

AI来了,新手如何着手学习软件开发?

AI时代新手学习软件开发的7步进化指南 &#xff08;附具体工具与避坑策略&#xff09; 一、建立“人机协作”学习观 AI是教练&#xff0c;不是替身 正确姿势&#xff1a;用AI辅助理解概念&#xff08;如让DeepSeek 、ChatGPT用生活案例解释递归&#xff09;&#xff0c;但坚持手…...

JDK 24 Class File API 介绍

概述 JDK 24 引入的 Class File API 提供了一套类型安全的 API 用于操作 Java 类文件。这套 API 允许我们以编程方式读取、修改和创建 Java 类文件&#xff0c;而不需要直接处理底层的字节码。 注1&#xff1a;JDK 24 已于2025年3月18日正式发布&#xff0c;Release信息参见官…...

C++23:现代C++的模块化革命与零成本抽象新高度

以下代码为伪代码&#xff0c;仅供参考 一、标准库的范式突破 1. std::expected&#xff1a;类型安全的错误处理 std::expected<DataPacket, ErrorCode> parsePacket(ByteStream& stream) {if (stream.header_valid()) return decode_packet(stream);elsereturn s…...

《K230 从熟悉到...》矩形检测

《K230 从熟悉到...》矩形检测 《庐山派 K230 从熟悉到...》矩形检测 矩形检测技术是一种广泛应用于电子图像处理的核心技术。它通过识别和分析图像中的矩形结构&#xff0c;为各种应用提供基础支持。从传统图像处理算法到现代深度学习技术&#xff0c;矩形检测的实现途径多种多…...

Unity 面向对象实战:掌握组件化设计与脚本通信,构建玩家敌人交互

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...

3. 第三放平台部署deepseek

有时候我们会发现使用deepseek服务器&#xff0c;异常卡顿&#xff0c;这是由于多方面原因造成的&#xff0c;比如说访问人数过多等。想要解决这个问题&#xff0c;我们可以选择第三方平台进行部署 第三方平台 我们可以选择的第三方平台很多&#xff0c;比如硅基流动、秘塔搜索…...

【C++指针】搭建起程序与内存深度交互的桥梁(下)

&#x1f525;&#x1f525; 个人主页 点击&#x1f525;&#x1f525; 每文一诗 &#x1f4aa;&#x1f3fc; 往者不可谏&#xff0c;来者犹可追——《论语微子篇》 译文&#xff1a;过去的事情已经无法挽回&#xff0c;未来的岁月还可以迎头赶上。 目录 C内存模型 new与…...

.NET开发基础知识1-10

1. 依赖注入&#xff08;Dependency Injection&#xff09; 技术知识&#xff1a;依赖注入是一种设计模式&#xff0c;它允许将对象的依赖关系从对象本身中分离出来&#xff0c;通过构造函数、属性或方法参数等方式注入到对象中。这样可以提高代码的可测试性、可维护性和可扩展…...

IEEE PDF Xpress校验出现 :字体无法嵌入问题以及pdf版本问题

文章目录 问题描述一、字体嵌入问题首先查看一下&#xff0c;哪些字体没有被嵌入查看window的font文件夹里的字体下载字体的网站修复字体嵌入问题 二、pdf版本不对 问题描述 在处理IEEE的camera ready的时候&#xff0c;提交到IEEE express的文件没有办法通过validate&#xf…...

cookie详解

一、cookie出现原因 http是无状态的&#xff0c;浏览器无法记录当前是哪个人浏览的&#xff0c;所以出现了cookie 作用&#xff1a;会话状态管理&#xff08;用户登录状态、购物车、游戏分数&#xff09;、个性化设置&#xff08;主题、自定义设置&#xff09;、浏览器行为跟…...

Mayo Clinic Platform在人工智能医疗领域的现状及启示意义研究

一、引言 1.1 研究背景与意义 在科技飞速发展的当下,人工智能(AI)已逐渐渗透至各个行业,医疗领域作为关乎人类生命健康的重要领域,也迎来了人工智能技术带来的深刻变革。人工智能医疗,作为人工智能与医疗行业深度融合的产物,正重塑着全球医疗的格局。 从全球范围来看,…...

Rust基础语法

以下是 Rust 语言基础语法的核心要点&#xff0c;结合与 JavaScript 的对比&#xff0c;帮助前端开发者快速掌握核心概念&#xff1a; 一、变量与常量 1. 变量声明 Rust&#xff1a;变量默认不可变&#xff0c;需用 mut 显式声明可变性。let x 5; // 不可变变量 le…...

如何将 Java 应用做成 EXE 的可执行软件

目录 前言一、情景介绍二、实现步骤1. 打 Jar 包2. 编写 bat 批处理文件3. bat 转 exe 前言 最近使用 GUI 帮朋友写了一个软件&#xff0c;为了方便他处理工作上的重复性且很麻烦的事情&#xff0c;程序是使用 Java 写的&#xff0c;就不得不面对一个问题&#xff1a;我必须将…...

第一篇:系统分析师首篇

目录 一、目标二、计划三、完成情况1.宏观思维导图2.过程中的团队管理和其它方面的思考 四、意外之喜(最少2点)1.计划内的明确认知和思想的提升标志2.计划外的具体事情提升内容和标志 一、目标 通过参加考试&#xff0c;训练学习能力&#xff0c;而非单纯以拿证为目的。 1.在复…...

自动关机监控器软件 - 您的电脑节能助手

## 自动关机监控器 - 您的电脑节能助手 自动关机监控器是一款基于Python开发的实用工具&#xff0c;旨在帮助用户节省电力资源并延长电脑使用寿命。该程序通过监控用户的鼠标和键盘活动&#xff0c;在设定的无活动时间后自动关闭计算机&#xff0c;特别适合需要长时间离开电脑但…...

线程概念与控制(中)

线程概念与控制&#xff08;上&#xff09;https://blog.csdn.net/Small_entreprene/article/details/146464905?sharetypeblogdetail&sharerId146464905&sharereferPC&sharesourceSmall_entreprene&sharefrommp_from_link我们经过上一篇的学习&#xff0c;接…...

K8S学习之基础六十二:helm部署memcached服务

helm部署memcached服务 #安装memcached的Chart docker load -i memcache_1_4_36.tar.gz #如果k8s用的是docker做容器运行时&#xff0c;用docker load -i导出镜像 ctr -nk8s.io images import memcache_1_4_36.tar.gz #如果k8s用的是containerd做容器运行时&#xff0c;用ctr…...

CPU 超线程技术以及如何关闭CPU超线程功能

CPU超线程技术介绍 CPU 超线程技术&#xff08;Hyper-Threading Technology&#xff0c;HT&#xff09;是英特尔提出的一种同时多线程&#xff08;Simultaneous Multi-Threading, SMT&#xff09;​实现方式&#xff0c;其核心思想是通过逻辑层面的优化&#xff0c;让单个物理…...

Redis 源码硬核解析系列专题 - 第二篇:核心数据结构之SDS(Simple Dynamic String)

1. 引言 Redis没有直接使用C语言的标准字符串(以\0结尾的字符数组),而是自定义了SDS(Simple Dynamic String)。SDS是Redis的基础数据结构之一,广泛用于键值存储、命令参数等场景。本篇将深入剖析SDS的实现原理、优势以及源码细节。 2. 为什么不用C标准字符串? C字符串…...

1--当「穷举」成为艺术:CTF暴力破解漏洞技术从入门到入刑指南(知识点讲解版)

当「穷举」成为艺术&#xff1a;CTF暴力破解漏洞技术从入门到入刑指南 引言&#xff1a;论暴力破解的哲学意义 “世界上本没有漏洞&#xff0c;密码设得简单了&#xff0c;便成了漏洞。” —— 鲁迅&#xff08;并没有说过&#xff09; 想象你是个不会撬锁的小偷&#xff0c;面…...

DHCP报文的详细流程

在DHCP协议的工作流程中&#xff0c;​Discover和Request报文使用广播MAC地址&#xff0c;而Offer和ACK报文通常使用单播MAC地址。这种差异源于DHCP协议的设计逻辑和网络通信的实际需求&#xff0c;具体原因如下&#xff1a; ​1. DHCP报文交互流程 DHCP的完整流程分为四个阶段…...

通信协议和特征

文章目录 双工时钟电平串并行 双工 全双工&#xff1a;全双工通信允许同一时刻数据在两个方向上同时进行传输。一般来说&#xff0c;全双工的通信都有两根数据线&#xff0c;一根发送&#xff0c;一根接收&#xff0c;二者互不影响。半双工&#xff1a;允许数据在两个方向上传…...

Python 循环全解析:从语法到实战的进阶之路

一、问答题 &#xff08;1&#xff09;下面的循环体被重复了多少次?每次循环的输出结果是什么? i1 while i < 10:if i % 2 0:print(i)死循环&#xff0c;没有输出结果 i1 while i < 10:if i % 2 0:print(i)i l死循环&#xff0c;没有输出结果 i 1 while i< 10…...

The Rust Programming Language 学习 (七)

常见集合 使用 Vector 存储表 Vec<T>&#xff0c;也被称为 vector。vector 允许我们在一个单独的数据结构中储存多于一个的值&#xff0c;它在内存中彼此相邻地排列所有的值。vector 只能储存相同类型的值。它们在拥有一系列项的场景下非常实用 新建Vector 为了创建一…...

[GXYCTF2019]禁止套娃1 [GitHack] [无参数RCE]

Git基础 Git信息泄露原理解析及利用总结 - FreeBuf网络安全行业门户 CTF中的GIT泄露_ctf git泄露-CSDN博客 Git结构 dirsearch扫出来一大堆东西&#xff08;然而这些并没有什么屁用&#xff09; 但也算起码了解了git结构了吧 /.git/HEAD&#xff1a;表示当前HEAD指针的指…...