init: mipu-open 对外开放项目统一管理仓库

- 添加 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>
This commit is contained in:
杨柳杰
2026-05-04 12:16:08 +08:00
commit b450b512a2
38 changed files with 5473 additions and 0 deletions

424
docs/04-03_booking-query.md Normal file
View File

@@ -0,0 +1,424 @@
<!-- mipuyun-api-doc: booking-query -->
# booking/query - 订单查询
# 订单查询(booking/query) API 说明文档
## 使用场景
> 1. 查询订单的详细信息和当前状态
> 2. 在支付完成后查询订单确认状态
> 3. 在客服系统中查询订单详情
> 4. 获取订单的完整行程、乘客和费用信息
## 错误场景(不应该使用本接口的场景)
> 1. 查询不存在的订单 ID
> 2. 查询不属于当前客户的订单clientCode 不匹配)
## 性能指标
> - 响应速度98% 的请求响应速度 < 500ms
> - 接口成功率:> 99.5%
## 请求说明
| **请求地址** | https://${endpoint}/booking/query |
| --- | --- |
| **请求方法** | 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"
}
```
#### 参数详情
| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** |
| --- | --- | --- | --- | --- |
| orderId | String | **是** | abbc4b57fb75 | 客户的订单号,用于查询订单详情 |
## 返回参数
### 成功响应
```json
{
"orderId": "abbc4b57fb75",
"requestId": "req-12345",
"agentCode": "u2web",
"status": "CONFIRMED",
"payStatus": "PAID",
"origin": "MIL",
"destination": "CAG",
"journeyType": "OW",
"pnr": "ABC123",
"pnrExpiryTime": "2025-12-25T12:00:00Z",
"feeItems": {
"baseFare": 100.00,
"taxes": 50.50,
"total": 150.50,
"currency": "EUR"
},
"passengers": [
{
"lastName": "Rossi",
"firstName": "Mario",
"passengerType": "ADT",
"adult": true,
"child": false,
"infant": false,
"dateOfBirth": "1980-01-15",
"gender": "M",
"documentType": "PASSPORT",
"documentNumber": "AA1234567",
"ancillaries": []
}
],
"segments": [
{
"airline": "AZ",
"flightNo": "AZ1234",
"dptAirport": "MIL",
"arrAirport": "CAG",
"dptTime": "2025-11-18T10:30:00Z",
"arrTime": "2025-11-18T12:15:00Z",
"equipment": "A320"
}
],
"credential": null,
"promoCode": "SAVE10",
"createTime": "2024-11-15T10:00:00Z",
"updateTime": "2024-11-15T10:30:00Z",
"retryCount": 3,
"retriedCount": 0
}
```
## 错误码说明
本接口可能返回以下错误码:
| **错误码** | **错误名称** | **说明** | **处理建议** |
| --- | --- | --- | --- |
| 42005 | BOOKING_NOT_FOUND | 订单不存在 | 请检查 orderId 是否正确,或订单是否属于当前客户 |
| 41003 | PRICE_CHANGED | 票价高于预期 | 航司侧价格已变动,请检查响应中的 feeItems 获取最新价格,引导用户确认是否继续 |
### 失败响应
#### 订单不存在 (42005)
```json
{
"code": 42005,
"msg": "Booking not found"
}
```
#### 票价变动 (41003)
```json
{
"code": 41003,
"msg": "Price changed. Please check the latest price in feeItems.",
"data": {
"orderId": "abbc4b57fb75",
"feeItems": {
"baseFare": 110.00,
"taxes": 52.50,
"total": 162.50,
"currency": "EUR"
}
}
}
```
### 响应字段说明
#### 基本字段
| **参数名称** | **类型** | **说明** |
| --- | --- | --- |
| orderId | String | 客户的订单号 |
| requestId | String | 请求 ID |
| agentCode | String | 代理商代码 |
| status | String | 订单状态(见下方状态说明) |
| payStatus | String | 支付状态(见下方支付状态说明) |
| origin | String | 出发地 IATA 3 字码 |
| destination | String | 到达地 IATA 3 字码 |
| journeyType | String | 行程类型<br>**OW**:单程<br>**RT**:往返 |
#### PNR 相关
| **参数名称** | **类型** | **说明** |
| --- | --- | --- |
| pnr | String | 航司 PNR 码(订座记录编号) |
| pnrExpiryTime | String | PNR 有效期ISO 8601 格式UTC 0 时区) |
#### 费用信息
| **参数名称** | **类型** | **说明** |
| --- | --- | --- |
| feeItems | Map | 费用明细(原始 JSON 对象)<br>详见:[feeItems 实体定义](/api-doc?doc=entity-fee-items) |
#### 乘客和航班
| **参数名称** | **类型** | **说明** |
| --- | --- | --- |
| passengers | Array\<BookingPassenger\> | 乘客信息列表(见 BookingPassenger 定义) |
| segments | Array\<BookingSegment\> | 航班段列表(见 BookingSegment 定义) |
#### 其他信息
| **参数名称** | **类型** | **说明** |
| --- | --- | --- |
| credential | Object | 订单凭据信息 |
| promoCode | String | 促销码 |
| createTime | DateTime | 订单创建时间ISO 8601 格式 |
| updateTime | DateTime | 订单最后更新时间ISO 8601 格式 |
| retryCount | Integer | 可重试的次数 |
| retriedCount | Integer | 已经重试的次数 |
## 状态说明
### 订单状态 (status)
| **状态** | **说明** |
| --- | --- |
| PENDING | 订单处理中,等待航司确认 |
| CONFIRMED | 订单已确认PNR 已生成 |
| CANCELLED | 订单已取消 |
| FAILED | 订单失败 |
### 支付状态 (payStatus)
| **状态** | **说明** |
| --- | --- |
| UNPAID | 未支付 |
| PENDING | 支付处理中 |
| PAID | 已支付 |
| REFUNDED | 已退款 |
| FAILED | 支付失败 |
## 数据来源说明
本接口返回的数据优先从 `responseJson` 字段解析,如果 `responseJson` 为空或解析失败code 不是 0 且 feeItems/passengers/segments 均为空),则从 `holdResponse` 字段回退获取。
## 业务流程
### 订单查询场景
```
1. 客户下单booking/hold→ 获取 orderId
2. 客户选择支付方式并支付booking/payment
3. 查询订单状态booking/query→ 确认订单状态
4. 如需要可以取消订单booking/cancel
```
## 常见问题
### 如果订单不存在会返回什么?
接口会返回错误响应code 为 40401msg 为 "Booking not found"。这种情况通常由以下原因造成:
1. orderId 错误或不存在
2. 订单属于其他客户clientCode 不匹配)
3. 订单已过期或被删除
### status 和 payStatus 有什么区别?
- **status**订单的整体状态PENDING/CONFIRMED/CANCELLED/FAILED
- **payStatus**订单的支付状态UNPAID/PENDING/PAID/REFUNDED/FAILED
### feeItems 返回什么结构?
`feeItems` 是一个原始的 Map 对象,直接从航司响应的 JSON 中解析。
详细的字段说明请参考:[feeItems 实体定义](/api-doc?doc=entity-fee-items)
### passengers 和 segments 的详细定义是什么?
#### BookingPassenger乘客信息
| **参数名称** | **类型** | **说明** |
| --- | --- | --- |
| lastName | String | 乘客姓 |
| firstName | String | 乘客名 |
| passengerType | String | 乘客类型ADT/CHD/INF |
| adult | Boolean | 是否为成人 |
| child | Boolean | 是否为儿童 |
| infant | Boolean | 是否为婴儿 |
| dateOfBirth | String | 出生日期 |
| gender | String | 性别M/F |
| documentType | String | 证件类型(如 PASSPORT |
| documentNumber | String | 证件号码 |
| ancillaries | Array | 附加服务列表 |
#### BookingSegment航班段信息
| **参数名称** | **类型** | **说明** |
| --- | --- | --- |
| airline | String | 航司代码IATA 2 字码) |
| flightNo | String | 航班号(如 AZ1234 |
| dptAirport | String | 出发机场 IATA 3 字码 |
| arrAirport | String | 到达机场 IATA 3 字码 |
| dptTime | String | 出发时间ISO 8601 格式 |
| arrTime | String | 到达时间ISO 8601 格式 |
| equipment | String | 机型(如 A320、B737 |
### 什么时候会从 holdResponse 回退数据?
`responseJson` 满足以下任一条件时,会从 `holdResponse` 回退 feeItems/passengers/segments
1. `responseJson` 为空
2. `responseJson` 解析失败
3. `code` 不是 0 且 feeItems/passengers/segments 均为空
这确保了即使订单最终状态失败,也能获取到 hold 阶段的数据。
### 遇到票价变动错误 (PRICE_CHANGED) 怎么办?
当接口返回错误码 41003 (PRICE_CHANGED) 时,表示航司侧票价高于预期。这种情况通常发生在:
1. 下单后到支付前,航司调整了票价
2. 库存紧张导致票价上涨
3. 促销活动价格已过期
**处理流程:**
```
1. 接收到 41003 错误响应
2. 从响应的 data.feeItems 中获取最新价格
3. 向用户展示价格变动信息
4. 询问用户是否继续
5a. 用户同意 → 重新调用 booking/hold 使用新价格
5b. 用户拒绝 → 取消订单流程
```
**关键点:**
- 错误响应中的 `feeItems` 包含最新的价格明细
- 需要用户明确确认后才能继续交易
## 业务案例
### 查询已确认的订单
#### 请求Request
```json
{
"orderId": "abbc4b57fb75"
}
```
#### 响应Response
```json
{
"orderId": "abbc4b57fb75",
"agentCode": "u2web",
"status": "CONFIRMED",
"payStatus": "PAID",
"origin": "MIL",
"destination": "CAG",
"journeyType": "OW",
"pnr": "ABC123",
"passengers": [
{
"lastName": "Rossi",
"firstName": "Mario",
"passengerType": "ADT"
}
],
"segments": [
{
"airline": "AZ",
"flightNo": "AZ1234",
"dptAirport": "MIL",
"arrAirport": "CAG",
"dptTime": "2025-11-18T10:30:00Z",
"arrTime": "2025-11-18T12:15:00Z"
}
],
"createTime": "2024-11-15T10:00:00Z",
"updateTime": "2024-11-15T10:30:00Z"
}
```
### 查询往返程订单
#### 请求Request
```json
{
"orderId": "rt-order-12345"
}
```
#### 响应Response
```json
{
"orderId": "rt-order-12345",
"journeyType": "RT",
"origin": "MIL",
"destination": "CAG",
"status": "CONFIRMED",
"payStatus": "PAID",
"pnr": "XYZ789",
"passengers": [
{
"lastName": "Rossi",
"firstName": "Mario",
"passengerType": "ADT"
},
{
"lastName": "Bianchi",
"firstName": "Luca",
"passengerType": "ADT"
}
],
"segments": [
{
"airline": "AZ",
"flightNo": "AZ1234",
"dptAirport": "MIL",
"arrAirport": "CAG",
"dptTime": "2025-11-18T10:30:00Z",
"arrTime": "2025-11-18T12:15:00Z"
},
{
"airline": "AZ",
"flightNo": "AZ5678",
"dptAirport": "CAG",
"arrAirport": "MIL",
"dptTime": "2025-11-25T14:00:00Z",
"arrTime": "2025-11-25T15:45:00Z"
}
],
"createTime": "2024-11-15T10:00:00Z",
"updateTime": "2024-11-15T10:30:00Z"
}
```