From 2c9f5b8a5a1fec970546f30966d8c5d4351a1f83 Mon Sep 17 00:00:00 2001
From: eric <465889110@qq.com>
Date: Tue, 26 Aug 2025 00:57:06 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=80=E6=AC=BE=E5=B8=A6?=
=?UTF-8?q?=E8=AF=81=E4=B9=A6=E8=AF=B7=E6=B1=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 22 +++
sczx_singlepay.iml | 173 ------------------
.../com/sczx/pay/mapper/OrderPayMapper.java | 2 +-
src/main/java/com/sczx/pay/sdk/WXPay.java | 73 +++++++-
.../java/com/sczx/pay/sdk/WXPayConfig.java | 11 ++
.../sczx/pay/service/WechatPayService.java | 68 ++++++-
src/main/resources/cert/1679965261.p12 | Bin 0 -> 2766 bytes
src/main/resources/cert/1685128771.p12 | Bin 0 -> 2766 bytes
src/main/resources/cert/1699979689.p12 | Bin 0 -> 2766 bytes
src/main/resources/cert/1702736781.p12 | Bin 0 -> 2774 bytes
src/main/resources/cert/1704580401.p12 | Bin 0 -> 2766 bytes
11 files changed, 164 insertions(+), 185 deletions(-)
delete mode 100644 sczx_singlepay.iml
create mode 100644 src/main/resources/cert/1679965261.p12
create mode 100644 src/main/resources/cert/1685128771.p12
create mode 100644 src/main/resources/cert/1699979689.p12
create mode 100644 src/main/resources/cert/1702736781.p12
create mode 100644 src/main/resources/cert/1704580401.p12
diff --git a/pom.xml b/pom.xml
index cdbb910..d430497 100644
--- a/pom.xml
+++ b/pom.xml
@@ -194,6 +194,28 @@
1.15
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+
+
+ org.apache.httpcomponents
+ httpcore
+ 4.4.14
+
+
+
+
+ org.apache.httpcomponents
+ httpmime
+ 4.5.13
+
+
diff --git a/sczx_singlepay.iml b/sczx_singlepay.iml
deleted file mode 100644
index 988da39..0000000
--- a/sczx_singlepay.iml
+++ /dev/null
@@ -1,173 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/com/sczx/pay/mapper/OrderPayMapper.java b/src/main/java/com/sczx/pay/mapper/OrderPayMapper.java
index b8e9fce..c720162 100644
--- a/src/main/java/com/sczx/pay/mapper/OrderPayMapper.java
+++ b/src/main/java/com/sczx/pay/mapper/OrderPayMapper.java
@@ -47,7 +47,7 @@ public interface OrderPayMapper {
"where payment_id = #{paymentId} and del_flag = '0')")
OrderMain getOrderStatusByOrderNo(@Param("paymentId") String paymentId);
- @Update("update zc_order_main as om,zc_order_sub as os set os.transaction_id = #{refundId},os.pay_status = #{payStatus} os.amount = #{refundFee},os.update_time = #{updateTime}" +
+ @Update("update zc_order_main as om,zc_order_sub as os set os.transaction_id = #{refundId},os.pay_status = #{payStatus}, os.amount = #{refundFee},os.update_time = #{updateTime}" +
" where om.order_id = os.order_id and os.payment_id = #{outTradeNo} and os.suborder_type = 'FD_DEPOSIT'" )
int updateSubOrderRefundStatus(@Param("outTradeNo") String outTradeNo,
@Param("payStatus") String payStatus,
diff --git a/src/main/java/com/sczx/pay/sdk/WXPay.java b/src/main/java/com/sczx/pay/sdk/WXPay.java
index 6579de4..db46bf3 100644
--- a/src/main/java/com/sczx/pay/sdk/WXPay.java
+++ b/src/main/java/com/sczx/pay/sdk/WXPay.java
@@ -1,11 +1,27 @@
package com.sczx.pay.sdk;
import com.sczx.pay.utils.WXPayUtil;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContexts;
+import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.KeyStore;
import java.util.Map;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+
+import javax.net.ssl.SSLContext;
+
+
/**
* 微信支付接口
*/
@@ -180,7 +196,7 @@ public class WXPay {
String xml = WXPayUtil.mapToXml(reqData);
logger.info("微信支付请求URL: {}, 请求数据: {}", url, xml);
- String response = httpRequest(url, xml, connectTimeoutMs, readTimeoutMs);
+ String response = httpsRequestWithCert(url, xml, connectTimeoutMs, readTimeoutMs);
logger.info("微信支付响应数据: {}", response);
return response;
@@ -230,6 +246,59 @@ public class WXPay {
}
}
+ /**
+ * 带证书的HTTPS请求
+ */
+ private String httpsRequestWithCert(String url, String requestData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+ // 加载证书
+ KeyStore keyStore = KeyStore.getInstance("PKCS12");
+ FileInputStream instream = new FileInputStream(new File(this.config.getCertPath()));
+ try {
+ keyStore.load(instream, this.config.getMchID().toCharArray());
+ } finally {
+ instream.close();
+ }
+
+ // 创建SSL上下文
+ SSLContext sslcontext = SSLContexts.custom()
+ .loadKeyMaterial(keyStore, this.config.getMchID().toCharArray())
+ .build();
+
+ // 创建SSL连接工厂
+ SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
+ sslcontext,
+ new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"},
+ null,
+ (hostname, session) -> true);
+
+ // 创建HTTP客户端
+ CloseableHttpClient httpclient = HttpClients.custom()
+ .setSSLSocketFactory(sslsf)
+ .build();
+
+ try {
+ // 创建POST请求
+ HttpPost httpost = new HttpPost(url);
+ httpost.addHeader("Content-Type", "application/xml;charset=UTF-8");
+ httpost.setEntity(new StringEntity(requestData, "UTF-8"));
+
+ // 执行请求
+ CloseableHttpResponse response = httpclient.execute(httpost);
+ try {
+ HttpEntity entity = response.getEntity();
+ String result = EntityUtils.toString(response.getEntity(), "UTF-8");
+ EntityUtils.consume(entity);
+ return result;
+ } finally {
+ response.close();
+ }
+ } finally {
+ httpclient.close();
+ }
+ }
+
+
+
/**
* 判断支付结果
*/
@@ -241,4 +310,6 @@ public class WXPay {
return false;
}
}
+
+
}
diff --git a/src/main/java/com/sczx/pay/sdk/WXPayConfig.java b/src/main/java/com/sczx/pay/sdk/WXPayConfig.java
index 8c446f9..95fc7b2 100644
--- a/src/main/java/com/sczx/pay/sdk/WXPayConfig.java
+++ b/src/main/java/com/sczx/pay/sdk/WXPayConfig.java
@@ -21,6 +21,8 @@ public abstract class WXPayConfig {
* 获取 API 密钥
*/
public abstract String getKey();
+
+ private String certPath;
/**
* 获取证书内容
@@ -40,4 +42,13 @@ public abstract class WXPayConfig {
public int getHttpReadTimeoutMs() {
return 8*1000;
}
+
+
+ public String getCertPath() {
+ return certPath;
+ }
+
+ public void setCertPath(String certPath) {
+ this.certPath = certPath;
+ }
}
diff --git a/src/main/java/com/sczx/pay/service/WechatPayService.java b/src/main/java/com/sczx/pay/service/WechatPayService.java
index b49eb17..355cf35 100644
--- a/src/main/java/com/sczx/pay/service/WechatPayService.java
+++ b/src/main/java/com/sczx/pay/service/WechatPayService.java
@@ -20,6 +20,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
+import java.io.File;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
@@ -248,27 +249,35 @@ public class WechatPayService {
return errorResult;
}
+ Map reqData = new HashMap<>();
+ reqData.put("transaction_id",String.valueOf(paymentRecord.getTransactionId()));
+ reqData.put("out_trade_no", request.getOutTradeNo());
+ reqData.put("out_refund_no", request.getOutRefundNo());
+ reqData.put("total_fee", String.valueOf(paymentRecord.getTotalFee()));
+ reqData.put("refund_fee", String.valueOf(request.getRefundFee()));
+ reqData.put("notify_url",refundNotifyUrl);
+
+
// 创建动态配置
DynamicWXPayConfig wxPayConfig = new DynamicWXPayConfig(
appId,
companyConfig.getMchId(),
companyConfig.getApikey(),
- notifyUrl
+ refundNotifyUrl
);
+ String certPath = "classpath*:cert/"+companyConfig.getMchId()+".p12";
+ String certAbsolutePath = getCertAbsolutePath(certPath);
+ wxPayConfig.setCertPath(certAbsolutePath);
+
+
+
WXPay wxPay = new WXPay(wxPayConfig);
- Map reqData = new HashMap<>();
- reqData.put("out_trade_no", request.getOutTradeNo());
- reqData.put("out_refund_no", request.getOutRefundNo());
- reqData.put("total_fee", String.valueOf(paymentRecord.getTotalFee()));
- reqData.put("refund_fee", String.valueOf(request.getRefundFee()));
- reqData.put("notify_url", refundNotifyUrl);
- if (request.getRefundDesc() != null) {
- reqData.put("refund_desc", request.getRefundDesc());
- }
+
+
// 退款需要证书,这里调用带证书的接口
Map result = wxPay.refund(reqData);
@@ -509,4 +518,43 @@ public class WechatPayService {
}
}
+
+ /**
+ * 获取证书文件的绝对路径
+ */
+ private String getCertAbsolutePath(String certPath) {
+ try {
+ // 如果certPath是绝对路径,直接返回
+ if (new File(certPath).isAbsolute()) {
+ return certPath;
+ }
+
+ // 如果是相对路径,则从classpath下获取
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ java.net.URL resource = classLoader.getResource(certPath);
+
+ if (resource != null) {
+ return resource.getPath();
+ } else {
+ // 如果在classpath中找不到,则尝试从当前类的classpath下获取
+ resource = WechatPayService.class.getClassLoader().getResource(certPath);
+ if (resource != null) {
+ return resource.getPath();
+ } else {
+ // 如果还找不到,则使用默认路径
+ String defaultPath = "cert/1679965261.p12";
+ resource = classLoader.getResource(defaultPath);
+ if (resource != null) {
+ return resource.getPath();
+ } else {
+ throw new RuntimeException("无法找到证书文件: " + certPath);
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("获取证书路径失败", e);
+ throw new RuntimeException("获取证书路径失败: " + e.getMessage(), e);
+ }
+ }
+
}
diff --git a/src/main/resources/cert/1679965261.p12 b/src/main/resources/cert/1679965261.p12
new file mode 100644
index 0000000000000000000000000000000000000000..1c638a19694c51f28b052d9c43ec57f350c81701
GIT binary patch
literal 2766
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
Jc#bpEzW~-b4c!0$
literal 0
HcmV?d00001
diff --git a/src/main/resources/cert/1685128771.p12 b/src/main/resources/cert/1685128771.p12
new file mode 100644
index 0000000000000000000000000000000000000000..475779e9fe7067cbb05d9c097cdbad40e88da200
GIT binary patch
literal 2766
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
Ijq7~>0%rCJ`~Uy|
literal 0
HcmV?d00001
diff --git a/src/main/resources/cert/1699979689.p12 b/src/main/resources/cert/1699979689.p12
new file mode 100644
index 0000000000000000000000000000000000000000..ac524362d11ca726e4cf0015330358ec3be71df9
GIT binary patch
literal 2766
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
GwEPQKA{6-m
literal 0
HcmV?d00001
diff --git a/src/main/resources/cert/1702736781.p12 b/src/main/resources/cert/1702736781.p12
new file mode 100644
index 0000000000000000000000000000000000000000..5caa54b17b9d985e849344ef6be6c3db22237e26
GIT binary patch
literal 2774
zcmY+^c{~(~76A7pI*FyPIH{aQ_6M`|YEC6qVgz3`nFN!Q
zYun#DR|5cC4!olZL~hyFhZG%Ait-b|Ho}xoX}_4Rd#1%6=o|e|AhJL>t=i^NZLx8R-@)kvk_WRqy}CaGJap9^XH#$xQ%#%rs2M{nYcVCZ9flFSIXtTYFD&
zuAVT)kb69RwE)>BPVeBzGtls6eE|Aag>%)|nk~K_I&7r2e@Ehyzw|VKNVpgo<5XJa
zLdSnrDNxMOzxyQM@^)yME)R~H!f`u-wHv)y;bV7V$WOlqZ+J=^YEI!0Z=^=lZMg7e
zk%K98;&c9nb(vp`c77LD+?B~KJ;q3j^w#9ZON6O@Y5h)XS}#S`EGM@)b%0fP<>@wo
z-gwNJHio?Bc1yt0udFEC_0#(vTfLq7k;dHY6dC8lo})6Fgh;4+ci4_^XT0gB=bZVi
z5JK^R-eTY=8?*2$(S24~;Z@)u!a7bi*gD$Zeek~1z_;_A@3zR1@foxR-r?Bf64^pj
zSnd79h*^QAF67R!ZM=`7du(Ka3xtDL@|+}ThJxSE%&`PJl6d&e5vI-Z@xF)+hM^c%
zS9E{k%{v*sI@ee$f8sC{c*VyZb{F2BE*!^e_E9=@R$~}Tvoo^t$&)5{?JQGKPoonR
ze@oVX|8>bpD$ss<%b&~`ezEl3ob_>M0wkvd#xy%a*%%SIizV`hWH$g16-S_!9#Xkf
zCs?#2l2K&?dQZB&DGMv&-$GBpB#+XZ1@^#)HcWA9@Tk=1g^~*ISNaoqmYhdLUMAkO
zo;mBM>f7j2^jcO9k!dV1$GLyaN<8O`%_)VU{{tQl1M&u9Kpv;@-P3XepZO1e5GLkR
zCpS-lT>C#2S^icLX>OFm!MHh2TY8kUX{^YvM3dY#lV0rbBCecn
zAjMUarjocKP4Bc9hUsq>x9W47-y_bWjgrm@_^#U%NEvyT*jHzR!xz4QZWYoFAR*t&
zd6aDyQ2dI!nJJ>ns)uqjse>CgZ{Az26H;b9VbvL%Uu9z>{dox<20LM10I*uPN;74{
z@D^c|QM)0x&T62ER6@B-rKL`MMlqsJVqm*kzVS*i(q3>^)@V(nEcHY1l3_LR52wN^
z7kzU-_bFd47ZXJ(4=fLQqWhgjHry|NDNnF5djGL?i~YM`&w0ke`5NvUP#Eqdv2%HK<@xjDE^8d8k<
zidN;Z3M+%$&EN;Jl*24?j;QWfplMG
zzB6TTMg2)YytHvue=3=QQ_vo>>UOD2UO3S9MLn}@JT6O?ow%F-)jK1IRaM)Ck-lHG
z_)F{EnV|=}pTf<&c}=6njtfBTmrE6MHKV)xwnSaKCO^>e`pu|-fY}FqI(4u)av1(R
zw03pb{Tr~FkH59hJ3cd_#DZOjW2@ySGSk>>0wr#$Awpm4Ky~(h$hU$ryXg1=@O77>TbP=dFrrR*UUmzNZC%I)fI
z1q?F}$pgIen-|CCQ|QC@d}K6|?gtjNdGvBdTH-@N@Q0=YTkieO1TM921?MKMNhq4*c(f`rtVRY#Y#L>%G7<-?5eiH{)PF=
zM3>$zgU^+A8eh!T
zTfq41DCs5FuI$jFipVl8QY|wXt|3Jn`LDIlPGKQDBzVG)SNm;}(;OwSSIaDstj7fZG61fIr|Nzzq-qkN_B*
zPC)=Pzz5)US{|n<8sG_6f=j~L!5{@r7G@C;00^t6`F1I@pd`q5g}vv$Rpw5D&fEa9
N@#tWuI&kJ1e*w~-C@ug1
literal 0
HcmV?d00001
diff --git a/src/main/resources/cert/1704580401.p12 b/src/main/resources/cert/1704580401.p12
new file mode 100644
index 0000000000000000000000000000000000000000..9578b62a54ee4d0e4058b7d67bf9495a74edba56
GIT binary patch
literal 2766
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
G;C}JSK|(
literal 0
HcmV?d00001