添加支付宝支付能力

This commit is contained in:
zk
2026-05-15 11:45:00 +08:00
parent fda9cc17ef
commit 221456681b
11 changed files with 383 additions and 11 deletions
+5
View File
@@ -63,6 +63,11 @@
<artifactId>wechatpay-java</artifactId>
<version>0.2.15</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.40.791.ALL</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
@@ -0,0 +1,41 @@
package org.jiayunet.alipay;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 支付宝客户端配置
*
* @author zk
*/
@Configuration
@ConditionalOnProperty(name = "alipay.status", havingValue = "open")
public class AlipayClientConfig {
@Value("${alipay.app_id}")
private String appId;
@Value("${alipay.private_key}")
private String privateKey;
@Value("${alipay.alipay_public_key}")
private String alipayPublicKey;
@Bean
public AlipayClient alipayClient() throws Exception {
AlipayConfig config = new AlipayConfig();
config.setServerUrl("https://openapi.alipay.com/gateway.do");
config.setAppId(appId);
config.setPrivateKey(privateKey);
config.setFormat("json");
config.setAlipayPublicKey(alipayPublicKey);
config.setCharset("UTF-8");
config.setSignType("RSA2");
return new DefaultAlipayClient(config);
}
}
@@ -0,0 +1,74 @@
package org.jiayunet.alipay;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* 支付宝支付回调入口
*
* @author zk
*/
@RestController
@ConditionalOnProperty(name = "alipay.status", havingValue = "open")
@RequestMapping("/public/alipayNotify")
@Slf4j
public class AlipayNotifyController {
@Value("${alipay.alipay_public_key}")
private String alipayPublicKey;
@Autowired
private AlipayNotifyMessageAbstract alipayNotifyMessageAbstract;
/**
* 支付结果回调
*/
@PostMapping("/pay")
public String pay(HttpServletRequest request) {
// 1. 获取所有回调参数
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
String[] values = requestParams.get(name);
String valueStr = String.join(",", values);
params.put(name, valueStr);
}
log.info("收到支付宝支付回调数据:{}", params);
// 2. SDK验签
boolean signVerified;
try {
signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
} catch (AlipayApiException e) {
log.error("支付宝回调验签异常", e);
return "failure";
}
if (!signVerified) {
log.error("支付宝回调验签失败 params:{}", params);
return "failure";
}
// 3. 验签通过,处理业务
try {
alipayNotifyMessageAbstract.payMessageHandle(params);
} catch (Exception e) {
log.error("支付宝回调业务处理异常", e);
return "failure";
}
return "success";
}
}
@@ -0,0 +1,21 @@
package org.jiayunet.alipay;
import java.util.Map;
/**
* 支付宝支付回调消息处理接口
* 使用前需要实现接口
*
* @author zk
*/
public interface AlipayNotifyMessageAbstract {
/**
* 支付结果回调消息处理
*
* @param params 回调参数(已验签)
*/
default void payMessageHandle(Map<String, String> params) {
System.out.println("支付宝支付的支付结果回调消息未处理");
}
}
@@ -0,0 +1,61 @@
package org.jiayunet.alipay;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
/**
* 支付宝电脑网站支付能力
*
* @author zk
*/
@ConditionalOnProperty(name = "alipay.status", havingValue = "open")
@Component
@Slf4j
public class AlipayPagePayAbility {
@Autowired
private AlipayClient alipayClient;
@Value("${alipay.notify_domain}")
private String notifyDomain;
/**
* 电脑网站支付下单
*
* @param outTradeNo 商户订单号
* @param totalAmount 金额(元),如 "39.00"
* @param subject 订单标题
* @return HTML表单字符串,前端直接渲染(内嵌二维码)
*/
public String prepay(String outTradeNo, String totalAmount, String subject) {
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(notifyDomain + "/public/alipayNotify/pay");
log.info("以默认设置支付宝回调地址为:{}", request.getNotifyUrl());
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
model.setOutTradeNo(outTradeNo);
model.setTotalAmount(totalAmount);
model.setSubject(subject);
model.setProductCode("FAST_INSTANT_TRADE_PAY");
model.setQrPayMode("4");
model.setQrcodeWidth(200L);
request.setBizModel(model);
try {
AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "POST");
return response.getBody();
} catch (AlipayApiException e) {
log.error("支付宝下单异常 outTradeNo:{} error:{}", outTradeNo, e.getMessage());
}
throw new RuntimeException("支付宝下单异常");
}
}