From ce672dc55cd31def8162d0ba0903f8c724ab703e Mon Sep 17 00:00:00 2001 From: allovine Date: Thu, 16 Jan 2025 13:46:02 +0800 Subject: [PATCH 1/4] =?UTF-8?q?:new:=20#3474=20=E3=80=90=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E3=80=91=E5=A2=9E=E5=8A=A02025.1.15=E6=AD=A3?= =?UTF-8?q?=E5=BC=8F=E4=B8=8A=E7=BA=BF=E7=9A=84=E5=95=86=E6=88=B7=E8=BD=AC?= =?UTF-8?q?=E8=B4=A6=E6=96=B0=E7=89=88=E6=9C=AC=E7=9A=84=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../transfer/TransferBillsNotifyResult.java | 79 +++++++++++++ .../bean/transfer/TransferBillsRequest.java | 108 ++++++++++++++++++ .../bean/transfer/TransferBillsResult.java | 55 +++++++++ .../wxpay/service/TransferService.java | 27 +++++ .../wxpay/service/WxPayService.java | 12 ++ .../service/impl/BaseWxPayServiceImpl.java | 6 + .../service/impl/TransferServiceImpl.java | 16 +++ .../service/impl/TransferServiceImplTest.java | 14 +++ 8 files changed, 317 insertions(+) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsNotifyResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsResult.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsNotifyResult.java new file mode 100644 index 000000000..80709a102 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsNotifyResult.java @@ -0,0 +1,79 @@ +package com.github.binarywang.wxpay.bean.transfer; + +import com.github.binarywang.wxpay.bean.notify.OriginNotifyResponse; +import com.github.binarywang.wxpay.bean.notify.WxPayBaseNotifyV3Result; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ *    商家转账到零钱接口将转账结果通知用户
+ *    文档地址:https://pay.weixin.qq.com/doc/v3/merchant/4012716434
+ *  
+ */ +@Data +public class TransferBillsNotifyResult implements Serializable, WxPayBaseNotifyV3Result { + /** + * 源数据 + */ + private OriginNotifyResponse rawData; + /** + * 解密后的数据 + */ + private TransferBillsNotifyResult.DecryptNotifyResult result; + + @Data + @NoArgsConstructor + public static class DecryptNotifyResult implements Serializable { + /** + * 商户号 + */ + @SerializedName(value = "mch_id") + private String mchId; + /** + * 商家批次单号 + */ + @SerializedName(value = "out_bill_no") + private String outBillNo; + /** + * 微信批次单号 + */ + @SerializedName(value = "transfer_bill_no") + private String transferBillNo; + /** + * 批次状态 + */ + @SerializedName(value = "state") + private String state; + /** + * 转账金额 + */ + @SerializedName(value = "transfer_amount") + private Integer transferAmount; + + /** + * 批次状态 + */ + @SerializedName(value = "openid") + private String openid; + + /** + * 单据创建时间 + */ + @SerializedName(value = "create_time") + private String createTime; + /** + * 最后一次状态变更时间 + */ + @SerializedName(value = "update_time") + private String updateTime; + /** + * 错误原因 + */ + @SerializedName(value = "fail_reason") + private String failReason; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsRequest.java new file mode 100644 index 000000000..230e564e4 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsRequest.java @@ -0,0 +1,108 @@ +package com.github.binarywang.wxpay.bean.transfer; + +import com.github.binarywang.wxpay.v3.SpecEncrypt; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 发起商家转账API参数 + * + * @author allovine + * created on 2025/1/15 + **/ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class TransferBillsRequest implements Serializable { + private static final long serialVersionUID = -2175582517588397437L; + + /** + * 直连商户的appid + */ + @SerializedName("appid") + private String appid; + + /** + * 商户系统内部的商家单号 + */ + @SerializedName("out_bill_no") + private String outBillNo; + + /** + * 转账场景ID + * 商户平台-产品中心-商家转账 申请 + * 佣金报酬 ID:1005 + */ + @SerializedName("transfer_scene_id") + private String transferSceneId; + + /** + * 用户在直连商户应用下的用户标示 + */ + @SerializedName("openid") + private String openid; + + /** + * 收款用户姓名 + */ + @SpecEncrypt + @SerializedName("user_name") + private String userName; + + /** + * 转账金额 + */ + @SerializedName("transfer_amount") + private Integer transferAmount; + + /** + * 转账备注 + */ + @SerializedName("transfer_remark") + private String transferRemark; + + /** + * 异步接收微信支付结果通知的回调地址,通知url必须为公网可访问的url,必须为https,不能携带参数 + */ + @SerializedName("notify_url") + private String notifyUrl; + + /** + * 用户收款感知 + */ + @SerializedName("user_recv_perception") + private String userRecvPerception; + + + /** + * 转账场景报备信息 + */ + @SerializedName("transfer_scene_report_infos") + private List transferSceneReportInfos; + + + @Data + @Builder(builderMethodName = "newBuilder") + @AllArgsConstructor + @NoArgsConstructor + public static class TransferSceneReportInfo { + /** + * 信息类型 + */ + @SerializedName("info_type") + private String infoType; + + /** + * 信息内容 + */ + @SerializedName("info_content") + private String infoContent; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsResult.java new file mode 100644 index 000000000..9f7aac7fb --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBillsResult.java @@ -0,0 +1,55 @@ +package com.github.binarywang.wxpay.bean.transfer; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 商家转账结果 + * + * @author allovine + * created on 2025/1/15 + **/ +@Data +@NoArgsConstructor +public class TransferBillsResult implements Serializable { + private static final long serialVersionUID = -2175582517588397437L; + + /** + * 商户单号 + */ + @SerializedName("out_bill_no") + private String outBillNo; + + /** + * 微信转账单号 + */ + @SerializedName("transfer_bill_no") + private String transferBillNo; + + /** + * 单据创建时间 + */ + @SerializedName("create_time") + private String createTime; + + /** + * 单据状态 + */ + @SerializedName("status") + private String status; + + /** + * 失败原因 + */ + @SerializedName("fail_reason") + private String failReason; + + /** + * 跳转领取页面的package信息 + */ + @SerializedName("package_info") + private String packageInfo; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/TransferService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/TransferService.java index ebf746214..c02430a96 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/TransferService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/TransferService.java @@ -111,4 +111,31 @@ public interface TransferService { */ TransferBatchDetailResult transferBatchesOutBatchNoDetail(String outBatchNo, String outDetailNo) throws WxPayException; + /** + *
+   *
+   * 2025.1.15 开始新接口 发起商家转账API
+   *
+   * 请求方式:POST(HTTPS)
+   * 请求地址:请求地址
+   *
+   * 文档地址:发起商家转账API
+   * 
+ * + * @param request 转账请求参数 + * @return TransferBillsResult 转账结果 + * @throws WxPayException . + */ + TransferBillsResult transferBills(TransferBillsRequest request) throws WxPayException; + + /** + * 2025.1.15 开始新接口 解析商家转账结果 + * 详见 + * + * @param notifyData 通知数据 + * @param header 通知头部数据,不传则表示不校验头 + * @return the wx transfer notify result + * @throws WxPayException the wx pay exception + */ + TransferBillsNotifyResult parseTransferBillsNotifyResult(String notifyData, SignatureHeader header) throws WxPayException; } 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 57c2937c6..19b4ed0a0 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 @@ -6,6 +6,7 @@ import com.github.binarywang.wxpay.bean.notify.*; import com.github.binarywang.wxpay.bean.request.*; import com.github.binarywang.wxpay.bean.result.*; import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; +import com.github.binarywang.wxpay.bean.transfer.TransferBillsNotifyResult; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.constant.WxPayConstants; import com.github.binarywang.wxpay.exception.WxPayException; @@ -991,6 +992,17 @@ public interface WxPayService { */ WxPayTransferBatchesNotifyV3Result parseTransferBatchesNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException; + /** + * 解析商家转账批次回调通知 + * https://pay.weixin.qq.com/doc/v3/merchant/4012712115 + * + * @param notifyData + * @param header + * @return + * @throws WxPayException + */ + TransferBillsNotifyResult parseTransferBillsNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException; + /** * 解析服务商模式退款结果通知 * 详见https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_11.shtml 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 c9fc1e7bd..7c2055cec 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 @@ -11,6 +11,7 @@ import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult; import com.github.binarywang.wxpay.bean.request.*; import com.github.binarywang.wxpay.bean.result.*; import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; +import com.github.binarywang.wxpay.bean.transfer.TransferBillsNotifyResult; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.config.WxPayConfigHolder; import com.github.binarywang.wxpay.constant.WxPayConstants; @@ -442,6 +443,11 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { return this.baseParseOrderNotifyV3Result(notifyData, header, WxPayTransferBatchesNotifyV3Result.class, WxPayTransferBatchesNotifyV3Result.DecryptNotifyResult.class); } + @Override + public TransferBillsNotifyResult parseTransferBillsNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException { + return this.baseParseOrderNotifyV3Result(notifyData, header, TransferBillsNotifyResult.class, TransferBillsNotifyResult.DecryptNotifyResult.class); + } + @Override public WxPayPartnerRefundNotifyV3Result parsePartnerRefundNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException { return this.baseParseOrderNotifyV3Result(notifyData, header, WxPayPartnerRefundNotifyV3Result.class, WxPayPartnerRefundNotifyV3Result.DecryptNotifyResult.class); diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/TransferServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/TransferServiceImpl.java index e62dc9c05..23bf7b13e 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/TransferServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/TransferServiceImpl.java @@ -85,4 +85,20 @@ public class TransferServiceImpl implements TransferService { String result = this.payService.getV3(url); return GSON.fromJson(result, TransferBatchDetailResult.class); } + + @Override + public TransferBillsResult transferBills(TransferBillsRequest request) throws WxPayException { + String url = String.format("%s/v3/fund-app/mch-transfer/transfer-bills", this.payService.getPayBaseUrl()); + if (request.getUserName() != null && request.getUserName().length() > 0) { + X509Certificate validCertificate = this.payService.getConfig().getVerifier().getValidCertificate(); + RsaCryptoUtil.encryptFields(request, validCertificate); + } + String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); + return GSON.fromJson(result, TransferBillsResult.class); + } + + @Override + public TransferBillsNotifyResult parseTransferBillsNotifyResult(String notifyData, SignatureHeader header) throws WxPayException { + return this.payService.baseParseOrderNotifyV3Result(notifyData, header, TransferBillsNotifyResult.class, TransferBillsNotifyResult.DecryptNotifyResult.class); + } } diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/TransferServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/TransferServiceImplTest.java index 7f89bd472..cd607dff0 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/TransferServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/TransferServiceImplTest.java @@ -2,6 +2,7 @@ package com.github.binarywang.wxpay.service.impl; import com.github.binarywang.wxpay.bean.transfer.QueryTransferBatchesRequest; import com.github.binarywang.wxpay.bean.transfer.TransferBatchesRequest; +import com.github.binarywang.wxpay.bean.transfer.TransferBillsRequest; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.testbase.ApiTestModule; @@ -73,4 +74,17 @@ public class TransferServiceImplTest { public void testTransferBatchesOutBatchNoDetail() throws WxPayException { log.info("商家明细单号查询明细单:{}", this.payService.getTransferService().transferBatchesOutBatchNoDetail("1655447999520", "1655447989156")); } + + @Test + public void testTransferBills() throws WxPayException { + TransferBillsRequest transferBillsRequest = TransferBillsRequest.newBuilder() + .appid("wxf636efh5xxxxx") + .outBillNo("1655447989156") + .transferSceneId("1005") + .transferAmount(100) + .transferRemark("测试转账") + .openid("oX_7Jzr9gSZz4X_Xc9-_7HGf8XzI") + .userName("测试用户").build(); + log.info("发起商家转账:{}", this.payService.getTransferService().transferBills(transferBillsRequest)); + } } -- Gitee From 5c0910b6e36577b751f20414abc8259062151b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=83=E8=B4=A7?= <252048765@qq.com> Date: Fri, 4 Jul 2025 19:29:40 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat(open):=20=E6=96=B0=E5=A2=9E=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E8=AE=A4=E8=AF=81=E5=8F=8A=E5=A4=87=E6=A1=88?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 WxOpenMaAuthAndIcpService 接口及实现类,提供小程序认证及备案服务 - 添加查询认证及备案进度、提交认证及备案信息等方法 - 新增类目查询相关功能,支持获取不同类型主体可设置的类目 - 优化 ICP 备案服务,支持创建备案任务及 --- .../open/properties/WxOpenProperties.java | 15 + .../open/api/WxOpenMaAuthAndIcpService.java | 32 + .../weixin/open/api/WxOpenMaBasicService.java | 25 +- .../weixin/open/api/WxOpenMaIcpService.java | 2 +- .../weixin/open/api/WxOpenMaService.java | 7 + .../impl/WxOpenMaAuthAndIcpServiceImpl.java | 40 + .../api/impl/WxOpenMaBasicServiceImpl.java | 8 + .../open/api/impl/WxOpenMaIcpServiceImpl.java | 4 +- .../open/api/impl/WxOpenMaServiceImpl.java | 3 + .../auth/MaAuthQueryIdentityTreeResult.java | 2 +- .../WxOpenQueryAuthAndIcpResult.java | 134 +++ .../WxOpenSubmitAuthAndIcpParam.java | 767 ++++++++++++++++++ .../WxOpenSubmitAuthAndIcpResult.java | 52 ++ .../icp/WxOpenCreateIcpVerifyTaskParam.java | 26 + .../WxOpenIcpCreateIcpVerifyTaskResult.java | 8 +- .../open/bean/message/WxOpenXmlMessage.java | 43 +- .../WxOpenGetAllCategoriesByTypeResult.java | 153 ++++ 17 files changed, 1306 insertions(+), 15 deletions(-) create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaAuthAndIcpService.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaAuthAndIcpServiceImpl.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenQueryAuthAndIcpResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenSubmitAuthAndIcpParam.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenSubmitAuthAndIcpResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/icp/WxOpenCreateIcpVerifyTaskParam.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenGetAllCategoriesByTypeResult.java diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java index 641c57b00..293d25139 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java @@ -108,6 +108,21 @@ public class WxOpenProperties { */ private int maxRetryTimes = 5; + /** + * 连接超时时间,单位毫秒 + */ + private int connectionTimeout = 5000; + + /** + * 读数据超时时间,即socketTimeout,单位毫秒 + */ + private int soTimeout = 1; + + /** + * 从连接池获取链接的超时时间,单位毫秒 + */ + private int connectionRequestTimeout = 5000; + } public enum StorageType { diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaAuthAndIcpService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaAuthAndIcpService.java new file mode 100644 index 000000000..de2c0a0de --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaAuthAndIcpService.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.open.api; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.open.bean.authandicp.WxOpenQueryAuthAndIcpResult; +import me.chanjar.weixin.open.bean.authandicp.WxOpenSubmitAuthAndIcpParam; +import me.chanjar.weixin.open.bean.authandicp.WxOpenSubmitAuthAndIcpResult; + +/** + * 微信第三方平台 小程序认证及备案 + * @author 痴货 + * @createTime 2025/06/18 23:00 + */ +public interface WxOpenMaAuthAndIcpService { + + String QUERY_AUTH_AND_ICP = "https://api.weixin.qq.com/wxa/sec/query_auth_and_icp"; + + String SUBMIT_AUTH_AND_ICP = "https://api.weixin.qq.com/wxa/sec/submit_auth_and_icp"; + + /** + * 查询小程序认证及备案进度。 + * @param procedureId 小程序认证及备案任务流程id + * @return 小程序认证及备案进度 + */ + WxOpenQueryAuthAndIcpResult queryAuthAndIcp(String procedureId) throws WxErrorException; + + /** + * 提交小程序认证及备案信息。 + * @param param 提交小程序认证及备案信息参数 + * @return 提交结果 + */ + WxOpenSubmitAuthAndIcpResult submitAuthAndIcp(WxOpenSubmitAuthAndIcpParam param) throws WxErrorException; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaBasicService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaBasicService.java index cae5faa78..6ef8484bd 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaBasicService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaBasicService.java @@ -54,19 +54,23 @@ public interface WxOpenMaBasicService { */ String OPEN_GET_ALL_CATEGORIES = "https://api.weixin.qq.com/cgi-bin/wxopen/getallcategories"; /** - * 8.2 添加类目 + * 8.2 获取不同类型主体可设置的类目 + */ + String OPEN_GET_ALL_CATEGORIES_BY_TYPE = "https://api.weixin.qq.com/cgi-bin/wxopen/getcategoriesbytype"; + /** + * 8.3 添加类目 */ String OPEN_ADD_CATEGORY = "https://api.weixin.qq.com/cgi-bin/wxopen/addcategory"; /** - * 8.3 删除类目 + * 8.4 删除类目 */ String OPEN_DELETE_CATEGORY = "https://api.weixin.qq.com/cgi-bin/wxopen/deletecategory"; /** - * 8.4 获取账号已经设置的所有类目 + * 8.5 获取账号已经设置的所有类目 */ String OPEN_GET_CATEGORY = "https://api.weixin.qq.com/cgi-bin/wxopen/getcategory"; /** - * 8.5 修改类目 + * 8.6 修改类目 */ String OPEN_MODIFY_CATEGORY = "https://api.weixin.qq.com/cgi-bin/wxopen/modifycategory"; @@ -168,7 +172,12 @@ public interface WxOpenMaBasicService { String getAllCategories() throws WxErrorException; /** - * 8.2添加类目 + * 8.2获取不同类型主体可设置的类目 + */ + WxOpenGetAllCategoriesByTypeResult getAllCategoriesByType(String verifyType) throws WxErrorException; + + /** + * 8.3添加类目 * * @param categoryList 类目列表 * @return . @@ -177,7 +186,7 @@ public interface WxOpenMaBasicService { WxOpenResult addCategory(List categoryList) throws WxErrorException; /** - * 8.3删除类目 + * 8.4删除类目 * * @param first 一级类目ID * @param second 二级类目ID @@ -187,7 +196,7 @@ public interface WxOpenMaBasicService { WxOpenResult deleteCategory(int first, int second) throws WxErrorException; /** - * 8.4获取账号已经设置的所有类目 + * 8.5获取账号已经设置的所有类目 * * @return . * @throws WxErrorException . @@ -195,7 +204,7 @@ public interface WxOpenMaBasicService { WxFastMaBeenSetCategoryResult getCategory() throws WxErrorException; /** - * 8.5修改类目 + * 8.6修改类目 * * @param category 实体 * @return . diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaIcpService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaIcpService.java index ad59b246c..182e12c2b 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaIcpService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaIcpService.java @@ -112,7 +112,7 @@ public interface WxOpenMaIcpService { * @return 人脸核验任务结果 * @throws WxErrorException e */ - WxOpenIcpCreateIcpVerifyTaskResult createIcpVerifyTask() throws WxErrorException; + WxOpenIcpCreateIcpVerifyTaskResult createIcpVerifyTask(WxOpenCreateIcpVerifyTaskParam param) throws WxErrorException; /** * 上传小程序备案媒体材料 diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java index 7a3bbca44..fef85d7f2 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java @@ -731,6 +731,13 @@ public interface WxOpenMaService extends WxMaService { */ WxOpenMaIcpService getIcpService(); + /** + * 小程序认证及备案服务 + * + * @return 小程序认证及备案服务 + */ + WxOpenMaAuthAndIcpService getAuthAndIcpService(); + /** * 小程序用户隐私保护指引服务 * diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaAuthAndIcpServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaAuthAndIcpServiceImpl.java new file mode 100644 index 000000000..50e07d94d --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaAuthAndIcpServiceImpl.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.open.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.open.api.WxOpenMaAuthAndIcpService; +import me.chanjar.weixin.open.bean.authandicp.WxOpenQueryAuthAndIcpResult; +import me.chanjar.weixin.open.bean.authandicp.WxOpenSubmitAuthAndIcpParam; +import me.chanjar.weixin.open.bean.authandicp.WxOpenSubmitAuthAndIcpResult; +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; + +/** + * 微信第三方平台 小程序认证及备案 + * + * @author 痴货 + * @createTime 2025/06/18 23:00 + */ +public class WxOpenMaAuthAndIcpServiceImpl implements WxOpenMaAuthAndIcpService { + + private final WxMaService wxMaService; + + public WxOpenMaAuthAndIcpServiceImpl(WxMaService wxMaService) { + this.wxMaService = wxMaService; + } + + @Override + public WxOpenQueryAuthAndIcpResult queryAuthAndIcp(String procedureId) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("procedure_id", procedureId); + String response = wxMaService.post(QUERY_AUTH_AND_ICP, params); + return WxOpenGsonBuilder.create().fromJson(response, WxOpenQueryAuthAndIcpResult.class); + } + + @Override + public WxOpenSubmitAuthAndIcpResult submitAuthAndIcp(WxOpenSubmitAuthAndIcpParam param) throws WxErrorException { + String response = wxMaService.post(SUBMIT_AUTH_AND_ICP, param); + return WxMaGsonBuilder.create().fromJson(response, WxOpenSubmitAuthAndIcpResult.class); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaBasicServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaBasicServiceImpl.java index 943d61011..26a03a065 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaBasicServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaBasicServiceImpl.java @@ -95,6 +95,14 @@ public class WxOpenMaBasicServiceImpl implements WxOpenMaBasicService { return wxMaService.get(OPEN_GET_ALL_CATEGORIES, ""); } + @Override + public WxOpenGetAllCategoriesByTypeResult getAllCategoriesByType(String verifyType) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("verify_type", verifyType); + String response = wxMaService.post(OPEN_GET_ALL_CATEGORIES_BY_TYPE, params); + return WxOpenGsonBuilder.create().fromJson(response, WxOpenGetAllCategoriesByTypeResult.class); + } + @Override public WxOpenResult addCategory(List categoryList) throws WxErrorException { Map map = new HashMap<>(); diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaIcpServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaIcpServiceImpl.java index dc78f22fe..5999fee87 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaIcpServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaIcpServiceImpl.java @@ -53,8 +53,8 @@ public class WxOpenMaIcpServiceImpl implements WxOpenMaIcpService { * @throws WxErrorException e */ @Override - public WxOpenIcpCreateIcpVerifyTaskResult createIcpVerifyTask() throws WxErrorException { - String response = wxMaService.post(CREATE_ICP_VERIFY_TASK, ""); + public WxOpenIcpCreateIcpVerifyTaskResult createIcpVerifyTask(WxOpenCreateIcpVerifyTaskParam param) throws WxErrorException { + String response = wxMaService.post(CREATE_ICP_VERIFY_TASK, param); return WxMaGsonBuilder.create().fromJson(response, WxOpenIcpCreateIcpVerifyTaskResult.class); } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java index 08bfc92bf..348906035 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java @@ -56,6 +56,8 @@ public class WxOpenMaServiceImpl extends WxMaServiceImpl implements WxOpenMaServ private final WxOpenMaShoppingOrdersService shoppingOrdersService; @Getter private final WxOpenMaEmbeddedService embeddedService; + @Getter + private final WxOpenMaAuthAndIcpService authAndIcpService; public WxOpenMaServiceImpl(WxOpenComponentService wxOpenComponentService, String appId, WxMaConfig wxMaConfig) { this.wxOpenComponentService = wxOpenComponentService; @@ -67,6 +69,7 @@ public class WxOpenMaServiceImpl extends WxMaServiceImpl implements WxOpenMaServ this.privacyService = new WxOpenMaPrivacyServiceImpl(this); this.shoppingOrdersService = new WxOpenMaShoppingOrdersServiceImpl(this); this.embeddedService = new WxOpenMaEmbeddedServiceImpl(this); + this.authAndIcpService = new WxOpenMaAuthAndIcpServiceImpl(this); initHttp(); } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/MaAuthQueryIdentityTreeResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/MaAuthQueryIdentityTreeResult.java index c3960a2b5..b7660d6da 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/MaAuthQueryIdentityTreeResult.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/MaAuthQueryIdentityTreeResult.java @@ -24,6 +24,6 @@ public class MaAuthQueryIdentityTreeResult extends WxOpenResult { * 子节点信息 非叶子节点必有 */ @Nullable - @SerializedName("node_list") + @SerializedName("identity_tree_list") private List nodeList; } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenQueryAuthAndIcpResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenQueryAuthAndIcpResult.java new file mode 100644 index 000000000..2c2e9e16b --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenQueryAuthAndIcpResult.java @@ -0,0 +1,134 @@ +package me.chanjar.weixin.open.bean.authandicp; + +import com.google.gson.annotations.SerializedName; +import lombok.*; +import me.chanjar.weixin.open.bean.result.WxOpenResult; + +import java.io.Serializable; +import java.util.List; + +/** + * @author 痴货 + * @Description + * @createTime 2025/06/18 23:00 + */ +@Getter +@Setter +@NoArgsConstructor +public class WxOpenQueryAuthAndIcpResult extends WxOpenResult { + + private static final long serialVersionUID = -1175687030580654852L; + + /** + * 当前任务流程状态,见下方任务流程状态枚举 + * 9 手机验证成功 + * 15 等待支付认证审核费用 + * 16 认证审核费用支付成功 + * 17 认证审核中 + * 18 认证审核驳回 + * 19 认证审核通过 + * 20 认证审核最终失败(不能再修改) + * 21 创建备案审核单失败 + * 22 备案平台审核中 + * 23 备案平台审核驳回 + * 24 备案管局审核中 + * 25 管局审核驳回 + * 26 认证及备案完成 + * 27 流程已过期 + * 28 流程已终止 + * 29 备案已撤回 + */ + @SerializedName("procedure_status") + private Integer procedureStatus; + + /** + * 小程序后台展示的认证订单号 + */ + @SerializedName("orderid") + private Integer orderId; + + /** + * 小程序认证审核单被驳回(procedure_status 为 18)时有效 + */ + @SerializedName("refill_reason") + private String refillReason; + + /** + * 小程序认证审核最终失败的原因(procedure_status 为 20)时有效 + */ + @SerializedName("fail_reason") + private String failReason; + + /** + * 小程序备案相关信息 + */ + @SerializedName("icp_audit") + private IcpAudit icpAudit; + + @Getter + @Setter + @NoArgsConstructor + public static class IcpAudit implements Serializable { + + private static final long serialVersionUID = 879913578852421216L; + + /** + * 错误提示,创建备案审核单失败时返回(procedure_status 为 21) + */ + @SerializedName("hints") + private List hints; + + /** + * 驳回原因,备案不通过时返回(procedure_status 为 23、25) + */ + @SerializedName("audit_data") + private AuditData auditData; + + /** + * 管局短信核验状态,仅当任务流程状态为 24(备案管局审核中)的时候才有效。1:等待核验中,2:核验完成,3:核验超时。 + */ + @SerializedName("sms_verify_status") + private Integer smsVerifyStatus; + + } + + @Getter + @Setter + @NoArgsConstructor + public static class AuditData implements Serializable { + + private static final long serialVersionUID = 2217833539540191890L; + + /** + * 审核不通过的字段中文名 + */ + @SerializedName("key_name") + private String keyName; + + /** + * 字段不通过的原因 + */ + @SerializedName("error") + private String error; + + /** + * 修改建议 + */ + @SerializedName("suggest") + private String suggest; + } + + @Data + @EqualsAndHashCode(callSuper = true) + public static class Hint extends WxOpenResult { + + private static final long serialVersionUID = 6585787444231265854L; + + /** + * 校验失败的字段 + */ + @SerializedName("err_field") + private String errField; + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenSubmitAuthAndIcpParam.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenSubmitAuthAndIcpParam.java new file mode 100644 index 000000000..c3377c3a8 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenSubmitAuthAndIcpParam.java @@ -0,0 +1,767 @@ +package me.chanjar.weixin.open.bean.authandicp; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.open.api.WxOpenMaIcpService; + +import java.io.Serializable; +import java.util.List; + +/** + * @author 痴货 + * @Description + * @createTime 2025/06/18 23:00 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class WxOpenSubmitAuthAndIcpParam implements Serializable { + + private static final long serialVersionUID = 5545621231231213158L; + + /** + * 认证数据 + */ + @SerializedName("auth_data") + private AuthData authData; + + /** + * 备案主体信息 + */ + @SerializedName("icp_subject") + private IcpSubject icpSubject; + + /** + * 微信小程序信息 + */ + @SerializedName("icp_applets") + private IcpApplets icpApplets; + + /** + * 其他备案媒体材料 + */ + @SerializedName("icp_materials") + private IcpMaterials icpMaterials; + + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class AuthData implements Serializable { + + private static final long serialVersionUID = 5545289494161613158L; + + /** + * 联系人信息 + */ + @SerializedName("contact_info") + private ContactInfo contactInfo; + + /** + * 发票信息,如果是服务商代缴模式,不需要填写 + */ + @SerializedName("invoice_info") + private InvoiceInfo invoiceInfo; + + /** + * 认证主体类型:1.企业;12.个体工商户;15.个人 + */ + @SerializedName("customer_type") + private Integer customerType; + + /** + * 支付方式 1:消耗服务商预购包 2:小程序开发者自行支付 + */ + @SerializedName("pay_type") + private Integer payType; + + /** + * 主体资质其他证明材料,最多上传10张图片 + */ + @SerializedName("qualification_other") + private List qualificationOther; + + /** + * 小程序账号名称 + */ + @SerializedName("account_name") + private String accountName; + + /** + * 小程序账号名称命名类型 1:基于自选词汇命名 2:基于商标命名 + */ + @SerializedName("account_name_type") + private String accountNameType; + + /** + * 名称命中关键词-补充材料,支持上传多张图片 + */ + @SerializedName("account_supplemental") + private List accountSupplemental; + + /** + * 认证类型为个人类型时可以选择要认证的身份,从 查询个人认证身份选项列表 里获取,填叶节点的name + */ + @SerializedName("auth_identification") + private String authIdentification; + + /** + * 填了 auth_identification 则必填。身份证明材料 (1)基于不同认证身份上传不同的材料;(2)认证类型=1时选填,支持上传10张图片 + */ + @SerializedName("auth_ident_material") + private List authIdentMaterial; + + /** + * 第三方联系电话 + */ + @SerializedName("third_party_phone") + private String thirdPartyPhone; + + /** + * 选择服务商代缴模式时必填。服务市场 appid,该服务市场账号主体必须与服务商账号主体一致 + */ + @SerializedName("service_appid") + private String serviceAppid; + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ContactInfo implements Serializable { + + private static final long serialVersionUID = -2962862643438222305L; + + /** + * 认证联系人姓名 + */ + @SerializedName("name") + private String name; + + /** + * 认证联系人邮箱 + */ + @SerializedName("email") + private String email; + + /** + * 认证联系人手机号 + */ + @SerializedName("mobile") + private String mobile; + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class InvoiceInfo implements Serializable { + + private static final long serialVersionUID = 4564894651613131322L; + + /** + * 发票类型 1: 不开发票 2: 电子发票 4: 增值税专票(数电类型) + */ + @SerializedName("invoice_type") + private String invoiceType; + + /** + * 发票类型=2时必填 电子发票开票信息 + */ + @SerializedName("electronic") + private Electronic electronic; + + /** + * 发票类型=4时必填 增值税专票(数电类型)开票信息 + */ + @SerializedName("vat") + private Vat vat; + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Electronic implements Serializable { + + private static final long serialVersionUID = 189498465135131444L; + + /** + * 纳税识别号(15位、17、18或20位) + */ + @SerializedName("id") + private String id; + + /** + * 发票备注(选填) + */ + @SerializedName("desc") + private String desc; + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Vat implements Serializable { + + private static final long serialVersionUID = 829892829816551512L; + + /** + * 企业电话 + */ + @SerializedName("enterprise_phone") + private String enterprisePhone; + + /** + * 纳税识别号(15位、17、18或20位) + */ + @SerializedName("id") + private String id; + + /** + * 企业注册地址 + */ + @SerializedName("enterprise_address") + private String enterpriseAddress; + + /** + * 企业开户银行(选填) + */ + @SerializedName("bank_name") + private String bankName; + + /** + * 企业银行账号(选填) + */ + @SerializedName("bank_account") + private String bankAccount; + + /** + * 发票备注(选填) + */ + @SerializedName("desc") + private String desc; + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class IcpSubject implements Serializable { + + private static final long serialVersionUID = -1256165165165165165L; + + /** + * 主体基本信息 + */ + @SerializedName("base_info") + private SubjectBaseInfo baseInfo; + + /** + * 个人主体额外信息 + */ + @SerializedName("personal_info") + private SubjectPersonalInfo personalInfo; + + /** + * 主体额外信息(个人备案时,如果存在与主体负责人信息相同的字段,则填入相同的值) + */ + @SerializedName("organize_info") + private SubjectOrganizeInfo organizeInfo; + + /** + * 主体负责人信息 + */ + @SerializedName("principal_info") + private SubjectPrincipalInfo principalInfo; + + /** + * 法人信息(非个人备案,且主体负责人不是法人时,必填) + */ + @SerializedName("legal_person_info") + private SubjectLegalPersonInfo legalPersonInfo; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SubjectBaseInfo implements Serializable { + + private static final long serialVersionUID = -1561561613212313445L; + + /** + * 主体性质,选项参考 获取单位性质,**仅支持企业、个体工商户、个人** + * {@link WxOpenMaIcpService#queryIcpSubjectTypes } + */ + @SerializedName("type") + private Integer type; + + /** + * 主办单位名称 + */ + @SerializedName("name") + private String name; + + /** + * 备案省份,使用省份代码 + */ + @SerializedName("province") + private String province; + + /** + * 备案城市,使用城市代码 + */ + @SerializedName("city") + private String city; + + /** + * 备案县区,使用县区代码 + */ + @SerializedName("district") + private String district; + + /** + * 通讯地址,必须属于备案省市区,地址开头的省市区不用填入 + */ + @SerializedName("address") + private String address; + + /** + * 主体信息备注,根据需要,如实填写 + */ + @SerializedName("comment") + private String comment; + + /** + * 主体备案号 + */ + @SerializedName("record_number") + private String recordNumber; + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SubjectPersonalInfo implements Serializable { + + private static final long serialVersionUID = -2151981561916519288L; + + /** + * 临时居住证明照片 media_id,个人备案且非本省人员,需要提供居住证、暂住证、社保证明、房产证等临时居住证明 + */ + @SerializedName("residence_permit") + private String residencePermit; + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SubjectOrganizeInfo implements Serializable { + + private static final long serialVersionUID = -1181121318132185161L; + + /** + * 主体证件类型 + * {@link WxOpenMaIcpService#queryIcpCertificateTypes} + */ + @SerializedName("certificate_type") + private Integer certificateType; + + /** + * 主体证件号码 + */ + @SerializedName("certificate_number") + private String certificateNumber; + + /** + * 主体证件住所 + */ + @SerializedName("certificate_address") + private String certificateAddress; + + /** + * 主体证件照片 media_id,如果小程序主体为非个人类型 + */ + @SerializedName("certificate_photo") + private String certificatePhoto; + + } + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SubjectPrincipalInfo implements Serializable { + + private static final long serialVersionUID = -2984191321918916511L; + + /** + * 负责人姓名 + */ + @SerializedName("name") + private String name; + + /** + * 负责人联系方式 + */ + @SerializedName("mobile") + private String mobile; + + /** + * 负责人电子邮件 + */ + @SerializedName("email") + private String email; + + /** + * 负责人应急联系方式 + */ + @SerializedName("emergency_contact") + private String emergencyContact; + + /** + * 负责人证件类型(获取证件类型 + * {@link WxOpenMaIcpService#queryIcpCertificateTypes()}) + */ + @SerializedName("certificate_type") + private Integer certificateType; + + /** + * 负责人证件号码 + */ + @SerializedName("certificate_number") + private String certificateNumber; + + /** + * 负责人证件有效期起始日期,格式为 YYYYmmdd + */ + @SerializedName("certificate_validity_date_start") + private String certificateValidityDateStart; + + /** + * 负责人证件有效期终止日期,格式为 YYYYmmdd + */ + @SerializedName("certificate_validity_date_end") + private String certificateValidityDateEnd; + + /** + * 负责人证件正面照片 media_id(身份证为人像面) + */ + @SerializedName("certificate_photo_front") + private String certificatePhotoFront; + + /** + * 负责人证件背面照片 media_id(身份证为国徽面) + */ + @SerializedName("certificate_photo_back") + private String certificatePhotoBack; + + /** + * 授权书 media_id,当主体负责人不是法人时需要主体负责人授权书,当小程序负责人不是法人时需要小程序负责人授权书 + */ + @SerializedName("authorization_letter") + private String authorizationLetter; + + /** + * 扫脸认证任务id(扫脸认证接口返回的task_id),仅小程序负责人需要扫脸,主体负责人无需扫脸 + */ + @SerializedName("verify_task_id") + private String verifyTaskId; + + } + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SubjectLegalPersonInfo implements Serializable { + + private static final long serialVersionUID = -1259198165316516161L; + + /** + * 法人代表姓名 + */ + @SerializedName("name") + private String name; + + /** + * 法人证件号码 + */ + @SerializedName("certificate_number") + private String certificateNumber; + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class IcpApplets implements Serializable { + + private static final long serialVersionUID = -2156129841651651651L; + + /** + * 微信小程序基本信息 + */ + @SerializedName("base_info") + private AppletsBaseInfo AppleBaseInfo; + + /** + * 小程序负责人信息 + */ + @SerializedName("principal_info") + private AppletsPrincipalInfo principalInfo; + + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class AppletsBaseInfo implements Serializable { + + private static final long serialVersionUID = 8404017028547715919L; + + /** + * 小程序ID,不用填写,后台自动拉取 + */ + @SerializedName("appid") + private String appId; + + /** + * 小程序名称,不用填写,后台自动拉取 + */ + @SerializedName("name") + private String name; + + /** + * 小程序服务内容类型,只能填写二级服务内容类型,最多5个 + * {@link WxOpenMaIcpService#queryIcpServiceContentTypes} + */ + @SerializedName("service_content_types") + private List serviceContentTypes; + + /** + * 前置审批项,列表中不能存在重复的前置审批类型id,如不涉及前置审批项,也需要填“以上都不涉及” + */ + @SerializedName("nrlx_details") + private List nrlxDetails; + + /** + * 请具体描述小程序实际经营内容、主要服务内容,该信息为主管部门审核重要依据,备注内容字数限制20-200字,请认真填写。 + */ + @SerializedName("comment") + private String comment; + + /** + * 小程序备案号,示例值:粤B2-20090059-1626X + * (申请小程序备案时不用填写,查询已备案详情时会返回) + */ + @SerializedName("record_number") + private String recordNumber; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class AppletsNrlxDetailItem implements Serializable { + + private static final long serialVersionUID = -9144721738792167000L; + + /** + * 前置审批类型 + * {@link WxOpenMaIcpService#queryIcpNrlxTypes} + */ + @SerializedName("type") + private Integer type; + + /** + * 前置审批号,如果前置审批类型不是“以上都不涉及”, + * 则必填,示例值:"粤-12345号 + */ + @SerializedName("code") + private String code; + + /** + * 前置审批媒体材料 media_id + */ + @SerializedName("media") + private String media; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class AppletsPrincipalInfo implements Serializable { + + private static final long serialVersionUID = 5088256283066784463L; + + /** + * 负责人姓名 + */ + @SerializedName("name") + private String name; + + /** + * 负责人联系方式 + */ + @SerializedName("mobile") + private String mobile; + + /** + * 负责人电子邮件 + */ + @SerializedName("email") + private String email; + + /** + * 负责人应急联系方式 + */ + @SerializedName("emergency_contact") + private String emergencyContact; + + /** + * 负责人证件类型 + * {@link WxOpenMaIcpService#queryIcpCertificateTypes} + */ + @SerializedName("certificate_type") + private Integer certificateType; + + /** + * 负责人证件号码 + */ + @SerializedName("certificate_number") + private String certificateNumber; + + /** + * 负责人证件有效期起始日期, + * 格式为 YYYYmmdd,示例值:"20230815" + */ + @SerializedName("certificate_validity_date_start") + private String certificateValidityDateStart; + + /** + * 负责人证件有效期终止日期, + * 格式为 YYYYmmdd, + * 如证件长期有效,请填写 "长期",示例值:"20330815" + */ + @SerializedName("certificate_validity_date_end") + private String certificateValidityDateEnd; + + /** + * 负责人证件正面照片 media_id + * (身份证为人像面) + */ + @SerializedName("certificate_photo_front") + private String certificatePhotoFront; + + /** + * 负责人证件背面照片 media_id + * (身份证为国徽面) + */ + @SerializedName("certificate_photo_back") + private String certificatePhotoBack; + + /** + * 授权书 media_id, + * 当主体负责人不是法人时需要主体负责人授权书, + * 当小程序负责人不是法人时需要小程序负责人授权书 + */ + @SerializedName("authorization_letter") + private String authorizationLetter; + + /** + * 扫脸认证任务id(扫脸认证接口返回的task_id), + * 仅小程序负责人需要扫脸,主体负责人无需扫脸 + */ + @SerializedName("verify_task_id") + private String verifyTaskId; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class IcpMaterials implements Serializable { + + private static final long serialVersionUID = -2651654844198165191L; + + /** + * 互联网信息服务承诺书 media_id,最多上传1个 + */ + @SerializedName("commitment_letter") + private List commitmentLetter; + + /** + * 主体更名函 media_id(非个人类型,且发生过更名时需要上传),最多上传1个 + */ + @SerializedName("business_name_change_letter") + private List businessNameChangeLetter; + + /** + * 党建确认函 media_id,最多上传1个 + */ + @SerializedName("party_building_confirmation_letter") + private List partyBuildingConfirmationLetter; + + /** + * 承诺视频 media_id,最多上传1个 + */ + @SerializedName("promise_video") + private List promiseVideo; + + /** + * 网站备案信息真实性责任告知书 media_id,最多上传1个 + */ + @SerializedName("authenticity_responsibility_letter") + private List authenticityResponsibilityLetter; + + /** + * 小程序备案信息真实性承诺书 media_id,最多上传1个 + */ + @SerializedName("authenticity_commitment_letter") + private List authenticityCommitmentLetter; + + /** + * 小程序建设方案书 media_id,最多上传1个 + */ + @SerializedName("website_construction_proposal") + private List websiteConstructionProposal; + + /** + * 主体其它附件 media_id,最多上传10个 + */ + @SerializedName("subject_other_materials") + private List subjectOtherMaterials; + + /** + * 小程序其它附件 media_id,最多上传10个 + */ + @SerializedName("applets_other_materials") + private List appletsOtherMaterials; + + /** + * 手持证件照 media_id,最多上传1个 + */ + @SerializedName("holding_certificate_photo") + private List holdingCertificatePhoto; + + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenSubmitAuthAndIcpResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenSubmitAuthAndIcpResult.java new file mode 100644 index 000000000..08dbc80f2 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/authandicp/WxOpenSubmitAuthAndIcpResult.java @@ -0,0 +1,52 @@ +package me.chanjar.weixin.open.bean.authandicp; + +import com.google.gson.annotations.SerializedName; +import lombok.*; +import me.chanjar.weixin.open.bean.result.WxOpenResult; + +import java.util.List; + +/** + * @author 痴货 + * @Description + * @createTime 2025/06/18 23:00 + */ +@Getter +@Setter +@NoArgsConstructor +public class WxOpenSubmitAuthAndIcpResult extends WxOpenResult { + + private static final long serialVersionUID = -1175687058498454852L; + + /** + * 错误提示 + */ + @SerializedName("hints") + private List hints; + + /** + * 小程序认证及备案任务流程 id + */ + @SerializedName("procedure_id") + private String procedureId; + + /** + * 小程序认证认证审核费用付费链接,当 pay_type 为 2 时返回 + */ + @SerializedName("pay_url") + private String payUrl; + + @Data + @EqualsAndHashCode(callSuper = true) + public static class Hint extends WxOpenResult { + + private static final long serialVersionUID = 6585787444231265854L; + + /** + * 校验失败的字段 + */ + @SerializedName("err_field") + private String errField; + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/icp/WxOpenCreateIcpVerifyTaskParam.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/icp/WxOpenCreateIcpVerifyTaskParam.java new file mode 100644 index 000000000..25be43a33 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/icp/WxOpenCreateIcpVerifyTaskParam.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.open.bean.icp; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author 痴货 + * @Description 发起小程序管理员人脸核身 + * @createTime 2025/06/21 00:20 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class WxOpenCreateIcpVerifyTaskParam { + + /** + * 小程序认证及备案二合一场景,填 true,否则为小程序备案场景。默认值为 false + */ + @SerializedName("along_with_auth") + private Boolean alongWithAuth; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/icp/WxOpenIcpCreateIcpVerifyTaskResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/icp/WxOpenIcpCreateIcpVerifyTaskResult.java index 8deb40133..f2ff3d166 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/icp/WxOpenIcpCreateIcpVerifyTaskResult.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/icp/WxOpenIcpCreateIcpVerifyTaskResult.java @@ -1,7 +1,5 @@ package me.chanjar.weixin.open.bean.icp; -import com.fasterxml.jackson.annotation.JsonProperty; - import com.google.gson.annotations.SerializedName; import lombok.Getter; import lombok.NoArgsConstructor; @@ -26,4 +24,10 @@ public class WxOpenIcpCreateIcpVerifyTaskResult extends WxOpenResult { @SerializedName("task_id") private String taskId; + /** + * 人脸核验任务url,{@link WxOpenCreateIcpVerifyTaskParam#alongWithAuth } 填 true 时返回 + */ + @SerializedName("verify_url") + private String verifyUrl; + } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java index dc6839c1a..dfa950123 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java @@ -155,6 +155,45 @@ public class WxOpenXmlMessage implements Serializable { private Integer beianStatus; //endregion + //region 小程序认证及备案的事件 infoType=notify_3rd_wxa_auth_and_icp + + /** + * 小程序认证及备案任务流程id + */ + @XStreamAlias("procedure_id") + private String procedureId; + + /** + * 任务流程状态 + * 9 手机验证成功 + * 15 等待支付认证审核费用 + * 16 认证审核费用支付成功 + * 17 认证审核中 + * 18 认证审核驳回 + * 19 认证审核通过 + * 20 认证审核最终失败(不能再修改) + * 21 创建备案审核单失败 + * 22 备案平台审核中 + * 23 备案平台审核驳回 + * 24 备案管局审核中 + * 25 管局审核驳回 + * 26 认证及备案完成 + * 27 流程已过期 + * 28 流程已终止 + * 29 备案已撤回 + */ + @XStreamAlias("procedure_status") + private Integer procedureStatus; + + //endregion + + /** + * 原始通知内容 + */ + private String context; + + //endregion + /** * 快速创建的小程序appId,已弃用,未来将删除 * @@ -277,7 +316,9 @@ public class WxOpenXmlMessage implements Serializable { WxOpenCryptUtil cryptUtil = new WxOpenCryptUtil(wxOpenConfigStorage); String plainText = cryptUtil.decryptXml(msgSignature, timestamp, nonce, encryptedXml); log.debug("解密后的原始xml消息内容:{}", plainText); - return fromXml(plainText); + WxOpenXmlMessage wxOpenXmlMessage = fromXml(plainText); + wxOpenXmlMessage.setContext(plainText); + return wxOpenXmlMessage; } public static WxMpXmlMessage fromEncryptedMpXml(String encryptedXml, WxOpenConfigStorage wxOpenConfigStorage, diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenGetAllCategoriesByTypeResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenGetAllCategoriesByTypeResult.java new file mode 100644 index 000000000..00cefeb37 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenGetAllCategoriesByTypeResult.java @@ -0,0 +1,153 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.io.Serializable; +import java.util.List; + +/** + * 获取所有类目 + * author 痴货 + */ +@Getter +@Setter +@NoArgsConstructor +public class WxOpenGetAllCategoriesByTypeResult extends WxOpenResult { + + private static final long serialVersionUID = -2845321894615646115L; + + /** + * 类目信息列表 + */ + @SerializedName("categories_list") + private CategoriesList categorieslist; + + @Getter + @Setter + @NoArgsConstructor + public static class CategoriesList implements Serializable { + + private static final long serialVersionUID = -2845321894615646115L; + + /** + * 类目信息 + */ + @SerializedName("categories") + private List categories; + } + + @Getter + @Setter + @NoArgsConstructor + public static class Categories implements Serializable { + + private static final long serialVersionUID = -284532256461546115L; + + /** + * 类目 ID + */ + @SerializedName("id") + private Integer id; + + /** + * 类目名称 + */ + @SerializedName("name") + private String name; + + /** + * 类目层级 + */ + @SerializedName("level") + private Integer level; + + /** + * 父类目 ID + */ + @SerializedName("father") + private Integer father; + + /** + * 子类目 ID + */ + @SerializedName("children") + private List children; + + /** + * 是否敏感类目(1 为敏感类目,需要提供相应资质审核;0 为非敏感类目,无需审核) + */ + @SerializedName("sensitive_type") + private Integer sensitiveType; + + /** + * sensitive_type 为 1 的类目需要提供的资质证明 + */ + @SerializedName("qualify") + private Qualify qualify; + + /** + * 类目权限范围 + */ + @SerializedName("scope") + private String scope; + + } + + @Getter + @Setter + @NoArgsConstructor + public static class Qualify implements Serializable { + + private static final long serialVersionUID = -2841894318945616115L; + + /** + * 资质证明列表 + */ + @SerializedName("exter_list") + private List exterList; + + /** + * 备注 + */ + @SerializedName("remark") + private String remark; + + } + + @Getter + @Setter + @NoArgsConstructor + public static class Exter implements Serializable { + + private static final long serialVersionUID = -2841894318945616115L; + + @SerializedName("inner_list") + private List innerList; + + } + + @Getter + @Setter + @NoArgsConstructor + public static class Inner implements Serializable { + + private static final long serialVersionUID = -15646131313516531L; + + /** + * 资质文件名称 + */ + @SerializedName("name") + private String name; + + /** + * 资质文件示例 + */ + @SerializedName("url") + private String url; + + } + +} -- Gitee From ce5313b5ab4e197e0115c4ba44c8fa9457ba95e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=83=E8=B4=A7?= <252048765@qq.com> Date: Fri, 4 Jul 2025 19:30:06 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat(config):=20=E6=B7=BB=E5=8A=A0=20HttpCl?= =?UTF-8?q?ient=20=E8=B6=85=E6=97=B6=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 WxMaProperties 和 WxMpProperties 中添加连接超时、读取超时等配置项 - 在 AbstractWxMaConfigStorageConfiguration 和 AbstractWxOpenConfigStorageConfiguration 中应用这些配置 - 更新 WxMpStorageAutoConfiguration 以支持新的超时配置 --- .../AbstractWxMaConfigStorageConfiguration.java | 16 ++++++++++++++++ .../miniapp/properties/WxMaProperties.java | 15 +++++++++++++++ .../mp/config/WxMpStorageAutoConfiguration.java | 15 +++++++++++++++ .../wxjava/mp/properties/WxMpProperties.java | 15 +++++++++++++++ ...AbstractWxOpenConfigStorageConfiguration.java | 16 ++++++++++++++++ 5 files changed, 77 insertions(+) diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/storage/AbstractWxMaConfigStorageConfiguration.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/storage/AbstractWxMaConfigStorageConfiguration.java index 6f44ac27e..bb0102253 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/storage/AbstractWxMaConfigStorageConfiguration.java +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/storage/AbstractWxMaConfigStorageConfiguration.java @@ -2,6 +2,8 @@ package com.binarywang.spring.starter.wxjava.miniapp.config.storage; import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; import org.apache.commons.lang3.StringUtils; /** @@ -10,6 +12,7 @@ import org.apache.commons.lang3.StringUtils; public abstract class AbstractWxMaConfigStorageConfiguration { protected WxMaDefaultConfigImpl config(WxMaDefaultConfigImpl config, WxMaProperties properties) { + WxMaProperties.ConfigStorage storage = properties.getConfigStorage(); config.setAppid(StringUtils.trimToNull(properties.getAppid())); config.setSecret(StringUtils.trimToNull(properties.getSecret())); config.setToken(StringUtils.trimToNull(properties.getToken())); @@ -24,6 +27,19 @@ public abstract class AbstractWxMaConfigStorageConfiguration { config.setHttpProxyPort(configStorageProperties.getHttpProxyPort()); } + // 设置自定义的HttpClient超时配置 + ApacheHttpClientBuilder clientBuilder = config.getApacheHttpClientBuilder(); + if (clientBuilder == null) { + clientBuilder = DefaultApacheHttpClientBuilder.get(); + } + if (clientBuilder instanceof DefaultApacheHttpClientBuilder) { + DefaultApacheHttpClientBuilder defaultBuilder = (DefaultApacheHttpClientBuilder) clientBuilder; + defaultBuilder.setConnectionTimeout(storage.getConnectionTimeout()); + defaultBuilder.setSoTimeout(storage.getSoTimeout()); + defaultBuilder.setConnectionRequestTimeout(storage.getConnectionRequestTimeout()); + config.setApacheHttpClientBuilder(defaultBuilder); + } + int maxRetryTimes = configStorageProperties.getMaxRetryTimes(); if (configStorageProperties.getMaxRetryTimes() < 0) { maxRetryTimes = 0; diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java index b7ccb4537..39fc9b29a 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java @@ -107,6 +107,21 @@ public class WxMaProperties { * */ private int maxRetryTimes = 5; + + /** + * 连接超时时间,单位毫秒 + */ + private int connectionTimeout = 5000; + + /** + * 读数据超时时间,即socketTimeout,单位毫秒 + */ + private int soTimeout = 5000; + + /** + * 从连接池获取链接的超时时间,单位毫秒 + */ + private int connectionRequestTimeout = 5000; } } diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java index deb527e69..4c0938454 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java @@ -9,6 +9,8 @@ import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.redis.JedisWxRedisOps; import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; import me.chanjar.weixin.common.redis.WxRedisOps; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; import me.chanjar.weixin.mp.config.WxMpConfigStorage; import me.chanjar.weixin.mp.config.WxMpHostConfig; import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; @@ -122,6 +124,19 @@ public class WxMpStorageAutoConfiguration { config.setSecret(properties.getSecret()); config.setToken(properties.getToken()); config.setAesKey(properties.getAesKey()); + WxMpProperties.ConfigStorage storage = properties.getConfigStorage(); + // 设置自定义的HttpClient超时配置 + ApacheHttpClientBuilder clientBuilder = config.getApacheHttpClientBuilder(); + if (clientBuilder == null) { + clientBuilder = DefaultApacheHttpClientBuilder.get(); + } + if (clientBuilder instanceof DefaultApacheHttpClientBuilder) { + DefaultApacheHttpClientBuilder defaultBuilder = (DefaultApacheHttpClientBuilder) clientBuilder; + defaultBuilder.setConnectionTimeout(storage.getConnectionTimeout()); + defaultBuilder.setSoTimeout(storage.getSoTimeout()); + defaultBuilder.setConnectionRequestTimeout(storage.getConnectionRequestTimeout()); + config.setApacheHttpClientBuilder(defaultBuilder); + } config.setUseStableAccessToken(wxMpProperties.isUseStableAccessToken()); config.setHttpProxyHost(configStorageProperties.getHttpProxyHost()); config.setHttpProxyUsername(configStorageProperties.getHttpProxyUsername()); diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java index a01fc0a52..ebd6f5772 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/properties/WxMpProperties.java @@ -102,6 +102,21 @@ public class WxMpProperties { */ private String httpProxyPassword; + /** + * 连接超时时间,单位毫秒 + */ + private int connectionTimeout = 5000; + + /** + * 读数据超时时间,即socketTimeout,单位毫秒 + */ + private int soTimeout = 1; + + /** + * 从连接池获取链接的超时时间,单位毫秒 + */ + private int connectionRequestTimeout = 5000; + } } diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/storage/AbstractWxOpenConfigStorageConfiguration.java b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/storage/AbstractWxOpenConfigStorageConfiguration.java index ee0443c9a..748ce80cd 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/storage/AbstractWxOpenConfigStorageConfiguration.java +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/storage/AbstractWxOpenConfigStorageConfiguration.java @@ -1,6 +1,8 @@ package com.binarywang.spring.starter.wxjava.open.config.storage; import com.binarywang.spring.starter.wxjava.open.properties.WxOpenProperties; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; /** @@ -28,6 +30,20 @@ public abstract class AbstractWxOpenConfigStorageConfiguration { } config.setRetrySleepMillis(retrySleepMillis); config.setMaxRetryTimes(maxRetryTimes); + + // 设置自定义的HttpClient超时配置 + ApacheHttpClientBuilder clientBuilder = config.getApacheHttpClientBuilder(); + if (clientBuilder == null) { + clientBuilder = DefaultApacheHttpClientBuilder.get(); + } + if (clientBuilder instanceof DefaultApacheHttpClientBuilder) { + DefaultApacheHttpClientBuilder defaultBuilder = (DefaultApacheHttpClientBuilder) clientBuilder; + defaultBuilder.setConnectionTimeout(storage.getConnectionTimeout()); + defaultBuilder.setSoTimeout(storage.getSoTimeout()); + defaultBuilder.setConnectionRequestTimeout(storage.getConnectionRequestTimeout()); + config.setApacheHttpClientBuilder(defaultBuilder); + } + return config; } } -- Gitee From 1eeaca6c69be77d5e1121ee9831f127e162af30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=83=E8=B4=A7?= <252048765@qq.com> Date: Fri, 4 Jul 2025 19:30:16 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat(miniapp):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E5=9F=BA=E6=9C=AC=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加小程序基本信息通知事件相关的字段和解析逻辑 - 新增 ret、first、second、reason、weAppReason、nickname 和 context 字段 - 修改 fromEncryptedXml 方法,将解密后的原始通知内容保存到 context 字段 --- .../wx/miniapp/bean/WxMaMessage.java | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) 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..d6543492c 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 @@ -212,6 +212,51 @@ public class WxMaMessage implements Serializable { @XStreamAlias("SubscribeMsgSentEvent") private WxMaSubscribeMsgEvent.SubscribeMsgSentEvent subscribeMsgSentEvent; + // 小程序基本信息 + + //region 小程序基本信息 infoType=notify_3rd_wxa_auth_and_icp + + /** + * 返回值 + */ + @XStreamAlias("ret") + private String ret; + + /** + * 一级类目id + */ + @XStreamAlias("first") + private String first; + + /** + * 二级类目id + */ + @XStreamAlias("second") + private String second; + + /** + * 驳回原因 + */ + @XStreamAlias("reason") + private String reason; + + /** + * 小程序代码审核驳回原因 + */ + @XStreamAlias("Reason") + private String weAppReason; + + /** + * 昵称 + */ + @XStreamAlias("nickname") + private String nickname; + + /** + * 原始通知内容 + */ + private String context; + /** * 不要直接使用这个字段, * 这个字段只是为了适配 SubscribeMsgPopupEvent SubscribeMsgChangeEvent SubscribeMsgSentEvent @@ -261,7 +306,9 @@ public class WxMaMessage implements Serializable { WxMaConfig wxMaConfig, String timestamp, String nonce, String msgSignature) { String plainText = new WxMaCryptUtils(wxMaConfig).decryptXml(msgSignature, timestamp, nonce, encryptedXml); - return fromXml(plainText); + WxMaMessage wxMaMessage = fromXml(plainText); + wxMaMessage.setContext(plainText); + return wxMaMessage; } public static WxMaMessage fromEncryptedXml(InputStream is, WxMaConfig wxMaConfig, String timestamp, -- Gitee