|
|
@@ -2,6 +2,7 @@ package com.yingpai.gupiao.service.impl;
|
|
|
|
|
|
import com.wechat.pay.java.core.Config;
|
|
|
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
|
|
+import com.wechat.pay.java.core.RSAPublicKeyConfig;
|
|
|
import com.wechat.pay.java.core.notification.NotificationConfig;
|
|
|
import com.wechat.pay.java.core.notification.NotificationParser;
|
|
|
import com.wechat.pay.java.core.notification.RequestParam;
|
|
|
@@ -52,7 +53,9 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
String apiV3Key = wxPayConfigService.getApiV3Key();
|
|
|
String privateKeyPath = wxPayConfigService.getPrivateKeyPath();
|
|
|
String certPath = wxPayConfigService.getCertPath();
|
|
|
- return mchId + "|" + apiV3Key + "|" + privateKeyPath + "|" + certPath;
|
|
|
+ String publicKeyPath = wxPayConfigService.getPublicKeyPath();
|
|
|
+ String publicKeyId = wxPayConfigService.getPublicKeyId();
|
|
|
+ return mchId + "|" + apiV3Key + "|" + privateKeyPath + "|" + certPath + "|" + publicKeyPath + "|" + publicKeyId;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -73,8 +76,10 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
String apiV3Key = wxPayConfigService.getApiV3Key();
|
|
|
String privateKeyPath = wxPayConfigService.getPrivateKeyPath();
|
|
|
String certPath = wxPayConfigService.getCertPath();
|
|
|
+ String publicKeyPath = wxPayConfigService.getPublicKeyPath();
|
|
|
+ String publicKeyId = wxPayConfigService.getPublicKeyId();
|
|
|
|
|
|
- if (mchId.isEmpty() || apiV3Key.isEmpty() || privateKeyPath.isEmpty() || certPath.isEmpty()) {
|
|
|
+ if (mchId.isEmpty() || apiV3Key.isEmpty() || privateKeyPath.isEmpty()) {
|
|
|
log.warn("微信支付配置不完整,跳过初始化");
|
|
|
config = null;
|
|
|
jsapiService = null;
|
|
|
@@ -89,13 +94,30 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
String mchSerialNo = loadCertSerialNo(certPath);
|
|
|
log.info("从证书读取序列号: {}", mchSerialNo);
|
|
|
|
|
|
- // 构建配置(自动获取微信平台证书)
|
|
|
- config = new RSAAutoCertificateConfig.Builder()
|
|
|
- .merchantId(mchId)
|
|
|
- .privateKey(privateKey)
|
|
|
- .merchantSerialNumber(mchSerialNo)
|
|
|
- .apiV3Key(apiV3Key)
|
|
|
- .build();
|
|
|
+ // 判断使用公钥模式还是自动证书模式
|
|
|
+ if (!publicKeyPath.isEmpty() && !publicKeyId.isEmpty()) {
|
|
|
+ // 使用微信支付公钥模式(新商户)
|
|
|
+ log.info("使用微信支付公钥模式初始化,公钥路径: {}", publicKeyPath);
|
|
|
+ String publicKey = loadPublicKey(publicKeyPath);
|
|
|
+
|
|
|
+ config = new RSAPublicKeyConfig.Builder()
|
|
|
+ .merchantId(mchId)
|
|
|
+ .privateKey(privateKey)
|
|
|
+ .merchantSerialNumber(mchSerialNo)
|
|
|
+ .apiV3Key(apiV3Key)
|
|
|
+ .publicKey(publicKey)
|
|
|
+ .publicKeyId(publicKeyId)
|
|
|
+ .build();
|
|
|
+ } else {
|
|
|
+ // 使用自动下载平台证书模式(老商户)
|
|
|
+ log.info("使用自动证书模式初始化");
|
|
|
+ config = new RSAAutoCertificateConfig.Builder()
|
|
|
+ .merchantId(mchId)
|
|
|
+ .privateKey(privateKey)
|
|
|
+ .merchantSerialNumber(mchSerialNo)
|
|
|
+ .apiV3Key(apiV3Key)
|
|
|
+ .build();
|
|
|
+ }
|
|
|
|
|
|
// 初始化JSAPI服务
|
|
|
jsapiService = new JsapiServiceExtension.Builder().config(config).build();
|
|
|
@@ -154,6 +176,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
.packageValue(response.getPackageVal())
|
|
|
.signType(response.getSignType())
|
|
|
.paySign(response.getPaySign())
|
|
|
+ .totalFee(amount)
|
|
|
.build();
|
|
|
}
|
|
|
|
|
|
@@ -207,6 +230,32 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
return transaction.getTradeState().name();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public String queryOrderByOutTradeNo(String orderNo) {
|
|
|
+ log.info("查询微信订单,orderNo: {}", orderNo);
|
|
|
+
|
|
|
+ // 确保SDK已初始化
|
|
|
+ ensureInitialized();
|
|
|
+
|
|
|
+ if (jsapiService == null) {
|
|
|
+ throw new RuntimeException("微信支付未初始化");
|
|
|
+ }
|
|
|
+
|
|
|
+ QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
|
|
|
+ request.setMchid(wxPayConfigService.getMchId());
|
|
|
+ request.setOutTradeNo(orderNo);
|
|
|
+
|
|
|
+ try {
|
|
|
+ Transaction transaction = jsapiService.queryOrderByOutTradeNo(request);
|
|
|
+ if (transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
|
|
|
+ return transaction.getTransactionId();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询微信订单失败,orderNo: {}", orderNo, e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public boolean refund(String orderNo, String refundNo, Integer totalAmount,
|
|
|
Integer refundAmount, String reason) {
|
|
|
@@ -234,6 +283,27 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 加载微信支付公钥文件
|
|
|
+ */
|
|
|
+ private String loadPublicKey(String path) {
|
|
|
+ try {
|
|
|
+ if (path.startsWith("classpath:")) {
|
|
|
+ String resourcePath = path.replace("classpath:", "");
|
|
|
+ ClassPathResource resource = new ClassPathResource(resourcePath);
|
|
|
+ try (BufferedReader reader = new BufferedReader(
|
|
|
+ new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) {
|
|
|
+ return reader.lines().collect(Collectors.joining("\n"));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return java.nio.file.Files.readString(java.nio.file.Paths.get(path));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("加载公钥失败: {}", path, e);
|
|
|
+ throw new RuntimeException("加载公钥失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 从证书文件读取序列号
|
|
|
*/
|