Browse Source

微信支付相关接口优化,支持自定义参数信息,不在默认使用配置信息

aimilin6688 8 years ago
parent
commit
02679bb665

+ 96 - 114
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,76 +189,17 @@ 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<String, String> params) {
-    return createSign(params, getConfig().getPartnerKey());
-  }
-
-  @Override
-  public String createSign(Map<String, String> params, String signKey) {
-    SortedMap<String, String> 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<String, String> params) {
-    return checkSign(params, getConfig().getPartnerKey());
-  }
-
-  @Override
-  public boolean checkSign(Map<String, String> 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)) ||
       (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(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<String, String> params) {
+    return createSign(params, getConfig().getPartnerKey());
+  }
+
+  @Override
+  public String createSign(Map<String, String> params, String signKey) {
+    SortedMap<String, String> 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<String, String> params) {
+    return checkSign(params, getConfig().getPartnerKey());
+  }
+
+  @Override
+  public boolean checkSign(Map<String, String> params, String signKey) {
+    String sign = this.createSign(params, signKey);
+    return sign.equals(params.get("sign"));
+  }
 }

+ 9 - 46
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{
   /**
    * <pre>
   * 公众账号appid
@@ -60,32 +60,6 @@ public class WxEntPayRequest {
 
   /**
    * <pre>
-  * 随机字符串
-  * nonce_str
-  *是
-  *5K8264ILTKCH16CQ2502SI8ZNMTM67VS
-  *String(32)
-  *随机字符串,不长于32位
-   * </pre>
-  */
-  @XStreamAlias("nonce_str")
-  private String nonceStr;
-
-  /**
-   * <pre>
-  * 签名
-  * sign
-  * 是
-  * C380BEC2BFD727A4B6845133519F3AD6
-  * String(32)
-  *签名,详见签名算法
-   * </pre>
-  */
-  @XStreamAlias("sign")
-  private String sign;
-
-  /**
-   * <pre>
   * 商户订单号
   * partner_trade_no
   * 是
@@ -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;
   }

+ 1 - 83
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 {
-  /**
-   * <pre>
-   * 公众账号ID
-   * appid
-   * 是
-   * String(32)
-   * wx8888888888888888
-   * 微信分配的公众账号ID(企业号corpid即为此appId)
-   * </pre>
-   */
-  @XStreamAlias("appid")
-  private String appid;
-
-  /**
-   * <pre>
-   * 商户号
-   * mch_id
-   * 是
-   * String(32)
-   * 1900000109
-   * 微信支付分配的商户号
-   * </pre>
-   */
-  @XStreamAlias("mch_id")
-  private String mchId;
-
+public class WxPayRefundRequest extends WxPayBaseRequest {
   /**
    * <pre>
    * 设备号
@@ -62,32 +36,6 @@ public class WxPayRefundRequest {
 
   /**
    * <pre>
-   * 随机字符串
-   * nonce_str
-   * 是
-   * String(32)
-   * 5K8264ILTKCH16CQ2502SI8ZNMTM67VS
-   * 随机字符串,不长于32位。推荐随机数生成算法
-   * </pre>
-   */
-  @XStreamAlias("nonce_str")
-  private String nonceStr;
-
-  /**
-   * <pre>
-   * 签名
-   * sign
-   * 是
-   * String(32)
-   * C380BEC2BFD727A4B6845133519F3AD6
-   * 签名,详见签名生成算法
-   * </pre>
-   */
-  @XStreamAlias("sign")
-  private String sign;
-
-  /**
-   * <pre>
    * 微信订单号
    * transaction_id
    * 跟out_trade_no二选一
@@ -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;
   }

+ 6 - 49
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位一天内不能重复的数字。  接口根据商户订单号支持重入,如出现超时可再调用。
@@ -91,27 +91,6 @@ public class WxPaySendRedpackRequest {
   private String wxAppid;
 
   /**
-   * mch_id
-   * 微信支付分配的商户号
-   */
-  @XStreamAlias("mch_id")
-  private String mchId;
-
-  /**
-   * nonce_str
-   * 随机字符串,不长于32位
-   */
-  @XStreamAlias("nonce_str")
-  private String nonceStr;
-
-  /**
-   * sign
-   * 详见<a href="https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3">签名生成算法</a>
-   */
-  @XStreamAlias("sign")
-  private String sign;
-
-  /**
    * <pre>
    * scene_id
    * 场景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() {