Pārlūkot izejas kodu

完善查询退款接口,并重构部分支付接口的实现,简化代码

master
Binary Wang pirms 8 gadiem
vecāks
revīzija
22723f9f2b
10 mainītis faili ar 351 papildinājumiem un 210 dzēšanām
  1. +73
    -67
      weixin-java-mp/pom.xml
  2. +13
    -8
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
  3. +39
    -80
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java
  4. +21
    -9
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java
  5. +1
    -3
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundRequest.java
  6. +85
    -22
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
  7. +14
    -3
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java
  8. +56
    -15
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResult.java
  9. +0
    -3
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java
  10. +49
    -0
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResultTest.java

+ 73
- 67
weixin-java-mp/pom.xml Parādīt failu

@@ -1,73 +1,79 @@
<?xml version="1.0"?>
<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>

+ 13
- 8
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java Parādīt failu

@@ -310,20 +310,25 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
}

@Override
public void setSslContextFilePath(String filePath) throws Exception {
public void setSslContextFilePath(String filePath) {
if (null == partnerId) {
throw new Exception("请先将partnerId进行赋值");
throw new IllegalArgumentException("请设置partnerId的值");
}

File file = new File(filePath);
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


+ 39
- 80
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java Parādīt failu

@@ -1,14 +1,11 @@
package me.chanjar.weixin.mp.api.impl;

import com.thoughtworks.xstream.XStream;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.BeanUtils;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpPayService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.pay.WxPayOrderNotifyResultConverter;
import me.chanjar.weixin.mp.bean.pay.request.*;
import me.chanjar.weixin.mp.bean.pay.result.*;
import org.apache.commons.codec.digest.DigestUtils;
@@ -54,20 +51,16 @@ public class WxMpPayServiceImpl implements WxMpPayService {

@Override
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())) {
request.setOpUserId(getConfig().getPartnerId());
request.setOpUserId(this.getConfig().getPartnerId());
}
checkParameters(request);
this.checkParameters(request);
request.setSign(this.createSign(request));

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);
return result;
}
@@ -79,12 +72,8 @@ public class WxMpPayServiceImpl implements WxMpPayService {
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();
initRequest(request);
this.initRequest(request);
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
request.setTransactionId(StringUtils.trimToNull(transactionId));
request.setOutRefundNo(StringUtils.trimToNull(outRefundNo));
@@ -92,8 +81,8 @@ public class WxMpPayServiceImpl implements WxMpPayService {
request.setSign(this.createSign(request));

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);
this.checkResult(result);
return result;
@@ -102,8 +91,9 @@ public class WxMpPayServiceImpl implements WxMpPayService {

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());
}

@@ -115,7 +105,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
+ result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: "
+ result.getErrCode() + ", 错误详情: " + result.getErrCodeDes())
.build();
log.error("结果业务代码异常,参数:{},详细:{}", result.toMap(), error);
log.error("结果业务代码异常,参数:{},详细:{}", map, error);
throw new WxErrorException(error);
}
}
@@ -138,10 +128,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException {
try {
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);
this.checkResult(result);
return result;
@@ -157,11 +144,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
@Override
public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request)
throws WxErrorException {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPaySendRedpackRequest.class);
xstream.processAnnotations(WxPaySendRedpackResult.class);

initRequest(request);
this.initRequest(request);
request.setSign(this.createSign(request));

String url = PAY_BASE_URL + "/mmpaymkttransfers/sendredpack";
@@ -169,18 +152,14 @@ public class WxMpPayServiceImpl implements WxMpPayService {
//裂变红包
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);
return result;
}

@Override
public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxErrorException {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPayRedpackQueryRequest.class);
xstream.processAnnotations(WxPayRedpackQueryResult.class);

WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest();
request.setMchBillNo(mchBillNo);
request.setBillType("MCHT");
@@ -188,8 +167,8 @@ public class WxMpPayServiceImpl implements WxMpPayService {
request.setSign(this.createSign(request));

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);
return result;
}
@@ -201,10 +180,6 @@ public class WxMpPayServiceImpl implements WxMpPayService {
throw new IllegalArgumentException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一");
}

XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPayOrderQueryRequest.class);
xstream.processAnnotations(WxPayOrderQueryResult.class);

WxPayOrderQueryRequest request = new WxPayOrderQueryRequest();
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
request.setTransactionId(StringUtils.trimToNull(transactionId));
@@ -212,8 +187,8 @@ public class WxMpPayServiceImpl implements WxMpPayService {
request.setSign(this.createSign(request));

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);
this.checkResult(result);
return result;
@@ -225,18 +200,14 @@ public class WxMpPayServiceImpl implements WxMpPayService {
throw new IllegalArgumentException("out_trade_no 不能为空");
}

XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPayOrderCloseRequest.class);
xstream.processAnnotations(WxPayOrderCloseResult.class);

WxPayOrderCloseRequest request = new WxPayOrderCloseRequest();
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
initRequest(request);
request.setSign(this.createSign(request));

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);

return result;
@@ -246,11 +217,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request)
throws WxErrorException {

XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPayUnifiedOrderRequest.class);
xstream.processAnnotations(WxPayUnifiedOrderResult.class);

initRequest(request);
this.initRequest(request);
if (StringUtils.isBlank(request.getNotifyURL())) {
request.setNotifyURL(getConfig().getNotifyURL());
}
@@ -261,12 +228,12 @@ public class WxMpPayServiceImpl implements WxMpPayService {
request.setSign(this.createSign(request));

String url = PAY_BASE_URL + "/pay/unifiedorder";
String xmlParam = xstream.toXML(request);
String xmlParam = request.toXML();
log.debug("微信统一下单接口,URL:{},参数:{}", url, xmlParam);

String responseContent = this.executeRequest(url, xmlParam);
log.debug("微信统一下单接口,URL:{},结果:{}", url, responseContent);
WxPayUnifiedOrderResult result = (WxPayUnifiedOrderResult) xstream.fromXML(responseContent);
WxPayUnifiedOrderResult result = WxPayUnifiedOrderResult.fromXML(responseContent, WxPayUnifiedOrderResult.class);
this.checkResult(result);
return result;
}
@@ -324,35 +291,27 @@ public class WxMpPayServiceImpl implements WxMpPayService {

@Override
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);
request.setSign(this.createSign(request));

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);
return result;
}

@Override
public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxErrorException {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxEntPayQueryRequest.class);
xstream.processAnnotations(WxEntPayQueryResult.class);

WxEntPayQueryRequest request = new WxEntPayQueryRequest();
initRequest(request);
this.initRequest(request);
request.setSign(this.createSign(request));

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);
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 {
SSLContext sslContext = getConfig().getSslContext();
if (null == sslContext) {
throw new Exception("请将配置类(即WxMpConfigStorage的实现类)中的SSLContext初始化");
throw new IllegalArgumentException("请先初始化配置类(即WxMpConfigStorage的实现类)中的SSLContext!");
}

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1"}, null,
@@ -412,17 +371,17 @@ public class WxMpPayServiceImpl implements WxMpPayService {

@Override
public String createSign(Object xmlBean) {
return createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey());
return this.createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey());
}

@Override
public String createSign(Object xmlBean, String signKey) {
return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey);
return this.createSign(BeanUtils.xmlBean2Map(xmlBean), signKey);
}

@Override
public String createSign(Map<String, String> params) {
return createSign(params, getConfig().getPartnerKey());
return this.createSign(params, this.getConfig().getPartnerKey());
}

@Override
@@ -443,17 +402,17 @@ public class WxMpPayServiceImpl implements WxMpPayService {

@Override
public boolean checkSign(Object xmlBean) {
return checkSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey());
return this.checkSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey());
}

@Override
public boolean checkSign(Object xmlBean, String signKey) {
return checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey);
return this.checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey);
}

@Override
public boolean checkSign(Map<String, String> params) {
return checkSign(params, getConfig().getPartnerKey());
return this.checkSign(params, getConfig().getPartnerKey());
}

@Override


+ 21
- 9
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java Parādīt failu

@@ -1,7 +1,9 @@
package me.chanjar.weixin.mp.bean.pay.request;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;

import java.math.BigDecimal;

@@ -17,6 +19,7 @@ import java.math.BigDecimal;
* <li>示例值
* <li>描述
* </pre>
*
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
*/
public abstract class WxPayBaseRequest {
@@ -69,12 +72,22 @@ public abstract class WxPayBaseRequest {
@XStreamAlias("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() {
return this.appid;
}

/**
* 如果配置中已经设置,可以不设置值
*
* @param appid 微信公众号appid
*/
public void setAppid(String appid) {
@@ -87,6 +100,7 @@ public abstract class WxPayBaseRequest {

/**
* 如果配置中已经设置,可以不设置值
*
* @param mchId 微信商户号
*/
public void setMchId(String mchId) {
@@ -99,6 +113,7 @@ public abstract class WxPayBaseRequest {

/**
* 默认采用时间戳为随机字符串,可以不设置
*
* @param nonceStr 随机字符串
*/
public void setNonceStr(String nonceStr) {
@@ -113,17 +128,14 @@ public abstract class WxPayBaseRequest {
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
public String toString() {
return ToStringUtils.toSimpleString(this);
}

public String toXML() {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(this.getClass());
return xstream.toXML(this);
}
}

+ 1
- 3
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundRequest.java Parādīt failu

@@ -1,7 +1,6 @@
package me.chanjar.weixin.mp.bean.pay.request;

import com.thoughtworks.xstream.annotations.XStreamAlias;

import me.chanjar.weixin.common.annotation.Required;

/**
@@ -144,8 +143,6 @@ public class WxPayRefundRequest extends WxPayBaseRequest {
@XStreamAlias("refund_account")
private String refundAccount;



public String getDeviceInfo() {
return this.deviceInfo;
}
@@ -217,4 +214,5 @@ public class WxPayRefundRequest extends WxPayBaseRequest {
public void setRefundAccount(String refundAccount) {
this.refundAccount = refundAccount;
}

}

+ 85
- 22
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java Parādīt failu

@@ -1,10 +1,19 @@
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 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.xml.XStreamInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.Map;

/**
@@ -15,65 +24,90 @@ import java.util.Map;
* </pre>
*/
public abstract class WxPayBaseResult {
@Override
public String toString() {
return ToStringUtils.toSimpleString(this);
}

/**
* 返回状态码
*/
@XStreamAlias("return_code")
protected String returnCode;

/**
* 返回信息
*/
@XStreamAlias("return_msg")
protected String returnMsg;
private String xmlString;
/**
* 业务结果
*/
@XStreamAlias("result_code")
private String resultCode;

/**
* 错误代码
*/
@XStreamAlias("err_code")
private String errCode;

/**
* 错误代码描述
*/
@XStreamAlias("err_code_des")
private String errCodeDes;

/**
* 公众账号ID
*/
@XStreamAlias("appid")
private String appid;

/**
* 商户号
*/
@XStreamAlias("mch_id")
private String mchId;

/**
* 随机字符串
*/
@XStreamAlias("nonce_str")
private String nonceStr;

/**
* 签名
*/
@XStreamAlias("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() {
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("暂时不支持此种类型的数据");
}
}

+ 14
- 3
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java Parādīt failu

@@ -1,10 +1,12 @@
package me.chanjar.weixin.mp.bean.pay.result;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
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 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.util.List;
@@ -376,6 +378,15 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializ

@Override
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;
}
}

+ 56
- 15
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResult.java Parādīt failu

@@ -2,6 +2,7 @@ package me.chanjar.weixin.mp.bean.pay.result;

import com.google.common.collect.Lists;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import io.restassured.path.xml.XmlPath;

import java.util.List;

@@ -186,7 +187,38 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
public void composeRefundRecords(String xmlString) {
if (this.refundCount != null && this.refundCount > 0) {
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>
*/
@XStreamAlias("refund_fee")
private String refundFee;
private Integer refundFee;

/**
* <pre>
@@ -254,7 +286,7 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
* </pre>
*/
@XStreamAlias("settlement_refund_fee")
private String settlementRefundFee;
private Integer settlementRefundFee;

/**
* <pre>
@@ -293,7 +325,7 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
* </pre>
*/
@XStreamAlias("coupon_refund_fee")
private String couponRefundFee;
private Integer couponRefundFee;

/**
* <pre>
@@ -306,7 +338,7 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
* </pre>
*/
@XStreamAlias("coupon_refund_count")
private String couponRefundCount;
private Integer couponRefundCount;

private List<RefundCoupon> refundCoupons;

@@ -364,19 +396,19 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
this.refundChannel = refundChannel;
}

public String getRefundFee() {
public Integer getRefundFee() {
return refundFee;
}

public void setRefundFee(String refundFee) {
public void setRefundFee(Integer refundFee) {
this.refundFee = refundFee;
}

public String getSettlementRefundFee() {
public Integer getSettlementRefundFee() {
return settlementRefundFee;
}

public void setSettlementRefundFee(String settlementRefundFee) {
public void setSettlementRefundFee(Integer settlementRefundFee) {
this.settlementRefundFee = settlementRefundFee;
}

@@ -396,19 +428,19 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
this.couponType = couponType;
}

public String getCouponRefundFee() {
public Integer getCouponRefundFee() {
return couponRefundFee;
}

public void setCouponRefundFee(String couponRefundFee) {
public void setCouponRefundFee(Integer couponRefundFee) {
this.couponRefundFee = couponRefundFee;
}

public String getCouponRefundCount() {
public Integer getCouponRefundCount() {
return couponRefundCount;
}

public void setCouponRefundCount(String couponRefundCount) {
public void setCouponRefundCount(Integer couponRefundCount) {
this.couponRefundCount = couponRefundCount;
}

@@ -446,6 +478,8 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
* 100
* 退款代金券批次ID ,$n为下标,$m为下标,从0开始编号
* </pre>
*
* @deprecated 貌似是被去掉了,但不知是何时!
*/
@XStreamAlias("coupon_refund_batch_id")
private String couponRefundBatchId;
@@ -474,9 +508,15 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
* </pre>
*/
@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.couponRefundId = couponRefundId;
this.couponRefundFee = couponRefundFee;
@@ -484,5 +524,6 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
}

}

}


+ 0
- 3
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java Parādīt failu

@@ -13,8 +13,6 @@ import me.chanjar.weixin.mp.bean.pay.result.*;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;

import java.io.File;

/**
* 测试支付相关接口
* Created by Binary Wang on 2016/7/28.
@@ -90,7 +88,6 @@ public class WxMpPayServiceImplTest {
*/
@Test
public void testQueryRedpack() throws Exception {
File keyFile = new File("E:\\dlt.p12");
WxPayRedpackQueryResult redpackResult = this.wxService.getPayService().queryRedpack("aaaa");
System.err.println(redpackResult);
}


+ 49
- 0
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResultTest.java Parādīt failu

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

}

}

Notiek ielāde…
Atcelt
Saglabāt