尚品汇-支付宝支付同步异步回调实现(四十七)

news/2024/9/17 7:43:06/ 标签: java, 前端, javascript

目录:

(1)订单支付码有效时间

(2)支付后回调—同步回调

(3)支付宝回调—异步回调

(1)订单支付码有效时间

(2)支付后回调—同步回调

 

 

static修饰,不能通过Vuale注解获取配置文件的值,可以通过下面的方法进行获取值 

 

实现类放开同步回调地址 

 

 

成功页面:

 修改配置类:

控制器AlipayController

/*** 支付宝回调* @return*/
@RequestMapping("callback/return")
public String callBack() {// 同步回调给用户展示信息return "redirect:" + AlipayConfig.return_order_url;
}

在web-all 项目中添加对应的返回控制器

/*** 支付成功页* @return*/
@GetMapping("pay/success.html")
public String success() {return "payment/success";
}

 

最终跳转到这个页面:

 

(3)支付宝回调—异步回调

 

 

 

 

 

 

... 

 

 

 

 

异步回调有两个重要的职责:

确认并记录用户已付款通知电商模块。新版本的支付接口已经取消了同步回调的支付结果传递。所以用户付款成功与否全看异步回调。

接收到回调要做的事情:

  1. 验证回调信息的真伪
  2. 验证用户付款的成功与否
  3. 把新的支付状态写入支付信息表{paymentInfo}中。
  4. 通知电商
  5. 给支付宝返回回执。

 

 

应用公网暴露 

支付宝异步回调,需要我们的应用在公网上,怎么办呢?可以使用一个软件把我们的应用跟公网绑定,相当于我们的应用就在公网了

 

 

 

authttoken是申请的

双击启动:就实现了我们的应用进行了公网地址的绑定

 

这样就接受到了异步回调的数据了:

 

配置类: 

 

 

 

 

控制器AlipayController

@Autowired
private PaymentService paymentService;
@PostMapping("/callback/notify")
@ResponseBody
public String callbackNotify(@RequestParam Map<String, String> paramsMap){System.out.println("你回来了.....");// Map<String, String> paramsMap = ... // 将异步通知中收到的所有参数都存放到map中//返回的异步结果进行验签boolean signVerified = false; //调用SDK验证签名try {//参数阿里公钥、字符编码、签名算法signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);} catch (AlipayApiException e) {e.printStackTrace();}//  获取异步通知的参数中的订单号!String outTradeNo = paramsMap.get("out_trade_no");//  获取异步通知的参数中的订单总金额!String totalAmount = paramsMap.get("total_amount");//  获取异步通知的参数中的appId!String appId = paramsMap.get("app_id");//  获取异步通知的参数中的交易状态!String tradeStatus = paramsMap.get("trade_status");//  根据outTradeNo 查询数据!PaymentInfo paymentinfo = this.paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());//  保证异步通知的幂等性!notify_idString notifyId = paramsMap.get("notify_id");//  true:if(signVerified){// TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failureif (paymentinfo==null || new BigDecimal("0.01").compareTo(new BigDecimal(totalAmount))!=0|| AlipayConfig.app_id.equals(appId)){return "failure";}//  放入redis! setnx:当 key 不存在的时候生效!Boolean flag = this.redisTemplate.opsForValue().setIfAbsent(notifyId, notifyId, 1462, TimeUnit.MINUTES);//  说明已经处理过了!if (!flag){return "failure";}if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)){//  修改交易记录状态!再订单状态!this.paymentService.paySuccess(outTradeNo,PaymentType.ALIPAY.name(),paramsMap);//  this.paymentService.paySuccess(paymentinfo.getId(),paramsMap);return "success";}}else{// TODO 验签失败则记录异常日志,并在response中返回failure.return "failure";}return "failure";
}

幂等性:多次操作跟一次操作是一样的

这里更上面返回的不一样,返回sucess,支付宝就不会再发送了,如果返回faild支付宝会间隔一段的时间持续发送,返回啥都一样功能都能够实现 

 

为了保证更新支付状态时出现异常,前面存不进去了,出现异常删掉前面Redis中的key 

 

 

接口PaymentService

/*** 获取paymentInfo 对象* @param outTradeNo* @param name* @return*/
PaymentInfo getPaymentInfo(String outTradeNo, String name);/*** 支付成功更新交易记录方法* @param outTradeNo* @param name* @param paramMap*/
void paySuccess(String outTradeNo, String name, Map<String, String> paramMap);/*** 根据outTradeNo 支付方式name 更新数据* @param outTradeNo* @param name* @param paymentInfo*/
void updatePaymentInfo(String outTradeNo, String name, PaymentInfo paymentInfo);

实现类

@Override
public PaymentInfo getPaymentInfo(String outTradeNo, String name) {//  select * from payment_info where out_trade_no = ? and payment_type = ?QueryWrapper<PaymentInfo> paymentInfoQueryWrapper = new QueryWrapper<>();paymentInfoQueryWrapper.eq("out_trade_no",outTradeNo);paymentInfoQueryWrapper.eq("payment_type",name);return paymentInfoMapper.selectOne(paymentInfoQueryWrapper);
}@Override
public void paySuccess(String outTradeNo, String paymentType, Map<String, String> paramsMap) {//  根据outTradeNo,paymentType 查询PaymentInfo paymentInfoQuery = this.getPaymentInfo(outTradeNo, paymentType);if (paymentInfoQuery==null){return;}try {//  改造一下更新的方法!PaymentInfo paymentInfo = new PaymentInfo();//回调时间paymentInfo.setCallbackTime(new Date());//支付状态paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());/回调内容paymentInfo.setCallbackContent(paramsMap.toString());//交易编号paymentInfo.setTradeNo(paramsMap.get("trade_no"));//  查询条件也可以作为更新条件!this.updatePaymentInfo(outTradeNo, paymentType, paymentInfo);} catch (Exception e) {//  删除keythis.redisTemplate.delete(paramsMap.get("notify_id"));e.printStackTrace();}}//  更新交易状态记录!
public void updatePaymentInfo(String outTradeNo, String name, PaymentInfo paymentInfo) {QueryWrapper<PaymentInfo> paymentInfoQueryWrapper = new QueryWrapper<>();paymentInfoQueryWrapper.eq("out_trade_no",outTradeNo);paymentInfoQueryWrapper.eq("payment_type",name);paymentInfoMapper.update(paymentInfo,paymentInfoQueryWrapper);
}

 支付成功后数据库的状态会更改


http://www.ppmy.cn/news/1522599.html

相关文章

【Jupyter Notebook】安装与使用

打开Anaconda Navigator点击"Install"(Launch安装前是Install)点击"Launch"点击"File"-"New"-"Notebook"​ 5.点击"Select"选择Python版本 6.输入测试代码并按"Enter+Shift"运行代码: 代码如下: …

考研系列-408真题数据结构篇(18-23)

写在前面 此文章是本人在备考过程中408真题数据结构部分(2018年-2023年)的易错题及相应的知识点整理,后期复习也尝尝用到,对于知识提炼归纳理解起到了很大的作用,分享出来希望帮助到大家~ # 2018年 1.堆的建立(从后往前进行调整) 2.算法(正整数和数组之间关系的建立)

k8s API资源对象ingress

有了Service之后&#xff0c;我们可以访问这个Service的IP&#xff08;clusterIP&#xff09;来请求对应的Pod&#xff0c;但是这只能是在集群内部访问。 要想让外部用户访问此资源&#xff0c;可以使用NodePort&#xff0c;即在node节点上暴漏一个端口出来&#xff0c;但是这…

pytorch+深度学习实现图像的神经风格迁移

本文的完整代码和部署教程已上传至本人的GitHub仓库&#xff0c;欢迎各位朋友批评指正&#xff01; 1.各代码文件详解 1.1 train.py train.py 文件负责训练神经风格迁移模型。 加载内容和风格图片&#xff1a;使用 utils.load_image 函数加载并预处理内容和风格图片。初始化…

Banana Pi BPI-SM9 AI 计算模组采用算能科技BM1688芯片方案设计

产品概述 香蕉派 Banana Pi BPI-SM9 16-ENC-A3 深度学习计算模组搭载算能科技高集成度处理器 BM1688&#xff0c;功耗低、算力强、接口丰富、兼容性好。支持INT4/INT8/FP16/BF16/FP32混合精度计算&#xff0c;可支持 16 路高清视频实时分析&#xff0c;灵活应对图像、语音、自…

Java中等题-摆动序列(力扣)

如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如&#xff0c; [1, 7, 4, 9, 2, 5] 是一个 摆动序列 &…

数据库锁之行级锁、记录锁、间隙锁和临键锁

1. 行级锁 InnoDB 引擎支持行级锁&#xff0c;而MyISAM 引擎不支持行级锁&#xff0c;只支持表级锁。行级锁是基于索引实现的。 对于普通的select语句&#xff0c;是不会加记录锁的&#xff0c;因为它属于快照读&#xff0c;通过在MVCC中的undo log版本链实现。如果要在查询时对…

Python 安装selenium的办法

之前一直安装python以为要进入python的菜单进行输入 如下 老是提示错误,原来是我搞错了,安装这个直接进入cmd即可 如下 pip install selenium 再用pip list查看一下是否安装成功

git 提交代码由原先账号密码调整为ssh

如果你希望将 Git 提交代码的身份验证方式从用户名和密码切换到 SSH&#xff0c;你需要进行以下几个步骤&#xff1a; 1. 生成 SSH 密钥对 如果你还没有 SSH 密钥对&#xff0c;可以使用以下命令生成一个新的密钥对&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_em…

基于SpringBoot校园快递代取系统

基于springbootvue实现的校园快递代取系统&#xff08;源码L文ppt&#xff09;4-049 3系统设计 3.1.1系统结构图 系统结构图可以把杂乱无章的模块按照设计者的思维方式进行调整排序&#xff0c;可以让设计者在之后的添加&#xff0c;修改程序内容…

C++设计模式——Chain of Responsibility职责链模式

一&#xff0c;职责链模式的定义 职责链模式&#xff0c;又被称为责任链模式&#xff0c;是一种行为型设计模式&#xff0c;它让多个对象依次处理收到的请求&#xff0c;直到处理完成为止。 职责链模式需要使用多个对象&#xff0c;其中的每个对象要么处理请求&#xff0c;要…

iPhone手机清理软件:照片清理功能全解析

在数字化生活中&#xff0c;智能手机成为我们记录生活点滴的主要工具&#xff0c;尤其是iPhone&#xff0c;以其卓越的相机功能备受用户青睐。然而&#xff0c;成千上万的照片迅速堆积&#xff0c;不仅占用了大量存储空间&#xff0c;还使得设备运行缓慢。在众多解决方案中&…

数据传输安全——混合加解密(国密)

国密SM2与SM4混合加密解密工具类详解及其与其他加密算法的对比分析 在当今互联网时代,信息安全变得尤为重要。随着国家密码局发布的商用密码算法(即国密算法)逐渐普及,SM2和SM4等算法因其高效性和安全性成为了国内应用中的重要组成部分。本文不仅将详细介绍一个基于Java的…

如何本地搭建Whisper语音识别模型

要在本地搭建Whisper语音识别模型&#xff0c;你需要遵循以下步骤&#xff0c;注意Whisper模型是由OpenAI发布的&#xff0c;但基于你的要求&#xff0c;这里将尽可能提供详细的指导&#xff1a; 环境准备&#xff1a; 首先&#xff0c;确保你的计算机安装了Python&#xff0c;…

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT&#xff0c;这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频&#xff0c;并利用 SAM 2 进行 3D 空间分割&#xff0c;无需进一步训练或 2D-3D 投影。 我们的框架…

Mac(M2)系统手动安装ADB

ADB压缩包下载地址 下载解压后运行命令 zsh命令 // /Desktop/android为解压后文件夹的路径 ~ 符号表示跟目录1. echo export PATH$PATH:~/Desktop/android/platform-tools/ >> ~/.zshrc// 使第一步配置生效 2. source ~/.zshrc shell命令 // /Desktop/android为解…

计算机组成原理:总线技术深度解析

目录 1. 总线技术概述 1.1 什么是总线&#xff1f; 1.2 总线的基本功能 2. 总线的类型 2.1 内部总线 2.2 外部总线 3. 总线的标准与协议 3.1 常见的总线标准 3.2 总线协议 4. 总线的性能考量 4.1 带宽 4.2 延迟 4.3 可扩展性 5. 总线的未来趋势 6. 结语 在计算机…

VMware中共享文件夹没了怎么办?

1.进入root su root 需要提前设置密码 sudo passwd root 2.创建一个hgfs文件夹&#xff0c;share就在这里面 sudo mkdir /mnt/hgfs/ 3.输入下面的命令 sudo mount -t fuse.vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other 4.然后就能找到share文件夹了&#xff0c;注意每…

PDF读取表格写入EXCEL

声明&#xff1a;只记录&#xff0c;不推荐&#xff0c;因为e-iceblue的spire.pdf是收费的&#xff0c;要licence。 pom引入 <repositories><repository><id>com.e-iceblue</id><name>e-iceblue</name><url>https://repo.e-iceblu…

《云原生安全攻防》-- K8s攻击案例:高权限Service Account接管集群

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 在本节课程中…