- 添加 mipu-api 作为 git submodule (Claude Code Skill) - 迁移 API 文档源文件到 docs/ 目录统一维护 - 添加 Gitea Actions 工作流:tag推送自动打包docs并发布Release - Skill 运行时自动从 mipu-open Release 下载最新文档 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
343 lines
7.8 KiB
Markdown
343 lines
7.8 KiB
Markdown
<!-- mipuyun-api-doc: booking-retry -->
|
||
# booking/retry - 订单重试
|
||
|
||
# 订单重试(booking/retry) API 说明文档
|
||
|
||
## 使用场景
|
||
|
||
> 1. 当订单创建失败时,可以通过本接口重试订单
|
||
> 2. 用于自动或手动恢复失败的订单
|
||
> 3. 支持指定重试次数,避免无限重试
|
||
|
||
## 错误场景(不应该使用本接口的场景)
|
||
|
||
> 1. 订单已成功时(status=CONFIRMED)不需要重试
|
||
> 1. 订单已取消时不能重试
|
||
> 1. 重试次数已达上限时继续重试
|
||
|
||
## 性能指标
|
||
|
||
> - 响应速度:98% 的请求响应速度 < 3000ms(包含重试处理时间)
|
||
> - 接口成功率:> 95%
|
||
|
||
## 请求说明
|
||
|
||
| **请求地址** | https://${endpoint}/booking/retry |
|
||
| --- | --- |
|
||
| **请求方法** | POST |
|
||
|
||
## 请求参数
|
||
|
||
### Header
|
||
|
||
| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** |
|
||
| --- | --- | --- | --- | --- |
|
||
| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON |
|
||
| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝。 |
|
||
| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key |
|
||
| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret |
|
||
|
||
###
|
||
|
||
### 请求体
|
||
|
||
```json
|
||
{
|
||
"orderId": "abbc4b57fb75",
|
||
"retryCount": 1
|
||
}
|
||
```
|
||
|
||
#### 参数详情
|
||
|
||
| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** |
|
||
| --- | --- | --- | --- | --- |
|
||
| orderId | String | **是** | abbc4b57fb75 | 客户的订单号,用于重试失败的订单 |
|
||
| retryCount | Integer | 否 | 1 | 重试次数,用于追踪当前是第几次重试<br>**不提供**:系统将自动重试<br>**提供**:使用指定的重试次数 |
|
||
|
||
## 返回参数
|
||
|
||
### 成功响应
|
||
|
||
```json
|
||
{
|
||
"id": 12345,
|
||
"orderId": "abbc4b57fb75",
|
||
"journeyType": "OW",
|
||
"origin": "MIL",
|
||
"destination": "CAG",
|
||
"departureDate": "20251118",
|
||
"returnDate": null,
|
||
"adults": 1,
|
||
"children": 0,
|
||
"infants": 0,
|
||
"status": "PENDING",
|
||
"pnr": null,
|
||
"pnrExpiryTime": null,
|
||
"agent": "u2web",
|
||
"outboundFareFamily": "promo",
|
||
"inboundFareFamily": null,
|
||
"totalPrice": 150.50,
|
||
"currency": "EUR",
|
||
"createTime": "20241115100000",
|
||
"updateTime": "20241115101500",
|
||
"passengers": [
|
||
{
|
||
"firstName": "first",
|
||
"lastName": "last",
|
||
"passengerType": "ADT"
|
||
}
|
||
],
|
||
"contactInfo": {
|
||
"firstName": "san",
|
||
"lastName": "zhang",
|
||
"email": "san.zhang@gmail.com",
|
||
"phone": "0086-18912345678"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 失败响应
|
||
|
||
#### 订单不存在
|
||
```json
|
||
null
|
||
```
|
||
|
||
### 响应字段说明
|
||
|
||
| **参数名称** | **类型** | **示例值** | **说明** |
|
||
| --- | --- | --- | --- |
|
||
| id | Long | 12345 | 系统内部订单 ID(仅用于调试) |
|
||
| orderId | String | "abbc4b57fb75" | 客户的订单号 |
|
||
| journeyType | String | "OW" | 行程类型<br>**OW**:单程<br>**RT**:往返 |
|
||
| origin | String | "MIL" | 出发地 IATA 3 字码 |
|
||
| destination | String | "CAG" | 到达地 IATA 3 字码 |
|
||
| departureDate | String | "20251118" | 出发日期,格式 YYYYMMDD |
|
||
| returnDate | String/null | null | 返程日期,格式 YYYYMMDD(仅往返程有值) |
|
||
| adults | Integer | 1 | 成人数量 |
|
||
| children | Integer | 0 | 儿童数量 |
|
||
| infants | Integer | 0 | 婴儿数量 |
|
||
| status | String | "PENDING" | 订单状态<br>**PENDING**:处理中(重试中)<br>**CONFIRMED**:已确认<br>**FAILED**:失败 |
|
||
| pnr | String/null | null | 航司 PNR 码(订座记录编号),重试中可能为空 |
|
||
| pnrExpiryTime | String/null | null | PNR 有效期,格式 YYYYMMDDHHmmss(UTC 0 时区) |
|
||
| agent | String | "u2web" | Agent 代码 |
|
||
| outboundFareFamily | String | "promo" | 去程票价族 |
|
||
| inboundFareFamily | String/null | null | 回程票价族(仅往返程有值) |
|
||
| totalPrice | BigDecimal | 150.50 | 订单总价 |
|
||
| currency | String | "EUR" | 币种代码 |
|
||
| createTime | String | "20241115100000" | 订单创建时间,格式 YYYYMMDDHHmmss |
|
||
| updateTime | String | "20241115101500" | 订单最后更新时间,格式 YYYYMMDDHHmmss |
|
||
| passengers | Array<PassengerInfo> | | 乘客信息列表 |
|
||
| contactInfo | Object | | 联系人信息 |
|
||
|
||
## 业务流程
|
||
|
||
### 订单重试流程
|
||
|
||
```
|
||
1. 客户下单(booking/hold)→ 订单创建失败
|
||
↓
|
||
2. 系统或客户检测到失败状态
|
||
↓
|
||
3. 调用重试接口(booking/retry)→ 指定 retryCount
|
||
↓
|
||
4. 系统重新处理订单
|
||
↓
|
||
5a. 成功:status=CONFIRMED,返回订单详情
|
||
↓
|
||
5b. 失败:status=FAILED,可以再次重试
|
||
```
|
||
|
||
### 自动重试策略
|
||
|
||
建议的自动重试策略:
|
||
|
||
```
|
||
第 1 次重试(retryCount=1):立即重试
|
||
第 2 次重试(retryCount=2):等待 30 秒
|
||
第 3 次重试(retryCount=3):等待 60 秒
|
||
第 4 次重试(retryCount=4):等待 120 秒
|
||
超过 4 次:停止重试,联系客服
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
### 什么时候应该使用重试接口?
|
||
|
||
当订单状态为 **FAILED** 时,可以考虑使用重试接口:
|
||
1. 航司系统临时不可用
|
||
2. 网络超时
|
||
3. 航司返回临时错误
|
||
|
||
### retryCount 的作用是什么?
|
||
|
||
retryCount 用于:
|
||
1. **追踪重试次数**:记录当前是第几次重试
|
||
2. **防止无限重试**:可以设置最大重试次数上限
|
||
3. **系统监控**:用于监控重试频率和成功率
|
||
|
||
### 如果订单不存在会返回什么?
|
||
|
||
接口会返回 `null`。这种情况通常由以下原因造成:
|
||
1. orderId 错误或不存在
|
||
2. 订单属于其他客户(clientCode 不匹配)
|
||
|
||
### 重试后订单状态仍然是 FAILED 怎么办?
|
||
|
||
如果多次重试后仍然失败:
|
||
1. 检查错误信息和日志
|
||
2. 确认订单参数是否正确
|
||
3. 检查航司系统是否正常
|
||
4. 联系技术支持
|
||
|
||
### 可以重试已确认的订单吗?
|
||
|
||
不建议。如果订单状态已经是 **CONFIRMED**,重试没有意义。建议先调用 **booking/query** 查询订单状态,确认订单确实失败后再重试。
|
||
|
||
## 业务案例
|
||
|
||
### 第 1 次重试失败的订单
|
||
|
||
#### 请求(Request)
|
||
|
||
```json
|
||
{
|
||
"orderId": "abbc4b57fb75",
|
||
"retryCount": 1
|
||
}
|
||
```
|
||
|
||
#### 响应(Response)
|
||
|
||
```json
|
||
{
|
||
"id": 12345,
|
||
"orderId": "abbc4b57fb75",
|
||
"journeyType": "OW",
|
||
"origin": "MIL",
|
||
"destination": "CAG",
|
||
"departureDate": "20251118",
|
||
"adults": 1,
|
||
"status": "PENDING",
|
||
"pnr": null,
|
||
"totalPrice": 150.50,
|
||
"currency": "EUR",
|
||
"createTime": "20241115100000",
|
||
"updateTime": "20241115101500"
|
||
}
|
||
```
|
||
|
||
### 第 2 次重试(等待后)
|
||
|
||
#### 请求(Request)
|
||
|
||
```json
|
||
{
|
||
"orderId": "abbc4b57fb75",
|
||
"retryCount": 2
|
||
}
|
||
```
|
||
|
||
#### 响应(Response)
|
||
|
||
```json
|
||
{
|
||
"id": 12345,
|
||
"orderId": "abbc4b57fb75",
|
||
"status": "CONFIRMED",
|
||
"pnr": "ABC123",
|
||
"pnrExpiryTime": "20251225120000",
|
||
"updateTime": "20241115102000"
|
||
}
|
||
```
|
||
|
||
### 重试不存在的订单
|
||
|
||
#### 请求(Request)
|
||
|
||
```json
|
||
{
|
||
"orderId": "nonexistent-order-id",
|
||
"retryCount": 1
|
||
}
|
||
```
|
||
|
||
#### 响应(Response)
|
||
|
||
```json
|
||
null
|
||
```
|
||
|
||
### 不指定 retryCount 的重试
|
||
|
||
#### 请求(Request)
|
||
|
||
```json
|
||
{
|
||
"orderId": "abbc4b57fb75"
|
||
}
|
||
```
|
||
|
||
#### 响应(Response)
|
||
|
||
```json
|
||
{
|
||
"orderId": "abbc4b57fb75",
|
||
"status": "PENDING",
|
||
"updateTime": "20241115103000"
|
||
}
|
||
```
|
||
|
||
**说明**:不提供 retryCount 时,系统将自动管理重试次数。
|
||
|
||
## 重试最佳实践
|
||
|
||
### 1. 指数退避策略
|
||
|
||
```json
|
||
{
|
||
"retryCount": 1,
|
||
"waitTime": 0
|
||
}
|
||
```
|
||
→ 失败后立即重试
|
||
|
||
```json
|
||
{
|
||
"retryCount": 2,
|
||
"waitTime": 30
|
||
}
|
||
```
|
||
→ 失败后等待 30 秒
|
||
|
||
```json
|
||
{
|
||
"retryCount": 3,
|
||
"waitTime": 60
|
||
}
|
||
```
|
||
→ 失败后等待 60 秒
|
||
|
||
### 2. 最大重试次数限制
|
||
|
||
建议设置最大重试次数为 **3-5 次**,超过后:
|
||
- 停止自动重试
|
||
- 通知客服介入
|
||
- 记录错误日志
|
||
|
||
### 3. 重试前先查询状态
|
||
|
||
```javascript
|
||
// 1. 先查询订单状态
|
||
const order = await bookingQuery({ orderId: "xxx" });
|
||
|
||
// 2. 确认订单失败后再重试
|
||
if (order.status === "FAILED") {
|
||
await bookingRetry({
|
||
orderId: "xxx",
|
||
retryCount: 1
|
||
});
|
||
}
|
||
```
|