第三方自动出票供应商协议
协议版本 v3.7。第三方 HTTP 供应商按本协议实现接口,平台在自动出票时主动调用供应商。所有渠道统一使用同一套标准协议。
标准流程
平台在查价前生成唯一的外采任务号 procurementNo,后续所有请求都复用这个任务号。
| 步骤 | 路径 | 要求 | Idempotency-Key | 说明 |
|---|---|---|---|---|
| 查价 | /quote/search | 必填 | 否 | 返回完整 policies 报价列表 |
| 验价 | /quote/verify | 可选 | 否 | 确认价格,可更新 supplierOfferData |
| 创单 | /order/create | 必填 | 是 | 返回 supplierOrderNo |
| 支付 | /order/pay | 可选 | 是 | 创单后、出票前支付 |
| 出票 | /order/issue | 必填 | 是 | 提交出票,最终结果以查单为准 |
| 查单 | /order/query | 必填 | 可安全重复 | 轮询状态、票号和采购信息 |
| 取消 | /order/cancel | 预留 | 建议 | 当前人工终止不会调用 |
可选能力由渠道配置开关控制:
supportsPnrData:开启且订单有 PNR 时,平台先查询 IBE D3 / C9,并在请求中携带pnr、pnrContent、c9FareDetails;supportsQuoteVerify:是否在创单前调用验价;supportsOrderPay:是否在创单后、出票前调用支付。
任何可选字段没有值时,平台不会发送空字段。
通信约定
| 项目 | 约定 |
|---|---|
| HTTP 方法 | 全部使用 POST |
| Content-Type | application/json; charset=UTF-8 |
| 时间 / 日期格式 | yyyy-MM-dd HH:mm:ss / yyyy-MM-dd |
| 金额 | JSON number,单位为 currency 对应币种 |
| 成功码 | 0、1、200 |
| 国内 / 国际 | orderRegionType=1 国内,orderRegionType=2 国际 |
请求头
| 请求头 | 必填条件 | 说明 |
|---|---|---|
X-Request-Id | 必填 | 单次 HTTP 请求 ID,供应商应写入日志 |
X-App-Key | HMAC 必填 | 渠道 App Key |
X-Timestamp | HMAC 必填 | 13 位毫秒时间戳 |
X-Nonce | HMAC 必填 | 单次随机字符串 |
X-Signature | HMAC 必填 | HMAC-SHA256 小写十六进制签名 |
Authorization | Bearer 必填 | Bearer {token} |
Idempotency-Key | 创单 / 支付 / 出票必填 | 同任务、同操作重试时保持不变 |
渠道鉴权模式支持 HMAC_SHA256、BEARER_TOKEN、NONE。
HMAC-SHA256 签名
signContent = appKey + "\n" + timestamp + "\n" + nonce + "\n" + rawRequestBody
X-Signature = hexLower(HMAC_SHA256(appSecret, signContent))rawRequestBody 是实际发送的原始 JSON 字符串。验签时必须使用收到的原始 body,不能重新格式化或重新序列化。
响应包络
{ "code": 0, "message": "success", "data": {} }业务失败时应返回非成功的 code 和明确的 message。不要用 HTTP 200 加空 data 表示失败。
查价 POST /quote/search
平台发送订单号、行程、完整乘客列表和全部航段,主要字段如下:
| 字段 | 说明 |
|---|---|
procurementNo / orderSerialNo | 外采任务号、平台业务订单号 |
purchaseChannelCode / channelKind | 渠道编码;channelKind 固定为 EXTERNAL_OPEN |
orderRegionType | 1 国内,2 国际 |
depCode / arrCode、depCityCode / arrCityCode | 首程出发、最终到达的机场码和城市码 |
date / flyNo / depTime / arrTime | 首段日期、航班号、起降时间 |
tripType | ONEWAY 或 ROUND_TRIP |
adultNum / childNum / infantNum / studentNum | 各类乘客数量 |
passengers | 完整乘客列表,包括姓名、类型(ADT / CHD / INF / STU)、证件、票价等 |
segments / routing | 全部航段,以及按去程 / 回程拆分的航程 |
pnr / pnrSourceType / pnrContent / c9FareDetails | 开启 PNR 资料且查询成功时才发送 |
响应返回报价数组 policies:
{
"code": 0,
"message": "success",
"data": {
"policies": [
{
"offerId": "OFFER-001",
"supplierName": "澳洲航空直营",
"supplierTags": ["极速出票"],
"currency": "CNY",
"tripType": "ONEWAY",
"adultTicketPrice": 1150,
"adultTaxesAndFees": 397,
"adultSettlementPrice": 1514.65,
"totalPrice": 1514.65,
"adultCabin": "L",
"remainingSeats": 3,
"reimbursementType": "E",
"fareType": "PUB",
"shouldRebuild": 1,
"ticketTimeLimit": "2026-07-28 11:00:00",
"refundTicketRule": "按航司规定",
"changeTicketRule": "按航司规定",
"checkedLuggageAllowance": "1PC 23KG",
"supplierOfferData": { "sessionId": "SESSION-001" }
}
]
}
}| 字段 | 说明 |
|---|---|
offerId | 必填,当前任务内稳定的报价 ID |
supplierName / supplierCode / supplierTags | 展示名称、内部编码、自定义标签(最多 5 个) |
adultTicketPrice / childTicketPrice | 对应乘客类型订单必填 |
adultSettlementPrice / totalPrice | 单人结算价、整单采购总价;比价时优先使用 totalPrice |
adultCabin / childCabin | 实际可订舱位 |
reimbursementType | 报销凭证:T 行程单、F 发票、E 电子发票、D 行程单+发票 |
fareType | PUB 公布、PRV 私有、GW 官网 |
shouldRebuild | 是否换编码:1 是,2 否 |
supplierOfferData | 供应商私有数据,平台原样透传到后续步骤 |
创单、支付、出票
三个接口共用同一套订单请求结构:
| 字段 | 说明 |
|---|---|
procurementNo | 任务号,全流程不变 |
supplierOrderNo | 创单返回的供应商订单号,支付和出票时必填 |
paymentMode | 当前固定为 SUPPLIER_SELF_PAY |
order | 完整订单快照:订单号、区域、行程类型、联系人、乘客、航段、选中报价 |
offer / passengers / contact | 选中的报价、本次出票的乘客、联系人 |
supplierOfferData | 上一步返回的私有数据 |
- 创单:返回
supplierOrderNo,缺失时平台判定创单失败。必须按Idempotency-Key持久化,重复请求返回同一个订单号。 - 支付:在创单后、出票前调用,同样要求幂等。
- 出票:成功只代表已受理,平台随后立即进入查单。相同
Idempotency-Key的重试禁止重复出票。
查单 POST /order/query
处理中:
{ "code": 0, "message": "success", "data": { "supplierOrderNo": "S202607280001", "status": "PROCESSING", "message": "航司出票中" } }返回 ISSUED 时必须提供:
| 字段 | 说明 |
|---|---|
totalPrice / currency | 整单采购金额与币种 |
procurementAccount / payType / payAccount | 采购账号、支付方式、支付账号;也可放在每张票中 |
exchangeRate / exchangeFromCurrency / exchangeToCurrency | 外币采购时必填 |
tickets | 每位乘客的 passengerId、ticketNo、票面价、采购金额和支付信息 |
segments | 回填规则要求完整航段时必填,平台逐段校验 |
供应商状态
| 状态 | 终态 | 含义 |
|---|---|---|
PENDING | 否 | 待处理或尚未受理 |
ACCEPTED | 否 | 已受理 |
PROCESSING | 否 | 处理中,平台继续查单 |
ISSUED | 是 | 出票成功,必须同时返回完整 tickets |
FAILED | 是 / 待处理 | 业务失败,平台停止当前步骤,等待人工重试 |
CANCELLED | 是 | 已取消 |
未知状态默认按 PROCESSING 处理。如果供应商使用其他状态名,可以在渠道配置中增加状态映射。
可选出票回调
POST {baseUrl}/prod-api/externalProcurement/externalOpenPlatform/callback/issue
供应商在状态变化后回调,平台随即发起一次查单。平台不直接采信回调中的票号,最终结果以 /order/query 的响应为准。
幂等与重试
- 国际订单在第三方 HTTP 渠道上同时只允许一个活动任务;
- 步骤失败后只允许人工重试当前步骤,不会自动创建新任务;
- 重试创单、支付、出票时,复用原任务号、供应商订单号和
Idempotency-Key; - 已出票的任务永久禁止重新创单;
- 网络超时等情况可能触发有限次数的底层重试,供应商接口必须能安全地重复处理。
联调验收清单
- 关闭 PNR 资料开关时,请求中不存在
pnr、pnrContent、c9FareDetails; - 验价、支付开关分别关闭时,流程跳过对应接口;
- 每一步返回的
supplierOfferData能在下一步收到; - 创单、支付、出票以
Idempotency-Key实现强幂等; - 查单可以安全地重复调用,并正确返回各种状态;
- 能通过
X-Request-Id、procurementNo、supplierOrderNo定位单次调用的日志。