From 4742874ad840d7e1e3ac79dc288b38e9a642319d Mon Sep 17 00:00:00 2001 From: 无关风月 <443237572@qq.com> Date: 星期一, 02 六月 2025 19:11:00 +0800 Subject: [PATCH] bug修改 --- cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java | 354 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 177 insertions(+), 177 deletions(-) diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java index 4f63fcc..ce1e4be 100644 --- a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java +++ b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java @@ -1,177 +1,177 @@ -package com.dsh.activity.util.wx; - -import com.dsh.activity.util.wx.WXPaySignatureCertificateUtil; -import com.dsh.activity.util.wx.WxPayAesUtil; -import com.dsh.activity.util.wx.WxV3PayConfig; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; - -@RestController -@RequestMapping("/api/appPayment") // 路径前缀,与常量中配置的回调URL匹配 -public class WxPayNotifyController { - - private static final Logger log = LoggerFactory.getLogger(WxPayNotifyController.class); - - private final ObjectMapper objectMapper; - - @Autowired - public WxPayNotifyController(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - } - - /** - * 接收微信支付结果通知 - * URL需要与 WXPayConstants.WECHAT_PAY_NOTIFY_URL 匹配 - */ - @PostMapping("/weChatPayNotify") - public ResponseEntity<Map<String, String>> handleWeChatPayNotify(HttpServletRequest request, @RequestBody String requestBody) { - - Map<String, String> responseMap = new HashMap<>(); - try { - // 1. 验证签名 (使用工具类,它会处理证书) - boolean verifyResult = WXPaySignatureCertificateUtil.verifyNotify(request, requestBody); - if (!verifyResult) { - log.error("微信支付通知验签失败!"); - responseMap.put("code", "FAIL"); - responseMap.put("message", "验签失败"); - return new ResponseEntity<>(responseMap, HttpStatus.BAD_REQUEST); // 返回错误状态码 - } - log.info("微信支付通知验签成功。"); - - // 2. 解析通知体 - JsonNode notifyData = objectMapper.readTree(requestBody); - String eventType = notifyData.get("event_type").asText(); - - // 只处理支付成功的通知类型 - if ("TRANSACTION.SUCCESS".equals(eventType)) { - log.info("处理支付成功通知..."); - JsonNode resourceNode = notifyData.get("resource"); - String associatedData = resourceNode.get("associated_data").asText(); - String nonce = resourceNode.get("nonce").asText(); - String ciphertext = resourceNode.get("ciphertext").asText(); - - // 3. 解密关键信息 - String decryptedDataJson = WxPayAesUtil.decrypt(WxV3PayConfig.apiV3Key, associatedData, nonce, ciphertext); - log.info("解密后的支付通知信息: {}", decryptedDataJson); - JsonNode decryptedData = objectMapper.readTree(decryptedDataJson); - - // 4. 处理业务逻辑 - String outTradeNo = decryptedData.get("out_trade_no").asText(); - String transactionId = decryptedData.get("transaction_id").asText(); - String tradeState = decryptedData.get("trade_state").asText(); - // ... 获取其他需要的信息,例如支付金额、用户openid等 - - // TODO: 在这里实现你的业务逻辑: - // 1. 根据 outTradeNo 查询你的数据库订单状态。 - // 2. 判断订单是否已经处理过(防止重复处理通知)。 - // 3. 如果订单未处理且 tradeState 为 SUCCESS,则更新订单状态为支付成功。 - // 4. 记录 transactionId (微信支付订单号)。 - // 5. 执行后续业务流程(如发货、增加积分等)。 - // 6. 如果处理失败,可以考虑记录日志并后续重试,但仍需返回成功给微信,避免微信重复通知。 - - log.info("业务逻辑处理完成,商户订单号: {}, 微信订单号: {}", outTradeNo, transactionId); - - } else { - log.warn("收到非支付成功类型的通知: {}", eventType); - // 其他类型的通知,根据需要处理或忽略 - } - - // 5. 返回成功响应给微信平台 - responseMap.put("code", "SUCCESS"); - responseMap.put("message", "成功"); - return new ResponseEntity<>(responseMap, HttpStatus.OK); - - } catch (Exception e) { - log.error("处理微信支付通知异常", e); - responseMap.put("code", "FAIL"); - responseMap.put("message", "处理失败"); - // 即使处理失败,也尽量返回成功给微信,避免重复通知轰炸,然后在后台处理异常。 - // 但如果验签失败,可以返回错误状态码。 - return new ResponseEntity<>(responseMap, HttpStatus.INTERNAL_SERVER_ERROR); // 或者返回OK,根据策略定 - } - } - - - /** - * 接收微信退款结果通知 - * URL需要与 WXPayConstants.WECHAT_REFUNDS_NOTIFY_URL 匹配 - */ - @PostMapping("/weChatPayRefundsNotify") - public ResponseEntity<Map<String, String>> handleWeChatRefundsNotify(HttpServletRequest request, @RequestBody String requestBody) { - - Map<String, String> responseMap = new HashMap<>(); - try { - // 1. 验证签名 - boolean verifyResult = WXPaySignatureCertificateUtil.verifyNotify(request, requestBody); - if (!verifyResult) { - log.error("微信退款通知验签失败!"); - responseMap.put("code", "FAIL"); - responseMap.put("message", "验签失败"); - return new ResponseEntity<>(responseMap, HttpStatus.BAD_REQUEST); - } - log.info("微信退款通知验签成功。"); - - // 2. 解析通知体 - JsonNode notifyData = objectMapper.readTree(requestBody); - String eventType = notifyData.get("event_type").asText(); - - // 处理退款成功或异常的通知 - if ("REFUND.SUCCESS".equals(eventType) || "REFUND.ABNORMAL".equals(eventType) || "REFUND.CLOSED".equals(eventType)) { - log.info("处理退款通知,类型: {}", eventType); - JsonNode resourceNode = notifyData.get("resource"); - String associatedData = resourceNode.get("associated_data").asText(); - String nonce = resourceNode.get("nonce").asText(); - String ciphertext = resourceNode.get("ciphertext").asText(); - - // 3. 解密关键信息 - String decryptedDataJson = WxPayAesUtil.decrypt(WxV3PayConfig.apiV3Key, associatedData, nonce, ciphertext); - log.info("解密后的退款通知信息: {}", decryptedDataJson); - JsonNode decryptedData = objectMapper.readTree(decryptedDataJson); - - // 4. 处理业务逻辑 - String outTradeNo = decryptedData.get("out_trade_no").asText(); - String outRefundNo = decryptedData.get("out_refund_no").asText(); - String refundStatus = decryptedData.get("refund_status").asText(); // SUCCESS, CLOSED, ABNORMAL - // ... 获取其他需要的信息,例如退款金额、微信退款单号 refund_id 等 - - // TODO: 在这里实现你的退款业务逻辑: - // 1. 根据 outRefundNo 查询你的数据库退款单状态。 - // 2. 判断退款单是否已经处理过。 - // 3. 根据 refundStatus 更新退款单状态。 - // 4. 如果退款成功 (SUCCESS),可能需要执行一些操作,如返还库存、通知用户等。 - // 5. 如果退款关闭或异常,也需要记录状态。 - - log.info("退款业务逻辑处理完成,商户订单号: {}, 商户退款单号: {}, 退款状态: {}", outTradeNo, outRefundNo, refundStatus); - - } else { - log.warn("收到非退款类型的通知: {}", eventType); - } - - // 5. 返回成功响应给微信平台 - responseMap.put("code", "SUCCESS"); - responseMap.put("message", "成功"); - return new ResponseEntity<>(responseMap, HttpStatus.OK); - - } catch (Exception e) { - log.error("处理微信退款通知异常", e); - responseMap.put("code", "FAIL"); - responseMap.put("message", "处理失败"); - return new ResponseEntity<>(responseMap, HttpStatus.INTERNAL_SERVER_ERROR); - } - } - -} +//package com.dsh.activity.util.wx; +// +//import com.dsh.activity.util.wx.WXPaySignatureCertificateUtil; +//import com.dsh.activity.util.wx.WxPayAesUtil; +//import com.dsh.activity.util.wx.WxV3PayConfig; +//import com.fasterxml.jackson.databind.JsonNode; +//import com.fasterxml.jackson.databind.ObjectMapper; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ResponseEntity; +//import org.springframework.web.bind.annotation.PostMapping; +//import org.springframework.web.bind.annotation.RequestBody; +//import org.springframework.web.bind.annotation.RequestMapping; +//import org.springframework.web.bind.annotation.RestController; +// +//import javax.servlet.http.HttpServletRequest; +//import java.nio.charset.StandardCharsets; +//import java.util.HashMap; +//import java.util.Map; +// +//@RestController +//@RequestMapping("/api/appPayment") // 路径前缀,与常量中配置的回调URL匹配 +//public class WxPayNotifyController { +// +// private static final Logger log = LoggerFactory.getLogger(WxPayNotifyController.class); +// +// private final ObjectMapper objectMapper; +// +// @Autowired +// public WxPayNotifyController(ObjectMapper objectMapper) { +// this.objectMapper = objectMapper; +// } +// +// /** +// * 接收微信支付结果通知 +// * URL需要与 WXPayConstants.WECHAT_PAY_NOTIFY_URL 匹配 +// */ +// @PostMapping("/weChatPayNotify") +// public ResponseEntity<Map<String, String>> handleWeChatPayNotify(HttpServletRequest request, @RequestBody String requestBody) { +// +// Map<String, String> responseMap = new HashMap<>(); +// try { +// // 1. 验证签名 (使用工具类,它会处理证书) +// boolean verifyResult = WXPaySignatureCertificateUtil.verifyNotify(request, requestBody); +// if (!verifyResult) { +// log.error("微信支付通知验签失败!"); +// responseMap.put("code", "FAIL"); +// responseMap.put("message", "验签失败"); +// return new ResponseEntity<>(responseMap, HttpStatus.BAD_REQUEST); // 返回错误状态码 +// } +// log.info("微信支付通知验签成功。"); +// +// // 2. 解析通知体 +// JsonNode notifyData = objectMapper.readTree(requestBody); +// String eventType = notifyData.get("event_type").asText(); +// +// // 只处理支付成功的通知类型 +// if ("TRANSACTION.SUCCESS".equals(eventType)) { +// log.info("处理支付成功通知..."); +// JsonNode resourceNode = notifyData.get("resource"); +// String associatedData = resourceNode.get("associated_data").asText(); +// String nonce = resourceNode.get("nonce").asText(); +// String ciphertext = resourceNode.get("ciphertext").asText(); +// +// // 3. 解密关键信息 +// String decryptedDataJson = WxPayAesUtil.decrypt(WxV3PayConfig.apiV3Key, associatedData, nonce, ciphertext); +// log.info("解密后的支付通知信息: {}", decryptedDataJson); +// JsonNode decryptedData = objectMapper.readTree(decryptedDataJson); +// +// // 4. 处理业务逻辑 +// String outTradeNo = decryptedData.get("out_trade_no").asText(); +// String transactionId = decryptedData.get("transaction_id").asText(); +// String tradeState = decryptedData.get("trade_state").asText(); +// // ... 获取其他需要的信息,例如支付金额、用户openid等 +// +// // TODO: 在这里实现你的业务逻辑: +// // 1. 根据 outTradeNo 查询你的数据库订单状态。 +// // 2. 判断订单是否已经处理过(防止重复处理通知)。 +// // 3. 如果订单未处理且 tradeState 为 SUCCESS,则更新订单状态为支付成功。 +// // 4. 记录 transactionId (微信支付订单号)。 +// // 5. 执行后续业务流程(如发货、增加积分等)。 +// // 6. 如果处理失败,可以考虑记录日志并后续重试,但仍需返回成功给微信,避免微信重复通知。 +// +// log.info("业务逻辑处理完成,商户订单号: {}, 微信订单号: {}", outTradeNo, transactionId); +// +// } else { +// log.warn("收到非支付成功类型的通知: {}", eventType); +// // 其他类型的通知,根据需要处理或忽略 +// } +// +// // 5. 返回成功响应给微信平台 +// responseMap.put("code", "SUCCESS"); +// responseMap.put("message", "成功"); +// return new ResponseEntity<>(responseMap, HttpStatus.OK); +// +// } catch (Exception e) { +// log.error("处理微信支付通知异常", e); +// responseMap.put("code", "FAIL"); +// responseMap.put("message", "处理失败"); +// // 即使处理失败,也尽量返回成功给微信,避免重复通知轰炸,然后在后台处理异常。 +// // 但如果验签失败,可以返回错误状态码。 +// return new ResponseEntity<>(responseMap, HttpStatus.INTERNAL_SERVER_ERROR); // 或者返回OK,根据策略定 +// } +// } +// +// +// /** +// * 接收微信退款结果通知 +// * URL需要与 WXPayConstants.WECHAT_REFUNDS_NOTIFY_URL 匹配 +// */ +// @PostMapping("/weChatPayRefundsNotify") +// public ResponseEntity<Map<String, String>> handleWeChatRefundsNotify(HttpServletRequest request, @RequestBody String requestBody) { +// +// Map<String, String> responseMap = new HashMap<>(); +// try { +// // 1. 验证签名 +// boolean verifyResult = WXPaySignatureCertificateUtil.verifyNotify(request, requestBody); +// if (!verifyResult) { +// log.error("微信退款通知验签失败!"); +// responseMap.put("code", "FAIL"); +// responseMap.put("message", "验签失败"); +// return new ResponseEntity<>(responseMap, HttpStatus.BAD_REQUEST); +// } +// log.info("微信退款通知验签成功。"); +// +// // 2. 解析通知体 +// JsonNode notifyData = objectMapper.readTree(requestBody); +// String eventType = notifyData.get("event_type").asText(); +// +// // 处理退款成功或异常的通知 +// if ("REFUND.SUCCESS".equals(eventType) || "REFUND.ABNORMAL".equals(eventType) || "REFUND.CLOSED".equals(eventType)) { +// log.info("处理退款通知,类型: {}", eventType); +// JsonNode resourceNode = notifyData.get("resource"); +// String associatedData = resourceNode.get("associated_data").asText(); +// String nonce = resourceNode.get("nonce").asText(); +// String ciphertext = resourceNode.get("ciphertext").asText(); +// +// // 3. 解密关键信息 +// String decryptedDataJson = WxPayAesUtil.decrypt(WxV3PayConfig.apiV3Key, associatedData, nonce, ciphertext); +// log.info("解密后的退款通知信息: {}", decryptedDataJson); +// JsonNode decryptedData = objectMapper.readTree(decryptedDataJson); +// +// // 4. 处理业务逻辑 +// String outTradeNo = decryptedData.get("out_trade_no").asText(); +// String outRefundNo = decryptedData.get("out_refund_no").asText(); +// String refundStatus = decryptedData.get("refund_status").asText(); // SUCCESS, CLOSED, ABNORMAL +// // ... 获取其他需要的信息,例如退款金额、微信退款单号 refund_id 等 +// +// // TODO: 在这里实现你的退款业务逻辑: +// // 1. 根据 outRefundNo 查询你的数据库退款单状态。 +// // 2. 判断退款单是否已经处理过。 +// // 3. 根据 refundStatus 更新退款单状态。 +// // 4. 如果退款成功 (SUCCESS),可能需要执行一些操作,如返还库存、通知用户等。 +// // 5. 如果退款关闭或异常,也需要记录状态。 +// +// log.info("退款业务逻辑处理完成,商户订单号: {}, 商户退款单号: {}, 退款状态: {}", outTradeNo, outRefundNo, refundStatus); +// +// } else { +// log.warn("收到非退款类型的通知: {}", eventType); +// } +// +// // 5. 返回成功响应给微信平台 +// responseMap.put("code", "SUCCESS"); +// responseMap.put("message", "成功"); +// return new ResponseEntity<>(responseMap, HttpStatus.OK); +// +// } catch (Exception e) { +// log.error("处理微信退款通知异常", e); +// responseMap.put("code", "FAIL"); +// responseMap.put("message", "处理失败"); +// return new ResponseEntity<>(responseMap, HttpStatus.INTERNAL_SERVER_ERROR); +// } +// } +// +//} -- Gitblit v1.7.1