Browse Source

新增小程序微信境外支付

hyq 6 years ago
parent
commit
785056c0ee
23 changed files with 1319 additions and 223 deletions
  1. 1 1
      kmall-admin/src/main/java/com/kmall/admin/service/OrderService.java
  2. 15 31
      kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java
  3. 86 0
      kmall-admin/src/main/resources/conf/wx-global.properties
  4. 1 0
      kmall-admin/src/main/resources/spring/spring-context.xml
  5. 1 0
      kmall-admin/src/main/resources/spring/spring-main.xml
  6. 62 0
      kmall-admin/src/main/resources/spring/spring-wx-global-pay.xml
  7. 1 0
      kmall-admin/src/main/webapp/WEB-INF/web.xml
  8. 3 5
      kmall-api/src/main/java/com/kmall/api/api/ApiPayController.java
  9. 285 0
      kmall-api/src/main/java/com/kmall/api/api/wxGlobal/ApiWxGlobalPayController.java
  10. 1 0
      kmall-api/src/main/java/com/kmall/api/service/ApiPayService.java
  11. 203 0
      kmall-api/src/main/java/com/kmall/api/service/wxGlobal/ApiWxGlobalPayService.java
  12. 12 0
      kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayDevProperties.java
  13. 12 0
      kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayProdProperties.java
  14. 181 0
      kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayProperties.java
  15. 41 0
      kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayPropertiesBuilder.java
  16. 39 0
      kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayPropertiesConfiguration.java
  17. 5 5
      kmall-common/src/main/java/com/kmall/common/utils/wechat/WechatUtil.java
  18. 61 72
      kmall-common/src/main/java/com/kmall/common/utils/wechat/wxglobal/WechatGlobalUtil.java
  19. 9 0
      kmall-common/src/main/java/com/kmall/common/utils/wechat/wxglobal/dto/WechatGlobalQueryApiResult.java
  20. 1 0
      kmall-framework/src/main/webapp/WEB-INF/web.xml
  21. 1 0
      kmall-framework/src/test/resources/applicationContext-test.xml
  22. 283 107
      kmall-schedule/src/main/java/com/kmall/schedule/service/QzOrderService.java
  23. 15 2
      kmall-schedule/src/main/resources/mybatis/mapper/QzOrderMapper.xml

+ 1 - 1
kmall-admin/src/main/java/com/kmall/admin/service/OrderService.java

@@ -87,5 +87,5 @@ public interface OrderService {
 
     Map orderSubmit(List<OfflineCartEntity> offlineCartEntityList,SysUserEntity user);
 
-    int confirmPay(Long id, Dict.payFlag payFlag,String orderSnWx);
+    int confirmPay(Long id, String payFlag,String orderSnWx);
 }

+ 15 - 31
kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java

@@ -114,27 +114,7 @@ public class OrderServiceImpl
             return;
         }
         // 更新库存
-        Map<String, Object> map = new HashMap<String, Object>();
-        map.put("orderId", order.getId());
-        List<OrderGoodsEntity> orderGoodsVoList = orderGoodsDao.queryList(map);
-        for (OrderGoodsEntity orderGoodsEntity : orderGoodsVoList) {
-            ProductStoreRelaEntity storeRelaEntity = productStoreRelaDao
-                    .queryByStoreIdProductId(Long.valueOf(order.getStoreId()),
-                                             Long.valueOf(orderGoodsEntity.getProductId()));
-            if (null == storeRelaEntity || null == storeRelaEntity.getSellVolume()) {
-                storeRelaEntity.setSellVolume(0);
-            }
-            BigDecimal sellVolume = new BigDecimal(storeRelaEntity.getSellVolume() - orderGoodsEntity.getNumber());//销售量
-            if (sellVolume.compareTo(Constant.ZERO) < 0) {
-                sellVolume = Constant.ZERO;
-            }
-            storeRelaEntity.setSellVolume(Integer.parseInt(sellVolume.toString()));
-            if (null == storeRelaEntity.getStockNum()) {
-                storeRelaEntity.setStockNum(0);
-            }
-            storeRelaEntity.setStockNum(storeRelaEntity.getStockNum() + orderGoodsEntity.getNumber());//库存数量
-            productStoreRelaDao.update(storeRelaEntity);
-        }
+        updateStock(order);
     }
 
     @Override
@@ -275,14 +255,11 @@ public class OrderServiceImpl
         if (order.getOrderStatus() == Integer.parseInt(Dict.orderStatus.item_201.getItem())) {
             order.setOrderStatus(Integer.parseInt(Dict.orderStatus.item_401.getItem()));
         }
-
         if (Dict.payFlag.item_cash.getItem().equals(order.getPayFlag())) {
             order.setPayStatus(Integer.parseInt(Dict.payStatus.item_4.getItem()));
         }else{
             order.setPayStatus(Integer.parseInt(Dict.payStatus.item_3.getItem()));
-
             OrderRefundEntity mallOrderRefund = orderRefundDao.queryObjectByOrderId(order.getId());
-
             OrderRefundEntity orderRefund = new OrderRefundEntity();
             orderRefund.setRefundId(result.getRefund_id());
             orderRefund.setOutRefundNo(result.getOut_refund_no());
@@ -302,9 +279,7 @@ public class OrderServiceImpl
                 orderRefundDao.save(orderRefund);//退款记录
             }
         }
-
         orderDao.update(order);//修改为退款中
-
         // 判断是否有优惠券
         UserCouponEntity couponVo = userCouponDao.queryByOrderId(order.getId());
         if (null != couponVo) {
@@ -315,13 +290,17 @@ public class OrderServiceImpl
             return;
         }
         // 更新库存
+        updateStock(order);
+    }
+
+    private void updateStock(OrderEntity order){
         Map<String, Object> map = new HashMap<String, Object>();
         map.put("orderId", order.getId());
         List<OrderGoodsEntity> orderGoodsVoList = orderGoodsDao.queryList(map);
         for (OrderGoodsEntity orderGoodsEntity : orderGoodsVoList) {
             ProductStoreRelaEntity storeRelaEntity = productStoreRelaDao
                     .queryByStoreIdProductId(Long.valueOf(order.getStoreId()),
-                                             Long.valueOf(orderGoodsEntity.getProductId()));
+                            Long.valueOf(orderGoodsEntity.getProductId()));
             if (null == storeRelaEntity || null == storeRelaEntity.getSellVolume()) {
                 storeRelaEntity.setSellVolume(0);
             }
@@ -337,7 +316,6 @@ public class OrderServiceImpl
             productStoreRelaDao.update(storeRelaEntity);
         }
     }
-
     /**
      * 处理用户退款申请
      *
@@ -515,6 +493,12 @@ public class OrderServiceImpl
         return orderEntity;
     }
 
+    /**
+     * 普货商品生成线下订单
+     * @param offlineCartList
+     * @param user
+     * @return
+     */
     @Transactional
     @Override
     public Map orderSubmit(List<OfflineCartEntity> offlineCartList, SysUserEntity user) {
@@ -670,7 +654,7 @@ public class OrderServiceImpl
         orderInfo.setIntegralMoney(Constant.ZERO);
         orderInfo.setCreateTime(new Date());
         orderInfo.setModTime(new Date());
-        orderInfo.setIsOnfflineOrder(Dict.isOnfflineOrder.item_1.getItem());
+        orderInfo.setIsOnfflineOrder(Dict.isOnfflineOrder.item_1.getItem());//线下购买
         /*//标记该订单已使用优惠券
         if(couponVo != null){
             couponVo.setUsed_time(new Date());
@@ -713,7 +697,7 @@ public class OrderServiceImpl
     }
 
     @Override
-    public int confirmPay(Long id, Dict.payFlag payFlag,String orderSnWx) {
+    public int confirmPay(Long id, String payFlag,String orderSnWx) {
         SysUserEntity user = ShiroUtils.getUserEntity();
         if (user == null) {
             throw new RRException("用户登录超时,请重新登录");
@@ -736,7 +720,7 @@ public class OrderServiceImpl
         }
         orderEntity.setOrderStatus(Integer.parseInt(Dict.orderStatus.item_201.getItem()));
         orderEntity.setPayStatus(Integer.parseInt(Dict.payStatus.item_2.getItem()));
-        orderEntity.setPayFlag(payFlag.getItem());
+        orderEntity.setPayFlag(payFlag);
         orderEntity.setPayTime(new Date());
         if(orderSnWx != null){
             orderEntity.setOrderSnWx(orderSnWx);

+ 86 - 0
kmall-admin/src/main/resources/conf/wx-global.properties

@@ -0,0 +1,86 @@
+########## 微信小程序配置 ##########
+
+# [dev, prod]
+pay.wx.global.env = dev
+
+
+#========== 开发环境 ==========
+#小程序ID
+wx.global.dev.appId=wxb6b30b1b14ee502a
+#小程序密钥
+wx.global.dev.secret=be0234dbbbde4ce68df43dd2b5e4c7b1
+#商户号
+wx.global.dev.mchId=
+#支付签名
+wx.global.dev.paySignKey=
+#交易类型
+wx.global.dev.tradeType=JSAPI
+#商户币种
+wx.global.dev.feeType=CNY
+#证书名称,对应不同的商户号
+wx.global.dev.certName=/cert/apiclient_cert.p12
+#支付回调地址
+wx.global.dev.notifyUrl=http://qhdswl.f3322.net:9001/platform-framework/api/global/pay/notify
+#获取code的请求地址
+wx.global.dev.getCode=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STAT#wechat_redirect
+#获取Web_access_tokenhttps的请求地址
+wx.global.dev.webAccessTokenhttps = https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code
+#拉取用户信息的请求地址
+wx.global.dev.userMessage=https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN
+#微信统一下单接口路径
+wx.global.dev.uniformorder=https://api.mch.weixin.qq.com/pay/unifiedorder
+#退款地址
+wx.global.dev.refundUrl=https://api.mch.weixin.qq.com/secapi/pay/refund
+#退款回调地址
+wx.global.dev.refundNotifyUrl=http://qhdswl.f3322.net:9001/platform-framework/api/global/pay/refundNotify
+#退款查询地址
+wx.global.dev.refundqueryUrl=https://api.mch.weixin.qq.com/pay/refundquery
+#微信查询订单状态
+wx.global.dev.orderquery=https://api.mch.weixin.qq.com/pay/orderquery
+#查询汇率
+wx.global.dev.ratequery=https://api.mch.weixin.qq.com/pay/queryexchagerate
+#服务器Ip
+wx.global.dev.spbillCreateIp=127.0.0.1
+
+
+
+#========== 生产环境 ==========
+
+#小程序ID
+wx.global.prod.appId=wxb6b30b1b14ee502a
+#小程序密钥
+wx.global.prod.secret=be0234dbbbde4ce68df43dd2b5e4c7b1
+#商户号
+wx.global.prod.mchId=
+#支付签名
+wx.global.prod.paySignKey=
+#交易类型
+wx.global.prod.tradeType=JSAPI
+#商户币种
+wx.global.prod.feeType=CNY
+#证书名称,对应不同的商户号
+wx.global.prod.certName=/cert/apiclient_cert.p12
+#支付回调地址
+wx.global.prod.notifyUrl=https://mp.k1net.cn/api/global/pay/notify
+#获取code的请求地址
+wx.global.prod.getCode=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STAT#wechat_redirect
+#获取Web_access_tokenhttps的请求地址
+wx.global.prod.webAccessTokenhttps = https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code
+#拉取用户信息的请求地址
+wx.global.prod.userMessage=https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN
+#微信统一下单接口路径
+wx.global.prod.uniformorder=https://api.mch.weixin.qq.com/pay/unifiedorder
+#退款地址
+wx.global.prod.refundUrl=https://api.mch.weixin.qq.com/secapi/pay/refund
+#退款回调地址
+wx.global.prod.refundNotifyUrl=https://mp.k1net.cn/api/global/pay/refundNotify
+#退款查询地址
+wx.global.prod.refundqueryUrl=https://api.mch.weixin.qq.com/pay/refundquery
+#微信查询订单状态
+wx.global.prod.orderquery=https://api.mch.weixin.qq.com/pay/orderquery
+#查询汇率
+wx.global.prod.ratequery=https://api.mch.weixin.qq.com/pay/queryexchagerate
+#服务器Ip
+wx.global.prod.spbillCreateIp=127.0.0.1
+
+

+ 1 - 0
kmall-admin/src/main/resources/spring/spring-context.xml

@@ -27,6 +27,7 @@
                 <value>classpath:conf/redis.properties</value>
                 <value>classpath:conf/servlet.properties</value>
                 <value>classpath:conf/wx-mp.properties</value>
+                <value>classpath:conf/wx-global.properties</value>
                 <value>classpath:conf/pingan-pay.properties</value>
                 <value>classpath:conf/oms-merch.properties</value>
                 <value>classpath:conf/print-ticket.properties</value>

+ 1 - 0
kmall-admin/src/main/resources/spring/spring-main.xml

@@ -18,6 +18,7 @@
     <import resource="spring-redis.xml"/>
     <import resource="spring-express-kdn.xml"/>
     <import resource="spring-wx-pay.xml"/>
+    <import resource="spring-wx-global-pay.xml"/>
     <import resource="spring-pingan-pay.xml"/>
     <import resource="spring-jdbc.xml"/>
     <import resource="spring-oms-merch.xml"/>

+ 62 - 0
kmall-admin/src/main/resources/spring/spring-wx-global-pay.xml

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xmlns:mvc="http://www.springframework.org/schema/mvc"
+       xsi:schemaLocation="
+        http://www.springframework.org/schema/beans 
+        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
+        http://www.springframework.org/schema/context
+        http://www.springframework.org/schema/context/spring-context-4.2.xsd
+     	http://www.springframework.org/schema/aop
+     	http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
+		http://www.springframework.org/schema/mvc
+     	http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
+
+    <bean id="commonWxGlobalPayProdProperties" class="com.kmall.common.service.pay.global.CommonWxGlobalPayProdProperties">
+        <property name="appId" value="${wx.global.prod.appId}"/>
+        <property name="secret" value="${wx.global.prod.secret}"/>
+        <property name="mchId" value="${wx.global.prod.mchId}"/>
+        <property name="paySignKey" value="${wx.global.prod.paySignKey}"/>
+
+        <property name="tradeType" value="${wx.global.prod.tradeType}"/>
+        <property name="feeType" value="${wx.global.prod.feeType}"/>
+        <property name="certName" value="${wx.global.prod.certName}"/>
+        <property name="notifyUrl" value="${wx.global.prod.notifyUrl}"/>
+        <property name="getCode" value="${wx.global.prod.getCode}"/>
+
+        <property name="webAccessTokenhttps" value="${wx.global.prod.webAccessTokenhttps}"/>
+        <property name="userMessage" value="${wx.global.prod.userMessage}"/>
+        <property name="uniformorder" value="${wx.global.prod.uniformorder}"/>
+        <property name="refundUrl" value="${wx.global.prod.refundUrl}"/>
+        <property name="refundqueryUrl" value="${wx.global.prod.refundqueryUrl}"/>
+        <property name="orderquery" value="${wx.global.prod.orderquery}"/>
+        <property name="ratequery" value="${wx.global.prod.ratequery}"/>
+        <property name="spbillCreateIp" value="${wx.global.prod.spbillCreateIp}"/>
+        <property name="refundNotifyUrl" value="${wx.global.prod.refundNotifyUrl}"/>
+    </bean>
+
+    <bean id="commonWxGlobalPayDevProperties" class="com.kmall.common.service.pay.global.CommonWxGlobalPayDevProperties">
+        <property name="appId" value="${wx.global.dev.appId}"/>
+        <property name="secret" value="${wx.global.dev.secret}"/>
+        <property name="mchId" value="${wx.global.dev.mchId}"/>
+        <property name="paySignKey" value="${wx.global.dev.paySignKey}"/>
+
+        <property name="tradeType" value="${wx.global.dev.tradeType}"/>
+        <property name="feeType" value="${wx.global.dev.feeType}"/>
+        <property name="certName" value="${wx.global.dev.certName}"/>
+        <property name="notifyUrl" value="${wx.global.dev.notifyUrl}"/>
+        <property name="getCode" value="${wx.global.dev.getCode}"/>
+
+        <property name="webAccessTokenhttps" value="${wx.global.dev.webAccessTokenhttps}"/>
+        <property name="userMessage" value="${wx.global.dev.userMessage}"/>
+        <property name="uniformorder" value="${wx.global.dev.uniformorder}"/>
+        <property name="refundUrl" value="${wx.global.dev.refundUrl}"/>
+        <property name="refundqueryUrl" value="${wx.global.dev.refundqueryUrl}"/>
+        <property name="orderquery" value="${wx.global.dev.orderquery}"/>
+        <property name="ratequery" value="${wx.global.dev.ratequery}"/>
+        <property name="spbillCreateIp" value="${wx.global.dev.spbillCreateIp}"/>
+        <property name="refundNotifyUrl" value="${wx.global.dev.refundNotifyUrl}"/>
+    </bean>
+</beans>

+ 1 - 0
kmall-admin/src/main/webapp/WEB-INF/web.xml

@@ -12,6 +12,7 @@
             classpath:spring/spring-express-kdn.xml,
             classpath:spring/spring-redis.xml,
             classpath:spring/spring-wx-pay.xml,
+            classpath:spring/spring-wx-global-pay.xml,
             classpath:spring/spring-pingan-pay.xml,
             classpath:spring/spring-jdbc.xml,,
             classpath:spring/spring-oms-merch.xml,

+ 3 - 5
kmall-api/src/main/java/com/kmall/api/api/ApiPayController.java

@@ -53,8 +53,6 @@ public class ApiPayController extends ApiBaseAction {
     @Autowired
     private ApiOrderRefundMapper mallOrderRefundMapper;
 
-
-
     /**
      */
     @RequestMapping("index")
@@ -163,7 +161,7 @@ public class ApiPayController extends ApiBaseAction {
                 updateFailProcessBatch(processRecordEntityList, "支付失败," +return_msg);//更新订单流转信息
                 addOrderExceptionRecord(orderVoList, Dict.exceptionStatus.item_00.getItem(),"支付失败," +return_msg);//记录订单异常信息
                 return toResponsFail("支付失败," + return_msg);
-            } else if (return_code.equalsIgnoreCase("SUCCESS")) {
+            } else if (return_code.equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
                 // 返回数据
                 String result_code = MapUtils.getString("result_code", resultUn);
                 String err_code_des = MapUtils.getString("err_code_des", resultUn);
@@ -171,7 +169,7 @@ public class ApiPayController extends ApiBaseAction {
                     updateFailProcessBatch(processRecordEntityList, "支付失败," +err_code_des);//更新订单流转信息
                     addOrderExceptionRecord(orderVoList, Dict.exceptionStatus.item_00.getItem(),"支付失败," +err_code_des);//记录订单异常信息
                     return toResponsFail("支付失败," + err_code_des);
-                } else if (result_code.equalsIgnoreCase("SUCCESS")) {
+                } else if (result_code.equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
                     apiPayService.payPrepay(resultObj, resultUn, nonceStr, orderVoList);
                     orderProcessRecordService.updateBatch(processRecordEntityList);//更新订单流转信息
                     return toResponsObject(0, "微信统一订单下单成功", resultObj);
@@ -249,7 +247,7 @@ public class ApiPayController extends ApiBaseAction {
                 logger.error("订单" + out_trade_no + "支付失败");
                 response.getWriter().write(setXml("SUCCESS", "OK"));
                 response.getWriter().close();
-            } else if (result_code.equalsIgnoreCase("SUCCESS")) {
+            } else if (result_code.equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
                 //验签
                 String sign = result.getSign();
                 String time_end = result.getTime_end();

+ 285 - 0
kmall-api/src/main/java/com/kmall/api/api/wxGlobal/ApiWxGlobalPayController.java

@@ -0,0 +1,285 @@
+package com.kmall.api.api.wxGlobal;
+
+import com.kmall.api.annotation.IgnoreAuth;
+import com.kmall.api.annotation.LoginUser;
+import com.kmall.api.contants.Dict;
+import com.kmall.api.entity.*;
+import com.kmall.api.service.*;
+import com.kmall.api.service.wxGlobal.ApiWxGlobalPayService;
+import com.kmall.api.util.ApiBaseAction;
+import com.kmall.api.util.CommonUtil;
+import com.kmall.common.utils.CharUtil;
+import com.kmall.common.utils.Constant;
+import com.kmall.common.utils.XmlUtil;
+import com.kmall.common.utils.wechat.AESUtil;
+import com.kmall.common.utils.wechat.WechatRefundApiResult;
+import com.kmall.common.utils.wechat.WechatRefundNotifyResult;
+import com.kmall.common.utils.wechat.WechatUtil;
+import com.kmall.common.utils.wechat.wxglobal.WechatGlobalUtil;
+import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalNotifyResult;
+import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalQueryApiResult;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.*;
+
+
+/**
+ * 微信境外支付
+ *
+ * @author huangyq
+ * @email
+ * @date 2018-12-11 17:01
+ */
+@RestController
+@RequestMapping("/api/global/pay")
+public class ApiWxGlobalPayController extends ApiBaseAction {
+    private Logger logger = Logger.getLogger(ApiWxGlobalPayController.class);
+    @Autowired
+    private ApiOrderService orderService;
+    @Autowired
+    private ApiOrderGoodsService orderGoodsService;
+    @Autowired
+    private ApiWxGlobalPayService apiWxGlobalPayService;
+    @Autowired
+    private ApiOrderProcessRecordService orderProcessRecordService;
+    @Autowired
+    private ApiOrderExceptionRecordService apiOrderExceptionRecordService;
+
+    /**
+     * 发起支付
+     * @param loginUser
+     * @param orderIds
+     * @param isMergePay
+     * @return
+     */
+    @GetMapping("pay_prepay")
+    public Object payPrepay(@LoginUser UserVo loginUser, Long[] orderIds,String isMergePay) {
+        logger.info("微信支付接口>>>>>>payPrepay start");
+        List<Long> orderIdList=new ArrayList<>();
+        String merchOrderSn = "";
+        for(int i=0;i<orderIds.length;i++){
+            orderIdList.add(orderIds[i]);
+        }
+        BigDecimal actual_price = Constant.ZERO;
+        List<OrderVo> orderVoList = orderService.queryObjectByIdList(orderIdList);
+        List<OrderProcessRecordEntity> processRecordEntityList = new ArrayList<>();
+
+        for (OrderVo orderInfo:orderVoList) {
+            if (orderInfo.getOrder_status() == 101) {
+                return toResponsObject(400, "订单号为"+orderInfo.getOrder_sn()+"的订单超时支付,已取消", "");
+            }
+            if (orderInfo.getPay_status() != 0 && orderInfo.getPay_status() != 1) {
+                return toResponsObject(400, "订单号为"+orderInfo.getOrder_sn()+"的订单已支付,请不要重复操作", "");
+            }
+            OrderProcessRecordEntity processRecordEntity = orderProcessRecordService.queryObjectByOrderSn(orderInfo.getOrder_sn());
+            if(processRecordEntity != null){
+                OrderProcessRecordEntity entity = new OrderProcessRecordEntity();
+                entity.setOrderSn(orderInfo.getOrder_sn());
+                entity.setUserId(Integer.valueOf(loginUser.getId()+""));
+                entity.setId(processRecordEntity.getId());
+                entity.setPayStartTime(new Date());
+                processRecordEntityList.add(entity);
+            }
+            merchOrderSn = orderInfo.getMerchOrderSn();
+            //如此次是单笔支付,则判断下单时该商户订单是否是拆单订单,如果都满足,则更新商户订单号,生成新的预支付信息
+            if(Dict.isMergePay.item_0.getItem().equalsIgnoreCase(isMergePay)) {
+                if ("2".equalsIgnoreCase(orderInfo.getIsMergePay())) {//多笔订单单笔支付,则商户订单号,生成新的预支付信息
+                    merchOrderSn = "EMATO"+ CommonUtil.generateOrderNumber();
+                    orderInfo.setMerchOrderSn(merchOrderSn);
+                }
+            }
+            actual_price = actual_price.add(orderInfo.getActual_price());
+        }
+        String nonceStr = CharUtil.getRandomString(32);
+        Map<Object, Object> resultObj = new HashMap();
+
+        try {
+            //订单的商品
+            List<OrderGoodsVo> orderGoods = orderGoodsService.queryListByIds(orderIdList);
+            String body = "";
+            if (null != orderGoods) {
+                body = "商城-";
+                for (OrderGoodsVo goodsVo : orderGoods) {
+                    body = body + goodsVo.getGoods_name() + "、";
+                }
+                if (body.length() > 0) {
+                    body = body.substring(0, body.length() - 1);
+                }
+            }
+            //统一下单
+            WechatGlobalQueryApiResult queryApiResult = WechatGlobalUtil.unifiedOrder(merchOrderSn, body, actual_price, loginUser.getWeixin_openid());
+            // 响应报文
+            String return_code = queryApiResult.getReturn_code();
+            String return_msg = queryApiResult.getReturn_msg();
+            //
+            if (return_code.equalsIgnoreCase("FAIL")) {
+                updateFailProcessBatch(processRecordEntityList, "支付失败 ," +return_msg);//更新订单流转信息
+                addOrderExceptionRecord(orderVoList, Dict.exceptionStatus.item_00.getItem(),"支付失败 ," +return_msg);//记录订单异常信息
+                return toResponsFail("支付失败 ," + return_msg);
+            } else if (return_code.equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                // 返回数据
+                String result_code = queryApiResult.getResult_code();
+                String err_code_des = queryApiResult.getErr_code_des();
+                if (result_code.equalsIgnoreCase("FAIL")) {
+                    updateFailProcessBatch(processRecordEntityList, "支付失败 ," +err_code_des);//更新订单流转信息
+                    addOrderExceptionRecord(orderVoList, Dict.exceptionStatus.item_00.getItem(),"支付失败 ," +err_code_des);//记录订单异常信息
+                    return toResponsFail("支付失败 ," + err_code_des);
+                } else if (result_code.equalsIgnoreCase(WechatGlobalUtil.WXTradeState.SUCCESS.getCode())) {
+                    apiWxGlobalPayService.payPrepay(resultObj, queryApiResult, nonceStr, orderVoList);
+                    orderProcessRecordService.updateBatch(processRecordEntityList);//更新订单流转信息
+                    return toResponsObject(0, "微信统一订单下单成功", resultObj);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            updateFailProcessBatch(processRecordEntityList, "下单失败,error=" + e.getMessage());//更新订单流转信息
+            return toResponsFail("下单失败,error=" + e.getMessage());
+        }
+        return toResponsFail("下单失败");
+    }
+
+    /**
+     * 更新订单支付失败流转信息
+     * @param processRecordEntityList
+     * @param return_msg
+     */
+    public void updateFailProcessBatch(List<OrderProcessRecordEntity> processRecordEntityList,String return_msg){
+        for (OrderProcessRecordEntity orderProcessRecordEntity : processRecordEntityList) {
+            orderProcessRecordEntity.setIsPaymentSend(Dict.isSend.item_0.getItem());
+            orderProcessRecordEntity.setProcessContent(return_msg);
+        }
+        orderProcessRecordService.updateBatch(processRecordEntityList);
+    }
+
+    /**
+     * 记录订单异常信息
+     * @param orderVoList
+     * @param exceptionStatus
+     * @param expContent
+     */
+    public void addOrderExceptionRecord(List<OrderVo> orderVoList,String exceptionStatus,String expContent){
+        for (OrderVo orderInfo: orderVoList) {
+            MallOrderExceptionRecord mallOrderExceptionRecord = new MallOrderExceptionRecord();
+            mallOrderExceptionRecord.setUserId(Integer.parseInt(orderInfo.getUser_id()+""));
+            mallOrderExceptionRecord.setOrderSn(orderInfo.getOrder_sn());
+            mallOrderExceptionRecord.setExceptionContent(expContent);
+            mallOrderExceptionRecord.setExceptionStatus(exceptionStatus);
+            mallOrderExceptionRecord.setCreateTime(new Date());
+            apiOrderExceptionRecordService.save(mallOrderExceptionRecord);
+        }
+    }
+
+    /**
+     * 微信订单回调接口
+     *
+     * @return
+     */
+    @IgnoreAuth
+    @RequestMapping(value = "/notify", produces = "text/html;charset=UTF-8")
+    @ResponseBody
+    public void notify(HttpServletRequest request, HttpServletResponse response) {
+        logger.info("微信订单回调接口>>>>>>notify start");
+        try {
+            request.setCharacterEncoding("UTF-8");
+            response.setContentType("text/html;charset=UTF-8");
+            response.setCharacterEncoding("UTF-8");
+            response.setHeader("Access-Control-Allow-Origin", "*");
+            InputStream in = request.getInputStream();
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int len = 0;
+            while ((len = in.read(buffer)) != -1) {
+                out.write(buffer, 0, len);
+            }
+            out.close();
+            in.close();
+            String reponseXml = new String(out.toByteArray(), "utf-8");//xml数据
+            logger.error("reponseXml:" + reponseXml);
+            WechatGlobalNotifyResult result = (WechatGlobalNotifyResult) XmlUtil.xmlStrToBean(reponseXml, WechatGlobalNotifyResult.class);
+            String result_code = result.getResult_code();
+            if (result_code.equalsIgnoreCase("FAIL")) {
+                String out_trade_no = result.getOut_trade_no();//订单编号
+                logger.error("订单 " + out_trade_no + " 支付失败");
+                response.getWriter().write(setXml(WechatGlobalUtil.WXTradeState.SUCCESS.getCode(), "OK"));
+                response.getWriter().close();
+            } else if (result_code.equalsIgnoreCase(WechatGlobalUtil.WXTradeState.SUCCESS.getCode())) {
+                String time_end = result.getTime_end();
+                String out_trade_no = result.getOut_trade_no();//商户订单号
+                String transaction_id = result.getTransaction_id();//微信支付订单号
+                String total_fee = result.getTotal_fee();//订单编号
+                logger.error("订单 " + out_trade_no + " 支付成功");
+                // 业务处理
+                apiWxGlobalPayService.notify(out_trade_no,total_fee,transaction_id,time_end);
+                response.getWriter().write(setXml(WechatGlobalUtil.WXTradeState.SUCCESS.getCode(), "OK"));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return;
+        }
+    }
+
+    /**
+     * 微信订单退款回调接口
+     *
+     * @return
+     */
+    @IgnoreAuth
+    @RequestMapping(value = "/refundNotify", produces = "text/html;charset=UTF-8")
+    @ResponseBody
+    public void refundNotify(HttpServletRequest request, HttpServletResponse response) {
+        logger.info("微信订单退款回调接口》》》》refundNotify start");
+        try {
+            request.setCharacterEncoding("UTF-8");
+            response.setCharacterEncoding("UTF-8");
+            response.setContentType("text/html;charset=UTF-8");
+            response.setHeader("Access-Control-Allow-Origin", "*");
+            InputStream in = request.getInputStream();
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int len = 0;
+            while ((len = in.read(buffer)) != -1) {
+                out.write(buffer, 0, len);
+            }
+            out.close();
+            in.close();
+            String reponseXml = new String(out.toByteArray(), "utf-8");//xml数据
+            logger.error("reponseXml :" + reponseXml);
+            WechatRefundNotifyResult result = (WechatRefundNotifyResult) XmlUtil.xmlStrToBean(reponseXml, WechatRefundNotifyResult.class);
+
+            if (result.getReturn_code().equalsIgnoreCase("FAIL")) {
+                logger.info("微信查询接口调用失败 : "+result.getReturn_msg());
+                response.getWriter().write(setXml(WechatGlobalUtil.WXTradeState.SUCCESS.getCode(), "OK"));
+                response.getWriter().close();
+            }else {
+                String req_info = result.getReq_info();//加密信息
+                String aesResult = AESUtil.decryptData(req_info);
+                System.out.println(aesResult);
+                WechatRefundApiResult refundApiResult = (WechatRefundApiResult) XmlUtil.xmlStrToBean(aesResult, WechatRefundApiResult.class);
+
+                logger.error("订单 " + refundApiResult.getOut_trade_no() + "退款成功");
+                // 业务处理
+                apiWxGlobalPayService.refundNotify(refundApiResult);
+                response.getWriter().write(setXml(WechatGlobalUtil.WXTradeState.SUCCESS.getCode(), "OK"));
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return;
+        }
+    }
+
+    //返回微信服务
+    public static String setXml(String return_code, String return_msg) {
+        return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
+    }
+}

+ 1 - 0
kmall-api/src/main/java/com/kmall/api/service/ApiPayService.java

@@ -77,6 +77,7 @@ public class ApiPayService {
         for (OrderVo orderInfo: orderVoList) {
             // 业务处理
             orderInfo.setPay_id(prepay_id);
+            orderInfo.setPayFlag(Dict.payFlag.item_weixin.getItem());
             orderInfo.setPay_status(Integer.parseInt(Dict.payStatus.item_1.getItem())); // 付款中
             orderInfo.setOrder_status(Integer.parseInt(Dict.orderStatus.item_100.getItem()));
             orderService.update(orderInfo);

+ 203 - 0
kmall-api/src/main/java/com/kmall/api/service/wxGlobal/ApiWxGlobalPayService.java

@@ -0,0 +1,203 @@
+package com.kmall.api.service.wxGlobal;
+
+import com.kmall.api.contants.Dict;
+import com.kmall.api.dao.*;
+import com.kmall.api.entity.*;
+import com.kmall.api.service.ApiGoodsGroupOpenDetailService;
+import com.kmall.api.service.ApiGoodsGroupOpenService;
+import com.kmall.api.service.ApiOrderService;
+import com.kmall.api.service.PayerChildOrderRealService;
+import com.kmall.api.service.pay.wxpay.WxPayPropertiesBuilder;
+import com.kmall.common.entity.FormIdsEntity;
+import com.kmall.common.service.FormIdsService;
+import com.kmall.common.utils.Constant;
+import com.kmall.common.utils.DateUtils;
+import com.kmall.common.utils.MapUtils;
+import com.kmall.common.utils.wechat.WechatRefundApiResult;
+import com.kmall.common.utils.wechat.WechatUtil;
+import com.kmall.common.utils.wechat.wxglobal.WechatGlobalUtil;
+import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalQueryApiResult;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+/**
+ * 小程序form_id收集Service实现类
+ *
+ * @author Scott
+ * @email
+ * @date 2017-12-16 15:32:50
+ */
+@Service
+public class ApiWxGlobalPayService {
+    private static Logger logger = Logger.getLogger(ApiWxGlobalPayService.class);
+    @Autowired
+    private ApiOrderService orderService;
+    @Autowired
+    private FormIdsService formIdsService;
+    @Autowired
+    private PayerChildOrderRealService payerChildOrderRealService;
+    @Autowired
+    private ApiOrderExceptionRecordMapper mallOrderExceptionRecordMapper;
+    @Autowired
+    private ApiOrderProcessRecordMapper orderProcessRecordMapper;
+    @Autowired
+    private ApiOrderRefundMapper mallOrderRefundMapper;
+
+
+    @Transactional
+    public void payPrepay(Map<Object, Object> resultObj, WechatGlobalQueryApiResult queryApiResult, String nonceStr, List<OrderVo> orderVoList) {
+        logger.info("payPrepay》》》》更新订单状态");
+        String prepay_id = queryApiResult.getPrepay_id();
+        resultObj.put("appId", WxPayPropertiesBuilder.instance().getAppId());
+        resultObj.put("timeStamp", DateUtils.timeToStr(System.currentTimeMillis() / 1000, DateUtils.DATE_TIME_PATTERN));
+        resultObj.put("nonceStr", nonceStr);
+        resultObj.put("package", "prepay_id=" + prepay_id);
+        resultObj.put("signType", "MD5");
+        String paySign = WechatUtil.arraySign(resultObj, WxPayPropertiesBuilder.instance().getPaySignKey());
+        resultObj.put("paySign", paySign);
+        for (OrderVo orderInfo: orderVoList) {
+            // 业务处理
+            orderInfo.setPay_id(prepay_id);
+            orderInfo.setPayFlag(Dict.payFlag.item_wxglobalpay.getItem());
+            orderInfo.setOrder_status(Integer.parseInt(Dict.orderStatus.item_100.getItem()));
+            orderInfo.setPay_status(Integer.parseInt(Dict.payStatus.item_1.getItem())); // 付款中
+            orderService.update(orderInfo);
+
+            Map map = new HashMap();
+            map.put("orderSn", orderInfo.getOrder_sn());
+            List<PayerChildOrderRealEntity> list = payerChildOrderRealService.queryList(map);
+            PayerChildOrderRealEntity entity = new PayerChildOrderRealEntity();
+            entity.setGoodsBizType(orderInfo.getOrderBizType());
+            entity.setOrderSn(orderInfo.getOrder_sn());
+            entity.setMerchSn(orderInfo.getMerchSn());
+            entity.setMerchOrderSn(orderInfo.getMerchOrderSn());
+            entity.setPayNo(orderInfo.getPay_id());
+            entity.setPayPrice(orderInfo.getActual_price());
+            entity.setCreateTime(new Date());
+            entity.setModTime(new Date());
+            entity.setUserId(Integer.parseInt(orderInfo.getUser_id() + ""));
+            if(list.size() > 0) {
+                for (PayerChildOrderRealEntity payerChildOrderRealEntity:list) {
+                    entity.setId(payerChildOrderRealEntity.getId());
+                    payerChildOrderRealService.update(entity);
+                }
+            }else{
+                payerChildOrderRealService.save(entity);//记录微信返回的支付单与子订单信息
+            }
+            FormIdsEntity formIdsEntity = formIdsService.getFormIdsByMerchOrderSn(orderInfo.getMerchOrderSn());
+            if(formIdsEntity != null){
+                FormIdsEntity formIds = new FormIdsEntity();
+                formIds.setMerchOrderSn(orderInfo.getMerchOrderSn());
+                formIds.setFormId(prepay_id);
+                formIds.setValidNum(formIdsEntity.getValidNum()+1);
+                formIds.setId(formIdsEntity.getId());
+                formIdsService.releaseFormIds(formIds);
+            }else{
+                // 保存form_id
+                formIdsService.save(orderInfo.getUser_id(), prepay_id, 1, orderInfo.getMerchOrderSn());
+            }
+        }
+    }
+
+    @Transactional
+    public void notify(String out_trade_no,String total_fee,String transaction_id,String time_end) {
+        // 业务处理
+        List<OrderVo> orderVoList = orderService.queryObjectByMerchOrderSn(out_trade_no);
+        List<OrderProcessRecordEntity> processRecordEntityList = new ArrayList<>();
+        Date timeEnd = DateUtils.convertStringToDate(time_end,DateUtils.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS);
+        if(orderVoList != null && orderVoList.size()>0) {
+            for(OrderVo orderInfo:orderVoList) {
+                //校验返回的订单金额是否与商户侧的订单金额一致
+                String actualPrice = String.valueOf(orderInfo.getActual_price().multiply(Constant.ONE_HUNDRED));
+                if(!total_fee.equalsIgnoreCase(actualPrice)){//不一致
+                    MallOrderExceptionRecord mallOrderExceptionRecord = new MallOrderExceptionRecord();
+                    mallOrderExceptionRecord.setUserId(Integer.parseInt(orderInfo.getUser_id()+""));
+                    mallOrderExceptionRecord.setOrderSn(orderInfo.getOrder_sn());
+                    mallOrderExceptionRecord.setExceptionStatus(Dict.exceptionStatus.item_04.getItem());
+                    mallOrderExceptionRecord.setCreateTime(new Date());
+                    mallOrderExceptionRecord.setExceptionContent("微信支付回调返回的订单金额与商户订单金额不一致");
+                    mallOrderExceptionRecordMapper.save(mallOrderExceptionRecord);//支付订单异常记录
+                }
+                if(Dict.orderStatus.item_100.getItem().equalsIgnoreCase(orderInfo.getOrder_status()+"")
+                        && Dict.payStatus.item_1.getItem().equalsIgnoreCase(orderInfo.getPay_status()+"")){
+
+                    OrderProcessRecordEntity processRecordEntity = orderProcessRecordMapper.queryObjectByOrderSn(orderInfo.getOrder_sn());
+                    if(processRecordEntity != null){
+                        OrderProcessRecordEntity entity = new OrderProcessRecordEntity();
+                        entity.setOrderSn(orderInfo.getOrder_sn());
+                        entity.setUserId(Integer.valueOf(orderInfo.getUser_id()+""));
+                        entity.setId(processRecordEntity.getId());
+                        entity.setIsPaymentSend(Dict.isSend.item_1.getItem());
+                        entity.setPaySuccTime(timeEnd);//微信下单完成时间
+                        processRecordEntityList.add(entity);
+                    }
+
+                    orderInfo.setPayTransactionId(transaction_id);
+                    orderInfo.setPay_status(Integer.parseInt(Dict.payStatus.item_2.getItem()));
+                    orderInfo.setPay_time(timeEnd);//微信下单完成时间
+                    if (orderInfo.getOrder_status() == Integer.parseInt(Dict.orderStatus.item_100.getItem())) {
+                        orderInfo.setOrder_status(Integer.parseInt(Dict.orderStatus.item_201.getItem()));
+                    }
+                    orderService.update(orderInfo);
+                    orderProcessRecordMapper.updateBatch(processRecordEntityList);//更新订单流转信息
+
+                    // 微信支付成功通知
+                    orderService.notifyPaySuccess(orderInfo);
+                }
+            }
+        }
+    }
+
+
+    @Transactional
+    public void refundNotify(WechatRefundApiResult refundApiResult) {
+        String success_time = refundApiResult.getSuccess_time();
+        String out_trade_no = refundApiResult.getOut_trade_no();//商户订单号
+        // 业务处理
+        List<OrderVo> orderVoList = orderService.queryOrderByMerchOrderSnAndRefundStatus(out_trade_no);
+        Date successTime = DateUtils.strToDate(success_time);
+        if(orderVoList != null && orderVoList.size()>0) {
+            for(OrderVo orderInfo:orderVoList) {
+                if(orderInfo.getOrder_status() == Integer.parseInt(Dict.orderStatus.item_201.getItem())
+                        || orderInfo.getOrder_status() == Integer.parseInt(Dict.orderStatus.item_401.getItem())){
+                    MallOrderRefund mallOrderRefund = mallOrderRefundMapper.queryObjectByOrderId(orderInfo.getId()+"");
+                    MallOrderRefund orderRefund = new MallOrderRefund();
+                    if(mallOrderRefund != null){
+                        orderRefund.setOutRefundNo(refundApiResult.getOut_refund_no());
+                        orderRefund.setRefundTime(successTime);//退款成功时间
+                        orderRefund.setRefundId(refundApiResult.getRefund_id());
+                        orderRefund.setRefundMoney(BigDecimal.valueOf(Long.valueOf(refundApiResult.getRefund_fee())).divide(Constant.ONE_HUNDRED));
+                        if (refundApiResult.getRefund_status().equalsIgnoreCase(WechatGlobalUtil.WXTradeState.SUCCESS.getCode())) {
+                            orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_2.getItem()));
+                            orderRefund.setWechatRefundStatusDes("退款成功");
+                        } else if (refundApiResult.getRefund_status().equalsIgnoreCase("PROCESSING")) {
+                            orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_5.getItem()));
+                            orderRefund.setWechatRefundStatusDes("退款处理中");
+                        } else if (refundApiResult.getRefund_status().equalsIgnoreCase("REFUNDCLOSE")) {
+                            orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_4.getItem()));
+                            orderRefund.setWechatRefundStatusDes("退款关闭");
+                        } else if (refundApiResult.getRefund_status().equalsIgnoreCase("CHANGE")) {
+                            orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_4.getItem()));
+                            orderRefund.setWechatRefundStatusDes("退款异常");
+                        }
+                        orderRefund.setRefundRecvAccout(refundApiResult.getRefund_recv_accout());
+                        orderRefund.setId(mallOrderRefund.getId());
+                        mallOrderRefundMapper.update(orderRefund);//更新订单退款信息
+
+                        OrderVo orderVo = new OrderVo();
+                        orderVo.setPay_status(Integer.parseInt(Dict.payStatus.item_4.getItem()));
+                        orderVo.setOrder_status(Integer.parseInt(Dict.orderStatus.item_401.getItem()));
+                        orderVo.setId(orderInfo.getId());
+                        orderService.update(orderVo);
+                    }
+                }
+            }
+        }
+    }
+
+}

+ 12 - 0
kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayDevProperties.java

@@ -0,0 +1,12 @@
+package com.kmall.common.service.pay.global;
+
+import java.io.Serializable;
+
+/**
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-09-27
+ */
+public class CommonWxGlobalPayDevProperties extends CommonWxGlobalPayProperties implements Serializable {
+    
+}

+ 12 - 0
kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayProdProperties.java

@@ -0,0 +1,12 @@
+package com.kmall.common.service.pay.global;
+
+import java.io.Serializable;
+
+/**
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-09-27
+ */
+public class CommonWxGlobalPayProdProperties extends CommonWxGlobalPayProperties implements Serializable {
+    
+}

+ 181 - 0
kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayProperties.java

@@ -0,0 +1,181 @@
+package com.kmall.common.service.pay.global;
+
+import java.io.Serializable;
+
+/**
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-09-27
+ */
+public class CommonWxGlobalPayProperties implements Serializable {
+
+    private static final long serialVersionUID = -5150960165047052585L;
+
+    private String appId;
+    private String secret;
+    private String mchId;
+    private String paySignKey;
+
+    private String tradeType;
+    private String certName;
+    private String notifyUrl;
+    private String getCode;
+
+    private String webAccessTokenhttps;
+    private String userMessage;
+    private String uniformorder;
+    private String refundUrl;
+
+    private String refundqueryUrl;
+    private String orderquery;
+    private String ratequery;
+    private String spbillCreateIp;
+    private String refundNotifyUrl;
+    private String feeType;
+
+    public String getFeeType() {
+        return feeType;
+    }
+
+    public void setFeeType(String feeType) {
+        this.feeType = feeType;
+    }
+
+    public String getRatequery() {
+        return ratequery;
+    }
+
+    public void setRatequery(String ratequery) {
+        this.ratequery = ratequery;
+    }
+
+    public String getRefundNotifyUrl() {
+        return refundNotifyUrl;
+    }
+
+    public void setRefundNotifyUrl(String refundNotifyUrl) {
+        this.refundNotifyUrl = refundNotifyUrl;
+    }
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    public String getSecret() {
+        return secret;
+    }
+
+    public void setSecret(String secret) {
+        this.secret = secret;
+    }
+
+    public String getMchId() {
+        return mchId;
+    }
+
+    public void setMchId(String mchId) {
+        this.mchId = mchId;
+    }
+
+    public String getPaySignKey() {
+        return paySignKey;
+    }
+
+    public void setPaySignKey(String paySignKey) {
+        this.paySignKey = paySignKey;
+    }
+
+    public String getTradeType() {
+        return tradeType;
+    }
+
+    public void setTradeType(String tradeType) {
+        this.tradeType = tradeType;
+    }
+
+    public String getCertName() {
+        return certName;
+    }
+
+    public void setCertName(String certName) {
+        this.certName = certName;
+    }
+
+    public String getNotifyUrl() {
+        return notifyUrl;
+    }
+
+    public void setNotifyUrl(String notifyUrl) {
+        this.notifyUrl = notifyUrl;
+    }
+
+    public String getGetCode() {
+        return getCode;
+    }
+
+    public void setGetCode(String getCode) {
+        this.getCode = getCode;
+    }
+
+    public String getWebAccessTokenhttps() {
+        return webAccessTokenhttps;
+    }
+
+    public void setWebAccessTokenhttps(String webAccessTokenhttps) {
+        this.webAccessTokenhttps = webAccessTokenhttps;
+    }
+
+    public String getUserMessage() {
+        return userMessage;
+    }
+
+    public void setUserMessage(String userMessage) {
+        this.userMessage = userMessage;
+    }
+
+    public String getUniformorder() {
+        return uniformorder;
+    }
+
+    public void setUniformorder(String uniformorder) {
+        this.uniformorder = uniformorder;
+    }
+
+    public String getRefundUrl() {
+        return refundUrl;
+    }
+
+    public void setRefundUrl(String refundUrl) {
+        this.refundUrl = refundUrl;
+    }
+
+    public String getRefundqueryUrl() {
+        return refundqueryUrl;
+    }
+
+    public void setRefundqueryUrl(String refundqueryUrl) {
+        this.refundqueryUrl = refundqueryUrl;
+    }
+
+    public String getOrderquery() {
+        return orderquery;
+    }
+
+    public void setOrderquery(String orderquery) {
+        this.orderquery = orderquery;
+    }
+
+    public String getSpbillCreateIp() {
+        return spbillCreateIp;
+    }
+
+    public void setSpbillCreateIp(String spbillCreateIp) {
+        this.spbillCreateIp = spbillCreateIp;
+    }
+
+
+}

+ 41 - 0
kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayPropertiesBuilder.java

@@ -0,0 +1,41 @@
+package com.kmall.common.service.pay.global;
+
+import com.kmall.common.service.pay.wxpay.CommonWxPayProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-09-27
+ */
+@Component
+public class CommonWxGlobalPayPropertiesBuilder {
+    private static final Logger logger = LoggerFactory.getLogger(CommonWxGlobalPayPropertiesBuilder.class);
+
+    @Autowired
+    @Qualifier("commonWxGlobalPayProperties")
+    private CommonWxGlobalPayProperties commonWxGlobalPayProperties;
+
+    private static CommonWxGlobalPayProperties wxPayProp;
+
+    /**
+     * Bean 向静态变量赋值
+     */
+    @PostConstruct
+    private void init(){
+        logger.info("CommonWxPayProperties初始化开始......");
+        wxPayProp = commonWxGlobalPayProperties;
+    }
+
+    public static CommonWxGlobalPayProperties instance(){
+        logger.info("CommonWxPayProperties实例返回");
+        return wxPayProp;
+    }
+
+}

+ 39 - 0
kmall-common/src/main/java/com/kmall/common/service/pay/global/CommonWxGlobalPayPropertiesConfiguration.java

@@ -0,0 +1,39 @@
+package com.kmall.common.service.pay.global;
+
+import com.kmall.common.service.pay.wxpay.CommonWxPayDevProperties;
+import com.kmall.common.service.pay.wxpay.CommonWxPayProdProperties;
+import com.kmall.common.service.pay.wxpay.CommonWxPayProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-09-27
+ */
+@Component
+public class CommonWxGlobalPayPropertiesConfiguration {
+    private static final String PROD = "prod";
+    private static final String DEV = "dev";
+
+    @Value("${pay.wx.global.env}")
+    private String evn = PROD;
+
+    @Autowired
+    private CommonWxGlobalPayProdProperties commonWxGlobalPayProdProperties;
+
+    @Autowired
+    private CommonWxGlobalPayDevProperties commonWxGlobalPayDevProperties;
+
+    @Bean
+    public CommonWxGlobalPayProperties commonWxGlobalPayProperties(){
+        if (evn.equalsIgnoreCase(PROD)) {
+            return commonWxGlobalPayProdProperties;
+        }else {
+            return commonWxGlobalPayDevProperties;
+        }
+    }
+
+}

+ 5 - 5
kmall-common/src/main/java/com/kmall/common/utils/wechat/WechatUtil.java

@@ -174,7 +174,7 @@ public class WechatUtil {
     /**
      * 请求微信https
      **/
-    private static String sendSSLPostToWx(String mapToXml, SSLConnectionSocketFactory sslcsf, String requestUrl) {
+    public static String sendSSLPostToWx(String mapToXml, SSLConnectionSocketFactory sslcsf, String requestUrl) {
         HttpPost httPost = new HttpPost(requestUrl);
         httPost.addHeader("Connection", "keep-alive");
         httPost.addHeader("Accept", "*/*");
@@ -474,9 +474,9 @@ public class WechatUtil {
         String reponseXml = sendMicropaySSLPostToWx(mapToXml);
         WechatMicropayApiResult result =
                 (WechatMicropayApiResult) XmlUtil.xmlStrToBean(reponseXml, WechatMicropayApiResult.class);
-        if ("SUCCESS".equals(result.getReturn_code()) && "OK".equals(result.getReturn_msg())) {
+        if (WXTradeState.SUCCESS.getCode().equals(result.getReturn_code()) && "OK".equals(result.getReturn_msg())) {
             //支付成功
-            if ("SUCCESS".equals(result.getResult_code())) {
+            if (WXTradeState.SUCCESS.getCode().equals(result.getResult_code())) {
                 result.setTrade_state(WXTradeState.SUCCESS.getCode());
             } else if ("FAIL".equals(result.getResult_code())) {
                 //支付中
@@ -527,7 +527,7 @@ public class WechatUtil {
     }
 
     /**
-     * 绑定提交付款码支付请求输入参数
+     * 绑定提交付款码支付请求参数
      *
      * @param shop_name    门店名称
      * @param orderBizType 订单业务类型
@@ -536,7 +536,7 @@ public class WechatUtil {
      * @param orderMoney   订单总金额,单位:元
      * @param ip           当前机器ip
      * @param auth_code    扫码得到支付授权码
-     * @return 提交付款码支付请求输入参数
+     * @return 提交付款码支付请求参数
      */
     private static Map<Object, Object> buildMicropayRequsetMapParam(String shop_name, String orderBizType,
                                                                     String attach, String out_trade_no,

+ 61 - 72
kmall-common/src/main/java/com/kmall/common/utils/wechat/wxglobal/WechatGlobalUtil.java

@@ -2,36 +2,26 @@ package com.kmall.common.utils.wechat.wxglobal;
 
 import com.alibaba.druid.support.logging.Log;
 import com.alibaba.druid.support.logging.LogFactory;
-import com.kmall.common.service.pay.wxpay.CommonWxPayPropertiesBuilder;
+import com.kmall.common.service.pay.global.CommonWxGlobalPayPropertiesBuilder;
 import com.kmall.common.utils.*;
 import com.kmall.common.utils.wechat.*;
 import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalQueryApiResult;
 import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalQueryRateResult;
 import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalRefundApiResult;
 import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalRefundQueryResult;
+import org.apache.commons.lang.StringUtils;
 import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
-import org.apache.http.config.RegistryBuilder;
-import org.apache.http.conn.socket.ConnectionSocketFactory;
-import org.apache.http.conn.socket.PlainConnectionSocketFactory;
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.impl.client.HttpClients;
-import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
 import org.apache.http.util.EntityUtils;
 
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.math.MathContext;
-import java.net.URLEncoder;
 import java.util.*;
 
 /**
@@ -105,6 +95,46 @@ public class WechatGlobalUtil {
         }
     }
 
+    /**
+     * 统一下单
+     * @param out_trade_no 商户订单号
+     * @param body 商品描述
+     * @param actual_price 实付金额
+     * @param openId 微信openId
+     * @return
+     */
+    public static WechatGlobalQueryApiResult unifiedOrder(String out_trade_no,String body,BigDecimal actual_price,String openId) {
+        Map<Object, Object> param = new TreeMap<>();
+        param.put("appid", CommonWxGlobalPayPropertiesBuilder.instance().getAppId());
+        param.put("mch_id", CommonWxGlobalPayPropertiesBuilder.instance().getMchId());// 商家账号
+        String randomStr = CharUtil.getRandomNum(18).toUpperCase();
+        param.put("nonce_str", randomStr);// 随机字符串
+        if(StringUtils.isNotEmpty(body)) {
+            param.put("body", body);// 商品描述
+        }else{
+            param.put("body", "商城-支付");// 商品描述
+        }
+        param.put("out_trade_no", out_trade_no);// 商户订单编号
+        //支付金额
+        param.put("total_fee", actual_price.multiply(Constant.ONE_HUNDRED).intValue());// 消费金额
+        param.put("fee_type",CommonWxGlobalPayPropertiesBuilder.instance().getFeeType());//标价币种
+        param.put("spbill_create_ip", CommonWxGlobalPayPropertiesBuilder.instance().getSpbillCreateIp());
+        param.put("notify_url", CommonWxGlobalPayPropertiesBuilder.instance().getNotifyUrl());// 回调地址
+        param.put("trade_type", CommonWxGlobalPayPropertiesBuilder.instance().getTradeType());// 交易类型APP
+        param.put("openid", openId);
+        String sign = WechatUtil.arraySign(param, CommonWxGlobalPayPropertiesBuilder.instance().getPaySignKey());
+        param.put("sign", sign);// 数字签证
+
+        String xml = MapUtils.convertMap2Xml(param);
+        logger.info("xml:" + xml);
+        logger.info("*******查询订单(WX Request:" + xml);
+        String reponseXml = WechatUtil.sendSSLPostToWx(xml, WechatConfig.getSslcsf(), CommonWxGlobalPayPropertiesBuilder.instance().getUniformorder());
+        logger.info("*******查询订单(WX Response:" + reponseXml);
+        WechatGlobalQueryApiResult result =
+                (WechatGlobalQueryApiResult) XmlUtil.xmlStrToBean(reponseXml, WechatGlobalQueryApiResult.class);
+
+        return result;
+    }
 
     /**
      * 微信境外查询订单
@@ -115,12 +145,12 @@ public class WechatGlobalUtil {
         //初始化请求微信服务器的配置信息包括appid密钥等
         //构建请求参数
         Map<Object, Object> params = new HashMap<Object, Object>();
-        params.put("appid", CommonWxPayPropertiesBuilder.instance().getAppId());//微信分配的公众账号ID(企业号corpid即为此appId)
-        params.put("mch_id", CommonWxPayPropertiesBuilder.instance().getMchId());//微信支付分配的商户号
+        params.put("appid", CommonWxGlobalPayPropertiesBuilder.instance().getAppId());//微信分配的公众账号ID(企业号corpid即为此appId)
+        params.put("mch_id", CommonWxGlobalPayPropertiesBuilder.instance().getMchId());//微信支付分配的商户号
         params.put("out_trade_no", out_trade_no);//商户传给微信的订单号
         params.put("nonce_str", CharUtil.getRandomString(16));//随机字符串,不长于32位。推荐随机数生成算法
         //签名前必须要参数全部写在前面
-        params.put("sign", WechatUtil.arraySign(params, CommonWxPayPropertiesBuilder.instance().getPaySignKey()));//签名
+        params.put("sign", WechatUtil.arraySign(params, CommonWxGlobalPayPropertiesBuilder.instance().getPaySignKey()));//签名
         String mapToXml = MapUtils.convertMap2Xml(params);
         //请求微信
         String reponseXml = sendQuerySSLPostToWx(mapToXml, WechatConfig.getSslcsf());
@@ -133,7 +163,7 @@ public class WechatGlobalUtil {
      **/
     private static String sendQuerySSLPostToWx(String mapToXml, SSLConnectionSocketFactory sslcsf) {
         logger.info("*******查询订单(WX Request:" + mapToXml);
-        String xmlStr = sendSSLPostToWx(mapToXml, sslcsf, CommonWxPayPropertiesBuilder.instance().getOrderquery());
+        String xmlStr = WechatUtil.sendSSLPostToWx(mapToXml, sslcsf, CommonWxGlobalPayPropertiesBuilder.instance().getOrderquery());
         logger.info("*******查询订单(WX Response:" + xmlStr);
         return xmlStr;
     }
@@ -147,15 +177,15 @@ public class WechatGlobalUtil {
         //初始化请求微信服务器的配置信息包括appid密钥等
         //构建请求参数
         Map<Object, Object> params = new HashMap<Object, Object>();
-        params.put("appid", CommonWxPayPropertiesBuilder.instance().getAppId());//微信分配的公众账号ID(企业号corpid即为此appId)
-        params.put("mch_id", CommonWxPayPropertiesBuilder.instance().getMchId());//微信支付分配的商户号
-        params.put("fee_type", "HKD");//外币币种
+        params.put("appid", CommonWxGlobalPayPropertiesBuilder.instance().getAppId());//微信分配的公众账号ID(企业号corpid即为此appId)
+        params.put("mch_id", CommonWxGlobalPayPropertiesBuilder.instance().getMchId());//微信支付分配的商户号
+        params.put("fee_type", CommonWxGlobalPayPropertiesBuilder.instance().getFeeType());//外币币种
         params.put("date", DateUtils.format(new Date(),DateUtils.DATE_TIME_PATTERN_YYYY_MM_DD));//格式为yyyyMMdd
         //签名前必须要参数全部写在前面
-        params.put("sign", WechatUtil.arraySign(params, CommonWxPayPropertiesBuilder.instance().getPaySignKey()));//签名
+        params.put("sign", WechatUtil.arraySign(params, CommonWxGlobalPayPropertiesBuilder.instance().getPaySignKey()));//签名
         String mapToXml = MapUtils.convertMap2Xml(params);
         //请求微信
-        String reponseXml = sendSSLPostToWx(mapToXml, WechatConfig.getSslcsf(), "https://api.mch.weixin.qq.com/pay/queryexchagerate");
+        String reponseXml = WechatUtil.sendSSLPostToWx(mapToXml, WechatConfig.getSslcsf(), CommonWxGlobalPayPropertiesBuilder.instance().getRatequery());
 
         WechatGlobalQueryRateResult result =
                 (WechatGlobalQueryRateResult) XmlUtil.xmlStrToBean(reponseXml, WechatGlobalQueryRateResult.class);
@@ -174,17 +204,17 @@ public class WechatGlobalUtil {
         BigDecimal bdRefundMoney = new BigDecimal(refundMoney, MathContext.DECIMAL32);
         //构建请求参数
         Map<Object, Object> params = new HashMap<Object, Object>();
-        params.put("appid", CommonWxPayPropertiesBuilder.instance().getAppId());//微信分配的公众账号ID(企业号corpid即为此appId)
-        params.put("mch_id", CommonWxPayPropertiesBuilder.instance().getMchId());//微信支付分配的商户号
+        params.put("appid", CommonWxGlobalPayPropertiesBuilder.instance().getAppId());//微信分配的公众账号ID(企业号corpid即为此appId)
+        params.put("mch_id", CommonWxGlobalPayPropertiesBuilder.instance().getMchId());//微信支付分配的商户号
         params.put("nonce_str", CharUtil.getRandomString(16));//随机字符串,不长于32位。推荐随机数生成算法
         params.put("out_trade_no", out_trade_no);//商户传给微信的订单号
         params.put("out_refund_no", System.currentTimeMillis() + "");//商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
         params.put("total_fee", bdOrderMoney.multiply(Constant.ONE_HUNDRED).intValue());//订单总金额,单位为分,只能为整数
         params.put("refund_fee", bdRefundMoney.multiply(Constant.ONE_HUNDRED).intValue());//退款总金额,订单总金额,单位为分,只能为整数
-        params.put("op_user_id", CommonWxPayPropertiesBuilder.instance().getMchId());//操作员帐号, 默认为商户号
-        params.put("notify_url", CommonWxPayPropertiesBuilder.instance().getRefundNotifyUrl());
+        params.put("op_user_id", CommonWxGlobalPayPropertiesBuilder.instance().getMchId());//操作员帐号, 默认为商户号
+        params.put("notify_url", CommonWxGlobalPayPropertiesBuilder.instance().getRefundNotifyUrl());
         //签名前必须要参数全部写在前面
-        params.put("sign", WechatUtil.arraySign(params, CommonWxPayPropertiesBuilder.instance().getPaySignKey()));//签名
+        params.put("sign", WechatUtil.arraySign(params, CommonWxGlobalPayPropertiesBuilder.instance().getPaySignKey()));//签名
         String mapToXml = MapUtils.convertMap2Xml(params);
 
         //请求微信
@@ -200,7 +230,7 @@ public class WechatGlobalUtil {
      **/
     public static String sendRefundSSLPostToWx(String mapToXml, SSLConnectionSocketFactory sslcsf) {
         logger.info("*******退款(WX Request:" + mapToXml);
-        String xmlStr = sendSSLPostToWx(mapToXml, sslcsf, CommonWxPayPropertiesBuilder.instance().getRefundUrl());
+        String xmlStr = WechatUtil.sendSSLPostToWx(mapToXml, sslcsf, CommonWxGlobalPayPropertiesBuilder.instance().getRefundUrl());
         logger.info("*******退款(WX Response:" + xmlStr);
         return xmlStr;
     }
@@ -213,12 +243,12 @@ public class WechatGlobalUtil {
      */
     public static WechatGlobalRefundQueryResult wxRefundquery(String out_trade_no) {
         Map<Object, Object> params = new HashMap<Object, Object>();
-        params.put("appid", CommonWxPayPropertiesBuilder.instance().getAppId());//微信分配的公众账号ID(企业号corpid即为此appId)
-        params.put("mch_id", CommonWxPayPropertiesBuilder.instance().getMchId());//微信支付分配的商户号
+        params.put("appid", CommonWxGlobalPayPropertiesBuilder.instance().getAppId());//微信分配的公众账号ID(企业号corpid即为此appId)
+        params.put("mch_id", CommonWxGlobalPayPropertiesBuilder.instance().getMchId());//微信支付分配的商户号
         params.put("nonce_str", CharUtil.getRandomString(16));//随机字符串,不长于32位。推荐随机数生成算法
         params.put("out_trade_no", out_trade_no);//商户侧传给微信的订单号
         //签名前必须要参数全部写在前面
-        params.put("sign", WechatUtil.arraySign(params, CommonWxPayPropertiesBuilder.instance().getPaySignKey()));//签名
+        params.put("sign", WechatUtil.arraySign(params, CommonWxGlobalPayPropertiesBuilder.instance().getPaySignKey()));//签名
         String mapToXml = MapUtils.convertMap2Xml(params);
         String reponseXml = sendRefundQerutySSLPostToWx(mapToXml, WechatConfig.getSslcsf());
         System.out.println(reponseXml);
@@ -229,52 +259,11 @@ public class WechatGlobalUtil {
     }
     public static String sendRefundQerutySSLPostToWx(String mapToXml, SSLConnectionSocketFactory sslcsf) {
         logger.info("*******退款查询(WX Request:" + mapToXml);
-        String xmlStr = sendSSLPostToWx(mapToXml, sslcsf, CommonWxPayPropertiesBuilder.instance().getRefundqueryUrl());
+        String xmlStr = WechatUtil.sendSSLPostToWx(mapToXml, sslcsf, CommonWxGlobalPayPropertiesBuilder.instance().getRefundqueryUrl());
         logger.info("*******退款查询(WX Response:" + xmlStr);
         return xmlStr;
     }
 
-    /**
-     * 请求微信https
-     **/
-    private static String sendSSLPostToWx(String mapToXml, SSLConnectionSocketFactory sslcsf, String requestUrl) {
-
-        HttpPost httPost = new HttpPost(requestUrl);
-        httPost.addHeader("Connection", "keep-alive");
-        httPost.addHeader("Accept", "*/*");
-        httPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
-        httPost.addHeader("Host", "api.mch.weixin.qq.com");
-        httPost.addHeader("X-Requested-With", "XMLHttpRequest");
-        httPost.addHeader("Cache-Control", "max-age=0");
-        httPost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
-        httPost.setEntity(new StringEntity(mapToXml, "UTF-8"));
-        CloseableHttpClient httpClient = null;
-        if (sslcsf != null) {
-            httpClient = HttpClients.custom().setSSLSocketFactory(sslcsf).build();
-        } else {
-            httpClient = HttpClients.createDefault();
-        }
-
-        CloseableHttpResponse response = null;
-        try {
-            response = httpClient.execute(httPost);
-            HttpEntity entity = response.getEntity();
-            String xmlStr = EntityUtils.toString(entity, "UTF-8");
-            return xmlStr;
-        } catch (Exception e) {
-            logger.error(e.getMessage(), e);
-            return null;
-        } finally {
-            try {
-                if (response != null) {
-                    response.close();
-                }
-            } catch (IOException e) {
-                logger.error(e.getMessage(), e);
-            }
-        }
-    }
-
     public static void main(String[] args) throws Exception {
         Map<Object, Object> parame = new TreeMap<Object, Object>();
         parame.put("mch_id", "");//

+ 9 - 0
kmall-common/src/main/java/com/kmall/common/utils/wechat/wxglobal/dto/WechatGlobalQueryApiResult.java

@@ -22,6 +22,7 @@ public class WechatGlobalQueryApiResult {
 	private String openId;//用户标识
 	private String is_subscribe;//是否关注公众账号
 	private String trade_type;//调用接口提交的交易类型,取值如下:JSAPI,NATIVE,APP,MICROPAY
+	private String prepay_id;//预支付编号
 	/**
 	 * SUCCESS—支付成功
 	 REFUND—转入退款
@@ -237,4 +238,12 @@ public class WechatGlobalQueryApiResult {
 	public void setRate(String rate) {
 		this.rate = rate;
 	}
+
+	public String getPrepay_id() {
+		return prepay_id;
+	}
+
+	public void setPrepay_id(String prepay_id) {
+		this.prepay_id = prepay_id;
+	}
 }

+ 1 - 0
kmall-framework/src/main/webapp/WEB-INF/web.xml

@@ -12,6 +12,7 @@
             classpath:spring/spring-express-kdn.xml,
             classpath:spring/spring-redis.xml,
             classpath:spring/spring-wx-pay.xml,
+            classpath:spring/spring-wx-global-pay.xml,
             classpath:spring/spring-pingan-pay.xml,
             classpath:spring/spring-jdbc.xml,
             classpath:spring/spring-oms-merch.xml,

+ 1 - 0
kmall-framework/src/test/resources/applicationContext-test.xml

@@ -25,6 +25,7 @@
                 <value>classpath:conf/redis.properties</value>
                 <value>classpath:conf/servlet.properties</value>
                 <value>classpath:conf/wx-mp.properties</value>
+                <value>classpath:conf/wx-global.properties</value>
                 <value>classpath:conf/pingan-pay.properties</value>
                 <value>classpath:conf/oms-merch.properties</value>
                 <value>classpath:conf/print-ticket.properties</value>

+ 283 - 107
kmall-schedule/src/main/java/com/kmall/schedule/service/QzOrderService.java

@@ -2,6 +2,9 @@ package com.kmall.schedule.service;
 
 import com.kmall.common.utils.*;
 import com.kmall.common.utils.wechat.*;
+import com.kmall.common.utils.wechat.wxglobal.WechatGlobalUtil;
+import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalQueryApiResult;
+import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalRefundQueryResult;
 import com.kmall.schedule.dao.OrderWXPayRecordMapper;
 import com.kmall.schedule.dao.QzGroupMapper;
 import com.kmall.schedule.dao.QzOrderMapper;
@@ -213,7 +216,7 @@ public class QzOrderService {
     }
 
     /**
-     * 更新退款中或小程序更新退款信息异常订单
+     * 更新退款中的,或小程序更新退款信息异常订单
      */
     @Transactional
     public void refundUpdate() {
@@ -223,79 +226,169 @@ public class QzOrderService {
         List<Map> refundOrderList = qzOrderMapper.queryRefundOrderList();
         if (null != refundOrderList && refundOrderList.size() > 0) {
             for (Map map : refundOrderList) {
-                String out_trade_no = MapUtils.getString("merch_order_sn", map);
-                String order_id = MapUtils.getString("order_id", map);
-                Integer is_onffline_order = MapUtils.getInteger("is_onffline_order", map);
-                String order_sn_wx = MapUtils.getString("order_sn_wx", map);
-
-                if (is_onffline_order == 1) {
-                    out_trade_no = order_sn_wx;
+                String pay_flag = MapUtils.getString("pay_flag", map);
+                String orderId = MapUtils.getString("order_id", map);
+                if(org.apache.commons.lang.StringUtils.isNotEmpty(pay_flag)) {
+                    if (pay_flag.equalsIgnoreCase("wxglobalpay")) {//微信国际支付
+                        wxGlobalRefundQuery(map);
+                    } else {//微信支付、平安支付、线下扫码支付
+                        wxRefundquery(map);
+                    }
+                }else{
+                    logger.info(">>>>>>>>>>>>>>>>>>>>refundUpdate 订单编号【"+orderId+"】的支付方式不能为空! ");
                 }
+            }
+        } else {
+            logger.info(">>>>>>>>>>>>>>>>>>>>refundUpdate 未查到退款数据 ");
+        }
+        logger.info(">>>>>>>>>>>>>>>>>>>>refundUpdate is end ");
+    }
 
-                WechatRefundQueryResult result = WechatUtil.wxRefundquery(out_trade_no);
-                if (result.getReturn_code().equalsIgnoreCase("SUCCESS")) {
-                    if (result.getResult_code().equalsIgnoreCase("SUCCESS")) {
-                        Map refundRaram = new HashMap();
-                        int msgCount = Integer.parseInt(result.getRefund_count());
-                        for (int i = 0; i < msgCount; i++) {
-                            WechatRefundQueryResult querySuccessResponseDto =
-                                    ReaderXmlForDOM4J.parse(result.getXmlStr(), i);
-                            if (result.getReturn_code().equalsIgnoreCase("SUCCESS")) {
-                                if (result.getResult_code().equalsIgnoreCase("SUCCESS")) {
-                                    result.setRefund_success_time(querySuccessResponseDto.getRefund_success_time());
-                                    result.setOut_refund_no(querySuccessResponseDto.getOut_refund_no());
-                                    result.setRefund_account(querySuccessResponseDto.getRefund_account());
-                                    result.setRefund_channel(querySuccessResponseDto.getRefund_channel());
-                                    result.setRefund_fee(querySuccessResponseDto.getRefund_fee());
-                                    result.setRefund_id(querySuccessResponseDto.getRefund_id());
-                                    result.setRefund_recv_accout(querySuccessResponseDto.getRefund_recv_accout());
-                                    result.setRefund_status(querySuccessResponseDto.getRefund_status());
-
-                                    Date successTime = DateUtils.strToDate(result.getRefund_success_time());
-                                    refundRaram.put("refundTime", successTime);
-                                    refundRaram.put("outRefundNo", result.getOut_refund_no());
-                                    refundRaram.put("refundId", result.getRefund_id());
-                                    refundRaram.put("refundMoney",
-                                                    BigDecimal.valueOf(Long.valueOf(result.getRefund_fee()))
-                                                              .divide(Constant.ONE_HUNDRED));
-                                    if (result.getRefund_status().equalsIgnoreCase("SUCCESS")) {
-                                        refundRaram.put("refundStatus", 2);
-                                        refundRaram.put("wechat_refund_status_des", "退款成功");
-                                    } else if (result.getRefund_status().equalsIgnoreCase("REFUNDCLOSE")) {
-                                        refundRaram.put("refundStatus", 4);
-                                        refundRaram.put("wechat_refund_status_des", "退款关闭");
-                                    } else if (result.getRefund_status().equalsIgnoreCase("PROCESSING")) {
-                                        refundRaram.put("refundStatus", 5);
-                                        refundRaram.put("wechat_refund_status_des", "退款处理中");
-                                    } else if (result.getRefund_status().equalsIgnoreCase("CHANGE")) {
-                                        refundRaram.put("refundStatus", 4);
-                                        refundRaram.put("wechat_refund_status_des", "退款异常");
-                                    }
-                                    refundRaram.put("refundRecvAccout", result.getRefund_recv_accout());
-                                    refundRaram.put("orderRefundId", result.getOut_refund_no());
-                                    qzOrderMapper.updateOrderRefund(refundRaram);//更新订单退款信息
-                                }
+    /**
+     * 微信支付、平安支付、线下扫码支付共用微信查询订单api
+     * @param map
+     */
+    private void  wxRefundquery(Map map){
+        logger.info(">>>>>>>>>>>>>>>>>>>>wxRefundquery 微信退款查询接口调用");
+        String out_trade_no = MapUtils.getString("merch_order_sn", map);
+        String order_id = MapUtils.getString("order_id", map);
+        String order_sn_wx = MapUtils.getString("order_sn_wx", map);
+        Integer is_onffline_order = MapUtils.getInteger("is_onffline_order", map);
+        if (is_onffline_order == 1) {
+            out_trade_no = order_sn_wx;
+        }
+        WechatRefundQueryResult result = WechatUtil.wxRefundquery(out_trade_no);
+        if (result.getReturn_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+            if (result.getResult_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                Map refundRaram = new HashMap();
+                int msgCount = Integer.parseInt(result.getRefund_count());
+                for (int i = 0; i < msgCount; i++) {
+                    WechatRefundQueryResult querySuccessResponseDto =
+                            ReaderXmlForDOM4J.parse(result.getXmlStr(), i);
+                    if (result.getReturn_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                        if (result.getResult_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                            result.setRefund_success_time(querySuccessResponseDto.getRefund_success_time());
+                            result.setOut_refund_no(querySuccessResponseDto.getOut_refund_no());
+                            result.setRefund_account(querySuccessResponseDto.getRefund_account());
+                            result.setRefund_channel(querySuccessResponseDto.getRefund_channel());
+                            result.setRefund_fee(querySuccessResponseDto.getRefund_fee());
+                            result.setRefund_id(querySuccessResponseDto.getRefund_id());
+                            result.setRefund_recv_accout(querySuccessResponseDto.getRefund_recv_accout());
+                            result.setRefund_status(querySuccessResponseDto.getRefund_status());
+
+                            Date successTime = DateUtils.strToDate(result.getRefund_success_time());
+                            refundRaram.put("refundTime", successTime);
+                            refundRaram.put("outRefundNo", result.getOut_refund_no());
+                            refundRaram.put("refundId", result.getRefund_id());
+                            refundRaram.put("refundMoney",
+                                    BigDecimal.valueOf(Long.valueOf(result.getRefund_fee()))
+                                            .divide(Constant.ONE_HUNDRED));
+                            if (result.getRefund_status().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                                refundRaram.put("refundStatus", 2);
+                                refundRaram.put("wechat_refund_status_des", "退款成功");
+                            } else if (result.getRefund_status().equalsIgnoreCase("REFUNDCLOSE")) {
+                                refundRaram.put("refundStatus", 4);
+                                refundRaram.put("wechat_refund_status_des", "退款关闭");
+                            } else if (result.getRefund_status().equalsIgnoreCase("CHANGE")) {
+                                refundRaram.put("refundStatus", 4);
+                                refundRaram.put("wechat_refund_status_des", "退款异常");
+                            } else if (result.getRefund_status().equalsIgnoreCase("PROCESSING")) {
+                                refundRaram.put("refundStatus", 5);
+                                refundRaram.put("wechat_refund_status_des", "退款处理中");
                             }
+                            refundRaram.put("refundRecvAccout", result.getRefund_recv_accout());
+                            refundRaram.put("orderRefundId", result.getOut_refund_no());
+                            qzOrderMapper.updateOrderRefund(refundRaram);//更新订单退款信息
                         }
+                    }
+                }
 
-                        Map orderRaram = new HashMap();
-                        orderRaram.put("payStatus", 4);
-                        orderRaram.put("orderStatus", 401);
-                        orderRaram.put("orderId", order_id);
-                        orderRaram.put("payTransactionId", result.getTransaction_id());
-                        qzOrderMapper.updateOrderInfo(orderRaram);
-                    } else {
-                        logger.info(">>>>>>>>>>>>>>>>>>>>refundUpdate 微信退款查询接口返回失败信息:code 【" + result.getErr_code() +
-                                    "】,des【" + result.getErr_code_des() + "】");
+                Map orderRaram = new HashMap();
+                orderRaram.put("payStatus", 4);
+                orderRaram.put("orderStatus", 401);
+                orderRaram.put("orderId", order_id);
+                orderRaram.put("payTransactionId", result.getTransaction_id());
+                qzOrderMapper.updateOrderInfo(orderRaram);
+            } else {
+                logger.info(">>>>>>>>>>>>>>>>>>>>wxRefundquery 微信退款查询接口返回失败信息:code 【" + result.getErr_code() +
+                        "】,des【" + result.getErr_code_des() + "】");
+            }
+        } else {
+            logger.info(">>>>>>>>>>>>>>>>>>>>wxRefundquery 微信退款查询接口调用失败: " + result.getReturn_msg());
+        }
+    }
+
+    /**
+     * 微信国际支付微信查询订单api
+     * @param map
+     */
+    private void  wxGlobalRefundQuery(Map map){
+        logger.info(">>>>>>>>>>>>>>>>>>>>wxGlobalRefundQuery 微信国际退款查询接口调用");
+        String out_trade_no = MapUtils.getString("merch_order_sn", map);
+        String order_id = MapUtils.getString("order_id", map);
+        WechatGlobalRefundQueryResult result = WechatGlobalUtil.wxRefundquery(out_trade_no);
+        if (result.getReturn_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+            if (result.getResult_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                Map refundRaram = new HashMap();
+                int msgCount = Integer.parseInt(result.getRefund_count());
+                for (int i = 0; i < msgCount; i++) {
+                    //微信部分退款时返回的多条退款信息数据解析
+                    WechatRefundQueryResult querySuccessResponseDto = ReaderXmlForDOM4J.parse(result.getXmlStr(), i);
+                    if (result.getReturn_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                        if (result.getResult_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                            //微信部分退款时返回的多条退款信息数据
+                            result.setRefund_fee(querySuccessResponseDto.getRefund_fee());
+                            result.setOut_refund_no(querySuccessResponseDto.getOut_refund_no());
+                            result.setRefund_id(querySuccessResponseDto.getRefund_id());
+                            result.setRefund_channel(querySuccessResponseDto.getRefund_channel());
+                            result.setRefund_status(querySuccessResponseDto.getRefund_status());
+                            result.setRefund_account(querySuccessResponseDto.getRefund_account());
+                            result.setRefund_recv_accout(querySuccessResponseDto.getRefund_recv_accout());
+                            result.setRefund_success_time(querySuccessResponseDto.getRefund_success_time());
+
+                            refundRaram.put("refundTime", DateUtils.strToDate(result.getRefund_success_time()));
+                            refundRaram.put("outRefundNo", result.getOut_refund_no());
+                            refundRaram.put("refundId", result.getRefund_id());
+                            refundRaram.put("refundMoney",
+                                    BigDecimal.valueOf(Long.valueOf(result.getRefund_fee()))
+                                            .divide(Constant.ONE_HUNDRED));//退款金额
+                            refundRaram.put("totalFee", result.getTotal_fee());//标价金额
+                            refundRaram.put("feeType", result.getFee_type());//标价币种
+                            refundRaram.put("cashFee", result.getCash_fee());//用户支付金额
+                            refundRaram.put("cashFeeType", result.getCash_fee_type());//用户支付金额币种
+                            refundRaram.put("rate", result.getRate());//汇率
+                            if (result.getRefund_status().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                                refundRaram.put("refundStatus", 2);
+                                refundRaram.put("wechat_refund_status_des", "退款成功");
+                            } else if (result.getRefund_status().equalsIgnoreCase("PROCESSING")) {
+                                refundRaram.put("refundStatus", 5);
+                                refundRaram.put("wechat_refund_status_des", "退款处理中");
+                            } else if (result.getRefund_status().equalsIgnoreCase("REFUNDCLOSE")) {
+                                refundRaram.put("refundStatus", 4);
+                                refundRaram.put("wechat_refund_status_des", "退款关闭");
+                            } else if (result.getRefund_status().equalsIgnoreCase("CHANGE")) {
+                                refundRaram.put("refundStatus", 4);
+                                refundRaram.put("wechat_refund_status_des", "退款异常");
+                            }
+                            refundRaram.put("refundRecvAccout", result.getRefund_recv_accout());
+                            refundRaram.put("orderRefundId", result.getOut_refund_no());
+                            qzOrderMapper.updateOrderRefund(refundRaram);//更新订单退款信息
+                        }
                     }
-                } else {
-                    logger.info(">>>>>>>>>>>>>>>>>>>>refundUpdate 微信退款查询接口调用失败: " + result.getReturn_msg());
                 }
+                Map orderRaram = new HashMap();
+                orderRaram.put("payStatus", 4);
+                orderRaram.put("orderStatus", 401);
+                orderRaram.put("orderId", order_id);
+                orderRaram.put("payTransactionId", result.getTransaction_id());
+                qzOrderMapper.updateOrderInfo(orderRaram);
+            } else {
+                logger.info(">>>>>>>>>>>>>>>>>>>>wxGlobalRefundQuery 微信国际退款查询接口返回失败信息:code 【" + result.getErr_code() +
+                        "】,des【" + result.getErr_code_des() + "】");
             }
         } else {
-            logger.info(">>>>>>>>>>>>>>>>>>>>refundUpdate 未查到退款数据 ");
+            logger.info(">>>>>>>>>>>>>>>>>>>>wxGlobalRefundQuery 微信国际退款查询接口调用失败: " + result.getReturn_msg());
         }
-        logger.info(">>>>>>>>>>>>>>>>>>>>refundUpdate is end ");
     }
 
 
@@ -310,50 +403,16 @@ public class QzOrderService {
         List<Map> orderList = qzOrderMapper.queryPayingOrderList();
         if (null != orderList && orderList.size() > 0) {
             for (Map map : orderList) {
-                String out_trade_no = MapUtils.getString("merch_order_sn", map);
+                String pay_flag = MapUtils.getString("pay_flag", map);
                 String orderId = MapUtils.getString("order_id", map);
-                String add_time = MapUtils.getString("add_time", map);
-                Integer number = MapUtils.getInteger("number", map);
-                Integer stock_num = MapUtils.getInteger("stock_num", map);
-                Long storeRelaId = MapUtils.getLong("storeRelaId", map);
-
-                Date addTime = DateUtils.strToDate(add_time);
-                Date nowDate = new Date();
-                WechatRefundApiResult result = WechatUtil.wxOrderQuery(out_trade_no);
-                if (result.getReturn_code().equalsIgnoreCase("SUCCESS")) {
-                    if (result.getResult_code().equalsIgnoreCase("SUCCESS") &&
-                        result.getTrade_state().equalsIgnoreCase("SUCCESS")) {
-                        Date successTime = DateUtils.convertStringToDate(result.getTime_end(),
-                                                                         DateUtils.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS);
-                        Map orderRaram = new HashMap();
-                        orderRaram.put("payStatus", 2);//已支付
-                        orderRaram.put("orderStatus", 201);//已支付
-                        orderRaram.put("payTransactionId", result.getTransaction_id());
-                        orderRaram.put("payTime", successTime);
-                        orderRaram.put("orderId", orderId);
-                        qzOrderMapper.updateOrderInfo(orderRaram);
-                    } else if (result.getResult_code().equalsIgnoreCase("SUCCESS") &&
-                               result.getTrade_state().equalsIgnoreCase("NOTPAY")) {//订单未支付
-                        Map orderRaram = new HashMap();
-                        if (getDateBetween(addTime, nowDate) >= 15) {//订单下单时间超过15分钟直接取消订单
-                            orderRaram.put("payStatus", 0);//支付状态未支付
-                            orderRaram.put("orderStatus", 101);//订单状态已取消
-                            Map param = new HashMap();
-                            param.put("id", storeRelaId);
-                            param.put("stock_num", stock_num + number);
-                            qzOrderMapper.updateStockNum(param);
-                        } else {
-                            orderRaram.put("payStatus", 0);//支付状态未支付
-                            orderRaram.put("orderStatus", 0);//订单状态未支付
-                        }
-                        orderRaram.put("orderId", orderId);
-                        qzOrderMapper.updateOrderInfo(orderRaram);
-                    } else {
-                        logger.info(">>>>>>>>>>>>>>>>>>>>orderQueryUpdate 微信查询接口返回失败信息:code 【" + result.getErr_code() +
-                                    "】,des【" + result.getErr_code_des() + "】");
+                if(org.apache.commons.lang.StringUtils.isNotEmpty(pay_flag)) {
+                    if (pay_flag.equalsIgnoreCase("wxglobalpay")) {//微信国际支付
+                        wxGlobalOrderQuery(map);
+                    } else {//微信支付、平安支付、线下扫码支付
+                        wxOrderQuery(map);
                     }
-                } else {
-                    logger.info(">>>>>>>>>>>>>>>>>>>>orderQueryUpdate 微信查询接口调用失败: " + result.getReturn_msg());
+                }else{
+                    logger.info(">>>>>>>>>>>>>>>>>>>>refundUpdate 订单编号【"+orderId+"】的支付方式不能为空! ");
                 }
             }
         } else {
@@ -362,6 +421,117 @@ public class QzOrderService {
         logger.info(">>>>>>>>>>>>>>>>>>>>orderQueryUpdate is end ");
     }
 
+    /**
+     * 微信查询接口
+     * @param map
+     */
+    private void wxOrderQuery(Map map){
+        logger.info(">>>>>>>>>>>>>>>>>>>>wxOrderQuery 微信查询接口调用");
+        String out_trade_no = MapUtils.getString("merch_order_sn", map);
+        String orderId = MapUtils.getString("order_id", map);
+        String add_time = MapUtils.getString("add_time", map);
+        Integer number = MapUtils.getInteger("number", map);
+        Integer stock_num = MapUtils.getInteger("stock_num", map);
+        Long storeRelaId = MapUtils.getLong("storeRelaId", map);
+        Date addTime = DateUtils.strToDate(add_time);
+        Date nowDate = new Date();
+
+        WechatRefundApiResult result = WechatUtil.wxOrderQuery(out_trade_no);
+        if (result.getReturn_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+            if (result.getResult_code().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode()) &&
+                    result.getTrade_state().equalsIgnoreCase(WechatUtil.WXTradeState.SUCCESS.getCode())) {
+                Date successTime = DateUtils.convertStringToDate(result.getTime_end(),
+                        DateUtils.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS);
+                Map orderRaram = new HashMap();
+                orderRaram.put("payStatus", 2);//已支付
+                orderRaram.put("orderStatus", 201);//已支付
+                orderRaram.put("payTransactionId", result.getTransaction_id());
+                orderRaram.put("payTime", successTime);
+                orderRaram.put("orderId", orderId);
+                qzOrderMapper.updateOrderInfo(orderRaram);
+            } else if (result.getResult_code().equalsIgnoreCase("SUCCESS") &&
+                    result.getTrade_state().equalsIgnoreCase("NOTPAY")) {//订单未支付
+                Map orderRaram = new HashMap();
+                if (getDateBetween(addTime, nowDate) >= 15) {//订单下单时间超过15分钟直接取消订单
+                    orderRaram.put("payStatus", 0);//支付状态未支付
+                    orderRaram.put("orderStatus", 101);//订单状态已取消
+                    Map param = new HashMap();
+                    param.put("id", storeRelaId);
+                    param.put("stock_num", stock_num + number);
+                    qzOrderMapper.updateStockNum(param);
+                } else {
+                    orderRaram.put("payStatus", 0);//支付状态未支付
+                    orderRaram.put("orderStatus", 0);//订单状态未支付
+                }
+                orderRaram.put("orderId", orderId);
+                qzOrderMapper.updateOrderInfo(orderRaram);
+            } else {
+                logger.info(">>>>>>>>>>>>>>>>>>>>wxOrderQuery 微信查询接口返回失败信息:code 【" + result.getErr_code() +
+                        "】,des【" + result.getErr_code_des() + "】");
+            }
+        } else {
+            logger.info(">>>>>>>>>>>>>>>>>>>>wxOrderQuery 微信查询接口调用失败: " + result.getReturn_msg());
+        }
+    }
+
+    /**
+     * 微信国际查询接口
+     * @param map
+     */
+    private void wxGlobalOrderQuery(Map map){
+        logger.info(">>>>>>>>>>>>>>>>>>>>wxGlobalOrderQuery 微信查询接口调用");
+        String out_trade_no = MapUtils.getString("merch_order_sn", map);
+        String orderId = MapUtils.getString("order_id", map);
+        String add_time = MapUtils.getString("add_time", map);
+        Integer number = MapUtils.getInteger("number", map);
+        Integer stock_num = MapUtils.getInteger("stock_num", map);
+        Long storeRelaId = MapUtils.getLong("storeRelaId", map);
+        Date addTime = DateUtils.strToDate(add_time);
+        Date nowDate = new Date();
+
+        WechatGlobalQueryApiResult result = WechatGlobalUtil.wxOrderQuery(out_trade_no);
+        if (result.getReturn_code().equalsIgnoreCase(WechatGlobalUtil.WXTradeState.SUCCESS.getCode())) {
+            if (result.getResult_code().equalsIgnoreCase(WechatGlobalUtil.WXTradeState.SUCCESS.getCode()) &&
+                    result.getTrade_state().equalsIgnoreCase(WechatGlobalUtil.WXTradeState.SUCCESS.getCode())) {
+                Date successTime = DateUtils.convertStringToDate(result.getTime_end(),
+                        DateUtils.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS);
+                Map orderRaram = new HashMap();
+                orderRaram.put("payStatus", 2);//已支付
+                orderRaram.put("orderStatus", 201);//已支付
+                orderRaram.put("payTransactionId", result.getTransaction_id());
+                orderRaram.put("payTime", successTime);
+                orderRaram.put("orderId", orderId);
+
+                orderRaram.put("totalFee", result.getTotal_fee());//标价金额
+                orderRaram.put("feeType", result.getFee_type());//标价币种
+                orderRaram.put("cashFee", result.getCash_fee());//用户支付金额
+                orderRaram.put("cashFeeType", result.getCash_fee_type());//用户支付金额币种
+                orderRaram.put("rate", result.getRate());//汇率
+                qzOrderMapper.updateOrderInfo(orderRaram);
+            } else if (result.getResult_code().equalsIgnoreCase(WechatGlobalUtil.WXTradeState.SUCCESS.getCode()) &&
+                    result.getTrade_state().equalsIgnoreCase("NOTPAY")) {//订单未支付
+                Map orderRaram = new HashMap();
+                if (getDateBetween(addTime, nowDate) >= 15) {//订单下单时间超过15分钟直接取消订单
+                    Map param = new HashMap();
+                    param.put("id", storeRelaId);
+                    param.put("stock_num", stock_num + number);
+                    qzOrderMapper.updateStockNum(param);
+                    orderRaram.put("payStatus", 0);//支付状态未支付
+                    orderRaram.put("orderStatus", 101);//订单状态已取消
+                } else {
+                    orderRaram.put("payStatus", 0);//支付状态未支付
+                    orderRaram.put("orderStatus", 0);//订单状态未支付
+                }
+                orderRaram.put("orderId", orderId);
+                qzOrderMapper.updateOrderInfo(orderRaram);
+            } else {
+                logger.info(">>>>>>>>>>>>>>>>>>>>wxGlobalOrderQuery 微信查询接口返回失败信息:code 【" + result.getErr_code() +
+                        "】,des【" + result.getErr_code_des() + "】");
+            }
+        } else {
+            logger.info(">>>>>>>>>>>>>>>>>>>>wxGlobalOrderQuery 微信查询接口调用失败: " + result.getReturn_msg());
+        }
+    }
 
     /**
      * 查询付款码支付记录的支付状态
@@ -382,7 +552,7 @@ public class QzOrderService {
                 Integer id = MapUtils.getInteger("id", map);
 
                 WechatRefundApiResult result = WechatUtil.wxOrderQuery(out_trade_no_wx);
-                if ("SUCCESS".equals(result.getReturn_code()) && "SUCCESS".equals(result.getResult_code())) {
+                if (WechatUtil.WXTradeState.SUCCESS.getCode().equals(result.getReturn_code()) && WechatUtil.WXTradeState.SUCCESS.getCode().equals(result.getResult_code())) {
                     Map recordRaram = new HashMap();
                     recordRaram.put("id", id);
                     recordRaram.put("trade_state", result.getTrade_state());
@@ -468,6 +638,9 @@ public class QzOrderService {
         logger.info(">>>>>>>>>>>>>>>>>>>>查询付款码支付记录的支付状态 结束<<<<<<<<<<<<<<<<<<<<<<<");
     }
 
+    /**
+     * 商品发货后7天自动确认收货
+     */
     @Transactional
     public void shipmentOrderAutoTakeGoods() {
         logger.info(">>>>>>>>>>>>>>>>>>>>shipmentOrderAutoTakeGoods is start ");
@@ -493,6 +666,9 @@ public class QzOrderService {
         logger.info(">>>>>>>>>>>>>>>>>>>>shipmentOrderAutoTakeGoods is end ");
     }
 
+    /**
+     * 确认收货后30天自动确认好评
+     */
     @Transactional
     public void receiptOrderAutoComment() {
         logger.info(">>>>>>>>>>>>>>>>>>>>receiptOrderAutoComment is start ");

+ 15 - 2
kmall-schedule/src/main/resources/mybatis/mapper/QzOrderMapper.xml

@@ -48,7 +48,8 @@
 
 
     <select id="queryRefundOrderList" resultType="map">
-        select a.pay_transaction_id,a.merch_order_sn,a.order_sn,a.order_status,a.pay_status,f.out_refund_no,f.refund_id,f.order_id,f.id 'orderRefundId',a.is_onffline_order,a.order_sn_wx
+        select a.pay_transaction_id,a.merch_order_sn,a.order_sn,a.order_status,a.pay_status,f.out_refund_no,f.refund_id,f.order_id,f.id 'orderRefundId',a.is_onffline_order,
+        a.order_sn_wx,a.pay_flag
         from mall_order a
         inner join mall_order_refund f on a.id = f.order_id	where (f.out_refund_no is null or f.refund_id is null
         or f.refund_time is null or f.wechat_refund_status_des is null) and a.order_status = '401' and f.refund_status
@@ -57,7 +58,7 @@
 
     <select id="queryPayingOrderList" resultType="map">
 		select a.pay_transaction_id,a.order_sn,a.order_status,a.pay_status,a.id 'order_id',a.merch_order_sn,date_format(a.add_time,'%Y-%m-%d %H:%i:%s') as add_time,
-        b.product_id,b.number,c.stock_num,c.id as storeRelaId
+        b.product_id,b.number,c.stock_num,c.id as storeRelaId,a.pay_flag
         from mall_order a
         LEFT JOIN mall_order_goods b ON a.id = b.order_id
         LEFT JOIN mall_product_store_rela c ON b.product_id = c.product_id
@@ -75,6 +76,12 @@
             <if test="orderSnWx != null">a.order_sn_wx = #{orderSnWx},</if>
             <if test="payTransactionId != null">a.pay_transaction_id = #{payTransactionId},</if>
             <if test="payTime != null">a.pay_time = #{payTime},</if>
+
+            <if test="totalFee != null">a.total_fee = #{totalFee},</if>
+            <if test="feeType != null">a.fee_type = #{feeType},</if>
+            <if test="cashFee != null">a.cash_fee = #{cashFee},</if>
+            <if test="cashFeeType != null">a.cash_fee_type = #{cashFeeType},</if>
+            <if test="rate != null">a.rate = #{rate},</if>
         </set>
         WHERE 1 = 1
         AND a.id = #{orderId}
@@ -89,6 +96,12 @@
             <if test="refundRecvAccout != null">a.refund_recv_accout = #{refundRecvAccout},</if>
             <if test="refundTime != null">a.refund_time = #{refundTime},</if>
             <if test="wechat_refund_status_des != null">a.wechat_refund_status_des = #{wechat_refund_status_des},</if>
+
+            <if test="totalFee != null">a.total_fee = #{totalFee},</if>
+            <if test="feeType != null">a.fee_type = #{feeType},</if>
+            <if test="cashFee != null">a.cash_fee = #{cashFee},</if>
+            <if test="cashFeeType != null">a.cash_fee_type = #{cashFeeType},</if>
+            <if test="rate != null">a.rate = #{rate},</if>
         </set>
         WHERE 1 = 1
         AND a.out_refund_no = #{orderRefundId}