wangming 4 semanas atrás
pai
commit
9d4eaecf03

+ 17 - 27
yami-shop-api/src/main/java/com/yami/shop/api/controller/PayController.java

@@ -13,21 +13,19 @@ import com.yami.shop.security.api.util.SecurityUtils;
 import com.yami.shop.service.*;
 import com.yami.shop.wx.po.JsapiPayInfoPo;
 import com.yami.shop.wx.service.WxProviderService;
+import com.yami.shop.wx.utils.CullenUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import lombok.SneakyThrows;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
-import java.util.Map;
 
 @RestController
-@RequestMapping("/order")
-//@RequestMapping("/p/order")
+@RequestMapping("/p/order")
 @Api(tags = "订单接口")
 @AllArgsConstructor
 public class PayController {
@@ -37,7 +35,6 @@ public class PayController {
     private final OrderService orderService;
     private final OrderRefundService orderRefundService;
     private final RefundDeliveryService refundDeliveryService;
-    @Autowired
     private final WxProviderService wxProviderService;
 
 
@@ -59,16 +56,13 @@ public class PayController {
             return ResponseEntity.ok().build();
         }
 
-        if (payInfo.getPayAmount() < 0.01) {
-            throw new GlobalException("订单金额有误,无法进行支付");
-        }
-
+        CullenUtils.validateDataThrowException(payInfo.getPayAmount() < 0.01, "订单金额有误,无法进行支付");
         JsapiPayInfoPo po = new JsapiPayInfoPo();
         po.setDescription(payInfo.getBody());
         po.setTotal((int) Arith.mul(payInfo.getPayAmount(), 100));
         po.setOpenId(user.getBizUserId());
         po.setOutTradeNo(payInfo.getPayNo());
-        po.setNotifyUrl("http://localhost:8112/notice/pay/order/" + payParam.getPayType());
+        po.setNotifyUrl(getNotifyUrl("http://localhost:8112"));
         return ResponseEntity.ok(wxProviderService.subJsapi(po));
     }
 
@@ -84,26 +78,18 @@ public class PayController {
 
         RefundDelivery refundDelivery = refundDeliveryService.getOne(new LambdaQueryWrapper<RefundDelivery>()
                 .eq(RefundDelivery::getRefundSn, payParam.getOrderNumbers()));
-        if (refundDelivery.getPayer().equals("1")) {
-            throw new GlobalException("无需支付");
-        }
-
-        PayInfoDto payInfoDto = new PayInfoDto();
-        payInfoDto.setBody("退货配送费");
-        payInfoDto.setPayAmount(refundDelivery.getPrice());
-        payInfoDto.setPayNo("refundSn" + payParam.getOrderNumbers());
-        payInfoDto.setIsScore(0);
-
-        payInfoDto.setBizUserId(user.getBizUserId());
-        payInfoDto.setPayType(payParam.getPayType());
-        payInfoDto.setApiNoticeUrl("/notice/pay/order/" + payParam.getPayType());
-        payInfoDto.setReturnUrl(payParam.getReturnUrl());
-
 
-        return payManagerService.doPay(httpResponse, payInfoDto);
+        CullenUtils.validateDataThrowException(refundDelivery.getPayer().equals("1"), "无需支付");
+        CullenUtils.validateDataThrowException(refundDelivery.getPrice() < 0.01, "订单金额有误,无法进行支付");
+        JsapiPayInfoPo po = new JsapiPayInfoPo();
+        po.setDescription("退货配送费");
+        po.setTotal((int) Arith.mul(refundDelivery.getPrice(), 100));
+        po.setOpenId(user.getBizUserId());
+        po.setOutTradeNo("refundSn" + payParam.getOrderNumbers());
+        po.setNotifyUrl(getNotifyUrl("http://localhost:8112"));
+        return ResponseEntity.ok(wxProviderService.subJsapi(po));
     }
 
-
     @GetMapping("/isPay/{orderNumbers}")
     @ApiOperation(value = "根据订单号查询该订单是否已经支付", notes = "根据订单号查询该订单是否已经支付")
     public ResponseEntity<Boolean> isPay(@PathVariable String orderNumbers) {
@@ -115,4 +101,8 @@ public class PayController {
         int count = orderService.count(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, orderNumber).eq(Order::getUserId, userId).eq(Order::getIsPayed, 1));
         return ResponseEntity.ok(count > 0);
     }
+
+    private static String getNotifyUrl(String uri) {
+        return uri.concat("/notice/pay/order/wxNotify");
+    }
 }

+ 36 - 11
yami-shop-api/src/main/java/com/yami/shop/api/controller/PayNoticeController.java

@@ -10,16 +10,16 @@
 
 package com.yami.shop.api.controller;
 
-import com.alipay.api.AlipayApiException;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.github.binarywang.wxpay.exception.WxPayException;
 import com.yami.shop.bean.bo.PayInfoBo;
 import com.yami.shop.bean.model.Order;
 import com.yami.shop.bean.model.OrderItem;
 import com.yami.shop.bean.model.RefundDelivery;
 import com.yami.shop.common.enums.PayType;
 import com.yami.shop.service.*;
+import com.yami.shop.wx.service.WxProviderService;
 import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -28,7 +28,7 @@ import org.springframework.web.bind.annotation.RestController;
 import springfox.documentation.annotations.ApiIgnore;
 
 import javax.servlet.http.HttpServletRequest;
-import java.io.UnsupportedEncodingException;
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 @ApiIgnore
@@ -47,14 +47,12 @@ public class PayNoticeController {
 
     private final RefundDeliveryService refundDeliveryService;
 
-    /**
-     * 支付异步回调
-     */
-    @RequestMapping("/order/{payType}")
-    public ResponseEntity<String> submit(HttpServletRequest request, @PathVariable Integer payType, @RequestBody(required = false) String xmlData) throws WxPayException, UnsupportedEncodingException, AlipayApiException {
+    private final WxProviderService wxProviderService;
 
-
-        PayInfoBo payInfoBo = payManagerService.validateAndGetPayInfo(request, PayType.instance(payType), xmlData);
+    @SneakyThrows
+    @RequestMapping("/order/wxNotify")
+    public ResponseEntity<String> wxNotify(HttpServletRequest request, HttpServletResponse response) {
+        PayInfoBo payInfoBo = wxProviderService.notifyParse(request,response);
 
         if (payInfoBo.getPayNo().contains("refundSn")) {
             String[] split = payInfoBo.getPayNo().split("refundSn");
@@ -66,7 +64,7 @@ public class PayNoticeController {
 
         } else {
             // 根据内部订单号更新order settlement
-            List<Order> orders = payService.paySuccess(payInfoBo.getPayNo(), payInfoBo.getBizPayNo(), payType);
+            List<Order> orders = payService.paySuccess(payInfoBo.getPayNo(), payInfoBo.getBizPayNo(), 1);
 
             // 移除缓存
             for (Order order : orders) {
@@ -81,4 +79,31 @@ public class PayNoticeController {
         return ResponseEntity.ok(payInfoBo.getSuccessString());
     }
 
+
+    @SneakyThrows
+    //@RequestMapping("/order/{payType}")
+    public ResponseEntity<String> submit(HttpServletRequest request, @PathVariable Integer payType, @RequestBody(required = false) String xmlData) {
+        PayInfoBo payInfoBo = payManagerService.validateAndGetPayInfo(request, PayType.instance(payType), xmlData);
+        if (payInfoBo.getPayNo().contains("refundSn")) {
+            String[] split = payInfoBo.getPayNo().split("refundSn");
+            RefundDelivery refundDelivery = refundDeliveryService.getOne(new LambdaQueryWrapper<RefundDelivery>()
+                    .eq(RefundDelivery::getRefundSn, split[1]));
+            refundDelivery.setPay(true);
+            refundDeliveryService.update(refundDelivery, new LambdaQueryWrapper<RefundDelivery>()
+                    .eq(RefundDelivery::getRefundSn, split[1]));
+        } else {
+            // 根据内部订单号更新order settlement
+            List<Order> orders = payService.paySuccess(payInfoBo.getPayNo(), payInfoBo.getBizPayNo(), payType);
+            // 移除缓存
+            for (Order order : orders) {
+                List<OrderItem> orderItems = order.getOrderItems();
+                for (OrderItem orderItem : orderItems) {
+                    productService.removeProductCacheByProdId(orderItem.getProdId());
+                    skuService.removeSkuCacheBySkuId(orderItem.getSkuId(), orderItem.getProdId());
+                }
+            }
+        }
+        return ResponseEntity.ok(payInfoBo.getSuccessString());
+    }
+
 }

+ 0 - 71
yami-shop-api/src/main/java/com/yami/shop/api/controller/WxPayController.java

@@ -1,71 +0,0 @@
-package com.yami.shop.api.controller;
-
-import com.alibaba.fastjson2.JSONObject;
-import com.yami.shop.wx.po.JsapiPayInfoPo;
-import com.yami.shop.wx.service.WxProviderService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import lombok.AllArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.Map;
-
-
-@RestController
-@AllArgsConstructor
-@Api(tags = "微信支付apiV3")
-@RequestMapping("/wx")
-public class WxPayController {
-
-    @Autowired
-    private final WxProviderService wxProviderService;
-
-    @PostMapping("jsapiPay")
-    @ApiOperation(value = "小程序支付", notes = "小程序支付")
-    public ResponseEntity<Map<String, Object>> jsapiPay(@Validated @RequestBody JsapiPayInfoPo po) {
-        return ResponseEntity.ok(wxProviderService.subJsapi(po));
-    }
-
-    @GetMapping("/refundOrder")
-    @ApiOperation(value = "小程序退款", notes = "小程序退款")
-    public ResponseEntity<String> refundOrder(String orderNo) {
-        return ResponseEntity.ok(wxProviderService.refundOrder(orderNo, 0,0));
-    }
-
-    @GetMapping("/getPayResultByOrderNo")
-    @ApiOperation(value = "查询微信支付订单", notes = "查询微信支付订单")
-    public ResponseEntity<Map<String, Object>> getPayResultByOrderNo(String orderNo) {
-        return ResponseEntity.ok(wxProviderService.getPayResultByOrderNo(orderNo));
-    }
-
-    @GetMapping("/queryRefundOrder")
-    @ApiOperation(value = "查询微信退款信息", notes = "查询微信退款信息")
-    public ResponseEntity<Map<String, Object>> queryRefundOrder(String refundNo) {
-        return ResponseEntity.ok(wxProviderService.queryRefundOrder(refundNo));
-    }
-
-    @PostMapping("/jsapiPay/notify")
-    @ApiOperation(value = "支付回调", notes = "支付回调")
-    public ResponseEntity<?> notify(HttpServletRequest request, HttpServletResponse response) {
-        JSONObject json = wxProviderService.notifyParse(request, response);
-        Object code = json.get("code");
-        if (code != null && code.equals("200")) {
-            JSONObject resourceJson = JSONObject.parseObject(json.get("wxData").toString());
-            JSONObject attach = resourceJson.getJSONObject("attach");
-            if (attach != null) {
-                Object orderNo = attach.get("orderNo");
-                if (orderNo != null) {
-                    System.out.println(orderNo);
-                }
-            }
-            return ResponseEntity.ok("success");
-        } else {
-            throw new RuntimeException("微信回调异常");
-        }
-    }
-}

+ 5 - 12
yami-shop-service/src/main/java/com/yami/shop/service/impl/PayServiceImpl.java

@@ -15,16 +15,13 @@ import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.yami.shop.bean.app.param.PayParam;
 import com.yami.shop.bean.enums.OrderType;
-import com.yami.shop.common.enums.PayType;
-import com.yami.shop.bean.enums.ScoreLogType;
 import com.yami.shop.bean.event.PaySuccessOrderEvent;
-import com.yami.shop.bean.event.UpdateUserScoreEvent;
 import com.yami.shop.bean.model.Order;
 import com.yami.shop.bean.model.OrderItem;
 import com.yami.shop.bean.model.OrderSettlement;
 import com.yami.shop.bean.pay.PayInfoDto;
+import com.yami.shop.common.enums.PayType;
 import com.yami.shop.common.exception.GlobalException;
-import com.yami.shop.common.exception.YamiShopBindException;
 import com.yami.shop.common.util.Arith;
 import com.yami.shop.dao.OrderMapper;
 import com.yami.shop.dao.OrderSettlementMapper;
@@ -35,7 +32,10 @@ import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 /**
@@ -71,17 +71,13 @@ public class PayServiceImpl implements PayService {
                             .eq(OrderSettlement::getUserId,userId)
                             .eq(OrderSettlement::getOrderNumber,orderNumber)
             );
-            System.out.println(orderSettlement);
             if (Objects.equals(orderSettlement.getPayStatus(), 1)) {
                 throw new GlobalException("支付失败,订单不在未支付状态");
             }
             Order order = orderMapper.getOrderByOrderNumber(orderNumber);
-            System.out.println("order"+order);
-            System.out.println(payParam.getPayType());
             order.setPayType(payParam.getPayType());
             orderMapper.updateById(order);
 
-
             orderSettlement.setPayNo(payNo);
             orderSettlement.setPayType(payParam.getPayType());
             orderSettlement.setUserId(userId);
@@ -140,7 +136,4 @@ public class PayServiceImpl implements PayService {
         }
         return orders;
     }
-
-
-
 }

+ 3 - 3
yami-shop-wx/src/main/java/com/yami/shop/wx/service/WxProviderService.java

@@ -1,6 +1,6 @@
 package com.yami.shop.wx.service;
 
-import com.alibaba.fastjson2.JSONObject;
+import com.yami.shop.bean.bo.PayInfoBo;
 import com.yami.shop.wx.po.JsapiPayInfoPo;
 
 import javax.servlet.http.HttpServletRequest;
@@ -11,9 +11,9 @@ public interface WxProviderService {
 
     Map<String, Object> subJsapi(JsapiPayInfoPo po);
 
-    String refundOrder(String orderNo,Integer refundMoney,Integer total);
+    String refundOrder(String orderNo, Integer refundMoney, Integer total);
 
-    JSONObject notifyParse(HttpServletRequest request, HttpServletResponse response);
+    PayInfoBo notifyParse(HttpServletRequest request, HttpServletResponse response);
 
     Map<String, Object> getPayResultByOrderNo(String orderNo);
 

+ 18 - 69
yami-shop-wx/src/main/java/com/yami/shop/wx/service/impl/WxProviderServiceImpl.java

@@ -10,10 +10,12 @@ import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
 import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
 import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
 import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
+import com.yami.shop.bean.bo.PayInfoBo;
 import com.yami.shop.wx.config.CombinePayUrlEnum;
 import com.yami.shop.wx.config.WechatPayServiceConfig;
 import com.yami.shop.wx.po.JsapiPayInfoPo;
 import com.yami.shop.wx.service.WxProviderService;
+import com.yami.shop.wx.utils.CullenUtils;
 import com.yami.shop.wx.utils.OrderUtils;
 import com.yami.shop.wx.utils.WechatPayValidator;
 import lombok.SneakyThrows;
@@ -48,6 +50,9 @@ public class WxProviderServiceImpl implements WxProviderService {
     @Autowired
     private WechatPayServiceConfig wechatPayServiceConfig;
 
+    private static final String WX_SUCCESS_XML = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
+
+
     public Map<String, Object> subJsapi(JsapiPayInfoPo po) {
         System.out.println("微信支付传入参数===========" + po);
         Map<String, Object> params = new HashMap<>(8);
@@ -359,32 +364,32 @@ public class WxProviderServiceImpl implements WxProviderService {
     private final ReentrantLock lock = new ReentrantLock();
 
     @Override
-    public JSONObject notifyParse(HttpServletRequest request, HttpServletResponse response) {
+    public PayInfoBo notifyParse(HttpServletRequest request, HttpServletResponse response) {
         JSONObject bodyJson = getNotifyBodyJson(request);
-        if (bodyJson == null) {
-            return falseMsg(response);
-        }
+        CullenUtils.validateDataThrowException(bodyJson == null, "回调通知验签失败...");
+        PayInfoBo bo = new PayInfoBo();
+
         if (lock.tryLock()) {
             try {
                 // 解密resource中的通知数据
+                assert bodyJson != null;
                 String resource = bodyJson.getString("resource");
                 JSONObject resourceJson = WechatPayValidator.decryptFromResource(resource, wechatPayServiceConfig.getApiV3Key());
                 System.out.println("=================== 服务商小程序支付回调解密resource中的通知数据 ===================\n" + resource);
-                Integer trans = statusTrans(resourceJson.getString("trade_state"));
-                if (trans == 1) {
-                    JSONObject successJson = trueMsg(response);
-                    successJson.put("wxData", resourceJson);
-                    return successJson;
+                if (resourceJson.getString("trade_state").equals("SUCCESS")) {
+                    bo.setPayNo(resourceJson.getString("out_trade_no"));
+                    bo.setBizPayNo(resourceJson.getString("transaction_id"));
+                    bo.setIsPaySuccess(true);
+                    bo.setSuccessString(WX_SUCCESS_XML);
+                    return bo;
                 } else {
-                    JSONObject failMsg = failMsg(response);
-                    failMsg.put("wxData", resourceJson);
-                    return failMsg;
+                    System.err.println("支付失败...");
                 }
             } finally {
                 lock.unlock();
             }
         }
-        return trueMsg(response);
+        return null;
     }
 
     private JSONObject getNotifyBodyJson(HttpServletRequest request) {
@@ -401,60 +406,4 @@ public class WxProviderServiceImpl implements WxProviderService {
         log.info("通知验签成功");
         return jsonObject;
     }
-
-    private JSONObject falseMsg(HttpServletResponse response) {
-        JSONObject resMap = new JSONObject();
-        response.setStatus(500);
-        resMap.put("code", "500");
-        resMap.put("message", "通知验签失败");
-        return resMap;
-    }
-
-    private JSONObject failMsg(HttpServletResponse response) {
-        JSONObject resMap = new JSONObject();
-        response.setStatus(500);
-        resMap.put("code", "500");
-        resMap.put("message", "失败");
-        return resMap;
-    }
-
-
-    /**
-     * 支付状态( 1-支付成功 )
-     *
-     * @param tradeState 微信返回支付状态码
-     * @return 状态
-     */
-    private Integer statusTrans(String tradeState) {
-        int payStatus;
-        if ("SUCCESS".equals(tradeState)) {
-            payStatus = 1;
-        } else if ("NOTPAY".equals(tradeState)) {
-            payStatus = 0;
-        } else if ("REVOKED".equals(tradeState)) {
-            payStatus = 4;
-        } else if ("CLOSED".equals(tradeState)) {
-            payStatus = 6;
-        } else if ("PAYERROR".equals(tradeState)) {
-            payStatus = 5;
-        } else {
-            payStatus = 8;
-        }
-        return payStatus;
-    }
-
-    /**
-     * 创建成功的JSON响应对象
-     *
-     * @param response HTTP响应对象,用于设置状态码
-     * @return 包含成功信息的JSONObject,包含code和message字段
-     */
-    private JSONObject trueMsg(HttpServletResponse response) {
-        JSONObject resMap = new JSONObject();
-        //成功应答
-        response.setStatus(200);
-        resMap.put("code", "200");
-        resMap.put("message", "成功");
-        return resMap;
-    }
 }

+ 74 - 0
yami-shop-wx/src/main/java/com/yami/shop/wx/utils/CullenUtils.java

@@ -0,0 +1,74 @@
+package com.yami.shop.wx.utils;
+
+import com.google.common.collect.Maps;
+import com.yami.shop.common.exception.GlobalException;
+
+import java.util.Map;
+
+/**
+ * @author Cullen
+ * @date 2015-12-12 00:00:00
+ */
+public class CullenUtils {
+
+    /**
+     * 校验参数是否满足表达式并抛出异常
+     *
+     * @param exp     表达式
+     * @param message 异常信息
+     */
+    public static void validateDataThrowException(Boolean exp, String message) {
+        if (exp) {
+            throw new GlobalException(message);
+        }
+    }
+
+
+    /**
+     * 校验参数是否满足表达式并抛出异常
+     *
+     * @param exp1    表达式
+     * @param exp2    表达式
+     * @param message 异常信息
+     */
+    public static void validateDataThrowException(Boolean exp1, Boolean exp2, String message) {
+        if (exp1) {
+            if (exp2) {
+                throw new GlobalException(message);
+            }
+        }
+    }
+
+    /**
+     * 例如:{auth=Kaur, enable=true, domain=www.hjx.org}
+     *
+     * @param input 文本
+     * @return map
+     */
+    public static Map<String, String> textToMap(String input) {
+        Map<String, String> map = Maps.newHashMap();
+        input = input.substring(1, input.length() - 1);
+        String[] keyValuePairs = input.split(", ");
+        for (String pair : keyValuePairs) {
+            String[] entry = pair.split("=");
+            String key = entry[0].trim();
+            String value = entry[1].trim();
+            if (value.startsWith("'") && value.endsWith("'")) {
+                value = value.substring(1, value.length() - 1);
+            }
+            map.put(key, value);
+        }
+        return map;
+    }
+
+    /**
+     * 判断是否是数字
+     *
+     * @param isNumeric isNumeric
+     * @return boolean
+     */
+    public static boolean isNumeric(String isNumeric) {
+        return isNumeric.matches("\\d+");
+    }
+
+}