一:参考文档
https://opendocs.alipay.com/openHome
二:依赖安装
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.40.0.ALL</version>
</dependency>
三:支付宝配置
alipay:
app-id: 你的沙箱appId
app-private-key: 你的应用私钥
alipay-public-key: 支付宝公钥
notify-url: https://xx/notify #异步回调地址,公网POST
return-url: http://xx/success #用户支付完页面跳转回前端
gateway: https://openapi-sandbox.dl.alipaydev.com/gateway.do #沙箱网关,上线改正式网关
四:支付宝配置读取类
package com.example.demo.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayProperties {
private String appId;
private String appPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
private String returnUrl;
private String gateway;
}
五:支付宝配置类
package com.example.demo.config;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.example.demo.properties.AlipayProperties;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AlipayConfig {
@Resource
private AlipayProperties alipayProperties;
@Bean
public AlipayClient alipayClient()
{
//构造client RSA2,UTF-8,JSON格式
return new DefaultAlipayClient(
alipayProperties.getGateway(),
alipayProperties.getAppId(),
alipayProperties.getAppPrivateKey(),
"json",
"UTF-8",
alipayProperties.getAlipayPublicKey(),
"RSA2");
}
}
六:调用示例
package com.example.demo.controller;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.example.demo.properties.AlipayProperties;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ui.Model;
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 java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@RestController
@RequestMapping("/alipay")
public class AlipayController {
@Resource
private AlipayClient alipayClient;
@Resource
private AlipayProperties alipayProperties;
/**
* 发起支付,电脑网站支付,返回form表单,前端直接渲染自动跳转支付宝收银台
*/
@GetMapping("/create")
public String createPay() throws Exception {
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl(alipayProperties.getReturnUrl());
request.setNotifyUrl(alipayProperties.getNotifyUrl());
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
//商户订单号,必须唯一
String outTradeNo = "ORDER_" + UUID.randomUUID().toString().replace("-","");
model.setOutTradeNo(outTradeNo);
model.setSubject("测试");
model.setTotalAmount("0.01"); //金额,字符串,保留2位小数
model.setProductCode("FAST_INSTANT_TRADE_PAY"); //电脑网站支付固定值
request.setBizModel(model);
//得到form表单html,前端直接输出
String form = alipayClient.pageExecute(request).getBody();
return form;
}
/**
* 【核心】异步通知接口 POST,支付宝主动调用,**必须公网可访问**
* 支付成功/退款等都会回调;验签成功后修改订单状态,返回 success
*/
@PostMapping("/notify")
public String notify(HttpServletRequest request, HttpServletResponse response) throws Exception{
Map<String, String> params = new HashMap<>();
Map<String, String[]> parameterMap = request.getParameterMap();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
params.put(entry.getKey(), entry.getValue()[0]);
}
// 1.验签,确认请求来自支付宝
boolean signVerified = AlipaySignature.rsaCheckV1(
params,
alipayProperties.getAlipayPublicKey(),
"UTF-8",
"RSA2");
if(!signVerified){
//支付宝回调验签失败
return "fail";
}
// 2.业务校验
String tradeStatus = params.get("trade_status");//状态
String outTradeNo = params.get("out_trade_no"); //商户订单号
String tradeNo = params.get("trade_no"); //支付宝交易号
String totalAmount = params.get("total_amount");//金额
if ("TRADE_SUCCESS".equals(tradeStatus)) {
//========业务代码:更新订单状态为已支付,注意幂等!========
}
//支付宝收到 success 就不再重试;返回其他会重复回调
return "success";
}
/**
* 同步页面跳转 returnUrl GET请求
* 支付宝会把参数拼在url后面,GET方式
*/
@GetMapping("/success")
public String returnUrl(HttpServletRequest request, Model model) throws Exception {
Map<String, String> params = new HashMap<>();
Map<String, String[]> parameterMap = request.getParameterMap();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
params.put(entry.getKey(), entry.getValue()[0]);
}
// 同步回调同样需要验签!防止伪造链接
boolean signVerified = AlipaySignature.rsaCheckV1(
params,
alipayProperties.getAlipayPublicKey(),
"UTF-8",
"RSA2");
if (!signVerified) {
//同步回调验签失败
model.addAttribute("msg", "验签失败,非法请求");
return "payFail";
}
// 获取参数
String outTradeNo = params.get("out_trade_no"); //商户订单号
String tradeNo = params.get("trade_no"); //支付宝交易号
String totalAmount = params.get("total_amount");//金额
String tradeStatus = params.get("trade_status");//状态
// 【仅页面展示】不要在这里修改订单状态!
// 建议:主动调用支付宝订单查询接口,实时确认订单状态,再展示页面
AlipayTradeQueryRequest queryRequest = new AlipayTradeQueryRequest();
queryRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\"}");
AlipayTradeQueryResponse resp = alipayClient.execute(queryRequest);
if(resp.isSuccess() && "TRADE_SUCCESS".equals(resp.getTradeStatus())){
model.addAttribute("outTradeNo", outTradeNo);
model.addAttribute("tradeNo", tradeNo);
model.addAttribute("amount", totalAmount);
model.addAttribute("msg", "支付成功");
return "paySuccess";
}else{
model.addAttribute("msg", "订单未支付成功");
return "payFail";
}
}
}
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/huaweichenai/article/details/168228084



