12 KiB
12 KiB
微信公众号与微信支付集成 - 任务清单
1. 依赖安装和配置准备
- 1.1 安装 PowerWeChat v3 SDK:
go get -u github.com/ArtisanCloud/PowerWeChat/v3 - 1.2 在
pkg/config/defaults/config.yaml中新增微信配置结构(wechat.official_account、wechat.payment) - 1.3 在
pkg/config/config.go中定义微信配置结构体(WechatConfig、OfficialAccountConfig、PaymentConfig) - 1.4 在
docs/environment-variables.md中添加微信相关环境变量说明
2. 错误码定义
- 2.1 在
pkg/errors/codes.go中新增微信相关错误码(1040-1049) - 2.2 在
pkg/errors/messages.go中添加对应的中英文错误消息
3. 微信服务基础设施(pkg/wechat)
- 3.1 实现
pkg/wechat/config.go- 创建 PowerWeChat 配置初始化函数 - 3.2 实现
pkg/wechat/official_account.go- OfficialAccount 服务实现- 3.2.1 实现
NewOfficialAccountService()初始化函数(集成 Redis 缓存) - 3.2.2 实现
GetUserInfo(ctx, code)方法(调用 OAuth.UserFromCode) - 3.2.3 实现
GetUserInfoByToken(ctx, accessToken, openID)方法
- 3.2.1 实现
- 3.3 实现
pkg/wechat/payment.go- Payment 服务实现- 3.3.1 实现
NewPaymentService()初始化函数(集成 Redis 缓存) - 3.3.2 实现
CreateJSAPIOrder(ctx, params)方法(JSAPI 支付下单) - 3.3.3 实现
CreateH5Order(ctx, params)方法(H5 支付下单) - 3.3.4 实现
QueryOrder(ctx, orderNo)方法(查询订单状态) - 3.3.5 实现
CloseOrder(ctx, orderNo)方法(关闭订单) - 3.3.6 实现
HandlePaymentNotify(request, callback)方法(支付回调处理)
- 3.3.1 实现
- 3.4 实现
pkg/wechat/wechat.go- 更新 Service 接口定义(保持向后兼容) - 3.5 删除
pkg/wechat/mock.go(替换为真实实现)
4. 配置验证和启动检查
- 4.1 在
cmd/api/main.go中添加微信配置验证逻辑 - 4.2 验证证书文件存在性和可读性(cert_path、key_path)
- 4.3 验证必填配置项(AppID、AppSecret、商户号、API 密钥)
- 4.4 配置缺失或证书文件不存在时记录 FATAL 日志并退出
5. DTO 定义
- 5.1 在
internal/model/dto/wechat_dto.go中定义微信相关 DTO- 5.1.1 定义
WechatOAuthRequest(code) - 5.1.2 定义
WechatOAuthResponse(token、customer) - 5.1.3 定义
WechatPayJSAPIRequest(openid) - 5.1.4 定义
WechatPayJSAPIResponse(prepay_id、pay_config) - 5.1.5 定义
WechatPayH5Request(scene_info) - 5.1.6 定义
WechatPayH5Response(h5_url) - 5.1.7 添加
description标签和验证标签(validate)
- 5.1.1 定义
6. Service 层实现 - 个人客户服务
- 6.1 修改
internal/service/personal_customer/service.go- 6.1.1 添加
wechatService wechat.Service字段(依赖注入) - 6.1.2 实现
WechatOAuthLogin(ctx, code)方法- 6.1.2.1 调用
wechatService.GetUserInfo()获取 OpenID/UnionID - 6.1.2.2 通过 OpenID 查询客户(Store.GetByWxOpenID)
- 6.1.2.3 如果客户不存在,创建新客户
- 6.1.2.4 如果客户存在,更新昵称和头像
- 6.1.2.5 生成 JWT Token 并返回
- 6.1.2.1 调用
- 6.1.3 修改现有
BindWechat(ctx, customerID, code)方法- 6.1.3.1 调用
wechatService.GetUserInfo()获取 OpenID/UnionID - 6.1.3.2 验证 OpenID 未被其他用户绑定
- 6.1.3.3 更新客户的 wx_open_id 和 wx_union_id
- 6.1.3.4 更新昵称和头像
- 6.1.3.1 调用
- 6.1.1 添加
7. Service 层实现 - 订单服务
- 7.1 修改
internal/service/order/service.go- 7.1.1 添加
wechatPayment wechat.PaymentService字段(依赖注入) - 7.1.2 实现
WechatPayJSAPI(ctx, orderID, openID)方法- 7.1.2.1 查询订单并验证状态为
pending - 7.1.2.2 调用
wechatPayment.CreateJSAPIOrder()创建支付订单 - 7.1.2.3 生成 JSSDK 支付配置
- 7.1.2.4 返回 prepay_id 和 pay_config
- 7.1.2.1 查询订单并验证状态为
- 7.1.3 实现
WechatPayH5(ctx, orderID, sceneInfo)方法- 7.1.3.1 查询订单并验证状态为
pending - 7.1.3.2 调用
wechatPayment.CreateH5Order()创建支付订单 - 7.1.3.3 返回 h5_url
- 7.1.3.1 查询订单并验证状态为
- 7.1.4 修改现有
HandlePaymentCallback(ctx, orderNo, paymentMethod)方法(保持幂等逻辑不变)
- 7.1.1 添加
8. Handler 层实现 - 个人客户 Handler
- 8.1 修改
internal/handler/app/personal_customer.go- 8.1.1 实现
WechatOAuthLogin(c *fiber.Ctx)方法(POST /api/c/v1/wechat/auth)- 8.1.1.1 解析请求参数(code)
- 8.1.1.2 调用
service.WechatOAuthLogin() - 8.1.1.3 返回 JWT Token 和客户信息
- 8.1.2 修改
BindWechat(c *fiber.Ctx)方法(POST /api/c/v1/bind-wechat)- 8.1.2.1 从 context 获取 customer_id
- 8.1.2.2 解析请求参数(code)
- 8.1.2.3 调用
service.BindWechat() - 8.1.2.4 返回成功响应
- 8.1.1 实现
9. Handler 层实现 - H5 订单 Handler
- 9.1 修改
internal/handler/h5/order.go- 9.1.1 实现
WechatPayJSAPI(c *fiber.Ctx)方法(POST /api/h5/orders/:id/wechat-pay/jsapi)- 9.1.1.1 解析路径参数(order_id)
- 9.1.1.2 解析请求参数(openid)
- 9.1.1.3 调用
orderService.WechatPayJSAPI() - 9.1.1.4 返回支付配置
- 9.1.2 实现
WechatPayH5(c *fiber.Ctx)方法(POST /api/h5/orders/:id/wechat-pay/h5)- 9.1.2.1 解析路径参数(order_id)
- 9.1.2.2 解析请求参数(scene_info)
- 9.1.2.3 调用
orderService.WechatPayH5() - 9.1.2.4 返回 h5_url
- 9.1.1 实现
10. Handler 层实现 - 支付回调 Handler
- 10.1 修改
internal/handler/callback/payment.go- 10.1.1 添加
wechatPayment wechat.PaymentService字段(依赖注入) - 10.1.2 重构
WechatPayCallback(c *fiber.Ctx)方法- 10.1.2.1 调用
wechatPayment.HandlePaymentNotify()自动验证签名 - 10.1.2.2 在回调函数中提取订单号
- 10.1.2.3 调用
orderService.HandlePaymentCallback()更新订单状态 - 10.1.2.4 返回 PowerWeChat 格式的响应
- 10.1.2.1 调用
- 10.1.1 添加
11. 路由注册
- 11.1 修改
internal/routes/personal.go- 11.1.1 添加公开路由:POST /api/c/v1/wechat/auth(WechatOAuthLogin)
- 11.1.2 保留现有认证路由:POST /api/c/v1/bind-wechat(BindWechat)
- 11.2 修改
internal/routes/order.go- 11.2.1 添加 H5 认证路由:POST /api/h5/orders/:id/wechat-pay/jsapi
- 11.2.2 添加 H5 认证路由:POST /api/h5/orders/:id/wechat-pay/h5
- 11.2.3 保留回调路由(无认证):POST /api/callback/wechat-pay
12. 依赖注入和初始化
- 12.1 修改
internal/bootstrap/services.go- 12.1.1 初始化
wechat.OfficialAccountService(传入 config、Redis client、logger) - 12.1.2 初始化
wechat.PaymentService(传入 config、Redis client、logger) - 12.1.3 将微信服务注入到
PersonalCustomerService - 12.1.4 将微信支付服务注入到
OrderService
- 12.1.1 初始化
- 12.2 修改
internal/bootstrap/handlers.go- 12.2.1 将微信支付服务注入到
PaymentHandler
- 12.2.1 将微信支付服务注入到
13. 文档生成器更新
- 13.1 修改
cmd/api/docs.go- 13.1.1 在
handlers结构体中添加新 Handler 的占位符(如需要) - 13.1.2 更新文档路由注册
- 13.1.1 在
- 13.2 修改
cmd/gendocs/main.go- 13.2.1 同步更新文档生成器的 Handler 初始化
14. 单元测试
- 14.1 测试
pkg/wechat/official_account.go- 14.1.1 测试
GetUserInfo()成功获取用户信息 - 14.1.2 测试授权码无效时的错误处理
- 14.1.3 测试 Access Token 缓存机制
- 14.1.1 测试
- 14.2 测试
pkg/wechat/payment.go- 14.2.1 测试
CreateJSAPIOrder()成功创建订单 - 14.2.2 测试
CreateH5Order()成功创建订单 - 14.2.3 测试
HandlePaymentNotify()签名验证 - 14.2.4 测试支付回调幂等性
- 14.2.1 测试
- 14.3 测试
internal/service/personal_customer/service.go- 14.3.1 测试
WechatOAuthLogin()首次登录创建客户 - 14.3.2 测试
WechatOAuthLogin()已有客户更新信息 - 14.3.3 测试
BindWechat()成功绑定 - 14.3.4 测试
BindWechat()OpenID 已被绑定
- 14.3.1 测试
- 14.4 测试
internal/service/order/service.go- 14.4.1 测试
WechatPayJSAPI()成功发起支付 - 14.4.2 测试
WechatPayH5()成功发起支付 - 14.4.3 测试订单状态不正确时的错误处理
- 14.4.1 测试
15. 集成测试
- 15.1 测试个人客户微信登录完整流程
- 15.1.1 测试
POST /api/c/v1/wechat/auth端点(Mock 微信 OAuth) - 15.1.2 验证返回 JWT Token 和客户信息
- 15.1.3 验证数据库中客户记录正确创建/更新
- 15.1.1 测试
- 15.2 测试微信绑定流程
- 15.2.1 测试
POST /api/c/v1/bind-wechat端点 - 15.2.2 验证绑定成功后 wx_open_id 更新
- 15.2.1 测试
- 15.3 测试 JSAPI 支付流程
- 15.3.1 测试
POST /api/h5/orders/:id/wechat-pay/jsapi端点 - 15.3.2 验证返回 prepay_id 和 pay_config
- 15.3.1 测试
- 15.4 测试 H5 支付流程
- 15.4.1 测试
POST /api/h5/orders/:id/wechat-pay/h5端点 - 15.4.2 验证返回 h5_url
- 15.4.1 测试
- 15.5 测试微信支付回调流程
- 15.5.1 测试
POST /api/callback/wechat-pay端点(Mock 微信签名) - 15.5.2 验证订单状态更新为
paid - 15.5.3 验证套餐激活和分佣计算触发
- 15.5.4 测试重复回调的幂等性
- 15.5.1 测试
16. 代码质量检查
- 16.1 运行
go fmt格式化所有新增代码 - 16.2 运行
go vet检查代码问题 - 16.3 运行
golangci-lint检查代码规范 - 16.4 检查所有注释使用中文
- 16.5 检查所有错误处理使用
pkg/errors - 16.6 检查所有常量定义在
pkg/constants/
17. 文档更新
- 17.1 创建
docs/wechat-integration/使用指南.md- 17.1.1 微信公众号配置说明(AppID、AppSecret、OAuth 回调域名)
- 17.1.2 微信支付配置说明(商户号、证书、回调 URL)
- 17.1.3 证书文件获取和安装流程
- 17.1.4 环境变量配置示例
- 17.2 创建
docs/wechat-integration/API 文档.md- 17.2.1 微信 OAuth 登录 API 说明
- 17.2.2 微信支付 API 说明(JSAPI + H5)
- 17.2.3 请求/响应示例
- 17.3 更新
README.md- 17.3.1 在核心功能章节添加微信集成说明
- 17.3.2 更新技术栈章节(新增 PowerWeChat)
- 17.4 更新
docs/environment-variables.md- 17.4.1 添加所有微信相关环境变量
- 17.5 更新
openspec/AGENTS.md(如需要)- 17.5.1 添加微信集成相关的开发规范
18. 部署准备
- 18.1 准备测试环境配置
- 18.1.1 获取微信测试公众号 AppID 和 AppSecret
- 18.1.2 获取微信支付测试商户号和证书
- 18.1.3 配置微信后台白名单(OAuth 回调域名、支付回调 URL)
- 18.2 准备生产环境配置
- 18.2.1 获取正式公众号 AppID 和 AppSecret
- 18.2.2 获取正式商户号和证书
- 18.2.3 配置生产环境微信后台白名单
- 18.3 创建证书管理文档
- 18.3.1 证书过期提醒机制
- 18.3.2 证书更新流程
- 18.3.3 证书存储安全规范
19. 验证和测试
- 19.1 本地开发环境验证
- 19.1.1 验证配置加载正确
- 19.1.2 验证证书文件读取正常
- 19.1.3 验证 Redis 缓存工作正常
- 19.2 测试环境集成测试
- 19.2.1 使用真实微信测试账号测试 OAuth 登录
- 19.2.2 使用真实商户号测试 JSAPI 支付(0.01 元测试订单)
- 19.2.3 使用真实商户号测试 H5 支付
- 19.2.4 验证支付回调正常触发和处理
- 19.3 压力测试
- 19.3.1 测试并发支付请求(100 QPS)
- 19.3.2 测试并发回调处理(50 QPS)
- 19.3.3 验证 Redis Token 缓存不会频繁刷新
20. 监控和告警
- 20.1 添加监控指标
- 20.1.1 微信 OAuth 成功率/失败率
- 20.1.2 支付发起成功率/失败率
- 20.1.3 支付回调接收数量/验证失败数量
- 20.1.4 Access Token 获取次数
- 20.2 配置告警规则(如有监控系统)
- 20.2.1 微信 OAuth 失败率 > 10% 告警
- 20.2.2 支付发起失败率 > 5% 告警
- 20.2.3 支付回调验证失败数量 > 10/分钟 告警