# shopping/search - 运价报价 ## 概述 航班搜索(Flight Search)API 用于驱动 Agent 去数据源(航司)获取对应数据。 ### 用户使用场景 本接口一般用于: - 查询单家航司报价 - 建立航司数据本地缓存 ### 错误场景(不建议使用) 本接口不适合以下场景: - **秒级搜索响应**:本接口为实时调用接口,响应时间依赖数据源(航司),一般响应时间在10秒左右。如需秒级搜索响应,请参考缓存搜索接口(cache/search)。 - **验价**:验价请使用 shopping/select(8秒内响应,成功率98%)。 ### 性能指标 | 指标 | 说明 | |------|------| | 响应速度 | 依赖数据源(航司)响应,根据大数据统计90%的请求在10秒内 | | 成功率 | >90% | ## 请求说明 | 项目 | 值 | |------|-----| | **请求地址** | `https://${endpoint}/shopping/search` | | **请求方法** | POST | | **注意事项** | Header 必须带压缩请求 | ### Header 参数 | 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | |----------|------|----------|--------|------| | Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | | Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝 | | client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | | client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | ### 请求体参数 > 注:灰色背景为高级特性,默认不填写,根据需要进行开发。 ```json { "journeyType": "OW", "origin": "MIL", "destination": "CAG", "departureDate": "20251118", "adults": 1, "children": 0, "infants": 0, "agent": "u2web", "proxy": "myproxy-us" } ``` | 参数名称 | 类型 | 是否必选 | 示例值(默认值) | 说明 | |----------|------|----------|-----------------|------| | journeyType | String | 是 | "OW" | 行程类型:OW=单程(OneWay),RT=往返(RoundTrip) | | origin | String | 是 | "CJJ" | 出发地,为IATA 3字码兼容城市或者机场3字码 | | originAirport | String | 否 | - | 出发机场 | | destination | String | 是 | "SHA" | 到达地,为IATA 3字码兼容城市或者机场3字码 | | destinationAirport | String | 否 | - | 到达机场 | | departureDate | String | 是 | 20240326 | 出发日期,格式为 `YYYYMMDD`(如2024年5月1日为20240501) | | returnDate | String | 否 | 20240423 | 返程日期,格式同 departureDate,仅当 journeyType=RT 时必传 | | adults | Integer | 是 | 2 | 成人乘机人数量 | | children | Integer | 是 | 1 | 儿童乘机人数量 | | infants | Integer | 是 | 0 | 婴儿乘机人数量 | | agent | String | 是 | "F9-web" | 你自行定义的执行器编码(Agent Code) | | proxy | String | 是 | - | 本次获取航司数据采用的代理方式。如需指定代理国家请在代理用户后面加上国家二字码,如 myproxy-US 代表美国 | | currency | String | 否 | - | 航司所支持的货币类型,如航司不支持对应货币,接口会进行报错 | | acceptCacheMinutes | Integer | 否 | 5 | 默认值:5。**如无特殊情况,本参数不建议设置或调整。**为了避免频繁请求航司设置的缓存,用户可以指定缓存时长,不填写为5分钟 | | async | Boolean | 是 | false | 是否启用 Webhook 异步模式。
- **false**: 同步模式,等待完整结果返回
- **true**: 异步模式,立即返回 202,结果通过 Webhook 回调

**异步模式说明**:
1. 系统会同步检查是否有新鲜缓存(acceptCacheMinutes),如有则立即返回
2. 无缓存时返回 202 Accepted,包含 requestId 用于追踪
3. 航司数据返回后,通过预先配置的 Webhook 回调通知

**注意**:使用异步模式需提前配置 `shopping_response` 类型的 Webhook | | callbackId | String | 否 | - | 异步模式下的业务回调标识,用于客户自行匹配业务。建议格式:`search_{origin}_{destination}_{departureDate}_{adults}-{children}-{infants}`,最大 50 个字符 | ## 返回参数 在线查看返回参数示例:https://jsonhero.io/j/XmTLWK94Ae5X | 参数名称 | 类型 | 示例值 | 说明 | |----------|------|--------|------| | itineraries | Array\ | - | 航线组合列表,包含不同航班拼接的行程方案。详见 [Itinerary 实体定义](08-01_itinerary.md) | | code | Integer | 0 | 系统状态码:0=成功,非0为失败 | | msg | String | null | 系统消息:成功时为 null,失败时返回具体系统提示信息 | | sessionId | String | 66d807b0-abbc-4b57-aeff-bbf4fc29fb75 | UUID:与航司通信的 session 值,可以用于加速后续动作,如继续获取包裹、选座、下单 | ### 异步模式响应(async=true) 当 `async=true` 且无可用缓存时,系统立即返回 202 Accepted: | 参数名称 | 类型 | 说明 | |----------|------|------| | code | Integer | 202(表示请求已接受,正在处理中) | | msg | String | "Accepted. Please wait for the webhook callback" | | requestId | String | 请求ID(UUID),用于追踪和关联 Webhook 回调 | | status | String | "PROCESSING"(处理中) | 完整结果将通过预先配置的 Webhook 回调返回。 ## 常见问题 ### origin/originAirport 的区别是什么? **origin**:出发地,建议传入 IATA 规定的城市码,必填 **originAirport**:出发机场,非必填 由于各个数据源对于城市码/机场码的需求场景不一致,服务端做了兼容处理。 一般情况只需要传入 Origin(城市码),我们会自动将 Origin 翻译为机场码,并对航司进行轮询获取所有数据。 部分特殊情况,如只需要搜索单个机场码,或者直接搜索城市码不希望服务端转换为机场码,请将需要搜索的三字码直接放入 originAirport。 **举例:** - 入参:`origin: LON` - 不传入 originAirport,服务端发送给航司:`originAirport: LCY, LGW, LHR, LTN, SEN, STN` - 传入 originAirport: LCY,服务端实际发送给航司:`originAirport: LCY` - 传入 originAirport: LON,服务端实际发送给航司:`originAirport: LON` **destination/destinationAirport 逻辑同 origin/originAirport** ### 这个接口会使用缓存吗? 默认情况本接口会读取一个 5 分钟短效缓存,如果你在 5 分钟重复请求同一个路线,那么第二次会直接返回缓存数据。 你也可以通过 `acceptCacheMinutes` 自己控制缓存时效。 ## 响应实体介绍 ### 响应示例 ```json { "code": 0, "msg": null, "sessionId": "66d807b0-abbc-4b57-aeff-bbf4fc29fb75", "itineraries": [ { "outboundSegments": [ { "index": 1, "carrier": "VJ", "flightNumber": "VJ884", "operatingCarrier": "", "operatingFlightnumber": "", "originAirport": "BOM", "destinationAirport": "SGN", "departureTime": "202510270040", "arrivalTime": "202510270705", "departureTerminal": "", "arrivalTerminal": "", "stopCities": "", "duration": 295, "aircraftCode": "330", "codeShare": false } ], "inboundSegments": [], "fares": [ { "fareBasis": "", "rtnFareBasis": "", "fareFamily": "Lion Economy", "rtnFareFamily": "", "currency": "USD", "adultFare": 100.00, "adultTax": 50.00, "bookingCode": "Y", "availableSeats": 7, "flightPolicy": { "airlineCode": "SL", "fareFamilyType": "Lion Economy", "freeAncillaryList": [ { "categoryCode": "CabinBaggageOverheadLocker", "segmentIndex": 1, "paxType": "ADT", "piece": 1, "weight": 7, "size": "" }, { "categoryCode": "StandardCheckedBaggage", "segmentIndex": 1, "paxType": "ADT", "piece": 1, "weight": 20 } ] } } ] } ] } ``` > **提示**:`itineraries` 数组中的每个元素是一个完整的行程方案,详见 [Itinerary 实体定义](08-01_itinerary.md)