diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java index 8935bc32..7c3db11f 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java @@ -1,18 +1,22 @@ package me.chanjar.weixin.common.util; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.thoughtworks.xstream.annotations.XStreamAlias; + import me.chanjar.weixin.common.annotation.Required; import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - /** *
* bean操作的一些工具类 @@ -21,6 +25,7 @@ import java.util.Map; **/ public class BeanUtils { + private static Logger log = LoggerFactory.getLogger(BeanUtils.class); /** * 检查bean里标记为@Required的field是否为空,为空则抛异常 @@ -48,41 +53,42 @@ public class BeanUtils { } if (!nullFields.isEmpty()) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("必填字段 " + nullFields + " 必须提供值").build()); + String msg = "必填字段 " + nullFields + " 必须提供值"; + log.debug(msg); + throw new WxErrorException(WxError.newBuilder().setErrorMsg(msg).build()); } } - /** - * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 - * @param bean 包含@XStreamAlias的xml bean对象 - * @return map对象 - */ - public static Map
+ * JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 + *+ * @since 2.5.0 + * @return + */ + String getTradeType(); String getToken(); @@ -112,4 +130,5 @@ public interface WxMpConfigStorage { * 是否自动刷新token */ boolean autoRefreshToken(); + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java index e874e793..61b75fbb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java @@ -20,6 +20,8 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { protected volatile String secret; protected volatile String partnerId; protected volatile String partnerKey; + protected volatile String notifyURL; + protected volatile String tradeType; protected volatile String token; protected volatile String accessToken; protected volatile String aesKey; @@ -267,8 +269,25 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { public void setPartnerKey(String partnerKey) { this.partnerKey = partnerKey; } + + + public String getNotifyURL() { + return notifyURL; + } - @Override + public void setNotifyURL(String notifyURL) { + this.notifyURL = notifyURL; + } + + public String getTradeType() { + return tradeType; + } + + public void setTradeType(String tradeType) { + this.tradeType = tradeType; + } + + @Override public File getTmpDirFile() { return this.tmpDirFile; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java index e1396afb..afe888f8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java @@ -1,7 +1,6 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.pay.WxPayJsSDKCallback; import me.chanjar.weixin.mp.bean.pay.request.WxEntPayRequest; import me.chanjar.weixin.mp.bean.pay.request.WxPayRefundRequest; import me.chanjar.weixin.mp.bean.pay.request.WxPaySendRedpackRequest; @@ -31,9 +30,8 @@ public interface WxMpPayService { * 接口地址:https://api.mch.weixin.qq.com/pay/orderquery * * - * @param transactionId 微信支付分配的商户号 + * @param transactionId 微信订单号 * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。 - * @throws WxErrorException */ WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException; @@ -50,7 +48,6 @@ public interface WxMpPayService { * * * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。 - * @throws WxErrorException */ WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxErrorException; @@ -60,7 +57,6 @@ public interface WxMpPayService { * 接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder * * @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置) - * @throws WxErrorException */ WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxErrorException; @@ -69,7 +65,6 @@ public interface WxMpPayService { * 详见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN * * @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置) - * @throws WxErrorException */ Map
- * 计算Map键值对是否和签名相符, - * 按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的 格式(即 key1=value1&key2=value2...)拼接成字符串 - *+ * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) + * + * @param xmlbean Bean需要标记有XML注解,默认使用配置中的PartnerKey进行签名 + * @return 签名字符串 + * @see #createSign(Map, String) + * @since 2.5.0 */ - boolean checkJSSDKCallbackDataSignature(Map
- * 订单支付状态回调 - * 支付结果通知(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7) - * /pre> - * - * @author ukid - */ -public class WxPayJsSDKCallback implements Serializable { - private static final long serialVersionUID = -4143804055690843641L; - private String return_code; - private String return_msg; - - private String appid; - private String mch_id; - private String device_info; - private String nonce_str; - private String sign; - private String result_code; - private String err_code; - private String err_code_des; - private String openid; - private String is_subscribe; - private String trade_type; - private String bank_type; - private String total_fee; - private String fee_type; - private String cash_fee; - private String cash_fee_type; - private String coupon_fee; - private String coupon_count; - private String coupon_batch_id_$n; - private String coupon_id_$n; - private String coupon_fee_$n; - private String transaction_id; - private String out_trade_no; - private String attach; - private String time_end; - - public String getReturn_code() { - return this.return_code; - } - - public void setReturn_code(String return_code) { - this.return_code = return_code; - } - - public String getReturn_msg() { - return this.return_msg; - } - - public void setReturn_msg(String return_msg) { - this.return_msg = return_msg; - } - - public String getAppid() { - return this.appid; - } - - public void setAppid(String appid) { - this.appid = appid; - } - - public String getMch_id() { - return this.mch_id; - } - - public void setMch_id(String mch_id) { - this.mch_id = mch_id; - } - - public String getDevice_info() { - return this.device_info; - } - - public void setDevice_info(String device_info) { - this.device_info = device_info; - } - - public String getNonce_str() { - return this.nonce_str; - } - - public void setNonce_str(String nonce_str) { - this.nonce_str = nonce_str; - } - - public String getSign() { - return this.sign; - } - - public void setSign(String sign) { - this.sign = sign; - } - - public String getResult_code() { - return this.result_code; - } - - public void setResult_code(String result_code) { - this.result_code = result_code; - } - - public String getErr_code() { - return this.err_code; - } - - public void setErr_code(String err_code) { - this.err_code = err_code; - } - - public String getErr_code_des() { - return this.err_code_des; - } - - public void setErr_code_des(String err_code_des) { - this.err_code_des = err_code_des; - } - - public String getOpenid() { - return this.openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - - public String getIs_subscribe() { - return this.is_subscribe; - } - - public void setIs_subscribe(String is_subscribe) { - this.is_subscribe = is_subscribe; - } - - public String getTrade_type() { - return this.trade_type; - } - - public void setTrade_type(String trade_type) { - this.trade_type = trade_type; - } - - public String getBank_type() { - return this.bank_type; - } - - public void setBank_type(String bank_type) { - this.bank_type = bank_type; - } - - public String getTotal_fee() { - return this.total_fee; - } - - public void setTotal_fee(String total_fee) { - this.total_fee = total_fee; - } - - public String getFee_type() { - return this.fee_type; - } - - public void setFee_type(String fee_type) { - this.fee_type = fee_type; - } - - public String getCash_fee() { - return this.cash_fee; - } - - public void setCash_fee(String cash_fee) { - this.cash_fee = cash_fee; - } - - public String getCash_fee_type() { - return this.cash_fee_type; - } - - public void setCash_fee_type(String cash_fee_type) { - this.cash_fee_type = cash_fee_type; - } - - public String getCoupon_fee() { - return this.coupon_fee; - } - - public void setCoupon_fee(String coupon_fee) { - this.coupon_fee = coupon_fee; - } - - public String getCoupon_count() { - return this.coupon_count; - } - - public void setCoupon_count(String coupon_count) { - this.coupon_count = coupon_count; - } - - public String getCoupon_batch_id_$n() { - return this.coupon_batch_id_$n; - } - - public void setCoupon_batch_id_$n(String coupon_batch_id_$n) { - this.coupon_batch_id_$n = coupon_batch_id_$n; - } - - public String getCoupon_id_$n() { - return this.coupon_id_$n; - } - - public void setCoupon_id_$n(String coupon_id_$n) { - this.coupon_id_$n = coupon_id_$n; - } - - public String getCoupon_fee_$n() { - return this.coupon_fee_$n; - } - - public void setCoupon_fee_$n(String coupon_fee_$n) { - this.coupon_fee_$n = coupon_fee_$n; - } - - public String getTransaction_id() { - return this.transaction_id; - } - - public void setTransaction_id(String transaction_id) { - this.transaction_id = transaction_id; - } - - public String getOut_trade_no() { - return this.out_trade_no; - } - - public void setOut_trade_no(String out_trade_no) { - this.out_trade_no = out_trade_no; - } - - public String getAttach() { - return this.attach; - } - - public void setAttach(String attach) { - this.attach = attach; - } - - public String getTime_end() { - return this.time_end; - } - - public void setTime_end(String time_end) { - this.time_end = time_end; - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java new file mode 100644 index 00000000..60b3f688 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java @@ -0,0 +1,64 @@ +package me.chanjar.weixin.mp.bean.pay; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.thoughtworks.xstream.annotations.XStreamAlias; + +/** + * 支付异步通知代金券详细 + */ +public class WxPayOrderNotifyCoupon implements Serializable { + /** + * @fields serialVersionUID + */ + private static final long serialVersionUID = -4165343733538156097L; + + @XStreamAlias("coupon_id") + private String couponId; + @XStreamAlias("coupon_type") + private String couponType; + @XStreamAlias("coupon_fee") + private Integer couponFee; + + public String getCouponId() { + return couponId; + } + + public void setCouponId(String couponId) { + this.couponId = couponId; + } + + public String getCouponType() { + return couponType; + } + + public void setCouponType(String couponType) { + this.couponType = couponType; + } + + public Integer getCouponFee() { + return couponFee; + } + + public void setCouponFee(Integer couponFee) { + this.couponFee = couponFee; + } + + public Map*/ - @SuppressWarnings("hiding") @XStreamAlias("mchid") private String mchId; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java index 341c3b2e..d6926d0e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java @@ -1,5 +1,7 @@ package me.chanjar.weixin.mp.bean.pay.request; +import java.math.BigDecimal; + import com.thoughtworks.xstream.annotations.XStreamAlias; import me.chanjar.weixin.common.util.ToStringUtils; @@ -71,6 +73,10 @@ public abstract class WxPayBaseRequest { return this.appid; } + /** + * 如果配置中已经设置,可以不设置值 + * @param appid + */ public void setAppid(String appid) { this.appid = appid; } @@ -79,6 +85,10 @@ public abstract class WxPayBaseRequest { return this.mchId; } + /** + * 如果配置中已经设置,可以不设置值 + * @param mchId + */ public void setMchId(String mchId) { this.mchId = mchId; } @@ -87,6 +97,10 @@ public abstract class WxPayBaseRequest { return this.nonceStr; } + /** + * 默认采用时间戳为随机字符串,可以不设置 + * @param nonceStr + */ public void setNonceStr(String nonceStr) { this.nonceStr = nonceStr; } @@ -98,6 +112,16 @@ public abstract class WxPayBaseRequest { public void setSign(String sign) { this.sign = sign; } + + /** + * 将单位为元转换为单位为分 + * + * @param yuan + * @return + */ + public static Integer yuanToFee(String yuan) { + return new BigDecimal(yuan).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue(); + } @Override public String toString() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java index 195e13b0..cf4c008f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java @@ -360,6 +360,10 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { return this.notifyURL; } + /** + * 如果配置中已经设置,可以不设置值 + * @param notifyURL + */ public void setNotifyURL(String notifyURL) { this.notifyURL = notifyURL; } @@ -368,6 +372,10 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { return this.tradeType; } + /** + * 如果配置中已经设置,可以不设置值 + * @param tradeType 交易类型 + */ public void setTradeType(String tradeType) { this.tradeType = tradeType; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java index 64310138..b719e333 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java @@ -1,6 +1,11 @@ package me.chanjar.weixin.mp.bean.pay.result; +import java.math.BigDecimal; +import java.util.Map; + import com.thoughtworks.xstream.annotations.XStreamAlias; + +import me.chanjar.weixin.common.util.BeanUtils; import me.chanjar.weixin.common.util.ToStringUtils; /** @@ -141,4 +146,17 @@ public abstract class WxPayBaseResult { public void setSign(String sign) { this.sign = sign; } + + /** + * 将单位分转换成单位圆 + * @param fee + * @return + */ + public static String feeToYuan(Integer fee) { + return new BigDecimal(Double.valueOf(fee) / 100).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(); + } + + public MaptoMap(int index) { + Map map = new HashMap<>(); + map.put("coupon_id_" + index, this.getCouponId()); + map.put("coupon_type_" + index, this.getCouponType()); + map.put("coupon_fee_" + index, this.getCouponFee() + ""); + return map; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java new file mode 100644 index 00000000..a1313ea0 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java @@ -0,0 +1,60 @@ +package me.chanjar.weixin.mp.bean.pay; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamOmitField; + +import me.chanjar.weixin.common.util.xml.XStreamInitializer; + +@XStreamAlias("xml") +public class WxPayOrderNotifyResponse { + @XStreamOmitField + private transient static final String FAIL = "FAIL"; + @XStreamOmitField + private transient static final String SUCCESS = "SUCCESS"; + + @XStreamAlias("return_code") + private String returnCode; + @XStreamAlias("return_msg") + private String returnMsg; + + public String getReturnCode() { + return returnCode; + } + + public void setReturnCode(String returnCode) { + this.returnCode = returnCode; + } + + public String getReturnMsg() { + return returnMsg; + } + + public void setReturnMsg(String returnMsg) { + this.returnMsg = returnMsg; + } + + public WxPayOrderNotifyResponse() { + super(); + } + + public WxPayOrderNotifyResponse(String returnCode, String returnMsg) { + super(); + this.returnCode = returnCode; + this.returnMsg = returnMsg; + } + + public static String fail(String msg) { + WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(FAIL, msg); + XStream xstream = XStreamInitializer.getInstance(); + xstream.autodetectAnnotations(true); + return xstream.toXML(response); + } + + public static String success(String msg) { + WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(SUCCESS, msg); + XStream xstream = XStreamInitializer.getInstance(); + xstream.autodetectAnnotations(true); + return xstream.toXML(response); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java new file mode 100644 index 00000000..bdd440b9 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java @@ -0,0 +1,130 @@ +package me.chanjar.weixin.mp.bean.pay; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.base.Function; +import com.google.common.collect.Maps; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderNotifyResult; + +public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter { + + public WxPayOrderNotifyResultConverter(Mapper mapper, ReflectionProvider reflectionProvider) { + super(mapper, reflectionProvider); + } + + @Override + @SuppressWarnings("rawtypes") + public boolean canConvert(Class type) { + return type.equals(WxPayOrderNotifyResult.class); + } + + @Override + public void marshal(Object original, HierarchicalStreamWriter writer, MarshallingContext context) { + super.marshal(original, writer, context); + WxPayOrderNotifyResult obj = (WxPayOrderNotifyResult) original; + List list = obj.getCouponList(); + if (list == null || list.size() == 0) { + return; + } + for (int i = 0; i < list.size(); i++) { + WxPayOrderNotifyCoupon coupon = list.get(i); + writer.startNode("coupon_id_" + i); + writer.setValue(coupon.getCouponId()); + writer.endNode(); + writer.startNode("coupon_type_" + i); + writer.setValue(coupon.getCouponType()); + writer.endNode(); + writer.startNode("coupon_fee_" + i); + writer.setValue(coupon.getCouponFee() + ""); + writer.endNode(); + } + } + + @Override + protected void marshallField(MarshallingContext context, Object newObj, Field field) { + if (field.getName().equals("couponList")) { + return; + } else { + super.marshallField(context, newObj, field); + } + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + WxPayOrderNotifyResult obj = new WxPayOrderNotifyResult(); + + List fields = new ArrayList<>(Arrays.asList(obj.getClass().getDeclaredFields())); + fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields())); + Map fieldMap = getFieldMap(fields); + + List coupons = new ArrayList<>(10); + while (reader.hasMoreChildren()) { + reader.moveDown(); + if (fieldMap.containsKey(reader.getNodeName())) { + Field field = fieldMap.get(reader.getNodeName()); + setFieldValue(context, obj, field); + } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_id_")) { + String id = (String) context.convertAnother(obj, String.class); + getIndex(coupons, reader.getNodeName()).setCouponId(id); + } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_type_")) { + String type = (String) context.convertAnother(obj, String.class); + getIndex(coupons, reader.getNodeName()).setCouponType(type); + } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_fee_")) { + Integer fee = (Integer) context.convertAnother(obj, Integer.class); + getIndex(coupons, reader.getNodeName()).setCouponFee(fee); + } + reader.moveUp(); + } + + obj.setCouponList(coupons); + return obj; + } + + private void setFieldValue(UnmarshallingContext context, WxPayOrderNotifyResult obj, Field field) { + Object val = context.convertAnother(obj, field.getType()); + try { + if (val != null) { + PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass()); + pd.getWriteMethod().invoke(obj, val); + } + } catch (Exception e) { + } + } + + private Map getFieldMap(List fields) { + Map fieldMap = Maps.uniqueIndex(fields, new Function () { + @Override + public String apply(Field field) { + if (field.isAnnotationPresent(XStreamAlias.class)) { + return field.getAnnotation(XStreamAlias.class).value(); + } + return field.getName(); + } + }); + return fieldMap; + } + + private WxPayOrderNotifyCoupon getIndex(List coupons, String nodeName) { + Integer index = Integer.valueOf(StringUtils.substring(nodeName, nodeName.lastIndexOf("_") + 1)); + if (index >= coupons.size() || coupons.get(index) == null) { + coupons.add(index, new WxPayOrderNotifyCoupon()); + } + return coupons.get(index); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java index 5982d3ee..df2de905 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java @@ -30,7 +30,6 @@ public class WxEntPayQueryRequest extends WxPayBaseRequest { * 微信支付分配的商户号 *
+ * 设备号 + * device_info + * 否 + * String(32) + * 013467007045764 + * 微信支付分配的终端设备号, + *+ * @fields deviceInfo + */ + @XStreamAlias("device_info") + private String deviceInfo; + + /** + *
+ * 用户标识 + * openid + * 是 + * String(128) + * wxd930ea5d5a258f4f + * 用户在商户appid下的唯一标识 + *+ * @fields openid + */ + @XStreamAlias("openid") + private String openid; + + /** + *
+ * 是否关注公众账号 + * is_subscribe + * 否 + * String(1) + * Y + * 用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效 + *+ * @fields isSubscribe + */ + @XStreamAlias("is_subscribe") + private String isSubscribe; + + + /** + *
+ * 交易类型 + * trade_type + * 是 + * String(16) + * JSAPI JSAPI、NATIVE、APP + *+ * @fields tradeType + */ + @XStreamAlias("trade_type") + private String tradeType; + + + /** + *
+ * 付款银行 + * bank_type + * 是 + * String(16) + * CMC + * 银行类型,采用字符串类型的银行标识,银行类型见银行列表 + *+ * @fields bankType + */ + @XStreamAlias("bank_type") + private String bankType; + + + /** + *
+ * 订单金额 + * total_fee + * 是 + * Int + * 100 + * 订单总金额,单位为分 + *+ * @fields totalFee + */ + @XStreamAlias("total_fee") + private Integer totalFee; + /** + *
+ * 应结订单金额 + * settlement_total_fee + * 否 + * Int + * 100 + * 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。 + *+ * @fields settlementTotalFee + */ + @XStreamAlias("settlement_total_fee") + private Integer settlementTotalFee; + /** + *
+ * 货币种类 + * fee_type + * 否 + * String(8) + * CNY + * 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 + *+ * @fields feeType + */ + @XStreamAlias("fee_type") + private String feeType; + /** + *
+ * 现金支付金额 + * cash_fee + * 是 + * Int + * 100 + * 现金支付金额订单现金支付金额,详见支付金额 + *+ * @fields cashFee + */ + @XStreamAlias("cash_fee") + private Integer cashFee; + /** + *
+ * 现金支付货币类型 + * cash_fee_type + * 否 + * String(16) + * CNY + * 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 + *+ * @fields cashFeeType + */ + @XStreamAlias("cash_fee_type") + private String cashFeeType; + /** + *
+ * 总代金券金额 + * coupon_fee + * 否 + * Int + * 10 + * 代金券金额<=订单金额,订单金额-代金券金额=现金支付金额,详见支付金额 + *+ * @fields couponFee + */ + @XStreamAlias("coupon_fee") + private Integer couponFee; + + /** + *
+ * 代金券使用数量 + * coupon_count + * 否 + * Int + * 1 + * 代金券使用数量 + */ + @XStreamAlias("coupon_count") + private Integer couponCount; + + private ListcouponList; + + + + /** + * + * 微信支付订单号 + * transaction_id + * 是 + * String(32) + * 1217752501201407033233368018 + * 微信支付订单号 + *+ * @fields transactionId + */ + @XStreamAlias("transaction_id") + private String transactionId; + + /** + *+ * 商户订单号 + * out_trade_no + * 是 + * String(32) + * 1212321211201407033568112322 + * 商户系统的订单号,与请求一致。 + *+ * @fields outTradeNo + */ + @XStreamAlias("out_trade_no") + private String outTradeNo; + /** + *+ * 商家数据包 + * attach + * 否 + * String(128) + * 123456 + * 商家数据包,原样返回 + *+ * @fields + */ + @XStreamAlias("attach") + private String attach; + /** + *+ * 支付完成时间 + * time_end + * 是 + * String(14) + * 20141030133525 + * 支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则 + *+ * @fields timeEnd + */ + @XStreamAlias("time_end") + private String timeEnd; + + + public Integer getCouponCount() { + return couponCount; + } + + public void setCouponCount(Integer couponCount) { + this.couponCount = couponCount; + } + + public ListgetCouponList() { + return couponList; + } + + public void setCouponList(List couponList) { + this.couponList = couponList; + } + + public String getDeviceInfo() { + return deviceInfo; + } + + public void setDeviceInfo(String deviceInfo) { + this.deviceInfo = deviceInfo; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getIsSubscribe() { + return isSubscribe; + } + + public void setIsSubscribe(String isSubscribe) { + this.isSubscribe = isSubscribe; + } + + public String getTradeType() { + return tradeType; + } + + public void setTradeType(String tradeType) { + this.tradeType = tradeType; + } + + public String getBankType() { + return bankType; + } + + public void setBankType(String bankType) { + this.bankType = bankType; + } + + public Integer getTotalFee() { + return totalFee; + } + + public void setTotalFee(Integer totalFee) { + this.totalFee = totalFee; + } + + public Integer getSettlementTotalFee() { + return settlementTotalFee; + } + + public void setSettlementTotalFee(Integer settlementTotalFee) { + this.settlementTotalFee = settlementTotalFee; + } + + public String getFeeType() { + return feeType; + } + + public void setFeeType(String feeType) { + this.feeType = feeType; + } + + public Integer getCashFee() { + return cashFee; + } + + public void setCashFee(Integer cashFee) { + this.cashFee = cashFee; + } + + public String getCashFeeType() { + return cashFeeType; + } + + public void setCashFeeType(String cashFeeType) { + this.cashFeeType = cashFeeType; + } + + public Integer getCouponFee() { + return couponFee; + } + + public void setCouponFee(Integer couponFee) { + this.couponFee = couponFee; + } + + public String getTransactionId() { + return transactionId; + } + + public void setTransactionId(String transactionId) { + this.transactionId = transactionId; + } + + public String getOutTradeNo() { + return outTradeNo; + } + + public void setOutTradeNo(String outTradeNo) { + this.outTradeNo = outTradeNo; + } + + public String getAttach() { + return attach; + } + + public void setAttach(String attach) { + this.attach = attach; + } + + public String getTimeEnd() { + return timeEnd; + } + + public void setTimeEnd(String timeEnd) { + this.timeEnd = timeEnd; + } + + @Override + public Map toMap(){ + Map resultMap = BeanUtils.xmlBean2Map(this); + if(this.getCouponCount() != null && this.getCouponCount() > 0){ + for (int i = 0; i < this.getCouponCount(); i++) { + WxPayOrderNotifyCoupon coupon = couponList.get(i); + resultMap.putAll(coupon.toMap(i)); + } + } + return resultMap; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/BaseBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/BaseBuilder.java index c5285d6f..3e40d178 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/BaseBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/BaseBuilder.java @@ -6,7 +6,8 @@ public class BaseBuilder { protected String msgType; protected String toUser; - public T toUser(String toUser) { + @SuppressWarnings("unchecked") + public T toUser(String toUser) { this.toUser = toUser; return (T) this; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java index e594565c..60cf675d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java @@ -8,12 +8,14 @@ public abstract class BaseBuilder { protected String fromUserName; - public BuilderType toUser(String touser) { + @SuppressWarnings("unchecked") + public BuilderType toUser(String touser) { this.toUserName = touser; return (BuilderType) this; } - public BuilderType fromUser(String fromusername) { + @SuppressWarnings("unchecked") + public BuilderType fromUser(String fromusername) { this.fromUserName = fromusername; return (BuilderType) this; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java index c40366ca..ceda65a6 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java @@ -23,7 +23,6 @@ import me.chanjar.weixin.common.util.json.WxGsonBuilder; public class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExecutor { - private File tmpDirFile; public MaterialVoiceAndImageDownloadRequestExecutor() { super(); @@ -31,7 +30,6 @@ public class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExec public MaterialVoiceAndImageDownloadRequestExecutor(File tmpDirFile) { super(); - this.tmpDirFile = tmpDirFile; } @Override