feat(tip): add personalized payment success experience
This commit is contained in:
@@ -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。
|
||||
Reference in New Issue
Block a user