From 9486766c806fe1d9e082b2fd02ea1cc558f1b443 Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期四, 08 五月 2025 09:21:57 +0800
Subject: [PATCH] bug修改

---
 cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java |  444 +++++++++++++++++++++++++++---------------------------
 1 files changed, 222 insertions(+), 222 deletions(-)

diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java
index 0b243e3..bd24df0 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java
@@ -1,222 +1,222 @@
-//package com.dsh.activity.util.wx;
-//
-//import com.dsh.activity.util.wx.WXPayConstants;
-//import com.dsh.activity.util.wx.WXPaySignatureCertificateUtil;
-//import com.dsh.activity.util.wx.WxV3PayConfig;
-//import com.fasterxml.jackson.databind.JsonNode; // 引入Jackson库处理JSON
-//import com.fasterxml.jackson.databind.ObjectMapper;
-//import com.fasterxml.jackson.databind.node.ObjectNode;
-//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.util.EntityUtils;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Component;
-//import org.springframework.stereotype.Service;
-//
-//import java.io.IOException;
-//import java.math.BigDecimal;
-//import java.nio.charset.StandardCharsets;
-//import java.util.HashMap;
-//import java.util.Map;
-//
-//@Component
-//public class WxAppPayService {
-//
-//    private static final Logger log = LoggerFactory.getLogger(WxAppPayService.class);
-//
-//    private final ObjectMapper objectMapper; // 用于JSON序列化和反序列化
-//    private final CloseableHttpClient wechatPayClient; // 注入通过工具类创建的HTTP客户端
-//
-//    @Autowired
-//    public WxAppPayService(ObjectMapper objectMapper) throws IOException {
-//        this.objectMapper = objectMapper;
-//        // 在构造函数中初始化带有签名验证功能的HTTP客户端
-//        this.wechatPayClient = WXPaySignatureCertificateUtil.getWechatPayClient();
-//        log.info("微信支付V3 HTTP客户端初始化完成。");
-//    }
-//
-//    /**
-//     * 创建APP支付预付单 (统一下单)
-//     *
-//     * @param description 商品描述
-//     * @param outTradeNo  商户订单号 (要求32个字符内,只能是数字、大小写字母_-|* 且在同一个商户号下唯一)
-//     * @param totalAmount 支付总金额 (单位:元)
-//     * @return 用于调起APP支付的参数 Map (appid, partnerid, prepayid, package, noncestr, timestamp, sign)
-//     * @throws IOException          网络或IO异常
-//     * @throws RuntimeException     支付请求失败或处理异常
-//     */
-//    public Map<String, String> createOrder(String description, String outTradeNo, BigDecimal totalAmount)
-//            throws IOException {
-//
-//        // 1. 构建请求URL
-//        String url = WXPayConstants.DOMAIN_API + WXPayConstants.PAY_TRANSACTIONS_APP;
-//        HttpPost httpPost = new HttpPost(url);
-//        httpPost.addHeader("Accept", "application/json");
-//        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
-//
-//        // 2. 构建请求体 JSON
-//        ObjectNode rootNode = objectMapper.createObjectNode();
-////        rootNode.put("appid", WxV3PayConfig.APP_ID);//服务商不需要该字段
-////        rootNode.put("mchid", WxV3PayConfig.Mch_ID);//服务商不需要该字段
-//        rootNode.put("description", description);
-//        rootNode.put("out_trade_no", outTradeNo);
-//        rootNode.put("notify_url", WXPayConstants.WECHAT_PAY_NOTIFY_URL); // 使用常量中的回调地址
-//
-//        ObjectNode amountNode = objectMapper.createObjectNode();
-//        // 微信支付金额单位为分,需要转换
-//        amountNode.put("total", totalAmount.multiply(new BigDecimal("100")).intValue());
-//        amountNode.put("currency", "CNY"); // 货币类型,默认人民币
-//        rootNode.set("amount", amountNode);
-//
-//        // 如果你是服务商模式,需要添加子商户信息
-//        rootNode.put("sp_mchid", WxV3PayConfig.Mch_ID);
-//        rootNode.put("sub_mchid", "123");
-//         rootNode.put("sp_appid", "wx41d32f362ba0f911");
-//        // rootNode.put("sub_appid", "子商户AppID"); // 如果子商户需要用自己的AppID拉起支付
-//
-//        String requestBody = rootNode.toString();
-//        log.info("微信APP支付下单请求体: {}", requestBody);
-//        httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
-//
-//        // 3. 发送请求
-//        try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
-//            int statusCode = response.getStatusLine().getStatusCode();
-//            String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
-//            log.info("微信APP支付下单响应状态码: {}, 响应体: {}", statusCode, responseBody);
-//
-//            if (statusCode == 200) { // HTTP状态码 200 表示成功
-//                JsonNode responseNode = objectMapper.readTree(responseBody);
-//                String prepayId = responseNode.get("prepay_id").asText();
-//                log.info("成功获取预支付交易会话标识 (prepay_id): {}", prepayId);
-//
-//                // 4. 生成调起支付所需的参数
-//                Map<String, String> payParams = WXPaySignatureCertificateUtil.buildAppPayParams(prepayId);
-//                log.info("生成APP支付参数: {}", payParams);
-//                return payParams;
-//
-//            } else {
-//                // 处理错误情况
-//                log.error("微信APP支付下单失败,状态码: {}, 响应: {}", statusCode, responseBody);
-//                // 可以根据 responseBody 中的 code 和 message 进一步分析错误
-//                throw new RuntimeException("微信APP支付下单失败: " + responseBody);
-//            }
-//        } catch (Exception e) {
-//            log.error("微信APP支付下单请求执行异常", e);
-//            throw new IOException("微信APP支付下单请求执行异常", e);
-//        }
-//    }
-//
-//     /**
-//     * 关闭订单 (根据商户订单号)
-//     *
-//     * @param outTradeNo 商户订单号
-//     * @return true 如果关闭成功或订单已关闭/不存在 (根据微信文档,成功是204 No Content)
-//     * @throws IOException          网络或IO异常
-//     * @throws RuntimeException     关闭请求失败或处理异常
-//     */
-//    public boolean closeOrder(String outTradeNo) throws IOException {
-//        // 1. 构建请求URL, 注意替换占位符
-//        String url = WXPayConstants.DOMAIN_API
-//                   + WXPayConstants.PAY_TRANSACTIONS_OUT_TRADE_NO.replace("{}", outTradeNo);
-//
-//        HttpPost httpPost = new HttpPost(url);
-//        httpPost.addHeader("Accept", "application/json");
-//        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
-//
-//        // 2. 构建请求体 JSON (只需要商户号)
-//        ObjectNode rootNode = objectMapper.createObjectNode();
-//        rootNode.put("mchid", WxV3PayConfig.Mch_ID);
-//        // 如果是服务商模式,则用 sp_mchid
-//         rootNode.put("sp_mchid", WxV3PayConfig.Mch_ID);
-//
-//        String requestBody = rootNode.toString();
-//        log.info("微信关单请求 URL: {}, 请求体: {}", url, requestBody);
-//        httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
-//
-//        // 3. 发送请求
-//        try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
-//            int statusCode = response.getStatusLine().getStatusCode();
-//            // 关单成功时,微信返回 HTTP 状态码 204 No Content
-//            log.info("微信关单响应状态码: {}", statusCode);
-//            if (statusCode == 204) {
-//                log.info("订单 {} 关闭成功。", outTradeNo);
-//                return true;
-//            } else {
-//                String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
-//                log.error("微信关单失败,商户订单号: {}, 状态码: {}, 响应: {}", outTradeNo, statusCode, responseBody);
-//                // 根据需要可以解析responseBody获取错误详情
-//                return false; // 或者抛出异常,根据业务决定
-//            }
-//        } catch (Exception e) {
-//            log.error("微信关单请求执行异常, 商户订单号: {}", outTradeNo, e);
-//            throw new IOException("微信关单请求执行异常", e);
-//        }
-//    }
-//
-//
-//    // --- 退款相关方法 (可选) ---
-//
-//    /**
-//     * 申请退款
-//     *
-//     * @param outTradeNo   原商户订单号
-//     * @param outRefundNo  商户退款单号 (商户系统内部的退款单号,要求唯一)
-//     * @param reason       退款原因 (可选)
-//     * @param refundAmount 退款金额 (单位:元)
-//     * @param totalAmount  原订单总金额 (单位:元)
-//     * @return 退款处理结果,可以返回微信返回的JSON节点或自定义对象
-//     * @throws IOException          网络或IO异常
-//     * @throws RuntimeException     退款请求失败或处理异常
-//     */
-//    public JsonNode createRefund(String outTradeNo, String outRefundNo, String reason,
-//                                BigDecimal refundAmount, BigDecimal totalAmount) throws IOException {
-//
-//        String url = WXPayConstants.DOMAIN_API + WXPayConstants.REFUND_DOMESTIC_REFUNDS;
-//        HttpPost httpPost = new HttpPost(url);
-//        httpPost.addHeader("Accept", "application/json");
-//        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
-//
-//        ObjectNode rootNode = objectMapper.createObjectNode();
-//        // 如果是服务商模式,需要添加子商户号
-//        // rootNode.put("sub_mchid", "子商户号");
-//        rootNode.put("out_trade_no", outTradeNo);
-//        rootNode.put("out_refund_no", outRefundNo);
-//        if (reason != null && !reason.isEmpty()) {
-//            rootNode.put("reason", reason);
-//        }
-//        // 设置退款回调地址
-//        rootNode.put("notify_url", WXPayConstants.WECHAT_REFUNDS_NOTIFY_URL);
-//
-//        ObjectNode amountNode = objectMapper.createObjectNode();
-//        amountNode.put("refund", refundAmount.multiply(new BigDecimal("100")).intValue()); // 退款金额,分
-//        amountNode.put("total", totalAmount.multiply(new BigDecimal("100")).intValue());   // 原订单金额,分
-//        amountNode.put("currency", "CNY");
-//        rootNode.set("amount", amountNode);
-//
-//        String requestBody = rootNode.toString();
-//        log.info("微信申请退款请求体: {}", requestBody);
-//        httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
-//
-//        try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
-//            int statusCode = response.getStatusLine().getStatusCode();
-//            String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
-//            log.info("微信申请退款响应状态码: {}, 响应体: {}", statusCode, responseBody);
-//
-//            if (statusCode == 200) { // 成功受理
-//                log.info("微信退款申请成功受理。");
-//                return objectMapper.readTree(responseBody);
-//            } else {
-//                log.error("微信申请退款失败,状态码: {}, 响应: {}", statusCode, responseBody);
-//                throw new RuntimeException("微信申请退款失败: " + responseBody);
-//            }
-//        } catch (Exception e) {
-//            log.error("微信申请退款请求执行异常", e);
-//            throw new IOException("微信申请退款请求执行异常", e);
-//        }
-//    }
-//
-//}
\ No newline at end of file
+package com.dsh.activity.util.wx;
+
+import com.dsh.activity.util.wx.WXPayConstants;
+import com.dsh.activity.util.wx.WXPaySignatureCertificateUtil;
+import com.dsh.activity.util.wx.WxV3PayConfig;
+import com.fasterxml.jackson.databind.JsonNode; // 引入Jackson库处理JSON
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+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.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class WxAppPayService {
+
+    private static final Logger log = LoggerFactory.getLogger(WxAppPayService.class);
+
+    private final ObjectMapper objectMapper; // 用于JSON序列化和反序列化
+    private final CloseableHttpClient wechatPayClient; // 注入通过工具类创建的HTTP客户端
+
+    @Autowired
+    public WxAppPayService(ObjectMapper objectMapper) throws IOException {
+        this.objectMapper = objectMapper;
+        // 在构造函数中初始化带有签名验证功能的HTTP客户端
+        this.wechatPayClient = WXPaySignatureCertificateUtil.getWechatPayClient();
+        log.info("微信支付V3 HTTP客户端初始化完成。");
+    }
+
+    /**
+     * 创建APP支付预付单 (统一下单)
+     *
+     * @param description 商品描述
+     * @param outTradeNo  商户订单号 (要求32个字符内,只能是数字、大小写字母_-|* 且在同一个商户号下唯一)
+     * @param totalAmount 支付总金额 (单位:元)
+     * @return 用于调起APP支付的参数 Map (appid, partnerid, prepayid, package, noncestr, timestamp, sign)
+     * @throws IOException          网络或IO异常
+     * @throws RuntimeException     支付请求失败或处理异常
+     */
+    public Map<String, String> createOrder(String description, String outTradeNo, BigDecimal totalAmount)
+            throws IOException {
+
+        // 1. 构建请求URL
+        String url = WXPayConstants.DOMAIN_API + WXPayConstants.PAY_TRANSACTIONS_APP;
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.addHeader("Accept", "application/json");
+        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+
+        // 2. 构建请求体 JSON
+        ObjectNode rootNode = objectMapper.createObjectNode();
+//        rootNode.put("appid", WxV3PayConfig.APP_ID);//服务商不需要该字段
+//        rootNode.put("mchid", WxV3PayConfig.Mch_ID);//服务商不需要该字段
+        rootNode.put("description", description);
+        rootNode.put("out_trade_no", outTradeNo);
+        rootNode.put("notify_url", WXPayConstants.WECHAT_PAY_NOTIFY_URL); // 使用常量中的回调地址
+
+        ObjectNode amountNode = objectMapper.createObjectNode();
+        // 微信支付金额单位为分,需要转换
+        amountNode.put("total", totalAmount.multiply(new BigDecimal("100")).intValue());
+        amountNode.put("currency", "CNY"); // 货币类型,默认人民币
+        rootNode.set("amount", amountNode);
+
+        // 如果你是服务商模式,需要添加子商户信息
+        rootNode.put("sp_mchid", WxV3PayConfig.Mch_ID);
+        rootNode.put("sub_mchid", "123");
+         rootNode.put("sp_appid", "wx41d32f362ba0f911");
+        // rootNode.put("sub_appid", "子商户AppID"); // 如果子商户需要用自己的AppID拉起支付
+
+        String requestBody = rootNode.toString();
+        log.info("微信APP支付下单请求体: {}", requestBody);
+        httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
+
+        // 3. 发送请求
+        try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
+            int statusCode = response.getStatusLine().getStatusCode();
+            String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+            log.info("微信APP支付下单响应状态码: {}, 响应体: {}", statusCode, responseBody);
+
+            if (statusCode == 200) { // HTTP状态码 200 表示成功
+                JsonNode responseNode = objectMapper.readTree(responseBody);
+                String prepayId = responseNode.get("prepay_id").asText();
+                log.info("成功获取预支付交易会话标识 (prepay_id): {}", prepayId);
+
+                // 4. 生成调起支付所需的参数
+                Map<String, String> payParams = WXPaySignatureCertificateUtil.buildAppPayParams(prepayId);
+                log.info("生成APP支付参数: {}", payParams);
+                return payParams;
+
+            } else {
+                // 处理错误情况
+                log.error("微信APP支付下单失败,状态码: {}, 响应: {}", statusCode, responseBody);
+                // 可以根据 responseBody 中的 code 和 message 进一步分析错误
+                throw new RuntimeException("微信APP支付下单失败: " + responseBody);
+            }
+        } catch (Exception e) {
+            log.error("微信APP支付下单请求执行异常", e);
+            throw new IOException("微信APP支付下单请求执行异常", e);
+        }
+    }
+
+     /**
+     * 关闭订单 (根据商户订单号)
+     *
+     * @param outTradeNo 商户订单号
+     * @return true 如果关闭成功或订单已关闭/不存在 (根据微信文档,成功是204 No Content)
+     * @throws IOException          网络或IO异常
+     * @throws RuntimeException     关闭请求失败或处理异常
+     */
+    public boolean closeOrder(String outTradeNo) throws IOException {
+        // 1. 构建请求URL, 注意替换占位符
+        String url = WXPayConstants.DOMAIN_API
+                   + WXPayConstants.PAY_TRANSACTIONS_OUT_TRADE_NO.replace("{}", outTradeNo);
+
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.addHeader("Accept", "application/json");
+        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+
+        // 2. 构建请求体 JSON (只需要商户号)
+        ObjectNode rootNode = objectMapper.createObjectNode();
+        rootNode.put("mchid", WxV3PayConfig.Mch_ID);
+        // 如果是服务商模式,则用 sp_mchid
+         rootNode.put("sp_mchid", WxV3PayConfig.Mch_ID);
+
+        String requestBody = rootNode.toString();
+        log.info("微信关单请求 URL: {}, 请求体: {}", url, requestBody);
+        httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
+
+        // 3. 发送请求
+        try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
+            int statusCode = response.getStatusLine().getStatusCode();
+            // 关单成功时,微信返回 HTTP 状态码 204 No Content
+            log.info("微信关单响应状态码: {}", statusCode);
+            if (statusCode == 204) {
+                log.info("订单 {} 关闭成功。", outTradeNo);
+                return true;
+            } else {
+                String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+                log.error("微信关单失败,商户订单号: {}, 状态码: {}, 响应: {}", outTradeNo, statusCode, responseBody);
+                // 根据需要可以解析responseBody获取错误详情
+                return false; // 或者抛出异常,根据业务决定
+            }
+        } catch (Exception e) {
+            log.error("微信关单请求执行异常, 商户订单号: {}", outTradeNo, e);
+            throw new IOException("微信关单请求执行异常", e);
+        }
+    }
+
+
+    // --- 退款相关方法 (可选) ---
+
+    /**
+     * 申请退款
+     *
+     * @param outTradeNo   原商户订单号
+     * @param outRefundNo  商户退款单号 (商户系统内部的退款单号,要求唯一)
+     * @param reason       退款原因 (可选)
+     * @param refundAmount 退款金额 (单位:元)
+     * @param totalAmount  原订单总金额 (单位:元)
+     * @return 退款处理结果,可以返回微信返回的JSON节点或自定义对象
+     * @throws IOException          网络或IO异常
+     * @throws RuntimeException     退款请求失败或处理异常
+     */
+    public JsonNode createRefund(String outTradeNo, String outRefundNo, String reason,
+                                BigDecimal refundAmount, BigDecimal totalAmount) throws IOException {
+
+        String url = WXPayConstants.DOMAIN_API + WXPayConstants.REFUND_DOMESTIC_REFUNDS;
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.addHeader("Accept", "application/json");
+        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+
+        ObjectNode rootNode = objectMapper.createObjectNode();
+        // 如果是服务商模式,需要添加子商户号
+        // rootNode.put("sub_mchid", "子商户号");
+        rootNode.put("out_trade_no", outTradeNo);
+        rootNode.put("out_refund_no", outRefundNo);
+        if (reason != null && !reason.isEmpty()) {
+            rootNode.put("reason", reason);
+        }
+        // 设置退款回调地址
+        rootNode.put("notify_url", WXPayConstants.WECHAT_REFUNDS_NOTIFY_URL);
+
+        ObjectNode amountNode = objectMapper.createObjectNode();
+        amountNode.put("refund", refundAmount.multiply(new BigDecimal("100")).intValue()); // 退款金额,分
+        amountNode.put("total", totalAmount.multiply(new BigDecimal("100")).intValue());   // 原订单金额,分
+        amountNode.put("currency", "CNY");
+        rootNode.set("amount", amountNode);
+
+        String requestBody = rootNode.toString();
+        log.info("微信申请退款请求体: {}", requestBody);
+        httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
+
+        try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
+            int statusCode = response.getStatusLine().getStatusCode();
+            String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+            log.info("微信申请退款响应状态码: {}, 响应体: {}", statusCode, responseBody);
+
+            if (statusCode == 200) { // 成功受理
+                log.info("微信退款申请成功受理。");
+                return objectMapper.readTree(responseBody);
+            } else {
+                log.error("微信申请退款失败,状态码: {}, 响应: {}", statusCode, responseBody);
+                throw new RuntimeException("微信申请退款失败: " + responseBody);
+            }
+        } catch (Exception e) {
+            log.error("微信申请退款请求执行异常", e);
+            throw new IOException("微信申请退款请求执行异常", e);
+        }
+    }
+
+}
\ No newline at end of file

--
Gitblit v1.7.1