Ver código fonte

微信支付退款回调

wanxl 2 anos atrás
pai
commit
0d8adc2ff1

+ 33 - 13
src/main/java/com/template/controller/HouseOrderController.java

@@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.template.annotation.PassToken;
 import com.template.api.HouseOrderAPI;
 import com.template.common.utils.*;
@@ -43,15 +45,21 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.client.RestTemplate;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedWriter;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
 import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
 import java.security.Signature;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
@@ -1643,10 +1651,10 @@ public class HouseOrderController implements HouseOrderAPI {
 
         HttpMethod httpMethod = HttpMethod.POST;
         String urlSuffix = "/v3/pay/transactions/jsapi";
-//        String urlSuffix = "/v3/pay/transactions/h5";
-        String certPath = wxPayV3Config.getCertPath();
-        String platformCertPath = wxPayV3Config.getPlatformCertPath();
-        String seriaNumber = SecurityUtil.getSerialNumber(certPath);
+////        String urlSuffix = "/v3/pay/transactions/h5";
+//        String certPath = wxPayV3Config.getCertPath();
+//        String platformCertPath = wxPayV3Config.getPlatformCertPath();
+//        String seriaNumber = SecurityUtil.getSerialNumber(certPath);
         // 签名,获取authStr
 //        String authStr = WechatPayV3Util.buildAuthorization(httpMethod,
 //                urlSuffix,
@@ -1987,6 +1995,7 @@ public class HouseOrderController implements HouseOrderAPI {
         System.out.println("接收到支付结果通知:" + data.toJSONString());
         //解密resource中的通知数据
         String resource = data.get("resource").toString();
+
         resourceMap = WechatPayApiV3Util.decryptFromResource(resource, "e10adc3949ba59abbe56e057f20f883e", 1);
         System.out.println("解析resource结果:" + resourceMap);
         return resourceMap;
@@ -2262,24 +2271,31 @@ public class HouseOrderController implements HouseOrderAPI {
     public void returnRefund(HttpServletRequest request, HttpServletResponse response) throws Exception {
         String inputLine = "";
         String notityXml = "";
+        String timestamp = request.getHeader("Wechatpay-Timestamp");
+        String nonce = request.getHeader("Wechatpay-Nonce");
+        String serialNo = request.getHeader("Wechatpay-Serial");
+        String signature = request.getHeader("Wechatpay-Signature");
         try {
             while ((inputLine = request.getReader().readLine()) != null) {
                 notityXml += inputLine;
             }
             //关闭流
             request.getReader().close();
-            System.out.println("微信回调内容信息:" + notityXml);
             //解析成json
             JSONObject data = JSONObject.parseObject(notityXml);
             //判断 支付是否成功
+            log.info("退款回调入参"+timestamp+"==="+nonce+"===="+serialNo+"======"+signature+"======="+notityXml);
             if ("REFUND.SUCCESS".equals(data.get("event_type"))) {
 
+                String plainText = WechatPayV3Util.verifyNotify(serialNo, notityXml, signature, nonce, timestamp,
+                        wxPayV3Config.getApiKey3(), wxPayV3Config.getPlatformCertPath());
+                log.info("退款回调明文"+plainText);
                 // 在这里处理接收到的支付结果通知数据
-                Map<String, Object> resourceMap = handlePaymentNotification(data);
-
+                JSONObject resourceMap = JSONObject.parseObject(plainText);
                 // 获取 trade_state 值
-                String tradeState = resourceMap.get("trade_state").toString();
+                String tradeState = resourceMap.get("refund_status").toString();
                 if (tradeState.equals("SUCCESS")) {
+
                     // 获取 amount 字段
                     Map<String, Object> amountMap = (Map<String, Object>) resourceMap.get("amount");
                     //获得 返回的商户订单号
@@ -2297,7 +2313,7 @@ public class HouseOrderController implements HouseOrderAPI {
                     String total_fee = amountMap.get("payer_refund").toString();
                     //业务逻辑------------
                     LambdaQueryWrapper<HouseOrder> wrapperHo = new LambdaQueryWrapper<>();
-                    wrapperHo.eq(HouseOrder::getHouseOrderNumber, outTradeNo);
+                    wrapperHo.eq(HouseOrder::getOrderNumber, outTradeNo);
                     HouseOrder rr = houseOrderService.getOne(wrapperHo);
                     if (ObjectUtils.isNotEmpty(rr)) {
                         LambdaQueryWrapper<RefundRecord> wrapperRr = new LambdaQueryWrapper<>();
@@ -2373,10 +2389,15 @@ public class HouseOrderController implements HouseOrderAPI {
             }
         } catch (Exception e) {
             e.printStackTrace();
-            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+//            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+//            JSONObject jsonObject = new JSONObject();
+//            jsonObject.put("code", "FAIL");
+//            jsonObject.put("message", "失败");
+//            response.getWriter().write(jsonObject.toJSONString());
+            response.setStatus(HttpServletResponse.SC_OK);
             JSONObject jsonObject = new JSONObject();
-            jsonObject.put("code", "FAIL");
-            jsonObject.put("message", "失败");
+            jsonObject.put("code", "SUCCESS");
+            jsonObject.put("message", "SUCCESS");
             response.getWriter().write(jsonObject.toJSONString());
         }
 
@@ -2450,6 +2471,5 @@ public class HouseOrderController implements HouseOrderAPI {
 
     }
 
-
 }
 

+ 2 - 2
src/main/java/com/template/model/weixin/WechatPayV3Util.java

@@ -236,7 +236,7 @@ public class WechatPayV3Util {
     }
 
     /**
-     * v3 支付异步通知验证签名
+     * v3 退款异步通知验证签名
      * @param serialNo 证书序列号
      * @param body 异步通知密文
      * @param signature 签名
@@ -268,7 +268,7 @@ public class WechatPayV3Util {
                 ObjectMapper mapper = new ObjectMapper();
                 JsonNode bodyNode = mapper.readTree(body);
                 String eventType = bodyNode.get("event_type").asText();
-                if ("TRANSACTION.SUCCESS".equals(eventType)) {
+                if ("REFUND.SUCCESS".equals(eventType)) {
                     JsonNode resourceNode = bodyNode.get("resource");
                     String cipherText = resourceNode.get("ciphertext").asText();
                     String nonceStr = resourceNode.get("nonce").asText();

+ 1 - 1
src/main/resources/application-dev.yml

@@ -97,7 +97,7 @@ wechat:
       keyPath: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\apiclient_key.pem
       certPath: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\apiclient_cert.pem
       certP12Path: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\apiclient_cert.p12
-      platformCertPath: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\apiclient_cert.p12
+      platformCertPath: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\wx_cert.pem
       mchId: 1609853253
       apiKey3: nanchangjiaotongxueyuan202188888
       apiKey: chuanghaikeji2021chuanghaikeji20

+ 1 - 1
src/main/resources/application.yml

@@ -99,7 +99,7 @@ wechat:
       keyPath: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\apiclient_key.pem
       certPath: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\apiclient_cert.pem
       certP12Path: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\apiclient_cert.p12
-      platformCertPath: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\apiclient_cert.p12
+      platformCertPath: F:\项目资料\创海项目资料\iHotel_student_houtai\src\main\resources\cert\wx_cert.pem
       mchId: 1609853253
       apiKey3: nanchangjiaotongxueyuan202188888
       apiKey: chuanghaikeji2021chuanghaikeji20