* 增加XML的快速模式,发送请求以及组装响应对象的时候,不再依赖java的反射机制。 1:提升性能 2:可以通过 graalvm 生成native image. 本次完成:全部BaseWxPayRequest的改造,部分BaseWxPayResult子类的改造。 * clean code * 标记 xmlDoc 为 transient 否则toString()方法中Gson可能会堆栈溢出 * 完成大多数BaseWxPayResult子类的改造。还有 notify.*Result下面留了两个TODO需要处理。 * toXML时遗漏了sign参数 * 使用dom4j简化了toXML,同时根据本版本构建native-image的demo已经提交: https://github.com/outersky/wx-micronaut-graal.git 供参考。 * 完成了最后两个Result的xml解析。dev1
@@ -5,6 +5,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 查询代金券信息请求对象类 | * 查询代金券信息请求对象类 | ||||
@@ -120,4 +122,15 @@ public class WxPayCouponInfoQueryRequest extends BaseWxPayRequest { | |||||
//do nothing | //do nothing | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -227,4 +228,23 @@ public class WxPayCouponInfoQueryResult extends BaseWxPayResult { | |||||
@XStreamAlias("is_partial_use") | @XStreamAlias("is_partial_use") | ||||
private String isPartialUse; | 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"); | |||||
} | |||||
} | } |
@@ -5,6 +5,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 发送代金券请求对象类 | * 发送代金券请求对象类 | ||||
@@ -132,4 +134,16 @@ public class WxPayCouponSendRequest extends BaseWxPayRequest { | |||||
protected void checkConstraints() { | protected void checkConstraints() { | ||||
//do nothing | //do nothing | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -136,4 +137,16 @@ public class WxPayCouponSendResult extends BaseWxPayResult { | |||||
@XStreamAlias("ret_msg") | @XStreamAlias("ret_msg") | ||||
private String retMsg; | 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"); | |||||
} | |||||
} | } |
@@ -5,6 +5,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 查询代金券批次请求对象类 | * 查询代金券批次请求对象类 | ||||
@@ -91,4 +93,13 @@ public class WxPayCouponStockQueryRequest extends BaseWxPayRequest { | |||||
//do nothing | //do nothing | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -6,6 +6,7 @@ import lombok.AllArgsConstructor; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -191,4 +192,20 @@ public class WxPayCouponStockQueryResult extends BaseWxPayResult { | |||||
@XStreamAlias("coupon_budget") | @XStreamAlias("coupon_budget") | ||||
private Integer couponBudget; | 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"); | |||||
} | |||||
} | } |
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -93,4 +94,17 @@ public class EntPayBankQueryResult extends BaseWxPayResult { | |||||
@XStreamAlias("reason") | @XStreamAlias("reason") | ||||
private String failReason; | 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"); | |||||
} | |||||
} | } |
@@ -10,6 +10,8 @@ import lombok.EqualsAndHashCode; | |||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 企业付款到银行卡的请求对象类 | * 企业付款到银行卡的请求对象类 | ||||
@@ -121,6 +123,16 @@ public class EntPayBankRequest extends BaseWxPayRequest { | |||||
return new String[]{"sign_type"}; | return new String[]{"sign_type"}; | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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 | @Override | ||||
protected boolean ignoreAppid() { | protected boolean ignoreAppid() { | ||||
return true; | return true; | ||||
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -48,4 +49,11 @@ public class EntPayBankResult extends BaseWxPayResult { | |||||
@XStreamAlias("cmms_amt") | @XStreamAlias("cmms_amt") | ||||
private Integer cmmsAmount; | 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"); | |||||
} | |||||
} | } |
@@ -10,6 +10,8 @@ import lombok.NoArgsConstructor; | |||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 企业付款请求对象. | * 企业付款请求对象. | ||||
@@ -55,4 +57,9 @@ public class EntPayQueryRequest extends BaseWxPayRequest { | |||||
protected String[] getIgnoredParamsForSign() { | protected String[] getIgnoredParamsForSign() { | ||||
return new String[]{"sign_type"}; | return new String[]{"sign_type"}; | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("partner_trade_no", partnerTradeNo); | |||||
} | |||||
} | } |
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -81,4 +82,17 @@ public class EntPayQueryResult extends BaseWxPayResult { | |||||
@XStreamAlias("desc") | @XStreamAlias("desc") | ||||
private String 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"); | |||||
} | |||||
} | } |
@@ -5,8 +5,11 @@ import com.github.binarywang.wxpay.exception.WxPayException; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import lombok.*; | import lombok.*; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* 红包发送记录查询请求 | * 红包发送记录查询请求 | ||||
* | |||||
* @author wuyong | * @author wuyong | ||||
* @date 2019-12-01 17:19 | * @date 2019-12-01 17:19 | ||||
*/ | */ | ||||
@@ -30,4 +33,9 @@ public class EntPayRedpackQueryRequest extends BaseWxPayRequest { | |||||
protected void checkConstraints() throws WxPayException { | protected void checkConstraints() throws WxPayException { | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("mch_billno", mchBillNo); | |||||
} | |||||
} | } |
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* 红包发送记录查询返回 | * 红包发送记录查询返回 | ||||
@@ -130,4 +131,24 @@ public class EntPayRedpackQueryResult extends BaseWxPayResult { | |||||
@XStreamAlias("sender_header_media_id") | @XStreamAlias("sender_header_media_id") | ||||
private Integer senderHeaderMediaId; | 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"); | |||||
} | |||||
} | } |
@@ -6,8 +6,11 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* 发送企业红包 | * 发送企业红包 | ||||
* | |||||
* @author wuyong | * @author wuyong | ||||
* @date 2019-12-1 | * @date 2019-12-1 | ||||
*/ | */ | ||||
@@ -144,4 +147,19 @@ public class EntPayRedpackRequest extends BaseWxPayRequest { | |||||
protected boolean isWxWorkSign() { | protected boolean isWxWorkSign() { | ||||
return true; | return true; | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -5,11 +5,13 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* 企业微信红包返回 | * 企业微信红包返回 | ||||
* | |||||
* @author wuyong | * @author wuyong | ||||
* @date 2019-12-01 11:31 | * @date 2019-12-01 11:31 | ||||
*/ | */ | ||||
@@ -77,4 +79,15 @@ public class EntPayRedpackResult extends BaseWxPayResult implements Serializable | |||||
@XStreamAlias("sender_header_media_id") | @XStreamAlias("sender_header_media_id") | ||||
private String senderHeaderMediaId; | 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"); | |||||
} | |||||
} | } |
@@ -10,6 +10,8 @@ import lombok.NoArgsConstructor; | |||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 企业付款请求对象. | * 企业付款请求对象. | ||||
@@ -195,4 +197,18 @@ public class EntPayRequest extends BaseWxPayRequest { | |||||
protected String[] getIgnoredParamsForSign() { | protected String[] getIgnoredParamsForSign() { | ||||
return new String[]{"sign_type"}; | return new String[]{"sign_type"}; | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -56,4 +57,13 @@ public class EntPayResult extends BaseWxPayResult { | |||||
@XStreamAlias("payment_time") | @XStreamAlias("payment_time") | ||||
private String paymentTime; | 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"); | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -28,4 +29,10 @@ public class GetPublicKeyResult extends BaseWxPayResult { | |||||
*/ | */ | ||||
@XStreamAlias("pub_key") | @XStreamAlias("pub_key") | ||||
private String pubKey; | private String pubKey; | ||||
@Override | |||||
protected void loadXML(Document d) { | |||||
mchId = readXMLString(d, "mch_id"); | |||||
pubKey = readXMLString(d, "pub_key"); | |||||
} | |||||
} | } |
@@ -13,7 +13,9 @@ import lombok.EqualsAndHashCode; | |||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||
import org.w3c.dom.Document; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
@@ -349,6 +351,51 @@ public class WxPayOrderNotifyResult extends BaseWxPayResult { | |||||
return resultMap; | 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 | @Override | ||||
public String toString() { | public String toString() { | ||||
return WxGsonBuilder.create().toJson(this); | return WxGsonBuilder.create().toJson(this); | ||||
@@ -19,6 +19,7 @@ import lombok.EqualsAndHashCode; | |||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -80,6 +81,45 @@ public class WxPayRefundNotifyResult extends BaseWxPayResult implements Serializ | |||||
private ReqInfo reqInfo; | 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 class WxPayRefundNotifyResult extends BaseWxPayResult implements Serializ | |||||
xstream.processAnnotations(ReqInfo.class); | xstream.processAnnotations(ReqInfo.class); | ||||
return (ReqInfo) xstream.fromXML(xmlString); | 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"); | |||||
} | |||||
} | } | ||||
} | } |
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -45,4 +46,11 @@ public class WxScanPayNotifyResult extends BaseWxPayResult { | |||||
@XStreamAlias("product_id") | @XStreamAlias("product_id") | ||||
private String productId; | private String productId; | ||||
@Override | |||||
protected void loadXML(Document d) { | |||||
openid = readXMLString(d, "openid"); | |||||
isSubscribe = readXMLString(d, "is_subscribe"); | |||||
productId = readXMLString(d, "product_id"); | |||||
} | |||||
} | } |
@@ -7,6 +7,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* @author Wang GuangXin 2019/10/23 14:02 | * @author Wang GuangXin 2019/10/23 14:02 | ||||
* @version 1.0 | * @version 1.0 | ||||
@@ -67,4 +69,11 @@ public class ProfitSharingFinishRequest extends BaseWxPayRequest { | |||||
protected void checkConstraints() throws WxPayException { | protected void checkConstraints() throws WxPayException { | ||||
this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("transaction_id", transactionId); | |||||
map.put("out_order_no", outOrderNo); | |||||
map.put("description", description); | |||||
} | |||||
} | } |
@@ -7,6 +7,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* @author Wang GuangXin 2019/10/22 15:44 | * @author Wang GuangXin 2019/10/22 15:44 | ||||
* @version 1.0 | * @version 1.0 | ||||
@@ -56,4 +58,10 @@ public class ProfitSharingQueryRequest extends BaseWxPayRequest { | |||||
public boolean ignoreAppid() { | public boolean ignoreAppid() { | ||||
return true; | return true; | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("transaction_id", transactionId); | |||||
map.put("out_order_no", outOrderNo); | |||||
} | |||||
} | } |
@@ -8,6 +8,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* @author Wang GuangXin 2019/10/22 15:51 | * @author Wang GuangXin 2019/10/22 15:51 | ||||
@@ -67,6 +68,18 @@ public class ProfitSharingQueryResult extends BaseWxPayResult { | |||||
return gson.fromJson(receivers, Receivers.class); | 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 | @Data | ||||
public class Receivers { | public class Receivers { | ||||
/** | /** | ||||
@@ -7,6 +7,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | 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 { | protected void checkConstraints() throws WxPayException { | ||||
this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("receiver", receiver); | |||||
} | |||||
} | } |
@@ -6,6 +6,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* @author Wang GuangXin 2019/10/22 14:54 | * @author Wang GuangXin 2019/10/22 14:54 | ||||
@@ -22,4 +23,9 @@ public class ProfitSharingReceiverResult extends BaseWxPayResult { | |||||
*/ | */ | ||||
@XStreamAlias("receiver") | @XStreamAlias("receiver") | ||||
private String receiver; | private String receiver; | ||||
@Override | |||||
protected void loadXML(Document d) { | |||||
receiver = readXMLString(d, "receiver"); | |||||
} | |||||
} | } |
@@ -7,6 +7,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* @author Wang GuangXin 2019/10/21 17:57 | * @author Wang GuangXin 2019/10/21 17:57 | ||||
* @version 1.0 | * @version 1.0 | ||||
@@ -81,4 +83,11 @@ public class ProfitSharingRequest extends BaseWxPayRequest { | |||||
// 目前仅支持HMAC-SHA256. | // 目前仅支持HMAC-SHA256. | ||||
this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("transaction_id", transactionId); | |||||
map.put("out_order_no", outOrderNo); | |||||
map.put("receivers", receivers); | |||||
} | |||||
} | } |
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* @author Wang GuangXin 2019/10/22 10:06 | * @author Wang GuangXin 2019/10/22 10:06 | ||||
@@ -30,4 +31,11 @@ public class ProfitSharingResult extends BaseWxPayResult { | |||||
*/ | */ | ||||
@XStreamAlias("order_id") | @XStreamAlias("order_id") | ||||
private String orderId; | 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"); | |||||
} | |||||
} | } |
@@ -8,6 +8,8 @@ import lombok.*; | |||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* @author Wang GuangXin 2019/10/23 15:32 | * @author Wang GuangXin 2019/10/23 15:32 | ||||
* @version 1.0 | * @version 1.0 | ||||
@@ -69,4 +71,11 @@ public class ProfitSharingReturnQueryRequest extends BaseWxPayRequest { | |||||
} | } | ||||
this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("order_id", orderId); | |||||
map.put("out_order_no", outOrderNo); | |||||
map.put("out_return_no", outReturnNo); | |||||
} | |||||
} | } |
@@ -8,6 +8,8 @@ import lombok.*; | |||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* @author Wang GuangXin 2019/10/23 14:27 | * @author Wang GuangXin 2019/10/23 14:27 | ||||
* @version 1.0 | * @version 1.0 | ||||
@@ -130,4 +132,15 @@ public class ProfitSharingReturnRequest extends BaseWxPayRequest { | |||||
} | } | ||||
this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | this.setSignType(WxPayConstants.SignType.HMAC_SHA256); | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -5,6 +5,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* @author Wang GuangXin 2019/10/23 14:41 | * @author Wang GuangXin 2019/10/23 14:41 | ||||
@@ -71,4 +72,19 @@ public class ProfitSharingReturnResult extends BaseWxPayResult { | |||||
*/ | */ | ||||
@XStreamAlias("finish_time") | @XStreamAlias("finish_time") | ||||
private String finishTime; | 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"); | |||||
} | |||||
} | } |
@@ -3,6 +3,7 @@ package com.github.binarywang.wxpay.bean.request; | |||||
import com.github.binarywang.wxpay.config.WxPayConfig; | import com.github.binarywang.wxpay.config.WxPayConfig; | ||||
import com.github.binarywang.wxpay.exception.WxPayException; | import com.github.binarywang.wxpay.exception.WxPayException; | ||||
import com.github.binarywang.wxpay.util.SignUtils; | import com.github.binarywang.wxpay.util.SignUtils; | ||||
import com.github.binarywang.wxpay.util.XmlConfig; | |||||
import com.thoughtworks.xstream.XStream; | import com.thoughtworks.xstream.XStream; | ||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import lombok.Data; | import lombok.Data; | ||||
@@ -12,9 +13,14 @@ import me.chanjar.weixin.common.util.BeanUtils; | |||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.dom4j.Document; | |||||
import org.dom4j.DocumentHelper; | |||||
import org.dom4j.Element; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.ALL_SIGN_TYPES; | import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.ALL_SIGN_TYPES; | ||||
@@ -202,14 +208,52 @@ public abstract class BaseWxPayRequest implements Serializable { | |||||
* @return the string | * @return the string | ||||
*/ | */ | ||||
public String toXML() { | public String toXML() { | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
//涉及到服务商模式的两个参数,在为空值时置为null,以免在请求时将空值传给微信服务器 | //涉及到服务商模式的两个参数,在为空值时置为null,以免在请求时将空值传给微信服务器 | ||||
this.setSubAppId(StringUtils.trimToNull(this.getSubAppId())); | this.setSubAppId(StringUtils.trimToNull(this.getSubAppId())); | ||||
this.setSubMchId(StringUtils.trimToNull(this.getSubMchId())); | this.setSubMchId(StringUtils.trimToNull(this.getSubMchId())); | ||||
if (XmlConfig.fastMode) { | |||||
return toFastXml(); | |||||
} | |||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(this.getClass()); | xstream.processAnnotations(this.getClass()); | ||||
return xstream.toXML(this); | return xstream.toXML(this); | ||||
} | } | ||||
/** | |||||
* 使用快速算法组装xml | |||||
* | |||||
* @return | |||||
*/ | |||||
private String toFastXml() { | |||||
try { | |||||
Document document = DocumentHelper.createDocument(); | |||||
Element root = document.addElement(xmlRootTagName()); | |||||
Map<String, String> signParams = getSignParams(); | |||||
signParams.put("sign", sign); | |||||
for (Map.Entry<String, String> 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. | * 签名时,是否忽略appid. | ||||
* | * | ||||
@@ -228,14 +272,14 @@ public abstract class BaseWxPayRequest implements Serializable { | |||||
return false; | return false; | ||||
} | } | ||||
protected boolean ignoreSubMchId(){ | |||||
protected boolean ignoreSubMchId() { | |||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* 是否是企业微信字段 | * 是否是企业微信字段 | ||||
*/ | */ | ||||
protected boolean isWxWorkSign(){ | |||||
protected boolean isWxWorkSign() { | |||||
return false; | return false; | ||||
} | } | ||||
@@ -248,6 +292,32 @@ public abstract class BaseWxPayRequest implements Serializable { | |||||
return new String[0]; | return new String[0]; | ||||
} | } | ||||
/** | |||||
* 获取签名时需要的参数. | |||||
* 注意:不含sign属性 | |||||
*/ | |||||
public Map<String, String> getSignParams() { | |||||
Map<String, String> 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<String, String> map); | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 检查参数,并设置签名. | * 检查参数,并设置签名. | ||||
@@ -3,6 +3,8 @@ package com.github.binarywang.wxpay.bean.request; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import lombok.*; | import lombok.*; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 授权码查询openid接口请求对象类 | * 授权码查询openid接口请求对象类 | ||||
@@ -35,4 +37,10 @@ public class WxPayAuthcode2OpenidRequest extends BaseWxPayRequest { | |||||
protected void checkConstraints() { | protected void checkConstraints() { | ||||
// nothing to do | // nothing to do | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("auth_code", authCode); | |||||
} | |||||
} | } |
@@ -2,6 +2,8 @@ package com.github.binarywang.wxpay.bean.request; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 支付请求默认对象类 | * 支付请求默认对象类 | ||||
@@ -21,4 +23,8 @@ public class WxPayDefaultRequest extends BaseWxPayRequest { | |||||
protected boolean ignoreAppid() { | protected boolean ignoreAppid() { | ||||
return true; | return true; | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
} | |||||
} | } |
@@ -9,6 +9,7 @@ import org.apache.commons.lang3.ArrayUtils; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -95,4 +96,13 @@ public class WxPayDownloadBillRequest extends BaseWxPayRequest { | |||||
Arrays.toString(BILL_TYPES), this.getBillType())); | Arrays.toString(BILL_TYPES), this.getBillType())); | ||||
} | } | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("device_info", deviceInfo); | |||||
map.put("bill_type", billType); | |||||
map.put("bill_date", billDate); | |||||
map.put("tar_type", tarType); | |||||
} | |||||
} | } |
@@ -9,6 +9,7 @@ import org.apache.commons.lang3.ArrayUtils; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -87,4 +88,11 @@ public class WxPayDownloadFundFlowRequest extends BaseWxPayRequest { | |||||
*/ | */ | ||||
this.setSignType(SIGN_TYPE_HMAC_SHA256); | this.setSignType(SIGN_TYPE_HMAC_SHA256); | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("bill_date", billDate); | |||||
map.put("account_type", accountType); | |||||
map.put("tar_type", tarType); | |||||
} | |||||
} | } |
@@ -4,6 +4,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 获取微信刷脸调用凭证请求对象类 | * 获取微信刷脸调用凭证请求对象类 | ||||
@@ -123,4 +125,15 @@ public class WxPayFaceAuthInfoRequest extends BaseWxPayRequest { | |||||
//do nothing | //do nothing | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -4,6 +4,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 提交刷脸支付请求对象类 | * 提交刷脸支付请求对象类 | ||||
@@ -174,4 +176,19 @@ public class WxPayFacepayRequest extends BaseWxPayRequest { | |||||
//do nothing | //do nothing | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -4,6 +4,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 提交付款码支付请求对象类 | * 提交付款码支付请求对象类 | ||||
@@ -255,4 +257,22 @@ public class WxPayMicropayRequest extends BaseWxPayRequest { | |||||
//do nothing | //do nothing | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -3,6 +3,8 @@ package com.github.binarywang.wxpay.bean.request; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import lombok.*; | import lombok.*; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 关闭订单请求对象类 | * 关闭订单请求对象类 | ||||
@@ -36,4 +38,10 @@ public class WxPayOrderCloseRequest extends BaseWxPayRequest { | |||||
protected void checkConstraints() { | protected void checkConstraints() { | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("out_trade_no", outTradeNo); | |||||
} | |||||
} | } |
@@ -5,6 +5,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 订单查询请求对象 | * 订单查询请求对象 | ||||
@@ -76,4 +78,12 @@ public class WxPayOrderQueryRequest extends BaseWxPayRequest { | |||||
throw new WxPayException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一"); | throw new WxPayException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一"); | ||||
} | } | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("version", version); | |||||
map.put("transaction_id", transactionId); | |||||
map.put("out_trade_no", outTradeNo); | |||||
} | |||||
} | } |
@@ -5,6 +5,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 撤销订单请求类 | * 撤销订单请求类 | ||||
@@ -53,4 +55,10 @@ public class WxPayOrderReverseRequest extends BaseWxPayRequest { | |||||
} | } | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("transaction_id", transactionId); | |||||
map.put("out_trade_no", outTradeNo); | |||||
} | |||||
} | } |
@@ -5,6 +5,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 拉取订单评价数据接口的请求参数封装类. | * 拉取订单评价数据接口的请求参数封装类. | ||||
@@ -84,4 +86,14 @@ public class WxPayQueryCommentRequest extends BaseWxPayRequest { | |||||
protected void checkConstraints() throws WxPayException { | protected void checkConstraints() throws WxPayException { | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("begin_time", beginTime); | |||||
map.put("end_time", endTime); | |||||
map.put("offset", offset.toString()); | |||||
if (limit != null) { | |||||
map.put("limit", limit.toString()); | |||||
} | |||||
} | |||||
} | } |
@@ -3,6 +3,8 @@ package com.github.binarywang.wxpay.bean.request; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import lombok.*; | import lombok.*; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 注释中各行对应含义: | * 注释中各行对应含义: | ||||
@@ -27,8 +29,9 @@ public class WxPayRedpackQueryRequest extends BaseWxPayRequest { | |||||
@Override | @Override | ||||
protected String[] getIgnoredParamsForSign() { | 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 | * mch_billno | ||||
@@ -55,4 +58,10 @@ public class WxPayRedpackQueryRequest extends BaseWxPayRequest { | |||||
protected void checkConstraints() { | protected void checkConstraints() { | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("mch_billno", mchBillNo); | |||||
map.put("bill_type", billType); | |||||
} | |||||
} | } |
@@ -5,6 +5,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* Created by Binary Wang on 2016-11-24. | * Created by Binary Wang on 2016-11-24. | ||||
@@ -91,4 +93,13 @@ public class WxPayRefundQueryRequest extends BaseWxPayRequest { | |||||
} | } | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -10,6 +10,7 @@ import org.apache.commons.lang3.ArrayUtils; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -165,7 +166,7 @@ public class WxPayRefundRequest extends BaseWxPayRequest { | |||||
* 类型:String(256) | * 类型:String(256) | ||||
* 示例值:https://weixin.qq.com/notify/ | * 示例值:https://weixin.qq.com/notify/ | ||||
* 描述: 异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数 | * 描述: 异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数 | ||||
如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。 | |||||
* 如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。 | |||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@XStreamAlias("notify_url") | @XStreamAlias("notify_url") | ||||
@@ -194,4 +195,19 @@ public class WxPayRefundRequest extends BaseWxPayRequest { | |||||
} | } | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -4,6 +4,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 微信支付-交易保障请求参数 | * 微信支付-交易保障请求参数 | ||||
@@ -174,4 +176,19 @@ public class WxPayReportRequest extends BaseWxPayRequest { | |||||
protected void checkConstraints() { | protected void checkConstraints() { | ||||
//do nothing | //do nothing | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -4,6 +4,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.*; | import lombok.*; | ||||
import lombok.experimental.Accessors; | import lombok.experimental.Accessors; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* 发送小程序红包请求参数对象. | * 发送小程序红包请求参数对象. | ||||
* | * | ||||
@@ -119,6 +121,21 @@ public class WxPaySendMiniProgramRedpackRequest extends BaseWxPayRequest { | |||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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 | @Override | ||||
public String getAppid() { | public String getAppid() { | ||||
return this.wxAppid; | return this.wxAppid; | ||||
@@ -3,6 +3,8 @@ package com.github.binarywang.wxpay.bean.request; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import lombok.*; | import lombok.*; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* 发送红包请求参数对象. | * 发送红包请求参数对象. | ||||
* Created by Binary Wang on 2016/9/24. | * Created by Binary Wang on 2016/9/24. | ||||
@@ -181,4 +183,18 @@ public class WxPaySendRedpackRequest extends BaseWxPayRequest { | |||||
this.wxAppid = appid; | this.wxAppid = appid; | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -3,6 +3,8 @@ package com.github.binarywang.wxpay.bean.request; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import lombok.*; | import lombok.*; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 转换短链接请求对象类 | * 转换短链接请求对象类 | ||||
@@ -35,4 +37,9 @@ public class WxPayShorturlRequest extends BaseWxPayRequest { | |||||
protected void checkConstraints() { | protected void checkConstraints() { | ||||
//do nothing | //do nothing | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> map) { | |||||
map.put("long_url", longUrl); | |||||
} | |||||
} | } |
@@ -9,6 +9,8 @@ import lombok.experimental.Accessors; | |||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 统一下单请求参数对象. | * 统一下单请求参数对象. | ||||
@@ -396,4 +398,30 @@ public class WxPayUnifiedOrderRequest extends BaseWxPayRequest { | |||||
super.checkAndSign(config); | super.checkAndSign(config); | ||||
} | } | ||||
@Override | |||||
protected void storeMap(Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -11,6 +11,7 @@ import javax.xml.xpath.XPathConstants; | |||||
import javax.xml.xpath.XPathExpressionException; | import javax.xml.xpath.XPathExpressionException; | ||||
import javax.xml.xpath.XPathFactory; | import javax.xml.xpath.XPathFactory; | ||||
import com.github.binarywang.wxpay.util.XmlConfig; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
@@ -30,6 +31,8 @@ import lombok.Data; | |||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||
import org.w3c.dom.*; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 微信支付结果共用属性类. | * 微信支付结果共用属性类. | ||||
@@ -107,8 +110,9 @@ public abstract class BaseWxPayResult implements Serializable { | |||||
/** | /** | ||||
* xml的Document对象,用于解析xml文本. | * xml的Document对象,用于解析xml文本. | ||||
* make xmlDoc transient to ensure toString() can work. | |||||
*/ | */ | ||||
private Document xmlDoc; | |||||
private transient Document xmlDoc; | |||||
/** | /** | ||||
* 将单位分转换成单位圆. | * 将单位分转换成单位圆. | ||||
@@ -129,6 +133,18 @@ public abstract class BaseWxPayResult implements Serializable { | |||||
* @return the t | * @return the t | ||||
*/ | */ | ||||
public static <T extends BaseWxPayResult> T fromXML(String xmlString, Class<T> clz) { | public static <T extends BaseWxPayResult> T fromXML(String xmlString, Class<T> 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 xstream = XStreamInitializer.getInstance(); | ||||
xstream.processAnnotations(clz); | xstream.processAnnotations(clz); | ||||
T result = (T) xstream.fromXML(xmlString); | T result = (T) xstream.fromXML(xmlString); | ||||
@@ -136,6 +152,70 @@ public abstract class BaseWxPayResult implements Serializable { | |||||
return result; | 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. | * Gets logger. | ||||
* | * | ||||
@@ -185,18 +265,19 @@ public abstract class BaseWxPayResult implements Serializable { | |||||
if (this.xmlDoc != null) { | if (this.xmlDoc != null) { | ||||
return this.xmlDoc; | return this.xmlDoc; | ||||
} | } | ||||
xmlDoc = openXML(xmlString); | |||||
return xmlDoc; | |||||
} | |||||
protected Document openXML(String content) { | |||||
try { | try { | ||||
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | ||||
factory.setExpandEntityReferences(false); | factory.setExpandEntityReferences(false); | ||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); | 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) { | } catch (Exception e) { | ||||
throw new RuntimeException("非法的xml文本内容:\n" + this.xmlString, e); | throw new RuntimeException("非法的xml文本内容:\n" + this.xmlString, e); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
@@ -205,7 +286,7 @@ public abstract class BaseWxPayResult implements Serializable { | |||||
* @param path the path | * @param path the path | ||||
* @return the xml value | * @return the xml value | ||||
*/ | */ | ||||
String getXmlValue(String... path) { | |||||
protected String getXmlValue(String... path) { | |||||
Document doc = this.getXmlDoc(); | Document doc = this.getXmlDoc(); | ||||
String expression = String.format("/%s//text()", Joiner.on("/").join(path)); | String expression = String.format("/%s//text()", Joiner.on("/").join(path)); | ||||
try { | try { | ||||
@@ -225,7 +306,7 @@ public abstract class BaseWxPayResult implements Serializable { | |||||
* @param path the path | * @param path the path | ||||
* @return the xml value as int | * @return the xml value as int | ||||
*/ | */ | ||||
Integer getXmlValueAsInt(String... path) { | |||||
protected Integer getXmlValueAsInt(String... path) { | |||||
String result = this.getXmlValue(path); | String result = this.getXmlValue(path); | ||||
if (StringUtils.isBlank(result)) { | if (StringUtils.isBlank(result)) { | ||||
return null; | return null; | ||||
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -30,4 +31,14 @@ public class WxPayAuthcode2OpenidResult extends BaseWxPayResult { | |||||
@XStreamAlias("openid") | @XStreamAlias("openid") | ||||
private String openid; | private String openid; | ||||
/** | |||||
* 从XML结构中加载额外的熟悉 | |||||
* | |||||
* @param d Document | |||||
*/ | |||||
@Override | |||||
protected void loadXML(Document d) { | |||||
openid = readXMLString(d, "openid"); | |||||
} | |||||
} | } |
@@ -1,6 +1,7 @@ | |||||
package com.github.binarywang.wxpay.bean.result; | package com.github.binarywang.wxpay.bean.result; | ||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -12,4 +13,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
*/ | */ | ||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
public class WxPayCommonResult extends BaseWxPayResult { | public class WxPayCommonResult extends BaseWxPayResult { | ||||
@Override | |||||
protected void loadXML(Document d) { | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@@ -35,4 +36,15 @@ public class WxPayFaceAuthInfoResult extends BaseWxPayResult implements Serializ | |||||
@XStreamAlias("expires_in") | @XStreamAlias("expires_in") | ||||
private String expiresIn; | private String expiresIn; | ||||
/** | |||||
* 从XML结构中加载额外的熟悉 | |||||
* | |||||
* @param d Document | |||||
*/ | |||||
@Override | |||||
protected void loadXML(Document d) { | |||||
authinfo = readXMLString(d, "authinfo"); | |||||
expiresIn = readXMLString(d, "expires_in"); | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -242,4 +243,30 @@ public class WxPayFacepayResult extends BaseWxPayResult { | |||||
@XStreamAlias("time_end") | @XStreamAlias("time_end") | ||||
private String timeEnd; | 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"); | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -215,4 +216,28 @@ public class WxPayMicropayResult extends BaseWxPayResult { | |||||
@XStreamAlias("promotion_detail") | @XStreamAlias("promotion_detail") | ||||
private String promotionDetail; | 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"); | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -25,4 +26,14 @@ public class WxPayOrderCloseResult extends BaseWxPayResult { | |||||
@XStreamAlias("result_msg") | @XStreamAlias("result_msg") | ||||
private String resultMsg; | private String resultMsg; | ||||
/** | |||||
* 从XML结构中加载额外的熟悉 | |||||
* | |||||
* @param d Document | |||||
*/ | |||||
@Override | |||||
protected void loadXML(Document d) { | |||||
resultMsg = readXMLString(d, "result_msg"); | |||||
} | |||||
} | } |
@@ -10,6 +10,7 @@ import lombok.Builder; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -32,7 +33,7 @@ import lombok.NoArgsConstructor; | |||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
public class WxPayOrderQueryResult extends BaseWxPayResult { | public class WxPayOrderQueryResult extends BaseWxPayResult { | ||||
private static final long serialVersionUID = 8241891654782412789L; | private static final long serialVersionUID = 8241891654782412789L; | ||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 字段名:营销详情. | * 字段名:营销详情. | ||||
@@ -290,6 +291,29 @@ public class WxPayOrderQueryResult extends BaseWxPayResult { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* 从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. | * The type Coupon. | ||||
*/ | */ | ||||
@@ -338,4 +362,5 @@ public class WxPayOrderQueryResult extends BaseWxPayResult { | |||||
private Integer couponFee; | private Integer couponFee; | ||||
} | } | ||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -32,4 +33,14 @@ public class WxPayOrderReverseResult extends BaseWxPayResult { | |||||
@XStreamAlias("recall") | @XStreamAlias("recall") | ||||
private String isRecall; | private String isRecall; | ||||
/** | |||||
* 从XML结构中加载额外的熟悉 | |||||
* | |||||
* @param d Document | |||||
*/ | |||||
@Override | |||||
protected void loadXML(Document d) { | |||||
isRecall = readXMLString(d, "recall"); | |||||
} | |||||
} | } |
@@ -1,12 +1,16 @@ | |||||
package com.github.binarywang.wxpay.bean.result; | package com.github.binarywang.wxpay.bean.result; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
import org.w3c.dom.Node; | |||||
import org.w3c.dom.NodeList; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -223,6 +227,43 @@ public class WxPayRedpackQueryResult extends BaseWxPayResult { | |||||
@XStreamAlias("hblist") | @XStreamAlias("hblist") | ||||
private List<RedpackInfo> redpackList; | private List<RedpackInfo> 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<RedpackInfo> 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. | * The type Redpack info. | ||||
*/ | */ | ||||
@@ -9,6 +9,7 @@ import lombok.Builder; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -172,6 +173,23 @@ public class WxPayRefundQueryResult extends BaseWxPayResult { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* 从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. | * The type Refund record. | ||||
*/ | */ | ||||
@@ -8,6 +8,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -119,7 +120,7 @@ public class WxPayRefundResult extends BaseWxPayResult implements Serializable { | |||||
/** | /** | ||||
* 组装生成退款代金券信息. | * 组装生成退款代金券信息. | ||||
*/ | */ | ||||
private void composeRefundCoupons() { | |||||
public void composeRefundCoupons() { | |||||
List<WxPayRefundCouponInfo> coupons = Lists.newArrayList(); | List<WxPayRefundCouponInfo> coupons = Lists.newArrayList(); | ||||
Integer refundCount = this.getCouponRefundCount(); | Integer refundCount = this.getCouponRefundCount(); | ||||
if (refundCount == null) { | if (refundCount == null) { | ||||
@@ -140,9 +141,27 @@ public class WxPayRefundResult extends BaseWxPayResult implements Serializable { | |||||
this.setRefundCoupons(coupons); | 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"); | |||||
} | } | ||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -31,4 +32,14 @@ public class WxPaySandboxSignKeyResult extends BaseWxPayResult { | |||||
@XStreamAlias("sandbox_signkey") | @XStreamAlias("sandbox_signkey") | ||||
private String sandboxSignKey; | private String sandboxSignKey; | ||||
/** | |||||
* 从XML结构中加载额外的熟悉 | |||||
* | |||||
* @param d Document | |||||
*/ | |||||
@Override | |||||
protected void loadXML(Document d) { | |||||
sandboxSignKey = readXMLString(d, "sandbox_signkey"); | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@@ -53,4 +54,13 @@ public class WxPaySendMiniProgramRedpackResult extends BaseWxPayResult implement | |||||
@XStreamAlias("send_listid") | @XStreamAlias("send_listid") | ||||
private String sendListId; | 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"); | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@@ -38,4 +39,19 @@ public class WxPaySendRedpackResult extends BaseWxPayResult implements Serializa | |||||
@XStreamAlias("send_listid") | @XStreamAlias("send_listid") | ||||
private String sendListid; | 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"); | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -31,4 +32,14 @@ public class WxPayShorturlResult extends BaseWxPayResult { | |||||
@XStreamAlias("short_url") | @XStreamAlias("short_url") | ||||
private String shortUrl; | private String shortUrl; | ||||
/** | |||||
* 从XML结构中加载额外的熟悉 | |||||
* | |||||
* @param d Document | |||||
*/ | |||||
@Override | |||||
protected void loadXML(Document d) { | |||||
shortUrl = readXMLString(d, "short_url"); | |||||
} | |||||
} | } |
@@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import org.w3c.dom.Document; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -43,4 +44,17 @@ public class WxPayUnifiedOrderResult extends BaseWxPayResult { | |||||
@XStreamAlias("code_url") | @XStreamAlias("code_url") | ||||
private String codeURL; | 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"); | |||||
} | |||||
} | } |
@@ -21,6 +21,7 @@ import com.github.binarywang.wxpay.service.ProfitSharingService; | |||||
import com.github.binarywang.wxpay.service.RedpackService; | import com.github.binarywang.wxpay.service.RedpackService; | ||||
import com.github.binarywang.wxpay.service.WxPayService; | import com.github.binarywang.wxpay.service.WxPayService; | ||||
import com.github.binarywang.wxpay.util.SignUtils; | import com.github.binarywang.wxpay.util.SignUtils; | ||||
import com.github.binarywang.wxpay.util.XmlConfig; | |||||
import com.google.common.base.Joiner; | import com.google.common.base.Joiner; | ||||
import com.google.common.collect.Maps; | import com.google.common.collect.Maps; | ||||
import jodd.io.ZipUtil; | import jodd.io.ZipUtil; | ||||
@@ -117,7 +118,8 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { | |||||
} | } | ||||
String responseContent = this.post(url, request.toXML(), true); | 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); | result.checkResult(this, request.getSignType(), true); | ||||
return result; | return result; | ||||
} | } | ||||
@@ -165,7 +167,13 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { | |||||
public WxPayRefundNotifyResult parseRefundNotifyResult(String xmlData) throws WxPayException { | public WxPayRefundNotifyResult parseRefundNotifyResult(String xmlData) throws WxPayException { | ||||
try { | try { | ||||
log.debug("微信支付退款异步通知参数:{}", xmlData); | 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); | log.debug("微信支付退款异步通知解析后的对象:{}", result); | ||||
return result; | return result; | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
@@ -65,7 +65,18 @@ public class SignUtils { | |||||
* @return 签名字符串 string | * @return 签名字符串 string | ||||
*/ | */ | ||||
public static String createSign(Object xmlBean, String signType, String signKey, String[] ignoredParams) { | public static String createSign(Object xmlBean, String signType, String signKey, String[] ignoredParams) { | ||||
return createSign(xmlBean2Map(xmlBean), signType, signKey, ignoredParams); | |||||
Map<String, String> 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 class SignUtils { | |||||
if (shouldSign) { | if (shouldSign) { | ||||
toSign.append(key).append("=").append(value).append("&"); | toSign.append(key).append("=").append(value).append("&"); | ||||
} | |||||
} | |||||
} | } | ||||
toSign.append("key=").append(signKey); | toSign.append("key=").append(signKey); | ||||
@@ -104,25 +115,26 @@ public class SignUtils { | |||||
/** | /** | ||||
* 企业微信签名 | * 企业微信签名 | ||||
* | |||||
* @param signType md5 目前接口要求使用的加密类型 | * @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<String, String> sortedMap = new HashMap<>(); | Map<String, String> 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("total_amount", totalAmount + ""); | ||||
sortedMap.put("wxappid",wxAppId); | |||||
sortedMap.put("wxappid", wxAppId); | |||||
Map<String, String> sortParams = new TreeMap<>(sortedMap); | Map<String, String> sortParams = new TreeMap<>(sortedMap); | ||||
Set<Map.Entry<String, String>> entries = sortParams.entrySet(); | Set<Map.Entry<String, String>> entries = sortParams.entrySet(); | ||||
Iterator<Map.Entry<String, String>> iterator = entries.iterator(); | Iterator<Map.Entry<String, String>> iterator = entries.iterator(); | ||||
StringBuilder toSign = new StringBuilder(); | StringBuilder toSign = new StringBuilder(); | ||||
while(iterator.hasNext()){ | |||||
while (iterator.hasNext()) { | |||||
Map.Entry entry = iterator.next(); | Map.Entry entry = iterator.next(); | ||||
String key = String.valueOf(entry.getKey()); | String key = String.valueOf(entry.getKey()); | ||||
String value = String.valueOf(entry.getValue()); | String value = String.valueOf(entry.getValue()); | ||||
@@ -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; | |||||
} |
@@ -1,5 +1,7 @@ | |||||
package com.github.binarywang.wxpay.bean.notify; | 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.*; | ||||
import org.testng.annotations.*; | import org.testng.annotations.*; | ||||
@@ -57,6 +59,27 @@ public class WxPayOrderNotifyResultTest { | |||||
Assert.assertEquals(result.getCouponList().get(0).getCouponId(), "10000"); | Assert.assertEquals(result.getCouponList().get(0).getCouponId(), "10000"); | ||||
Assert.assertEquals(result.getCouponList().get(1).getCouponId(), "10001"); | 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; | |||||
} | |||||
} | } | ||||
} | } |
@@ -7,6 +7,8 @@ import javax.crypto.Cipher; | |||||
import javax.crypto.spec.SecretKeySpec; | import javax.crypto.spec.SecretKeySpec; | ||||
import javax.inject.Inject; | 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.apache.commons.codec.binary.Base64; | ||||
import org.testng.annotations.*; | import org.testng.annotations.*; | ||||
@@ -78,4 +80,50 @@ public class WxPayRefundNotifyResultTest { | |||||
cipher.init(Cipher.ENCRYPT_MODE, key); | cipher.init(Cipher.ENCRYPT_MODE, key); | ||||
System.out.println(Base64.encodeBase64String(cipher.doFinal(xml.getBytes(StandardCharsets.UTF_8)))); | 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 = "<xml>" + | |||||
"<return_code>SUCCESS</return_code>" + | |||||
"<appid><![CDATA[****]]></appid>" + | |||||
"<mch_id><![CDATA[****]]></mch_id>" + | |||||
"<nonce_str><![CDATA[1ee38e38b04990449808688cf3a763b7]]></nonce_str>" + | |||||
"<req_info><![CDATA[q1QZlV5j/4I7CsJ3voq1zDgVAuzNM/Gg5JYHcpMZCLtg9KQlB6vShzsh8tgK60dU6yG2WVa0zeSDlK4B7wJCad1lUUP8Ar0Hm18M1ZEjw5vQU17wMzypRM0M9A4CcRLBezRZYzCka9CAH90E2FZ74y6VRe4DNR87t5n3DWVtSbWTBoaFUexHtNs6pyrqX77VvbilIyLZMv5ZYQYOobbQ1U3kime5He7ShEWZ0GPI3gq+z/ZOLsnIdJ5bsT4kokhq/531hSoZ5006vxRGGXnhJt8IYiG7R+oSQxZOYqYR5SKWF+0z2/g0zzM2QQlT2ynLWvBKvdVCLlgCjFN1DF4z/7IEK5FAISFP0GGF51hYw/LofL3ftlD7h7jvjOIgH5viJ0yFGmGCEFHcLKqg0DPXmzwXIrkgQSSQPsuZ6UbHUUG0L8YTRgLnl2FwNFskJIaNx0179Il6xveR1sCXbwSDGvGN78sFuQMztbnx+gFu6VYgv7C+5pFr87wHFAeuDXGTkVM6ucAwSanP7HuxSVvf7SrSrcovKslyqj869pSqn/AB0atiQ4eoq3kWaOqx87NHOV1st9SQW1SYH7SKz4jd9uhrQyDuPb6KJSg1Z2B4sU4187NjPzL4NpzZySgiYk2yXpWKhCLIz6BdZuWX79zgqxLbGxJJnhyy3tOzRWIlMkDOppGJyh8LO0LOqhXzwyrCYzPA+h2xcr7xN5WIW1IGJSZqHdURUtlemcB+yZivuzARNH0LE2MGUfuoNgZ5j1Osn7K88IrkAyKupcIEmG3ktVnPOd1A9RQ9eWbU+C7yKrl6u5ZRZOX0eElVszKfBFy4tu3XHlT7hd/zMFK5NJt8sE89k5m7M8KCGSgJ+Y90ZnUclQvDVtoR5CFkfqsP9fSpA1L+aKYsl2ESq5+fzcqsYRL3YLEhIipBKKrvg6Gy698oNeG+9oCIyuiFexJDq8ycBZ/AWiR+pFQVbNRaFbfKPR9zCW8gHwYOGnENNY9gABuuENqxxXDx9tEYkACd0H9ezLnu9psC6AuR41ACfo6wGKUA1TnpVEHsDbdvJBWDcw60l1hkmHQN2lYFy+eMusEX]]></req_info></xml>"; | |||||
String xmlDecryptedReqInfo = "<root>\n" + | |||||
"<out_refund_no><![CDATA[R4001312001201707262674894706_4]]></out_refund_no>\n" + | |||||
"<out_trade_no><![CDATA[201707260201501501005710775]]></out_trade_no>\n" + | |||||
"<refund_account><![CDATA[REFUND_SOURCE_UNSETTLED_FUNDS]]></refund_account>\n" + | |||||
"<refund_fee><![CDATA[15]]></refund_fee>\n" + | |||||
"<refund_id><![CDATA[50000203702017072601461713166]]></refund_id>\n" + | |||||
"<refund_recv_accout><![CDATA[用户零钱]]></refund_recv_accout>\n" + | |||||
"<refund_request_source><![CDATA[API]]></refund_request_source>\n" + | |||||
"<refund_status><![CDATA[SUCCESS]]></refund_status>\n" + | |||||
"<settlement_refund_fee><![CDATA[15]]></settlement_refund_fee>\n" + | |||||
"<settlement_total_fee><![CDATA[100]]></settlement_total_fee>\n" + | |||||
"<success_time><![CDATA[2017-07-26 02:45:49]]></success_time>\n" + | |||||
"<total_fee><![CDATA[100]]></total_fee>\n" + | |||||
"<transaction_id><![CDATA[4001312001201707262674894706]]></transaction_id>\n" + | |||||
"</root>"; | |||||
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; | |||||
} | |||||
} | |||||
} | } |
@@ -1,5 +1,6 @@ | |||||
package com.github.binarywang.wxpay.bean.notify; | package com.github.binarywang.wxpay.bean.notify; | ||||
import com.github.binarywang.wxpay.util.XmlConfig; | |||||
import org.testng.annotations.*; | import org.testng.annotations.*; | ||||
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; | import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; | ||||
@@ -50,4 +51,38 @@ public class WxScanPayNotifyResultTest { | |||||
assertThat(result.getSign()).isEqualTo("C380BEC2BFD727A4B6845133519F3AD6"); | assertThat(result.getSign()).isEqualTo("C380BEC2BFD727A4B6845133519F3AD6"); | ||||
} | } | ||||
/** | |||||
* Test from xml. | |||||
* fast mode. | |||||
*/ | |||||
@Test | |||||
public void testFromXMLFastMode() { | |||||
String xmlString = "<xml>\n" + | |||||
" <appid><![CDATA[wx8888888888888888]]></appid>\n" + | |||||
" <openid><![CDATA[o8GeHuLAsgefS_80exEr1cTqekUs]]></openid>\n" + | |||||
" <mch_id><![CDATA[1900000109]]></mch_id>\n" + | |||||
" <is_subscribe><![CDATA[Y]]></is_subscribe>\n" + | |||||
" <nonce_str><![CDATA[5K8264ILTKCH16CQ2502SI8ZNMTM67VS]]></nonce_str>\n" + | |||||
" <product_id><![CDATA[88888]]></product_id>\n" + | |||||
" <sign><![CDATA[C380BEC2BFD727A4B6845133519F3AD6]]></sign>\n" + | |||||
"</xml>"; | |||||
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; | |||||
} | |||||
} | |||||
} | } |
@@ -1,5 +1,6 @@ | |||||
package com.github.binarywang.wxpay.bean.result; | package com.github.binarywang.wxpay.bean.result; | ||||
import com.github.binarywang.wxpay.util.XmlConfig; | |||||
import org.testng.annotations.*; | import org.testng.annotations.*; | ||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
@@ -42,8 +43,8 @@ public class WxPayRedpackQueryResultTest { | |||||
"</hblist>\n" + | "</hblist>\n" + | ||||
"</xml>"; | "</xml>"; | ||||
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).isNotNull(); | ||||
assertThat(orderQueryResult.getRedpackList()).isNotEmpty(); | assertThat(orderQueryResult.getRedpackList()).isNotEmpty(); | ||||
@@ -51,4 +52,65 @@ public class WxPayRedpackQueryResultTest { | |||||
assertThat(orderQueryResult.getRedpackList().get(0).getOpenid()).isEqualTo("o3yHF0uHuckI3yE6lwWiFQBQdVDI"); | assertThat(orderQueryResult.getRedpackList().get(0).getOpenid()).isEqualTo("o3yHF0uHuckI3yE6lwWiFQBQdVDI"); | ||||
assertThat(orderQueryResult.getRedpackList().get(0).getReceiveTime()).isEqualTo("2018-01-23 13:45:31"); | 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 = "<xml>\n" + | |||||
"<return_code><![CDATA[SUCCESS]]></return_code>\n" + | |||||
"<return_msg><![CDATA[OK]]></return_msg>\n" + | |||||
"<result_code><![CDATA[SUCCESS]]></result_code>\n" + | |||||
"<err_code><![CDATA[SUCCESS]]></err_code>\n" + | |||||
"<err_code_des><![CDATA[OK]]></err_code_des>\n" + | |||||
"<mch_billno><![CDATA[1473919402201801230145075410]]></mch_billno>\n" + | |||||
"<mch_id><![CDATA[1497236182]]></mch_id>\n" + | |||||
"<detail_id><![CDATA[1000041701201801233000139830103]]></detail_id>\n" + | |||||
"<status><![CDATA[RECEIVED]]></status>\n" + | |||||
"<send_type><![CDATA[API]]></send_type>\n" + | |||||
"<hb_type><![CDATA[NORMAL]]></hb_type>\n" + | |||||
"<total_num>1</total_num>\n" + | |||||
"<total_amount>100</total_amount>\n" + | |||||
"<send_time><![CDATA[2018-01-23 13:45:08]]></send_time>\n" + | |||||
"<hblist>\n" + | |||||
"<hbinfo>\n" + | |||||
"<openid><![CDATA[o3yHF0uHuckI3yE6lwWiFQBQdVDI]]></openid>\n" + | |||||
"<amount>100</amount>\n" + | |||||
"<rcv_time><![CDATA[2018-01-23 13:45:31]]></rcv_time>\n" + | |||||
"</hbinfo>\n" + | |||||
"</hblist>\n" + | |||||
"</xml>"; | |||||
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) "); | |||||
} | |||||
} | } |
@@ -1,5 +1,6 @@ | |||||
package com.github.binarywang.wxpay.bean.result; | package com.github.binarywang.wxpay.bean.result; | ||||
import com.github.binarywang.wxpay.util.XmlConfig; | |||||
import org.testng.annotations.Test; | import org.testng.annotations.Test; | ||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
@@ -40,11 +41,67 @@ public class WxPayRefundResultTest { | |||||
" <refund_fee>2</refund_fee> \n" + | " <refund_fee>2</refund_fee> \n" + | ||||
"</xml>"; | "</xml>"; | ||||
WxPayRefundResult result = WxPayRefundResult.fromXML(xmlString); | |||||
WxPayRefundResult result = BaseWxPayResult.fromXML(xmlString, WxPayRefundResult.class); | |||||
result.composeRefundCoupons(); | |||||
assertThat(result.getRefundCoupons()).isNotEmpty(); | assertThat(result.getRefundCoupons()).isNotEmpty(); | ||||
assertThat(result.getRefundCoupons().get(0).getCouponRefundId()).isEqualTo("123"); | assertThat(result.getRefundCoupons().get(0).getCouponRefundId()).isEqualTo("123"); | ||||
assertThat(result.getRefundCoupons().get(0).getCouponType()).isEqualTo("CASH"); | assertThat(result.getRefundCoupons().get(0).getCouponType()).isEqualTo("CASH"); | ||||
assertThat(result.getRefundCoupons().get(0).getCouponRefundFee()).isEqualTo(1); | assertThat(result.getRefundCoupons().get(0).getCouponRefundFee()).isEqualTo(1); | ||||
} | } | ||||
@Test | |||||
public void testFromXMLFastMode() { | |||||
/* | |||||
该xml字符串来自于官方文档示例,稍加改造,加上代金卷 | |||||
refund_channel 是个什么鬼,官方文档只字不提 | |||||
*/ | |||||
String xmlString = "<xml>\n" + | |||||
" <return_code><![CDATA[SUCCESS]]></return_code>\n" + | |||||
" <return_msg><![CDATA[OK]]></return_msg>\n" + | |||||
" <appid><![CDATA[wx2421b1c4370ec43b]]></appid>\n" + | |||||
" <mch_id><![CDATA[10000100]]></mch_id>\n" + | |||||
" <nonce_str><![CDATA[NfsMFbUFpdbEhPXP]]></nonce_str>\n" + | |||||
" <sign><![CDATA[B7274EB9F8925EB93100DD2085FA56C0]]></sign>\n" + | |||||
" <result_code><![CDATA[SUCCESS]]></result_code>\n" + | |||||
" <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>\n" + | |||||
" <out_trade_no><![CDATA[1415757673]]></out_trade_no>\n" + | |||||
" <out_refund_no><![CDATA[1415701182]]></out_refund_no>\n" + | |||||
" <refund_id><![CDATA[2008450740201411110000174436]]></refund_id>\n" + | |||||
" <refund_channel><![CDATA[]]></refund_channel>\n" + | |||||
" <coupon_refund_fee>1</coupon_refund_fee>\n" + | |||||
" <coupon_refund_count>1</coupon_refund_count>\n" + | |||||
" <coupon_refund_id_0>123</coupon_refund_id_0>\n" + | |||||
" <coupon_refund_fee_0>1</coupon_refund_fee_0>\n" + | |||||
" <coupon_type_0><![CDATA[CASH]]></coupon_type_0>\n" + | |||||
" <refund_fee>2</refund_fee> \n" + | |||||
"</xml>"; | |||||
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) "); | |||||
} | |||||
} | } |
@@ -17,6 +17,7 @@ import com.github.binarywang.wxpay.exception.WxPayException; | |||||
import com.github.binarywang.wxpay.service.WxPayService; | import com.github.binarywang.wxpay.service.WxPayService; | ||||
import com.github.binarywang.wxpay.testbase.ApiTestModule; | import com.github.binarywang.wxpay.testbase.ApiTestModule; | ||||
import com.github.binarywang.wxpay.testbase.XmlWxPayConfig; | import com.github.binarywang.wxpay.testbase.XmlWxPayConfig; | ||||
import com.github.binarywang.wxpay.util.XmlConfig; | |||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
@@ -566,8 +567,18 @@ public class BaseWxPayServiceImplTest { | |||||
" <coupon_fee_1>200</coupon_fee_1>\n" + | " <coupon_fee_1>200</coupon_fee_1>\n" + | ||||
"</xml>"; | "</xml>"; | ||||
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); | System.out.println(result); | ||||
} | } | ||||
/** | /** | ||||