@@ -1,73 +1,79 @@ | |||||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||||
<project | <project | ||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" | |||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |||||
<modelVersion>4.0.0</modelVersion> | |||||
<parent> | |||||
<groupId>com.github.binarywang</groupId> | |||||
<artifactId>weixin-java-parent</artifactId> | |||||
<version>2.4.6.BETA</version> | |||||
</parent> | |||||
<artifactId>weixin-java-mp</artifactId> | |||||
<name>WeiXin Java Tools - MP</name> | |||||
<description>微信公众号Java SDK</description> | |||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"> | |||||
<modelVersion>4.0.0</modelVersion> | |||||
<parent> | |||||
<groupId>com.github.binarywang</groupId> | |||||
<artifactId>weixin-java-parent</artifactId> | |||||
<version>2.4.6.BETA</version> | |||||
</parent> | |||||
<artifactId>weixin-java-mp</artifactId> | |||||
<name>WeiXin Java Tools - MP</name> | |||||
<description>微信公众号Java SDK</description> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>com.github.binarywang</groupId> | |||||
<artifactId>weixin-java-common</artifactId> | |||||
<version>${project.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>junit</groupId> | |||||
<artifactId>junit</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.testng</groupId> | |||||
<artifactId>testng</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.mockito</groupId> | |||||
<artifactId>mockito-all</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.google.inject</groupId> | |||||
<artifactId>guice</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.eclipse.jetty</groupId> | |||||
<artifactId>jetty-server</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.eclipse.jetty</groupId> | |||||
<artifactId>jetty-servlet</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>joda-time</groupId> | |||||
<artifactId>joda-time</artifactId> | |||||
<version>2.9.4</version> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
</dependencies> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>com.github.binarywang</groupId> | |||||
<artifactId>weixin-java-common</artifactId> | |||||
<version>${project.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>junit</groupId> | |||||
<artifactId>junit</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.testng</groupId> | |||||
<artifactId>testng</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.mockito</groupId> | |||||
<artifactId>mockito-all</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.google.inject</groupId> | |||||
<artifactId>guice</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.eclipse.jetty</groupId> | |||||
<artifactId>jetty-server</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.eclipse.jetty</groupId> | |||||
<artifactId>jetty-servlet</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>joda-time</groupId> | |||||
<artifactId>joda-time</artifactId> | |||||
<version>2.9.4</version> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>io.rest-assured</groupId> | |||||
<artifactId>xml-path</artifactId> | |||||
<version>3.0.1</version> | |||||
</dependency> | |||||
<build> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-surefire-plugin</artifactId> | |||||
<configuration> | |||||
<suiteXmlFiles> | |||||
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile> | |||||
</suiteXmlFiles> | |||||
</configuration> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</dependencies> | |||||
<build> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-surefire-plugin</artifactId> | |||||
<configuration> | |||||
<suiteXmlFiles> | |||||
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile> | |||||
</suiteXmlFiles> | |||||
</configuration> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> | </project> |
@@ -310,20 +310,25 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
} | } | ||||
@Override | @Override | ||||
public void setSslContextFilePath(String filePath) throws Exception { | |||||
public void setSslContextFilePath(String filePath) { | |||||
if (null == partnerId) { | if (null == partnerId) { | ||||
throw new Exception("请先将partnerId进行赋值"); | |||||
throw new IllegalArgumentException("请设置partnerId的值"); | |||||
} | } | ||||
File file = new File(filePath); | File file = new File(filePath); | ||||
if (!file.exists()) { | if (!file.exists()) { | ||||
throw new RuntimeException(file.getPath() + ":文件不存在!在设置SSLContext的时候"); | |||||
throw new RuntimeException("证书文件:【" + file.getPath() + "】不存在!"); | |||||
} | |||||
try { | |||||
FileInputStream inputStream = new FileInputStream(file); | |||||
KeyStore keystore = KeyStore.getInstance("PKCS12"); | |||||
char[] partnerId2charArray = partnerId.toCharArray(); | |||||
keystore.load(inputStream, partnerId2charArray); | |||||
this.sslContext = SSLContexts.custom().loadKeyMaterial(keystore, partnerId2charArray).build(); | |||||
} catch (Exception e) { | |||||
throw new RuntimeException("证书文件有问题,请核实!", e); | |||||
} | } | ||||
FileInputStream inputStream = new FileInputStream(file); | |||||
KeyStore keystore = KeyStore.getInstance("PKCS12"); | |||||
char[] partnerId2charArray = partnerId.toCharArray(); | |||||
keystore.load(inputStream, partnerId2charArray); | |||||
this.sslContext = SSLContexts.custom().loadKeyMaterial(keystore, partnerId2charArray).build(); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -1,14 +1,11 @@ | |||||
package me.chanjar.weixin.mp.api.impl; | 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.bean.result.WxError; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.util.BeanUtils; | 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.WxMpConfigStorage; | ||||
import me.chanjar.weixin.mp.api.WxMpPayService; | import me.chanjar.weixin.mp.api.WxMpPayService; | ||||
import me.chanjar.weixin.mp.api.WxMpService; | import me.chanjar.weixin.mp.api.WxMpService; | ||||
import me.chanjar.weixin.mp.bean.pay.WxPayOrderNotifyResultConverter; | |||||
import me.chanjar.weixin.mp.bean.pay.request.*; | import me.chanjar.weixin.mp.bean.pay.request.*; | ||||
import me.chanjar.weixin.mp.bean.pay.result.*; | import me.chanjar.weixin.mp.bean.pay.result.*; | ||||
import org.apache.commons.codec.digest.DigestUtils; | import org.apache.commons.codec.digest.DigestUtils; | ||||
@@ -54,20 +51,16 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public WxPayRefundResult refund(WxPayRefundRequest request) throws WxErrorException { | public WxPayRefundResult refund(WxPayRefundRequest request) throws WxErrorException { | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxPayRefundRequest.class); | |||||
xstream.processAnnotations(WxPayRefundResult.class); | |||||
initRequest(request); | |||||
this.initRequest(request); | |||||
if (StringUtils.isBlank(request.getOpUserId())) { | if (StringUtils.isBlank(request.getOpUserId())) { | ||||
request.setOpUserId(getConfig().getPartnerId()); | |||||
request.setOpUserId(this.getConfig().getPartnerId()); | |||||
} | } | ||||
checkParameters(request); | |||||
this.checkParameters(request); | |||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
String url = PAY_BASE_URL + "/secapi/pay/refund"; | String url = PAY_BASE_URL + "/secapi/pay/refund"; | ||||
String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
WxPayRefundResult result = (WxPayRefundResult) xstream.fromXML(responseContent); | |||||
String responseContent = this.executeWithKey(url, request.toXML()); | |||||
WxPayRefundResult result = WxPayRefundResult.fromXML(responseContent, WxPayRefundResult.class); | |||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
} | } | ||||
@@ -79,12 +72,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
throw new IllegalArgumentException("transaction_id , out_trade_no,out_refund_no, refund_id 必须四选一"); | throw new IllegalArgumentException("transaction_id , out_trade_no,out_refund_no, refund_id 必须四选一"); | ||||
} | } | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxPayRefundQueryRequest.class); | |||||
xstream.processAnnotations(WxPayRefundQueryResult.class); | |||||
WxPayRefundQueryRequest request = new WxPayRefundQueryRequest(); | WxPayRefundQueryRequest request = new WxPayRefundQueryRequest(); | ||||
initRequest(request); | |||||
this.initRequest(request); | |||||
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | ||||
request.setTransactionId(StringUtils.trimToNull(transactionId)); | request.setTransactionId(StringUtils.trimToNull(transactionId)); | ||||
request.setOutRefundNo(StringUtils.trimToNull(outRefundNo)); | request.setOutRefundNo(StringUtils.trimToNull(outRefundNo)); | ||||
@@ -92,8 +81,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
String url = PAY_BASE_URL + "/pay/refundquery"; | String url = PAY_BASE_URL + "/pay/refundquery"; | ||||
String responseContent = this.executeRequest(url, xstream.toXML(request)); | |||||
WxPayRefundQueryResult result = (WxPayRefundQueryResult) xstream.fromXML(responseContent); | |||||
String responseContent = this.executeRequest(url, request.toXML()); | |||||
WxPayRefundQueryResult result = WxPayRefundQueryResult.fromXML(responseContent, WxPayRefundQueryResult.class); | |||||
result.composeRefundRecords(responseContent); | result.composeRefundRecords(responseContent); | ||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
@@ -102,8 +91,9 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
private void checkResult(WxPayBaseResult result) throws WxErrorException { | private void checkResult(WxPayBaseResult result) throws WxErrorException { | ||||
//校验返回结果签名 | //校验返回结果签名 | ||||
if (!checkSign(result.toMap())) { | |||||
log.debug("校验结果签名失败,参数:{}", result.toMap()); | |||||
Map<String, String> map = result.toMap(); | |||||
if (!this.checkSign(map)) { | |||||
log.debug("校验结果签名失败,参数:{}", map); | |||||
throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("参数格式校验错误!").build()); | throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("参数格式校验错误!").build()); | ||||
} | } | ||||
@@ -115,7 +105,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
+ result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: " | + result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: " | ||||
+ result.getErrCode() + ", 错误详情: " + result.getErrCodeDes()) | + result.getErrCode() + ", 错误详情: " + result.getErrCodeDes()) | ||||
.build(); | .build(); | ||||
log.error("结果业务代码异常,参数:{},详细:{}", result.toMap(), error); | |||||
log.error("结果业务代码异常,参数:{},详细:{}", map, error); | |||||
throw new WxErrorException(error); | throw new WxErrorException(error); | ||||
} | } | ||||
} | } | ||||
@@ -138,10 +128,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException { | public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException { | ||||
try { | try { | ||||
log.trace("微信支付回调参数详细:{}", xmlData); | log.trace("微信支付回调参数详细:{}", xmlData); | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxPayOrderNotifyResult.class); | |||||
xstream.registerConverter(new WxPayOrderNotifyResultConverter(xstream.getMapper(), xstream.getReflectionProvider())); | |||||
WxPayOrderNotifyResult result = (WxPayOrderNotifyResult) xstream.fromXML(xmlData); | |||||
WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlData); | |||||
log.debug("微信支付回调结果对象:{}", result); | log.debug("微信支付回调结果对象:{}", result); | ||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
@@ -157,11 +144,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) | public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) | ||||
throws WxErrorException { | throws WxErrorException { | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxPaySendRedpackRequest.class); | |||||
xstream.processAnnotations(WxPaySendRedpackResult.class); | |||||
initRequest(request); | |||||
this.initRequest(request); | |||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
String url = PAY_BASE_URL + "/mmpaymkttransfers/sendredpack"; | String url = PAY_BASE_URL + "/mmpaymkttransfers/sendredpack"; | ||||
@@ -169,18 +152,14 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
//裂变红包 | //裂变红包 | ||||
url = PAY_BASE_URL + "/mmpaymkttransfers/sendgroupredpack"; | url = PAY_BASE_URL + "/mmpaymkttransfers/sendgroupredpack"; | ||||
} | } | ||||
String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
WxPaySendRedpackResult result = (WxPaySendRedpackResult) xstream.fromXML(responseContent); | |||||
String responseContent = this.executeWithKey(url, request.toXML()); | |||||
WxPaySendRedpackResult result = WxPaySendRedpackResult.fromXML(responseContent, WxPaySendRedpackResult.class); | |||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
} | } | ||||
@Override | @Override | ||||
public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxErrorException { | public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxErrorException { | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxPayRedpackQueryRequest.class); | |||||
xstream.processAnnotations(WxPayRedpackQueryResult.class); | |||||
WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); | WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); | ||||
request.setMchBillNo(mchBillNo); | request.setMchBillNo(mchBillNo); | ||||
request.setBillType("MCHT"); | request.setBillType("MCHT"); | ||||
@@ -188,8 +167,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo"; | String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo"; | ||||
String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
WxPayRedpackQueryResult result = (WxPayRedpackQueryResult) xstream.fromXML(responseContent); | |||||
String responseContent = this.executeWithKey(url, request.toXML()); | |||||
WxPayRedpackQueryResult result = WxPayRedpackQueryResult.fromXML(responseContent, WxPayRedpackQueryResult.class); | |||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
} | } | ||||
@@ -201,10 +180,6 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
throw new IllegalArgumentException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一"); | throw new IllegalArgumentException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一"); | ||||
} | } | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxPayOrderQueryRequest.class); | |||||
xstream.processAnnotations(WxPayOrderQueryResult.class); | |||||
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)); | ||||
@@ -212,8 +187,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
String url = PAY_BASE_URL + "/pay/orderquery"; | String url = PAY_BASE_URL + "/pay/orderquery"; | ||||
String responseContent = this.executeRequest(url, xstream.toXML(request)); | |||||
WxPayOrderQueryResult result = (WxPayOrderQueryResult) xstream.fromXML(responseContent); | |||||
String responseContent = this.executeRequest(url, request.toXML()); | |||||
WxPayOrderQueryResult result = WxPayOrderQueryResult.fromXML(responseContent, WxPayOrderQueryResult.class); | |||||
result.composeCoupons(responseContent); | result.composeCoupons(responseContent); | ||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
@@ -225,18 +200,14 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
throw new IllegalArgumentException("out_trade_no 不能为空"); | throw new IllegalArgumentException("out_trade_no 不能为空"); | ||||
} | } | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxPayOrderCloseRequest.class); | |||||
xstream.processAnnotations(WxPayOrderCloseResult.class); | |||||
WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); | WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); | ||||
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); | ||||
initRequest(request); | initRequest(request); | ||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
String url = PAY_BASE_URL + "/pay/closeorder"; | String url = PAY_BASE_URL + "/pay/closeorder"; | ||||
String responseContent = this.executeRequest(url, xstream.toXML(request)); | |||||
WxPayOrderCloseResult result = (WxPayOrderCloseResult) xstream.fromXML(responseContent); | |||||
String responseContent = this.executeRequest(url, request.toXML()); | |||||
WxPayOrderCloseResult result = WxPayOrderCloseResult.fromXML(responseContent, WxPayOrderCloseResult.class); | |||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
@@ -246,11 +217,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) | public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) | ||||
throws WxErrorException { | throws WxErrorException { | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxPayUnifiedOrderRequest.class); | |||||
xstream.processAnnotations(WxPayUnifiedOrderResult.class); | |||||
initRequest(request); | |||||
this.initRequest(request); | |||||
if (StringUtils.isBlank(request.getNotifyURL())) { | if (StringUtils.isBlank(request.getNotifyURL())) { | ||||
request.setNotifyURL(getConfig().getNotifyURL()); | request.setNotifyURL(getConfig().getNotifyURL()); | ||||
} | } | ||||
@@ -261,12 +228,12 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
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); | |||||
String xmlParam = request.toXML(); | |||||
log.debug("微信统一下单接口,URL:{},参数:{}", url, xmlParam); | log.debug("微信统一下单接口,URL:{},参数:{}", url, xmlParam); | ||||
String responseContent = this.executeRequest(url, xmlParam); | String responseContent = this.executeRequest(url, xmlParam); | ||||
log.debug("微信统一下单接口,URL:{},结果:{}", url, responseContent); | log.debug("微信统一下单接口,URL:{},结果:{}", url, responseContent); | ||||
WxPayUnifiedOrderResult result = (WxPayUnifiedOrderResult) xstream.fromXML(responseContent); | |||||
WxPayUnifiedOrderResult result = WxPayUnifiedOrderResult.fromXML(responseContent, WxPayUnifiedOrderResult.class); | |||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
} | } | ||||
@@ -324,35 +291,27 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public WxEntPayResult entPay(WxEntPayRequest request) throws WxErrorException { | public WxEntPayResult entPay(WxEntPayRequest request) throws WxErrorException { | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxEntPayRequest.class); | |||||
xstream.processAnnotations(WxEntPayResult.class); | |||||
initRequest(request); | |||||
this.initRequest(request); | |||||
BeanUtils.checkRequiredFields(request); | BeanUtils.checkRequiredFields(request); | ||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
String url = PAY_BASE_URL + "/mmpaymkttransfers/promotion/transfers"; | String url = PAY_BASE_URL + "/mmpaymkttransfers/promotion/transfers"; | ||||
String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
WxEntPayResult result = (WxEntPayResult) xstream.fromXML(responseContent); | |||||
String responseContent = this.executeWithKey(url, request.toXML()); | |||||
WxEntPayResult result = WxEntPayResult.fromXML(responseContent, WxEntPayResult.class); | |||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
} | } | ||||
@Override | @Override | ||||
public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxErrorException { | public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxErrorException { | ||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxEntPayQueryRequest.class); | |||||
xstream.processAnnotations(WxEntPayQueryResult.class); | |||||
WxEntPayQueryRequest request = new WxEntPayQueryRequest(); | WxEntPayQueryRequest request = new WxEntPayQueryRequest(); | ||||
initRequest(request); | |||||
this.initRequest(request); | |||||
request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
String url = PAY_BASE_URL + "/mmpaymkttransfers/gettransferinfo"; | String url = PAY_BASE_URL + "/mmpaymkttransfers/gettransferinfo"; | ||||
String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
WxEntPayQueryResult result = (WxEntPayQueryResult) xstream.fromXML(responseContent); | |||||
String responseContent = this.executeWithKey(url, request.toXML()); | |||||
WxEntPayQueryResult result = WxEntPayQueryResult.fromXML(responseContent, WxEntPayQueryResult.class); | |||||
this.checkResult(result); | this.checkResult(result); | ||||
return result; | return result; | ||||
} | } | ||||
@@ -379,11 +338,11 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
} | } | ||||
} | } | ||||
private String executeRequestWithKeyFile(String url, String requestStr) throws WxErrorException { | |||||
private String executeWithKey(String url, String requestStr) throws WxErrorException { | |||||
try { | try { | ||||
SSLContext sslContext = getConfig().getSslContext(); | SSLContext sslContext = getConfig().getSslContext(); | ||||
if (null == sslContext) { | if (null == sslContext) { | ||||
throw new Exception("请将配置类(即WxMpConfigStorage的实现类)中的SSLContext初始化"); | |||||
throw new IllegalArgumentException("请先初始化配置类(即WxMpConfigStorage的实现类)中的SSLContext!"); | |||||
} | } | ||||
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1"}, null, | SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1"}, null, | ||||
@@ -412,17 +371,17 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public String createSign(Object xmlBean) { | public String createSign(Object xmlBean) { | ||||
return createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); | |||||
return this.createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); | |||||
} | } | ||||
@Override | @Override | ||||
public String createSign(Object xmlBean, String signKey) { | public String createSign(Object xmlBean, String signKey) { | ||||
return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey); | |||||
return this.createSign(BeanUtils.xmlBean2Map(xmlBean), signKey); | |||||
} | } | ||||
@Override | @Override | ||||
public String createSign(Map<String, String> params) { | public String createSign(Map<String, String> params) { | ||||
return createSign(params, getConfig().getPartnerKey()); | |||||
return this.createSign(params, this.getConfig().getPartnerKey()); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -443,17 +402,17 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
@Override | @Override | ||||
public boolean checkSign(Object xmlBean) { | public boolean checkSign(Object xmlBean) { | ||||
return checkSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); | |||||
return this.checkSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); | |||||
} | } | ||||
@Override | @Override | ||||
public boolean checkSign(Object xmlBean, String signKey) { | public boolean checkSign(Object xmlBean, String signKey) { | ||||
return checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey); | |||||
return this.checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey); | |||||
} | } | ||||
@Override | @Override | ||||
public boolean checkSign(Map<String, String> params) { | public boolean checkSign(Map<String, String> params) { | ||||
return checkSign(params, getConfig().getPartnerKey()); | |||||
return this.checkSign(params, getConfig().getPartnerKey()); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -1,7 +1,9 @@ | |||||
package me.chanjar.weixin.mp.bean.pay.request; | package me.chanjar.weixin.mp.bean.pay.request; | ||||
import com.thoughtworks.xstream.XStream; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||||
import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
@@ -17,6 +19,7 @@ import java.math.BigDecimal; | |||||
* <li>示例值 | * <li>示例值 | ||||
* <li>描述 | * <li>描述 | ||||
* </pre> | * </pre> | ||||
* | |||||
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | * @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | ||||
*/ | */ | ||||
public abstract class WxPayBaseRequest { | public abstract class WxPayBaseRequest { | ||||
@@ -69,12 +72,22 @@ public abstract class WxPayBaseRequest { | |||||
@XStreamAlias("sign") | @XStreamAlias("sign") | ||||
protected String sign; | protected String sign; | ||||
/** | |||||
* 将单位为元转换为单位为分 | |||||
* | |||||
* @param yuan 将要转换的元的数值字符串 | |||||
*/ | |||||
public static Integer yuanToFee(String yuan) { | |||||
return new BigDecimal(yuan).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue(); | |||||
} | |||||
public String getAppid() { | public String getAppid() { | ||||
return this.appid; | return this.appid; | ||||
} | } | ||||
/** | /** | ||||
* 如果配置中已经设置,可以不设置值 | * 如果配置中已经设置,可以不设置值 | ||||
* | |||||
* @param appid 微信公众号appid | * @param appid 微信公众号appid | ||||
*/ | */ | ||||
public void setAppid(String appid) { | public void setAppid(String appid) { | ||||
@@ -87,6 +100,7 @@ public abstract class WxPayBaseRequest { | |||||
/** | /** | ||||
* 如果配置中已经设置,可以不设置值 | * 如果配置中已经设置,可以不设置值 | ||||
* | |||||
* @param mchId 微信商户号 | * @param mchId 微信商户号 | ||||
*/ | */ | ||||
public void setMchId(String mchId) { | public void setMchId(String mchId) { | ||||
@@ -99,6 +113,7 @@ public abstract class WxPayBaseRequest { | |||||
/** | /** | ||||
* 默认采用时间戳为随机字符串,可以不设置 | * 默认采用时间戳为随机字符串,可以不设置 | ||||
* | |||||
* @param nonceStr 随机字符串 | * @param nonceStr 随机字符串 | ||||
*/ | */ | ||||
public void setNonceStr(String nonceStr) { | public void setNonceStr(String nonceStr) { | ||||
@@ -113,17 +128,14 @@ public abstract class WxPayBaseRequest { | |||||
this.sign = sign; | this.sign = sign; | ||||
} | } | ||||
/** | |||||
* 将单位为元转换为单位为分 | |||||
* | |||||
* @param yuan 将要转换的元的数值字符串 | |||||
*/ | |||||
public static Integer yuanToFee(String yuan) { | |||||
return new BigDecimal(yuan).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue(); | |||||
} | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return ToStringUtils.toSimpleString(this); | return ToStringUtils.toSimpleString(this); | ||||
} | } | ||||
public String toXML() { | |||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(this.getClass()); | |||||
return xstream.toXML(this); | |||||
} | |||||
} | } |
@@ -1,7 +1,6 @@ | |||||
package me.chanjar.weixin.mp.bean.pay.request; | package me.chanjar.weixin.mp.bean.pay.request; | ||||
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; | ||||
/** | /** | ||||
@@ -144,8 +143,6 @@ public class WxPayRefundRequest extends WxPayBaseRequest { | |||||
@XStreamAlias("refund_account") | @XStreamAlias("refund_account") | ||||
private String refundAccount; | private String refundAccount; | ||||
public String getDeviceInfo() { | public String getDeviceInfo() { | ||||
return this.deviceInfo; | return this.deviceInfo; | ||||
} | } | ||||
@@ -217,4 +214,5 @@ public class WxPayRefundRequest extends WxPayBaseRequest { | |||||
public void setRefundAccount(String refundAccount) { | public void setRefundAccount(String refundAccount) { | ||||
this.refundAccount = refundAccount; | this.refundAccount = refundAccount; | ||||
} | } | ||||
} | } |
@@ -1,10 +1,19 @@ | |||||
package me.chanjar.weixin.mp.bean.pay.result; | package me.chanjar.weixin.mp.bean.pay.result; | ||||
import com.google.common.collect.Maps; | |||||
import com.thoughtworks.xstream.XStream; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import me.chanjar.weixin.common.util.BeanUtils; | |||||
import io.restassured.internal.path.xml.NodeChildrenImpl; | |||||
import io.restassured.path.xml.XmlPath; | |||||
import io.restassured.path.xml.element.Node; | |||||
import io.restassured.path.xml.element.NodeChildren; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
import java.util.Iterator; | |||||
import java.util.Map; | import java.util.Map; | ||||
/** | /** | ||||
@@ -15,65 +24,90 @@ import java.util.Map; | |||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
public abstract class WxPayBaseResult { | public abstract class WxPayBaseResult { | ||||
@Override | |||||
public String toString() { | |||||
return ToStringUtils.toSimpleString(this); | |||||
} | |||||
/** | /** | ||||
* 返回状态码 | * 返回状态码 | ||||
*/ | */ | ||||
@XStreamAlias("return_code") | @XStreamAlias("return_code") | ||||
protected String returnCode; | protected String returnCode; | ||||
/** | /** | ||||
* 返回信息 | * 返回信息 | ||||
*/ | */ | ||||
@XStreamAlias("return_msg") | @XStreamAlias("return_msg") | ||||
protected String returnMsg; | protected String returnMsg; | ||||
private String xmlString; | |||||
/** | /** | ||||
* 业务结果 | * 业务结果 | ||||
*/ | */ | ||||
@XStreamAlias("result_code") | @XStreamAlias("result_code") | ||||
private String resultCode; | private String resultCode; | ||||
/** | /** | ||||
* 错误代码 | * 错误代码 | ||||
*/ | */ | ||||
@XStreamAlias("err_code") | @XStreamAlias("err_code") | ||||
private String errCode; | private String errCode; | ||||
/** | /** | ||||
* 错误代码描述 | * 错误代码描述 | ||||
*/ | */ | ||||
@XStreamAlias("err_code_des") | @XStreamAlias("err_code_des") | ||||
private String errCodeDes; | private String errCodeDes; | ||||
/** | /** | ||||
* 公众账号ID | * 公众账号ID | ||||
*/ | */ | ||||
@XStreamAlias("appid") | @XStreamAlias("appid") | ||||
private String appid; | private String appid; | ||||
/** | /** | ||||
* 商户号 | * 商户号 | ||||
*/ | */ | ||||
@XStreamAlias("mch_id") | @XStreamAlias("mch_id") | ||||
private String mchId; | private String mchId; | ||||
/** | /** | ||||
* 随机字符串 | * 随机字符串 | ||||
*/ | */ | ||||
@XStreamAlias("nonce_str") | @XStreamAlias("nonce_str") | ||||
private String nonceStr; | private String nonceStr; | ||||
/** | /** | ||||
* 签名 | * 签名 | ||||
*/ | */ | ||||
@XStreamAlias("sign") | @XStreamAlias("sign") | ||||
private String sign; | private String sign; | ||||
/** | |||||
* 将单位分转换成单位圆 | |||||
* | |||||
* @param fee 将要被转换为元的分的数值 | |||||
*/ | |||||
public static String feeToYuan(Integer fee) { | |||||
return new BigDecimal(Double.valueOf(fee) / 100).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(); | |||||
} | |||||
/** | |||||
* 从xml字符串创建bean对象 | |||||
*/ | |||||
public static <T extends WxPayBaseResult> T fromXML(String xmlString, Class<T> clz) { | |||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(clz); | |||||
T result = (T) xstream.fromXML(xmlString); | |||||
result.setXmlString(xmlString); | |||||
return result; | |||||
} | |||||
public String getXmlString() { | |||||
return this.xmlString; | |||||
} | |||||
public void setXmlString(String xmlString) { | |||||
this.xmlString = xmlString; | |||||
} | |||||
protected Logger getLogger() { | |||||
return LoggerFactory.getLogger(this.getClass()); | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return ToStringUtils.toSimpleString(this); | |||||
} | |||||
public String getReturnCode() { | public String getReturnCode() { | ||||
return this.returnCode; | return this.returnCode; | ||||
} | } | ||||
@@ -147,14 +181,43 @@ public abstract class WxPayBaseResult { | |||||
} | } | ||||
/** | /** | ||||
* 将单位分转换成单位圆 | |||||
* @param fee 将要被转换为元的分的数值 | |||||
* 将bean通过保存的xml字符串转换成map | |||||
*/ | */ | ||||
public static String feeToYuan(Integer fee) { | |||||
return new BigDecimal(Double.valueOf(fee) / 100).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(); | |||||
} | |||||
public Map<String,String> toMap(){ | |||||
return BeanUtils.xmlBean2Map(this); | |||||
public Map<String, String> toMap() { | |||||
Map<String, String> result = Maps.newHashMap(); | |||||
XmlPath xmlPath = new XmlPath(this.xmlString); | |||||
NodeChildren nodeChildren = xmlPath.getNodeChildren("xml"); | |||||
Iterator<Node> iterator = nodeChildren.nodeIterator(); | |||||
while (iterator.hasNext()) { | |||||
Node node = iterator.next(); | |||||
result.put(node.name(), node.value()); | |||||
} | |||||
return result; | |||||
} | |||||
private String getXmlValueIfExists(XmlPath xmlPath, String path) { | |||||
if (xmlPath.get(path) instanceof NodeChildrenImpl) { | |||||
if (((NodeChildrenImpl) xmlPath.get(path)).size() == 0) { | |||||
return null; | |||||
} | |||||
} | |||||
return xmlPath.getString(path); | |||||
} | |||||
protected <T> T getXmlValueIfExists(XmlPath xmlPath, String path, Class<T> clz) { | |||||
String value = this.getXmlValueIfExists(xmlPath, path); | |||||
if (value == null) { | |||||
return null; | |||||
} | |||||
switch (clz.getSimpleName()) { | |||||
case "String": | |||||
return (T) value; | |||||
case "Integer": | |||||
return (T) Integer.valueOf(value); | |||||
} | |||||
throw new UnsupportedOperationException("暂时不支持此种类型的数据"); | |||||
} | } | ||||
} | } |
@@ -1,10 +1,12 @@ | |||||
package me.chanjar.weixin.mp.bean.pay.result; | package me.chanjar.weixin.mp.bean.pay.result; | ||||
import com.thoughtworks.xstream.XStream; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import me.chanjar.weixin.common.util.BeanUtils; | import me.chanjar.weixin.common.util.BeanUtils; | ||||
import me.chanjar.weixin.common.util.ToStringUtils; | |||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||||
import me.chanjar.weixin.mp.bean.pay.WxPayOrderNotifyCoupon; | import me.chanjar.weixin.mp.bean.pay.WxPayOrderNotifyCoupon; | ||||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||||
import org.apache.commons.lang3.builder.ToStringStyle; | |||||
import me.chanjar.weixin.mp.bean.pay.WxPayOrderNotifyResultConverter; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -376,6 +378,15 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializ | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE); | |||||
return ToStringUtils.toSimpleString(this); | |||||
} | } | ||||
public static WxPayOrderNotifyResult fromXML(String xmlString) { | |||||
XStream xstream = XStreamInitializer.getInstance(); | |||||
xstream.processAnnotations(WxPayOrderNotifyResult.class); | |||||
xstream.registerConverter(new WxPayOrderNotifyResultConverter(xstream.getMapper(), xstream.getReflectionProvider())); | |||||
WxPayOrderNotifyResult result = (WxPayOrderNotifyResult) xstream.fromXML(xmlString); | |||||
result.setXmlString(xmlString); | |||||
return result; | |||||
} | |||||
} | } |
@@ -2,6 +2,7 @@ package me.chanjar.weixin.mp.bean.pay.result; | |||||
import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import io.restassured.path.xml.XmlPath; | |||||
import java.util.List; | import java.util.List; | ||||
@@ -186,7 +187,38 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
public void composeRefundRecords(String xmlString) { | public void composeRefundRecords(String xmlString) { | ||||
if (this.refundCount != null && this.refundCount > 0) { | if (this.refundCount != null && this.refundCount > 0) { | ||||
this.refundRecords = Lists.newArrayList(); | this.refundRecords = Lists.newArrayList(); | ||||
//TODO 暂时待实现 | |||||
XmlPath xmlPath = new XmlPath(xmlString); | |||||
for (int i = 0; i < this.refundCount; i++) { | |||||
RefundRecord refundRecord = new RefundRecord(); | |||||
this.refundRecords.add(refundRecord); | |||||
refundRecord.setOutRefundNo(this.getXmlValueIfExists(xmlPath, "xml.out_refund_no_" + i, String.class)); | |||||
refundRecord.setRefundId(this.getXmlValueIfExists(xmlPath, "xml.refund_id_" + i, String.class)); | |||||
refundRecord.setRefundChannel(this.getXmlValueIfExists(xmlPath, "xml.refund_channel_" + i, String.class)); | |||||
refundRecord.setRefundFee(this.getXmlValueIfExists(xmlPath, "xml.refund_fee_" + i, Integer.class)); | |||||
refundRecord.setSettlementRefundFee(this.getXmlValueIfExists(xmlPath, "xml.settlement_refund_fee_" + i, Integer.class)); | |||||
refundRecord.setCouponType(this.getXmlValueIfExists(xmlPath, "xml.coupon_type_" + i, String.class)); | |||||
refundRecord.setCouponRefundFee(this.getXmlValueIfExists(xmlPath, "xml.coupon_refund_fee_" + i, Integer.class)); | |||||
refundRecord.setCouponRefundCount(this.getXmlValueIfExists(xmlPath, "xml.coupon_refund_count_" + i, Integer.class)); | |||||
refundRecord.setRefundStatus(this.getXmlValueIfExists(xmlPath, "xml.refund_status_" + i, String.class)); | |||||
refundRecord.setRefundRecvAccout(this.getXmlValueIfExists(xmlPath, "xml.refund_recv_accout_" + i, String.class)); | |||||
if (refundRecord.getCouponRefundCount() == null || refundRecord.getCouponRefundCount() == 0) { | |||||
continue; | |||||
} | |||||
List<RefundRecord.RefundCoupon> coupons = Lists.newArrayList(); | |||||
for (int j = 0; j < refundRecord.getCouponRefundCount(); j++) { | |||||
coupons.add( | |||||
new RefundRecord.RefundCoupon( | |||||
this.getXmlValueIfExists(xmlPath, "xml.coupon_refund_id_" + i + "_" + j, String.class), | |||||
this.getXmlValueIfExists(xmlPath, "xml.coupon_refund_fee_" + i + "_" + j, Integer.class) | |||||
) | |||||
); | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -241,7 +273,7 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@XStreamAlias("refund_fee") | @XStreamAlias("refund_fee") | ||||
private String refundFee; | |||||
private Integer refundFee; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -254,7 +286,7 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@XStreamAlias("settlement_refund_fee") | @XStreamAlias("settlement_refund_fee") | ||||
private String settlementRefundFee; | |||||
private Integer settlementRefundFee; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -293,7 +325,7 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@XStreamAlias("coupon_refund_fee") | @XStreamAlias("coupon_refund_fee") | ||||
private String couponRefundFee; | |||||
private Integer couponRefundFee; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -306,7 +338,7 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@XStreamAlias("coupon_refund_count") | @XStreamAlias("coupon_refund_count") | ||||
private String couponRefundCount; | |||||
private Integer couponRefundCount; | |||||
private List<RefundCoupon> refundCoupons; | private List<RefundCoupon> refundCoupons; | ||||
@@ -364,19 +396,19 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
this.refundChannel = refundChannel; | this.refundChannel = refundChannel; | ||||
} | } | ||||
public String getRefundFee() { | |||||
public Integer getRefundFee() { | |||||
return refundFee; | return refundFee; | ||||
} | } | ||||
public void setRefundFee(String refundFee) { | |||||
public void setRefundFee(Integer refundFee) { | |||||
this.refundFee = refundFee; | this.refundFee = refundFee; | ||||
} | } | ||||
public String getSettlementRefundFee() { | |||||
public Integer getSettlementRefundFee() { | |||||
return settlementRefundFee; | return settlementRefundFee; | ||||
} | } | ||||
public void setSettlementRefundFee(String settlementRefundFee) { | |||||
public void setSettlementRefundFee(Integer settlementRefundFee) { | |||||
this.settlementRefundFee = settlementRefundFee; | this.settlementRefundFee = settlementRefundFee; | ||||
} | } | ||||
@@ -396,19 +428,19 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
this.couponType = couponType; | this.couponType = couponType; | ||||
} | } | ||||
public String getCouponRefundFee() { | |||||
public Integer getCouponRefundFee() { | |||||
return couponRefundFee; | return couponRefundFee; | ||||
} | } | ||||
public void setCouponRefundFee(String couponRefundFee) { | |||||
public void setCouponRefundFee(Integer couponRefundFee) { | |||||
this.couponRefundFee = couponRefundFee; | this.couponRefundFee = couponRefundFee; | ||||
} | } | ||||
public String getCouponRefundCount() { | |||||
public Integer getCouponRefundCount() { | |||||
return couponRefundCount; | return couponRefundCount; | ||||
} | } | ||||
public void setCouponRefundCount(String couponRefundCount) { | |||||
public void setCouponRefundCount(Integer couponRefundCount) { | |||||
this.couponRefundCount = couponRefundCount; | this.couponRefundCount = couponRefundCount; | ||||
} | } | ||||
@@ -446,6 +478,8 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
* 100 | * 100 | ||||
* 退款代金券批次ID ,$n为下标,$m为下标,从0开始编号 | * 退款代金券批次ID ,$n为下标,$m为下标,从0开始编号 | ||||
* </pre> | * </pre> | ||||
* | |||||
* @deprecated 貌似是被去掉了,但不知是何时! | |||||
*/ | */ | ||||
@XStreamAlias("coupon_refund_batch_id") | @XStreamAlias("coupon_refund_batch_id") | ||||
private String couponRefundBatchId; | private String couponRefundBatchId; | ||||
@@ -474,9 +508,15 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@XStreamAlias("coupon_refund_fee") | @XStreamAlias("coupon_refund_fee") | ||||
private String couponRefundFee; | |||||
private Integer couponRefundFee; | |||||
public RefundCoupon(String couponRefundBatchId, String couponRefundId, String couponRefundFee) { | |||||
public RefundCoupon(String couponRefundId, Integer couponRefundFee) { | |||||
this.couponRefundId = couponRefundId; | |||||
this.couponRefundFee = couponRefundFee; | |||||
} | |||||
@Deprecated | |||||
public RefundCoupon(String couponRefundBatchId, String couponRefundId, Integer couponRefundFee) { | |||||
this.couponRefundBatchId = couponRefundBatchId; | this.couponRefundBatchId = couponRefundBatchId; | ||||
this.couponRefundId = couponRefundId; | this.couponRefundId = couponRefundId; | ||||
this.couponRefundFee = couponRefundFee; | this.couponRefundFee = couponRefundFee; | ||||
@@ -484,5 +524,6 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -13,8 +13,6 @@ import me.chanjar.weixin.mp.bean.pay.result.*; | |||||
import org.testng.annotations.Guice; | import org.testng.annotations.Guice; | ||||
import org.testng.annotations.Test; | import org.testng.annotations.Test; | ||||
import java.io.File; | |||||
/** | /** | ||||
* 测试支付相关接口 | * 测试支付相关接口 | ||||
* Created by Binary Wang on 2016/7/28. | * Created by Binary Wang on 2016/7/28. | ||||
@@ -90,7 +88,6 @@ public class WxMpPayServiceImplTest { | |||||
*/ | */ | ||||
@Test | @Test | ||||
public void testQueryRedpack() throws Exception { | public void testQueryRedpack() throws Exception { | ||||
File keyFile = new File("E:\\dlt.p12"); | |||||
WxPayRedpackQueryResult redpackResult = this.wxService.getPayService().queryRedpack("aaaa"); | WxPayRedpackQueryResult redpackResult = this.wxService.getPayService().queryRedpack("aaaa"); | ||||
System.err.println(redpackResult); | System.err.println(redpackResult); | ||||
} | } | ||||
@@ -0,0 +1,49 @@ | |||||
package me.chanjar.weixin.mp.bean.pay.result; | |||||
import org.testng.Assert; | |||||
import org.testng.annotations.Test; | |||||
/** | |||||
* <pre> | |||||
* Created by Binary Wang on 2016-12-29. | |||||
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||||
* </pre> | |||||
*/ | |||||
public class WxPayRefundQueryResultTest { | |||||
@Test | |||||
public void composeRefundRecords() throws Exception { | |||||
/* | |||||
该xml字符串来自于官方文档示例 | |||||
*/ | |||||
String xmlString = "<xml>\n" + | |||||
" <appid><![CDATA[wx2421b1c4370ec43b]]></appid>\n" + | |||||
" <mch_id><![CDATA[10000100]]></mch_id>\n" + | |||||
" <nonce_str><![CDATA[TeqClE3i0mvn3DrK]]></nonce_str>\n" + | |||||
" <out_refund_no_0><![CDATA[1415701182]]></out_refund_no_0>\n" + | |||||
" <out_trade_no><![CDATA[1415757673]]></out_trade_no>\n" + | |||||
" <refund_count>1</refund_count>\n" + | |||||
" <refund_fee_0>1</refund_fee_0>\n" + | |||||
" <refund_id_0><![CDATA[2008450740201411110000174436]]></refund_id_0>\n" + | |||||
" <refund_status_0><![CDATA[PROCESSING]]></refund_status_0>\n" + | |||||
" <result_code><![CDATA[SUCCESS]]></result_code>\n" + | |||||
" <return_code><![CDATA[SUCCESS]]></return_code>\n" + | |||||
" <return_msg><![CDATA[OK]]></return_msg>\n" + | |||||
" <sign><![CDATA[1F2841558E233C33ABA71A961D27561C]]></sign>\n" + | |||||
" <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>\n" + | |||||
"</xml>"; | |||||
WxPayRefundQueryResult result = new WxPayRefundQueryResult(); | |||||
result.setRefundCount(1); | |||||
result.composeRefundRecords(xmlString); | |||||
Assert.assertNotNull(result.getRefundRecords()); | |||||
Assert.assertEquals(result.getRefundRecords().size(), 1); | |||||
Assert.assertEquals(result.getRefundRecords().get(0).getRefundId(), "2008450740201411110000174436"); | |||||
Assert.assertEquals(result.getRefundRecords().get(0).getRefundFee().intValue(), 1); | |||||
Assert.assertEquals(result.getRefundRecords().get(0).getOutRefundNo(), "1415701182"); | |||||
Assert.assertEquals(result.getRefundRecords().get(0).getRefundStatus(), "PROCESSING"); | |||||
} | |||||
} |