密钥工具下载 - 支付宝文档中心 (alipay.com)icon-default.png?t=N7T8https://opendocs.alipay.com/common/02kipk

打开手动生成应用公钥和应用私钥

配置pom文件,导入支付宝依赖,这里用的支付宝sdk2

      <!-- 支付宝支付jar包 -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.39.165.ALL</version>
        </dependency>

        <!--slf4j配置-->
        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.3</version>
        </dependency>

配置yml

alipay:
  #应用ID
  appId: ""
  #应用私钥
  applyPrivateKey: "上面生成的应用私钥拿过来"
  #支付宝公钥
  alipayPublicKey: "拿着应用公钥去你支付宝申请的app里面获取支付宝公钥"
  #支付宝通知地址,也就是回调地址,需内网穿透(NATAPP.cn)
  noturl:  http://84cjs9.natappfree.cc/callback

yml映射配置 AilConfig 类

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/*
author:ran
content:yml支付宝映射
date:2024/8/11
 */
@Data
@Component
public class AilConfig {
    @Value("${alipay.appId}")
    private String appId;
    @Value("${alipay.applyPrivateKey}")
    private String applyPrivateKey;
    @Value("${alipay.alipayPublicKey}")
    private String alipayPublicKey;
    @Value("${alipay.noturl}")
    private String noturl;

}

配置接收参数 AlipayDTO 类 

package com.my.dto;
import lombok.Data;
/*
author:ran
content:实体类,用于接收前端传参
date:2024/8/11
 */
@Data
public class AlipayDTO {
//接收前端传的金额
    private String price;
//    商品名
    private String title;
}

编写 AlipayTradeAppPayController类

package com.my.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.my.config.AilConfig;
import com.my.dto.AlipayDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/*
author:ran
content:app调用支付宝完整流程
date:2024/8/11
 */
@Slf4j
@RestController
public class AlipayTradeAppPayController {

    //注入配置类
    @Autowired
    private AilConfig ailConfig;

    //向ali发起请求
    @PostMapping("/pay")
//    这边用对象去接收
    public String pay(@RequestBody AlipayDTO alipayDTO) throws AlipayApiException {
//创建支付宝配置类
        AlipayConfig alipayConfig = new AlipayConfig();
//        请求支付宝地址,固定
        alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
        alipayConfig.setAppId(ailConfig.getAppId());//应用id
        alipayConfig.setPrivateKey(ailConfig.getApplyPrivateKey());//应用私钥
        alipayConfig.setFormat("json");//json格式 固定
        alipayConfig.setAlipayPublicKey(ailConfig.getAlipayPublicKey());//支付宝公钥
        alipayConfig.setCharset("UTF-8");//固定
        alipayConfig.setSignType("RSA2");//固定
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);

        // 构造请求参数以调用接口
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

        // 设置商户订单号,uuid,支付宝要求长度21
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 21);
        model.setOutTradeNo(uuid);

        // 设置通知参数选项
        List<String> queryOptions = new ArrayList<String>();
        queryOptions.add("hyb_amount");
        queryOptions.add("enterprise_pay_info");
        model.setQueryOptions(queryOptions);

        // 设置订单总金额
        model.setTotalAmount(alipayDTO.getPrice());

        // 设置订单标题
        model.setSubject(alipayDTO.getTitle());

        // 设置产品码
        model.setProductCode("QUICK_MSECURITY_PAY");

        // 设置公用回传参数
        model.setPassbackParams("merchantBizType%3d3C%26merchantBizNo%3d2016010101111");

        request.setBizModel(model);
        request.setNotifyUrl(ailConfig.getNoturl());
        // 第三方代调用模式下请设置app_auth_token

        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        String orderStr = response.getBody();

        if (!response.isSuccess()) {
            System.out.println("调用失败");
            return null;
        }
        System.out.println("调用成功");
        return orderStr;
    }


    //回调
    @GetMapping("/callback")
    public Map<String, Object> callback(HttpServletRequest request) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 获取支付宝GET过来反馈信息
            Map<String, String> params = new HashMap<String, String>();
            Map requestParams = request.getParameterMap();
            for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }
            // 获取支付宝的通知返回参数
            String out_trade_no = request.getParameter("out_trade_no");// 商户订单号
            String trade_no = request.getParameter("trade_no");// 支付宝交易号
            String seller_id = request.getParameter("seller_id");// 收款支付宝账号对应的支付宝唯一用户号
            String total_amount = request.getParameter("total_amount");// 交易金额
            String trade_status = request.getParameter("trade_status");// 交易状态
            log.info("notifyUrl异步回调,支付宝订单交易:[商户订单号]" + out_trade_no + ",[支付宝交易号trade_no]" + trade_no + ",[收款支付宝账号seller_id]" + seller_id + ",[交易金额total_amount]" + total_amount + ",[交易状态]" + trade_status);

            //调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, ailConfig.getAlipayPublicKey(), "utf-8"
                    , "RSA2"); //调用SDK验证签名


            if (signVerified) {
                if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
                    //根据商户订单号查询订单信息处理
                    result.put("out_trade_no", out_trade_no);
                    result.put("trade_no", trade_no);
                    result.put("seller_id", seller_id);
                    result.put("total_amount", total_amount);
                    result.put("trade_status", trade_status);
                    result.put("msg", "支付成功");
                    result.put("code", 200);
                    return result;

                } else {
                    result.put("msg", "支付失败");
                    result.put("code", 404);
                    return result;
                }
            } else {
                //验证失败
                log.error("验签失败,请联系管理员解决");
                result.put("msg", "支付失败");
                result.put("code", 500);
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("订单修改失败,请联系管理员解决");
            result.put("msg", "支付失败");
            result.put("code", 500);
            return result;
        }
    }

}
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐