| @@ -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"); | |||||
| } | |||||
| } | |||||