支付回调代码实现|学习笔记

简介: 快速学习支付回调代码实现

开发者学堂课程【RocketMQ 知识精讲与项目实战(第二阶段)支付回调代码实现】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/703/detail/12437


支付回调代码实现


1、根据分析的流程进行代码的实现

//创建接口传递参数将来 callbackpayment 方法是被第三方平台所调用的它回调接口时通常会提交参数最重要的是当前它包含支付业务的编号当前用户支付的状态封装成 TradePay

tradePay

package com. itheima .api ;

import com. itheima . entity. Result ;

import com. itheima. shop. pojo. TradePay;

public interface IPayService {

public Result createPayment(TradePay tradePay) ;

PublicResult callbackPayment(TradePay tradePay);

2、根据流程把注释进行完善

image.png

接收到回调的请求后

log.info("支付回调");

//1.判断用户支付状态if(tradePay.getIsPaid().intValue( )==ShopCode. SHOP_ ORDER_ PAY_ STATUS_ IS_ PAY. getCode(). intValue()

如果状态等于已经支付的状态就要做一系列的处理如果不等于已经支付的状态直接抛异常即可。

//2.更新支付订单状态为已支付

查询 payid根据支付 id 查到当前 pay 的对象

Long payId = tradePay. getPayid();当用户支付成功后会回调回来回调到方法上支付成功后获得当前支付订单的 id

TradePaypay=

tradePayMapper .selectByPrimaryKey(payid);

把支付订单查询出来

如果它等于空抛异常

//判断支付订单是否存在

if(pay==null){

CastException.cast(ShopCode.SHOP_PAYMENT_NOT_ FOUND);

}

如果订单存在

pay. setIsPaid(ShopCode . SHOP_ ORDER_ PAY_ STATUS_ IS_ PAY. getCode());将状态设置为已支付更新回去

在数据库中更新

Intr=tradePayMapper.

updateByPrimaryKeySelective(pay) ;

更新完获得结果如果等于1,更新成功发送消息到 mq让其他系统接收到当前支付成功的状态进行其他的处理创建支付成功的消息把对象创建出来存到数据库的 trade_mq_producer_temp 表表里面有 idgroup_namekeybody 等信息把这些信息在对象中进行封装

image.png

Log. info("订单支付状态改为已支付");

if(r==1){

//3.创建支付成功的信息

创建对象

TradeMqProducerTemp tradeMqProducerTemp = new

TradeMqProducerTemp();更新成功后创建消息的对象发送消息之前为保证消息一定要发送成功将消息持久化到数据库

id 的产生是通过字符串类型String.valuOf 进行转换

image.png

tradeMqProducerTemp. setId( String.valueOf( idWorker. nextId( ))) ;

3、完成属性的注入

@Value("${rocketmq . producer . group}")

private String groupName ;

@Value("${mq .topic}")

private String topic;

@Value( "${mq.pay.tag}")

private String tag;

4、封装数据为了避免应用编码可以把它配置到配置文件中继续封装

//3.创建支付成功的消息

TradeMqProducerTemp tradeMqProducerTemp = new

TradeMqProducerTemp();

tradeMqProducerTemp. setId(String. valueOf( idWorker.

nextId()));

tradeMqProducerTemp . setGroupName (groupName);

tradeMqProducerTemp. setMsgTopic(topic);

tradeMqProducerTemp. setMsgTag(tag);判断如果当前是发送成功的状态就将上一步持久化数据库的消息删除掉如果没有发送成功消息会保留到数据库里面可以做一些其他的处理比如写一个定时任务定时的扫描未发送成功的消息进行发送的处理

在这个过程中可以加上一些日志输出方便查看

@Slf4j

业务标识的key以当前支付订单的id作为业务标识的 key 比较好因为当前的支付订单已经完成支付将来也好去数据库中查询出来支付订单的数据它需要字符串所以进行转换

tradeMqProducerTemp. setMsgKey(String.

valueOf(tradePay. getPayId()));

转换成字符串

tradeMqProducerTemp.setMsgBody(JSON.toISONString(tradePay));

设置当前的创建时间

tradeMqProducerTemp. setCreateTime(new Date());

要发送消息的内容都已经创建好

5、借助 mapper从资料中找到

TradeMqProducerTempMapper.java 拿过来

image.png

把对应的 resources 映射文件

TradeMqProducerTempMapper.xml 拿过来

image.png

添加注解不报错

@mapper

6、@Autowired

privateTradeMqProducerTempMapper

mgProducerTImpMapper;

//4.为了消息能100%的发送到 MQ 将消息持久化数据库

mqProducerTempMapper . insert(tradeMqProducerTemp);

log. info("将支付成功消息持久化到数据库");

//5.发送消息到 MQ,封装方法

sendMessage (topic, tag, String. valueOf(tradePay.

getPayId()), JSON. toJSONString(tradePay));

接收结果

if( result. getSendStatus() . equals (SendStatus .SEND_ OK))

{

}

打印日志

Log . info("消息发送成功");

//6.等待发送结果,如果MQ接受到消息,删除发送成功的消息

mqProducerTempMapper.deleteByPrimaryKey( tradeMqProducerTemp . getId());

Log. info("持久化到数据库的消息删除");这样在测试时就可以看到日志的输出

通过 mapper 插入到数据库通过主键找到删掉这样就可以把已经发送的消息进行删除

如果是已经支付的状态抛出异常

}

}return new Result(ShopCode . SHOP_ SUCCESS.

getSuccess() , ShopCode . SHOP_ SUCCESS . getMessage();

}else{

CastException. cast(ShopCode.SHOP_PAYMENT_ PAY_ ERROR);

发送异常return new Result(ShopCode . SHOP_ FAIL. getSuccess(),

ShopCode . SHOP_FAIL . getMessage();

}

}

发送支付成功消息

@param topic

@param tag

@param key

@param body

private sendResult sendMessage(String topic, String tag,

String key, String body) {

使用字符串归类进行判断

if(StringUtils . isEmpty(topic)){

CastException. cast(ShopCode.SHOP_ MQ_ TOPIC_ IS_ EMPTY);

if(StringUtils . isEmpty(body)){

CastException.cast(ShopCode.SHOP_MQ_MESSAGE_ BODY_ IS_ EMPTY);

}

如果都没有问题创建message对象

Message message = new Message(topic, tag, key, body.

getBytes());

SendResult sendResult=rocketMQTemplate.

getProducer( ). send(message);发送完成后返回发送的结果

return sendResult;

根据这个结果判断目前持久化的消息是否从数据库中删掉

7、拿到模版类发送

@Autowired

private RocketMQT emplate rockatMQTemplate;

相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
hutool工具对象序列化和反序列化
hutool工具对象序列化和反序列化
hutool工具对象序列化和反序列化
|
9月前
|
PyTorch 编译器 算法框架/工具
NPU上如何使能pytorch图模式
本文介绍了PyTorch的`torch.compile`技术和TorchAir的相关内容。`torch.compile`通过将动态图转换为静态图并结合JIT编译,提升模型推理和训练效率。示例代码展示了如何使用`torch.compile`优化模型。TorchAir是昇腾为PyTorch提供的图模式扩展库,支持在昇腾设备上进行高效训练和推理。它基于Dynamo特性,将计算图转换为Ascend IR,并通过图引擎优化执行。文章还提供了TorchAir的使用示例及功能配置方法。
|
数据采集 存储 XML
Python爬虫定义入门知识
Python爬虫是用于自动化抓取互联网数据的程序。其基本概念包括爬虫、请求、响应和解析。常用库有Requests、BeautifulSoup、Scrapy和Selenium。工作流程包括发送请求、接收响应、解析数据和存储数据。注意事项包括遵守Robots协议、避免过度请求、处理异常和确保数据合法性。Python爬虫强大而灵活,但使用时需遵守法律法规。
|
编译器 网络虚拟化 C语言
2023年最全 Windows + VSCode 配置 OpenCV C++ 一站式开发调试环境教程
2023年最全 Windows + VSCode 配置 OpenCV C++ 一站式开发调试环境教程
3658 0
|
算法 计算机视觉 索引
Python3 OpenCV4 计算机视觉学习手册:1~5
Python3 OpenCV4 计算机视觉学习手册:1~5
282 0
|
负载均衡 监控 网络协议
在Linux中,LVS-DR模式原理是什么?
在Linux中,LVS-DR模式原理是什么?
|
Prometheus Cloud Native 调度
Sentinel 新版本发布,提升配置灵活性以及可观测配套
Sentinel 新版本发布,提升配置灵活性以及可观测配套
1574 97
|
资源调度 JavaScript 前端开发
搭建和部署nuxt项目
【8月更文挑战第8天】
621 0
|
机器学习/深度学习 算法 计算机视觉
YOLOv8改进之C2f模块融合CVPR2023 SCConv
卷积在各种计算机视觉任务中表现出色,但是由于卷积层提取冗余特征,其计算资源需求巨大。虽然过去用于改善网络效率的各种模型压缩策略和网络设计,包括网络剪枝、权重量化、低秩分解和知识蒸馏等。然而,这些方法都被视为后处理步骤,因此它们的性能通常受到给定初始模型的上限约束。而网络设计另辟蹊径,试图减少密集模型参数中的固有冗余,进一步开发轻量级网络模型。
1867 0
|
关系型数据库 MySQL Docker
Docker从容器中项目如何访问到宿主机MYSQL
Docker从容器中项目如何访问到宿主机MYSQL
4096 0