# 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 }); } ```