密钥工具下载 - 支付宝文档中心 (alipay.com)https://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;
}
}
}