跳到内容

微信生态

受众:开发者 摘要:微信公众号、小程序和微信开放平台的 Starter 接入边界、配置方式和后续核心模块路线。

框架使用 WxJava 作为微信公众号、小程序和微信开放平台 SDK 底座,只做 Spring Boot 自动配置、多账号治理、回调与微信域业务边界,不重复实现微信协议。

登录和支付已有独立主链路:微信登录 / 社交登录优先接入 IAM 的 JustAuth provider,微信支付优先接入 Payment / Cashier 的 IJPay provider。微信生态包只承接它们不覆盖或不适合承载的微信域能力,例如公众号回调、菜单、JS-SDK、小程序 code2Session、订阅消息和开放平台 authorizer 生命周期。

能力边界

能力当前入口说明
微信公众号WechatOfficialAccountManager / WechatOfficialService基于 WxJava weixin-java-mp,已支持回调、网页授权、JS-SDK、菜单、永久素材上传 / 删除 / 图文编辑 / 查询、微信平台模板同步、模板消息和客服消息基础能力
微信小程序WechatMiniappManager / WechatMiniappService基于 WxJava weixin-java-miniapp,已支持 code2Session、手机号、订阅消息和 JSAPI / 小程序支付上下文基础能力
微信开放平台WechatOpenPlatformManager / WechatOpenPlatformService基于 WxJava weixin-java-open,已支持第三方平台预授权、授权回调、component ticket 和 authorizer 快照
账号与回调底座spring-open-core-wechat账号元数据、Secret 引用、回调事件日志、消息日志和后台查询 API
统一身份桥接WechatIamIdentityService公众号 / 小程序 openid 与 unionid 绑定到 IAM iam_user;通用微信登录优先走 IAM + JustAuth
微信通知通道Notification.send("wechat", ...)复用公众号模板消息、公众号客服文本和小程序订阅消息,详见 Notification Starter
微信支付spring-open-starter-payment / Cashier / IJPay支付状态机不进入微信生态 starter;微信模块只输出 JSAPI / 小程序支付需要的 openid attributes

与 JustAuth / IJPay 的关系

框架不把所有微信相关能力都塞进一个“微信中台”。重叠能力按现有体系归属:

  • 登录主力:IAM + JustAuth。如果只需要微信开放平台扫码登录、公众号 OAuth 登录或企业微信登录,并且 JustAuth provider 已覆盖,优先把它作为 IAM 的登录方式配置和运维。微信生态包不管理 JustAuth provider 开关。
  • 支付主力:Payment / Cashier + IJPay。如果需求是微信支付下单、退款、通知回调、账务、结算或对账,优先在 Payment / Cashier 的 IJPay provider 内实现。微信生态包不管理 IJPay provider 开关。
  • 微信生态包:微信域能力补齐。公众号服务器回调、消息 / 事件、菜单、模板 / 客服消息、JS-SDK、小程序 code2Session / 手机号 / 订阅消息、开放平台第三方授权和 authorizer 生命周期,仍由 spring-open-starter-wechat + spring-open-core-wechat 承接。
  • 后续扩展。企业微信、视频号、小店等新增能力,应优先作为独立微信生态扩展包或 core 子能力引入;不要并入 JustAuth / IJPay,也不要让微信后台管理台管理登录或支付 provider。

Maven 依赖

xml
<dependency>
    <groupId>com.springopen</groupId>
    <artifactId>spring-open-starter-wechat</artifactId>
</dependency>
<dependency>
    <groupId>com.springopen</groupId>
    <artifactId>spring-open-core-wechat</artifactId>
</dependency>

配置示例

yaml
spring:
  open:
    wechat:
      default-official-account: main
      default-miniapp: mall
      default-open-platform: component
      official-accounts:
        main:
          app-id: wx-official-app-id
          secret: ${WECHAT_OFFICIAL_SECRET}
          token: ${WECHAT_OFFICIAL_TOKEN}
          encoding-aes-key: ${WECHAT_OFFICIAL_AES_KEY}
      miniapps:
        mall:
          app-id: wx-miniapp-app-id
          secret: ${WECHAT_MINIAPP_SECRET}
          token: ${WECHAT_MINIAPP_TOKEN}
          encoding-aes-key: ${WECHAT_MINIAPP_AES_KEY}
      open-platforms:
        component:
          component-app-id: wx-component-app-id
          component-app-secret: ${WECHAT_OPEN_SECRET}
          component-token: ${WECHAT_OPEN_TOKEN}
          component-aes-key: ${WECHAT_OPEN_AES_KEY}

账号 key 会按小写归一化。未配置账号时应用仍可启动,调用缺失账号会抛出配置异常。

回调配置与本地 smoke

微信后台配置回调 URL 时使用公网可访问地址;本地开发可用内网穿透把 http://localhost:8000 暴露给微信平台。回调入口是外部协议端点,响应为微信要求的原始文本,不套 Result<T>

平台后台URL
公众号服务器配置https://<domain>/api/v1/wechat/official/{accountCode}/callback
微信开放平台第三方平台授权事件接收 URLhttps://<domain>/api/v1/wechat/open-platform/{componentAccountCode}/callbacks

本地 smoke 可先用 mock 参数验证路由和原始响应形态;签名是否通过取决于账号 token / AESKey 配置:

bash
curl -i "http://localhost:8000/api/v1/wechat/official/main/callback?signature=mock&timestamp=1&nonce=n&echostr=ok"

curl -i -X POST "http://localhost:8000/api/v1/wechat/open-platform/component/callbacks?timestamp=1&nonce=n" \
  -H "Content-Type: text/xml" \
  --data '<xml></xml>'

预期外部协议入口返回 text/plainechostr / success / invalid signature 等原始文本;普通业务 API 如 oauth/authorize-urlcode2-sessionpre-auth-urlquery-auth 继续返回统一 JSON。

代码入口

java
WxMpService officialAccount = Wechat.officialAccounts().defaultService();
WxMaService miniapp = Wechat.miniapps().service("mall");
WxOpenService openPlatform = Wechat.openPlatforms().defaultService();

业务模块优先依赖 Manager 或 Facade,不直接扩散 WxJava 初始化逻辑。账号配置、Secret 引用、回调持久化、消息日志、公众号网页授权、小程序上下文输入和 JS-SDK 能力由 spring-open-core-wechat 承载;通用登录 provider 与支付 provider 分别回到 IAM + JustAuth、Payment / Cashier + IJPay。

如需通过统一通知体系发送微信消息,启用 spring.open.notification.channels.wechat.enabled=true 后使用 Notification.send("wechat", ...)。该通道只做 Notification SPI 到 WechatOfficialService / WechatMiniappService 的适配,发送审计仍进入 wechat_message_log,通道成败仍进入 Notification 发送日志。

Core 管理底座

spring-open-core-wechat 提供以下后台 API:

API权限说明
GET /api/v1/admin/wechat/accountswechat:account:view查询公众号、小程序、开放平台账号元数据
GET /api/v1/admin/wechat/eventswechat:event:view查询微信回调事件接收和处理状态
GET /api/v1/admin/wechat/messageswechat:message:view查询微信入站 / 出站消息日志
GET /api/v1/admin/wechat/messages/statisticswechat:message:view按筛选条件汇总微信消息发送效果统计
GET /api/v1/admin/wechat/messages/miniapp-subscribe/effectswechat:message:view按账号和模板汇总小程序订阅消息发送效果
POST /api/v1/admin/wechat/official/template-messagewechat:message:send发送公众号模板消息并写入出站消息日志
POST /api/v1/admin/wechat/official/kefu-text-messagewechat:message:send发送公众号客服文本消息并写入出站消息日志
POST /api/v1/admin/wechat/miniapp/subscribe-messagewechat:message:send发送小程序订阅消息并写入出站消息日志
GET /api/v1/admin/wechat/message-templateswechat:message-template:manage分页查询本地公众号模板 / 小程序订阅消息预设
POST /api/v1/admin/wechat/message-templateswechat:message-template:manage新增或更新本地消息模板预设
POST /api/v1/admin/wechat/message-templates/sync-officialwechat:message-template:manage按公众号账号从微信平台同步模板列表到本地预设
DELETE /api/v1/admin/wechat/message-templates/{id}wechat:message-template:manage删除本地消息模板预设
GET /api/v1/admin/wechat/official/material/countwechat:official-material:view查询公众号永久素材总数
GET /api/v1/admin/wechat/official/materialswechat:official-material:view按素材类型分页查询公众号永久素材列表
POST /api/v1/admin/wechat/official/materialswechat:official-material:manage上传公众号图片、语音、视频或缩略图永久素材
DELETE /api/v1/admin/wechat/official/materials/{mediaId}wechat:official-material:manage按 Media ID 删除公众号永久素材
POST /api/v1/admin/wechat/official/materials/{mediaId}/newswechat:official-material:manage按 Media ID 和图文索引编辑公众号图文素材
GET /api/v1/admin/wechat/open-platform/authorizerswechat:open-authorizer:view查询微信开放平台授权方账号快照
POST /api/v1/admin/wechat/open-platform/authorizer-infowechat:open-authorizer:view按授权方 appId 同步微信开放平台授权方资料
GET /api/v1/admin/wechat/official/{accountCode}/menuwechat:official-menu:manage查询公众号当前自定义菜单
POST /api/v1/admin/wechat/official/menuwechat:official-menu:manage按账号发布公众号自定义菜单 JSON
DELETE /api/v1/admin/wechat/official/{accountCode}/menuwechat:official-menu:manage删除公众号当前自定义菜单

Admin 前端菜单 微信生态 对应 /#/wechat,可查看账号、回调事件、消息日志、消息发送效果统计、小程序订阅模板效果、开放平台授权方状态,并提供公众号菜单查询、发布、删除、公众号永久素材统计 / 列表 / 明细查看、素材上传、删除和图文素材编辑、公众号模板消息 / 客服文本 / 小程序订阅消息发送、本地消息模板预设维护、按公众号账号从微信平台同步模板列表,以及一键应用到发送表单。

首批数据表:

  • wechat_account:微信账号配置,覆盖 official / miniapp / open-platform
  • wechat_account_secret:Secret 引用和 hint,不保存 appSecret、token 或 AESKey 明文。
  • wechat_callback_event:回调事件日志,保存 request、事件类型、payload hash 和处理状态。
  • wechat_message_log:入站 / 出站消息日志。
  • wechat_message_template:本地消息模板预设,保存账号、模板类型、模板 code、微信模板 ID、默认跳转、数据 schema、状态和备注。
  • wechat_open_authorizer:微信开放平台授权方快照,保存授权状态、账号类型、主体、功能集和最近同步时间。
  • iam_user_identity:IAM 统一身份表保存 wechat-official-openidwechat-miniapp-openidwechat-unionid,微信模块不单独创建用户身份表。

VO 只返回脱敏后的 verifyTokenRefMasked / encodingAesKeyRefMasked,不返回明文密钥或 Secret 引用全文。

公众号核心 API

微信平台回调是外部协议入口,返回微信要求的原始文本,不套 Result<T>

API说明
GET /api/v1/wechat/official/{accountCode}/callback微信服务器配置校验,验签通过后原样返回 echostr
POST /api/v1/wechat/official/{accountCode}/callback接收公众号消息 / 事件回调,完成验签、解析、事件日志和消息日志落库后返回 success

普通业务查询接口继续返回 Result<T>

API说明
GET /api/v1/wechat/official/oauth/authorize-url按账号、回调地址、scope 和 state 创建公众号网页授权地址
POST /api/v1/wechat/official/js-sdk/signature按账号和页面 URL 创建公众号 JS-SDK 初始化签名

WechatOfficialService 同时提供菜单发布 / 查询 / 删除、永久素材上传 / 删除 / 图文编辑 / 统计 / 分页查询、微信平台模板列表读取、模板消息发送和客服文本消息发送 facade。模板消息和客服消息发送结果会写入 wechat_message_log 出站日志,便于后台审计。后台同步模板时使用稳定编码 wx:<templateId> 写入本地预设;重复同步会更新模板名称、内容示例和行业元数据,但保留本地运营配置的默认跳转、状态和备注。

微信统一身份 API

普通身份 API 返回 Result<T>,其中登录接口返回 IAM LoginVO,绑定接口返回本次写入的 openid / unionid 绑定信息:

API认证说明
POST /api/v1/auth/wechat-official/login公开使用公众号网页授权 code 换取 openid / unionid,并进入 IAM 统一登录链路
POST /api/v1/auth/wechat-official/bind当前用户当前登录用户使用公众号网页授权 code 绑定 openid / unionid
POST /api/v1/auth/wechat-miniapp/login公开使用小程序登录 code 换取 openid / unionid,并进入 IAM 统一登录链路
POST /api/v1/auth/wechat-miniapp/bind当前用户当前登录用户使用小程序登录 code 绑定 openid / unionid

公众号请求体:

json
{
  "accountCode": "main",
  "code": "wechat-oauth-code",
  "lang": "zh_CN",
  "device": "web",
  "createUserIfAbsent": true
}

小程序请求体:

json
{
  "accountCode": "mall",
  "code": "miniapp-login-code",
  "device": "miniapp",
  "createUserIfAbsent": true
}

身份写入规则:

  • 公众号 openid:identity_type=wechat-official-openidprovider=<accountCode 小写>
  • 小程序 openid:identity_type=wechat-miniapp-openidprovider=<accountCode 小写>
  • unionid:identity_type=wechat-unionidprovider=wechat
  • 登录时优先使用 openid 命中已有身份;openid 未命中但 unionid 已存在时复用同一用户并补绑当前账号 openid;两者都不存在且 createUserIfAbsent=true 时创建 IAM 用户。

微信账号也会进入 IAM Identity Provider discovery。GET /api/v1/auth/identity/providers 会按启用的 wechat_account 产出 wechat-official:<accountCode>wechat-miniapp:<accountCode> descriptor,metadata 包含 accountCodeaccountTypeidentityTypeidentityProvider。统一动作入口支持:

Provider codeFlow通用绑定 payload
wechat-official:<accountCode>authorization-code{ "code": "...", "lang": "zh_CN" }
wechat-miniapp:<accountCode>miniapp-code{ "code": "..." }

通用 /api/v1/auth/identity/providers/{code}/bind 会从 provider code 解析 wechat_account.account_code 原值查找微信账号,忽略 payload 中的 accountCode,并把已验证 openid subject 绑定到当前用户;IAM 身份表里的 openid provider 仍使用小写账号编码。若业务需要一次性补绑 unionid,仍使用微信专用 /api/v1/auth/wechat-official/bind/api/v1/auth/wechat-miniapp/bind;这两个专用接口会继续写入 openid 和 unionid 两类身份。

用户端登录与绑定入口

App 与 PC 用户端已接入公众号 / 小程序登录和当前用户绑定入口。入口展示由后台能力控制,不在前端默认硬编码开放微信入口:

  • 登录入口读取 GET /api/v1/auth/capabilitiesloginMethods。只有下发 wechat-officialwechat-miniapp 且当前端环境匹配时,登录页才展示公众号 / 小程序 Tab。
  • 注册入口读取同一响应的 registerMethodsregister.password.enabled。后台关闭注册方式时,App / PC 不展示可点击注册入口。
  • 前端默认登录方式只保留密码、短信、邮箱、钱包和 Passkey;微信入口必须由后台显式下发。

公众号登录 / 绑定入口会调用 GET /api/v1/wechat/official/oauth/authorize-url 生成微信网页授权地址。授权回跳可携带以下 query:

text
mode=wechat-official
wechatAccountCode=main
code=<wechat-oauth-code>
state=<opaque-state>

PC 登录页 /login、App 登录页 /pages/login/index 会在后台能力允许时自动切换到公众号登录并提交;当前用户绑定页分别是 PC /account/security 和 App /pages/settings/index,绑定回跳使用 mode=wechat-official-bind

小程序登录 / 绑定入口复用小程序运行时返回的登录 code:

text
mode=wechat-miniapp
wechatAccountCode=mall
code=<miniapp-login-code>

PC 端提供手工粘贴小程序 code 的调试入口;App 小程序环境会优先尝试 uni.login({ provider: "weixin" }) 获取 code。H5 / 非微信小程序环境不能直接生成小程序 code,需要业务小程序容器回传。

当前前端文件入口:

文件能力
Appviews/app/src/pages/login/index.vue后台控制的公众号 / 小程序登录 Tab、授权回跳自动提交
Appviews/app/src/pages/settings/index.vue当前用户公众号 / 小程序身份绑定
PCviews/pc/app/pages/login.vue后台控制的公众号 / 小程序登录 Tab、公众号授权跳转、回跳自动提交
PCviews/pc/app/pages/account/security.vue当前用户公众号 / 小程序身份绑定

小程序核心 API

普通小程序 API 返回 Result<T>

API说明
POST /api/v1/wechat/miniapp/code2-session按小程序账号和临时登录 code 换取 openid / unionid 绑定输入;响应只返回脱敏后的 sessionKeyMasked
POST /api/v1/wechat/miniapp/payment-context按小程序账号和临时登录 code 生成 JSAPI / 小程序支付上下文;返回 scene=jsapiattributes.openid / attributes.openId / attributes.open_id / attributes.wechatAccountCode / attributes.wechatUnionId,不返回 session key 明文
POST /api/v1/wechat/miniapp/phone-number按小程序账号和手机号组件 code 换取手机号、纯手机号、区号与 watermark

WechatMiniappService 同时提供旧版 sessionKey + encryptedData + iv 手机号解析和订阅消息发送 facade。订阅消息发送结果会写入 wechat_message_log 出站日志;Notification 的 wechat 通道已复用该服务层能力,IAM 绑定接口复用 openid / unionid 输入。

小程序 payment-context 只负责把微信登录 code 兑换为支付上下文,不创建支付单、不保存支付状态、不处理退款。前端可把返回的 sceneattributes 原样传给 Cashier 下单,或放入 Payment Platform 开放支付 extraJson;Payment / Cashier + IJPay 主链路会统一识别 openidopenIdopen_id 三种 openid 别名。

微信开放平台核心 API

微信开放平台第三方平台回调是外部协议入口,返回微信要求的原始文本,不套 Result<T>

API说明
POST /api/v1/wechat/open-platform/{componentAccountCode}/callbacks接收 component ticket、授权成功 / 更新授权 / 取消授权等开放平台回调,完成验签、解密、事件日志和 authorizer 快照更新后返回 success

普通业务接口继续返回 Result<T>

API说明
POST /api/v1/wechat/open-platform/pre-auth-url按开放平台组件账号、回调地址、授权类型和业务小程序 appId 生成第三方平台预授权 URL
POST /api/v1/wechat/open-platform/query-auth按授权码换取授权方 access token / refresh token,并刷新本地授权方快照

授权回调会使用 WxJava 维护 component verify ticket、预授权码、授权码和 authorizer token 生命周期。本地表只保存授权方快照和 Secret 引用占位,不保存 appSecret、componentSecret、authorizer access token 或 refresh token 明文。

后续路线

  • 完整体收尾:用户端回调 smoke 和企业微信 / 视频号 / 小店等按后续明确需求扩展。

Released under the Apache License 2.0.