- 新增存储空间管理:会员套餐配置、用户容量/到期管理、后台支付记录查询 - 接入个人主体小程序虚拟支付:下单/发货推送/兜底查单(query_order) - 修复 adminStorageUsers 等接口鉴权、out_trade_no 长度、前端 requestVirtualPayment 参数 - 前端上传前容量预检,超容引导升级无限空间 - 我的页会员卡片展示「无限空间」与已用容量/到期时间 - 后台「存储空间管理」新增支付记录标签页
5.7 KiB
5.7 KiB
虚拟支付接入修复 + 部署验收清单
一、本次修复的两个问题
问题 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作为顶层参数传入。这些字段只能存在于signDataJSON 字符串内部,顶层仅允许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))。
二、部署步骤
- 后端:用
dist/past-windows-deploy.zip替换服务器上的部署目录并重启。 - 小程序前端:
weapp/pages/storage/storage.js已改动,请在微信开发者工具重新上传并提交审核发布。 - 配置:按下面清单逐项配置虚拟支付。
三、部署前检查清单(逐项验收)
对照微信个人主体虚拟支付接入文档,逐项验收。
| # | 检查项 | 本项目验收方法 / 操作 |
|---|---|---|
| 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 回显 + 签名校验,验证通过即可。
沙箱测试流程(上线前必做)
- 后台将
pay_env设为1,填入沙箱 OfferID / 沙箱 AppKey / 沙箱道具 ID。 - 用测试微信号打开小程序,进入「我的 → 存储空间」发起支付。
- 确认能拉起
wx.requestVirtualPayment,完成沙箱支付。 - 观察:支付成功后会员自动到账;若推送延迟,5 分钟内兜底查单会自动补发货。
- 测试通过后,把
pay_env改为0、换成正式 OfferID / AppKey / 道具 ID,再提交审核发布。