feat(tip): add personalized payment success experience

This commit is contained in:
2026-07-20 19:06:42 +08:00
parent c187f0b817
commit edf50e9cc4
16 changed files with 922 additions and 74 deletions
@@ -0,0 +1,126 @@
# Tip 支付成功结果 API 接口定义
## 1. 文档状态
本文档定义咖啡打赏支付成功后,前端展示累计打赏次数和角色感谢语所需的接口扩展,供后端实现和前后端联调使用。
本次不新增 Endpoint,仅扩展现有订单状态接口:
```http
GET /api/payment/order-status?order_id=<ORDER_ID>
```
## 2. 身份与统计口径
订单状态查询保持当前认证规则。前端存在 Token 时继续发送 Bearer Token,没有 Token 时不增加 `Authorization` Header。
`tipCount` 表示包含当前订单在内,同一付款身份向同一 `recipientCharacterId` 成功打赏的累计次数:
| 付款身份 | 统计方式 |
| --- | --- |
| 正式用户 Login Token | 按用户 ID 与收款角色 ID 统计 |
| 游客 Guest Token | 按游客 ID 与收款角色 ID 统计 |
| 无 Token 匿名用户 | 无法可靠跨订单识别,当前订单固定返回 `1` |
只有最终支付成功的 Tip 订单计入次数。pending、failed 或取消订单不增加次数。
## 3. 请求定义
### 3.1 请求地址
```http
GET <API_BASE_URL>/api/payment/order-status?order_id=<ORDER_ID>
```
### 3.2 Query 参数
| 字段 | 类型 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `order_id` | string | 是 | 创建支付订单接口返回的订单 ID。 |
### 3.3 请求示例
```bash
curl 'https://api.banlv-ai.com/api/payment/order-status?order_id=tip_order_123' \
-H 'Authorization: Bearer <TOKEN>'
```
匿名 Tip 订单不发送 Authorization Header
```bash
curl 'https://api.banlv-ai.com/api/payment/order-status?order_id=tip_order_123'
```
## 4. 响应定义
### 4.1 paid Tip 订单
```json
{
"code": 200,
"message": "success",
"success": true,
"data": {
"orderId": "tip_order_123",
"status": "paid",
"orderType": "tip",
"planId": "tip_coffee_usd_9_99",
"tipCount": 2,
"thankYouMessage": "You always know how to make my day a little sweeter."
}
}
```
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `orderId` | string | 当前订单 ID。 |
| `status` | `pending \| paid \| failed` | 当前支付状态。 |
| `orderType` | string | Tip 订单固定为 `tip`。 |
| `planId` | string | 当前订单套餐 ID。 |
| `tipCount` | integer \| null | 当前身份向当前角色累计成功打赏次数,最小值为 `1`。 |
| `thankYouMessage` | string \| null | 收款角色配置的纯文本感谢语。 |
`thankYouMessage` 不得包含 HTML。后端可以返回换行,前端会按纯文本保留展示。
### 4.2 pending、failed 和非 Tip 订单
非 paid Tip 订单不生成打赏成功结果,两个扩展字段必须返回 `null`
```json
{
"code": 200,
"message": "success",
"success": true,
"data": {
"orderId": "pay_order_456",
"status": "pending",
"orderType": "vip_monthly",
"planId": "vip_monthly",
"tipCount": null,
"thankYouMessage": null
}
}
```
角色感谢语配置缺失时,后端允许 paid Tip 响应中的 `thankYouMessage``null`,前端会展示本地通用感谢文案。
## 5. 幂等与一致性
后端在订单首次从非 paid 状态转换为 paid 时,必须原子完成以下操作:
1. 标记支付订单成功;
2. 将当前 Tip 计入付款身份和收款角色的累计次数;
3. 保存当前订单对应的 `tipCount`
4.`recipientCharacterId` 对应的角色配置读取并保存 `thankYouMessage`
同一支付回调重复执行时不得重复累计。对同一个 `order_id` 重复查询必须返回相同的 `tipCount``thankYouMessage`,后续新订单不能改变旧订单的成功结果。
## 6. 验收标准
1. 正式用户和 Guest 对不同角色的累计次数相互独立。
2. 无 Token 匿名用户的成功 Tip 订单返回 `tipCount=1`
3. 首次成功返回 `tipCount=1`,第二次成功返回 `tipCount=2`
4. pending、failed 和非 Tip 订单返回两个 `null` 扩展字段。
5. 同一支付回调重试不会重复增加次数。
6. 同一订单重复轮询得到稳定的次数和感谢语。
7. 感谢语为角色配置的纯文本,不返回 HTML。