Files
past-go/部署验收清单.md
T
CodeBuddy bf99e52937 feat: 存储空间管理、虚拟支付接入与容量守卫
- 新增存储空间管理:会员套餐配置、用户容量/到期管理、后台支付记录查询
- 接入个人主体小程序虚拟支付:下单/发货推送/兜底查单(query_order)
- 修复 adminStorageUsers 等接口鉴权、out_trade_no 长度、前端 requestVirtualPayment 参数
- 前端上传前容量预检,超容引导升级无限空间
- 我的页会员卡片展示「无限空间」与已用容量/到期时间
- 后台「存储空间管理」新增支付记录标签页
2026-10-30 23:45:39 +08:00

88 lines
5.7 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:后台「存储空间管理」提示「请先登录」
- **根因**:新增的 `admin_storage_users`、`admin_storage_user_update` 两个接口未加入后台鉴权白名单,被当成普通用户接口校验,所以返回「请先登录」。
- **修复**:已加入 `adminActions` 白名单,现在走后台 Cookie 会话鉴权,可正常拉取用户列表。
### 问题 2:前端存储支付页显示「支付失败,请稍后再试」
- **根因 A(后端)**:订单号 `out_trade_no` 为 `"SP" + 32 位随机串 = 34 位`,**超过微信要求的 8–32 位**,被微信拒绝。
- 修复:改为 `"S" + 31 位随机串 = 32 位`。
- **根因 B(前端)**:`wx.requestVirtualPayment` 误把 `offerId / env / productId / goodsPrice / buyQuantity / currencyType` 作为**顶层参数**传入。这些字段只能存在于 `signData` JSON 字符串内部,顶层仅允许 `signData / paySig / signature / mode` 四个参数。
- 修复:`pages/storage/storage.js` 已改为只传这四个参数。
### 额外增强:兜底查单(query_order)
- 新增服务端主动查单逻辑:服务启动后定时(默认 5 分钟)扫描 24 小时内未发货订单,调用微信 `query_order` 接口,已支付但推送丢失的订单会**自动补发货开通会员**,已关闭订单自动标记 `closed`。
- 新增 `internal/virtualpay` 的 `QueryOrder` 方法(签名:`pay_sig = HMAC-SHA256(AppKey, "/xpay/query_order&" + body)`)。
---
## 二、部署步骤
1. **后端**:用 `dist/past-windows-deploy.zip` 替换服务器上的部署目录并重启。
2. **小程序前端**:`weapp/pages/storage/storage.js` 已改动,请在微信开发者工具重新上传并提交审核发布。
3. **配置**:按下面清单逐项配置虚拟支付。
---
## 三、部署前检查清单(逐项验收)
> 对照微信个人主体虚拟支付接入文档,逐项验收。
| # | 检查项 | 本项目验收方法 / 操作 |
|---|--------|------------------------|
| 1 | 开放条件:个人主体 + 大陆身份证 + 服务类目「工具」+ 已完成认证与备案 | 微信公众平台(MP)后台确认 |
| 2 | 全终端月支付限额 10 万元,已了解并告知用户 | 确认知晓,可在会员页注明 |
| 3 | MP 后台「虚拟支付」能力已开通 | MP 后台 → 功能 → 虚拟支付,确认状态为已开通 |
| 4 | 已拿到 AppID / OfferID / 现网 AppKey | 见下方「配置项 A」 |
| 5 | 需 iOS 支付时已配置小程序简称 | 仅 iOS 需要,Android 可跳过 |
| 6 | 消息推送接收已部署 | 服务已提供回调地址(见「配置项 B」) |
| 7 | MP 后台已配置发货推送 URL,并完成一笔测试支付 | 见下方「配置项 B」+「沙箱测试」 |
| 8 | 服务器验签逻辑通过 | 已实现 `sha1(sort(token,timestamp,nonce))` 明文验签,`token` 需与 MP 后台一致 |
| 9 | 发货推送已做幂等 | 已实现:按 `out_trade_no` + `status='success'` 去重,重复推送不会重复开通 |
| 10 | 前端 `wx.requestVirtualPayment` 打通 | 本次已修复参数,见「问题 2」 |
| 11 | 兜底查单逻辑就绪(query_order) | 本次已新增,服务启动后自动运行 |
| 12 | 退款规则 / 结算周期与费率已说明 | 虚拟支付结算周期 T+1,费率见 MP 后台说明,需在会员页告知 |
| 13 | 上线后小额真单验证 | 正式上线后做一笔真实小额支付,确认到账与发货 |
---
## 配置项 A:支付通道配置(后台「存储空间」→「存储收费设置」)
| 字段 | 说明 | 沙箱(测试) | 正式(上线) |
|------|------|-------------|-------------|
| `pay_env` | 支付环境 | `1` | **`0`** |
| `pay_offer_id` | 支付应用 ID | 沙箱 OfferID | 正式 OfferID |
| `pay_app_key` | 正式环境 AppKey | 留空 | **正式 AppKey** |
| `pay_sandbox_key` | 沙箱 AppKey | 沙箱 AppKey | 可留空 |
| `month_product_id` | 包月道具 ID | 沙箱道具 ID | 正式道具 ID |
| `year_product_id` | 包年道具 ID | 沙箱道具 ID | 正式道具 ID |
| `month_price_cents` | 包月价格(分) | 与道具价格一致 | 与道具价格一致 |
| `year_price_cents` | 包年价格(分) | 与道具价格一致 | 与道具价格一致 |
| `pay_mode` | 支付模式 | `short_series_goods` | `short_series_goods` |
> **重要**:`month_product_id / year_product_id` 必须在微信「虚拟支付 → 道具管理」里创建,且**道具价格(分)必须与 `month_price_cents / year_price_cents` 完全一致**,否则支付时价格校验失败。
> `config.yaml` 里 `virtual_pay.env` 默认是 `1`(沙箱)。**正式上线前务必改成 `0`**,或在后台把 `pay_env` 改为 `0`(后台优先)。
---
## 配置项 B:发货推送回调(微信后台「消息推送」)
- **URL**:`https://你的域名/api/storage_pay_notify`
- **Token**:与 `config.yaml` 的 `virtual_pay.notify_token` 保持一致
- **消息加密方式**:选择 **明文模式**(当前代码按明文模式验签;若选安全模式需另行实现 AES 解密)
配置 URL 时微信会发起 GET 验证,服务端已实现 `echostr` 回显 + 签名校验,验证通过即可。
---
## 沙箱测试流程(上线前必做)
1. 后台将 `pay_env` 设为 `1`,填入沙箱 OfferID / 沙箱 AppKey / 沙箱道具 ID。
2. 用测试微信号打开小程序,进入「我的 → 存储空间」发起支付。
3. 确认能拉起 `wx.requestVirtualPayment`,完成沙箱支付。
4. 观察:支付成功后会员自动到账;若推送延迟,5 分钟内兜底查单会自动补发货。
5. 测试通过后,把 `pay_env` 改为 `0`、换成正式 OfferID / AppKey / 道具 ID,再提交审核发布。