From 067cfd446c481cfab593d584c1f8502fdade6cbe Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 11 Aug 2026 14:16:01 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=E5=85=81=E8=AE=B8V2=E6=B2=99?= =?UTF-8?q?=E7=AE=B1=E4=B8=8EV3=E9=85=8D=E7=BD=AE=E5=85=B1=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/BaseWxPayServiceImpl.java | 3 -- .../impl/WxPayServiceApacheHttpImpl.java | 12 ++++++ .../service/impl/WxPayServiceSandboxTest.java | 39 +++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceSandboxTest.java 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 d17c3ae69..15bd0ce34 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 @@ -368,9 +368,6 @@ public String getConfigKey(String mchId, String appId) { @Override public String getPayBaseUrl() { if (this.getConfig().isUseSandboxEnv()) { - if (StringUtils.isNotBlank(this.getConfig().getApiV3Key())) { - throw new WxRuntimeException("微信支付V3 目前不支持沙箱模式!"); - } return this.getConfig().getApiHostWithPathPrefix() + "/xdc/apiv2sandbox"; } return this.getConfig().getApiHostWithPathPrefix(); 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 12b85670f..976cb89d6 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 @@ -7,6 +7,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxRuntimeException; import me.chanjar.weixin.common.util.http.apache.ByteArrayResponseHandler; import me.chanjar.weixin.common.util.json.GsonParser; import org.apache.commons.lang3.StringUtils; @@ -128,6 +129,7 @@ public String postV3(String url, String requestStr) throws WxPayException { } private String requestV3(String url, String requestStr, HttpRequestBase httpRequestBase) throws WxPayException { + this.checkV3SandboxNotSupported(); CloseableHttpClient httpClient = this.createApiV3HttpClient(); try (CloseableHttpResponse response = httpClient.execute(httpRequestBase)) { //v3已经改为通过状态码判断200 204 成功 @@ -163,6 +165,7 @@ public String patchV3(String url, String requestStr) throws WxPayException { @Override public String postV3WithWechatpaySerial(String url, String requestStr) throws WxPayException { + this.checkV3SandboxNotSupported(); HttpPost httpPost = this.createHttpPost(url, requestStr); this.configureRequest(httpPost); CloseableHttpClient httpClient = this.createApiV3HttpClient(); @@ -199,6 +202,7 @@ public String postV3(String url, HttpPost httpPost) throws WxPayException { @Override public String requestV3(String url, HttpRequestBase httpRequest) throws WxPayException { + this.checkV3SandboxNotSupported(); this.configureRequest(httpRequest); CloseableHttpClient httpClient = this.createApiV3HttpClient(); try (CloseableHttpResponse response = httpClient.execute(httpRequest)) { @@ -243,6 +247,7 @@ public String getV3WithWechatPaySerial(String url) throws WxPayException { @Override public InputStream downloadV3(String url) throws WxPayException { + this.checkV3SandboxNotSupported(); HttpGet httpGet = new WxPayV3DownloadHttpGet(url); this.configureRequest(httpGet); CloseableHttpClient httpClient = this.createApiV3HttpClient(); @@ -285,6 +290,7 @@ public String deleteV3(String url) throws WxPayException { } private void configureRequest(HttpRequestBase request) { + this.checkV3SandboxNotSupported(); String serialNumber = getWechatPaySerial(getConfig()); String method = request.getMethod(); request.addHeader(ACCEPT, APPLICATION_JSON); @@ -300,6 +306,12 @@ private void configureRequest(HttpRequestBase request) { .build()); } + private void checkV3SandboxNotSupported() { + if (this.getConfig().isUseSandboxEnv()) { + throw new WxRuntimeException("微信支付V3 目前不支持沙箱模式!"); + } + } + private CloseableHttpClient createApiV3HttpClient() throws WxPayException { CloseableHttpClient apiV3HttpClient = this.getConfig().getApiV3HttpClient(); if (null == apiV3HttpClient) { diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceSandboxTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceSandboxTest.java new file mode 100644 index 000000000..1b4f37d9c --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceSandboxTest.java @@ -0,0 +1,39 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.config.WxPayConfig; +import me.chanjar.weixin.common.error.WxRuntimeException; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.expectThrows; + +public class WxPayServiceSandboxTest { + + @Test + public void shouldUseV2SandboxUrlWhenV3KeyIsConfigured() { + WxPayConfig config = new WxPayConfig(); + config.setApiHostUrl("https://api.mch.weixin.qq.com"); + config.setApiHostUrlPath("/payment-proxy"); + config.setApiV3Key("v3-key"); + config.setUseSandboxEnv(true); + + WxPayServiceImpl service = new WxPayServiceImpl(); + service.setConfig(config); + + assertEquals(service.getPayBaseUrl(), "https://api.mch.weixin.qq.com/payment-proxy/xdc/apiv2sandbox"); + } + + @Test + public void shouldRejectV3RequestWhenSandboxIsEnabled() { + WxPayConfig config = new WxPayConfig(); + config.setUseSandboxEnv(true); + + WxPayServiceImpl service = new WxPayServiceImpl(); + service.setConfig(config); + + WxRuntimeException exception = expectThrows(WxRuntimeException.class, + () -> service.postV3("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi", "{}")); + + assertEquals(exception.getMessage(), "微信支付V3 目前不支持沙箱模式!"); + } +} From 21ed2d411419968a6fc93462020335954713bb9c Mon Sep 17 00:00:00 2001 From: softboy99 Date: Wed, 12 Aug 2026 13:14:51 +0800 Subject: [PATCH 2/3] =?UTF-8?q?:new:=20#4092=20=E3=80=90=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E3=80=91=E5=A2=9E=E5=8A=A0=E5=BE=85=E5=8A=9E?= =?UTF-8?q?API=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/cp/api/WxCpService.java | 7 ++ .../weixin/cp/api/WxCpTodoService.java | 47 ++++++++ .../cp/api/impl/BaseWxCpServiceImpl.java | 6 + .../cp/api/impl/WxCpTodoServiceImpl.java | 50 ++++++++ .../chanjar/weixin/cp/bean/todo/WxCpTodo.java | 110 ++++++++++++++++++ .../weixin/cp/constant/WxCpApiPathConsts.java | 18 +++ .../cp/api/impl/WxCpTodoServiceImplTest.java | 76 ++++++++++++ weixin-java-cp/src/test/resources/testng.xml | 1 + 8 files changed, 315 insertions(+) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTodoService.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImpl.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/todo/WxCpTodo.java create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImplTest.java 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 269a69a47..9a715c1e9 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 @@ -673,4 +673,11 @@ public interface WxCpService extends WxService { * @return 人事助手服务 hr service */ WxCpHrService getHrService(); + + /** + * 获取待办服务 + * + * @return 待办服务 todo service + */ + WxCpTodoService getTodoService(); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTodoService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTodoService.java new file mode 100644 index 000000000..82f17c230 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTodoService.java @@ -0,0 +1,47 @@ +package me.chanjar.weixin.cp.api; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.bean.todo.WxCpTodo; + +import java.util.List; + +/** + * 企业微信待办接口. + *

+ * 官方文档: + * 获取待办详情, + * 更新待办状态 + * + * @author Binary Wang created on 2026-08-11 + */ +public interface WxCpTodoService { + /** + * 获取待办详情. + *

+ * 该接口用于获取指定的待办详情,请求参数仅包含必填的 todo_id,响应直接返回单个待办对象。 + *

+ * 请求方式: POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/todo/get?access_token=ACCESS_TOKEN + * + * @param todoId 待办ID + * @return 待办详情 wx cp todo + * @throws WxErrorException the wx error exception + */ + WxCpTodo get(String todoId) throws WxErrorException; + + /** + * 更新待办状态. + *

+ * 该接口用于修改指定的待办信息,支持修改待办整体状态(status 字段)、待办参与人及其状态(attendees[].userid / status 字段)。 + * 仅允许修改当前应用创建的待办,不允许修改已删除的待办。 + *

+ * 请求方式: POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/todo/update?access_token=ACCESS_TOKEN + * + * @param todoId 待办ID + * @param status 待办整体状态,可不传:0 - 完成;1 - 进行中。为 null 时不修改整体状态 + * @param attendees 待办参与人列表,最多支持20个参与人。为 null 或空时不修改参与人列表 + * @throws WxErrorException the wx error exception + */ + void update(String todoId, Integer status, List attendees) throws WxErrorException; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java index a3ec703ca..e351e5844 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java @@ -77,6 +77,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH private final WxCpCorpGroupService corpGroupService = new WxCpCorpGroupServiceImpl(this); private final WxCpIntelligentRobotService intelligentRobotService = new WxCpIntelligentRobotServiceImpl(this); private final WxCpHrService hrService = new WxCpHrServiceImpl(this); + private final WxCpTodoService todoService = new WxCpTodoServiceImpl(this); /** * 全局的是否正在刷新access token的锁. @@ -753,4 +754,9 @@ public WxCpIntelligentRobotService getIntelligentRobotService() { public WxCpHrService getHrService() { return this.hrService; } + + @Override + public WxCpTodoService getTodoService() { + return this.todoService; + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImpl.java new file mode 100644 index 000000000..627784b36 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImpl.java @@ -0,0 +1,50 @@ +package me.chanjar.weixin.cp.api.impl; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.api.WxCpTodoService; +import me.chanjar.weixin.cp.bean.todo.WxCpTodo; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Todo.*; + +/** + * 企业微信待办接口实现类. + * + * @author Binary Wang created on 2026-08-11 + */ +@Slf4j +@RequiredArgsConstructor +public class WxCpTodoServiceImpl implements WxCpTodoService { + private final WxCpService cpService; + + @Override + public WxCpTodo get(String todoId) throws WxErrorException { + final Map param = new HashMap<>(1); + param.put("todo_id", todoId); + final String response = this.cpService.post(this.cpService.getWxCpConfigStorage().getApiUrl(TODO_GET), + WxCpGsonBuilder.create().toJson(param)); + return WxCpGsonBuilder.create().fromJson(response, WxCpTodo.class); + } + + @Override + public void update(String todoId, Integer status, List attendees) throws WxErrorException { + final Map param = new HashMap<>(3); + param.put("todo_id", todoId); + if (status != null) { + param.put("status", status); + } + if (attendees != null && !attendees.isEmpty()) { + param.put("attendees", attendees); + } + + this.cpService.post(this.cpService.getWxCpConfigStorage().getApiUrl(TODO_UPDATE), + WxCpGsonBuilder.create().toJson(param)); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/todo/WxCpTodo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/todo/WxCpTodo.java new file mode 100644 index 000000000..a33eb1f4c --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/todo/WxCpTodo.java @@ -0,0 +1,110 @@ +package me.chanjar.weixin.cp.bean.todo; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.experimental.Accessors; +import me.chanjar.weixin.common.bean.ToJson; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * 待办信息bean. + *

+ * 官方文档: + * 获取待办详情 + * + * @author Binary Wang created on 2026-08-11 + */ +@Data +@Accessors(chain = true) +public class WxCpTodo implements Serializable, ToJson { + private static final long serialVersionUID = -1L; + + /** + * 待办ID + */ + @SerializedName("todo_id") + private String todoId; + /** + * 待办内容 + */ + @SerializedName("content") + private String content; + /** + * 待办创建人ID + */ + @SerializedName("creator") + private String creator; + /** + * 待办状态。 + * 0 - 已完成 + * 1 - 进行中 + * 2 - 已删除 + */ + @SerializedName("status") + private Integer status; + /** + * 待办创建时间戳(整型秒数) + */ + @SerializedName("create_time") + private Long createTime; + /** + * 待办参与人列表 + */ + @SerializedName("attendees") + private List attendees; + /** + * 待办截止时间戳(整型秒数) + */ + @SerializedName("end_time") + private Long endTime; + /** + * 提醒列表 + */ + @SerializedName("reminders") + private List reminders; + + @Override + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 待办参与人. + */ + @Data + @Accessors(chain = true) + public static class Attendee implements Serializable { + private static final long serialVersionUID = -1L; + + /** + * 待办参与人ID + */ + @SerializedName("userid") + private String userid; + /** + * 参与人的待办状态。 + * 0 - 完成 + * 1 - 进行中 + */ + @SerializedName("status") + private Integer status; + } + + /** + * 待办提醒. + */ + @Data + @Accessors(chain = true) + public static class Reminder implements Serializable { + private static final long serialVersionUID = -1L; + + /** + * 提醒时间戳(整型秒数) + */ + @SerializedName("remind_time") + private Long remindTime; + } +} 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 642e57987..d95bf0a13 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 @@ -1884,4 +1884,22 @@ interface Hr { */ String UPDATE_EMPLOYEE_FIELD_INFO = "/cgi-bin/hr/update_staff_info"; } + + /** + * 待办相关接口. + * 官方文档:https://developer.work.weixin.qq.com/document/path/101524 + */ + interface Todo { + /** + * 获取待办详情 + * https://developer.work.weixin.qq.com/document/path/101524 + */ + String TODO_GET = "/cgi-bin/todo/get"; + + /** + * 更新待办状态 + * https://developer.work.weixin.qq.com/document/path/101534 + */ + String TODO_UPDATE = "/cgi-bin/todo/update"; + } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImplTest.java new file mode 100644 index 000000000..d8569592e --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImplTest.java @@ -0,0 +1,76 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.ApiTestModule; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.todo.WxCpTodo; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.util.Arrays; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +/** + * 单元测试类. + * + * @author Binary Wang created on 2026-08-11 + */ +@Guice(modules = ApiTestModule.class) +public class WxCpTodoServiceImplTest { + /** + * The Wx service. + */ + @Inject + protected WxCpService wxService; + + private static final String TODO_ID = "17c7d2bd9f20d652840f72f59e796AAA"; + + /** + * Test get. + * + * @throws WxErrorException the wx error exception + */ + @Test + public void testGet() throws WxErrorException { + final WxCpTodo todo = this.wxService.getTodoService().get(TODO_ID); + assertNotNull(todo, "get() 返回的待办对象不应为 null"); + assertEquals(todo.getTodoId(), TODO_ID, "返回的 todo_id 应与请求一致"); + } + + /** + * Test update status only. + * + * @throws WxErrorException the wx error exception + */ + @Test + public void testUpdateStatusOnly() throws WxErrorException { + this.wxService.getTodoService().update(TODO_ID, 0, null); + // 更新成功后通过 get() 回查,验证整体状态确实写入 + final WxCpTodo todo = this.wxService.getTodoService().get(TODO_ID); + assertNotNull(todo, "回查待办不应为 null"); + assertEquals(todo.getStatus(), Integer.valueOf(0), "待办整体状态应为 0(完成)"); + } + + /** + * Test update with attendees. + * + * @throws WxErrorException the wx error exception + */ + @Test + public void testUpdateWithAttendees() throws WxErrorException { + this.wxService.getTodoService().update(TODO_ID, 1, + Arrays.asList( + new WxCpTodo.Attendee().setUserid("lisi").setStatus(0), + new WxCpTodo.Attendee().setUserid("zhangsan").setStatus(1) + )); + // 更新成功后通过 get() 回查,验证参与人列表确实写入 + final WxCpTodo todo = this.wxService.getTodoService().get(TODO_ID); + assertNotNull(todo, "回查待办不应为 null"); + assertNotNull(todo.getAttendees(), "attendees 列表不应为 null"); + assertEquals(todo.getAttendees().size(), 2, "参与人数量应为 2"); + assertEquals(todo.getStatus(), Integer.valueOf(1), "待办整体状态应为 1(进行中)"); + } +} diff --git a/weixin-java-cp/src/test/resources/testng.xml b/weixin-java-cp/src/test/resources/testng.xml index f63d3f30f..cb3b8362e 100644 --- a/weixin-java-cp/src/test/resources/testng.xml +++ b/weixin-java-cp/src/test/resources/testng.xml @@ -24,6 +24,7 @@ + From a1e317e2bcd2d769c5a8484de9cfae222cc21002 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Wed, 12 Aug 2026 13:18:07 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E7=BB=9F=E4=B8=80=E6=94=AF=E4=BB=98?= =?UTF-8?q?V3=E6=B2=99=E7=AE=B1=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/service/impl/BaseWxPayServiceImpl.java | 6 ++++++ .../service/impl/WxPayServiceApacheHttpImpl.java | 7 ------- .../impl/WxPayServiceHttpComponentsImpl.java | 4 ++++ .../service/impl/WxPayServiceSandboxTest.java | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 7 deletions(-) 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 15bd0ce34..8489f8062 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 @@ -373,6 +373,12 @@ public String getPayBaseUrl() { return this.getConfig().getApiHostWithPathPrefix(); } + protected void checkV3SandboxNotSupported() { + if (this.getConfig().isUseSandboxEnv()) { + throw new WxRuntimeException("微信支付V3 目前不支持沙箱模式!"); + } + } + @Override public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException { request.checkAndSign(this.getConfig()); 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 976cb89d6..5926bbacf 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 @@ -7,7 +7,6 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.common.error.WxRuntimeException; import me.chanjar.weixin.common.util.http.apache.ByteArrayResponseHandler; import me.chanjar.weixin.common.util.json.GsonParser; import org.apache.commons.lang3.StringUtils; @@ -306,12 +305,6 @@ private void configureRequest(HttpRequestBase request) { .build()); } - private void checkV3SandboxNotSupported() { - if (this.getConfig().isUseSandboxEnv()) { - throw new WxRuntimeException("微信支付V3 目前不支持沙箱模式!"); - } - } - private CloseableHttpClient createApiV3HttpClient() throws WxPayException { CloseableHttpClient apiV3HttpClient = this.getConfig().getApiV3HttpClient(); if (null == apiV3HttpClient) { diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceHttpComponentsImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceHttpComponentsImpl.java index cc5423302..837587e76 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceHttpComponentsImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceHttpComponentsImpl.java @@ -125,6 +125,7 @@ public String postV3(String url, String requestStr) throws WxPayException { } private String requestV3(String url, String requestStr, HttpRequestBase httpRequestBase) throws WxPayException { + this.checkV3SandboxNotSupported(); CloseableHttpClient httpClient = this.createApiV3HttpClient(); try (CloseableHttpResponse response = httpClient.execute(httpRequestBase)) { //v3已经改为通过状态码判断200 204 成功 @@ -160,6 +161,7 @@ public String patchV3(String url, String requestStr) throws WxPayException { @Override public String postV3WithWechatpaySerial(String url, String requestStr) throws WxPayException { + this.checkV3SandboxNotSupported(); HttpPost httpPost = this.createHttpPost(url, requestStr); this.configureRequest(httpPost); CloseableHttpClient httpClient = this.createApiV3HttpClient(); @@ -196,6 +198,7 @@ public String postV3(String url, HttpPost httpPost) throws WxPayException { @Override public String requestV3(String url, HttpRequestBase httpRequest) throws WxPayException { + this.checkV3SandboxNotSupported(); this.configureRequest(httpRequest); CloseableHttpClient httpClient = this.createApiV3HttpClient(); try (CloseableHttpResponse response = httpClient.execute(httpRequest)) { @@ -240,6 +243,7 @@ public String getV3WithWechatPaySerial(String url) throws WxPayException { @Override public InputStream downloadV3(String url) throws WxPayException { + this.checkV3SandboxNotSupported(); HttpGet httpGet = new WxPayV3DownloadHttpGet(url); this.configureRequest(httpGet); CloseableHttpClient httpClient = this.createApiV3HttpClient(); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceSandboxTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceSandboxTest.java index 1b4f37d9c..2daa9845a 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceSandboxTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceSandboxTest.java @@ -36,4 +36,18 @@ public void shouldRejectV3RequestWhenSandboxIsEnabled() { assertEquals(exception.getMessage(), "微信支付V3 目前不支持沙箱模式!"); } + + @Test + public void shouldRejectHttpComponentsV3RequestWhenSandboxIsEnabled() { + WxPayConfig config = new WxPayConfig(); + config.setUseSandboxEnv(true); + + WxPayServiceHttpComponentsImpl service = new WxPayServiceHttpComponentsImpl(); + service.setConfig(config); + + WxRuntimeException exception = expectThrows(WxRuntimeException.class, + () -> service.postV3("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi", "{}")); + + assertEquals(exception.getMessage(), "微信支付V3 目前不支持沙箱模式!"); + } }