fix(insurance): 充值接口返回支付链接 + 前端弹码/跳转改造说明 (#1725)
这个提交包含在:
父节点
4b3bf7a46c
当前提交
d313eecc4c
@ -0,0 +1,125 @@
|
||||
# fix(insurance): 充值接口返回支付链接 (V2 重构丢失修复)
|
||||
|
||||
**日期**: 2026-05-06 18:30
|
||||
**通知对象**: @mmg (前端)
|
||||
**关联 PR**: wx/HL #1725 (已 merge dev + 测试服部署 + round-trip 6/6 通过)
|
||||
**关联工单**: wx/HL #1724
|
||||
|
||||
---
|
||||
|
||||
## 一、用户反馈
|
||||
|
||||
正式环境 `admin.1814.love/insurance/products`「在线充值」弹窗:
|
||||
- 输入金额 + 选支付方式(支付宝/微信)
|
||||
- 点击「确认充值」
|
||||
- `POST /admin/insurance/recharge` 返回 `{"code":200,"message":"成功","data":null,"success":true}`
|
||||
- **没有任何充值页面 / 微信二维码 / 支付宝表单**,流程死在弹窗
|
||||
|
||||
## 二、根因
|
||||
|
||||
V2 重构 (PR #663) 把 Controller 返回从 `Result<Map<String,Object>>` 改成 `Result<Void>` 时,Service `recharge()` 一开始就是 `void`,**根本没解析保游网 `/Pay/GetRechargeData` 响应里的支付链接**。`RechargeRequest` DTO 里 `payType + backUrl` 已声明,但 Controller 没传给 Service,Service 内部硬编码 PayType=33。
|
||||
|
||||
## 三、修复
|
||||
|
||||
后端改 `recharge` 接口返回支付链接结构体,前端配合改弹码/跳转。
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `RechargeRespVO` (新) | 4 字段:payType/payUrl/formHtml/totalFee |
|
||||
| `AdminInsuranceController.recharge` | `Result<Void>` → `Result<RechargeRespVO>`,透传 DTO 字段 |
|
||||
| `InsuranceManageService.recharge` | 签名改 `(amount, payType, backUrl, adminId, adminName) → RechargeRespVO`,按 payType 解析保游 `Data` |
|
||||
| `OrderInsuranceErrorCode` | 加 `RECHARGE_PAY_TYPE_INVALID(540220)` / `RECHARGE_EMPTY_PAY_DATA(540221)` |
|
||||
|
||||
## 四、API 改动 (前端必看)
|
||||
|
||||
### 请求 `POST /admin/insurance/recharge` (字段未变,提醒强校验)
|
||||
|
||||
```json
|
||||
{
|
||||
"money": 100.00, // 必填,0.01 ≤ ≤ 100000
|
||||
"payType": 33, // 必填!!! 11=支付宝 / 33=微信
|
||||
"backUrl": "https://admin.test.1814.love/insurance/products" // 选填,支付宝跳回地址
|
||||
}
|
||||
```
|
||||
|
||||
⚠️ **`payType` 现在是后端必填**(DTO `@NotNull`)。旧前端如果没传会返 `code:400 message:"payType: 支付方式不能为空"`,请确认前端选择支付方式后必须把值塞 payload。
|
||||
|
||||
### 响应 (新增 data 结构)
|
||||
|
||||
**微信扫码 (payType=33)**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"payType": 33,
|
||||
"payUrl": "weixin://wxpay/bizpayurl?pr=rKqjDdSz3", // ← 微信扫码 URL
|
||||
"formHtml": null,
|
||||
"totalFee": "0.01" // 单位元字符串
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
**支付宝 (payType=11)**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"payType": 11,
|
||||
"payUrl": null,
|
||||
"formHtml": "<form id='alipaysubmit' name='alipaysubmit' action='https://mapi.alipay.com/gateway.do?_input_charset=utf-8' method='post'>...<input ... /></form><script>document.forms['alipaysubmit'].submit();</script>", // ← 完整 HTML 表单
|
||||
"totalFee": null
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
### 业务错误码
|
||||
|
||||
| code | message | 触发条件 |
|
||||
|---|---|---|
|
||||
| 400 | `money: 充值金额最小0.01元` / `充值金额最大100000元` / `充值金额不能为空` | DTO 校验失败 |
|
||||
| 400 | `payType: 支付方式不能为空` | DTO `@NotNull` |
|
||||
| 540220 | 充值支付方式无效, 只支持 11=支付宝 / 33=微信 | payType 不在 (11, 33) |
|
||||
| 540221 | 保游网未返回支付数据 | 第三方异常 |
|
||||
| 540210 | 保游网 errorMessage | 保游 isSuccess=false |
|
||||
|
||||
## 五、前端处理建议
|
||||
|
||||
### 微信扫码 (payType=33)
|
||||
|
||||
`payUrl` 是 `weixin://wxpay/bizpayurl?pr=xxx` 协议链接。**用 qrcode 库本地渲染成二维码图片**贴弹窗里,提示「请用微信扫码完成支付」。扫码后微信会自动唤起支付。
|
||||
|
||||
```js
|
||||
// 推荐用 qrcode (npm: qrcode 或 vue-qr)
|
||||
import QRCode from 'qrcode'
|
||||
QRCode.toDataURL(resp.data.payUrl, (err, url) => {
|
||||
qrImage.value = url // <img :src="qrImage" />
|
||||
})
|
||||
```
|
||||
|
||||
### 支付宝 (payType=11)
|
||||
|
||||
`formHtml` 是完整 `<form>...</form><script>document.forms['alipaysubmit'].submit();</script>`,**整段塞一个隐藏 div / 临时新窗口**触发自动 submit 跳支付宝网关。
|
||||
|
||||
```js
|
||||
// 推荐:开新窗口 document.write 整段写入,自动 submit 跳支付宝
|
||||
const w = window.open('', '_blank')
|
||||
w.document.write(resp.data.formHtml)
|
||||
// 或者塞当前页隐藏 iframe + iframe.contentDocument.write
|
||||
```
|
||||
|
||||
⚠️ formHtml 里包含 `return_url` 字段(后端透传 `backUrl`),用户支付宝付完会跳回该地址。前端建议把 `backUrl` 设为充值页本身,例:`window.location.origin + '/insurance/products'`。
|
||||
|
||||
## 六、测试服 round-trip 已验证
|
||||
|
||||
- 微信:`data.payUrl=weixin://wxpay/bizpayurl?pr=rKqjDdSz3` 非空 ✓
|
||||
- 支付宝:`data.formHtml=<form id='alipaysubmit' action='https://mapi.alipay.com/gateway.do' ...>` 完整 HTML ✓
|
||||
- 反例:payType=99 / money=0 / 缺 payType 全部正确报错 ✓
|
||||
|
||||
## 七、部署计划
|
||||
|
||||
- 测试服:已部署 (deploy task `7e8d25cf` success)
|
||||
- 正式环境:等用户合 dev → main 后通知运维部署
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户