# 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 | 重试次数,用于追踪当前是第几次重试
**不提供**:系统将自动重试
**提供**:使用指定的重试次数 |
## 返回参数
### 成功响应
```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" | 行程类型
**OW**:单程
**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" | 订单状态
**PENDING**:处理中(重试中)
**CONFIRMED**:已确认
**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 | | 乘客信息列表 |
| 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
});
}
```