diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c70396482..0b16b4779 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -28,7 +28,7 @@ $ git push
* 定期使用项目仓库内容更新自己仓库内容。
```bash
-$ git remote add upstream https://github.com/Wechat-Group/WxJava
+$ git remote add upstream https://github.com/binarywang/WxJava
$ git fetch upstream
$ git checkout develop
$ git rebase upstream/develop
diff --git a/pom.xml b/pom.xml
index c7c40521b..5c00e66a7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
pom
WxJava - Weixin/Wechat Java SDK
微信开发Java SDK
diff --git a/solon-plugins/pom.xml b/solon-plugins/pom.xml
index 9585e9617..8d14b4461 100644
--- a/solon-plugins/pom.xml
+++ b/solon-plugins/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
pom
wx-java-solon-plugins
@@ -14,7 +14,7 @@
WxJava 各个模块的 Solon Plugin
- 3.0.1
+ 3.2.0
diff --git a/solon-plugins/wx-java-channel-multi-solon-plugin/pom.xml b/solon-plugins/wx-java-channel-multi-solon-plugin/pom.xml
index a9b794a96..84c14a101 100644
--- a/solon-plugins/wx-java-channel-multi-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-channel-multi-solon-plugin/pom.xml
@@ -5,7 +5,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-channel-solon-plugin/README.md b/solon-plugins/wx-java-channel-solon-plugin/README.md
new file mode 100644
index 000000000..a7168a8ed
--- /dev/null
+++ b/solon-plugins/wx-java-channel-solon-plugin/README.md
@@ -0,0 +1,92 @@
+# wx-java-channel-solon-plugin
+
+## 快速开始
+1. 引入依赖
+ ```xml
+
+
+ com.github.binarywang
+ wx-java-channel-solon-plugin
+ ${version}
+
+
+
+
+ redis.clients
+ jedis
+ ${jedis.version}
+
+
+
+
+ org.redisson
+ redisson
+ ${redisson.version}
+
+
+ ```
+2. 添加配置(app.properties)
+ ```properties
+ # 视频号配置(必填)
+ ## 视频号小店的appId和secret
+ wx.channel.app-id=@appId
+ wx.channel.secret=@secret
+ # 视频号配置 选填
+ ## 设置视频号小店消息服务器配置的token
+ wx.channel.token=@token
+ ## 设置视频号小店消息服务器配置的EncodingAESKey
+ wx.channel.aes-key=
+ ## 支持JSON或者XML格式,默认JSON
+ wx.channel.msg-data-format=JSON
+ ## 是否使用稳定版 Access Token
+ wx.channel.use-stable-access-token=false
+
+
+ # ConfigStorage 配置(选填)
+ ## 配置类型: memory(默认), jedis, redisson, redis_template
+ wx.channel.config-storage.type=memory
+ ## 相关redis前缀配置: wx:channel(默认)
+ wx.channel.config-storage.key-prefix=wx:channel
+ wx.channel.config-storage.redis.host=127.0.0.1
+ wx.channel.config-storage.redis.port=6379
+ wx.channel.config-storage.redis.password=123456
+
+
+ # http 客户端配置(选填)
+ ## # http客户端类型: http_client(默认)
+ wx.channel.config-storage.http-client-type=http_client
+ wx.channel.config-storage.http-proxy-host=
+ wx.channel.config-storage.http-proxy-port=
+ wx.channel.config-storage.http-proxy-username=
+ wx.channel.config-storage.http-proxy-password=
+ ## 最大重试次数,默认:5 次,如果小于 0,则为 0
+ wx.channel.config-storage.max-retry-times=5
+ ## 重试时间间隔步进,默认:1000 毫秒,如果小于 0,则为 1000
+ wx.channel.config-storage.retry-sleep-millis=1000
+ ```
+3. 自动注入的类型
+- `WxChannelService`
+- `WxChannelConfig`
+4. 使用样例
+
+```java
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.channel.bean.shop.ShopInfoResponse;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.noear.solon.annotation.Inject;
+
+@Component
+public class DemoService {
+ @Inject
+ private WxChannelService wxChannelService;
+
+ public String getShopInfo() throws WxErrorException {
+ // 获取店铺基本信息
+ ShopInfoResponse response = wxChannelService.getBasicService().getShopInfo();
+ // 此处为演示,如果要返回response的结果,建议自己封装一个VO,避免直接返回response
+ return JsonUtils.encode(response);
+ }
+}
+```
+
diff --git a/solon-plugins/wx-java-channel-solon-plugin/pom.xml b/solon-plugins/wx-java-channel-solon-plugin/pom.xml
index 4e0dc723a..6238a55e4 100644
--- a/solon-plugins/wx-java-channel-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-channel-solon-plugin/pom.xml
@@ -3,7 +3,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-cp-multi-solon-plugin/pom.xml b/solon-plugins/wx-java-cp-multi-solon-plugin/pom.xml
index 9cf2b3172..742b86239 100644
--- a/solon-plugins/wx-java-cp-multi-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-cp-multi-solon-plugin/pom.xml
@@ -4,7 +4,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-cp-solon-plugin/pom.xml b/solon-plugins/wx-java-cp-solon-plugin/pom.xml
index 46266b8e8..b758ff8a5 100644
--- a/solon-plugins/wx-java-cp-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-cp-solon-plugin/pom.xml
@@ -4,7 +4,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-miniapp-multi-solon-plugin/pom.xml b/solon-plugins/wx-java-miniapp-multi-solon-plugin/pom.xml
index 1e5dab26b..52db2699b 100644
--- a/solon-plugins/wx-java-miniapp-multi-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-miniapp-multi-solon-plugin/pom.xml
@@ -5,7 +5,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-miniapp-solon-plugin/pom.xml b/solon-plugins/wx-java-miniapp-solon-plugin/pom.xml
index 805018b81..fd8643699 100644
--- a/solon-plugins/wx-java-miniapp-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-miniapp-solon-plugin/pom.xml
@@ -4,7 +4,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-mp-multi-solon-plugin/pom.xml b/solon-plugins/wx-java-mp-multi-solon-plugin/pom.xml
index 4ccc4fa7d..4ba79c8a5 100644
--- a/solon-plugins/wx-java-mp-multi-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-mp-multi-solon-plugin/pom.xml
@@ -5,7 +5,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-mp-solon-plugin/pom.xml b/solon-plugins/wx-java-mp-solon-plugin/pom.xml
index 3aa2b9be4..bea895694 100644
--- a/solon-plugins/wx-java-mp-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-mp-solon-plugin/pom.xml
@@ -5,7 +5,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-open-solon-plugin/pom.xml b/solon-plugins/wx-java-open-solon-plugin/pom.xml
index 355ef6f93..80a5df100 100644
--- a/solon-plugins/wx-java-open-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-open-solon-plugin/pom.xml
@@ -5,7 +5,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-pay-solon-plugin/pom.xml b/solon-plugins/wx-java-pay-solon-plugin/pom.xml
index 6357cc908..4dabbe46b 100644
--- a/solon-plugins/wx-java-pay-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-pay-solon-plugin/pom.xml
@@ -5,7 +5,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/solon-plugins/wx-java-qidian-solon-plugin/pom.xml b/solon-plugins/wx-java-qidian-solon-plugin/pom.xml
index 4ff6dba00..23ad77ea1 100644
--- a/solon-plugins/wx-java-qidian-solon-plugin/pom.xml
+++ b/solon-plugins/wx-java-qidian-solon-plugin/pom.xml
@@ -3,7 +3,7 @@
wx-java-solon-plugins
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml
index c5cb2954d..7f185f9fe 100644
--- a/spring-boot-starters/pom.xml
+++ b/spring-boot-starters/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
pom
wx-java-spring-boot-starters
diff --git a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/pom.xml
index dca311c01..e7faca156 100644
--- a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-channel-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-channel-spring-boot-starter/pom.xml
index 8f427c6d0..360c71d1a 100644
--- a/spring-boot-starters/wx-java-channel-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-channel-spring-boot-starter/pom.xml
@@ -3,7 +3,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-cp-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-cp-multi-spring-boot-starter/pom.xml
index 6ea0eb005..a32306110 100644
--- a/spring-boot-starters/wx-java-cp-multi-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-cp-multi-spring-boot-starter/pom.xml
@@ -4,7 +4,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml
index fdbe3d1e5..37b185228 100644
--- a/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml
@@ -4,7 +4,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/pom.xml
index cedde8174..5736c9dec 100644
--- a/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
index fba6da9e0..41f449da3 100644
--- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
@@ -4,7 +4,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-mp-multi-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-multi-spring-boot-starter/pom.xml
index 867f57055..11680de01 100644
--- a/spring-boot-starters/wx-java-mp-multi-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-mp-multi-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
index cddf39300..20a527eba 100644
--- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
index 189ff9467..95d3a9941 100644
--- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
index d4de4e77f..9a415ef12 100644
--- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/spring-boot-starters/wx-java-qidian-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-qidian-spring-boot-starter/pom.xml
index e118aba65..795cfcbe7 100644
--- a/spring-boot-starters/wx-java-qidian-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-qidian-spring-boot-starter/pom.xml
@@ -3,7 +3,7 @@
wx-java-spring-boot-starters
com.github.binarywang
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/weixin-graal/pom.xml b/weixin-graal/pom.xml
index 338a22a56..323df0d86 100644
--- a/weixin-graal/pom.xml
+++ b/weixin-graal/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
weixin-graal
diff --git a/weixin-java-channel/pom.xml b/weixin-java-channel/pom.xml
index 8d34754cb..3264a2fe9 100644
--- a/weixin-java-channel/pom.xml
+++ b/weixin-java-channel/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
weixin-java-channel
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java
index 78e391e77..f3cab1f4b 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java
@@ -42,4 +42,8 @@ public class OrderCommissionInfo implements Serializable {
/** 达人openfinderid */
@JsonProperty("openfinderid")
private String openFinderId;
+
+ /** 新带货平台 id */
+ @JsonProperty("talent_id")
+ private String talentId;
}
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index e89234d17..d45cc46d4 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
weixin-java-common
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/DefaultApacheHttpClientBuilder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/DefaultApacheHttpClientBuilder.java
index 4c06f5168..12f04ba20 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/DefaultApacheHttpClientBuilder.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/DefaultApacheHttpClientBuilder.java
@@ -59,7 +59,7 @@ public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder {
* 设置为负数是使用系统默认设置(非3000ms的默认值,而是httpClient的默认设置).
*
*/
- private int connectionRequestTimeout = -1;
+ private int connectionRequestTimeout = 3000;
/**
* 建立链接的超时时间,默认为5000ms.由于是在链接池获取链接,此设置应该并不起什么作用
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index 467ba9885..23cdd4d22 100644
--- a/weixin-java-cp/pom.xml
+++ b/weixin-java-cp/pom.xml
@@ -7,7 +7,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
weixin-java-cp
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpAgentWorkBenchService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpAgentWorkBenchService.java
index c50aa2f5f..67c57a8a8 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpAgentWorkBenchService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpAgentWorkBenchService.java
@@ -36,4 +36,12 @@ public interface WxCpAgentWorkBenchService {
* @throws WxErrorException the wx error exception
*/
void setWorkBenchData(WxCpAgentWorkBench wxCpAgentWorkBench) throws WxErrorException;
+
+ /**
+ * Batch sets work bench data.
+ *
+ * @param wxCpAgentWorkBench the wx cp agent work bench
+ * @throws WxErrorException the wx error exception
+ */
+ void batchSetWorkBenchData(WxCpAgentWorkBench wxCpAgentWorkBench) throws WxErrorException;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java
index 86b342f2f..5a53829dc 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java
@@ -75,6 +75,19 @@ public interface WxCpKfService {
*/
WxCpKfServicerOpResp addServicer(String openKfid, List userIdList) throws WxErrorException;
+ /**
+ * 接待人员管理
+ * 添加指定客服账号的接待人员,每个客服账号目前最多可添加2000个接待人员,20个部门。
+ * userid_list和department_id_list至少需要填其中一个
+ *
+ * @param openKfid 客服帐号ID
+ * @param userIdList 接待人员userid列表。第三方应用填密文userid,即open_userid 可填充个数:1 ~ 100。超过100个需分批调用。
+ * @param departmentIdList 接待人员部门id列表 可填充个数:0 ~ 20。
+ * @return 添加客服账号结果 wx cp kf servicer op resp
+ * @throws WxErrorException 异常
+ */
+ WxCpKfServicerOpResp addServicer(String openKfid, List userIdList,List departmentIdList) throws WxErrorException;
+
/**
* 接待人员管理
* 从客服帐号删除接待人员
@@ -86,6 +99,19 @@ public interface WxCpKfService {
*/
WxCpKfServicerOpResp delServicer(String openKfid, List userIdList) throws WxErrorException;
+ /**
+ * 接待人员管理
+ * 从客服帐号删除接待人员
+ * userid_list和department_id_list至少需要填其中一个
+ *
+ * @param openKfid 客服帐号ID
+ * @param userIdList 接待人员userid列表。第三方应用填密文userid,即open_userid 可填充个数:1 ~ 100。超过100个需分批调用。
+ * @param departmentIdList 接待人员部门id列表 可填充个数:0 ~ 100。超过100个需分批调用。
+ * @return 删除客服账号结果 wx cp kf servicer op resp
+ * @throws WxErrorException 异常
+ */
+ WxCpKfServicerOpResp delServicer(String openKfid, List userIdList, List departmentIdList) throws WxErrorException;
+
/**
* 接待人员管理
* 获取某个客服帐号的接待人员列表
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentWorkBenchServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentWorkBenchServiceImpl.java
index bb5c191e9..b0bbb3864 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentWorkBenchServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentWorkBenchServiceImpl.java
@@ -38,4 +38,10 @@ public void setWorkBenchData(WxCpAgentWorkBench wxCpAgentWorkBench) throws WxErr
final String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(WORKBENCH_DATA_SET));
this.mainService.post(url, wxCpAgentWorkBench.toUserDataString());
}
+
+ @Override
+ public void batchSetWorkBenchData(WxCpAgentWorkBench wxCpAgentWorkBench) throws WxErrorException {
+ final String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(WORKBENCH_BATCH_DATA_SET));
+ this.mainService.post(url, wxCpAgentWorkBench.toBatchUserDataString());
+ }
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java
index 29e84c516..be4f2a585 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java
@@ -70,23 +70,62 @@ public WxCpKfAccountLinkResp getAccountLink(WxCpKfAccountLink link) throws WxErr
@Override
public WxCpKfServicerOpResp addServicer(String openKfid, List userIdList) throws WxErrorException {
- return servicerOp(openKfid, userIdList, SERVICER_ADD);
+ return servicerOp(openKfid, userIdList, null, SERVICER_ADD);
+ }
+
+ @Override
+ public WxCpKfServicerOpResp addServicer(String openKfId, List userIdList, List departmentIdList) throws WxErrorException {
+ validateParameters(SERVICER_ADD, userIdList, departmentIdList);
+ return servicerOp(openKfId, userIdList, departmentIdList, SERVICER_ADD);
}
@Override
public WxCpKfServicerOpResp delServicer(String openKfid, List userIdList) throws WxErrorException {
- return servicerOp(openKfid, userIdList, SERVICER_DEL);
+ return servicerOp(openKfid, userIdList, null, SERVICER_DEL);
}
- private WxCpKfServicerOpResp servicerOp(String openKfid, List userIdList, String uri) throws WxErrorException {
+ @Override
+ public WxCpKfServicerOpResp delServicer(String openKfid, List userIdList, List departmentIdList) throws WxErrorException {
+ validateParameters(SERVICER_DEL, userIdList, departmentIdList);
+ return servicerOp(openKfid, userIdList, departmentIdList, SERVICER_DEL);
+ }
+
+ private void validateParameters(String uri, List userIdList, List departmentIdList) {
+ if ((userIdList == null || userIdList.isEmpty()) && (departmentIdList == null || departmentIdList.isEmpty())) {
+ throw new IllegalArgumentException("userid_list和department_id_list至少需要填其中一个");
+ }
+ if (SERVICER_DEL.equals(uri)) {
+ if (userIdList != null && userIdList.size() > 100) {
+ throw new IllegalArgumentException("可填充个数:0 ~ 100。超过100个需分批调用。");
+ }
+ if (departmentIdList != null && departmentIdList.size() > 100) {
+ throw new IllegalArgumentException("可填充个数:0 ~ 100。超过100个需分批调用。");
+ }
+ } else {
+ if (userIdList != null && userIdList.size() > 100) {
+ throw new IllegalArgumentException("可填充个数:0 ~ 100。超过100个需分批调用。");
+ }
+ if (departmentIdList != null && departmentIdList.size() > 20) {
+ throw new IllegalArgumentException("可填充个数:0 ~ 20。");
+ }
+ }
+ }
+
+ private WxCpKfServicerOpResp servicerOp(String openKfid, List userIdList, List departmentIdList, String uri) throws WxErrorException {
String url = cpService.getWxCpConfigStorage().getApiUrl(uri);
JsonObject json = new JsonObject();
json.addProperty("open_kfid", openKfid);
- JsonArray userIdArray = new JsonArray();
- userIdList.forEach(userIdArray::add);
- json.add("userid_list", userIdArray);
-
+ if (userIdList != null && !userIdList.isEmpty()) {
+ JsonArray userIdArray = new JsonArray();
+ userIdList.forEach(userIdArray::add);
+ json.add("userid_list", userIdArray);
+ }
+ if (departmentIdList != null && !departmentIdList.isEmpty()) {
+ JsonArray departmentIdArray = new JsonArray();
+ departmentIdList.forEach(departmentIdArray::add);
+ json.add("department_id_list", departmentIdArray);
+ }
String responseContent = cpService.post(url, json.toString());
return WxCpKfServicerOpResp.fromJson(responseContent);
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java
index 2a64f52bc..d04a051c0 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java
@@ -13,6 +13,8 @@
import me.chanjar.weixin.cp.bean.workbench.WxCpSecondVerificationInfo;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import java.util.Optional;
+
import static me.chanjar.weixin.common.api.WxConsts.OAuth2Scope.*;
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.OAuth2.*;
@@ -74,9 +76,9 @@ public WxCpOauth2UserInfo getUserInfo(Integer agentId, String code) throws WxErr
JsonObject jo = GsonParser.parse(responseText);
return WxCpOauth2UserInfo.builder()
- .userId(GsonHelper.getString(jo, "UserId"))
+ .userId(Optional.ofNullable(GsonHelper.getString(jo, "UserId")).orElse(GsonHelper.getString(jo, "userid")))
.deviceId(GsonHelper.getString(jo, "DeviceId"))
- .openId(GsonHelper.getString(jo, "OpenId"))
+ .openId(Optional.ofNullable(GsonHelper.getString(jo, "OpenId")).orElse(GsonHelper.getString(jo, "openid")))
.userTicket(GsonHelper.getString(jo, "user_ticket"))
.expiresIn(GsonHelper.getString(jo, "expires_in"))
.externalUserId(GsonHelper.getString(jo, "external_userid"))
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgentWorkBench.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgentWorkBench.java
index e74173ee3..2a3e4448b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgentWorkBench.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgentWorkBench.java
@@ -6,6 +6,7 @@
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.cp.bean.workbench.WorkBenchKeyData;
import me.chanjar.weixin.cp.bean.workbench.WorkBenchList;
import me.chanjar.weixin.cp.constant.WxCpConsts;
@@ -33,6 +34,10 @@ public class WxCpAgentWorkBench implements Serializable {
* 用户的userid
*/
private String userId;
+ /**
+ * 用户的userIds
+ */
+ private List useridList;
/**
* 应用id
*/
@@ -58,6 +63,15 @@ public class WxCpAgentWorkBench implements Serializable {
* 参考示例:今日要闻
*/
private Boolean enableWebviewClick;
+ /**
+ * 高度。可以有两种选择:single_row与double_row。当为single_row时,高度为106px(如果隐藏标题则为147px)。
+ * 当为double_row时,高度固定为171px(如果隐藏标题则为212px)。默认值为double_row
+ */
+ private String height;
+ /**
+ * 是否要隐藏展示了应用名称的标题部分,默认值为false。
+ */
+ private Boolean hideTitle;
private List keyDataList;
@@ -93,6 +107,20 @@ public String toUserDataString() {
return userDataObject.toString();
}
+ /**
+ * 生成批量用户数据Json字符串
+ *
+ * @return the string
+ */
+ public String toBatchUserDataString() {
+ JsonObject userDataObject = new JsonObject();
+ userDataObject.addProperty("agentid", this.agentId);
+ JsonArray useridList = WxGsonBuilder.create().toJsonTree(this.useridList).getAsJsonArray();
+ userDataObject.add("userid_list", useridList);
+ this.handleBatch(userDataObject);
+ return userDataObject.toString();
+ }
+
/**
* 处理不用类型的工作台数据
*/
@@ -140,9 +168,9 @@ private void handle(JsonObject templateObject) {
webview.addProperty("url", this.url);
webview.addProperty("jump_url", this.jumpUrl);
webview.addProperty("pagepath", this.pagePath);
- if (null != this.enableWebviewClick) {
- webview.addProperty("enable_webview_click", this.enableWebviewClick);
- }
+ webview.addProperty("enable_webview_click", this.enableWebviewClick);
+ webview.addProperty("height", this.height);
+ webview.addProperty("hide_title", this.hideTitle);
templateObject.add("webview", webview);
break;
}
@@ -152,4 +180,75 @@ private void handle(JsonObject templateObject) {
}
}
+ /**
+ * 处理不用类型的工作台数据
+ */
+ private void handleBatch(JsonObject templateObject) {
+ switch (this.getType()) {
+ case WxCpConsts.WorkBenchType.KEYDATA: {
+ JsonArray keyDataArray = new JsonArray();
+ JsonObject itemsObject = new JsonObject();
+ for (WorkBenchKeyData keyDataItem : this.keyDataList) {
+ JsonObject keyDataObject = new JsonObject();
+ keyDataObject.addProperty("key", keyDataItem.getKey());
+ keyDataObject.addProperty("data", keyDataItem.getData());
+ keyDataObject.addProperty("jump_url", keyDataItem.getJumpUrl());
+ keyDataObject.addProperty("pagepath", keyDataItem.getPagePath());
+ keyDataArray.add(keyDataObject);
+ }
+ itemsObject.add("items", keyDataArray);
+ JsonObject dataObject = new JsonObject();
+ dataObject.addProperty("type", WxCpConsts.WorkBenchType.KEYDATA);
+ dataObject.add("keydata", itemsObject);
+ templateObject.add("data", dataObject);
+ break;
+ }
+ case WxCpConsts.WorkBenchType.IMAGE: {
+ JsonObject image = new JsonObject();
+ image.addProperty("url", this.url);
+ image.addProperty("jump_url", this.jumpUrl);
+ image.addProperty("pagepath", this.pagePath);
+ JsonObject dataObject = new JsonObject();
+ dataObject.addProperty("type", WxCpConsts.WorkBenchType.IMAGE);
+ dataObject.add("image", image);
+ templateObject.add("data", dataObject);
+ break;
+ }
+ case WxCpConsts.WorkBenchType.LIST: {
+ JsonArray listArray = new JsonArray();
+ JsonObject itemsObject = new JsonObject();
+ for (WorkBenchList listItem : this.lists) {
+ JsonObject listObject = new JsonObject();
+ listObject.addProperty("title", listItem.getTitle());
+ listObject.addProperty("jump_url", listItem.getJumpUrl());
+ listObject.addProperty("pagepath", listItem.getPagePath());
+ listArray.add(listObject);
+ }
+ itemsObject.add("items", listArray);
+ JsonObject dataObject = new JsonObject();
+ dataObject.addProperty("type", WxCpConsts.WorkBenchType.LIST);
+ dataObject.add("list", itemsObject);
+ templateObject.add("data", dataObject);
+ break;
+ }
+ case WxCpConsts.WorkBenchType.WEBVIEW: {
+ JsonObject webview = new JsonObject();
+ webview.addProperty("url", this.url);
+ webview.addProperty("jump_url", this.jumpUrl);
+ webview.addProperty("pagepath", this.pagePath);
+ webview.addProperty("enable_webview_click", this.enableWebviewClick);
+ webview.addProperty("height", this.height);
+ webview.addProperty("hide_title", this.hideTitle);
+ JsonObject dataObject = new JsonObject();
+ dataObject.addProperty("type", WxCpConsts.WorkBenchType.WEBVIEW);
+ dataObject.add("webview", webview);
+ templateObject.add("data", dataObject);
+ break;
+ }
+ default: {
+ //do nothing
+ }
+ }
+ }
+
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlApprovalInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlApprovalInfo.java
index 7193c7cf6..798a5c8b0 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlApprovalInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlApprovalInfo.java
@@ -118,7 +118,7 @@ public static class NotifyNode implements Serializable {
/**
* 抄送人userid
*/
- @XStreamAlias("ItemUserid")
+ @XStreamAlias("ItemUserId")
@XStreamConverter(value = XStreamCDataConverter.class)
private String itemUserId;
@@ -190,7 +190,7 @@ public static class Item implements Serializable {
/**
* 分支审批人userid
*/
- @XStreamAlias("ItemUserid")
+ @XStreamAlias("ItemUserId")
@XStreamConverter(value = XStreamCDataConverter.class)
private String itemUserId;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/msgaudit/WxCpChatModel.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/msgaudit/WxCpChatModel.java
index 8a9d2130d..c88cb7b9b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/msgaudit/WxCpChatModel.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/msgaudit/WxCpChatModel.java
@@ -603,7 +603,7 @@ public static class File implements Serializable {
private String sdkFileId;
@SerializedName("filesize")
- private Integer fileSize;
+ private Long fileSize;
/**
* From json file.
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
index 3aecf7212..d70f0ff4c 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
@@ -130,6 +130,10 @@ interface WorkBench {
* The constant WORKBENCH_DATA_SET.
*/
String WORKBENCH_DATA_SET = "/cgi-bin/agent/set_workbench_data";
+ /**
+ * The constant WORKBENCH_BATCH_DATA_SET.
+ */
+ String WORKBENCH_BATCH_DATA_SET = "/cgi-bin/agent/batch_set_workbench_data";
}
/**
diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml
index cfe52b968..3c5c3fd95 100644
--- a/weixin-java-miniapp/pom.xml
+++ b/weixin-java-miniapp/pom.xml
@@ -7,7 +7,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
weixin-java-miniapp
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaImmediateDeliveryServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaImmediateDeliveryServiceImpl.java
index 05e8f2e0a..342224eff 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaImmediateDeliveryServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaImmediateDeliveryServiceImpl.java
@@ -207,7 +207,7 @@ public GetDeliveryListResponse getDeliveryList() throws WxErrorException {
@Override
public WxMaBaseResponse updateWaybillGoods(UpdateWaybillGoodsRequest request) throws WxErrorException {
- String responseContent = this.wxMaService.post(InstantDelivery.GET_DELIVERY_LIST_URL,request);
+ String responseContent = this.wxMaService.post(InstantDelivery.UPDATE_WAYBILL_GOODS_URL,request);
WxMaBaseResponse response = WxMaGsonBuilder.create().fromJson(responseContent, WxMaBaseResponse.class);
if (response.getErrcode() == -1) {
throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp));
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java
index 7a004b845..75d8174ca 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java
@@ -31,7 +31,7 @@ public class WxMaMessage implements Serializable {
private static final long serialVersionUID = -3586245291677274914L;
/**
- * 使用dom4j解析的存放所有xml属性和值的map.
+ * 使用dom4j解析的存放所有xml或json属性和值的map.
*/
private Map allFieldsMap;
@@ -287,6 +287,7 @@ public static WxMaMessage fromJson(String json) {
}
message.setUselessMsg(null);
}
+ message.setAllFieldsMap(WxMaGsonBuilder.create().fromJson(json, Map.class));
return message;
}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java
index d61ade73c..30d52b17c 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java
@@ -626,7 +626,7 @@ public interface InstantDelivery {
String GET_DELIVERY_LIST_URL =
"https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/get_delivery_list";
- /** 获取运力id列表get_delivery_list 商户使用此接口获取所有运力id的列表 */
+ /** 物流服务-查询组件-更新物品信息接口 update_waybill_goods 更新物品信息 */
String UPDATE_WAYBILL_GOODS_URL =
"https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/update_waybill_goods";
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index 0aecd36da..0b8adf038 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -7,7 +7,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
weixin-java-mp
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java
index 6d4869b6a..86555aa4a 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java
@@ -50,12 +50,12 @@ public void initHttp() {
clientBuilder.proxy(getRequestHttpProxy().getProxy());
//设置授权
- clientBuilder.authenticator(new Authenticator() {
+ clientBuilder.proxyAuthenticator(new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword());
return response.request().newBuilder()
- .header("Authorization", credential)
+ .header("Proxy-Authorization", credential)
.build();
}
});
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpMapConfigImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpMapConfigImpl.java
index cd701d1ef..72e6e615f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpMapConfigImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpMapConfigImpl.java
@@ -15,7 +15,7 @@ public class WxMpMapConfigImpl extends WxMpDefaultConfigImpl {
private static final long serialVersionUID = 5311395137835650104L;
- private static final ConcurrentHashMap CONCURRENT_HASH_MAP = new ConcurrentHashMap<>(1);
+ private final ConcurrentHashMap CONCURRENT_HASH_MAP = new ConcurrentHashMap<>(1);
private static final String MAP_KEY = "access_token";
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMapConfigImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMapConfigImplTest.java
new file mode 100644
index 000000000..167c0e019
--- /dev/null
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMapConfigImplTest.java
@@ -0,0 +1,58 @@
+package me.chanjar.weixin.mp.api.impl;
+
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.test.ApiTestModule;
+import me.chanjar.weixin.mp.config.impl.WxMpMapConfigImpl;
+import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * 测试 ConcurrentHashMap 保存配置信息
+ * @author jimmyjimmy-sw
+ */
+@Test
+@Guice(modules = ApiTestModule.class)
+public class WxMpMapConfigImplTest {
+
+ @Inject
+ private WxMpService wxService;
+
+ /**
+ * 测试多租户保存 WxMpMapConfigImpl 到 WxMpService,切换之后能获取到租户各自AppId对应的token
+ * @throws WxErrorException
+ */
+ @Test
+ public void testAppidSwitch() throws WxErrorException {
+ // 保存租户A的配置信息,并获取token
+ WxMpMapConfigImpl configAppA = new WxMpMapConfigImpl();
+ String appidA = "APPID_A";
+ configAppA.setAppId(appidA);
+ configAppA.setSecret("APP_SECRET_A");
+ configAppA.useStableAccessToken(true);
+ String tokenA = "TOKEN_A";
+ configAppA.updateAccessToken(tokenA,60 * 60 * 1);
+ wxService.addConfigStorage(appidA, configAppA);
+ WxMpConfigStorageHolder.set(appidA);
+ assertEquals(this.wxService.getAccessToken(),tokenA);
+
+ // 保存租户B的配置信息,并获取token
+ WxMpMapConfigImpl configAppB = new WxMpMapConfigImpl();
+ String appidB = "APPID_B";
+ configAppB.setAppId(appidB);
+ configAppB.setSecret("APP_SECRET_B");
+ configAppB.useStableAccessToken(true);
+ String tokenB = "TOKEN_B";
+ configAppB.updateAccessToken(tokenB,60 * 60 * 1);
+ wxService.addConfigStorage(appidB, configAppB);
+ WxMpConfigStorageHolder.set(appidB);
+ assertEquals(this.wxService.getAccessToken(),tokenB);
+
+ // 上下文切换到租户A 获取租户A的token
+ WxMpConfigStorageHolder.set(appidA);
+ assertEquals(this.wxService.getAccessToken(),tokenA);
+ }
+}
diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml
index f7fac62e6..d09746719 100644
--- a/weixin-java-open/pom.xml
+++ b/weixin-java-open/pom.xml
@@ -7,7 +7,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
weixin-java-open
diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
index 6eeb06624..4525620d7 100644
--- a/weixin-java-pay/pom.xml
+++ b/weixin-java-pay/pom.xml
@@ -5,7 +5,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
4.0.0
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderV3Request.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderV3Request.java
index 98dae388e..8ac588de8 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderV3Request.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderV3Request.java
@@ -250,6 +250,12 @@ public static class Payer implements Serializable {
*/
@SerializedName(value = "openid")
private String openid;
+
+ /**
+ * 实名支付用户身份标识
+ */
+ @SerializedName(value = "identity")
+ private Identity identity;
}
@Data
@@ -572,4 +578,36 @@ public static class SettleInfo implements Serializable {
@SerializedName(value = "profit_sharing")
private Boolean profitSharing;
}
+
+
+ @Data
+ @NoArgsConstructor
+ public static class Identity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 证件类型
+ * IDCARD:身份证
+ * HONGKONG_MACAO:港澳回乡证
+ * HONGKONG_MACAO_RESIDENT:港澳居住证
+ * TAIWAN_RESIDENT:台湾居住证
+ * FOREIGN_RESIDENT:外国人永居证
+ * OVERSEA_PASSPORT:护照
+ */
+ @SerializedName(value = "type")
+ private String type;
+ /**
+ * 证件号
+ * 证件号,如身份证号。
+ * 示例值:43102119910910512X
+ */
+ @SerializedName(value = "number")
+ private String number;
+ /**
+ * 证件姓名。
+ * 示例值:周星星
+ */
+ @SerializedName(value = "name")
+ private String name;
+ }
}
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/VerifierBuilder.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/VerifierBuilder.java
new file mode 100644
index 000000000..c7bc14f52
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/VerifierBuilder.java
@@ -0,0 +1,131 @@
+package com.github.binarywang.wxpay.config;
+
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.v3.auth.*;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+/**
+ * 验证器构建.
+ *
+ * @author holy
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+class VerifierBuilder {
+ /**
+ * 构建验证器.
+ *
+ * 场景
+ *
+ * 1. 老商户号,只有平台证书,未开通公钥 (已验证)
+ * 2. 新商户号,被强制开通公钥,没有平台证书 (已验证)
+ * 3. 老商户号,有平台证书,主动开通公钥 (未验证,具备条件的朋友,可以帮忙验证下)
+ * ...
+ *
+ *
+ * @param certSerialNo c
+ * @param mchId m
+ * @param apiV3Key a
+ * @param merchantPrivateKey m
+ * @param wxPayHttpProxy w
+ * @param certAutoUpdateTime c
+ * @param payBaseUrl p
+ * @param publicKeyId p
+ * @param publicKey p
+ * @return v
+ * @throws WxPayException e
+ */
+ @SuppressWarnings("java:S107")
+ static Verifier build(
+ // 平台证书 - 依赖参数
+ String certSerialNo,
+ String mchId,
+ String apiV3Key,
+ PrivateKey merchantPrivateKey,
+ WxPayHttpProxy wxPayHttpProxy,
+ int certAutoUpdateTime,
+ String payBaseUrl,
+ // 公钥 - 依赖参数
+ String publicKeyId,
+ PublicKey publicKey
+ ) throws WxPayException {
+ Verifier certificatesVerifier = null;
+ Exception ex = null;
+
+ // 构建平台证书验证器
+ // (沿用旧逻辑)优先构建平台证书验证器,因为公钥验证器需要平台证书验证器 (见以下 .setOtherVerifier )
+ // 新商户号默认无平台证书,已确认无法构建平台证书验证器,会抛出异常;老商户号,有平台证书主动开通公钥的情况,待具备条件的朋友验证
+ // 建议公钥模式稳定后,优先构建公钥验证器,以免每次都尝试构建平台证书验证器,且失败 {@link com.github.binarywang.wxpay.v3.auth.PublicCertificateVerifier.verify}
+ if (merchantPrivateKey != null && StringUtils.isNoneBlank(certSerialNo, apiV3Key)) {
+ try {
+ certificatesVerifier = getCertificatesVerifier(
+ certSerialNo, mchId, apiV3Key, merchantPrivateKey, wxPayHttpProxy, certAutoUpdateTime, payBaseUrl
+ );
+ } catch (Exception e) {
+ ex = e;
+ }
+ }
+
+ // 构建公钥验证器
+ if (publicKey != null && StringUtils.isNotBlank(publicKeyId)) {
+ try {
+ certificatesVerifier = getPublicCertVerifier(publicKeyId, publicKey, certificatesVerifier);
+ } catch (Exception e) {
+ ex = e;
+ }
+ }
+ if (certificatesVerifier != null) {
+ return certificatesVerifier;
+ }
+
+ // 有异常时抛出
+ if (ex != null) {
+ throw new WxPayException(ex.getMessage(), ex);
+ }
+
+ // 没有证书验证器时。不确定是否抛出异常,沿用之前逻辑,返回 null
+ return null;
+ }
+
+ /**
+ * 获取证书验证器.
+ *
+ * @param certSerialNo certSerialNo
+ * @param mchId mchId
+ * @param apiV3Key apiV3Key
+ * @param merchantPrivateKey merchantPrivateKey
+ * @param wxPayHttpProxy wxPayHttpProxy
+ * @param certAutoUpdateTime certAutoUpdateTime
+ * @param payBaseUrl payBaseUrl
+ * @return verifier
+ */
+ private static AutoUpdateCertificatesVerifier getCertificatesVerifier(
+ String certSerialNo, String mchId, String apiV3Key, PrivateKey merchantPrivateKey,
+ WxPayHttpProxy wxPayHttpProxy, int certAutoUpdateTime, String payBaseUrl
+ ) {
+ return new AutoUpdateCertificatesVerifier(
+ new WxPayCredentials(mchId, new PrivateKeySigner(certSerialNo, merchantPrivateKey)),
+ apiV3Key.getBytes(StandardCharsets.UTF_8), certAutoUpdateTime,
+ payBaseUrl, wxPayHttpProxy);
+ }
+
+ /**
+ * 获取公钥验证器.
+ *
+ * @param publicKeyId id
+ * @param publicKey key
+ * @param certificatesVerifier verifier
+ * @return verifier
+ */
+ private static Verifier getPublicCertVerifier(String publicKeyId, PublicKey publicKey, Verifier certificatesVerifier) {
+ Verifier publicCertificatesVerifier = new PublicCertificateVerifier(publicKey, publicKeyId);
+ publicCertificatesVerifier.setOtherVerifier(certificatesVerifier);
+ certificatesVerifier = publicCertificatesVerifier;
+ return certificatesVerifier;
+ }
+}
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 35558d563..2cfec2bc1 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
@@ -4,7 +4,8 @@
import com.github.binarywang.wxpay.util.HttpProxyUtils;
import com.github.binarywang.wxpay.util.ResourcesUtils;
import com.github.binarywang.wxpay.v3.WxPayV3HttpClientBuilder;
-import com.github.binarywang.wxpay.v3.auth.*;
+import com.github.binarywang.wxpay.v3.auth.Verifier;
+import com.github.binarywang.wxpay.v3.auth.WxPayValidator;
import com.github.binarywang.wxpay.v3.util.PemUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -19,7 +20,6 @@
import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.URL;
-import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -227,6 +227,11 @@ public class WxPayConfig {
*/
private Verifier verifier;
+ /**
+ * 是否将全部v3接口的请求都添加Wechatpay-Serial请求头,默认不添加
+ */
+ private boolean strictlyNeedWechatPaySerial = false;
+
/**
* 返回所设置的微信支付接口请求地址域名.
*
@@ -320,16 +325,12 @@ public CloseableHttpClient initApiV3HttpClient() throws WxPayException {
//构造Http Proxy正向代理
WxPayHttpProxy wxPayHttpProxy = getWxPayHttpProxy();
- Verifier certificatesVerifier;
- if (publicKey == null) {
- certificatesVerifier =
- new AutoUpdateCertificatesVerifier(
- new WxPayCredentials(mchId, new PrivateKeySigner(certSerialNo, merchantPrivateKey)),
- this.getApiV3Key().getBytes(StandardCharsets.UTF_8), this.getCertAutoUpdateTime(),
- this.getPayBaseUrl(), wxPayHttpProxy);
- } else {
- certificatesVerifier = new PublicCertificateVerifier(publicKey, publicKeyId);
- }
+ // 构造证书验签器
+ Verifier certificatesVerifier = VerifierBuilder.build(
+ this.getCertSerialNo(), this.getMchId(), this.getApiV3Key(), merchantPrivateKey, wxPayHttpProxy,
+ this.getCertAutoUpdateTime(), this.getPayBaseUrl(),
+ this.getPublicKeyId(), publicKey
+ );
WxPayV3HttpClientBuilder wxPayV3HttpClientBuilder = WxPayV3HttpClientBuilder.create()
.withMerchant(mchId, certSerialNo, merchantPrivateKey)
@@ -382,7 +383,7 @@ private InputStream loadConfigInputStream(String configString, String configPath
if (configContent != null) {
return new ByteArrayInputStream(configContent);
}
-
+
if (StringUtils.isNotEmpty(configString)) {
configContent = Base64.getDecoder().decode(configString);
return new ByteArrayInputStream(configContent);
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
index 1fa2f8dc8..530609a7d 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
@@ -251,7 +251,7 @@ public WxPayRefundResult refundV2(WxPayRefundRequest request) throws WxPayExcept
@Override
public WxPayRefundV3Result refundV3(WxPayRefundV3Request request) throws WxPayException {
String url = String.format("%s/v3/refund/domestic/refunds", this.getPayBaseUrl());
- String response = this.postV3(url, GSON.toJson(request));
+ String response = this.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(response, WxPayRefundV3Result.class);
}
@@ -294,21 +294,21 @@ public WxPayRefundQueryResult refundQueryV2(WxPayRefundQueryRequest request) thr
@Override
public WxPayRefundQueryV3Result refundQueryV3(String outRefundNo) throws WxPayException {
String url = String.format("%s/v3/refund/domestic/refunds/%s", this.getPayBaseUrl(), outRefundNo);
- String response = this.getV3(url);
+ String response = this.getV3WithWechatPaySerial(url);
return GSON.fromJson(response, WxPayRefundQueryV3Result.class);
}
@Override
public WxPayRefundQueryV3Result refundQueryV3(WxPayRefundQueryV3Request request) throws WxPayException {
String url = String.format("%s/v3/refund/domestic/refunds/%s", this.getPayBaseUrl(), request.getOutRefundNo());
- String response = this.getV3(url);
+ String response = this.getV3WithWechatPaySerial(url);
return GSON.fromJson(response, WxPayRefundQueryV3Result.class);
}
@Override
public WxPayRefundQueryV3Result refundPartnerQueryV3(WxPayRefundQueryV3Request request) throws WxPayException {
String url = String.format("%s/v3/refund/domestic/refunds/%s?sub_mchid=%s", this.getPayBaseUrl(), request.getOutRefundNo(), request.getSubMchid());
- String response = this.getV3(url);
+ String response = this.getV3WithWechatPaySerial(url);
return GSON.fromJson(response, WxPayRefundQueryV3Result.class);
}
@@ -323,13 +323,13 @@ public WxPayOrderNotifyResult parseOrderNotifyResult(String xmlData, String sign
log.debug("微信支付异步通知请求参数:{}", xmlData);
WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlData);
if (signType == null) {
+ this.switchover(result.getMchId(), result.getAppid());
if (result.getSignType() != null) {
// 如果解析的通知对象中signType有值,则使用它进行验签
signType = result.getSignType();
- } else if (configMap.get(result.getMchId()).getSignType() != null) {
+ } else if (this.getConfig().getSignType() != null) {
// 如果配置中signType有值,则使用它进行验签
- signType = configMap.get(result.getMchId()).getSignType();
- this.switchover(result.getMchId(), result.getAppid());
+ signType = this.getConfig().getSignType();
}
}
@@ -523,7 +523,7 @@ public WxPayOrderQueryV3Result queryOrderV3(WxPayOrderQueryV3Request request) th
url = String.format("%s/v3/pay/transactions/id/%s", this.getPayBaseUrl(), request.getTransactionId());
}
String query = String.format("?mchid=%s", request.getMchid());
- String response = this.getV3(url + query);
+ String response = this.getV3WithWechatPaySerial(url + query);
return GSON.fromJson(response, WxPayOrderQueryV3Result.class);
}
@@ -548,14 +548,14 @@ public WxPayPartnerOrderQueryV3Result queryPartnerOrderV3(WxPayPartnerOrderQuery
url = String.format("%s/v3/pay/partner/transactions/id/%s", this.getPayBaseUrl(), request.getTransactionId());
}
String query = String.format("?sp_mchid=%s&sub_mchid=%s", request.getSpMchId(), request.getSubMchId());
- String response = this.getV3(url + query);
+ String response = this.getV3WithWechatPaySerial(url + query);
return GSON.fromJson(response, WxPayPartnerOrderQueryV3Result.class);
}
@Override
public CombineQueryResult queryCombine(String combineOutTradeNo) throws WxPayException {
String url = String.format("%s/v3/combine-transactions/out-trade-no/%s", this.getPayBaseUrl(), combineOutTradeNo);
- String response = this.getV3(url);
+ String response = this.getV3WithWechatPaySerial(url);
return GSON.fromJson(response, CombineQueryResult.class);
}
@@ -609,7 +609,7 @@ public void closeOrderV3(WxPayOrderCloseV3Request request) throws WxPayException
request.setMchid(this.getConfig().getMchId());
}
String url = String.format("%s/v3/pay/transactions/out-trade-no/%s/close", this.getPayBaseUrl(), request.getOutTradeNo());
- this.postV3(url, GSON.toJson(request));
+ this.postV3WithWechatpaySerial(url, GSON.toJson(request));
}
@Override
@@ -621,13 +621,13 @@ public void closePartnerOrderV3(WxPayPartnerOrderCloseV3Request request) throws
request.setSubMchId(this.getConfig().getSubMchId());
}
String url = String.format("%s/v3/pay/partner/transactions/out-trade-no/%s/close", this.getPayBaseUrl(), request.getOutTradeNo());
- this.postV3(url, GSON.toJson(request));
+ this.postV3WithWechatpaySerial(url, GSON.toJson(request));
}
@Override
public void closeCombine(CombineCloseRequest request) throws WxPayException {
String url = String.format("%s/v3/combine-transactions/out-trade-no/%s/close", this.getPayBaseUrl(), request.getCombineOutTradeNo());
- this.postV3(url, GSON.toJson(request));
+ this.postV3WithWechatpaySerial(url, GSON.toJson(request));
}
@Override
@@ -771,7 +771,7 @@ public WxPayUnifiedOrderV3Result unifiedPartnerOrderV3(TradeTypeEnum tradeType,
}
String url = this.getPayBaseUrl() + tradeType.getBasePartnerUrl();
- String response = this.postV3(url, GSON.toJson(request));
+ String response = this.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(response, WxPayUnifiedOrderV3Result.class);
}
@@ -788,7 +788,7 @@ public WxPayUnifiedOrderV3Result unifiedOrderV3(TradeTypeEnum tradeType, WxPayUn
}
String url = this.getPayBaseUrl() + tradeType.getPartnerUrl();
- String response = this.postV3(url, GSON.toJson(request));
+ String response = this.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(response, WxPayUnifiedOrderV3Result.class);
}
@@ -801,14 +801,14 @@ public CombineTransactionsResult combine(TradeTypeEnum tradeType, CombineTransac
request.setCombineMchid(this.getConfig().getMchId());
}
String url = this.getPayBaseUrl() + tradeType.getCombineUrl();
- String response = this.postV3(url, GSON.toJson(request));
+ String response = this.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(response, CombineTransactionsResult.class);
}
@Override
public T combineTransactions(TradeTypeEnum tradeType, CombineTransactionsRequest request) throws WxPayException {
CombineTransactionsResult result = this.combine(tradeType, request);
- return result.getPayInfo(tradeType, request.getCombineAppid(), request.getCombineAppid(), this.getConfig().getPrivateKey());
+ return result.getPayInfo(tradeType, request.getCombineAppid(), request.getCombineMchid(), this.getConfig().getPrivateKey());
}
@Override
@@ -1114,7 +1114,7 @@ public WxPayApplyBillV3Result applyTradeBill(WxPayApplyTradeBillV3Request reques
} else {
url = String.format("%s/v3/bill/tradebill?bill_date=%s&bill_type=%s&tar_type=%s", this.getPayBaseUrl(), request.getBillDate(), request.getBillType(), request.getTarType());
}
- String response = this.getV3(url);
+ String response = this.getV3WithWechatPaySerial(url);
return GSON.fromJson(response, WxPayApplyBillV3Result.class);
}
@@ -1126,7 +1126,7 @@ public WxPayApplyBillV3Result applyFundFlowBill(WxPayApplyFundFlowBillV3Request
} else {
url = String.format("%s/v3/bill/fundflowbill?bill_date=%s&account_type=%s&tar_type=%s", this.getPayBaseUrl(), request.getBillDate(), request.getAccountType(), request.getTarType());
}
- String response = this.getV3(url);
+ String response = this.getV3WithWechatPaySerial(url);
return GSON.fromJson(response, WxPayApplyBillV3Result.class);
}
@@ -1155,7 +1155,7 @@ public WxPayCodepayResult codepay(WxPayCodepayRequest request) throws WxPayExcep
request.setMchid(this.getConfig().getMchId());
}
String url = String.format("%s/v3/pay/transactions/codepay", this.getPayBaseUrl());
- String body = this.postV3(url, GSON.toJson(request));
+ String body = this.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(body, WxPayCodepayResult.class);
}
@@ -1181,7 +1181,7 @@ public WxPayOrderReverseV3Result reverseOrderV3(WxPayOrderReverseV3Request reque
}
// 拼接参数请求路径并发送
String url = String.format("%s/v3/pay/transactions/out-trade-no/%s/reverse", this.getPayBaseUrl(), request.getOutTradeNo());
- String response = this.postV3(url, GSON.toJson(request));
+ String response = this.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(response, WxPayOrderReverseV3Result.class);
}
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java
index 7fd793979..f57ff13d4 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java
@@ -100,6 +100,8 @@ public String postV3(String url, String requestStr) throws WxPayException {
HttpPost httpPost = this.createHttpPost(url, requestStr);
httpPost.addHeader(ACCEPT, APPLICATION_JSON);
httpPost.addHeader(CONTENT_TYPE, APPLICATION_JSON);
+ String serialNumber = getWechatpaySerial(getConfig());
+ httpPost.addHeader("Wechatpay-Serial", serialNumber);
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
//v3已经改为通过状态码判断200 204 成功
int statusCode = response.getStatusLine().getStatusCode();
@@ -241,6 +243,9 @@ public String requestV3(String url, HttpRequestBase httpRequest) throws WxPayExc
@Override
public String getV3(String url) throws WxPayException {
+ if (this.getConfig().isStrictlyNeedWechatPaySerial()) {
+ return getV3WithWechatPaySerial(url);
+ }
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader(ACCEPT, APPLICATION_JSON);
httpGet.addHeader(CONTENT_TYPE, APPLICATION_JSON);
@@ -387,10 +392,9 @@ private WxPayException convertException(JsonObject jsonObject) {
* @return
*/
private String getWechatpaySerial(WxPayConfig wxPayConfig) {
- String serialNumber = wxPayConfig.getVerifier().getValidCertificate().getSerialNumber().toString(16).toUpperCase();
if (StringUtils.isNotBlank(wxPayConfig.getPublicKeyId())) {
- serialNumber = wxPayConfig.getPublicKeyId();
+ return wxPayConfig.getPublicKeyId();
}
- return serialNumber;
+ return wxPayConfig.getVerifier().getValidCertificate().getSerialNumber().toString(16).toUpperCase();
}
}
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/PublicCertificateVerifier.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/PublicCertificateVerifier.java
index 9344fc6f8..8c9c4f356 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/PublicCertificateVerifier.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/PublicCertificateVerifier.java
@@ -9,6 +9,8 @@ public class PublicCertificateVerifier implements Verifier{
private final PublicKey publicKey;
+ private Verifier certificateVerifier;
+
private final X509PublicCertificate publicCertificate;
public PublicCertificateVerifier(PublicKey publicKey, String publicId) {
@@ -16,8 +18,15 @@ public PublicCertificateVerifier(PublicKey publicKey, String publicId) {
this.publicCertificate = new X509PublicCertificate(publicKey, publicId);
}
+ public void setOtherVerifier(Verifier verifier) {
+ this.certificateVerifier = verifier;
+ }
+
@Override
public boolean verify(String serialNumber, byte[] message, String signature) {
+ if (!serialNumber.contains("PUB_KEY_ID") && this.certificateVerifier != null) {
+ return this.certificateVerifier.verify(serialNumber, message, signature);
+ }
try {
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initVerify(publicKey);
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/Verifier.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/Verifier.java
index 49f92e2f5..22676601c 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/Verifier.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/Verifier.java
@@ -7,4 +7,6 @@ public interface Verifier {
X509Certificate getValidCertificate();
+
+ default void setOtherVerifier(Verifier verifier) {};
}
diff --git a/weixin-java-qidian/pom.xml b/weixin-java-qidian/pom.xml
index 737af413d..f7f0d9ac6 100644
--- a/weixin-java-qidian/pom.xml
+++ b/weixin-java-qidian/pom.xml
@@ -7,7 +7,7 @@
com.github.binarywang
wx-java
- 4.7.2.B
+ 4.7.4.B
weixin-java-qidian