From dd7ad1ab0ead2aa3c9f7fc35cc9b0635309c642a Mon Sep 17 00:00:00 2001
From: rentaiming <806181062@qq.com>
Date: 星期二, 21 五月 2024 18:34:55 +0800
Subject: [PATCH] 提交支付

---
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/证书使用说明.txt                    |   20 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/AppPayReqData.java               |  125 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/WXPayRequest.java                |  331 +++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/PayToTheUserReqData.java         |  176 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/SignUtils.java                        |   36 
 ruoyi-modules/ruoyi-order/pom.xml                                                                              |   33 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Configure.java                     |  202 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/UtilDate.java                         |   71 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/rootca.pem                  |   19 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayDomainSimpleImpl.java        |  101 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderAuctionBondService.java                  |    3 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayUtil.java                     |  301 ++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/PayDemoActivity.java                  |  101 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayConstants.java                |   52 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/AlipayCore.java                       |   98 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderAuctionBondController.java             |   27 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/RandomStringGenerator.java         |   28 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_cert.pem          |   26 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/DateUtil.java                                     |  954 +++++++++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/HttpsRequest_2.java                |  188 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/AlipayNotify.java                     |   27 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/Base64.java                           |  281 ++
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java                |   21 
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java                     |    5 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_key.pem             |   28 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/JsapiTicketUtil.java               |  157 +
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/dto/OrderAuctionBondDTO.java              |   15 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/WXPay.java                                |  304 ++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/rootca.pem                    |   19 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/UnifiedorderService.java          |   30 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayConfig.java                   |  103 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_key.pem           |   28 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/IServiceRequest.java              |   20 
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/GoodsSkuClient.java                  |    3 
 ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/service/impl/AuctionSalesroomGoodsServiceImpl.java |   20 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderAuctionBondServiceImpl.java          |   21 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/SinataUtil.java                                   |  345 +++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_cert.pem            |   26 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/RefundReqData.java               |  210 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayConfigImpl.java              |   89 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Util.java                          |  126 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/config/AlipayConfig.java                   |   42 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_cert.p12            |    0 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/ParamUtil.java                                    |   34 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/证书使用说明.txt                  |   20 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/RefundService.java                |   34 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/IWXPayDomain.java                  |   42 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/XMLParser.java                     |   43 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/BaseService.java                  |   49 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Log.java                           |   59 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_cert.p12          |    0 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/MD5.java                           |   59 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/HttpsRequest.java                  |  187 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/UnifiedorderReqData.java         |  285 ++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/RSA.java                              |  134 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Signature.java                     |  122 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/PayToTheUserService.java          |   30 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayPerformance.java             |  148 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/WXPayReport.java                 |  268 ++
 59 files changed, 6,320 insertions(+), 6 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/dto/OrderAuctionBondDTO.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/dto/OrderAuctionBondDTO.java
new file mode 100644
index 0000000..c81596e
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/dto/OrderAuctionBondDTO.java
@@ -0,0 +1,15 @@
+package com.ruoyi.system.api.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class OrderAuctionBondDTO {
+    @ApiModelProperty(value = "拍卖会id")
+    private Long auctionSalesroomId;
+
+    @ApiModelProperty(value = "获奖用户ID")
+    private List<Long>  userList;
+}
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java
index 87b45a2..8721568 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java
@@ -1,7 +1,14 @@
 package com.ruoyi.system.api.factory;
 
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.system.api.domain.PromotionVideo;
+import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO;
+import com.ruoyi.system.api.domain.dto.OrderDTO;
 import com.ruoyi.system.api.feignClient.OrderClient;
+import com.ruoyi.system.api.feignClient.PromotionClient;
 import org.springframework.cloud.openfeign.FallbackFactory;
+
+import java.util.List;
 
 /**
  * @author mitao
@@ -11,6 +18,18 @@
 
     @Override
     public OrderClient create(Throwable cause) {
-        return null;
+        return new OrderClient(){
+
+
+            @Override
+            public R<Boolean> saveOrderOne(OrderDTO orderDTO) {
+                return R.fail("通过视频集合查询用户失败:" + cause.getMessage());
+            }
+
+            @Override
+            public R<Boolean> getOrderAuctionBond(OrderAuctionBondDTO orderAuctionBondDTO) {
+                return R.fail("通过视频集合查询用户失败:" + cause.getMessage());
+            }
+        };
     }
 }
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/GoodsSkuClient.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/GoodsSkuClient.java
index 42e8ac9..d0011ef 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/GoodsSkuClient.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/GoodsSkuClient.java
@@ -21,4 +21,7 @@
 
     @PostMapping("/goods-sku/updateGoodsSkuOne")
     R<Boolean> updateGoodsSkuOne(@RequestBody GoodsSku goodsSku);
+
+
+
 }
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java
index 5ca18dc..f273b2d 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java
@@ -3,6 +3,7 @@
 import com.ruoyi.common.core.constant.ServiceNameConstants;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.system.api.domain.GoodsSku;
+import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO;
 import com.ruoyi.system.api.domain.dto.OrderDTO;
 import com.ruoyi.system.api.factory.OrderFallbackFactory;
 import org.springframework.cloud.openfeign.FeignClient;
@@ -15,4 +16,8 @@
     @PostMapping("/order/saveOrderOne")
     R<Boolean> saveOrderOne(@RequestBody OrderDTO orderDTO);
 
+
+    @PostMapping("/order-auction-bond/getOrderAuctionBond")
+    R<Boolean> getOrderAuctionBond(@RequestBody OrderAuctionBondDTO orderAuctionBondDTO);
+
 }
diff --git a/ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/service/impl/AuctionSalesroomGoodsServiceImpl.java b/ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/service/impl/AuctionSalesroomGoodsServiceImpl.java
index e8da7fd..b25cf07 100644
--- a/ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/service/impl/AuctionSalesroomGoodsServiceImpl.java
+++ b/ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/service/impl/AuctionSalesroomGoodsServiceImpl.java
@@ -21,8 +21,10 @@
 import com.ruoyi.common.core.enums.OrderFromEnum;
 import com.ruoyi.system.api.domain.GoodsSku;
 import com.ruoyi.system.api.domain.MemberAddress;
+import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO;
 import com.ruoyi.system.api.feignClient.GoodsSkuClient;
 import com.ruoyi.system.api.feignClient.MemberClient;
+import com.ruoyi.system.api.feignClient.OrderClient;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -55,6 +57,9 @@
 
     @Resource
     private MemberClient emberClient;
+
+    @Resource
+    private OrderClient orderClient;
 
 
     /**
@@ -184,7 +189,7 @@
                 auctionSalesroomVO.setNextAuctionSalesroomGoods(nextAuctionSalesroomGoods);
             }
             LambdaQueryWrapper<AuctionSalesroomGoods> wrapper2=Wrappers.lambdaQuery();
-            wrapper2.in(AuctionSalesroomGoods::getSortNum,list);
+            wrapper2.notIn(AuctionSalesroomGoods::getSortNum,list);
             wrapper2.eq(AuctionSalesroomGoods::getDelFlag,0);
             wrapper2.eq(AuctionSalesroomGoods::getAuctionSalesroomId,SalesroomId);
             wrapper2.orderByAsc(AuctionSalesroomGoods::getSortNum);
@@ -195,7 +200,7 @@
                 R<GoodsSku> goodsSkuOne2 = goodsSkuClient.getGoodsSkuOne(salesroomGoods.getGoodsSkuId());
                 GoodsSku goodsSku2=goodsSkuOne2.getData();
                 forepartAuctionSalesroomGoodsVO1.setGoodsSkuName(salesroomGoods.getGoodsSkuName());
-                forepartAuctionSalesroomGoodsVO1.setCoverPic(goodsSku.getCoverPic());
+                forepartAuctionSalesroomGoodsVO1.setCoverPic(goodsSku2.getCoverPic());
                 auctionSalesroomGoodsVOS.add(forepartAuctionSalesroomGoodsVO1);
             }
 
@@ -309,6 +314,7 @@
 
         AuctionSalesroomGoods auctionSalesroomGoods=iAuctionSalesroomGoodsService.getById(auctionSalesroomGoodsDTO.getGoodsSkuId());
         List<AuctionBidRecord> auctionBidRecordList=new ArrayList<>();
+        List<Long> list=new ArrayList<>();
         if (auctionSalesroomGoods.getStatus().getCode()==1) {
             LambdaQueryWrapper<AuctionBidRecord> wrapper = Wrappers.lambdaQuery();
             wrapper.eq(AuctionBidRecord::getGoodsSkuId, auctionSalesroomGoodsDTO.getGoodsSkuId());
@@ -316,21 +322,29 @@
             wrapper.orderByDesc(AuctionBidRecord::getLastBidAmount);
             auctionBidRecordList = iAuctionBidRecordService.list(wrapper);
             //判断
-
             if (auctionBidRecordList.size() >= auctionSalesroomGoods.getItemQuantity()) {
                 for (int i = 0; i <= auctionSalesroomGoods.getItemQuantity(); i++) {
                     AuctionBidRecord auctionBidRecord = auctionBidRecordList.get(i);
                     auctionBidRecord.setStatus(BidStatusEnum.SUCCESSFUL);
                     AddOrder(auctionBidRecord.getGoodsSkuId(),auctionBidRecord.getMemberId(),auctionBidRecord.getLastBidAmount(),auctionSalesroom.getBound());
+
+                    list.add(auctionBidRecord.getMemberId());
                 }
             } else {
                 for (int i = 0; i <= auctionBidRecordList.size(); i++) {
                     AuctionBidRecord auctionBidRecord = auctionBidRecordList.get(i);
                     auctionBidRecord.setStatus(BidStatusEnum.SUCCESSFUL);
+                    AddOrder(auctionBidRecord.getGoodsSkuId(),auctionBidRecord.getMemberId(),auctionBidRecord.getLastBidAmount(),auctionSalesroom.getBound());
+                    list.add(auctionBidRecord.getMemberId());
                 }
             }
         }
 
+        OrderAuctionBondDTO orderAuctionBondDTO=new OrderAuctionBondDTO();
+        orderAuctionBondDTO.setAuctionSalesroomId(auctionSalesroom.getId());
+        orderAuctionBondDTO.setUserList(list);
+        orderClient.getOrderAuctionBond(orderAuctionBondDTO);
+
     }
 
 
diff --git a/ruoyi-modules/ruoyi-order/pom.xml b/ruoyi-modules/ruoyi-order/pom.xml
index 21c4fd8..c6527bc 100644
--- a/ruoyi-modules/ruoyi-order/pom.xml
+++ b/ruoyi-modules/ruoyi-order/pom.xml
@@ -101,6 +101,33 @@
       <version>1.2.47</version>
     </dependency>
 
+
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>2.2.4</version>
+      <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>com.thoughtworks.xstream</groupId>
+      <artifactId>xstream</artifactId>
+      <version>1.4.8</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.alibaba</groupId>
+      <artifactId>fastjson</artifactId>
+      <version>1.2.4</version>
+    </dependency>
+
+    <dependency>
+      <groupId>net.sf.json-lib</groupId>
+      <artifactId>json-lib</artifactId>
+      <version>2.4</version>
+      <classifier>jdk15</classifier>
+    </dependency>
+
     <dependency>
       <groupId>cn.afterturn</groupId>
       <artifactId>easypoi-spring-boot-starter</artifactId>
@@ -112,6 +139,12 @@
         </exclusion>
       </exclusions>
     </dependency>
+      <dependency>
+          <groupId>com.alibaba</groupId>
+          <artifactId>fastjson</artifactId>
+          <version>1.2.47</version>
+          <scope>compile</scope>
+      </dependency>
 
   </dependencies>
 
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderAuctionBondController.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderAuctionBondController.java
index 01f67b6..76aa20c 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderAuctionBondController.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderAuctionBondController.java
@@ -1,9 +1,16 @@
 package com.ruoyi.order.controller;
 
 
-import org.springframework.web.bind.annotation.RequestMapping;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.order.domain.pojo.OrderAuctionBond;
+import com.ruoyi.order.service.IOrderAuctionBondService;
+import com.ruoyi.system.api.domain.GoodsSku;
+import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.poi.ss.formula.functions.T;
+import org.springframework.web.bind.annotation.*;
 
-import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
 
 /**
  * <p>
@@ -17,4 +24,20 @@
 @RequestMapping("/order-auction-bond")
 public class OrderAuctionBondController {
 
+    @Resource
+    private IOrderAuctionBondService  iOrderAuctionBondService;
+
+    /**
+     * 获取当前商品信息
+     *这些还要掉退款,但是还没有支付或者微信
+     *
+     */
+    @PostMapping("/getOrderAuctionBond")
+    @ResponseBody
+    public R<T> getOrderAuctionBond(@RequestBody OrderAuctionBondDTO orderAuctionBondDTO) {
+        iOrderAuctionBondService.getOrderAuctionBond(orderAuctionBondDTO);
+        return R.ok();
+
+    }
+
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderAuctionBondService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderAuctionBondService.java
index 6e7e02e..e8aaf5d 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderAuctionBondService.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderAuctionBondService.java
@@ -2,6 +2,8 @@
 
 import com.ruoyi.order.domain.pojo.OrderAuctionBond;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO;
+import org.springframework.web.bind.annotation.RequestBody;
 
 /**
  * <p>
@@ -12,5 +14,6 @@
  * @since 2024-05-16
  */
 public interface IOrderAuctionBondService extends IService<OrderAuctionBond> {
+   void getOrderAuctionBond( OrderAuctionBondDTO orderAuctionBondDTO);
 
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderAuctionBondServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderAuctionBondServiceImpl.java
index 8a662f8..7f5ccd6 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderAuctionBondServiceImpl.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderAuctionBondServiceImpl.java
@@ -1,10 +1,17 @@
 package com.ruoyi.order.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.order.domain.pojo.OrderAuctionBond;
 import com.ruoyi.order.mapper.OrderAuctionBondMapper;
 import com.ruoyi.order.service.IOrderAuctionBondService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO;
 import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.awt.*;
+import java.util.List;
 
 /**
  * <p>
@@ -17,4 +24,18 @@
 @Service
 public class OrderAuctionBondServiceImpl extends ServiceImpl<OrderAuctionBondMapper, OrderAuctionBond> implements IOrderAuctionBondService {
 
+    @Resource
+    private IOrderAuctionBondService iOrderAuctionBondService;
+    @Override
+    public void getOrderAuctionBond( OrderAuctionBondDTO orderAuctionBondDTO) {
+
+        LambdaQueryWrapper<OrderAuctionBond> wrapper= Wrappers.lambdaQuery();
+        wrapper.notIn(OrderAuctionBond::getMemberId,orderAuctionBondDTO.getUserList());
+        wrapper.eq(OrderAuctionBond::getDelFlag,0);
+        wrapper.eq(OrderAuctionBond::getAuctionSalesroomId,orderAuctionBondDTO.getAuctionSalesroomId());
+        List<OrderAuctionBond> orderAuctionBondList=iOrderAuctionBondService.list(wrapper);
+        for (OrderAuctionBond orderAuctionBond:orderAuctionBondList){
+
+        }
+    }
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/DateUtil.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/DateUtil.java
new file mode 100644
index 0000000..5d3fff8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/DateUtil.java
@@ -0,0 +1,954 @@
+package com.ruoyi.order.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * <h3>处理时间的工具类</h3>
+ */
+public class DateUtil {
+
+	private static TimeZone tz = TimeZone.getTimeZone("GMT+8");
+
+	//private static TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+
+
+	/**
+	 * 得到系统日期
+	 * @return
+	 */
+	public static Date getDate() { 
+		TimeZone.setDefault(tz);
+		return new Date();
+	}
+	
+	/**
+     * 获取当然凌晨的时间
+     * @return Date
+     */
+	public static Date getZero() {
+		 Calendar calendar = Calendar.getInstance();
+         calendar.setTime(new Date());
+         calendar.set(Calendar.HOUR_OF_DAY, 0);
+         calendar.set(Calendar.MINUTE, 0);
+         calendar.set(Calendar.SECOND, 0);
+         return calendar.getTime();
+	}
+
+	/**
+     * 判断日期是否在from,to之内
+     *"yyyy-MM-dd" 格式
+     * @param time 指定日期 
+     * @param from 开始日期
+     * @param to   结束日期
+     * @return true 在之间  false 不在之间
+     */
+    public static boolean belongCalendar(Date time, Date from, Date to) {
+        Calendar date = Calendar.getInstance();
+        date.setTime(time);
+
+        Calendar after = Calendar.getInstance();
+        after.setTime(from);
+
+        Calendar before = Calendar.getInstance();
+        before.setTime(to);
+
+        if ( (date.after(after) && date.before(before)) || (time.compareTo(from)==0 || time.compareTo(to)==0) ) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+	/**
+	 * 两个时间之差
+	 * @param startTime 
+	 * @param endTime 
+	 * @param format
+	 * @return
+	 * @throws ParseException 
+	 */
+	public static String dateDiff(String startTime, String endTime,
+			String format) throws ParseException {
+		// 按照传入的格式生成一个simpledateformate对象
+		SimpleDateFormat sd = new SimpleDateFormat(format);
+		long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
+		long nh = 1000 * 60 * 60;// 一小时的毫秒数
+		long nm = 1000 * 60;// 一分钟的毫秒数
+		long ns = 1000;// 一秒钟的毫秒数
+		long diff;
+		long day = 0;
+		long hour = 0;
+		long min = 0;
+		long sec = 0;
+		//long time=0;
+		String strTime="";
+		// 获得两个时间的毫秒时间差异
+		diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
+		day = diff / nd;// 计算差多少天
+		hour = diff % nd / nh + day * 24;// 计算差多少小时
+		min = diff % nd % nh / nm + day * 24 * 60;// 计算差多少分钟
+		sec = diff % nd % nh % nm / ns;// 计算差多少秒
+		// 输出结果
+		/*System.out.println("时间相差:" + day + "天" + (hour - day * 24) + "小时"
+				+ (min - day * 24 * 60) + "分钟" + sec + "秒。");
+		System.out.println("hour=" + hour + ",min=" + min);*/
+		if(day==1){
+			strTime="昨天";
+		}
+		else if(day>1){
+			//strTime=day+"天前";
+			strTime=startTime.substring(0, 10);
+		}
+		else if(hour>=1 && hour<24){
+			strTime=hour+"小时前";
+		}
+		else{
+			if(min==0){strTime=sec+"秒钟前";}else{
+				strTime=min+"分钟前";
+			}
+
+		}
+		// if (str.equalsIgnoreCase("h")) {
+		// return hour;
+		// } else {
+		// return min;
+		// }
+
+		// if (str.equalsIgnoreCase("h")) {
+		// return hour;
+		// } else {
+		// return min;
+		// }
+		return strTime;
+	} 
+
+	/**
+	 * 得到系统Calendar日期
+	 * @return
+	 */
+	public static Calendar getCalendar() {
+		TimeZone.setDefault(tz);
+		Calendar cal = Calendar.getInstance();
+		return cal;
+	}
+
+	/**
+	 * 获取当前时间
+	 * @return
+	 */
+	public static long getMillisecond() {
+		long millisecond = 0;
+		TimeZone.setDefault(tz);
+		Calendar cal = Calendar.getInstance();
+		millisecond = cal.getTimeInMillis();
+		return millisecond;
+	}
+
+	/**
+	 * 获取本月1号的时间戳
+	 * @return
+	 */
+	public static long getMillisecond_MONTH() {
+		long millisecond = 0;
+		TimeZone.setDefault(tz);
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.DAY_OF_MONTH, 1);
+		millisecond = cal.getTimeInMillis();
+		return millisecond;
+	}
+
+	/**
+	 * 获取上个月1号的时间戳
+	 * @return
+	 */
+	public static long getMillisecond_FRONTMONTH() {
+		long millisecond = 0;
+		Calendar cal = getCalendar();
+		cal.set(Calendar.DAY_OF_MONTH, 1);
+		cal.set(Calendar.MONTH, Calendar.MONTH-2);
+		millisecond = cal.getTimeInMillis();
+		return millisecond;
+	}
+
+	/**
+	 * 获取当前毫秒数
+	 * @return long
+	 */
+	public static long getCurMilli() { 
+		long millisecond = 0;
+		Calendar cal = Calendar.getInstance();
+		millisecond = cal.getTimeInMillis();
+		return millisecond;
+	}
+
+
+	/**
+	 * 日期转毫秒
+	 * @param date
+	 * @return
+	 */
+	public static long getMillisecond(Date date) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		String newDate = "";
+		if (!"".equals(date)) {
+			newDate = sdf.format(date);
+		} else {
+			newDate = sdf.format(DateUtil.getDate());
+		}
+		long millisecond = 0;
+		try {
+			millisecond = sdf.parse(newDate).getTime();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return millisecond;
+	}
+
+
+	/**
+	 * 日期转毫秒(加24小时,yyyy-MM-dd HH:mm:ss)
+	 * @param date
+	 * @return
+	 */
+	public static long getMillisecond_24h(Date date) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		String newDate = "";
+		if (!"".equals(date)) {
+			newDate = sdf.format(date);
+		} else {
+			newDate = sdf.format(DateUtil.getDate());
+		}
+		long millisecond = 24*3600*1000;
+		try {
+			millisecond += sdf.parse(newDate).getTime();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return millisecond;
+	}
+
+	/**
+	 * 日期转毫秒(加N年)
+	 * @param date
+	 * @return
+	 */
+	public static long getMillisecond_year(String date, Integer year){
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		String newDate = "";
+		if ("".equals(date)) {
+			newDate = sdf.format(DateUtil.getDate());
+		} else {
+			newDate = getDateTime(Long.parseLong(date));
+		}
+		Date dt = null;
+		try {
+			dt = sdf.parse(newDate);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		Calendar rightNow = Calendar.getInstance();
+		rightNow.setTime(dt);
+		rightNow.add(Calendar.YEAR, year);
+		Date dt1 = rightNow.getTime();
+		return dt1.getTime();
+	}
+
+	/**
+	 * 日期转毫秒(加N天)
+	 * @param date 毫秒字符串
+	 * @return
+	 */
+	public static long getMillisecond_day(String date, Integer day){
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		String newDate = "";
+		if ("".equals(date)) {
+			newDate = sdf.format(DateUtil.getDate());
+		} else {
+			newDate = getDateTime(Long.parseLong(date));
+		}
+		Date dt = null;
+		try {
+			dt = sdf.parse(newDate);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		Calendar rightNow = Calendar.getInstance();
+		rightNow.setTime(dt);
+		rightNow.add(Calendar.DATE, day);
+		Date dt1 = rightNow.getTime();
+		return dt1.getTime();
+	}
+
+	/**
+	 * 日期转毫秒(加N月)
+	 * @param date
+	 * @return
+	 */
+	public static long getMillisecond_month(String date, Integer day){
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		String newDate = "";
+		if ("".equals(date)) {
+			newDate = sdf.format(DateUtil.getDate());
+		} else {
+			newDate = getDateTime(Long.parseLong(date));
+		}
+		Date dt = null;
+		try {
+			dt = sdf.parse(newDate);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		Calendar rightNow = Calendar.getInstance();
+		rightNow.setTime(dt);
+		rightNow.add(Calendar.MONTH, day);
+		Date dt1 = rightNow.getTime();
+		return dt1.getTime();
+	}
+
+	/**
+	 * 字符串日期转毫秒
+	 * @param date
+	 * @return
+	 */
+	public static long getMillisecond_str(String date) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		if ("".equals(date)) {
+			date = sdf.format(DateUtil.getDate());
+		} 
+		long millisecond = 0;
+		try {
+			millisecond = sdf.parse(date).getTime();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return millisecond;
+	}
+
+	/**
+	 * 字符串日期转毫秒
+	 * @param date
+	 * @return
+	 */
+	public static long getMillisecond_strYmd(String date) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		if ("".equals(date)) {
+			date = sdf.format(DateUtil.getDate());
+		} 
+		long millisecond = 0;
+		try {
+			millisecond = sdf.parse(date).getTime();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return millisecond;
+	}
+
+	/**
+	 * 字符串日期转Date
+	 * @param string
+	 * @return date
+	 * @throws ParseException 
+	 */
+	public static Date getStrToDate(String dateString) throws ParseException { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  
+		Date date = sdf.parse(dateString);
+		return date;
+	}
+
+	/**
+	 * 字符串日期转Date
+	 * @param date
+	 * @return
+	 */
+	public static Date getDate_str(String dateStr) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		sdf.setTimeZone(tz);
+		if ("".equals(dateStr)) {
+			dateStr = sdf.format(DateUtil.getDate());
+		} 
+		Date date = null;
+		try {
+			date = sdf.parse(dateStr);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return date;
+	}
+
+	/**
+	 * 字符串日期转Date yyyy-MM-dd HH:mm
+	 * @param date
+	 * @return
+	 */
+	public static Date getDate_str2(String dateStr) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+		sdf.setTimeZone(tz);
+		if ("".equals(dateStr)) {
+			dateStr = sdf.format(DateUtil.getDate());
+		} 
+		Date date = null;
+		try {
+			date = sdf.parse(dateStr);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return date;
+	}
+	
+	/**
+	 * 字符串日期转Date yyyy-MM-dd HH:mm:ss
+	 * @param date
+	 * @return
+	 */
+	public static Date getDate_str3(String dateStr) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		sdf.setTimeZone(tz);
+		if ("".equals(dateStr)) {
+			dateStr = sdf.format(DateUtil.getDate());
+		} 
+		Date date = null;
+		try {
+			date = sdf.parse(dateStr);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return date;
+	}
+
+	/**
+	 * 字符串日期转Date
+	 * @param date
+	 * @return
+	 */
+	public static Date getDate_strYMd(Long dateStr) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		if (dateStr == null) {
+			dateStr = DateUtil.getCurMilli();
+		} 
+		Date date = null;
+		try {
+			date = sdf.parse(sdf.format(new Date(dateStr)));
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return date;
+	}
+
+	/**
+	 * 毫秒转Date
+	 * @param date
+	 * @return
+	 */
+	public static Date getDate_strYMdHms(Long dateStr) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		if (dateStr == null) {
+			dateStr = DateUtil.getCurMilli();
+		} 
+		Date date = null;
+		try {
+			date = sdf.parse(sdf.format(new Date(dateStr)));
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return date;
+	}
+
+	/**
+	 * 字符串日期转Date
+	 * @param date
+	 * @return
+	 */
+	public static Date getDate_strYMdHm(Long dateStr) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+		if (dateStr == null) {
+			dateStr = DateUtil.getCurMilli();
+		} 
+		Date date = null;
+		try {
+			date = sdf.parse(sdf.format(new Date(dateStr)));
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return date;
+	}
+
+	/**
+	 * 字符串日期转毫秒
+	 * @param date
+	 * @return
+	 */
+	public static long getMillisecond_strDmy(String date) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
+		if ("".equals(date)) {
+			date = sdf.format(DateUtil.getDate());
+		} 
+		long millisecond = 0;
+		try {
+			millisecond = sdf.parse(date).getTime();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return millisecond;
+	}
+
+	/**
+	 * 字符串日期转毫秒转毫秒(加24小时)
+	 * @param date
+	 * @return
+	 */
+	public static long getMillisecond_str_24h(String date) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		if ("".equals(date)) {
+			date = sdf.format(DateUtil.getDate());
+		} 
+		long millisecond = 24*3600*1000;
+		try {
+			millisecond += sdf.parse(date).getTime();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return millisecond;
+	}
+
+	/**
+	 * 字符串日期转毫秒转毫秒(加24小时)
+	 * @param date
+	 * @return
+	 */
+	public static long getMillisecond_strYmd_24h(String date) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		if ("".equals(date)) {
+			date = sdf.format(DateUtil.getDate());
+		} 
+		long millisecond = 24*3600*1000;
+		try {
+			millisecond += sdf.parse(date).getTime();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return millisecond;
+	}
+
+	/**
+	 * 毫秒转日期
+	 * @param millisecond
+	 * @return
+	 */
+	public static String getDate(long millisecond) { 
+		if (millisecond == 0) {
+			millisecond = getCurMilli();
+		}
+		SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
+		Calendar calendar = getCalendar();
+		calendar.setTimeInMillis(millisecond);
+		return dateformat.format(calendar.getTime());
+	}
+	/**
+	 * 转换为指定格式的时间
+	 * @return Date
+	 */
+	public static Date getDate(String date, String pattern)  {
+		SimpleDateFormat format = new SimpleDateFormat(pattern);
+		Date d = null;
+		try {
+			d = format.parse(date);
+		} catch (ParseException ex) {
+			return null;
+		}
+		return d;
+	}
+
+	/**
+	 * 毫秒转日期
+	 * @param millisecond
+	 * @return
+	 */
+	public static String getDate_HH(long millisecond) { 
+		if (millisecond == 0) {
+			millisecond = getCurMilli();
+		}
+		SimpleDateFormat dateformat = new SimpleDateFormat("HH");
+		Calendar calendar = getCalendar();
+		calendar.setTimeInMillis(millisecond);
+		return dateformat.format(calendar.getTime());
+	}
+
+	/**
+	 * 毫秒转日期时间
+	 * @param millisecond
+	 * @return
+	 */
+	public static String getDateTime(long millisecond) { 
+		if (millisecond == 0) {
+			millisecond = getCurMilli();
+		}
+		SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		Calendar calendar = getCalendar();
+		calendar.setTimeInMillis(millisecond);
+		return dateformat.format(calendar.getTime());
+	}
+
+	/**
+	 * 毫秒转年月日
+	 * @param millisecond
+	 * @return
+	 */
+	public static String getDateYMD(long millisecond) { 
+		if (millisecond == 0) {
+			millisecond = getCurMilli();
+		}
+		SimpleDateFormat dateformat = new SimpleDateFormat("yyyy年MM月dd日");
+		Calendar calendar = getCalendar();
+		calendar.setTimeInMillis(millisecond);
+		return dateformat.format(calendar.getTime());
+	}
+
+	/**
+	 * 两日期相差毫秒
+	 * @param startDate
+	 * @param endDate
+	 * @return
+	 */
+	public static long getMinusMillisecond(Date startDate, Date endDate) { 
+		long startMillisecond = getMillisecond(startDate);
+		long endMillisecond = getMillisecond(endDate);
+		long minusMillisecond = endMillisecond-startMillisecond;
+		if (minusMillisecond < 0) {
+			minusMillisecond = 0;
+		}
+		return minusMillisecond;
+	}
+
+	/**
+	 * 两日期相差天数
+	 * @param startDate
+	 * @param endDate
+	 * @return
+	 */
+	public static long getMinusDay(Date startDate, Date endDate) { 
+		long startMillisecond = getMillisecond(startDate);
+		long endMillisecond = getMillisecond(endDate);
+		long minusMillisecond = endMillisecond-startMillisecond;
+		long day = 0;
+		if (minusMillisecond < 0) {
+			day = 0;
+		} else {
+			day = minusMillisecond/(24*3600*1000); 
+		}
+		return day;
+	}
+
+	/**
+	 * 前N天毫秒
+	 * @param day
+	 * @return
+	 */
+	public static long getRetreatDay_millisecond(int day) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		long nowMillisecond = 0; 
+		try {
+			nowMillisecond = sdf.parse(sdf.format(DateUtil.getDate())).getTime();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		nowMillisecond += 24*3600*1000;
+		long retreatMillisecond = 24*3600*1000*day;
+		return nowMillisecond - retreatMillisecond;
+	}
+	
+	
+	/**
+	 * 前N天时间
+	 * @param day
+	 * @return
+	 */
+	public static String getRetreatDay_millisecond1(int day) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		long nowMillisecond = 0; 
+		try {
+			nowMillisecond = sdf.parse(sdf.format(DateUtil.getDate())).getTime();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		nowMillisecond += 24*3600*1000;
+		long retreatMillisecond = 24*3600*1000*day;
+		long s=nowMillisecond - retreatMillisecond;
+		Date date = new Date(s);
+		String res = sdf.format(date);
+		return res;
+	}
+
+	/**
+	 * 日期转秒
+	 * @param date
+	 * @return
+	 */
+	public static long getDecond(Date date) { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		String newDate = "";
+		if (!"".equals(date)) {
+			newDate = sdf.format(date);
+		} else {
+			newDate = sdf.format(DateUtil.getDate());
+		}
+		long second = 0; 
+		try {
+			second = sdf.parse(newDate).getTime()/1000;
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} 
+		return second;
+	}
+
+	/**
+	 * 日期转String
+	 * @param date
+	 * @return
+	 * @throws ParseException 
+	 */
+	public static String getDateToString(Date date) throws ParseException { 
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		String newDate = sdf.format(date);	
+		long millisecond = sdf.parse(newDate).getTime(); 
+		Calendar calendar = getCalendar();
+		calendar.setTimeInMillis(millisecond);
+		return sdf.format(calendar.getTime());
+	}
+
+	/**
+	 * 毫秒转星期XX
+	 * @param millisecond
+	 * @return
+	 */
+	public static int getDate_week(Long millisecond) { 
+		if (millisecond == null) {
+			millisecond = getCurMilli();
+		}
+		Calendar cal = getCalendar();
+		cal.setTimeInMillis(millisecond);
+		return cal.get(Calendar.DAY_OF_WEEK)-1;
+
+	}
+
+	/**
+	 * 获取当前系统时间已yyyy-MM-dd HH:mm:ss格式化的字符串
+	 */
+	public static String nowStr(){
+
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
+		return dateFormat.format(getDate());
+	}
+
+	/**
+	 * 
+	 * 获取之前几天日期
+	 * @param pattern yyyy-MM-dd(默认)
+	 * @param few 之前几天
+	 */
+	public static String beforeFewDayStr(String pattern, Integer few) {
+
+		if(pattern == null || "".equals(pattern)){
+			pattern = "yyyy-MM-dd";
+		}
+		Calendar c = getCalendar();
+		c.add(Calendar.DATE,-few);
+		return new SimpleDateFormat(pattern).format(c.getTime());
+	}
+
+	/**
+	 * 获取今天日期
+	 * @param pattern yyyy-MM-dd(默认)
+	 */
+	public static String todayStr(String pattern) {
+
+		if(pattern == null || "".equals(pattern)){
+			pattern = "yyyy-MM-dd";
+		}
+		return new SimpleDateFormat(pattern).format(getDate());
+	}
+
+	/**
+	 * 获取当前系统时间戳字符串
+	 */
+	public static String nowDateLongStr(){
+
+		return getDate().getTime()+"";
+	}
+
+	/**
+	 * 获取当前系统时间
+	 * @return
+	 */
+	public static Date now(){
+
+		return getDate();
+	}
+
+
+	public static void main(String[] args) throws ParseException {
+        //打印测试日期包含
+        Date time1  = getDate_str("2017-3-11");
+        Date time2 = getDate_str("2017-3-15");
+        Date time3 = getDate_str("2017-3-17");
+        Date time4 = getDate_str("2017-3-12");
+        Date time5 = getDate_str("2017-3-16");
+        Date from = getDate_str("2017-3-12");
+        Date to= getDate_str("2017-3-16");
+        System.out.println(belongCalendar(time1,from,to));
+        System.out.println(belongCalendar(time2,from,to));
+        System.out.println(belongCalendar(time3,from,to));
+        System.out.println(belongCalendar(time4,from,to));
+        System.out.println(belongCalendar(time5,from,to));
+        System.out.println(nowStr());
+        
+
+	}
+
+	/**
+	 *  把日期往后增加一天. 正数往后推,负数往前移动
+	 * @param day
+	 * @return
+	 */
+	public static String getString(int day) {
+		Date date=new Date();//取时间
+		Calendar calendar = new GregorianCalendar();
+		calendar.setTime(date);
+		calendar.add(calendar.DATE,day);//把日期往后增加一天.整数往后推,负数往前移动
+		date=calendar.getTime(); //这个时间就是日期往后推一天的结果 
+		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+		String dateString = formatter.format(date);
+		return dateString;
+	}
+
+
+
+	
+    /** 
+    * 根据当前日期获得所在周的日期区间(周一和周日日期) 
+    *  
+    * @return 
+    * @author zhaoxuepu 
+    * @throws ParseException 
+    */  
+    public static String getTimeInterval(Date date) {
+    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+         Calendar cal = Calendar.getInstance();  
+         cal.setTime(date);  
+         // 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了  
+         int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天  
+         if (1 == dayWeek) {  
+            cal.add(Calendar.DAY_OF_MONTH, -1);  
+         }  
+         // System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期  
+         // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一  
+         cal.setFirstDayOfWeek(Calendar.MONDAY);  
+         // 获得当前日期是一个星期的第几天  
+         int day = cal.get(Calendar.DAY_OF_WEEK);  
+         // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值  
+         cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);  
+         String imptimeBegin = sdf.format(cal.getTime());  
+         // System.out.println("所在周星期一的日期:" + imptimeBegin);  
+         cal.add(Calendar.DATE, 6);  
+         String imptimeEnd = sdf.format(cal.getTime());  
+         // System.out.println("所在周星期日的日期:" + imptimeEnd);  
+         return imptimeBegin + "," + imptimeEnd;  
+    }  
+      
+      
+    /** 
+    * 根据当前日期获得上周的日期区间(上周周一和周日日期) 
+    *  
+    * @return 
+    * @author zhaoxuepu 
+    */  
+    public static String getLastTimeInterval() {  
+    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+         Calendar calendar1 = Calendar.getInstance();  
+         Calendar calendar2 = Calendar.getInstance();  
+         int dayOfWeek = calendar1.get(Calendar.DAY_OF_WEEK) - 1;  
+         int offset1 = 1 - dayOfWeek;  
+         int offset2 = 7 - dayOfWeek;  
+         calendar1.add(Calendar.DATE, offset1 - 7);  
+         calendar2.add(Calendar.DATE, offset2 - 7);  
+         // System.out.println(sdf.format(calendar1.getTime()));// last Monday  
+         String lastBeginDate = sdf.format(calendar1.getTime());  
+         // System.out.println(sdf.format(calendar2.getTime()));// last Sunday  
+         String lastEndDate = sdf.format(calendar2.getTime());  
+         return lastBeginDate + "," + lastEndDate;  
+    }
+
+	
+    
+    
+    
+    
+    public static String DateYUE(){
+    SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
+    Calendar c = Calendar.getInstance();    
+           c.add(Calendar.MONTH, 0);
+           c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 
+           String first = format.format(c.getTime());
+           
+           //获取当前月最后一天
+           Calendar ca = Calendar.getInstance();    
+           ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));  
+           String last = format.format(ca.getTime());
+		   return first+","+last;
+    }
+    
+    
+    
+    
+    
+   
+  public static String  getBeforeFirstMonthdate(){
+    SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
+    Calendar calendar=Calendar.getInstance();
+    Calendar calendar1=Calendar.getInstance();
+    calendar.add(Calendar.MONTH, -1);
+    calendar.set(Calendar.DAY_OF_MONTH, 1);
+    
+    int month=calendar1.get(Calendar.MONTH);
+    calendar1.set(Calendar.MONTH, month-1);
+    calendar1.set(Calendar.DAY_OF_MONTH, calendar1.getActualMaximum(Calendar.DAY_OF_MONTH));
+    String str=format.format(calendar.getTime());
+    String str1=format.format(calendar1.getTime());
+    
+	return str+","+str1;
+    }
+    
+  
+  /** 
+   * 获取某年第一天和最后一天日期 
+   * @param year 年份 
+   * @return Date 
+   */  
+  
+  public static String getYearFirst(int year){  
+	  SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
+      Calendar calendar = Calendar.getInstance();  
+      calendar.clear();  
+      calendar.set(Calendar.YEAR, year);  
+      
+      
+      Calendar calendar1 = Calendar.getInstance();  
+      calendar1.clear();  
+      calendar1.set(Calendar.YEAR, year);  
+      calendar1.roll(Calendar.DAY_OF_YEAR, -1);  
+   
+      
+      String str=format.format(calendar.getTime());
+      String str1=format.format(calendar1.getTime());
+      
+      
+      return str+","+str1;  
+  }  
+    	
+	
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/ParamUtil.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/ParamUtil.java
new file mode 100644
index 0000000..3ff58b2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/ParamUtil.java
@@ -0,0 +1,34 @@
+package com.ruoyi.order.util;
+
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * 配置信息
+ *
+ * @version 1.0
+ */
+public class ParamUtil {
+
+	/**
+	 * 获取配置信息
+	 */
+	private static Properties properties = new Properties();
+	static{
+		try {
+			//获取properties文件
+			properties.load(ParamUtil.class.getClassLoader().getResourceAsStream("conf/param.properties"));
+		} catch (IOException e) {e.printStackTrace();}
+	}
+	
+	/**
+	 * 获取配置参数值
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public static String getValue(String key){		
+		return (String)properties.get(key);
+	}
+	
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/SinataUtil.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/SinataUtil.java
new file mode 100644
index 0000000..fb7e844
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/SinataUtil.java
@@ -0,0 +1,345 @@
+package com.ruoyi.order.util;
+
+import java.io.UnsupportedEncodingException;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 基本数据处理工具类
+ */
+public class SinataUtil {
+
+	
+	/**
+	 * List集合分页<br/> 
+	 * 创建人:Mryang<br/>
+	 * 时间:2016年7月28日-下午2:58:14 <br/> 
+	 * @param <T>
+	 * @param pageNo
+	 * @param pageSize
+	 * @param list 
+	 * @throws Exception List<UserOrderList> <br/>
+	 */
+	public static <T> List<T> listpage(int pageNo, int pageSize, List<T> list) throws Exception {
+		List<T> result = new ArrayList<T>();
+		if (list != null && list.size() > 0) {
+			int allCount = list.size();
+			if(pageNo > 1 && allCount < pageSize) {
+				return new ArrayList<>();
+			}
+			int pageCount = (allCount + pageSize - 1) / pageSize;
+			if (pageNo >= pageCount) {
+				pageNo = pageCount;
+			}
+			int start = (pageNo - 1) * pageSize;
+			int end = pageNo * pageSize;
+			if (end >= allCount) {
+				end = allCount;
+			}
+			for (int i = start; i < end; i++) {
+				result.add(list.get(i));
+			}
+		}
+		return (result != null && result.size() > 0) ? result : new ArrayList<T>();
+	}
+
+	/**
+	 * Double类型取整
+	 * @param num
+	 * @return
+	 */
+	public static String doubleTrans(double num) {
+		return String.valueOf((long) num);
+	}
+
+	/**
+	 * Double类型保留1位小数
+	 * 
+	 * @param num
+	 * @return
+	 */
+	public static String doubleRetainOne(double num) {
+		DecimalFormat dfs = new DecimalFormat("0.0");
+		return dfs.format(num);
+	}
+
+	/**
+	 * Double类型保留2位小数
+	 * 
+	 * @param num
+	 * @return
+	 */
+	public static String doubleRetainTwo(double num) {
+		DecimalFormat dfs = new DecimalFormat("0.00");
+		String.format("%.2f", num);
+		return dfs.format(num);
+	}
+
+	/**
+	 * Double类型保留1位小数(四舍五入)
+	 * 
+	 * @param num
+	 * @return
+	 */
+	public static String doubleForwardOne(double num) {
+		return String.format("%.1f", num);
+	}
+
+	/**
+	 * Double类型保留2位小数(四舍五入)
+	 * 
+	 * @param num
+	 * @return
+	 */
+	public static String doubleForwardTwo(double num) {
+		return String.format("%.2f", num);
+	}
+
+	/**
+	 * 字符串转换成Ascii
+	 * 
+	 * @param value
+	 * @return
+	 */
+	public static String stringToAscii(String value) {
+		StringBuffer sbu = new StringBuffer();
+		char[] chars = value.toCharArray();
+		for (int i = 0; i < chars.length; i++) {
+			if (i != chars.length - 1) {
+				sbu.append((int) chars[i]);
+			} else {
+				sbu.append((int) chars[i]);
+			}
+		}
+		return sbu.toString();
+	}
+
+	/**
+	 * 小数转换为百分比
+	 *  
+	 * @param decimal
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String decTurnPercent(double decimal) {
+		NumberFormat num = NumberFormat.getPercentInstance();
+		num.setMaximumIntegerDigits(3);
+		num.setMaximumFractionDigits(2);
+		return num.format(decimal);
+	}
+
+	/**
+	 * Ascii转换成字符串
+	 * 
+	 * @param value
+	 * @return
+	 */
+	public static String asciiToString(String value) {
+		String[] chars = value.split(",");
+		StringBuffer sbu = new StringBuffer();
+		for (int i = 0; i < chars.length; i++) {
+			sbu.append((char) Integer.parseInt(chars[i]));
+		}
+		return sbu.toString();
+	}
+
+	/**
+	 * 字符串转换unicode
+	 * 
+	 * @param string
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String string2Unicode(String string) {
+		StringBuffer unicode = new StringBuffer();
+		for (int i = 0; i < string.length(); i++) {
+			// 取出每一个字符
+			char c = string.charAt(i);
+			// 转换为unicode
+			unicode.append("\\u" + Integer.toHexString(c));
+		}
+		return unicode.toString();
+	}
+
+	/**
+	 * unicode 转字符串
+	 * 
+	 * @param unicode
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String unicode2String(String unicode) {
+		StringBuffer string = new StringBuffer();
+		String[] hex = unicode.split("\\\\u");
+		for (int i = 1; i < hex.length; i++) {
+			// 转换出每一个代码点
+			int data = Integer.parseInt(hex[i], 16);
+			// 追加成string
+			string.append((char) data);
+		}
+		return string.toString();
+	}
+
+	/**
+	 * 字符串编码转换的实现方法
+	 * 
+	 * @param str
+	 *            待转换编码的字符串
+	 * @param newCharset
+	 *            目标编码
+	 * @return
+	 * @throws UnsupportedEncodingException
+	 */
+	public static String changeCharset(String str, String newCharset) throws UnsupportedEncodingException {
+		if (str != null) {
+			// 用默认字符编码解码字符串。
+			byte[] bs = str.getBytes();
+			// 用新的字符编码生成字符串
+			return new String(bs, newCharset);
+		}
+		return null;
+	}
+
+	/**
+	 * 注: \n 回车( ) \t 水平制表符( ) \s 空格(\u0008) \r 换行( )
+	 * 
+	 * @param str
+	 * @return
+	 */
+	public static String replaceBlank(String str) {
+		String dest = "";
+		if (str != null) {
+			Pattern p = Pattern.compile("\\s*|\t|\r|\n");
+			Matcher m = p.matcher(str);
+			dest = m.replaceAll("");
+		}
+		return dest;
+	}
+
+	/**
+	 * 判断该字符串不能为空
+	 * 
+	 * @param str
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static boolean isNotEmpty(Object str) {
+		return !isEmpty(str);
+	}
+	
+	
+	public static boolean isNotEmptyUndefined(Object str) {
+		return !isEmpty(str) && !str.toString().equals("undefined");
+	}
+
+	/**
+	 * 字符串编码转换的实现方法
+	 * 
+	 * @param str
+	 *            待转换编码的字符串
+	 * @param oldCharset
+	 *            原编码
+	 * @param newCharset
+	 *            目标编码
+	 * @return
+	 * @throws UnsupportedEncodingException
+	 */
+	public static String changeCharset(String str, String oldCharset, String newCharset) throws UnsupportedEncodingException {
+		if (str != null) {
+			// 用旧的字符编码解码字符串。解码可能会出现异常。
+			byte[] bs = str.getBytes(oldCharset);
+			// 用新的字符编码生成字符串
+			return new String(bs, newCharset);
+		}
+		return null;
+	}
+
+	/**
+	 * 给手机号码加分割符
+	 * 
+	 * @param phone
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String splitPhone(String phone) {
+		if (isNotEmpty(phone)) {
+			String strone = phone.substring(0, 3);
+			String strtwo = phone.substring(strone.length(), 7);
+			String strthree = phone.substring(strtwo.length() + strone.length(), phone.length());
+			return strone + "-" + strtwo + "-" + strthree;
+		}
+		return "";
+	}
+
+	/**
+	 * 非空判断
+	 * 
+	 * @param str
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static boolean isEmpty(Object str) {
+		return str == null || str.toString().length() == 0 || str.equals("") || str.toString().matches("\\s*");
+	}
+
+	/**
+	 * 把米转换成公里
+	 * 
+	 * @param km
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static Double kmTransKilo(Integer m) {
+		return Math.round(m / 100d) / 10d;
+	}
+	
+	/**
+	 * 将List<{@link Object}>转换成List<{@link T}>
+	 * 
+	 * @param list
+	 *            将要转换的对象
+	 * @param clazs
+	 *            需要转换的泛型对象
+	 * @return
+	 * @author TaoNingBo
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> List<T> fromToObject(List<?> list, Class<T> clazs) {
+		List<T> t = new ArrayList<T>();
+		for (Object object : list) {
+			t.add((T) object);
+		}
+		return t;
+	}
+	
+	 /**
+     * 生成 uuid, 即用来标识一笔单,也用做 nonce_str
+     * @return
+     */
+    public static String generateUUID() {
+        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
+    }
+	
+	/**
+	 * 将List<{@link Object}>转换成List<{@link Map<String, Object>}>
+	 * 
+	 * @param list
+	 * @return
+	 * @author TaoNingBo
+	 */
+	@SuppressWarnings("unchecked")
+	public static List<Map<String, Object>> fromToObject_M(List<?> list) {
+		List<Map<String, Object>> t = new ArrayList<Map<String, Object>>();
+		for (Object object : list) {
+			t.add((Map<String, Object>) object);
+		}
+		return t;
+	}
+	
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/config/AlipayConfig.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/config/AlipayConfig.java
new file mode 100644
index 0000000..c4eb2b5
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/config/AlipayConfig.java
@@ -0,0 +1,42 @@
+package com.ruoyi.order.util.alipay.config;
+
+
+import com.ruoyi.order.util.ParamUtil;
+
+/**
+ * 类名:AlipayConfig 功能:基础配置类 详细:设置帐户有关信息及返回路径 版本:3.3 日期:2012-08-10
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ * 
+ * 附:该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ * 
+ * 提示:如何获取安全校验码和合作身份者ID 1.用您的签约支付宝账号登录支付宝网站(www.alipay.com)
+ * 2.点击“商家服务”(https://b.alipay.com/order/myOrder.htm)
+ * 3.点击“查询合作者身份(PID)”、“查询安全校验码(Key)”安全校验码查看时,输入支付密码后,页面呈灰色的现象,怎么办? 解决方法:
+ * 1、检查浏览器配置,不让浏览器做弹框屏蔽设置 2、更换浏览器或电脑,重新登录查询。
+ */
+
+public class  AlipayConfig {
+
+	// ↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+	// 商户的私钥
+	public static String private_key = ParamUtil.getValue("private_key");
+	// 商户收款账号
+	public static final String seller_email = ParamUtil.getValue("seller_email");
+	// 支付宝的公钥
+	public static String ali_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgRS4mO8v95swMPfUAezNK5hM+M/HqX0GT/QEPaICcQU1CNAup7pZuFm0jWyWrA0eOOWCzN5Qky0UEWZjZAd06xvYtxCNCgKh3SoGXWNUVIQ/iTFrZHWK9hn58Krm0vTLSZH1fxhqcYZmiE/ndeJvWRNHZB2UEQhLc5mE/nl3fC3zvMUcY77btfFm/MLRdJRSK83trG1dJ4pXqmROi77rg3dIF6rsdtqB3BCLQ9mks6m/lTx89tcZD6TVooMd4tPUsBnC0bWjqm2d020ufLEi6sf+Lh5UUsT6ueNTk1Pbc/5oOlRjOeV/MQLj4icoWstKn8pWc97FTVAQ9Pmce3COKQIDAQAB";
+	// appId
+	public static String app_id = ParamUtil.getValue("app_id");
+	// 回调地址
+	public static String notify_url = ParamUtil.getValue("notify_url");
+	// ↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
+
+	// 调试用,创建TXT日志文件夹路径
+	public static String log_path = "E:\\";
+
+	// 字符编码格式 目前支持 gbk 或 utf-8
+	public static String input_charset = "utf-8";
+
+	// 签名方式 不需修改
+	public static String sign_type = "RSA2";
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/Base64.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/Base64.java
new file mode 100644
index 0000000..d8c8c80
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/Base64.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2010 The MobileSecurePay Project
+ * All right reserved.
+ * author: shiqun.shi@alipay.com
+ */
+
+package com.ruoyi.order.util.alipay.sign;
+
+public final class Base64 {
+
+	static private final int BASELENGTH = 128;
+	static private final int LOOKUPLENGTH = 64;
+	static private final int TWENTYFOURBITGROUP = 24;
+	static private final int EIGHTBIT = 8;
+	static private final int SIXTEENBIT = 16;
+	static private final int FOURBYTE = 4;
+	static private final int SIGN = -128;
+	static private final char PAD = '=';
+	static private final boolean fDebug = false;
+	static final private byte[] base64Alphabet = new byte[BASELENGTH];
+	static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+	static {
+		for (int i = 0; i < BASELENGTH; ++i) {
+			base64Alphabet[i] = -1;
+		}
+		for (int i = 'Z'; i >= 'A'; i--) {
+			base64Alphabet[i] = (byte) (i - 'A');
+		}
+		for (int i = 'z'; i >= 'a'; i--) {
+			base64Alphabet[i] = (byte) (i - 'a' + 26);
+		}
+
+		for (int i = '9'; i >= '0'; i--) {
+			base64Alphabet[i] = (byte) (i - '0' + 52);
+		}
+
+		base64Alphabet['+'] = 62;
+		base64Alphabet['/'] = 63;
+
+		for (int i = 0; i <= 25; i++) {
+			lookUpBase64Alphabet[i] = (char) ('A' + i);
+		}
+
+		for (int i = 26, j = 0; i <= 51; i++, j++) {
+			lookUpBase64Alphabet[i] = (char) ('a' + j);
+		}
+
+		for (int i = 52, j = 0; i <= 61; i++, j++) {
+			lookUpBase64Alphabet[i] = (char) ('0' + j);
+		}
+		lookUpBase64Alphabet[62] = (char) '+';
+		lookUpBase64Alphabet[63] = (char) '/';
+
+	}
+
+	private static boolean isWhiteSpace(char octect) {
+		return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+	}
+
+	private static boolean isPad(char octect) {
+		return (octect == PAD);
+	}
+
+	private static boolean isData(char octect) {
+		return (octect < BASELENGTH && base64Alphabet[octect] != -1);
+	}
+
+	/**
+	 * Encodes hex octects into Base64
+	 *
+	 * @param binaryData
+	 *            Array containing binaryData
+	 * @return Encoded Base64 array
+	 */
+	public static String encode(byte[] binaryData) {
+
+		if (binaryData == null) {
+			return null;
+		}
+
+		int lengthDataBits = binaryData.length * EIGHTBIT;
+		if (lengthDataBits == 0) {
+			return "";
+		}
+
+		int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+		int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+		int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
+		char encodedData[] = null;
+
+		encodedData = new char[numberQuartet * 4];
+
+		byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+
+		int encodedIndex = 0;
+		int dataIndex = 0;
+		if (fDebug) {
+			System.out.println("number of triplets = " + numberTriplets);
+		}
+
+		for (int i = 0; i < numberTriplets; i++) {
+			b1 = binaryData[dataIndex++];
+			b2 = binaryData[dataIndex++];
+			b3 = binaryData[dataIndex++];
+
+			if (fDebug) {
+				System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
+			}
+
+			l = (byte) (b2 & 0x0f);
+			k = (byte) (b1 & 0x03);
+
+			byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+			byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+			byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
+
+			if (fDebug) {
+				System.out.println("val2 = " + val2);
+				System.out.println("k4   = " + (k << 4));
+				System.out.println("vak  = " + (val2 | (k << 4)));
+			}
+
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+		}
+
+		// form integral number of 6-bit groups
+		if (fewerThan24bits == EIGHTBIT) {
+			b1 = binaryData[dataIndex];
+			k = (byte) (b1 & 0x03);
+			if (fDebug) {
+				System.out.println("b1=" + b1);
+				System.out.println("b1<<2 = " + (b1 >> 2));
+			}
+			byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
+			encodedData[encodedIndex++] = PAD;
+			encodedData[encodedIndex++] = PAD;
+		} else if (fewerThan24bits == SIXTEENBIT) {
+			b1 = binaryData[dataIndex];
+			b2 = binaryData[dataIndex + 1];
+			l = (byte) (b2 & 0x0f);
+			k = (byte) (b1 & 0x03);
+
+			byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+			byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
+			encodedData[encodedIndex++] = PAD;
+		}
+
+		return new String(encodedData);
+	}
+
+	/**
+	 * Decodes Base64 data into octects
+	 *
+	 * @param encoded
+	 *            string containing Base64 data
+	 * @return Array containind decoded data.
+	 */
+	public static byte[] decode(String encoded) {
+
+		if (encoded == null) {
+			return null;
+		}
+
+		char[] base64Data = encoded.toCharArray();
+		// remove white spaces
+		int len = removeWhiteSpace(base64Data);
+
+		if (len % FOURBYTE != 0) {
+			return null;// should be divisible by four
+		}
+
+		int numberQuadruple = (len / FOURBYTE);
+
+		if (numberQuadruple == 0) {
+			return new byte[0];
+		}
+
+		byte decodedData[] = null;
+		byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+		char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
+
+		int i = 0;
+		int encodedIndex = 0;
+		int dataIndex = 0;
+		decodedData = new byte[(numberQuadruple) * 3];
+
+		for (; i < numberQuadruple - 1; i++) {
+
+			if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
+					|| !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) {
+				return null;
+			} // if found "no data" just return null
+
+			b1 = base64Alphabet[d1];
+			b2 = base64Alphabet[d2];
+			b3 = base64Alphabet[d3];
+			b4 = base64Alphabet[d4];
+
+			decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+			decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+			decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+		}
+
+		if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
+			return null;// if found "no data" just return null
+		}
+
+		b1 = base64Alphabet[d1];
+		b2 = base64Alphabet[d2];
+
+		d3 = base64Data[dataIndex++];
+		d4 = base64Data[dataIndex++];
+		if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters
+			if (isPad(d3) && isPad(d4)) {
+				if ((b2 & 0xf) != 0)// last 4 bits should be zero
+				{
+					return null;
+				}
+				byte[] tmp = new byte[i * 3 + 1];
+				System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+				tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
+				return tmp;
+			} else if (!isPad(d3) && isPad(d4)) {
+				b3 = base64Alphabet[d3];
+				if ((b3 & 0x3) != 0)// last 2 bits should be zero
+				{
+					return null;
+				}
+				byte[] tmp = new byte[i * 3 + 2];
+				System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+				tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+				tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+				return tmp;
+			} else {
+				return null;
+			}
+		} else { // No PAD e.g 3cQl
+			b3 = base64Alphabet[d3];
+			b4 = base64Alphabet[d4];
+			decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+			decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+			decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+
+		}
+
+		return decodedData;
+	}
+
+	/**
+	 * remove WhiteSpace from MIME containing encoded Base64 data.
+	 *
+	 * @param data
+	 *            the byte array of base64 data (with WS)
+	 * @return the new length
+	 */
+	private static int removeWhiteSpace(char[] data) {
+		if (data == null) {
+			return 0;
+		}
+
+		// count characters that's not whitespace
+		int newSize = 0;
+		int len = data.length;
+		for (int i = 0; i < len; i++) {
+			if (!isWhiteSpace(data[i])) {
+				data[newSize++] = data[i];
+			}
+		}
+		return newSize;
+	}
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/RSA.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/RSA.java
new file mode 100644
index 0000000..9375733
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/RSA.java
@@ -0,0 +1,134 @@
+package com.ruoyi.order.util.alipay.sign;
+
+import javax.crypto.Cipher;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+public class RSA {
+
+	public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
+
+	/**
+	 * RSA签名
+	 * 
+	 * @param content
+	 *            待签名数据
+	 * @param privateKey
+	 *            商户私钥
+	 * @param input_charset
+	 *            编码格式
+	 * @return 签名值
+	 */
+	public static String sign(String content, String privateKey, String input_charset) {
+		try {
+			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
+			KeyFactory keyf = KeyFactory.getInstance("RSA");
+			PrivateKey priKey = keyf.generatePrivate(priPKCS8);
+			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
+			signature.initSign(priKey);
+			signature.update(content.getBytes(input_charset));
+			byte[] signed = signature.sign();
+			return Base64.encode(signed);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * RSA验签名检查
+	 * 
+	 * @param content
+	 *            待签名数据
+	 * @param sign
+	 *            签名值
+	 * @param ali_public_key
+	 *            支付宝公钥
+	 * @param input_charset
+	 *            编码格式
+	 * @return 布尔值
+	 */
+	public static boolean verify(String content, String sign, String ali_public_key, String input_charset) {
+		try {
+			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+			byte[] encodedKey = Base64.decode(ali_public_key);
+			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
+			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
+			signature.initVerify(pubKey);
+			signature.update(content.getBytes(input_charset));
+			boolean bverify = signature.verify(Base64.decode(sign));
+			return bverify;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return false;
+	}
+
+	/**
+	 * 解密
+	 * 
+	 * @param content
+	 *            密文
+	 * @param private_key
+	 *            商户私钥
+	 * @param input_charset
+	 *            编码格式
+	 * @return 解密后的字符串
+	 */
+	public static String decrypt(String content, String private_key, String input_charset) throws Exception {
+		PrivateKey prikey = getPrivateKey(private_key);
+
+		Cipher cipher = Cipher.getInstance("RSA");
+		cipher.init(Cipher.DECRYPT_MODE, prikey);
+
+		InputStream ins = new ByteArrayInputStream(Base64.decode(content));
+		ByteArrayOutputStream writer = new ByteArrayOutputStream();
+		// rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
+		byte[] buf = new byte[128];
+		int bufl;
+
+		while ((bufl = ins.read(buf)) != -1) {
+			byte[] block = null;
+
+			if (buf.length == bufl) {
+				block = buf;
+			} else {
+				block = new byte[bufl];
+				for (int i = 0; i < bufl; i++) {
+					block[i] = buf[i];
+				}
+			}
+
+			writer.write(cipher.doFinal(block));
+		}
+
+		return new String(writer.toByteArray(), input_charset);
+	}
+
+	/**
+	 * 得到私钥
+	 * 
+	 * @param key
+	 *            密钥字符串(经过base64编码)
+	 * @throws Exception
+	 */
+	public static PrivateKey getPrivateKey(String key) throws Exception {
+		byte[] keyBytes;
+
+		keyBytes = Base64.decode(key);
+
+		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
+
+		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+
+		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
+
+		return privateKey;
+	}
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/SignUtils.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/SignUtils.java
new file mode 100644
index 0000000..c2a6633
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/sign/SignUtils.java
@@ -0,0 +1,36 @@
+package com.ruoyi.order.util.alipay.sign;
+
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+public class SignUtils {
+
+	private static final String ALGORITHM = "RSA";
+
+	private static final String SIGN_ALGORITHMS = "SHA1WithRSA";
+
+	private static final String DEFAULT_CHARSET = "UTF-8";
+
+	public static String sign(String content, String privateKey) {
+		try {
+			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
+			KeyFactory keyf = KeyFactory.getInstance(ALGORITHM);
+			PrivateKey priKey = keyf.generatePrivate(priPKCS8);
+
+			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
+
+			signature.initSign(priKey);
+			signature.update(content.getBytes(DEFAULT_CHARSET));
+
+			byte[] signed = signature.sign();
+
+			return Base64.encode(signed);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		return null;
+	}
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/AlipayCore.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/AlipayCore.java
new file mode 100644
index 0000000..53a7dc9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/AlipayCore.java
@@ -0,0 +1,98 @@
+package com.ruoyi.order.util.alipay.util;
+
+
+
+import com.ruoyi.order.util.alipay.config.AlipayConfig;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.*;
+
+/* *
+ *类名:AlipayFunction
+ *功能:支付宝接口公用函数类
+ *详细:该类是请求、通知返回两个文件所调用的公用函数核心处理文件,不需要修改
+ *版本:3.3
+ *日期:2012-08-14
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ */
+
+public class AlipayCore {
+
+    /** 
+     * 除去数组中的空值和签名参数
+     * @param sArray 签名参数组
+     * @return 去掉空值与签名参数后的新签名参数组
+     */
+    public static Map<String, String> paraFilter(Map<String, String> sArray) {
+
+        Map<String, String> result = new HashMap<String, String>();
+
+        if (sArray == null || sArray.size() <= 0) {
+            return result;
+        }
+
+        for (String key : sArray.keySet()) {
+            String value = sArray.get(key);
+            if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
+                || key.equalsIgnoreCase("sign_type")) {
+                continue;
+            }
+            result.put(key, value);
+        }
+
+        return result;
+    }
+
+    /** 
+     * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
+     * @param params 需要排序并参与字符拼接的参数组
+     * @return 拼接后字符串
+     */
+    public static String createLinkString(Map<String, String> params) {
+
+        List<String> keys = new ArrayList<String>(params.keySet());
+        Collections.sort(keys);
+
+        String prestr = "";
+
+        for (int i = 0; i < keys.size(); i++) {
+            String key = keys.get(i);
+            String value = params.get(key);
+
+            if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符
+                prestr = prestr + key + "=" + value;
+            } else {
+                prestr = prestr + key + "=" + value + "&";
+            }
+        }
+
+        return prestr;
+    }
+
+    /** 
+     * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
+     * @param sWord 要写入日志里的文本内容
+     */
+    public static void logResult(String sWord) {
+        FileWriter writer = null;
+        try {
+            writer = new FileWriter(AlipayConfig.log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
+            writer.write(sWord);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/AlipayNotify.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/AlipayNotify.java
new file mode 100644
index 0000000..57ef6d6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/AlipayNotify.java
@@ -0,0 +1,27 @@
+package com.ruoyi.order.util.alipay.util;
+
+
+
+/* *
+ *类名:AlipayNotify
+ *功能:支付宝通知处理类
+ *详细:处理支付宝各接口通知返回
+ *版本:3.3
+ *日期:2012-08-17
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考
+
+ *************************注意*************************
+ *调试通知返回时,可查看或改写log日志的写入TXT里的数据,来检查通知返回是否正常
+ */
+public class AlipayNotify {
+
+  public static void main(String[] args) {
+	System.out.println("11111111111111111111");
+	String dd="2017-09-02 17:11";
+	System.out.println(dd.length());
+}
+
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/PayDemoActivity.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/PayDemoActivity.java
new file mode 100644
index 0000000..6952611
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/PayDemoActivity.java
@@ -0,0 +1,101 @@
+package com.ruoyi.order.util.alipay.util;
+
+
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.domain.AlipayTradeAppPayModel;
+import com.alipay.api.request.AlipayTradeAppPayRequest;
+import com.alipay.api.response.AlipayTradeAppPayResponse;
+import com.alipay.config.AlipayConfig;
+
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * 支付宝签名工具类<
+ */
+@SuppressWarnings("unused")
+public class PayDemoActivity {
+
+	 /**		支付宝参数配置项	*/
+		public static String serverUrl = "https://openapi.alipay.com/gateway.do";
+		public static String format = "json";
+		public static String charset = "UTF-8";
+		public static String signType = "RSA2";
+		
+		public static String APP_ID = AlipayConfig.app_id;
+		public static String APP_PRIVATE_KEY = AlipayConfig.private_key;
+		public static String ALIPAY_PUBLIC_KEY = AlipayConfig.ali_public_key;
+		public static String NOTIFY_URL = AlipayConfig.notify_url;
+		
+		//实例化客户端
+		private static AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, APP_ID, APP_PRIVATE_KEY, format, charset, ALIPAY_PUBLIC_KEY, signType);
+		
+		
+	/**
+	 * @throws AlipayApiException 
+	 * @throws UnsupportedEncodingException 
+	 * @throws UnsupportedEncodingException 
+	 * @throws AlipayApiException 
+	 * 
+	 * 方法功能说明:支付宝2.0 app支付  
+	 * 创建:2017年2月10日 by tzj
+	 * 修改:日期 by 修改者  
+	 * 修改内容:  
+	 * @参数: @param subject
+	 * @参数: @param body
+	 * @参数: @param price
+	 * @参数: @param out_trade_no
+	 * @参数: @param notify_url
+	 * @参数: @return      
+	 * @return Map<String,Object>     
+	 * @throws
+	 */
+	public static Map<String, Object> appPay(String subject, String body, Double price, String out_trade_no) throws UnsupportedEncodingException, AlipayApiException{
+
+		String outtradeno = out_trade_no;
+		String total_amount = price+"";
+		
+		/*********** 测试数据(仅供测试) ************/
+//			subject = "subject"+DateUtil.getTodayDate("yyMMssHHmmss");
+//			total_amount = "0.01";
+		
+		/*********** 测试数据(仅供测试)end ************/
+		
+			Map<String, Object> map = new HashMap<>();
+		try {
+		
+			//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
+			AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
+			//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
+			AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
+			model.setBody(body);
+			model.setSubject(subject);
+			model.setOutTradeNo(outtradeno);
+			model.setTimeoutExpress("30m");
+			model.setTotalAmount(total_amount);
+			model.setProductCode("QUICK_MSECURITY_PAY");
+			request.setBizModel(model);
+			request.setNotifyUrl(NOTIFY_URL);
+			// 这里和普通的接口调用不同,使用的是sdkExecute
+			AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
+			String string = response.getBody();
+			
+			int one = string.lastIndexOf("&");
+			String s=string.substring(0,(one));
+			
+			map.put("orderInfo", s);
+			System.out.println(java.net.URLDecoder.decode(s, "UTF-8"));
+			System.out.println(java.net.URLDecoder.decode(response.getBody(), "UTF-8"));
+			
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		 return map;
+	}
+	
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/UtilDate.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/UtilDate.java
new file mode 100644
index 0000000..df083e0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/alipay/util/UtilDate.java
@@ -0,0 +1,71 @@
+
+package com.ruoyi.order.util.alipay.util;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Random;
+
+/* *
+ *类名:UtilDate
+ *功能:自定义订单类
+ *详细:工具类,可以用作获取系统日期、订单编号等
+ *版本:3.3
+ *日期:2012-08-17
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ */
+public class UtilDate {
+	
+    /** 年月日时分秒(无下划线) yyyyMMddHHmmss */
+    public static final String dtLong                  = "yyyyMMddHHmmss";
+    
+    /** 完整时间 yyyy-MM-dd HH:mm:ss */
+    public static final String simple                  = "yyyy-MM-dd HH:mm:ss";
+    
+    /** 年月日(无下划线) yyyyMMdd */
+    public static final String dtShort                 = "yyyyMMdd";
+	
+    
+    /**
+     * 返回系统当前时间(精确到毫秒),作为一个唯一的订单编号
+     * @return
+     *      以yyyyMMddHHmmss为格式的当前系统时间
+     */
+	public  static String getOrderNum(){
+		Date date=new Date();
+		DateFormat df=new SimpleDateFormat(dtLong);
+		return df.format(date);
+	}
+	
+	/**
+	 * 获取系统当前日期(精确到毫秒),格式:yyyy-MM-dd HH:mm:ss
+	 * @return
+	 */
+	public  static String getDateFormatter(){
+		Date date=new Date();
+		DateFormat df=new SimpleDateFormat(simple);
+		return df.format(date);
+	}
+	
+	/**
+	 * 获取系统当期年月日(精确到天),格式:yyyyMMdd
+	 * @return
+	 */
+	public static String getDate(){
+		Date date=new Date();
+		DateFormat df=new SimpleDateFormat(dtShort);
+		return df.format(date);
+	}
+	
+	/**
+	 * 产生随机的三位数
+	 * @return
+	 */
+	public static String getThree(){
+		Random rad=new Random();
+		return rad.nextInt(1000)+"";
+	}
+	
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/WXPay.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/WXPay.java
new file mode 100644
index 0000000..7ec78f2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/WXPay.java
@@ -0,0 +1,304 @@
+package com.tencent;
+import java.util.Map;
+
+
+import com.tencent.common.Configure;
+import com.tencent.common.WXPayConfig;
+import com.tencent.common.WXPayConstants;
+import com.tencent.common.WXPayConstants.SignType;
+import com.tencent.common.WXPayUtil;
+import com.tencent.protocol.RefundReqData;
+import com.tencent.protocol.UnifiedorderReqData;
+import com.tencent.protocol.WXPayRequest;
+import com.tencent.service.RefundService;
+import com.tencent.service.UnifiedorderService;
+/**
+ * SDK总入口
+ */
+/**
+ * SDK总入口
+ */
+public class WXPay {
+	
+	  private WXPayConfig config;
+	    private SignType signType;
+	    private boolean autoReport;
+	    private boolean useSandbox;
+	    private String notifyUrl;
+	    private WXPayRequest wxPayRequest;
+	 
+	    public WXPay(final WXPayConfig config) throws Exception {
+	        this(config, null, true, false);
+	    }
+
+	    public WXPay(final WXPayConfig config, final boolean autoReport) throws Exception {
+	        this(config, null, autoReport, false);
+	    }
+
+
+	    public WXPay(final WXPayConfig config, final boolean autoReport, final boolean useSandbox) throws Exception{
+	        this(config, null, autoReport, useSandbox);
+	    }
+
+	    public WXPay(final WXPayConfig config, final String notifyUrl) throws Exception {
+	        this(config, notifyUrl, true, false);
+	    }
+
+	    public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport) throws Exception {
+	        this(config, notifyUrl, autoReport, false);
+	    }
+
+	    public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception {
+	        this.config = config;
+	        this.notifyUrl = notifyUrl;
+	        this.autoReport = autoReport;
+	        this.useSandbox = useSandbox;
+	        if (useSandbox) {
+	            this.signType = SignType.MD5; // 沙箱环境
+	        }
+	        else {
+	            this.signType = SignType.HMACSHA256;
+	        }
+	        this.wxPayRequest = new WXPayRequest(config);
+	    }
+
+    /**
+     * 初始化SDK依赖的几个关键配置
+     * @param key 签名算法需要用到的秘钥
+     * @param appID 公众账号ID
+     * @param mchID 商户ID
+     * @param sdbMchID 子商户ID,受理模式必填
+     * @param certLocalPath HTTP证书在服务器中的路径,用来加载证书用
+     * @param certPassword HTTP证书的密码,默认等于MCHID
+     */
+    public static void initSDKConfiguration(String key,String appID,String mchID,String sdbMchID,String certLocalPath,String certPassword){
+        System.out.println("________@@@@@______initSDKConfiguration");
+    	Configure.setKey(key);
+        Configure.setAppID(appID);
+        Configure.setMchID(mchID);
+        Configure.setSubMchID(sdbMchID);
+        Configure.setCertLocalPath(certLocalPath);
+        Configure.setCertPassword(certPassword);
+    }
+    
+    /**
+     * 请求统一下单服务
+     */
+    public static String requestUnifiedorderService(Integer apptype,UnifiedorderReqData unifiedorderReqData) throws Exception{
+        return new UnifiedorderService(apptype).request(unifiedorderReqData);
+    }
+    
+    
+    /**
+     * 商家向用户付款(提现)
+     */
+   /* public static String requestPayToTheUserService(Integer apptype, PayToTheUserReqData payToTheUserReqData) throws Exception{
+        return new PayToTheUserService(apptype).request(payToTheUserReqData);
+    }*/
+
+    /**
+     * 请求退款服务
+     */
+    public static String requestRefundService(Integer apptype, RefundReqData refundReqData) throws Exception{
+        return new RefundService(apptype).request(refundReqData);
+    }
+    
+    /**
+     * 提交刷卡支付,针对软POS,尽可能做成功
+     * 内置重试机制,最多60s
+     * @param reqData
+     * @return
+     * @throws Exception
+     */
+    public Map<String, String> microPayWithPos(Map<String, String> reqData) throws Exception {
+        return this.microPayWithPos(reqData, 6*1000);
+    }
+    
+    /**
+     * 作用:提交刷卡支付<br>
+     * 场景:刷卡支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> microPay(Map<String, String> reqData) throws Exception {
+        return this.microPay(reqData, 6*1000, 8*1000);
+    }
+
+
+    /**
+     * 作用:提交刷卡支付<br>
+     * 场景:刷卡支付
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> microPay(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+       /* if (this.useSandbox) {//沙箱环境
+            url = WXPayConstants.SANDBOX_MICROPAY_URL_SUFFIX;
+        }*/
+        url = WXPayConstants.MICROPAY_URL_SUFFIX;
+        String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+    /**
+     * 不需要证书的请求
+     * @param urlSuffix String
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 超时时间,单位是毫秒
+     * @param readTimeoutMs 超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public String requestWithoutCert(String urlSuffix, Map<String, String> reqData,
+                                     int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String msgUUID = reqData.get("nonce_str");
+        String reqBody = WXPayUtil.mapToXml(reqData);
+
+        String resp = new WXPayRequest(config).requestWithoutCert(urlSuffix, msgUUID, reqBody, connectTimeoutMs, readTimeoutMs, autoReport);
+        return resp;
+    }
+
+    
+    /**
+     * 处理 HTTPS API返回数据,转换成Map对象。return_code为SUCCESS时,验证签名。
+     * @param xmlStr API返回的XML格式数据
+     * @return Map类型数据
+     * @throws Exception
+     */
+    public Map<String, String> processResponseXml(String xmlStr) throws Exception {
+        /*String RETURN_CODE = "return_code";
+        String return_code;*/
+        Map<String, String> respData = WXPayUtil.xmlToMap(xmlStr);
+        return respData;
+    /*    if (respData.containsKey(RETURN_CODE)) {
+            return_code = respData.get(RETURN_CODE);
+        }
+        else {
+            throw new Exception(String.format("No `return_code` in XML: %s", xmlStr));
+        }
+
+        if (return_code.equals(WXPayConstants.FAIL)) {
+            return respData;
+        }
+        else if (return_code.equals(WXPayConstants.SUCCESS)) {
+           if (this.isResponseSignatureValid(respData)) {
+               return respData;
+           }
+           else {
+               throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr));
+           }
+        }
+        else {
+            throw new Exception(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr));
+        }*/
+    }
+    
+    /**
+     * 判断xml数据的sign是否有效,必须包含sign字段,否则返回false。
+     *
+     * @param reqData 向wxpay post的请求数据
+     * @return 签名是否有效
+     * @throws Exception
+     */
+    public boolean isResponseSignatureValid(Map<String, String> reqData) throws Exception {
+        // 返回数据的签名方式和请求中给定的签名方式是一致的
+        return WXPayUtil.isSignatureValid(reqData, this.config.getKey(), this.signType);
+    }
+    
+    /**
+     * 向 Map 中添加 appid、mch_id、nonce_str、sign_type、sign <br>
+     * 该函数适用于商户适用于统一下单等接口,不适用于红包、代金券接口
+     *
+     * @param reqData
+     * @return
+     * @throws Exception
+     */
+    public Map<String, String> fillRequestData(Map<String, String> reqData) throws Exception {
+        reqData.put("appid", Configure.getAppid());       
+        reqData.put("mch_id", Configure.getMchid());
+        reqData.put("nonce_str", WXPayUtil.generateUUID());
+        reqData.put("sign_type", WXPayConstants.MD5);
+        //reqData.put("sign_type", WXPayConstants.HMACSHA256);
+        reqData.put("sign", WXPayUtil.generateSignature(reqData, Configure.getKey(), SignType.MD5));
+        return reqData;
+    }
+    
+    /**
+     * 提交刷卡支付,针对软POS,尽可能做成功
+     * 内置重试机制,最多60s
+     * @param reqData
+     * @param connectTimeoutMs
+     * @return
+     * @throws Exception
+     */
+    public Map<String, String> microPayWithPos(Map<String, String> reqData, int connectTimeoutMs) throws Exception {
+        int remainingTimeMs = 10*1000;
+        long startTimestampMs = 0;
+        Map<String, String> lastResult = null;
+        Exception lastException = null;
+
+        
+        while (true) {
+            startTimestampMs = WXPayUtil.getCurrentTimestampMs();
+            int readTimeoutMs = remainingTimeMs - connectTimeoutMs;
+            if (readTimeoutMs > 1000) {
+                try {
+                    lastResult = this.microPay(reqData, connectTimeoutMs, readTimeoutMs);
+                    String returnCode = lastResult.get("return_code");//return_code
+                    if (returnCode.equals("SUCCESS")) {break;
+                 /*       String resultCode = lastResult.get("result_code");
+                        String errCode = lastResult.get("err_code");
+                        if (resultCode.equals("SUCCESS")) {
+                            break;
+                        }
+                        else {
+                            // 看错误码,若支付结果未知,则重试提交刷卡支付
+                            if (errCode.equals("SYSTEMERROR") || errCode.equals("BANKERROR") || errCode.equals("USERPAYING")) {
+                                remainingTimeMs = remainingTimeMs - (int)(WXPayUtil.getCurrentTimestampMs() - startTimestampMs);
+                                if (remainingTimeMs <= 100) {
+                                    break;
+                                }
+                                else {
+                                    WXPayUtil.getLogger().info("microPayWithPos: try micropay again");
+                                    if (remainingTimeMs > 5*1000) {
+                                        Thread.sleep(5*1000);
+                                    }
+                                    else {
+                                        Thread.sleep(1*1000);
+                                    }
+                                    continue;
+                                }
+                            }
+                            else {
+                                break;
+                            }
+                        }*/
+                    }
+                    else {
+                        break;
+                    }
+                }
+                catch (Exception ex) {
+                    lastResult = null;
+                    lastException = ex;
+                }
+            }
+            else {
+                break;
+            }
+        }
+
+        if (lastResult == null) {
+            throw lastException;
+        }
+        else {
+            return lastResult;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Configure.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Configure.java
new file mode 100644
index 0000000..a1c12dd
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Configure.java
@@ -0,0 +1,202 @@
+package com.ruoyi.order.util.tencent.common;
+
+
+import com.ruoyi.order.util.ParamUtil;
+
+/**
+ * User: TZJ
+ * Date: 2017/08/29
+ * Time: 14:40
+ * 这里放置微信支付的各种配置数据
+ */
+public class Configure {
+//这个就是自己要保管好的私有Key了(切记只能放在自己的后台代码里,不能放在任何可能被看到源代码的客户端程序中)
+	// 每次自己Post数据给API的时候都要用这个key来对所有字段进行签名,生成的签名会放在Sign这个字段,API收到Post数据的时候也会用同样的签名算法对Post过来的数据进行签名和验证
+	// 收到API的返回的时候也要用这个key来对返回的数据算下签名,跟API的Sign数据进行比较,如果值不一致,有可能数据被第三方给篡改
+
+	private static String key = ParamUtil.getValue("key");
+
+	//用户端开发者平台的appid
+	private static String appID = ParamUtil.getValue("appID");
+	//公众号的appid
+	private static String GappID = ParamUtil.getValue("GappID");
+	//小程序的appid
+	private static String XappID = ParamUtil.getValue("XappID");
+	
+	//公众号的appSecret
+	private static String appSecret = ParamUtil.getValue("appSecret");
+
+	//微信支付分配的商户号ID(开通公众号的微信支付功能之后可以获取到)
+	private static String mchID = ParamUtil.getValue("mchID");
+	
+	private static String GmchID = ParamUtil.getValue("GmchID");
+	
+	private static String XmchID = ParamUtil.getValue("XmchID");
+	
+	//微信回调地址
+	public static String wx_notify_url = ParamUtil.getValue("wx_notify_url");
+
+	//受理模式下给子商户分配的子商户号
+	private static String subMchID = "";
+
+	//HTTPS证书的本地路径
+	private static String certLocalPath;
+	static{//从服务器相对路径中获取
+		certLocalPath = Configure.class.getClassLoader().getResource("").getPath() + "com/tencent/common/cert/apiclient_cert.p12";
+	}
+	
+	//HTTPS证书密码,默认密码等于商户号MCHID
+		private static String certPassword = mchID;
+
+	//HTTPS证书的本地路径
+	private static String certLocalPath_2;
+	static{//从服务器相对路径中获取
+		certLocalPath_2 = Configure.class.getClassLoader().getResource("").getPath() + "com/tencent/common/cert_2/apiclient_cert.p12";
+	}	
+	
+	//HTTPS证书密码,默认密码等于商户号MCHID
+	private static String certPassword_2 = GmchID;
+	
+	//是否使用异步线程的方式来上报API测速,默认为异步模式
+	private static boolean useThreadToDoReport = true;
+
+	//机器IP
+	private static String ip = "";
+
+	//以下是几个API的路径:
+	//1)被扫支付API
+	public static String PAY_API = "https://api.mch.weixin.qq.com/pay/micropay";
+
+	//2)被扫支付查询API
+	public static String PAY_QUERY_API = "https://api.mch.weixin.qq.com/pay/orderquery";
+
+	//3)退款API
+	public static String REFUND_API = "https://api.mch.weixin.qq.com/secapi/pay/refund";
+
+	//4)退款查询API
+	public static String REFUND_QUERY_API = "https://api.mch.weixin.qq.com/pay/refundquery";
+
+	//5)撤销API
+	public static String REVERSE_API = "https://api.mch.weixin.qq.com/secapi/pay/reverse";
+
+	//6)下载对账单API
+	public static String DOWNLOAD_BILL_API = "https://api.mch.weixin.qq.com/pay/downloadbill";
+
+	//7) 统计上报API
+	public static String REPORT_API = "https://api.mch.weixin.qq.com/payitil/report";
+	
+	//商家支付用户(提现)API
+	public static String PayToTheUser_API = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
+
+	//统一下单API(预支付生成接口)
+	public static String UNIFIEDORDER_API = "https://api.mch.weixin.qq.com/pay/unifiedorder";
+	
+	public static boolean isUseThreadToDoReport() {
+		return useThreadToDoReport;
+	}
+
+	public static void setUseThreadToDoReport(boolean useThreadToDoReport) {
+		Configure.useThreadToDoReport = useThreadToDoReport;
+	}
+
+	public static String HttpsRequestClassName = "com.tencent.common.HttpsRequest";
+	
+	public static String HttpsRequestClassName_2 = "com.tencent.common.HttpsRequest_2";
+
+	public static void setKey(String key) {
+		Configure.key = key;
+	}
+
+	public static void setAppID(String appID) {
+		Configure.appID = appID;
+	}
+
+	public static void setMchID(String mchID) {
+		Configure.mchID = mchID;
+	}
+
+	public static void setSubMchID(String subMchID) {
+		Configure.subMchID = subMchID;
+	}
+
+	public static void setCertLocalPath(String certLocalPath) {
+		Configure.certLocalPath = certLocalPath;
+	}
+
+	public static void setCertPassword(String certPassword) {
+		Configure.certPassword = certPassword;
+	}
+
+	public static void setIp(String ip) {
+		Configure.ip = ip;
+	}
+
+	public static String getKey(){
+		return key;
+	}
+	
+	public static String getAppid(){
+		return appID;
+	}
+	public static String getGappid(){
+		return GappID;
+	}
+	public static String getXappid(){
+		return XappID;
+	}	
+	public static String getMchid(){
+		return mchID;
+	}
+	
+	public static String getGmchid(){
+		return GmchID;
+	}
+	public static String getXmchid(){
+		return XmchID;
+	}
+
+	public static String getCertPassword_2() {
+		return certPassword_2;
+	}
+
+	public static void setCertPassword_2(String certPassword_2) {
+		Configure.certPassword_2 = certPassword_2;
+	}
+
+	public static String getSubMchid(){
+		return subMchID;
+	}
+	
+	public static String getCertLocalPath(){
+		return certLocalPath;
+	}
+	
+	public static String getCertLocalPath_2() {
+		return certLocalPath_2;
+	}
+
+	public static void setCertLocalPath_2(String certLocalPath_2) {
+		Configure.certLocalPath_2 = certLocalPath_2;
+	}
+
+	public static String getCertPassword(){
+		return certPassword;
+	}
+
+	public static String getIP(){
+		return ip;
+	}
+
+	public static String getAppSecret() {
+		return appSecret;
+	}
+
+	public static void setAppSecret(String appSecret) {
+		Configure.appSecret = appSecret;
+	}
+
+	public static void setHttpsRequestClassName(String name){
+		HttpsRequestClassName = name;
+	}
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/HttpsRequest.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/HttpsRequest.java
new file mode 100644
index 0000000..e546561
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/HttpsRequest.java
@@ -0,0 +1,187 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.io.File;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLContexts;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+import com.tencent.service.IServiceRequest;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
+
+/**
+ * User: rizenguo
+ * Date: 2014/10/29
+ * Time: 14:36
+ */
+@SuppressWarnings("deprecation")
+public class HttpsRequest implements IServiceRequest{
+
+    public interface ResultListener {
+        public void onConnectionPoolTimeoutError();
+    }
+
+    //表示请求器是否已经做了初始化工作
+    private boolean hasInit = false;
+
+    //连接超时时间,默认10秒
+    private int socketTimeout = 10000;
+
+    //传输超时时间,默认30秒
+    private int connectTimeout = 30000;
+
+    //请求器的配置
+    private RequestConfig requestConfig;
+
+    //HTTP请求器
+    private CloseableHttpClient httpClient;
+
+    public HttpsRequest() throws UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, IOException {
+        init();
+    }
+
+    private void init() throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
+
+        KeyStore keyStore = KeyStore.getInstance("PKCS12");
+        FileInputStream instream = new FileInputStream(new File(Configure.getCertLocalPath()));//加载本地的证书进行https加密传输
+        try {
+            keyStore.load(instream, Configure.getCertPassword().toCharArray());//设置证书密码
+        } catch (CertificateException e) {
+            e.printStackTrace();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } finally {
+            instream.close();
+        }
+
+        // Trust own CA and all self-signed certs
+        SSLContext sslcontext = SSLContexts.custom()
+                .loadKeyMaterial(keyStore, Configure.getCertPassword().toCharArray())
+                .build();
+        // Allow TLSv1 protocol only
+        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
+                sslcontext,
+                new String[]{"TLSv1"},
+                null,
+                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
+
+        httpClient = HttpClients.custom()
+                .setSSLSocketFactory(sslsf)
+                .build();
+
+        //根据默认超时限制初始化requestConfig
+        requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
+
+        hasInit = true;
+    }
+
+    /**
+     * 通过Https往API post xml数据
+     *
+     * @param url    API地址
+     * @param xmlObj 要提交的XML数据对象
+     * @return API回包的实际数据
+     * @throws IOException
+     * @throws KeyStoreException
+     * @throws UnrecoverableKeyException
+     * @throws NoSuchAlgorithmException
+     * @throws KeyManagementException
+     */
+
+    public String sendPost(String url, Object xmlObj) throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
+
+        if (!hasInit) {
+            init();
+        }
+
+        String result = null;
+
+        HttpPost httpPost = new HttpPost(url);
+
+        //解决XStream对出现双下划线的bug
+        XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
+
+        //将要提交给API的数据对象转换成XML格式数据Post给API
+        String postDataXML = xStreamForRequestPostData.toXML(xmlObj);
+
+//      Util.log("API,POST过去的数据是:\n"+postDataXML);
+
+        //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
+        StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
+        httpPost.addHeader("Content-Type", "text/xml");
+        httpPost.setEntity(postEntity);
+
+        //设置请求器的配置
+        httpPost.setConfig(requestConfig);
+
+
+        try {
+            HttpResponse response = httpClient.execute(httpPost);
+
+            HttpEntity entity = response.getEntity();
+
+            result = EntityUtils.toString(entity, "UTF-8");
+
+        } catch (Exception e) {
+           e.printStackTrace();
+
+        } finally {
+            httpPost.abort();
+        }
+
+        return result;
+    }
+
+    /**
+     * 设置连接超时时间
+     *
+     * @param socketTimeout 连接时长,默认10秒
+     */
+    public void setSocketTimeout(int socketTimeout) {
+        this.socketTimeout = socketTimeout;
+        resetRequestConfig();
+    }
+
+    /**
+     * 设置传输超时时间
+     *
+     * @param connectTimeout 传输时长,默认30秒
+     */
+    public void setConnectTimeout(int connectTimeout) {
+    	this.connectTimeout = connectTimeout;
+        resetRequestConfig();
+    }
+
+    private void resetRequestConfig(){
+        requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
+    }
+
+    /**
+     * 允许商户自己做更高级更复杂的请求器配置
+     *
+     * @param requestConfig 设置HttpsRequest的请求器配置
+     */
+    public void setRequestConfig(RequestConfig requestConfig) {
+    	this.requestConfig = requestConfig;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/HttpsRequest_2.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/HttpsRequest_2.java
new file mode 100644
index 0000000..606fb11
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/HttpsRequest_2.java
@@ -0,0 +1,188 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.io.File;
+
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLContexts;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+import com.tencent.service.IServiceRequest;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
+
+/**
+ * User: rizenguo
+ * Date: 2014/10/29
+ * Time: 14:36
+ */
+@SuppressWarnings("deprecation")
+public class HttpsRequest_2 implements IServiceRequest{
+
+    public interface ResultListener {
+        public void onConnectionPoolTimeoutError();
+    }
+
+    //表示请求器是否已经做了初始化工作
+    private boolean hasInit = false;
+
+    //连接超时时间,默认10秒
+    private int socketTimeout = 10000;
+
+    //传输超时时间,默认30秒
+    private int connectTimeout = 30000;
+
+    //请求器的配置
+    private RequestConfig requestConfig;
+
+    //HTTP请求器
+    private CloseableHttpClient httpClient;
+
+    public HttpsRequest_2() throws UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, IOException {
+        init();
+    }
+
+    private void init() throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
+
+        KeyStore keyStore = KeyStore.getInstance("PKCS12");
+        FileInputStream instream = new FileInputStream(new File(Configure.getCertLocalPath_2()));//加载本地的证书进行https加密传输
+        try {
+            keyStore.load(instream, Configure.getCertPassword_2().toCharArray());//设置证书密码
+        } catch (CertificateException e) {
+            e.printStackTrace();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } finally {
+            instream.close();
+        }
+
+        // Trust own CA and all self-signed certs
+        SSLContext sslcontext = SSLContexts.custom()
+                .loadKeyMaterial(keyStore, Configure.getCertPassword_2().toCharArray())
+                .build();
+        // Allow TLSv1 protocol only
+        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
+                sslcontext,
+                new String[]{"TLSv1"},
+                null,
+                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
+
+        httpClient = HttpClients.custom()
+                .setSSLSocketFactory(sslsf)
+                .build();
+
+        //根据默认超时限制初始化requestConfig
+        requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
+
+        hasInit = true;
+    }
+
+    /**
+     * 通过Https往API post xml数据
+     *
+     * @param url    API地址
+     * @param xmlObj 要提交的XML数据对象
+     * @return API回包的实际数据
+     * @throws IOException
+     * @throws KeyStoreException
+     * @throws UnrecoverableKeyException
+     * @throws NoSuchAlgorithmException
+     * @throws KeyManagementException
+     */
+
+    public String sendPost(String url, Object xmlObj) throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
+
+        if (!hasInit) {
+            init();
+        }
+
+        String result = null;
+
+        HttpPost httpPost = new HttpPost(url);
+
+        //解决XStream对出现双下划线的bug
+        XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
+
+        //将要提交给API的数据对象转换成XML格式数据Post给API
+        String postDataXML = xStreamForRequestPostData.toXML(xmlObj);
+
+//      Util.log("API,POST过去的数据是:\n"+postDataXML);
+
+        //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
+        StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
+        httpPost.addHeader("Content-Type", "text/xml");
+        httpPost.setEntity(postEntity);
+
+        //设置请求器的配置
+        httpPost.setConfig(requestConfig);
+
+
+        try {
+            HttpResponse response = httpClient.execute(httpPost);
+
+            HttpEntity entity = response.getEntity();
+
+            result = EntityUtils.toString(entity, "UTF-8");
+
+        } catch (Exception e) {
+           e.printStackTrace();
+
+        } finally {
+            httpPost.abort();
+        }
+
+        return result;
+    }
+
+    /**
+     * 设置连接超时时间
+     *
+     * @param socketTimeout 连接时长,默认10秒
+     */
+    public void setSocketTimeout(int socketTimeout) {
+        this.socketTimeout = socketTimeout;
+        resetRequestConfig();
+    }
+
+    /**
+     * 设置传输超时时间
+     *
+     * @param connectTimeout 传输时长,默认30秒
+     */
+    public void setConnectTimeout(int connectTimeout) {
+    	this.connectTimeout = connectTimeout;
+        resetRequestConfig();
+    }
+
+    private void resetRequestConfig(){
+        requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
+    }
+
+    /**
+     * 允许商户自己做更高级更复杂的请求器配置
+     *
+     * @param requestConfig 设置HttpsRequest的请求器配置
+     */
+    public void setRequestConfig(RequestConfig requestConfig) {
+    	this.requestConfig = requestConfig;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/IWXPayDomain.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/IWXPayDomain.java
new file mode 100644
index 0000000..6c91eb0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/IWXPayDomain.java
@@ -0,0 +1,42 @@
+package com.ruoyi.order.util.tencent.common;
+
+/**
+ * 域名管理,实现主备域名自动切换
+ */
+public abstract interface IWXPayDomain {
+    /**
+     * 上报域名网络状况
+     * @param domain 域名。 比如:api.mch.weixin.qq.com
+     * @param elapsedTimeMillis 耗时
+     * @param ex 网络请求中出现的异常。
+     *           null表示没有异常
+     *           ConnectTimeoutException,表示建立网络连接异常
+     *           UnknownHostException, 表示dns解析异常
+     */
+    abstract void report(final String domain, long elapsedTimeMillis, final Exception ex);
+
+    /**
+     * 获取域名
+     * @param config 配置
+     * @return 域名
+     */
+    abstract DomainInfo getDomain(final WXPayConfig config);
+
+    static class DomainInfo{
+        public String domain;       //域名
+        public boolean primaryDomain;     //该域名是否为主域名。例如:api.mch.weixin.qq.com为主域名
+        public DomainInfo(String domain, boolean primaryDomain) {
+            this.domain = domain;
+            this.primaryDomain = primaryDomain;
+        }
+
+        @Override
+        public String toString() {
+            return "DomainInfo{" +
+                    "domain='" + domain + '\'' +
+                    ", primaryDomain=" + primaryDomain +
+                    '}';
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/JsapiTicketUtil.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/JsapiTicketUtil.java
new file mode 100644
index 0000000..6f86f99
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/JsapiTicketUtil.java
@@ -0,0 +1,157 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.json.JSONObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+/***
+ * @author V型知识库  www.vxzsk.com
+ *
+ */
+public class JsapiTicketUtil {
+     
+    /***
+     * 模拟get请求
+     * @param url
+     * @param charset
+     * @param timeout
+     * @return
+     */
+     public static String sendGet(String url, String charset, int timeout)
+      {
+        String result = "";
+        try
+        {
+          URL u = new URL(url);
+          try
+          {
+            URLConnection conn = u.openConnection();
+            conn.connect();
+            conn.setConnectTimeout(timeout);
+            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
+            String line="";
+            while ((line = in.readLine()) != null)
+            {
+             
+              result = result + line;
+            }
+            in.close();
+          } catch (IOException e) {
+            return result;
+          }
+        }
+        catch (MalformedURLException e)
+        {
+          return result;
+        }
+       
+        return result;
+      }
+     /***
+      * 获取acess_token 
+      * 来源www.vxzsk.com
+      * @return
+      */
+     public static String getAccessToken(){
+            String appid=Configure.getGappid();//应用IDwxa15aa9429f9646fd
+            String appSecret="3f14c55e683735aefd19271959e27187";//(应用密钥)3f14c55e683735aefd19271959e27187
+            String url ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+appSecret+"";
+            String backData=sendGet(url, "utf-8", 10000);
+            String accessToken = (String) JSONObject.fromObject(backData).get("access_token");
+            return accessToken;
+     }
+    /***
+      * 获取jsapiTicket
+      * 来源 www.vxzsk.com
+      * @return
+      */
+    public static String getJSApiTicket(){ 
+        //获取token
+        String acess_token= JsapiTicketUtil.getAccessToken();
+           
+        String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+acess_token+"&type=jsapi";  
+        String backData=sendGet(urlStr, "utf-8", 10000);  
+        String ticket = (String) JSONObject.fromObject(backData).get("ticket");  
+        return  ticket;  
+           
+    }  
+    /**
+     * 获取用户openid(公众号)
+     * @return
+     */
+    public static String getOpenId(String code){ 
+           
+        String urlStr = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+Configure.getGappid()+"&secret=3f14c55e683735aefd19271959e27187&code="+code+"&grant_type=authorization_code";  
+        String backData=sendGet(urlStr, "utf-8", 10000);  
+        String ticket = (String) JSONObject.fromObject(backData).get("openid");  
+        return  ticket;            
+    }  
+    
+    /**
+     * 获取用户openid(小程序)
+     * @return
+     */
+    public static String getOpenId2(String code){ 
+           
+        String urlStr = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+Configure.getXappid()+"&secret=9a38480b9c220688d4fed071d490d732&code="+code+"&grant_type=authorization_code";  
+        String backData=sendGet(urlStr, "utf-8", 10000);  
+        String ticket = (String) JSONObject.fromObject(backData).get("openid");  
+        return  ticket;            
+    } 
+    /**
+     * 获取请求用户信息的access_token
+     *
+     * @param code
+     * @return
+     */
+//    public static Map<String, String> getUserInfoAccessToken(String code) {
+//        JsonObject object = null;
+//        Map<String, String> data = new HashMap();
+//        try {
+//            String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
+//                                       "wx614b91446fc49a0e","ca2288ec80d4e05976425a6508e9b7", code);
+//            DefaultHttpClient httpClient = new DefaultHttpClient();
+//            HttpGet httpGet = new HttpGet(url);
+//            HttpResponse httpResponse = httpClient.execute(httpGet);
+//            HttpEntity httpEntity = httpResponse.getEntity();
+//            String tokens = EntityUtils.toString(httpEntity, "utf-8");
+//            Gson token_gson = new Gson();
+//            object = token_gson.fromJson(tokens, JsonObject.class);
+//            data.put("openid", object.get("openid").toString().replaceAll("\"", ""));
+//            data.put("access_token", object.get("access_token").toString().replaceAll("\"", ""));
+//        } catch (Exception ex) {
+//        }
+//        return data;
+//    }
+    public static String getCode(){
+    	JsonObject object = null;
+        Map<String, String> data = new HashMap();
+        try {
+        	String codes = String.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect",
+                    "wx614b91446fc49a0e", "http://www.txciot.com/resources/html/first.html", "snsapi_base", "xxxx_state");
+            DefaultHttpClient httpClient = new DefaultHttpClient();
+           return sendGet(codes, "utf-8", 10000);
+        } catch (Exception ex) {
+        	return "";
+        }
+    }
+    public static void main(String[] args) {
+    	System.out.println(URLEncoder.encode("http://www.txciot.com/resources/html/first.html"));
+    	//System.out.println(getUserInfoAccessToken(getCode()));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Log.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Log.java
new file mode 100644
index 0000000..7df776e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Log.java
@@ -0,0 +1,59 @@
+package com.ruoyi.order.util.tencent.common;
+
+import org.slf4j.Logger;
+
+/**
+ * User: rizenguo
+ * Date: 2014/11/12
+ * Time: 14:32
+ */
+public class Log {
+
+    public static final String LOG_TYPE_TRACE = "logTypeTrace";
+    public static final String LOG_TYPE_DEBUG = "logTypeDebug";
+    public static final String LOG_TYPE_INFO = "logTypeInfo";
+    public static final String LOG_TYPE_WARN = "logTypeWarn";
+    public static final String LOG_TYPE_ERROR = "logTypeError";
+
+    //打印日志
+    private Logger logger;
+
+    public Log(Logger log){
+        logger = log;
+    }
+
+    public void t(String s){
+        logger.trace(s);
+    }
+
+    public void d(String s){
+        logger.debug(s);
+    }
+
+    public void i(String s){
+        logger.info(s);
+    }
+
+    public void w(String s){
+        logger.warn(s);
+    }
+
+    public void e(String s){
+        logger.error(s);
+    }
+
+    public void log(String type,String s){
+        if(type.equals(Log.LOG_TYPE_TRACE)){
+            t(s);
+        }else if(type.equals(Log.LOG_TYPE_DEBUG)){
+            d(s);
+        }else if(type.equals(Log.LOG_TYPE_INFO)){
+            i(s);
+        }else if(type.equals(Log.LOG_TYPE_WARN)){
+            w(s);
+        }else if(type.equals(Log.LOG_TYPE_ERROR)){
+            e(s);
+        }
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/MD5.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/MD5.java
new file mode 100644
index 0000000..00cbe6d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/MD5.java
@@ -0,0 +1,59 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.security.MessageDigest;
+
+/**
+ * User: rizenguo
+ * Date: 2014/10/23
+ * Time: 15:43
+ */
+public class MD5 {
+    private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
+            "8", "9", "a", "b", "c", "d", "e", "f"};
+
+    /**
+     * 转换字节数组为16进制字串
+     * @param b 字节数组
+     * @return 16进制字串
+     */
+    public static String byteArrayToHexString(byte[] b) {
+        StringBuilder resultSb = new StringBuilder();
+        for (byte aB : b) {
+            resultSb.append(byteToHexString(aB));
+        }
+        return resultSb.toString();
+    }
+
+    /**
+     * 转换byte到16进制
+     * @param b 要转换的byte
+     * @return 16进制格式
+     */
+    private static String byteToHexString(byte b) {
+        int n = b;
+        if (n < 0) {
+            n = 256 + n;
+        }
+        int d1 = n / 16;
+        int d2 = n % 16;
+        return hexDigits[d1] + hexDigits[d2];
+    }
+
+    /**
+     * MD5编码
+     * @param origin 原始字符串
+     * @return 经过MD5加密之后的结果
+     */
+    public static String MD5Encode(String origin) {
+        String resultString = null;
+        try {
+            resultString = origin;
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            resultString = byteArrayToHexString(md.digest(resultString.getBytes("UTF-8")));//微信支付有汉字时出现签名错误的解决办法
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return resultString;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/RandomStringGenerator.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/RandomStringGenerator.java
new file mode 100644
index 0000000..3f6596f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/RandomStringGenerator.java
@@ -0,0 +1,28 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.util.Random;
+
+/**
+ * User: rizenguo
+ * Date: 2014/10/29
+ * Time: 14:18
+ */
+public class RandomStringGenerator {
+
+    /**
+     * 获取一定长度的随机字符串
+     * @param length 指定字符串长度
+     * @return 一定长度的字符串
+     */
+    public static String getRandomStringByLength(int length) {
+        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
+        Random random = new Random();
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < length; i++) {
+            int number = random.nextInt(base.length());
+            sb.append(base.charAt(number));
+        }
+        return sb.toString();
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Signature.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Signature.java
new file mode 100644
index 0000000..89f3439
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Signature.java
@@ -0,0 +1,122 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.xml.sax.SAXException;
+
+/**
+ * User: tzj
+ * Date: 2017/06/17
+ * Time: 15:23
+ */
+public class Signature {
+    /**
+     * 签名算法
+     * @param o 要参与签名的数据对象
+     * @return 签名
+     * @throws IllegalAccessException
+     */
+    public static String getSign(Object o) throws IllegalAccessException {
+        ArrayList<String> list = new ArrayList<String>();
+        Class<? extends Object> cls = o.getClass();
+        Field[] fields = cls.getDeclaredFields();
+        for (Field f : fields) {
+            f.setAccessible(true);
+            if (f.get(o) != null && f.get(o) != "") {
+                list.add(f.getName() + "=" + f.get(o) + "&");
+            }
+        }
+        int size = list.size();
+        String [] arrayToSort = list.toArray(new String[size]);
+        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
+        StringBuilder sb = new StringBuilder();
+        for(int i = 0; i < size; i ++) {
+            sb.append(arrayToSort[i]);
+        }
+        String result = sb.toString();
+        result += "key=" + Configure.getKey();
+        Util.log("Sign Before MD5:" + result);
+        result = MD5.MD5Encode(result).toUpperCase();
+        Util.log("Sign Result:" + result);
+        return result;
+    }
+
+    public static String getSign(Integer apptype,Map<String,Object> map){
+        ArrayList<String> list = new ArrayList<String>();
+        for(Map.Entry<String,Object> entry:map.entrySet()){
+            if(entry.getValue()!=""){
+                list.add(entry.getKey() + "=" + entry.getValue() + "&");
+            }
+        }
+        int size = list.size();
+        String [] arrayToSort = list.toArray(new String[size]);
+        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
+        StringBuilder sb = new StringBuilder();
+        for(int i = 0; i < size; i ++) {
+            sb.append(arrayToSort[i]);
+        }
+        String result = sb.toString();
+			result += "key=" + Configure.getKey();
+        
+//        Util.log("Sign Before MD5:" + result);
+        result = MD5.MD5Encode(result).toUpperCase();
+//        Util.log("Sign Result:" + result);
+        return result;
+    }
+
+    /**
+     * 从API返回的XML数据里面重新计算一次签名
+     * @param responseString API返回的XML数据
+     * @return 新鲜出炉的签名
+     * @throws ParserConfigurationException
+     * @throws IOException
+     * @throws SAXException
+     */
+    public static String getSignFromResponseString(Integer apptype, String responseString) throws IOException, SAXException, ParserConfigurationException {
+        Map<String,Object> map = XMLParser.getMapFromXML(responseString);
+        //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
+        map.put("sign","");
+        //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
+        return Signature.getSign(apptype, map);
+    }
+
+    /**
+     * 检验API返回的数据里面的签名是否合法,避免数据在传输的过程中被第三方篡改
+     * @param responseString API返回的XML数据字符串
+     * @return API签名是否合法
+     * @throws ParserConfigurationException
+     * @throws IOException
+     * @throws SAXException
+     */
+    public static boolean checkIsSignValidFromResponseString(Integer apptype, String responseString) throws ParserConfigurationException, IOException, SAXException {
+
+        Map<String,Object> map = XMLParser.getMapFromXML(responseString);
+        Util.log(map.toString());
+
+        String signFromAPIResponse = map.get("sign").toString();
+        if(signFromAPIResponse=="" || signFromAPIResponse == null){
+            Util.log("API返回的数据签名数据不存在,有可能被第三方篡改!!!");
+            return false;
+        }
+        Util.log("服务器回包里面的签名是:" + signFromAPIResponse);
+        //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
+        map.put("sign","");
+        //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
+        String signForAPIResponse = Signature.getSign(apptype, map);
+
+        if(!signForAPIResponse.equals(signFromAPIResponse)){
+            //签名验不过,表示这个API返回的数据有可能已经被篡改了
+            Util.log("API返回的数据签名验证不通过,有可能被第三方篡改!!!");
+            return false;
+        }
+        Util.log("恭喜,API返回的数据签名验证通过!!!");
+        return true;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Util.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Util.java
new file mode 100644
index 0000000..368aa0b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/Util.java
@@ -0,0 +1,126 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.io.ByteArrayInputStream;
+
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.thoughtworks.xstream.XStream;
+
+
+/**
+ * User: tzj
+ * Date: 2017/08/23
+ * Time: 14:59
+ */
+public class Util {
+
+    Logger logger= LoggerFactory.getLogger(getClass());
+    /**
+     * 通过反射的方式遍历对象的属性和属性值,方便调试
+     *
+     * @param o 要遍历的对象
+     * @throws Exception
+     */
+    public static void reflect(Object o) throws Exception {
+        Class<? extends Object> cls = o.getClass();
+        Field[] fields = cls.getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            Field f = fields[i];
+            f.setAccessible(true);
+            Util.log(f.getName() + " -> " + f.get(o));
+        }
+    }
+
+    public static byte[] readInput(InputStream in) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        int len = 0;
+        byte[] buffer = new byte[1024];
+        while ((len = in.read(buffer)) > 0) {
+            out.write(buffer, 0, len);
+        }
+        out.close();
+        in.close();
+        return out.toByteArray();
+    }
+
+    public static String inputStreamToString(InputStream is) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        int i;
+        while ((i = is.read()) != -1) {
+            baos.write(i);
+        }
+        return baos.toString();
+    }
+
+
+    public static InputStream getStringStream(String sInputString) {
+        ByteArrayInputStream tInputStringStream = null;
+        if (sInputString != null && !sInputString.trim().equals("")) {
+        	try {
+        		tInputStringStream = new ByteArrayInputStream(sInputString.getBytes("UTF-8"));
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+        }
+        return tInputStringStream;
+    }
+
+    public static Object getObjectFromXML(String xml, Class<?> tClass) {
+        //将从API返回的XML数据映射到Java对象
+        XStream xStreamForResponseData = new XStream();
+        xStreamForResponseData.alias("xml", tClass);
+        xStreamForResponseData.ignoreUnknownElements();//暂时忽略掉一些新增的字段
+        return xStreamForResponseData.fromXML(xml);
+    }
+
+    public static String getStringFromMap(Map<String, Object> map, String key, String defaultValue) {
+        if (key == "" || key == null) {
+            return defaultValue;
+        }
+        String result = (String) map.get(key);
+        if (result == null) {
+            return defaultValue;
+        } else {
+            return result;
+        }
+    }
+
+    public static int getIntFromMap(Map<String, Object> map, String key) {
+        if (key == "" || key == null) {
+            return 0;
+        }
+        if (map.get(key) == null) {
+            return 0;
+        }
+        return Integer.parseInt((String) map.get(key));
+    }
+
+    /**
+     * 打log接口
+     * @param log 要打印的log字符串
+     * @return 返回log
+     */
+    public static String log(Object log){
+        System.out.println(log.toString());
+        return log.toString();
+    }
+
+    /**
+     * 读取本地的xml数据,一般用来自测用
+     * @param localPath 本地xml文件路径
+     * @return 读到的xml字符串
+     */
+    public static String getLocalXMLString(String localPath) throws IOException {
+        return Util.inputStreamToString(Util.class.getResourceAsStream(localPath));
+    }
+
+}
+
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayConfig.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayConfig.java
new file mode 100644
index 0000000..7ea0fb3
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayConfig.java
@@ -0,0 +1,103 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.io.InputStream;
+
+public abstract class WXPayConfig {
+
+
+
+    /**
+     * 获取 App ID
+     *
+     * @return App ID
+     */
+	public abstract String getAppID();
+
+
+    /**
+     * 获取 Mch ID
+     *
+     * @return Mch ID
+     */
+    public abstract String getMchID();
+
+
+    /**
+     * 获取 API 密钥
+     *
+     * @return API密钥
+     */
+    public abstract String getKey();
+
+
+    /**
+     * 获取商户证书内容
+     *
+     * @return 商户证书内容
+     */
+    public abstract InputStream getCertStream();
+
+    /**
+     * HTTP(S) 连接超时时间,单位毫秒
+     *
+     * @return
+     */
+    public int getHttpConnectTimeoutMs() {
+        return 6*1000;
+    }
+
+    /**
+     * HTTP(S) 读数据超时时间,单位毫秒
+     *
+     * @return
+     */
+    public int getHttpReadTimeoutMs() {
+        return 8*1000;
+    }
+
+    /**
+     * 获取WXPayDomain, 用于多域名容灾自动切换
+     * @return
+     */
+    public abstract IWXPayDomain getWXPayDomain();
+
+    /**
+     * 是否自动上报。
+     * 若要关闭自动上报,子类中实现该函数返回 false 即可。
+     *
+     * @return
+     */
+    public boolean shouldAutoReport() {
+        return true;
+    }
+
+    /**
+     * 进行健康上报的线程的数量
+     *
+     * @return
+     */
+    public int getReportWorkerNum() {
+        return 6;
+    }
+
+
+    /**
+     * 健康上报缓存消息的最大数量。会有线程去独立上报
+     * 粗略计算:加入一条消息200B,10000消息占用空间 2000 KB,约为2MB,可以接受
+     *
+     * @return
+     */
+    public int getReportQueueMaxSize() {
+        return 10000;
+    }
+
+    /**
+     * 批量上报,一次最多上报多个数据
+     *
+     * @return
+     */
+    public int getReportBatchSize() {
+        return 10;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayConstants.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayConstants.java
new file mode 100644
index 0000000..cfe76e6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayConstants.java
@@ -0,0 +1,52 @@
+package com.ruoyi.order.util.tencent.common;
+
+/**
+ * 常量
+ */
+public class WXPayConstants {
+
+    public enum SignType {
+        MD5, HMACSHA256
+    }
+
+    public static final String DOMAIN_API = "api.mch.weixin.qq.com";
+    public static final String DOMAIN_API2 = "api2.mch.weixin.qq.com";
+    public static final String DOMAIN_APIHK = "apihk.mch.weixin.qq.com";
+    public static final String DOMAIN_APIUS = "apius.mch.weixin.qq.com";
+
+
+    public static final String FAIL     = "FAIL";
+    public static final String SUCCESS  = "SUCCESS";
+    public static final String HMACSHA256 = "HMAC-SHA256";
+    public static final String MD5 = "MD5";
+
+    public static final String FIELD_SIGN = "sign";
+    public static final String FIELD_SIGN_TYPE = "sign_type";
+
+    public static final String MICROPAY_URL_SUFFIX     = "/pay/micropay";
+    public static final String UNIFIEDORDER_URL_SUFFIX = "/pay/unifiedorder";
+    public static final String ORDERQUERY_URL_SUFFIX   = "/pay/orderquery";
+    public static final String REVERSE_URL_SUFFIX      = "/secapi/pay/reverse";
+    public static final String CLOSEORDER_URL_SUFFIX   = "/pay/closeorder";
+    public static final String REFUND_URL_SUFFIX       = "/secapi/pay/refund";
+    public static final String REFUNDQUERY_URL_SUFFIX  = "/pay/refundquery";
+    public static final String DOWNLOADBILL_URL_SUFFIX = "/pay/downloadbill";
+    public static final String REPORT_URL_SUFFIX       = "/payitil/report";
+    public static final String SHORTURL_URL_SUFFIX     = "/tools/shorturl";
+    public static final String AUTHCODETOOPENID_URL_SUFFIX = "/tools/authcodetoopenid";
+
+    // sandbox
+    public static final String SANDBOX_MICROPAY_URL_SUFFIX     = "/sandboxnew/pay/micropay";
+    public static final String SANDBOX_UNIFIEDORDER_URL_SUFFIX = "/sandboxnew/pay/unifiedorder";
+    public static final String SANDBOX_ORDERQUERY_URL_SUFFIX   = "/sandboxnew/pay/orderquery";
+    public static final String SANDBOX_REVERSE_URL_SUFFIX      = "/sandboxnew/secapi/pay/reverse";
+    public static final String SANDBOX_CLOSEORDER_URL_SUFFIX   = "/sandboxnew/pay/closeorder";
+    public static final String SANDBOX_REFUND_URL_SUFFIX       = "/sandboxnew/secapi/pay/refund";
+    public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX  = "/sandboxnew/pay/refundquery";
+    public static final String SANDBOX_DOWNLOADBILL_URL_SUFFIX = "/sandboxnew/pay/downloadbill";
+    public static final String SANDBOX_REPORT_URL_SUFFIX       = "/sandboxnew/payitil/report";
+    public static final String SANDBOX_SHORTURL_URL_SUFFIX     = "/sandboxnew/tools/shorturl";
+    public static final String SANDBOX_AUTHCODETOOPENID_URL_SUFFIX = "/sandboxnew/tools/authcodetoopenid";
+
+}
+
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayUtil.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayUtil.java
new file mode 100644
index 0000000..a4551ca
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/WXPayUtil.java
@@ -0,0 +1,301 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.*;
+import java.security.MessageDigest;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ruoyi.order.util.tencent.common.WXPayConstants.SignType;
+
+
+public class WXPayUtil {
+
+    /**
+     * XML格式字符串转换为Map
+     *
+     * @param strXML XML字符串
+     * @return XML数据转换后的Map
+     * @throws Exception
+     */
+    public static Map<String, String> xmlToMap(String strXML) throws Exception {
+        try {
+            Map<String, String> data = new HashMap<String, String>();
+            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
+            org.w3c.dom.Document doc = documentBuilder.parse(stream);
+            doc.getDocumentElement().normalize();
+            NodeList nodeList = doc.getDocumentElement().getChildNodes();
+            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
+                Node node = nodeList.item(idx);
+                if (node.getNodeType() == Node.ELEMENT_NODE) {
+                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
+                    data.put(element.getNodeName(), element.getTextContent());
+                }
+            }
+            try {
+                stream.close();
+            } catch (Exception ex) {
+                // do nothing
+            }
+            return data;
+        } catch (Exception ex) {
+            WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
+            throw ex;
+        }
+
+    }
+
+    /**
+     * 将Map转换为XML格式的字符串
+     *
+     * @param data Map类型数据
+     * @return XML格式的字符串
+     * @throws Exception
+     */
+    public static String mapToXml(Map<String, String> data) throws Exception {
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
+        org.w3c.dom.Document document = documentBuilder.newDocument();
+        org.w3c.dom.Element root = document.createElement("xml");
+        document.appendChild(root);
+        for (String key: data.keySet()) {
+            String value = data.get(key);
+            if (value == null) {
+                value = "";
+            }
+            value = value.trim();
+            org.w3c.dom.Element filed = document.createElement(key);
+            filed.appendChild(document.createTextNode(value));
+            root.appendChild(filed);
+        }
+        TransformerFactory tf = TransformerFactory.newInstance();
+        Transformer transformer = tf.newTransformer();
+        DOMSource source = new DOMSource(document);
+        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        StringWriter writer = new StringWriter();
+        StreamResult result = new StreamResult(writer);
+        transformer.transform(source, result);
+        String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
+        try {
+            writer.close();
+        }
+        catch (Exception ex) {
+        }
+        return output;
+    }
+
+
+    /**
+     * 生成带有 sign 的 XML 格式字符串
+     *
+     * @param data Map类型数据
+     * @param key API密钥
+     * @return 含有sign字段的XML
+     */
+    public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {
+        return generateSignedXml(data, key, SignType.MD5);
+    }
+
+    /**
+     * 生成带有 sign 的 XML 格式字符串
+     *
+     * @param data Map类型数据
+     * @param key API密钥
+     * @param signType 签名类型
+     * @return 含有sign字段的XML
+     */
+    public static String generateSignedXml(final Map<String, String> data, String key, SignType signType) throws Exception {
+        String sign = generateSignature(data, key, signType);
+        data.put(WXPayConstants.FIELD_SIGN, sign);
+        return mapToXml(data);
+    }
+
+
+    /**
+     * 判断签名是否正确
+     *
+     * @param xmlStr XML格式数据
+     * @param key API密钥
+     * @return 签名是否正确
+     * @throws Exception
+     */
+    public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
+        Map<String, String> data = xmlToMap(xmlStr);
+        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
+            return false;
+        }
+        String sign = data.get(WXPayConstants.FIELD_SIGN);
+        return generateSignature(data, key).equals(sign);
+    }
+
+    /**
+     * 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。
+     *
+     * @param data Map类型数据
+     * @param key API密钥
+     * @return 签名是否正确
+     * @throws Exception
+     */
+    public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
+        return isSignatureValid(data, key, SignType.MD5);
+    }
+
+    /**
+     * 判断签名是否正确,必须包含sign字段,否则返回false。
+     *
+     * @param data Map类型数据
+     * @param key API密钥
+     * @param signType 签名方式
+     * @return 签名是否正确
+     * @throws Exception
+     */
+    public static boolean isSignatureValid(Map<String, String> data, String key, SignType signType) throws Exception {
+        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
+            return false;
+        }
+        String sign = data.get(WXPayConstants.FIELD_SIGN);
+        return generateSignature(data, key, signType).equals(sign);
+    }
+
+    /**
+     * 生成签名
+     *
+     * @param data 待签名数据
+     * @param key API密钥
+     * @return 签名
+     */
+    public static String generateSignature(final Map<String, String> data, String key) throws Exception {
+        return generateSignature(data, key, SignType.MD5);
+    }
+
+    /**
+     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
+     *
+     * @param data 待签名数据
+     * @param key API密钥
+     * @param signType 签名方式
+     * @return 签名
+     */
+    public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {
+        Set<String> keySet = data.keySet();
+        String[] keyArray = keySet.toArray(new String[keySet.size()]);
+        Arrays.sort(keyArray);
+        StringBuilder sb = new StringBuilder();
+        for (String k : keyArray) {
+            if (k.equals(WXPayConstants.FIELD_SIGN)) {
+                continue;
+            }
+            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
+                sb.append(k).append("=").append(data.get(k).trim()).append("&");
+        }
+        sb.append("key=").append(key);
+        if (SignType.MD5.equals(signType)) {
+            return MD5(sb.toString()).toUpperCase();
+        }
+        else if (SignType.HMACSHA256.equals(signType)) {
+            return HMACSHA256(sb.toString(), key);
+        }
+        else {
+            throw new Exception(String.format("Invalid sign_type: %s", signType));
+        }
+    }
+
+
+    /**
+     * 获取随机字符串 Nonce Str
+     *
+     * @return String 随机字符串
+     */
+    public static String generateNonceStr() {
+        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
+    }
+
+
+    /**
+     * 生成 MD5
+     *
+     * @param data 待处理数据
+     * @return MD5结果
+     */
+    public static String MD5(String data) throws Exception {
+        java.security.MessageDigest md = MessageDigest.getInstance("MD5");
+        byte[] array = md.digest(data.getBytes("UTF-8"));
+        StringBuilder sb = new StringBuilder();
+        for (byte item : array) {
+            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
+        }
+        return sb.toString().toUpperCase();
+    }
+
+    /**
+     * 生成 HMACSHA256
+     * @param data 待处理数据
+     * @param key 密钥
+     * @return 加密结果
+     * @throws Exception
+     */
+    public static String HMACSHA256(String data, String key) throws Exception {
+        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
+        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
+        sha256_HMAC.init(secret_key);
+        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
+        StringBuilder sb = new StringBuilder();
+        for (byte item : array) {
+            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
+        }
+        return sb.toString().toUpperCase();
+    }
+
+    /**
+     * 日志
+     * @return
+     */
+    public static Logger getLogger() {
+        Logger logger = LoggerFactory.getLogger("wxpay java sdk");
+        return logger;
+    }
+
+    /**
+     * 获取当前时间戳,单位秒
+     * @return
+     */
+    public static long getCurrentTimestamp() {
+        return System.currentTimeMillis()/1000;
+    }
+
+    /**
+     * 获取当前时间戳,单位毫秒
+     * @return
+     */
+    public static long getCurrentTimestampMs() {
+        return System.currentTimeMillis();
+    }
+
+    /**
+     * 生成 uuid, 即用来标识一笔单,也用做 nonce_str
+     * @return
+     */
+    public static String generateUUID() {
+        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/XMLParser.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/XMLParser.java
new file mode 100644
index 0000000..c6e4a1f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/XMLParser.java
@@ -0,0 +1,43 @@
+package com.ruoyi.order.util.tencent.common;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+public class XMLParser {
+
+    public static Map<String,Object> getMapFromXML(String xmlString) throws ParserConfigurationException, IOException, SAXException {
+
+        //这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        InputStream is =  Util.getStringStream(xmlString);
+        Document document = builder.parse(is);
+
+        //获取到document里面的全部结点
+        NodeList allNodes = document.getFirstChild().getChildNodes();
+        Node node;
+        Map<String, Object> map = new HashMap<String, Object>();
+        int i=0;
+        while (i < allNodes.getLength()) {
+            node = allNodes.item(i);
+            if(node instanceof Element){
+                map.put(node.getNodeName(),node.getTextContent());
+            }
+            i++;
+        }
+        return map;
+    }
+    
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_cert.p12 b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_cert.p12
new file mode 100644
index 0000000..07690fc
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_cert.p12
Binary files differ
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_cert.pem b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_cert.pem
new file mode 100644
index 0000000..5435148
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_cert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEbzCCA9igAwIBAgIEAapJajANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
+Q04xEjAQBgNVBAgTCUd1YW5nZG9uZzERMA8GA1UEBxMIU2hlbnpoZW4xEDAOBgNV
+BAoTB1RlbmNlbnQxDDAKBgNVBAsTA1dYRzETMBEGA1UEAxMKTW1wYXltY2hDQTEf
+MB0GCSqGSIb3DQEJARYQbW1wYXltY2hAdGVuY2VudDAeFw0xODAyMDIxMTA3NDRa
+Fw0yODAxMzExMTA3NDRaMIGeMQswCQYDVQQGEwJDTjESMBAGA1UECBMJR3Vhbmdk
+b25nMREwDwYDVQQHEwhTaGVuemhlbjEQMA4GA1UEChMHVGVuY2VudDEOMAwGA1UE
+CxMFTU1QYXkxMzAxBgNVBAMUKuaIkOmDvemprOWPr+aXtuWwmue9kee7nOenkeaK
+gOaciemZkOWFrOWPuDERMA8GA1UEBBMIOTM1NTUzMzUwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDF+apUVzPxdAF2FA8r2kg6aPeLynMRsUE17eW+wPZS
+q8mVMrwACzYePbL5003/snEsEU936qnEiu8t5J6w+74dc3mQMr88FW29jD9MQOYR
+yOeWz+LVKFXqA7sm9Aj+7hFrcjxdjl2FvKoITTSXNbtM71FrhsGXsnW/1Zjl3sSy
+cu2qBq40QNqpefzz2gJ+vbtROy+ZynK7QaSwOtiFZuIbPgYv6W18wmigss6JuVkM
+MZUquK4yDIPhwJ4Dk4lLXak1qqNfplfVKQtOo+MHdfIHnG9Z9q+R4iEvAGF4oxaR
+zeKFk+zir8E8xEngmnH0ESue7fn9qh6q0mO7xTaYaG0HAgMBAAGjggFGMIIBQjAJ
+BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh0iQ0VTLUNBIEdlbmVyYXRlIENlcnRp
+ZmljYXRlIjAdBgNVHQ4EFgQUYkOGN8XaKFwFtBCoEBKwGCnBbtYwgb8GA1UdIwSB
+tzCBtIAUPgUm9iJitBVbiM1kfrDUYqflhnShgZCkgY0wgYoxCzAJBgNVBAYTAkNO
+MRIwEAYDVQQIEwlHdWFuZ2RvbmcxETAPBgNVBAcTCFNoZW56aGVuMRAwDgYDVQQK
+EwdUZW5jZW50MQwwCgYDVQQLEwNXWEcxEzARBgNVBAMTCk1tcGF5bWNoQ0ExHzAd
+BgkqhkiG9w0BCQEWEG1tcGF5bWNoQHRlbmNlbnSCCQC7VJcrvADoVzAOBgNVHQ8B
+Af8EBAMCBsAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQAD
+gYEARXIWwdW50A3JM8BIC94argtpvZXqTj5hWeheeJSDBxNVFv/WzdahqZx7Yokn
+DP/Ac6dekFfvvXR6ujwevEUTFbpSac1h7k7u/URmwH/R2URTevPTrMeg5D+gLeYP
+nEJ+GhyRRAFOoGbN1SoK4f1j6pExpl2GaQ0PVNv7NRVW1tI=
+-----END CERTIFICATE-----
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_key.pem b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_key.pem
new file mode 100644
index 0000000..680a521
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/apiclient_key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDF+apUVzPxdAF2
+FA8r2kg6aPeLynMRsUE17eW+wPZSq8mVMrwACzYePbL5003/snEsEU936qnEiu8t
+5J6w+74dc3mQMr88FW29jD9MQOYRyOeWz+LVKFXqA7sm9Aj+7hFrcjxdjl2FvKoI
+TTSXNbtM71FrhsGXsnW/1Zjl3sSycu2qBq40QNqpefzz2gJ+vbtROy+ZynK7QaSw
+OtiFZuIbPgYv6W18wmigss6JuVkMMZUquK4yDIPhwJ4Dk4lLXak1qqNfplfVKQtO
+o+MHdfIHnG9Z9q+R4iEvAGF4oxaRzeKFk+zir8E8xEngmnH0ESue7fn9qh6q0mO7
+xTaYaG0HAgMBAAECggEBAL1yjrYqxIAX3JYb1/DE7z1F2S0iTD7v+lEbGDEUAiNW
+VI67gAAiumTx8eTzeb5oCbh70CoWmuKDeSHXlqwSGvmf2QJOLYXXk65BGQllSURX
+lpZQ1OXZtW08qMk72afqNS02oeF9LK2fvq43A053koaqtKVKzNLXaaprQecm599C
+P+BdahdKk6SE39cOB9fMfX1s5BZRJUhIKNBmcEBsgo9xtKTvgvbgBkSvFBd2ycMo
+5KRUbquytqIfwDJTETn7FZqh86+BgLOsWEQZ+1ByEJkFNdOGfjz0HVxNMY60j42D
+u9fsIMFup+a/oP190atMSt+GE6ZjgQit/LsF7BrPaiECgYEA7uUDZIpQ1j07MZP+
+CFMGIE8aTlhvbWho67HCCLDAAv2ZdOSusV66iMzEfDkfOcj9fp8OlfbK2ocUCkS5
+5hQAuAk4O8KTmbGgf71gyFZzddZkilc1UAgHVMj9wVp2PfLmpb6iFhazd4enwTPs
+TKxogxfXWRQKQqkCnunOSS7m7V8CgYEA1CaXqMWm2v52FHN8dl8AnH6YjwOQpNXI
+qNOyA8Af03dEQ5w/sNlusiF73/FIgErb0be4rgIvJOW0ziBU9RKn/vB5wl4IpJjM
+JuL3hh7RlAbfSWaqaKCZKIDolS2vtvwKp9mZgmxWgvKx3Q/L8I1MXPIZTTRpGwIe
+HyBxYBTSeVkCgYEAuRHbzgDFXSN0fxUKYMKI5XDCjV0/fX+8gJNmITtklSyHvKII
+n8omMiKIOUA7a5XEpFpuf0kAn8izgrz5Uz+9ytUBpnI3zIJqN2ur1af7rJdZrj6f
+Q4/ktg87XpZJMfbCLjb/9KLDh98k26zw6/lIwf4vS4gV5sxuBlRVBib6qXsCgYA9
+2f6PWwi5gkSk08KutCX2ekY6M9zg4d89sXKN+16MBZKmb5B2G/5U+sQl1y+/D5Ql
+AX5bZRGfnUTob661QLov7qZhD49PhajHkZZ+yM9ra9F/keoO1PuyPlsQ2yAGplbo
+9tz1lGZoiR9oBun7eQaRdpf/1U7ra+OiSZAkZg2zCQKBgQCl+bszQ202CkLchQ1R
+Mu2svFFi+BeVvtA8yp4Il3bznxkgBZJ1/4gB+u84f9ybfpKHok7+f+iHVGJSNiay
+Uw5ouE6oNEJODsvWDDliCjrckGUBDmJ8XOHEkm3MPOmEov8UJ6twev/QWhEfEUZk
+fclCYjgt3YJ3XW9hXgORWhJj9g==
+-----END PRIVATE KEY-----
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/rootca.pem b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/rootca.pem
new file mode 100644
index 0000000..7a36225
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/rootca.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
+UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
+dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
+MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
+dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
+BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
+cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
+AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
+MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
+aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
+ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
+IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
+MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
+A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
+7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
+1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git "a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/\350\257\201\344\271\246\344\275\277\347\224\250\350\257\264\346\230\216.txt" "b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/\350\257\201\344\271\246\344\275\277\347\224\250\350\257\264\346\230\216.txt"
new file mode 100644
index 0000000..e8a73dd
--- /dev/null
+++ "b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert/\350\257\201\344\271\246\344\275\277\347\224\250\350\257\264\346\230\216.txt"
@@ -0,0 +1,20 @@
+欢迎使用微信支付!
+微信支付API共四份(证书pkcs12格式、证书pem格式、证书密钥pem格式、CA证书),为接口中强制要求时需携带的证书文件。
+证书属于敏感信息,请妥善保管不要泄露和被他人复制。
+不同开发语言下的证书格式不同,以下为说明指引:
+	证书pkcs12格式(apiclient_cert.p12)
+		包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份
+		部分安全性要求较高的API需要使用该证书来确认您的调用身份
+		windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:10010000)
+	证书pem格式(apiclient_cert.pem)
+		从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制
+		部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
+		您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem
+	证书密钥pem格式(apiclient_key.pem)
+		从apiclient_cert.p12中导出密钥部分的文件,为pem格式
+		部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
+		您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem
+	CA证书(rootca.pem)
+		微信支付api服务器上也部署了证明微信支付身份的服务器证书,您在使用api进行调用时也需要验证所调用服务器及域名的真实性
+		该文件为签署微信支付证书的权威机构的根证书,可以用来验证微信支付服务器证书的真实性
+		某些环境和工具已经内置了若干权威机构的根证书,无需引用该证书也可以正常进行验证,这里提供给您在未内置所必须根证书的环境中载入使用
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_cert.p12 b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_cert.p12
new file mode 100644
index 0000000..9364e13
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_cert.p12
Binary files differ
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_cert.pem b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_cert.pem
new file mode 100644
index 0000000..e3ed127
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_cert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEbDCCA9WgAwIBAgIEAV66BDANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
+Q04xEjAQBgNVBAgTCUd1YW5nZG9uZzERMA8GA1UEBxMIU2hlbnpoZW4xEDAOBgNV
+BAoTB1RlbmNlbnQxDDAKBgNVBAsTA1dYRzETMBEGA1UEAxMKTW1wYXltY2hDQTEf
+MB0GCSqGSIb3DQEJARYQbW1wYXltY2hAdGVuY2VudDAeFw0xNzA2MjkwNjQwMzha
+Fw0yNzA2MjcwNjQwMzhaMIGbMQswCQYDVQQGEwJDTjESMBAGA1UECBMJR3Vhbmdk
+b25nMREwDwYDVQQHEwhTaGVuemhlbjEQMA4GA1UEChMHVGVuY2VudDEOMAwGA1UE
+CxMFTU1QYXkxMDAuBgNVBAMUJ+WTiOWwlOa7qOWQjeeahOe9kee7nOenkeaKgOac
+iemZkOWFrOWPuDERMA8GA1UEBBMIMzE4OTQ3MDYwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQDJS/abCCpwvnppCU0TxW84PF2cqpUF3Ip9KmQytNCPRZPK
+q299efclcWOYozB7zSY4OsZ9UyAod1+HsFEjyJBTWyJfakNewiF6AIsydZtFZ65t
+8ReQ66VTebB1imEq/OrQMXphBwJ1TSH5Jk2pW7JA9U5LqZ3apgDa9PrFHY4dhnkf
+IxQI6Xn0Y7fUJsGszP+5ETbtlLW5PZQiE2H8T3xCwH3mnmg/rppTZaBVIE/7SskW
+iEVPd8g/fec8xDAoAulv1FsBdrPGXyWiFkpcTdrQKHaMa0J7AtMfSnMb1Z/pAIQp
+DxCjCJRM0gfvZNOj2nyqbZD3JJAP8LFnTrasdb/NAgMBAAGjggFGMIIBQjAJBgNV
+HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh0iQ0VTLUNBIEdlbmVyYXRlIENlcnRpZmlj
+YXRlIjAdBgNVHQ4EFgQUBMf3KHk8wfRKtAdcnz+VCFwDdeYwgb8GA1UdIwSBtzCB
+tIAUPgUm9iJitBVbiM1kfrDUYqflhnShgZCkgY0wgYoxCzAJBgNVBAYTAkNOMRIw
+EAYDVQQIEwlHdWFuZ2RvbmcxETAPBgNVBAcTCFNoZW56aGVuMRAwDgYDVQQKEwdU
+ZW5jZW50MQwwCgYDVQQLEwNXWEcxEzARBgNVBAMTCk1tcGF5bWNoQ0ExHzAdBgkq
+hkiG9w0BCQEWEG1tcGF5bWNoQHRlbmNlbnSCCQC7VJcrvADoVzAOBgNVHQ8BAf8E
+BAMCBsAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEA
+EFcsWO+7E4v7NNdprZYbYASr4e4Uw+EO+RLbkuFUQhHTGMW/biFlYounarNncTFs
+SylXIkCylTRxSZmLNhr8D9/TJ1c9Vrbp8SqlgS5DlhLU3PGjmY7Yl+Zth06v6kv+
+0GqwKCljlN+DQNq2wxL7z3S/XDZGTb8tAhLtOKyPkpg=
+-----END CERTIFICATE-----
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_key.pem b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_key.pem
new file mode 100644
index 0000000..78dbd07
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/apiclient_key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQDJS/abCCpwvnpp
+CU0TxW84PF2cqpUF3Ip9KmQytNCPRZPKq299efclcWOYozB7zSY4OsZ9UyAod1+H
+sFEjyJBTWyJfakNewiF6AIsydZtFZ65t8ReQ66VTebB1imEq/OrQMXphBwJ1TSH5
+Jk2pW7JA9U5LqZ3apgDa9PrFHY4dhnkfIxQI6Xn0Y7fUJsGszP+5ETbtlLW5PZQi
+E2H8T3xCwH3mnmg/rppTZaBVIE/7SskWiEVPd8g/fec8xDAoAulv1FsBdrPGXyWi
+FkpcTdrQKHaMa0J7AtMfSnMb1Z/pAIQpDxCjCJRM0gfvZNOj2nyqbZD3JJAP8LFn
+Trasdb/NAgMBAAECggEAPP5pgNxej78HtF//HOiMJMwVyWzeruH+jKKVrc+gCmmY
+uKZtp+WW/592AEAiZsDovc0Ba+QOMHTLW4APdfpF0RwiNCsssr+8CQ21H9sG62bZ
+MbMF4wGkHMEYuOTvQGlWdTMo09Gd6xEuJCJ5EcIZJxmtWbvRevkl9TKZ8bRc5ZDZ
+2s/8cgzps9lbnkbTZ9TAF7n7XOlPy4YqIBKW33RCHUtQCfCDERLaBRAG6SbNUsBQ
+SUYq6PsroFtqgwXxbygVsXfNBBfXZ8nfyqupvkOto+2NJjDr6cm5cT+bMyStcNdN
+UAssNUbw7DjcQ+0esS0Z9K7Tah5kmLzzGcDnyNoLgQKBgQDtLeEzRWU9QIksvzUb
+tIAwz/yLTVAQ74/ke6VP4pAWkLdgcVWxY+HOfXyNTWC3MZ2BSyj3oTaahgCQAVb3
+dXmRDWjRWggUcTLNWgZCcjPw4oshdzVPz1t5WR9/9c+UDqSFSrBGVJ5cVLNpDxSk
+1KYX7gNdu+h8RTKpKxyOleJaEQKBgQDZRShPjZYvcLNv79y3cT8RHX8qi2akd7by
+X6VwxoFeZ5TeK51fdZjUSyU5/8Jmq9m+K3W7edYrzAOiLYYSCNAVQEoxqGacPla2
+OlpiSPbtafoIy0ovsJvV6DAZwwtF0cowvdNnXvPsYlKlAKCXnRxf+Ap9/XYArBD6
+dTpcj1Ht/QKBgQDHhCK/GI9TeWhrZeVtCugTJ8MQA9doh72JvKGRk8sV0GMSFAS8
+FoOrSlBuJTtIn8oZK3qo5MqkLjlm6lmYDRBYfuk/wvatC5RqvmIpnxwmdMwJONh1
+7L7MU7Z10/fsWmz3W57xatlUXkQWCoOZLPETjDr0rM+jSiqVuBhrsZYZoQKBgGN8
+mFW9Fm0IpRF3etCAyYkTwZwAkvJyYtIe28mFC83njjIhNIF2fpGPCy/AngqXXDAJ
+BHLg+iG53FwRjleJs4ZXluGgI8Qdg2UT2TkyAed6ZGRMed7WdrT/Ca9yMSI6SuQA
+t+GYiAbQitlFLUPfTBPhpyRDwBnUsD2PGjcx5SkdAn8KkFSMExG4y4eZD+UxLXsj
+/QfQj0eUyzu5XyvPXLD9XV1YL3pX7+DxvU98ogFH4QBh2KtDbe2RldyiH8toSP0F
+kXoj4/CtUp8EDBpeLgbdxCYvKW+Lz9oyPNouhkV7m0KRrHV/3CPOeHqkh0dNdW6f
+RKW9WsNAtAS2ncev7Mjj
+-----END PRIVATE KEY-----
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/rootca.pem b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/rootca.pem
new file mode 100644
index 0000000..7a36225
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/rootca.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
+UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
+dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
+MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
+dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
+BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
+cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
+AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
+MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
+aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
+ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
+IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
+MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
+A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
+7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
+1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git "a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/\350\257\201\344\271\246\344\275\277\347\224\250\350\257\264\346\230\216.txt" "b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/\350\257\201\344\271\246\344\275\277\347\224\250\350\257\264\346\230\216.txt"
new file mode 100644
index 0000000..e8a73dd
--- /dev/null
+++ "b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/common/cert_2/\350\257\201\344\271\246\344\275\277\347\224\250\350\257\264\346\230\216.txt"
@@ -0,0 +1,20 @@
+欢迎使用微信支付!
+微信支付API共四份(证书pkcs12格式、证书pem格式、证书密钥pem格式、CA证书),为接口中强制要求时需携带的证书文件。
+证书属于敏感信息,请妥善保管不要泄露和被他人复制。
+不同开发语言下的证书格式不同,以下为说明指引:
+	证书pkcs12格式(apiclient_cert.p12)
+		包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份
+		部分安全性要求较高的API需要使用该证书来确认您的调用身份
+		windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:10010000)
+	证书pem格式(apiclient_cert.pem)
+		从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制
+		部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
+		您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem
+	证书密钥pem格式(apiclient_key.pem)
+		从apiclient_cert.p12中导出密钥部分的文件,为pem格式
+		部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
+		您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem
+	CA证书(rootca.pem)
+		微信支付api服务器上也部署了证明微信支付身份的服务器证书,您在使用api进行调用时也需要验证所调用服务器及域名的真实性
+		该文件为签署微信支付证书的权威机构的根证书,可以用来验证微信支付服务器证书的真实性
+		某些环境和工具已经内置了若干权威机构的根证书,无需引用该证书也可以正常进行验证,这里提供给您在未内置所必须根证书的环境中载入使用
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/AppPayReqData.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/AppPayReqData.java
new file mode 100644
index 0000000..92842f3
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/AppPayReqData.java
@@ -0,0 +1,125 @@
+package com.ruoyi.order.util.tencent.protocol;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.ruoyi.order.util.DateUtil;
+import com.ruoyi.order.util.tencent.common.RandomStringGenerator;
+import com.ruoyi.order.util.tencent.common.Signature;
+
+
+/**
+ * 调起支付-API需要提交的数据
+ * @author pan
+ */
+public class AppPayReqData {
+
+    //每个字段具体的意思请查看API文档
+	private String appid;//公众账号ID
+	private String partnerid;//商户号
+	private String prepayid;//预支付编号(微信返回的支付交易会话ID)
+	private String _package = "Sign=WXPay";//扩展字段(暂填写固定值Sign=WXPay)
+	private String noncestr = RandomStringGenerator.getRandomStringByLength(32);//随机字符串 (32位)
+	private String timestamp = DateUtil.nowDateLongStr().substring(0, 10);//时间戳
+	private String sign;//签名 
+	/**
+	 * 调用微信支付
+	 * @param appid 微信分配的APPID
+	 * @param partnerid 微信支付分配的商户号ID
+	 * @param prepayid 预支付编号(微信返回的支付交易会话ID)
+	 */
+    public AppPayReqData(Integer apptype, String appid, String partnerid, String prepayid, String noncestr){
+    	//微信分配的APPID
+    	this.appid = appid;
+    	//微信支付接口与预支付接口随机字符串,保持一致!
+    	this.noncestr = noncestr;
+        //微信支付分配的商户号ID
+    	this.partnerid = partnerid;
+        //预支付编号(微信返回的支付交易会话ID)
+        this.prepayid = prepayid;
+		// 根据API给的签名规则进行签名
+		String sign = Signature.getSign(apptype, toMap());
+		setSign(sign);//微信公众号(最后参与签名的参数有appId, timeStamp, nonceStr, package, signType)
+    }
+
+    public Map<String,Object> toMap(){
+        Map<String,Object> map = new HashMap<String, Object>();
+        Field[] fields = this.getClass().getDeclaredFields();
+        for (Field field : fields) {
+            Object obj;
+            try {
+                obj = field.get(this);
+                if(obj!=null){
+                    if ("_package".equals(field.getName())) {
+                    	map.put("package", obj);
+					}else{
+						 map.put(field.getName(), obj);
+					}
+                }
+            } catch (IllegalArgumentException e) {
+                e.printStackTrace();
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+        }
+        return map;
+    }
+
+	public String getAppid() {
+		return appid;
+	}
+
+	public void setAppid(String appid) {
+		this.appid = appid;
+	}
+
+	public String getPartnerid() {
+		return partnerid;
+	}
+
+	public void setPartnerid(String partnerid) {
+		this.partnerid = partnerid;
+	}
+
+	public String getPrepayid() {
+		return prepayid;
+	}
+
+	public void setPrepayid(String prepayid) {
+		this.prepayid = prepayid;
+	}
+
+	public String get_package() {
+		return _package;
+	}
+
+	public void set_package(String _package) {
+		this._package = _package;
+	}
+
+	public String getNoncestr() {
+		return noncestr;
+	}
+
+	public void setNoncestr(String noncestr) {
+		this.noncestr = noncestr;
+	}
+
+	public String getTimestamp() {
+		return timestamp;
+	}
+
+	public void setTimestamp(String timestamp) {
+		this.timestamp = timestamp;
+	}
+
+	public String getSign() {
+		return sign;
+	}
+
+	public void setSign(String sign) {
+		this.sign = sign;
+	}
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/PayToTheUserReqData.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/PayToTheUserReqData.java
new file mode 100644
index 0000000..75f16ca
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/PayToTheUserReqData.java
@@ -0,0 +1,176 @@
+/*package com.tencent.protocol;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.tencent.common.Configure;
+import com.tencent.common.RandomStringGenerator;
+import com.tencent.common.Signature;
+
+*//**
+ * 商户想用户付款(提现)
+ *//*
+public class PayToTheUserReqData {
+
+	//每个字段具体的意思请查看API文档 https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
+	private String mch_appid;//公众账号appid		是	wx8888888888888888	String	微信分配的公众账号ID(企业号corpid即为此appId)
+	private String mchid;//商户号		是	1900000109	String(32)	微信支付分配的商户号
+	private String nonce_str;// 随机字符串		是	5K8264ILTKCH16CQ2502SI8ZNMTM67VS	String(32)	随机字符串,不长于32位
+	private String sign;// 签名		是	C380BEC2BFD727A4B6845133519F3AD6	String(32)	签名,详见签名算法
+	private String partner_trade_no;// 商户订单号		是	10000098201411111234567890	String	商户订单号,需保持唯一性
+	private String openid;// 用户openid	是	oxTWIuGaIt6gTKsQRLau2M0yL16E	String	商户appid下,某用户的openid
+	private String check_name;// 校验用户姓名选项	是	OPTION_CHECK	String	NO_CHECK:不校验真实姓名 	FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账)	OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
+	private String re_user_name;// 收款用户姓名		可选	马花花	String	收款用户真实姓名。 	如果check_name设置为FORCE_CHECK或OPTION_CHECK,则必填用户真实姓名
+	private Integer amount;// 金额		是	10099	int	企业付款金额,单位为分
+	private String desc;// 企业付款描述信息		是	理赔	String	企业付款操作说明信息。必填。
+	private String spbill_create_ip = "127.0.0.1";// Ip地址		是	192.168.0.1	String(32)	调用接口的机器Ip地址
+
+	*//**
+	 * 企业向用户付款
+	 * @param partner_trade_no 商户订单号,需保持唯一性
+	 * @param openid 商户appid下,某用户的openid
+	 * @param check_name 校验用户姓名选项:NO_CHECK:不校验真实姓名  FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账)OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
+	 * @param re_user_name 收款用户姓名
+	 * @param amount 企业付款金额,单位为分
+	 * @param desc 企业付款描述信息
+	 * @param spbill_create_ip 调用接口的机器Ip地址
+	 *//*
+	public PayToTheUserReqData(String partner_trade_no, String openid, String re_user_name, Integer amount, String desc){
+
+		//微信分配的公众号ID(开通公众号之后可以获取到)
+		setMch_appid(Configure.getAppid());
+
+		//微信支付分配的商户号ID(开通公众号的微信支付功能之后可以获取到)
+		setMchid(Configure.getMchid());
+		setPartner_trade_no(partner_trade_no);
+		setOpenid(openid);
+		setCheck_name("OPTION_CHECK");//默认:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
+		//      setRe_user_name(re_user_name);
+		setAmount(amount);
+		setDesc(desc);
+
+		//随机字符串,不长于32 位
+		setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
+
+		//根据API给的签名规则进行签名
+		String sign;
+		try {
+			sign = Signature.getSign(toMap());
+			setSign(sign);//把签名数据设置到Sign这个属性中
+		} catch (IllegalAccessException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	public String getMch_appid() {
+		return mch_appid;
+	}
+
+	public void setMch_appid(String mch_appid) {
+		this.mch_appid = mch_appid;
+	}
+
+	public String getMchid() {
+		return mchid;
+	}
+
+	public void setMchid(String mchid) {
+		this.mchid = mchid;
+	}
+
+	public String getNonce_str() {
+		return nonce_str;
+	}
+
+	public void setNonce_str(String nonce_str) {
+		this.nonce_str = nonce_str;
+	}
+
+	public String getSign() {
+		return sign;
+	}
+
+	public void setSign(String sign) {
+		this.sign = sign;
+	}
+
+	public String getPartner_trade_no() {
+		return partner_trade_no;
+	}
+
+	public void setPartner_trade_no(String partner_trade_no) {
+		this.partner_trade_no = partner_trade_no;
+	}
+
+	public String getOpenid() {
+		return openid;
+	}
+
+	public void setOpenid(String openid) {
+		this.openid = openid;
+	}
+
+	public String getCheck_name() {
+		return check_name;
+	}
+
+	public void setCheck_name(String check_name) {
+		this.check_name = check_name;
+	}
+
+	public String getRe_user_name() {
+		return re_user_name;
+	}
+
+	public void setRe_user_name(String re_user_name) {
+		this.re_user_name = re_user_name;
+	}
+
+	public Integer getAmount() {
+		return amount;
+	}
+
+	public void setAmount(Integer amount) {
+		this.amount = amount;
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+
+	public void setDesc(String desc) {
+		this.desc = desc;
+	}
+
+	public String getSpbill_create_ip() {
+		return spbill_create_ip;
+	}
+
+	public void setSpbill_create_ip(String spbill_create_ip) {
+		this.spbill_create_ip = spbill_create_ip;
+	}
+
+
+	public Map<String,Object> toMap(){
+		Map<String,Object> map = new HashMap<String, Object>();
+		Field[] fields = this.getClass().getDeclaredFields();
+		for (Field field : fields) {
+			Object obj;
+			try {
+				obj = field.get(this);
+				if(obj!=null){
+					map.put(field.getName(), obj);
+				}
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			}
+		}
+		return map;
+	}
+
+}
+*/
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/RefundReqData.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/RefundReqData.java
new file mode 100644
index 0000000..a917abc
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/RefundReqData.java
@@ -0,0 +1,210 @@
+package com.tencent.protocol;
+
+import com.ruoyi.order.util.tencent.common.Configure;
+import com.ruoyi.order.util.tencent.common.RandomStringGenerator;
+import com.ruoyi.order.util.tencent.common.Signature;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+/**
+ * 商户退款-API需要提交的数据
+ * @author pan
+ */
+public class RefundReqData {
+
+	//每个字段具体的意思请查看API文档
+	private String appid = "";
+	private String mch_id = "";
+	private String device_info = "";
+	private String nonce_str = "";
+	private String sign = "";
+	private String transaction_id = "";
+	private String out_trade_no = "";
+	private String out_refund_no = "";
+	private int total_fee = 0;
+	private int refund_fee = 0;
+	private String refund_fee_type = "CNY";
+	private String op_user_id = "";
+	private String pay_type = "";//2微信app支付,3公众号支付,4小程序支付
+
+	/**
+	 * 请求退款服务
+	 * @param transactionID 是微信系统为每一笔支付交易分配的订单号,通过这个订单号可以标识这笔交易,它由支付订单API支付成功时返回的数据里面获取到。建议优先使用
+	 * @param outTradeNo 商户系统内部的订单号,transaction_id 、out_trade_no 二选一,如果同时存在优先级:transaction_id>out_trade_no
+	 * @param deviceInfo 微信支付分配的终端设备号,与下单一致
+	 * @param outRefundNo 商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
+	 * @param totalFee 订单总金额,单位为分
+	 * @param refundFee 退款总金额,单位为分,可以做部分退款
+	 * @param opUserID 操作员帐号, 默认为商户号
+	 * @param refundFeeType 货币类型,符合ISO 4217标准的三位字母代码,默认为CNY(人民币)
+	 */
+	public RefundReqData(String transactionID, String outTradeNo, String outRefundNo, int totalFee, int refundFee,String payType) {
+		// 微信分配的公众号ID(开通公众号之后可以获取到)
+
+		if (payType.equals("2")) {//微信app
+			System.out.println("微信app退款!!!!!!!!!!!");
+			setAppid(Configure.getAppid());
+			setMch_id(Configure.getMchid());
+			setOp_user_id(getMch_id());
+		}else if(payType.equals("3")) {//微信公众号
+			System.out.println("微信公众号退款!!!!!!!!!!!");
+			setAppid(Configure.getGappid());
+			setMch_id(Configure.getGmchid());
+			setOp_user_id(Configure.getGmchid());
+		}else if(payType.equals("4")) {//微信小程序
+			System.out.println("微信小程序退款!!!!!!!!!!!");
+			setAppid(Configure.getXappid());
+			setMch_id(Configure.getXmchid());
+			setOp_user_id(Configure.getXmchid());
+		}
+
+		//transaction_id是微信系统为每一笔支付交易分配的订单号,通过这个订单号可以标识这笔交易,它由支付订单API支付成功时返回的数据里面获取到。
+		setTransaction_id(transactionID);
+
+		//商户系统自己生成的唯一的订单号
+		setOut_trade_no(outTradeNo);
+
+		setOut_refund_no(outRefundNo);
+
+		setTotal_fee(totalFee);
+
+		setRefund_fee(refundFee);
+
+		//随机字符串,不长于32 位
+		setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
+
+		//根据API给的签名规则进行签名
+		String sign = Signature.getSign(1,toMap());
+		setSign(sign);//把签名数据设置到Sign这个属性中
+
+
+	}
+
+	public String getAppid() {
+		return appid;
+	}
+
+	public void setAppid(String appid) {
+		this.appid = appid;
+	}
+
+	public String getMch_id() {
+		return mch_id;
+	}
+
+	public void setMch_id(String mch_id) {
+		this.mch_id = mch_id;
+	}
+
+	public String getDevice_info() {
+		return device_info;
+	}
+
+	public void setDevice_info(String device_info) {
+		this.device_info = device_info;
+	}
+
+	public String getNonce_str() {
+		return nonce_str;
+	}
+
+	public void setNonce_str(String nonce_str) {
+		this.nonce_str = nonce_str;
+	}
+
+	public String getSign() {
+		return sign;
+	}
+
+	public void setSign(String sign) {
+		this.sign = sign;
+	}
+
+	public String getTransaction_id() {
+		return transaction_id;
+	}
+
+	public void setTransaction_id(String transaction_id) {
+		this.transaction_id = transaction_id;
+	}
+
+	public String getOut_trade_no() {
+		return out_trade_no;
+	}
+
+	public void setOut_trade_no(String out_trade_no) {
+		this.out_trade_no = out_trade_no;
+	}
+
+	public String getOut_refund_no() {
+		return out_refund_no;
+	}
+
+	public void setOut_refund_no(String out_refund_no) {
+		this.out_refund_no = out_refund_no;
+	}
+
+	public int getTotal_fee() {
+		return total_fee;
+	}
+
+	public void setTotal_fee(int total_fee) {
+		this.total_fee = total_fee;
+	}
+
+	public int getRefund_fee() {
+		return refund_fee;
+	}
+
+	public void setRefund_fee(int refund_fee) {
+		this.refund_fee = refund_fee;
+	}
+
+	public String getOp_user_id() {
+		return op_user_id;
+	}
+
+	public void setOp_user_id(String op_user_id) {
+		this.op_user_id = op_user_id;
+	}
+
+	public String getRefund_fee_type() {
+		return refund_fee_type;
+	}
+
+	public void setRefund_fee_type(String refund_fee_type) {
+		this.refund_fee_type = refund_fee_type;
+	}	
+
+	public String getPay_type() {
+		return pay_type;
+	}
+
+	public void setPay_type(String pay_type) {
+		this.pay_type = pay_type;
+	}
+
+	public Map<String,Object> toMap(){
+		Map<String,Object> map = new HashMap<String, Object>();
+		Field[] fields = this.getClass().getDeclaredFields();
+		for (Field field : fields) {
+			Object obj;
+			try {
+				obj = field.get(this);
+				if(obj!=null){
+					map.put(field.getName(), obj);
+				}
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			}
+		}
+		return map;
+	}
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/UnifiedorderReqData.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/UnifiedorderReqData.java
new file mode 100644
index 0000000..ee959fd
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/UnifiedorderReqData.java
@@ -0,0 +1,285 @@
+package com.ruoyi.order.util.tencent.protocol;
+
+import com.ruoyi.order.util.SinataUtil;
+import com.ruoyi.order.util.tencent.common.Configure;
+import com.ruoyi.order.util.tencent.common.RandomStringGenerator;
+import com.ruoyi.order.util.tencent.common.Signature;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+/**
+ * 请求统一下单-API需要提交的数据
+ * @author pan
+ */
+public class UnifiedorderReqData {
+
+	//每个字段具体的意思请查看API文档
+	private String appid;//公众账号ID (内置)
+	private String mch_id;//商户号  (内置)
+	private String nonce_str;//随机字符串 (内置)
+	private String sign;//签名 
+
+
+	//接口调用需要的参数
+	private String body;//商品描述
+	private String out_trade_no;//商户订单号
+	private Integer total_fee;//总金额
+	private String spbill_create_ip;//终端IP
+	private String notify_url;//通知地址
+	private String trade_type;//交易类型
+	private String openid;//用户标识
+
+	/**
+	 * 预支付请求需要的参数(获取微信统一下单-必填参数)
+	 * 公众账号ID 	appid (内置)
+	 * 商户号  	mch_id (内置)
+	 * 随机字符串  	nonce_str (内置)
+	 * 签名 	sign (内置)
+	 * @param body				商品描述 
+	 * @param out_trade_no		商户订单号
+	 * @param total_fee			总金额 (单位:分)
+	 * @param notify_url		通知地址
+	 */
+	public UnifiedorderReqData(Integer apptype, String out_trade_no, String body, Double total_fee, String notify_url){
+
+		//乘客appID与商户号
+		this.appid = Configure.getAppid();
+
+		//微信支付分配的商户号ID(开通公众号的微信支付功能之后可以获取到)
+		this.mch_id = Configure.getMchid();
+
+		//随机字符串,不长于32 位
+		//        setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
+		this.nonce_str = RandomStringGenerator.getRandomStringByLength(32);
+
+
+		//		setBody(body);// 商品描述
+		this.body = body;
+
+		//		setOut_trade_no(out_trade_no);// 商户订单号
+		this.out_trade_no = out_trade_no;
+
+		//		setTotal_fee();// 总金额
+		String money= SinataUtil.doubleRetainTwo(total_fee*100d);
+		this.total_fee = Integer.parseInt(money.substring(0,money.length()-3));
+
+		//		setNotify_url(notify_url);// 通知地址
+		this.notify_url = notify_url;
+		//		setTrade_type("APP");// 交易类型,默认:APP
+		this.trade_type = "APP";
+		// 根据API给的签名规则进行签名
+		this.sign =  Signature.getSign(apptype, toMap());
+
+	}
+
+
+	/**
+	 * 预支付请求需要的参数(获取微信统一下单-必填参数)(公众号)
+	 * 公众账号ID 	appid (内置)
+	 * 商户号  	mch_id (内置)
+	 * 随机字符串  	nonce_str (内置)
+	 * 签名 	sign (内置)
+	 * @param body				商品描述 
+	 * @param out_trade_no		商户订单号
+	 * @param total_fee			总金额 (单位:分)
+	 * @param notify_url		通知地址
+	 * @throws IllegalAccessException 
+	 */
+	public UnifiedorderReqData(String out_trade_no, String body, Double total_fee, String notify_url,String trade_type,String openid) throws IllegalAccessException{
+
+		//appID与商户号
+		this.appid = Configure.getGappid();
+
+		//微信支付分配的商户号ID(开通公众号的微信支付功能之后可以获取到)
+		this.mch_id = Configure.getGmchid();
+
+		//随机字符串,不长于32 位
+		//        setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
+		this.nonce_str = RandomStringGenerator.getRandomStringByLength(32);
+
+
+		//		setBody(body);// 商品描述
+		this.body = body;
+
+		//		setOut_trade_no(out_trade_no);// 商户订单号
+		this.out_trade_no = out_trade_no;
+
+		//		setTotal_fee();// 总金额
+		String money=SinataUtil.doubleRetainTwo(total_fee*100d);
+		this.total_fee = Integer.parseInt(money.substring(0,money.length()-3));
+		//this.total_fee = (int)(total_fee * 100);
+
+		//		setNotify_url(notify_url);// 通知地址
+		this.notify_url = notify_url;
+		/*trade_type 交易类型JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里
+		MICROPAY--刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口*/
+
+		this.trade_type = trade_type;
+		this.openid = openid;
+		// 根据API给的签名规则进行签名
+		this.sign =  Signature.getSign(1,toMap());
+
+	}
+	
+	/**
+	 * 预支付请求需要的参数(获取微信统一下单-必填参数)(小程序)
+	 * 公众账号ID 	appid (内置)
+	 * 商户号  	mch_id (内置)
+	 * 随机字符串  	nonce_str (内置)
+	 * 签名 	sign (内置)
+	 * @param body				商品描述 
+	 * @param out_trade_no		商户订单号
+	 * @param total_fee			总金额 (单位:分)
+	 * @param notify_url		通知地址
+	 * @throws IllegalAccessException 
+	 */
+	public UnifiedorderReqData(String out_trade_no, Double total_fee, String notify_url,String trade_type,String openid) throws IllegalAccessException{
+
+		//appID与商户号
+		this.appid = Configure.getXappid();
+
+		//微信支付分配的商户号ID(开通公众号的微信支付功能之后可以获取到)
+		this.mch_id = Configure.getXmchid();
+
+		//随机字符串,不长于32 位
+		//        setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
+		this.nonce_str = RandomStringGenerator.getRandomStringByLength(32);
+
+
+		//		setBody(body);// 商品描述
+		this.body = "小程序支付";
+
+		//		setOut_trade_no(out_trade_no);// 商户订单号
+		this.out_trade_no = out_trade_no;
+
+		//		setTotal_fee();// 总金额
+		String money=SinataUtil.doubleRetainTwo(total_fee*100d);
+		this.total_fee = Integer.parseInt(money.substring(0,money.length()-3));
+		//this.total_fee = (int)(total_fee * 100);
+
+		//		setNotify_url(notify_url);// 通知地址
+		this.notify_url = notify_url;
+		/*trade_type 交易类型JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里
+		MICROPAY--刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口*/
+
+		this.trade_type = trade_type;
+		this.openid = openid;
+		// 根据API给的签名规则进行签名
+		this.sign =  Signature.getSign(1,toMap());
+
+	}
+
+	public Map<String,Object> toMap(){
+		Map<String,Object> map = new HashMap<String, Object>();
+		Field[] fields = this.getClass().getDeclaredFields();
+		for (Field field : fields) {
+			Object obj;
+			try {
+				obj = field.get(this);
+				if(obj!=null){
+					map.put(field.getName(), obj);
+				}
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			}
+		}
+		return map;
+	}
+
+	public String getAppid() {
+		return appid;
+	}
+
+	public void setAppid(String appid) {
+		this.appid = appid;
+	}
+
+	public String getMch_id() {
+		return mch_id;
+	}
+
+	public void setMch_id(String mch_id) {
+		this.mch_id = mch_id;
+	}
+
+	public String getNonce_str() {
+		return nonce_str;
+	}
+
+	public void setNonce_str(String nonce_str) {
+		this.nonce_str = nonce_str;
+	}
+
+	public String getSign() {
+		return sign;
+	}
+
+	public void setSign(String sign) {
+		this.sign = sign;
+	}
+
+	public String getBody() {
+		return body;
+	}
+
+	public void setBody(String body) {
+		this.body = body;
+	}
+
+	public String getOut_trade_no() {
+		return out_trade_no;
+	}
+
+	public void setOut_trade_no(String out_trade_no) {
+		this.out_trade_no = out_trade_no;
+	}
+
+	public Integer getTotal_fee() {
+		return total_fee;
+	}
+
+	public void setTotal_fee(Integer total_fee) {
+		this.total_fee = total_fee;
+	}
+
+	public String getSpbill_create_ip() {
+		return spbill_create_ip;
+	}
+
+	public void setSpbill_create_ip(String spbill_create_ip) {
+		this.spbill_create_ip = spbill_create_ip;
+	}
+
+	public String getNotify_url() {
+		return notify_url;
+	}
+
+	public void setNotify_url(String notify_url) {
+		this.notify_url = notify_url;
+	}
+
+	public String getTrade_type() {
+		return trade_type;
+	}
+
+	public void setTrade_type(String trade_type) {
+		this.trade_type = trade_type;
+	}
+
+
+	public String getOpenid() {
+		return openid;
+	}
+
+
+	public void setOpenid(String openid) {
+		this.openid = openid;
+	}
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/WXPayReport.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/WXPayReport.java
new file mode 100644
index 0000000..79c99c0
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/WXPayReport.java
@@ -0,0 +1,268 @@
+package com.ruoyi.order.util.tencent.protocol;
+
+import com.ruoyi.order.util.tencent.common.WXPayConfig;
+import com.ruoyi.order.util.tencent.common.WXPayUtil;
+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.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.HttpClientBuilder;
+import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
+import org.apache.http.util.EntityUtils;
+
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * 交易保障
+ */
+public class WXPayReport {
+
+    public static class ReportInfo {
+
+        /**
+         * 布尔变量使用int。0为false, 1为true。
+         */
+
+        // 基本信息
+        private String version = "v0";
+        private String sdk = "wxpay java sdk v1.0";
+        private String uuid;  // 交易的标识
+        private long timestamp;   // 上报时的时间戳,单位秒
+        private long elapsedTimeMillis; // 耗时,单位 毫秒
+
+        // 针对主域名
+        private String firstDomain;  // 第1次请求的域名
+        private boolean primaryDomain; //是否主域名
+        private int firstConnectTimeoutMillis;  // 第1次请求设置的连接超时时间,单位 毫秒
+        private int firstReadTimeoutMillis;  // 第1次请求设置的读写超时时间,单位 毫秒
+        private int firstHasDnsError;  // 第1次请求是否出现dns问题
+        private int firstHasConnectTimeout; // 第1次请求是否出现连接超时
+        private int firstHasReadTimeout; // 第1次请求是否出现连接超时
+
+        public ReportInfo(String uuid, long timestamp, long elapsedTimeMillis, String firstDomain, boolean primaryDomain, int firstConnectTimeoutMillis, int firstReadTimeoutMillis, boolean firstHasDnsError, boolean firstHasConnectTimeout, boolean firstHasReadTimeout) {
+            this.uuid = uuid;
+            this.timestamp = timestamp;
+            this.elapsedTimeMillis = elapsedTimeMillis;
+            this.firstDomain = firstDomain;
+            this.primaryDomain = primaryDomain;
+            this.firstConnectTimeoutMillis = firstConnectTimeoutMillis;
+            this.firstReadTimeoutMillis = firstReadTimeoutMillis;
+            this.firstHasDnsError = firstHasDnsError?1:0;
+            this.firstHasConnectTimeout = firstHasConnectTimeout?1:0;
+            this.firstHasReadTimeout = firstHasReadTimeout?1:0;
+         }
+
+        @Override
+        public String toString() {
+            return "ReportInfo{" +
+                    "version='" + version + '\'' +
+                    ", sdk='" + sdk + '\'' +
+                    ", uuid='" + uuid + '\'' +
+                    ", timestamp=" + timestamp +
+                    ", elapsedTimeMillis=" + elapsedTimeMillis +
+                    ", firstDomain='" + firstDomain + '\'' +
+                    ", primaryDomain=" + primaryDomain +
+                    ", firstConnectTimeoutMillis=" + firstConnectTimeoutMillis +
+                    ", firstReadTimeoutMillis=" + firstReadTimeoutMillis +
+                    ", firstHasDnsError=" + firstHasDnsError +
+                    ", firstHasConnectTimeout=" + firstHasConnectTimeout +
+                    ", firstHasReadTimeout=" + firstHasReadTimeout +
+                    '}';
+        }
+
+        /**
+         * 转换成 csv 格式
+         *
+         * @return
+         */
+        public String toLineString(String key) {
+            String separator = ",";
+            Object[] objects = new Object[] {
+                version, sdk, uuid, timestamp, elapsedTimeMillis,
+                    firstDomain, primaryDomain, firstConnectTimeoutMillis, firstReadTimeoutMillis,
+                    firstHasDnsError, firstHasConnectTimeout, firstHasReadTimeout
+            };
+            StringBuffer sb = new StringBuffer();
+            for(Object obj: objects) {
+                sb.append(obj).append(separator);
+            }
+            try {
+                String sign = WXPayUtil.HMACSHA256(sb.toString(), key);
+                sb.append(sign);
+                return sb.toString();
+            }
+            catch (Exception ex) {
+                return null;
+            }
+
+        }
+
+    }
+
+    private static final String REPORT_URL = "http://report.mch.weixin.qq.com/wxpay/report/default";
+    // private static final String REPORT_URL = "http://127.0.0.1:5000/test";
+
+
+    private static final int DEFAULT_CONNECT_TIMEOUT_MS = 6*1000;
+    private static final int DEFAULT_READ_TIMEOUT_MS = 8*1000;
+
+    private LinkedBlockingQueue<String> reportMsgQueue = null;
+    private WXPayConfig config;
+    private ExecutorService executorService;
+
+    private volatile static WXPayReport INSTANCE;
+
+    private WXPayReport(final WXPayConfig config) {
+        this.config = config;
+        reportMsgQueue = new LinkedBlockingQueue<String>(config.getReportQueueMaxSize());
+
+        // 添加处理线程
+        executorService = Executors.newFixedThreadPool(config.getReportWorkerNum(), new ThreadFactory() {
+            public Thread newThread(Runnable r) {
+                Thread t = Executors.defaultThreadFactory().newThread(r);
+                t.setDaemon(true);
+                return t;
+            }
+        });
+
+        if (config.shouldAutoReport()) {
+            WXPayUtil.getLogger().info("report worker num: {}", config.getReportWorkerNum());
+            for (int i = 0; i < config.getReportWorkerNum(); ++i) {
+                executorService.execute(new Runnable() {
+                    public void run() {
+                        while (true) {
+                            // 先用 take 获取数据
+                            try {
+                                StringBuffer sb = new StringBuffer();
+                                String firstMsg = reportMsgQueue.take();
+                                WXPayUtil.getLogger().info("get first report msg: {}", firstMsg);
+                                String msg = null;
+                                sb.append(firstMsg); //会阻塞至有消息
+                                int remainNum = config.getReportBatchSize() - 1;
+                                for (int j=0; j<remainNum; ++j) {
+                                    WXPayUtil.getLogger().info("try get remain report msg");
+                                    // msg = reportMsgQueue.poll();  // 不阻塞了
+                                    msg = reportMsgQueue.take();
+                                    WXPayUtil.getLogger().info("get remain report msg: {}", msg);
+                                    if (msg == null) {
+                                        break;
+                                    }
+                                    else {
+                                        sb.append("\n");
+                                        sb.append(msg);
+                                    }
+                                }
+                                // 上报
+                                WXPayReport.httpRequest(sb.toString(), DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
+                            }
+                            catch (Exception ex) {
+                                WXPayUtil.getLogger().warn("report fail. reason: {}", ex.getMessage());
+                            }
+                        }
+                    }
+                });
+            }
+        }
+
+    }
+
+    /**
+     * 单例,双重校验,请在 JDK 1.5及更高版本中使用
+     *
+     * @param config
+     * @return
+     */
+    public static WXPayReport getInstance(WXPayConfig config) {
+        if (INSTANCE == null) {
+            synchronized (WXPayReport.class) {
+                if (INSTANCE == null) {
+                    INSTANCE = new WXPayReport(config);
+                }
+            }
+        }
+        return INSTANCE;
+    }
+
+    public void report(String uuid, long elapsedTimeMillis,
+                       String firstDomain, boolean primaryDomain, int firstConnectTimeoutMillis, int firstReadTimeoutMillis,
+                       boolean firstHasDnsError, boolean firstHasConnectTimeout, boolean firstHasReadTimeout) {
+        long currentTimestamp = WXPayUtil.getCurrentTimestamp();
+        ReportInfo reportInfo = new ReportInfo(uuid, currentTimestamp, elapsedTimeMillis,
+                firstDomain, primaryDomain, firstConnectTimeoutMillis, firstReadTimeoutMillis,
+                firstHasDnsError, firstHasConnectTimeout, firstHasReadTimeout);
+        String data = reportInfo.toLineString(config.getKey());
+        WXPayUtil.getLogger().info("report {}", data);
+        if (data != null) {
+            reportMsgQueue.offer(data);
+        }
+    }
+
+
+    @Deprecated
+    private void reportSync(final String data) throws Exception {
+        httpRequest(data, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
+    }
+
+    @Deprecated
+    private void reportAsync(final String data) throws Exception {
+        new Thread(new Runnable() {
+            public void run() {
+                try {
+                    httpRequest(data, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
+                }
+                catch (Exception ex) {
+                    WXPayUtil.getLogger().warn("report fail. reason: {}", ex.getMessage());
+                }
+            }
+        }).start();
+    }
+
+    /**
+     * http 请求
+     * @param data
+     * @param connectTimeoutMs
+     * @param readTimeoutMs
+     * @return
+     * @throws Exception
+     */
+    private static String httpRequest(String data, int connectTimeoutMs, int readTimeoutMs) throws Exception{
+        BasicHttpClientConnectionManager connManager;
+        connManager = new BasicHttpClientConnectionManager(
+                RegistryBuilder.<ConnectionSocketFactory>create()
+                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
+                        .register("https", SSLConnectionSocketFactory.getSocketFactory())
+                        .build(),
+                null,
+                null,
+                null
+        );
+        HttpClient httpClient = HttpClientBuilder.create()
+                .setConnectionManager(connManager)
+                .build();
+
+        HttpPost httpPost = new HttpPost(REPORT_URL);
+
+        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
+        httpPost.setConfig(requestConfig);
+
+        StringEntity postEntity = new StringEntity(data, "UTF-8");
+        httpPost.addHeader("Content-Type", "text/xml");
+        httpPost.addHeader("User-Agent", "wxpay sdk java v1.0 ");  // TODO: 很重要,用来检测 sdk 的使用情况,要不要加上商户信息?
+        httpPost.setEntity(postEntity);
+
+        HttpResponse httpResponse = httpClient.execute(httpPost);
+        HttpEntity httpEntity = httpResponse.getEntity();
+        return EntityUtils.toString(httpEntity, "UTF-8");
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/WXPayRequest.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/WXPayRequest.java
new file mode 100644
index 0000000..8e50521
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/protocol/WXPayRequest.java
@@ -0,0 +1,331 @@
+package com.ruoyi.order.util.tencent.protocol;
+
+import com.ruoyi.order.util.tencent.common.IWXPayDomain;
+import com.ruoyi.order.util.tencent.common.WXPayConfig;
+import com.ruoyi.order.util.tencent.common.WXPayUtil;
+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.HttpPost;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.ConnectTimeoutException;
+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.HttpClientBuilder;
+import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
+import org.apache.http.util.EntityUtils;
+
+
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+
+import java.io.InputStream;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+
+public class WXPayRequest {
+    private WXPayConfig config;
+    public WXPayRequest(WXPayConfig config) throws Exception{
+
+        this.config = config;
+    }
+
+    /**
+     * 请求,只请求一次,不做重试
+     * @param domain
+     * @param urlSuffix
+     * @param uuid
+     * @param data
+     * @param connectTimeoutMs
+     * @param readTimeoutMs
+     * @param useCert 是否使用证书,针对退款、撤销等操作
+     * @return
+     * @throws Exception
+     */
+    private String requestOnce(final String domain, String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean useCert) throws Exception {
+        BasicHttpClientConnectionManager connManager;
+        if (useCert) {
+            // 证书
+            char[] password = config.getMchID().toCharArray();
+            InputStream certStream = config.getCertStream();
+            KeyStore ks = KeyStore.getInstance("PKCS12");
+            ks.load(certStream, password);
+
+            // 实例化密钥库 & 初始化密钥工厂
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+            kmf.init(ks, password);
+
+            // 创建 SSLContext
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
+
+            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
+                    sslContext);
+
+            connManager = new BasicHttpClientConnectionManager(
+                    RegistryBuilder.<ConnectionSocketFactory>create()
+                            .register("http", PlainConnectionSocketFactory.getSocketFactory())
+                            .register("https", sslConnectionSocketFactory)
+                            .build(),
+                    null,
+                    null,
+                    null
+            );
+        }
+        else {
+            connManager = new BasicHttpClientConnectionManager(
+                    RegistryBuilder.<ConnectionSocketFactory>create()
+                            .register("http", PlainConnectionSocketFactory.getSocketFactory())
+                            .register("https", SSLConnectionSocketFactory.getSocketFactory())
+                            .build(),
+                    null,
+                    null,
+                    null
+            );
+        }
+
+        HttpClient httpClient = HttpClientBuilder.create()
+                .setConnectionManager(connManager)
+                .build();
+
+        String url = "https://" + domain + urlSuffix;
+        HttpPost httpPost = new HttpPost(url);
+
+        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
+        httpPost.setConfig(requestConfig);
+
+        StringEntity postEntity = new StringEntity(data, "UTF-8");
+        httpPost.addHeader("Content-Type", "text/xml");
+        httpPost.addHeader("User-Agent", "wxpay sdk java v1.0 " + config.getMchID());  // TODO: 很重要,用来检测 sdk 的使用情况,要不要加上商户信息?
+        httpPost.setEntity(postEntity);
+
+        HttpResponse httpResponse = httpClient.execute(httpPost);
+        HttpEntity httpEntity = httpResponse.getEntity();
+        return EntityUtils.toString(httpEntity, "UTF-8");
+
+    }
+
+
+    private String request(String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean useCert, boolean autoReport) throws Exception {
+        Exception exception = null;
+        long elapsedTimeMillis = 0;
+        long startTimestampMs = WXPayUtil.getCurrentTimestampMs();
+        boolean firstHasDnsErr = false;
+        boolean firstHasConnectTimeout = false;
+        boolean firstHasReadTimeout = false;
+        IWXPayDomain.DomainInfo domainInfo = config.getWXPayDomain().getDomain(config);
+        if(domainInfo == null){
+            throw new Exception("WXPayConfig.getWXPayDomain().getDomain() is empty or null");
+        }
+        try {
+            String result = requestOnce(domainInfo.domain, urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, useCert);
+            elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
+            config.getWXPayDomain().report(domainInfo.domain, elapsedTimeMillis, null);
+            WXPayReport.getInstance(config).report(
+                    uuid,
+                    elapsedTimeMillis,
+                    domainInfo.domain,
+                    domainInfo.primaryDomain,
+                    connectTimeoutMs,
+                    readTimeoutMs,
+                    firstHasDnsErr,
+                    firstHasConnectTimeout,
+                    firstHasReadTimeout);
+            return result;
+        }
+        catch (UnknownHostException ex) {  // dns 解析错误,或域名不存在
+            exception = ex;
+            firstHasDnsErr = true;
+            elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
+            WXPayUtil.getLogger().warn("UnknownHostException for domainInfo {}", domainInfo);
+            WXPayReport.getInstance(config).report(
+                    uuid,
+                    elapsedTimeMillis,
+                    domainInfo.domain,
+                    domainInfo.primaryDomain,
+                    connectTimeoutMs,
+                    readTimeoutMs,
+                    firstHasDnsErr,
+                    firstHasConnectTimeout,
+                    firstHasReadTimeout
+            );
+        }
+        catch (ConnectTimeoutException ex) {
+            exception = ex;
+            firstHasConnectTimeout = true;
+            elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
+            WXPayUtil.getLogger().warn("connect timeout happened for domainInfo {}", domainInfo);
+            WXPayReport.getInstance(config).report(
+                    uuid,
+                    elapsedTimeMillis,
+                    domainInfo.domain,
+                    domainInfo.primaryDomain,
+                    connectTimeoutMs,
+                    readTimeoutMs,
+                    firstHasDnsErr,
+                    firstHasConnectTimeout,
+                    firstHasReadTimeout
+            );
+        }
+        catch (SocketTimeoutException ex) {
+            exception = ex;
+            firstHasReadTimeout = true;
+            elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
+            WXPayUtil.getLogger().warn("timeout happened for domainInfo {}", domainInfo);
+            WXPayReport.getInstance(config).report(
+                    uuid,
+                    elapsedTimeMillis,
+                    domainInfo.domain,
+                    domainInfo.primaryDomain,
+                    connectTimeoutMs,
+                    readTimeoutMs,
+                    firstHasDnsErr,
+                    firstHasConnectTimeout,
+                    firstHasReadTimeout);
+        }
+        catch (Exception ex) {
+            exception = ex;
+            elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
+            WXPayReport.getInstance(config).report(
+                    uuid,
+                    elapsedTimeMillis,
+                    domainInfo.domain,
+                    domainInfo.primaryDomain,
+                    connectTimeoutMs,
+                    readTimeoutMs,
+                    firstHasDnsErr,
+                    firstHasConnectTimeout,
+                    firstHasReadTimeout);
+        }
+        config.getWXPayDomain().report(domainInfo.domain, elapsedTimeMillis, exception);
+        throw exception;
+    }
+
+
+    /**
+     * 可重试的,非双向认证的请求
+     * @param urlSuffix
+     * @param uuid
+     * @param data
+     * @return
+     */
+    public String requestWithoutCert(String urlSuffix, String uuid, String data, boolean autoReport) throws Exception {
+        return this.request(urlSuffix, uuid, data, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs(), false, autoReport);
+        //return requestWithoutCert(urlSuffix, uuid, data, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs(), autoReport);
+    }
+
+    /**
+     * 可重试的,非双向认证的请求
+     * @param urlSuffix
+     * @param uuid
+     * @param data
+     * @param connectTimeoutMs
+     * @param readTimeoutMs
+     * @return
+     */
+    public String requestWithoutCert(String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs,  boolean autoReport) throws Exception {
+        return this.request(urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, false, autoReport);
+
+        /*
+        String result;
+        Exception exception;
+        boolean shouldRetry = false;
+
+        boolean useCert = false;
+        try {
+            result = requestOnce(domain, urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, useCert);
+            return result;
+        }
+        catch (UnknownHostException ex) {  // dns 解析错误,或域名不存在
+            exception = ex;
+            WXPayUtil.getLogger().warn("UnknownHostException for domain {}, try to use {}", domain, this.primaryDomain);
+            shouldRetry = true;
+        }
+        catch (ConnectTimeoutException ex) {
+            exception = ex;
+            WXPayUtil.getLogger().warn("connect timeout happened for domain {}, try to use {}", domain, this.primaryDomain);
+            shouldRetry = true;
+        }
+        catch (SocketTimeoutException ex) {
+            exception = ex;
+            shouldRetry = false;
+        }
+        catch (Exception ex) {
+            exception = ex;
+            shouldRetry = false;
+        }
+
+        if (shouldRetry) {
+            result = requestOnce(this.primaryDomain, urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, useCert);
+            return result;
+        }
+        else {
+            throw exception;
+        }
+        */
+    }
+
+    /**
+     * 可重试的,双向认证的请求
+     * @param urlSuffix
+     * @param uuid
+     * @param data
+     * @return
+     */
+    public String requestWithCert(String urlSuffix, String uuid, String data, boolean autoReport) throws Exception {
+        return this.request(urlSuffix, uuid, data, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs(), true, autoReport);
+        //return requestWithCert(urlSuffix, uuid, data, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs(), autoReport);
+    }
+
+    /**
+     * 可重试的,双向认证的请求
+     * @param urlSuffix
+     * @param uuid
+     * @param data
+     * @param connectTimeoutMs
+     * @param readTimeoutMs
+     * @return
+     */
+    public String requestWithCert(String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean autoReport) throws Exception {
+        return this.request(urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, true, autoReport);
+
+        /*
+        String result;
+        Exception exception;
+        boolean shouldRetry = false;
+
+        boolean useCert = true;
+        try {
+            result = requestOnce(domain, urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, useCert);
+            return result;
+        }
+        catch (ConnectTimeoutException ex) {
+            exception = ex;
+            WXPayUtil.getLogger().warn(String.format("connect timeout happened for domain {}, try to use {}", domain, this.primaryDomain));
+            shouldRetry = true;
+        }
+        catch (SocketTimeoutException ex) {
+            exception = ex;
+            shouldRetry = false;
+        }
+        catch (Exception ex) {
+            exception = ex;
+            shouldRetry = false;
+        }
+
+        if (shouldRetry && this.primaryDomain != null) {
+            result = requestOnce(this.primaryDomain, urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, useCert, autoReport);
+            return result;
+        }
+        else {
+            throw exception;
+        }
+        */
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/BaseService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/BaseService.java
new file mode 100644
index 0000000..af9da18
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/BaseService.java
@@ -0,0 +1,49 @@
+package com.ruoyi.order.util.tencent.service;
+import com.ruoyi.order.util.tencent.common.Configure;
+
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+
+
+
+/**
+ * User: rizenguo
+ * Date: 2014/12/10
+ * Time: 15:44
+ * 服务的基类
+ */
+public class BaseService{
+
+	//API的地址
+	private String apiURL;
+
+	//发请求的HTTPS请求器
+	private IServiceRequest serviceRequest;
+
+	public BaseService(Integer apptype,String api) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+		apiURL = api;
+	
+		   if (apptype.equals(2)) {//微信小程序和公众号的
+	        	Class<?> c = Class.forName(Configure.HttpsRequestClassName_2);
+	            serviceRequest = (IServiceRequest) c.newInstance();
+			} else {//微信app的
+				Class<?> c = Class.forName(Configure.HttpsRequestClassName);
+				serviceRequest = (IServiceRequest) c.newInstance();
+			}
+	}
+
+	protected String sendPost(Object xmlObj) throws UnrecoverableKeyException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+		return serviceRequest.sendPost(apiURL, xmlObj);
+	}
+
+	/**
+	 * 供商户想自定义自己的HTTP请求器用
+	 * @param request 实现了IserviceRequest接口的HttpsRequest
+	 */
+	public void setServiceRequest(IServiceRequest request){
+		serviceRequest = request;
+	}
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/IServiceRequest.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/IServiceRequest.java
new file mode 100644
index 0000000..9b21366
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/IServiceRequest.java
@@ -0,0 +1,20 @@
+package com.ruoyi.order.util.tencent.service;
+
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+
+/**
+ * User: rizenguo
+ * Date: 2014/12/10
+ * Time: 15:16
+ * 这里定义服务层需要请求器标准接口
+ */
+public interface IServiceRequest {
+
+    //Service依赖的底层https请求器必须实现这么一个接口
+    public String sendPost(String api_url, Object xmlObj) throws UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, IOException;
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/PayToTheUserService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/PayToTheUserService.java
new file mode 100644
index 0000000..6560e34
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/PayToTheUserService.java
@@ -0,0 +1,30 @@
+/*package com.ruoyi.order.util.tencent.service;
+
+import com.tencent.common.Configure;
+import com.tencent.protocol.PayToTheUserReqData;
+
+
+public class PayToTheUserService extends BaseService{
+
+    public PayToTheUserService(Integer apptype) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
+        super(apptype,Configure.PayToTheUser_API);
+    }
+
+    *//**
+     * 请求商户向用户支付
+     * @param refundReqData 这个数据对象里面包含了API要求提交的各种数据字段
+     * @return API返回的XML数据
+     * @throws Exception
+     *//*
+    public String request(PayToTheUserReqData payToTheUserReqData) throws Exception {
+
+        //--------------------------------------------------------------------
+        //发送HTTPS的Post请求到API地址
+        //--------------------------------------------------------------------
+        String responseString = sendPost(payToTheUserReqData);
+
+        return responseString;
+    }
+
+}
+*/
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/RefundService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/RefundService.java
new file mode 100644
index 0000000..782be4b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/RefundService.java
@@ -0,0 +1,34 @@
+package com.ruoyi.order.util.tencent.service;
+
+
+import com.ruoyi.order.util.tencent.common.Configure;
+import com.tencent.protocol.RefundReqData;
+
+/**
+ * User: rizenguo
+ * Date: 2014/10/29
+ * Time: 16:04
+ */
+public class RefundService extends BaseService{
+
+    public RefundService(Integer apptype) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
+        super(apptype, Configure.REFUND_API);
+    }
+
+    /**
+     * 请求退款服务
+     * @param refundReqData 这个数据对象里面包含了API要求提交的各种数据字段
+     * @return API返回的XML数据
+     * @throws Exception
+     */
+    public String request(RefundReqData refundReqData) throws Exception {
+
+        //--------------------------------------------------------------------
+        //发送HTTPS的Post请求到API地址
+        //--------------------------------------------------------------------
+        String responseString = sendPost(refundReqData);
+
+        return responseString;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/UnifiedorderService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/UnifiedorderService.java
new file mode 100644
index 0000000..2bd8371
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/UnifiedorderService.java
@@ -0,0 +1,30 @@
+package com.ruoyi.order.util.tencent.service;
+
+
+import com.ruoyi.order.util.tencent.common.Configure;
+import com.ruoyi.order.util.tencent.protocol.UnifiedorderReqData;
+
+/**
+ * 统一下单服务
+ * @author pen
+ */
+public class UnifiedorderService extends BaseService{
+
+    public UnifiedorderService(Integer apptype) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
+        super(apptype, Configure.UNIFIEDORDER_API);
+    }
+
+    /**
+     * 统一下单服务
+     * @param UnifiedorderReqData 这个数据对象里面包含了API要求提交的各种数据字段
+     */
+    public String request(UnifiedorderReqData unifiedorderReqData) throws Exception {
+
+        //--------------------------------------------------------------------
+        //发送HTTPS的Post请求到API地址
+        //--------------------------------------------------------------------
+        String responseString = sendPost(unifiedorderReqData);
+
+        return responseString;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayConfigImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayConfigImpl.java
new file mode 100644
index 0000000..8254fcb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayConfigImpl.java
@@ -0,0 +1,89 @@
+package com.ruoyi.order.util.tencent.service;
+
+import com.ruoyi.order.util.tencent.common.IWXPayDomain;
+import com.ruoyi.order.util.tencent.common.WXPayConfig;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+
+
+public class WXPayConfigImpl extends WXPayConfig {
+
+    private byte[] certData;
+    private static WXPayConfigImpl INSTANCE;
+
+    private WXPayConfigImpl() throws Exception{
+        String certPath = WXPayConfigImpl.class.getClassLoader().getResource("").getPath() + "com/tencent/common/cert/apiclient_cert.p12";
+        File file = new File(certPath);
+        InputStream certStream = new FileInputStream(file);
+        this.certData = new byte[(int) file.length()];
+        certStream.read(this.certData);
+        certStream.close();
+    }
+
+    public static WXPayConfigImpl getInstance() throws Exception{
+        if (INSTANCE == null) {
+            synchronized (WXPayConfigImpl.class) {
+                if (INSTANCE == null) {
+                    INSTANCE = new WXPayConfigImpl();
+                }
+            }
+        }
+        return INSTANCE;
+    }
+
+
+    public String getMchID() {
+        return "11473623";
+    }
+
+    public String getKey() {
+        return "2ab9071b06b9f739b950ddb41db2690d";
+    }
+
+    public InputStream getCertStream() {
+        ByteArrayInputStream certBis;
+        certBis = new ByteArrayInputStream(this.certData);
+        return certBis;
+    }
+
+
+    public int getHttpConnectTimeoutMs() {
+        return 2000;
+    }
+
+    public int getHttpReadTimeoutMs() {
+        return 10000;
+    }
+
+    public IWXPayDomain getWXPayDomain() {
+        return WXPayDomainSimpleImpl.instance();
+    }
+
+    public String getPrimaryDomain() {
+        return "api.mch.weixin.qq.com";
+    }
+
+    public String getAlternateDomain() {
+        return "api2.mch.weixin.qq.com";
+    }
+
+    @Override
+    public int getReportWorkerNum() {
+        return 1;
+    }
+
+    @Override
+    public int getReportBatchSize() {
+        return 2;
+    }
+
+	@Override
+	public String getAppID() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayDomainSimpleImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayDomainSimpleImpl.java
new file mode 100644
index 0000000..4440c94
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayDomainSimpleImpl.java
@@ -0,0 +1,101 @@
+package com.ruoyi.order.util.tencent.service;
+import com.ruoyi.order.util.tencent.common.IWXPayDomain;
+import com.ruoyi.order.util.tencent.common.WXPayConfig;
+import com.ruoyi.order.util.tencent.common.WXPayConstants;
+import org.apache.http.conn.ConnectTimeoutException;
+
+
+
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by blaketang on 2017/6/16.
+ */
+public class WXPayDomainSimpleImpl implements IWXPayDomain {
+    private WXPayDomainSimpleImpl(){}
+    private static class WxpayDomainHolder{
+        private static IWXPayDomain holder = new WXPayDomainSimpleImpl();
+    }
+    public static IWXPayDomain instance(){
+        return WxpayDomainHolder.holder;
+    }
+
+    public synchronized void report(final String domain, long elapsedTimeMillis, final Exception ex) {
+        DomainStatics info = domainData.get(domain);
+        if(info == null){
+            info = new DomainStatics(domain);
+            domainData.put(domain, info);
+        }
+
+        if(ex == null){ //success
+            if(info.succCount >= 2){    //continue succ, clear error count
+                info.connectTimeoutCount = info.dnsErrorCount = info.otherErrorCount = 0;
+            }else{
+                ++info.succCount;
+            }
+        }else if(ex instanceof ConnectTimeoutException){
+            info.succCount = info.dnsErrorCount = 0;
+            ++info.connectTimeoutCount;
+        }else if(ex instanceof UnknownHostException){
+            info.succCount = 0;
+            ++info.dnsErrorCount;
+        }else{
+            info.succCount = 0;
+            ++info.otherErrorCount;
+        }
+    }
+
+    public synchronized DomainInfo getDomain(final WXPayConfig config) {
+        DomainStatics primaryDomain = domainData.get(WXPayConstants.DOMAIN_API);
+        if(primaryDomain == null ||
+                primaryDomain.isGood()) {
+            return new DomainInfo(WXPayConstants.DOMAIN_API, true);
+        }
+
+        long now = System.currentTimeMillis();
+        if(switchToAlternateDomainTime == 0){   //first switch
+            switchToAlternateDomainTime = now;
+            return new DomainInfo(WXPayConstants.DOMAIN_API2, false);
+        }else if(now - switchToAlternateDomainTime < MIN_SWITCH_PRIMARY_MSEC){
+            DomainStatics alternateDomain = domainData.get(WXPayConstants.DOMAIN_API2);
+            if(alternateDomain == null ||
+                alternateDomain.isGood() ||
+                alternateDomain.badCount() < primaryDomain.badCount()){
+                return new DomainInfo(WXPayConstants.DOMAIN_API2, false);
+            }else{
+                return new DomainInfo(WXPayConstants.DOMAIN_API, true);
+            }
+        }else{  //force switch back
+            switchToAlternateDomainTime = 0;
+            primaryDomain.resetCount();
+            DomainStatics alternateDomain = domainData.get(WXPayConstants.DOMAIN_API2);
+            if(alternateDomain != null)
+                alternateDomain.resetCount();
+            return new DomainInfo(WXPayConstants.DOMAIN_API, true);
+        }
+    }
+
+    static class DomainStatics {
+        final String domain;
+        int succCount = 0;
+        int connectTimeoutCount = 0;
+        int dnsErrorCount =0;
+        int otherErrorCount = 0;
+
+        DomainStatics(String domain) {
+            this.domain = domain;
+        }
+        void resetCount(){
+            succCount = connectTimeoutCount = dnsErrorCount = otherErrorCount = 0;
+        }
+        boolean isGood(){ return connectTimeoutCount <= 2 && dnsErrorCount <= 2; }
+        int badCount(){
+            return connectTimeoutCount + dnsErrorCount * 5 + otherErrorCount / 4;
+        }
+    }
+    private final int MIN_SWITCH_PRIMARY_MSEC = 3 * 60 * 1000;  //3 minutes
+    private long switchToAlternateDomainTime = 0;
+    private Map<String, DomainStatics> domainData = new HashMap<String, DomainStatics>();
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayPerformance.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayPerformance.java
new file mode 100644
index 0000000..63ff623
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/tencent/service/WXPayPerformance.java
@@ -0,0 +1,148 @@
+/*package com.ruoyi.order.util.tencent.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.tencent.WXPay;
+import com.tencent.common.WXPayUtil;
+
+public class WXPayPerformance {
+
+
+	private WXPay wxpay;
+	private WXPayConfigImpl config;
+
+	public WXPayPerformance() throws Exception {
+		config = WXPayConfigImpl.getInstance();
+		wxpay = new WXPay(config);
+	}
+
+	*//**
+	 * 商户 扫码抢 扫码支付
+	 * @param out_trade_no
+	 * @param body
+	 * @param total_fee
+	 * @param auth_code
+	 *//*
+	public Map<String, String> doMicropayWithPos(String out_trade_no,String body,String total_fee,String auth_code) {
+		HashMap<String, String> data = new HashMap<String, String>();
+		data.put("out_trade_no", out_trade_no);
+		data.put("body", body);
+		data.put("total_fee", total_fee);
+		data.put("auth_code", auth_code);
+		Map<String, String> r=new HashMap<>();
+		try {
+			 r = wxpay.microPayWithPos(data);
+			System.out.println(r);
+		} catch (Exception e) {			
+			e.printStackTrace();
+			return r;
+		}
+		return r;
+	}
+
+	
+    *//**
+     * 统一 下单2.0
+     *//*
+    public Map<String, String> doUnifiedOrder(String out_trade_no,String total_fee,String notify_url) {
+        HashMap<String, String> data = new HashMap<String, String>();
+        data.put("body", "超级教材");
+        data.put("out_trade_no", out_trade_no);
+        data.put("device_info", "");
+        data.put("fee_type", "CNY");
+        data.put("total_fee", total_fee);
+        //data.put("spbill_create_ip", "123.12.12.123");
+        data.put("notify_url", notify_url);
+        data.put("trade_type", "APP");
+        //data.put("product_id", "12");
+        // data.put("time_expire", "20170112104120");
+
+        try {
+            Map<String, String> r = wxpay.unifiedOrder(data);
+            System.out.println(r);
+            return r;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+	//    public void doReport() {
+	//        HashMap<String, String> data = new HashMap<String, String>();
+	//        data.put("interface_url", "20160822");
+	//        data.put("bill_type", "ALL");
+	//    }
+
+	*//**
+	 * 小测试
+	 *//*
+	public void test001() {
+		String xmlStr="<xml><return_code><![CDATA[SUCCESS]]></return_code>\n" +
+				"<return_msg><![CDATA[OK]]></return_msg>\n" +
+				"<appid><![CDATA[wx273fe72f2db863ed]]></appid>\n" +
+				"<mch_id><![CDATA[1228845802]]></mch_id>\n" +
+				"<nonce_str><![CDATA[lCXjx3wNx45HfTV2]]></nonce_str>\n" +
+				"<sign><![CDATA[68D7573E006F0661FD2A77BA59124E87]]></sign>\n" +
+				"<result_code><![CDATA[SUCCESS]]></result_code>\n" +
+				"<openid><![CDATA[oZyc_uPx_oed7b4q1yKmj_3M2fTU]]></openid>\n" +
+				"<is_subscribe><![CDATA[N]]></is_subscribe>\n" +
+				"<trade_type><![CDATA[NATIVE]]></trade_type>\n" +
+				"<bank_type><![CDATA[CFT]]></bank_type>\n" +
+				"<total_fee>1</total_fee>\n" +
+				"<fee_type><![CDATA[CNY]]></fee_type>\n" +
+				"<transaction_id><![CDATA[4008852001201608221983528929]]></transaction_id>\n" +
+				"<out_trade_no><![CDATA[20160822162018]]></out_trade_no>\n" +
+				"<attach><![CDATA[]]></attach>\n" +
+				"<time_end><![CDATA[20160822202556]]></time_end>\n" +
+				"<trade_state><![CDATA[SUCCESS]]></trade_state>\n" +
+				"<cash_fee>1</cash_fee>\n" +
+				"</xml>";
+		try {
+			System.out.println(xmlStr);
+			System.out.println("+++++++++++++++++");
+			System.out.println(WXPayUtil.isSignatureValid(xmlStr, config.getKey()));
+			Map<String, String> hm = WXPayUtil.xmlToMap(xmlStr);
+			System.out.println("+++++++++++++++++");
+			System.out.println(hm);
+			System.out.println(hm.get("attach").length());
+
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	public void testHelloWorld() throws Exception {
+		for (int i=0; i<1000; ++i) {
+			System.out.println("hi");
+			Thread.sleep(1000);
+		}
+	}
+
+
+	public static void main(String[] args) throws Exception {    	
+       //测试商户扫码支付
+		WXPayPerformance dodo = new WXPayPerformance();
+		Map<String, String> r =dodo.doMicropayWithPos("11151521","测试","1","130226992988325162");
+		if(r.isEmpty()){
+			System.out.println("--------------->");
+		}else{
+			if(r.containsKey("err_code_des")){
+				System.out.println("支付失败:"+r.get("err_code_des"));
+			}else{
+				if(r.get("return_msg").equals("OK")){
+					System.out.println("支付成功:"+r.get("err_code_des"));
+				}
+			}
+		}
+		 //测试app支付
+		WXPayPerformance dodo1 = new WXPayPerformance();
+		dodo1.doUnifiedOrder("12121", "1", "http://192.168.1.90:8080/textbook/app/pay/wxpay/notify");
+
+	}
+}
+
+
+*/
\ No newline at end of file

--
Gitblit v1.7.1