@@ -4,6 +4,7 @@ import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | |||
import javax.net.ssl.SSLContext; | |||
import java.io.File; | |||
import java.util.concurrent.locks.Lock; | |||
@@ -81,6 +82,23 @@ public interface WxMpConfigStorage { | |||
String getPartnerId(); | |||
String getPartnerKey(); | |||
/** | |||
* 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数。 | |||
* @since 2.5.0 | |||
* @return | |||
*/ | |||
String getNotifyURL(); | |||
/** | |||
* 交易类型 | |||
* <pre> | |||
* JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 | |||
* </pre> | |||
* @since 2.5.0 | |||
* @return | |||
*/ | |||
String getTradeType(); | |||
String getToken(); | |||
@@ -112,4 +130,5 @@ public interface WxMpConfigStorage { | |||
* 是否自动刷新token | |||
*/ | |||
boolean autoRefreshToken(); | |||
} |
@@ -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; | |||
} | |||
@@ -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; | |||
@@ -107,15 +106,82 @@ public interface WxMpPayService { | |||
* 读取支付结果通知 | |||
* 详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 | |||
*/ | |||
WxPayJsSDKCallback getJSSDKCallbackData(String xmlData) throws WxErrorException; | |||
WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException; | |||
/** | |||
* 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) | |||
* | |||
* @param xmlbean Bean需要标记有XML注解,默认使用配置中的PartnerKey进行签名 | |||
* @since 2.5.0 | |||
* @return 签名字符串 | |||
* @see #createSign(Map, String) | |||
*/ | |||
String createSign(Object xmlbean); | |||
/** | |||
* 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) | |||
* @param xmlbean Bean需要标记有XML注解 | |||
* @param signKey 签名Key | |||
* @return 签名字符串 | |||
* @see #createSign(Map, String) | |||
*/ | |||
String createSign(Object xmlbean, String signKey); | |||
/** | |||
* 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) | |||
* @param prams 参数信息,默认使用配置中的PartnerKey进行签名 | |||
* @param signKey 签名Key | |||
* @return 签名字符串 | |||
* @see #createSign(Map, String) | |||
*/ | |||
String createSign(Map<String, String> prams); | |||
/** | |||
* 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) | |||
* @param prams 参数信息 | |||
* @param signKey 签名Key | |||
* @return 签名字符串 | |||
*/ | |||
String createSign(Map<String, String> prams, String signKey); | |||
/** | |||
* <pre> | |||
* 计算Map键值对是否和签名相符, | |||
* 按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的 格式(即 key1=value1&key2=value2...)拼接成字符串 | |||
* </pre> | |||
* 校验签名是否正确,默认使用配置中的PartnerKey进行签名 | |||
* @param xmlbean Bean需要标记有XML注解 | |||
* @return true - 签名校验成功,false - 签名校验失败 | |||
* @see #checkSign(Map, String) | |||
*/ | |||
boolean checkSign(Object xmlbean); | |||
/** | |||
* 校验签名是否正确 | |||
* @param xmlbean Bean需要标记有XML注解 | |||
* @param signKey 校验的签名Key | |||
* @return true - 签名校验成功,false - 签名校验失败 | |||
* @see #checkSign(Map, String) | |||
*/ | |||
boolean checkSign(Object xmlbean, String signKey); | |||
/** | |||
* 校验签名是否正确,默认使用配置中的PartnerKey进行签名 | |||
* @param prams 需要校验的参数Map | |||
* @return true - 签名校验成功,false - 签名校验失败 | |||
* @see #checkSign(Map, String) | |||
*/ | |||
boolean checkSign(Map<String, String> prams); | |||
/** | |||
* 校验签名是否正确 | |||
* @param prams 需要校验的参数Map | |||
* @param signKey 校验的签名Key | |||
* @return true - 签名校验成功,false - 签名校验失败 | |||
* @see #checkSign(Map, String) | |||
*/ | |||
boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm, String signature); | |||
boolean checkSign(Map<String, String> prams, String signKey); | |||
/** | |||
* 发送微信红包给个人用户 | |||
@@ -5,7 +5,6 @@ import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.api.WxMpMenuService; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult; | |||
import me.chanjar.weixin.mp.bean.menu.WxMpSelfMenuInfo; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
@@ -1,15 +1,17 @@ | |||
package me.chanjar.weixin.mp.api.impl; | |||
import com.thoughtworks.xstream.XStream; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.BeanUtils; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import me.chanjar.weixin.mp.api.WxMpPayService; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.pay.WxPayJsSDKCallback; | |||
import me.chanjar.weixin.mp.bean.pay.request.*; | |||
import me.chanjar.weixin.mp.bean.pay.result.*; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.IOException; | |||
import java.security.KeyStore; | |||
import java.util.Arrays; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.SortedMap; | |||
import java.util.TreeMap; | |||
import javax.net.ssl.SSLContext; | |||
import org.apache.commons.codec.digest.DigestUtils; | |||
import org.apache.commons.lang3.ArrayUtils; | |||
import org.apache.commons.lang3.StringUtils; | |||
@@ -27,12 +29,36 @@ import org.apache.http.util.EntityUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import javax.net.ssl.SSLContext; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.IOException; | |||
import java.security.KeyStore; | |||
import java.util.*; | |||
import com.thoughtworks.xstream.XStream; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.BeanUtils; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import me.chanjar.weixin.mp.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.api.WxMpPayService; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.pay.WxPayOrderNotifyResultConverter; | |||
import me.chanjar.weixin.mp.bean.pay.request.WxEntPayQueryRequest; | |||
import me.chanjar.weixin.mp.bean.pay.request.WxEntPayRequest; | |||
import me.chanjar.weixin.mp.bean.pay.request.WxPayOrderCloseRequest; | |||
import me.chanjar.weixin.mp.bean.pay.request.WxPayOrderQueryRequest; | |||
import me.chanjar.weixin.mp.bean.pay.request.WxPayRedpackQueryRequest; | |||
import me.chanjar.weixin.mp.bean.pay.request.WxPayRefundQueryRequest; | |||
import me.chanjar.weixin.mp.bean.pay.request.WxPayRefundRequest; | |||
import me.chanjar.weixin.mp.bean.pay.request.WxPaySendRedpackRequest; | |||
import me.chanjar.weixin.mp.bean.pay.request.WxPayUnifiedOrderRequest; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxEntPayQueryResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxEntPayResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxPayBaseResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderCloseResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderNotifyResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderQueryResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxPayRedpackQueryResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxPayRefundQueryResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxPayRefundResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxPaySendRedpackResult; | |||
import me.chanjar.weixin.mp.bean.pay.result.WxPayUnifiedOrderResult; | |||
/** | |||
* Created by Binary Wang on 2016/7/28. | |||
@@ -47,9 +73,11 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
"REFUND_SOURCE_UNSETTLED_FUNDS"}; | |||
protected final Logger log = LoggerFactory.getLogger(this.getClass()); | |||
private WxMpService wxMpService; | |||
private WxMpConfigStorage config; | |||
public WxMpPayServiceImpl(WxMpService wxMpService) { | |||
this.wxMpService = wxMpService; | |||
this.config = wxMpService.getWxMpConfigStorage(); | |||
} | |||
@Override | |||
@@ -61,13 +89,12 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
xstream.processAnnotations(WxPayRefundRequest.class); | |||
xstream.processAnnotations(WxPayRefundResult.class); | |||
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
String partnerId = this.wxMpService.getWxMpConfigStorage().getPartnerId(); | |||
request.setAppid(this.config.getAppId()); | |||
String partnerId = this.config.getPartnerId(); | |||
request.setMchId(partnerId); | |||
request.setNonceStr(System.currentTimeMillis() + ""); | |||
request.setOpUserId(partnerId); | |||
String sign = this.createSign(BeanUtils.xmlBean2Map(request), this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
request.setSign(sign); | |||
request.setSign(this.createSign(request)); | |||
String url = PAY_BASE_URL + "/secapi/pay/refund"; | |||
String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), partnerId); | |||
@@ -93,13 +120,10 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
request.setOutRefundNo(StringUtils.trimToNull(outRefundNo)); | |||
request.setRefundId(StringUtils.trimToNull(refundId)); | |||
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId()); | |||
request.setAppid(this.config.getAppId()); | |||
request.setMchId(this.config.getPartnerId()); | |||
request.setNonceStr(System.currentTimeMillis() + ""); | |||
String sign = this.createSign(BeanUtils.xmlBean2Map(request), | |||
this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
request.setSign(sign); | |||
request.setSign(this.createSign(request)); | |||
String url = PAY_BASE_URL + "/pay/refundquery"; | |||
@@ -109,8 +133,15 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
this.checkResult(result); | |||
return result; | |||
} | |||
private void checkResult(WxPayBaseResult result) throws WxErrorException { | |||
//校验返回结果签名 | |||
if(!checkSign(result.toMap())){ | |||
throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("参数格式校验错误!").build()); | |||
} | |||
//校验结果是否成功 | |||
if (!"SUCCESS".equalsIgnoreCase(result.getReturnCode()) | |||
|| !"SUCCESS".equalsIgnoreCase(result.getResultCode())) { | |||
throw new WxErrorException(WxError.newBuilder().setErrorCode(-1) | |||
@@ -136,23 +167,23 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
} | |||
@Override | |||
public WxPayJsSDKCallback getJSSDKCallbackData(String xmlData) throws WxErrorException { | |||
public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException { | |||
try { | |||
XStream xstream = XStreamInitializer.getInstance(); | |||
xstream.alias("xml", WxPayJsSDKCallback.class); | |||
return (WxPayJsSDKCallback) xstream.fromXML(xmlData); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
xstream.autodetectAnnotations(true); | |||
xstream.registerConverter(new WxPayOrderNotifyResultConverter(xstream.getMapper(),xstream.getReflectionProvider())); | |||
WxPayOrderNotifyResult result = (WxPayOrderNotifyResult) xstream.fromXML(xmlData); | |||
this.checkResult(result); | |||
return result; | |||
}catch (WxErrorException e) { | |||
log.error(e.getMessage(),e); | |||
throw e; | |||
}catch (Exception e) { | |||
log.error(e.getMessage(),e); | |||
throw new WxErrorException(WxError.newBuilder().setErrorMsg("发生异常" + e.getMessage()).build()); | |||
} | |||
} | |||
@Override | |||
public boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm, | |||
String signature) { | |||
return signature.equals(this.createSign(kvm, | |||
this.wxMpService.getWxMpConfigStorage().getPartnerKey())); | |||
} | |||
@Override | |||
public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile) | |||
@@ -161,14 +192,11 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
xstream.processAnnotations(WxPaySendRedpackRequest.class); | |||
xstream.processAnnotations(WxPaySendRedpackResult.class); | |||
request.setWxAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
String mchId = this.wxMpService.getWxMpConfigStorage().getPartnerId(); | |||
request.setWxAppid(this.config.getAppId()); | |||
String mchId = this.config.getPartnerId(); | |||
request.setMchId(mchId); | |||
request.setNonceStr(System.currentTimeMillis() + ""); | |||
String sign = this.createSign(BeanUtils.xmlBean2Map(request), | |||
this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
request.setSign(sign); | |||
request.setSign(this.createSign(request)); | |||
String url = PAY_BASE_URL + "/mmpaymkttransfers/sendredpack"; | |||
if (request.getAmtType() != null) { | |||
@@ -177,8 +205,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
} | |||
String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), mchId); | |||
WxPaySendRedpackResult result = (WxPaySendRedpackResult) xstream | |||
.fromXML(responseContent); | |||
WxPaySendRedpackResult result = (WxPaySendRedpackResult) xstream.fromXML(responseContent); | |||
this.checkResult(result); | |||
return result; | |||
} | |||
@@ -193,13 +220,12 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
request.setMchBillNo(mchBillNo); | |||
request.setBillType("MCHT"); | |||
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
String mchId = this.wxMpService.getWxMpConfigStorage().getPartnerId(); | |||
request.setAppid(this.config.getAppId()); | |||
String mchId = this.config.getPartnerId(); | |||
request.setMchId(mchId); | |||
request.setNonceStr(System.currentTimeMillis() + ""); | |||
String sign = this.createSign(BeanUtils.xmlBean2Map(request), | |||
this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
String sign = this.createSign(request); | |||
request.setSign(sign); | |||
String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo"; | |||
@@ -208,30 +234,59 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
this.checkResult(result); | |||
return result; | |||
} | |||
@Override | |||
public String createSign(Object xmlBean) { | |||
return createSign(BeanUtils.xmlBean2Map(xmlBean),this.config.getPartnerKey()); | |||
} | |||
@Override | |||
public String createSign(Object xmlBean, String signKey) { | |||
return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey); | |||
} | |||
@Override | |||
public String createSign(Map<String, String> params) { | |||
return createSign(params,this.config.getPartnerKey()); | |||
} | |||
/** | |||
* 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) | |||
* | |||
* @param packageParams 原始参数 | |||
* @param signKey 加密Key(即 商户Key) | |||
* @return 签名字符串 | |||
*/ | |||
private String createSign(Map<String, String> packageParams, String signKey) { | |||
SortedMap<String, String> sortedMap = new TreeMap<>(packageParams); | |||
@Override | |||
public String createSign(Map<String, String> params, String signKey) { | |||
SortedMap<String, String> sortedMap = new TreeMap<>(params); | |||
StringBuilder toSign = new StringBuilder(); | |||
for (String key : sortedMap.keySet()) { | |||
String value = packageParams.get(key); | |||
if (null != value && !"".equals(value) && !"sign".equals(key) | |||
&& !"key".equals(key)) { | |||
String value = params.get(key); | |||
if (StringUtils.isNotEmpty(value) && !"sign".equals(key) && !"key".equals(key)) { | |||
toSign.append(key + "=" + value + "&"); | |||
} | |||
} | |||
toSign.append("key=" + signKey); | |||
return DigestUtils.md5Hex(toSign.toString()).toUpperCase(); | |||
} | |||
@Override | |||
public boolean checkSign(Object xmlBean) { | |||
return checkSign(BeanUtils.xmlBean2Map(xmlBean) , this.config.getPartnerKey()); | |||
} | |||
@Override | |||
public boolean checkSign(Object xmlBean, String signKey) { | |||
return checkSign(BeanUtils.xmlBean2Map(xmlBean) , signKey); | |||
} | |||
@Override | |||
public boolean checkSign(Map<String, String> params) { | |||
return checkSign(params , this.config.getPartnerKey()); | |||
} | |||
@Override | |||
public boolean checkSign(Map<String, String> params, String signKey) { | |||
String sign = this.createSign(params , signKey); | |||
return sign.equals(params.get("sign")); | |||
} | |||
@Override | |||
public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException { | |||
@@ -247,13 +302,10 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); | |||
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | |||
request.setTransactionId(StringUtils.trimToNull(transactionId)); | |||
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId()); | |||
request.setAppid(this.config.getAppId()); | |||
request.setMchId(this.config.getPartnerId()); | |||
request.setNonceStr(System.currentTimeMillis() + ""); | |||
String sign = this.createSign(BeanUtils.xmlBean2Map(request), | |||
this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
request.setSign(sign); | |||
request.setSign(this.createSign(request)); | |||
String url = PAY_BASE_URL + "/pay/orderquery"; | |||
@@ -276,13 +328,10 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); | |||
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | |||
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId()); | |||
request.setAppid(this.config.getAppId()); | |||
request.setMchId(this.config.getPartnerId()); | |||
request.setNonceStr(System.currentTimeMillis() + ""); | |||
String sign = this.createSign(BeanUtils.xmlBean2Map(request), | |||
this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
request.setSign(sign); | |||
request.setSign(this.createSign(request)); | |||
String url = PAY_BASE_URL + "/pay/closeorder"; | |||
@@ -302,13 +351,25 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
xstream.processAnnotations(WxPayUnifiedOrderRequest.class); | |||
xstream.processAnnotations(WxPayUnifiedOrderResult.class); | |||
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId()); | |||
request.setNonceStr(System.currentTimeMillis() + ""); | |||
String sign = this.createSign(BeanUtils.xmlBean2Map(request), | |||
this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
request.setSign(sign); | |||
WxMpConfigStorage config = this.config; | |||
//如果没有设置,则使用配置中默认值 | |||
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)); | |||
String url = PAY_BASE_URL + "/pay/unifiedorder"; | |||
@@ -345,7 +406,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
} | |||
Map<String, String> payInfo = new HashMap<>(); | |||
payInfo.put("appId", this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
payInfo.put("appId", this.config.getAppId()); | |||
// 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 | |||
payInfo.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); | |||
payInfo.put("nonceStr", System.currentTimeMillis() + ""); | |||
@@ -354,9 +415,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
if ("NATIVE".equals(request.getTradeType())) { | |||
payInfo.put("codeUrl", unifiedOrderResult.getCodeURL()); | |||
} | |||
String finalSign = this.createSign(payInfo, this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
payInfo.put("paySign", finalSign); | |||
payInfo.put("paySign", this.createSign(payInfo)); | |||
return payInfo; | |||
} | |||
@@ -368,12 +427,10 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
xstream.processAnnotations(WxEntPayRequest.class); | |||
xstream.processAnnotations(WxEntPayResult.class); | |||
request.setMchAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId()); | |||
request.setMchAppid(this.config.getAppId()); | |||
request.setMchId(this.config.getPartnerId()); | |||
request.setNonceStr(System.currentTimeMillis() + ""); | |||
String sign = this.createSign(BeanUtils.xmlBean2Map(request), this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
request.setSign(sign); | |||
request.setSign(this.createSign(request)); | |||
String url = PAY_BASE_URL + "/mmpaymkttransfers/promotion/transfers"; | |||
@@ -390,12 +447,10 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
xstream.processAnnotations(WxEntPayQueryResult.class); | |||
WxEntPayQueryRequest request = new WxEntPayQueryRequest(); | |||
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId()); | |||
request.setAppid(this.config.getAppId()); | |||
request.setMchId(this.config.getPartnerId()); | |||
request.setNonceStr(System.currentTimeMillis() + ""); | |||
String sign = this.createSign(BeanUtils.xmlBean2Map(request), this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
request.setSign(sign); | |||
request.setSign(this.createSign(request)); | |||
String url = PAY_BASE_URL + "/mmpaymkttransfers/gettransferinfo"; | |||
@@ -456,5 +511,4 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg(e.getMessage()).build(), e); | |||
} | |||
} | |||
} |
@@ -62,7 +62,8 @@ public abstract class WxMpXmlOutMessage implements Serializable { | |||
this.msgType = msgType; | |||
} | |||
public String toXml() { | |||
@SuppressWarnings("unchecked") | |||
public String toXml() { | |||
return XStreamTransformer.toXml((Class<WxMpXmlOutMessage>) this.getClass(), this); | |||
} | |||
@@ -1,267 +0,0 @@ | |||
package me.chanjar.weixin.mp.bean.pay; | |||
import me.chanjar.weixin.common.util.ToStringUtils; | |||
import java.io.Serializable; | |||
/** | |||
* <pre> | |||
* 订单支付状态回调 | |||
* 支付结果通知(详见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); | |||
} | |||
} |
@@ -0,0 +1,59 @@ | |||
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<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); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
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); | |||
} | |||
} |
@@ -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<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); | |||
} | |||
} |
@@ -30,7 +30,6 @@ public class WxEntPayQueryRequest extends WxPayBaseRequest { | |||
* 微信支付分配的商户号 | |||
* </pre> | |||
*/ | |||
@SuppressWarnings("hiding") | |||
@XStreamAlias("mchid") | |||
private String mchId; | |||
@@ -71,6 +71,10 @@ public abstract class WxPayBaseRequest { | |||
return this.appid; | |||
} | |||
/** | |||
* 如果配置中已经设置,可以不设置值 | |||
* @param appid | |||
*/ | |||
public void setAppid(String appid) { | |||
this.appid = appid; | |||
} | |||
@@ -79,6 +83,10 @@ public abstract class WxPayBaseRequest { | |||
return this.mchId; | |||
} | |||
/** | |||
* 如果配置中已经设置,可以不设置值 | |||
* @param mchId | |||
*/ | |||
public void setMchId(String mchId) { | |||
this.mchId = mchId; | |||
} | |||
@@ -87,6 +95,10 @@ public abstract class WxPayBaseRequest { | |||
return this.nonceStr; | |||
} | |||
/** | |||
* 默认采用时间戳为随机字符串,可以不设置 | |||
* @param nonceStr | |||
*/ | |||
public void setNonceStr(String nonceStr) { | |||
this.nonceStr = nonceStr; | |||
} | |||
@@ -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; | |||
} | |||
@@ -1,6 +1,10 @@ | |||
package me.chanjar.weixin.mp.bean.pay.result; | |||
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 +145,8 @@ public abstract class WxPayBaseResult { | |||
public void setSign(String sign) { | |||
this.sign = sign; | |||
} | |||
public Map<String,String> toMap(){ | |||
return BeanUtils.xmlBean2Map(this); | |||
} | |||
} |
@@ -0,0 +1,414 @@ | |||
package me.chanjar.weixin.mp.bean.pay.result; | |||
import java.io.Serializable; | |||
import java.math.BigDecimal; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import me.chanjar.weixin.common.util.BeanUtils; | |||
import me.chanjar.weixin.mp.bean.pay.WxPayOrderNotifyCoupon; | |||
/** | |||
* 支付结果通用通知 ,文档见:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 | |||
* @author aimilin6688 | |||
* @since 2.5.0 | |||
*/ | |||
@XStreamAlias("xml") | |||
public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializable { | |||
/** | |||
* @fields serialVersionUID | |||
*/ | |||
private static final long serialVersionUID = 5389718115223345496L; | |||
/** | |||
* <pre> | |||
* 设备号 | |||
* device_info | |||
* 否 | |||
* String(32) | |||
* 013467007045764 | |||
* 微信支付分配的终端设备号, | |||
* </pre> | |||
* @fields deviceInfo | |||
*/ | |||
@XStreamAlias("device_info") | |||
private String deviceInfo; | |||
/** | |||
* <pre> | |||
* 用户标识 | |||
* openid | |||
* 是 | |||
* String(128) | |||
* wxd930ea5d5a258f4f | |||
* 用户在商户appid下的唯一标识 | |||
* </pre> | |||
* @fields openid | |||
*/ | |||
@XStreamAlias("openid") | |||
private String openid; | |||
/** | |||
* <pre> | |||
* 是否关注公众账号 | |||
* is_subscribe | |||
* 否 | |||
* String(1) | |||
* Y | |||
* 用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效 | |||
* </pre> | |||
* @fields isSubscribe | |||
*/ | |||
@XStreamAlias("is_subscribe") | |||
private String isSubscribe; | |||
/** | |||
* <pre> | |||
* 交易类型 | |||
* trade_type | |||
* 是 | |||
* String(16) | |||
* JSAPI JSAPI、NATIVE、APP | |||
* </pre> | |||
* @fields tradeType | |||
*/ | |||
@XStreamAlias("trade_type") | |||
private String tradeType; | |||
/** | |||
* <pre> | |||
* 付款银行 | |||
* bank_type | |||
* 是 | |||
* String(16) | |||
* CMC | |||
* 银行类型,采用字符串类型的银行标识,银行类型见银行列表 | |||
* </pre> | |||
* @fields bankType | |||
*/ | |||
@XStreamAlias("bank_type") | |||
private String bankType; | |||
/** | |||
* <pre> | |||
* 订单金额 | |||
* total_fee | |||
* 是 | |||
* Int | |||
* 100 | |||
* 订单总金额,单位为分 | |||
* </pre> | |||
* @fields totalFee | |||
*/ | |||
@XStreamAlias("total_fee") | |||
private Integer totalFee; | |||
/** | |||
* <pre> | |||
* 应结订单金额 | |||
* settlement_total_fee | |||
* 否 | |||
* Int | |||
* 100 | |||
* 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。 | |||
* </pre> | |||
* @fields settlementTotalFee | |||
*/ | |||
@XStreamAlias("settlement_total_fee") | |||
private Integer settlementTotalFee; | |||
/** | |||
* <pre> | |||
* 货币种类 | |||
* fee_type | |||
* 否 | |||
* String(8) | |||
* CNY | |||
* 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 | |||
* </pre> | |||
* @fields feeType | |||
*/ | |||
@XStreamAlias("fee_type") | |||
private String feeType; | |||
/** | |||
* <pre> | |||
* 现金支付金额 | |||
* cash_fee | |||
* 是 | |||
* Int | |||
* 100 | |||
* 现金支付金额订单现金支付金额,详见支付金额 | |||
* </pre> | |||
* @fields cashFee | |||
*/ | |||
@XStreamAlias("cash_fee") | |||
private Integer cashFee; | |||
/** | |||
* <pre> | |||
* 现金支付货币类型 | |||
* cash_fee_type | |||
* 否 | |||
* String(16) | |||
* CNY | |||
* 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 | |||
* </pre> | |||
* @fields cashFeeType | |||
*/ | |||
@XStreamAlias("cash_fee_type") | |||
private String cashFeeType; | |||
/** | |||
* <pre> | |||
* 总代金券金额 | |||
* coupon_fee | |||
* 否 | |||
* Int | |||
* 10 | |||
* 代金券金额<=订单金额,订单金额-代金券金额=现金支付金额,详见支付金额 | |||
* </pre> | |||
* @fields couponFee | |||
*/ | |||
@XStreamAlias("coupon_fee") | |||
private Integer couponFee; | |||
/** | |||
* <pre> | |||
* 代金券使用数量 | |||
* coupon_count | |||
* 否 | |||
* Int | |||
* 1 | |||
* 代金券使用数量 | |||
*/ | |||
@XStreamAlias("coupon_count") | |||
private Integer couponCount; | |||
private List<WxPayOrderNotifyCoupon> couponList; | |||
/** | |||
* <pre> | |||
* 微信支付订单号 | |||
* transaction_id | |||
* 是 | |||
* String(32) | |||
* 1217752501201407033233368018 | |||
* 微信支付订单号 | |||
* </pre> | |||
* @fields transactionId | |||
*/ | |||
@XStreamAlias("transaction_id") | |||
private String transactionId; | |||
/** | |||
* <pre> | |||
* 商户订单号 | |||
* out_trade_no | |||
* 是 | |||
* String(32) | |||
* 1212321211201407033568112322 | |||
* 商户系统的订单号,与请求一致。 | |||
* </pre> | |||
* @fields outTradeNo | |||
*/ | |||
@XStreamAlias("out_trade_no") | |||
private String outTradeNo; | |||
/** | |||
* <pre> | |||
* 商家数据包 | |||
* attach | |||
* 否 | |||
* String(128) | |||
* 123456 | |||
* 商家数据包,原样返回 | |||
* </pre> | |||
* @fields | |||
*/ | |||
@XStreamAlias("attach") | |||
private String attach; | |||
/** | |||
* <pre> | |||
* 支付完成时间 | |||
* time_end | |||
* 是 | |||
* String(14) | |||
* 20141030133525 | |||
* 支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则 | |||
* </pre> | |||
* @fields timeEnd | |||
*/ | |||
@XStreamAlias("time_end") | |||
private String timeEnd; | |||
public Integer getCouponCount() { | |||
return couponCount; | |||
} | |||
public void setCouponCount(Integer couponCount) { | |||
this.couponCount = couponCount; | |||
} | |||
public List<WxPayOrderNotifyCoupon> getCouponList() { | |||
return couponList; | |||
} | |||
public void setCouponList(List<WxPayOrderNotifyCoupon> 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<String,String> toMap(){ | |||
Map<String,String> resultMap = BeanUtils.xmlBean2Map(this); | |||
if(this.getCouponCount() > 0){ | |||
for (int i = 0; i < this.getCouponCount(); i++) { | |||
WxPayOrderNotifyCoupon coupon = couponList.get(i); | |||
resultMap.putAll(coupon.toMap(i)); | |||
} | |||
} | |||
return resultMap; | |||
} | |||
/** | |||
* 将单位分转换成单位圆 | |||
* @param fee | |||
* @return | |||
*/ | |||
public static String feeToYuan(Integer fee) { | |||
return new BigDecimal(Double.valueOf(fee) / 100).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(); | |||
} | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE); | |||
} | |||
} |
@@ -6,7 +6,8 @@ public class BaseBuilder<T> { | |||
protected String msgType; | |||
protected String toUser; | |||
public T toUser(String toUser) { | |||
@SuppressWarnings("unchecked") | |||
public T toUser(String toUser) { | |||
this.toUser = toUser; | |||
return (T) this; | |||
} | |||
@@ -8,12 +8,14 @@ public abstract class BaseBuilder<BuilderType, ValueType> { | |||
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; | |||
} | |||
@@ -23,7 +23,6 @@ import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||
public class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExecutor<InputStream, String> { | |||
private File tmpDirFile; | |||
public MaterialVoiceAndImageDownloadRequestExecutor() { | |||
super(); | |||
@@ -31,7 +30,6 @@ public class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExec | |||
public MaterialVoiceAndImageDownloadRequestExecutor(File tmpDirFile) { | |||
super(); | |||
this.tmpDirFile = tmpDirFile; | |||
} | |||
@Override | |||