@@ -1,18 +1,22 @@ | |||||
package me.chanjar.weixin.common.util; | 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.Lists; | ||||
import com.google.common.collect.Maps; | import com.google.common.collect.Maps; | ||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import me.chanjar.weixin.common.annotation.Required; | import me.chanjar.weixin.common.annotation.Required; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | 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; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* bean操作的一些工具类 | * bean操作的一些工具类 | ||||
@@ -21,6 +25,7 @@ import java.util.Map; | |||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
public class BeanUtils { | public class BeanUtils { | ||||
private static Logger log = LoggerFactory.getLogger(BeanUtils.class); | |||||
/** | /** | ||||
* 检查bean里标记为@Required的field是否为空,为空则抛异常 | * 检查bean里标记为@Required的field是否为空,为空则抛异常 | ||||
@@ -48,41 +53,42 @@ public class BeanUtils { | |||||
} | } | ||||
if (!nullFields.isEmpty()) { | 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<String, String> xmlBean2Map(Object bean) { | |||||
Map<String, String> result = Maps.newHashMap(); | |||||
List<Field> fields = new ArrayList<>( Arrays.asList(bean.getClass().getDeclaredFields())); | |||||
fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); | |||||
for (Field field : fields) { | |||||
try { | |||||
boolean isAccessible = field.isAccessible(); | |||||
field.setAccessible(true); | |||||
if (field.get(bean) == null) { | |||||
field.setAccessible(isAccessible); | |||||
continue; | |||||
} | |||||
/** | |||||
* 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 | |||||
* | |||||
* @param bean 包含@XStreamAlias的xml bean对象 | |||||
* @return map对象 | |||||
*/ | |||||
public static Map<String, String> xmlBean2Map(Object bean) { | |||||
Map<String, String> result = Maps.newHashMap(); | |||||
List<Field> fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); | |||||
fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); | |||||
for (Field field : fields) { | |||||
try { | |||||
boolean isAccessible = field.isAccessible(); | |||||
field.setAccessible(true); | |||||
if (field.get(bean) == null) { | |||||
field.setAccessible(isAccessible); | |||||
continue; | |||||
} | |||||
if (field.isAnnotationPresent(XStreamAlias.class)) { | |||||
result.put(field.getAnnotation(XStreamAlias.class).value(), | |||||
field.get(bean).toString()); | |||||
} | |||||
if (field.isAnnotationPresent(XStreamAlias.class)) { | |||||
result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); | |||||
} | |||||
field.setAccessible(isAccessible); | |||||
} catch (SecurityException | IllegalArgumentException | |||||
| IllegalAccessException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
field.setAccessible(isAccessible); | |||||
} catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | |||||
return result; | |||||
} | |||||
return result; | |||||
} | |||||
} | } |
@@ -73,11 +73,17 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
"REFUND_SOURCE_UNSETTLED_FUNDS"}; | "REFUND_SOURCE_UNSETTLED_FUNDS"}; | ||||
protected final Logger log = LoggerFactory.getLogger(this.getClass()); | protected final Logger log = LoggerFactory.getLogger(this.getClass()); | ||||
private WxMpService wxMpService; | private WxMpService wxMpService; | ||||
private WxMpConfigStorage config; | |||||
private WxMpConfigStorage config = null; | |||||
public WxMpPayServiceImpl(WxMpService wxMpService) { | public WxMpPayServiceImpl(WxMpService wxMpService) { | ||||
this.wxMpService = wxMpService; | this.wxMpService = wxMpService; | ||||
this.config = wxMpService.getWxMpConfigStorage(); | |||||
} | |||||
private WxMpConfigStorage getConfig(){ | |||||
if(config == null){ | |||||
this.config = wxMpService.getWxMpConfigStorage(); | |||||
} | |||||
return this.config; | |||||
} | } | ||||
@Override | @Override | ||||
@@ -89,8 +95,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
xstream.processAnnotations(WxPayRefundRequest.class); | xstream.processAnnotations(WxPayRefundRequest.class); | ||||
xstream.processAnnotations(WxPayRefundResult.class); | xstream.processAnnotations(WxPayRefundResult.class); | ||||
request.setAppid(this.config.getAppId()); | |||||
String partnerId = this.config.getPartnerId(); | |||||
request.setAppid(getConfig().getAppId()); | |||||
String partnerId = getConfig().getPartnerId(); | |||||
request.setMchId(partnerId); | request.setMchId(partnerId); | ||||
request.setNonceStr(System.currentTimeMillis() + ""); | request.setNonceStr(System.currentTimeMillis() + ""); | ||||
request.setOpUserId(partnerId); | request.setOpUserId(partnerId); | ||||
@@ -120,8 +126,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
request.setOutRefundNo(StringUtils.trimToNull(outRefundNo)); | request.setOutRefundNo(StringUtils.trimToNull(outRefundNo)); | ||||
request.setRefundId(StringUtils.trimToNull(refundId)); | request.setRefundId(StringUtils.trimToNull(refundId)); | ||||
request.setAppid(this.config.getAppId()); | |||||
request.setMchId(this.config.getPartnerId()); | |||||
request.setAppid(getConfig().getAppId()); | |||||
request.setMchId(getConfig().getPartnerId()); | |||||
request.setNonceStr(System.currentTimeMillis() + ""); | request.setNonceStr(System.currentTimeMillis() + ""); | ||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
@@ -138,17 +144,20 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
private void checkResult(WxPayBaseResult result) throws WxErrorException { | private void checkResult(WxPayBaseResult result) throws WxErrorException { | ||||
//校验返回结果签名 | //校验返回结果签名 | ||||
if(!checkSign(result.toMap())){ | if(!checkSign(result.toMap())){ | ||||
log.debug("校验结果签名失败,参数:{}",result.toMap()); | |||||
throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("参数格式校验错误!").build()); | throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("参数格式校验错误!").build()); | ||||
} | } | ||||
//校验结果是否成功 | //校验结果是否成功 | ||||
if (!"SUCCESS".equalsIgnoreCase(result.getReturnCode()) | if (!"SUCCESS".equalsIgnoreCase(result.getReturnCode()) | ||||
|| !"SUCCESS".equalsIgnoreCase(result.getResultCode())) { | || !"SUCCESS".equalsIgnoreCase(result.getResultCode())) { | ||||
throw new WxErrorException(WxError.newBuilder().setErrorCode(-1) | |||||
.setErrorMsg("返回代码: " + result.getReturnCode() + ", 返回信息: " | |||||
+ result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: " | |||||
+ result.getErrCode() + ", 错误详情: " + result.getErrCodeDes()) | |||||
.build()); | |||||
WxError error = WxError.newBuilder().setErrorCode(-1) | |||||
.setErrorMsg("返回代码: " + result.getReturnCode() + ", 返回信息: " | |||||
+ result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: " | |||||
+ result.getErrCode() + ", 错误详情: " + result.getErrCodeDes()) | |||||
.build(); | |||||
log.debug("结果校验失败,参数:{},详细:{}",result.toMap(),error); | |||||
throw new WxErrorException(error); | |||||
} | } | ||||
} | } | ||||
@@ -157,7 +166,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
if (StringUtils.isNotBlank(request.getRefundAccount())) { | if (StringUtils.isNotBlank(request.getRefundAccount())) { | ||||
if (!ArrayUtils.contains(REFUND_ACCOUNT, request.getRefundAccount())) { | if (!ArrayUtils.contains(REFUND_ACCOUNT, request.getRefundAccount())) { | ||||
throw new IllegalArgumentException("refund_account目前必须为" + Arrays.toString(REFUND_ACCOUNT) + "其中之一"); | |||||
throw new IllegalArgumentException("refund_account目前必须为" + Arrays.toString(REFUND_ACCOUNT) + "其中之一,实际值:"+ request.getRefundAccount()); | |||||
} | } | ||||
} | } | ||||
@@ -169,10 +178,12 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException { | public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException { | ||||
try { | try { | ||||
log.trace("微信支付回调参数详细:{}", xmlData); | |||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.autodetectAnnotations(true); | |||||
xstream.processAnnotations(WxPayOrderNotifyResult.class); | |||||
xstream.registerConverter(new WxPayOrderNotifyResultConverter(xstream.getMapper(),xstream.getReflectionProvider())); | xstream.registerConverter(new WxPayOrderNotifyResultConverter(xstream.getMapper(),xstream.getReflectionProvider())); | ||||
WxPayOrderNotifyResult result = (WxPayOrderNotifyResult) xstream.fromXML(xmlData); | WxPayOrderNotifyResult result = (WxPayOrderNotifyResult) xstream.fromXML(xmlData); | ||||
log.debug("微信支付回调结果对象:{}",result); | |||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
}catch (WxErrorException e) { | }catch (WxErrorException e) { | ||||
@@ -192,8 +203,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
xstream.processAnnotations(WxPaySendRedpackRequest.class); | xstream.processAnnotations(WxPaySendRedpackRequest.class); | ||||
xstream.processAnnotations(WxPaySendRedpackResult.class); | xstream.processAnnotations(WxPaySendRedpackResult.class); | ||||
request.setWxAppid(this.config.getAppId()); | |||||
String mchId = this.config.getPartnerId(); | |||||
request.setWxAppid(getConfig().getAppId()); | |||||
String mchId = getConfig().getPartnerId(); | |||||
request.setMchId(mchId); | request.setMchId(mchId); | ||||
request.setNonceStr(System.currentTimeMillis() + ""); | request.setNonceStr(System.currentTimeMillis() + ""); | ||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
@@ -220,8 +231,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
request.setMchBillNo(mchBillNo); | request.setMchBillNo(mchBillNo); | ||||
request.setBillType("MCHT"); | request.setBillType("MCHT"); | ||||
request.setAppid(this.config.getAppId()); | |||||
String mchId = this.config.getPartnerId(); | |||||
request.setAppid(getConfig().getAppId()); | |||||
String mchId = getConfig().getPartnerId(); | |||||
request.setMchId(mchId); | request.setMchId(mchId); | ||||
request.setNonceStr(System.currentTimeMillis() + ""); | request.setNonceStr(System.currentTimeMillis() + ""); | ||||
@@ -237,7 +248,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public String createSign(Object xmlBean) { | public String createSign(Object xmlBean) { | ||||
return createSign(BeanUtils.xmlBean2Map(xmlBean),this.config.getPartnerKey()); | |||||
return createSign(BeanUtils.xmlBean2Map(xmlBean),getConfig().getPartnerKey()); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -247,7 +258,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public String createSign(Map<String, String> params) { | public String createSign(Map<String, String> params) { | ||||
return createSign(params,this.config.getPartnerKey()); | |||||
return createSign(params,getConfig().getPartnerKey()); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -268,7 +279,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public boolean checkSign(Object xmlBean) { | public boolean checkSign(Object xmlBean) { | ||||
return checkSign(BeanUtils.xmlBean2Map(xmlBean) , this.config.getPartnerKey()); | |||||
return checkSign(BeanUtils.xmlBean2Map(xmlBean) , getConfig().getPartnerKey()); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -278,7 +289,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public boolean checkSign(Map<String, String> params) { | public boolean checkSign(Map<String, String> params) { | ||||
return checkSign(params , this.config.getPartnerKey()); | |||||
return checkSign(params , getConfig().getPartnerKey()); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -302,8 +313,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); | WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); | ||||
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | ||||
request.setTransactionId(StringUtils.trimToNull(transactionId)); | request.setTransactionId(StringUtils.trimToNull(transactionId)); | ||||
request.setAppid(this.config.getAppId()); | |||||
request.setMchId(this.config.getPartnerId()); | |||||
request.setAppid(getConfig().getAppId()); | |||||
request.setMchId(getConfig().getPartnerId()); | |||||
request.setNonceStr(System.currentTimeMillis() + ""); | request.setNonceStr(System.currentTimeMillis() + ""); | ||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
@@ -328,8 +339,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); | WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); | ||||
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | ||||
request.setAppid(this.config.getAppId()); | |||||
request.setMchId(this.config.getPartnerId()); | |||||
request.setAppid(getConfig().getAppId()); | |||||
request.setMchId(getConfig().getPartnerId()); | |||||
request.setNonceStr(System.currentTimeMillis() + ""); | request.setNonceStr(System.currentTimeMillis() + ""); | ||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
@@ -345,37 +356,27 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) | public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) | ||||
throws WxErrorException { | throws WxErrorException { | ||||
checkParameters(request); | |||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.processAnnotations(WxPayUnifiedOrderRequest.class); | xstream.processAnnotations(WxPayUnifiedOrderRequest.class); | ||||
xstream.processAnnotations(WxPayUnifiedOrderResult.class); | xstream.processAnnotations(WxPayUnifiedOrderResult.class); | ||||
WxMpConfigStorage config = this.config; | |||||
request.setAppid(getConfig().getAppId()); | |||||
request.setMchId(getConfig().getPartnerId()); | |||||
request.setNotifyURL(getConfig().getNotifyURL()); | |||||
request.setTradeType(getConfig().getTradeType()); | |||||
request.setNonceStr(System.currentTimeMillis() + ""); | |||||
checkParameters(request);//校验参数 | |||||
//如果没有设置,则使用配置中默认值 | |||||
if(StringUtils.isBlank(request.getAppid())){ | |||||
request.setAppid(config.getAppId()); | |||||
} | |||||
if(StringUtils.isBlank(request.getMchId())){ | |||||
request.setMchId(config.getPartnerId()); | |||||
} | |||||
if(StringUtils.isBlank(request.getNotifyURL())){ | |||||
request.setNotifyURL(config.getNotifyURL()); | |||||
} | |||||
if(StringUtils.isBlank(request.getTradeType())){ | |||||
request.setTradeType(config.getTradeType()); | |||||
} | |||||
if(StringUtils.isBlank(request.getNonceStr())){ | |||||
request.setNonceStr(System.currentTimeMillis() + ""); | |||||
} | |||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
String url = PAY_BASE_URL + "/pay/unifiedorder"; | String url = PAY_BASE_URL + "/pay/unifiedorder"; | ||||
String xmlParam = xstream.toXML(request); | |||||
log.debug("微信统一下单接口,URL:{},参数:{}",url, xmlParam); | |||||
String responseContent = this.executeRequest(url, xstream.toXML(request)); | |||||
WxPayUnifiedOrderResult result = (WxPayUnifiedOrderResult) xstream | |||||
.fromXML(responseContent); | |||||
String responseContent = this.executeRequest(url, xmlParam); | |||||
log.debug("微信统一下单接口,URL:{},结果:{}",url, responseContent); | |||||
WxPayUnifiedOrderResult result = (WxPayUnifiedOrderResult) xstream.fromXML(responseContent); | |||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
} | } | ||||
@@ -384,7 +385,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
BeanUtils.checkRequiredFields(request); | BeanUtils.checkRequiredFields(request); | ||||
if (!ArrayUtils.contains(TRADE_TYPES, request.getTradeType())) { | if (!ArrayUtils.contains(TRADE_TYPES, request.getTradeType())) { | ||||
throw new IllegalArgumentException("trade_type目前必须为" + Arrays.toString(TRADE_TYPES) + "其中之一"); | |||||
throw new IllegalArgumentException("trade_type目前必须为" + Arrays.toString(TRADE_TYPES) + "其中之一,实际值:"+request.getTradeType()); | |||||
} | } | ||||
if ("JSAPI".equals(request.getTradeType()) && request.getOpenid() == null) { | if ("JSAPI".equals(request.getTradeType()) && request.getOpenid() == null) { | ||||
@@ -406,7 +407,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
} | } | ||||
Map<String, String> payInfo = new HashMap<>(); | Map<String, String> payInfo = new HashMap<>(); | ||||
payInfo.put("appId", this.config.getAppId()); | |||||
payInfo.put("appId", getConfig().getAppId()); | |||||
// 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 | // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 | ||||
payInfo.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); | payInfo.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); | ||||
payInfo.put("nonceStr", System.currentTimeMillis() + ""); | payInfo.put("nonceStr", System.currentTimeMillis() + ""); | ||||
@@ -427,8 +428,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
xstream.processAnnotations(WxEntPayRequest.class); | xstream.processAnnotations(WxEntPayRequest.class); | ||||
xstream.processAnnotations(WxEntPayResult.class); | xstream.processAnnotations(WxEntPayResult.class); | ||||
request.setMchAppid(this.config.getAppId()); | |||||
request.setMchId(this.config.getPartnerId()); | |||||
request.setMchAppid(getConfig().getAppId()); | |||||
request.setMchId(getConfig().getPartnerId()); | |||||
request.setNonceStr(System.currentTimeMillis() + ""); | request.setNonceStr(System.currentTimeMillis() + ""); | ||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
@@ -447,8 +448,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
xstream.processAnnotations(WxEntPayQueryResult.class); | xstream.processAnnotations(WxEntPayQueryResult.class); | ||||
WxEntPayQueryRequest request = new WxEntPayQueryRequest(); | WxEntPayQueryRequest request = new WxEntPayQueryRequest(); | ||||
request.setAppid(this.config.getAppId()); | |||||
request.setMchId(this.config.getPartnerId()); | |||||
request.setAppid(getConfig().getAppId()); | |||||
request.setMchId(getConfig().getPartnerId()); | |||||
request.setNonceStr(System.currentTimeMillis() + ""); | request.setNonceStr(System.currentTimeMillis() + ""); | ||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
@@ -13,47 +13,52 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
* 支付异步通知代金券详细 | * 支付异步通知代金券详细 | ||||
*/ | */ | ||||
public class WxPayOrderNotifyCoupon implements Serializable { | 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<String,String> toMap(int index){ | |||||
Map<String,String> 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); | |||||
} | |||||
/** | |||||
* @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<String, String> toMap(int index) { | |||||
Map<String, String> 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); | |||||
} | |||||
} | } |
@@ -1,6 +1,5 @@ | |||||
package me.chanjar.weixin.mp.bean.pay; | package me.chanjar.weixin.mp.bean.pay; | ||||
import com.thoughtworks.xstream.XStream; | import com.thoughtworks.xstream.XStream; | ||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamOmitField; | import com.thoughtworks.xstream.annotations.XStreamOmitField; | ||||
@@ -9,53 +8,53 @@ import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
public class WxPayOrderNotifyResponse { | 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); | |||||
} | |||||
@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); | |||||
} | |||||
} | } |
@@ -24,107 +24,107 @@ import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderNotifyResult; | |||||
public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter { | 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<WxPayOrderNotifyCoupon> 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<Field> fields = new ArrayList<>(Arrays.asList(obj.getClass().getDeclaredFields())); | |||||
fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields())); | |||||
Map<String, Field> fieldMap = getFieldMap(fields); | |||||
List<WxPayOrderNotifyCoupon> 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<String, Field> getFieldMap(List<Field> fields) { | |||||
Map<String, Field> fieldMap = Maps.uniqueIndex(fields, new Function<Field, String>() { | |||||
@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<WxPayOrderNotifyCoupon> 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); | |||||
} | |||||
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<WxPayOrderNotifyCoupon> 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<Field> fields = new ArrayList<>(Arrays.asList(obj.getClass().getDeclaredFields())); | |||||
fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields())); | |||||
Map<String, Field> fieldMap = getFieldMap(fields); | |||||
List<WxPayOrderNotifyCoupon> 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<String, Field> getFieldMap(List<Field> fields) { | |||||
Map<String, Field> fieldMap = Maps.uniqueIndex(fields, new Function<Field, String>() { | |||||
@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<WxPayOrderNotifyCoupon> 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); | |||||
} | |||||
} | } |
@@ -388,7 +388,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializ | |||||
@Override | @Override | ||||
public Map<String,String> toMap(){ | public Map<String,String> toMap(){ | ||||
Map<String,String> resultMap = BeanUtils.xmlBean2Map(this); | Map<String,String> resultMap = BeanUtils.xmlBean2Map(this); | ||||
if(this.getCouponCount() > 0){ | |||||
if(this.getCouponCount() != null && this.getCouponCount() > 0){ | |||||
for (int i = 0; i < this.getCouponCount(); i++) { | for (int i = 0; i < this.getCouponCount(); i++) { | ||||
WxPayOrderNotifyCoupon coupon = couponList.get(i); | WxPayOrderNotifyCoupon coupon = couponList.get(i); | ||||
resultMap.putAll(coupon.toMap(i)); | resultMap.putAll(coupon.toMap(i)); | ||||