1
0
mirror of synced 2025-12-15 11:41:42 +08:00

Compare commits

...

12 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
4bf69cbbc6 修复商家转账API路径错误
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
2025-12-05 04:48:38 +00:00
copilot-swe-agent[bot]
aa94c5c4d4 Initial plan 2025-12-05 04:31:36 +00:00
Copilot
4e46486f2c 🎨 #3598 【企业微信】 会话存档接口添加对音视频通话(voiptext)消息类型的支持 2025-12-04 19:43:15 +08:00
Copilot
219a8f4f36 🎨 #3620 【小程序】修复同城配送API签名错误问题(添加RSA私钥序列号到签名payload和请求头) 2025-12-04 19:40:03 +08:00
Copilot
cd4317ab3e 🎨 #3384 【公众号】为 starter 添加 HttpComponents (httpclient5) 支持 2025-12-04 19:38:10 +08:00
Copilot
085125960b 🎨 #3608 【微信支付】修复 fullPublicKeyModel 配置在 Spring Boot Starter 和 Solon 插件中无效的问题 2025-12-03 17:27:24 +08:00
Copilot
524762704c 🆕 #3524 【小程序】添加多端登录 code2VerifyInfo 接口的支持 2025-12-03 17:25:53 +08:00
Copilot
f7a196c129 🎨 修复支付公钥模式下回调验证serialNumber空指针异常 2025-12-02 12:08:01 +08:00
Copilot
3bf3595dc1 🎨 修复 WxCpApprovalWorkflowDemo.java 的兼容性和编译错误 2025-12-02 12:03:03 +08:00
Copilot
4d0617f7bf 🐛 #3515 修复OkHttp请求方式时代理认证头设置错误的问题 2025-12-02 11:24:40 +08:00
Binary Wang
fd3bbde725 🔖 发布 4.7.9.B 测试版本 2025-11-28 22:37:15 +08:00
Binary Wang
84e70febdf update agent description
更新代理名称和描述为中文,并强调提交信息也需使用中文。
2025-11-28 21:54:48 +08:00
62 changed files with 262 additions and 66 deletions

View File

@@ -4,10 +4,10 @@
# To make this agent available, merge this file into the default repository branch.
# For format details, see: https://gh.io/customagents/config
name: 自定义的
description: 需要用中文
name: 全部用中文
description: 需要用中文包括PR标题和分析总结过程
---
# My Agent
请使用中文输出思考过程和总结提交commit信息也要使用中文
请使用中文输出思考过程和总结,包括PR标题提交commit信息也要使用中文

View File

@@ -65,7 +65,6 @@
1. [`WxJava` 荣获 `GitCode` 2024年度十大开源社区奖项](https://mp.weixin.qq.com/s/wM_UlMsDm3IZ1CPPDvcvQw)。
2. 项目合作洽谈请联系微信`binary0000`在微信里自行搜索并添加好友请注明来意如有关于SDK问题需讨论请参考下文入群讨论不要加此微信
3. **2024-12-30 发布 [【4.7.0正式版】](https://mp.weixin.qq.com/s/_7k-XLYBqeJJhvHWCsdT0A)**
4. **从 4.7.8.B 版本开始支持 Quarkus/GraalVM Native Image详见 [【Quarkus 支持文档】](QUARKUS_SUPPORT.md)**
5. 贡献源码可以参考视频:[【贡献源码全过程(上集)】](https://mp.weixin.qq.com/s/3xUZSATWwHR_gZZm207h7Q)、[【贡献源码全过程(下集)】](https://mp.weixin.qq.com/s/nyzJwVVoYSJ4hSbwyvTx9A) ,友情提供:[程序员小山与Bug](https://space.bilibili.com/473631007)
6. 新手重要提示本项目仅是一个SDK开发工具包未提供Web实现建议使用 `maven``gradle` 引用本项目即可使用本SDK提供的各种功能详情可参考 **[【Demo项目】](demo.md)** 或本项目中的部分单元测试代码;
7. 微信开发新手请务必阅读【开发文档】([Gitee Wiki](https://gitee.com/binary/weixin-java-tools/wikis/Home) 或者 [Github Wiki](https://github.com/binarywang/WxJava/wiki))的常见问题部分,可以少走很多弯路,节省不少时间。

View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
<packaging>pom</packaging>
<name>WxJava - Weixin/Wechat Java SDK</name>
<description>微信开发Java SDK</description>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<packaging>pom</packaging>
<artifactId>wx-java-solon-plugins</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -46,13 +46,20 @@ public class WxPayAutoConfiguration {
payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
payConfig.setUseSandboxEnv(this.properties.isUseSandboxEnv());
payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl()));
//以下是apiv3以及支付分相关
payConfig.setServiceId(StringUtils.trimToNull(this.properties.getServiceId()));
payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.properties.getPayScoreNotifyUrl()));
payConfig.setPayScorePermissionNotifyUrl(StringUtils.trimToNull(this.properties.getPayScorePermissionNotifyUrl()));
payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath()));
payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath()));
payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getCertSerialNo()));
payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiv3Key()));
payConfig.setPublicKeyId(StringUtils.trimToNull(this.properties.getPublicKeyId()));
payConfig.setPublicKeyPath(StringUtils.trimToNull(this.properties.getPublicKeyPath()));
payConfig.setApiHostUrl(StringUtils.trimToNull(this.properties.getApiHostUrl()));
payConfig.setStrictlyNeedWechatPaySerial(this.properties.isStrictlyNeedWechatPaySerial());
payConfig.setFullPublicKeyModel(this.properties.isFullPublicKeyModel());
wxPayService.setConfig(payConfig);
return wxPayService;

View File

@@ -82,4 +82,40 @@ public class WxPayProperties {
*/
private boolean useSandboxEnv;
/**
* 微信支付异步回调地址通知url必须为直接可访问的url不能携带参数
*/
private String notifyUrl;
/**
* 微信支付分授权回调地址
*/
private String payScorePermissionNotifyUrl;
/**
* 公钥ID
*/
private String publicKeyId;
/**
* pub_key.pem证书文件的绝对路径或者以classpath:开头的类路径.
*/
private String publicKeyPath;
/**
* 自定义API主机地址用于替换默认的 https://api.mch.weixin.qq.com
* 例如http://proxy.company.com:8080
*/
private String apiHostUrl;
/**
* 是否将全部v3接口的请求都添加Wechatpay-Serial请求头默认不添加
*/
private boolean strictlyNeedWechatPaySerial = false;
/**
* 是否完全使用公钥模式(用以微信从平台证书到公钥的灰度切换),默认不使用
*/
private boolean fullPublicKeyModel = false;
}

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>wx-java-solon-plugins</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<packaging>pom</packaging>
<artifactId>wx-java-spring-boot-starters</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -44,6 +44,11 @@
<artifactId>okhttp</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -39,6 +39,11 @@
<artifactId>okhttp</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>

View File

@@ -4,6 +4,7 @@ import com.binarywang.spring.starter.wxjava.mp.enums.HttpClientType;
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl;
import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpComponentsImpl;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.api.impl.WxMpServiceJoddHttpImpl;
import me.chanjar.weixin.mp.api.impl.WxMpServiceOkHttpImpl;
@@ -35,6 +36,9 @@ public class WxMpServiceAutoConfiguration {
case HttpClient:
wxMpService = newWxMpServiceHttpClientImpl();
break;
case HttpComponents:
wxMpService = newWxMpServiceHttpComponentsImpl();
break;
default:
wxMpService = newWxMpServiceImpl();
break;
@@ -60,4 +64,8 @@ public class WxMpServiceAutoConfiguration {
return new WxMpServiceJoddHttpImpl();
}
private WxMpService newWxMpServiceHttpComponentsImpl() {
return new WxMpServiceHttpComponentsImpl();
}
}

View File

@@ -19,4 +19,8 @@ public enum HttpClientType {
* JoddHttp.
*/
JoddHttp,
/**
* HttpComponents (Apache HttpClient 5.x).
*/
HttpComponents,
}

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -62,6 +62,8 @@ public class WxPayAutoConfiguration {
payConfig.setPublicKeyId(StringUtils.trimToNull(this.properties.getPublicKeyId()));
payConfig.setPublicKeyPath(StringUtils.trimToNull(this.properties.getPublicKeyPath()));
payConfig.setApiHostUrl(StringUtils.trimToNull(this.properties.getApiHostUrl()));
payConfig.setStrictlyNeedWechatPaySerial(this.properties.isStrictlyNeedWechatPaySerial());
payConfig.setFullPublicKeyModel(this.properties.isFullPublicKeyModel());
wxPayService.setConfig(payConfig);
return wxPayService;

View File

@@ -106,4 +106,14 @@ public class WxPayProperties {
*/
private String apiHostUrl;
/**
* 是否将全部v3接口的请求都添加Wechatpay-Serial请求头默认不添加
*/
private boolean strictlyNeedWechatPaySerial = false;
/**
* 是否完全使用公钥模式(用以微信从平台证书到公钥的灰度切换),默认不使用
*/
private boolean fullPublicKeyModel = false;
}

View File

@@ -3,7 +3,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<artifactId>weixin-graal</artifactId>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<artifactId>weixin-java-channel</artifactId>

View File

@@ -41,11 +41,11 @@ public class WxChannelServiceOkHttpImpl extends BaseWxChannelServiceImpl<OkHttpC
this.httpProxy = OkHttpProxyInfo.httpProxy(this.config.getHttpProxyHost(), this.config.getHttpProxyPort(), this.config.getHttpProxyUsername(), this.config.getHttpProxyPassword());
okhttp3.OkHttpClient.Builder clientBuilder = new okhttp3.OkHttpClient.Builder();
clientBuilder.proxy(this.getRequestHttpProxy().getProxy());
clientBuilder.authenticator(new Authenticator() {
clientBuilder.proxyAuthenticator(new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic(WxChannelServiceOkHttpImpl.this.httpProxy.getProxyUsername(), WxChannelServiceOkHttpImpl.this.httpProxy.getProxyPassword());
return response.request().newBuilder().header("Authorization", credential).build();
return response.request().newBuilder().header("Proxy-Authorization", credential).build();
}
});
this.httpClient = clientBuilder.build();

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<artifactId>weixin-java-common</artifactId>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<artifactId>weixin-java-cp</artifactId>

View File

@@ -86,12 +86,12 @@ public class WxCpServiceOkHttpImpl extends BaseWxCpServiceImpl<OkHttpClient, OkH
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
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();
}
});

View File

@@ -202,6 +202,12 @@ public class WxCpChatModel implements Serializable {
@SerializedName("sphfeed")
private SphFeed sphFeed;
/**
* 音视频通话消息
*/
@SerializedName("voiptext")
private VoipText voipText;
/**
* From json wx cp chat model.
*
@@ -1333,4 +1339,40 @@ public class WxCpChatModel implements Serializable {
}
/**
* 音视频通话消息
*/
@Getter
@Setter
public static class VoipText implements Serializable {
private static final long serialVersionUID = -5028321625140879571L;
@SerializedName("callduration")
private Integer callDuration;
@SerializedName("invitetype")
private Integer inviteType;
/**
* From json voip text.
*
* @param json the json
* @return the voip text
*/
public static VoipText fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, VoipText.class);
}
/**
* To json string.
*
* @return the string
*/
public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}
}
}

View File

@@ -108,12 +108,12 @@ public class WxCpTpServiceOkHttpImpl extends BaseWxCpTpServiceImpl<OkHttpClient,
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
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();
}
});

View File

@@ -4,6 +4,7 @@ import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.oa.WxCpApprovalDetailResult;
import me.chanjar.weixin.cp.bean.oa.WxCpApprovalInfo;
import me.chanjar.weixin.cp.bean.oa.WxCpOaApplyEventRequest;
import me.chanjar.weixin.cp.bean.oa.WxCpOaApprovalTemplateResult;
import me.chanjar.weixin.cp.bean.oa.applydata.ApplyDataContent;
import me.chanjar.weixin.cp.bean.oa.applydata.ContentValue;
@@ -86,14 +87,14 @@ public class WxCpApprovalWorkflowDemo {
System.out.println("审批单号: " + detail.getSpNo());
System.out.println("审批名称: " + detail.getSpName());
System.out.println("审批状态: " + detail.getSpStatus().getCode());
System.out.println("申请人: " + detail.getApplyer().getUserId());
System.out.println("审批状态: " + detail.getSpStatus());
System.out.println("申请人: " + detail.getApplier().getUserId());
System.out.println("申请时间: " + detail.getApplyTime());
// 打印审批记录
if (detail.getSpRecord() != null) {
detail.getSpRecord().forEach(record -> {
System.out.println("审批节点状态: " + record.getSpStatus());
if (detail.getSpRecords() != null) {
Arrays.stream(detail.getSpRecords()).forEach(record -> {
System.out.println("审批节点状态: " + record.getStatus());
System.out.println("审批人: " + record.getDetails());
});
}
@@ -112,7 +113,7 @@ public class WxCpApprovalWorkflowDemo {
WxCpApprovalInfo approvalInfo = wxCpService.getOaService()
.getApprovalInfo(startTime, endTime, "0", 100, null);
System.out.println("获取到的审批单数量: " + approvalInfo.getCount());
System.out.println("获取到的审批单数量: " + (approvalInfo.getSpNoList() != null ? approvalInfo.getSpNoList().size() : 0));
// 遍历审批单号
if (approvalInfo.getSpNoList() != null) {
@@ -130,7 +131,7 @@ public class WxCpApprovalWorkflowDemo {
public void templateManagement() throws Exception {
// 获取模板详情
String templateId = "3Tka1eD6v6JfzhDMqPd3aMkFdxqtJMc2ZRioUBGCNS";
var templateResult = wxCpService.getOaService().getTemplateDetail(templateId);
WxCpOaApprovalTemplateResult templateResult = wxCpService.getOaService().getTemplateDetail(templateId);
System.out.println("模板名称: " + templateResult.getTemplateNames());
System.out.println("模板内容: " + templateResult.getTemplateContent());

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<artifactId>weixin-java-miniapp</artifactId>

View File

@@ -1,5 +1,6 @@
package cn.binarywang.wx.miniapp.api;
import cn.binarywang.wx.miniapp.bean.WxMaCode2VerifyInfoResult;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
@@ -87,4 +88,18 @@ public interface WxMaUserService {
* @return .
*/
boolean checkUserInfo(String sessionKey, String rawData, String signature);
/**
* 多端登录验证接口.
* <p>
* 通过 code 换取用户登录态信息,用于多端登录场景(如手表端)。
* </p>
* 文档地址:<a href="https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/miniapp/openapi/code2Verifyinfo.html">多端登录</a>
*
* @param code 登录时获取的 code
* @param checkcode 手表授权页面返回的 checkcode
* @return 登录验证结果,包含 session_key、openid、unionid 和 is_limit 字段
* @throws WxErrorException 调用微信接口失败时抛出
*/
WxMaCode2VerifyInfoResult getCode2VerifyInfo(String code, String checkcode) throws WxErrorException;
}

View File

@@ -912,6 +912,10 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
String rndStr = UUID.randomUUID().toString().replace("-", "").substring(0, 30);
String aesKey = this.getWxMaConfig().getApiSignatureAesKey();
String aesKeySn = this.getWxMaConfig().getApiSignatureAesKeySn();
String rsaKeySn = this.getWxMaConfig().getApiSignatureRsaPrivateKeySn();
if (rsaKeySn == null || rsaKeySn.isEmpty()) {
throw new SecurityException("ApiSignatureRsaPrivateKeySn不能为空请检查配置");
}
jsonObject.addProperty("_n", rndStr);
jsonObject.addProperty("_appid", appId);
@@ -956,7 +960,7 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
String requestJson = reqData.toString();
// 计算签名 RSA
String payload = urlPath + "\n" + appId + "\n" + timestamp + "\n" + requestJson;
String payload = urlPath + "\n" + appId + "\n" + timestamp + "\n" + rsaKeySn + "\n" + requestJson;
byte[] dataBuffer = payload.getBytes(StandardCharsets.UTF_8);
RSAPrivateKey priKey;
try {
@@ -985,6 +989,7 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
header.put("Wechatmp-Signature", signatureString);
header.put("Wechatmp-Appid", appId);
header.put("Wechatmp-TimeStamp", String.valueOf(timestamp));
header.put("Wechatmp-Serial", rsaKeySn);
log.debug("发送请求uri:{}, headers:{}, postData:{}", url, header, requestJson);
WxMaApiResponse response =
this.execute(ApiSignaturePostRequestExecutor.create(this), url, header, requestJson);

View File

@@ -32,12 +32,12 @@ public class WxMaServiceOkHttpImpl extends BaseWxMaServiceImpl<OkHttpClient, OkH
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
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();
}
});

View File

@@ -2,6 +2,7 @@ package cn.binarywang.wx.miniapp.api.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.bean.WxMaCode2VerifyInfoResult;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
@@ -18,6 +19,7 @@ import org.apache.commons.codec.digest.DigestUtils;
import java.util.Map;
import static cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants.User.CODE_2_VERIFY_INFO_URL;
import static cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants.User.GET_PHONE_NUMBER_URL;
import static cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants.User.SET_USER_STORAGE;
@@ -86,4 +88,13 @@ public class WxMaUserServiceImpl implements WxMaUserService {
return generatedSignature.equals(signature);
}
@Override
public WxMaCode2VerifyInfoResult getCode2VerifyInfo(String code, String checkcode) throws WxErrorException {
JsonObject param = new JsonObject();
param.addProperty("code", code);
param.addProperty("checkcode", checkcode);
String responseContent = this.service.post(CODE_2_VERIFY_INFO_URL, param.toString());
return WxMaCode2VerifyInfoResult.fromJson(responseContent);
}
}

View File

@@ -0,0 +1,44 @@
package cn.binarywang.wx.miniapp.bean;
import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* <pre>
* 多端登录验证接口的响应
* 文档地址https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/miniapp/openapi/code2Verifyinfo.html
*
* 微信返回报文:{"errcode": 0, "errmsg": "ok", "session_key":"xxx", "openid":"xxx", "unionid":"xxx", "is_limit": false}
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class WxMaCode2VerifyInfoResult implements Serializable {
private static final long serialVersionUID = -2468325025088437364L;
@SerializedName("session_key")
private String sessionKey;
@SerializedName("openid")
private String openid;
@SerializedName("unionid")
private String unionid;
/**
* 是否为受限用户
*/
@SerializedName("is_limit")
private Boolean isLimit;
public static WxMaCode2VerifyInfoResult fromJson(String json) {
return WxMaGsonBuilder.create().fromJson(json, WxMaCode2VerifyInfoResult.class);
}
}

View File

@@ -364,6 +364,8 @@ public class WxMaApiUrlConstants {
String SET_USER_STORAGE =
"https://api.weixin.qq.com/wxa/set_user_storage?appid=%s&signature=%s&openid=%s&sig_method=%s";
String GET_PHONE_NUMBER_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";
/** 多端登录验证接口 */
String CODE_2_VERIFY_INFO_URL = "https://api.weixin.qq.com/wxa/sec/checkcode2verifyinfo";
}
public interface Ocr {

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<artifactId>weixin-java-mp</artifactId>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<artifactId>weixin-java-open</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -21,7 +21,7 @@ public interface BusinessOperationTransferService {
* 发起运营工具商家转账
*
* 请求方式POSTHTTPS
* 请求地址https://api.mch.weixin.qq.com/v3/fund-app/operation/mch-transfer/transfer-bills
* 请求地址https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills
*
* 文档地址:<a href="https://pay.weixin.qq.com/doc/v3/merchant/4012711988">运营工具-商家转账API</a>
* </pre>
@@ -37,7 +37,7 @@ public interface BusinessOperationTransferService {
* 查询运营工具转账结果
*
* 请求方式GETHTTPS
* 请求地址https://api.mch.weixin.qq.com/v3/fund-app/operation/mch-transfer/transfer-bills/out-bill-no/{out_bill_no}
* 请求地址https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/{out_bill_no}
*
* 文档地址:<a href="https://pay.weixin.qq.com/doc/v3/merchant/4012711988">运营工具-商家转账API</a>
* </pre>
@@ -53,7 +53,7 @@ public interface BusinessOperationTransferService {
* 通过商户单号查询运营工具转账结果
*
* 请求方式GETHTTPS
* 请求地址https://api.mch.weixin.qq.com/v3/fund-app/operation/mch-transfer/transfer-bills/out-bill-no/{out_bill_no}
* 请求地址https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/{out_bill_no}
*
* 文档地址:<a href="https://pay.weixin.qq.com/doc/v3/merchant/4012711988">运营工具-商家转账API</a>
* </pre>
@@ -69,7 +69,7 @@ public interface BusinessOperationTransferService {
* 通过微信转账单号查询运营工具转账结果
*
* 请求方式GETHTTPS
* 请求地址https://api.mch.weixin.qq.com/v3/fund-app/operation/mch-transfer/transfer-bills/transfer-bill-no/{transfer_bill_no}
* 请求地址https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills/transfer-bill-no/{transfer_bill_no}
*
* 文档地址:<a href="https://pay.weixin.qq.com/doc/v3/merchant/4012711988">运营工具-商家转账API</a>
* </pre>

View File

@@ -33,7 +33,7 @@ public class BusinessOperationTransferServiceImpl implements BusinessOperationTr
request.setAppid(this.wxPayService.getConfig().getAppId());
}
String url = String.format("%s/v3/fund-app/operation/mch-transfer/transfer-bills", this.wxPayService.getPayBaseUrl());
String url = String.format("%s/v3/fund-app/mch-transfer/transfer-bills", this.wxPayService.getPayBaseUrl());
// 如果传入了用户姓名需要进行RSA加密
if (StringUtils.isNotEmpty(request.getUserName())) {
@@ -58,7 +58,7 @@ public class BusinessOperationTransferServiceImpl implements BusinessOperationTr
@Override
public BusinessOperationTransferQueryResult queryOperationTransferByOutBillNo(String outBillNo) throws WxPayException {
String url = String.format("%s/v3/fund-app/operation/mch-transfer/transfer-bills/out-bill-no/%s",
String url = String.format("%s/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/%s",
this.wxPayService.getPayBaseUrl(), outBillNo);
String response = wxPayService.getV3(url);
return GSON.fromJson(response, BusinessOperationTransferQueryResult.class);
@@ -66,7 +66,7 @@ public class BusinessOperationTransferServiceImpl implements BusinessOperationTr
@Override
public BusinessOperationTransferQueryResult queryOperationTransferByTransferBillNo(String transferBillNo) throws WxPayException {
String url = String.format("%s/v3/fund-app/operation/mch-transfer/transfer-bills/transfer-bill-no/%s",
String url = String.format("%s/v3/fund-app/mch-transfer/transfer-bills/transfer-bill-no/%s",
this.wxPayService.getPayBaseUrl(), transferBillNo);
String response = wxPayService.getV3(url);
return GSON.fromJson(response, BusinessOperationTransferQueryResult.class);

View File

@@ -24,8 +24,8 @@ public class PublicCertificateVerifier implements Verifier{
@Override
public boolean verify(String serialNumber, byte[] message, String signature) {
// 如果序列号不包含"PUB_KEY_ID"且有证书验证器,先尝试证书验证
if (!serialNumber.contains("PUB_KEY_ID") && this.certificateVerifier != null) {
// 如果序列号不为空且不包含"PUB_KEY_ID"且有证书验证器,先尝试证书验证
if (serialNumber != null && !serialNumber.contains("PUB_KEY_ID") && this.certificateVerifier != null) {
try {
if (this.certificateVerifier.verify(serialNumber, message, signature)) {
return true;

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>4.7.8.B</version>
<version>4.7.9.B</version>
</parent>
<artifactId>weixin-java-qidian</artifactId>

View File

@@ -80,11 +80,11 @@ public class WxQidianServiceOkHttpImpl extends BaseWxQidianServiceImpl<OkHttpCli
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).build();
return response.request().newBuilder().header("Proxy-Authorization", credential).build();
}
});
httpClient = clientBuilder.build();