目录
[2.创建并配置alipay.properties 支付宝的配置文件](#2.创建并配置alipay.properties 支付宝的配置文件)
[3.AliPayConfig.java 读取配置](#3.AliPayConfig.java 读取配置)
[4.AliPayController 支付宝支付的控制层](#4.AliPayController 支付宝支付的控制层)
SSM项目接入支付宝电脑网页沙箱支付可以参考程序员青戈的演示视频【知识点学习】最新版支付宝沙箱支付完整教学,适用于各种基于SpringBoot+Vue管理系统,纯小白也能学的会_哔哩哔哩_bilibili
1.引入支付宝的SDK
在项目的pom中添加支付宝沙箱的必要依赖
java
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.35.79.ALL</version>
</dependency>
2.创建并配置alipay.properties 支付宝的配置文件
支付宝的APPID、应用私钥、支付宝公钥、异步发送通知消息的 URL 地址的获取可以查看支付宝电脑网页沙箱支付demo,and内网穿透技术_idea如何导入支付宝网站支付沙箱环境并运行-CSDN博客
java
alipay.appId=APPID
alipay.appPrivateKey=应用私钥
alipay.alipayPublicKey=支付宝公钥
alipay.notifyUrl=异步发送通知消息的 URL 地址
3.AliPayConfig.java 读取配置
程序员青戈提供的SpringBoot中AliPayConfig.java的配置
java
package com.example.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
private String appId;
private String appPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppPrivateKey() {
return appPrivateKey;
}
public void setAppPrivateKey(String appPrivateKey) {
this.appPrivateKey = appPrivateKey;
}
public String getAlipayPublicKey() {
return alipayPublicKey;
}
public void setAlipayPublicKey(String alipayPublicKey) {
this.alipayPublicKey = alipayPublicKey;
}
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
}
修改为适合我的SSM项目如下
java
@Configuration
@PropertySource("classpath:alipay.properties") // 指定配置文件路径
public class AliPayConfig {
//支付宝的AppId
@Value("${alipay.appId}")
private String appId;
//应用私钥
@Value("${alipay.appPrivateKey}")
private String appPrivateKey;
//支付宝公钥
@Value("${alipay.alipayPublicKey}")
private String alipayPublicKey;
//支付宝通知本地的接口完整地址
@Value("${alipay.notifyUrl}")
private String notifyUrl;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppPrivateKey() {
return appPrivateKey;
}
public void setAppPrivateKey(String appPrivateKey) {
this.appPrivateKey = appPrivateKey;
}
public String getAlipayPublicKey() {
return alipayPublicKey;
}
public void setAlipayPublicKey(String alipayPublicKey) {
this.alipayPublicKey = alipayPublicKey;
}
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
}
4.AliPayController 支付宝支付的控制层
这个接口要根据自己的项目进行更改
但是传入订单编号、订单的总金额等是必要的
这里改为自己项目想要在支付宝支付结束后跳转的页面
java
request.setReturnUrl("http://localhost:8080/orders");
java
package com.example.controller;
import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.example.common.config.AliPayConfig;
import com.example.entity.Orders;
import com.example.service.OrdersService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
// https://natapp.cn/
// ekihat7647@sandbox.com
@RestController
@RequestMapping("/alipay")
public class AliPayController {
// 支付宝沙箱网关地址
private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
private static final String FORMAT = "JSON";
private static final String CHARSET = "UTF-8";
//签名方式
private static final String SIGN_TYPE = "RSA2";
@Resource
private AliPayConfig aliPayConfig;
@Resource
private OrdersService ordersService;
@GetMapping("/pay") // /alipay/pay?orderNo=xxx
public void pay(String orderNo, HttpServletResponse httpResponse) throws Exception {
// 查询订单信息
Orders orders = ordersService.selectByOrderNo(orderNo);
if (orders == null) {
return;
}
// 1. 创建Client,通用SDK提供的Client,负责调用支付宝的API
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
// 2. 创建 Request并设置Request参数
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); // 发送请求的 Request类
request.setNotifyUrl(aliPayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.set("out_trade_no", orders.getOrderNo()); // 我们自己生成的订单编号
bizContent.set("total_amount", orders.getTotal()); // 订单的总金额
bizContent.set("subject", orders.getGoodsName()); // 支付的名称
bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY"); // 固定配置
request.setBizContent(bizContent.toString());
request.setReturnUrl("http://localhost:8080/orders"); // 支付完成后自动跳转到本地页面的路径
// 执行请求,拿到响应的结果,返回给浏览器
String form = "";
try {
form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}
httpResponse.setContentType("text/html;charset=" + CHARSET);
httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
@PostMapping("/notify") // 注意这里必须是POST接口
public void payNotify(HttpServletRequest request) throws Exception {
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
}
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名
// 支付宝验签
if (checkSignature) {
// 验签通过
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
// 更新订单状态为已支付,设置支付信息
Orders orders = ordersService.selectByOrderNo(tradeNo);
orders.setStatus("已支付");
orders.setPayTime(gmtPayment);
orders.setPayNo(alipayTradeNo);
ordersService.updateById(orders);
}
}
}
/**
* 退款接口
*/
@PutMapping("/refund")
public Result refund(String orderNo) {
Orders orders = ordersService.selectByOrderNo(orderNo);
if (ObjectUtil.isNull(orders)) {
throw new CustomException("500", "未找到订单");
}
// 1. 创建Client,通用SDK提供的Client,负责调用支付宝的API
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
// 2. 创建 Request并设置Request参数
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
request.setNotifyUrl(aliPayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.set("out_trade_no", orders.getOrderNo()); // 我们自己生成的订单编号 必须是不重复的退款订单号
bizContent.set("refund_amount", orders.getTotal()); // 订单的总金额
bizContent.set("trade_no", orders.getPayNo()); // 支付宝支付订单号
bizContent.set("out_request_no", IdUtil.fastSimpleUUID()); // 随机数
request.setBizContent(bizContent.toString());
try {
// 退款调用接口
AlipayTradeRefundResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
System.out.println("订单号" + orderNo + "退款成功");
}
Orders dbOrder = ordersService.selectByOrderNo(orderNo);
dbOrder.setStatus("已退款");
ordersService.updateById(dbOrder);
} catch (AlipayApiException e) {
e.printStackTrace();
System.err.println("退款失败");
}
return Result.success();
}
}
根据上面代码修改为我的项目之后如下
我将支付的名称进行了写死,使用的商品信息来源于ItemOrderService,并且进行了传入订单判空处理
java
// https://natapp.cn/
// ekihat7647@sandbox.com
@RestController
@RequestMapping("/alipay")
public class AliPayController {
private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
private static final String FORMAT = "JSON";
private static final String CHARSET = "UTF-8";
private static final String SIGN_TYPE = "RSA2";
@Resource
private AliPayConfig aliPayConfig;
@Resource
private ItemOrderService itemOrderService;
/**
* 支付接口(使用 GET 请求接收订单号)
* @param httpResponse 响应
* @throws Exception 异常
*/
//@GetMapping("/pay")
@CrossOrigin
@RequestMapping(value = "/pay", method = {RequestMethod.GET, RequestMethod.POST})
public void pay(@RequestParam("orderNo") String orderNo, HttpServletResponse httpResponse) throws Exception {
System.out.println("接收到的订单号:" + orderNo);
if (orderNo == null || orderNo.isEmpty()) {
System.out.println("订单号为空");
return;
}
// 查询订单信息
ItemOrder itemOrder = itemOrderService.selectByOrderNo(orderNo);
if (itemOrder == null) {
System.out.println("订单未找到,订单号:" + orderNo);
return;
}
// 构造支付宝支付请求
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setNotifyUrl(aliPayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", itemOrder.getCode()); // 订单号
bizContent.put("total_amount", itemOrder.getTotal()); // 总金额
bizContent.put("subject", "商品购买");
bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
alipayRequest.setBizContent(bizContent.toString());
alipayRequest.setReturnUrl("http://localhost:8080/order/myOrder"); // 支付成功后的回调页面
ItemOrder itemOrderl = itemOrderService.selectByOrderNo(orderNo);
itemOrderl.setStatus(0);//订单已支付
itemOrderService.updateByPrimaryKeySelective(itemOrderl);
// 执行支付请求并获取支付宝表单
String form = alipayClient.pageExecute(alipayRequest).getBody();
System.out.println("支付宝支付表单:" + form);
// 返回支付表单给前端
httpResponse.setContentType("text/html;charset=" + CHARSET);
httpResponse.getWriter().write(form);
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
/**
* 支付宝支付成功的回调接口(POST 请求)
* @param request 支付宝回调请求
* @throws Exception 异常
*/
@PostMapping("/notify")
public void payNotify(HttpServletRequest request) throws Exception {
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
}
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名
// 支付宝验签
if (checkSignature) {
// 验签通过
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
// 更新订单状态为已支付,设置支付信息
ItemOrder itemOrder = itemOrderService.selectByOrderNo(tradeNo);
itemOrder.setStatus(0); // 订单已支付
itemOrderService.updateByPrimaryKeySelective(itemOrder);
}
}
}
}
5.接入本人的SSM项目的逻辑流程
5.1引入支付宝依赖
5.2配置alipay.properties
5.3我的订单结算
这里能自动生成订单号,并将订单号传给前端
java
@RequestMapping("/exAdd")
@ResponseBody
public ResponseEntity<String> exAdd(@RequestBody List<CartDto> list, HttpServletRequest request, HttpSession session, HttpServletResponse response) throws Exception {
JSONObject js = new JSONObject();//构造JSON响应数据
Object attribute = session.getAttribute("userId");
if (attribute == null) {
js.put(Consts.RES, 0); // 用户未登录
response.setContentType("application/json"); // 确保响应头是 JSON
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(js.toJSONString()); // 返回 401 Unauthorized
}
Integer userId = Integer.valueOf(attribute.toString());//将userId转换为整数
User byId = userService.getById(userId);
if (StringUtils.isEmpty(byId.getAddress())) {
js.put(Consts.RES, 2); // 地址未设置
response.setContentType("application/json"); // 确保响应头是 JSON
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(js.toJSONString()); // 返回 400 Bad Request
}
//计算总金额
//保存id列表
List<Integer> ids = new ArrayList<>();
BigDecimal to = new BigDecimal(0);
for (CartDto c : list) {
ids.add(c.getId());
Cart load = cartService.selectByPrimaryKey(c.getId());
BigDecimal price = load.getPrice();
Integer num = c.getNum();
to = to.add(price.multiply(new BigDecimal(num)));
}
// 生成订单号
long orderNoLong = getOrderNo(); // long 类型订单号
String orderNoString = String.valueOf(orderNoLong); // 转换为 String 类型存储在数据库
// 生成订单
ItemOrder itemOrder = new ItemOrder();
itemOrder.setStatus(4); // 订单状态:待支付
itemOrder.setCode(orderNoString); // 使用字符串订单号存储在数据库中
itemOrder.setTotal(to.setScale(2, BigDecimal.ROUND_HALF_UP).toString());//设置订单总金额 两位小数
itemOrder.setUserId(userId);
itemOrder.setAddtime(new Date());//添加当前时间
itemOrderService.insert(itemOrder);
// 插入订单详情
// 为每个购物车生成订单详情
for (CartDto c : list) {
Cart load = cartService.selectByPrimaryKey(c.getId());
OrderDetail de = new OrderDetail();
de.setItemId(load.getItemId());
de.setOrderId(itemOrder.getId());
de.setStatus(4); // 待支付
de.setNum(c.getNum());
de.setTotal(load.getPrice().multiply(new BigDecimal(c.getNum())).toString());
orderDetailService.insert(de);
// 更新商品成交数量
Item load2 = itemService.selectByPrimaryKey(load.getItemId());
load2.setGmnum(load2.getGmnum() + c.getNum());
itemService.updateByPrimaryKeySelective(load2);
// 删除购物车
cartService.deleteByPrimaryKey(c.getId());
}
js.put(Consts.RES, 1);
js.put("orderNo", orderNoString); // 返回字符串格式订单号
response.setContentType("application/json"); // 确保响应头是 JSON
return ResponseEntity.status(HttpStatus.OK).body(js.toJSONString()); // 返回 200 OK 和 JSON 内容
}
// 生成订单号(long 类型)
private static String date;
private static long orderNum = 0L;
public static synchronized long getOrderNo() {
String str = new SimpleDateFormat("yyyyMMddHHmm").format(new Date());
if (date == null || !date.equals(str)) {
date = str;
orderNum = 0L;
}
orderNum++;
long orderNO = Long.parseLong(date) * 10000;
orderNO += orderNum;
return orderNO; // 返回 long 类型订单号
}
5.4结算的前端和支付宝的调用
java
/**
* 结算--进入购买流程
*/
function ifJs() {
var arr = [];
$(".xzWxz.on").each(function () {
var $id = $(this).parent().attr("data-id");
var $num = $(this).parent().find(".xzSl").find("input").val();
var obj = {};
obj.id = $id;
obj.num = $num;
arr.push(obj);
});
if (arr.length === 0) {
alert("请至少选择一个商品结算");
return false;
}
console.log(arr); // 打印要发送的请求数据,检查格式
$.ajax({
type: "POST",
url: "/order/exAdd",
data: JSON.stringify(arr),
contentType: "application/json", // 确保请求头是 JSON 格式
dataType: "json", // 告诉 jQuery 期望服务器返回 JSON 格式的响应
success: function (result, textStatus, xhr) {
// 打印原始返回结果
console.log('原始返回结果:', result);
// 检查返回的 Content-Type 是否为 JSON 格式
var contentType = xhr.getResponseHeader("Content-Type");
if (contentType && contentType.includes("application/json")) {
console.log("返回的内容是 JSON 格式");
} else {
console.error("返回的响应是非 JSON 内容,可能是错误页面");
alert("请求失败,服务器返回的是非 JSON 内容,可能是错误页面");
// 如果是登录问题或权限问题,可以重定向到登录页面
if (result && result.includes && result.includes("登录")) {
window.location.href = "/user/uIndex"; // 重定向到登录页面
}
return;
}
try {
// 如果返回的是字符串,尝试解析成 JSON 对象
if (typeof result === 'string') {
result = JSON.parse(result);
console.log('解析后的结果:', result);
}
// 确保 result 是一个有效的对象
if (typeof result !== 'object' || result === null) {
throw new Error("返回的结果不是有效的对象");
}
const responseData = result;
// 根据返回的 res 值执行不同的操作
if (responseData.res === 0) {
alert("请登录");
window.location.href = "/user/uIndex";
} else if (responseData.res === 2) {
alert("请编辑地址");
} else if (responseData.res === 1) {
if (responseData.orderNo) {
//alert("购买成功:" + responseData.orderNo);
console.log("购买成功:", responseData.orderNo);
// 调用支付逻辑
startAlipayPayment(responseData.orderNo);
} else {
console.error('返回数据中没有 orderNo');
}
} else {
console.error("未知的返回值:", responseData);
alert("系统异常,请稍后再试");
}
} catch (e) {
console.error('解析响应数据时发生错误:', e);
alert("请求失败,无法处理返回数据");
}
},
error: function (xhr, textStatus, errorThrown) {
// 打印错误日志
console.error("请求失败,状态:", textStatus, "错误信息:", errorThrown);
alert("请求失败,请稍后再试");
}
});
}
// 启动支付宝支付
function startAlipayPayment(orderNo) {
//alert("orderNo: " + orderNo);
var requestUrl = "/alipay/pay"; // 直接请求支付接口的 URL
console.log("请求 URL: ", requestUrl); // 打印请求 URL,查看是否正确拼接了 orderNo
// 创建一个临时表单
var formElement = document.createElement('form');
formElement.action = requestUrl; // 设置表单的目标地址
formElement.method = 'POST'; // 使用 POST 提交表单
// 创建一个隐藏的输入字段用于传递订单号
var orderNoInput = document.createElement('input');
orderNoInput.type = 'hidden';
orderNoInput.name = 'orderNo';
orderNoInput.value = orderNo;
// 将隐藏字段添加到表单
formElement.appendChild(orderNoInput);
// 将表单元素添加到页面
document.body.appendChild(formElement);
// 提交表单进行支付
formElement.submit();
}
5.5支付宝调用的后端
java
/**
* 支付宝执行
*/
@RestController
@RequestMapping("/alipay")
public class AliPayController {
private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
private static final String FORMAT = "JSON";
private static final String CHARSET = "UTF-8";
private static final String SIGN_TYPE = "RSA2";
@Resource
private AliPayConfig aliPayConfig;
@Resource
private ItemOrderService itemOrderService;
/**
* 支付接口(使用 GET 请求接收订单号)
* @param httpResponse 响应
* @throws Exception 异常
*/
//@GetMapping("/pay")
@CrossOrigin
//允许跨域请求
@RequestMapping(value = "/pay", method = {RequestMethod.GET, RequestMethod.POST})
public void pay(@RequestParam("orderNo") String orderNo, HttpServletResponse httpResponse) throws Exception {
System.out.println("接收到的订单号:" + orderNo);
if (orderNo == null || orderNo.isEmpty()) {
System.out.println("订单号为空");
return;
}
// 查询订单信息
ItemOrder itemOrder = itemOrderService.selectByOrderNo(orderNo);
if (itemOrder == null) {
System.out.println("订单未找到,订单号:" + orderNo);
return;
}
// 构造支付宝支付请求
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setNotifyUrl(aliPayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", itemOrder.getCode()); // 订单号
bizContent.put("total_amount", itemOrder.getTotal()); // 总金额
bizContent.put("subject", "商品购买");
bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
alipayRequest.setBizContent(bizContent.toString());
alipayRequest.setReturnUrl("http://localhost:8080/order/myOrder"); // 支付成功后的回调页面
ItemOrder itemOrderl = itemOrderService.selectByOrderNo(orderNo);
itemOrderl.setStatus(0);//订单已支付
itemOrderService.updateByPrimaryKeySelective(itemOrderl);
// 执行支付请求并获取支付宝表单
String form = alipayClient.pageExecute(alipayRequest).getBody();
System.out.println("支付宝支付表单:" + form);
// 返回支付表单给前端
httpResponse.setContentType("text/html;charset=" + CHARSET);
httpResponse.getWriter().write(form);
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
/**
* 支付宝支付成功的回调接口(POST 请求)
* @param request 支付宝回调请求
* @throws Exception 异常
*/
@PostMapping("/notify")
public void payNotify(HttpServletRequest request) throws Exception {
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
}
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名
// 支付宝验签
if (checkSignature) {
// 验签通过
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
// 更新订单状态为已支付,设置支付信息
ItemOrder itemOrder = itemOrderService.selectByOrderNo(tradeNo);
itemOrder.setStatus(0); // 订单已支付
itemOrderService.updateByPrimaryKeySelective(itemOrder);
}
}
}
}