2 Commits 0eec3f1662 ... 11ccd85137

Auteur SHA1 Bericht Datum
  panlijun 11ccd85137 Merge branch 'feature/wxPay' of http://git.aseanbusiness.cn/qzyReal/market-server into feature/wxPay 3 weken geleden
  panlijun 7c94c83ec5 增加了微信支付接口处理。 3 weken geleden

+ 10 - 0
sp-service/level-one-server/pom.xml

@@ -26,6 +26,16 @@
             <artifactId>sp-base</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.github.wechatpay-apiv3</groupId>
+            <artifactId>wechatpay-java</artifactId>
+            <version>0.2.14</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-pay</artifactId>
+            <version>4.6.0</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 4 - 1
sp-service/level-one-server/src/main/java/com/pj/tb_people/TbPeople.java

@@ -309,5 +309,8 @@ public class TbPeople extends Model<TbPeople> implements Serializable {
 	 */
 	private Double wallet;
 
-
+	/**
+	 *  微信OpenId
+	 */
+	private String wxOpenId;
 }

+ 1 - 1
sp-service/level-one-server/src/main/java/com/pj/tb_people/TbPeopleMapper.xml

@@ -17,7 +17,7 @@
 			   p.group_id, p.group_name, p.status, p.role, p.lng, p.lat, p.last_location, p.address, p.address_ids,
 			   p.detail_address, p.is_lock, p.left_price, p.judge_status, p.judge_content, p.register_time, p.judge_time,
 			   p.person_id, p.create_time, p.create_by, p.create_name, p.update_time, p.update_by, p.update_name,
-			   p.delete_status, p.trade_area_id, p.trade_area_name,p.wallet
+			   p.delete_status, p.trade_area_id, p.trade_area_name,p.wallet,p.wx_open_id
 		from  tb_people p
 	</sql>
 

+ 173 - 44
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_record/TbWalletAppController.java

@@ -1,10 +1,21 @@
 package com.pj.tb_wallet_record;
 
-
+import cn.dev33.satoken.spring.SpringMVCUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
+import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
+import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
+import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
+import com.github.binarywang.wxpay.constant.WxPayConstants;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.pj.common.core.utils.StringUtils;
 import com.pj.current.dto.APPLoginUserInfo;
 import com.pj.current.satoken.StpAPPUserUtil;
 import com.pj.enummj.DeleteStatus;
-import com.pj.tb_order.TbOrder;
+import com.pj.tb_banner.TbBanner;
 import com.pj.tb_people.TbPeople;
 import com.pj.tb_people.TbPeopleService;
 import com.pj.tb_wallet_record.vo.WalletRecordAppVo;
@@ -12,25 +23,33 @@ import com.pj.tb_wallet_topdown.TbWalletTopdown;
 import com.pj.tb_wallet_topdown.TbWalletTopdownService;
 import com.pj.tb_wallet_topup.TbWalletTopup;
 import com.pj.tb_wallet_topup.TbWalletTopupService;
+import com.pj.utils.LogUtil;
 import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.sg.WebNbUtil;
 import com.pj.utils.so.SoMap;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
-import java.math.BigDecimal;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
 import java.util.Date;
 import java.util.List;
 
 
-
 /**
  * Controller: tb_wallet_record -- 服务点交易记录
  * @author plj
  */
+
 @RestController
 @RequestMapping("/app/WalletManage/")
 public class TbWalletAppController {
 
+    public static final String CZ_TABLE_NAME = "topup";
+    public static final String TX_TABLE_NAME = "topdown";
+
     /**
      * 底层 Service 对象
      */
@@ -52,6 +71,13 @@ public class TbWalletAppController {
     TbPeopleService tbPeopleService;
 
     /**
+     * 微信支付 Service 对象
+     */
+    @Autowired
+    private WxPayService wxService;
+
+
+    /**
      * 查集合 - 根据条件(参数为空时代表忽略指定条件)
      *
      * @return
@@ -92,32 +118,56 @@ public class TbWalletAppController {
         return AjaxJson.getSuccessData(t);
     }
     /*
-    * 服务点提现
+    * 服务点充值
      */
     @RequestMapping("topupSave")
-    public AjaxJson topupSave(@RequestParam("amount") Integer amount,@RequestParam("outTradeNo")String outTradeNo,@RequestParam("transactionId") String transactionId) {
+    public AjaxJson topupSave(@RequestParam("amount") Integer amount,@RequestParam("goodsName")String goodsName) {
         //获取登录人
         APPLoginUserInfo appLoginInfo = StpAPPUserUtil.getAPPLoginInfo();
-        TbWalletTopup tbWalletTopup = new TbWalletTopup();
-        Date date = new Date();
-        tbWalletTopup.setMchid("AAAAAA1111111111AAAAAA");
-        tbWalletTopup.setOutTradeNo(outTradeNo);
-        tbWalletTopup.setAmount(String.valueOf(amount/100));
-        tbWalletTopup.setTransactionId(transactionId);
-        tbWalletTopup.setPeopleId(appLoginInfo.getFk().toString());
-        tbWalletTopup.setTopupTime(date);
-        tbWalletTopup.setCreateTime(date);
-        tbWalletTopup.setCreateBy(appLoginInfo.getLoginId().toString());
-        tbWalletTopup.setCreateName(appLoginInfo.getLoginName());
-        tbWalletTopup.setDeleteStatus(DeleteStatus.DELETE_STATUS_ON.getCode());
-        boolean ret=tbWalletTopupService.save(tbWalletTopup);
-        if(ret){
-            TbPeople tbPeople = tbPeopleService.getById(appLoginInfo.getFk());
-            tbPeople.setWallet(tbPeople.getWallet()+amount/100);
-            tbPeopleService.updateById(tbPeople);
+        TbPeople tbPeople = tbPeopleService.getById(appLoginInfo.getFk());
+        if(StringUtils.isBlank(tbPeople.getWxOpenId())){
+            return AjaxJson.getError("未绑定微信用户!");
+        }
+        try {
+            TbWalletTopup tbWalletTopup = new TbWalletTopup();
+            Date date = new Date();
+            tbWalletTopup.setMchid(this.wxService.getConfig().getMchId());
+            tbWalletTopup.setOutTradeNo(CZ_TABLE_NAME+System.currentTimeMillis());
+            tbWalletTopup.setGoodsName(goodsName);
+            tbWalletTopup.setAmount(amount.toString());
+            tbWalletTopup.setPeopleId(tbPeople.getId().toString());
+            tbWalletTopup.setTopupTime(date);
+            tbWalletTopup.setCreateTime(date);
+            tbWalletTopup.setCreateBy(appLoginInfo.getLoginId().toString());
+            tbWalletTopup.setCreateName(appLoginInfo.getLoginName());
+
+            //调用统一下单接口,并组装生成支付所需参数对象
+            WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
+            // 商品描述
+            request.setBody(tbWalletTopup.getGoodsName());
+            // 商户订单编号
+            request.setOutTradeNo(tbWalletTopup.getOutTradeNo());
+            //支付金额
+            request.setTotalFee(BaseWxPayRequest.yuanToFen(tbWalletTopup.getAmount()));
+            request.setSpbillCreateIp(WebNbUtil.getIP(SpringMVCUtil.getRequest()));
+            // 回调地址
+            request.setNotifyUrl(wxService.getConfig().getNotifyUrl());
+            // 交易类型APP
+            request.setTradeType(wxService.getConfig().getTradeType());
+            request.setOpenid(tbPeople.getWxOpenId());
+            WxPayMpOrderResult data = wxService.createOrder(request);
+            // 业务处理
+            tbWalletTopup.setTransactionId(data.getPackageValue());
+            // 付款中
+            tbWalletTopup.setPayStatus(1);
+            tbWalletTopupService.save(tbWalletTopup);
             return AjaxJson.getSuccess();
-        }else{
-            return AjaxJson.getError("操作失败!");
+        } catch (WxPayException e) {
+            e.printStackTrace();
+            return AjaxJson.getError("微信支付失败," + e.getReturnMsg());
+        }catch (Exception e) {
+            e.printStackTrace();
+            return AjaxJson.getError("下单失败," + e.getMessage());
         }
     }
 
@@ -125,33 +175,112 @@ public class TbWalletAppController {
     * 服务点提现
      */
     @RequestMapping("topdownSave")
-    public AjaxJson topdownSave(@RequestParam("amount") Integer amount,@RequestParam("outTradeNo")String outTradeNo,@RequestParam("transactionId") String transactionId) {
+    public AjaxJson topdownSave(@RequestParam("amount") Integer amount,@RequestParam("goodsName")String goodsName) {
         //获取登录人
         APPLoginUserInfo appLoginInfo = StpAPPUserUtil.getAPPLoginInfo();
         TbPeople tbPeople = tbPeopleService.getById(appLoginInfo.getFk());
-        if(tbPeople.getWallet()<amount/100){
+        if (tbPeople.getWallet() < amount) {
             return AjaxJson.getError("余额不足!");
         }
-        TbWalletTopdown tbWalletTopdown = new TbWalletTopdown();
-        Date date = new Date();
-        tbWalletTopdown.setMchid("AAAAAA1111111111AAAAAA");
-        tbWalletTopdown.setOutTradeNo(outTradeNo);
-        tbWalletTopdown.setAmount(String.valueOf(amount/100));
-        tbWalletTopdown.setTransactionId(transactionId);
-        tbWalletTopdown.setPeopleId(appLoginInfo.getFk().toString());
-        tbWalletTopdown.setTopdownTime(date);
-        tbWalletTopdown.setCreateTime(date);
-        tbWalletTopdown.setCreateBy(appLoginInfo.getLoginId().toString());
-        tbWalletTopdown.setCreateName(appLoginInfo.getLoginName());
-        tbWalletTopdown.setDeleteStatus(DeleteStatus.DELETE_STATUS_ON.getCode());
-        boolean ret=tbWalletTopdownService.save(tbWalletTopdown);
-        if(ret){
-            tbPeople.setWallet(tbPeople.getWallet()-amount/100);
+        try {
+            TbWalletTopdown tbWalletTopdown = new TbWalletTopdown();
+            Date date = new Date();
+            tbWalletTopdown.setMchid(this.wxService.getConfig().getMchId());
+            tbWalletTopdown.setOutTradeNo(TX_TABLE_NAME + System.currentTimeMillis());
+            tbWalletTopdown.setGoodsName(goodsName);
+            tbWalletTopdown.setAmount(amount.toString());
+            tbWalletTopdown.setPeopleId(tbPeople.getId().toString());
+            tbWalletTopdown.setTopdownTime(date);
+            tbWalletTopdown.setCreateTime(date);
+            tbWalletTopdown.setCreateBy(appLoginInfo.getLoginId().toString());
+            tbWalletTopdown.setCreateName(appLoginInfo.getLoginName());
+
+            //调用企业付款到零钱接口,并组装接口所需参数对象
+            EntPayRequest request = new EntPayRequest();
+            // 商品描述
+            request.setDescription(tbWalletTopdown.getGoodsName());
+            // 商户订单编号
+            request.setPartnerTradeNo(tbWalletTopdown.getOutTradeNo());
+            //支付金额
+            request.setAmount(BaseWxPayRequest.yuanToFen(tbWalletTopdown.getAmount()));
+            request.setSpbillCreateIp(WebNbUtil.getIP(SpringMVCUtil.getRequest()));
+            // 交易类型APP
+            request.setCheckName(WxPayConstants.CheckNameOption.FORCE_CHECK);
+            request.setReUserName(tbPeople.getBankName());
+            request.setOpenid(tbPeople.getWxOpenId());
+            EntPayResult data = this.wxService.getEntPayService().entPay(request);
+            // 业务处理
+            tbWalletTopdown.setTransactionId(data.getPaymentNo());
+            // 成功
+            tbWalletTopdown.setPayStatus(2);
+            tbWalletTopdownService.updateById(tbWalletTopdown);
+            tbPeople.setWallet(tbPeople.getWallet()-Double.parseDouble(tbWalletTopdown.getAmount()));
             tbPeopleService.updateById(tbPeople);
             return AjaxJson.getSuccess();
-        }else{
-            return AjaxJson.getError("操作失败!");
+        } catch (WxPayException e) {
+            e.printStackTrace();
+            return AjaxJson.getError("微信支付失败," + e.getReturnMsg());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxJson.getError("下单失败," + e.getMessage());
+        }
+
+    }
+
+    /**
+     * 微信支付回调接口
+     * @return
+     */
+    @RequestMapping(value = "/wxPay/notify", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
+    public void notify(HttpServletRequest request, HttpServletResponse response) {
+        try {
+            request.setCharacterEncoding("UTF-8");
+            response.setCharacterEncoding("UTF-8");
+            response.setContentType("text/html;charset=UTF-8");
+            response.setHeader("Access-Control-Allow-Origin", "*");
+            InputStream in = request.getInputStream();
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int len = 0;
+            while ((len = in.read(buffer)) != -1) {
+                out.write(buffer, 0, len);
+            }
+            out.close();
+            in.close();
+            //xml数据
+            String reponseXml = new String(out.toByteArray(), "utf-8");
+            WxPayOrderNotifyResult result = wxService.parseOrderNotifyResult(reponseXml);
+            String resultCode = result.getResultCode();
+            String outTradeNo = result.getOutTradeNo();
+            if ("FAIL".equalsIgnoreCase(resultCode)) {
+                LogUtil.info("订单" + outTradeNo + "支付失败");
+                response.getWriter().write(setXml("SUCCESS", "OK"));
+            } else if ("SUCCESS".equalsIgnoreCase(resultCode)) {
+                LogUtil.info("订单" + outTradeNo + "支付成功");
+                // 充值数据处理
+                if(outTradeNo.indexOf(CZ_TABLE_NAME)>-1){
+                    QueryWrapper<TbWalletTopup> queryWrapper = new QueryWrapper<>();
+                    queryWrapper.eq("outTradeNo", outTradeNo);
+                    TbWalletTopup tbWalletTopup=tbWalletTopupService.list(queryWrapper).get(0);
+                    tbWalletTopup.setPayStatus(2);
+                    tbWalletTopupService.updateById(tbWalletTopup);
+
+                    TbPeople tbPeople = tbPeopleService.getById(tbWalletTopup.getPeopleId());
+                    tbPeople.setWallet(tbPeople.getWallet()+Double.parseDouble(tbWalletTopup.getAmount()));
+                    tbPeopleService.updateById(tbPeople);
+                }
+                response.getWriter().write(setXml("SUCCESS", "OK"));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
         }
     }
 
+    //返回微信服务
+    public static String setXml(String returnCode, String returnMsg) {
+        return "<xml><return_code><![CDATA[" + returnCode + "]]></return_code><return_msg><![CDATA[" + returnMsg + "]]></return_msg></xml>";
+    }
 }
+
+
+

+ 0 - 6
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_record/TbWalletRecord.java

@@ -127,10 +127,4 @@ public class TbWalletRecord extends Model<TbWalletRecord> implements Serializabl
 	private Integer deleteStatus;
 
 
-
-
-
-	
-
-
 }

+ 46 - 0
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_record/WxPayConfiguration.java

@@ -0,0 +1,46 @@
+package com.pj.tb_wallet_record;
+
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author plj
+ */
+@Configuration
+@ConditionalOnClass(WxPayService.class)
+@EnableConfigurationProperties(WxPayProperties.class)
+@AllArgsConstructor
+public class WxPayConfiguration {
+  @Autowired
+  private WxPayProperties properties;
+
+  @Bean
+  @ConditionalOnMissingBean
+  public WxPayService wxService() {
+    WxPayConfig payConfig = new WxPayConfig();
+    payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
+    payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
+    payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
+    payConfig.setTradeType(StringUtils.trimToNull(this.properties.getTradeType()));
+    payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiV3Key()));
+    payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
+    payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl()));
+
+    // 可以指定是否使用沙箱环境
+    payConfig.setUseSandboxEnv(false);
+
+    WxPayService wxPayService = new WxPayServiceImpl();
+    wxPayService.setConfig(payConfig);
+    return wxPayService;
+  }
+
+}

+ 47 - 0
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_record/WxPayProperties.java

@@ -0,0 +1,47 @@
+package com.pj.tb_wallet_record;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * wxpay pay properties.
+ * @author plj
+ */
+@Data
+@ConfigurationProperties(prefix = "wx.pay")
+public class WxPayProperties {
+  /**
+   * 设置微信公众号或者小程序等的appid
+   */
+  private String appId;
+
+  /**
+   * 微信支付商户号
+   */
+  private String mchId;
+
+  /**
+   * 微信支付商户密钥
+   */
+  private String mchKey;
+
+  /**
+   * 交易类型 JSAPI、APP
+   */
+  private String tradeType;
+
+  /**
+   * APIv3密钥
+   */
+  private String apiV3Key;
+
+  /**
+   * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定
+   */
+  private String keyPath;
+
+  /**
+   * 支付回调地址
+   */
+  private String notifyUrl;
+}

+ 118 - 0
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_topdown/EntPayController.java

@@ -0,0 +1,118 @@
+package com.pj.tb_wallet_topdown;
+
+import com.github.binarywang.wxpay.bean.entpay.*;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 企业付款相关接口
+ * @author plj
+ */
+
+@RestController
+@RequestMapping("/EntPay/")
+public class EntPayController {
+  @Autowired
+  private WxPayService wxService;
+
+  /**
+   * <pre>
+   * 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。
+   * 比如目前的保险行业向客户退保、给付、理赔。
+   * 企业付款将使用商户的可用余额,需确保可用余额充足。查看可用余额、充值、提现请登录商户平台“资金管理”https://pay.weixin.qq.com/进行操作。
+   * 注意:与商户微信支付收款资金并非同一账户,需要单独充值。
+   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
+   * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers
+   * </pre>
+   *
+   * @param request 请求对象
+   */
+  @ApiOperation(value = "企业付款到零钱")
+  @PostMapping("/entPay")
+  public EntPayResult entPay(@RequestBody EntPayRequest request) throws WxPayException {
+    return this.wxService.getEntPayService().entPay(request);
+  }
+
+  /**
+   * <pre>
+   * 查询企业付款API
+   * 用于商户的企业付款操作进行结果查询,返回付款操作详细结果。
+   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
+   * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo
+   * </pre>
+   *
+   * @param partnerTradeNo 商户订单号
+   */
+  @ApiOperation(value = "查询企业付款到零钱的结果")
+  @GetMapping("/queryEntPay/{partnerTradeNo}")
+  public EntPayQueryResult queryEntPay(@PathVariable String partnerTradeNo) throws WxPayException {
+    return this.wxService.getEntPayService().queryEntPay(partnerTradeNo);
+  }
+
+
+  /**
+   * <pre>
+   * 获取RSA加密公钥API.
+   * RSA算法使用说明(非对称加密算法,算法采用RSA/ECB/OAEPPadding模式)
+   * 1、 调用获取RSA公钥API获取RSA公钥,落地成本地文件,假设为public.pem
+   * 2、 确定public.pem文件的存放路径,同时修改代码中文件的输入路径,加载RSA公钥
+   * 3、 用标准的RSA加密库对敏感信息进行加密,选择RSA_PKCS1_OAEP_PADDING填充模式
+   * (eg:Java的填充方式要选 " RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING")
+   * 4、 得到进行rsa加密并转base64之后的密文
+   * 5、 将密文传给微信侧相应字段,如付款接口(enc_bank_no/enc_true_name)
+   *
+   * 接口默认输出PKCS#1格式的公钥,商户需根据自己开发的语言选择公钥格式
+   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7&index=4
+   * 接口链接:https://fraud.mch.weixin.qq.com/risk/getpublickey
+   * </pre>
+   *
+   * @return the public key
+   * @throws WxPayException the wx pay exception
+   */
+  @ApiOperation(value = "获取RSA加密公钥")
+  @GetMapping("/getPublicKey")
+  public String getPublicKey() throws WxPayException {
+    return this.wxService.getEntPayService().getPublicKey();
+  }
+
+  /**
+   * 企业付款到银行卡.
+   * <pre>
+   * 用于企业向微信用户银行卡付款
+   * 目前支持接口API的方式向指定微信用户的银行卡付款。
+   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_2
+   * 接口链接:https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank
+   * </pre>
+   *
+   * @param request 请求对象
+   * @return the ent pay bank result
+   * @throws WxPayException the wx pay exception
+   */
+  @ApiOperation(value = "企业付款到银行卡")
+  @PostMapping("/payBank")
+  public EntPayBankResult payBank(EntPayBankRequest request) throws WxPayException {
+    return this.wxService.getEntPayService().payBank(request);
+  }
+
+  /**
+   * 企业付款到银行卡查询.
+   * <pre>
+   * 用于对商户企业付款到银行卡操作进行结果查询,返回付款操作详细结果。
+   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_3
+   * 接口链接:https://api.mch.weixin.qq.com/mmpaysptrans/query_bank
+   * </pre>
+   *
+   * @param partnerTradeNo 商户订单号
+   * @return the ent pay bank query result
+   * @throws WxPayException the wx pay exception
+   */
+  @ApiOperation(value = "查询企业付款到银行卡的结果")
+  @GetMapping("/queryPayBank/{partnerTradeNo}")
+  public EntPayBankQueryResult queryPayBank(@PathVariable String partnerTradeNo) throws WxPayException {
+    return this.wxService.getEntPayService().queryPayBank(partnerTradeNo);
+  }
+
+}

+ 8 - 9
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_topdown/TbWalletTopdown.java

@@ -65,7 +65,12 @@ public class TbWalletTopdown extends Model<TbWalletTopdown> implements Serializa
 	/**
 	 * 微信支付系统生成的订单号 
 	 */
-	private String transactionId;	
+	private String transactionId;
+
+	/**
+	 * 商品名称
+	 */
+	private String goodsName;
 
 	/**
 	 * 提现金额 
@@ -108,15 +113,9 @@ public class TbWalletTopdown extends Model<TbWalletTopdown> implements Serializa
 	private String updateName;	
 
 	/**
-	 * 删除状态(0=禁用,1=启用) 
+	 * 支付状态(0=未支付,1=支付中,2=已支付)
 	 */
-	private Integer deleteStatus;	
-
-
-
-
-
-	
+	private Integer payStatus;
 
 
 }

+ 12 - 11
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_topdown/TbWalletTopdownMapper.xml

@@ -28,6 +28,7 @@
 			<if test=' this.has("mchid") '> and w.mchid = #{mchid} </if>
 			<if test=' this.has("outTradeNo") '> and w.out_trade_no = #{outTradeNo} </if>
 			<if test=' this.has("transactionId") '> and w.transaction_id = #{transactionId} </if>
+			<if test=' this.has("goodsName") '> and w.goods_name = #{goodsName} </if>
 			<if test=' this.has("amount") '> and w.amount = #{amount} </if>
 			<if test=' this.has("topdownTime") '> and w.topdown_time = #{topdownTime} </if>
 			<if test=' this.has("createTime") '> and w.create_time = #{createTime} </if>
@@ -36,8 +37,7 @@
 			<if test=' this.has("updateTime") '> and w.update_time = #{updateTime} </if>
 			<if test=' this.has("updateBy") '> and w.update_by = #{updateBy} </if>
 			<if test=' this.has("updateName") '> and w.update_name = #{updateName} </if>
-			<if test=' this.has("deleteStatus") '> and w.delete_status = #{deleteStatus} </if>
-			<if test=' this.has("peopleName") '> and p.name = #{peopleName} </if>
+			<if test=' this.has("payStatus") '> and w.pay_status = #{payStatus} </if>
 		</where>
 		order by
 		<choose>
@@ -46,15 +46,16 @@
 			<when test='sortType == 3'> mchid desc </when>
 			<when test='sortType == 4'> out_trade_no desc </when>
 			<when test='sortType == 5'> transaction_id desc </when>
-			<when test='sortType == 6'> amount desc </when>
-			<when test='sortType == 7'> topdown_time desc </when>
-			<when test='sortType == 8'> create_time desc </when>
-			<when test='sortType == 9'> create_by desc </when>
-			<when test='sortType == 10'> create_name desc </when>
-			<when test='sortType == 11'> update_time desc </when>
-			<when test='sortType == 12'> update_by desc </when>
-			<when test='sortType == 13'> update_name desc </when>
-			<when test='sortType == 14'> delete_status desc </when>
+			<when test='sortType == 6'> goods_name desc </when>
+			<when test='sortType == 7'> amount desc </when>
+			<when test='sortType == 8'> topdown_time desc </when>
+			<when test='sortType == 9'> create_time desc </when>
+			<when test='sortType == 10'> create_by desc </when>
+			<when test='sortType == 11'> create_name desc </when>
+			<when test='sortType == 12'> update_time desc </when>
+			<when test='sortType == 13'> update_by desc </when>
+			<when test='sortType == 14'> update_name desc </when>
+			<when test='sortType == 15'> pay_status desc </when>
 			<otherwise> topdown_time desc </otherwise>
 		</choose>
 	</select>

+ 8 - 10
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_topup/TbWalletTopup.java

@@ -65,9 +65,13 @@ public class TbWalletTopup extends Model<TbWalletTopup> implements Serializable
 	/**
 	 * 微信支付系统生成的订单号 
 	 */
-	private String transactionId;	
+	private String transactionId;
 
 	/**
+	 * 商品名称
+	 */
+	private String goodsName;
+	/**
 	 * 充值金额 
 	 */
 	private String amount;	
@@ -105,18 +109,12 @@ public class TbWalletTopup extends Model<TbWalletTopup> implements Serializable
 	/**
 	 * 更新人名称 
 	 */
-	private String updateName;	
+	private String updateName;
 
 	/**
-	 * 删除状态(0=禁用,1=启用) 
+	 * 支付状态(0=未支付,1=支付中,2=已支付)
 	 */
-	private Integer deleteStatus;	
-
-
-
-
-
-	
+	private Integer payStatus;
 
 
 }

+ 14 - 5
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_topup/TbWalletTopupController.java

@@ -1,9 +1,20 @@
 package com.pj.tb_wallet_topup;
 
+import java.util.Date;
 import java.util.List;
 
+import com.github.binarywang.wxpay.bean.coupon.*;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
+import com.github.binarywang.wxpay.bean.notify.WxScanPayNotifyResult;
+import com.github.binarywang.wxpay.bean.request.*;
+import com.github.binarywang.wxpay.bean.result.*;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
 import com.pj.tb_wallet_topup.vo.ValletTopupVo;
 import com.pj.utils.so.SoMap;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
@@ -27,6 +38,9 @@ public class TbWalletTopupController {
 	@Autowired
 	TbWalletTopupService tbWalletTopupService;
 
+	@Autowired
+	private WxPayService wxService;
+
 	/** 增 */  
 	@RequestMapping("add")
 	@SaCheckPermission(TbWalletTopup.PERMISSION_CODE_ADD)
@@ -88,10 +102,5 @@ public class TbWalletTopupController {
 		return AjaxJson.getByLine(line);
 	}
 	
-	
-
-	
-	
-	
 
 }

+ 13 - 19
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_topup/TbWalletTopupMapper.xml

@@ -28,6 +28,7 @@
 			<if test=' this.has("mchid") '> and w.mchid = #{mchid} </if>
 			<if test=' this.has("outTradeNo") '> and w.out_trade_no = #{outTradeNo} </if>
 			<if test=' this.has("transactionId") '> and w.transaction_id = #{transactionId} </if>
+			<if test=' this.has("goodsName") '> and w.goods_name = #{goodsName} </if>
 			<if test=' this.has("amount") '> and w.amount = #{amount} </if>
 			<if test=' this.has("topupTime") '> and w.topup_time = #{topupTime} </if>
 			<if test=' this.has("createTime") '> and w.create_time = #{createTime} </if>
@@ -36,8 +37,7 @@
 			<if test=' this.has("updateTime") '> and w.update_time = #{updateTime} </if>
 			<if test=' this.has("updateBy") '> and w.update_by = #{updateBy} </if>
 			<if test=' this.has("updateName") '> and w.update_name = #{updateName} </if>
-			<if test=' this.has("deleteStatus") '> and w.delete_status = #{deleteStatus} </if>
-			<if test=' this.has("peopleName") '> and p.name = #{peopleName} </if>
+			<if test=' this.has("payStatus") '> and w.pay_status = #{payStatus} </if>
 		</where>
 		order by
 		<choose>
@@ -46,26 +46,20 @@
 			<when test='sortType == 3'> mchid desc </when>
 			<when test='sortType == 4'> out_trade_no desc </when>
 			<when test='sortType == 5'> transaction_id desc </when>
-			<when test='sortType == 6'> amount desc </when>
-			<when test='sortType == 7'> topup_time desc </when>
-			<when test='sortType == 8'> create_time desc </when>
-			<when test='sortType == 9'> create_by desc </when>
-			<when test='sortType == 10'> create_name desc </when>
-			<when test='sortType == 11'> update_time desc </when>
-			<when test='sortType == 12'> update_by desc </when>
-			<when test='sortType == 13'> update_name desc </when>
-			<when test='sortType == 14'> delete_status desc </when>
+			<when test='sortType == 6'> goods_name desc </when>
+			<when test='sortType == 7'> amount desc </when>
+			<when test='sortType == 8'> topup_time desc </when>
+			<when test='sortType == 9'> create_time desc </when>
+			<when test='sortType == 10'> create_by desc </when>
+			<when test='sortType == 11'> create_name desc </when>
+			<when test='sortType == 12'> update_time desc </when>
+			<when test='sortType == 13'> update_by desc </when>
+			<when test='sortType == 14'> update_name desc </when>
+			<when test='sortType == 15'> pay_status desc </when>
 			<otherwise> topup_time desc </otherwise>
 		</choose>
 	</select>
-	
-	
-	
-	
-	
-	
-	
-	
+
 	
 
 </mapper>

+ 0 - 1
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_topup/TbWalletTopupService.java

@@ -35,7 +35,6 @@ public class TbWalletTopupService extends ServiceImpl<TbWalletTopupMapper, TbWal
 	/** 改 */
 	void update(TbWalletTopup t){
 		updateById(t);
-
 	}
 
 	/** 查 */

+ 352 - 0
sp-service/level-one-server/src/main/java/com/pj/tb_wallet_topup/WxPayController.java

@@ -0,0 +1,352 @@
+package com.pj.tb_wallet_topup;
+
+import com.github.binarywang.wxpay.bean.coupon.*;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
+import com.github.binarywang.wxpay.bean.notify.WxScanPayNotifyResult;
+import com.github.binarywang.wxpay.bean.request.*;
+import com.github.binarywang.wxpay.bean.result.*;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import java.util.Date;
+
+
+/**
+ * @author plj
+ */
+@Slf4j
+@RestController
+@RequestMapping("/WxPay/")
+public class WxPayController {
+  @Autowired
+  private WxPayService wxService;
+
+  /**
+   * <pre>
+   * 查询订单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2)
+   * 该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
+   * 需要调用查询接口的情况:
+   * ◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
+   * ◆ 调用支付接口后,返回系统错误或未知交易状态情况;
+   * ◆ 调用被扫支付API,返回USERPAYING的状态;
+   * ◆ 调用关单或撤销接口API之前,需确认支付状态;
+   * 接口地址:https://api.mch.weixin.qq.com/pay/orderquery
+   * </pre>
+   *
+   * @param transactionId 微信订单号
+   * @param outTradeNo    商户系统内部的订单号,当没提供transactionId时需要传这个。
+   */
+  @ApiOperation(value = "查询订单")
+  @GetMapping("/queryOrder")
+  public WxPayOrderQueryResult queryOrder(@RequestParam(required = false) String transactionId,
+                                          @RequestParam(required = false) String outTradeNo)
+    throws WxPayException {
+    return this.wxService.queryOrder(transactionId, outTradeNo);
+  }
+
+  @ApiOperation(value = "查询订单")
+  @PostMapping("/queryOrder")
+  public WxPayOrderQueryResult queryOrder(@RequestBody WxPayOrderQueryRequest wxPayOrderQueryRequest) throws WxPayException {
+    return this.wxService.queryOrder(wxPayOrderQueryRequest);
+  }
+
+  /**
+   * <pre>
+   * 关闭订单
+   * 应用场景
+   * 以下情况需要调用关单接口:
+   * 1. 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;
+   * 2. 系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。
+   * 注意:订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。
+   * 接口地址:https://api.mch.weixin.qq.com/pay/closeorder
+   * 是否需要证书:   不需要。
+   * </pre>
+   *
+   * @param outTradeNo 商户系统内部的订单号
+   */
+  @ApiOperation(value = "关闭订单")
+  @GetMapping("/closeOrder/{outTradeNo}")
+  public WxPayOrderCloseResult closeOrder(@PathVariable String outTradeNo) throws WxPayException {
+    return this.wxService.closeOrder(outTradeNo);
+  }
+
+  @ApiOperation(value = "关闭订单")
+  @PostMapping("/closeOrder")
+  public WxPayOrderCloseResult closeOrder(@RequestBody WxPayOrderCloseRequest wxPayOrderCloseRequest) throws WxPayException {
+    return this.wxService.closeOrder(wxPayOrderCloseRequest);
+  }
+
+  /**
+   * 调用统一下单接口,并组装生成支付所需参数对象.
+   *
+   * @param request 统一下单请求参数
+   * @param <T>     请使用{@link com.github.binarywang.wxpay.bean.order}包下的类
+   * @return 返回 {@link com.github.binarywang.wxpay.bean.order}包下的类对象
+   */
+  @ApiOperation(value = "统一下单,并组装所需支付参数")
+  @PostMapping("/createOrder")
+  public <T> T createOrder(@RequestBody WxPayUnifiedOrderRequest request) throws WxPayException {
+    log.error(this.wxService.getConfig().toString());
+    return this.wxService.createOrder(request);
+  }
+
+  /**
+   * 统一下单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
+   * 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
+   * 接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder
+   *
+   * @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置)
+   */
+  @ApiOperation(value = "原生的统一下单接口")
+  @PostMapping("/unifiedOrder")
+  public WxPayUnifiedOrderResult unifiedOrder(@RequestBody WxPayUnifiedOrderRequest request) throws WxPayException {
+    return this.wxService.unifiedOrder(request);
+  }
+
+  /**
+   * <pre>
+   * 微信支付-申请退款
+   * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
+   * 接口链接:https://api.mch.weixin.qq.com/secapi/pay/refund
+   * </pre>
+   *
+   * @param request 请求对象
+   * @return 退款操作结果
+   */
+  @ApiOperation(value = "退款")
+  @PostMapping("/refund")
+  public WxPayRefundResult refund(@RequestBody WxPayRefundRequest request) throws WxPayException {
+    return this.wxService.refund(request);
+  }
+
+  /**
+   * <pre>
+   * 微信支付-查询退款
+   * 应用场景:
+   *  提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,
+   *  银行卡支付的退款3个工作日后重新查询退款状态。
+   * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
+   * 接口链接:https://api.mch.weixin.qq.com/pay/refundquery
+   * </pre>
+   * 以下四个参数四选一
+   *
+   * @param transactionId 微信订单号
+   * @param outTradeNo    商户订单号
+   * @param outRefundNo   商户退款单号
+   * @param refundId      微信退款单号
+   * @return 退款信息
+   */
+  @ApiOperation(value = "退款查询")
+  @GetMapping("/refundQuery")
+  public WxPayRefundQueryResult refundQuery(@RequestParam(required = false) String transactionId,
+                                            @RequestParam(required = false) String outTradeNo,
+                                            @RequestParam(required = false) String outRefundNo,
+                                            @RequestParam(required = false) String refundId)
+    throws WxPayException {
+    return this.wxService.refundQuery(transactionId, outTradeNo, outRefundNo, refundId);
+  }
+
+  @ApiOperation(value = "退款查询")
+  @PostMapping("/refundQuery")
+  public WxPayRefundQueryResult refundQuery(@RequestBody WxPayRefundQueryRequest wxPayRefundQueryRequest) throws WxPayException {
+    return this.wxService.refundQuery(wxPayRefundQueryRequest);
+  }
+
+  @ApiOperation(value = "支付回调通知处理")
+  @PostMapping("/notify/order")
+  public String parseOrderNotifyResult(@RequestBody String xmlData) throws WxPayException {
+    final WxPayOrderNotifyResult notifyResult = this.wxService.parseOrderNotifyResult(xmlData);
+    // TODO 根据自己业务场景需要构造返回对象
+    return WxPayNotifyResponse.success("成功");
+  }
+
+  @ApiOperation(value = "退款回调通知处理")
+  @PostMapping("/notify/refund")
+  public String parseRefundNotifyResult(@RequestBody String xmlData) throws WxPayException {
+    final WxPayRefundNotifyResult result = this.wxService.parseRefundNotifyResult(xmlData);
+    // TODO 根据自己业务场景需要构造返回对象
+    return WxPayNotifyResponse.success("成功");
+  }
+
+  @ApiOperation(value = "扫码支付回调通知处理")
+  @PostMapping("/notify/scanpay")
+  public String parseScanPayNotifyResult(String xmlData) throws WxPayException {
+    final WxScanPayNotifyResult result = this.wxService.parseScanPayNotifyResult(xmlData);
+    // TODO 根据自己业务场景需要构造返回对象
+    return WxPayNotifyResponse.success("成功");
+  }
+
+  /**
+   * 发送微信红包给个人用户
+   * <pre>
+   * 文档详见:
+   * 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
+   *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
+   * 发送裂变红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4
+   *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack
+   * </pre>
+   *
+   * @param request 请求对象
+   */
+  @ApiOperation(value = "发送红包")
+  @PostMapping("/sendRedpack")
+  public WxPaySendRedpackResult sendRedpack(@RequestBody WxPaySendRedpackRequest request) throws WxPayException {
+    return this.wxService.getRedpackService().sendRedpack(request);
+  }
+
+  /**
+   * <pre>
+   *   查询红包记录
+   *   用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。
+   *   请求Url	https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo
+   *   是否需要证书	是(证书及使用说明详见商户证书)
+   *   请求方式	POST
+   * </pre>
+   *
+   * @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890
+   */
+  @ApiOperation(value = "查询红包")
+  @GetMapping("/queryRedpack/{mchBillNo}")
+  public WxPayRedpackQueryResult queryRedpack(@PathVariable String mchBillNo) throws WxPayException {
+    return this.wxService.getRedpackService().queryRedpack(mchBillNo);
+  }
+
+
+  /**
+   * <pre>
+   * 扫码支付模式一生成二维码的方法
+   * 二维码中的内容为链接,形式为:
+   * weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX
+   * 其中XXXXX为商户需要填写的内容,商户将该链接生成二维码,如需要打印发布二维码,需要采用此格式。商户可调用第三方库生成二维码图片。
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4
+   * </pre>
+   *
+   * @param productId 产品Id
+   * @return 生成的二维码URL连接
+   */
+  public String createScanPayQrcodeMode1(String productId) {
+    return this.wxService.createScanPayQrcodeMode1(productId);
+  }
+
+  /**
+   * <pre>
+   * 交易保障
+   * 应用场景:
+   *  商户在调用微信支付提供的相关接口时,会得到微信支付返回的相关信息以及获得整个接口的响应时间。
+   *  为提高整体的服务水平,协助商户一起提高服务质量,微信支付提供了相关接口调用耗时和返回信息的主动上报接口,
+   *  微信支付可以根据商户侧上报的数据进一步优化网络部署,完善服务监控,和商户更好的协作为用户提供更好的业务体验。
+   * 接口地址: https://api.mch.weixin.qq.com/payitil/report
+   * 是否需要证书:不需要
+   * </pre>
+   */
+  @ApiOperation(value = "提交交易保障数据")
+  @PostMapping("/report")
+  public void report(@RequestBody WxPayReportRequest request) throws WxPayException {
+    this.wxService.report(request);
+  }
+
+  /**
+   * <pre>
+   * 下载对账单
+   * 商户可以通过该接口下载历史交易清单。比如掉单、系统错误等导致商户侧和微信侧数据不一致,通过对账单核对后可校正支付状态。
+   * 注意:
+   * 1、微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账单中,跟原支付单订单号一致,bill_type为REVOKED;
+   * 2、微信在次日9点启动生成前一天的对账单,建议商户10点后再获取;
+   * 3、对账单中涉及金额的字段单位为“元”。
+   * 4、对账单接口只能下载三个月以内的账单。
+   * 接口链接:https://api.mch.weixin.qq.com/pay/downloadbill
+   * 详情请见: <a href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6">下载对账单</a>
+   * </pre>
+   *
+   * @param billDate   对账单日期 bill_date	下载对账单的日期,格式:20140603
+   * @param billType   账单类型	bill_type	ALL,返回当日所有订单信息,默认值,SUCCESS,返回当日成功支付的订单,REFUND,返回当日退款订单
+   * @param tarType    压缩账单	tar_type	非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。
+   * @param deviceInfo 设备号	device_info	非必传参数,终端设备号
+   * @return 保存到本地的临时文件
+   */
+  @ApiOperation(value = "下载对账单")
+  @GetMapping("/downloadBill/{billDate}/{billType}/{tarType}/{deviceInfo}")
+  public WxPayBillResult downloadBill(@PathVariable String billDate, @PathVariable String billType,
+                                      @PathVariable String tarType, @PathVariable String deviceInfo) throws WxPayException {
+    return this.wxService.downloadBill(billDate, billType, tarType, deviceInfo);
+  }
+
+  @ApiOperation(value = "下载对账单")
+  @PostMapping("/downloadBill")
+  public WxPayBillResult downloadBill(WxPayDownloadBillRequest wxPayDownloadBillRequest) throws WxPayException {
+    return this.wxService.downloadBill(wxPayDownloadBillRequest);
+  }
+
+  /**
+   * <pre>
+   * 提交刷卡支付
+   * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
+   * 应用场景:
+   * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,由商户收银台或者商户后台调用该接口发起支付。
+   * 提醒1:提交支付请求后微信会同步返回支付结果。当返回结果为“系统错误”时,商户系统等待5秒后调用【查询订单API】,查询支付实际交易结果;当返回结果为“USERPAYING”时,商户系统可设置间隔时间(建议10秒)重新查询支付结果,直到支付成功或超时(建议30秒);
+   * 提醒2:在调用查询接口返回后,如果交易状况不明晰,请调用【撤销订单API】,此时如果交易失败则关闭订单,该单不能再支付成功;如果交易成功,则将扣款退回到用户账户。当撤销无返回或错误时,请再次调用。注意:请勿扣款后立即调用【撤销订单API】,建议至少15秒后再调用。撤销订单API需要双向证书。
+   * 接口地址:   https://api.mch.weixin.qq.com/pay/micropay
+   * 是否需要证书:不需要。
+   * </pre>
+   */
+  @ApiOperation(value = "提交刷卡支付")
+  @PostMapping("/micropay")
+  public WxPayMicropayResult micropay(@RequestBody WxPayMicropayRequest request) throws WxPayException {
+    return this.wxService.micropay(request);
+  }
+
+  /**
+   * <pre>
+   * 撤销订单API
+   * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
+   * 应用场景:
+   *  支付交易返回失败或支付系统超时,调用该接口撤销交易。如果此订单用户支付失败,微信支付系统会将此订单关闭;如果用户支付成功,微信支付系统会将此订单资金退还给用户。
+   *  注意:7天以内的交易单可调用撤销,其他正常支付的单如需实现相同功能请调用申请退款API。提交支付交易后调用【查询订单API】,没有明确的支付结果再调用【撤销订单API】。
+   *  调用支付接口后请勿立即调用撤销订单API,建议支付后至少15s后再调用撤销订单接口。
+   *  接口链接 :https://api.mch.weixin.qq.com/secapi/pay/reverse
+   *  是否需要证书:请求需要双向证书。
+   * </pre>
+   */
+  @ApiOperation(value = "撤销订单")
+  @PostMapping("/reverseOrder")
+  public WxPayOrderReverseResult reverseOrder(@RequestBody WxPayOrderReverseRequest request) throws WxPayException {
+    return this.wxService.reverseOrder(request);
+  }
+
+  @ApiOperation(value = "获取沙箱环境签名key")
+  @GetMapping("/getSandboxSignKey")
+  public String getSandboxSignKey() throws WxPayException {
+    return this.wxService.getSandboxSignKey();
+  }
+
+  @ApiOperation(value = "发放代金券")
+  @PostMapping("/sendCoupon")
+  public WxPayCouponSendResult sendCoupon(@RequestBody WxPayCouponSendRequest request) throws WxPayException {
+    return this.wxService.sendCoupon(request);
+  }
+
+  @ApiOperation(value = "查询代金券批次")
+  @PostMapping("/queryCouponStock")
+  public WxPayCouponStockQueryResult queryCouponStock(@RequestBody WxPayCouponStockQueryRequest request) throws WxPayException {
+    return this.wxService.queryCouponStock(request);
+  }
+
+  @ApiOperation(value = "查询代金券信息")
+  @PostMapping("/queryCouponInfo")
+  public WxPayCouponInfoQueryResult queryCouponInfo(@RequestBody WxPayCouponInfoQueryRequest request) throws WxPayException {
+    return this.wxService.queryCouponInfo(request);
+  }
+
+  @ApiOperation(value = "拉取订单评价数据")
+  @PostMapping("/queryComment")
+  public String queryComment(Date beginDate, Date endDate, Integer offset, Integer limit) throws WxPayException {
+    return this.wxService.queryComment(beginDate, endDate, offset, limit);
+  }
+
+}
+