Files
2026-01-30 17:25:30 +08:00

258 lines
12 KiB
Markdown
Raw Blame History

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