diff --git a/README.md b/README.md index 967d4595..877d901c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Weixin Java Tools —— 微信公众号&企业号开发 Java SDK +WeixinJavaTools 微信支付、公众号&企业号开发Java SDK ===================================== [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent) [![Build Status](https://travis-ci.org/Wechat-Group/weixin-java-tools.svg?branch=develop)](https://travis-ci.org/Wechat-Group/weixin-java-tools) @@ -48,7 +48,7 @@ Weixin Java Tools —— 微信公众号&企业号开发 Java SDK ## Maven & Gradle 最新正式版本 -* 公众号(订阅号、服务号): +* 公众号(订阅号、服务号及微信支付): maven: ```xml diff --git a/pom.xml b/pom.xml index c941dbc7..b257fece 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.github.binarywang weixin-java-parent - 2.6.0-SNAPSHOT + 2.5.2.BETA pom WeiXin Java Tools - Parent 微信公众号、企业号上级POM @@ -86,7 +86,8 @@ weixin-java-common weixin-java-cp weixin-java-mp - weixin-java-osgi + weixin-java-pay + diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 1d1ad69c..f2756129 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.6.0-SNAPSHOT + 2.5.2.BETA weixin-java-common diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java index 3553c5f6..1ecd9f65 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java @@ -101,6 +101,7 @@ public class WxConsts { public static final String EVT_KF_CLOSE_SESSION = "kf_close_session"; // 客服关闭会话 public static final String EVT_KF_SWITCH_SESSION = "kf_switch_session"; // 客服转接会话 public static final String EVT_POI_CHECK_NOTIFY = "poi_check_notify"; //门店审核事件推送 + public static final String EVN_SUBMIT_MEMBERCARD_USER_INFO = "submit_membercard_user_info"; //接收会员信息事件推送 //以下为微信认证事件 /** * 资质认证成功 @@ -135,13 +136,6 @@ public class WxConsts { public static final String MEDIA_VIDEO = "video"; public static final String MEDIA_THUMB = "thumb"; public static final String MEDIA_FILE = "file"; - /////////////////////// - // 文件类型 - /////////////////////// - public static final String FILE_JPG = "jpeg"; - public static final String FILE_MP3 = "mp3"; - public static final String FILE_AMR = "amr"; - public static final String FILE_MP4 = "mp4"; /** * 点击推事件 */ diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index e49f6c16..c6640046 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.6.0-SNAPSHOT + 2.5.2.BETA weixin-java-cp diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/TestConstants.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/TestConstants.java new file mode 100644 index 00000000..03c84e92 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/TestConstants.java @@ -0,0 +1,17 @@ +package me.chanjar.weixin.cp.api; + +/** + *
+ * 仅供测试使用的一些常量
+ * Created by Binary Wang on 2017-3-9.
+ * 
+ */ +public class TestConstants { + /////////////////////// + // 文件类型 + /////////////////////// + public static final String FILE_JPG = "jpeg"; + public static final String FILE_MP3 = "mp3"; + public static final String FILE_AMR = "amr"; + public static final String FILE_MP4 = "mp4"; +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java index fe379226..d9fb2605 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java @@ -54,10 +54,10 @@ public class WxCpMediaAPITest { @DataProvider public Object[][] uploadMedia() { return new Object[][]{ - new Object[]{WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, "mm.jpeg"}, - new Object[]{WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, "mm.mp3"}, - new Object[]{WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, "mm.mp4"}, - new Object[]{WxConsts.MEDIA_FILE, WxConsts.FILE_JPG, "mm.jpeg"} + new Object[]{WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, "mm.jpeg"}, + new Object[]{WxConsts.MEDIA_VOICE, TestConstants.FILE_MP3, "mm.mp3"}, + new Object[]{WxConsts.MEDIA_VIDEO, TestConstants.FILE_MP4, "mm.mp4"}, + new Object[]{WxConsts.MEDIA_FILE, TestConstants.FILE_JPG, "mm.jpeg"} }; } diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 9cbea35a..74d99189 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.6.0-SNAPSHOT + 2.5.2.BETA weixin-java-mp WeiXin Java Tools - MP @@ -18,21 +18,11 @@ weixin-java-common ${project.version} - - junit - junit - test - org.testng testng test - - org.mockito - mockito-all - test - com.google.inject guice @@ -54,16 +44,6 @@ 2.9.4 test - - io.rest-assured - xml-path - 3.0.1 - - - com.github.binarywang - qrcode-utils - 1.0 - diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java index 79ae9318..f4053899 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java @@ -3,7 +3,6 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; -import javax.net.ssl.SSLContext; import java.io.File; import java.util.concurrent.locks.Lock; @@ -82,27 +81,6 @@ public interface WxMpConfigStorage { String getSecret(); - String getPartnerId(); - - String getPartnerKey(); - - /** - * 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数。 - * - * @since 2.5.0 - */ - String getNotifyURL(); - - /** - * 交易类型 - *
-   * JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付
-   * 
- * - * @since 2.5.0 - */ - String getTradeType(); - String getToken(); String getAesKey(); @@ -121,17 +99,6 @@ public interface WxMpConfigStorage { File getTmpDirFile(); - SSLContext getSslContext(); - - void setSslContext(SSLContext sslContext); - - /** - * 在此之前,必须将partnerId进行赋值 - * - * @param filePath apiclient_cert.p12的文件的绝对路径 - */ - void setSslContextFilePath(String filePath) throws Exception; - /** * http client builder * @@ -144,8 +111,4 @@ public interface WxMpConfigStorage { */ boolean autoRefreshToken(); - /** - * 微信支付是否使用仿真测试环境 - */ - boolean useSandboxForWxPay(); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java index f2292684..4bd1daec 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java @@ -3,12 +3,8 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.util.ToStringUtils; import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; -import org.apache.http.ssl.SSLContexts; -import javax.net.ssl.SSLContext; import java.io.File; -import java.io.FileInputStream; -import java.security.KeyStore; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -21,10 +17,6 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { protected volatile String appId; protected volatile String secret; - protected volatile String partnerId; - protected volatile String partnerKey; - protected volatile String notifyURL; - protected volatile String tradeType; protected volatile String token; protected volatile String accessToken; protected volatile String aesKey; @@ -52,8 +44,6 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { */ protected volatile File tmpDirFile; - protected volatile SSLContext sslContext; - protected volatile ApacheHttpClientBuilder apacheHttpClientBuilder; @Override @@ -61,10 +51,6 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { return this.accessToken; } - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - @Override public Lock getAccessTokenLock() { return this.accessTokenLock; @@ -96,23 +82,11 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { return this.jsapiTicket; } - public void setJsapiTicket(String jsapiTicket) { - this.jsapiTicket = jsapiTicket; - } - @Override public Lock getJsapiTicketLock() { return this.jsapiTicketLock; } - public long getJsapiTicketExpiresTime() { - return this.jsapiTicketExpiresTime; - } - - public void setJsapiTicketExpiresTime(long jsapiTicketExpiresTime) { - this.jsapiTicketExpiresTime = jsapiTicketExpiresTime; - } - @Override public boolean isJsapiTicketExpired() { return System.currentTimeMillis() > this.jsapiTicketExpiresTime; @@ -256,88 +230,49 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { } @Override - public String getPartnerId() { - return this.partnerId; + public File getTmpDirFile() { + return this.tmpDirFile; } - public void setPartnerId(String partnerId) { - this.partnerId = partnerId; + public void setTmpDirFile(File tmpDirFile) { + this.tmpDirFile = tmpDirFile; } @Override - public String getPartnerKey() { - return this.partnerKey; - } - - public void setPartnerKey(String partnerKey) { - this.partnerKey = partnerKey; - } - - - public String getNotifyURL() { - return notifyURL; - } - - public void setNotifyURL(String notifyURL) { - this.notifyURL = notifyURL; - } - - public String getTradeType() { - return tradeType; + public ApacheHttpClientBuilder getApacheHttpClientBuilder() { + return this.apacheHttpClientBuilder; } - public void setTradeType(String tradeType) { - this.tradeType = tradeType; + public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { + this.apacheHttpClientBuilder = apacheHttpClientBuilder; } - @Override - public File getTmpDirFile() { - return this.tmpDirFile; + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; } - public void setTmpDirFile(File tmpDirFile) { - this.tmpDirFile = tmpDirFile; + public void setJsapiTicket(String jsapiTicket) { + this.jsapiTicket = jsapiTicket; } - @Override - public SSLContext getSslContext() { - return this.sslContext; + public long getJsapiTicketExpiresTime() { + return this.jsapiTicketExpiresTime; } - @Override - public void setSslContext(SSLContext context) { - this.sslContext = context; + public void setJsapiTicketExpiresTime(long jsapiTicketExpiresTime) { + this.jsapiTicketExpiresTime = jsapiTicketExpiresTime; } - @Override - public void setSslContextFilePath(String filePath) { - if (null == partnerId) { - throw new IllegalArgumentException("请设置partnerId的值"); - } - - File file = new File(filePath); - if (!file.exists()) { - 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); - } + public void setCardApiTicket(String cardApiTicket) { + this.cardApiTicket = cardApiTicket; } - @Override - public ApacheHttpClientBuilder getApacheHttpClientBuilder() { - return this.apacheHttpClientBuilder; + public long getCardApiTicketExpiresTime() { + return this.cardApiTicketExpiresTime; } - public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { - this.apacheHttpClientBuilder = apacheHttpClientBuilder; + public void setCardApiTicketExpiresTime(long cardApiTicketExpiresTime) { + this.cardApiTicketExpiresTime = cardApiTicketExpiresTime; } @Override @@ -345,8 +280,4 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { return true; } - @Override - public boolean useSandboxForWxPay() { - return false; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index dc05a2ee..cf1401a5 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -311,13 +311,6 @@ public interface WxMpService { */ WxMpCardService getCardService(); - /** - * 返回微信支付相关接口方法的实现类对象,以方便调用其各个接口 - * - * @return WxMpPayService - */ - WxMpPayService getPayService(); - /** * 返回数据分析统计相关接口方法的实现类对象,以方便调用其各个接口 * diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java index eb1e58aa..406e8712 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java @@ -28,9 +28,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.concurrent.locks.Lock; -//import org.apache.http.conn.ssl.DefaultHostnameVerifier; -//import org.apache.http.conn.ssl.SSLConnectionSocketFactory; - public class WxMpServiceImpl implements WxMpService { private static final JsonParser JSON_PARSER = new JsonParser(); @@ -45,7 +42,6 @@ public class WxMpServiceImpl implements WxMpService { private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this); private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this); private WxMpCardService cardService = new WxMpCardServiceImpl(this); - private WxMpPayService payService = new WxMpPayServiceImpl(this); private WxMpStoreService storeService = new WxMpStoreServiceImpl(this); private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this); private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); @@ -59,7 +55,7 @@ public class WxMpServiceImpl implements WxMpService { @Override public boolean checkSignature(String timestamp, String nonce, String signature) { try { - return SHA1.gen(this.wxMpConfigStorage.getToken(), timestamp, nonce) + return SHA1.gen(this.getWxMpConfigStorage().getToken(), timestamp, nonce) .equals(signature); } catch (Exception e) { return false; @@ -73,18 +69,18 @@ public class WxMpServiceImpl implements WxMpService { @Override public String getAccessToken(boolean forceRefresh) throws WxErrorException { - Lock lock = this.wxMpConfigStorage.getAccessTokenLock(); + Lock lock = this.getWxMpConfigStorage().getAccessTokenLock(); try { lock.lock(); if (forceRefresh) { - this.wxMpConfigStorage.expireAccessToken(); + this.getWxMpConfigStorage().expireAccessToken(); } - if (this.wxMpConfigStorage.isAccessTokenExpired()) { + if (this.getWxMpConfigStorage().isAccessTokenExpired()) { String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" + - "&appid=" + this.wxMpConfigStorage.getAppId() + "&secret=" - + this.wxMpConfigStorage.getSecret(); + "&appid=" + this.getWxMpConfigStorage().getAppId() + "&secret=" + + this.getWxMpConfigStorage().getSecret(); try { HttpGet httpGet = new HttpGet(url); if (this.httpProxy != null) { @@ -98,7 +94,7 @@ public class WxMpServiceImpl implements WxMpService { throw new WxErrorException(error); } WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); - this.wxMpConfigStorage.updateAccessToken(accessToken.getAccessToken(), + this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); } finally { httpGet.releaseConnection(); @@ -110,7 +106,7 @@ public class WxMpServiceImpl implements WxMpService { } finally { lock.unlock(); } - return this.wxMpConfigStorage.getAccessToken(); + return this.getWxMpConfigStorage().getAccessToken(); } @Override @@ -120,27 +116,27 @@ public class WxMpServiceImpl implements WxMpService { @Override public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { - Lock lock = this.wxMpConfigStorage.getJsapiTicketLock(); + Lock lock = this.getWxMpConfigStorage().getJsapiTicketLock(); try { lock.lock(); if (forceRefresh) { - this.wxMpConfigStorage.expireJsapiTicket(); + this.getWxMpConfigStorage().expireJsapiTicket(); } - if (this.wxMpConfigStorage.isJsapiTicketExpired()) { + if (this.getWxMpConfigStorage().isJsapiTicketExpired()) { String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi"; String responseContent = execute(new SimpleGetRequestExecutor(), url, null); JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); - this.wxMpConfigStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds); + this.getWxMpConfigStorage().updateJsapiTicket(jsapiTicket, expiresInSeconds); } } finally { lock.unlock(); } - return this.wxMpConfigStorage.getJsapiTicket(); + return this.getWxMpConfigStorage().getJsapiTicket(); } @Override @@ -151,7 +147,7 @@ public class WxMpServiceImpl implements WxMpService { String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, "noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url); WxJsapiSignature jsapiSignature = new WxJsapiSignature(); - jsapiSignature.setAppId(this.wxMpConfigStorage.getAppId()); + jsapiSignature.setAppId(this.getWxMpConfigStorage().getAppId()); jsapiSignature.setTimestamp(timestamp); jsapiSignature.setNonceStr(noncestr); jsapiSignature.setUrl(url); @@ -216,7 +212,7 @@ public class WxMpServiceImpl implements WxMpService { public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) { StringBuilder url = new StringBuilder(); url.append("https://open.weixin.qq.com/connect/oauth2/authorize?"); - url.append("appid=").append(this.wxMpConfigStorage.getAppId()); + url.append("appid=").append(this.getWxMpConfigStorage().getAppId()); url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI)); url.append("&response_type=code"); url.append("&scope=").append(scope); @@ -232,7 +228,7 @@ public class WxMpServiceImpl implements WxMpService { String state) { StringBuilder url = new StringBuilder(); url.append("https://open.weixin.qq.com/connect/qrconnect?"); - url.append("appid=").append(this.wxMpConfigStorage.getAppId()); + url.append("appid=").append(this.getWxMpConfigStorage().getAppId()); url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI)); url.append("&response_type=code"); url.append("&scope=").append(scope); @@ -258,8 +254,8 @@ public class WxMpServiceImpl implements WxMpService { public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException { StringBuilder url = new StringBuilder(); url.append("https://api.weixin.qq.com/sns/oauth2/access_token?"); - url.append("appid=").append(this.wxMpConfigStorage.getAppId()); - url.append("&secret=").append(this.wxMpConfigStorage.getSecret()); + url.append("appid=").append(this.getWxMpConfigStorage().getAppId()); + url.append("&secret=").append(this.getWxMpConfigStorage().getSecret()); url.append("&code=").append(code); url.append("&grant_type=authorization_code"); @@ -270,7 +266,7 @@ public class WxMpServiceImpl implements WxMpService { public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException { StringBuilder url = new StringBuilder(); url.append("https://api.weixin.qq.com/sns/oauth2/refresh_token?"); - url.append("appid=").append(this.wxMpConfigStorage.getAppId()); + url.append("appid=").append(this.getWxMpConfigStorage().getAppId()); url.append("&grant_type=refresh_token"); url.append("&refresh_token=").append(refreshToken); @@ -397,8 +393,8 @@ public class WxMpServiceImpl implements WxMpService { */ if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token - this.wxMpConfigStorage.expireAccessToken(); - if (this.wxMpConfigStorage.autoRefreshToken()) { + this.getWxMpConfigStorage().expireAccessToken(); + if (this.getWxMpConfigStorage().autoRefreshToken()) { return this.execute(executor, uri, data); } } @@ -424,26 +420,19 @@ public class WxMpServiceImpl implements WxMpService { } private void initHttpClient() { - ApacheHttpClientBuilder apacheHttpClientBuilder = this.wxMpConfigStorage - .getApacheHttpClientBuilder(); + WxMpConfigStorage configStorage = this.getWxMpConfigStorage(); + ApacheHttpClientBuilder apacheHttpClientBuilder = configStorage.getApacheHttpClientBuilder(); if (null == apacheHttpClientBuilder) { apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); } - apacheHttpClientBuilder.httpProxyHost(this.wxMpConfigStorage.getHttpProxyHost()) - .httpProxyPort(this.wxMpConfigStorage.getHttpProxyPort()) - .httpProxyUsername(this.wxMpConfigStorage.getHttpProxyUsername()) - .httpProxyPassword(this.wxMpConfigStorage.getHttpProxyPassword()); - - // if (this.wxMpConfigStorage.getSSLContext() != null) { - // SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( - // this.wxMpConfigStorage.getSSLContext(), new String[] { "TLSv1" }, null, - // new DefaultHostnameVerifier()); - // apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf); - // } + apacheHttpClientBuilder.httpProxyHost(configStorage.getHttpProxyHost()) + .httpProxyPort(configStorage.getHttpProxyPort()) + .httpProxyUsername(configStorage.getHttpProxyUsername()) + .httpProxyPassword(configStorage.getHttpProxyPassword()); - if (this.wxMpConfigStorage.getHttpProxyHost() != null && this.wxMpConfigStorage.getHttpProxyPort() > 0) { - this.httpProxy = new HttpHost(this.wxMpConfigStorage.getHttpProxyHost(), this.wxMpConfigStorage.getHttpProxyPort()); + if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { + this.httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); } this.httpClient = apacheHttpClientBuilder.build(); @@ -505,11 +494,6 @@ public class WxMpServiceImpl implements WxMpService { return this.cardService; } - @Override - public WxMpPayService getPayService() { - return this.payService; - } - @Override public WxMpDataCubeService getDataCubeService() { return this.dataCubeService; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java deleted file mode 100644 index 1cf783a8..00000000 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java +++ /dev/null @@ -1,392 +0,0 @@ -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 me.chanjar.weixin.mp.bean.pay.WxPayOrderNotifyResultConverter; - -import java.io.Serializable; -import java.util.List; -import java.util.Map; - -/** - * 支付结果通用通知 ,文档见:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 - * @author aimilin6688 - * @since 2.5.0 - */ -@XStreamAlias("xml") -public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializable { - - private static final long serialVersionUID = 5389718115223345496L; - - - /** - *
-	 * 设备号
-	 * device_info
-	 * 否
-	 * String(32)
-	 * 013467007045764
-	 * 微信支付分配的终端设备号,
-	 * 
- */ - @XStreamAlias("device_info") - private String deviceInfo; - - /** - *
-	 * 用户标识
-	 * openid
-	 * 是
-	 * String(128)
-	 * wxd930ea5d5a258f4f
-	 * 用户在商户appid下的唯一标识
-	 * 
- */ - @XStreamAlias("openid") - private String openid; - - /** - *
-	 * 是否关注公众账号
-	 * is_subscribe
-	 * 否
-	 * String(1)
-	 * Y
-	 * 用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
-	 * 
- */ - @XStreamAlias("is_subscribe") - private String isSubscribe; - - - /** - *
-	 * 交易类型
-	 * trade_type
-	 * 是
-	 * String(16)
-	 * JSAPI	JSAPI、NATIVE、APP
-	 * 
- */ - @XStreamAlias("trade_type") - private String tradeType; - - - /** - *
-	 * 付款银行
-	 * bank_type
-	 * 是
-	 * String(16)
-	 * CMC
-	 * 银行类型,采用字符串类型的银行标识,银行类型见银行列表
-	 * 
- */ - @XStreamAlias("bank_type") - private String bankType; - - - /** - *
-	 * 订单金额
-	 * total_fee
-	 * 是
-	 * Int
-	 * 100
-	 * 订单总金额,单位为分
-	 * 
- */ - @XStreamAlias("total_fee") - private Integer totalFee; - /** - *
-	 * 应结订单金额
-	 * settlement_total_fee
-	 * 否
-	 * Int
-	 * 100
-	 * 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
-	 * 
- */ - @XStreamAlias("settlement_total_fee") - private Integer settlementTotalFee; - /** - *
-	 * 货币种类
-	 * fee_type
-	 * 否
-	 * String(8)
-	 * CNY
-	 * 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
-	 * 
- */ - @XStreamAlias("fee_type") - private String feeType; - /** - *
-	 * 现金支付金额
-	 * cash_fee
-	 * 是
-	 * Int
-	 * 100
-	 * 现金支付金额订单现金支付金额,详见支付金额
-	 * 
- */ - @XStreamAlias("cash_fee") - private Integer cashFee; - /** - *
-	 * 现金支付货币类型
-	 * cash_fee_type
-	 * 否
-	 * String(16)
-	 * CNY
-	 * 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
-	 * 
- */ - @XStreamAlias("cash_fee_type") - private String cashFeeType; - /** - *
-	 * 总代金券金额
-	 * coupon_fee
-	 * 否
-	 * Int
-	 * 10
-	 * 代金券金额<=订单金额,订单金额-代金券金额=现金支付金额,详见支付金额
-	 * 
- */ - @XStreamAlias("coupon_fee") - private Integer couponFee; - - /** - *
-   * 代金券使用数量
-   * coupon_count
-   * 否
-   * Int
-   * 1
-   * 代金券使用数量
-   * 
- */ - @XStreamAlias("coupon_count") - private Integer couponCount; - - private List couponList; - - /** - *
-	 * 微信支付订单号
-	 * transaction_id
-	 * 是
-	 * String(32)
-	 * 1217752501201407033233368018
-	 * 微信支付订单号
-	 * 
- */ - @XStreamAlias("transaction_id") - private String transactionId; - - /** - *
-	 * 商户订单号
-	 * out_trade_no
-	 * 是
-	 * String(32)
-	 * 1212321211201407033568112322
-	 * 商户系统的订单号,与请求一致。
-	 * 
- */ - @XStreamAlias("out_trade_no") - private String outTradeNo; - /** - *
-	 * 商家数据包
-	 * attach
-	 * 否
-	 * String(128)
-	 * 123456
-	 * 商家数据包,原样返回
-	 * 
- */ - @XStreamAlias("attach") - private String attach; - /** - *
-	 * 支付完成时间
-	 * time_end
-	 * 是
-	 * String(14)
-	 * 20141030133525
-	 * 支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
-	 * 
- */ - @XStreamAlias("time_end") - private String timeEnd; - - public Integer getCouponCount() { - return couponCount; - } - - public void setCouponCount(Integer couponCount) { - this.couponCount = couponCount; - } - - public List getCouponList() { - return couponList; - } - - public void setCouponList(List couponList) { - this.couponList = couponList; - } - - public String getDeviceInfo() { - return deviceInfo; - } - - public void setDeviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - } - - public String getOpenid() { - return openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - - public String getIsSubscribe() { - return isSubscribe; - } - - public void setIsSubscribe(String isSubscribe) { - this.isSubscribe = isSubscribe; - } - - public String getTradeType() { - return tradeType; - } - - public void setTradeType(String tradeType) { - this.tradeType = tradeType; - } - - public String getBankType() { - return bankType; - } - - public void setBankType(String bankType) { - this.bankType = bankType; - } - - public Integer getTotalFee() { - return totalFee; - } - - public void setTotalFee(Integer totalFee) { - this.totalFee = totalFee; - } - - public Integer getSettlementTotalFee() { - return settlementTotalFee; - } - - public void setSettlementTotalFee(Integer settlementTotalFee) { - this.settlementTotalFee = settlementTotalFee; - } - - public String getFeeType() { - return feeType; - } - - public void setFeeType(String feeType) { - this.feeType = feeType; - } - - public Integer getCashFee() { - return cashFee; - } - - public void setCashFee(Integer cashFee) { - this.cashFee = cashFee; - } - - public String getCashFeeType() { - return cashFeeType; - } - - public void setCashFeeType(String cashFeeType) { - this.cashFeeType = cashFeeType; - } - - public Integer getCouponFee() { - return couponFee; - } - - public void setCouponFee(Integer couponFee) { - this.couponFee = couponFee; - } - - public String getTransactionId() { - return transactionId; - } - - public void setTransactionId(String transactionId) { - this.transactionId = transactionId; - } - - public String getOutTradeNo() { - return outTradeNo; - } - - public void setOutTradeNo(String outTradeNo) { - this.outTradeNo = outTradeNo; - } - - public String getAttach() { - return attach; - } - - public void setAttach(String attach) { - this.attach = attach; - } - - public String getTimeEnd() { - return timeEnd; - } - - public void setTimeEnd(String timeEnd) { - this.timeEnd = timeEnd; - } - - @Override - public Map toMap(){ - Map resultMap = BeanUtils.xmlBean2Map(this); - if(this.getCouponCount() != null && this.getCouponCount() > 0){ - for (int i = 0; i < this.getCouponCount(); i++) { - WxPayOrderNotifyCoupon coupon = couponList.get(i); - resultMap.putAll(coupon.toMap(i)); - } - } - return resultMap; - } - - @Override - public String toString() { - 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; - } -} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java index 3c42f66c..dd7541ff 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java @@ -6,6 +6,7 @@ import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.api.test.TestConfigStorage; +import me.chanjar.weixin.mp.api.test.TestConstants; import me.chanjar.weixin.mp.bean.WxMpMassNews; import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; import me.chanjar.weixin.mp.bean.WxMpMassTagMessage; @@ -101,7 +102,7 @@ public class WxMpMassMessageAPITest { .getSystemResourceAsStream("mm.mp4")) { // 上传视频到媒体库 WxMediaUploadResult uploadMediaRes = this.wxService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, inputStream); + .mediaUpload(WxConsts.MEDIA_VIDEO, TestConstants.FILE_MP4, inputStream); Assert.assertNotNull(uploadMediaRes); Assert.assertNotNull(uploadMediaRes.getMediaId()); @@ -122,7 +123,7 @@ public class WxMpMassMessageAPITest { try (InputStream inputStream = ClassLoader .getSystemResourceAsStream("mm.jpeg")) { WxMediaUploadResult uploadMediaRes = this.wxService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, inputStream); + .mediaUpload(WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, inputStream); Assert.assertNotNull(uploadMediaRes); Assert.assertNotNull(uploadMediaRes.getMediaId()); messages[1] = new Object[]{WxConsts.MASS_MSG_IMAGE, uploadMediaRes.getMediaId()}; @@ -134,7 +135,7 @@ public class WxMpMassMessageAPITest { try (InputStream inputStream = ClassLoader .getSystemResourceAsStream("mm.mp3")) { WxMediaUploadResult uploadMediaRes = this.wxService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, inputStream); + .mediaUpload(WxConsts.MEDIA_VOICE, TestConstants.FILE_MP3, inputStream); Assert.assertNotNull(uploadMediaRes); Assert.assertNotNull(uploadMediaRes.getMediaId()); messages[2] = new Object[]{WxConsts.MASS_MSG_VOICE, uploadMediaRes.getMediaId()}; @@ -147,7 +148,7 @@ public class WxMpMassMessageAPITest { .getSystemResourceAsStream("mm.jpeg")) { // 上传照片到媒体库 WxMediaUploadResult uploadMediaRes = this.wxService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, inputStream); + .mediaUpload(WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, inputStream); Assert.assertNotNull(uploadMediaRes); Assert.assertNotNull(uploadMediaRes.getMediaId()); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImplTest.java index ca90a7b5..6bb1e58b 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImplTest.java @@ -7,6 +7,7 @@ import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; +import me.chanjar.weixin.mp.api.test.TestConstants; import me.chanjar.weixin.mp.bean.material.*; import org.testng.annotations.*; @@ -45,10 +46,10 @@ public class WxMpMaterialServiceImplTest { @DataProvider public Object[][] mediaFiles() { return new Object[][]{ - new Object[]{WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, "mm.jpeg"}, - new Object[]{WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, "mm.mp3"}, - new Object[]{WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, "mm.mp4"}, - new Object[]{WxConsts.MEDIA_THUMB, WxConsts.FILE_JPG, "mm.jpeg"} + new Object[]{WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, "mm.jpeg"}, + new Object[]{WxConsts.MEDIA_VOICE, TestConstants.FILE_MP3, "mm.mp3"}, + new Object[]{WxConsts.MEDIA_VIDEO, TestConstants.FILE_MP4, "mm.mp4"}, + new Object[]{WxConsts.MEDIA_THUMB, TestConstants.FILE_JPG, "mm.jpeg"} }; } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java deleted file mode 100644 index 2783ee7f..00000000 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java +++ /dev/null @@ -1,195 +0,0 @@ -package me.chanjar.weixin.mp.api.impl; - -import com.github.binarywang.utils.qrcode.QrcodeUtils; -import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.test.ApiTestModule; -import me.chanjar.weixin.mp.api.test.TestConfigStorage; -import me.chanjar.weixin.mp.bean.pay.request.*; -import me.chanjar.weixin.mp.bean.pay.result.*; -import org.testng.annotations.*; - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.testng.Assert.*; - -/** - * 测试支付相关接口 - * Created by Binary Wang on 2016/7/28. - * - * @author binarywang (https://github.com/binarywang) - */ -@Test -@Guice(modules = ApiTestModule.class) -public class WxMpPayServiceImplTest { - - @Inject - protected WxMpService wxService; - - @Test - public void testGetPayInfo() throws Exception { - - } - - @Test - public void testDownloadBill() throws Exception { - File file = this.wxService.getPayService().downloadBill("20170101", "ALL", "GZIP", "1111111"); - assertNotNull(file); - //必填字段为空时,抛出异常 - this.wxService.getPayService().downloadBill("", "", "", null); - } - - @Test - public void testReport() throws Exception { - WxPayReportRequest request = new WxPayReportRequest(); - request.setInterfaceUrl("hahahah"); - request.setSignType("HMAC-SHA256");//貌似接口未校验此字段 - request.setExecuteTime(1000); - request.setReturnCode("aaa"); - request.setResultCode("aaa"); - request.setUserIp("8.8.8"); - this.wxService.getPayService().report(request); - } - - /** - * 需要证书的接口需要先执行该方法 - */ - @Test - public void setSSLKey() { - TestConfigStorage config = (TestConfigStorage) this.wxService.getWxMpConfigStorage(); - config.setSslContextFilePath(config.getKeyPath()); - } - - /** - * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#refund(WxPayRefundRequest)} . - */ - @Test(dependsOnMethods = {"setSSLKey"}) - public void testRefund() throws Exception { - WxPayRefundRequest request = new WxPayRefundRequest(); - request.setOutRefundNo("aaa"); - request.setOutTradeNo("1111"); - request.setTotalFee(1222); - request.setRefundFee(111); - WxPayRefundResult result = this.wxService.getPayService().refund(request); - System.err.println(result); - } - - /** - * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#refundQuery(String, String, String, String)} . - */ - @Test - public void testRefundQuery() throws Exception { - WxPayRefundQueryResult result; - - result = this.wxService.getPayService().refundQuery("1", "", "", ""); - System.err.println(result); - result = this.wxService.getPayService().refundQuery("", "2", "", ""); - System.err.println(result); - result = this.wxService.getPayService().refundQuery("", "", "3", ""); - System.err.println(result); - result = this.wxService.getPayService().refundQuery("", "", "", "4"); - System.err.println(result); - //测试四个参数都填的情况,应该报异常的 - result = this.wxService.getPayService().refundQuery("1", "2", "3", "4"); - System.err.println(result); - } - - /** - * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#sendRedpack(WxPaySendRedpackRequest)} . - */ - @Test(dependsOnMethods = {"setSSLKey"}) - public void testSendRedpack() throws Exception { - WxPaySendRedpackRequest request = new WxPaySendRedpackRequest(); - request.setActName("abc"); - request.setClientIp("aaa"); - request.setMchBillNo("aaaa"); - request - .setReOpenid(((TestConfigStorage) this.wxService.getWxMpConfigStorage()).getOpenid()); - WxPaySendRedpackResult redpackResult = this.wxService.getPayService().sendRedpack(request); - System.err.println(redpackResult); - } - - /** - * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#queryRedpack(String)}. - */ - @Test(dependsOnMethods = {"setSSLKey"}) - public void testQueryRedpack() throws Exception { - WxPayRedpackQueryResult redpackResult = this.wxService.getPayService().queryRedpack("aaaa"); - System.err.println(redpackResult); - } - - /** - * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#unifiedOrder(WxPayUnifiedOrderRequest)}. - */ - @Test - public void testUnifiedOrder() throws WxErrorException { - WxPayUnifiedOrderResult result = this.wxService.getPayService() - .unifiedOrder(WxPayUnifiedOrderRequest.builder().body("1111111") - .totalFee(1).spbillCreateIp("111111").notifyURL("111111") - .tradeType("JSAPI").openid("122").outTradeNo("111111").build()); - System.err.println(result); - } - - /** - * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#queryOrder(String, String)} . - */ - @Test - public final void testQueryOrder() throws WxErrorException { - //System.err.println(this.wxService.getPayService().queryOrder(null, null)); - System.err.println(this.wxService.getPayService().queryOrder("11212121", null)); - System.err.println(this.wxService.getPayService().queryOrder(null, "11111")); - } - - /** - * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#closeOrder(String)} . - */ - @Test - public final void testCloseOrder() throws WxErrorException { - System.err.println(this.wxService.getPayService().closeOrder("11212121")); - } - - /** - * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#entPay(WxEntPayRequest)}. - */ - @Test(dependsOnMethods = {"setSSLKey"}) - public final void testEntPay() throws WxErrorException { - WxEntPayRequest request = new WxEntPayRequest(); - System.err.println(this.wxService.getPayService().entPay(request)); - } - - /** - * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#queryEntPay(String)}. - */ - @Test(dependsOnMethods = {"setSSLKey"}) - public final void testQueryEntPay() throws WxErrorException { - System.err.println(this.wxService.getPayService().queryEntPay("11212121")); - } - - @Test - public void testCreateScanPayQrcodeMode1() throws Exception { - String productId = "abc"; - byte[] bytes = this.wxService.getPayService().createScanPayQrcodeMode1(productId, null, null); - Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); - Files.write(qrcodeFilePath, bytes); - String qrcodeContent = QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()); - System.out.println(qrcodeContent); - - assertTrue(qrcodeContent.startsWith("weixin://wxpay/bizpayurl?")); - assertTrue(qrcodeContent.contains("product_id=" + productId)); - } - - @Test - public void testCreateScanPayQrcodeMode2() throws Exception { - String qrcodeContent = "abc"; - byte[] bytes = this.wxService.getPayService().createScanPayQrcodeMode2(qrcodeContent, null, null); - Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); - Files.write(qrcodeFilePath, bytes); - - assertEquals(QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()), qrcodeContent); - } - - -} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java index c957bde8..31ad47b6 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java @@ -17,8 +17,7 @@ public class ApiTestModule implements Module { @Override public void configure(Binder binder) { try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) { - TestConfigStorage config = this - .fromXml(TestConfigStorage.class, is1); + TestConfigStorage config = this.fromXml(TestConfigStorage.class, is1); config.setAccessTokenLock(new ReentrantLock()); WxMpService wxService = new WxMpServiceImpl(); wxService.setWxMpConfigStorage(config); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java index 0dc91151..6400f81d 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java @@ -64,10 +64,4 @@ public class TestConfigStorage extends WxMpInMemoryConfigStorage { super.accessTokenLock = lock; } - @Override - public boolean useSandboxForWxPay() { - return false; - //沙箱环境不成熟,有问题无法使用,暂时屏蔽掉 - // return true; - } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConstants.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConstants.java new file mode 100644 index 00000000..557e0dc0 --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConstants.java @@ -0,0 +1,17 @@ +package me.chanjar.weixin.mp.api.test; + +/** + *
+ * 仅供测试使用的一些常量
+ * Created by Binary Wang on 2017-3-9.
+ * 
+ */ +public class TestConstants { + /////////////////////// + // 文件类型 + /////////////////////// + public static final String FILE_JPG = "jpeg"; + public static final String FILE_MP3 = "mp3"; + public static final String FILE_AMR = "amr"; + public static final String FILE_MP4 = "mp4"; +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoImageHandler.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoImageHandler.java index 2cfb8ce3..2390071b 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoImageHandler.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoImageHandler.java @@ -6,6 +6,7 @@ import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.test.TestConstants; import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.message.WxMpXmlOutImageMessage; import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; @@ -18,7 +19,7 @@ public class DemoImageHandler implements WxMpMessageHandler { WxMpService wxMpService, WxSessionManager sessionManager) { try { WxMediaUploadResult wxMediaUploadResult = wxMpService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, ClassLoader.getSystemResourceAsStream("mm.jpeg")); + .mediaUpload(WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, ClassLoader.getSystemResourceAsStream("mm.jpeg")); WxMpXmlOutImageMessage m = WxMpXmlOutMessage .IMAGE() diff --git a/weixin-java-osgi/pom.xml b/weixin-java-osgi/pom.xml index 892870f0..b44ef85d 100644 --- a/weixin-java-osgi/pom.xml +++ b/weixin-java-osgi/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.6.0-SNAPSHOT + 2.5.2.BETA weixin-java-osgi diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml new file mode 100644 index 00000000..a192271b --- /dev/null +++ b/weixin-java-pay/pom.xml @@ -0,0 +1,52 @@ + + + + weixin-java-parent + com.github.binarywang + 2.5.2.BETA + + 4.0.0 + + weixin-java-pay + WeiXin Java Tools - PAY + 微信支付 Java SDK + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + + org.jodd + jodd-http + 3.7 + + + + io.rest-assured + xml-path + 3.0.1 + + + com.github.binarywang + qrcode-utils + 1.0 + + + + org.testng + testng + test + + + com.google.inject + guice + test + + + + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyCoupon.java similarity index 93% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyCoupon.java index 60b3f688..c72ddcb2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyCoupon.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyCoupon.java @@ -1,64 +1,63 @@ -package me.chanjar.weixin.mp.bean.pay; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; - -import com.thoughtworks.xstream.annotations.XStreamAlias; - -/** - * 支付异步通知代金券详细 - */ -public class WxPayOrderNotifyCoupon implements Serializable { - /** - * @fields serialVersionUID - */ - private static final long serialVersionUID = -4165343733538156097L; - - @XStreamAlias("coupon_id") - private String couponId; - @XStreamAlias("coupon_type") - private String couponType; - @XStreamAlias("coupon_fee") - private Integer couponFee; - - public String getCouponId() { - return couponId; - } - - public void setCouponId(String couponId) { - this.couponId = couponId; - } - - public String getCouponType() { - return couponType; - } - - public void setCouponType(String couponType) { - this.couponType = couponType; - } - - public Integer getCouponFee() { - return couponFee; - } - - public void setCouponFee(Integer couponFee) { - this.couponFee = couponFee; - } - - public Map toMap(int index) { - Map map = new HashMap<>(); - map.put("coupon_id_" + index, this.getCouponId()); - map.put("coupon_type_" + index, this.getCouponType()); - map.put("coupon_fee_" + index, this.getCouponFee() + ""); - return map; - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); - } -} +package com.github.binarywang.wxpay.bean; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * 支付异步通知代金券详细 + */ +public class WxPayOrderNotifyCoupon implements Serializable { + /** + * @fields serialVersionUID + */ + private static final long serialVersionUID = -4165343733538156097L; + + @XStreamAlias("coupon_id") + private String couponId; + @XStreamAlias("coupon_type") + private String couponType; + @XStreamAlias("coupon_fee") + private Integer couponFee; + + public String getCouponId() { + return couponId; + } + + public void setCouponId(String couponId) { + this.couponId = couponId; + } + + public String getCouponType() { + return couponType; + } + + public void setCouponType(String couponType) { + this.couponType = couponType; + } + + public Integer getCouponFee() { + return couponFee; + } + + public void setCouponFee(Integer couponFee) { + this.couponFee = couponFee; + } + + public Map toMap(int index) { + Map map = new HashMap<>(); + map.put("coupon_id_" + index, this.getCouponId()); + map.put("coupon_type_" + index, this.getCouponType()); + map.put("coupon_fee_" + index, this.getCouponFee() + ""); + return map; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyResponse.java similarity index 94% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyResponse.java index a1313ea0..7df76a95 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResponse.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyResponse.java @@ -1,60 +1,59 @@ -package me.chanjar.weixin.mp.bean.pay; - -import com.thoughtworks.xstream.XStream; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamOmitField; - -import me.chanjar.weixin.common.util.xml.XStreamInitializer; - -@XStreamAlias("xml") -public class WxPayOrderNotifyResponse { - @XStreamOmitField - private transient static final String FAIL = "FAIL"; - @XStreamOmitField - private transient static final String SUCCESS = "SUCCESS"; - - @XStreamAlias("return_code") - private String returnCode; - @XStreamAlias("return_msg") - private String returnMsg; - - public String getReturnCode() { - return returnCode; - } - - public void setReturnCode(String returnCode) { - this.returnCode = returnCode; - } - - public String getReturnMsg() { - return returnMsg; - } - - public void setReturnMsg(String returnMsg) { - this.returnMsg = returnMsg; - } - - public WxPayOrderNotifyResponse() { - super(); - } - - public WxPayOrderNotifyResponse(String returnCode, String returnMsg) { - super(); - this.returnCode = returnCode; - this.returnMsg = returnMsg; - } - - public static String fail(String msg) { - WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(FAIL, msg); - XStream xstream = XStreamInitializer.getInstance(); - xstream.autodetectAnnotations(true); - return xstream.toXML(response); - } - - public static String success(String msg) { - WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(SUCCESS, msg); - XStream xstream = XStreamInitializer.getInstance(); - xstream.autodetectAnnotations(true); - return xstream.toXML(response); - } -} +package com.github.binarywang.wxpay.bean; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamOmitField; +import me.chanjar.weixin.common.util.xml.XStreamInitializer; + +@XStreamAlias("xml") +public class WxPayOrderNotifyResponse { + @XStreamOmitField + private transient static final String FAIL = "FAIL"; + @XStreamOmitField + private transient static final String SUCCESS = "SUCCESS"; + + @XStreamAlias("return_code") + private String returnCode; + @XStreamAlias("return_msg") + private String returnMsg; + + public WxPayOrderNotifyResponse() { + super(); + } + + public WxPayOrderNotifyResponse(String returnCode, String returnMsg) { + super(); + this.returnCode = returnCode; + this.returnMsg = returnMsg; + } + + public static String fail(String msg) { + WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(FAIL, msg); + XStream xstream = XStreamInitializer.getInstance(); + xstream.autodetectAnnotations(true); + return xstream.toXML(response); + } + + public static String success(String msg) { + WxPayOrderNotifyResponse response = new WxPayOrderNotifyResponse(SUCCESS, msg); + XStream xstream = XStreamInitializer.getInstance(); + xstream.autodetectAnnotations(true); + return xstream.toXML(response); + } + + public String getReturnCode() { + return returnCode; + } + + public void setReturnCode(String returnCode) { + this.returnCode = returnCode; + } + + public String getReturnMsg() { + return returnMsg; + } + + public void setReturnMsg(String returnMsg) { + this.returnMsg = returnMsg; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java similarity index 87% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java index df2de905..5574948a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.request; +package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; import me.chanjar.weixin.common.annotation.Required; @@ -16,6 +16,7 @@ import me.chanjar.weixin.common.util.ToStringUtils; *
  • 描述 * * Created by Binary Wang on 2016/10/19. + * * @author binarywang (https://github.com/binarywang) */ @XStreamAlias("xml") @@ -29,20 +30,20 @@ public class WxEntPayQueryRequest extends WxPayBaseRequest { * String(32) * 微信支付分配的商户号 * - */ + */ @XStreamAlias("mchid") private String mchId; /** *
    -  * 商户订单号
    -  * partner_trade_no
    -  * 是
    -  * 10000098201411111234567890
    -  * String
    -  * 商户订单号
    +   * 商户订单号
    +   * partner_trade_no
    +   * 是
    +   * 10000098201411111234567890
    +   * String
    +   * 商户订单号
        * 
    - */ + */ @Required @XStreamAlias("partner_trade_no") private String partnerTradeNo; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java similarity index 63% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java index bc6ae574..56783883 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxEntPayRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.request; +package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; import me.chanjar.weixin.common.util.ToStringUtils; @@ -15,140 +15,141 @@ import me.chanjar.weixin.common.util.ToStringUtils; *
  • 描述 * * Created by Binary Wang on 2016/10/02. + * * @author binarywang (https://github.com/binarywang) */ @XStreamAlias("xml") -public class WxEntPayRequest extends WxPayBaseRequest{ +public class WxEntPayRequest extends WxPayBaseRequest { /** *
    -  * 公众账号appid
    -  * mch_appid
    -  * 是
    -  * wx8888888888888888
    -  * String
    -  * 微信分配的公众账号ID(企业号corpid即为此appId)
    +   * 公众账号appid
    +   * mch_appid
    +   * 是
    +   * wx8888888888888888
    +   * String
    +   * 微信分配的公众账号ID(企业号corpid即为此appId)
        * 
    - */ + */ @XStreamAlias("mch_appid") private String mchAppid; /** *
    -  *  商户号
    -  *  mchid
    -  *  是
    -  *  1900000109
    -  *  String(32)
    -  *  微信支付分配的商户号
    +   *  商户号
    +   *  mchid
    +   *  是
    +   *  1900000109
    +   *  String(32)
    +   *  微信支付分配的商户号
        * 
    - */ + */ @XStreamAlias("mchid") private String mchId; /** *
    -  * 设备号
    -  * device_info
    -  * 否
    -  * 13467007045764
    -  * String(32)
    -  *微信支付分配的终端设备号
    +   * 设备号
    +   * device_info
    +   * 否
    +   * 13467007045764
    +   * String(32)
    +   * 微信支付分配的终端设备号
        * 
    - */ + */ @XStreamAlias("device_info") private String deviceInfo; /** *
    -  * 商户订单号
    -  * partner_trade_no
    -  * 是
    -  * 10000098201411111234567890
    -  * String
    -  * 商户订单号
    +   * 商户订单号
    +   * partner_trade_no
    +   * 是
    +   * 10000098201411111234567890
    +   * String
    +   * 商户订单号
        * 
    - */ + */ @XStreamAlias("partner_trade_no") private String partnerTradeNo; /** *
    -  * 需保持唯一性 用户openid
    -  * openid
    -  * 是
    -  * oxTWIuGaIt6gTKsQRLau2M0yL16E
    -  * String
    -  * 商户appid下,某用户的openid
    +   * 需保持唯一性 用户openid
    +   * openid
    +   * 是
    +   * oxTWIuGaIt6gTKsQRLau2M0yL16E
    +   * String
    +   * 商户appid下,某用户的openid
        * 
    - */ + */ @XStreamAlias("openid") private String openid; /** *
    -  * 校验用户姓名选项
    -  * check_name
    -  * 是
    -  * OPTION_CHECK
    -  * String
    -  * NO_CHECK:不校验真实姓名 
    -  * FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) 
    -  * OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
    +   * 校验用户姓名选项
    +   * check_name
    +   * 是
    +   * OPTION_CHECK
    +   * String
    +   * NO_CHECK:不校验真实姓名 
    +   * FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) 
    +   * OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
        * 
    - */ + */ @XStreamAlias("check_name") private String checkName; /** *
    -  * 收款用户姓名
    -  * re_user_name
    -  * 可选
    -  * 马花花
    -  * String
    -  * 收款用户真实姓名。
    -  * 如果check_name设置为FORCE_CHECK或OPTION_CHECK,  则必填用户真实姓名
    +   * 收款用户姓名
    +   * re_user_name
    +   * 可选
    +   * 马花花
    +   * String
    +   * 收款用户真实姓名。
    +   * 如果check_name设置为FORCE_CHECK或OPTION_CHECK,  则必填用户真实姓名
        * 
    - */ + */ @XStreamAlias("re_user_name") private String reUserName; /** *
    -  * 金额
    -  * amount
    -  * 是
    -  * 10099
    -  * int
    -  * 企业付款金额, 单位为分
    +   * 金额
    +   * amount
    +   * 是
    +   * 10099
    +   * int
    +   * 企业付款金额, 单位为分
        * 
    - */ + */ @XStreamAlias("amount") private Integer amount; /** *
    -  * 企业付款描述信息
    -  * desc
    -  * 是
    -  * 理赔
    -  * String
    -  * 企业付款操作说明信息。必填。
    +   * 企业付款描述信息
    +   * desc
    +   * 是
    +   * 理赔
    +   * String
    +   * 企业付款操作说明信息。必填。
        * 
    - */ + */ @XStreamAlias("desc") private String description; /** *
    -  * Ip地址
    -  * spbill_create_ip
    -  * 是
    -  * 192.168.0.1
    -  * String(32)
    -  * 调用接口的机器Ip地址
    +   * Ip地址
    +   * spbill_create_ip
    +   * 是
    +   * 192.168.0.1
    +   * String(32)
    +   * 调用接口的机器Ip地址
        * 
    - */ + */ @XStreamAlias("spbill_create_ip") private String spbillCreateIp; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java similarity index 77% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java index c13f1b8f..2e34f0a2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.request; +package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -47,6 +47,32 @@ public abstract class WxPayBaseRequest { */ @XStreamAlias("mch_id") protected String mchId; + + /** + *
    +   * 服务商模式下的子商户公众账号ID
    +   * sub_appid
    +   * 是
    +   * String(32)
    +   * wxd678efh567hg6787
    +   * 微信分配的子商户公众账号ID
    +   * 
    + */ + @XStreamAlias("sub_appid") + protected String subAppId; + + /** + *
    +   * 服务商模式下的子商户号
    +   * sub_mch_id
    +   * 是
    +   * String(32)
    +   * 1230000109
    +   * 微信支付分配的子商户号,开发者模式下必填
    +   * 
    + */ + @XStreamAlias("sub_mch_id") + protected String subMchId; /** *
        * 随机字符串
    @@ -128,6 +154,22 @@ public abstract class WxPayBaseRequest {
         this.sign = sign;
       }
     
    +  public String getSubAppId() {
    +    return subAppId;
    +  }
    +
    +  public void setSubAppId(String subAppId) {
    +    this.subAppId = subAppId;
    +  }
    +
    +  public String getSubMchId() {
    +    return subMchId;
    +  }
    +
    +  public void setSubMchId(String subMchId) {
    +    this.subMchId = subMchId;
    +  }
    +
       @Override
       public String toString() {
         return ToStringUtils.toSimpleString(this);
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayDownloadBillRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
    similarity index 97%
    rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayDownloadBillRequest.java
    rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
    index 9e1ab4dc..fac28aba 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayDownloadBillRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
    @@ -1,4 +1,4 @@
    -package me.chanjar.weixin.mp.bean.pay.request;
    +package com.github.binarywang.wxpay.bean.request;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
     import me.chanjar.weixin.common.annotation.Required;
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
    similarity index 85%
    rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java
    rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
    index 8f26750f..43206e36 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderCloseRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
    @@ -1,4 +1,4 @@
    -package me.chanjar.weixin.mp.bean.pay.request;
    +package com.github.binarywang.wxpay.bean.request;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
     
    @@ -10,7 +10,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
      * 
    */ @XStreamAlias("xml") -public class WxPayOrderCloseRequest extends WxPayBaseRequest{ +public class WxPayOrderCloseRequest extends WxPayBaseRequest { /** *
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
    similarity index 96%
    rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderQueryRequest.java
    rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
    index 3cc7dd2b..a0982764 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayOrderQueryRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
    @@ -1,4 +1,4 @@
    -package me.chanjar.weixin.mp.bean.pay.request;
    +package com.github.binarywang.wxpay.bean.request;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
     
    @@ -14,6 +14,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
      * 
  • 示例值 *
  • 描述 *
  • + * * @author binarywang(Binary Wang) */ @XStreamAlias("xml") diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRedpackQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java similarity index 95% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRedpackQueryRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java index de7eee93..ae7ec352 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRedpackQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.request; +package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java similarity index 98% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundQueryRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java index 373b0917..06687c36 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.request; +package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java similarity index 60% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java index 22bc6ae2..d8e7e403 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.request; +package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; import me.chanjar.weixin.common.annotation.Required; @@ -143,6 +143,28 @@ public class WxPayRefundRequest extends WxPayBaseRequest { @XStreamAlias("refund_account") private String refundAccount; + private WxPayRefundRequest(Builder builder) { + setDeviceInfo(builder.deviceInfo); + setAppid(builder.appid); + setTransactionId(builder.transactionId); + setMchId(builder.mchId); + setOutTradeNo(builder.outTradeNo); + setSubAppId(builder.subAppId); + setSubMchId(builder.subMchId); + setOutRefundNo(builder.outRefundNo); + setNonceStr(builder.nonceStr); + setTotalFee(builder.totalFee); + setSign(builder.sign); + setRefundFee(builder.refundFee); + setRefundFeeType(builder.refundFeeType); + setOpUserId(builder.opUserId); + setRefundAccount(builder.refundAccount); + } + + public static Builder newBuilder() { + return new Builder(); + } + public String getDeviceInfo() { return this.deviceInfo; } @@ -215,4 +237,103 @@ public class WxPayRefundRequest extends WxPayBaseRequest { this.refundAccount = refundAccount; } + public static final class Builder { + private String deviceInfo; + private String appid; + private String transactionId; + private String mchId; + private String outTradeNo; + private String subAppId; + private String subMchId; + private String outRefundNo; + private String nonceStr; + private Integer totalFee; + private String sign; + private Integer refundFee; + private String refundFeeType; + private String opUserId; + private String refundAccount; + + private Builder() { + } + + public Builder deviceInfo(String deviceInfo) { + this.deviceInfo = deviceInfo; + return this; + } + + public Builder appid(String appid) { + this.appid = appid; + return this; + } + + public Builder transactionId(String transactionId) { + this.transactionId = transactionId; + return this; + } + + public Builder mchId(String mchId) { + this.mchId = mchId; + return this; + } + + public Builder outTradeNo(String outTradeNo) { + this.outTradeNo = outTradeNo; + return this; + } + + public Builder subAppId(String subAppId) { + this.subAppId = subAppId; + return this; + } + + public Builder subMchId(String subMchId) { + this.subMchId = subMchId; + return this; + } + + public Builder outRefundNo(String outRefundNo) { + this.outRefundNo = outRefundNo; + return this; + } + + public Builder nonceStr(String nonceStr) { + this.nonceStr = nonceStr; + return this; + } + + public Builder totalFee(Integer totalFee) { + this.totalFee = totalFee; + return this; + } + + public Builder sign(String sign) { + this.sign = sign; + return this; + } + + public Builder refundFee(Integer refundFee) { + this.refundFee = refundFee; + return this; + } + + public Builder refundFeeType(String refundFeeType) { + this.refundFeeType = refundFeeType; + return this; + } + + public Builder opUserId(String opUserId) { + this.opUserId = opUserId; + return this; + } + + public Builder refundAccount(String refundAccount) { + this.refundAccount = refundAccount; + return this; + } + + public WxPayRefundRequest build() { + return new WxPayRefundRequest(this); + } + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayReportRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java similarity index 99% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayReportRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java index 44b047f8..6795536f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayReportRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.request; +package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; import me.chanjar.weixin.common.annotation.Required; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java similarity index 82% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java index 95cdac22..b49253a4 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java @@ -1,18 +1,19 @@ -package me.chanjar.weixin.mp.bean.pay.request; +package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; /** - * 发送红包请求参数对象 - * Created by Binary Wang on 2016/9/24. + * 发送红包请求参数对象 + * Created by Binary Wang on 2016/9/24. + * * @author binarywang (https://github.com/binarywang) */ @XStreamAlias("xml") -public class WxPaySendRedpackRequest extends WxPayBaseRequest{ +public class WxPaySendRedpackRequest extends WxPayBaseRequest { /** - * mch_billno - * 商户订单号(每个订单号必须唯一) 组成:mch_id+yyyymmdd+10位一天内不能重复的数字。 接口根据商户订单号支持重入,如出现超时可再调用。 - */ + * mch_billno + * 商户订单号(每个订单号必须唯一) 组成:mch_id+yyyymmdd+10位一天内不能重复的数字。 接口根据商户订单号支持重入,如出现超时可再调用。 + */ @XStreamAlias("mch_billno") private String mchBillNo; @@ -25,60 +26,60 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest{ private String sendName; /** - * re_openid - * 接受红包的用户 用户在wxappid下的openid + * re_openid + * 接受红包的用户 用户在wxappid下的openid */ @XStreamAlias("re_openid") private String reOpenid; /** - * total_amount - * 红包总额 + * total_amount + * 红包总额 */ @XStreamAlias("total_amount") private Integer totalAmount; /** - * total_num - * 红包发放总人数 + * total_num + * 红包发放总人数 */ @XStreamAlias("total_num") private Integer totalNum; /** - * amt_type - * 红包金额设置方式 - * ALL_RAND—全部随机,商户指定总金额和红包发放总人数,由微信支付随机计算出各红包金额 - * 裂变红包必填 + * amt_type + * 红包金额设置方式 + * ALL_RAND—全部随机,商户指定总金额和红包发放总人数,由微信支付随机计算出各红包金额 + * 裂变红包必填 */ @XStreamAlias("amt_type") private String amtType; /** - * wishing - * 红包祝福语 + * wishing + * 红包祝福语 */ @XStreamAlias("wishing") private String wishing; /** - * client_ip - * 服务器Ip地址 - * 调用接口的机器Ip地址 + * client_ip + * 服务器Ip地址 + * 调用接口的机器Ip地址 */ @XStreamAlias("client_ip") private String clientIp; /** - * act_name - * 活动名称 + * act_name + * 活动名称 */ @XStreamAlias("act_name") private String actName; /** - * remark - * 备注 + * remark + * 备注 */ @XStreamAlias("remark") private String remark; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java similarity index 92% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java index cf4c008f..4e1d5a5d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayUnifiedOrderRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java @@ -1,7 +1,6 @@ -package me.chanjar.weixin.mp.bean.pay.request; +package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; - import me.chanjar.weixin.common.annotation.Required; /** @@ -17,6 +16,7 @@ import me.chanjar.weixin.common.annotation.Required; *
  • 描述 * * Created by Binary Wang on 2016/9/25. + * * @author binarywang (https://github.com/binarywang) */ @XStreamAlias("xml") @@ -56,35 +56,35 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { * 否 * String(6000) * { "goods_detail":[ - { - "goods_id":"iphone6s_16G", - "wxpay_goods_id":"1001", - "goods_name":"iPhone6s 16G", - "goods_num":1, - "price":528800, - "goods_category":"123456", - "body":"苹果手机" - }, - { - "goods_id":"iphone6s_32G", - "wxpay_goods_id":"1002", - "goods_name":"iPhone6s 32G", - "quantity":1, - "price":608800, - "goods_category":"123789", - "body":"苹果手机" - } - ] - } - 商品详细列表,使用Json格式,传输签名前请务必使用CDATA标签将JSON文本串保护起来。 - goods_detail []: - └ goods_id String 必填 32 商品的编号 - └ wxpay_goods_id String 可选 32 微信支付定义的统一商品编号 - └ goods_name String 必填 256 商品名称 - └ goods_num Int 必填 商品数量 - └ price Int 必填 商品单价,单位为分 - └ goods_category String 可选 32 商品类目Id - └ body String 可选 1000 商品描述信息 + * { + * "goods_id":"iphone6s_16G", + * "wxpay_goods_id":"1001", + * "goods_name":"iPhone6s 16G", + * "goods_num":1, + * "price":528800, + * "goods_category":"123456", + * "body":"苹果手机" + * }, + * { + * "goods_id":"iphone6s_32G", + * "wxpay_goods_id":"1002", + * "goods_name":"iPhone6s 32G", + * "quantity":1, + * "price":608800, + * "goods_category":"123789", + * "body":"苹果手机" + * } + * ] + * } + * 商品详细列表,使用Json格式,传输签名前请务必使用CDATA标签将JSON文本串保护起来。 + * goods_detail []: + * └ goods_id String 必填 32 商品的编号 + * └ wxpay_goods_id String 可选 32 微信支付定义的统一商品编号 + * └ goods_name String 必填 256 商品名称 + * └ goods_num Int 必填 商品数量 + * └ price Int 必填 商品单价,单位为分 + * └ goods_category String 可选 32 商品类目Id + * └ body String 可选 1000 商品描述信息 * */ @XStreamAlias("detail") @@ -267,6 +267,9 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { @XStreamAlias("openid") private String openid; + public static WxUnifiedOrderRequestBuilder builder() { + return new WxUnifiedOrderRequestBuilder(); + } public String getDeviceInfo() { return this.deviceInfo; @@ -362,6 +365,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { /** * 如果配置中已经设置,可以不设置值 + * * @param notifyURL */ public void setNotifyURL(String notifyURL) { @@ -374,6 +378,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { /** * 如果配置中已经设置,可以不设置值 + * * @param tradeType 交易类型 */ public void setTradeType(String tradeType) { @@ -404,10 +409,6 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { this.openid = openid; } - public static WxUnifiedOrderRequestBuilder builder() { - return new WxUnifiedOrderRequestBuilder(); - } - public static class WxUnifiedOrderRequestBuilder { private String appid; private String mchId; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxEntPayQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayQueryResult.java similarity index 97% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxEntPayQueryResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayQueryResult.java index 8ffbeff2..dac69e17 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxEntPayQueryResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayQueryResult.java @@ -1,10 +1,11 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 企业付款查询返回结果 * Created by Binary Wang on 2016/10/19. + * * @author binarywang (https://github.com/binarywang) */ @XStreamAlias("xml") diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxEntPayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayResult.java similarity index 96% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxEntPayResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayResult.java index 5a8c4b75..fa0a4e5f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxEntPayResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayResult.java @@ -1,10 +1,11 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 企业付款返回结果 * Created by Binary Wang on 2016/10/02. + * * @author binarywang (https://github.com/binarywang) */ @XStreamAlias("xml") diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java similarity index 90% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java index 4dd133ab..f68379b8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.google.common.collect.Maps; import com.thoughtworks.xstream.XStream; @@ -61,6 +61,16 @@ public abstract class WxPayBaseResult { */ @XStreamAlias("mch_id") private String mchId; + /** + * 服务商模式下的子公众账号ID + */ + @XStreamAlias("appid") + private String subAppId; + /** + * 服务商模式下的子商户号 + */ + @XStreamAlias("sub_mch_id") + private String subMchId; /** * 随机字符串 */ @@ -181,6 +191,22 @@ public abstract class WxPayBaseResult { this.sign = sign; } + public String getSubAppId() { + return subAppId; + } + + public void setSubAppId(String subAppId) { + this.subAppId = subAppId; + } + + public String getSubMchId() { + return subMchId; + } + + public void setSubMchId(String subMchId) { + this.subMchId = subMchId; + } + /** * 将bean通过保存的xml字符串转换成map */ diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayCommonResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java similarity index 88% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayCommonResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java index a6e7de5f..1fc4d309 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayCommonResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java similarity index 92% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java index ccfa07bf..7221251f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderCloseResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderNotifyResult.java new file mode 100644 index 00000000..723702a4 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderNotifyResult.java @@ -0,0 +1,392 @@ +package com.github.binarywang.wxpay.bean.result; + +import com.github.binarywang.wxpay.bean.WxPayOrderNotifyCoupon; +import com.github.binarywang.wxpay.converter.WxPayOrderNotifyResultConverter; +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 java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 支付结果通用通知 ,文档见:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 + * + * @author aimilin6688 + * @since 2.5.0 + */ +@XStreamAlias("xml") +public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializable { + + private static final long serialVersionUID = 5389718115223345496L; + + /** + *
    +   * 设备号
    +   * device_info
    +   * 否
    +   * String(32)
    +   * 013467007045764
    +   * 微信支付分配的终端设备号,
    +   * 
    + */ + @XStreamAlias("device_info") + private String deviceInfo; + + /** + *
    +   * 用户标识
    +   * openid
    +   * 是
    +   * String(128)
    +   * wxd930ea5d5a258f4f
    +   * 用户在商户appid下的唯一标识
    +   * 
    + */ + @XStreamAlias("openid") + private String openid; + + /** + *
    +   * 是否关注公众账号
    +   * is_subscribe
    +   * 否
    +   * String(1)
    +   * Y
    +   * 用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
    +   * 
    + */ + @XStreamAlias("is_subscribe") + private String isSubscribe; + + + /** + *
    +   * 交易类型
    +   * trade_type
    +   * 是
    +   * String(16)
    +   * JSAPI	JSAPI、NATIVE、APP
    +   * 
    + */ + @XStreamAlias("trade_type") + private String tradeType; + + + /** + *
    +   * 付款银行
    +   * bank_type
    +   * 是
    +   * String(16)
    +   * CMC
    +   * 银行类型,采用字符串类型的银行标识,银行类型见银行列表
    +   * 
    + */ + @XStreamAlias("bank_type") + private String bankType; + + + /** + *
    +   * 订单金额
    +   * total_fee
    +   * 是
    +   * Int
    +   * 100
    +   * 订单总金额,单位为分
    +   * 
    + */ + @XStreamAlias("total_fee") + private Integer totalFee; + /** + *
    +   * 应结订单金额
    +   * settlement_total_fee
    +   * 否
    +   * Int
    +   * 100
    +   * 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
    +   * 
    + */ + @XStreamAlias("settlement_total_fee") + private Integer settlementTotalFee; + /** + *
    +   * 货币种类
    +   * fee_type
    +   * 否
    +   * String(8)
    +   * CNY
    +   * 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   * 
    + */ + @XStreamAlias("fee_type") + private String feeType; + /** + *
    +   * 现金支付金额
    +   * cash_fee
    +   * 是
    +   * Int
    +   * 100
    +   * 现金支付金额订单现金支付金额,详见支付金额
    +   * 
    + */ + @XStreamAlias("cash_fee") + private Integer cashFee; + /** + *
    +   * 现金支付货币类型
    +   * cash_fee_type
    +   * 否
    +   * String(16)
    +   * CNY
    +   * 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   * 
    + */ + @XStreamAlias("cash_fee_type") + private String cashFeeType; + /** + *
    +   * 总代金券金额
    +   * coupon_fee
    +   * 否
    +   * Int
    +   * 10
    +   * 代金券金额<=订单金额,订单金额-代金券金额=现金支付金额,详见支付金额
    +   * 
    + */ + @XStreamAlias("coupon_fee") + private Integer couponFee; + + /** + *
    +   * 代金券使用数量
    +   * coupon_count
    +   * 否
    +   * Int
    +   * 1
    +   * 代金券使用数量
    +   * 
    + */ + @XStreamAlias("coupon_count") + private Integer couponCount; + + private List couponList; + + /** + *
    +   * 微信支付订单号
    +   * transaction_id
    +   * 是
    +   * String(32)
    +   * 1217752501201407033233368018
    +   * 微信支付订单号
    +   * 
    + */ + @XStreamAlias("transaction_id") + private String transactionId; + + /** + *
    +   * 商户订单号
    +   * out_trade_no
    +   * 是
    +   * String(32)
    +   * 1212321211201407033568112322
    +   * 商户系统的订单号,与请求一致。
    +   * 
    + */ + @XStreamAlias("out_trade_no") + private String outTradeNo; + /** + *
    +   * 商家数据包
    +   * attach
    +   * 否
    +   * String(128)
    +   * 123456
    +   * 商家数据包,原样返回
    +   * 
    + */ + @XStreamAlias("attach") + private String attach; + /** + *
    +   * 支付完成时间
    +   * time_end
    +   * 是
    +   * String(14)
    +   * 20141030133525
    +   * 支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
    +   * 
    + */ + @XStreamAlias("time_end") + private String timeEnd; + + 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; + } + + public Integer getCouponCount() { + return couponCount; + } + + public void setCouponCount(Integer couponCount) { + this.couponCount = couponCount; + } + + public List getCouponList() { + return couponList; + } + + public void setCouponList(List couponList) { + this.couponList = couponList; + } + + public String getDeviceInfo() { + return deviceInfo; + } + + public void setDeviceInfo(String deviceInfo) { + this.deviceInfo = deviceInfo; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getIsSubscribe() { + return isSubscribe; + } + + public void setIsSubscribe(String isSubscribe) { + this.isSubscribe = isSubscribe; + } + + public String getTradeType() { + return tradeType; + } + + public void setTradeType(String tradeType) { + this.tradeType = tradeType; + } + + public String getBankType() { + return bankType; + } + + public void setBankType(String bankType) { + this.bankType = bankType; + } + + public Integer getTotalFee() { + return totalFee; + } + + public void setTotalFee(Integer totalFee) { + this.totalFee = totalFee; + } + + public Integer getSettlementTotalFee() { + return settlementTotalFee; + } + + public void setSettlementTotalFee(Integer settlementTotalFee) { + this.settlementTotalFee = settlementTotalFee; + } + + public String getFeeType() { + return feeType; + } + + public void setFeeType(String feeType) { + this.feeType = feeType; + } + + public Integer getCashFee() { + return cashFee; + } + + public void setCashFee(Integer cashFee) { + this.cashFee = cashFee; + } + + public String getCashFeeType() { + return cashFeeType; + } + + public void setCashFeeType(String cashFeeType) { + this.cashFeeType = cashFeeType; + } + + public Integer getCouponFee() { + return couponFee; + } + + public void setCouponFee(Integer couponFee) { + this.couponFee = couponFee; + } + + public String getTransactionId() { + return transactionId; + } + + public void setTransactionId(String transactionId) { + this.transactionId = transactionId; + } + + public String getOutTradeNo() { + return outTradeNo; + } + + public void setOutTradeNo(String outTradeNo) { + this.outTradeNo = outTradeNo; + } + + public String getAttach() { + return attach; + } + + public void setAttach(String attach) { + this.attach = attach; + } + + public String getTimeEnd() { + return timeEnd; + } + + public void setTimeEnd(String timeEnd) { + this.timeEnd = timeEnd; + } + + @Override + public Map toMap() { + Map resultMap = BeanUtils.xmlBean2Map(this); + if (this.getCouponCount() != null && this.getCouponCount() > 0) { + for (int i = 0; i < this.getCouponCount(); i++) { + WxPayOrderNotifyCoupon coupon = couponList.get(i); + resultMap.putAll(coupon.toMap(i)); + } + } + return resultMap; + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java similarity index 99% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java index 8cdf4e6d..a4379ab1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.google.common.collect.Lists; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -396,7 +396,7 @@ public class WxPayOrderQueryResult extends WxPayBaseResult { if (this.couponCount != null && this.couponCount > 0) { this.coupons = Lists.newArrayList(); XmlPath xmlPath = new XmlPath(this.getXmlString()); - for (int i = 0; i < this.couponCount; i++){ + for (int i = 0; i < this.couponCount; i++) { this.coupons.add(new Coupon(this.getXmlValue(xmlPath, "xml.coupon_type_" + i, String.class), this.getXmlValue(xmlPath, "xml.coupon_id_" + i, String.class), this.getXmlValue(xmlPath, "xml.coupon_fee_" + i, Integer.class))); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRedpackQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java similarity index 99% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRedpackQueryResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java index 6febaa37..e0b86732 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRedpackQueryResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java similarity index 99% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java index 1e569ac1..e3604b88 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.google.common.collect.Lists; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -186,7 +186,7 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { /** * 组装生成退款记录属性的内容 - */ + */ public void composeRefundRecords() { if (this.refundCount != null && this.refundCount > 0) { this.refundRecords = Lists.newArrayList(); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java similarity index 98% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java index d00e2db5..1e6126b2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java @@ -1,19 +1,19 @@ -package me.chanjar.weixin.mp.bean.pay.result; - -import java.io.Serializable; +package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; +import java.io.Serializable; + /** *
      * 微信支付-申请退款返回结果
      * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
      * 
    - * @author liukaitj * + * @author liukaitj */ @XStreamAlias("xml") -public class WxPayRefundResult extends WxPayBaseResult implements Serializable{ +public class WxPayRefundResult extends WxPayBaseResult implements Serializable { private static final long serialVersionUID = 1L; @XStreamAlias("device_info") diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPaySendRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java similarity index 97% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPaySendRedpackResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java index 8fe009bc..868f089b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPaySendRedpackResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java @@ -1,14 +1,14 @@ -package me.chanjar.weixin.mp.bean.pay.result; - -import java.io.Serializable; +package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; +import java.io.Serializable; + /** * 向微信用户个人发现金红包返回结果 * https://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5 - * @author kane * + * @author kane */ @XStreamAlias("xml") public class WxPaySendRedpackResult extends WxPayBaseResult implements Serializable { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayUnifiedOrderResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java similarity index 87% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayUnifiedOrderResult.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java index 5097cd10..f6d82bd1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayUnifiedOrderResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java @@ -1,11 +1,11 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; /** *
      * 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"返回的结果
    - * 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
    + * 统一下单(详见http://com.github.binarywang.wechat.pay.bean.pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
      * 
    * * @author chanjarster diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java new file mode 100644 index 00000000..56eba3ac --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java @@ -0,0 +1,157 @@ +package com.github.binarywang.wxpay.config; + +import org.apache.http.ssl.SSLContexts; + +import javax.net.ssl.SSLContext; +import java.io.File; +import java.io.FileInputStream; +import java.security.KeyStore; + +/** + * 微信支付配置 + * + * @author Binary Wang (https://github.com/binarywang) + */ +public class WxPayConfig { + private String appId; + private String subAppId; + private String mchId; + private String mchKey; + private String subMchId; + private String notifyUrl; + private String tradeType; + private SSLContext sslContext; + private String keyPath; + + public void setNotifyUrl(String notifyUrl) { + this.notifyUrl = notifyUrl; + } + + public void setTradeType(String tradeType) { + this.tradeType = tradeType; + } + + /** + * 设置证书 + * @param keyPath apiclient_cert.p12的文件的绝对路径 + */ + public void setKeyPath(String keyPath) { + this.keyPath = keyPath; + } + + public String getKeyPath() { + return keyPath; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public void setSubAppId(String subAppId) { + this.subAppId = subAppId; + } + + public void setMchId(String mchId) { + this.mchId = mchId; + } + + public void setMchKey(String mchKey) { + this.mchKey = mchKey; + } + + public void setSubMchId(String subMchId) { + this.subMchId = subMchId; + } + + public void setSslContext(SSLContext sslContext) { + this.sslContext = sslContext; + } + + /** + * 商户号 + */ + public String getMchId() { + return this.mchId; + } + + /** + * 商户密钥 + */ + public String getMchKey() { + return this.mchKey; + } + + /** + * 公众号appid + */ + public String getAppId() { + return this.appId; + } + + /** + * 服务商模式下的子商户公众账号ID + */ + public String getSubAppId() { + return this.subAppId; + } + + /** + * 服务商模式下的子商户号 + */ + public String getSubMchId() { + return this.subMchId; + } + + /** + * 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数。 + */ + public String getNotifyUrl() { + return this.notifyUrl; + } + + /** + * 交易类型 + *
    +   * JSAPI--公众号支付
    +   * NATIVE--原生扫码支付
    +   * APP--app支付
    +   * 
    + */ + public String getTradeType() { + return this.tradeType; + } + + public SSLContext getSslContext() { + return this.sslContext; + } + + /** + * 微信支付是否使用仿真测试环境 + * 默认不使用 + */ + public boolean useSandboxForWxPay() { + return false; + } + + public SSLContext initSSLContext() { + if (null == mchId) { + throw new IllegalArgumentException("请確保mchId已設置"); + } + + File file = new File(this.keyPath); + if (!file.exists()) { + throw new RuntimeException("证书文件:【" + file.getPath() + "】不存在!"); + } + + try { + FileInputStream inputStream = new FileInputStream(file); + KeyStore keystore = KeyStore.getInstance("PKCS12"); + char[] partnerId2charArray = mchId.toCharArray(); + keystore.load(inputStream, partnerId2charArray); + this.sslContext = SSLContexts.custom().loadKeyMaterial(keystore, partnerId2charArray).build(); + return this.sslContext; + } catch (Exception e) { + throw new RuntimeException("证书文件有问题,请核实!", e); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/converter/WxPayOrderNotifyResultConverter.java similarity index 95% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/converter/WxPayOrderNotifyResultConverter.java index bdd440b9..0e375bd6 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/WxPayOrderNotifyResultConverter.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/converter/WxPayOrderNotifyResultConverter.java @@ -1,130 +1,129 @@ -package me.chanjar.weixin.mp.bean.pay; - -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; - -import com.google.common.base.Function; -import com.google.common.collect.Maps; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.converters.MarshallingContext; -import com.thoughtworks.xstream.converters.UnmarshallingContext; -import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter; -import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.mapper.Mapper; - -import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderNotifyResult; - -public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter { - - public WxPayOrderNotifyResultConverter(Mapper mapper, ReflectionProvider reflectionProvider) { - super(mapper, reflectionProvider); - } - - @Override - @SuppressWarnings("rawtypes") - public boolean canConvert(Class type) { - return type.equals(WxPayOrderNotifyResult.class); - } - - @Override - public void marshal(Object original, HierarchicalStreamWriter writer, MarshallingContext context) { - super.marshal(original, writer, context); - WxPayOrderNotifyResult obj = (WxPayOrderNotifyResult) original; - List list = obj.getCouponList(); - if (list == null || list.size() == 0) { - return; - } - for (int i = 0; i < list.size(); i++) { - WxPayOrderNotifyCoupon coupon = list.get(i); - writer.startNode("coupon_id_" + i); - writer.setValue(coupon.getCouponId()); - writer.endNode(); - writer.startNode("coupon_type_" + i); - writer.setValue(coupon.getCouponType()); - writer.endNode(); - writer.startNode("coupon_fee_" + i); - writer.setValue(coupon.getCouponFee() + ""); - writer.endNode(); - } - } - - @Override - protected void marshallField(MarshallingContext context, Object newObj, Field field) { - if (field.getName().equals("couponList")) { - return; - } else { - super.marshallField(context, newObj, field); - } - } - - @Override - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - WxPayOrderNotifyResult obj = new WxPayOrderNotifyResult(); - - List fields = new ArrayList<>(Arrays.asList(obj.getClass().getDeclaredFields())); - fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields())); - Map fieldMap = getFieldMap(fields); - - List coupons = new ArrayList<>(10); - while (reader.hasMoreChildren()) { - reader.moveDown(); - if (fieldMap.containsKey(reader.getNodeName())) { - Field field = fieldMap.get(reader.getNodeName()); - setFieldValue(context, obj, field); - } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_id_")) { - String id = (String) context.convertAnother(obj, String.class); - getIndex(coupons, reader.getNodeName()).setCouponId(id); - } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_type_")) { - String type = (String) context.convertAnother(obj, String.class); - getIndex(coupons, reader.getNodeName()).setCouponType(type); - } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_fee_")) { - Integer fee = (Integer) context.convertAnother(obj, Integer.class); - getIndex(coupons, reader.getNodeName()).setCouponFee(fee); - } - reader.moveUp(); - } - - obj.setCouponList(coupons); - return obj; - } - - private void setFieldValue(UnmarshallingContext context, WxPayOrderNotifyResult obj, Field field) { - Object val = context.convertAnother(obj, field.getType()); - try { - if (val != null) { - PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass()); - pd.getWriteMethod().invoke(obj, val); - } - } catch (Exception e) { - } - } - - private Map getFieldMap(List fields) { - Map fieldMap = Maps.uniqueIndex(fields, new Function() { - @Override - public String apply(Field field) { - if (field.isAnnotationPresent(XStreamAlias.class)) { - return field.getAnnotation(XStreamAlias.class).value(); - } - return field.getName(); - } - }); - return fieldMap; - } - - private WxPayOrderNotifyCoupon getIndex(List coupons, String nodeName) { - Integer index = Integer.valueOf(StringUtils.substring(nodeName, nodeName.lastIndexOf("_") + 1)); - if (index >= coupons.size() || coupons.get(index) == null) { - coupons.add(index, new WxPayOrderNotifyCoupon()); - } - return coupons.get(index); - } -} +package com.github.binarywang.wxpay.converter; + +import com.github.binarywang.wxpay.bean.WxPayOrderNotifyCoupon; +import com.github.binarywang.wxpay.bean.result.WxPayOrderNotifyResult; +import com.google.common.base.Function; +import com.google.common.collect.Maps; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; +import org.apache.commons.lang3.StringUtils; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter { + + public WxPayOrderNotifyResultConverter(Mapper mapper, ReflectionProvider reflectionProvider) { + super(mapper, reflectionProvider); + } + + @Override + @SuppressWarnings("rawtypes") + public boolean canConvert(Class type) { + return type.equals(WxPayOrderNotifyResult.class); + } + + @Override + public void marshal(Object original, HierarchicalStreamWriter writer, MarshallingContext context) { + super.marshal(original, writer, context); + WxPayOrderNotifyResult obj = (WxPayOrderNotifyResult) original; + List list = obj.getCouponList(); + if (list == null || list.size() == 0) { + return; + } + for (int i = 0; i < list.size(); i++) { + WxPayOrderNotifyCoupon coupon = list.get(i); + writer.startNode("coupon_id_" + i); + writer.setValue(coupon.getCouponId()); + writer.endNode(); + writer.startNode("coupon_type_" + i); + writer.setValue(coupon.getCouponType()); + writer.endNode(); + writer.startNode("coupon_fee_" + i); + writer.setValue(coupon.getCouponFee() + ""); + writer.endNode(); + } + } + + @Override + protected void marshallField(MarshallingContext context, Object newObj, Field field) { + if (field.getName().equals("couponList")) { + return; + } else { + super.marshallField(context, newObj, field); + } + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + WxPayOrderNotifyResult obj = new WxPayOrderNotifyResult(); + + List fields = new ArrayList<>(Arrays.asList(obj.getClass().getDeclaredFields())); + fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields())); + Map fieldMap = getFieldMap(fields); + + List coupons = new ArrayList<>(10); + while (reader.hasMoreChildren()) { + reader.moveDown(); + if (fieldMap.containsKey(reader.getNodeName())) { + Field field = fieldMap.get(reader.getNodeName()); + setFieldValue(context, obj, field); + } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_id_")) { + String id = (String) context.convertAnother(obj, String.class); + getIndex(coupons, reader.getNodeName()).setCouponId(id); + } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_type_")) { + String type = (String) context.convertAnother(obj, String.class); + getIndex(coupons, reader.getNodeName()).setCouponType(type); + } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_fee_")) { + Integer fee = (Integer) context.convertAnother(obj, Integer.class); + getIndex(coupons, reader.getNodeName()).setCouponFee(fee); + } + reader.moveUp(); + } + + obj.setCouponList(coupons); + return obj; + } + + private void setFieldValue(UnmarshallingContext context, WxPayOrderNotifyResult obj, Field field) { + Object val = context.convertAnother(obj, field.getType()); + try { + if (val != null) { + PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass()); + pd.getWriteMethod().invoke(obj, val); + } + } catch (Exception e) { + } + } + + private Map getFieldMap(List fields) { + Map fieldMap = Maps.uniqueIndex(fields, new Function() { + @Override + public String apply(Field field) { + if (field.isAnnotationPresent(XStreamAlias.class)) { + return field.getAnnotation(XStreamAlias.class).value(); + } + return field.getName(); + } + }); + return fieldMap; + } + + private WxPayOrderNotifyCoupon getIndex(List coupons, String nodeName) { + Integer index = Integer.valueOf(StringUtils.substring(nodeName, nodeName.lastIndexOf("_") + 1)); + if (index >= coupons.size() || coupons.get(index) == null) { + coupons.add(index, new WxPayOrderNotifyCoupon()); + } + return coupons.get(index); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java similarity index 93% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 543b59bd..34ba8cdc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -1,23 +1,26 @@ -package me.chanjar.weixin.mp.api; +package com.github.binarywang.wxpay.service; +import com.github.binarywang.wxpay.bean.request.*; +import com.github.binarywang.wxpay.bean.result.*; +import com.github.binarywang.wxpay.config.WxPayConfig; import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.pay.request.*; -import me.chanjar.weixin.mp.bean.pay.result.*; import java.io.File; import java.util.Map; /** + *
      * 微信支付相关接口
      * Created by Binary Wang on 2016/7/28.
    + * 
    * * @author binarywang (https://github.com/binarywang) */ -public interface WxMpPayService { +public interface WxPayService { /** *
    -   * 查询订单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2)
    +   * 查询订单(详见https://com.github.binarywang.wechat.pay.bean.pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2)
        * 该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
        * 需要调用查询接口的情况:
        * ◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
    @@ -49,7 +52,7 @@ public interface WxMpPayService {
       WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxErrorException;
     
       /**
    -   * 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
    +   * 统一下单(详见http://com.github.binarywang.wechat.pay.bean.pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
        * 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
        * 接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder
        *
    @@ -65,6 +68,16 @@ public interface WxMpPayService {
        */
       Map getPayInfo(WxPayUnifiedOrderRequest request) throws WxErrorException;
     
    +  /**
    +   * 获取配置
    +   */
    +  WxPayConfig getConfig();
    +
    +  /**
    +   * 设置配置对象
    +   */
    +  void setConfig(WxPayConfig config);
    +
       /**
        * 
        * 微信支付-申请退款
    @@ -81,7 +94,8 @@ public interface WxMpPayService {
        * 
        * 微信支付-查询退款
        * 应用场景:
    -   *  提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。
    +   *  提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,
    +   *  银行卡支付的退款3个工作日后重新查询退款状态。
        * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
        * 接口链接:https://api.mch.weixin.qq.com/pay/refundquery
        * 
    @@ -93,11 +107,12 @@ public interface WxMpPayService { * @param refundId 微信退款单号 * @return 退款信息 */ - WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, String outRefundNo, String refundId) throws WxErrorException; + WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, String outRefundNo, String refundId) + throws WxErrorException; /** * 读取支付结果通知 - * 详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 + * 详见http://com.github.binarywang.wechat.pay.bean.pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 */ WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java similarity index 73% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java index fae2d931..dea7a7e8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java @@ -1,20 +1,21 @@ -package me.chanjar.weixin.mp.api.impl; +package com.github.binarywang.wxpay.service.impl; import com.github.binarywang.utils.qrcode.QrcodeUtils; +import com.github.binarywang.wxpay.bean.request.*; +import com.github.binarywang.wxpay.bean.result.*; +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.service.WxPayService; import com.google.common.collect.Maps; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; 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.mp.api.WxMpConfigStorage; -import me.chanjar.weixin.mp.api.WxMpPayService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.pay.request.*; -import me.chanjar.weixin.mp.bean.pay.result.*; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.CharEncoding; import org.apache.commons.lang3.StringUtils; import org.apache.http.Consts; -import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.DefaultHostnameVerifier; @@ -28,7 +29,7 @@ import org.slf4j.LoggerFactory; import javax.net.ssl.SSLContext; import java.io.File; -import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.util.*; /** @@ -36,28 +37,31 @@ import java.util.*; * * @author binarywang (https://github.com/binarywang) */ -public class WxMpPayServiceImpl implements WxMpPayService { +public class WxPayServiceImpl implements WxPayService { private static final String PAY_BASE_URL = "https://api.mch.weixin.qq.com"; private static final String[] TRADE_TYPES = new String[]{"JSAPI", "NATIVE", "APP"}; private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS", "REFUND_SOURCE_UNSETTLED_FUNDS"}; - private static final String[] BILL_TYPE = new String[]{"ALL","REFUND","SUCCESS"};; + private static final String[] BILL_TYPE = new String[]{"ALL", "REFUND", "SUCCESS"}; + private final Logger log = LoggerFactory.getLogger(this.getClass()); - private WxMpService wxMpService; - public WxMpPayServiceImpl(WxMpService wxMpService) { - this.wxMpService = wxMpService; + private WxPayConfig config; + + @Override + public WxPayConfig getConfig() { + return this.config; } - private WxMpConfigStorage getConfig() { - return wxMpService.getWxMpConfigStorage(); + @Override + public void setConfig(WxPayConfig config) { + this.config = config; } - private String getPayBaseUrl(){ - if(this.getConfig().useSandboxForWxPay()){ + private String getPayBaseUrl() { + if (this.getConfig().useSandboxForWxPay()) { return PAY_BASE_URL + "/sandboxnew"; } - return PAY_BASE_URL; } @@ -65,22 +69,27 @@ public class WxMpPayServiceImpl implements WxMpPayService { public WxPayRefundResult refund(WxPayRefundRequest request) throws WxErrorException { this.initRequest(request); if (StringUtils.isBlank(request.getOpUserId())) { - request.setOpUserId(this.getConfig().getPartnerId()); + request.setOpUserId(this.getConfig().getMchId()); } + this.checkParameters(request); request.setSign(this.createSign(request)); String url = this.getPayBaseUrl() + "/secapi/pay/refund"; - String responseContent = this.executeWithKey(url, request.toXML()); + String responseContent = this.postWithKey(url, request.toXML()); WxPayRefundResult result = WxPayRefundResult.fromXML(responseContent, WxPayRefundResult.class); this.checkResult(result); return result; } @Override - public WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, String outRefundNo, String refundId) throws WxErrorException { - if ((StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo) && StringUtils.isBlank(outRefundNo) && StringUtils.isBlank(refundId)) || - (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(outTradeNo) && StringUtils.isNotBlank(outRefundNo) && StringUtils.isNotBlank(refundId))) { + public WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, + String outRefundNo, String refundId) + throws WxErrorException { + if ((StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo) + && StringUtils.isBlank(outRefundNo) && StringUtils.isBlank(refundId)) || + (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(outTradeNo) + && StringUtils.isNotBlank(outRefundNo) && StringUtils.isNotBlank(refundId))) { throw new IllegalArgumentException("transaction_id , out_trade_no,out_refund_no, refund_id 必须四选一"); } @@ -93,18 +102,17 @@ public class WxMpPayServiceImpl implements WxMpPayService { request.setSign(this.createSign(request)); String url = this.getPayBaseUrl() + "/pay/refundquery"; - String responseContent = this.executeRequest(url, request.toXML()); + String responseContent = this.post(url, request.toXML()); WxPayRefundQueryResult result = WxPayRefundQueryResult.fromXML(responseContent, WxPayRefundQueryResult.class); result.composeRefundRecords(); this.checkResult(result); return result; } - private void checkResult(WxPayBaseResult result) throws WxErrorException { //校验返回结果签名 Map map = result.toMap(); - if (result.getSign() != null &&!this.checkSign(map)) { + if (result.getSign() != null && !this.checkSign(map)) { log.debug("校验结果签名失败,参数:{}", map); throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("参数格式校验错误!").build()); } @@ -112,12 +120,28 @@ public class WxMpPayServiceImpl implements WxMpPayService { //校验结果是否成功 if (!"SUCCESS".equalsIgnoreCase(result.getReturnCode()) || !"SUCCESS".equalsIgnoreCase(result.getResultCode())) { - WxError error = WxError.newBuilder().setErrorCode(-1) - .setErrorMsg("返回代码: " + result.getReturnCode() + ", 返回信息: " - + result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: " - + result.getErrCode() + ", 错误详情: " + result.getErrCodeDes()) + StringBuilder errorMsg = new StringBuilder(); + if (result.getReturnCode() != null) { + errorMsg.append("返回代码:" + result.getReturnCode()); + } + if (result.getReturnMsg() != null) { + errorMsg.append(",返回信息:" + result.getReturnMsg()); + } + if (result.getResultCode() != null) { + errorMsg.append(",结果代码:" + result.getResultCode()); + } + if (result.getErrCode() != null) { + errorMsg.append(",错误代码:" + result.getErrCode()); + } + if (result.getErrCodeDes() != null) { + errorMsg.append(",错误详情:" + result.getErrCodeDes()); + } + + WxError error = WxError.newBuilder() + .setErrorCode(-1) + .setErrorMsg(errorMsg.toString()) .build(); - log.error("结果业务代码异常,参数:{},详细:{}", map, error); + log.error("\n结果业务代码异常,返回結果:{},\n{}", map, error); throw new WxErrorException(error); } } @@ -129,8 +153,9 @@ public class WxMpPayServiceImpl implements WxMpPayService { throw new IllegalArgumentException("tar_type值如果存在,只能为GZIP"); } - if ( !ArrayUtils.contains(BILL_TYPE, request.getBillType())) { - throw new IllegalArgumentException("bill_tpye目前必须为" + Arrays.toString(BILL_TYPE) + "其中之一,实际值:" + request.getBillType()); + if (!ArrayUtils.contains(BILL_TYPE, request.getBillType())) { + throw new IllegalArgumentException("bill_tpye目前必须为" + Arrays.toString(BILL_TYPE) + + "其中之一,实际值:" + request.getBillType()); } } @@ -140,7 +165,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { if (StringUtils.isNotBlank(request.getRefundAccount())) { if (!ArrayUtils.contains(REFUND_ACCOUNT, request.getRefundAccount())) { - throw new IllegalArgumentException("refund_account目前必须为" + Arrays.toString(REFUND_ACCOUNT) + "其中之一,实际值:" + request.getRefundAccount()); + throw new IllegalArgumentException("refund_account目前必须为" + Arrays.toString(REFUND_ACCOUNT) + + "其中之一,实际值:" + request.getRefundAccount()); } } @@ -152,7 +178,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException { try { - log.trace("微信支付回调参数详细:{}", xmlData); + log.debug("微信支付回调参数详细:{}", xmlData); WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlData); log.debug("微信支付回调结果对象:{}", result); this.checkResult(result); @@ -177,7 +203,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { //裂变红包 url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendgroupredpack"; } - String responseContent = this.executeWithKey(url, request.toXML()); + String responseContent = this.postWithKey(url, request.toXML()); WxPaySendRedpackResult result = WxPaySendRedpackResult.fromXML(responseContent, WxPaySendRedpackResult.class); //毋须校验,因为没有返回签名信息 // this.checkResult(result); @@ -193,7 +219,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { request.setSign(this.createSign(request)); String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gethbinfo"; - String responseContent = this.executeWithKey(url, request.toXML()); + String responseContent = this.postWithKey(url, request.toXML()); WxPayRedpackQueryResult result = WxPayRedpackQueryResult.fromXML(responseContent, WxPayRedpackQueryResult.class); this.checkResult(result); return result; @@ -213,7 +239,11 @@ public class WxMpPayServiceImpl implements WxMpPayService { request.setSign(this.createSign(request)); String url = this.getPayBaseUrl() + "/pay/orderquery"; - String responseContent = this.executeRequest(url, request.toXML()); + String responseContent = this.post(url, request.toXML()); + if (StringUtils.isBlank(responseContent)) { + throw new WxErrorException(WxError.newBuilder().setErrorMsg("无响应结果").build()); + } + WxPayOrderQueryResult result = WxPayOrderQueryResult.fromXML(responseContent, WxPayOrderQueryResult.class); result.composeCoupons(); this.checkResult(result); @@ -223,17 +253,17 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxErrorException { if (StringUtils.isBlank(outTradeNo)) { - throw new IllegalArgumentException("out_trade_no 不能为空"); + throw new IllegalArgumentException("out_trade_no不能为空"); } WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); - initRequest(request); + this.initRequest(request); request.setSign(this.createSign(request)); String url = this.getPayBaseUrl() + "/pay/closeorder"; - String responseContent = this.executeRequest(url, request.toXML()); - WxPayOrderCloseResult result = WxPayOrderCloseResult.fromXML(responseContent, WxPayOrderCloseResult.class); + String responseContent = this.post(url, request.toXML()); + WxPayOrderCloseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderCloseResult.class); this.checkResult(result); return result; @@ -242,23 +272,20 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxErrorException { - this.initRequest(request); if (StringUtils.isBlank(request.getNotifyURL())) { - request.setNotifyURL(getConfig().getNotifyURL()); + request.setNotifyURL(getConfig().getNotifyUrl()); } + if (StringUtils.isBlank(request.getTradeType())) { request.setTradeType(getConfig().getTradeType()); } - checkParameters(request);//校验参数 + + this.checkParameters(request);//校验参数 request.setSign(this.createSign(request)); String url = this.getPayBaseUrl() + "/pay/unifiedorder"; - String xmlParam = request.toXML(); - log.debug("微信统一下单接口,URL:{},参数:{}", url, xmlParam); - - String responseContent = this.executeRequest(url, xmlParam); - log.debug("微信统一下单接口,URL:{},结果:{}", url, responseContent); + String responseContent = this.post(url, request.toXML()); WxPayUnifiedOrderResult result = WxPayUnifiedOrderResult.fromXML(responseContent, WxPayUnifiedOrderResult.class); this.checkResult(result); return result; @@ -266,11 +293,21 @@ public class WxMpPayServiceImpl implements WxMpPayService { private void initRequest(WxPayBaseRequest request) { if (StringUtils.isBlank(request.getAppid())) { - request.setAppid(getConfig().getAppId()); + request.setAppid(this.getConfig().getAppId()); } + if (StringUtils.isBlank(request.getMchId())) { - request.setMchId(getConfig().getPartnerId()); + request.setMchId(this.getConfig().getMchId()); + } + + if (StringUtils.isBlank(request.getSubAppId())) { + request.setSubAppId(this.getConfig().getSubAppId()); + } + + if (StringUtils.isBlank(request.getSubMchId())) { + request.setSubMchId(this.getConfig().getSubMchId()); } + if (StringUtils.isBlank(request.getNonceStr())) { request.setNonceStr(String.valueOf(System.currentTimeMillis())); } @@ -297,13 +334,14 @@ public class WxMpPayServiceImpl implements WxMpPayService { WxPayUnifiedOrderResult unifiedOrderResult = this.unifiedOrder(request); String prepayId = unifiedOrderResult.getPrepayId(); if (StringUtils.isBlank(prepayId)) { - throw new RuntimeException(String.format("Failed to get prepay id due to error code '%s'(%s).", + throw new RuntimeException(String.format("无法获取prepay id,错误代码: '%s',信息:%s。", unifiedOrderResult.getErrCode(), unifiedOrderResult.getErrCodeDes())); } Map payInfo = new HashMap<>(); payInfo.put("appId", getConfig().getAppId()); - // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 + // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。 + // 但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 payInfo.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); payInfo.put("nonceStr", String.valueOf(System.currentTimeMillis())); payInfo.put("package", "prepay_id=" + prepayId); @@ -323,7 +361,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { String url = this.getPayBaseUrl() + "/mmpaymkttransfers/promotion/transfers"; - String responseContent = this.executeWithKey(url, request.toXML()); + String responseContent = this.postWithKey(url, request.toXML()); WxEntPayResult result = WxEntPayResult.fromXML(responseContent, WxEntPayResult.class); this.checkResult(result); return result; @@ -336,7 +374,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { request.setSign(this.createSign(request)); String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo"; - String responseContent = this.executeWithKey(url, request.toXML()); + String responseContent = this.postWithKey(url, request.toXML()); WxEntPayQueryResult result = WxEntPayQueryResult.fromXML(responseContent, WxEntPayQueryResult.class); this.checkResult(result); return result; @@ -348,7 +386,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { StringBuilder codeUrl = new StringBuilder("weixin://wxpay/bizpayurl?"); Map params = Maps.newHashMap(); params.put("appid", this.getConfig().getAppId()); - params.put("mch_id", this.getConfig().getPartnerId()); + params.put("mch_id", this.getConfig().getMchId()); params.put("product_id", productId); params.put("time_stamp", String.valueOf(System.currentTimeMillis())); params.put("nonce_str", String.valueOf(System.currentTimeMillis())); @@ -383,7 +421,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { request.setSign(this.createSign(request)); String url = this.getPayBaseUrl() + "/payitil/report"; - String responseContent = this.wxMpService.post(url, request.toXML()); + String responseContent = this.post(url, request.toXML()); WxPayCommonResult result = WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class); this.checkResult(result); } @@ -401,7 +439,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { String url = this.getPayBaseUrl() + "/pay/downloadbill"; //TODO 返回的内容可能是文件流,也有可能是xml,需要区分对待 - String responseContent = this.wxMpService.post(url, request.toXML()); + String responseContent = this.post(url, request.toXML()); WxPayCommonResult result = WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class); this.checkResult(result); @@ -409,42 +447,41 @@ public class WxMpPayServiceImpl implements WxMpPayService { return null; } - private String executeRequest(String url, String requestStr) throws WxErrorException { - HttpPost httpPost = new HttpPost(url); - if (this.wxMpService.getHttpProxy() != null) { - httpPost.setConfig(RequestConfig.custom().setProxy(this.wxMpService.getHttpProxy()).build()); + private String post(String url, String xmlParam) { + String requestString = null; + try { + requestString = new String(xmlParam.getBytes(CharEncoding.UTF_8), CharEncoding.ISO_8859_1); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); } - try (CloseableHttpClient httpclient = HttpClients.custom().build()) { - httpPost.setEntity(new StringEntity(new String(requestStr.getBytes("UTF-8"), "ISO-8859-1"))); - - try (CloseableHttpResponse response = httpclient.execute(httpPost)) { - String result = EntityUtils.toString(response.getEntity(), Consts.UTF_8); - this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", url, requestStr, result); - return result; - } - } catch (IOException e) { - this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[EXCEPTION]: {}", url, requestStr, e.getMessage()); - throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg(e.getMessage()).build(), e); - } finally { - httpPost.releaseConnection(); + HttpRequest request = HttpRequest.post(url).body(requestString); + HttpResponse response = request.send(); + String responseString = null; + try { + responseString = new String(response.bodyText().getBytes(CharEncoding.ISO_8859_1), CharEncoding.UTF_8); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); } + + this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", url, xmlParam, responseString); + return responseString; } - private String executeWithKey(String url, String requestStr) throws WxErrorException { + /** + * 由于暂时未找到使用jodd-http实现证书配置的办法,故而暂时使用httpclient + */ + private String postWithKey(String url, String requestStr) throws WxErrorException { try { - SSLContext sslContext = getConfig().getSslContext(); + SSLContext sslContext = this.getConfig().getSslContext(); if (null == sslContext) { - throw new IllegalArgumentException("请先初始化配置类(即WxMpConfigStorage的实现类)中的SSLContext!"); + sslContext = this.getConfig().initSSLContext(); } - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1"}, null, - new DefaultHostnameVerifier()); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, + new String[]{"TLSv1"}, null, new DefaultHostnameVerifier()); HttpPost httpPost = new HttpPost(url); - if (this.wxMpService.getHttpProxy() != null) { - httpPost.setConfig(RequestConfig.custom().setProxy(this.wxMpService.getHttpProxy()).build()); - } try (CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build()) { httpPost.setEntity(new StringEntity(new String(requestStr.getBytes("UTF-8"), "ISO-8859-1"))); @@ -464,7 +501,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public String createSign(Object xmlBean) { - return this.createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); + return this.createSign(BeanUtils.xmlBean2Map(xmlBean), this.getConfig().getMchKey()); } @Override @@ -474,14 +511,14 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public String createSign(Map params) { - return this.createSign(params, this.getConfig().getPartnerKey()); + return this.createSign(params, this.getConfig().getMchKey()); } @Override public String createSign(Map params, String signKey) { - if(this.getConfig().useSandboxForWxPay()){ + if (this.getConfig().useSandboxForWxPay()) { //使用仿真测试环境 - //TODO 目前测试发现,以下两行代码都会出问题,所以暂不建议使用这个仿真测试环境 + //TODO 目前测试发现,以下两行代码都会出问题,所以暂不建议使用仿真测试环境 signKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; //return "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; } @@ -502,7 +539,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public boolean checkSign(Object xmlBean) { - return this.checkSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); + return this.checkSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getMchKey()); } @Override @@ -512,7 +549,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { @Override public boolean checkSign(Map params) { - return this.checkSign(params, getConfig().getPartnerKey()); + return this.checkSign(params, getConfig().getMchKey()); } @Override diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java similarity index 94% rename from weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResultTest.java rename to weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java index aaab37a2..c99f4115 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java @@ -1,5 +1,6 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; import org.testng.*; import org.testng.annotations.*; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResultTest.java similarity index 98% rename from weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResultTest.java rename to weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResultTest.java index e0fd9808..d847a155 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResultTest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import org.testng.*; import org.testng.annotations.*; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResultTest.java similarity index 97% rename from weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResultTest.java rename to weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResultTest.java index 6b8a9ae9..6ca4192a 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResultTest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import org.testng.*; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPaySendRedpackResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResultTest.java similarity index 98% rename from weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPaySendRedpackResultTest.java rename to weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResultTest.java index f2aa0a94..1985c924 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay/result/WxPaySendRedpackResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResultTest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.pay.result; +package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.XStream; import me.chanjar.weixin.common.util.xml.XStreamInitializer; diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxMpPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxMpPayServiceImplTest.java new file mode 100644 index 00000000..c658d124 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxMpPayServiceImplTest.java @@ -0,0 +1,196 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.utils.qrcode.QrcodeUtils; +import com.github.binarywang.wxpay.bean.request.*; +import com.github.binarywang.wxpay.bean.result.*; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.testbase.ApiTestModule; +import com.github.binarywang.wxpay.testbase.XmlWxPayConfig; +import com.google.inject.Inject; +import me.chanjar.weixin.common.exception.WxErrorException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.*; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.testng.Assert.*; + +/** + * 测试支付相关接口 + * Created by Binary Wang on 2016/7/28. + * + * @author binarywang (https://github.com/binarywang) + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMpPayServiceImplTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Inject + protected WxPayService wxService; + + @Test + public void testGetPayInfo() throws Exception { + + } + + @Test + public void testDownloadBill() throws Exception { + File file = this.wxService.downloadBill("20170101", "ALL", "GZIP", "1111111"); + assertNotNull(file); + //必填字段为空时,抛出异常 + this.wxService.downloadBill("", "", "", null); + } + + @Test + public void testReport() throws Exception { + WxPayReportRequest request = new WxPayReportRequest(); + request.setInterfaceUrl("hahahah"); + request.setSignType("HMAC-SHA256");//貌似接口未校验此字段 + request.setExecuteTime(1000); + request.setReturnCode("aaa"); + request.setResultCode("aaa"); + request.setUserIp("8.8.8"); + this.wxService.report(request); + } + + /** + * Test method for {@link WxPayService#refund(WxPayRefundRequest)} . + */ + @Test//(dependsOnMethods = {"setSSLKey"}) + public void testRefund() throws Exception { + WxPayRefundResult result = this.wxService.refund( + WxPayRefundRequest.newBuilder() + .outRefundNo("aaa") + .outTradeNo("1111") + .totalFee(1222) + .refundFee(111) + .build()); + this.logger.info(result.toString()); + } + + /** + * Test method for {@link WxPayService#refundQuery(java.lang.String, java.lang.String, java.lang.String, java.lang.String)} . + */ + @Test + public void testRefundQuery() throws Exception { + WxPayRefundQueryResult result; + + result = this.wxService.refundQuery("1", "", "", ""); + this.logger.info(result.toString()); + + result = this.wxService.refundQuery("", "2", "", ""); + this.logger.info(result.toString()); + + result = this.wxService.refundQuery("", "", "3", ""); + this.logger.info(result.toString()); + + result = this.wxService.refundQuery("", "", "", "4"); + this.logger.info(result.toString()); + + //测试四个参数都填的情况,应该报异常的 + result = this.wxService.refundQuery("1", "2", "3", "4"); + this.logger.info(result.toString()); + } + + /** + * Test method for {@link WxPayService#sendRedpack(WxPaySendRedpackRequest)} . + */ + @Test//(dependsOnMethods = {"setSSLKey"}) + public void testSendRedpack() throws Exception { + WxPaySendRedpackRequest request = new WxPaySendRedpackRequest(); + request.setActName("abc"); + request.setClientIp("aaa"); + request.setMchBillNo("aaaa"); + request.setReOpenid(((XmlWxPayConfig) this.wxService.getConfig()).getOpenid()); + WxPaySendRedpackResult redpackResult = this.wxService.sendRedpack(request); + this.logger.info(redpackResult.toString()); + } + + /** + * Test method for {@link WxPayService#queryRedpack(java.lang.String)}. + */ + @Test//(dependsOnMethods = {"setSSLKey"}) + public void testQueryRedpack() throws Exception { + WxPayRedpackQueryResult redpackResult = this.wxService.queryRedpack("aaaa"); + this.logger.info(redpackResult.toString()); + } + + /** + * Test method for {@link WxPayService#unifiedOrder(WxPayUnifiedOrderRequest)}. + */ + @Test + public void testUnifiedOrder() throws WxErrorException { + WxPayUnifiedOrderResult result = this.wxService + .unifiedOrder(WxPayUnifiedOrderRequest.builder() + .body("我去") + .totalFee(1) + .spbillCreateIp("111111") + .notifyURL("111111") + .tradeType("JSAPI") + .openid(((XmlWxPayConfig) this.wxService.getConfig()).getOpenid()) + .outTradeNo("111111") + .build()); + this.logger.info(result.toString()); + } + + /** + * Test method for {@link WxPayService#queryOrder(java.lang.String, java.lang.String)} . + */ + @Test + public void testQueryOrder() throws WxErrorException { + this.logger.info(this.wxService.queryOrder("11212121", null).toString()); + this.logger.info(this.wxService.queryOrder(null, "11111").toString()); + } + + /** + * Test method for {@link WxPayService#closeOrder(java.lang.String)} . + */ + @Test + public void testCloseOrder() throws WxErrorException { + this.logger.info(this.wxService.closeOrder("11212121").toString()); + } + + /** + * Test method for {@link WxPayService#entPay(WxEntPayRequest)}. + */ + @Test//(dependsOnMethods = {"setSSLKey"}) + public void testEntPay() throws WxErrorException { + WxEntPayRequest request = new WxEntPayRequest(); + this.logger.info(this.wxService.entPay(request).toString()); + } + + /** + * Test method for {@link WxPayService#queryEntPay(java.lang.String)}. + */ + @Test//(dependsOnMethods = {"setSSLKey"}) + public void testQueryEntPay() throws WxErrorException { + this.logger.info(this.wxService.queryEntPay("11212121").toString()); + } + + @Test + public void testCreateScanPayQrcodeMode1() throws Exception { + String productId = "abc"; + byte[] bytes = this.wxService.createScanPayQrcodeMode1(productId, null, null); + Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); + Files.write(qrcodeFilePath, bytes); + String qrcodeContent = QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()); + this.logger.info(qrcodeContent); + + assertTrue(qrcodeContent.startsWith("weixin://wxpay/bizpayurl?")); + assertTrue(qrcodeContent.contains("product_id=" + productId)); + } + + @Test + public void testCreateScanPayQrcodeMode2() throws Exception { + String qrcodeContent = "abc"; + byte[] bytes = this.wxService.createScanPayQrcodeMode2(qrcodeContent, null, null); + Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); + Files.write(qrcodeFilePath, bytes); + assertEquals(QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()), qrcodeContent); + } + +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/ApiTestModule.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/ApiTestModule.java new file mode 100644 index 00000000..d5a028d1 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/ApiTestModule.java @@ -0,0 +1,38 @@ +package com.github.binarywang.wxpay.testbase; + +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import com.google.inject.Binder; +import com.google.inject.Module; +import com.thoughtworks.xstream.XStream; +import me.chanjar.weixin.common.util.xml.XStreamInitializer; + +import java.io.IOException; +import java.io.InputStream; + +public class ApiTestModule implements Module { + + @Override + public void configure(Binder binder) { + try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) { + XmlWxPayConfig config = this.fromXml(XmlWxPayConfig.class, is1); + WxPayService wxService = new WxPayServiceImpl(); + wxService.setConfig(config); + + binder.bind(WxPayService.class).toInstance(wxService); + binder.bind(WxPayConfig.class).toInstance(config); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + private T fromXml(Class clazz, InputStream is) { + XStream xstream = XStreamInitializer.getInstance(); + xstream.alias("xml", clazz); + xstream.processAnnotations(clazz); + return (T) xstream.fromXML(is); + } + +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/XmlWxPayConfig.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/XmlWxPayConfig.java new file mode 100644 index 00000000..a10f36f3 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/XmlWxPayConfig.java @@ -0,0 +1,31 @@ +package com.github.binarywang.wxpay.testbase; + +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.http.ssl.SSLContexts; + +import javax.net.ssl.SSLContext; +import java.io.File; +import java.io.FileInputStream; +import java.security.KeyStore; + +@XStreamAlias("xml") +public class XmlWxPayConfig extends WxPayConfig { + private String openid; + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + @Override + public boolean useSandboxForWxPay() { + //沙箱环境不成熟,有问题无法使用,暂时屏蔽掉 + // return true; + return false; + } +} diff --git a/weixin-java-pay/src/test/resources/logback-test.xml b/weixin-java-pay/src/test/resources/logback-test.xml new file mode 100644 index 00000000..75de28c0 --- /dev/null +++ b/weixin-java-pay/src/test/resources/logback-test.xml @@ -0,0 +1,16 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + diff --git a/weixin-java-pay/src/test/resources/test-config.sample.xml b/weixin-java-pay/src/test/resources/test-config.sample.xml new file mode 100644 index 00000000..1e64cbe4 --- /dev/null +++ b/weixin-java-pay/src/test/resources/test-config.sample.xml @@ -0,0 +1,13 @@ + + 公众号appid + 微信商户平台ID + 商户平台设置的API密钥 + + 商户平台的证书文件地址 + 某个openId +