diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java index 61726e0405..539ad988b9 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java @@ -5,6 +5,8 @@ import lombok.*; import me.chanjar.weixin.common.annotation.Required; +import java.util.Map; + /** *
  * 查询代金券信息请求对象类
@@ -120,4 +122,15 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("coupon_id", couponId);
+    map.put("stock_id", stockId);
+    map.put("openid", openid);
+    map.put("op_user_id", opUserId);
+    map.put("device_info", deviceInfo);
+    map.put("version", version);
+    map.put("type", type);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java
index cab25062af..9001541b7a 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -227,4 +228,23 @@ public class WxPayCouponInfoQueryResult extends BaseWxPayResult {
   @XStreamAlias("is_partial_use")
   private String isPartialUse;
 
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    couponStockId = readXMLString(d, "coupon_stock_id");
+    couponId = readXMLString(d, "coupon_id");
+    couponValue = readXMLInteger(d, "coupon_value");
+    couponMinimum = readXMLInteger(d, "coupon_minimum");
+    couponName = readXMLString(d, "coupon_name");
+    couponState = readXMLString(d, "coupon_state");
+    couponDesc = readXMLString(d, "coupon_desc");
+    couponUseValue = readXMLInteger(d, "coupon_use_value");
+    couponRemainValue = readXMLInteger(d, "coupon_remain_value");
+    beginTime = readXMLString(d, "begin_time");
+    endTime = readXMLString(d, "end_time");
+    sendTime = readXMLString(d, "send_time");
+    consumerMchId = readXMLString(d, "consumer_mch_id");
+    sendSource = readXMLString(d, "send_source");
+    isPartialUse = readXMLString(d, "is_partial_use");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java
index 5fa6da7de2..a43ce51d99 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  * 发送代金券请求对象类
@@ -132,4 +134,16 @@ public class WxPayCouponSendRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
     //do nothing
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("coupon_stock_id", couponStockId);
+    map.put("openid_count", openidCount.toString());
+    map.put("partner_trade_no", partnerTradeNo);
+    map.put("openid", openid);
+    map.put("op_user_id", opUserId);
+    map.put("device_info", deviceInfo);
+    map.put("version", version);
+    map.put("type", type);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java
index 314845e46e..9350e58847 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -136,4 +137,16 @@ public class WxPayCouponSendResult extends BaseWxPayResult {
   @XStreamAlias("ret_msg")
   private String retMsg;
 
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    couponStockId = readXMLString(d, "coupon_stock_id");
+    respCount = readXMLInteger(d, "resp_count");
+    successCount = readXMLInteger(d, "success_count");
+    failedCount = readXMLInteger(d, "failed_count");
+    openid = readXMLString(d, "openid");
+    retCode = readXMLString(d, "ret_code");
+    couponId = readXMLString(d, "coupon_id");
+    retMsg = readXMLString(d, "ret_msg");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java
index b8a78b40bf..bae6a563ea 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  * 查询代金券批次请求对象类
@@ -91,4 +93,13 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("coupon_stock_id", couponStockId);
+    map.put("op_user_id", opUserId);
+    map.put("device_info", deviceInfo);
+    map.put("version", version);
+    map.put("type", type);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java
index f3e91d030b..b338f4081b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java
@@ -6,6 +6,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -191,4 +192,20 @@ public class WxPayCouponStockQueryResult extends BaseWxPayResult {
   @XStreamAlias("coupon_budget")
   private Integer couponBudget;
 
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    couponStockId = readXMLString(d, "coupon_stock_id");
+    couponName = readXMLString(d, "coupon_name");
+    couponValue = readXMLInteger(d, "coupon_value");
+    couponMinimum = readXMLInteger(d, "coupon_mininumn");
+    couponStockStatus = readXMLInteger(d, "coupon_stock_status");
+    couponTotal = readXMLInteger(d, "coupon_total");
+    maxQuota = readXMLInteger(d, "max_quota");
+    isSendNum = readXMLInteger(d, "is_send_num");
+    beginTime = readXMLString(d, "begin_time");
+    endTime = readXMLString(d, "end_time");
+    createTime = readXMLString(d, "create_time");
+    couponBudget = readXMLInteger(d, "coupon_budget");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java
index 6020dbed77..72adc1c9aa 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -93,4 +94,17 @@ public class EntPayBankQueryResult extends BaseWxPayResult {
   @XStreamAlias("reason")
   private String failReason;
 
+  @Override
+  protected void loadXML(Document d) {
+    partnerTradeNo = readXMLString(d, "partner_trade_no");
+    paymentNo = readXMLString(d, "payment_no");
+    bankNoMd5 = readXMLString(d, "bank_no_md5");
+    trueNameMd5 = readXMLString(d, "true_name_md5");
+    amount = readXMLInteger(d, "amount");
+    status = readXMLString(d, "status");
+    cmmsAmount = readXMLInteger(d, "cmms_amt");
+    createTime = readXMLString(d, "create_time");
+    paySuccessTime = readXMLString(d, "pay_succ_time");
+    failReason = readXMLString(d, "reason");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java
index 05ccebc23c..04c26403c2 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java
@@ -10,6 +10,8 @@
 import lombok.NoArgsConstructor;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  企业付款到银行卡的请求对象类
@@ -121,6 +123,16 @@ protected String[] getIgnoredParamsForSign() {
     return new String[]{"sign_type"};
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("partner_trade_no", partnerTradeNo);
+    map.put("enc_bank_no", encBankNo);
+    map.put("enc_true_name", encTrueName);
+    map.put("bank_code", bankCode);
+    map.put("amount", amount.toString());
+    map.put("desc", description);
+  }
+
   @Override
   protected boolean ignoreAppid() {
     return true;
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java
index 078e27e849..0d38645afe 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -48,4 +49,11 @@ public class EntPayBankResult extends BaseWxPayResult {
   @XStreamAlias("cmms_amt")
   private Integer cmmsAmount;
 
+  @Override
+  protected void loadXML(Document d) {
+    amount = readXMLInteger(d, "amount");
+    partnerTradeNo = readXMLString(d, "partner_trade_no");
+    paymentNo = readXMLString(d, "payment_no");
+    cmmsAmount = readXMLInteger(d, "cmms_amt");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java
index 21de8fca35..779d59823b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java
@@ -10,6 +10,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 
+import java.util.Map;
+
 /**
  * 
  * 企业付款请求对象.
@@ -55,4 +57,9 @@ public String toString() {
   protected String[] getIgnoredParamsForSign() {
     return new String[]{"sign_type"};
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("partner_trade_no", partnerTradeNo);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java
index e9f6d2213f..6dee1d0911 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -81,4 +82,17 @@ public class EntPayQueryResult extends BaseWxPayResult {
   @XStreamAlias("desc")
   private String desc;
 
+  @Override
+  protected void loadXML(Document d) {
+    partnerTradeNo = readXMLString(d, "partner_trade_no");
+    detailId = readXMLString(d, "detail_id");
+    status = readXMLString(d, "status");
+    reason = readXMLString(d, "reason");
+    openid = readXMLString(d, "openid");
+    transferName = readXMLString(d, "transfer_name");
+    paymentAmount = readXMLInteger(d, "payment_amount");
+    transferTime = readXMLString(d, "transfer_time");
+    paymentTime = readXMLString(d, "payment_time");
+    desc = readXMLString(d, "desc");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java
index 29fc517f00..74e5b4b1a0 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java
@@ -5,8 +5,11 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 红包发送记录查询请求
+ *
  * @author wuyong
  * @date 2019-12-01 17:19
  */
@@ -30,4 +33,9 @@ public class EntPayRedpackQueryRequest extends BaseWxPayRequest {
   protected void checkConstraints() throws WxPayException {
 
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java
index 1235fe1bd4..000498519f 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 红包发送记录查询返回
@@ -130,4 +131,24 @@ public class EntPayRedpackQueryResult extends BaseWxPayResult {
   @XStreamAlias("sender_header_media_id")
   private Integer senderHeaderMediaId;
 
+  @Override
+  protected void loadXML(Document d) {
+    mchBillNo = readXMLString(d, "mch_billno");
+    detailId = readXMLString(d, "detailId");
+    status = readXMLString(d, "status");
+    sendType = readXMLString(d, "send_type");
+    totalAmount = readXMLInteger(d, "total_amount");
+    reason = readXMLInteger(d, "reason");
+    sendTime = readXMLString(d, "send_time");
+    refundTime = readXMLString(d, "refund_time");
+    refundAmount = readXMLInteger(d, "refund_amount");
+    wishing = readXMLString(d, "wishing");
+    remark = readXMLString(d, "remark");
+    actName = readXMLString(d, "act_name");
+    openid = readXMLString(d, "openid");
+    amount = readXMLInteger(d, "amount");
+    rcvTime = readXMLInteger(d, "rcv_time");
+    senderName = readXMLInteger(d, "sender_name");
+    senderHeaderMediaId = readXMLInteger(d, "sender_header_media_id");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java
index 0ab8bddab5..762499e693 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java
@@ -6,8 +6,11 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 发送企业红包
+ *
  * @author wuyong
  * @date 2019-12-1
  */
@@ -144,4 +147,19 @@ protected boolean ignoreSubMchId() {
   protected boolean isWxWorkSign() {
     return true;
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+    map.put("wxappid", wxAppId);
+    map.put("sender_name", senderName);
+    map.put("agentid", agentId);
+    map.put("sender_header_media_id", senderHeaderMediaId);
+    map.put("re_openid", reOpenid);
+    map.put("total_amount", totalAmount.toString());
+    map.put("wishing", wishing);
+    map.put("act_name", actName);
+    map.put("remark", remark);
+    map.put("scene_id", sceneId);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java
index 677ac88f89..98cce357c9 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java
@@ -5,11 +5,13 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 import java.io.Serializable;
 
 /**
  * 企业微信红包返回
+ *
  * @author wuyong
  * @date 2019-12-01 11:31
  */
@@ -77,4 +79,15 @@ public class EntPayRedpackResult extends BaseWxPayResult implements Serializable
   @XStreamAlias("sender_header_media_id")
   private String senderHeaderMediaId;
 
+  @Override
+  protected void loadXML(Document d) {
+    mchBillNo = readXMLString(d, "mch_billno");
+    mchId = readXMLString(d, "mch_id");
+    wxAppId = readXMLString(d, "wxappid");
+    reOpenid = readXMLString(d, "re_openid");
+    totalAmount = readXMLString(d, "totalAmount");
+    sendListId = readXMLString(d, "sendListid");
+    senderName = readXMLString(d, "sender_name");
+    senderHeaderMediaId = readXMLString(d, "sender_header_media_id");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java
index 24c1c185ac..6f89254714 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java
@@ -10,6 +10,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 
+import java.util.Map;
+
 /**
  * 
  * 企业付款请求对象.
@@ -195,4 +197,18 @@ public void setMchId(String mchId) {
   protected String[] getIgnoredParamsForSign() {
     return new String[]{"sign_type"};
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_appid", mchAppid);
+    map.put("mchid", mchId);
+    map.put("device_info", deviceInfo);
+    map.put("partner_trade_no", partnerTradeNo);
+    map.put("openid", openid);
+    map.put("check_name", checkName);
+    map.put("re_user_name", reUserName);
+    map.put("amount", amount.toString());
+    map.put("desc", description);
+    map.put("spbill_create_ip", spbillCreateIp);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java
index 223c196395..9863e83bcc 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -56,4 +57,13 @@ public class EntPayResult extends BaseWxPayResult {
   @XStreamAlias("payment_time")
   private String paymentTime;
 
+  @Override
+  protected void loadXML(Document d) {
+    mchId = readXMLString(d, "mchid");
+    mchAppid = readXMLString(d, "mch_appid");
+    deviceInfo = readXMLString(d, "device_info");
+    partnerTradeNo = readXMLString(d, "partner_trade_no");
+    paymentNo = readXMLString(d, "payment_no");
+    paymentTime = readXMLString(d, "payment_time");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java
index f7f62afb7e..2a9cc8c6ad 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java
@@ -4,6 +4,7 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -28,4 +29,10 @@ public class GetPublicKeyResult extends BaseWxPayResult {
    */
   @XStreamAlias("pub_key")
   private String pubKey;
+
+  @Override
+  protected void loadXML(Document d) {
+    mchId = readXMLString(d, "mch_id");
+    pubKey = readXMLString(d, "pub_key");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java
index 93fb4b2705..b1a8fe9d2d 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java
@@ -13,7 +13,9 @@
 import lombok.NoArgsConstructor;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import org.w3c.dom.Document;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -349,6 +351,51 @@ public Map toMap() {
     return resultMap;
   }
 
+  @Override
+  protected void loadXML(Document d) {
+    promotionDetail = readXMLString(d, "promotion_detail");
+    deviceInfo = readXMLString(d, "device_info");
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    subOpenid = readXMLString(d, "sub_openid");
+    subIsSubscribe = readXMLString(d, "sub_is_subscribe");
+    tradeType = readXMLString(d, "trade_type");
+    bankType = readXMLString(d, "bank_type");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    feeType = readXMLString(d, "fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    couponFee = readXMLInteger(d, "coupon_fee");
+    couponCount = readXMLInteger(d, "coupon_count");
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    attach = readXMLString(d, "attach");
+    timeEnd = readXMLString(d, "time_end");
+    version = readXMLString(d, "version");
+    rateValue = readXMLString(d, "rate_value");
+    signType = readXMLString(d, "sign_type");
+
+    composeCoupons();
+  }
+
+  /**
+   * 通过xml组装couponList属性内容.
+   */
+  protected void composeCoupons() {
+    if (this.couponCount == null || this.couponCount == 0) {
+      return;
+    }
+    this.couponList = new ArrayList(couponCount);
+    for (int i = 0; i < this.couponCount; i++) {
+      WxPayOrderNotifyCoupon coupon = new WxPayOrderNotifyCoupon();
+      coupon.setCouponId(this.getXmlValue("xml/coupon_id_" + i));
+      coupon.setCouponType(this.getXmlValue("xml/coupon_type_" + i));
+      coupon.setCouponFee(this.getXmlValueAsInt("xml/coupon_fee_" + i));
+      couponList.add(coupon);
+    }
+  }
+
   @Override
   public String toString() {
     return WxGsonBuilder.create().toJson(this);
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java
index ad56852824..d9f4cbd5f8 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java
@@ -19,6 +19,7 @@
 import lombok.NoArgsConstructor;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -80,6 +81,45 @@ public static WxPayRefundNotifyResult fromXML(String xmlString, String mchKey) t
 
   private ReqInfo reqInfo;
 
+  // 解密后的reqInfo 字符串
+  private transient String decryptedReqInfo;
+
+  @Override
+  protected void loadXML(Document d) {
+    reqInfoString = readXMLString(d, "req_info");
+  }
+
+  /**
+   * 解密并解析reqInfo
+   *
+   * @param mchKey
+   * @throws WxPayException
+   */
+  public void decryptReqInfo(String mchKey) throws WxPayException {
+    //如果是失败,直接返回,不用解析
+    if (WxPayConstants.ResultCode.FAIL.equals(getReturnCode())) {
+      return;
+    }
+    try {
+      final String keyMd5String = DigestUtils.md5Hex(mchKey).toLowerCase();
+      SecretKeySpec key = new SecretKeySpec(keyMd5String.getBytes(StandardCharsets.UTF_8), "AES");
+
+      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+      cipher.init(Cipher.DECRYPT_MODE, key);
+      decryptedReqInfo = new String(cipher.doFinal(Base64.decodeBase64(reqInfoString)), StandardCharsets.UTF_8);
+      loadReqInfo(decryptedReqInfo);
+    } catch (Exception e) {
+      throw new WxPayException("解密退款通知加密信息时出错", e);
+    }
+  }
+
+  // 本方法独立出来方便测试
+  protected void loadReqInfo(String decryptedReqInfo) {
+    Document document = openXML(decryptedReqInfo);
+    reqInfo = new ReqInfo();
+    reqInfo.loadXML(document);
+  }
+
   /**
    * 加密信息字段解密后的内容.
    */
@@ -272,6 +312,23 @@ public static ReqInfo fromXML(String xmlString) {
       xstream.processAnnotations(ReqInfo.class);
       return (ReqInfo) xstream.fromXML(xmlString);
     }
+
+    public void loadXML(Document d) {
+      transactionId = readXMLString(d, "transaction_id");
+      outTradeNo = readXMLString(d, "out_trade_no");
+      refundId = readXMLString(d, "refund_id");
+      outRefundNo = readXMLString(d, "out_refund_no");
+      totalFee = readXMLInteger(d, "total_fee");
+      settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+      refundFee = readXMLInteger(d, "refund_fee");
+      settlementRefundFee = readXMLInteger(d, "settlement_refund_fee");
+      refundStatus = readXMLString(d, "refund_status");
+      successTime = readXMLString(d, "success_time");
+      refundRecvAccout = readXMLString(d, "refund_recv_accout");
+      refundAccount = readXMLString(d, "refund_account");
+      refundRequestSource = readXMLString(d, "refund_request_source");
+    }
   }
 
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java
index a87adabedd..9c9c451372 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -45,4 +46,11 @@ public class WxScanPayNotifyResult extends BaseWxPayResult {
   @XStreamAlias("product_id")
   private String productId;
 
+  @Override
+  protected void loadXML(Document d) {
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    productId = readXMLString(d, "product_id");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java
index 22cd545083..3a0ee93648 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java
@@ -7,6 +7,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/23 14:02
  * @version 1.0
@@ -67,4 +69,11 @@ public class ProfitSharingFinishRequest extends BaseWxPayRequest {
   protected void checkConstraints() throws WxPayException {
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("transaction_id", transactionId);
+    map.put("out_order_no", outOrderNo);
+    map.put("description", description);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java
index 583276f3d7..c4009858cb 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java
@@ -7,6 +7,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/22 15:44
  * @version 1.0
@@ -56,4 +58,10 @@ protected void checkConstraints() throws WxPayException {
   public boolean ignoreAppid() {
     return true;
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("transaction_id", transactionId);
+    map.put("out_order_no", outOrderNo);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java
index 6affffe670..49fdf74552 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java
@@ -8,6 +8,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * @author Wang GuangXin 2019/10/22 15:51
@@ -67,6 +68,18 @@ public ProfitSharingQueryResult.Receivers formatReceivers() {
     return gson.fromJson(receivers, Receivers.class);
   }
 
+  @Override
+  protected void loadXML(Document d) {
+    transactionId = readXMLString(d, "transaction_id");
+    outOrderNo = readXMLString(d, "out_order_no");
+    orderId = readXMLString(d, "orderId");
+    status = readXMLString(d, "status");
+    closeReason = readXMLString(d, "close_reason");
+    receivers = readXMLString(d, "receivers");
+    amount = readXMLInteger(d, "amount");
+    description = readXMLString(d, "description");
+  }
+
   @Data
   public class Receivers {
     /**
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java
index 3d00d5dd7c..db64854395 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java
@@ -7,6 +7,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 添加/删除分账接受方请求对象
  *
@@ -44,4 +46,9 @@ public class ProfitSharingReceiverRequest extends BaseWxPayRequest {
   protected void checkConstraints() throws WxPayException {
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("receiver", receiver);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java
index 0b9f53881c..806632fe54 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java
@@ -6,6 +6,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * @author Wang GuangXin 2019/10/22 14:54
@@ -22,4 +23,9 @@ public class ProfitSharingReceiverResult extends BaseWxPayResult {
    */
   @XStreamAlias("receiver")
   private String receiver;
+
+  @Override
+  protected void loadXML(Document d) {
+    receiver = readXMLString(d, "receiver");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java
index 6e6c2a3147..e3b1f5690c 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java
@@ -7,6 +7,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/21 17:57
  * @version 1.0
@@ -81,4 +83,11 @@ protected void checkConstraints() throws WxPayException {
     // 目前仅支持HMAC-SHA256.
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("transaction_id", transactionId);
+    map.put("out_order_no", outOrderNo);
+    map.put("receivers", receivers);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java
index 122821cf91..daea0e64db 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * @author Wang GuangXin 2019/10/22 10:06
@@ -30,4 +31,11 @@ public class ProfitSharingResult extends BaseWxPayResult {
    */
   @XStreamAlias("order_id")
   private String orderId;
+
+  @Override
+  protected void loadXML(Document d) {
+    transactionId = readXMLString(d, "transaction_id");
+    outOrderNo = readXMLString(d, "out_order_no");
+    orderId = readXMLString(d, "order_id");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java
index e2a2da4739..734c805401 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java
@@ -8,6 +8,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/23 15:32
  * @version 1.0
@@ -69,4 +71,11 @@ protected void checkConstraints() throws WxPayException {
     }
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("order_id", orderId);
+    map.put("out_order_no", outOrderNo);
+    map.put("out_return_no", outReturnNo);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java
index 6bdc73aa62..3e389a467a 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java
@@ -8,6 +8,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/23 14:27
  * @version 1.0
@@ -130,4 +132,15 @@ protected void checkConstraints() throws WxPayException {
     }
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("order_id", orderId);
+    map.put("out_order_no", outOrderNo);
+    map.put("out_return_no", outReturnNo);
+    map.put("return_account_type", returnAccountType);
+    map.put("return_account", returnAccount);
+    map.put("return_amount", returnAmount.toString());
+    map.put("description", description);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java
index 814bcf2d58..2828d4ab82 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * @author Wang GuangXin 2019/10/23 14:41
@@ -71,4 +72,19 @@ public class ProfitSharingReturnResult extends BaseWxPayResult {
    */
   @XStreamAlias("finish_time")
   private String finishTime;
+
+  @Override
+  protected void loadXML(Document d) {
+    orderId = readXMLString(d, "order_id");
+    outOrderNo = readXMLString(d, "out_order_no");
+    outReturnNo = readXMLString(d, "out_return_no");
+    returnNo = readXMLString(d, "return_no");
+    returnAccountType = readXMLString(d, "return_account_type");
+    returnAccount = readXMLString(d, "return_account");
+    returnAmount = readXMLInteger(d, "return_amount");
+    description = readXMLString(d, "description");
+    result = readXMLString(d, "result");
+    failReason = readXMLString(d, "fail_reason");
+    finishTime = readXMLString(d, "finish_time");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
index 0b85f41e93..d60e56893b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
@@ -3,6 +3,7 @@
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.util.SignUtils;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.Data;
@@ -12,9 +13,14 @@
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
 import org.apache.commons.lang3.StringUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
 
 import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.ALL_SIGN_TYPES;
 
@@ -202,14 +208,52 @@ public String toString() {
    * @return the string
    */
   public String toXML() {
-    XStream xstream = XStreamInitializer.getInstance();
     //涉及到服务商模式的两个参数,在为空值时置为null,以免在请求时将空值传给微信服务器
     this.setSubAppId(StringUtils.trimToNull(this.getSubAppId()));
     this.setSubMchId(StringUtils.trimToNull(this.getSubMchId()));
+    if (XmlConfig.fastMode) {
+      return toFastXml();
+    }
+    XStream xstream = XStreamInitializer.getInstance();
     xstream.processAnnotations(this.getClass());
     return xstream.toXML(this);
   }
 
+  /**
+   * 使用快速算法组装xml
+   *
+   * @return
+   */
+  private String toFastXml() {
+    try {
+      Document document = DocumentHelper.createDocument();
+      Element root = document.addElement(xmlRootTagName());
+
+      Map signParams = getSignParams();
+      signParams.put("sign", sign);
+      for (Map.Entry entry : signParams.entrySet()) {
+        if (entry.getValue() == null) {
+          continue;
+        }
+        Element elm = root.addElement(entry.getKey());
+        elm.addText(entry.getValue());
+      }
+
+      return document.asXML();
+    } catch (Exception e) {
+      throw new RuntimeException("generate xml error", e);
+    }
+  }
+
+  /**
+   * 返回xml结构的根节点名称
+   *
+   * @return 默认返回"xml", 特殊情况可以在子类中覆盖
+   */
+  protected String xmlRootTagName() {
+    return "xml";
+  }
+
   /**
    * 签名时,是否忽略appid.
    *
@@ -228,14 +272,14 @@ protected boolean ignoreSubAppId() {
     return false;
   }
 
-  protected boolean ignoreSubMchId(){
+  protected boolean ignoreSubMchId() {
     return false;
   }
 
   /**
    * 是否是企业微信字段
    */
-  protected boolean isWxWorkSign(){
+  protected boolean isWxWorkSign() {
     return false;
   }
 
@@ -248,6 +292,32 @@ protected String[] getIgnoredParamsForSign() {
     return new String[0];
   }
 
+  /**
+   * 获取签名时需要的参数.
+   * 注意:不含sign属性
+   */
+  public Map getSignParams() {
+    Map map = new HashMap<>();
+    map.put("appid", appid);
+    map.put("mch_id", mchId);
+    map.put("sub_appid", subAppId);
+    map.put("sub_mch_id", subMchId);
+    map.put("nonce_str", nonceStr);
+    map.put("sign_type", signType);
+
+    storeMap(map);
+    return map;
+  }
+
+  /**
+   * 将属性组装到一个Map中,供签名和最终发送XML时使用.
+   * 这里需要将所有的属性全部保存进来,签名的时候会自动调用getIgnoredParamsForSign进行忽略,
+   * 不用担心。否则最终生成的XML会缺失。
+   *
+   * @param map 传入的属性Map
+   */
+  abstract protected void storeMap(Map map);
+
   /**
    * 
    * 检查参数,并设置签名.
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java
index 3b156407db..c9d5505b36 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 
  * 授权码查询openid接口请求对象类
@@ -35,4 +37,10 @@ public class WxPayAuthcode2OpenidRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
     // nothing to do
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("auth_code", authCode);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java
index e44a6111e7..34a707bed7 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java
@@ -2,6 +2,8 @@
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 
+import java.util.Map;
+
 /**
  * 
  *  支付请求默认对象类
@@ -21,4 +23,8 @@ protected void checkConstraints() {
   protected boolean ignoreAppid() {
     return true;
   }
+
+  @Override
+  protected void storeMap(Map map) {
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
index e616224db7..383dbe5b7c 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
@@ -9,6 +9,7 @@
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.Arrays;
+import java.util.Map;
 
 /**
  * 
@@ -95,4 +96,13 @@ protected void checkConstraints() throws WxPayException {
         Arrays.toString(BILL_TYPES), this.getBillType()));
     }
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("device_info", deviceInfo);
+    map.put("bill_type", billType);
+    map.put("bill_date", billDate);
+    map.put("tar_type", tarType);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java
index 8ce06238e6..efb14fc7c0 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java
@@ -9,6 +9,7 @@
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.Arrays;
+import java.util.Map;
 
 /**
  * 
@@ -87,4 +88,11 @@ protected void checkConstraints() throws WxPayException {
      */
     this.setSignType(SIGN_TYPE_HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("bill_date", billDate);
+    map.put("account_type", accountType);
+    map.put("tar_type", tarType);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFaceAuthInfoRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFaceAuthInfoRequest.java
index eb53e38c6a..cef831a3d6 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFaceAuthInfoRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFaceAuthInfoRequest.java
@@ -4,6 +4,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  获取微信刷脸调用凭证请求对象类
@@ -123,4 +125,15 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("store_id", storeId);
+    map.put("store_name", storeName);
+    map.put("device_id", deviceId);
+    map.put("attach", attach);
+    map.put("rawdata", rawdata);
+    map.put("now", now);
+    map.put("version", version);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFacepayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFacepayRequest.java
index 2c70a8945c..e9821c506c 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFacepayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFacepayRequest.java
@@ -4,6 +4,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  提交刷脸支付请求对象类
@@ -174,4 +176,19 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("device_info", deviceInfo);
+    map.put("body", body);
+    map.put("detail", detail);
+    map.put("attach", attach);
+    map.put("out_trade_no", outTradeNo);
+    map.put("total_fee", totalFee.toString());
+    map.put("fee_type", feeType);
+    map.put("spbill_create_ip", spbillCreateIp);
+    map.put("goods_tag", goodsTag);
+    map.put("openid", openid);
+    map.put("face_code", faceCode);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
index 4fb27dd8bf..cdded3110d 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
@@ -4,6 +4,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  提交付款码支付请求对象类
@@ -255,4 +257,22 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("version", version);
+    map.put("body", body);
+    map.put("detail", detail);
+    map.put("attach", attach);
+    map.put("out_trade_no", outTradeNo);
+    map.put("total_fee", totalFee.toString());
+    map.put("fee_type", feeType);
+    map.put("spbill_create_ip", spbillCreateIp);
+    map.put("goods_tag", goodsTag);
+    map.put("limit_pay", limitPay);
+    map.put("time_start", timeStart);
+    map.put("time_expire", timeExpire);
+    map.put("auth_code", authCode);
+    map.put("scene_info", sceneInfo);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
index e430460e39..3758653a03 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 
  *  关闭订单请求对象类
@@ -36,4 +38,10 @@ public class WxPayOrderCloseRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
 
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("out_trade_no", outTradeNo);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
index 221b04f172..ffcd52d171 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * 
  * 订单查询请求对象
@@ -76,4 +78,12 @@ protected void checkConstraints() throws WxPayException {
       throw new WxPayException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一");
     }
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("version", version);
+    map.put("transaction_id", transactionId);
+    map.put("out_trade_no", outTradeNo);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
index 5394631b3c..73c5034696 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * 
  * 撤销订单请求类
@@ -53,4 +55,10 @@ protected void checkConstraints() throws WxPayException {
     }
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("transaction_id", transactionId);
+    map.put("out_trade_no", outTradeNo);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java
index 5ff1c76a04..5c4a9fe2ff 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  拉取订单评价数据接口的请求参数封装类.
@@ -84,4 +86,14 @@ public class WxPayQueryCommentRequest extends BaseWxPayRequest {
   protected void checkConstraints() throws WxPayException {
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("begin_time", beginTime);
+    map.put("end_time", endTime);
+    map.put("offset", offset.toString());
+    if (limit != null) {
+      map.put("limit", limit.toString());
+    }
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java
index 9303810753..01ca5cafd4 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 
  *   注释中各行对应含义:
@@ -27,8 +29,9 @@ public class WxPayRedpackQueryRequest extends BaseWxPayRequest {
 
   @Override
   protected String[] getIgnoredParamsForSign() {
-    return new String[]{"sub_appid","sub_mch_id","sign_type"};
+    return new String[]{"sub_appid", "sub_mch_id", "sign_type"};
   }
+
   /**
    * 商户订单号
    * mch_billno
@@ -55,4 +58,10 @@ protected String[] getIgnoredParamsForSign() {
   protected void checkConstraints() {
 
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+    map.put("bill_type", billType);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java
index 4df8a63db9..d9befee6f6 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * 
  * Created by Binary Wang on 2016-11-24.
@@ -91,4 +93,13 @@ protected void checkConstraints() throws WxPayException {
     }
 
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("device_info", deviceInfo);
+    map.put("transaction_id", transactionId);
+    map.put("out_trade_no", outTradeNo);
+    map.put("out_refund_no", outRefundNo);
+    map.put("refund_id", refundId);
+  }
 }
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 1383e4f5b1..924d46ffdd 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
@@ -10,6 +10,7 @@
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.Arrays;
+import java.util.Map;
 
 /**
  * 
@@ -165,7 +166,7 @@ public class WxPayRefundRequest extends BaseWxPayRequest {
    * 类型:String(256)
    * 示例值:https://weixin.qq.com/notify/
    * 描述:	异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数
-   如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。
+   * 如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。
    * 
*/ @XStreamAlias("notify_url") @@ -194,4 +195,19 @@ protected void checkConstraints() throws WxPayException { } } + @Override + protected void storeMap(Map map) { + map.put("device_info", deviceInfo); + map.put("transaction_id", transactionId); + map.put("out_trade_no", outTradeNo); + map.put("out_refund_no", outRefundNo); + map.put("total_fee", totalFee.toString()); + map.put("refund_fee", refundFee.toString()); + map.put("refund_fee_type", refundFeeType); + map.put("op_user_id", opUserId); + map.put("refund_account", refundAccount); + map.put("refund_desc", refundDesc); + map.put("notify_url", notifyUrl); + } + } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java index 3e5364c5ce..56cd490a55 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java @@ -4,6 +4,8 @@ import lombok.*; import me.chanjar.weixin.common.annotation.Required; +import java.util.Map; + /** *
  * 微信支付-交易保障请求参数
@@ -174,4 +176,19 @@ public class WxPayReportRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
     //do nothing
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("device_info", deviceInfo);
+    map.put("interface_url", interfaceUrl);
+    map.put("execute_time_", executeTime.toString());
+    map.put("return_code", returnCode);
+    map.put("return_msg", returnMsg);
+    map.put("result_code", resultCode);
+    map.put("err_code", errCode);
+    map.put("err_code_des", errCodeDes);
+    map.put("out_trade_no", outTradeNo);
+    map.put("user_ip", userIp);
+    map.put("time", time);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java
index 62cfe490a7..fd727ab6aa 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java
@@ -4,6 +4,8 @@
 import lombok.*;
 import lombok.experimental.Accessors;
 
+import java.util.Map;
+
 /**
  * 发送小程序红包请求参数对象.
  *
@@ -119,6 +121,21 @@ protected void checkConstraints() {
 
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+    map.put("send_name", sendName);
+    map.put("re_openid", reOpenid);
+    map.put("total_amount", totalAmount.toString());
+    map.put("total_num", totalNum.toString());
+    map.put("wishing", wishing);
+    map.put("act_name", actName);
+    map.put("remark", remark);
+    map.put("notify_way", notifyWay);
+    map.put("scene_id", sceneId);
+    map.put("wxappid", wxAppid);
+  }
+
   @Override
   public String getAppid() {
     return this.wxAppid;
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java
index 977f363f6a..4a8bae4f57 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 发送红包请求参数对象.
  * Created by Binary Wang on 2016/9/24.
@@ -181,4 +183,18 @@ public void setAppid(String appid) {
     this.wxAppid = appid;
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+    map.put("send_name", sendName);
+    map.put("re_openid", reOpenid);
+    map.put("total_amount", totalAmount.toString());
+    map.put("total_num", totalNum.toString());
+    map.put("amt_type", amtType);
+    map.put("wishing", wishing);
+    map.put("client_ip", clientIp);
+    map.put("act_name", actName);
+    map.put("remark", remark);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java
index 87ac41054b..8602740bb8 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 
  * 转换短链接请求对象类
@@ -35,4 +37,9 @@ public class WxPayShorturlRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
     //do nothing
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("long_url", longUrl);
+  }
 }
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 54d443881d..fc5949dfdf 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
@@ -9,6 +9,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * 
  * 统一下单请求参数对象.
@@ -396,4 +398,30 @@ public void checkAndSign(WxPayConfig config) throws WxPayException {
     super.checkAndSign(config);
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("version", version);
+    map.put("device_info", deviceInfo);
+    map.put("body", body);
+    map.put("detail", detail);
+    map.put("attach", attach);
+    map.put("out_trade_no", outTradeNo);
+    map.put("fee_type", feeType);
+    map.put("total_fee", totalFee.toString());
+    map.put("spbill_create_ip", spbillCreateIp);
+    map.put("time_start", timeStart);
+    map.put("time_expire", timeExpire);
+    map.put("goods_tag", goodsTag);
+    map.put("notify_url", notifyUrl);
+    map.put("trade_type", tradeType);
+    map.put("product_id", productId);
+    map.put("limit_pay", limitPay);
+    map.put("openid", openid);
+    map.put("sub_openid", subOpenid);
+    map.put("receipt", receipt);
+    map.put("scene_info", sceneInfo);
+    map.put("fingerprint", fingerprint);
+    map.put("profit_sharing", profitSharing);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java
index 5a1ea64e83..d58f20fb18 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java
@@ -11,6 +11,7 @@
 import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
 
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,6 +31,8 @@
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
 
+import org.w3c.dom.*;
+
 /**
  * 
  * 微信支付结果共用属性类.
@@ -107,8 +110,9 @@ public abstract class BaseWxPayResult implements Serializable {
 
   /**
    * xml的Document对象,用于解析xml文本.
+   * make xmlDoc transient to ensure toString() can work.
    */
-  private Document xmlDoc;
+  private transient Document xmlDoc;
 
   /**
    * 将单位分转换成单位圆.
@@ -129,6 +133,18 @@ public static String fenToYuan(Integer fen) {
    * @return the t
    */
   public static  T fromXML(String xmlString, Class clz) {
+    if (XmlConfig.fastMode) {
+      try {
+        BaseWxPayResult t = clz.newInstance();
+        t.setXmlString(xmlString);
+        Document doc = t.getXmlDoc();
+        t.loadBasicXML(doc);
+        t.loadXML(doc);
+        return (T) t;
+      } catch (Exception e) {
+        throw new RuntimeException("parse xml error", e);
+      }
+    }
     XStream xstream = XStreamInitializer.getInstance();
     xstream.processAnnotations(clz);
     T result = (T) xstream.fromXML(xmlString);
@@ -136,6 +152,70 @@ public static  T fromXML(String xmlString, Class c
     return result;
   }
 
+  /**
+   * 从XML文档中加载属性,供子类覆盖加载额外的属性
+   *
+   * @param d Document
+   */
+  protected abstract void loadXML(Document d);
+
+  /**
+   * 从XML文档中加载基础属性
+   *
+   * @param d Document
+   */
+  private void loadBasicXML(Document d) {
+    returnCode = readXMLString(d, "return_code");
+    returnMsg = readXMLString(d, "return_msg");
+    resultCode = readXMLString(d, "result_code");
+    errCode = readXMLString(d, "err_code");
+    errCodeDes = readXMLString(d, "err_code_des");
+    appid = readXMLString(d, "appid");
+    mchId = readXMLString(d, "mch_id");
+    subAppId = readXMLString(d, "sub_appid");
+    subMchId = readXMLString(d, "sub_mch_id");
+    nonceStr = readXMLString(d, "nonce_str");
+    sign = readXMLString(d, "sign");
+  }
+
+  public static Integer readXMLInteger(Node d, String tagName) {
+    String content = readXMLString(d, tagName);
+    if (content == null || content.trim().length() == 0) return null;
+    return Integer.parseInt(content);
+  }
+
+  public static String readXMLString(Node d, String tagName) {
+    if (!d.hasChildNodes()) return null;
+    NodeList childNodes = d.getChildNodes();
+    for (int i = 0, j = childNodes.getLength(); i < j; i++) {
+      Node node = childNodes.item(i);
+      if (tagName.equals(node.getNodeName())) {
+        if (!node.hasChildNodes()) return null;
+        return node.getFirstChild().getNodeValue();
+      }
+    }
+    return null;
+  }
+
+  public static String readXMLString(Document d, String tagName) {
+    NodeList elements = d.getElementsByTagName(tagName);
+    if (elements == null || elements.getLength() == 0) {
+      return null;
+    }
+
+    Node node = elements.item(0).getFirstChild();
+    if (node == null) {
+      return null;
+    }
+    return node.getNodeValue();
+  }
+
+  public static Integer readXMLInteger(Document d, String tagName) {
+    String content = readXMLString(d, tagName);
+    if (content == null || content.trim().length() == 0) return null;
+    return Integer.parseInt(content);
+  }
+
   /**
    * Gets logger.
    *
@@ -185,18 +265,19 @@ private Document getXmlDoc() {
     if (this.xmlDoc != null) {
       return this.xmlDoc;
     }
+    xmlDoc = openXML(xmlString);
+    return xmlDoc;
+  }
 
+  protected Document openXML(String content) {
     try {
       final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
       factory.setExpandEntityReferences(false);
       factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
-      this.xmlDoc = factory.newDocumentBuilder()
-        .parse(new ByteArrayInputStream(this.xmlString.getBytes(StandardCharsets.UTF_8)));
-      return xmlDoc;
+      return factory.newDocumentBuilder().parse(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
     } catch (Exception e) {
       throw new RuntimeException("非法的xml文本内容:\n" + this.xmlString, e);
     }
-
   }
 
   /**
@@ -205,7 +286,7 @@ private Document getXmlDoc() {
    * @param path the path
    * @return the xml value
    */
-  String getXmlValue(String... path) {
+  protected String getXmlValue(String... path) {
     Document doc = this.getXmlDoc();
     String expression = String.format("/%s//text()", Joiner.on("/").join(path));
     try {
@@ -225,7 +306,7 @@ String getXmlValue(String... path) {
    * @param path the path
    * @return the xml value as int
    */
-  Integer getXmlValueAsInt(String... path) {
+  protected Integer getXmlValueAsInt(String... path) {
     String result = this.getXmlValue(path);
     if (StringUtils.isBlank(result)) {
       return null;
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java
index 2c36d32f03..76526ff685 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -30,4 +31,14 @@ public class WxPayAuthcode2OpenidResult extends BaseWxPayResult {
   @XStreamAlias("openid")
   private String openid;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    openid = readXMLString(d, "openid");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java
index cc0a3a6edc..1dda6483b4 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java
@@ -1,6 +1,7 @@
 package com.github.binarywang.wxpay.bean.result;
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -12,4 +13,7 @@
  */
 @XStreamAlias("xml")
 public class WxPayCommonResult extends BaseWxPayResult {
+  @Override
+  protected void loadXML(Document d) {
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFaceAuthInfoResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFaceAuthInfoResult.java
index 95dcf71eb4..5c357c560f 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFaceAuthInfoResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFaceAuthInfoResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 import java.io.Serializable;
 
@@ -35,4 +36,15 @@ public class WxPayFaceAuthInfoResult extends BaseWxPayResult implements Serializ
   @XStreamAlias("expires_in")
   private String expiresIn;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    authinfo = readXMLString(d, "authinfo");
+    expiresIn = readXMLString(d, "expires_in");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFacepayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFacepayResult.java
index 27e33d7bfc..c19a92c488 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFacepayResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFacepayResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -242,4 +243,30 @@ public class WxPayFacepayResult extends BaseWxPayResult {
   @XStreamAlias("time_end")
   private String timeEnd;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    subOpenid = readXMLString(d, "sub_openid");
+    subsSubscribe = readXMLString(d, "sub_is_subscribe");
+    tradeType = readXMLString(d, "trade_type");
+    bankType = readXMLString(d, "bank_type");
+    feeType = readXMLString(d, "fee_type");
+    totalFee = readXMLInteger(d, "total_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    detail = readXMLString(d, "detail");
+    attach = readXMLString(d, "attach");
+    promotionDetail = readXMLString(d, "promotion_detail");
+    timeEnd = readXMLString(d, "time_end");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java
index 36f910be63..b7de7ffec1 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -215,4 +216,28 @@ public class WxPayMicropayResult extends BaseWxPayResult {
   @XStreamAlias("promotion_detail")
   private String promotionDetail;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    tradeType = readXMLString(d, "trade_type");
+    bankType = readXMLString(d, "bank_type");
+    feeType = readXMLString(d, "fee_type");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    couponFee = readXMLInteger(d, "coupon_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    attach = readXMLString(d, "attach");
+    timeEnd = readXMLString(d, "time_end");
+    promotionDetail = readXMLString(d, "promotion_detail");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java
index a71c8ab7ed..a098cbb5fc 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -25,4 +26,14 @@ public class WxPayOrderCloseResult extends BaseWxPayResult {
   @XStreamAlias("result_msg")
   private String resultMsg;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    resultMsg = readXMLString(d, "result_msg");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java
index c7534b79c5..906a8cf12f 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java
@@ -10,6 +10,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -32,7 +33,7 @@
 @XStreamAlias("xml")
 public class WxPayOrderQueryResult extends BaseWxPayResult {
   private static final long serialVersionUID = 8241891654782412789L;
-  
+
   /**
    * 
    * 字段名:营销详情.
@@ -290,6 +291,29 @@ public void composeCoupons() {
     }
   }
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    promotionDetail = readXMLString(d, "promotion_detail");
+    deviceInfo = readXMLString(d, "device_info");
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    tradeType = readXMLString(d, "trade_type");
+    tradeState = readXMLString(d, "trade_state");
+    bankType = readXMLString(d, "bank_type");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    feeType = readXMLString(d, "fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    couponFee = readXMLInteger(d, "coupon_fee");
+    couponCount = readXMLInteger(d, "coupon_count");
+  }
+
   /**
    * The type Coupon.
    */
@@ -338,4 +362,5 @@ public static class Coupon implements Serializable {
     private Integer couponFee;
 
   }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
index 578139929e..210e9e4aab 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -32,4 +33,14 @@ public class WxPayOrderReverseResult extends BaseWxPayResult {
   @XStreamAlias("recall")
   private String isRecall;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    isRecall = readXMLString(d, "recall");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java
index 4f05bfde68..91c6eb7f22 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java
@@ -1,12 +1,16 @@
 package com.github.binarywang.wxpay.bean.result;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 /**
  * 
@@ -223,6 +227,43 @@ public class WxPayRedpackQueryResult extends BaseWxPayResult {
   @XStreamAlias("hblist")
   private List redpackList;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    mchBillNo = readXMLString(d, "mch_billno");
+    detailId = readXMLString(d, "detail_id");
+    status = readXMLString(d, "status");
+    sendType = readXMLString(d, "send_type");
+    hbType = readXMLString(d, "hb_type");
+    totalNum = readXMLInteger(d, "total_num");
+    totalAmount = readXMLInteger(d, "total_amount");
+    sendTime = readXMLString(d, "send_time");
+    refundTime = readXMLString(d, "refund_time");
+    refundAmount = readXMLInteger(d, "refund_amount");
+    wishing = readXMLString(d, "wishing");
+    remark = readXMLString(d, "remark");
+    actName = readXMLString(d, "act_name");
+
+    NodeList nodeList = d.getElementsByTagName("hbinfo");
+    List list = new ArrayList<>(nodeList.getLength());
+
+    for (int i = 0, j = nodeList.getLength(); i < j; i++) {
+      Node node = nodeList.item(i);
+      RedpackInfo rp = new RedpackInfo();
+      rp.amount = readXMLInteger(node, "amount");
+      rp.openid = readXMLString(node, "openid");
+      rp.receiveTime = readXMLString(node, "rcv_time");
+      list.add(rp);
+    }
+
+    redpackList = list;
+
+  }
+
   /**
    * The type Redpack info.
    */
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java
index 3bc6a2b4b6..ecdf933b6b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java
@@ -9,6 +9,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -172,6 +173,23 @@ public void composeRefundRecords() {
     }
   }
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    feeType = readXMLString(d, "fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    refundCount = readXMLInteger(d, "refund_count");
+  }
+
   /**
    * The type Refund record.
    */
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java
index 9b971123aa..57fb333595 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java
@@ -8,6 +8,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -119,7 +120,7 @@ public class WxPayRefundResult extends BaseWxPayResult implements Serializable {
   /**
    * 组装生成退款代金券信息.
    */
-  private void composeRefundCoupons() {
+  public void composeRefundCoupons() {
     List coupons = Lists.newArrayList();
     Integer refundCount = this.getCouponRefundCount();
     if (refundCount == null) {
@@ -140,9 +141,27 @@ private void composeRefundCoupons() {
     this.setRefundCoupons(coupons);
   }
 
-  public static WxPayRefundResult fromXML(String xml) {
-    WxPayRefundResult result = BaseWxPayResult.fromXML(xml, WxPayRefundResult.class);
-    result.composeRefundCoupons();
-    return result;
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    outRefundNo = readXMLString(d, "out_refund_no");
+    refundId = readXMLString(d, "refund_id");
+    refundFee = readXMLInteger(d, "refund_fee");
+    settlementRefundFee = readXMLInteger(d, "settlement_refund_fee");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    feeType = readXMLString(d, "fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    cashRefundFee = readXMLInteger(d, "cash_refund_fee");
+    couponRefundCount = readXMLInteger(d, "coupon_refund_count");
+    couponRefundFee = readXMLInteger(d, "coupon_refund_fee");
   }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java
index cf3f9355db..b1af69c6b0 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -31,4 +32,14 @@ public class WxPaySandboxSignKeyResult extends BaseWxPayResult {
   @XStreamAlias("sandbox_signkey")
   private String sandboxSignKey;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    sandboxSignKey = readXMLString(d, "sandbox_signkey");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java
index bb9bfee8a1..c707fee7f1 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 import java.io.Serializable;
 
@@ -53,4 +54,13 @@ public class WxPaySendMiniProgramRedpackResult extends BaseWxPayResult implement
   @XStreamAlias("send_listid")
   private String sendListId;
 
+  @Override
+  protected void loadXML(Document d) {
+    mchBillNo = readXMLString(d, "mch_billno");
+    wxAppid = readXMLString(d, "wxappid");
+    reOpenid = readXMLString(d, "re_openid");
+    totalAmount = readXMLInteger(d, "total_amount");
+    packageName = readXMLString(d, "package");
+    sendListId = readXMLString(d, "send_listid");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java
index 2855daef79..adc6a688fc 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 import java.io.Serializable;
 
@@ -38,4 +39,19 @@ public class WxPaySendRedpackResult extends BaseWxPayResult implements Serializa
   @XStreamAlias("send_listid")
   private String sendListid;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    mchBillno = readXMLString(d, "mch_billno");
+    wxappid = readXMLString(d, "wxappid");
+    reOpenid = readXMLString(d, "re_openid");
+    totalAmount = readXMLInteger(d, "total_amount");
+    sendTime = readXMLString(d, "send_time");
+    sendListid = readXMLString(d, "send_listid");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java
index 1937004f47..b213024edc 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -31,4 +32,14 @@ public class WxPayShorturlResult extends BaseWxPayResult {
   @XStreamAlias("short_url")
   private String shortUrl;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    shortUrl = readXMLString(d, "short_url");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java
index cf97f75abc..3345f0c0fb 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -43,4 +44,17 @@ public class WxPayUnifiedOrderResult extends BaseWxPayResult {
   @XStreamAlias("code_url")
   private String codeURL;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    prepayId = readXMLString(d, "prepay_id");
+    tradeType = readXMLString(d, "trade_type");
+    mwebUrl = readXMLString(d, "mweb_url");
+    codeURL = readXMLString(d, "code_url");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
index 9f363eaf25..c0782f90d0 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
@@ -21,6 +21,7 @@
 import com.github.binarywang.wxpay.service.RedpackService;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.util.SignUtils;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import com.google.common.base.Joiner;
 import com.google.common.collect.Maps;
 import jodd.io.ZipUtil;
@@ -117,7 +118,8 @@ public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayExceptio
     }
 
     String responseContent = this.post(url, request.toXML(), true);
-    WxPayRefundResult result = WxPayRefundResult.fromXML(responseContent);
+    WxPayRefundResult result = BaseWxPayResult.fromXML(responseContent, WxPayRefundResult.class);
+    result.composeRefundCoupons();
     result.checkResult(this, request.getSignType(), true);
     return result;
   }
@@ -165,7 +167,13 @@ public WxPayOrderNotifyResult parseOrderNotifyResult(String xmlData) throws WxPa
   public WxPayRefundNotifyResult parseRefundNotifyResult(String xmlData) throws WxPayException {
     try {
       log.debug("微信支付退款异步通知参数:{}", xmlData);
-      WxPayRefundNotifyResult result = WxPayRefundNotifyResult.fromXML(xmlData, this.getConfig().getMchKey());
+      WxPayRefundNotifyResult result;
+      if (XmlConfig.fastMode) {
+        result = BaseWxPayResult.fromXML(xmlData, WxPayRefundNotifyResult.class);
+        result.decryptReqInfo(this.getConfig().getMchKey());
+      } else {
+        result = WxPayRefundNotifyResult.fromXML(xmlData, this.getConfig().getMchKey());
+      }
       log.debug("微信支付退款异步通知解析后的对象:{}", result);
       return result;
     } catch (Exception e) {
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 8490e00993..0d1962ff43 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
@@ -65,7 +65,18 @@ public static String createSign(Map params, String signKey) {
    * @return 签名字符串 string
    */
   public static String createSign(Object xmlBean, String signType, String signKey, String[] ignoredParams) {
-    return createSign(xmlBean2Map(xmlBean), signType, signKey, ignoredParams);
+    Map map = null;
+
+    if (XmlConfig.fastMode) {
+      if (xmlBean instanceof BaseWxPayRequest) {
+        map = ((BaseWxPayRequest) xmlBean).getSignParams();
+      }
+    }
+    if (map == null) {
+      map = xmlBean2Map(xmlBean);
+    }
+
+    return createSign(map, signType, signKey, ignoredParams);
   }
 
   /**
@@ -91,7 +102,7 @@ public static String createSign(Map params, String signType, Str
 
       if (shouldSign) {
         toSign.append(key).append("=").append(value).append("&");
-    }
+      }
     }
 
     toSign.append("key=").append(signKey);
@@ -104,25 +115,26 @@ public static String createSign(Map params, String signType, Str
 
   /**
    * 企业微信签名
+   *
    * @param signType md5 目前接口要求使用的加密类型
    */
-  public static String createEntSign(String actName,String mchBillNo,String mchId,String nonceStr,
-                                     String reOpenid,Integer totalAmount,String wxAppId,String signKey,
-                                     String signType){
+  public static String createEntSign(String actName, String mchBillNo, String mchId, String nonceStr,
+                                     String reOpenid, Integer totalAmount, String wxAppId, String signKey,
+                                     String signType) {
     Map sortedMap = new HashMap<>();
-    sortedMap.put("act_name",actName);
-    sortedMap.put("mch_billno",mchBillNo);
-    sortedMap.put("mch_id",mchId);
-    sortedMap.put("nonce_str",nonceStr);
-    sortedMap.put("re_openid",reOpenid);
+    sortedMap.put("act_name", actName);
+    sortedMap.put("mch_billno", mchBillNo);
+    sortedMap.put("mch_id", mchId);
+    sortedMap.put("nonce_str", nonceStr);
+    sortedMap.put("re_openid", reOpenid);
     sortedMap.put("total_amount", totalAmount + "");
-    sortedMap.put("wxappid",wxAppId);
+    sortedMap.put("wxappid", wxAppId);
 
     Map sortParams = new TreeMap<>(sortedMap);
     Set> entries = sortParams.entrySet();
     Iterator> iterator = entries.iterator();
     StringBuilder toSign = new StringBuilder();
-    while(iterator.hasNext()){
+    while (iterator.hasNext()) {
       Map.Entry entry = iterator.next();
       String key = String.valueOf(entry.getKey());
       String value = String.valueOf(entry.getValue());
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/XmlConfig.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/XmlConfig.java
new file mode 100644
index 0000000000..3cd776841d
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/XmlConfig.java
@@ -0,0 +1,23 @@
+package com.github.binarywang.wxpay.util;
+
+public class XmlConfig {
+
+  /**
+   * 是否使用快速模式
+   *
+   * 如果设置为true,将会影响下面的方法,不再使用反射的方法来进行xml转换。
+   * 1: BaseWxPayRequest的toXML方法
+   * 2: BaseWxPayResult的fromXML方法
+   * @see com.github.binarywang.wxpay.bean.request.BaseWxPayRequest#toXML
+   * @see com.github.binarywang.wxpay.bean.result.BaseWxPayResult#fromXML
+   *
+   * 启用快速模式后,将能:
+   * 1:性能提升约 10 ~ 15倍
+   * 2:可以通过 graalvm 生成native image,大大减少系统开销(CPU,RAM),加快应用启动速度(亚秒级),加快系统部署速度(脱离JRE).
+   *
+   * 参考测试案例: com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResultTest#benchmark
+   * 参考网址: https://www.graalvm.org/
+   */
+  public static boolean fastMode = false;
+
+}
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java
index a22916dea7..f79e0859f0 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java
@@ -1,5 +1,7 @@
 package com.github.binarywang.wxpay.bean.notify;
 
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.testng.*;
 import org.testng.annotations.*;
 
@@ -57,6 +59,27 @@ public void testFromXML() {
 
     Assert.assertEquals(result.getCouponList().get(0).getCouponId(), "10000");
     Assert.assertEquals(result.getCouponList().get(1).getCouponId(), "10001");
+
+    //fast mode test
+    XmlConfig.fastMode = true;
+    try {
+      result = BaseWxPayResult.fromXML(xmlString, WxPayOrderNotifyResult.class);
+
+      Assert.assertEquals(result.getCouponCount().intValue(), 2);
+      Assert.assertNotNull(result.getCouponList());
+      Assert.assertEquals(result.getCouponList().size(), 2);
+
+      Assert.assertEquals(result.getCouponList().get(0).getCouponFee().intValue(), 100);
+      Assert.assertEquals(result.getCouponList().get(1).getCouponFee().intValue(), 200);
+
+      Assert.assertEquals(result.getCouponList().get(0).getCouponType(), "CASH");
+      Assert.assertEquals(result.getCouponList().get(1).getCouponType(), "NO_CASH");
+
+      Assert.assertEquals(result.getCouponList().get(0).getCouponId(), "10000");
+      Assert.assertEquals(result.getCouponList().get(1).getCouponId(), "10001");
+    } finally {
+      XmlConfig.fastMode = false;
+    }
   }
 
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java
index ba7ed54501..963afb2618 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java
@@ -7,6 +7,8 @@
 import javax.crypto.spec.SecretKeySpec;
 import javax.inject.Inject;
 
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.apache.commons.codec.binary.Base64;
 import org.testng.annotations.*;
 
@@ -78,4 +80,50 @@ public void encodeReqInfo() throws Exception {
     cipher.init(Cipher.ENCRYPT_MODE, key);
     System.out.println(Base64.encodeBase64String(cipher.doFinal(xml.getBytes(StandardCharsets.UTF_8))));
   }
+
+  /**
+   * Test from xml.
+   * fast mode
+   *
+   * @throws WxPayException the wx pay exception
+   */
+  public void testFromXMLFastMode() throws WxPayException {
+    String xmlString = "" +
+      "SUCCESS" +
+      "" +
+      "" +
+      "" +
+      "";
+
+    String xmlDecryptedReqInfo = "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "";
+
+    XmlConfig.fastMode = true;
+    try {
+      WxPayRefundNotifyResult refundNotifyResult = BaseWxPayResult.fromXML(xmlString, WxPayRefundNotifyResult.class);
+      System.out.println(refundNotifyResult.getReqInfoString());
+
+      refundNotifyResult.loadReqInfo(xmlDecryptedReqInfo);
+      assertEquals(refundNotifyResult.getReqInfo().getRefundFee().intValue(), 15);
+      assertEquals(refundNotifyResult.getReqInfo().getRefundStatus(), "SUCCESS");
+      assertEquals(refundNotifyResult.getReqInfo().getRefundRecvAccout(), "用户零钱");
+      System.out.println(refundNotifyResult);
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+  }
+
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java
index 04853e15a2..3d77eb34ae 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java
@@ -1,5 +1,6 @@
 package com.github.binarywang.wxpay.bean.notify;
 
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.testng.annotations.*;
 
 import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
@@ -50,4 +51,38 @@ public void testFromXML() {
     assertThat(result.getSign()).isEqualTo("C380BEC2BFD727A4B6845133519F3AD6");
   }
 
+
+  /**
+   * Test from xml.
+   * fast mode.
+   */
+  @Test
+  public void testFromXMLFastMode() {
+    String xmlString = "\n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "";
+
+    XmlConfig.fastMode = true;
+    try {
+      WxScanPayNotifyResult result = BaseWxPayResult.fromXML(xmlString, WxScanPayNotifyResult.class);
+
+      assertThat(result).isNotNull();
+
+      assertThat(result.getAppid()).isEqualTo("wx8888888888888888");
+      assertThat(result.getOpenid()).isEqualTo("o8GeHuLAsgefS_80exEr1cTqekUs");
+      assertThat(result.getMchId()).isEqualTo("1900000109");
+      assertThat(result.getNonceStr()).isEqualTo("5K8264ILTKCH16CQ2502SI8ZNMTM67VS");
+      assertThat(result.getProductId()).isEqualTo("88888");
+      assertThat(result.getSign()).isEqualTo("C380BEC2BFD727A4B6845133519F3AD6");
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+  }
+
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java
index b771cbb1d5..617e2afdf4 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java
@@ -1,5 +1,6 @@
 package com.github.binarywang.wxpay.bean.result;
 
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.testng.annotations.*;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -42,8 +43,8 @@ public void testFromXML() {
       "\n" +
       "";
 
-    WxPayRedpackQueryResult orderQueryResult = WxPayRedpackQueryResult.fromXML(xmlString, WxPayRedpackQueryResult.class);
-    System.out.println(orderQueryResult);
+    WxPayRedpackQueryResult orderQueryResult = BaseWxPayResult.fromXML(xmlString, WxPayRedpackQueryResult.class);
+//    System.out.println(orderQueryResult);
     assertThat(orderQueryResult).isNotNull();
 
     assertThat(orderQueryResult.getRedpackList()).isNotEmpty();
@@ -51,4 +52,65 @@ public void testFromXML() {
     assertThat(orderQueryResult.getRedpackList().get(0).getOpenid()).isEqualTo("o3yHF0uHuckI3yE6lwWiFQBQdVDI");
     assertThat(orderQueryResult.getRedpackList().get(0).getReceiveTime()).isEqualTo("2018-01-23 13:45:31");
   }
+
+  /**
+   * Test from xml.
+   * FastMode
+   */
+  @Test
+  public void testFromXMLFastMode() {
+    XmlConfig.fastMode = true;
+    String xmlString = "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "1\n" +
+      "100\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "100\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "";
+
+    try {
+      WxPayRedpackQueryResult orderQueryResult = BaseWxPayResult.fromXML(xmlString, WxPayRedpackQueryResult.class);
+//      System.out.println(orderQueryResult);
+      assertThat(orderQueryResult).isNotNull();
+
+      assertThat(orderQueryResult.getRedpackList()).isNotEmpty();
+      assertThat(orderQueryResult.getRedpackList().get(0).getAmount()).isEqualTo(100);
+      assertThat(orderQueryResult.getRedpackList().get(0).getOpenid()).isEqualTo("o3yHF0uHuckI3yE6lwWiFQBQdVDI");
+      assertThat(orderQueryResult.getRedpackList().get(0).getReceiveTime()).isEqualTo("2018-01-23 13:45:31");
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+  }
+
+  @Test
+  void benchmark() {
+    long now = System.currentTimeMillis();
+    int loops = 10000;
+    for (int i = 0; i < loops; i++) {
+      testFromXML();
+    }
+    System.out.println(" reflect mode:\t" + (System.currentTimeMillis() - now) + " (ms) ");
+
+    now = System.currentTimeMillis();
+    for (int i = 0; i < loops; i++) {
+      testFromXMLFastMode();
+    }
+    System.out.println(" fast    mode:\t" + (System.currentTimeMillis() - now) + " (ms) ");
+  }
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java
index 730bd37a09..e03028ad42 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java
@@ -1,5 +1,6 @@
 package com.github.binarywang.wxpay.bean.result;
 
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.testng.annotations.Test;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -40,11 +41,67 @@ public void testFromXML() {
       "   2 \n" +
       "";
 
-    WxPayRefundResult result = WxPayRefundResult.fromXML(xmlString);
-
+    WxPayRefundResult result = BaseWxPayResult.fromXML(xmlString, WxPayRefundResult.class);
+    result.composeRefundCoupons();
     assertThat(result.getRefundCoupons()).isNotEmpty();
     assertThat(result.getRefundCoupons().get(0).getCouponRefundId()).isEqualTo("123");
     assertThat(result.getRefundCoupons().get(0).getCouponType()).isEqualTo("CASH");
     assertThat(result.getRefundCoupons().get(0).getCouponRefundFee()).isEqualTo(1);
   }
+
+  @Test
+  public void testFromXMLFastMode() {
+    /*
+      该xml字符串来自于官方文档示例,稍加改造,加上代金卷
+      refund_channel 是个什么鬼,官方文档只字不提
+     */
+    String xmlString = "\n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   1\n" +
+      "   1\n" +
+      "   123\n" +
+      "   1\n" +
+      "   \n" +
+      "   2 \n" +
+      "";
+    XmlConfig.fastMode = true;
+    try {
+      WxPayRefundResult result = BaseWxPayResult.fromXML(xmlString, WxPayRefundResult.class);
+      result.composeRefundCoupons();
+      assertThat(result.getRefundCoupons()).isNotEmpty();
+      assertThat(result.getRefundCoupons().get(0).getCouponRefundId()).isEqualTo("123");
+      assertThat(result.getRefundCoupons().get(0).getCouponType()).isEqualTo("CASH");
+      assertThat(result.getRefundCoupons().get(0).getCouponRefundFee()).isEqualTo(1);
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+  }
+
+  @Test
+  void benchmark() {
+    long now = System.currentTimeMillis();
+    int loops = 10000;
+    for (int i = 0; i < loops; i++) {
+      testFromXML();
+    }
+    System.out.println(" reflect mode:\t" + (System.currentTimeMillis() - now) + " (ms) ");
+
+    now = System.currentTimeMillis();
+    for (int i = 0; i < loops; i++) {
+      testFromXMLFastMode();
+    }
+    System.out.println(" fast    mode:\t" + (System.currentTimeMillis() - now) + " (ms) ");
+  }
+
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
index d6e688cf50..ab850d0b5b 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
@@ -17,6 +17,7 @@
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.testbase.ApiTestModule;
 import com.github.binarywang.wxpay.testbase.XmlWxPayConfig;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import com.google.inject.Inject;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.Logger;
@@ -566,8 +567,18 @@ public void testParseOrderNotifyResult() throws Exception {
       "   200\n" +
       "";
 
-    WxPayOrderNotifyResult result = this.payService.parseOrderNotifyResult(xmlString);
+    XmlConfig.fastMode = true;
+    WxPayOrderNotifyResult result;
+    try {
+      result = BaseWxPayResult.fromXML(xmlString, WxPayOrderNotifyResult.class);
+      System.out.println(result);
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+
+    result = this.payService.parseOrderNotifyResult(xmlString);
     System.out.println(result);
+
   }
 
   /**