支付宝沙箱接入SSM项目

目录

1.引入支付宝的SDK

[2.创建并配置alipay.properties 支付宝的配置文件](#2.创建并配置alipay.properties 支付宝的配置文件)

[3.AliPayConfig.java 读取配置](#3.AliPayConfig.java 读取配置)

[4.AliPayController 支付宝支付的控制层](#4.AliPayController 支付宝支付的控制层)

5.接入本人的SSM项目的逻辑流程

5.1引入支付宝依赖

5.2配置alipay.properties

5.3我的订单结算

5.4结算的前端和支付宝的调用

5.5支付宝调用的后端


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);
            }
        }
    }

}
相关推荐
ytuglt几秒前
android framework.jar 在应用中使用
android·java·jar
爱喝ad奶2 分钟前
maven 下载依赖 jhash:2.1.2 和对应 jar 包
java·maven·jar
Yang-Never26 分钟前
Shader -> RadialGradient圆心渐变着色器详解
android·java·kotlin·android studio
AnnyYoung1 小时前
yum系统报错:SyntaxError: multiple exception types must be parenthesized
linux·运维·服务器·centos
master-dragon1 小时前
Spring bean的生命周期和扩展
java·spring
茉莉玫瑰花茶1 小时前
Linux第一个系统程序---进度条
linux·运维·服务器
java1234_小锋1 小时前
Redis有哪些常用应用场景?
java·数据库·redis
潇与上海1 小时前
【pycharm发现找不到python打包工具,且无法下载】
ide·python·pycharm
代码飞走咯1 小时前
PyCharm文档管理
ide·python·pycharm
beiback1 小时前
下载导出Tomcat上的excle文档,浏览器上显示下载
java·tomcat