diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java index 4675946c..9bd4dad2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java @@ -44,8 +44,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { private static final String PAY_BASE_URL = "https://api.mch.weixin.qq.com"; private static final String[] TRADE_TYPES = new String[]{"JSAPI", "NATIVE", "APP"}; - private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS", - "REFUND_SOURCE_UNSETTLED_FUNDS"}; + private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS","REFUND_SOURCE_UNSETTLED_FUNDS"}; private final Logger log = LoggerFactory.getLogger(this.getClass()); private WxMpService wxMpService; @@ -58,23 +57,20 @@ public class WxMpPayServiceImpl implements WxMpPayService { } @Override - public WxPayRefundResult refund(WxPayRefundRequest request, File keyFile) - throws WxErrorException { - checkParameters(request); - + public WxPayRefundResult refund(WxPayRefundRequest request, File keyFile) throws WxErrorException { XStream xstream = XStreamInitializer.getInstance(); xstream.processAnnotations(WxPayRefundRequest.class); xstream.processAnnotations(WxPayRefundResult.class); - - request.setAppid(getConfig().getAppId()); - String partnerId = getConfig().getPartnerId(); - request.setMchId(partnerId); - request.setNonceStr(System.currentTimeMillis() + ""); - request.setOpUserId(partnerId); + + initRequest(request); + if(StringUtils.isBlank(request.getOpUserId())){ + request.setOpUserId(getConfig().getPartnerId()); + } + checkParameters(request); request.setSign(this.createSign(request)); String url = PAY_BASE_URL + "/secapi/pay/refund"; - String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), partnerId); + String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), request.getMchId()); WxPayRefundResult result = (WxPayRefundResult) xstream.fromXML(responseContent); this.checkResult(result); return result; @@ -92,18 +88,14 @@ public class WxMpPayServiceImpl implements WxMpPayService { xstream.processAnnotations(WxPayRefundQueryResult.class); WxPayRefundQueryRequest request = new WxPayRefundQueryRequest(); + initRequest(request); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); request.setTransactionId(StringUtils.trimToNull(transactionId)); request.setOutRefundNo(StringUtils.trimToNull(outRefundNo)); request.setRefundId(StringUtils.trimToNull(refundId)); - - request.setAppid(getConfig().getAppId()); - request.setMchId(getConfig().getPartnerId()); - request.setNonceStr(System.currentTimeMillis() + ""); request.setSign(this.createSign(request)); String url = PAY_BASE_URL + "/pay/refundquery"; - String responseContent = this.executeRequest(url, xstream.toXML(request)); WxPayRefundQueryResult result = (WxPayRefundQueryResult) xstream.fromXML(responseContent); result.composeRefundRecords(responseContent); @@ -127,7 +119,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { + result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: " + result.getErrCode() + ", 错误详情: " + result.getErrCodeDes()) .build(); - log.debug("结果校验失败,参数:{},详细:{}", result.toMap(), error); + log.error("结果业务代码异常,参数:{},详细:{}", result.toMap(), error); throw new WxErrorException(error); } } @@ -174,10 +166,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { xstream.processAnnotations(WxPaySendRedpackRequest.class); xstream.processAnnotations(WxPaySendRedpackResult.class); - request.setWxAppid(getConfig().getAppId()); - String mchId = getConfig().getPartnerId(); - request.setMchId(mchId); - request.setNonceStr(System.currentTimeMillis() + ""); + initRequest(request); request.setSign(this.createSign(request)); String url = PAY_BASE_URL + "/mmpaymkttransfers/sendredpack"; @@ -185,8 +174,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { //裂变红包 url = PAY_BASE_URL + "/mmpaymkttransfers/sendgroupredpack"; } - - String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), mchId); + String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), request.getMchId()); WxPaySendRedpackResult result = (WxPaySendRedpackResult) xstream.fromXML(responseContent); this.checkResult(result); return result; @@ -201,75 +189,16 @@ public class WxMpPayServiceImpl implements WxMpPayService { WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); request.setMchBillNo(mchBillNo); request.setBillType("MCHT"); - - request.setAppid(getConfig().getAppId()); - String mchId = getConfig().getPartnerId(); - request.setMchId(mchId); - request.setNonceStr(System.currentTimeMillis() + ""); - - String sign = this.createSign(request); - request.setSign(sign); + initRequest(request); + request.setSign(this.createSign(request)); String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo"; - String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), mchId); + String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), request.getMchId()); WxPayRedpackQueryResult result = (WxPayRedpackQueryResult) xstream.fromXML(responseContent); this.checkResult(result); return result; } - @Override - public String createSign(Object xmlBean) { - return createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); - } - - @Override - public String createSign(Object xmlBean, String signKey) { - return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey); - } - - @Override - public String createSign(Map params) { - return createSign(params, getConfig().getPartnerKey()); - } - - @Override - public String createSign(Map params, String signKey) { - SortedMap sortedMap = new TreeMap<>(params); - - StringBuilder toSign = new StringBuilder(); - for (String key : sortedMap.keySet()) { - String value = params.get(key); - if (StringUtils.isNotEmpty(value) && !"sign".equals(key) && !"key".equals(key)) { - toSign.append(key + "=" + value + "&"); - } - } - - toSign.append("key=" + signKey); - return DigestUtils.md5Hex(toSign.toString()).toUpperCase(); - } - - @Override - public boolean checkSign(Object xmlBean) { - return checkSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); - } - - @Override - public boolean checkSign(Object xmlBean, String signKey) { - return checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey); - } - - @Override - public boolean checkSign(Map params) { - return checkSign(params, getConfig().getPartnerKey()); - } - - @Override - public boolean checkSign(Map params, String signKey) { - String sign = this.createSign(params, signKey); - return sign.equals(params.get("sign")); - } - - @Override public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException { if ((StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo)) || @@ -284,13 +213,10 @@ public class WxMpPayServiceImpl implements WxMpPayService { WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); request.setTransactionId(StringUtils.trimToNull(transactionId)); - request.setAppid(getConfig().getAppId()); - request.setMchId(getConfig().getPartnerId()); - request.setNonceStr(System.currentTimeMillis() + ""); + initRequest(request); request.setSign(this.createSign(request)); String url = PAY_BASE_URL + "/pay/orderquery"; - String responseContent = this.executeRequest(url, xstream.toXML(request)); WxPayOrderQueryResult result = (WxPayOrderQueryResult) xstream.fromXML(responseContent); result.composeCoupons(responseContent); @@ -310,13 +236,10 @@ public class WxMpPayServiceImpl implements WxMpPayService { WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); - request.setAppid(getConfig().getAppId()); - request.setMchId(getConfig().getPartnerId()); - request.setNonceStr(System.currentTimeMillis() + ""); + initRequest(request); request.setSign(this.createSign(request)); String url = PAY_BASE_URL + "/pay/closeorder"; - String responseContent = this.executeRequest(url, xstream.toXML(request)); WxPayOrderCloseResult result = (WxPayOrderCloseResult) xstream.fromXML(responseContent); this.checkResult(result); @@ -331,16 +254,17 @@ public class WxMpPayServiceImpl implements WxMpPayService { XStream xstream = XStreamInitializer.getInstance(); xstream.processAnnotations(WxPayUnifiedOrderRequest.class); xstream.processAnnotations(WxPayUnifiedOrderResult.class); - - request.setAppid(getConfig().getAppId()); - request.setMchId(getConfig().getPartnerId()); - request.setNotifyURL(getConfig().getNotifyURL()); - request.setTradeType(getConfig().getTradeType()); - request.setNonceStr(System.currentTimeMillis() + ""); - + + initRequest(request); + if(StringUtils.isBlank(request.getNotifyURL())){ + request.setNotifyURL(getConfig().getNotifyURL()); + } + if(StringUtils.isBlank(request.getTradeType())){ + request.setTradeType(getConfig().getTradeType()); + } checkParameters(request);//校验参数 - request.setSign(this.createSign(request)); + String url = PAY_BASE_URL + "/pay/unifiedorder"; String xmlParam = xstream.toXML(request); log.debug("微信统一下单接口,URL:{},参数:{}", url, xmlParam); @@ -351,6 +275,18 @@ public class WxMpPayServiceImpl implements WxMpPayService { this.checkResult(result); return result; } + + private void initRequest(WxPayBaseRequest request){ + if(StringUtils.isBlank(request.getAppid())){ + request.setAppid(getConfig().getAppId()); + } + if(StringUtils.isBlank(request.getMchId())){ + request.setMchId(getConfig().getPartnerId()); + } + if(StringUtils.isBlank(request.getNonceStr())){ + request.setNonceStr(String.valueOf(System.currentTimeMillis())); + } + } private void checkParameters(WxPayUnifiedOrderRequest request) throws WxErrorException { BeanUtils.checkRequiredFields(request); @@ -381,7 +317,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { payInfo.put("appId", getConfig().getAppId()); // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 payInfo.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); - payInfo.put("nonceStr", System.currentTimeMillis() + ""); + payInfo.put("nonceStr", String.valueOf(System.currentTimeMillis())); payInfo.put("package", "prepay_id=" + prepayId); payInfo.put("signType", "MD5"); if ("NATIVE".equals(request.getTradeType())) { @@ -393,15 +329,12 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public WxEntPayResult entPay(WxEntPayRequest request, File keyFile) throws WxErrorException { - BeanUtils.checkRequiredFields(request); - XStream xstream = XStreamInitializer.getInstance(); xstream.processAnnotations(WxEntPayRequest.class); xstream.processAnnotations(WxEntPayResult.class); - - request.setMchAppid(getConfig().getAppId()); - request.setMchId(getConfig().getPartnerId()); - request.setNonceStr(System.currentTimeMillis() + ""); + + initRequest(request); + BeanUtils.checkRequiredFields(request); request.setSign(this.createSign(request)); String url = PAY_BASE_URL + "/mmpaymkttransfers/promotion/transfers"; @@ -419,13 +352,10 @@ public class WxMpPayServiceImpl implements WxMpPayService { xstream.processAnnotations(WxEntPayQueryResult.class); WxEntPayQueryRequest request = new WxEntPayQueryRequest(); - request.setAppid(getConfig().getAppId()); - request.setMchId(getConfig().getPartnerId()); - request.setNonceStr(System.currentTimeMillis() + ""); + initRequest(request); request.setSign(this.createSign(request)); String url = PAY_BASE_URL + "/mmpaymkttransfers/gettransferinfo"; - String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), request.getMchId()); WxEntPayQueryResult result = (WxEntPayQueryResult) xstream.fromXML(responseContent); this.checkResult(result); @@ -483,4 +413,56 @@ public class WxMpPayServiceImpl implements WxMpPayService { throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg(e.getMessage()).build(), e); } } + + @Override + public String createSign(Object xmlBean) { + return createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); + } + + @Override + public String createSign(Object xmlBean, String signKey) { + return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey); + } + + @Override + public String createSign(Map params) { + return createSign(params, getConfig().getPartnerKey()); + } + + @Override + public String createSign(Map params, String signKey) { + SortedMap sortedMap = new TreeMap<>(params); + + StringBuilder toSign = new StringBuilder(); + for (String key : sortedMap.keySet()) { + String value = params.get(key); + if (StringUtils.isNotEmpty(value) && !"sign".equals(key) && !"key".equals(key)) { + toSign.append(key + "=" + value + "&"); + } + } + + toSign.append("key=" + signKey); + return DigestUtils.md5Hex(toSign.toString()).toUpperCase(); + } + + @Override + public boolean checkSign(Object xmlBean) { + return checkSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); + } + + @Override + public boolean checkSign(Object xmlBean, String signKey) { + return checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey); + } + + @Override + public boolean checkSign(Map params) { + return checkSign(params, getConfig().getPartnerKey()); + } + + @Override + public boolean checkSign(Map params, String signKey) { + String sign = this.createSign(params, signKey); + return sign.equals(params.get("sign")); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java index ef6e8d0a..bc6ae574 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java @@ -18,7 +18,7 @@ import me.chanjar.weixin.common.util.ToStringUtils; * @author binarywang (https://github.com/binarywang) */ @XStreamAlias("xml") -public class WxEntPayRequest { +public class WxEntPayRequest extends WxPayBaseRequest{ /** *
   * 公众账号appid
@@ -58,32 +58,6 @@ public class WxEntPayRequest {
   @XStreamAlias("device_info")
   private String deviceInfo;
 
-  /**
-   * 
-  * 随机字符串
-  * nonce_str
-  *是
-  *5K8264ILTKCH16CQ2502SI8ZNMTM67VS
-  *String(32)
-  *随机字符串,不长于32位
-   * 
- */ - @XStreamAlias("nonce_str") - private String nonceStr; - - /** - *
-  * 签名
-  * sign
-  * 是
-  * C380BEC2BFD727A4B6845133519F3AD6
-  * String(32)
-  *签名,详见签名算法
-   * 
- */ - @XStreamAlias("sign") - private String sign; - /** *
   * 商户订单号
@@ -178,18 +152,23 @@ public class WxEntPayRequest {
   @XStreamAlias("spbill_create_ip")
   private String spbillCreateIp;
 
-  public String getMchAppid() {
+
+  @Override
+  public String getAppid() {
     return this.mchAppid;
   }
 
-  public void setMchAppid(String mchAppid) {
-    this.mchAppid = mchAppid;
+  @Override
+  public void setAppid(String appid) {
+    this.mchAppid = appid;
   }
 
+  @Override
   public String getMchId() {
     return this.mchId;
   }
 
+  @Override
   public void setMchId(String mchId) {
     this.mchId = mchId;
   }
@@ -202,22 +181,6 @@ public class WxEntPayRequest {
     this.deviceInfo = deviceInfo;
   }
 
-  public String getNonceStr() {
-    return this.nonceStr;
-  }
-
-  public void setNonceStr(String nonceStr) {
-    this.nonceStr = nonceStr;
-  }
-
-  public String getSign() {
-    return this.sign;
-  }
-
-  public void setSign(String sign) {
-    this.sign = sign;
-  }
-
   public String getPartnerTradeNo() {
     return this.partnerTradeNo;
   }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundRequest.java
index 9a0c0178..66ba5d34 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundRequest.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundRequest.java
@@ -20,33 +20,7 @@ import me.chanjar.weixin.common.annotation.Required;
  *         Created by Binary Wang on 2016-10-08.
  */
 @XStreamAlias("xml")
-public class WxPayRefundRequest {
-  /**
-   * 
-   * 公众账号ID
-   * appid
-   * 是
-   * String(32)
-   * wx8888888888888888
-   * 微信分配的公众账号ID(企业号corpid即为此appId)
-   * 
- */ - @XStreamAlias("appid") - private String appid; - - /** - *
-   * 商户号
-   * mch_id
-   * 是
-   * String(32)
-   * 1900000109
-   * 微信支付分配的商户号
-   * 
- */ - @XStreamAlias("mch_id") - private String mchId; - +public class WxPayRefundRequest extends WxPayBaseRequest { /** *
    * 设备号
@@ -60,32 +34,6 @@ public class WxPayRefundRequest {
   @XStreamAlias("device_info")
   private String deviceInfo;
 
-  /**
-   * 
-   * 随机字符串
-   * nonce_str
-   * 是
-   * String(32)
-   * 5K8264ILTKCH16CQ2502SI8ZNMTM67VS
-   * 随机字符串,不长于32位。推荐随机数生成算法
-   * 
- */ - @XStreamAlias("nonce_str") - private String nonceStr; - - /** - *
-   * 签名
-   * sign
-   * 是
-   * String(32)
-   * C380BEC2BFD727A4B6845133519F3AD6
-   * 签名,详见签名生成算法
-   * 
- */ - @XStreamAlias("sign") - private String sign; - /** *
    * 微信订单号
@@ -196,21 +144,7 @@ public class WxPayRefundRequest {
   @XStreamAlias("refund_account")
   private String refundAccount;
 
-  public String getAppid() {
-    return this.appid;
-  }
 
-  public void setAppid(String appid) {
-    this.appid = appid;
-  }
-
-  public String getMchId() {
-    return this.mchId;
-  }
-
-  public void setMchId(String mchId) {
-    this.mchId = mchId;
-  }
 
   public String getDeviceInfo() {
     return this.deviceInfo;
@@ -220,22 +154,6 @@ public class WxPayRefundRequest {
     this.deviceInfo = deviceInfo;
   }
 
-  public String getNonceStr() {
-    return this.nonceStr;
-  }
-
-  public void setNonceStr(String nonceStr) {
-    this.nonceStr = nonceStr;
-  }
-
-  public String getSign() {
-    return this.sign;
-  }
-
-  public void setSign(String sign) {
-    this.sign = sign;
-  }
-
   public String getTransactionId() {
     return this.transactionId;
   }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java
index 535b2941..95cdac22 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java
@@ -8,7 +8,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
  * @author binarywang (https://github.com/binarywang)
  */
 @XStreamAlias("xml")
-public class WxPaySendRedpackRequest {
+public class WxPaySendRedpackRequest extends WxPayBaseRequest{
   /**
   * mch_billno
   * 商户订单号(每个订单号必须唯一)  组成:mch_id+yyyymmdd+10位一天内不能重复的数字。  接口根据商户订单号支持重入,如出现超时可再调用。
@@ -90,27 +90,6 @@ public class WxPaySendRedpackRequest {
   @XStreamAlias("wxappid")
   private String wxAppid;
 
-  /**
-   * mch_id
-   * 微信支付分配的商户号
-   */
-  @XStreamAlias("mch_id")
-  private String mchId;
-
-  /**
-   * nonce_str
-   * 随机字符串,不长于32位
-   */
-  @XStreamAlias("nonce_str")
-  private String nonceStr;
-
-  /**
-   * sign
-   * 详见签名生成算法
-   */
-  @XStreamAlias("sign")
-  private String sign;
-
   /**
    * 
    * scene_id
@@ -237,36 +216,14 @@ public class WxPaySendRedpackRequest {
     this.remark = remark;
   }
 
-  public String getWxAppid() {
+  @Override
+  public String getAppid() {
     return this.wxAppid;
   }
 
-  public void setWxAppid(String wxAppid) {
-    this.wxAppid = wxAppid;
-  }
-
-  public String getMchId() {
-    return this.mchId;
-  }
-
-  public void setMchId(String mchId) {
-    this.mchId = mchId;
-  }
-
-  public String getNonceStr() {
-    return this.nonceStr;
-  }
-
-  public void setNonceStr(String nonceStr) {
-    this.nonceStr = nonceStr;
-  }
-
-  public String getSign() {
-    return this.sign;
-  }
-
-  public void setSign(String sign) {
-    this.sign = sign;
+  @Override
+  public void setAppid(String appid) {
+    this.wxAppid = appid;
   }
 
   public String getSceneId() {