fix: 修复微信支付回跳刷新与查单确认

This commit is contained in:
2026-05-14 23:52:01 +08:00
parent cf3dcc6195
commit 2801b55d2f
21 changed files with 880 additions and 119 deletions

View File

@@ -85,17 +85,42 @@
}
```
### 3.3 `POST /api/profile/recharge/wechat/notify`
### 3.3 `POST /api/profile/recharge/orders/{order_id}/wechat/confirm`
需要 Bearer JWT。该接口用于小程序支付页返回 web-view 后的主动查单确认,不替代微信支付通知:
1. 后端读取本地 `profile_recharge_order` 并校验订单归属、支付渠道和当前状态。
2. 若订单已是 `paid`,直接返回订单与账户中心快照。
3. 若订单仍是 `pending`,后端调用微信支付按商户订单号查单接口。
4. 只有微信查单返回 `trade_state = "SUCCESS"` 时,才调用统一入账 procedure 把订单改为 `paid` 并写入钱包流水或会员状态。
5. 如果微信查单仍不是 `SUCCESS`,接口返回当前 pending 订单与账户中心快照;前端只显示“支付已提交”,不提前发放泥点或会员。
响应结构:
```json
{
"order": {
"orderId": "rcg...",
"status": "paid"
},
"center": {
"walletBalance": 120
}
}
```
### 3.4 `POST /api/profile/recharge/wechat/notify`
微信支付通知地址,无需 Bearer JWT。行为
1. 真实渠道使用微信支付平台公钥和 `Wechatpay-*` 请求头验签。
1. 真实渠道使用微信支付平台公钥和 `Wechatpay-*` 请求头验签;验签必须使用原始 HTTP body bytes 构造 `timestamp\nnonce\nbody\n`,不能先把 body 转成字符串再重建
2. 使用 `WECHAT_PAY_API_V3_KEY` 解密通知 `resource`
3. 仅当 `trade_state = "SUCCESS"` 时确认订单支付。
4. 使用微信通知里的 `out_trade_no` 查本地 `profile_recharge_order.order_id`,把订单从 `pending` 改为 `paid`
5. 将微信平台订单号写入 `provider_transaction_id`,用于对账、查单、退款和客服排障。
6. 在同一 SpacetimeDB procedure 内写入钱包流水或会员到期时间,确保重复通知幂等。
7. 验签、解密和业务确认通过后返回 HTTP `204 No Content`;不要返回 V2 XML。
8. 微信支付公钥模式下,真实请求会携带 `Wechatpay-Serial: PUB_KEY_ID_...`,通知验签必须要求回调头 `Wechatpay-Serial``WECHAT_PAY_PLATFORM_SERIAL_NO` 对应;若不匹配应返回 `401` 并在日志里记录 reason。
关键环境变量:
@@ -118,6 +143,9 @@
3. 默认打开 `泥点充值`,可切换到 `会员卡充值`
4. 点击套餐后调用下单接口,按钮进入处理中状态;小程序环境走 native 支付页拉起 `wx.requestPayment`,支付页返回后刷新 `profileDashboard`
- 小程序 web-view 内的 H5 只负责加载微信 JS-SDK 并通过 `wx.miniProgram.navigateTo` 跳转到 `/pages/wechat-pay/index`;实际支付必须在小程序 native 页调用 `wx.requestPayment`,不要切换为 H5 支付产品。
- native 支付页通过 `wx_pay_result=<requestId>:success|cancel|fail` 回填 web-viewH5 在 `hashchange``focus``pageshow``visibilitychange` 中都会尝试消费该结果,避免小程序返回 web-view 时没有触发单一事件导致状态不刷新。
- `success` 只表示微信客户端支付流程返回成功,前端随后调用 `POST /api/profile/recharge/orders/{order_id}/wechat/confirm` 由服务端查单确认;只有通知或服务端查单确认为 `SUCCESS` 才入账。
- `cancel``fail` 只复位按钮、刷新账户中心并展示状态,不调用入账逻辑。
5. 弹窗内不写大段说明文案,只保留必要金额、泥点、会员权益和状态反馈。
6. 会员卡充值区以套餐卡片优先展示周期、价格和处理状态;移动端单列,桌面端三列,权益表允许横向滚动,避免小屏挤压。