| | |
| | | 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.Service; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | } |
| | | //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); |
| | | // } |
| | | // } |
| | | // |
| | | //} |