diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java index 91bbdb69..2a394ab2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java @@ -38,7 +38,7 @@ public class WxMpSelfMenuInfo implements Serializable { public static class WxMpSelfMenuButton implements Serializable { private static final long serialVersionUID = -4426602953309048341L; - + /** *
      * 菜单的类型,公众平台官网上能够设置的菜单类型有view(跳转网页)、text(返回文本,下同)、img、photo、video、voice。
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java
index fad6d444..ad191166 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java
@@ -14,6 +14,8 @@ import org.apache.commons.lang3.StringUtils;
 
 import java.math.BigDecimal;
 
+import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.ALL_SIGN_TYPES;
+
 /**
  * 
  * Created by Binary Wang on 2016-10-24.
@@ -189,8 +191,9 @@ public abstract class WxPayBaseRequest {
    * 
* * @param config 支付配置对象,用于读取相应系统配置信息 + * @param isIgnoreSignType 签名时,是否忽略signType */ - public void checkAndSign(WxPayConfig config) throws WxPayException { + public void checkAndSign(WxPayConfig config, boolean isIgnoreSignType) throws WxPayException { this.checkFields(); if (StringUtils.isBlank(getAppid())) { @@ -209,11 +212,24 @@ public abstract class WxPayBaseRequest { this.setSubMchId(config.getSubMchId()); } + if (StringUtils.isBlank(getSignType())) { + if (config.getSignType() != null && !ALL_SIGN_TYPES.contains(config.getSignType())) { + throw new WxPayException("非法的signType配置:" + config.getSignType() + ",请检查配置!"); + } + this.setSignType(StringUtils.trimToNull(config.getSignType())); + } else { + if (!ALL_SIGN_TYPES.contains(this.getSignType())) { + throw new WxPayException("非法的sign_type参数:" + this.getSignType()); + } + } + if (StringUtils.isBlank(getNonceStr())) { this.setNonceStr(String.valueOf(System.currentTimeMillis())); } + //设置签名字段的值 - this.setSign(SignUtils.createSign(this, config.getMchKey(), this.signType)); + this.setSign(SignUtils.createSign(this, this.getSignType(), config.getMchKey(), + isIgnoreSignType)); } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java index ce6cf747..1a3b85e8 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java @@ -165,12 +165,12 @@ public class WxPayRefundRequest extends WxPayBaseRequest { private String refundDesc; @Override - public void checkAndSign(WxPayConfig config) throws WxPayException { + public void checkAndSign(WxPayConfig config, boolean isIgnoreSignType) throws WxPayException { if (StringUtils.isBlank(this.getOpUserId())) { this.setOpUserId(config.getMchId()); } - super.checkAndSign(config); + super.checkAndSign(config, isIgnoreSignType); } @Override diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java index f45a2d0c..c2bc9f45 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java @@ -349,7 +349,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { } @Override - public void checkAndSign(WxPayConfig config) throws WxPayException { + public void checkAndSign(WxPayConfig config, boolean isIgnoreSignType) throws WxPayException { if (StringUtils.isBlank(this.getNotifyURL())) { this.setNotifyURL(config.getNotifyUrl()); } @@ -358,7 +358,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { this.setTradeType(config.getTradeType()); } - super.checkAndSign(config); + super.checkAndSign(config, isIgnoreSignType); } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java index d2ba58a9..93a34260 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java @@ -216,12 +216,13 @@ public abstract class WxPayBaseResult { /** * 校验返回结果签名 * + * @param signType 签名类型 * @param checkSuccess 是否同时检查结果是否成功 */ - public void checkResult(WxPayServiceAbstractImpl wxPayService, boolean checkSuccess) throws WxPayException { + public void checkResult(WxPayServiceAbstractImpl wxPayService, String signType, boolean checkSuccess) throws WxPayException { //校验返回结果签名 Map map = toMap(); - if (getSign() != null && !SignUtils.checkSign(map, wxPayService.getConfig().getMchKey())) { + if (getSign() != null && !SignUtils.checkSign(map, signType, wxPayService.getConfig().getMchKey())) { this.getLogger().debug("校验结果签名失败,参数:{}", map); throw new WxPayException("参数格式校验错误!"); } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java index 7d8cd5e1..684073d0 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java @@ -36,6 +36,7 @@ public class WxPayConfig { private String subMchId; private String notifyUrl; private String tradeType; + private String signType; private SSLContext sslContext; private String keyPath; private boolean useSandboxEnv = false; @@ -139,6 +140,19 @@ public class WxPayConfig { this.tradeType = tradeType; } + /** + * 签名方式 + * 有两种HMAC_SHA256 和MD5 + * @see com.github.binarywang.wxpay.constant.WxPayConstants.SignType + */ + public String getSignType() { + return this.signType; + } + + public void setSignType(String signType) { + this.signType = signType; + } + public SSLContext getSslContext() { return this.sslContext; } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java index d56271a8..8e9eea95 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java @@ -1,6 +1,9 @@ package com.github.binarywang.wxpay.constant; +import com.google.common.collect.Lists; + import java.text.SimpleDateFormat; +import java.util.List; /** *
@@ -96,6 +99,7 @@ public class WxPayConstants {
   public static class SignType {
     public static final String HMAC_SHA256 = "HMAC-SHA256";
     public static final String MD5 = "MD5";
+    public static final List ALL_SIGN_TYPES = Lists.newArrayList(HMAC_SHA256, MD5);
   }
 
   /**
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImpl.java
index 57cef5b8..1d5632bb 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImpl.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImpl.java
@@ -72,12 +72,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
 
   @Override
   public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/secapi/pay/refund";
     String responseContent = this.post(url, request.toXML(), true);
     WxPayRefundResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
@@ -90,13 +90,13 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
     request.setOutRefundNo(StringUtils.trimToNull(outRefundNo));
     request.setRefundId(StringUtils.trimToNull(refundId));
 
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/pay/refundquery";
     String responseContent = this.post(url, request.toXML(), false);
     WxPayRefundQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundQueryResult.class);
     result.composeRefundRecords();
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
@@ -112,7 +112,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
       log.debug("微信支付异步通知请求参数:{}", xmlData);
       WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlData);
       log.debug("微信支付异步通知请求解析后的对象:{}", result);
-      result.checkResult(this, false);
+      result.checkResult(this, null, false);
       return result;
     } catch (WxPayException e) {
       log.error(e.getMessage(), e);
@@ -138,7 +138,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
 
   @Override
   public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendredpack";
     if (request.getAmtType() != null) {
@@ -156,12 +156,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
     WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest();
     request.setMchBillNo(mchBillNo);
     request.setBillType(BillType.MCHT);
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gethbinfo";
     String responseContent = this.post(url, request.toXML(), true);
     WxPayRedpackQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRedpackQueryResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
@@ -170,7 +170,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
     WxPayOrderQueryRequest request = new WxPayOrderQueryRequest();
     request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
     request.setTransactionId(StringUtils.trimToNull(transactionId));
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/pay/orderquery";
     String responseContent = this.post(url, request.toXML(), false);
@@ -180,7 +180,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
 
     WxPayOrderQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderQueryResult.class);
     result.composeCoupons();
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
@@ -192,12 +192,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
 
     WxPayOrderCloseRequest request = new WxPayOrderCloseRequest();
     request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/pay/closeorder";
     String responseContent = this.post(url, request.toXML(), false);
     WxPayOrderCloseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderCloseResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
 
     return result;
   }
@@ -236,7 +236,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
         configMap.put("appid", appId);
 
         payResult = WxPayAppOrderResult.builder()
-          .sign(SignUtils.createSign(configMap, this.getConfig().getMchKey(), null))
+          .sign(SignUtils.createSign(configMap, null, this.getConfig().getMchKey(), false))
           .prepayId(prepayId)
           .partnerId(partnerId)
           .appId(appId)
@@ -255,9 +255,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
           .signType(SignType.MD5)
           .build();
         ((WxPayMpOrderResult) payResult)
-          .setPaySign(SignUtils.createSign(payResult, this.getConfig().getMchKey(), null));
+          .setPaySign(SignUtils.createSign(payResult, null, this.getConfig().getMchKey(), false));
         break;
       }
+      default: {
+        throw new WxPayException("该交易类型暂不支持");
+      }
     }
 
     return (T) payResult;
@@ -265,12 +268,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
 
   @Override
   public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/pay/unifiedorder";
     String responseContent = this.post(url, request.toXML(), false);
     WxPayUnifiedOrderResult result = WxPayBaseResult.fromXML(responseContent, WxPayUnifiedOrderResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
@@ -303,7 +306,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
       configMap.put("noncestr", nonceStr);
       configMap.put("appid", appId);
       // 此map用于客户端与微信服务器交互
-      payInfo.put("sign", SignUtils.createSign(configMap, this.getConfig().getMchKey(), null));
+      payInfo.put("sign", SignUtils.createSign(configMap, null, this.getConfig().getMchKey(), false));
       payInfo.put("prepayId", prepayId);
       payInfo.put("partnerId", partnerId);
       payInfo.put("appId", appId);
@@ -317,7 +320,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
       payInfo.put("nonceStr", nonceStr);
       payInfo.put("package", "prepay_id=" + prepayId);
       payInfo.put("signType", SignType.MD5);
-      payInfo.put("paySign", SignUtils.createSign(payInfo, this.getConfig().getMchKey(), null));
+      payInfo.put("paySign", SignUtils.createSign(payInfo, null, this.getConfig().getMchKey(), false));
     }
 
     return payInfo;
@@ -325,12 +328,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
 
   @Override
   public WxEntPayResult entPay(WxEntPayRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
     String url = this.getPayBaseUrl() + "/mmpaymkttransfers/promotion/transfers";
 
     String responseContent = this.post(url, request.toXML(), true);
     WxEntPayResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
@@ -338,12 +341,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
   public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException {
     WxEntPayQueryRequest request = new WxEntPayQueryRequest();
     request.setPartnerTradeNo(partnerTradeNo);
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo";
     String responseContent = this.post(url, request.toXML(), true);
     WxEntPayQueryResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayQueryResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
@@ -364,7 +367,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
     params.put("time_stamp", String.valueOf(System.currentTimeMillis() / 1000));//这里需要秒,10位数字
     params.put("nonce_str", String.valueOf(System.currentTimeMillis()));
 
-    String sign = SignUtils.createSign(params, this.getConfig().getMchKey(), null);
+    String sign = SignUtils.createSign(params, null, this.getConfig().getMchKey(), false);
     params.put("sign", sign);
 
     for (String key : params.keySet()) {
@@ -389,13 +392,14 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
     return QrcodeUtils.createQrcode(content, sideLength, logoFile);
   }
 
+  @Override
   public void report(WxPayReportRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/payitil/report";
     String responseContent = this.post(url, request.toXML(), false);
     WxPayCommonResult result = WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
   }
 
   @Override
@@ -406,7 +410,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
     request.setTarType(tarType);
     request.setDeviceInfo(deviceInfo);
 
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/pay/downloadbill";
     String responseContent = this.post(url, request.toXML(), false);
@@ -488,34 +492,34 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
 
   @Override
   public WxPayMicropayResult micropay(WxPayMicropayRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/pay/micropay";
     String responseContent = this.post(url, request.toXML(), false);
     WxPayMicropayResult result = WxPayBaseResult.fromXML(responseContent, WxPayMicropayResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
   @Override
   public WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/secapi/pay/reverse";
     String responseContent = this.post(url, request.toXML(), true);
     WxPayOrderReverseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderReverseResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
   @Override
   public String shorturl(WxPayShorturlRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/tools/shorturl";
     String responseContent = this.post(url, request.toXML(), false);
     WxPayShorturlResult result = WxPayBaseResult.fromXML(responseContent, WxPayShorturlResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result.getShortUrl();
   }
 
@@ -526,12 +530,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
 
   @Override
   public String authcode2Openid(WxPayAuthcode2OpenidRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/tools/authcodetoopenid";
     String responseContent = this.post(url, request.toXML(), false);
     WxPayAuthcode2OpenidResult result = WxPayBaseResult.fromXML(responseContent, WxPayAuthcode2OpenidResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result.getOpenid();
   }
 
@@ -543,45 +547,45 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
   @Override
   public String getSandboxSignKey() throws WxPayException {
     WxPayDefaultRequest request = new WxPayDefaultRequest();
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey";
     String responseContent = this.post(url, request.toXML(), false);
     WxPaySandboxSignKeyResult result = WxPayBaseResult.fromXML(responseContent, WxPaySandboxSignKeyResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result.getSandboxSignKey();
   }
 
   @Override
   public WxPayCouponSendResult sendCoupon(WxPayCouponSendRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/mmpaymkttransfers/send_coupon";
     String responseContent = this.post(url, request.toXML(), true);
     WxPayCouponSendResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponSendResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
   @Override
   public WxPayCouponStockQueryResult queryCouponStock(WxPayCouponStockQueryRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/mmpaymkttransfers/query_coupon_stock";
     String responseContent = this.post(url, request.toXML(), false);
     WxPayCouponStockQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponStockQueryResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
   @Override
   public WxPayCouponInfoQueryResult queryCouponInfo(WxPayCouponInfoQueryRequest request) throws WxPayException {
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), false);
 
     String url = this.getPayBaseUrl() + "/mmpaymkttransfers/querycouponsinfo";
     String responseContent = this.post(url, request.toXML(), false);
     WxPayCouponInfoQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponInfoQueryResult.class);
-    result.checkResult(this, true);
+    result.checkResult(this, request.getSignType(), true);
     return result;
   }
 
@@ -605,7 +609,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
     request.setLimit(limit);
     request.setSignType(SignType.HMAC_SHA256);
 
-    request.checkAndSign(this.getConfig());
+    request.checkAndSign(this.getConfig(), true);
 
     String url = this.getPayBaseUrl() + "/billcommentsp/batchquerycomment";
 
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
index 35a53c2c..c3014c76 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
@@ -27,31 +27,40 @@ public class SignUtils {
   /**
    * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3)
    *
-   * @param xmlBean  Bean需要标记有XML注解
-   * @param signKey  签名Key
-   * @param signType 签名类型,如果为空,则默认为MD5
+   * @param xmlBean          Bean需要标记有XML注解
+   * @param signType         签名类型,如果为空,则默认为MD5
+   * @param signKey          签名Key
+   * @param isIgnoreSignType 签名时,是否忽略signType
    * @return 签名字符串
    */
-  public static String createSign(Object xmlBean, String signKey, String signType) {
-    return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey, signType);
+  public static String createSign(Object xmlBean, String signType, String signKey, boolean isIgnoreSignType) {
+    return createSign(BeanUtils.xmlBean2Map(xmlBean), signType, signKey, isIgnoreSignType);
   }
 
   /**
    * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3)
    *
-   * @param params   参数信息
-   * @param signKey  签名Key
-   * @param signType 签名类型,如果为空,则默认为md5
+   * @param params           参数信息
+   * @param signType         签名类型,如果为空,则默认为MD5
+   * @param signKey          签名Key
+   * @param isIgnoreSignType 签名时,是否忽略signType
    * @return 签名字符串
    */
-  public static String createSign(Map params, String signKey, String signType) {
+  public static String createSign(Map params, String signType, String signKey, boolean isIgnoreSignType) {
     SortedMap sortedMap = new TreeMap<>(params);
 
     StringBuilder toSign = new StringBuilder();
     for (String key : sortedMap.keySet()) {
       String value = params.get(key);
-      if (StringUtils.isNotEmpty(value) &&
-        !Lists.newArrayList("sign", "key", "sign_type").contains(key)) {
+      boolean shouldSign = false;
+      if (isIgnoreSignType && "sign_type".equals(key)) {
+        shouldSign = false;
+      } else if (StringUtils.isNotEmpty(value)
+        && !Lists.newArrayList("sign", "key").contains(key)) {
+        shouldSign = true;
+      }
+
+      if (shouldSign) {
         toSign.append(key).append("=").append(value).append("&");
       }
     }
@@ -81,25 +90,27 @@ public class SignUtils {
   /**
    * 校验签名是否正确
    *
-   * @param xmlBean Bean需要标记有XML注解
-   * @param signKey 校验的签名Key
+   * @param xmlBean  Bean需要标记有XML注解
+   * @param signType 签名类型,如果为空,则默认为MD5
+   * @param signKey  校验的签名Key
    * @return true - 签名校验成功,false - 签名校验失败
-   * @see #checkSign(Map, String)
+   * @see #checkSign(Map, String, String)
    */
-  public static boolean checkSign(Object xmlBean, String signKey) {
-    return checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey);
+  public static boolean checkSign(Object xmlBean, String signType, String signKey) {
+    return checkSign(BeanUtils.xmlBean2Map(xmlBean), signType, signKey);
   }
 
   /**
    * 校验签名是否正确
    *
-   * @param params  需要校验的参数Map
-   * @param signKey 校验的签名Key
+   * @param params   需要校验的参数Map
+   * @param signType 签名类型,如果为空,则默认为MD5
+   * @param signKey  校验的签名Key
    * @return true - 签名校验成功,false - 签名校验失败
-   * @see #checkSign(Map, String)
+   * @see #checkSign(Map, String, String)
    */
-  public static boolean checkSign(Map params, String signKey) {
-    String sign = createSign(params, signKey, null);
+  public static boolean checkSign(Map params, String signType, String signKey) {
+    String sign = createSign(params, signType, signKey, false);
     return sign.equals(params.get("sign"));
   }
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImplTest.java
index 3c27ce18..b6f7caf1 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImplTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImplTest.java
@@ -46,16 +46,17 @@ public class WxPayServiceAbstractImplTest {
    */
   @Test
   public void testUnifiedOrder() throws WxPayException {
-    WxPayUnifiedOrderResult result = this.payService
-      .unifiedOrder(WxPayUnifiedOrderRequest.newBuilder()
-        .body("我去")
-        .totalFee(1)
-        .spbillCreateIp("11.1.11.1")
-        .notifyURL("111111")
-        .tradeType(TradeType.JSAPI)
-        .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid())
-        .outTradeNo("1111112")
-        .build());
+    WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
+      .body("我去")
+      .totalFee(1)
+      .spbillCreateIp("11.1.11.1")
+      .notifyURL("111111")
+      .tradeType(TradeType.JSAPI)
+      .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid())
+      .outTradeNo("1111112")
+      .build();
+    request.setSignType(SignType.HMAC_SHA256);
+    WxPayUnifiedOrderResult result = this.payService.unifiedOrder(request);
     this.logger.info(result.toString());
     this.logger.warn(this.payService.getWxApiData().toString());
   }
@@ -284,13 +285,15 @@ public class WxPayServiceAbstractImplTest {
 
   @Test
   public void testMicropay() throws Exception {
-    WxPayMicropayResult result = this.payService.micropay(WxPayMicropayRequest.newBuilder()
-      .body("body")
-      .outTradeNo("aaaaa")
-      .totalFee(123)
-      .spbillCreateIp("127.0.0.1")
-      .authCode("aaa")
-      .build());
+    WxPayMicropayResult result = this.payService.micropay(
+      WxPayMicropayRequest
+        .newBuilder()
+        .body("body")
+        .outTradeNo("aaaaa")
+        .totalFee(123)
+        .spbillCreateIp("127.0.0.1")
+        .authCode("aaa")
+        .build());
     this.logger.info(result.toString());
   }
 
@@ -306,9 +309,11 @@ public class WxPayServiceAbstractImplTest {
 
   @Test
   public void testReverseOrder() throws Exception {
-    WxPayOrderReverseResult result = this.payService.reverseOrder(WxPayOrderReverseRequest.newBuilder()
-      .outTradeNo("1111")
-      .build());
+    WxPayOrderReverseResult result = this.payService.reverseOrder(
+      WxPayOrderReverseRequest
+        .newBuilder()
+        .outTradeNo("1111")
+        .build());
     assertNotNull(result);
     this.logger.info(result.toString());
   }
@@ -359,33 +364,38 @@ public class WxPayServiceAbstractImplTest {
 
   @Test
   public void testQueryCouponStock() throws Exception {
-    WxPayCouponStockQueryResult result = this.payService.queryCouponStock(WxPayCouponStockQueryRequest.newBuilder()
-      .couponStockId("123")
-      .build());
+    WxPayCouponStockQueryResult result = this.payService.queryCouponStock(
+      WxPayCouponStockQueryRequest
+        .newBuilder()
+        .couponStockId("123")
+        .build());
     this.logger.info(result.toString());
   }
 
   @Test
   public void testQueryCouponInfo() throws Exception {
-    WxPayCouponInfoQueryResult result = this.payService.queryCouponInfo(WxPayCouponInfoQueryRequest.newBuilder()
-      .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4")
-      .couponId("11")
-      .stockId("1121")
-      .build());
+    WxPayCouponInfoQueryResult result = this.payService.queryCouponInfo(
+      WxPayCouponInfoQueryRequest
+        .newBuilder()
+        .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4")
+        .couponId("11")
+        .stockId("1121")
+        .build());
     this.logger.info(result.toString());
   }
 
   /**
-   * 目前调用接口总报“系统繁忙,清稍后再试”,怀疑根本没法使用
+   * 只支持拉取90天内的评论数据
    */
   @Test
   public void testQueryComment() throws Exception {
     Calendar calendar = Calendar.getInstance();
-    calendar.add(Calendar.DAY_OF_MONTH, -2);
-    Date beginDate = calendar.getTime();
-    calendar.add(Calendar.MONTH, -1);
+    calendar.add(Calendar.DAY_OF_MONTH, -1);
     Date endDate = calendar.getTime();
-    this.payService.queryComment(beginDate, endDate, 0, null);
+    calendar.add(Calendar.DAY_OF_MONTH, -88);
+    Date beginDate = calendar.getTime();
+    String result = this.payService.queryComment(beginDate, endDate, 0, null);
+    this.logger.info(result);
   }
 
   @Test
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/util/SignUtilsTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/util/SignUtilsTest.java
index 23d7088b..57c185b5 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/util/SignUtilsTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/util/SignUtilsTest.java
@@ -20,7 +20,7 @@ public class SignUtilsTest {
   public void testCreateSign() throws Exception {
     String signKey = "192006250b4c09247ec02edce69f6a2d";
     String message = "appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
-    assertEquals(SignUtils.createSign((Splitter.on("&").withKeyValueSeparator("=").split(message)), signKey, null),
+    assertEquals(SignUtils.createSign((Splitter.on("&").withKeyValueSeparator("=").split(message)), null, signKey, false),
       "9A0A8659F005D6984697E2CA0A9CF3B7");
   }
 
@@ -29,7 +29,7 @@ public class SignUtilsTest {
     String signKey = "192006250b4c09247ec02edce69f6a2d";
     final String message = "appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
     String sign = SignUtils.createSign(Splitter.on("&").withKeyValueSeparator("=").split(message),
-      signKey, HMAC_SHA256);
+      HMAC_SHA256, signKey, false);
     assertEquals(sign, "6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6");
   }