WxJava Documentation

微信开发 Java SDK ,支持包括微信支付,开放平台,小程序,企业微信,视频号,公众号等的后端开发

33,017 stars Java Java 1 file · ~11,578 tokens #cp#hacktoberfest#java#miniapp#miniprogram#mp#open#sdk
RAW Doc

File: README.md

WxJava - 微信开发 Java SDK










微信 `Java` 开发工具包,支持包括微信支付、开放平台、公众号、企业微信、视频号、小程序等微信功能模块的后端开发。

特别赞助

赞助商招募中,欢迎联系合作。

关注公众号

想获得技术交流群(QQ群/微信群/钉钉群)等信息,请扫码关注 WxJava 公众号:

目录索引

快速开始(3分钟)

  1. 根据业务场景选择模块(见下方“我该选哪个模块?”)
  2. 引入 Maven 依赖并选择对应模块
  3. 参考最小示例完成初始化并调用 API

AI 编程智能体 SKILL 安装

仓库的 skills 目录提供面向 WxJava 用户和贡献者的通用 SKILL,包括模块选择、接入、排障、接口贡献和升级迁移。每个 SKILL 都以 SKILL.md 为入口,可用于支持该约定的 AI 编程智能体。

支持远程安装 SKILL 的智能体,可以直接使用自然语言指令安装所需目录。例如:

安装 https://github.com/binarywang/WxJava/tree/develop/skills/wxjava-integration-guide 中的技能。

可安装的 SKILL 包括:

不支持远程安装时,可将所需的 skills/wxjava-* 目录复制到智能体的 SKILL 目录或工作区配置目录;不同智能体的目录和启用方式请以其官方文档为准。

以 Codex 为例,可复制到个人 SKILL 目录:

shell
git clone https://github.com/binarywang/WxJava.git
mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
cp -R WxJava/skills/wxjava-* "${CODEX_HOME:-$HOME/.codex}/skills/"

如果已在本仓库根目录,可直接执行:

shell
mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
cp -R skills/wxjava-* "${CODEX_HOME:-$HOME/.codex}/skills/"

重启或新建智能体会话后,即可按需使用。例如:使用 wxjava-integration-guide 为我的 Spring Boot 项目接入微信支付。

我该选哪个模块?

业务场景 模块 artifactId
微信公众号开发 MP weixin-java-mp
微信小程序开发 MiniApp weixin-java-miniapp
微信支付 Pay weixin-java-pay
企业微信 CP weixin-java-cp
微信开放平台(第三方平台) Open weixin-java-open
视频号 / 微信小店 Channel weixin-java-channel

移动端(iOS/Android)微信登录、分享等能力仍需集成微信官方客户端 SDK;本项目为服务端 SDK。

重要信息

  1. WxJava 荣获 GitCode 2024年度十大开源社区奖项。
  2. 项目合作洽谈请联系微信binary0000(在微信里自行搜索并添加好友,请注明来意,如有关于SDK问题需讨论请参考下文入群讨论,不要加此微信)。
  3. 2026-01-03 发布 【4.8.0正式版】!
  4. 贡献源码可以参考视频:【贡献源码全过程(上集)】、【贡献源码全过程(下集)】 ,友情提供:程序员小山与Bug
  5. 新手重要提示:本项目仅是一个SDK开发工具包,未提供Web实现,建议使用 maven 或 gradle 引用本项目即可使用本SDK提供的各种功能,详情可参考 【Demo项目】 或本项目中的部分单元测试代码;
  6. 微信开发新手请务必阅读【开发文档】(Gitee Wiki 或者 Github Wiki)的常见问题部分,可以少走很多弯路,节省不少时间。
  7. 技术交流群:想获得QQ群/微信群/钉钉企业群等信息的同学,请使用微信扫描上面的微信公众号二维码关注 WxJava 后点击相关菜单即可获取加入方式,同时也可以在微信中搜索 weixin-java-tools 或 WxJava 后选择正确的公众号进行关注,该公众号会及时通知SDK相关更新信息,并不定期分享微信Java开发相关技术知识;
  8. 钉钉技术交流群:32206329(技术交流2群), 30294972(技术交流1群,目前已满),35724728(通知群,实时通知Github项目变更记录)。
  9. 微信开发新手或者Java开发新手在群内提问或新开Issue提问前,请先阅读【提问的智慧】,并确保已查阅过 【开发文档Wiki】 ,避免浪费大家的宝贵时间;
  10. 寻求帮助时需贴代码或大长串异常信息的,请利用 http://paste.ubuntu.com

其他说明

  1. 阅读源码的同学请注意,本SDK为简化代码编译时加入了lombok支持,如果不了解lombok的话,请先学习下相关知识,比如可以阅读此文章;
  2. 如有新功能需求,发现BUG,或者由于微信官方接口调整导致的代码问题,可以直接在【Issues】页提出issue,便于讨论追踪问题;
  3. 如果需要贡献代码,请务必在提交PR之前先仔细阅读【代码贡献指南】,谢谢理解配合;
  4. 目前本SDK最新版本要求的JDK最低版本是8,使用7的同学可以使用WxJava 3.8.0及以前版本,而还在使用JDK6的用户请参考【此项目】 ,而其他更早的JDK版本则需要自己改造实现。
  5. 本项目在开源中国的页面,欢迎大家积极留言评分 🙂
  6. SDK开发文档请查阅 【开发文档Wiki】,部分文档可能未能及时更新,如有发现,可以及时上报或者自行修改。
  7. 如果本开发工具包对您有所帮助,欢迎对我们的努力进行肯定,可以直接前往【托管于码云的项目首页】,在页尾部分找到“捐助”按钮进行打赏,多多益善 😄。非常感谢各位打赏和捐助的同学!
  8. 各个模块的Javadoc可以在线查看:weixin-java-miniapp、weixin-java-pay、weixin-java-mp、weixin-java-common、weixin-java-cp、weixin-java-open
  9. 本SDK项目在以下代码托管网站同步更新:

Maven 引用方式

注意:最新版本(包括测试版)为 ,以下为最新正式版。

方式一:使用 BOM 统一管理版本(推荐)

如果同时使用多个 WxJava 模块,推荐通过 BOM 统一管理版本,无需为每个模块单独指定版本号。
wx-java-bom 从 4.8.3.B 版本开始提供,请使用该版本或更高版本:

xml
<wx-java.version>4.8.3.B</wx-java.version>


<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.github.binarywang</groupId>
      <artifactId>wx-java-bom</artifactId>
      <version>${wx-java.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

之后直接引入所需模块,无需指定版本:

xml
<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>weixin-java-mp</artifactId>
</dependency>
<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>weixin-java-pay</artifactId>
</dependency>

方式二:直接引用单个模块

xml
<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>(不同模块参考下文)</artifactId>
  <version>4.8.0</version>
</dependency>
  • 微信小程序:weixin-java-miniapp
  • 微信支付:weixin-java-pay
  • 微信开放平台:weixin-java-open
  • 微信公众号:weixin-java-mp
  • 企业微信:weixin-java-cp
  • 微信视频号/微信小店:weixin-java-channel

注意:

  • 移动应用开发:如果你的移动应用(iOS/Android App)需要接入微信登录、分享等功能:
    • 微信登录(网页授权):使用 weixin-java-open 模块,在服务端处理 OAuth 授权
    • 微信支付:使用 weixin-java-pay 模块
    • 客户端集成:需使用微信官方提供的移动端SDK(iOS/Android),本项目为服务端SDK
  • 微信开放平台(weixin-java-open)主要用于第三方平台,代公众号或小程序进行开发和管理

最小示例

公众号(MP)示例:获取 AccessToken

java
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
config.setAppId("your-app-id");
config.setSecret("your-secret");

WxMpService wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(config);

String accessToken = wxMpService.getAccessToken();
System.out.println(accessToken);

小程序(MiniApp)示例:code2Session

java
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
config.setAppid("your-app-id");
config.setSecret("your-secret");

WxMaService wxMaService = new WxMaServiceImpl();
wxMaService.setWxMaConfig(config);

WxMaJscode2SessionResult result = wxMaService.getUserService().getSessionInfo("js-code");
System.out.println(result.getOpenid());

版本说明

点此展开查看

  1. 本项目定为大约每半年左右发布一次正式版,遇到重大问题需修复会及时提交新版本,欢迎大家随时提交 Pull Request;
  2. 每次代码更新都会自动构建出新版本方便及时尝鲜,版本号格式为 x.x.x-时间戳;
  3. 发布正式版时,develop 分支代码合并进入 release 分支),版本号格式为 X.X.0(如2.1.0,2.2.0等);
  4. 每隔一段时间后,会发布测试版本(如3.6.8.B,即尾号不为0,并添加B,以区别于正式版),代码仅存在于 develop 分支中;
  5. 目前最新版本号为 ,也可以通过访问以下链接分别查看各个模块最新的版本:
    【微信支付】 、【小程序】 、【公众号】 、【企业微信】、【开放平台】、【视频号】

应用案例

完整案例登记列表,请【访问这里】查看,欢迎登记更多的案例。

以下为节选的部分案例, 点此展开查看

开源项目:

小程序:

  • (京东)友家铺子,友家铺子店长版,京粉精选
  • 喵星人贴吧助手(扫码关注)
  • 树懒揽书+
  • 广廉快线,鹏城巴士等
  • 当燃挑战、sportlight轻灵运动
  • 360考试宝典
  • 民医台
  • 来一团商家版
  • 史必达(史丹利)
  • 嘀嗒云印
  • 维沃吼吼
  • 王朝社区(比亚迪新能源社区)
  • 极吼吼手机上门回收换新
  • 未来信封
  • 5G惠享
  • 生菜wordpress转小程序
  • 丽日购

公众号:

  • 中国电信上海网厅(sh_189)
  • E答平台
  • 宁夏生鲜365
  • 通服货滴
  • 神龙养车
  • 沃音乐商务智能
  • 光环云社群
  • 手机排队
  • 全民约跑健身便利店
  • 民医台
  • YshopMall
  • 好行景区直通车以及全国40多个公众号
  • 我奥篮球公众号
  • 未来信封官微
  • 银川智云问诊
  • 5G惠享

企业微信:

  • HTC企业微信
  • 掌上史丹利
  • 药店益

其他:

  • 高善人力资源
  • 小猪餐餐
  • 餐饮系统
  • 微信公众号管理系统:http://demo.joolun.com
  • 锐捷网络:Saleslink

贡献者列表

特别感谢参与贡献的所有同学,所有贡献者列表请在此处查看,欢迎大家继续踊跃贡献代码!

GitHub Stargazers over time


File: docs/CP_MSG_AUDIT_SDK_SAFE_USAGE.md

企业微信会话存档SDK安全使用指南

说明

该方案已废弃,请使用新版本:CP_MSG_AUDIT_THREADLOCAL_LIFECYCLE_REFACTOR.md

问题背景

在使用企业微信会话存档功能时,部分开发者遇到了JVM崩溃的问题。典型错误信息如下:

text
SIGSEGV (0xb) at pc=0x00007fcd50460d93
Problematic frame:
C  [libWeWorkFinanceSdk_Java.so+0x260d93]  WeWorkFinanceSdk::TryRefresh(std::string const&, std::string const&, int)+0x23

问题原因

旧版API设计存在以下问题:

  1. SDK生命周期管理混乱

    • getChatDatas() 方法会返回SDK实例给调用方
    • 开发者需要手动调用 Finance.DestroySdk() 来销毁SDK
    • 但SDK在框架内部有7200秒的缓存机制
  2. 手动销毁导致缓存失效

    • 当开发者手动销毁SDK后,框架缓存中的SDK引用变为无效
    • 后续调用(如 getMediaFile())仍然使用已销毁的SDK
    • 底层C++库访问无效指针,导致SIGSEGV错误
  3. 多线程并发问题

    • 在多线程环境下,一个线程销毁SDK后
    • 其他线程仍在使用该SDK,导致崩溃

解决方案

从 4.8.0 版本开始,WxJava提供了新的安全API,完全由框架管理SDK生命周期。

新API列表

旧API(已废弃) 新API(推荐使用) 说明
getChatDatas() getChatRecords() 拉取聊天记录,不暴露SDK
getDecryptData(sdk, ...) getDecryptChatData(...) 解密聊天数据,无需传入SDK
getChatPlainText(sdk, ...) getChatRecordPlainText(...) 获取明文数据,无需传入SDK
getMediaFile(sdk, ...) downloadMediaFile(...) 下载媒体文件,无需传入SDK

使用示例

错误用法(旧API,已废弃)

java
// ❌ 不推荐:容易导致JVM崩溃
WxCpMsgAuditService msgAuditService = wxCpService.getMsgAuditService();

// 拉取聊天记录
WxCpChatDatas chatDatas = msgAuditService.getChatDatas(seq, 1000L, null, null, 1000L);

for (WxCpChatDatas.WxCpChatData chatData : chatDatas.getChatData()) {
    // 解密数据
    WxCpChatModel model = msgAuditService.getDecryptData(chatDatas.getSdk(), chatData, 2);
    
    // 下载媒体文件
    if ("image".equals(model.getMsgType())) {
        String sdkFileId = model.getImage().getSdkFileId();
        msgAuditService.getMediaFile(chatDatas.getSdk(), sdkFileId, null, null, 1000L, targetPath);
    }
}

// ❌ 危险操作:手动销毁SDK可能导致后续调用崩溃
Finance.DestroySdk(chatDatas.getSdk());

正确用法(新API,推荐)

java
// ✅ 推荐:SDK生命周期由框架自动管理,安全可靠
WxCpMsgAuditService msgAuditService = wxCpService.getMsgAuditService();

// 拉取聊天记录(不返回SDK)
List<WxCpChatDatas.WxCpChatData> chatRecords = 
    msgAuditService.getChatRecords(seq, 1000L, null, null, 1000L);

for (WxCpChatDatas.WxCpChatData chatData : chatRecords) {
    // 解密数据(无需传入SDK)
    WxCpChatModel model = msgAuditService.getDecryptChatData(chatData, 2);
    
    // 下载媒体文件(无需传入SDK)
    if ("image".equals(model.getMsgType())) {
        String sdkFileId = model.getImage().getSdkFileId();
        msgAuditService.downloadMediaFile(sdkFileId, null, null, 1000L, targetPath);
    }
}

// ✅ 无需手动销毁SDK,框架会自动管理

完整示例:拉取并处理会话存档

text
/* Detailed source-code truncated for AI context efficiency. */

使用Lambda处理媒体文件流

新API同样支持使用Lambda表达式处理媒体文件的数据流:

java
msgAuditService.downloadMediaFile(sdkFileId, null, null, 1000L, data -> {
    try {
        // 处理每个数据分片(大文件会分片传输)
        // 例如:上传到云存储、写入数据库等
        uploadToCloud(data);
    } catch (Exception e) {
        e.printStackTrace();
    }
});

技术实现原理

引用计数机制

新API在内部实现了SDK引用计数机制:

  1. 获取SDK时:引用计数 +1
  2. 使用完成后:引用计数 -1
  3. 计数归零且SDK已过期时:SDK被销毁并清理缓存
  4. 计数归零但SDK未过期时:保留缓存,供后续调用直接复用

注意:引用计数归零并不等同于立即销毁SDK。只有在 SDK 已超过有效期的情况下,框架才会调用 Finance.DestroySdk() 释放资源。这一机制避免了每次 API 调用后的频繁初始化/销毁循环。

java
// 框架内部实现(简化版)
public void downloadMediaFile(String sdkFileId, ...) {
    long sdk = initSdk();  // 获取或初始化SDK(有效期内直接复用缓存)
    configStorage.incrementMsgAuditSdkRefCount(sdk);  // 引用计数 +1

    try {
        // 执行实际操作
        getMediaFile(sdk, sdkFileId, ...);
    } finally {
        // 确保引用计数一定会减少;仅在归零且过期时销毁
        configStorage.decrementMsgAuditSdkRefCount(sdk);  // 引用计数 -1
    }
}

SDK缓存机制

SDK初始化后会缓存7200秒,避免频繁初始化:

  • 首次调用:初始化新的SDK
  • 7200秒内:复用缓存的SDK(即使引用计数曾归零也不重新初始化)
  • 超过7200秒:下次 acquireMsgAuditSdk() 返回0,触发重新初始化,旧SDK在重新初始化时被销毁

新API的引用计数机制与缓存机制完美配合,确保SDK不会被提前销毁,也不会永久残留。

迁移指南

第一步:使用新API替换旧API

查找代码中的旧API调用:

java
// 查找模式
getChatDatas(
getDecryptData(.*sdk
getChatPlainText(.*sdk
getMediaFile(.*sdk
Finance.DestroySdk(

替换为对应的新API(参考前面的对照表)。

第二步:移除手动SDK管理代码

删除所有 Finance.DestroySdk() 调用,SDK生命周期由框架自动管理。

第三步:测试验证

  1. 在测试环境验证新API功能正常
  2. 观察日志,确认没有SDK相关的错误
  3. 进行压力测试,验证多线程环境下的稳定性

常见问题

Q1: 旧代码会立即停止工作吗?

A: 不会。旧API被标记为 @Deprecated,但仍然可用,只是不推荐继续使用。建议尽快迁移到新API以避免潜在问题。

Q2: 如何知道SDK是否被正确释放?

A: 框架会自动管理SDK生命周期,开发者无需关心。如果需要调试,可以查看配置存储中的引用计数。

Q3: 多线程环境下新API安全吗?

A: 是的。新API使用了引用计数机制,配合 synchronized 关键字,确保多线程环境下的安全性。

Q4: 性能会受影响吗?

A: 不会。新API在实现上增加了引用计数的开销,但这是轻量级的操作(原子操作),对性能影响可以忽略不计。SDK缓存机制保持不变。

Q5: 可以同时使用新旧API吗?

A: 技术上可以,但强烈不推荐。混用可能导致SDK生命周期管理混乱,建议统一使用新API。

相关链接

版本要求

  • 最低版本: 4.8.0
  • 推荐版本: 最新版本

反馈与支持

如果在使用过程中遇到问题,请:

  1. 查看本文档的常见问题部分
  2. 在 GitHub 上提交 Issue
  3. 加入微信群获取社区支持

最后更新时间: 2026-01-14


File: docs/HTTPCLIENT_UPGRADE_GUIDE.md

HttpClient 升级指南

概述

从 WxJava 4.7.x 版本开始,项目开始支持并推荐使用 Apache HttpClient 5.x(HttpComponents Client 5),同时保持对 HttpClient 4.x 的向后兼容。

为什么升级?

  1. Apache HttpClient 5.x 是最新稳定版本:提供更好的性能和更多的功能
  2. HttpClient 4.x 已经进入维护模式:不再积极开发新功能
  3. 更好的安全性:HttpClient 5.x 包含最新的安全更新和改进
  4. 向前兼容:为未来的开发做好准备

支持的 HTTP 客户端

HTTP 客户端 版本 配置值 状态 说明
Apache HttpClient 5.x 5.6.3 HttpComponents ⭐ 推荐 最新稳定版本
Apache HttpClient 4.x 4.5.13 HttpClient ✅ 支持 向后兼容
OkHttp 4.12.0 OkHttp ✅ 支持 需自行添加依赖
Jodd-http 6.3.0 JoddHttp ✅ 支持 需自行添加依赖

模块支持情况

模块 HttpClient 5.x 支持 默认客户端
weixin-java-mp(公众号) ✅ 是 HttpComponents (5.x)
weixin-java-cp(企业微信) ⚠️ 视集成方式而定 参考对应 starter 配置
weixin-java-channel(视频号) ✅ 是 HttpComponents (5.x)
weixin-java-qidian(企点) ✅ 是 HttpComponents (5.x)
weixin-java-miniapp(小程序) ✅ 是 HttpComponents (5.x)
weixin-java-pay(支付) ✅ 是 HttpComponents (5.x)
weixin-java-open(开放平台) ✅ 是 HttpComponents (5.x)

注意:

  • weixin-java-cp 模块的支持情况取决于具体使用的 Starter 版本,请参考对应模块文档。

对现有项目的影响

对新项目

  • 无需任何修改,直接使用最新版本即可
  • 支持 HttpClient 5.x 的模块会自动使用 HttpComponents (5.x)

对现有项目

  • 向后兼容:不需要修改任何代码
  • 如果希望继续使用 HttpClient 4.x,只需在配置中显式指定,pay 模块会自动包含 httpclient4 依赖(因为某些接口必须使用 httpclient4)
    其他模块(mp、miniapp、cp、open、channel、qidian)如果需要使用 httpclient4,必须显式在项目中添加 httpclient4 依赖

迁移步骤

1. 更新 WxJava 版本

在 pom.xml 中更新版本:

xml
<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>weixin-java-mp</artifactId>
  <version>最新版本</version> 
</dependency>

2. 检查配置(可选)

Spring Boot 项目

在 application.properties 或 application.yml 中:

properties
# 使用 HttpClient 5.x(推荐,无需配置,已经是默认值)
wx.mp.config-storage.http-client-type=HttpComponents

# 或者继续使用 HttpClient 4.x
wx.mp.config-storage.http-client-type=HttpClient

纯 Java 项目

java
// 使用 HttpClient 5.x(推荐)
WxMpService wxMpService = new WxMpServiceHttpComponentsImpl();

// 或者继续使用 HttpClient 4.x
WxMpService wxMpService = new WxMpServiceHttpClientImpl();

3. 测试应用

升级后,建议进行全面测试以确保一切正常工作。

常见问题

Q: 升级后会不会破坏现有代码?

A: 不会。项目保持完全向后兼容,HttpClient 4.x 的所有实现都保持不变。

Q: 我需要修改代码吗?

A: 大多数情况下不需要。如果希望继续使用 HttpClient 4.x,只需在配置中指定 http-client-type=HttpClient ,并引入 HttpClient 4.x 依赖即可。

Q: 我可以在同一个项目中同时使用两个版本吗?

A: 可以。不同的模块可以配置使用不同的 HTTP 客户端。例如,MP 模块使用 HttpClient 5.x,pay 模块部分接口仍使用 HttpClient 4.x,但也可以按需配置为 HttpClient 5.x。

Q: 如何排除不需要的依赖?

A: 如果只想使用一个版本,可以在 pom.xml 中排除另一个:

xml
<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>weixin-java-mp</artifactId>
  <version>最新版本</version>
  <exclusions>
    
    <exclusion>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpmime</artifactId>
    </exclusion>
  </exclusions>
</dependency>

配置参考

Spring Boot 完整配置示例

properties
# 公众号配置
wx.mp.app-id=your_app_id
wx.mp.secret=your_secret
wx.mp.token=your_token
wx.mp.aes-key=your_aes_key

# HTTP 客户端配置
wx.mp.config-storage.http-client-type=HttpComponents  # HttpComponents, HttpClient, OkHttp, JoddHttp

# HTTP 代理配置(可选)
wx.mp.config-storage.http-proxy-host=proxy.example.com
wx.mp.config-storage.http-proxy-port=8080
wx.mp.config-storage.http-proxy-username=proxy_user
wx.mp.config-storage.http-proxy-password=proxy_pass

# 超时配置(可选)
wx.mp.config-storage.connection-timeout=5000
wx.mp.config-storage.so-timeout=5000
wx.mp.config-storage.connection-request-timeout=5000

技术细节

HttpClient 4.x 与 5.x 的主要区别

  1. 包名变更:

    • HttpClient 4.x: org.apache.http.*
    • HttpClient 5.x: org.apache.hc.client5.*, org.apache.hc.core5.*
  2. API 改进:

    • HttpClient 5.x 提供更现代的 API 设计
    • 更好的异步支持
    • 改进的连接池管理
  3. 性能优化:

    • HttpClient 5.x 包含多项性能优化
    • 更好的资源管理

项目中的实现

WxJava 项目通过策略模式支持多种 HTTP 客户端:

text
weixin-java-common/
├── util/http/
│   ├── apache/          # HttpClient 4.x 实现
│   ├── hc/              # HttpClient 5.x (HttpComponents) 实现
│   ├── okhttp/          # OkHttp 实现
│   └── jodd/            # Jodd-http 实现

每个模块都有对应的 Service 实现类:

  • *ServiceHttpClientImpl - 使用 HttpClient 4.x
  • *ServiceHttpComponentsImpl - 使用 HttpClient 5.x
  • *ServiceOkHttpImpl - 使用 OkHttp
  • *ServiceJoddHttpImpl - 使用 Jodd-http

反馈与支持

如果在升级过程中遇到问题,请:

  1. 查看 项目 Wiki
  2. 在 GitHub Issues 中搜索或提交问题
  3. 加入技术交流群(见 README.md)

总结

  • ✅ 推荐使用 HttpClient 5.x:性能更好,功能更强
  • ✅ 向后兼容:可以继续使用 HttpClient 4.x
  • ✅ 灵活配置:支持多种 HTTP 客户端,按需选择
  • ✅ 平滑迁移:无需修改代码,仅需配置,若不使用 HttpClient 5.x ,引入其他依赖即可

File: docs/MINIAPP_KEFU_SERVICE.md

WeChat Mini Program Customer Service Management

This document describes the new customer service management functionality added to the WxJava Mini Program SDK.

Overview

Previously, the mini program module only had:

  • WxMaCustomserviceWorkService - For binding mini programs to enterprise WeChat customer service
  • WxMaMsgService.sendKefuMsg() - For sending customer service messages

The new WxMaKefuService adds comprehensive customer service management capabilities:

Features

Customer Service Account Management

  • kfList() - Get list of customer service accounts
  • kfAccountAdd() - Add new customer service account
  • kfAccountUpdate() - Update customer service account
  • kfAccountDel() - Delete customer service account

Session Management

  • kfSessionCreate() - Create customer service session
  • kfSessionClose() - Close customer service session
  • kfSessionGet() - Get customer session status
  • kfSessionList() - Get customer service session list

Usage Example

java
// Get the customer service management service
WxMaKefuService kefuService = wxMaService.getKefuService();

// Add a new customer service account
WxMaKfAccountRequest request = WxMaKfAccountRequest.builder()
    .kfAccount("service001@example")
    .kfNick("Customer Service 001")
    .kfPwd("password123")
    .build();
boolean result = kefuService.kfAccountAdd(request);

// Create a session between user and customer service
boolean sessionResult = kefuService.kfSessionCreate("user_openid", "service001@example");

// Get customer service list
WxMaKfList kfList = kefuService.kfList();

Bean Classes

Request Objects

  • WxMaKfAccountRequest - For customer service account operations
  • WxMaKfSessionRequest - For session operations

Response Objects

  • WxMaKfInfo - Customer service account information
  • WxMaKfList - List of customer service accounts
  • WxMaKfSession - Session information
  • WxMaKfSessionList - List of sessions

API Endpoints

The service uses the following WeChat Mini Program API endpoints:

  • https://api.weixin.qq.com/cgi-bin/customservice/getkflist - Get customer service list
  • https://api.weixin.qq.com/customservice/kfaccount/add - Add customer service account
  • https://api.weixin.qq.com/customservice/kfaccount/update - Update customer service account
  • https://api.weixin.qq.com/customservice/kfaccount/del - Delete customer service account
  • https://api.weixin.qq.com/customservice/kfsession/create - Create session
  • https://api.weixin.qq.com/customservice/kfsession/close - Close session
  • https://api.weixin.qq.com/customservice/kfsession/getsession - Get session
  • https://api.weixin.qq.com/customservice/kfsession/getsessionlist - Get session list

Integration

The service is automatically available through the main WxMaService interface:

java
WxMaKefuService kefuService = wxMaService.getKefuService();

This fills the gap mentioned in the original issue and provides full customer service management capabilities for WeChat Mini Programs.


File: docs/NEW_TRANSFER_API_SUPPORT.md

微信支付新版商户转账API支持

问题解答

问题: 新开通的商户号只能使用最新版本的商户转账接口,WxJava是否支持?

答案: WxJava 已经完整支持新版商户转账API! 从2025年1月15日开始生效的新版转账API已在WxJava中实现。

新版转账API特性

1. API接口对比

特性 传统转账API 新版转账API (2025.1.15+)
服务类 MerchantTransferService TransferService
API路径 /v3/transfer/batches /v3/fund-app/mch-transfer/transfer-bills
转账方式 批量转账 单笔转账
场景支持 基础场景 丰富场景(如佣金报酬等)
撤销功能 ❌ 不支持 ✅ 支持
授权模式 仅需确认模式 ✅ 支持免确认授权模式
适用范围 所有商户 新开通商户必须使用

2. 新版API功能列表

✅ 发起转账 - transferBills()
✅ 查询转账 - getBillsByOutBillNo() / getBillsByTransferBillNo()
✅ 撤销转账 - transformBillsCancel()
✅ 回调通知 - parseTransferBillsNotifyResult()
✅ RSA加密 - 自动处理用户姓名加密
✅ 场景支持 - 支持多种转账场景ID
✅ 授权模式 - 支持免确认收款授权模式

3. 收款授权模式支持

新增功能:免确认收款授权模式

  • 需确认收款授权模式(默认):用户需要手动确认才能收款
  • 免确认收款授权模式:用户授权后,收款无需确认,转账直接到账

使用方法

java
// 免确认授权模式 - 提升用户体验
TransferBillsRequest request = TransferBillsRequest.newBuilder()
    .receiptAuthorizationMode(WxPayConstants.ReceiptAuthorizationMode.NO_CONFIRM_RECEIPT_AUTHORIZATION)
    // 其他参数...
    .build();

// 需确认授权模式(默认)
TransferBillsRequest request2 = TransferBillsRequest.newBuilder()
    .receiptAuthorizationMode(WxPayConstants.ReceiptAuthorizationMode.CONFIRM_RECEIPT_AUTHORIZATION)
    // 其他参数...
    .build();

快速开始

1. 获取服务实例

java
// 获取WxPayService实例
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(config);

// 获取新版转账服务 - 这就是新开通商户需要使用的服务!
TransferService transferService = wxPayService.getTransferService();

2. 发起转账(新版API)

java
// 构建转账请求
TransferBillsRequest request = TransferBillsRequest.newBuilder()
    .appid("your_appid")                    // 应用ID
    .outBillNo("T" + System.currentTimeMillis()) // 商户转账单号
    .transferSceneId("1005")                // 转账场景ID(佣金报酬)
    .openid("user_openid")                  // 用户openid
    .userName("张三")                        // 收款用户姓名(可选,自动加密)
    .transferAmount(100)                    // 转账金额(分)
    .transferRemark("佣金报酬")              // 转账备注
    .build();

// 发起转账
TransferBillsResult result = transferService.transferBills(request);
System.out.println("转账成功,微信转账单号:" + result.getTransferBillNo());

3. 查询转账结果

java
// 通过商户单号查询
TransferBillsGetResult result = transferService.getBillsByOutBillNo("T1642567890123");

// 通过微信转账单号查询  
TransferBillsGetResult result2 = transferService.getBillsByTransferBillNo("wx_transfer_bill_no");

System.out.println("转账状态:" + result.getState());

4. 撤销转账(新功能)

java
// 撤销转账
TransferBillsCancelResult cancelResult = transferService.transformBillsCancel("T1642567890123");
System.out.println("撤销状态:" + cancelResult.getState());

重要说明

转账场景ID (transfer_scene_id)

  • 1005: 佣金报酬(常用场景)
  • 其他场景需要在微信商户平台申请

转账状态说明

  • ACCEPTED: 转账已受理
  • PROCESSING: 转账处理中
  • SUCCESS: 转账成功
  • FAIL: 转账失败
  • CANCELLED: 转账撤销完成

新开通商户使用建议

  1. 优先使用 TransferService (新版API)
  2. 不要使用 MerchantTransferService (可能不支持)
  3. 必须设置 转账场景ID (transfer_scene_id)
  4. 建议开启 回调通知以实时获取转账结果

完整示例代码

详细的使用示例请参考:

常见问题

Q: 我是新开通的商户,应该使用哪个服务?
A: 使用 TransferService,这是专为新版API设计的服务。

Q: 新版API和旧版API有什么区别?
A: 新版API使用单笔转账模式,支持更丰富的转账场景,并且支持撤销功能。

Q: 如何设置转账场景ID?
A: 在商户平台申请相应场景,常用的佣金报酬场景ID是"1005"。

Q: 用户姓名需要加密吗?
A: WxJava会自动处理RSA加密,您只需要传入明文姓名即可。

版本要求

  • WxJava 版本:4.7.0+
  • 支持时间:2025年1月15日+
  • 适用商户:所有商户(新开通商户强制使用)

通过以上说明,新开通的微信支付商户可以放心使用WxJava进行商户转账操作!


File: docs/NEW_TRANSFER_API_USAGE.md

微信支付新版商户转账API使用指南

概述

从2025年1月15日开始,微信支付推出了新版的商户转账API。新开通的商户号只能使用最新版本的商户转账接口。WxJava 已经完整支持新版转账API。

API对比

传统转账API (仍然支持)

  • 服务类: MerchantTransferService
  • API前缀: /v3/transfer/batches
  • 特点: 支持批量转账,一次可以转账给多个用户

新版转账API (2025.1.15+)

  • 服务类: TransferService
  • API前缀: /v3/fund-app/mch-transfer/transfer-bills
  • 特点: 单笔转账,支持更丰富的转账场景

收款授权模式功能

授权模式说明

微信支付转账支持两种收款授权模式:

1. 需确认收款授权模式(默认)

  • 常量: WxPayConstants.ReceiptAuthorizationMode.CONFIRM_RECEIPT_AUTHORIZATION
  • 特点: 用户收到转账后需要手动点击确认才能到账
  • 适用场景: 一般的转账场景
  • 用户体验: 安全性高,但需要额外操作

2. 免确认收款授权模式

  • 常量: WxPayConstants.ReceiptAuthorizationMode.NO_CONFIRM_RECEIPT_AUTHORIZATION
  • 特点: 用户事先授权后,转账直接到账,无需确认
  • 适用场景: 高频转账场景,如佣金发放、返现等
  • 用户体验: 体验流畅,无需额外操作
  • 前提条件: 需要用户事先进行授权

使用示例

免确认授权模式转账

java
TransferBillsRequest request = TransferBillsRequest.newBuilder()
    .appid("your_appid")
    .outBillNo("NO_CONFIRM_" + System.currentTimeMillis())
    .transferSceneId("1005")                       // 佣金报酬场景
    .openid("user_openid")
    .transferAmount(200)                           // 2元
    .transferRemark("免确认收款转账")
    .receiptAuthorizationMode(WxPayConstants.ReceiptAuthorizationMode.NO_CONFIRM_RECEIPT_AUTHORIZATION)
    .userRecvPerception("Y")
    .build();

try {
    TransferBillsResult result = transferService.transferBills(request);
    System.out.println("转账成功,直接到账:" + result.getTransferBillNo());
} catch (WxPayException e) {
    if ("USER_NOT_AUTHORIZED".equals(e.getErrCode())) {
        System.err.println("用户未授权免确认收款,请先引导用户进行授权");
    }
}

需确认授权模式转账(默认)

java
TransferBillsRequest request = TransferBillsRequest.newBuilder()
    .appid("your_appid")
    .outBillNo("CONFIRM_" + System.currentTimeMillis())
    .transferSceneId("1005")
    .openid("user_openid")
    .transferAmount(150)                           // 1.5元
    .transferRemark("需确认收款转账")
    // .receiptAuthorizationMode(...) // 不设置时使用默认的确认模式
    .userRecvPerception("Y")
    .build();

TransferBillsResult result = transferService.transferBills(request);
System.out.println("转账发起成功,等待用户确认:" + result.getPackageInfo());

错误处理

使用免确认授权模式时,需要处理以下可能的错误:

java
try {
    TransferBillsResult result = transferService.transferBills(request);
} catch (WxPayException e) {
    switch (e.getErrCode()) {
        case "USER_NOT_AUTHORIZED":
            // 用户未授权免确认收款
            System.err.println("请先引导用户进行免确认收款授权");
            // 可以引导用户到授权页面
            break;
        case "AUTHORIZATION_EXPIRED":
            // 授权已过期
            System.err.println("用户授权已过期,请重新授权");
            break;
        default:
            System.err.println("转账失败:" + e.getMessage());
    }
}

使用建议

  1. 高频转账场景推荐使用免确认模式,提升用户体验
  2. 首次使用需引导用户进行授权
  3. 处理异常妥善处理授权相关异常,提供友好的错误提示
  4. 场景选择根据业务场景选择合适的授权模式

使用新版转账API

1. 获取服务实例

java
// 获取WxPayService实例
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(config);

// 获取新版转账服务
TransferService transferService = wxPayService.getTransferService();

2. 发起转账

java
// 构建转账请求
TransferBillsRequest request = TransferBillsRequest.newBuilder()
    .appid("your_appid")                           // 应用ID
    .outBillNo("T" + System.currentTimeMillis())   // 商户转账单号
    .transferSceneId("1005")                       // 转账场景ID(佣金报酬)
    .openid("user_openid")                         // 用户openid
    .userName("张三")                               // 收款用户姓名(可选,需要加密)
    .transferAmount(100)                           // 转账金额(分)
    .transferRemark("佣金报酬")                     // 转账备注
    .notifyUrl("https://your-domain.com/notify")   // 回调地址(可选)
    .userRecvPerception("Y")                       // 用户收款感知(可选)
    .build();

try {
    TransferBillsResult result = transferService.transferBills(request);
    System.out.println("转账成功,微信转账单号:" + result.getTransferBillNo());
    System.out.println("状态:" + result.getState());
} catch (WxPayException e) {
    System.err.println("转账失败:" + e.getMessage());
}

3. 查询转账结果

java
// 通过商户单号查询
String outBillNo = "T1642567890123";
TransferBillsGetResult result = transferService.getBillsByOutBillNo(outBillNo);

// 通过微信转账单号查询
String transferBillNo = "1000000000000000000000000001";
TransferBillsGetResult result2 = transferService.getBillsByTransferBillNo(transferBillNo);

System.out.println("转账状态:" + result.getState());
System.out.println("转账金额:" + result.getTransferAmount());

4. 撤销转账

java
// 撤销转账(仅在特定状态下可撤销)
String outBillNo = "T1642567890123";
TransferBillsCancelResult cancelResult = transferService.transformBillsCancel(outBillNo);
System.out.println("撤销结果:" + cancelResult.getState());

5. 处理回调通知

java
// 在回调接口中处理通知
@PostMapping("/transfer/notify")
public String handleTransferNotify(HttpServletRequest request) throws Exception {
    String notifyData = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);
    
    // 构建签名头
    SignatureHeader header = new SignatureHeader();
    header.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
    header.setNonce(request.getHeader("Wechatpay-Nonce"));
    header.setSignature(request.getHeader("Wechatpay-Signature"));
    header.setSerial(request.getHeader("Wechatpay-Serial"));
    
    try {
        TransferBillsNotifyResult notifyResult = transferService.parseTransferBillsNotifyResult(notifyData, header);
        
        // 处理业务逻辑
        String outBillNo = notifyResult.getOutBillNo();
        String state = notifyResult.getState();
        
        System.out.println("转账单号:" + outBillNo + ",状态:" + state);
        
        return "SUCCESS";
    } catch (WxPayException e) {
        System.err.println("验签失败:" + e.getMessage());
        return "FAIL";
    }
}

重要参数说明

转账场景ID (transfer_scene_id)

  • 1005: 佣金报酬(常用)
  • 其他场景ID需要在商户平台申请

转账状态

  • PROCESSING: 转账中
  • SUCCESS: 转账成功
  • FAILED: 转账失败
  • REFUNDED: 已退款

用户收款感知 (user_recv_perception)

  • Y: 用户会收到微信转账通知
  • N: 用户不会收到微信转账通知

新旧API对比总结

特性 传统API (MerchantTransferService) 新版API (TransferService)
发起方式 批量转账 单笔转账
API路径 /v3/transfer/batches /v3/fund-app/mch-transfer/transfer-bills
场景支持 基础转账场景 丰富的转账场景
回调通知 支持 支持
撤销功能 不支持 支持
适用商户 所有商户 新开通商户必须使用

注意事项

  1. 新开通的商户号: 必须使用新版API (TransferService)
  2. 转账场景ID: 需要在商户平台申请相应的转账场景
  3. 用户姓名加密: 如果传入用户姓名,会自动进行RSA加密
  4. 回调验签: 建议开启回调验签以确保安全性
  5. 错误处理: 妥善处理各种异常情况

通过以上指南,您可以轻松使用WxJava的新版商户转账API功能。


File: docs/QUARKUS_SUPPORT.md

WxJava Quarkus/GraalVM Native Image Support

概述

从 4.7.8.B 版本开始,WxJava 提供了对 Quarkus 和 GraalVM Native Image 的支持。这允许您将使用 WxJava 的应用程序编译为原生可执行文件,从而获得更快的启动速度和更低的内存占用。

问题背景

在之前的版本中,使用 Quarkus 构建 Native Image 时会遇到以下错误:

text
Error: Unsupported features in 3 methods
Detailed message:
Error: Detected an instance of Random/SplittableRandom class in the image heap. 
Instances created during image generation have cached seed values and don't behave as expected.
The culprit object has been instantiated by the 'org.apache.http.impl.auth.NTLMEngineImpl' class initializer

解决方案

为了解决这个问题,WxJava 进行了以下改进:

1. Random 实例的延迟初始化

所有 java.util.Random 实例都已改为延迟初始化,避免在类加载时创建:

  • RandomUtils - 使用双重检查锁定模式延迟初始化
  • SignUtils - 使用双重检查锁定模式延迟初始化
  • WxCryptUtil - 使用双重检查锁定模式延迟初始化

2. Native Image 配置

在 weixin-java-common 模块中添加了 GraalVM Native Image 配置文件:

  • META-INF/native-image/com.github.binarywang/weixin-java-common/native-image.properties

    • 配置 Apache HttpClient 相关类在运行时初始化,避免在构建时创建 SecureRandom 实例
  • META-INF/native-image/com.github.binarywang/weixin-java-common/reflect-config.json

    • 配置反射访问的类和方法

使用方式

Quarkus 项目配置

在您的 Quarkus 项目中使用 WxJava,只需正常引入依赖即可:

xml
<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>weixin-java-miniapp</artifactId>  
  <version>4.7.8.B</version>
</dependency>

构建 Native Image

使用 Quarkus 构建原生可执行文件:

bash
./mvnw package -Pnative

或使用容器构建:

bash
./mvnw package -Pnative -Dquarkus.native.container-build=true

GraalVM Native Image

如果直接使用 GraalVM Native Image 工具:

bash
native-image --no-fallback \
  -H:+ReportExceptionStackTraces \
  -jar your-application.jar

WxJava 的配置文件会自动被 Native Image 工具识别和应用。

测试验证

建议在构建 Native Image 后进行以下测试:

  1. 验证应用程序可以正常启动
  2. 验证微信 API 调用功能正常
  3. 验证随机字符串生成功能正常
  4. 验证加密/解密功能正常

已知限制

  • 本配置主要针对 Quarkus 3.x 和 GraalVM 22.x+ 版本进行测试
  • 如果使用其他 Native Image 构建工具(如 Spring Native),可能需要额外配置
  • 部分反射使用可能需要根据实际使用的 WxJava 功能进行调整

问题反馈

如果在使用 Quarkus/GraalVM Native Image 时遇到问题,请通过以下方式反馈:

  1. 在 GitHub Issues 提交问题
  2. 提供详细的错误信息和 Native Image 构建日志
  3. 说明使用的 Quarkus 版本和 GraalVM 版本

参考资料

贡献

欢迎提交 PR 完善 Quarkus/GraalVM 支持!如果您发现了新的兼容性问题或有改进建议,请参考 代码贡献指南。


File: others/weixin-java-config/README.md

weixin-java-config

1.目录说明:多配置文件目录

2.项目多配置集锦

yml
wechat:
  pay: #微信服务商支付
    configs:
    - appId: wxe97b2x9c2b3d #spAppId
      mchId: 16486610 #服务商商户
      subAppId: wx118cexxe3c07679 #子appId
      subMchId: 16496705 #子商户
      apiV3Key: Dc1DBwSc094jAKDGR5aqqb7PTHr #apiV3密钥
      privateKeyPath: classpath:cert/apiclient_key.pem #服务商证书文件,apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径(可以配置绝对路径)
      privateCertPath: classpath:cert/apiclient_cert.pem #apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径
  miniapp: #小程序
    configs:
    - appid: wx118ce3xxc76ccg
      secret: 8a132a276ee2f8fb58b1ed8f2
      token: #微信小程序消息服务器配置的token
      aesKey: #微信小程序消息服务器配置的EncodingAESKey
      msgDataFormat: JSON
  cp: #企业微信
    corpId: wwa3be8efd2addfgj
    appConfigs:
    - agentId: 10001 #客户联系
      secret: T5fTj1n-sBAT4rKNW5c9IYNfPdXZ8-oGol5tX
      token: 2bSNqTcLtFYBUa1u2
      aesKey: AXazu2Xyw44SNY1x8go2phn9p9B2O9oiEfqPN
    - agentId: 10003 #会话内容存档
      secret: xIpum7Yt4NMXcyxdzcQ2l_46BG4QIQDR57MhA
      token:
      aesKey:
    - agentId: 3010011 #打卡
      secret: 3i2Mhfusifaw_-04bMYI8OoKGxPe9mDALbUxV
      token:
      aesKey:
    - agentId: 19998 #通讯录同步
      secret: rNyDae0Pg-3d-wqTd_ozMSJfF0DEjTCz3b_pr
      token: xUke8yZciAZqImGZ
      aesKey: EUTVyArqJcfnpFiudxjRpuOexNqBoPbwrNG3R
    - agentId: 20000 #微盘
      secret: D-TVMvUji7PZZdjhZOSgiy2MTuBd0OCdvI_zi
      token:
      aesKey:

3.主要代码

1)微信服务商支付

java
@Data
@ConfigurationProperties(prefix = "wechat.pay")
public class WxPayProperties {

    private List<Config> configs;

    @Getter
    @Setter
    public static class Config {

        private String appId;
        private String mchId;
        private String subAppId;
        private String subMchId;
        private String apiV3Key;
        private String privateKeyPath;
        private String privateCertPath;

    }

}
java
@Configuration
@EnableConfigurationProperties(WxPayProperties.class)
@AllArgsConstructor
public class WxPayConfiguration {

    private WxPayProperties properties;

    @Bean
    public WxPayService wxPayService() {

        // 多配置
        WxPayService wxPayService = new WxPayServiceImpl();
        Map<String, WxPayConfig> payConfigs = this.properties.getConfigs().stream().map(config -> {
            WxPayConfig payConfig = new WxPayConfig();
            payConfig.setAppId(StringUtils.trimToNull(config.getAppId()));
            payConfig.setMchId(StringUtils.trimToNull(config.getMchId()));
            payConfig.setSubAppId(StringUtils.trimToNull(config.getSubAppId()));
            payConfig.setSubMchId(StringUtils.trimToNull(config.getSubMchId()));
            payConfig.setApiV3Key(StringUtils.trimToNull(config.getApiV3Key()));
            payConfig.setPrivateKeyPath(StringUtils.trimToNull(config.getPrivateKeyPath()));
            payConfig.setPrivateCertPath(StringUtils.trimToNull(config.getPrivateCertPath()));

            // 可以指定是否使用沙箱环境
            payConfig.setUseSandboxEnv(false);
            return payConfig;
        }).collect(Collectors.toMap(config -> config.getSubMchId(), a -> a));

        wxPayService.setMultiConfig(payConfigs);
        return wxPayService;
    }

}

2)微信小程序

java
@Setter
@Getter
@ConfigurationProperties(prefix = "wechat.miniapp")
public class WxMaProperties {

    private List<Config> configs;

    @Data
    public static class Config {

        /**
         * 设置微信小程序的appid
         */
        private String appid;

        /**
         * 设置微信小程序的Secret
         */
        private String secret;

        /**
         * 设置微信小程序消息服务器配置的token
         */
        private String token;

        /**
         * 设置微信小程序消息服务器配置的EncodingAESKey
         */
        private String aesKey;

        /**
         * 消息格式,XML或者JSON
         */
        private String msgDataFormat;

    }

}
text
/* Detailed source-code truncated for AI context efficiency. */

3)企业微信

java
@Getter
@Setter
@ConfigurationProperties(prefix = "wechat.cp")
public class WxCpProperties {

  /**
   * 设置企业微信的corpId
   */
  private String corpId;

  private List<AppConfig> appConfigs;

  @Getter
  @Setter
  public static class AppConfig {
    /**
     * 设置企业微信应用的AgentId
     */
    private Integer agentId;

    /**
     * 设置企业微信应用的Secret
     */
    private String secret;

    /**
     * 设置企业微信应用的token
     */
    private String token;

    /**
     * 设置企业微信应用的EncodingAESKey
     */
    private String aesKey;

  }

}
text
/* Detailed source-code truncated for AI context efficiency. */

4.其他请移步wiki:GitHub wiki


File: solon-plugins/wx-java-channel-multi-solon-plugin/README.md

wx-java-channel-multi-solon-plugin

快速开始

  1. 引入依赖

    xml
    <dependencies>
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>wx-java-channel-multi-solon-plugin</artifactId>
            <version>${version}</version>
        </dependency>
    
        
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>${jedis.version}</version>
        </dependency>
    
        
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>${redisson.version}</version>
        </dependency>
    </dependencies>
  2. 添加配置(app.properties)

    properties
    # 视频号配置
    ## 应用 1 配置(必填)
    wx.channel.apps.tenantId1.app-id=@appId
    wx.channel.apps.tenantId1.secret=@secret
    ## 选填
    wx.channel.apps.tenantId1.use-stable-access-token=false
    wx.channel.apps.tenantId1.token=
    wx.channel.apps.tenantId1.aes-key=
    ## 应用 2 配置(必填)
    wx.channel.apps.tenantId2.app-id=@appId
    wx.channel.apps.tenantId2.secret=@secret
    ## 选填
    wx.channel.apps.tenantId2.use-stable-access-token=false
    wx.channel.apps.tenantId2.token=
    wx.channel.apps.tenantId2.aes-key=
    
    # ConfigStorage 配置(选填)
    ## 配置类型: memory(默认), jedis, redisson, redis_template
    wx.channel.config-storage.type=memory
    ## 相关redis前缀配置: wx:channel:multi(默认)
    wx.channel.config-storage.key-prefix=wx:channel:multi
    wx.channel.config-storage.redis.host=127.0.0.1
    wx.channel.config-storage.redis.port=6379
    wx.channel.config-storage.redis.password=123456
    
    # http 客户端配置(选填)
    ## # http客户端类型: http_client(默认)
    wx.channel.config-storage.http-client-type=http_client
    wx.channel.config-storage.http-proxy-host=
    wx.channel.config-storage.http-proxy-port=
    wx.channel.config-storage.http-proxy-username=
    wx.channel.config-storage.http-proxy-password=
    ## 最大重试次数,默认:5 次,如果小于 0,则为 0
    wx.channel.config-storage.max-retry-times=5
    ## 重试时间间隔步进,默认:1000 毫秒,如果小于 0,则为 1000
    wx.channel.config-storage.retry-sleep-millis=1000
  3. 自动注入的类型:WxChannelMultiServices

  4. 使用样例

    text

/* Detailed source-code truncated for AI context efficiency. */

text
---

## File: solon-plugins/wx-java-channel-solon-plugin/README.md

# wx-java-channel-solon-plugin

## 快速开始
1. 引入依赖
    ```xml
    <dependencies>
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>wx-java-channel-solon-plugin</artifactId>
            <version>${version}</version>
        </dependency>
   
        
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>${jedis.version}</version>
        </dependency>

        
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>${redisson.version}</version>
        </dependency>
    </dependencies>
    ```
2. 添加配置(app.properties)
    ```properties
    # 视频号配置(必填)
    ## 视频号小店的appId和secret
    wx.channel.app-id=@appId
    wx.channel.secret=@secret
    # 视频号配置 选填
    ## 设置视频号小店消息服务器配置的token
    wx.channel.token=@token
    ## 设置视频号小店消息服务器配置的EncodingAESKey
    wx.channel.aes-key=
    ## 支持JSON或者XML格式,默认JSON
    wx.channel.msg-data-format=JSON
    ## 是否使用稳定版 Access Token
    wx.channel.use-stable-access-token=false
    
    
    # ConfigStorage 配置(选填)
    ## 配置类型: memory(默认), jedis, redisson, redis_template
    wx.channel.config-storage.type=memory
    ## 相关redis前缀配置: wx:channel(默认)
    wx.channel.config-storage.key-prefix=wx:channel
    wx.channel.config-storage.redis.host=127.0.0.1
    wx.channel.config-storage.redis.port=6379
    wx.channel.config-storage.redis.password=123456
 
    
    # http 客户端配置(选填)
    ## # http客户端类型: http_client(默认)
    wx.channel.config-storage.http-client-type=http_client
    wx.channel.config-storage.http-proxy-host=
    wx.channel.config-storage.http-proxy-port=
    wx.channel.config-storage.http-proxy-username=
    wx.channel.config-storage.http-proxy-password=
    ## 最大重试次数,默认:5 次,如果小于 0,则为 0
    wx.channel.config-storage.max-retry-times=5
    ## 重试时间间隔步进,默认:1000 毫秒,如果小于 0,则为 1000
    wx.channel.config-storage.retry-sleep-millis=1000
    ```
3. 自动注入的类型
- `WxChannelService`
- `WxChannelConfig`
4. 使用样例

```java
import me.chanjar.weixin.channel.api.WxChannelService;
import me.chanjar.weixin.channel.bean.shop.ShopInfoResponse;
import me.chanjar.weixin.channel.util.JsonUtils;
import me.chanjar.weixin.common.error.WxErrorException;
import org.noear.solon.annotation.Inject;

@Component
public class DemoService {
  @Inject
  private WxChannelService wxChannelService;

  public String getShopInfo() throws WxErrorException {
    // 获取店铺基本信息
    ShopInfoResponse response = wxChannelService.getBasicService().getShopInfo();
    // 此处为演示,如果要返回response的结果,建议自己封装一个VO,避免直接返回response
    return JsonUtils.encode(response);
  }
}