From e296d237ebad5fa49effa37f8ab4a138a9e28393 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 13 Feb 2017 17:51:11 +0800 Subject: [PATCH 01/63] minor updates --- .../main/java/me/chanjar/weixin/mp/api/WxMpPayService.java | 4 ++-- .../me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java index 004cd5bc..543b59bd 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java @@ -28,7 +28,7 @@ public interface WxMpPayService { * * * @param transactionId 微信订单号 - * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。 + * @param outTradeNo 商户系统内部的订单号,当没提供transactionId时需要传这个。 */ WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException; @@ -44,7 +44,7 @@ public interface WxMpPayService { * 是否需要证书: 不需要。 * * - * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。 + * @param outTradeNo 商户系统内部的订单号 */ WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxErrorException; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java index b0ccacd9..4424e211 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java @@ -404,6 +404,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { WxPayCommonResult result = WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class); this.checkResult(result); + //TODO 待实现,暂时无测试帐号,无法调试 return null; } From b2b04609dbbb0b75e14783372e2904a4e932e5d9 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 13 Feb 2017 17:57:58 +0800 Subject: [PATCH 02/63] update version to 2.6.0-SNAPSHOT --- build.gradle | 2 +- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-osgi/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index e5231e24..e572c391 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ allprojects { apply plugin: 'maven' group = 'com.github.binarywang' - version = '2.5.0' + version = '2.6.0-SNAPSHOT' } subprojects { diff --git a/pom.xml b/pom.xml index 57ae6b92..c941dbc7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.github.binarywang weixin-java-parent - 2.5.0 + 2.6.0-SNAPSHOT pom WeiXin Java Tools - Parent 微信公众号、企业号上级POM diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 12611c12..1d1ad69c 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.0 + 2.6.0-SNAPSHOT weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 6478ada2..e49f6c16 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.0 + 2.6.0-SNAPSHOT weixin-java-cp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 7070d018..9cbea35a 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.0 + 2.6.0-SNAPSHOT weixin-java-mp WeiXin Java Tools - MP diff --git a/weixin-java-osgi/pom.xml b/weixin-java-osgi/pom.xml index fbcfaba6..892870f0 100644 --- a/weixin-java-osgi/pom.xml +++ b/weixin-java-osgi/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.0 + 2.6.0-SNAPSHOT weixin-java-osgi From e2a19959633ad4780287d9f9bfc8fb7064fb9d07 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 14 Feb 2017 16:57:53 +0800 Subject: [PATCH 03/63] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E4=BC=81=E4=B8=9A=E7=BA=A2=E5=8C=85=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9A=E5=8F=91=E9=80=81=E7=BA=A2=E5=8C=85?= =?UTF-8?q?=E7=9A=84=E8=BF=94=E5=9B=9E=E7=BB=93=E6=9E=9C=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E7=AD=BE=E5=90=8D=EF=BC=8C=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E8=BF=9B=E8=A1=8C=E7=AD=BE=E5=90=8D=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E3=80=82=20#140?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java index 4424e211..fae2d931 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java @@ -179,7 +179,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { } String responseContent = this.executeWithKey(url, request.toXML()); WxPaySendRedpackResult result = WxPaySendRedpackResult.fromXML(responseContent, WxPaySendRedpackResult.class); - this.checkResult(result); + //毋须校验,因为没有返回签名信息 + // this.checkResult(result); return result; } From 00c2aae212d947f20d4193d19e3e16698be61ebd Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 19 Feb 2017 18:17:48 +0800 Subject: [PATCH 04/63] small update for a test method --- .../me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java index 42819b2f..51b80e36 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java @@ -93,7 +93,7 @@ public class WxMpMenuServiceImplTest { } @Test - public void testCreateMenu2() throws WxErrorException { + public void testCreateMenu_by_json() throws WxErrorException { String a = "{\n" + " \"menu\": {\n" + " \"button\": [\n" From 29f054a9c1d122c648ae45d15ab92424b422a1d6 Mon Sep 17 00:00:00 2001 From: YuJian Date: Sat, 25 Feb 2017 18:10:42 +0800 Subject: [PATCH 05/63] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8E=A5=E6=94=B6?= =?UTF-8?q?=E4=BC=9A=E5=91=98=E4=BF=A1=E6=81=AF=E4=BA=8B=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E7=B1=BB=E5=9E=8B=E5=B8=B8=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 事件推送用于“用户填写、提交资料后,会有事件推送给商家,开发者可以在接收到事件通知后调用激活接口,传入会员卡号、初始积分等信息或者调用拉取会员信息接口获取会员信息,进行会员管理。” --- .../src/main/java/me/chanjar/weixin/common/api/WxConsts.java | 1 + 1 file changed, 1 insertion(+) 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..40057dde 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"; //接收会员信息事件推送 //以下为微信认证事件 /** * 资质认证成功 From 70a4512030a19bc996f098ae762bfa7e0f8724a7 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Wed, 1 Mar 2017 23:35:48 +0800 Subject: [PATCH 06/63] =?UTF-8?q?#123=20=E6=94=AF=E6=8C=81=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=95=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/api/WxMpConfigStorage.java | 10 +++++ .../mp/api/WxMpInMemoryConfigStorage.java | 20 +++++++++ .../mp/api/impl/WxMpPayServiceImpl.java | 10 +++++ .../mp/bean/pay/request/WxPayBaseRequest.java | 42 +++++++++++++++++++ .../mp/bean/pay/result/WxPayBaseResult.java | 26 ++++++++++++ 5 files changed, 108 insertions(+) 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..0e623260 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 @@ -80,6 +80,16 @@ public interface WxMpConfigStorage { String getAppId(); + /** + * 服务商模式下的子商户公众账号ID + */ + String getSubAppId(); + + /** + * 服务商模式下的子商户号 + */ + String getSubMchId(); + String getSecret(); String getPartnerId(); 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..34ef4f5d 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 @@ -20,6 +20,8 @@ import java.util.concurrent.locks.ReentrantLock; public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { protected volatile String appId; + protected volatile String subAppId; + protected volatile String subMchId; protected volatile String secret; protected volatile String partnerId; protected volatile String partnerKey; @@ -349,4 +351,22 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { public boolean useSandboxForWxPay() { return false; } + + @Override + public String getSubAppId() { + return subAppId; + } + + public void setSubAppId(String subAppId) { + this.subAppId = subAppId; + } + + @Override + public String getSubMchId() { + return subMchId; + } + + public void setSubMchId(String subMchId) { + this.subMchId = subMchId; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java index fae2d931..d8a98544 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java @@ -268,9 +268,19 @@ public class WxMpPayServiceImpl implements WxMpPayService { if (StringUtils.isBlank(request.getAppid())) { request.setAppid(getConfig().getAppId()); } + if (StringUtils.isBlank(request.getMchId())) { request.setMchId(getConfig().getPartnerId()); } + + if (StringUtils.isBlank(request.getSubAppId())) { + request.setAppid(getConfig().getSubAppId()); + } + + if (StringUtils.isBlank(request.getSubMchId())) { + request.setMchId(getConfig().getSubMchId()); + } + if (StringUtils.isBlank(request.getNonceStr())) { request.setNonceStr(String.valueOf(System.currentTimeMillis())); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java index c13f1b8f..d7867191 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayBaseRequest.java @@ -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/result/WxPayBaseResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
index 4dd133ab..b7227085 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayBaseResult.java
@@ -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
    */

From 0f6b246c54504bd041e088848e95a2c97a327542 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Wed, 1 Mar 2017 23:39:13 +0800
Subject: [PATCH 07/63] =?UTF-8?q?=E5=8F=91=E5=B8=83=E4=B8=B4=E6=97=B6?=
 =?UTF-8?q?=E7=89=88=E6=9C=AC2.5.1.BETA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 pom.xml                    | 2 +-
 weixin-java-common/pom.xml | 2 +-
 weixin-java-cp/pom.xml     | 2 +-
 weixin-java-mp/pom.xml     | 2 +-
 weixin-java-osgi/pom.xml   | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index c941dbc7..15e60765 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.1.BETA
   pom
   WeiXin Java Tools - Parent
   微信公众号、企业号上级POM
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index 1d1ad69c..84c10bc5 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.1.BETA
   
 
   weixin-java-common
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index e49f6c16..e233bfc7 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.1.BETA
   
 
   weixin-java-cp
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index 9cbea35a..08bb297b 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.1.BETA
   
   weixin-java-mp
   WeiXin Java Tools - MP
diff --git a/weixin-java-osgi/pom.xml b/weixin-java-osgi/pom.xml
index 892870f0..6cc65720 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.1.BETA
   
 
   weixin-java-osgi

From eee954b7361d7974977c2d2a741c012f98f52391 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 5 Mar 2017 22:49:17 +0800
Subject: [PATCH 08/63] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98?=
 =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81=E7=8B=AC=E7=AB=8B=E6=88=90?=
 =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=AD=90=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 pom.xml                                       |   1 +
 weixin-java-mp/pom.xml                        |  20 -
 .../weixin/mp/api/WxMpConfigStorage.java      |  47 ---
 .../mp/api/WxMpInMemoryConfigStorage.java     | 101 -----
 .../me/chanjar/weixin/mp/api/WxMpService.java |   7 -
 .../weixin/mp/api/impl/WxMpServiceImpl.java   |   6 -
 .../pay/result/WxPayOrderNotifyResult.java    | 392 ------------------
 .../mp/api/impl/WxMpPayServiceImplTest.java   | 195 ---------
 .../weixin/mp/api/test/TestConfigStorage.java |   6 -
 weixin-java-pay/pom.xml                       |  50 +++
 .../wxpay/bean}/WxPayOrderNotifyCoupon.java   | 127 +++---
 .../wxpay/bean}/WxPayOrderNotifyResponse.java | 119 +++---
 .../bean}/request/WxEntPayQueryRequest.java   |  19 +-
 .../wxpay/bean}/request/WxEntPayRequest.java  | 151 +++----
 .../wxpay/bean}/request/WxPayBaseRequest.java |   2 +-
 .../request/WxPayDownloadBillRequest.java     |   2 +-
 .../bean}/request/WxPayOrderCloseRequest.java |   4 +-
 .../bean}/request/WxPayOrderQueryRequest.java |   3 +-
 .../request/WxPayRedpackQueryRequest.java     |   2 +-
 .../request/WxPayRefundQueryRequest.java      |   2 +-
 .../bean}/request/WxPayRefundRequest.java     | 123 +++++-
 .../bean}/request/WxPayReportRequest.java     |   2 +-
 .../request/WxPaySendRedpackRequest.java      |  53 +--
 .../request/WxPayUnifiedOrderRequest.java     |  71 ++--
 .../bean}/result/WxEntPayQueryResult.java     |   3 +-
 .../wxpay/bean}/result/WxEntPayResult.java    |   3 +-
 .../wxpay/bean}/result/WxPayBaseResult.java   |   2 +-
 .../wxpay/bean}/result/WxPayCommonResult.java |   2 +-
 .../bean}/result/WxPayOrderCloseResult.java   |   2 +-
 .../bean/result/WxPayOrderNotifyResult.java   | 392 ++++++++++++++++++
 .../bean}/result/WxPayOrderQueryResult.java   |   4 +-
 .../bean}/result/WxPayRedpackQueryResult.java |   2 +-
 .../bean}/result/WxPayRefundQueryResult.java  |   4 +-
 .../wxpay/bean}/result/WxPayRefundResult.java |  10 +-
 .../bean}/result/WxPaySendRedpackResult.java  |   8 +-
 .../bean}/result/WxPayUnifiedOrderResult.java |   4 +-
 .../binarywang/wxpay/config/WxPayConfig.java  | 157 +++++++
 .../WxPayOrderNotifyResultConverter.java      | 259 ++++++------
 .../wxpay/service/WxPayService.java           |  33 +-
 .../wxpay/service/impl/WxPayServiceImpl.java  | 211 ++++++----
 .../bean}/result/WxPayBaseResultTest.java     |   3 +-
 .../result/WxPayOrderQueryResultTest.java     |   2 +-
 .../result/WxPayRefundQueryResultTest.java    |   2 +-
 .../result/WxPaySendRedpackResultTest.java    |   2 +-
 .../service/impl/WxMpPayServiceImplTest.java  | 196 +++++++++
 .../wxpay/testbase/ApiTestModule.java         |  38 ++
 .../wxpay/testbase/XmlWxPayConfig.java        |  31 ++
 .../src/test/resources/logback-test.xml       |  16 +
 .../src/test/resources/test-config.sample.xml |  13 +
 49 files changed, 1596 insertions(+), 1308 deletions(-)
 delete mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderNotifyResult.java
 delete mode 100644 weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java
 create mode 100644 weixin-java-pay/pom.xml
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/WxPayOrderNotifyCoupon.java (93%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/WxPayOrderNotifyResponse.java (94%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxEntPayQueryRequest.java (87%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxEntPayRequest.java (63%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPayBaseRequest.java (98%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPayDownloadBillRequest.java (97%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPayOrderCloseRequest.java (85%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPayOrderQueryRequest.java (96%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPayRedpackQueryRequest.java (95%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPayRefundQueryRequest.java (98%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPayRefundRequest.java (60%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPayReportRequest.java (99%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPaySendRedpackRequest.java (82%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/request/WxPayUnifiedOrderRequest.java (92%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxEntPayQueryResult.java (97%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxEntPayResult.java (96%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxPayBaseResult.java (99%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxPayCommonResult.java (88%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxPayOrderCloseResult.java (92%)
 create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderNotifyResult.java
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxPayOrderQueryResult.java (99%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxPayRedpackQueryResult.java (99%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxPayRefundQueryResult.java (99%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxPayRefundResult.java (98%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxPaySendRedpackResult.java (97%)
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean}/result/WxPayUnifiedOrderResult.java (87%)
 create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java
 rename {weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/converter}/WxPayOrderNotifyResultConverter.java (95%)
 rename weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java (93%)
 rename weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java => weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java (74%)
 rename {weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean}/result/WxPayBaseResultTest.java (94%)
 rename {weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean}/result/WxPayOrderQueryResultTest.java (98%)
 rename {weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean}/result/WxPayRefundQueryResultTest.java (97%)
 rename {weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/pay => weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean}/result/WxPaySendRedpackResultTest.java (98%)
 create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxMpPayServiceImplTest.java
 create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/ApiTestModule.java
 create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/XmlWxPayConfig.java
 create mode 100644 weixin-java-pay/src/test/resources/logback-test.xml
 create mode 100644 weixin-java-pay/src/test/resources/test-config.sample.xml

diff --git a/pom.xml b/pom.xml
index 15e60765..702cf9d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,7 @@
     weixin-java-common
     weixin-java-cp
     weixin-java-mp
+    weixin-java-pay
     weixin-java-osgi
   
 
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index 08bb297b..d2f658d6 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -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 0e623260..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;
 
@@ -80,39 +79,8 @@ public interface WxMpConfigStorage {
 
   String getAppId();
 
-  /**
-   * 服务商模式下的子商户公众账号ID
-   */
-  String getSubAppId();
-
-  /**
-   * 服务商模式下的子商户号
-   */
-  String getSubMchId();
-
   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(); @@ -131,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 * @@ -154,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 34ef4f5d..df062f1e 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; @@ -20,13 +16,7 @@ import java.util.concurrent.locks.ReentrantLock; public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { protected volatile String appId; - protected volatile String subAppId; - protected volatile String subMchId; 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; @@ -54,8 +44,6 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { */ protected volatile File tmpDirFile; - protected volatile SSLContext sslContext; - protected volatile ApacheHttpClientBuilder apacheHttpClientBuilder; @Override @@ -257,41 +245,6 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { return ToStringUtils.toSimpleString(this); } - @Override - public String getPartnerId() { - return this.partnerId; - } - - public void setPartnerId(String partnerId) { - this.partnerId = partnerId; - } - - @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 void setTradeType(String tradeType) { - this.tradeType = tradeType; - } - @Override public File getTmpDirFile() { return this.tmpDirFile; @@ -301,38 +254,6 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { this.tmpDirFile = tmpDirFile; } - @Override - public SSLContext getSslContext() { - return this.sslContext; - } - - @Override - public void setSslContext(SSLContext context) { - this.sslContext = context; - } - - @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); - } - } - @Override public ApacheHttpClientBuilder getApacheHttpClientBuilder() { return this.apacheHttpClientBuilder; @@ -347,26 +268,4 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { return true; } - @Override - public boolean useSandboxForWxPay() { - return false; - } - - @Override - public String getSubAppId() { - return subAppId; - } - - public void setSubAppId(String subAppId) { - this.subAppId = subAppId; - } - - @Override - public String getSubMchId() { - return subMchId; - } - - public void setSubMchId(String subMchId) { - this.subMchId = subMchId; - } } 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..b86be56f 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 @@ -45,7 +45,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); @@ -505,11 +504,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/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/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-pay/pom.xml b/weixin-java-pay/pom.xml new file mode 100644 index 00000000..1c387ac1 --- /dev/null +++ b/weixin-java-pay/pom.xml @@ -0,0 +1,50 @@ + + + + weixin-java-parent + com.github.binarywang + 2.5.1.BETA + + 4.0.0 + + weixin-java-pay + + + + 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 98% 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 d7867191..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; 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 99% 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 b7227085..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; 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 74% 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 d8a98544..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,19 +293,19 @@ 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.setAppid(getConfig().getSubAppId()); + request.setSubAppId(this.getConfig().getSubAppId()); } if (StringUtils.isBlank(request.getSubMchId())) { - request.setMchId(getConfig().getSubMchId()); + request.setSubMchId(this.getConfig().getSubMchId()); } if (StringUtils.isBlank(request.getNonceStr())) { @@ -307,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); @@ -333,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; @@ -346,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; @@ -358,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())); @@ -393,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); } @@ -411,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); @@ -419,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"))); @@ -474,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 @@ -484,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"; } @@ -512,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 @@ -522,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..820101c5 --- /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.TestPayConfig; +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(((TestPayConfig) 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("122") + .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..0ca02bb6 --- /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")) { + TestPayConfig config = this.fromXml(TestPayConfig.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..227c365d --- /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 TestPayConfig 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 + From 710b0f64802417e60d4e7d1c88c601c935414b41 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 5 Mar 2017 22:50:11 +0800 Subject: [PATCH 09/63] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81=E7=8B=AC=E7=AB=8B=E6=88=90?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=AD=90=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/WxMpPayServiceImplTest.java | 6 +- .../wxpay/testbase/ApiTestModule.java | 2 +- .../wxpay/testbase/XmlWxPayConfig.java | 62 +++++++++---------- 3 files changed, 35 insertions(+), 35 deletions(-) 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 index 820101c5..c658d124 100644 --- 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 @@ -5,7 +5,7 @@ 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.TestPayConfig; +import com.github.binarywang.wxpay.testbase.XmlWxPayConfig; import com.google.inject.Inject; import me.chanjar.weixin.common.exception.WxErrorException; import org.slf4j.Logger; @@ -105,7 +105,7 @@ public class WxMpPayServiceImplTest { request.setActName("abc"); request.setClientIp("aaa"); request.setMchBillNo("aaaa"); - request.setReOpenid(((TestPayConfig) this.wxService.getConfig()).getOpenid()); + request.setReOpenid(((XmlWxPayConfig) this.wxService.getConfig()).getOpenid()); WxPaySendRedpackResult redpackResult = this.wxService.sendRedpack(request); this.logger.info(redpackResult.toString()); } @@ -131,7 +131,7 @@ public class WxMpPayServiceImplTest { .spbillCreateIp("111111") .notifyURL("111111") .tradeType("JSAPI") - .openid("122") + .openid(((XmlWxPayConfig) this.wxService.getConfig()).getOpenid()) .outTradeNo("111111") .build()); this.logger.info(result.toString()); 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 index 0ca02bb6..d5a028d1 100644 --- 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 @@ -16,7 +16,7 @@ public class ApiTestModule implements Module { @Override public void configure(Binder binder) { try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) { - TestPayConfig config = this.fromXml(TestPayConfig.class, is1); + XmlWxPayConfig config = this.fromXml(XmlWxPayConfig.class, is1); WxPayService wxService = new WxPayServiceImpl(); wxService.setConfig(config); 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 index 227c365d..a10f36f3 100644 --- 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 @@ -1,31 +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 TestPayConfig 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; - } -} +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; + } +} From d50d58dedd20d9ac0fcc592430d93b800aa27e29 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 6 Mar 2017 00:51:21 +0800 Subject: [PATCH 10/63] =?UTF-8?q?=E5=8F=91=E5=B8=83=E4=B8=B4=E6=97=B6?= =?UTF-8?q?=E7=89=88=E6=9C=AC2.5.2.BETA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 3 +-- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-osgi/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 702cf9d0..a204972c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.github.binarywang weixin-java-parent - 2.5.1.BETA + 2.5.2.BETA pom WeiXin Java Tools - Parent 微信公众号、企业号上级POM @@ -87,7 +87,6 @@ weixin-java-cp weixin-java-mp weixin-java-pay - weixin-java-osgi diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 84c10bc5..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.5.1.BETA + 2.5.2.BETA weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index e233bfc7..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.5.1.BETA + 2.5.2.BETA weixin-java-cp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index d2f658d6..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.5.1.BETA + 2.5.2.BETA weixin-java-mp WeiXin Java Tools - MP diff --git a/weixin-java-osgi/pom.xml b/weixin-java-osgi/pom.xml index 6cc65720..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.5.1.BETA + 2.5.2.BETA weixin-java-osgi diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 1c387ac1..cef2f578 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ weixin-java-parent com.github.binarywang - 2.5.1.BETA + 2.5.2.BETA 4.0.0 From f3ac9983be315fe107a3871728e14e5318cd24ee Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 6 Mar 2017 00:54:26 +0800 Subject: [PATCH 11/63] update pom --- weixin-java-pay/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index cef2f578..a192271b 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -10,6 +10,8 @@ 4.0.0 weixin-java-pay + WeiXin Java Tools - PAY + 微信支付 Java SDK From 7340e03636e01045d648c298012795ca5f3a271c Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 9 Mar 2017 11:09:43 +0800 Subject: [PATCH 12/63] =?UTF-8?q?=E5=B0=86=E9=83=A8=E5=88=86=E4=BB=85?= =?UTF-8?q?=E4=BE=9B=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=B8=B8=E9=87=8F=E6=8C=AA=E8=B5=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + .../me/chanjar/weixin/common/api/WxConsts.java | 7 ------- .../me/chanjar/weixin/cp/api/TestConstants.java | 17 +++++++++++++++++ .../chanjar/weixin/cp/api/WxCpMediaAPITest.java | 8 ++++---- .../weixin/mp/api/WxMpMassMessageAPITest.java | 9 +++++---- .../api/impl/WxMpMaterialServiceImplTest.java | 9 +++++---- .../weixin/mp/api/test/TestConstants.java | 17 +++++++++++++++++ .../weixin/mp/demo/DemoImageHandler.java | 3 ++- 8 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/TestConstants.java create mode 100644 weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConstants.java diff --git a/pom.xml b/pom.xml index a204972c..b257fece 100644 --- a/pom.xml +++ b/pom.xml @@ -87,6 +87,7 @@ weixin-java-cp weixin-java-mp weixin-java-pay + 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 40057dde..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 @@ -136,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/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/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/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() From d9472e4e4ce93bffb8f0e131b31181d0df39f149 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 10 Mar 2017 16:42:07 +0800 Subject: [PATCH 13/63] =?UTF-8?q?=E6=B8=85=E7=90=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/api/WxMpInMemoryConfigStorage.java | 16 ---------------- .../weixin/mp/api/impl/WxMpServiceImpl.java | 3 --- .../weixin/mp/api/test/ApiTestModule.java | 3 +-- 3 files changed, 1 insertion(+), 21 deletions(-) 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 df062f1e..12d2dbc5 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 @@ -51,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; @@ -86,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; 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 b86be56f..f5a8d24d 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(); 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); From 4be02996d3c8f3fc7820e31b17fe02794a23646f Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 10 Mar 2017 17:35:44 +0800 Subject: [PATCH 14/63] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BC=BA=E5=B0=91?= =?UTF-8?q?=E7=9A=84setter=E5=92=8Cgetter=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mp/api/WxMpInMemoryConfigStorage.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) 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 12d2dbc5..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 @@ -247,6 +247,34 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { this.apacheHttpClientBuilder = apacheHttpClientBuilder; } + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public void setJsapiTicket(String jsapiTicket) { + this.jsapiTicket = jsapiTicket; + } + + public long getJsapiTicketExpiresTime() { + return this.jsapiTicketExpiresTime; + } + + public void setJsapiTicketExpiresTime(long jsapiTicketExpiresTime) { + this.jsapiTicketExpiresTime = jsapiTicketExpiresTime; + } + + public void setCardApiTicket(String cardApiTicket) { + this.cardApiTicket = cardApiTicket; + } + + public long getCardApiTicketExpiresTime() { + return this.cardApiTicketExpiresTime; + } + + public void setCardApiTicketExpiresTime(long cardApiTicketExpiresTime) { + this.cardApiTicketExpiresTime = cardApiTicketExpiresTime; + } + @Override public boolean autoRefreshToken() { return true; From 7ee9ac0beb927e9d98cc0bdbbb140ac1587733da Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 13 Mar 2017 16:02:09 +0800 Subject: [PATCH 15/63] replace this.wxMpConfigStorage with this.getWxMpConfigStorage() #155 --- .../weixin/mp/api/impl/WxMpServiceImpl.java | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) 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 f5a8d24d..dc3ea6c0 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 @@ -55,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; @@ -69,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) { @@ -94,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(); @@ -106,7 +106,7 @@ public class WxMpServiceImpl implements WxMpService { } finally { lock.unlock(); } - return this.wxMpConfigStorage.getAccessToken(); + return this.getWxMpConfigStorage().getAccessToken(); } @Override @@ -116,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 @@ -147,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); @@ -212,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); @@ -228,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); @@ -254,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"); @@ -266,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); @@ -393,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); } } @@ -426,20 +426,20 @@ public class WxMpServiceImpl implements WxMpService { apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); } - apacheHttpClientBuilder.httpProxyHost(this.wxMpConfigStorage.getHttpProxyHost()) - .httpProxyPort(this.wxMpConfigStorage.getHttpProxyPort()) - .httpProxyUsername(this.wxMpConfigStorage.getHttpProxyUsername()) - .httpProxyPassword(this.wxMpConfigStorage.getHttpProxyPassword()); + apacheHttpClientBuilder.httpProxyHost(this.getWxMpConfigStorage().getHttpProxyHost()) + .httpProxyPort(this.getWxMpConfigStorage().getHttpProxyPort()) + .httpProxyUsername(this.getWxMpConfigStorage().getHttpProxyUsername()) + .httpProxyPassword(this.getWxMpConfigStorage().getHttpProxyPassword()); - // if (this.wxMpConfigStorage.getSSLContext() != null) { + // if (this.getWxMpConfigStorage().getSSLContext() != null) { // SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( - // this.wxMpConfigStorage.getSSLContext(), new String[] { "TLSv1" }, null, + // this.getWxMpConfigStorage().getSSLContext(), new String[] { "TLSv1" }, null, // new DefaultHostnameVerifier()); // apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf); // } - if (this.wxMpConfigStorage.getHttpProxyHost() != null && this.wxMpConfigStorage.getHttpProxyPort() > 0) { - this.httpProxy = new HttpHost(this.wxMpConfigStorage.getHttpProxyHost(), this.wxMpConfigStorage.getHttpProxyPort()); + if (this.getWxMpConfigStorage().getHttpProxyHost() != null && this.getWxMpConfigStorage().getHttpProxyPort() > 0) { + this.httpProxy = new HttpHost(this.getWxMpConfigStorage().getHttpProxyHost(), this.getWxMpConfigStorage().getHttpProxyPort()); } this.httpClient = apacheHttpClientBuilder.build(); From db85c1990b675d764730bc6f38a320ae9da87241 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 13 Mar 2017 17:02:24 +0800 Subject: [PATCH 16/63] replace this.wxMpConfigStorage with this.getWxMpConfigStorage() #155 --- .../weixin/mp/api/impl/WxMpServiceImpl.java | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) 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 dc3ea6c0..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 @@ -420,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.getWxMpConfigStorage().getHttpProxyHost()) - .httpProxyPort(this.getWxMpConfigStorage().getHttpProxyPort()) - .httpProxyUsername(this.getWxMpConfigStorage().getHttpProxyUsername()) - .httpProxyPassword(this.getWxMpConfigStorage().getHttpProxyPassword()); + apacheHttpClientBuilder.httpProxyHost(configStorage.getHttpProxyHost()) + .httpProxyPort(configStorage.getHttpProxyPort()) + .httpProxyUsername(configStorage.getHttpProxyUsername()) + .httpProxyPassword(configStorage.getHttpProxyPassword()); - // if (this.getWxMpConfigStorage().getSSLContext() != null) { - // SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( - // this.getWxMpConfigStorage().getSSLContext(), new String[] { "TLSv1" }, null, - // new DefaultHostnameVerifier()); - // apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf); - // } - - if (this.getWxMpConfigStorage().getHttpProxyHost() != null && this.getWxMpConfigStorage().getHttpProxyPort() > 0) { - this.httpProxy = new HttpHost(this.getWxMpConfigStorage().getHttpProxyHost(), this.getWxMpConfigStorage().getHttpProxyPort()); + if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { + this.httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); } this.httpClient = apacheHttpClientBuilder.build(); From 024d8309473c05b6797b1972acdaa1119f548335 Mon Sep 17 00:00:00 2001 From: aimilin6688 Date: Tue, 14 Mar 2017 11:27:36 +0800 Subject: [PATCH 17/63] =?UTF-8?q?=E6=89=AB=E6=8F=8F=E6=94=AF=E4=BB=98=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=94=9F=E6=88=90=E4=BA=8C=E7=BB=B4=E7=A0=81?= =?UTF-8?q?URL=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/service/WxPayService.java | 13 +++++++++ .../wxpay/service/impl/WxPayServiceImpl.java | 29 ++++++++++++------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 34ba8cdc..9097d8ab 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -262,6 +262,19 @@ public interface WxPayService { * @return 生成的二维码的字节数组 */ byte[] createScanPayQrcodeMode1(String productId, File logoFile, Integer sideLength); + + /** + *
    +   * 扫码支付模式一生成二维码的方法
    +   * 二维码中的内容为链接,形式为:
    +   * weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX
    +   * 其中XXXXX为商户需要填写的内容,商户将该链接生成二维码,如需要打印发布二维码,需要采用此格式。商户可调用第三方库生成二维码图片。
    +   * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4
    +   * 
    + * @param productId 产品Id + * @return 生成的二维码URL连接 + */ + String createScanPayQrcodeMode1(String productId); /** *
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java
    index dea7a7e8..b480a5f3 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java
    @@ -382,37 +382,44 @@ public class WxPayServiceImpl implements WxPayService {
     
       @Override
       public byte[] createScanPayQrcodeMode1(String productId, File logoFile, Integer sideLength) {
    -    //weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX
    +    String content = createScanPayQrcodeMode1(productId);
    +    return createQrcode(content, logoFile, sideLength);
    +  }
    +  
    +  @Override
    +  public String createScanPayQrcodeMode1(String productId){
    +	//weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX
         StringBuilder codeUrl = new StringBuilder("weixin://wxpay/bizpayurl?");
         Map params = Maps.newHashMap();
         params.put("appid", this.getConfig().getAppId());
         params.put("mch_id", this.getConfig().getMchId());
         params.put("product_id", productId);
    -    params.put("time_stamp", String.valueOf(System.currentTimeMillis()));
    +    params.put("time_stamp", String.valueOf(System.currentTimeMillis() / 1000));//这里需要秒,10位数字
         params.put("nonce_str", String.valueOf(System.currentTimeMillis()));
     
         String sign = this.createSign(params);
         params.put("sign", sign);
     
    +    
         for (String key : params.keySet()) {
           codeUrl.append(key + "=" + params.get(key) + "&");
         }
     
         String content = codeUrl.toString().substring(0, codeUrl.length() - 1);
    -    if (sideLength == null || sideLength < 1) {
    -      return QrcodeUtils.createQrcode(content, logoFile);
    -    }
    -
    -    return QrcodeUtils.createQrcode(content, sideLength, logoFile);
    +    log.debug("扫码支付模式一生成二维码的URL:{}",content);
    +    return  content;
       }
     
       @Override
       public byte[] createScanPayQrcodeMode2(String codeUrl, File logoFile, Integer sideLength) {
    -    if (sideLength == null || sideLength < 1) {
    -      return QrcodeUtils.createQrcode(codeUrl, logoFile);
    +    return createQrcode(codeUrl, logoFile, sideLength);
    +  }
    +  
    +  private byte[] createQrcode(String content, File logoFile, Integer sideLength) {
    +	if (sideLength == null || sideLength < 1) {
    +      return QrcodeUtils.createQrcode(content, logoFile);
         }
    -
    -    return QrcodeUtils.createQrcode(codeUrl, sideLength, logoFile);
    +    return QrcodeUtils.createQrcode(content, sideLength, logoFile);
       }
     
       public void report(WxPayReportRequest request) throws WxErrorException {
    
    From b8c8d105796a39e62fe671d24c23acebf8dfd020 Mon Sep 17 00:00:00 2001
    From: aimilin6688 
    Date: Tue, 14 Mar 2017 11:53:25 +0800
    Subject: [PATCH 18/63] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=AB=E7=A0=81?=
     =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=9B=9E=E6=8E=89=E7=BB=93=E6=9E=9CBean?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../bean/result/WxScanPayNotifyResult.java    | 24 +++++++++++++++++++
     1 file changed, 24 insertions(+)
     create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxScanPayNotifyResult.java
    
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxScanPayNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxScanPayNotifyResult.java
    new file mode 100644
    index 00000000..5bf11068
    --- /dev/null
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxScanPayNotifyResult.java
    @@ -0,0 +1,24 @@
    +package com.github.binarywang.wxpay.bean.result;
    +
    +import java.io.Serializable;
    +
    +import com.thoughtworks.xstream.annotations.XStreamAlias;
    +
    +public class WxScanPayNotifyResult  extends WxPayBaseResult implements Serializable{
    +  private static final long serialVersionUID = 3381324564266118986L;
    +  
    +  /**
    +   * 预支付ID
    +   */
    +  @XStreamAlias("prepay_id")
    +  private String prepayId;
    +
    +  public String getPrepayId() {
    +    return prepayId;
    +  }
    +
    +  public void setPrepayId(String prepayId) {
    +    this.prepayId = prepayId;
    +  }
    +  
    +}
    
    From 9d5f19c9601f1dc427e958a3da0e04bc29abaa76 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Tue, 14 Mar 2017 11:37:06 +0800
    Subject: [PATCH 19/63] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=8F=9C=E5=8D=95?=
     =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=8E=A5=E5=8F=A3=E5=8F=8D=E5=BA=8F=E5=88=97?=
     =?UTF-8?q?=E5=8C=96=E6=97=B6subButtons=E4=B8=BA=E7=A9=BA=E7=9A=84?=
     =?UTF-8?q?=E9=97=AE=E9=A2=98=20#142?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java
    index 48979f7c..125043c8 100644
    --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java
    +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java
    @@ -1,5 +1,6 @@
     package me.chanjar.weixin.common.bean.menu;
     
    +import com.google.gson.annotations.SerializedName;
     import me.chanjar.weixin.common.util.ToStringUtils;
     
     import java.io.Serializable;
    @@ -13,8 +14,11 @@ public class WxMenuButton implements Serializable {
       private String name;
       private String key;
       private String url;
    +
    +  @SerializedName("media_id")
       private String mediaId;
     
    +  @SerializedName("sub_button")
       private List subButtons = new ArrayList<>();
     
       @Override
    
    From 6ad58a80bef755463e07ce639eb8b12139038d7d Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Mon, 20 Mar 2017 11:21:54 +0800
    Subject: [PATCH 20/63] =?UTF-8?q?=E5=8F=91=E5=B8=83=E4=B8=B4=E6=97=B6?=
     =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E6=9C=AC=202.5.3.BETA?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     pom.xml                    | 2 +-
     weixin-java-common/pom.xml | 2 +-
     weixin-java-cp/pom.xml     | 2 +-
     weixin-java-mp/pom.xml     | 2 +-
     weixin-java-pay/pom.xml    | 2 +-
     5 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/pom.xml b/pom.xml
    index b257fece..89de1ee1 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -5,7 +5,7 @@
       4.0.0
       com.github.binarywang
       weixin-java-parent
    -  2.5.2.BETA
    +  2.5.3.BETA
       pom
       WeiXin Java Tools - Parent
       微信公众号、企业号上级POM
    diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
    index f2756129..4af9053d 100644
    --- a/weixin-java-common/pom.xml
    +++ b/weixin-java-common/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.2.BETA
    +    2.5.3.BETA
       
     
       weixin-java-common
    diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
    index c6640046..032d3102 100644
    --- a/weixin-java-cp/pom.xml
    +++ b/weixin-java-cp/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.2.BETA
    +    2.5.3.BETA
       
     
       weixin-java-cp
    diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
    index 74d99189..da6388a2 100644
    --- a/weixin-java-mp/pom.xml
    +++ b/weixin-java-mp/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.2.BETA
    +    2.5.3.BETA
       
       weixin-java-mp
       WeiXin Java Tools - MP
    diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
    index a192271b..ad85dc85 100644
    --- a/weixin-java-pay/pom.xml
    +++ b/weixin-java-pay/pom.xml
    @@ -5,7 +5,7 @@
       
         weixin-java-parent
         com.github.binarywang
    -    2.5.2.BETA
    +    2.5.3.BETA
       
       4.0.0
     
    
    From 1649b30e23b951e1444233b4ed0bd97b4a3b8fee Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Tue, 21 Mar 2017 16:40:27 +0800
    Subject: [PATCH 21/63] remove junit
    
    ---
     pom.xml                    | 6 ------
     weixin-java-common/pom.xml | 5 -----
     2 files changed, 11 deletions(-)
    
    diff --git a/pom.xml b/pom.xml
    index 89de1ee1..c1bb1511 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -158,12 +158,6 @@
     
       
         
    -      
    -        junit
    -        junit
    -        4.11
    -        test
    -      
           
             com.google.inject
             guice
    diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
    index 4af9053d..47257f73 100644
    --- a/weixin-java-common/pom.xml
    +++ b/weixin-java-common/pom.xml
    @@ -19,11 +19,6 @@
           xstream
           1.4.7
         
    -    
    -      junit
    -      junit
    -      test
    -    
         
           org.testng
           testng
    
    From b4a454dfeda8d3e542b9f3a7336826f38f345a1b Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Tue, 21 Mar 2017 16:41:48 +0800
    Subject: [PATCH 22/63] =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BB=A3=E7=A0=81?=
     =?UTF-8?q?=EF=BC=8C=E5=8E=BB=E6=8E=89=E5=B8=A6=E6=9D=A5=E8=BF=87=E5=A4=9A?=
     =?UTF-8?q?jar=E5=8C=85=E4=BE=9D=E8=B5=96=E7=9A=84xml-path=EF=BC=8C?=
     =?UTF-8?q?=E4=BD=BF=E7=94=A8java=E8=87=AA=E5=B8=A6=E7=9A=84xpath=E6=9D=A5?=
     =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=9B=B8=E5=BA=94=E5=8A=9F=E8=83=BD=E3=80=82?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     weixin-java-pay/pom.xml                       |   5 -
     .../wxpay/bean/result/WxPayBaseResult.java    | 106 ++++++++++++------
     .../bean/result/WxPayOrderQueryResult.java    |   8 +-
     .../bean/result/WxPayRefundQueryResult.java   |  26 ++---
     .../bean/result/WxPayBaseResultTest.java      |  24 +++-
     5 files changed, 104 insertions(+), 65 deletions(-)
    
    diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
    index ad85dc85..20489828 100644
    --- a/weixin-java-pay/pom.xml
    +++ b/weixin-java-pay/pom.xml
    @@ -26,11 +26,6 @@
           3.7
           
         
    -    
    -      io.rest-assured
    -      xml-path
    -      3.0.1
    -    
         
           com.github.binarywang
           qrcode-utils
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    index f68379b8..a23a2604 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    @@ -1,20 +1,26 @@
     package com.github.binarywang.wxpay.bean.result;
     
    +import com.google.common.base.Joiner;
     import com.google.common.collect.Maps;
     import com.thoughtworks.xstream.XStream;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    -import io.restassured.internal.path.xml.NodeChildrenImpl;
    -import io.restassured.internal.path.xml.NodeImpl;
    -import io.restassured.path.xml.XmlPath;
    -import io.restassured.path.xml.element.Node;
    -import io.restassured.path.xml.exception.XmlPathException;
     import me.chanjar.weixin.common.util.ToStringUtils;
     import me.chanjar.weixin.common.util.xml.XStreamInitializer;
    +import org.apache.commons.lang3.StringUtils;
     import org.slf4j.Logger;
     import org.slf4j.LoggerFactory;
    -
    +import org.w3c.dom.Document;
    +import org.w3c.dom.NodeList;
    +import org.xml.sax.SAXException;
    +
    +import javax.xml.parsers.DocumentBuilderFactory;
    +import javax.xml.parsers.ParserConfigurationException;
    +import javax.xml.xpath.XPathConstants;
    +import javax.xml.xpath.XPathExpressionException;
    +import javax.xml.xpath.XPathFactory;
    +import java.io.ByteArrayInputStream;
    +import java.io.IOException;
     import java.math.BigDecimal;
    -import java.util.Iterator;
     import java.util.Map;
     
     /**
    @@ -82,6 +88,11 @@ public abstract class WxPayBaseResult {
       @XStreamAlias("sign")
       private String sign;
     
    +  /**
    +   * xml的Document对象,用于解析xml文本
    +   */
    +  private Document xmlDoc;
    +
       /**
        * 将单位分转换成单位圆
        *
    @@ -211,51 +222,74 @@ public abstract class WxPayBaseResult {
        * 将bean通过保存的xml字符串转换成map
        */
       public Map toMap() {
    -    Map result = Maps.newHashMap();
    -    XmlPath xmlPath = new XmlPath(this.xmlString);
    -    NodeImpl rootNode = null;
    -    try {
    -      rootNode = xmlPath.get("xml");
    -    } catch (XmlPathException e) {
    +    if (StringUtils.isBlank(this.xmlString)) {
           throw new RuntimeException("xml数据有问题,请核实!");
         }
     
    -    if (rootNode == null) {
    -      throw new RuntimeException("xml数据有问题,请核实!");
    -    }
    +    Map result = Maps.newHashMap();
    +    Document doc = this.getXmlDoc();
     
    -    Iterator iterator = rootNode.children().nodeIterator();
    -    while (iterator.hasNext()) {
    -      Node node = iterator.next();
    -      result.put(node.name(), node.value());
    +    try {
    +      NodeList list = (NodeList) XPathFactory.newInstance().newXPath()
    +        .compile("/xml/*")
    +        .evaluate(doc, XPathConstants.NODESET);
    +      int len = list.getLength();
    +      for (int i = 0; i < len; i++) {
    +        result.put(list.item(i).getNodeName(), list.item(i).getTextContent());
    +      }
    +    } catch (XPathExpressionException e) {
    +      throw new RuntimeException("非法的xml文本内容:" + xmlString);
         }
     
         return result;
       }
     
    -  private String getXmlValue(XmlPath xmlPath, String path) {
    -    if (xmlPath.get(path) instanceof NodeChildrenImpl) {
    -      if (((NodeChildrenImpl) xmlPath.get(path)).size() == 0) {
    -        return null;
    -      }
    +  /**
    +   * 将xml字符串转换成Document对象,以便读取其元素值
    +   */
    +  protected Document getXmlDoc() {
    +    if (this.xmlDoc != null) {
    +      return this.xmlDoc;
    +    }
    +
    +    try {
    +      this.xmlDoc = DocumentBuilderFactory
    +        .newInstance()
    +        .newDocumentBuilder()
    +        .parse(new ByteArrayInputStream(this.xmlString.getBytes("UTF-8")));
    +      return xmlDoc;
    +    } catch (SAXException | IOException | ParserConfigurationException e) {
    +      throw new RuntimeException("非法的xml文本内容:" + this.xmlString);
         }
     
    -    return xmlPath.getString(path);
       }
     
    -  protected  T getXmlValue(XmlPath xmlPath, String path, Class clz) {
    -    String value = this.getXmlValue(xmlPath, path);
    -    if (value == null) {
    -      return null;
    +  /**
    +   * 获取xml中元素的值
    +   */
    +  protected String getXmlValue(String... path) {
    +    Document doc = this.getXmlDoc();
    +    String expression = String.format("/%s//text()", Joiner.on("/").join(path));
    +    try {
    +      return (String) XPathFactory
    +        .newInstance()
    +        .newXPath()
    +        .compile(expression)
    +        .evaluate(doc, XPathConstants.STRING);
    +    } catch (XPathExpressionException e) {
    +      throw new RuntimeException("未找到相应路径的文本:" + expression);
         }
    +  }
     
    -    switch (clz.getSimpleName()) {
    -      case "String":
    -        return (T) value;
    -      case "Integer":
    -        return (T) Integer.valueOf(value);
    +  /**
    +   * 获取xml中元素的值,作为int值返回
    +   */
    +  protected Integer getXmlValueAsInt(String... path) {
    +    String result = this.getXmlValue(path);
    +    if (StringUtils.isBlank(result)) {
    +      return null;
         }
     
    -    throw new UnsupportedOperationException("暂时不支持此种类型的数据");
    +    return Integer.valueOf(result);
       }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java
    index a4379ab1..ff087bf0 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java
    @@ -2,7 +2,6 @@ package com.github.binarywang.wxpay.bean.result;
     
     import com.google.common.collect.Lists;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    -import io.restassured.path.xml.XmlPath;
     
     import java.util.List;
     
    @@ -395,11 +394,10 @@ public class WxPayOrderQueryResult extends WxPayBaseResult {
       public void composeCoupons() {
         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++) {
    -        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)));
    +        this.coupons.add(new Coupon(this.getXmlValue("xml/coupon_type_" + i),
    +          this.getXmlValue("xml/coupon_id_" + i),
    +          this.getXmlValueAsInt("xml/coupon_fee_" + i)));
           }
         }
       }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java
    index e3604b88..1916fdb9 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java
    @@ -2,7 +2,6 @@ package com.github.binarywang.wxpay.bean.result;
     
     import com.google.common.collect.Lists;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    -import io.restassured.path.xml.XmlPath;
     
     import java.util.List;
     
    @@ -190,22 +189,21 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
       public void composeRefundRecords() {
         if (this.refundCount != null && this.refundCount > 0) {
           this.refundRecords = Lists.newArrayList();
    -      XmlPath xmlPath = new XmlPath(this.getXmlString());
     
           for (int i = 0; i < this.refundCount; i++) {
             RefundRecord refundRecord = new RefundRecord();
             this.refundRecords.add(refundRecord);
     
    -        refundRecord.setOutRefundNo(this.getXmlValue(xmlPath, "xml.out_refund_no_" + i, String.class));
    -        refundRecord.setRefundId(this.getXmlValue(xmlPath, "xml.refund_id_" + i, String.class));
    -        refundRecord.setRefundChannel(this.getXmlValue(xmlPath, "xml.refund_channel_" + i, String.class));
    -        refundRecord.setRefundFee(this.getXmlValue(xmlPath, "xml.refund_fee_" + i, Integer.class));
    -        refundRecord.setSettlementRefundFee(this.getXmlValue(xmlPath, "xml.settlement_refund_fee_" + i, Integer.class));
    -        refundRecord.setCouponType(this.getXmlValue(xmlPath, "xml.coupon_type_" + i, String.class));
    -        refundRecord.setCouponRefundFee(this.getXmlValue(xmlPath, "xml.coupon_refund_fee_" + i, Integer.class));
    -        refundRecord.setCouponRefundCount(this.getXmlValue(xmlPath, "xml.coupon_refund_count_" + i, Integer.class));
    -        refundRecord.setRefundStatus(this.getXmlValue(xmlPath, "xml.refund_status_" + i, String.class));
    -        refundRecord.setRefundRecvAccout(this.getXmlValue(xmlPath, "xml.refund_recv_accout_" + i, String.class));
    +        refundRecord.setOutRefundNo(this.getXmlValue("xml/out_refund_no_" + i));
    +        refundRecord.setRefundId(this.getXmlValue("xml/refund_id_" + i));
    +        refundRecord.setRefundChannel(this.getXmlValue("xml/refund_channel_" + i));
    +        refundRecord.setRefundFee(this.getXmlValueAsInt("xml/refund_fee_" + i));
    +        refundRecord.setSettlementRefundFee(this.getXmlValueAsInt("xml/settlement_refund_fee_" + i));
    +        refundRecord.setCouponType(this.getXmlValue("xml/coupon_type_" + i));
    +        refundRecord.setCouponRefundFee(this.getXmlValueAsInt("xml/coupon_refund_fee_" + i));
    +        refundRecord.setCouponRefundCount(this.getXmlValueAsInt("xml/coupon_refund_count_" + i));
    +        refundRecord.setRefundStatus(this.getXmlValue("xml/refund_status_" + i));
    +        refundRecord.setRefundRecvAccout(this.getXmlValue("xml/refund_recv_accout_" + i));
     
             if (refundRecord.getCouponRefundCount() == null || refundRecord.getCouponRefundCount() == 0) {
               continue;
    @@ -215,8 +213,8 @@ public class WxPayRefundQueryResult extends WxPayBaseResult {
             for (int j = 0; j < refundRecord.getCouponRefundCount(); j++) {
               coupons.add(
                 new RefundRecord.RefundCoupon(
    -              this.getXmlValue(xmlPath, "xml.coupon_refund_id_" + i + "_" + j, String.class),
    -              this.getXmlValue(xmlPath, "xml.coupon_refund_fee_" + i + "_" + j, Integer.class)
    +              this.getXmlValue("xml/coupon_refund_id_" + i + "_" + j),
    +              this.getXmlValueAsInt("xml/coupon_refund_fee_" + i + "_" + j)
                 )
               );
             }
    diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java
    index c99f4115..d6a1f7b8 100644
    --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java
    +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java
    @@ -1,6 +1,5 @@
     package com.github.binarywang.wxpay.bean.result;
     
    -import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
     import org.testng.*;
     import org.testng.annotations.*;
     
    @@ -13,6 +12,15 @@ import java.util.Map;
      * 
    */ public class WxPayBaseResultTest { + + @Test + public void testGetXmlValue() throws Exception { + } + + @Test + public void testXml2Doc() throws Exception { + } + @Test public void testToMap() throws Exception { WxPayOrderQueryResult result = new WxPayOrderQueryResult(); @@ -40,11 +48,17 @@ public class WxPayBaseResultTest { Map map = result.toMap(); System.out.println(map); - Assert.assertEquals("SUCCESS", map.get("return_code")); - Assert.assertEquals("订单额外描述", map.get("attach")); + Assert.assertEquals(map.get("return_code"), "SUCCESS"); + Assert.assertEquals(map.get("attach"), "订单额外描述"); + + } - result.setXmlString(""); - System.out.println(result.toMap()); + @Test(expectedExceptions = {RuntimeException.class}) + public void testToMap_with_empty_xmlString() { + WxPayOrderQueryResult result = new WxPayOrderQueryResult(); + result.setXmlString(" "); + Map map = result.toMap(); + System.out.println(map); } } From 86cdb500c6e29608638516ff2836c72776b4f8bd Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 21 Mar 2017 16:46:20 +0800 Subject: [PATCH 23/63] remove junit --- weixin-java-cp/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 032d3102..35f20559 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -19,11 +19,6 @@ weixin-java-common ${project.version}
    - - junit - junit - test - org.testng testng From 6847a41759073168f05a1db409470d98803bfb23 Mon Sep 17 00:00:00 2001 From: "F.Dong" Date: Tue, 21 Mar 2017 17:02:35 +0800 Subject: [PATCH 24/63] pull request (#163) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 新增两个接口:获取设备绑定的用户、获取用户绑定的设备 * update * 申请设备二维码接口的返回格式有变动,做出相应更改。 --- .../weixin/mp/api/WxMpDeviceService.java | 19 +++++++ .../mp/api/impl/WxMpDeviceServiceImpl.java | 22 ++++++-- .../weixin/mp/bean/device/BaseResp.java | 22 ++++---- .../bean/device/WxDeviceBindDeviceResult.java | 46 +++++++++++++++ .../mp/bean/device/WxDeviceOpenIdResult.java | 56 +++++++++++++++++++ .../mp/bean/device/WxDeviceQrCodeResult.java | 14 ++--- 6 files changed, 158 insertions(+), 21 deletions(-) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java index a565011c..2580d23a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java @@ -76,5 +76,24 @@ public interface WxMpDeviceService { */ WxDeviceBindResult compelUnbind(WxDeviceBind wxDeviceBind) throws WxErrorException; + /** + *
    +   *   通过device type和device id 获取设备主人的openid
    +   *   详情请见:http://iot.weixin.qq.com/wiki/new/index.html?page=3-4-11
    +   * 
    + * @param deviceType 设备类型,目前为"公众账号原始ID" + * @param deviceId 设备ID + * @return WxDeviceOpenIdResult + */ + WxDeviceOpenIdResult getOpenId(String deviceType,String deviceId) throws WxErrorException; + /** + *
    +   *   通过openid获取用户在当前devicetype下绑定的deviceid列表`
    +   *   详情请见:http://iot.weixin.qq.com/wiki/new/index.html?page=3-4-12
    +   * 
    + * @param openId 要查询的用户的openid + * @return WxDeviceBindDeviceResult + */ + WxDeviceBindDeviceResult getBindDevice(String openId) throws WxErrorException; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java index e7dbea1b..5c942365 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java @@ -23,7 +23,7 @@ public class WxMpDeviceServiceImpl implements WxMpDeviceService { @Override public TransMsgResp transMsg(WxDeviceMsg msg) throws WxErrorException { String url = API_URL_PREFIX + "/transmsg"; - String response = this.wxMpService.post(url,msg.toJson()); + String response = this.wxMpService.post(url, msg.toJson()); return TransMsgResp.fromJson(response); } @@ -37,21 +37,21 @@ public class WxMpDeviceServiceImpl implements WxMpDeviceService { @Override public WxDeviceAuthorizeResult authorize(WxDeviceAuthorize wxDeviceAuthorize) throws WxErrorException { String url = API_URL_PREFIX + "/authorize_device"; - String response = this.wxMpService.post(url,wxDeviceAuthorize.toJson()); + String response = this.wxMpService.post(url, wxDeviceAuthorize.toJson()); return WxDeviceAuthorizeResult.fromJson(response); } @Override public WxDeviceBindResult bind(WxDeviceBind wxDeviceBind) throws WxErrorException { String url = API_URL_PREFIX + "/bind"; - String response = this.wxMpService.post(url,wxDeviceBind.toJson()); + String response = this.wxMpService.post(url, wxDeviceBind.toJson()); return WxDeviceBindResult.fromJson(response); } @Override public WxDeviceBindResult compelBind(WxDeviceBind wxDeviceBind) throws WxErrorException { String url = API_URL_PREFIX + "/compel_bind"; - String response = this.wxMpService.post(url,wxDeviceBind.toJson()); + String response = this.wxMpService.post(url, wxDeviceBind.toJson()); return WxDeviceBindResult.fromJson(response); } @@ -68,5 +68,19 @@ public class WxMpDeviceServiceImpl implements WxMpDeviceService { String response = this.wxMpService.post(url, wxDeviceBind.toJson()); return WxDeviceBindResult.fromJson(response); } + + @Override + public WxDeviceOpenIdResult getOpenId(String deviceType, String deviceId) throws WxErrorException { + String url = API_URL_PREFIX + "/get_openid"; + String response = this.wxMpService.get(url, "device_type=" + deviceType + "&device_id=" + deviceId); + return WxDeviceOpenIdResult.fromJson(response); + } + + @Override + public WxDeviceBindDeviceResult getBindDevice(String openId) throws WxErrorException { + String url = API_URL_PREFIX+"/get_bind_device"; + String response = this.wxMpService.get(url,"openid="+openId); + return WxDeviceBindDeviceResult.fromJson(response); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java index 41629c55..b0dd6ec3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java @@ -38,23 +38,25 @@ public class BaseResp extends AbstractDeviceBean{ } private class BaseInfo { - private String device_type; - private String device_id; + @SerializedName("device_type") + private String deviceType; + @SerializedName("device_id") + private String deviceId; - public String getDevice_type() { - return device_type; + public String getDeviceType() { + return deviceType; } - public void setDevice_type(String device_type) { - this.device_type = device_type; + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; } - public String getDevice_id() { - return device_id; + public String getDeviceId() { + return deviceId; } - public void setDevice_id(String device_id) { - this.device_id = device_id; + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java new file mode 100644 index 00000000..d0ed2dcd --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java @@ -0,0 +1,46 @@ +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * Created by keungtung on 16/12/2016. + */ +public class WxDeviceBindDeviceResult extends AbstractDeviceBean { + @SerializedName("resp_msg") + private RespMsg respMsg; + @SerializedName("openid") + private String openId; + @SerializedName("device_list") + private List devices; + + public static WxDeviceBindDeviceResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindDeviceResult.class); + } + + private class Device { + @SerializedName("device_type") + private String deviceType; + @SerializedName("device_id") + private String deviceId; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java new file mode 100644 index 00000000..0a23eddd --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java @@ -0,0 +1,56 @@ +package me.chanjar.weixin.mp.bean.device; + +import com.google.gson.annotations.SerializedName; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + * Created by keungtung on 16/12/2016. + */ +public class WxDeviceOpenIdResult extends AbstractDeviceBean { + @SerializedName("errcode") + private Integer errCode; + @SerializedName("errmsg") + private String errMsg; + @SerializedName("open_id") + private List openIds; + @SerializedName("resp_msg") + private RespMsg respMsg; + + public static WxDeviceOpenIdResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxDeviceOpenIdResult.class); + } + + public Integer getErrCode() { + return errCode; + } + + public void setErrCode(Integer errCode) { + this.errCode = errCode; + } + + public String getErrMsg() { + return errMsg; + } + + public void setErrMsg(String errMsg) { + this.errMsg = errMsg; + } + + public List getOpenIds() { + return openIds; + } + + public void setOpenIds(List openIds) { + this.openIds = openIds; + } + + public RespMsg getRespMsg() { + return respMsg; + } + + public void setRespMsg(RespMsg respMsg) { + this.respMsg = respMsg; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java index 9c89ff67..ff3028be 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java @@ -6,15 +6,15 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; /** * Created by keungtung on 10/12/2016. */ -public class WxDeviceQrCodeResult extends AbstractDeviceBean{ +public class WxDeviceQrCodeResult extends AbstractDeviceBean { @SerializedName("deviceid") private String deviceId; @SerializedName("qrticket") private String qrTicket; @SerializedName("devicelicence") private String deviceLicence; - @SerializedName("resp_msg") - private RespMsg respMsg; + @SerializedName("base_resp") + private BaseResp baseResp; public static WxDeviceQrCodeResult fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxDeviceQrCodeResult.class); @@ -28,12 +28,12 @@ public class WxDeviceQrCodeResult extends AbstractDeviceBean{ this.deviceLicence = deviceLicence; } - public RespMsg getRespMsg() { - return respMsg; + public BaseResp getBaseResp() { + return baseResp; } - public void setRespMsg(RespMsg respMsg) { - this.respMsg = respMsg; + public void setBaseResp(BaseResp baseResp) { + this.baseResp = baseResp; } public String getDeviceId() { From bf2b4eed55a7ba472f7de1070b3b2578a52ee145 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 21 Mar 2017 18:01:30 +0800 Subject: [PATCH 25/63] =?UTF-8?q?=E5=AD=97=E7=AC=A6=E7=BC=96=E7=A0=81?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E7=94=A8=E5=B8=B8=E9=87=8F=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../binarywang/wxpay/service/impl/WxPayServiceImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java index b480a5f3..6e0cb148 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java @@ -385,7 +385,7 @@ public class WxPayServiceImpl implements WxPayService { String content = createScanPayQrcodeMode1(productId); return createQrcode(content, logoFile, sideLength); } - + @Override public String createScanPayQrcodeMode1(String productId){ //weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX @@ -400,7 +400,7 @@ public class WxPayServiceImpl implements WxPayService { String sign = this.createSign(params); params.put("sign", sign); - + for (String key : params.keySet()) { codeUrl.append(key + "=" + params.get(key) + "&"); } @@ -414,7 +414,7 @@ public class WxPayServiceImpl implements WxPayService { public byte[] createScanPayQrcodeMode2(String codeUrl, File logoFile, Integer sideLength) { return createQrcode(codeUrl, logoFile, sideLength); } - + private byte[] createQrcode(String content, File logoFile, Integer sideLength) { if (sideLength == null || sideLength < 1) { return QrcodeUtils.createQrcode(content, logoFile); @@ -491,7 +491,7 @@ public class WxPayServiceImpl implements WxPayService { HttpPost httpPost = new HttpPost(url); try (CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build()) { - httpPost.setEntity(new StringEntity(new String(requestStr.getBytes("UTF-8"), "ISO-8859-1"))); + httpPost.setEntity(new StringEntity(new String(requestStr.getBytes(CharEncoding.UTF_8), CharEncoding.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); From 9cdfaec7f3cd714ba8b9e503d842bc298cd7e3fd Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Wed, 22 Mar 2017 15:23:37 +0800 Subject: [PATCH 26/63] =?UTF-8?q?=E4=BC=81=E4=B8=9A=E4=BB=98=E6=AC=BE?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E4=B8=ADmchId=E5=AD=97=E6=AE=B5=E7=9A=84?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E8=AE=BE=E7=BD=AE=E5=8E=BB=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bean/request/WxEntPayQueryRequest.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java index 5574948a..30ff0a87 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java @@ -21,19 +21,6 @@ import me.chanjar.weixin.common.util.ToStringUtils; */ @XStreamAlias("xml") public class WxEntPayQueryRequest extends WxPayBaseRequest { - /** - *
    -   * 商户号
    -   * mch_id
    -   * 是
    -   * 10000098
    -   * String(32)
    -   * 微信支付分配的商户号
    -   * 
    - */ - @XStreamAlias("mchid") - private String mchId; - /** *
        * 商户订单号
    @@ -48,16 +35,6 @@ public class WxEntPayQueryRequest extends WxPayBaseRequest {
       @XStreamAlias("partner_trade_no")
       private String partnerTradeNo;
     
    -  @Override
    -  public String getMchId() {
    -    return this.mchId;
    -  }
    -
    -  @Override
    -  public void setMchId(String mchId) {
    -    this.mchId = mchId;
    -  }
    -
       public String getPartnerTradeNo() {
         return this.partnerTradeNo;
       }
    
    From 998445e3c07097048927fa4cf8d147cc077dfb8c Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Wed, 22 Mar 2017 17:05:59 +0800
    Subject: [PATCH 27/63] =?UTF-8?q?=E5=8F=91=E5=B8=83=E4=B8=B4=E6=97=B6?=
     =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E6=9C=AC2.5.4.BETA?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     pom.xml                    | 2 +-
     weixin-java-common/pom.xml | 2 +-
     weixin-java-cp/pom.xml     | 2 +-
     weixin-java-mp/pom.xml     | 2 +-
     weixin-java-pay/pom.xml    | 2 +-
     5 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/pom.xml b/pom.xml
    index c1bb1511..4a5acb94 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -5,7 +5,7 @@
       4.0.0
       com.github.binarywang
       weixin-java-parent
    -  2.5.3.BETA
    +  2.5.4.BETA
       pom
       WeiXin Java Tools - Parent
       微信公众号、企业号上级POM
    diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
    index 47257f73..6b9728f2 100644
    --- a/weixin-java-common/pom.xml
    +++ b/weixin-java-common/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.3.BETA
    +    2.5.4.BETA
       
     
       weixin-java-common
    diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
    index 35f20559..c517b8f8 100644
    --- a/weixin-java-cp/pom.xml
    +++ b/weixin-java-cp/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.3.BETA
    +    2.5.4.BETA
       
     
       weixin-java-cp
    diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
    index da6388a2..18673a83 100644
    --- a/weixin-java-mp/pom.xml
    +++ b/weixin-java-mp/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.3.BETA
    +    2.5.4.BETA
       
       weixin-java-mp
       WeiXin Java Tools - MP
    diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
    index 20489828..5ef5bc7d 100644
    --- a/weixin-java-pay/pom.xml
    +++ b/weixin-java-pay/pom.xml
    @@ -5,7 +5,7 @@
       
         weixin-java-parent
         com.github.binarywang
    -    2.5.3.BETA
    +    2.5.4.BETA
       
       4.0.0
     
    
    From 2df0f56849a2920552fbf5838eee32b891876627 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Wed, 22 Mar 2017 18:24:22 +0800
    Subject: [PATCH 28/63] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=BB=98=E8=AE=A4?=
     =?UTF-8?q?=E6=97=A0=E5=8F=82=E6=9E=84=E9=80=A0=E6=96=B9=E6=B3=95?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../binarywang/wxpay/bean/request/WxPayRefundRequest.java      | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
    index d8e7e403..36fb76d6 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
    @@ -143,6 +143,9 @@ public class WxPayRefundRequest extends WxPayBaseRequest {
       @XStreamAlias("refund_account")
       private String refundAccount;
     
    +  public WxPayRefundRequest() {
    +  }
    +
       private WxPayRefundRequest(Builder builder) {
         setDeviceInfo(builder.deviceInfo);
         setAppid(builder.appid);
    
    From db6e91a360c1a843e41e4e72c87204a54ffa353e Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Wed, 22 Mar 2017 18:37:00 +0800
    Subject: [PATCH 29/63] remove something
    
    ---
     .../wxpay/service/impl/WxMpPayServiceImplTest.java     | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    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
    index c658d124..bf5e7e34 100644
    --- 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
    @@ -60,7 +60,7 @@ public class WxMpPayServiceImplTest {
       /**
        * Test method for {@link WxPayService#refund(WxPayRefundRequest)} .
        */
    -  @Test//(dependsOnMethods = {"setSSLKey"})
    +  @Test
       public void testRefund() throws Exception {
         WxPayRefundResult result = this.wxService.refund(
           WxPayRefundRequest.newBuilder()
    @@ -99,7 +99,7 @@ public class WxMpPayServiceImplTest {
       /**
        * Test method for {@link WxPayService#sendRedpack(WxPaySendRedpackRequest)} .
        */
    -  @Test//(dependsOnMethods = {"setSSLKey"})
    +  @Test
       public void testSendRedpack() throws Exception {
         WxPaySendRedpackRequest request = new WxPaySendRedpackRequest();
         request.setActName("abc");
    @@ -113,7 +113,7 @@ public class WxMpPayServiceImplTest {
       /**
        * Test method for {@link WxPayService#queryRedpack(java.lang.String)}.
        */
    -  @Test//(dependsOnMethods = {"setSSLKey"})
    +  @Test
       public void testQueryRedpack() throws Exception {
         WxPayRedpackQueryResult redpackResult = this.wxService.queryRedpack("aaaa");
         this.logger.info(redpackResult.toString());
    @@ -157,7 +157,7 @@ public class WxMpPayServiceImplTest {
       /**
        * Test method for {@link WxPayService#entPay(WxEntPayRequest)}.
        */
    -  @Test//(dependsOnMethods = {"setSSLKey"})
    +  @Test
       public void testEntPay() throws WxErrorException {
         WxEntPayRequest request = new WxEntPayRequest();
         this.logger.info(this.wxService.entPay(request).toString());
    @@ -166,7 +166,7 @@ public class WxMpPayServiceImplTest {
       /**
        * Test method for {@link WxPayService#queryEntPay(java.lang.String)}.
        */
    -  @Test//(dependsOnMethods = {"setSSLKey"})
    +  @Test
       public void testQueryEntPay() throws WxErrorException {
         this.logger.info(this.wxService.queryEntPay("11212121").toString());
       }
    
    From 8ec509a30b73033adb106f36031dc6fc31fcc319 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Wed, 22 Mar 2017 18:37:36 +0800
    Subject: [PATCH 30/63] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BC=81=E4=B8=9A?=
     =?UTF-8?q?=E4=BB=98=E6=AC=BE=E6=9F=A5=E8=AF=A2=E7=9A=84=E4=BB=A3=E7=A0=81?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../github/binarywang/wxpay/service/impl/WxPayServiceImpl.java   | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java
    index 6e0cb148..ffa8127d 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java
    @@ -370,6 +370,7 @@ public class WxPayServiceImpl implements WxPayService {
       @Override
       public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxErrorException {
         WxEntPayQueryRequest request = new WxEntPayQueryRequest();
    +    request.setPartnerTradeNo(partnerTradeNo);
         this.initRequest(request);
         request.setSign(this.createSign(request));
     
    
    From 13e4b1462318fe75d1e4314cc3343ee94e092d55 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Thu, 23 Mar 2017 17:18:00 +0800
    Subject: [PATCH 31/63] fix some code
    
    ---
     .../java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java     | 2 ++
     .../me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java | 5 ++---
     2 files changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java
    index ddfd02a5..ba8665e9 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java
    +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpQrcodeService.java
    @@ -6,8 +6,10 @@ import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
     import java.io.File;
     
     /**
    + * 
      * 二维码相关操作接口
      * 文档地址:https://mp.weixin.qq.com/wiki?action=doc&id=mp1443433542&t=0.9274944716856435
    + * 
    * @author Binary Wang */ public interface WxMpQrcodeService { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java index 26d86baa..8659f2af 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java @@ -43,9 +43,8 @@ public class WxMpQrcodeServiceImpl implements WxMpQrcodeService { String url = API_URL_PREFIX + "/create"; JsonObject json = new JsonObject(); json.addProperty("action_name", "QR_SCENE"); - if (expireSeconds != null) { - json.addProperty("expire_seconds", expireSeconds); - } + json.addProperty("expire_seconds", expireSeconds); + JsonObject actionInfo = new JsonObject(); JsonObject scene = new JsonObject(); scene.addProperty("scene_id", sceneId); From d35e094df6f4ee81da625241fa81a13df36ffcac Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 23 Mar 2017 17:27:51 +0800 Subject: [PATCH 32/63] add missing test --- .../{WxMpPayServiceImplTest.java => WxPayServiceImplTest.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/{WxMpPayServiceImplTest.java => WxPayServiceImplTest.java} (100%) 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/WxPayServiceImplTest.java similarity index 100% rename from weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxMpPayServiceImplTest.java rename to weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java From f63e9349453724c441d848ce12dc0a8f649116e2 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 23 Mar 2017 17:28:01 +0800 Subject: [PATCH 33/63] add missing test --- .../service/impl/WxPayServiceImplTest.java | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java index bf5e7e34..7fa30ac2 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java @@ -15,6 +15,7 @@ import org.testng.annotations.*; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Map; import static org.testng.Assert.*; @@ -26,23 +27,24 @@ import static org.testng.Assert.*; */ @Test @Guice(modules = ApiTestModule.class) -public class WxMpPayServiceImplTest { +public class WxPayServiceImplTest { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Inject - protected WxPayService wxService; + protected WxPayService payService; @Test public void testGetPayInfo() throws Exception { - + Map payInfo = this.payService.getPayInfo(WxPayUnifiedOrderRequest.builder().body("abc").build()); + this.logger.info(payInfo.toString()); } @Test public void testDownloadBill() throws Exception { - File file = this.wxService.downloadBill("20170101", "ALL", "GZIP", "1111111"); + File file = this.payService.downloadBill("20170101", "ALL", "GZIP", "1111111"); assertNotNull(file); //必填字段为空时,抛出异常 - this.wxService.downloadBill("", "", "", null); + this.payService.downloadBill("", "", "", null); } @Test @@ -54,7 +56,7 @@ public class WxMpPayServiceImplTest { request.setReturnCode("aaa"); request.setResultCode("aaa"); request.setUserIp("8.8.8"); - this.wxService.report(request); + this.payService.report(request); } /** @@ -62,7 +64,7 @@ public class WxMpPayServiceImplTest { */ @Test public void testRefund() throws Exception { - WxPayRefundResult result = this.wxService.refund( + WxPayRefundResult result = this.payService.refund( WxPayRefundRequest.newBuilder() .outRefundNo("aaa") .outTradeNo("1111") @@ -79,20 +81,20 @@ public class WxMpPayServiceImplTest { public void testRefundQuery() throws Exception { WxPayRefundQueryResult result; - result = this.wxService.refundQuery("1", "", "", ""); + result = this.payService.refundQuery("1", "", "", ""); this.logger.info(result.toString()); - result = this.wxService.refundQuery("", "2", "", ""); + result = this.payService.refundQuery("", "2", "", ""); this.logger.info(result.toString()); - result = this.wxService.refundQuery("", "", "3", ""); + result = this.payService.refundQuery("", "", "3", ""); this.logger.info(result.toString()); - result = this.wxService.refundQuery("", "", "", "4"); + result = this.payService.refundQuery("", "", "", "4"); this.logger.info(result.toString()); //测试四个参数都填的情况,应该报异常的 - result = this.wxService.refundQuery("1", "2", "3", "4"); + result = this.payService.refundQuery("1", "2", "3", "4"); this.logger.info(result.toString()); } @@ -105,8 +107,8 @@ public class WxMpPayServiceImplTest { request.setActName("abc"); request.setClientIp("aaa"); request.setMchBillNo("aaaa"); - request.setReOpenid(((XmlWxPayConfig) this.wxService.getConfig()).getOpenid()); - WxPaySendRedpackResult redpackResult = this.wxService.sendRedpack(request); + request.setReOpenid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()); + WxPaySendRedpackResult redpackResult = this.payService.sendRedpack(request); this.logger.info(redpackResult.toString()); } @@ -115,7 +117,7 @@ public class WxMpPayServiceImplTest { */ @Test public void testQueryRedpack() throws Exception { - WxPayRedpackQueryResult redpackResult = this.wxService.queryRedpack("aaaa"); + WxPayRedpackQueryResult redpackResult = this.payService.queryRedpack("aaaa"); this.logger.info(redpackResult.toString()); } @@ -124,14 +126,14 @@ public class WxMpPayServiceImplTest { */ @Test public void testUnifiedOrder() throws WxErrorException { - WxPayUnifiedOrderResult result = this.wxService + WxPayUnifiedOrderResult result = this.payService .unifiedOrder(WxPayUnifiedOrderRequest.builder() .body("我去") .totalFee(1) .spbillCreateIp("111111") .notifyURL("111111") .tradeType("JSAPI") - .openid(((XmlWxPayConfig) this.wxService.getConfig()).getOpenid()) + .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()) .outTradeNo("111111") .build()); this.logger.info(result.toString()); @@ -142,8 +144,8 @@ public class WxMpPayServiceImplTest { */ @Test public void testQueryOrder() throws WxErrorException { - this.logger.info(this.wxService.queryOrder("11212121", null).toString()); - this.logger.info(this.wxService.queryOrder(null, "11111").toString()); + this.logger.info(this.payService.queryOrder("11212121", null).toString()); + this.logger.info(this.payService.queryOrder(null, "11111").toString()); } /** @@ -151,7 +153,7 @@ public class WxMpPayServiceImplTest { */ @Test public void testCloseOrder() throws WxErrorException { - this.logger.info(this.wxService.closeOrder("11212121").toString()); + this.logger.info(this.payService.closeOrder("11212121").toString()); } /** @@ -160,7 +162,7 @@ public class WxMpPayServiceImplTest { @Test public void testEntPay() throws WxErrorException { WxEntPayRequest request = new WxEntPayRequest(); - this.logger.info(this.wxService.entPay(request).toString()); + this.logger.info(this.payService.entPay(request).toString()); } /** @@ -168,13 +170,13 @@ public class WxMpPayServiceImplTest { */ @Test public void testQueryEntPay() throws WxErrorException { - this.logger.info(this.wxService.queryEntPay("11212121").toString()); + this.logger.info(this.payService.queryEntPay("11212121").toString()); } @Test public void testCreateScanPayQrcodeMode1() throws Exception { String productId = "abc"; - byte[] bytes = this.wxService.createScanPayQrcodeMode1(productId, null, null); + byte[] bytes = this.payService.createScanPayQrcodeMode1(productId, null, null); Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); Files.write(qrcodeFilePath, bytes); String qrcodeContent = QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()); @@ -187,7 +189,7 @@ public class WxMpPayServiceImplTest { @Test public void testCreateScanPayQrcodeMode2() throws Exception { String qrcodeContent = "abc"; - byte[] bytes = this.wxService.createScanPayQrcodeMode2(qrcodeContent, null, null); + byte[] bytes = this.payService.createScanPayQrcodeMode2(qrcodeContent, null, null); Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); Files.write(qrcodeFilePath, bytes); assertEquals(QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()), qrcodeContent); From 6945e7e0f9bc84794f3b7f90cd139c2e38ea9365 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 23 Mar 2017 18:18:22 +0800 Subject: [PATCH 34/63] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=88=B7=E5=8D=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E6=8F=90=E4=BA=A4API=20#101?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bean/request/WxPayMicropayRequest.java | 375 ++++++++++++++++++ .../wxpay/bean/result/WxPayBaseResult.java | 12 +- .../bean/result/WxPayMicropayResult.java | 328 +++++++++++++++ .../wxpay/service/WxPayService.java | 15 +- .../wxpay/service/impl/WxPayServiceImpl.java | 25 +- .../service/impl/WxPayServiceImplTest.java | 15 + 6 files changed, 761 insertions(+), 9 deletions(-) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java new file mode 100644 index 00000000..10aac649 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java @@ -0,0 +1,375 @@ +package com.github.binarywang.wxpay.bean.request; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import me.chanjar.weixin.common.annotation.Required; + +/** + *
    + *  提交刷卡支付请求对象类
    + * Created by Binary Wang on 2017-3-23.
    + * @author binarywang(Binary Wang)
    + * 
    + */ +@XStreamAlias("xml") +public class WxPayMicropayRequest extends WxPayBaseRequest { + /** + *
    +   * 签名类型
    +   * sign_type
    +   * 否
    +   * String(32)
    +   * HMAC-SHA256
    +   * 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
    +   **/
    +  @XStreamAlias("sign_type")
    +  private String signType;
    +
    +  /**
    +   * 
    +   * 商品描述
    +   * body
    +   * 是
    +   * String(128)
    +   * image形象店-深圳腾大- QQ公仔
    +   * 商品简单描述,该字段须严格按照规范传递,具体请见参数规定
    +   **/
    +  @Required
    +  @XStreamAlias("body")
    +  private String body;
    +
    +  /**
    +   * 
    +   * 商品详情
    +   * detail
    +   * 否
    +   * String(6000)
    +   *
    +   * 单品优惠功能字段,需要接入请见详细说明
    +   **/
    +  @XStreamAlias("detail")
    +  private String detail;
    +
    +  /**
    +   * 
    +   * 附加数据
    +   * attach
    +   * 否
    +   * String(127)
    +   * 说明
    +   * 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
    +   **/
    +  @XStreamAlias("attach")
    +  private String attach;
    +
    +  /**
    +   * 
    +   * 商户订单号
    +   * out_trade_no
    +   * 是
    +   * String(32)
    +   * 1217752501201407033233368018
    +   * 商户系统内部的订单号,32个字符内、可包含字母,其他说明见商户订单号
    +   **/
    +  @Required
    +  @XStreamAlias("out_trade_no")
    +  private String outTradeNo;
    +
    +  /**
    +   * 
    +   * 订单金额
    +   * total_fee
    +   * 是
    +   * Int
    +   * 888
    +   * 订单总金额,单位为分,只能为整数,详见支付金额
    +   **/
    +  @Required
    +  @XStreamAlias("total_fee")
    +  private Integer totalFee;
    +
    +  /**
    +   * 
    +   * 货币类型
    +   * fee_type
    +   * 否
    +   * String(16)
    +   * CNY
    +   * 符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   **/
    +  @XStreamAlias("fee_type")
    +  private String feeType;
    +
    +  /**
    +   * 
    +   * 终端IP
    +   * spbill_create_ip
    +   * 是
    +   * String(16)
    +   * 8.8.8.8
    +   * 调用微信支付API的机器IP
    +   **/
    +  @Required
    +  @XStreamAlias("spbill_create_ip")
    +  private String spbillCreateIp;
    +
    +  /**
    +   * 
    +   * 商品标记
    +   * goods_tag
    +   * 否
    +   * String(32)
    +   * 1234
    +   * 商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
    +   **/
    +  @XStreamAlias("goods_tag")
    +  private String goodsTag;
    +
    +  /**
    +   * 
    +   * 指定支付方式
    +   * limit_pay
    +   * 否
    +   * String(32)
    +   * no_credit
    +   * no_credit--指定不能使用信用卡支付
    +   **/
    +  @XStreamAlias("limit_pay")
    +  private String limitPay;
    +
    +  /**
    +   * 
    +   * 授权码
    +   * auth_code
    +   * 是
    +   * String(128)
    +   * 120061098828009406
    +   * 扫码支付授权码,设备读取用户微信中的条码或者二维码信息注:用户刷卡条形码规则:18位纯数字,以10、11、12、13、14、15开头)
    +   **/
    +  @Required
    +  @XStreamAlias("auth_code")
    +  private String authCode;
    +
    +  private WxPayMicropayRequest(Builder builder) {
    +    setSignType(builder.signType);
    +    setBody(builder.body);
    +    setAppid(builder.appid);
    +    setDetail(builder.detail);
    +    setMchId(builder.mchId);
    +    setAttach(builder.attach);
    +    setSubAppId(builder.subAppId);
    +    setOutTradeNo(builder.outTradeNo);
    +    setSubMchId(builder.subMchId);
    +    setTotalFee(builder.totalFee);
    +    setNonceStr(builder.nonceStr);
    +    setFeeType(builder.feeType);
    +    setSign(builder.sign);
    +    setSpbillCreateIp(builder.spbillCreateIp);
    +    setGoodsTag(builder.goodsTag);
    +    setLimitPay(builder.limitPay);
    +    setAuthCode(builder.authCode);
    +  }
    +
    +  public static Builder newBuilder() {
    +    return new Builder();
    +  }
    +
    +  public String getSignType() {
    +    return this.signType;
    +  }
    +
    +  public void setSignType(String signType) {
    +    this.signType = signType;
    +  }
    +
    +  public String getBody() {
    +    return this.body;
    +  }
    +
    +  public void setBody(String body) {
    +    this.body = body;
    +  }
    +
    +  public String getDetail() {
    +    return this.detail;
    +  }
    +
    +  public void setDetail(String detail) {
    +    this.detail = detail;
    +  }
    +
    +  public String getAttach() {
    +    return this.attach;
    +  }
    +
    +  public void setAttach(String attach) {
    +    this.attach = attach;
    +  }
    +
    +  public String getOutTradeNo() {
    +    return this.outTradeNo;
    +  }
    +
    +  public void setOutTradeNo(String outTradeNo) {
    +    this.outTradeNo = outTradeNo;
    +  }
    +
    +  public Integer getTotalFee() {
    +    return this.totalFee;
    +  }
    +
    +  public void setTotalFee(Integer totalFee) {
    +    this.totalFee = totalFee;
    +  }
    +
    +  public String getFeeType() {
    +    return this.feeType;
    +  }
    +
    +  public void setFeeType(String feeType) {
    +    this.feeType = feeType;
    +  }
    +
    +  public String getSpbillCreateIp() {
    +    return this.spbillCreateIp;
    +  }
    +
    +  public void setSpbillCreateIp(String spbillCreateIp) {
    +    this.spbillCreateIp = spbillCreateIp;
    +  }
    +
    +  public String getGoodsTag() {
    +    return this.goodsTag;
    +  }
    +
    +  public void setGoodsTag(String goodsTag) {
    +    this.goodsTag = goodsTag;
    +  }
    +
    +  public String getLimitPay() {
    +    return this.limitPay;
    +  }
    +
    +  public void setLimitPay(String limitPay) {
    +    this.limitPay = limitPay;
    +  }
    +
    +  public String getAuthCode() {
    +    return this.authCode;
    +  }
    +
    +  public void setAuthCode(String authCode) {
    +    this.authCode = authCode;
    +  }
    +
    +  public static final class Builder {
    +    private String signType;
    +    private String body;
    +    private String appid;
    +    private String detail;
    +    private String mchId;
    +    private String attach;
    +    private String subAppId;
    +    private String outTradeNo;
    +    private String subMchId;
    +    private Integer totalFee;
    +    private String nonceStr;
    +    private String feeType;
    +    private String sign;
    +    private String spbillCreateIp;
    +    private String goodsTag;
    +    private String limitPay;
    +    private String authCode;
    +
    +    private Builder() {
    +    }
    +
    +    public Builder signType(String signType) {
    +      this.signType = signType;
    +      return this;
    +    }
    +
    +    public Builder body(String body) {
    +      this.body = body;
    +      return this;
    +    }
    +
    +    public Builder appid(String appid) {
    +      this.appid = appid;
    +      return this;
    +    }
    +
    +    public Builder detail(String detail) {
    +      this.detail = detail;
    +      return this;
    +    }
    +
    +    public Builder mchId(String mchId) {
    +      this.mchId = mchId;
    +      return this;
    +    }
    +
    +    public Builder attach(String attach) {
    +      this.attach = attach;
    +      return this;
    +    }
    +
    +    public Builder subAppId(String subAppId) {
    +      this.subAppId = subAppId;
    +      return this;
    +    }
    +
    +    public Builder outTradeNo(String outTradeNo) {
    +      this.outTradeNo = outTradeNo;
    +      return this;
    +    }
    +
    +    public Builder subMchId(String subMchId) {
    +      this.subMchId = subMchId;
    +      return this;
    +    }
    +
    +    public Builder totalFee(Integer totalFee) {
    +      this.totalFee = totalFee;
    +      return this;
    +    }
    +
    +    public Builder nonceStr(String nonceStr) {
    +      this.nonceStr = nonceStr;
    +      return this;
    +    }
    +
    +    public Builder feeType(String feeType) {
    +      this.feeType = feeType;
    +      return this;
    +    }
    +
    +    public Builder sign(String sign) {
    +      this.sign = sign;
    +      return this;
    +    }
    +
    +    public Builder spbillCreateIp(String spbillCreateIp) {
    +      this.spbillCreateIp = spbillCreateIp;
    +      return this;
    +    }
    +
    +    public Builder goodsTag(String goodsTag) {
    +      this.goodsTag = goodsTag;
    +      return this;
    +    }
    +
    +    public Builder limitPay(String limitPay) {
    +      this.limitPay = limitPay;
    +      return this;
    +    }
    +
    +    public Builder authCode(String authCode) {
    +      this.authCode = authCode;
    +      return this;
    +    }
    +
    +    public WxPayMicropayRequest build() {
    +      return new WxPayMicropayRequest(this);
    +    }
    +  }
    +}
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    index a23a2604..fed9544c 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    @@ -41,7 +41,9 @@ public abstract class WxPayBaseResult {
        */
       @XStreamAlias("return_msg")
       protected String returnMsg;
    -  private String xmlString;
    +
    +  //当return_code为SUCCESS的时候,还会包括以下字段:
    +
       /**
        * 业务结果
        */
    @@ -70,7 +72,7 @@ public abstract class WxPayBaseResult {
       /**
        * 服务商模式下的子公众账号ID
        */
    -  @XStreamAlias("appid")
    +  @XStreamAlias("sub_appid")
       private String subAppId;
       /**
        * 服务商模式下的子商户号
    @@ -88,6 +90,12 @@ public abstract class WxPayBaseResult {
       @XStreamAlias("sign")
       private String sign;
     
    +  //以下为辅助属性
    +  /**
    +   * xml字符串
    +   */
    +  private String xmlString;
    +
       /**
        * xml的Document对象,用于解析xml文本
        */
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java
    new file mode 100644
    index 00000000..2f8842af
    --- /dev/null
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java
    @@ -0,0 +1,328 @@
    +package com.github.binarywang.wxpay.bean.result;
    +
    +import com.thoughtworks.xstream.annotations.XStreamAlias;
    +
    +/**
    + * 
    + * 提交刷卡支付接口响应结果对象类
    + * Created by Binary Wang on 2017-3-23.
    + * @author binarywang(Binary Wang)
    + * 
    + */ +@XStreamAlias("xml") +public class WxPayMicropayResult extends WxPayBaseResult { + /** + *
    +   * 用户标识
    +   * openid
    +   * 是
    +   * String(128)
    +   * Y
    +   * 用户在商户appid 下的唯一标识
    +   * 
    + **/ + @XStreamAlias("openid") + private String openid; + + /** + *
    +   * 是否关注公众账号
    +   * is_subscribe
    +   * 是
    +   * String(1)
    +   * Y
    +   * 用户是否关注公众账号,仅在公众账号类型支付有效,取值范围:Y或N;Y-关注;N-未关注
    +   * 
    + **/ + @XStreamAlias("is_subscribe") + private String isSubscribe; + + /** + *
    +   * 交易类型
    +   * trade_type
    +   * 是
    +   * String(16)
    +   * MICROPAY
    +   * 支付类型为MICROPAY(即扫码支付)
    +   * 
    + **/ + @XStreamAlias("trade_type") + private String tradeType; + + /** + *
    +   * 付款银行
    +   * bank_type
    +   * 是
    +   * String(32)
    +   * CMC
    +   * 银行类型,采用字符串类型的银行标识,值列表详见银行类型
    +   * 
    + **/ + @XStreamAlias("bank_type") + private String bankType; + + /** + *
    +   * 货币类型
    +   * fee_type
    +   * 否
    +   * String(16)
    +   * CNY
    +   * 符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   * 
    + **/ + @XStreamAlias("fee_type") + private String feeType; + + /** + *
    +   * 订单金额
    +   * total_fee
    +   * 是
    +   * Int
    +   * 888
    +   * 订单总金额,单位为分,只能为整数,详见支付金额
    +   * 
    + **/ + @XStreamAlias("total_fee") + private String totalFee; + + /** + *
    +   * 应结订单金额
    +   * settlement_total_fee
    +   * 否
    +   * Int
    +   * 100
    +   * 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
    +   * 
    + **/ + @XStreamAlias("settlement_total_fee") + private Integer settlementTotalFee; + + /** + *
    +   * 代金券金额
    +   * coupon_fee
    +   * 否
    +   * Int
    +   * 100
    +   * “代金券”金额<=订单金额,订单金额-“代金券”金额=现金支付金额,详见支付金额
    +   * 
    + **/ + @XStreamAlias("coupon_fee") + private Integer couponFee; + + /** + *
    +   * 现金支付货币类型
    +   * cash_fee_type
    +   * 否
    +   * String(16)
    +   * CNY
    +   * 符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   * 
    + **/ + @XStreamAlias("cash_fee_type") + private String cashFeeType; + + /** + *
    +   * 现金支付金额
    +   * cash_fee
    +   * 是
    +   * Int
    +   * 100
    +   * 订单现金支付金额,详见支付金额
    +   * 
    + **/ + @XStreamAlias("cash_fee") + private Integer cashFee; + + /** + *
    +   * 微信支付订单号
    +   * transaction_id
    +   * 是
    +   * String(32)
    +   * 1217752501201407033233368018
    +   * 微信支付订单号
    +   * 
    + **/ + @XStreamAlias("transaction_id") + private String transactionId; + + /** + *
    +   * 商户订单号
    +   * out_trade_no
    +   * 是
    +   * String(32)
    +   * 1217752501201407033233368018
    +   * 商户系统的订单号,与请求一致。
    +   * 
    + **/ + @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; + + /** + *
    +   * 营销详情
    +   * promotion_detail
    +   * 否
    +   * String(6000)
    +   * 示例见下文
    +   * 新增返回,单品优惠功能字段,需要接入请见详细说明
    +   * 
    + **/ + @XStreamAlias("promotion_detail") + private String promotionDetail; + + public String getOpenid() { + return this.openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getIsSubscribe() { + return this.isSubscribe; + } + + public void setIsSubscribe(String isSubscribe) { + this.isSubscribe = isSubscribe; + } + + public String getTradeType() { + return this.tradeType; + } + + public void setTradeType(String tradeType) { + this.tradeType = tradeType; + } + + public String getBankType() { + return this.bankType; + } + + public void setBankType(String bankType) { + this.bankType = bankType; + } + + public String getFeeType() { + return this.feeType; + } + + public void setFeeType(String feeType) { + this.feeType = feeType; + } + + public String getTotalFee() { + return this.totalFee; + } + + public void setTotalFee(String totalFee) { + this.totalFee = totalFee; + } + + public Integer getSettlementTotalFee() { + return this.settlementTotalFee; + } + + public void setSettlementTotalFee(Integer settlementTotalFee) { + this.settlementTotalFee = settlementTotalFee; + } + + public Integer getCouponFee() { + return this.couponFee; + } + + public void setCouponFee(Integer couponFee) { + this.couponFee = couponFee; + } + + public String getCashFeeType() { + return this.cashFeeType; + } + + public void setCashFeeType(String cashFeeType) { + this.cashFeeType = cashFeeType; + } + + public Integer getCashFee() { + return this.cashFee; + } + + public void setCashFee(Integer cashFee) { + this.cashFee = cashFee; + } + + public String getTransactionId() { + return this.transactionId; + } + + public void setTransactionId(String transactionId) { + this.transactionId = transactionId; + } + + public String getOutTradeNo() { + return this.outTradeNo; + } + + public void setOutTradeNo(String outTradeNo) { + this.outTradeNo = outTradeNo; + } + + public String getAttach() { + return this.attach; + } + + public void setAttach(String attach) { + this.attach = attach; + } + + public String getTimeEnd() { + return this.timeEnd; + } + + public void setTimeEnd(String timeEnd) { + this.timeEnd = timeEnd; + } + + public String getPromotionDetail() { + return this.promotionDetail; + } + + public void setPromotionDetail(String promotionDetail) { + this.promotionDetail = promotionDetail; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 9097d8ab..0473d9ba 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -262,7 +262,7 @@ public interface WxPayService { * @return 生成的二维码的字节数组 */ byte[] createScanPayQrcodeMode1(String productId, File logoFile, Integer sideLength); - + /** *
        * 扫码支付模式一生成二维码的方法
    @@ -324,4 +324,17 @@ public interface WxPayService {
        * @return 保存到本地的临时文件
        */
       File downloadBill(String billDate, String billType, String tarType, String deviceInfo) throws WxErrorException;
    +
    +  /**
    +   * 
    +   * 提交刷卡支付
    +   * 应用场景:
    +   * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,由商户收银台或者商户后台调用该接口发起支付。
    +   * 提醒1:提交支付请求后微信会同步返回支付结果。当返回结果为“系统错误”时,商户系统等待5秒后调用【查询订单API】,查询支付实际交易结果;当返回结果为“USERPAYING”时,商户系统可设置间隔时间(建议10秒)重新查询支付结果,直到支付成功或超时(建议30秒);
    +   * 提醒2:在调用查询接口返回后,如果交易状况不明晰,请调用【撤销订单API】,此时如果交易失败则关闭订单,该单不能再支付成功;如果交易成功,则将扣款退回到用户账户。当撤销无返回或错误时,请再次调用。注意:请勿扣款后立即调用【撤销订单API】,建议至少15秒后再调用。撤销订单API需要双向证书。
    +   * 接口地址:   https://api.mch.weixin.qq.com/pay/micropay
    +   * 是否需要证书:不需要。
    +   * 
    + */ + WxPayMicropayResult micropay(WxPayMicropayRequest request) throws WxErrorException; } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java index ffa8127d..371b50c8 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java @@ -122,19 +122,19 @@ public class WxPayServiceImpl implements WxPayService { || !"SUCCESS".equalsIgnoreCase(result.getResultCode())) { StringBuilder errorMsg = new StringBuilder(); if (result.getReturnCode() != null) { - errorMsg.append("返回代码:" + result.getReturnCode()); + errorMsg.append("返回代码:").append(result.getReturnCode()); } if (result.getReturnMsg() != null) { - errorMsg.append(",返回信息:" + result.getReturnMsg()); + errorMsg.append(",返回信息:").append(result.getReturnMsg()); } if (result.getResultCode() != null) { - errorMsg.append(",结果代码:" + result.getResultCode()); + errorMsg.append(",结果代码:").append(result.getResultCode()); } if (result.getErrCode() != null) { - errorMsg.append(",错误代码:" + result.getErrCode()); + errorMsg.append(",错误代码:").append(result.getErrCode()); } if (result.getErrCodeDes() != null) { - errorMsg.append(",错误详情:" + result.getErrCodeDes()); + errorMsg.append(",错误详情:").append(result.getErrCodeDes()); } WxError error = WxError.newBuilder() @@ -389,7 +389,7 @@ public class WxPayServiceImpl implements WxPayService { @Override public String createScanPayQrcodeMode1(String productId){ - //weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX + //weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX StringBuilder codeUrl = new StringBuilder("weixin://wxpay/bizpayurl?"); Map params = Maps.newHashMap(); params.put("appid", this.getConfig().getAppId()); @@ -455,6 +455,19 @@ public class WxPayServiceImpl implements WxPayService { return null; } + @Override + public WxPayMicropayResult micropay(WxPayMicropayRequest request) throws WxErrorException { + this.initRequest(request); + BeanUtils.checkRequiredFields(request); + request.setSign(this.createSign(request)); + + String url = this.getPayBaseUrl() + "/pay/micropay"; + String responseContent = this.post(url, request.toXML()); + WxPayMicropayResult result = WxPayBaseResult.fromXML(responseContent, WxPayMicropayResult.class); + this.checkResult(result); + return result; + } + private String post(String url, String xmlParam) { String requestString = null; try { diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java index 7fa30ac2..6b4a0939 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java @@ -195,4 +195,19 @@ public class WxPayServiceImplTest { assertEquals(QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()), qrcodeContent); } + @Test + public void testGetOrderNotifyResult() throws Exception { + } + + @Test + public void testMicropay() throws Exception { + WxPayMicropayResult result = this.payService.micropay(WxPayMicropayRequest.newBuilder() + .body("body") + .outTradeNo("aaaaa") + .totalFee(123) + .spbillCreateIp("127.0.0.1") + .authCode("aaa") + .build()); + this.logger.info(result.toString()); + } } From 3f4cdb7bf5568de7226e22610571cfb6d2e3ba0c Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 24 Mar 2017 11:11:02 +0800 Subject: [PATCH 35/63] =?UTF-8?q?=E6=92=A4=E9=94=80=E8=AE=A2=E5=8D=95API?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E9=87=8D=E6=9E=84=E7=9B=B8=E5=85=B3=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E7=AE=80=E5=8C=96=E5=BC=80=E5=8F=91=20#101?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bean/request/WxEntPayQueryRequest.java | 5 + .../wxpay/bean/request/WxEntPayRequest.java | 5 + .../wxpay/bean/request/WxPayBaseRequest.java | 58 +++ .../request/WxPayDownloadBillRequest.java | 18 + .../bean/request/WxPayMicropayRequest.java | 5 + .../bean/request/WxPayOrderCloseRequest.java | 4 + .../bean/request/WxPayOrderQueryRequest.java | 9 + .../request/WxPayOrderReverseRequest.java | 163 +++++++++ .../request/WxPayRedpackQueryRequest.java | 5 + .../bean/request/WxPayRefundQueryRequest.java | 12 + .../bean/request/WxPayRefundRequest.java | 34 +- .../bean/request/WxPayReportRequest.java | 5 + .../bean/request/WxPaySendRedpackRequest.java | 5 + .../request/WxPayUnifiedOrderRequest.java | 36 ++ .../wxpay/bean/result/WxPayBaseResult.java | 44 +++ .../bean/result/WxPayOrderReverseResult.java | 34 ++ .../wxpay/service/WxPayService.java | 94 +---- .../wxpay/service/impl/WxPayServiceImpl.java | 329 ++++-------------- .../binarywang/wxpay/util/SignUtils.java | 84 +++++ 19 files changed, 607 insertions(+), 342 deletions(-) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java index 30ff0a87..f9135c34 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java @@ -43,6 +43,11 @@ public class WxEntPayQueryRequest extends WxPayBaseRequest { this.partnerTradeNo = partnerTradeNo; } + @Override + protected void checkConstraints() { + //do nothing + } + @Override public String toString() { return ToStringUtils.toSimpleString(this); diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java index 56783883..fd43fb1a 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java @@ -154,6 +154,11 @@ public class WxEntPayRequest extends WxPayBaseRequest { private String spbillCreateIp; + @Override + protected void checkConstraints() { + + } + @Override public String getAppid() { return this.mchAppid; diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java index 2e34f0a2..4d5cbbaa 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java @@ -1,9 +1,14 @@ package com.github.binarywang.wxpay.bean.request; +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.util.SignUtils; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.util.BeanUtils; import me.chanjar.weixin.common.util.ToStringUtils; import me.chanjar.weixin.common.util.xml.XStreamInitializer; +import org.apache.commons.lang3.StringUtils; import java.math.BigDecimal; @@ -23,6 +28,22 @@ import java.math.BigDecimal; * @author binarywang(Binary Wang) */ public abstract class WxPayBaseRequest { + /** + * 检查请求参数内容,包括必填参数以及特殊约束 + */ + protected void checkFields() throws WxErrorException { + //check required fields + BeanUtils.checkRequiredFields(this); + + //check other parameters + this.checkConstraints(); + } + + /** + * 检查约束情况 + */ + protected abstract void checkConstraints(); + /** *
        * 公众账号ID
    @@ -180,4 +201,41 @@ public abstract class WxPayBaseRequest {
         xstream.processAnnotations(this.getClass());
         return xstream.toXML(this);
       }
    +
    +  /**
    +   * 
    +   * 检查参数,并设置签名
    +   * 1、检查参数(注意:子类实现需要检查参数的而外功能时,请在调用父类的方法前进行相应判断)
    +   * 2、补充系统参数,如果未传入则从配置里读取
    +   * 3、生成签名,并设置进去
    +   * 
    + * @param config 支付配置对象,用于读取相应系统配置信息 + */ + public void checkAndSign(WxPayConfig config) throws WxErrorException { + this.checkFields(); + + if (StringUtils.isBlank(getAppid())) { + this.setAppid(config.getAppId()); + } + + if (StringUtils.isBlank(getMchId())) { + this.setMchId(config.getMchId()); + } + + if (StringUtils.isBlank(getSubAppId())) { + this.setSubAppId(config.getSubAppId()); + } + + if (StringUtils.isBlank(getSubMchId())) { + this. setSubMchId(config.getSubMchId()); + } + + if (StringUtils.isBlank(getNonceStr())) { + this.setNonceStr(String.valueOf(System.currentTimeMillis())); + } + + //设置签名字段的值 + this.setSign(SignUtils.createSign(this, config.getMchKey())); + } + } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java index fac28aba..ed02060f 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java @@ -2,6 +2,10 @@ package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; import me.chanjar.weixin.common.annotation.Required; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; /** *
    @@ -12,6 +16,8 @@ import me.chanjar.weixin.common.annotation.Required;
      */
     @XStreamAlias("xml")
     public class WxPayDownloadBillRequest extends WxPayBaseRequest {
    +  private static final String[] BILL_TYPE = new String[]{"ALL", "REFUND", "SUCCESS"};
    +
       /**
        * 
        * 设备号
    @@ -120,4 +126,16 @@ public class WxPayDownloadBillRequest extends WxPayBaseRequest {
       public void setTarType(String tarType) {
         this.tarType = tarType;
       }
    +
    +  @Override
    +  protected void checkConstraints() {
    +    if (StringUtils.isNotBlank(this.getTarType()) && !"GZIP".equals(this.getTarType())) {
    +      throw new IllegalArgumentException("tar_type值如果存在,只能为GZIP");
    +    }
    +
    +    if (!ArrayUtils.contains(BILL_TYPE, this.getBillType())) {
    +      throw new IllegalArgumentException(String.format("bill_tpye目前必须为%s其中之一,实际值:%s",
    +        Arrays.toString(BILL_TYPE), this.getBillType()));
    +    }
    +  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
    index 10aac649..a0253378 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
    @@ -261,6 +261,11 @@ public class WxPayMicropayRequest extends WxPayBaseRequest {
         this.authCode = authCode;
       }
     
    +  @Override
    +  protected void checkConstraints() {
    +    //do nothing
    +  }
    +
       public static final class Builder {
         private String signType;
         private String body;
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
    index 43206e36..21968ac9 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
    @@ -33,4 +33,8 @@ public class WxPayOrderCloseRequest extends WxPayBaseRequest {
         this.outTradeNo = outTradeNo;
       }
     
    +  @Override
    +  protected void checkConstraints() {
    +
    +  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
    index a0982764..49972799 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
    @@ -1,6 +1,7 @@
     package com.github.binarywang.wxpay.bean.request;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import org.apache.commons.lang3.StringUtils;
     
     /**
      * 
    @@ -61,4 +62,12 @@ public class WxPayOrderQueryRequest extends WxPayBaseRequest {
       public void setOutTradeNo(String outTradeNo) {
         this.outTradeNo = outTradeNo;
       }
    +
    +  @Override
    +  protected void checkConstraints() {
    +    if ((StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo)) ||
    +      (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(outTradeNo))) {
    +      throw new IllegalArgumentException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一");
    +    }
    +  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
    new file mode 100644
    index 00000000..6aef2aa0
    --- /dev/null
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
    @@ -0,0 +1,163 @@
    +package com.github.binarywang.wxpay.bean.request;
    +
    +import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import org.apache.commons.lang3.StringUtils;
    +
    +/**
    + * 
    + * 撤销订单请求类
    + * Created by Binary Wang on 2017-3-23.
    + * @author binarywang(Binary Wang)
    + * 
    + */ +@XStreamAlias("xml") +public class WxPayOrderReverseRequest extends WxPayBaseRequest { + + /** + *
    +   * 微信订单号
    +   * transaction_id
    +   * String(28)
    +   * 1217752501201400000000000000
    +   * 微信的订单号,优先使用
    +   * 
    + */ + @XStreamAlias("transaction_id") + private String transactionId; + + /** + *
    +   * 商户订单号
    +   * out_trade_no
    +   * String(32)
    +   * 1217752501201400000000000000
    +   * 商户系统内部的订单号
    +   * transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no
    +   * 
    + */ + @XStreamAlias("out_trade_no") + private String outTradeNo; + + /** + *
    +   * 签名类型
    +   * sign_type
    +   * 否
    +   * String(32)
    +   * HMAC-SHA256
    +   * 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
    +   **/
    +  @XStreamAlias("sign_type")
    +  private String signType;
    +
    +  private WxPayOrderReverseRequest(Builder builder) {
    +    setTransactionId(builder.transactionId);
    +    setAppid(builder.appid);
    +    setOutTradeNo(builder.outTradeNo);
    +    setMchId(builder.mchId);
    +    setSignType(builder.signType);
    +    setSubAppId(builder.subAppId);
    +    setSubMchId(builder.subMchId);
    +    setNonceStr(builder.nonceStr);
    +    setSign(builder.sign);
    +  }
    +
    +  public static Builder newBuilder() {
    +    return new Builder();
    +  }
    +
    +  public String getTransactionId() {
    +    return this.transactionId;
    +  }
    +
    +  public void setTransactionId(String transactionId) {
    +    this.transactionId = transactionId;
    +  }
    +
    +  public String getOutTradeNo() {
    +    return this.outTradeNo;
    +  }
    +
    +  public void setOutTradeNo(String outTradeNo) {
    +    this.outTradeNo = outTradeNo;
    +  }
    +
    +  public String getSignType() {
    +    return this.signType;
    +  }
    +
    +  public void setSignType(String signType) {
    +    this.signType = signType;
    +  }
    +
    +  @Override
    +  protected void checkConstraints() {
    +    if (StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo)) {
    +      throw new IllegalArgumentException("transaction_id 和 out_trade_no不能同时为空!");
    +    }
    +  }
    +
    +  public static final class Builder {
    +    private String transactionId;
    +    private String appid;
    +    private String outTradeNo;
    +    private String mchId;
    +    private String signType;
    +    private String subAppId;
    +    private String subMchId;
    +    private String nonceStr;
    +    private String sign;
    +
    +    private Builder() {
    +    }
    +
    +    public Builder transactionId(String transactionId) {
    +      this.transactionId = transactionId;
    +      return this;
    +    }
    +
    +    public Builder appid(String appid) {
    +      this.appid = appid;
    +      return this;
    +    }
    +
    +    public Builder outTradeNo(String outTradeNo) {
    +      this.outTradeNo = outTradeNo;
    +      return this;
    +    }
    +
    +    public Builder mchId(String mchId) {
    +      this.mchId = mchId;
    +      return this;
    +    }
    +
    +    public Builder signType(String signType) {
    +      this.signType = signType;
    +      return this;
    +    }
    +
    +    public Builder subAppId(String subAppId) {
    +      this.subAppId = subAppId;
    +      return this;
    +    }
    +
    +    public Builder subMchId(String subMchId) {
    +      this.subMchId = subMchId;
    +      return this;
    +    }
    +
    +    public Builder nonceStr(String nonceStr) {
    +      this.nonceStr = nonceStr;
    +      return this;
    +    }
    +
    +    public Builder sign(String sign) {
    +      this.sign = sign;
    +      return this;
    +    }
    +
    +    public WxPayOrderReverseRequest build() {
    +      return new WxPayOrderReverseRequest(this);
    +    }
    +  }
    +}
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java
    index ae7ec352..191db469 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java
    @@ -54,4 +54,9 @@ public class WxPayRedpackQueryRequest extends WxPayBaseRequest {
       public void setMchBillNo(String mchBillNo) {
         this.mchBillNo = mchBillNo;
       }
    +
    +  @Override
    +  protected void checkConstraints() {
    +
    +  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java
    index 06687c36..1efa23db 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java
    @@ -1,6 +1,7 @@
     package com.github.binarywang.wxpay.bean.request;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import org.apache.commons.lang3.StringUtils;
     
     /**
      * 
    @@ -132,4 +133,15 @@ public class WxPayRefundQueryRequest extends WxPayBaseRequest {
       public void setRefundId(String refundId) {
         this.refundId = refundId;
       }
    +
    +  @Override
    +  protected void checkConstraints() {
    +    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 必须四选一");
    +    }
    +
    +  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
    index 36fb76d6..c7fc8c26 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
    @@ -1,7 +1,13 @@
     package com.github.binarywang.wxpay.bean.request;
     
    +import com.github.binarywang.wxpay.config.WxPayConfig;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
     import me.chanjar.weixin.common.annotation.Required;
    +import me.chanjar.weixin.common.exception.WxErrorException;
    +import org.apache.commons.lang3.ArrayUtils;
    +import org.apache.commons.lang3.StringUtils;
    +
    +import java.util.Arrays;
     
     /**
      * 
    @@ -13,13 +19,25 @@ import me.chanjar.weixin.common.annotation.Required;
      * 
  • 类型 *
  • 示例值 *
  • 描述 + * Created by Binary Wang on 2016-10-08. *
  • * * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016-10-08. */ @XStreamAlias("xml") public class WxPayRefundRequest extends WxPayBaseRequest { + private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS", + "REFUND_SOURCE_UNSETTLED_FUNDS"}; + + @Override + public void checkAndSign(WxPayConfig config) throws WxErrorException { + if (StringUtils.isBlank(this.getOpUserId())) { + this.setOpUserId(config.getMchId()); + } + + super.checkAndSign(config); + } + /** *
        * 设备号
    @@ -240,6 +258,20 @@ public class WxPayRefundRequest extends WxPayBaseRequest {
         this.refundAccount = refundAccount;
       }
     
    +  @Override
    +  protected void checkConstraints() {
    +    if (StringUtils.isNotBlank(this.getRefundAccount())) {
    +      if (!ArrayUtils.contains(REFUND_ACCOUNT, this.getRefundAccount())) {
    +        throw new IllegalArgumentException(String.format("refund_account目前必须为%s其中之一,实际值:%s",
    +          Arrays.toString(REFUND_ACCOUNT), this.getRefundAccount()));
    +      }
    +    }
    +
    +    if (StringUtils.isBlank(this.getOutTradeNo()) && StringUtils.isBlank(this.getTransactionId())) {
    +      throw new IllegalArgumentException("transaction_id 和 out_trade_no 不能同时为空,必须提供一个");
    +    }
    +  }
    +
       public static final class Builder {
         private String deviceInfo;
         private String appid;
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java
    index 6795536f..8b3f88b9 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java
    @@ -270,4 +270,9 @@ public class WxPayReportRequest extends WxPayBaseRequest {
       public void setTime(String time) {
         this.time = time;
       }
    +
    +  @Override
    +  protected void checkConstraints() {
    +    //do nothing
    +  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java
    index b49253a4..f7082fc3 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java
    @@ -217,6 +217,11 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest {
         this.remark = remark;
       }
     
    +  @Override
    +  protected void checkConstraints() {
    +
    +  }
    +
       @Override
       public String getAppid() {
         return this.wxAppid;
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java
    index 4e1d5a5d..48b059d3 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java
    @@ -1,7 +1,13 @@
     package com.github.binarywang.wxpay.bean.request;
     
    +import com.github.binarywang.wxpay.config.WxPayConfig;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
     import me.chanjar.weixin.common.annotation.Required;
    +import me.chanjar.weixin.common.exception.WxErrorException;
    +import org.apache.commons.lang3.ArrayUtils;
    +import org.apache.commons.lang3.StringUtils;
    +
    +import java.util.Arrays;
     
     /**
      * 
    @@ -21,6 +27,7 @@ import me.chanjar.weixin.common.annotation.Required;
      */
     @XStreamAlias("xml")
     public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
    +  private static final String[] TRADE_TYPES = new String[]{"JSAPI", "NATIVE", "APP"};
     
       /**
        * 
    @@ -409,6 +416,35 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
         this.openid = openid;
       }
     
    +  @Override
    +  protected void checkConstraints() {
    +    if (!ArrayUtils.contains(TRADE_TYPES, this.getTradeType())) {
    +      throw new IllegalArgumentException(String.format("trade_type目前必须为%s其中之一,实际值:%s",
    +        Arrays.toString(TRADE_TYPES), this.getTradeType()));
    +    }
    +
    +    if ("JSAPI".equals(this.getTradeType()) && this.getOpenid() == null) {
    +      throw new IllegalArgumentException("当 trade_type是'JSAPI'时未指定openid");
    +    }
    +
    +    if ("NATIVE".equals(this.getTradeType()) && this.getProductId() == null) {
    +      throw new IllegalArgumentException("当 trade_type是'NATIVE'时未指定product_id");
    +    }
    +  }
    +
    +  @Override
    +  public void checkAndSign(WxPayConfig config) throws WxErrorException {
    +    if (StringUtils.isBlank(this.getNotifyURL())) {
    +      this.setNotifyURL(config.getNotifyUrl());
    +    }
    +
    +    if (StringUtils.isBlank(this.getTradeType())) {
    +      this.setTradeType(config.getTradeType());
    +    }
    +
    +    super.checkAndSign(config);
    +  }
    +
       public static class WxUnifiedOrderRequestBuilder {
         private String appid;
         private String mchId;
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    index fed9544c..899703c8 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    @@ -1,9 +1,13 @@
     package com.github.binarywang.wxpay.bean.result;
     
    +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
    +import com.github.binarywang.wxpay.util.SignUtils;
     import com.google.common.base.Joiner;
     import com.google.common.collect.Maps;
     import com.thoughtworks.xstream.XStream;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import me.chanjar.weixin.common.bean.result.WxError;
    +import me.chanjar.weixin.common.exception.WxErrorException;
     import me.chanjar.weixin.common.util.ToStringUtils;
     import me.chanjar.weixin.common.util.xml.XStreamInitializer;
     import org.apache.commons.lang3.StringUtils;
    @@ -300,4 +304,44 @@ public abstract class WxPayBaseResult {
     
         return Integer.valueOf(result);
       }
    +
    +  /**
    +   * 校验返回结果签名
    +   */
    +  public void checkResult(WxPayServiceImpl wxPayService) throws WxErrorException {
    +    //校验返回结果签名
    +    Map map = toMap();
    +    if (getSign() != null && !SignUtils.checkSign(map, wxPayService.getConfig().getMchKey())) {
    +      this.getLogger().debug("校验结果签名失败,参数:{}", map);
    +      throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("参数格式校验错误!").build());
    +    }
    +
    +    //校验结果是否成功
    +    if (!"SUCCESS".equalsIgnoreCase(getReturnCode())
    +      || !"SUCCESS".equalsIgnoreCase(getResultCode())) {
    +      StringBuilder errorMsg = new StringBuilder();
    +      if (getReturnCode() != null) {
    +        errorMsg.append("返回代码:").append(getReturnCode());
    +      }
    +      if (getReturnMsg() != null) {
    +        errorMsg.append(",返回信息:").append(getReturnMsg());
    +      }
    +      if (getResultCode() != null) {
    +        errorMsg.append(",结果代码:").append(getResultCode());
    +      }
    +      if (getErrCode() != null) {
    +        errorMsg.append(",错误代码:").append(getErrCode());
    +      }
    +      if (getErrCodeDes() != null) {
    +        errorMsg.append(",错误详情:").append(getErrCodeDes());
    +      }
    +
    +      WxError error = WxError.newBuilder()
    +        .setErrorCode(-1)
    +        .setErrorMsg(errorMsg.toString())
    +        .build();
    +      this.getLogger().error("\n结果业务代码异常,返回結果:{},\n{}", map, error);
    +      throw new WxErrorException(error);
    +    }
    +  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
    new file mode 100644
    index 00000000..7732a962
    --- /dev/null
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
    @@ -0,0 +1,34 @@
    +package com.github.binarywang.wxpay.bean.result;
    +
    +import com.thoughtworks.xstream.annotations.XStreamAlias;
    +
    +/**
    + * 
    + * 撤销订单响应结果类
    + * Created by Binary Wang on 2017-3-23.
    + * @author binarywang(Binary Wang)
    + * 
    + */ +public class WxPayOrderReverseResult extends WxPayBaseResult { + + /** + *
    +   * 是否重调
    +   * recall
    +   * 是
    +   * String(1)
    +   * Y
    +   * 是否需要继续调用撤销,Y-需要,N-不需要
    +   * 
    + **/ + @XStreamAlias("recall") + private String isRecall; + + public String getIsRecall() { + return this.isRecall; + } + + public void setIsRecall(String isRecall) { + this.isRecall = isRecall; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 0473d9ba..902669e7 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -116,84 +116,6 @@ public interface WxPayService { */ WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException; - /** - * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) - * - * @param xmlbean Bean需要标记有XML注解,默认使用配置中的PartnerKey进行签名 - * @return 签名字符串 - * @see #createSign(Map, String) - * @since 2.5.0 - */ - String createSign(Object xmlbean); - - /** - * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) - * - * @param xmlbean Bean需要标记有XML注解 - * @param signKey 签名Key - * @return 签名字符串 - * @see #createSign(Map, String) - */ - String createSign(Object xmlbean, String signKey); - - /** - * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) - * - * @param prams 参数信息,默认使用配置中的PartnerKey进行签名 - * @return 签名字符串 - * @see #createSign(Map, String) - */ - String createSign(Map prams); - - - /** - * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) - * - * @param prams 参数信息 - * @param signKey 签名Key - * @return 签名字符串 - */ - String createSign(Map prams, String signKey); - - - /** - * 校验签名是否正确,默认使用配置中的PartnerKey进行签名 - * - * @param xmlbean Bean需要标记有XML注解 - * @return true - 签名校验成功,false - 签名校验失败 - * @see #checkSign(Map, String) - */ - boolean checkSign(Object xmlbean); - - /** - * 校验签名是否正确 - * - * @param xmlbean Bean需要标记有XML注解 - * @param signKey 校验的签名Key - * @return true - 签名校验成功,false - 签名校验失败 - * @see #checkSign(Map, String) - */ - boolean checkSign(Object xmlbean, String signKey); - - /** - * 校验签名是否正确,默认使用配置中的PartnerKey进行签名 - * - * @param prams 需要校验的参数Map - * @return true - 签名校验成功,false - 签名校验失败 - * @see #checkSign(Map, String) - */ - boolean checkSign(Map prams); - - /** - * 校验签名是否正确 - * - * @param params 需要校验的参数Map - * @param signKey 校验的签名Key - * @return true - 签名校验成功,false - 签名校验失败 - * @see #checkSign(Map, String) - */ - boolean checkSign(Map params, String signKey); - /** * 发送微信红包给个人用户 *
    @@ -271,6 +193,7 @@ public interface WxPayService {
        * 其中XXXXX为商户需要填写的内容,商户将该链接生成二维码,如需要打印发布二维码,需要采用此格式。商户可调用第三方库生成二维码图片。
        * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4
        * 
    + * * @param productId 产品Id * @return 生成的二维码URL连接 */ @@ -328,6 +251,7 @@ public interface WxPayService { /** *
        * 提交刷卡支付
    +   * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
        * 应用场景:
        * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,由商户收银台或者商户后台调用该接口发起支付。
        * 提醒1:提交支付请求后微信会同步返回支付结果。当返回结果为“系统错误”时,商户系统等待5秒后调用【查询订单API】,查询支付实际交易结果;当返回结果为“USERPAYING”时,商户系统可设置间隔时间(建议10秒)重新查询支付结果,直到支付成功或超时(建议30秒);
    @@ -337,4 +261,18 @@ public interface WxPayService {
        * 
    */ WxPayMicropayResult micropay(WxPayMicropayRequest request) throws WxErrorException; + + /** + *
    +   * 撤销订单API
    +   * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
    +   * 应用场景:
    +   *  支付交易返回失败或支付系统超时,调用该接口撤销交易。如果此订单用户支付失败,微信支付系统会将此订单关闭;如果用户支付成功,微信支付系统会将此订单资金退还给用户。
    +   *  注意:7天以内的交易单可调用撤销,其他正常支付的单如需实现相同功能请调用申请退款API。提交支付交易后调用【查询订单API】,没有明确的支付结果再调用【撤销订单API】。
    +   *  调用支付接口后请勿立即调用撤销订单API,建议支付后至少15s后再调用撤销订单接口。
    +   *  接口链接 :https://api.mch.weixin.qq.com/secapi/pay/reverse
    +   *  是否需要证书:请求需要双向证书。
    +   *
    + */ + WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) throws WxErrorException; } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java index 371b50c8..7ed530be 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java @@ -5,14 +5,12 @@ 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.github.binarywang.wxpay.util.SignUtils; 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 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; @@ -30,7 +28,8 @@ import org.slf4j.LoggerFactory; import javax.net.ssl.SSLContext; import java.io.File; import java.io.UnsupportedEncodingException; -import java.util.*; +import java.util.HashMap; +import java.util.Map; /** * Created by Binary Wang on 2016/7/28. @@ -38,12 +37,7 @@ import java.util.*; * @author binarywang (https://github.com/binarywang) */ 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 final Logger log = LoggerFactory.getLogger(this.getClass()); private WxPayConfig config; @@ -62,126 +56,47 @@ public class WxPayServiceImpl implements WxPayService { if (this.getConfig().useSandboxForWxPay()) { return PAY_BASE_URL + "/sandboxnew"; } + return PAY_BASE_URL; } @Override public WxPayRefundResult refund(WxPayRefundRequest request) throws WxErrorException { - this.initRequest(request); - if (StringUtils.isBlank(request.getOpUserId())) { - request.setOpUserId(this.getConfig().getMchId()); - } - - this.checkParameters(request); - request.setSign(this.createSign(request)); + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/secapi/pay/refund"; String responseContent = this.postWithKey(url, request.toXML()); - WxPayRefundResult result = WxPayRefundResult.fromXML(responseContent, WxPayRefundResult.class); - this.checkResult(result); + WxPayRefundResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundResult.class); + result.checkResult(this); return result; } @Override - public WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, - String outRefundNo, String 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 必须四选一"); - } - WxPayRefundQueryRequest request = new WxPayRefundQueryRequest(); - this.initRequest(request); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); request.setTransactionId(StringUtils.trimToNull(transactionId)); request.setOutRefundNo(StringUtils.trimToNull(outRefundNo)); request.setRefundId(StringUtils.trimToNull(refundId)); - request.setSign(this.createSign(request)); + + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/pay/refundquery"; String responseContent = this.post(url, request.toXML()); - WxPayRefundQueryResult result = WxPayRefundQueryResult.fromXML(responseContent, WxPayRefundQueryResult.class); + WxPayRefundQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundQueryResult.class); result.composeRefundRecords(); - this.checkResult(result); + result.checkResult(this); return result; } - private void checkResult(WxPayBaseResult result) throws WxErrorException { - //校验返回结果签名 - Map map = result.toMap(); - if (result.getSign() != null && !this.checkSign(map)) { - log.debug("校验结果签名失败,参数:{}", map); - throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("参数格式校验错误!").build()); - } - - //校验结果是否成功 - if (!"SUCCESS".equalsIgnoreCase(result.getReturnCode()) - || !"SUCCESS".equalsIgnoreCase(result.getResultCode())) { - StringBuilder errorMsg = new StringBuilder(); - if (result.getReturnCode() != null) { - errorMsg.append("返回代码:").append(result.getReturnCode()); - } - if (result.getReturnMsg() != null) { - errorMsg.append(",返回信息:").append(result.getReturnMsg()); - } - if (result.getResultCode() != null) { - errorMsg.append(",结果代码:").append(result.getResultCode()); - } - if (result.getErrCode() != null) { - errorMsg.append(",错误代码:").append(result.getErrCode()); - } - if (result.getErrCodeDes() != null) { - errorMsg.append(",错误详情:").append(result.getErrCodeDes()); - } - - WxError error = WxError.newBuilder() - .setErrorCode(-1) - .setErrorMsg(errorMsg.toString()) - .build(); - log.error("\n结果业务代码异常,返回結果:{},\n{}", map, error); - throw new WxErrorException(error); - } - } - - private void checkParameters(WxPayDownloadBillRequest request) throws WxErrorException { - BeanUtils.checkRequiredFields(request); - - if (StringUtils.isNotBlank(request.getTarType()) && !"GZIP".equals(request.getTarType())) { - throw new IllegalArgumentException("tar_type值如果存在,只能为GZIP"); - } - - if (!ArrayUtils.contains(BILL_TYPE, request.getBillType())) { - throw new IllegalArgumentException("bill_tpye目前必须为" + Arrays.toString(BILL_TYPE) - + "其中之一,实际值:" + request.getBillType()); - } - - } - - private void checkParameters(WxPayRefundRequest request) throws WxErrorException { - BeanUtils.checkRequiredFields(request); - - if (StringUtils.isNotBlank(request.getRefundAccount())) { - if (!ArrayUtils.contains(REFUND_ACCOUNT, request.getRefundAccount())) { - throw new IllegalArgumentException("refund_account目前必须为" + Arrays.toString(REFUND_ACCOUNT) - + "其中之一,实际值:" + request.getRefundAccount()); - } - } - - if (StringUtils.isBlank(request.getOutTradeNo()) && StringUtils.isBlank(request.getTransactionId())) { - throw new IllegalArgumentException("transaction_id 和 out_trade_no 不能同时为空,必须提供一个"); - } - } - @Override public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErrorException { try { log.debug("微信支付回调参数详细:{}", xmlData); WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlData); log.debug("微信支付回调结果对象:{}", result); - this.checkResult(result); + result.checkResult(this); return result; } catch (WxErrorException e) { log.error(e.getMessage(), e); @@ -193,18 +108,17 @@ public class WxPayServiceImpl implements WxPayService { } @Override - public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) - throws WxErrorException { - this.initRequest(request); - request.setSign(this.createSign(request)); + public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxErrorException { + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendredpack"; if (request.getAmtType() != null) { //裂变红包 url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendgroupredpack"; } + String responseContent = this.postWithKey(url, request.toXML()); - WxPaySendRedpackResult result = WxPaySendRedpackResult.fromXML(responseContent, WxPaySendRedpackResult.class); + WxPaySendRedpackResult result = WxPayBaseResult.fromXML(responseContent, WxPaySendRedpackResult.class); //毋须校验,因为没有返回签名信息 // this.checkResult(result); return result; @@ -215,28 +129,21 @@ public class WxPayServiceImpl implements WxPayService { WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); request.setMchBillNo(mchBillNo); request.setBillType("MCHT"); - initRequest(request); - request.setSign(this.createSign(request)); + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gethbinfo"; String responseContent = this.postWithKey(url, request.toXML()); - WxPayRedpackQueryResult result = WxPayRedpackQueryResult.fromXML(responseContent, WxPayRedpackQueryResult.class); - this.checkResult(result); + WxPayRedpackQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRedpackQueryResult.class); + result.checkResult(this); return result; } @Override public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException { - if ((StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo)) || - (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(outTradeNo))) { - throw new IllegalArgumentException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一"); - } - WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); request.setTransactionId(StringUtils.trimToNull(transactionId)); - initRequest(request); - request.setSign(this.createSign(request)); + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/pay/orderquery"; String responseContent = this.post(url, request.toXML()); @@ -244,9 +151,9 @@ public class WxPayServiceImpl implements WxPayService { throw new WxErrorException(WxError.newBuilder().setErrorMsg("无响应结果").build()); } - WxPayOrderQueryResult result = WxPayOrderQueryResult.fromXML(responseContent, WxPayOrderQueryResult.class); + WxPayOrderQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderQueryResult.class); result.composeCoupons(); - this.checkResult(result); + result.checkResult(this); return result; } @@ -258,77 +165,27 @@ public class WxPayServiceImpl implements WxPayService { WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); - this.initRequest(request); - request.setSign(this.createSign(request)); + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/pay/closeorder"; String responseContent = this.post(url, request.toXML()); WxPayOrderCloseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderCloseResult.class); - this.checkResult(result); + result.checkResult(this); return result; } @Override - public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) - throws WxErrorException { - this.initRequest(request); - if (StringUtils.isBlank(request.getNotifyURL())) { - request.setNotifyURL(getConfig().getNotifyUrl()); - } - - if (StringUtils.isBlank(request.getTradeType())) { - request.setTradeType(getConfig().getTradeType()); - } - - this.checkParameters(request);//校验参数 - request.setSign(this.createSign(request)); + public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxErrorException { + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/pay/unifiedorder"; String responseContent = this.post(url, request.toXML()); - WxPayUnifiedOrderResult result = WxPayUnifiedOrderResult.fromXML(responseContent, WxPayUnifiedOrderResult.class); - this.checkResult(result); + WxPayUnifiedOrderResult result = WxPayBaseResult.fromXML(responseContent, WxPayUnifiedOrderResult.class); + result.checkResult(this); return result; } - private void initRequest(WxPayBaseRequest request) { - if (StringUtils.isBlank(request.getAppid())) { - request.setAppid(this.getConfig().getAppId()); - } - - if (StringUtils.isBlank(request.getMchId())) { - 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())); - } - } - - private void checkParameters(WxPayUnifiedOrderRequest request) throws WxErrorException { - BeanUtils.checkRequiredFields(request); - - if (!ArrayUtils.contains(TRADE_TYPES, request.getTradeType())) { - throw new IllegalArgumentException("trade_type目前必须为" + Arrays.toString(TRADE_TYPES) + "其中之一,实际值:" + request.getTradeType()); - } - - if ("JSAPI".equals(request.getTradeType()) && request.getOpenid() == null) { - throw new IllegalArgumentException("当 trade_type是'JSAPI'时未指定openid"); - } - - if ("NATIVE".equals(request.getTradeType()) && request.getProductId() == null) { - throw new IllegalArgumentException("当 trade_type是'NATIVE'时未指定product_id"); - } - } - @Override public Map getPayInfo(WxPayUnifiedOrderRequest request) throws WxErrorException { WxPayUnifiedOrderResult unifiedOrderResult = this.unifiedOrder(request); @@ -349,21 +206,18 @@ public class WxPayServiceImpl implements WxPayService { if ("NATIVE".equals(request.getTradeType())) { payInfo.put("codeUrl", unifiedOrderResult.getCodeURL()); } - payInfo.put("paySign", this.createSign(payInfo)); + payInfo.put("paySign", SignUtils.createSign(payInfo, this.getConfig().getMchKey())); return payInfo; } @Override public WxEntPayResult entPay(WxEntPayRequest request) throws WxErrorException { - this.initRequest(request); - BeanUtils.checkRequiredFields(request); - request.setSign(this.createSign(request)); - + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/mmpaymkttransfers/promotion/transfers"; String responseContent = this.postWithKey(url, request.toXML()); - WxEntPayResult result = WxEntPayResult.fromXML(responseContent, WxEntPayResult.class); - this.checkResult(result); + WxEntPayResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayResult.class); + result.checkResult(this); return result; } @@ -371,25 +225,24 @@ public class WxPayServiceImpl implements WxPayService { public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxErrorException { WxEntPayQueryRequest request = new WxEntPayQueryRequest(); request.setPartnerTradeNo(partnerTradeNo); - this.initRequest(request); - request.setSign(this.createSign(request)); + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo"; String responseContent = this.postWithKey(url, request.toXML()); - WxEntPayQueryResult result = WxEntPayQueryResult.fromXML(responseContent, WxEntPayQueryResult.class); - this.checkResult(result); + WxEntPayQueryResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayQueryResult.class); + result.checkResult(this); return result; } @Override public byte[] createScanPayQrcodeMode1(String productId, File logoFile, Integer sideLength) { - String content = createScanPayQrcodeMode1(productId); - return createQrcode(content, logoFile, sideLength); + String content = this.createScanPayQrcodeMode1(productId); + return this.createQrcode(content, logoFile, sideLength); } @Override - public String createScanPayQrcodeMode1(String productId){ - //weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX + public String createScanPayQrcodeMode1(String productId) { + //weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX StringBuilder codeUrl = new StringBuilder("weixin://wxpay/bizpayurl?"); Map params = Maps.newHashMap(); params.put("appid", this.getConfig().getAppId()); @@ -398,7 +251,7 @@ public class WxPayServiceImpl implements WxPayService { params.put("time_stamp", String.valueOf(System.currentTimeMillis() / 1000));//这里需要秒,10位数字 params.put("nonce_str", String.valueOf(System.currentTimeMillis())); - String sign = this.createSign(params); + String sign = SignUtils.createSign(params, this.getConfig().getMchKey()); params.put("sign", sign); @@ -407,72 +260,80 @@ public class WxPayServiceImpl implements WxPayService { } String content = codeUrl.toString().substring(0, codeUrl.length() - 1); - log.debug("扫码支付模式一生成二维码的URL:{}",content); - return content; + log.debug("扫码支付模式一生成二维码的URL:{}", content); + return content; } @Override public byte[] createScanPayQrcodeMode2(String codeUrl, File logoFile, Integer sideLength) { - return createQrcode(codeUrl, logoFile, sideLength); + return this.createQrcode(codeUrl, logoFile, sideLength); } private byte[] createQrcode(String content, File logoFile, Integer sideLength) { - if (sideLength == null || sideLength < 1) { + if (sideLength == null || sideLength < 1) { return QrcodeUtils.createQrcode(content, logoFile); } + return QrcodeUtils.createQrcode(content, sideLength, logoFile); } public void report(WxPayReportRequest request) throws WxErrorException { - BeanUtils.checkRequiredFields(request); - this.initRequest(request); - request.setSign(this.createSign(request)); + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/payitil/report"; String responseContent = this.post(url, request.toXML()); WxPayCommonResult result = WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class); - this.checkResult(result); + result.checkResult(this); } @Override public File downloadBill(String billDate, String billType, String tarType, String deviceInfo) throws WxErrorException { WxPayDownloadBillRequest request = new WxPayDownloadBillRequest(); - this.initRequest(request); request.setBillType(billType); request.setBillDate(billDate); request.setTarType(tarType); request.setDeviceInfo(deviceInfo); - this.checkParameters(request); - request.setSign(this.createSign(request)); + + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/pay/downloadbill"; //TODO 返回的内容可能是文件流,也有可能是xml,需要区分对待 String responseContent = this.post(url, request.toXML()); WxPayCommonResult result = WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class); - this.checkResult(result); + result.checkResult(this); //TODO 待实现,暂时无测试帐号,无法调试 return null; } @Override public WxPayMicropayResult micropay(WxPayMicropayRequest request) throws WxErrorException { - this.initRequest(request); - BeanUtils.checkRequiredFields(request); - request.setSign(this.createSign(request)); + request.checkAndSign(this.getConfig()); String url = this.getPayBaseUrl() + "/pay/micropay"; String responseContent = this.post(url, request.toXML()); WxPayMicropayResult result = WxPayBaseResult.fromXML(responseContent, WxPayMicropayResult.class); - this.checkResult(result); + result.checkResult(this); + return result; + } + + @Override + public WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) throws WxErrorException { + request.checkAndSign(this.getConfig()); + + String url = this.getPayBaseUrl() + "/secapi/pay/reverse"; + String responseContent = this.postWithKey(url, request.toXML()); + WxPayOrderReverseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderReverseResult.class); + result.checkResult(this); return result; } private String post(String url, String xmlParam) { - String requestString = null; + String requestString = xmlParam; try { requestString = new String(xmlParam.getBytes(CharEncoding.UTF_8), CharEncoding.ISO_8859_1); } catch (UnsupportedEncodingException e) { + //实际上不会发生该异常 e.printStackTrace(); } @@ -520,62 +381,4 @@ public class WxPayServiceImpl implements WxPayService { } } - @Override - public String createSign(Object xmlBean) { - return this.createSign(BeanUtils.xmlBean2Map(xmlBean), this.getConfig().getMchKey()); - } - - @Override - public String createSign(Object xmlBean, String signKey) { - return this.createSign(BeanUtils.xmlBean2Map(xmlBean), signKey); - } - - @Override - public String createSign(Map params) { - return this.createSign(params, this.getConfig().getMchKey()); - } - - @Override - public String createSign(Map params, String signKey) { - if (this.getConfig().useSandboxForWxPay()) { - //使用仿真测试环境 - //TODO 目前测试发现,以下两行代码都会出问题,所以暂不建议使用仿真测试环境 - signKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; - //return "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; - } - - SortedMap sortedMap = new TreeMap<>(params); - - StringBuilder toSign = new StringBuilder(); - for (String key : sortedMap.keySet()) { - String value = params.get(key); - if (StringUtils.isNotEmpty(value) && !"sign".equals(key) && !"key".equals(key)) { - toSign.append(key + "=" + value + "&"); - } - } - - toSign.append("key=" + signKey); - return DigestUtils.md5Hex(toSign.toString()).toUpperCase(); - } - - @Override - public boolean checkSign(Object xmlBean) { - return this.checkSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getMchKey()); - } - - @Override - public boolean checkSign(Object xmlBean, String signKey) { - return this.checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey); - } - - @Override - public boolean checkSign(Map params) { - return this.checkSign(params, getConfig().getMchKey()); - } - - @Override - public boolean checkSign(Map params, String signKey) { - String sign = this.createSign(params, signKey); - return sign.equals(params.get("sign")); - } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java new file mode 100644 index 00000000..2a6030f3 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java @@ -0,0 +1,84 @@ +package com.github.binarywang.wxpay.util; + +import me.chanjar.weixin.common.util.BeanUtils; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + *
    + * 签名相关工具类
    + * Created by Binary Wang on 2017-3-23.
    + * @author binarywang(Binary Wang)
    + * 
    + */ +public class SignUtils { + + /** + * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) + * + * @param xmlBean Bean需要标记有XML注解 + * @param signKey 签名Key + * @return 签名字符串 + */ + public static String createSign(Object xmlBean, String signKey) { + return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey); + } + + /** + * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) + * + * @param params 参数信息 + * @param signKey 签名Key + * @return 签名字符串 + */ + public static String createSign(Map params, String signKey) { +// if (this.getConfig().useSandboxForWxPay()) { +// //使用仿真测试环境 +// //TODO 目前测试发现,以下两行代码都会出问题,所以暂不建议使用仿真测试环境 +// signKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; +// //return "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; +// } + + SortedMap sortedMap = new TreeMap<>(params); + + StringBuilder toSign = new StringBuilder(); + for (String key : sortedMap.keySet()) { + String value = params.get(key); + if (StringUtils.isNotEmpty(value) && !"sign".equals(key) && !"key".equals(key)) { + toSign.append(key + "=" + value + "&"); + } + } + + toSign.append("key=" + signKey); + return DigestUtils.md5Hex(toSign.toString()).toUpperCase(); + } + + /** + * 校验签名是否正确 + * + * @param xmlBean Bean需要标记有XML注解 + * @param signKey 校验的签名Key + * @return true - 签名校验成功,false - 签名校验失败 + * @see #checkSign(Map, String) + */ + public static boolean checkSign(Object xmlBean, String signKey) { + return checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey); + } + + /** + * 校验签名是否正确 + * + * @param params 需要校验的参数Map + * @param signKey 校验的签名Key + * @return true - 签名校验成功,false - 签名校验失败 + * @see #checkSign(Map, String) + */ + public static boolean checkSign(Map params, String signKey) { + String sign = createSign(params, signKey); + return sign.equals(params.get("sign")); + } +} From 9acb01cd176cc299651208049912eb86afd20e41 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 24 Mar 2017 11:12:00 +0800 Subject: [PATCH 36/63] add test for reverseOdrer method --- .../binarywang/wxpay/config/WxPayConfig.java | 2 +- .../service/impl/WxPayServiceImplTest.java | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) 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 index 56eba3ac..c03b2482 100644 --- 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 @@ -135,7 +135,7 @@ public class WxPayConfig { public SSLContext initSSLContext() { if (null == mchId) { - throw new IllegalArgumentException("请確保mchId已設置"); + throw new IllegalArgumentException("请确保商户号mch_id已设置"); } File file = new File(this.keyPath); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java index 6b4a0939..2bbc09e8 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java @@ -210,4 +210,23 @@ public class WxPayServiceImplTest { .build()); this.logger.info(result.toString()); } + + @Test + public void testGetConfig() throws Exception { + } + + @Test + public void testSetConfig() throws Exception { + } + + @Test + public void testReverseOrder() throws Exception { + WxPayOrderReverseResult result = this.payService.reverseOrder(WxPayOrderReverseRequest.newBuilder() + .outTradeNo("1111") + .build()); + assertNotNull(result); + this.logger.info(result.toString()); + + } + } From 9f2f2f8844795bad42a985c5e96edb536e7931e4 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 24 Mar 2017 14:48:56 +0800 Subject: [PATCH 37/63] update test --- .../wxpay/service/impl/WxPayServiceImplTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java index 2bbc09e8..f668e96c 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java @@ -35,7 +35,15 @@ public class WxPayServiceImplTest { @Test public void testGetPayInfo() throws Exception { - Map payInfo = this.payService.getPayInfo(WxPayUnifiedOrderRequest.builder().body("abc").build()); + Map payInfo = this.payService.getPayInfo(WxPayUnifiedOrderRequest.builder() + .body("我去") + .totalFee(1) + .spbillCreateIp("111111") + .notifyURL("111111") + .tradeType("JSAPI") + .outTradeNo("111111") + .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()) + .build()); this.logger.info(payInfo.toString()); } @@ -226,7 +234,6 @@ public class WxPayServiceImplTest { .build()); assertNotNull(result); this.logger.info(result.toString()); - } } From 612beb2c10926b8f9ee5af4d2a1365c7437bbeb5 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 24 Mar 2017 14:50:57 +0800 Subject: [PATCH 38/63] =?UTF-8?q?=E5=8F=91=E5=B8=83=E4=B8=B4=E6=97=B6?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E6=9C=AC2.5.5.BETA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 4a5acb94..8367f9f4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.github.binarywang weixin-java-parent - 2.5.4.BETA + 2.5.5.BETA pom WeiXin Java Tools - Parent 微信公众号、企业号上级POM diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 6b9728f2..24b71dcc 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.4.BETA + 2.5.5.BETA weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index c517b8f8..2a6ea6f2 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.4.BETA + 2.5.5.BETA weixin-java-cp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 18673a83..62ef79e0 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.4.BETA + 2.5.5.BETA weixin-java-mp WeiXin Java Tools - MP diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 5ef5bc7d..79abe83b 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ weixin-java-parent com.github.binarywang - 2.5.4.BETA + 2.5.5.BETA 4.0.0 From 3d3ab2b5a9f2ce7ae1a6e86d687573f94364524b Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 24 Mar 2017 17:23:08 +0800 Subject: [PATCH 39/63] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E7=9A=84MsgID=E7=9A=84=E9=97=AE=E9=A2=98=20#?= =?UTF-8?q?165?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/mp/util/xml/XStreamTransformer.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java index 6edd6536..e2c0e0ea 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java @@ -49,7 +49,7 @@ public class XStreamTransformer { * @param clz 类型 * @param xStream xml解析器 */ - public static void register(Class clz, XStream xStream) { + private static void register(Class clz, XStream xStream) { CLASS_2_XSTREAM_INSTANCE.put(clz, xStream); } @@ -57,10 +57,15 @@ public class XStreamTransformer { * 会自动注册该类及其子类 * @param clz 要注册的类 */ - public static void registerClass(Class clz) { + private static void registerClass(Class clz) { XStream xstream = XStreamInitializer.getInstance(); xstream.processAnnotations(clz); xstream.processAnnotations(getInnerClasses(clz)); + if(clz.equals(WxMpXmlMessage.class)){ + // 操蛋的微信,模板消息推送成功的消息是MsgID,其他消息推送过来是MsgId + xstream.aliasField("MsgID", WxMpXmlMessage.class, "msgId"); + } + register(clz, xstream); } From 96d72fe5424553141dc65e06d83ce7fa712f6c11 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 27 Mar 2017 14:22:33 +0800 Subject: [PATCH 40/63] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E8=BD=AC=E6=8D=A2=E7=9F=AD=E9=93=BE=E6=8E=A5?= =?UTF-8?q?API=20#101?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bean/request/WxPayShorturlRequest.java | 46 +++++++++++++++++++ .../bean/result/WxPayOrderReverseResult.java | 1 + .../bean/result/WxPayShorturlResult.java | 34 ++++++++++++++ .../wxpay/service/WxPayService.java | 33 +++++++++++-- .../wxpay/service/impl/WxPayServiceImpl.java | 16 +++++++ .../service/impl/WxPayServiceImplTest.java | 17 ++++++- 6 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java new file mode 100644 index 00000000..849d9283 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java @@ -0,0 +1,46 @@ +package com.github.binarywang.wxpay.bean.request; + +import com.thoughtworks.xstream.annotations.XStreamAlias; + +/** + *
    + * 转换短链接请求对象类
    + * Created by Binary Wang on 2017-3-27.
    + * @author binarywang(Binary Wang)
    + * 
    + */ +@XStreamAlias("xml") +public class WxPayShorturlRequest extends WxPayBaseRequest { + /** + *
    +   * URL链接
    +   * long_url
    +   * 是
    +   * String(512)
    +   * weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX
    +   * 需要转换的URL,签名用原串,传输需URLencode
    +   * 
    + */ + @XStreamAlias("long_url") + private String longUrl; + + public String getLongUrl() { + return this.longUrl; + } + + public void setLongUrl(String longUrl) { + this.longUrl = longUrl; + } + + public WxPayShorturlRequest() { + } + + public WxPayShorturlRequest(String longUrl) { + this.longUrl = longUrl; + } + + @Override + protected void checkConstraints() { + //do nothing + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java index 7732a962..c80b72d2 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java @@ -9,6 +9,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @author binarywang(Binary Wang) *
    */ +@XStreamAlias("xml") public class WxPayOrderReverseResult extends WxPayBaseResult { /** diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java new file mode 100644 index 00000000..2f93cb81 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java @@ -0,0 +1,34 @@ +package com.github.binarywang.wxpay.bean.result; + +import com.thoughtworks.xstream.annotations.XStreamAlias; + +/** + *
    + * 转换短链接结果对象类
    + * Created by Binary Wang on 2017-3-27.
    + * @author binarywang(Binary Wang)
    + * 
    + */ +@XStreamAlias("xml") +public class WxPayShorturlResult extends WxPayBaseResult { + /** + *
    +   * URL链接
    +   * short_url
    +   * 是
    +   * String(64)
    +   * weixin://wxpay/s/XXXXXX
    +   * 转换后的URL
    +   * 
    + */ + @XStreamAlias("short_url") + private String shortUrl; + + public String getShortUrl() { + return this.shortUrl; + } + + public void setShortUrl(String shortUrl) { + this.shortUrl = shortUrl; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 902669e7..e61ff863 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -267,12 +267,39 @@ public interface WxPayService { * 撤销订单API * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3 * 应用场景: - * 支付交易返回失败或支付系统超时,调用该接口撤销交易。如果此订单用户支付失败,微信支付系统会将此订单关闭;如果用户支付成功,微信支付系统会将此订单资金退还给用户。 - * 注意:7天以内的交易单可调用撤销,其他正常支付的单如需实现相同功能请调用申请退款API。提交支付交易后调用【查询订单API】,没有明确的支付结果再调用【撤销订单API】。 + * 支付交易返回失败或支付系统超时,调用该接口撤销交易。如果此订单用户支付失败,微信支付系统会将此订单关闭; + * 如果用户支付成功,微信支付系统会将此订单资金退还给用户。 + * 注意:7天以内的交易单可调用撤销,其他正常支付的单如需实现相同功能请调用申请退款API。 + * 提交支付交易后调用【查询订单API】,没有明确的支付结果再调用【撤销订单API】。 * 调用支付接口后请勿立即调用撤销订单API,建议支付后至少15s后再调用撤销订单接口。 * 接口链接 :https://api.mch.weixin.qq.com/secapi/pay/reverse * 是否需要证书:请求需要双向证书。 - *
    + *
    */ WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) throws WxErrorException; + + /** + *
    +   *  转换短链接
    +   *  应用场景:
    +   *     该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量,提升扫描速度和精确度。
    +   *  接口地址:https://api.mch.weixin.qq.com/tools/shorturl
    +   *  是否需要证书:否
    +   * 
    + * @param request 请求对象 + */ + String shorturl(WxPayShorturlRequest request) throws WxErrorException; + + /** + *
    +   *  转换短链接
    +   *  应用场景:
    +   *     该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量,提升扫描速度和精确度。
    +   *  接口地址:https://api.mch.weixin.qq.com/tools/shorturl
    +   *  是否需要证书:否
    +   * 
    + * @param longUrl 需要被压缩的网址 + */ + String shorturl(String longUrl) throws WxErrorException; + } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java index 7ed530be..aea06943 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java @@ -328,6 +328,22 @@ public class WxPayServiceImpl implements WxPayService { return result; } + @Override + public String shorturl(WxPayShorturlRequest request) throws WxErrorException { + request.checkAndSign(this.getConfig()); + + String url = this.getPayBaseUrl() + "/tools/shorturl"; + String responseContent = this.post(url, request.toXML()); + WxPayShorturlResult result = WxPayBaseResult.fromXML(responseContent, WxPayShorturlResult.class); + result.checkResult(this); + return result.getShortUrl(); + } + + @Override + public String shorturl(String longUrl) throws WxErrorException { + return this.shorturl(new WxPayShorturlRequest(longUrl)); + } + private String post(String url, String xmlParam) { String requestString = xmlParam; try { diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java index f668e96c..3898d137 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java @@ -28,10 +28,11 @@ import static org.testng.Assert.*; @Test @Guice(modules = ApiTestModule.class) public class WxPayServiceImplTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Inject - protected WxPayService payService; + private WxPayService payService; @Test public void testGetPayInfo() throws Exception { @@ -221,10 +222,12 @@ public class WxPayServiceImplTest { @Test public void testGetConfig() throws Exception { + // no need to test } @Test public void testSetConfig() throws Exception { + // no need to test } @Test @@ -236,4 +239,16 @@ public class WxPayServiceImplTest { this.logger.info(result.toString()); } + @Test + public void testShorturl() throws Exception { + String longUrl = "weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX"; + + String result = this.payService.shorturl(new WxPayShorturlRequest(longUrl)); + assertNotNull(result); + this.logger.info(result.toString()); + + result = this.payService.shorturl(longUrl); + assertNotNull(result); + this.logger.info(result.toString()); + } } From 0418f172f5452e3888749d06517cd50aee5d844d Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 27 Mar 2017 15:35:10 +0800 Subject: [PATCH 41/63] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=20=E6=8E=88=E6=9D=83=E7=A0=81=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2OPENID=E6=8E=A5=E5=8F=A3API=20#101?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/WxPayAuthcode2OpenidRequest.java | 46 +++++++++++++++++++ .../result/WxPayAuthcode2OpenidResult.java | 40 ++++++++++++++++ .../wxpay/service/WxPayService.java | 30 ++++++++++-- .../wxpay/service/impl/WxPayServiceImpl.java | 16 +++++++ .../service/impl/WxPayServiceImplTest.java | 19 ++++++-- 5 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java new file mode 100644 index 00000000..594fa496 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java @@ -0,0 +1,46 @@ +package com.github.binarywang.wxpay.bean.request; + +import com.thoughtworks.xstream.annotations.XStreamAlias; + +/** + *
    + * 授权码查询openid接口请求对象类
    + * Created by Binary Wang on 2017-3-27.
    + * @author binarywang(Binary Wang)
    + * 
    + */ +@XStreamAlias("xml") +public class WxPayAuthcode2OpenidRequest extends WxPayBaseRequest { + + /** + *
    +   *     授权码
    +   *     auth_code
    +   *     是
    +   *     String(128)
    +   *     扫码支付授权码,设备读取用户微信中的条码或者二维码信息
    +   * 
    + */ + @XStreamAlias("auth_code") + private String authCode; + + public WxPayAuthcode2OpenidRequest() { + } + + public WxPayAuthcode2OpenidRequest(String authCode) { + this.authCode = authCode; + } + + public String getAuthCode() { + return this.authCode; + } + + public void setAuthCode(String authCode) { + this.authCode = authCode; + } + + @Override + protected void checkConstraints() { + // nothing to do + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java new file mode 100644 index 00000000..f56c61a7 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java @@ -0,0 +1,40 @@ +package com.github.binarywang.wxpay.bean.result; + +import com.thoughtworks.xstream.annotations.XStreamAlias; + +/** + *
    + *  授权码查询openid接口请求结果类
    + * Created by Binary Wang on 2017-3-27.
    + * @author binarywang(Binary Wang)
    + * 
    + */ +@XStreamAlias("xml") +public class WxPayAuthcode2OpenidResult extends WxPayBaseResult { + /** + *
    +   *   用户标识
    +   *   openid
    +   *   是
    +   *   String(128)
    +   *   用户在商户appid下的唯一标识
    +   * 
    + */ + @XStreamAlias("openid") + private String openid; + + public WxPayAuthcode2OpenidResult() { + } + + public WxPayAuthcode2OpenidResult(String openid) { + this.openid = openid; + } + + public String getOpenid() { + return this.openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index e61ff863..e336cd21 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -281,6 +281,8 @@ public interface WxPayService { /** *
        *  转换短链接
    +   *  文档地址:
    +   *     https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_9&index=8
        *  应用场景:
        *     该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量,提升扫描速度和精确度。
        *  接口地址:https://api.mch.weixin.qq.com/tools/shorturl
    @@ -293,13 +295,33 @@ public interface WxPayService {
       /**
        * 
        *  转换短链接
    -   *  应用场景:
    -   *     该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量,提升扫描速度和精确度。
    -   *  接口地址:https://api.mch.weixin.qq.com/tools/shorturl
    -   *  是否需要证书:否
        * 
    + * @see WxPayService#shorturl(WxPayShorturlRequest) * @param longUrl 需要被压缩的网址 */ String shorturl(String longUrl) throws WxErrorException; + /** + *
    +   * 授权码查询OPENID接口
    +   *    通过授权码查询公众号Openid,调用查询后,该授权码只能由此商户号发起扣款,直至授权码更新。
    +   * 文档地址:
    +   *    https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9
    +   * 接口链接:
    +   *    https://api.mch.weixin.qq.com/tools/authcodetoopenid
    +   * 
    + * @param request 请求对象 + * @return openid + */ + String authcode2Openid(WxPayAuthcode2OpenidRequest request) throws WxErrorException; + + /** + *
    +   * 授权码查询OPENID接口
    +   * 
    + * @see WxPayService#authcode2Openid(WxPayAuthcode2OpenidRequest) + * @param authCode 授权码 + * @return openid + */ + String authcode2Openid(String authCode) throws WxErrorException; } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java index aea06943..c26d0583 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImpl.java @@ -344,6 +344,22 @@ public class WxPayServiceImpl implements WxPayService { return this.shorturl(new WxPayShorturlRequest(longUrl)); } + @Override + public String authcode2Openid(WxPayAuthcode2OpenidRequest request) throws WxErrorException { + request.checkAndSign(this.getConfig()); + + String url = this.getPayBaseUrl() + "/tools/authcodetoopenid"; + String responseContent = this.post(url, request.toXML()); + WxPayAuthcode2OpenidResult result = WxPayBaseResult.fromXML(responseContent, WxPayAuthcode2OpenidResult.class); + result.checkResult(this); + return result.getOpenid(); + } + + @Override + public String authcode2Openid(String authCode) throws WxErrorException { + return this.authcode2Openid(new WxPayAuthcode2OpenidRequest(authCode)); + } + private String post(String url, String xmlParam) { String requestString = xmlParam; try { diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java index 3898d137..93b0b8b5 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceImplTest.java @@ -28,7 +28,6 @@ import static org.testng.Assert.*; @Test @Guice(modules = ApiTestModule.class) public class WxPayServiceImplTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Inject @@ -245,10 +244,24 @@ public class WxPayServiceImplTest { String result = this.payService.shorturl(new WxPayShorturlRequest(longUrl)); assertNotNull(result); - this.logger.info(result.toString()); + this.logger.info(result); result = this.payService.shorturl(longUrl); assertNotNull(result); - this.logger.info(result.toString()); + this.logger.info(result); } + + @Test + public void testAuthcode2Openid() throws Exception { + String authCode = "11111"; + + String result = this.payService.authcode2Openid(new WxPayAuthcode2OpenidRequest(authCode)); + assertNotNull(result); + this.logger.info(result); + + result = this.payService.authcode2Openid(authCode); + assertNotNull(result); + this.logger.info(result); + } + } From 29353ffc3dd26fbdba7d3705438269797bc1ab21 Mon Sep 17 00:00:00 2001 From: lly835 Date: Mon, 27 Mar 2017 16:35:39 +0800 Subject: [PATCH 42/63] =?UTF-8?q?access=5Ftoken=E7=BC=93=E5=AD=98=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0redis=E6=94=AF=E6=8C=81=20(#169)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 + weixin-java-mp/pom.xml | 4 + .../mp/api/WxMpInRedisConfigStorage.java | 309 ++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java diff --git a/pom.xml b/pom.xml index 8367f9f4..e83c2c1b 100644 --- a/pom.xml +++ b/pom.xml @@ -106,6 +106,7 @@ 2.5 1.10 9.3.0.RC0 + 2.9.0 @@ -193,6 +194,11 @@ guava ${guava.version} + + redis.clients + jedis + ${jedis.version} + diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 62ef79e0..32f04f25 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -44,6 +44,10 @@ 2.9.4 test + + redis.clients + jedis + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java new file mode 100644 index 00000000..89648268 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java @@ -0,0 +1,309 @@ +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 redis.clients.jedis.Jedis; + +import javax.net.ssl.SSLContext; +import java.io.File; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * 基于Redis的微信配置provider + * + * @author lly835 + */ +public class WxMpInRedisConfigStorage implements WxMpConfigStorage { + + private final static String ACCESS_TOKEN_KEY = "wechat_access_token_"; + + private final static String JSAPI_TICKET_KEY = "wechat_jsapi_ticket_"; + + private final static String CARDAPI_TICKET_KEY = "wechat_cardapi_ticket_"; + + 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; + protected volatile long expiresTime; + + protected volatile String oauth2redirectUri; + + protected volatile String httpProxyHost; + protected volatile int httpProxyPort; + protected volatile String httpProxyUsername; + protected volatile String httpProxyPassword; + + protected volatile String jsapiTicket; + protected volatile long jsapiTicketExpiresTime; + + protected volatile String cardApiTicket; + protected volatile long cardApiTicketExpiresTime; + + protected Lock accessTokenLock = new ReentrantLock(); + protected Lock jsapiTicketLock = new ReentrantLock(); + protected Lock cardApiTicketLock = new ReentrantLock(); + + /** + * 临时文件目录 + */ + protected volatile File tmpDirFile; + + protected volatile SSLContext sslContext; + + protected volatile ApacheHttpClientBuilder apacheHttpClientBuilder; + + protected Jedis jedis; + + @Override + public String getAccessToken() { + return jedis.get(ACCESS_TOKEN_KEY.concat(appId)); + } + + @Override + public Lock getAccessTokenLock() { + return this.accessTokenLock; + } + + @Override + public boolean isAccessTokenExpired() { + return getAccessToken() == null ? true : false; + } + + @Override + public synchronized void updateAccessToken(WxAccessToken accessToken) { + updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); + } + + @Override + public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { + this.accessToken = accessToken; + this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; + jedis.set(ACCESS_TOKEN_KEY.concat(appId), accessToken); + jedis.expire(ACCESS_TOKEN_KEY.concat(appId), expiresInSeconds - 200); + } + + @Override + public void expireAccessToken() { + this.expiresTime = 0; + } + + @Override + public String getJsapiTicket() { + return this.jsapiTicket; + } + + public void setJsapiTicket(String jsapiTicket) { + this.jsapiTicket = jsapiTicket; + } + + @Override + public Lock getJsapiTicketLock() { + return this.jsapiTicketLock; + } + + @Override + public boolean isJsapiTicketExpired() { + return getJsapiTicket() == null ? true : false; + } + + @Override + public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { + this.jsapiTicket = jsapiTicket; + // 预留200秒的时间 + this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; + jedis.set(JSAPI_TICKET_KEY.concat(appId), accessToken); + jedis.expire(JSAPI_TICKET_KEY.concat(appId), expiresInSeconds - 200); + } + + @Override + public void expireJsapiTicket() { + this.jsapiTicketExpiresTime = 0; + } + + /** + * 卡券api_ticket + */ + @Override + public String getCardApiTicket() { + return this.cardApiTicket; + } + + @Override + public Lock getCardApiTicketLock() { + return this.cardApiTicketLock; + } + + @Override + public boolean isCardApiTicketExpired() { + return System.currentTimeMillis() > this.cardApiTicketExpiresTime; + } + + @Override + public synchronized void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { + this.cardApiTicket = cardApiTicket; + // 预留200秒的时间 + this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; + jedis.set(CARDAPI_TICKET_KEY.concat(appId), accessToken); + jedis.expire(CARDAPI_TICKET_KEY.concat(appId), expiresInSeconds - 200); + } + + @Override + public void expireCardApiTicket() { + this.cardApiTicketExpiresTime = 0; + } + + @Override + public String getAppId() { + return this.appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + @Override + public String getSecret() { + return this.secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + @Override + public String getToken() { + return this.token; + } + + public void setToken(String token) { + this.token = token; + } + + @Override + public long getExpiresTime() { + return this.expiresTime; + } + + public void setExpiresTime(long expiresTime) { + this.expiresTime = expiresTime; + } + + @Override + public String getAesKey() { + return this.aesKey; + } + + public void setAesKey(String aesKey) { + this.aesKey = aesKey; + } + + @Override + public String getOauth2redirectUri() { + return this.oauth2redirectUri; + } + + public void setOauth2redirectUri(String oauth2redirectUri) { + this.oauth2redirectUri = oauth2redirectUri; + } + + @Override + public String getHttpProxyHost() { + return this.httpProxyHost; + } + + public void setHttpProxyHost(String httpProxyHost) { + this.httpProxyHost = httpProxyHost; + } + + @Override + public int getHttpProxyPort() { + return this.httpProxyPort; + } + + public void setHttpProxyPort(int httpProxyPort) { + this.httpProxyPort = httpProxyPort; + } + + @Override + public String getHttpProxyUsername() { + return this.httpProxyUsername; + } + + public void setHttpProxyUsername(String httpProxyUsername) { + this.httpProxyUsername = httpProxyUsername; + } + + @Override + public String getHttpProxyPassword() { + return this.httpProxyPassword; + } + + public void setHttpProxyPassword(String httpProxyPassword) { + this.httpProxyPassword = httpProxyPassword; + } + + @Override + public String toString() { + return ToStringUtils.toSimpleString(this); + } + + public void setPartnerId(String partnerId) { + this.partnerId = partnerId; + } + + 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 void setTradeType(String tradeType) { + this.tradeType = tradeType; + } + + @Override + public File getTmpDirFile() { + return this.tmpDirFile; + } + + public void setTmpDirFile(File tmpDirFile) { + this.tmpDirFile = tmpDirFile; + } + + @Override + public ApacheHttpClientBuilder getApacheHttpClientBuilder() { + return this.apacheHttpClientBuilder; + } + + public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { + this.apacheHttpClientBuilder = apacheHttpClientBuilder; + } + + @Override + public boolean autoRefreshToken() { + return true; + } + + public void setJedis(Jedis jedis) { + this.jedis = jedis; + } +} From 54ee287c116d421a07dcf3ed286a75c75d997b01 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 27 Mar 2017 17:15:24 +0800 Subject: [PATCH 43/63] =?UTF-8?q?=E7=BE=A4=E5=8F=91=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=A0=BC=E5=BC=8F=E4=B8=AD=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E5=AF=B9towxname=E5=92=8Ctouser=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mp/bean/WxMpMassPreviewMessage.java | 21 +++++++++++++------ .../WxMpMassPreviewMessageGsonAdapter.java | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java index b49ffc38..d70ac570 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java @@ -9,7 +9,8 @@ import java.io.Serializable; */ public class WxMpMassPreviewMessage implements Serializable { private static final long serialVersionUID = 9095211638358424020L; - private String toWxUsername; + private String toWxUserName; + private String toWxUserOpenid; private String msgType; private String content; private String mediaId; @@ -18,12 +19,12 @@ public class WxMpMassPreviewMessage implements Serializable { super(); } - public String getToWxUsername() { - return this.toWxUsername; + public String getToWxUserName() { + return this.toWxUserName; } - public void setToWxUsername(String toWxUsername) { - this.toWxUsername = toWxUsername; + public void setToWxUserName(String toWxUserName) { + this.toWxUserName = toWxUserName; } public String getMsgType() { @@ -41,7 +42,7 @@ public class WxMpMassPreviewMessage implements Serializable { * 如果msgtype和media_id不匹配的话,会返回系统繁忙的错误 *
    * - * @param msgType + * @param msgType 消息类型 */ public void setMsgType(String msgType) { this.msgType = msgType; @@ -63,6 +64,14 @@ public class WxMpMassPreviewMessage implements Serializable { this.mediaId = mediaId; } + public String getToWxUserOpenid() { + return this.toWxUserOpenid; + } + + public void setToWxUserOpenid(String toWxUserOpenid) { + this.toWxUserOpenid = toWxUserOpenid; + } + public String toJson() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java index fd3e52df..b5871e6b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java @@ -17,6 +17,7 @@ public class WxMpMassPreviewMessageGsonAdapter implements JsonSerializer Date: Mon, 27 Mar 2017 17:19:17 +0800 Subject: [PATCH 44/63] fix --- .../weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java index b5871e6b..fd210fb3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java @@ -16,7 +16,7 @@ public class WxMpMassPreviewMessageGsonAdapter implements JsonSerializer Date: Sun, 26 Mar 2017 23:48:17 +0800 Subject: [PATCH 45/63] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BF=AE=E8=A1=A5javad?= =?UTF-8?q?oc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/cp/api/WxCpService.java | 135 +++++++----------- .../weixin/cp/api/WxCpServiceImpl.java | 4 +- 2 files changed, 51 insertions(+), 88 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index b5bf50c9..bd0b322f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -28,9 +28,9 @@ public interface WxCpService { * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=验证消息真实性 *
    * - * @param msgSignature - * @param timestamp - * @param nonce + * @param msgSignature 消息签名 + * @param timestamp 时间戳 + * @param nonce 随机数 * @param data 微信传输过来的数据,有可能是echoStr,有可能是xml消息 */ boolean checkSignature(String msgSignature, String timestamp, String nonce, String data); @@ -41,14 +41,13 @@ public interface WxCpService { * 企业在员工验证成功后,调用本方法告诉企业号平台该员工关注成功。 *
    * - * @param userId + * @param userId 用户id */ void userAuthenticated(String userId) throws WxErrorException; /** * 获取access_token, 不强制刷新access_token * - * @throws WxErrorException * @see #getAccessToken(boolean) */ String getAccessToken() throws WxErrorException; @@ -63,14 +62,12 @@ public interface WxCpService { *
    * * @param forceRefresh 强制刷新 - * @throws me.chanjar.weixin.common.exception.WxErrorException */ String getAccessToken(boolean forceRefresh) throws WxErrorException; /** * 获得jsapi_ticket,不强制刷新jsapi_ticket * - * @throws WxErrorException * @see #getJsapiTicket(boolean) */ String getJsapiTicket() throws WxErrorException; @@ -84,7 +81,6 @@ public interface WxCpService { *
    * * @param forceRefresh 强制刷新 - * @throws WxErrorException */ String getJsapiTicket(boolean forceRefresh) throws WxErrorException; @@ -113,15 +109,13 @@ public interface WxCpService { * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} * @param fileType 文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts} * @param inputStream 输入流 - * @throws WxErrorException */ WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) - throws WxErrorException, IOException; + throws WxErrorException, IOException; /** - * @param mediaType - * @param file - * @throws WxErrorException + * @param mediaType 媒体类型 + * @param file 文件对象 * @see #mediaUpload(String, String, InputStream) */ WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException; @@ -133,20 +127,18 @@ public interface WxCpService { * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=上传下载多媒体文件 *
    * - * @param media_id + * @param mediaId 媒体id * @return 保存到本地的临时文件 - * @throws WxErrorException */ - File mediaDownload(String media_id) throws WxErrorException; + File mediaDownload(String mediaId) throws WxErrorException; /** *
        * 发送消息
    -   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=发送消息
    +   * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E
        * 
    * - * @param message - * @throws WxErrorException + * @param message 要发送的消息对象 */ void messageSend(WxCpMessage message) throws WxErrorException; @@ -158,8 +150,7 @@ public interface WxCpService { * 注意: 这个方法使用WxCpConfigStorage里的agentId *
    * - * @param menu - * @throws WxErrorException + * @param menu 菜单对象 * @see #menuCreate(Integer, WxMenu) */ void menuCreate(WxMenu menu) throws WxErrorException; @@ -173,8 +164,7 @@ public interface WxCpService { *
    * * @param agentId 企业号应用的id - * @param menu - * @throws WxErrorException + * @param menu 菜单对象 * @see #menuCreate(me.chanjar.weixin.common.bean.menu.WxMenu) */ void menuCreate(Integer agentId, WxMenu menu) throws WxErrorException; @@ -187,7 +177,6 @@ public interface WxCpService { * 注意: 这个方法使用WxCpConfigStorage里的agentId *
    * - * @throws WxErrorException * @see #menuDelete(Integer) */ void menuDelete() throws WxErrorException; @@ -201,7 +190,6 @@ public interface WxCpService { *
    * * @param agentId 企业号应用的id - * @throws WxErrorException * @see #menuDelete() */ void menuDelete(Integer agentId) throws WxErrorException; @@ -214,7 +202,6 @@ public interface WxCpService { * 注意: 这个方法使用WxCpConfigStorage里的agentId *
    * - * @throws WxErrorException * @see #menuGet(Integer) */ WxMenu menuGet() throws WxErrorException; @@ -228,7 +215,6 @@ public interface WxCpService { *
    * * @param agentId 企业号应用的id - * @throws WxErrorException * @see #menuGet() */ WxMenu menuGet(Integer agentId) throws WxErrorException; @@ -242,7 +228,6 @@ public interface WxCpService { * * @param depart 部门 * @return 部门id - * @throws WxErrorException */ Integer departCreate(WxCpDepart depart) throws WxErrorException; @@ -251,8 +236,6 @@ public interface WxCpService { * 部门管理接口 - 查询所有部门 * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=部门管理接口 *
    - * - * @throws WxErrorException */ List departGet() throws WxErrorException; @@ -264,7 +247,6 @@ public interface WxCpService { *
    * * @param group 要更新的group,group的id,name必须设置 - * @throws WxErrorException */ void departUpdate(WxCpDepart group) throws WxErrorException; @@ -273,8 +255,7 @@ public interface WxCpService { * 部门管理接口 - 删除部门 *
    * - * @param departId - * @throws WxErrorException + * @param departId 部门id */ void departDelete(Integer departId) throws WxErrorException; @@ -288,7 +269,6 @@ public interface WxCpService { * @param departId 必填。部门id * @param fetchChild 非必填。1/0:是否递归获取子部门下面的成员 * @param status 非必填。0获取全部员工,1获取已关注成员列表,2获取禁用成员列表,4获取未关注成员列表。status可叠加 - * @throws WxErrorException */ List userList(Integer departId, Boolean fetchChild, Integer status) throws WxErrorException; @@ -302,73 +282,66 @@ public interface WxCpService { * @param departId 必填。部门id * @param fetchChild 非必填。1/0:是否递归获取子部门下面的成员 * @param status 非必填。0获取全部员工,1获取已关注成员列表,2获取禁用成员列表,4获取未关注成员列表。status可叠加 - * @throws WxErrorException */ List departGetUsers(Integer departId, Boolean fetchChild, Integer status) throws WxErrorException; /** * 新建用户 * - * @param user - * @throws WxErrorException + * @param user 用户对象 */ void userCreate(WxCpUser user) throws WxErrorException; /** * 更新用户 * - * @param user - * @throws WxErrorException + * @param user 用户对象 */ void userUpdate(WxCpUser user) throws WxErrorException; /** * 删除用户 * - * @param userid - * @throws WxErrorException + * @param userid 用户id */ void userDelete(String userid) throws WxErrorException; /** *
        * 批量删除成员
    -   *
        * http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E6.89.B9.E9.87.8F.E5.88.A0.E9.99.A4.E6.88.90.E5.91.98
        * 
    * * @param userids 员工UserID列表。对应管理端的帐号 - * @throws WxErrorException */ void userDelete(String[] userids) throws WxErrorException; /** * 获取用户 * - * @param userid - * @throws WxErrorException + * @param userid 用户id */ WxCpUser userGet(String userid) throws WxErrorException; /** * 创建标签 * - * @param tagName + * @param tagName 标签名 */ String tagCreate(String tagName) throws WxErrorException; /** * 更新标签 * - * @param tagId - * @param tagName + * @param tagId 标签id + * @param tagName 标签名 */ void tagUpdate(String tagId, String tagName) throws WxErrorException; /** * 删除标签 * - * @param tagId + * @param tagId 标签id */ void tagDelete(String tagId) throws WxErrorException; @@ -380,24 +353,24 @@ public interface WxCpService { /** * 获取标签成员 * - * @param tagId + * @param tagId 标签ID */ List tagGetUsers(String tagId) throws WxErrorException; /** * 增加标签成员 * - * @param tagId - * @param userIds + * @param tagId 标签id + * @param userIds 用户ID 列表 */ void tagAddUsers(String tagId, List userIds, List partyIds) throws WxErrorException; /** - *
    +   * 
        * 构造oauth2授权的url连接
        * 
    * - * @param state + * @param state 状态码 * @return url */ String oauth2buildAuthorizationUrl(String state); @@ -408,8 +381,8 @@ public interface WxCpService { * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=企业获取code *
    * - * @param redirectUri - * @param state + * @param redirectUri 跳转链接地址 + * @param state 状态码 * @return url */ String oauth2buildAuthorizationUrl(String redirectUri, String state); @@ -423,7 +396,7 @@ public interface WxCpService { * 注意: 这个方法使用WxCpConfigStorage里的agentId *
    * - * @param code + * @param code 微信oauth授权返回的代码 * @return [userid, deviceid] * @see #oauth2getUserInfo(Integer, String) */ @@ -439,7 +412,7 @@ public interface WxCpService { *
    * * @param agentId 企业号应用的id - * @param code + * @param code 微信oauth授权返回的代码 * @return [userid, deviceid] * @see #oauth2getUserInfo(String) */ @@ -449,8 +422,8 @@ public interface WxCpService { /** * 移除标签成员 * - * @param tagId - * @param userIds + * @param tagId 标签id + * @param userIds 用户id列表 */ void tagRemoveUsers(String tagId, List userIds) throws WxErrorException; @@ -463,7 +436,6 @@ public interface WxCpService { * @param userId 用户的userid * @param inviteTips 推送到微信上的提示语(只有认证号可以使用)。当使用微信推送时,该字段默认为“请关注XXX企业号”,邮件邀请时,该字段无效。 * @return 1:微信邀请 2.邮件邀请 - * @throws WxErrorException */ int invite(String userId, String inviteTips) throws WxErrorException; @@ -474,25 +446,22 @@ public interface WxCpService { *
    * * @return { "ip_list": ["101.226.103.*", "101.226.62.*"] } - * @throws WxErrorException */ String[] getCallbackIp() throws WxErrorException; /** * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 * - * @param url - * @param queryParam - * @throws WxErrorException + * @param url 接口地址 + * @param queryParam 请求参数 */ String get(String url, String queryParam) throws WxErrorException; /** * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求 * - * @param url - * @param postData - * @throws WxErrorException + * @param url 接口地址 + * @param postData 请求body字符串 */ String post(String url, String postData) throws WxErrorException; @@ -503,19 +472,18 @@ public interface WxCpService { * 可以参考,{@link me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor}的实现方法 *
    * - * @param executor - * @param uri - * @param data - * @param - * @param - * @throws WxErrorException + * @param executor 执行器 + * @param uri 请求地址 + * @param data 参数 + * @param 请求值类型 + * @param 返回值类型 */ T execute(RequestExecutor executor, String uri, E data) throws WxErrorException; /** * 注入 {@link WxCpConfigStorage} 的实现 * - * @param wxConfigProvider + * @param wxConfigProvider 配置对象 */ void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider); @@ -525,7 +493,7 @@ public interface WxCpService { * 默认:1000ms *
    * - * @param retrySleepMillis + * @param retrySleepMillis 重试休息时间 */ void setRetrySleepMillis(int retrySleepMillis); @@ -535,7 +503,7 @@ public interface WxCpService { * 默认:5次 *
    * - * @param maxRetryTimes + * @param maxRetryTimes 最大重试次数 */ void setMaxRetryTimes(int maxRetryTimes); @@ -550,7 +518,7 @@ public interface WxCpService { * 获取某个sessionId对应的session,如果sessionId没有对应的session,若create为true则新建一个,否则返回null。 * * @param id id可以为任意字符串,建议使用FromUserName作为id - * @param create + * @param create 是否新建 */ WxSession getSession(String id, boolean create); @@ -560,31 +528,26 @@ public interface WxCpService { * WxCpService默认使用的是{@link me.chanjar.weixin.common.session.StandardSessionManager} *
    * - * @param sessionManager + * @param sessionManager 会话管理器 */ void setSessionManager(WxSessionManager sessionManager); /** * 上传部门列表覆盖企业号上的部门信息 * - * @param mediaId - * @throws WxErrorException + * @param mediaId 媒体id */ String replaceParty(String mediaId) throws WxErrorException; /** * 上传用户列表覆盖企业号上的用户信息 * - * @param mediaId - * @throws WxErrorException + * @param mediaId 媒体id */ String replaceUser(String mediaId) throws WxErrorException; /** * 获取异步任务结果 - * - * @param joinId - * @throws WxErrorException */ String getTaskResult(String joinId) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java index a10eb42e..0105e78d 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java @@ -238,12 +238,12 @@ public class WxCpServiceImpl implements WxCpService { } @Override - public File mediaDownload(String media_id) throws WxErrorException { + public File mediaDownload(String mediaId) throws WxErrorException { String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get"; return execute( new MediaDownloadRequestExecutor( this.configStorage.getTmpDirFile()), - url, "media_id=" + media_id); + url, "media_id=" + mediaId); } From 3ead031c2b6f9fd454c19799595e7221ddc3d26f Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 27 Mar 2017 22:16:32 +0800 Subject: [PATCH 46/63] =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=8F=B7mpnews=E6=B6=88=E6=81=AF=E7=B1=BB=E5=9E=8B=20=20#143?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/cp/bean/article/MpnewsArticle.java | 139 ++++++++++++++++++ .../weixin/cp/bean/article/NewArticle.java | 49 ++++++ .../chanjar/weixin/cp/bean/WxCpMessage.java | 68 +++------ .../cp/bean/messagebuilder/MpnewsBuilder.java | 48 ++++++ .../cp/bean/messagebuilder/NewsBuilder.java | 5 +- .../cp/util/json/WxCpMessageGsonAdapter.java | 27 +++- .../weixin/cp/bean/WxCpMessageTest.java | 46 +++++- 7 files changed, 329 insertions(+), 53 deletions(-) create mode 100644 weixin-java-common/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java create mode 100644 weixin-java-common/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java b/weixin-java-common/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java new file mode 100644 index 00000000..7904da20 --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java @@ -0,0 +1,139 @@ +package me.chanjar.weixin.cp.bean.article; + +/** + *
    + *  Created by BinaryWang on 2017/3/27.
    + * 
    + * @author Binary Wang + */ +public class MpnewsArticle { + private String title; + private String thumbMediaId; + private String author; + private String contentSourceUrl; + private String content; + private String digest; + private String showCoverPic; + + private MpnewsArticle(Builder builder) { + setTitle(builder.title); + setThumbMediaId(builder.thumbMediaId); + setAuthor(builder.author); + setContentSourceUrl(builder.contentSourceUrl); + setContent(builder.content); + setDigest(builder.digest); + setShowCoverPic(builder.showCoverPic); + } + + public static Builder newBuilder() { + return new Builder(); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getThumbMediaId() { + return thumbMediaId; + } + + public void setThumbMediaId(String thumbMediaId) { + this.thumbMediaId = thumbMediaId; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getContentSourceUrl() { + return contentSourceUrl; + } + + public void setContentSourceUrl(String contentSourceUrl) { + this.contentSourceUrl = contentSourceUrl; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getDigest() { + return digest; + } + + public void setDigest(String digest) { + this.digest = digest; + } + + public String getShowCoverPic() { + return showCoverPic; + } + + public void setShowCoverPic(String showCoverPic) { + this.showCoverPic = showCoverPic; + } + + public static final class Builder { + private String title; + private String thumbMediaId; + private String author; + private String contentSourceUrl; + private String content; + private String digest; + private String showCoverPic; + + private Builder() { + } + + public Builder title(String title) { + this.title = title; + return this; + } + + public Builder thumbMediaId(String thumbMediaId) { + this.thumbMediaId = thumbMediaId; + return this; + } + + public Builder author(String author) { + this.author = author; + return this; + } + + public Builder contentSourceUrl(String contentSourceUrl) { + this.contentSourceUrl = contentSourceUrl; + return this; + } + + public Builder content(String content) { + this.content = content; + return this; + } + + public Builder digest(String digest) { + this.digest = digest; + return this; + } + + public Builder showCoverPic(String showCoverPic) { + this.showCoverPic = showCoverPic; + return this; + } + + public MpnewsArticle build() { + return new MpnewsArticle(this); + } + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java b/weixin-java-common/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java new file mode 100644 index 00000000..d4c056d5 --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java @@ -0,0 +1,49 @@ +package me.chanjar.weixin.cp.bean.article; + +/** + *
    + *  Created by BinaryWang on 2017/3/27.
    + * 
    + * + * @author Binary Wang + */ +public class NewArticle { + + private String title; + private String description; + private String url; + private String picUrl; + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getUrl() { + return this.url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getPicUrl() { + return this.picUrl; + } + + public void setPicUrl(String picUrl) { + this.picUrl = picUrl; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java index c25c170b..324df209 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java @@ -1,5 +1,7 @@ package me.chanjar.weixin.cp.bean; +import me.chanjar.weixin.cp.bean.article.MpnewsArticle; +import me.chanjar.weixin.cp.bean.article.NewArticle; import me.chanjar.weixin.cp.bean.messagebuilder.*; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; @@ -28,7 +30,16 @@ public class WxCpMessage implements Serializable { private String musicUrl; private String hqMusicUrl; private String safe; - private List articles = new ArrayList<>(); + private List articles = new ArrayList<>(); + private List mpnewsArticles = new ArrayList<>(); + + public List getMpnewsArticles() { + return mpnewsArticles; + } + + public void setMpnewsArticles(List mpnewsArticles) { + this.mpnewsArticles = mpnewsArticles; + } /** * 获得文本消息builder @@ -65,6 +76,13 @@ public class WxCpMessage implements Serializable { return new NewsBuilder(); } + /** + * 获得mpnews图文消息builder + */ + public static MpnewsBuilder MPNEWS() { + return new MpnewsBuilder(); + } + /** * 获得文件消息builder */ @@ -117,9 +135,10 @@ public class WxCpMessage implements Serializable { * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MUSIC} * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VIDEO} * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_NEWS} + * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MPNEWS} * * - * @param msgType + * @param msgType 消息类型 */ public void setMsgType(String msgType) { this.msgType = msgType; @@ -189,11 +208,11 @@ public class WxCpMessage implements Serializable { this.hqMusicUrl = hqMusicUrl; } - public List getArticles() { + public List getArticles() { return this.articles; } - public void setArticles(List articles) { + public void setArticles(List articles) { this.articles = articles; } @@ -201,45 +220,4 @@ public class WxCpMessage implements Serializable { return WxCpGsonBuilder.INSTANCE.create().toJson(this); } - public static class WxArticle { - - private String title; - private String description; - private String url; - private String picUrl; - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getPicUrl() { - return this.picUrl; - } - - public void setPicUrl(String picUrl) { - this.picUrl = picUrl; - } - - } - } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java new file mode 100644 index 00000000..21ab2549 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java @@ -0,0 +1,48 @@ +package me.chanjar.weixin.cp.bean.messagebuilder; + +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.article.MpnewsArticle; + +import java.util.ArrayList; +import java.util.List; + +/** + * mpnews类型的图文消息builder + *
    + * 用法:
    + * WxCustomMessage m = WxCustomMessage.MPNEWS().addArticle(article).toUser(...).build();
    + * 
    + * + * @author Binary Wang + */ +public final class MpnewsBuilder extends BaseBuilder { + private List articles = new ArrayList<>(); + + private String mediaId; + + public MpnewsBuilder() { + this.msgType = WxConsts.CUSTOM_MSG_MPNEWS; + } + + public MpnewsBuilder mediaId(String mediaId) { + this.mediaId = mediaId; + return this; + } + + public MpnewsBuilder addArticle(MpnewsArticle article) { + this.articles.add(article); + return this; + } + + @Override + public WxCpMessage build() { + WxCpMessage m = super.build(); + m.setMpnewsArticles(this.articles); + if (this.mediaId != null) { + m.setMediaId(this.mediaId); + } + + return m; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java index 8ea90872..e0df095e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java @@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.bean.messagebuilder; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.article.NewArticle; import java.util.ArrayList; import java.util.List; @@ -17,13 +18,13 @@ import java.util.List; */ public final class NewsBuilder extends BaseBuilder { - private List articles = new ArrayList<>(); + private List articles = new ArrayList<>(); public NewsBuilder() { this.msgType = WxConsts.CUSTOM_MSG_NEWS; } - public NewsBuilder addArticle(WxCpMessage.WxArticle article) { + public NewsBuilder addArticle(NewArticle article) { this.articles.add(article); return this; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java index 7bf09c71..949709ab 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java @@ -11,6 +11,8 @@ package me.chanjar.weixin.cp.util.json; import com.google.gson.*; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.article.MpnewsArticle; +import me.chanjar.weixin.cp.bean.article.NewArticle; import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Type; @@ -71,7 +73,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer { if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgType())) { JsonObject newsJsonObject = new JsonObject(); JsonArray articleJsonArray = new JsonArray(); - for (WxCpMessage.WxArticle article : message.getArticles()) { + for (NewArticle article : message.getArticles()) { JsonObject articleJson = new JsonObject(); articleJson.addProperty("title", article.getTitle()); articleJson.addProperty("description", article.getDescription()); @@ -83,6 +85,29 @@ public class WxCpMessageGsonAdapter implements JsonSerializer { messageJson.add("news", newsJsonObject); } + if (WxConsts.CUSTOM_MSG_MPNEWS.equals(message.getMsgType())) { + JsonObject newsJsonObject = new JsonObject(); + if (message.getMediaId() != null) { + newsJsonObject.addProperty("media_id", message.getMediaId()); + }else { + JsonArray articleJsonArray = new JsonArray(); + for (MpnewsArticle article : message.getMpnewsArticles()) { + JsonObject articleJson = new JsonObject(); + articleJson.addProperty("title", article.getTitle()); + articleJson.addProperty("thumb_media_id", article.getThumbMediaId()); + articleJson.addProperty("author", article.getAuthor()); + articleJson.addProperty("content_source_url", article.getContentSourceUrl()); + articleJson.addProperty("content", article.getContent()); + articleJson.addProperty("digest", article.getDigest()); + articleJson.addProperty("show_cover_pic", article.getShowCoverPic()); + articleJsonArray.add(articleJson); + } + + newsJsonObject.add("articles", articleJsonArray); + } + messageJson.add("mpnews", newsJsonObject); + } + return messageJson; } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java index 12b62e34..5f93aba9 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java @@ -1,7 +1,8 @@ package me.chanjar.weixin.cp.bean; import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.cp.bean.WxCpMessage.WxArticle; +import me.chanjar.weixin.cp.bean.article.NewArticle; +import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import org.testng.Assert; import org.testng.annotations.Test; @@ -68,14 +69,14 @@ public class WxCpMessageTest { reply.setToUser("OPENID"); reply.setMsgType(WxConsts.CUSTOM_MSG_NEWS); - WxArticle article1 = new WxArticle(); + NewArticle article1 = new NewArticle(); article1.setUrl("URL"); article1.setPicUrl("PIC_URL"); article1.setDescription("Is Really A Happy Day"); article1.setTitle("Happy Day"); reply.getArticles().add(article1); - WxArticle article2 = new WxArticle(); + NewArticle article2 = new NewArticle(); article2.setUrl("URL"); article2.setPicUrl("PIC_URL"); article2.setDescription("Is Really A Happy Day"); @@ -87,13 +88,13 @@ public class WxCpMessageTest { } public void testNewsBuild() { - WxArticle article1 = new WxArticle(); + NewArticle article1 = new NewArticle(); article1.setUrl("URL"); article1.setPicUrl("PIC_URL"); article1.setDescription("Is Really A Happy Day"); article1.setTitle("Happy Day"); - WxArticle article2 = new WxArticle(); + NewArticle article2 = new NewArticle(); article2.setUrl("URL"); article2.setPicUrl("PIC_URL"); article2.setDescription("Is Really A Happy Day"); @@ -104,4 +105,39 @@ public class WxCpMessageTest { Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); } + public void testMpnewsBuild_with_articles() { + MpnewsArticle article1 = MpnewsArticle.newBuilder() + .title("Happy Day") + .author("aaaaaa") + .content("hahaha") + .contentSourceUrl("nice url") + .digest("digest") + .showCoverPic("heihei") + .thumbMediaId("thumb") + .build(); + + MpnewsArticle article2 = MpnewsArticle.newBuilder() + .title("Happy Day") + .author("aaaaaa") + .content("hahaha") + .contentSourceUrl("nice url") + .digest("digest") + .showCoverPic("heihei") + .thumbMediaId("thumb") + .build(); + + WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); + + Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\"," + + "\"mpnews\":{\"articles\":[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}," + + "{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}]}}"); + } + + public void testMpnewsBuild_with_media_id() { + WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").mediaId("mmm").build(); + + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"media_id\":\"mmm\"}}"); + } + } From 5d92da6a354a4c6f6650da4217802aa4d64505cd Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 28 Mar 2017 23:14:16 +0800 Subject: [PATCH 47/63] =?UTF-8?q?=E7=AE=80=E5=8C=96test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/cp/bean/WxCpMessageTest.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java index 5f93aba9..ce75b066 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java @@ -6,6 +6,8 @@ import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import org.testng.Assert; import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; + @Test public class WxCpMessageTest { @@ -14,12 +16,12 @@ public class WxCpMessageTest { reply.setToUser("OPENID"); reply.setMsgType(WxConsts.CUSTOM_MSG_TEXT); reply.setContent("sfsfdsdf"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); } public void testTextBuild() { WxCpMessage reply = WxCpMessage.TEXT().toUser("OPENID").content("sfsfdsdf").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); } public void testImageReply() { @@ -27,12 +29,12 @@ public class WxCpMessageTest { reply.setToUser("OPENID"); reply.setMsgType(WxConsts.CUSTOM_MSG_IMAGE); reply.setMediaId("MEDIA_ID"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); } public void testImageBuild() { WxCpMessage reply = WxCpMessage.IMAGE().toUser("OPENID").mediaId("MEDIA_ID").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); } public void testVoiceReply() { @@ -40,12 +42,12 @@ public class WxCpMessageTest { reply.setToUser("OPENID"); reply.setMsgType(WxConsts.CUSTOM_MSG_VOICE); reply.setMediaId("MEDIA_ID"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); } public void testVoiceBuild() { WxCpMessage reply = WxCpMessage.VOICE().toUser("OPENID").mediaId("MEDIA_ID").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); } public void testVideoReply() { @@ -56,12 +58,12 @@ public class WxCpMessageTest { reply.setThumbMediaId("MEDIA_ID"); reply.setTitle("TITLE"); reply.setDescription("DESCRIPTION"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); } public void testVideoBuild() { WxCpMessage reply = WxCpMessage.VIDEO().toUser("OPENID").title("TITLE").mediaId("MEDIA_ID").thumbMediaId("MEDIA_ID").description("DESCRIPTION").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); } public void testNewsReply() { @@ -84,7 +86,7 @@ public class WxCpMessageTest { reply.getArticles().add(article2); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); } public void testNewsBuild() { @@ -102,7 +104,7 @@ public class WxCpMessageTest { WxCpMessage reply = WxCpMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); } public void testMpnewsBuild_with_articles() { @@ -128,7 +130,7 @@ public class WxCpMessageTest { WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\"," + + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\"," + "\"mpnews\":{\"articles\":[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}," + "{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}]}}"); } @@ -136,7 +138,7 @@ public class WxCpMessageTest { public void testMpnewsBuild_with_media_id() { WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").mediaId("mmm").build(); - Assert.assertEquals(reply.toJson(), + assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"media_id\":\"mmm\"}}"); } From 2d5fcb31b4c2d2044c9f5787ac65e9bf9b918eb1 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 28 Mar 2017 23:14:35 +0800 Subject: [PATCH 48/63] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E5=8A=A0=E5=85=A5=E5=AF=B9=E5=B0=8F=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81=20#170?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/common/bean/menu/WxMenuButton.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java index 125043c8..aecbcfd0 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java @@ -10,14 +10,64 @@ import java.util.List; public class WxMenuButton implements Serializable { private static final long serialVersionUID = -1070939403109776555L; + /** + *
    +   * 菜单的响应动作类型:
    +   * view表示网页类型,
    +   * click表示点击类型,
    +   * miniprogram表示小程序类型
    +   * 
    + */ private String type; + + /** + * 菜单标题,不超过16个字节,子菜单不超过60个字节 + */ private String name; + + /** + *
    +   * 菜单KEY值,用于消息接口推送,不超过128字节
    +   * click等点击类型必须
    +   * 
    + */ private String key; + + /** + *
    +   * 网页链接,用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
    +   * view、miniprogram类型必须
    +   * 
    + */ private String url; + /** + *
    +   * 调用新增永久素材接口返回的合法media_id
    +   * media_id类型和view_limited类型必须
    +   * 
    + */ @SerializedName("media_id") private String mediaId; + /** + *
    +   * 小程序的appid
    +   * miniprogram类型必须
    +   * 
    + */ + @SerializedName("appid") + private String appiId; + + /** + *
    +   * 小程序的页面路径
    +   * miniprogram类型必须
    +   * 
    + */ + @SerializedName("pagepath") + private String pagePath; + @SerializedName("sub_button") private List subButtons = new ArrayList<>(); @@ -73,4 +123,20 @@ public class WxMenuButton implements Serializable { public void setMediaId(String mediaId) { this.mediaId = mediaId; } + + public String getAppiId() { + return appiId; + } + + public void setAppiId(String appiId) { + this.appiId = appiId; + } + + public String getPagePath() { + return pagePath; + } + + public void setPagePath(String pagePath) { + this.pagePath = pagePath; + } } From 60c82e92aeec12f1c235badeaba3bbc1ced2ccef Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 28 Mar 2017 23:18:34 +0800 Subject: [PATCH 49/63] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=B8=AD=E6=96=87=E7=9A=84=E5=B8=B8=E9=87=8F=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/common/api/WxConsts.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) 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 1ecd9f65..7baded48 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 @@ -55,15 +55,15 @@ public class WxConsts { /////////////////////// public static final String MASS_ST_SUCCESS = "send success"; public static final String MASS_ST_FAIL = "send fail"; - public static final String MASS_ST_涉嫌广告 = "err(10001)"; - public static final String MASS_ST_涉嫌政治 = "err(20001)"; - public static final String MASS_ST_涉嫌社会 = "err(20004)"; - public static final String MASS_ST_涉嫌色情 = "err(20002)"; - public static final String MASS_ST_涉嫌违法犯罪 = "err(20006)"; - public static final String MASS_ST_涉嫌欺诈 = "err(20008)"; - public static final String MASS_ST_涉嫌版权 = "err(20013)"; - public static final String MASS_ST_涉嫌互推_互相宣传 = "err(22000)"; - public static final String MASS_ST_涉嫌其他 = "err(21000)"; + public static final String MASS_ST_10001 = "err(10001)"; + public static final String MASS_ST_20001 = "err(20001)"; + public static final String MASS_ST_20004 = "err(20004)"; + public static final String MASS_ST_20002 = "err(20002)"; + public static final String MASS_ST_20006 = "err(20006)"; + public static final String MASS_ST_20008 = "err(20008)"; + public static final String MASS_ST_20013 = "err(20013)"; + public static final String MASS_ST_22000 = "err(22000)"; + public static final String MASS_ST_21000 = "err(21000)"; /** * 群发反馈消息代码所对应的文字描述 @@ -210,14 +210,14 @@ public class WxConsts { static { MASS_ST_2_DESC.put(MASS_ST_SUCCESS, "发送成功"); MASS_ST_2_DESC.put(MASS_ST_FAIL, "发送失败"); - MASS_ST_2_DESC.put(MASS_ST_涉嫌广告, "涉嫌广告"); - MASS_ST_2_DESC.put(MASS_ST_涉嫌政治, "涉嫌政治"); - MASS_ST_2_DESC.put(MASS_ST_涉嫌社会, "涉嫌社会"); - MASS_ST_2_DESC.put(MASS_ST_涉嫌色情, "涉嫌色情"); - MASS_ST_2_DESC.put(MASS_ST_涉嫌违法犯罪, "涉嫌违法犯罪"); - MASS_ST_2_DESC.put(MASS_ST_涉嫌欺诈, "涉嫌欺诈"); - MASS_ST_2_DESC.put(MASS_ST_涉嫌版权, "涉嫌版权"); - MASS_ST_2_DESC.put(MASS_ST_涉嫌互推_互相宣传, "涉嫌互推_互相宣传"); - MASS_ST_2_DESC.put(MASS_ST_涉嫌其他, "涉嫌其他"); + MASS_ST_2_DESC.put(MASS_ST_10001, "涉嫌广告"); + MASS_ST_2_DESC.put(MASS_ST_20001, "涉嫌政治"); + MASS_ST_2_DESC.put(MASS_ST_20004, "涉嫌社会"); + MASS_ST_2_DESC.put(MASS_ST_20002, "涉嫌色情"); + MASS_ST_2_DESC.put(MASS_ST_20006, "涉嫌违法犯罪"); + MASS_ST_2_DESC.put(MASS_ST_20008, "涉嫌欺诈"); + MASS_ST_2_DESC.put(MASS_ST_20013, "涉嫌版权"); + MASS_ST_2_DESC.put(MASS_ST_22000, "涉嫌互推_互相宣传"); + MASS_ST_2_DESC.put(MASS_ST_21000, "涉嫌其他"); } } From a4daf56dad5b978129f00d3eaec968240a38b8e7 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 28 Mar 2017 23:22:34 +0800 Subject: [PATCH 50/63] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E5=8A=A0=E5=85=A5=E5=AF=B9=E5=B0=8F=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81=20#170?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/me/chanjar/weixin/common/api/WxConsts.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) 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 7baded48..435ba8e0 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 @@ -136,19 +136,23 @@ 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 BUTTON_CLICK = "click"; /////////////////////// // 自定义菜单的按钮类型 /////////////////////// + /** + * 点击推事件 + */ + public static final String BUTTON_CLICK = "click"; /** * 跳转URL */ public static final String BUTTON_VIEW = "view"; + /** + * 跳转到小程序 + */ + public static final String BUTTON_MINIPROGRAM = "miniprogram"; /** * 扫码推事件 */ @@ -181,6 +185,7 @@ public class WxConsts { * 跳转图文消息URL */ public static final String BUTTON_VIEW_LIMITED = "view_limited"; + /** * 不弹出授权页面,直接跳转,只能获取用户openid */ From aa49f96bf1b0d87263273fd86e50d0b328f1b685 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Wed, 29 Mar 2017 11:41:25 +0800 Subject: [PATCH 51/63] adjust pom --- pom.xml | 11 ++++++----- weixin-java-common/pom.xml | 5 ----- weixin-java-cp/pom.xml | 10 ++++------ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index e83c2c1b..7546f332 100644 --- a/pom.xml +++ b/pom.xml @@ -115,6 +115,11 @@ slf4j-api ${slf4j.version} + + com.thoughtworks.xstream + xstream + 1.4.9 + ch.qos.logback logback-classic @@ -154,6 +159,7 @@ com.google.guava guava + ${guava.version} @@ -189,11 +195,6 @@ ${jetty.version} test - - com.google.guava - guava - ${guava.version} - redis.clients jedis diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 24b71dcc..63ea95e6 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -14,11 +14,6 @@ 微信公众号、企业号Java SDK Common - - com.thoughtworks.xstream - xstream - 1.4.7 - org.testng testng diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 2a6ea6f2..c6500c49 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -19,6 +19,10 @@ weixin-java-common ${project.version} + + redis.clients + jedis + org.testng testng @@ -44,12 +48,6 @@ jetty-servlet test - - redis.clients - jedis - 2.9.0 - true - From 490ba068c592a8519cb67ef485dc9bf6c594bb9e Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 30 Mar 2017 17:59:25 +0800 Subject: [PATCH 52/63] =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=AF=B9=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20#172?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mp/bean/template/WxMpTemplateMessage.java | 71 +++++++++++++++++++ .../json/WxMpTemplateMessageGsonAdapter.java | 7 ++ .../template/WxMpTemplateMessageTest.java | 31 ++++++++ 3 files changed, 109 insertions(+) create mode 100644 weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessageTest.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java index df8e708d..f70090ef 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java @@ -12,11 +12,38 @@ import java.util.List; public class WxMpTemplateMessage implements Serializable { private static final long serialVersionUID = 5063374783759519418L; + /** + * 接收者openid + */ private String toUser; + + /** + * 模板ID + */ private String templateId; + + /** + *
    +   * 跳小程序所需数据,不需跳小程序可不用传该数据
    +   * url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。
    +   * 开发者可根据实际需要选择其中一种跳转方式即可。当用户的微信客户端版本不支持跳小程序时,将会跳转至url。
    +   * 
    + */ private String url; + /** + * 模板跳转链接 + * @see #url + */ + private MiniProgram miniProgram; + + /** + * 模板数据 + */ private List data = new ArrayList<>(); + public WxMpTemplateMessage() { + } + public String getToUser() { return this.toUser; } @@ -53,6 +80,14 @@ public class WxMpTemplateMessage implements Serializable { this.data.add(datum); } + public MiniProgram getMiniProgram() { + return this.miniProgram; + } + + public void setMiniProgram(MiniProgram miniProgram) { + this.miniProgram = miniProgram; + } + public String toJson() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); } @@ -61,11 +96,41 @@ public class WxMpTemplateMessage implements Serializable { return new WxMpTemplateMessageBuilder(); } + public static class MiniProgram { + private String appid; + private String pagePath; + + public MiniProgram() { + } + + public MiniProgram(String appid, String pagePath) { + this.appid = appid; + this.pagePath = pagePath; + } + + public String getAppid() { + return this.appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getPagePath() { + return this.pagePath; + } + + public void setPagePath(String pagePath) { + this.pagePath = pagePath; + } + } + public static class WxMpTemplateMessageBuilder { private String toUser; private String templateId; private String url; private List data = new ArrayList<>(); + private MiniProgram miniProgram; public WxMpTemplateMessageBuilder toUser(String toUser) { this.toUser = toUser; @@ -95,12 +160,18 @@ public class WxMpTemplateMessage implements Serializable { return this; } + public WxMpTemplateMessageBuilder miniProgram(MiniProgram miniProgram) { + this.miniProgram = miniProgram; + return this; + } + public WxMpTemplateMessage build() { WxMpTemplateMessage m = new WxMpTemplateMessage(); m.toUser = this.toUser; m.templateId = this.templateId; m.url = this.url; m.data = this.data; + m.miniProgram = this.miniProgram; return m; } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java index be6f5dc7..d6e0ff1d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java @@ -28,6 +28,13 @@ public class WxMpTemplateMessageGsonAdapter implements JsonSerializer + * Created by Binary Wang on 2017-3-30. + * @author binarywang(Binary Wang) + * + */ +public class WxMpTemplateMessageTest { + @Test + public void testToJson() throws Exception { + WxMpTemplateMessage tm = WxMpTemplateMessage.builder() + .toUser("OPENID") + .templateId("ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY") + .miniProgram(new WxMpTemplateMessage.MiniProgram("xiaochengxuappid12345", "index?foo=bar")) + .url("http://weixin.qq.com/download") + .build(); + + tm.addWxMpTemplateData( + new WxMpTemplateData("first", "haahah", "#FF00FF")); + tm.addWxMpTemplateData( + new WxMpTemplateData("remark", "heihei", "#FF00FF")); + + assertEquals(tm.toJson(), "{\"touser\":\"OPENID\",\"template_id\":\"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY\",\"url\":\"http://weixin.qq.com/download\",\"miniprogram\":{\"appid\":\"xiaochengxuappid12345\",\"pagepath\":\"index?foo=bar\"},\"data\":{\"first\":{\"value\":\"haahah\",\"color\":\"#FF00FF\"},\"remark\":{\"value\":\"heihei\",\"color\":\"#FF00FF\"}}}"); + } + +} From e45a1cabe57ce28fbe961779ba7a8cf6b76ee240 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 30 Mar 2017 18:06:16 +0800 Subject: [PATCH 53/63] =?UTF-8?q?=E5=8F=91=E5=B8=83=E4=B8=B4=E6=97=B6?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E6=9C=AC2.5.6.BETA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 7546f332..967d5876 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.github.binarywang weixin-java-parent - 2.5.5.BETA + 2.5.6.BETA pom WeiXin Java Tools - Parent 微信公众号、企业号上级POM diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 63ea95e6..04d351c9 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.5.BETA + 2.5.6.BETA weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index c6500c49..8bb55b2a 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.5.BETA + 2.5.6.BETA weixin-java-cp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 32f04f25..1c7e7648 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang weixin-java-parent - 2.5.5.BETA + 2.5.6.BETA weixin-java-mp WeiXin Java Tools - MP diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 79abe83b..79cba959 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ weixin-java-parent com.github.binarywang - 2.5.5.BETA + 2.5.6.BETA 4.0.0 From 7ce46ed0a253096c915981c9820cacf2a3964e10 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 30 Mar 2017 18:28:09 +0800 Subject: [PATCH 54/63] fix a typo --- .../chanjar/weixin/common/bean/menu/WxMenuButton.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java index aecbcfd0..aa6ea4cf 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java @@ -57,7 +57,7 @@ public class WxMenuButton implements Serializable { * */ @SerializedName("appid") - private String appiId; + private String appId; /** *
    @@ -124,12 +124,12 @@ public class WxMenuButton implements Serializable {
         this.mediaId = mediaId;
       }
     
    -  public String getAppiId() {
    -    return appiId;
    +  public String getAppId() {
    +    return appId;
       }
     
    -  public void setAppiId(String appiId) {
    -    this.appiId = appiId;
    +  public void setAppId(String appId) {
    +    this.appId = appId;
       }
     
       public String getPagePath() {
    
    From 89870bbb92e8f72762a54d50fc8c64827af3cb26 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Thu, 30 Mar 2017 19:30:36 +0800
    Subject: [PATCH 55/63] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E8=8F=9C?=
     =?UTF-8?q?=E5=8D=95=E5=8A=A0=E5=85=A5=E5=AF=B9=E5=B0=8F=E7=A8=8B=E5=BA=8F?=
     =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81=20#170?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../common/util/json/WxMenuGsonAdapter.java   |  4 +
     .../mp/api/impl/WxMpMenuServiceImplTest.java  | 75 +++++++++----------
     2 files changed, 40 insertions(+), 39 deletions(-)
    
    diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMenuGsonAdapter.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMenuGsonAdapter.java
    index 578aa41c..526b5f29 100644
    --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMenuGsonAdapter.java
    +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMenuGsonAdapter.java
    @@ -46,6 +46,8 @@ public class WxMenuGsonAdapter implements JsonSerializer, JsonDeserializ
         buttonJson.addProperty("key", button.getKey());
         buttonJson.addProperty("url", button.getUrl());
         buttonJson.addProperty("media_id", button.getMediaId());
    +    buttonJson.addProperty("appid", button.getAppId());
    +    buttonJson.addProperty("pagepath", button.getPagePath());
         if (button.getSubButtons() != null && button.getSubButtons().size() > 0) {
           JsonArray buttonArray = new JsonArray();
           for (WxMenuButton sub_button : button.getSubButtons()) {
    @@ -114,6 +116,8 @@ public class WxMenuGsonAdapter implements JsonSerializer, JsonDeserializ
         button.setUrl(GsonHelper.getString(json, "url"));
         button.setType(GsonHelper.getString(json, "type"));
         button.setMediaId(GsonHelper.getString(json, "media_id"));
    +    button.setAppId(GsonHelper.getString(json, "appid"));
    +    button.setPagePath(GsonHelper.getString(json, "pagepath"));
         return button;
       }
     
    diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java
    index 51b80e36..dac37f26 100644
    --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java
    +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java
    @@ -94,42 +94,37 @@ public class WxMpMenuServiceImplTest {
     
       @Test
       public void testCreateMenu_by_json() throws WxErrorException {
    -    String a = "{\n"
    -      + "  \"menu\": {\n"
    -      + "    \"button\": [\n"
    -      + "      {\n"
    -      + "        \"type\": \"click\",\n"
    -      + "        \"name\": \"今日歌曲\",\n"
    -      + "        \"key\": \"V1001_TODAY_MUSIC\"\n"
    -      + "      },\n"
    -      + "      {\n"
    -      + "        \"type\": \"click\",\n"
    -      + "        \"name\": \"歌手简介\",\n"
    -      + "        \"key\": \"V1001_TODAY_SINGER\"\n"
    -      + "      },\n"
    -      + "      {\n"
    -      + "        \"name\": \"菜单\",\n"
    -      + "        \"sub_button\": [\n"
    -      + "          {\n"
    -      + "            \"type\": \"view\",\n"
    -      + "            \"name\": \"搜索\",\n"
    -      + "            \"url\": \"http://www.soso.com/\"\n"
    -      + "          },\n"
    -      + "          {\n"
    -      + "            \"type\": \"view\",\n"
    -      + "            \"name\": \"视频\",\n"
    -      + "            \"url\": \"http://v.qq.com/\"\n"
    -      + "          },\n"
    -      + "          {\n"
    -      + "            \"type\": \"click\",\n"
    -      + "            \"name\": \"赞一下我们\",\n"
    -      + "            \"key\": \"V1001_GOOD\"\n"
    -      + "          }\n"
    -      + "        ]\n"
    -      + "      }\n"
    -      + "    ]\n"
    -      + "  }\n"
    -      + "}";
    +    String a = "{\n" +
    +      "  \"button\": [\n" +
    +      "    {\n" +
    +      "      \"type\": \"click\",\n" +
    +      "      \"name\": \"今日歌曲\",\n" +
    +      "      \"key\": \"V1001_TODAY_MUSIC\"\n" +
    +      "    },\n" +
    +      "    {\n" +
    +      "      \"name\": \"菜单\",\n" +
    +      "      \"sub_button\": [\n" +
    +      "        {\n" +
    +      "          \"type\": \"view\",\n" +
    +      "          \"name\": \"搜索\",\n" +
    +      "          \"url\": \"http://www.soso.com/\"\n" +
    +      "        },\n" +
    +      "        {\n" +
    +      "          \"type\": \"miniprogram\",\n" +
    +      "          \"name\": \"wxa\",\n" +
    +      "          \"url\": \"http://mp.weixin.qq.com\",\n" +
    +      "          \"appid\": \"wx286b93c14bbf93aa\",\n" +
    +      "          \"pagepath\": \"pages/lunar/index.html\"\n" +
    +      "        },\n" +
    +      "        {\n" +
    +      "          \"type\": \"click\",\n" +
    +      "          \"name\": \"赞一下我们\",\n" +
    +      "          \"key\": \"V1001_GOOD\"\n" +
    +      "        }\n" +
    +      "      ]\n" +
    +      "    }\n" +
    +      "  ]\n" +
    +      "}";
     
         WxMenu menu = WxMenu.fromJson(a);
         System.out.println(menu.toJson());
    @@ -157,9 +152,11 @@ public class WxMpMenuServiceImplTest {
         button1.setKey("V1001_TODAY_MUSIC");
     
         WxMenuButton button2 = new WxMenuButton();
    -    button2.setType(WxConsts.BUTTON_CLICK);
    -    button2.setName("歌手简介");
    -    button2.setKey("V1001_TODAY_SINGER");
    +    button2.setType(WxConsts.BUTTON_MINIPROGRAM);
    +    button2.setName("小程序");
    +    button2.setAppId("wx286b93c14bbf93aa");
    +    button2.setPagePath("pages/lunar/index.html");
    +    button2.setUrl("http://mp.weixin.qq.com");
     
         WxMenuButton button3 = new WxMenuButton();
         button3.setName("菜单");
    
    From 66f04c48e0a04ea8068128f5f23039c40a4486b7 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Fri, 31 Mar 2017 14:16:09 +0800
    Subject: [PATCH 56/63] =?UTF-8?q?=E5=8F=91=E5=B8=83=E4=B8=B4=E6=97=B6?=
     =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E6=9C=AC2.5.7.BETA?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     pom.xml                    | 2 +-
     weixin-java-common/pom.xml | 2 +-
     weixin-java-cp/pom.xml     | 2 +-
     weixin-java-mp/pom.xml     | 2 +-
     weixin-java-pay/pom.xml    | 2 +-
     5 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/pom.xml b/pom.xml
    index 967d5876..d80ea515 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -5,7 +5,7 @@
       4.0.0
       com.github.binarywang
       weixin-java-parent
    -  2.5.6.BETA
    +  2.5.7.BETA
       pom
       WeiXin Java Tools - Parent
       微信公众号、企业号上级POM
    diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
    index 04d351c9..dafd4e9c 100644
    --- a/weixin-java-common/pom.xml
    +++ b/weixin-java-common/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.6.BETA
    +    2.5.7.BETA
       
     
       weixin-java-common
    diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
    index 8bb55b2a..7bb40a5e 100644
    --- a/weixin-java-cp/pom.xml
    +++ b/weixin-java-cp/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.6.BETA
    +    2.5.7.BETA
       
     
       weixin-java-cp
    diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
    index 1c7e7648..830d3b53 100644
    --- a/weixin-java-mp/pom.xml
    +++ b/weixin-java-mp/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.6.BETA
    +    2.5.7.BETA
       
       weixin-java-mp
       WeiXin Java Tools - MP
    diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
    index 79cba959..97ff279c 100644
    --- a/weixin-java-pay/pom.xml
    +++ b/weixin-java-pay/pom.xml
    @@ -5,7 +5,7 @@
       
         weixin-java-parent
         com.github.binarywang
    -    2.5.6.BETA
    +    2.5.7.BETA
       
       4.0.0
     
    
    From bc0fbf76a5dcf75312ea4149c0b15c2764334279 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Mon, 10 Apr 2017 10:24:32 +0800
    Subject: [PATCH 57/63] =?UTF-8?q?=E8=A7=84=E8=8C=83=E7=BB=9F=E4=B8=80openi?=
     =?UTF-8?q?d=E7=9A=84=E9=97=AE=E9=A2=98=20#177?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../weixin/mp/bean/result/WxMpUserList.java   | 22 +++++++++----------
     .../mp/util/json/WxUserListGsonAdapter.java   |  4 ++--
     .../mp/api/impl/WxMpUserServiceImplTest.java  |  2 +-
     3 files changed, 14 insertions(+), 14 deletions(-)
    
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java
    index 94b51f6c..210abc05 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java
    +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java
    @@ -14,8 +14,8 @@ public class WxMpUserList {
     
       protected int total = -1;
       protected int count = -1;
    -  protected List openIds = new ArrayList<>();
    -  protected String nextOpenId;
    +  protected List openids = new ArrayList<>();
    +  protected String nextOpenid;
       public int getTotal() {
         return this.total;
       }
    @@ -28,19 +28,19 @@ public class WxMpUserList {
       public void setCount(int count) {
         this.count = count;
       }
    -  public List getOpenIds() {
    -    return this.openIds;
    +  public List getOpenids() {
    +    return this.openids;
       }
    -  public void setOpenIds(List openIds) {
    -    this.openIds = openIds;
    +  public void setOpenids(List openids) {
    +    this.openids = openids;
       }
    -  public String getNextOpenId() {
    -    return this.nextOpenId;
    +  public String getNextOpenid() {
    +    return this.nextOpenid;
       }
    -  public void setNextOpenId(String nextOpenId) {
    -    this.nextOpenId = nextOpenId;
    +  public void setNextOpenid(String nextOpenid) {
    +    this.nextOpenid = nextOpenid;
       }
    -  
    +
       public static WxMpUserList fromJson(String json) {
         return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpUserList.class);
       }
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java
    index 1c06d074..cd39fb9f 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java
    +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java
    @@ -22,11 +22,11 @@ public class WxUserListGsonAdapter implements JsonDeserializer {
         WxMpUserList wxMpUserList = new WxMpUserList();
         wxMpUserList.setTotal(GsonHelper.getInteger(o, "total"));
         wxMpUserList.setCount(GsonHelper.getInteger(o, "count"));
    -    wxMpUserList.setNextOpenId(GsonHelper.getString(o, "next_openid"));
    +    wxMpUserList.setNextOpenid(GsonHelper.getString(o, "next_openid"));
         if (o.get("data") != null && !o.get("data").isJsonNull() && !o.get("data").getAsJsonObject().get("openid").isJsonNull()) {
           JsonArray data = o.get("data").getAsJsonObject().get("openid").getAsJsonArray();
           for (int i = 0; i < data.size(); i++) {
    -        wxMpUserList.getOpenIds().add(GsonHelper.getAsString(data.get(i)));
    +        wxMpUserList.getOpenids().add(GsonHelper.getAsString(data.get(i)));
           }
         }
         return wxMpUserList;
    diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java
    index 09ba9e99..27f11791 100644
    --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java
    +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java
    @@ -70,7 +70,7 @@ public class WxMpUserServiceImplTest {
         Assert.assertNotNull(wxMpUserList);
         Assert.assertFalse(wxMpUserList.getCount() == -1);
         Assert.assertFalse(wxMpUserList.getTotal() == -1);
    -    Assert.assertFalse(wxMpUserList.getOpenIds().size() == -1);
    +    Assert.assertFalse(wxMpUserList.getOpenids().size() == -1);
         System.out.println(wxMpUserList);
       }
     
    
    From 89470660ef1fa76a88ae522024a40565ba933685 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Mon, 10 Apr 2017 10:53:58 +0800
    Subject: [PATCH 58/63] =?UTF-8?q?WxMpUserList=E9=87=8Ctotal=E7=B1=BB?=
     =?UTF-8?q?=E5=9E=8B=E6=94=B9=E4=B8=BAlong=20#176?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java | 6 +++---
     .../chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java  | 2 +-
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java
    index 210abc05..87ce18cd 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java
    +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java
    @@ -12,14 +12,14 @@ import java.util.List;
      */
     public class WxMpUserList {
     
    -  protected int total = -1;
    +  protected long total = -1;
       protected int count = -1;
       protected List openids = new ArrayList<>();
       protected String nextOpenid;
    -  public int getTotal() {
    +  public long getTotal() {
         return this.total;
       }
    -  public void setTotal(int total) {
    +  public void setTotal(long total) {
         this.total = total;
       }
       public int getCount() {
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java
    index cd39fb9f..e150a63f 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java
    +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java
    @@ -20,7 +20,7 @@ public class WxUserListGsonAdapter implements JsonDeserializer {
       public WxMpUserList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
         JsonObject o = json.getAsJsonObject();
         WxMpUserList wxMpUserList = new WxMpUserList();
    -    wxMpUserList.setTotal(GsonHelper.getInteger(o, "total"));
    +    wxMpUserList.setTotal(GsonHelper.getLong(o, "total"));
         wxMpUserList.setCount(GsonHelper.getInteger(o, "count"));
         wxMpUserList.setNextOpenid(GsonHelper.getString(o, "next_openid"));
         if (o.get("data") != null && !o.get("data").isJsonNull() && !o.get("data").getAsJsonObject().get("openid").isJsonNull()) {
    
    From 0ff63ba3cbcea79f2fe524140f03486699f49782 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Mon, 10 Apr 2017 11:14:20 +0800
    Subject: [PATCH 59/63] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=A8=E6=88=B7?=
     =?UTF-8?q?=E6=A0=87=E7=AD=BEid=E7=B1=BB=E5=9E=8B=E4=B8=8D=E4=B8=80?=
     =?UTF-8?q?=E8=87=B4=E7=9A=84=E9=97=AE=E9=A2=98=20#175?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../weixin/common/util/json/GsonHelper.java    | 18 ++++++++++++++++--
     .../weixin/mp/bean/result/WxMpUser.java        |  6 +++---
     .../mp/util/json/WxMpUserGsonAdapter.java      |  2 +-
     3 files changed, 20 insertions(+), 6 deletions(-)
    
    diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java
    index ec30c6b0..6166da9e 100644
    --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java
    +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java
    @@ -9,13 +9,13 @@
     package me.chanjar.weixin.common.util.json;
     
     
    -import java.util.List;
    -
     import com.google.common.collect.Lists;
     import com.google.gson.JsonArray;
     import com.google.gson.JsonElement;
     import com.google.gson.JsonObject;
     
    +import java.util.List;
    +
     
     public class GsonHelper {
     
    @@ -130,6 +130,20 @@ public class GsonHelper {
         return result.toArray(new Integer[0]);
       }
     
    +  public static Long[] getLongArray(JsonObject o, String string) {
    +    JsonArray jsonArray = getAsJsonArray(o.getAsJsonArray(string));
    +    if (jsonArray == null) {
    +      return null;
    +    }
    +
    +    List result = Lists.newArrayList();
    +    for (int i = 0; i < jsonArray.size(); i++) {
    +      result.add(jsonArray.get(i).getAsLong());
    +    }
    +
    +    return result.toArray(new Long[0]);
    +  }
    +
       public static JsonArray getAsJsonArray(JsonElement element) {
         return element == null ? null : element.getAsJsonArray();
       }
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
    index 8d7090fd..7131de5c 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
    +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
    @@ -32,7 +32,7 @@ public class WxMpUser implements Serializable {
       private Integer sexId;
       private String remark;
       private Integer groupId;
    -  private Integer[] tagIds;
    +  private Long[] tagIds;
     
       public Boolean getSubscribe() {
         return this.subscribe;
    @@ -150,11 +150,11 @@ public class WxMpUser implements Serializable {
         this.groupId = groupId;
       }
     
    -  public Integer[] getTagIds() {
    +  public Long[] getTagIds() {
         return this.tagIds;
       }
     
    -  public void setTagIds(Integer[] tagIds) {
    +  public void setTagIds(Long[] tagIds) {
         this.tagIds = tagIds;
       }
     
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserGsonAdapter.java
    index f351a79d..e47d405f 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserGsonAdapter.java
    +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserGsonAdapter.java
    @@ -36,7 +36,7 @@ public class WxMpUserGsonAdapter implements JsonDeserializer {
         Integer sexId = GsonHelper.getInteger(o, "sex");
         wxMpUser.setRemark(GsonHelper.getString(o, "remark"));
         wxMpUser.setGroupId(GsonHelper.getInteger(o, "groupid"));
    -    wxMpUser.setTagIds(GsonHelper.getIntArray(o, "tagid_list"));
    +    wxMpUser.setTagIds(GsonHelper.getLongArray(o, "tagid_list"));
         wxMpUser.setSexId(sexId);
         if (new Integer(1).equals(sexId)) {
           wxMpUser.setSex("男");
    
    From 68fbb2ee3e63209195df471470de6ac7774fce78 Mon Sep 17 00:00:00 2001
    From: flying 
    Date: Wed, 12 Apr 2017 16:42:43 +0800
    Subject: [PATCH 60/63] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9F=BA=E4=BA=8ERedis?=
     =?UTF-8?q?=E7=9A=84=E5=BE=AE=E4=BF=A1=E9=85=8D=E7=BD=AE=E7=9A=84bug?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../mp/api/WxMpInRedisConfigStorage.java      | 247 +-----------------
     1 file changed, 14 insertions(+), 233 deletions(-)
    
    diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java
    index 89648268..b2bb9b4e 100644
    --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java
    +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java
    @@ -1,21 +1,14 @@
     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 redis.clients.jedis.Jedis;
     
    -import javax.net.ssl.SSLContext;
    -import java.io.File;
    -import java.util.concurrent.locks.Lock;
    -import java.util.concurrent.locks.ReentrantLock;
    -
     /**
      * 基于Redis的微信配置provider
      *
      * @author lly835
      */
    -public class WxMpInRedisConfigStorage implements WxMpConfigStorage {
    +@SuppressWarnings("hiding")
    +public class WxMpInRedisConfigStorage extends WxMpInMemoryConfigStorage {
     
       private final static String ACCESS_TOKEN_KEY = "wechat_access_token_";
     
    @@ -23,43 +16,6 @@ public class WxMpInRedisConfigStorage implements WxMpConfigStorage {
     
       private final static String CARDAPI_TICKET_KEY = "wechat_cardapi_ticket_";
     
    -  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;
    -  protected volatile long expiresTime;
    -
    -  protected volatile String oauth2redirectUri;
    -
    -  protected volatile String httpProxyHost;
    -  protected volatile int httpProxyPort;
    -  protected volatile String httpProxyUsername;
    -  protected volatile String httpProxyPassword;
    -
    -  protected volatile String jsapiTicket;
    -  protected volatile long jsapiTicketExpiresTime;
    -
    -  protected volatile String cardApiTicket;
    -  protected volatile long cardApiTicketExpiresTime;
    -
    -  protected Lock accessTokenLock = new ReentrantLock();
    -  protected Lock jsapiTicketLock = new ReentrantLock();
    -  protected Lock cardApiTicketLock = new ReentrantLock();
    -
    -  /**
    -   * 临时文件目录
    -   */
    -  protected volatile File tmpDirFile;
    -
    -  protected volatile SSLContext sslContext;
    -
    -  protected volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
    -
       protected Jedis jedis;
     
       @Override
    @@ -67,46 +23,25 @@ public class WxMpInRedisConfigStorage implements WxMpConfigStorage {
         return jedis.get(ACCESS_TOKEN_KEY.concat(appId));
       }
     
    -  @Override
    -  public Lock getAccessTokenLock() {
    -    return this.accessTokenLock;
    -  }
    -
       @Override
       public boolean isAccessTokenExpired() {
           return getAccessToken() == null ? true : false;
       }
     
    -  @Override
    -  public synchronized void updateAccessToken(WxAccessToken accessToken) {
    -    updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
    -  }
    -
    -  @Override
    +@Override
       public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
    -    this.accessToken = accessToken;
    -    this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
         jedis.set(ACCESS_TOKEN_KEY.concat(appId), accessToken);
         jedis.expire(ACCESS_TOKEN_KEY.concat(appId), expiresInSeconds - 200);
       }
     
       @Override
       public void expireAccessToken() {
    -    this.expiresTime = 0;
    +    jedis.expire(ACCESS_TOKEN_KEY.concat(appId), 0);
       }
     
       @Override
       public String getJsapiTicket() {
    -    return this.jsapiTicket;
    -  }
    -
    -  public void setJsapiTicket(String jsapiTicket) {
    -    this.jsapiTicket = jsapiTicket;
    -  }
    -
    -  @Override
    -  public Lock getJsapiTicketLock() {
    -    return this.jsapiTicketLock;
    +    return jedis.get(JSAPI_TICKET_KEY.concat(appId));
       }
     
       @Override
    @@ -116,16 +51,13 @@ public class WxMpInRedisConfigStorage implements WxMpConfigStorage {
     
       @Override
       public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
    -    this.jsapiTicket = jsapiTicket;
    -    // 预留200秒的时间
    -    this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
    -    jedis.set(JSAPI_TICKET_KEY.concat(appId), accessToken);
    +    jedis.set(JSAPI_TICKET_KEY.concat(appId), jsapiTicket);
         jedis.expire(JSAPI_TICKET_KEY.concat(appId), expiresInSeconds - 200);
       }
     
       @Override
       public void expireJsapiTicket() {
    -    this.jsapiTicketExpiresTime = 0;
    +    jedis.expire(JSAPI_TICKET_KEY.concat(appId), 0);
       }
     
       /**
    @@ -133,177 +65,26 @@ public class WxMpInRedisConfigStorage implements WxMpConfigStorage {
        */
       @Override
       public String getCardApiTicket() {
    -    return this.cardApiTicket;
    -  }
    -
    -  @Override
    -  public Lock getCardApiTicketLock() {
    -    return this.cardApiTicketLock;
    +    return jedis.get(CARDAPI_TICKET_KEY.concat(appId));
       }
     
       @Override
       public boolean isCardApiTicketExpired() {
    -    return System.currentTimeMillis() > this.cardApiTicketExpiresTime;
    +    return getCardApiTicket() == null ? true : false;
       }
     
       @Override
       public synchronized void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
    -    this.cardApiTicket = cardApiTicket;
    -    // 预留200秒的时间
    -    this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
    -    jedis.set(CARDAPI_TICKET_KEY.concat(appId), accessToken);
    +    jedis.set(CARDAPI_TICKET_KEY.concat(appId), cardApiTicket);
         jedis.expire(CARDAPI_TICKET_KEY.concat(appId), expiresInSeconds - 200);
       }
     
       @Override
       public void expireCardApiTicket() {
    -    this.cardApiTicketExpiresTime = 0;
    -  }
    -
    -  @Override
    -  public String getAppId() {
    -    return this.appId;
    -  }
    -
    -  public void setAppId(String appId) {
    -    this.appId = appId;
    -  }
    -
    -  @Override
    -  public String getSecret() {
    -    return this.secret;
    -  }
    -
    -  public void setSecret(String secret) {
    -    this.secret = secret;
    -  }
    -
    -  @Override
    -  public String getToken() {
    -    return this.token;
    -  }
    -
    -  public void setToken(String token) {
    -    this.token = token;
    -  }
    -
    -  @Override
    -  public long getExpiresTime() {
    -    return this.expiresTime;
    -  }
    -
    -  public void setExpiresTime(long expiresTime) {
    -    this.expiresTime = expiresTime;
    -  }
    -
    -  @Override
    -  public String getAesKey() {
    -    return this.aesKey;
    -  }
    -
    -  public void setAesKey(String aesKey) {
    -    this.aesKey = aesKey;
    -  }
    -
    -  @Override
    -  public String getOauth2redirectUri() {
    -    return this.oauth2redirectUri;
    -  }
    -
    -  public void setOauth2redirectUri(String oauth2redirectUri) {
    -    this.oauth2redirectUri = oauth2redirectUri;
    -  }
    -
    -  @Override
    -  public String getHttpProxyHost() {
    -    return this.httpProxyHost;
    -  }
    -
    -  public void setHttpProxyHost(String httpProxyHost) {
    -    this.httpProxyHost = httpProxyHost;
    -  }
    -
    -  @Override
    -  public int getHttpProxyPort() {
    -    return this.httpProxyPort;
    -  }
    -
    -  public void setHttpProxyPort(int httpProxyPort) {
    -    this.httpProxyPort = httpProxyPort;
    -  }
    -
    -  @Override
    -  public String getHttpProxyUsername() {
    -    return this.httpProxyUsername;
    -  }
    -
    -  public void setHttpProxyUsername(String httpProxyUsername) {
    -    this.httpProxyUsername = httpProxyUsername;
    -  }
    -
    -  @Override
    -  public String getHttpProxyPassword() {
    -    return this.httpProxyPassword;
    -  }
    -
    -  public void setHttpProxyPassword(String httpProxyPassword) {
    -    this.httpProxyPassword = httpProxyPassword;
    -  }
    -
    -  @Override
    -  public String toString() {
    -    return ToStringUtils.toSimpleString(this);
    -  }
    -
    -  public void setPartnerId(String partnerId) {
    -    this.partnerId = partnerId;
    -  }
    -
    -  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 void setTradeType(String tradeType) {
    -    this.tradeType = tradeType;
    -  }
    -
    -  @Override
    -  public File getTmpDirFile() {
    -    return this.tmpDirFile;
    -  }
    -
    -  public void setTmpDirFile(File tmpDirFile) {
    -    this.tmpDirFile = tmpDirFile;
    -  }
    -
    -  @Override
    -  public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
    -    return this.apacheHttpClientBuilder;
    -  }
    -
    -  public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) {
    -    this.apacheHttpClientBuilder = apacheHttpClientBuilder;
    -  }
    -
    -  @Override
    -  public boolean autoRefreshToken() {
    -    return true;
    +    jedis.expire(CARDAPI_TICKET_KEY.concat(appId), 0);
       }
     
       public void setJedis(Jedis jedis) {
    -        this.jedis = jedis;
    -    }
    -}
    +    this.jedis = jedis;
    +  }
    +}
    \ No newline at end of file
    
    From da6cd44502fbd5c87c2ecc5d38ad66a7f5d2ec41 Mon Sep 17 00:00:00 2001
    From: flying 
    Date: Wed, 12 Apr 2017 18:27:58 +0800
    Subject: [PATCH 61/63] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=94=AF=E4=BB=98?=
     =?UTF-8?q?=E7=BB=93=E6=9E=9C=E9=80=9A=E7=9F=A5=E7=BC=BA=E5=A4=B1CDATA?=
     =?UTF-8?q?=E9=83=A8=E5=88=86=EF=BC=8C=E5=AF=BC=E8=87=B4=E5=BE=AE=E4=BF=A1?=
     =?UTF-8?q?=E9=87=8D=E5=A4=8D=E5=8F=91=E9=80=81=E9=80=9A=E7=9F=A5?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../binarywang/wxpay/bean/WxPayOrderNotifyResponse.java      | 5 +++++
     1 file changed, 5 insertions(+)
    
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyResponse.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyResponse.java
    index 7df76a95..9d960c08 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyResponse.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayOrderNotifyResponse.java
    @@ -2,7 +2,10 @@ package com.github.binarywang.wxpay.bean;
     
     import com.thoughtworks.xstream.XStream;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import com.thoughtworks.xstream.annotations.XStreamConverter;
     import com.thoughtworks.xstream.annotations.XStreamOmitField;
    +
    +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
     import me.chanjar.weixin.common.util.xml.XStreamInitializer;
     
     @XStreamAlias("xml")
    @@ -13,7 +16,9 @@ public class WxPayOrderNotifyResponse {
       private transient static final String SUCCESS = "SUCCESS";
     
       @XStreamAlias("return_code")
    +  @XStreamConverter(value = XStreamCDataConverter.class)
       private String returnCode;
    +  @XStreamConverter(value = XStreamCDataConverter.class)
       @XStreamAlias("return_msg")
       private String returnMsg;
     
    
    From c79f77c994f7ebd0e38dbb714409c74a2422e1f6 Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Thu, 13 Apr 2017 22:02:10 +0800
    Subject: [PATCH 62/63] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E7=89=88=E6=9C=AC?=
     =?UTF-8?q?=E5=8F=B7=E4=B8=BA2.6.0?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     build.gradle               |  3 +--
     pom.xml                    |  2 +-
     readme.md                  | 17 +++++++++--------
     weixin-java-common/pom.xml |  2 +-
     weixin-java-cp/pom.xml     |  2 +-
     weixin-java-mp/pom.xml     |  2 +-
     weixin-java-pay/pom.xml    |  2 +-
     7 files changed, 15 insertions(+), 15 deletions(-)
    
    diff --git a/build.gradle b/build.gradle
    index e572c391..23ec2c52 100644
    --- a/build.gradle
    +++ b/build.gradle
    @@ -2,7 +2,7 @@ allprojects  {
       apply plugin: 'maven'
     
       group = 'com.github.binarywang'
    -  version = '2.6.0-SNAPSHOT'
    +  version = '2.6.0'
     }
     
     subprojects {
    @@ -27,7 +27,6 @@ subprojects {
         compile group: 'commons-codec', name: 'commons-codec', version:'1.10'
         compile group: 'commons-io', name: 'commons-io', version:'2.5'
         compile group: 'org.apache.commons', name: 'commons-lang3', version:'3.4'
    -    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version:'2.8.0'
         compile group: 'redis.clients', name: 'jedis', version:'2.9.0'
         testCompile group: 'ch.qos.logback', name: 'logback-classic', version:'1.1.2'
       }
    diff --git a/pom.xml b/pom.xml
    index d80ea515..2447fd71 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -5,7 +5,7 @@
       4.0.0
       com.github.binarywang
       weixin-java-parent
    -  2.5.7.BETA
    +  2.6.0
       pom
       WeiXin Java Tools - Parent
       微信公众号、企业号上级POM
    diff --git a/readme.md b/readme.md
    index e533f7da..5f10da8a 100644
    --- a/readme.md
    +++ b/readme.md
    @@ -6,14 +6,15 @@
     ### 注意事项:
     1. 声明: ***本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。***
     1. **新手请注意,本项目仅是一个开发工具包(即SDK),未提供Web实现,建议使用maven或gradle引用本项目即可使用本SDK提供的各种功能,详情可参考下文中提到的Demo项目或本项目中的部分单元测试代码;如果没有贡献代码的意愿,不建议下载项目的源码自行编译,因为如果想看源码使用maven也是可以下载源码的**;
    -1. 最新更新:**2017-2-12 发布[【2.5.0正式版】](https://github.com/Wechat-Group/weixin-java-tools/releases)**!
    +1. 最新更新:**2017-4-13 发布[【2.6.0正式版】](https://github.com/Wechat-Group/weixin-java-tools/releases)**!
     1. 开源中国网站的本项目介绍的首页链接地址:https://www.oschina.net/p/weixin-java-tools-new
     1. 自2.0.0版本以来,公众号的接口调整比较大,主要是为了解决主接口类过于庞大不方便管理的问题,将接口实现代码按模块进行拆分。
    +1. 自2.6.0版本开始,微信支付相关功能抽出独立为一个模块,详细使用方式请参考相关demo;
     1. SDK详细开发文档请查阅 [【Wiki】](https://github.com/wechat-group/weixin-java-tools/wiki),部分文档可能未能及时更新,如有发现,可以及时上报或者自行修改。***另外微信开发新手请务必阅读wiki首页的常见问题部分,可以少走很多弯路,节省不少时间。***
     1. 各个模块的Javadoc可以在线查看(有可能是最新的测试版本的,请注意观察版本号):[weixin-java-pay](https://binarywang.github.io/weixin-java-pay-javadoc/)、[weixin-java-mp](https://binarywang.github.io/weixin-java-mp-javadoc/)、[weixin-java-common](https://binarywang.github.io/weixin-java-common-javadoc/)、[weixin-java-cp](https://binarywang.github.io/weixin-java-cp-javadoc/)
     1. 本SDK要求的最低JDK版本是7,还在使用JDK6的用户请参考[【此项目】]( https://github.com/binarywang/weixin-java-tools-for-jdk6) ,而其他更早的JDK版本则需要自己改造实现。
     1. 如有新功能需求,发现BUG,或者由于微信官方接口调整导致的代码问题,可以直接在[【Issues】](https://github.com/Wechat-Group/weixin-java-tools/issues)页提出issue,便于讨论追踪问题;
    -1. 如果想贡献代码,请阅读[【代码贡献指南】](CONTRIBUTION.md);
    +1. 如果想贡献代码,请阅读[【代码贡献指南】](contribution.md);
     1. 捐助渠道已开通,如有意向请前往托管于码云的项目首页(具体地址见下文)的页面评论区上方,可以找到“捐助”按钮,非常感谢各位捐助的同学!
     
     ---------------------------------
    @@ -58,12 +59,12 @@ maven:
     
       com.github.binarywang
       weixin-java-pay
    -  2.5.7.BETA
    +  2.6.0
     
     ```
     gradle:
     ```groovy
    -compile 'com.github.binarywang:weixin-java-pay:2.5.7.BETA'
    +compile 'com.github.binarywang:weixin-java-pay:2.6.0'
     ```
     
     * 公众号(订阅号及服务号):
    @@ -73,12 +74,12 @@ maven:
     
       com.github.binarywang
       weixin-java-mp
    -  2.5.0
    +  2.6.0
     
     ```
     gradle:
     ```groovy
    -compile 'com.github.binarywang:weixin-java-mp:2.5.0'
    +compile 'com.github.binarywang:weixin-java-mp:2.6.0'
     ```
     
     * 企业号:
    @@ -88,10 +89,10 @@ maven:
     
       com.github.binarywang
       weixin-java-cp
    -  2.5.0
    +  2.6.0
     
     ```
     gradle:
     ```groovy
    -compile 'com.github.binarywang:weixin-java-cp:2.5.0'
    +compile 'com.github.binarywang:weixin-java-cp:2.6.0'
     ```
    diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
    index dafd4e9c..946c65c2 100644
    --- a/weixin-java-common/pom.xml
    +++ b/weixin-java-common/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.7.BETA
    +    2.6.0
       
     
       weixin-java-common
    diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
    index 7bb40a5e..88f83f0f 100644
    --- a/weixin-java-cp/pom.xml
    +++ b/weixin-java-cp/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.7.BETA
    +    2.6.0
       
     
       weixin-java-cp
    diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
    index 830d3b53..3f4bf649 100644
    --- a/weixin-java-mp/pom.xml
    +++ b/weixin-java-mp/pom.xml
    @@ -6,7 +6,7 @@
       
         com.github.binarywang
         weixin-java-parent
    -    2.5.7.BETA
    +    2.6.0
       
       weixin-java-mp
       WeiXin Java Tools - MP
    diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
    index 97ff279c..d0d50455 100644
    --- a/weixin-java-pay/pom.xml
    +++ b/weixin-java-pay/pom.xml
    @@ -5,7 +5,7 @@
       
         weixin-java-parent
         com.github.binarywang
    -    2.5.7.BETA
    +    2.6.0
       
       4.0.0
     
    
    From 7c32fccfffca67b7b4d8726ca4541bf8e3eb963b Mon Sep 17 00:00:00 2001
    From: Binary Wang 
    Date: Thu, 13 Apr 2017 22:05:10 +0800
    Subject: [PATCH 63/63] Rename CONTRIBUTION.md to contribution.md
    
    ---
     CONTRIBUTION.md => contribution.md | 0
     1 file changed, 0 insertions(+), 0 deletions(-)
     rename CONTRIBUTION.md => contribution.md (100%)
    
    diff --git a/CONTRIBUTION.md b/contribution.md
    similarity index 100%
    rename from CONTRIBUTION.md
    rename to contribution.md