分销商标准接口开发文档 v2.4
版本历史
| 版本号 |
日期 |
描述 |
| v1.0 |
2017-05-08 |
首版 |
| v1.1 |
2017-09-15 |
新增订单核销回调接口 |
| v1.2 |
2018-01-09 |
订单详情接口支持回传确认码 |
| v1.3 |
2018-03-12 |
1、提供请求报文示例 2、修改了部分接口字段的命名方式,OTA 修改为 ota 3、细化了接口返回的错误码 |
| v1.4 |
2018-03-22 |
1、修改退款接口,分销子订单号为非必传,默认所有子订单全部退款。 2、修改下单接口支持同步返回确认码和 pdf 数据流 3、修改订单状态通知接口,支持推送确认码和 pdf 数据流 |
| v1.5 |
2018-03-28 |
下单接口和订单状态通知接口,支持返回 pdf 数据流 |
| v1.6 |
2018-04-23 |
下单接口对传入的价格做校验,如果和报价单不一致会返回价格错误的错误码。 |
| v1.7 |
2018-07-02 |
增加了接口对接时的注意事项 |
| v1.8 |
2018-08-28 |
子订单项 增加了预约时间的字段 |
| V1.9 |
2019-04-26 |
新增商家系统自定义bookingNos字段 1.在预定完成时,订单状态回调接口中新增 bookingNos。2.在分销商查询供应商订单接口中新增bookingNo |
| v2.0 |
2019-08-08 |
对于接送机及包车支持一次下多辆车,且可支持不同车型。注意:包车只支持一日包车 |
| v2.1 |
2022-12-07 |
下单接口,子订单参数节点新增passengerCount(乘客数)、luggageCount(行李数) |
| v2.2 |
2023-04-11 |
订单状态回调接口新增otaSubOrderIds字段,废弃otaSubOrderId,同一个商品,支持多个子订单预订完成 |
| v2.3 |
2023-04-20 |
优化订单状态回调接口 |
| v2.4 |
2025-02-25 |
优化订单状态回调接口 |
API 调用时序图
说明:
- 此时序图中商家系统指供应商,分销商系统指agent
- 对于分销侧API目前只提供订单对接相关接口,对于商品信息,SKUID,价格等可联系support@bookingmeta.com索取在线报价单。在线报价单中有SKUID,可将相对应的SKUID填写到分销商系统中做好映射工作

概述
- 所有接口的请求方式均为
HTTP POST,请求参数为JSON格式的字符串,放在HTTP BODY中。
- 生成签名所需要的密钥
secret由商家系统分配给分销商系统,请妥善保存,请求时不要传递 secret。
- 关于重试逻辑,如果分销商系统没有接到响应成功的结果,可以发起重试请求,重试时不要修改订单号,同一个订单号如果商家系统已经处理成功,会返回上一次处理成功的结果,否则会继续尝试处理业务流程。
接口地址
通用传入参数格式
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaId |
int |
11 |
必须 |
由商家系统分配给分销商的唯一标识 |
10086 |
| method |
String |
64 |
必须 |
接口名称 |
trade.create |
| sign |
String |
32 |
必须 |
签名生成规则,md5(otaId+secret+timestamp+base64(body)) |
202cb962ac59075b964b07152d234b70 |
| timestamp |
int |
11 |
必须 |
请求时间戳,精确到秒,超过10秒的请求 , 商家系统不予处理。 |
1507986131 |
| body |
Object |
|
必须 |
具体业务接口传入参数的JSON对象,请求时请使用base64 编码 |
e1wib3RhT3JkZXJJZFwiOlwiMjAxNzAzMDEwMDAwMDFcIn0 |
传入参数示例
{
"otaId": 18654,
"method": "trade.detail",
"sign": "202cb962ac59075b964b07152d234b70",
"timestamp": 1507986131,
"body": "e1wib3RhT3JkZXJJZFwiOlwiMjAxNzAzMDEwMDAwMDFcIn0="
}
返回结果格式
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| code |
ApiCodeEnum |
16 |
必须 |
接口响应码 |
SUCCESS |
| msg |
String |
32 |
必须 |
信息提示 |
请求成功 |
| data |
Object |
|
|
具体业务接口返回的 JSON 对象 |
|
| requestId |
String |
128 |
必须 |
每次请求的唯一标识,商家系统可通过该标识追踪每次传入和返回的报文 |
d0d438e1b7a311e7a4c064006a34ea1e |
返回结果示例
{
"code": "SUCCESS",
"msg": "请求成功",
"data": {
"otaOrderId": "20170301000001",
"orderId": "201703010000012",
"status": 1
},
"requestId": "d0d438e1b7a311e7a4c064006a34ea1e"
}
签名示例代码(Java 版本)
package com.yourpackage;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
public class SignUtil {
public static void main(String[] args) {
String otaId = "1983";
String secret = "xxxSecretxxx";
String timestamp = System.currentTimeMillis() / 1000L + "";
String body = "{\n" +
" \"orderId\": \"201703010000012\",\n" +
"}";
String sign = getSign(otaId, secret, timestamp, getBase64String(body));
System.out.println(sign);
//7344b388578a87837d3899f797a295bb
}
public static String getSign(String otaId, String secret, String timestamp, String body) {
String combinedString = otaId + secret + timestamp + body;
String sign = md5(combinedString);
return sign;
}
/**
* Md5加密
*
* @param str 待加密的数据
* @return Md5加密后的结果
*/
private static String md5(String str) {
if (str == null) return "";
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(str.getBytes("UTF-8"));
} catch (Exception e) {
return "";
}
byte[] byteArray = messageDigest.digest();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < byteArray.length; i++) {
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
sb.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
else
sb.append(Integer.toHexString(0xFF & byteArray[i]));
}
return sb.toString();
}
private static final char[] CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.toCharArray();
public static String getBase64String(String input) {
String base64String;
try {
base64String = new String(encodeToChar(input.getBytes("UTF-8"), false));
} catch (UnsupportedEncodingException ignore) {
base64String = "";
}
return base64String;
}
private static char[] encodeToChar(byte[] arr, boolean lineSeparator) {
int len = arr != null ? arr.length : 0;
if (len == 0) {
return new char[0];
}
int evenlen = len / 3 * 3;
int cnt = (len - 1) / 3 + 1 << 2;
int destLen = cnt + (lineSeparator ? (cnt - 1) / 76 << 1 : 0);
char[] dest = new char[destLen];
int s = 0;
int d = 0;
for (int cc = 0; s < evenlen; ) {
int i = (arr[(s++)] & 0xFF) << 16 | (arr[(s++)] & 0xFF) << 8 | arr[(s++)] & 0xFF;
dest[(d++)] = CHARS[(i >>> 18 & 0x3F)];
dest[(d++)] = CHARS[(i >>> 12 & 0x3F)];
dest[(d++)] = CHARS[(i >>> 6 & 0x3F)];
dest[(d++)] = CHARS[(i & 0x3F)];
if (!lineSeparator) continue;
cc++;
if ((cc == 19) && (d < destLen - 2)) {
dest[(d++)] = '\r';
dest[(d++)] = '\n';
cc = 0;
}
}
int left = len - evenlen;
if (left > 0) {
int i = (arr[evenlen] & 0xFF) << 10 | (left == 2 ? (arr[(len - 1)] & 0xFF) << 2 : 0);
dest[(destLen - 4)] = CHARS[(i >> 12)];
dest[(destLen - 3)] = CHARS[(i >>> 6 & 0x3F)];
dest[(destLen - 2)] = (left == 2 ? CHARS[(i & 0x3F)] : '=');
dest[(destLen - 1)] = '=';
}
return dest;
}
}
商家系统提供的接口
创建订单
接口说明
- 用户在 OTA 下单并完成支付时,通过此接口将订单信息同步给商家系统。
- 商家系统收到 OTA 下单请求时,首先判断 OTA 订单号在系统中是否存在,若存在,直接返回下单结果;若不存在,创建订单返回下单结果。
- 下单时会对分销商传入的价格做检查,请核对接口传入的价格是否与报价单一致,不一致会返回价格错误的错误码。
- 分销子订单号不能重复,下单时会做校验。
- 接口名称:trade.create
请求参数
SubOrderInfo 子订单信息
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaSubOrderId |
String |
64 |
必须 |
分销商系统的子订单号,如果没有,可以和主订单号一致,注意,多个分销子订单号不能重复。 |
186593816746070 |
| productName |
String |
256 |
|
分销端的商品名称 |
普吉岛海钓包船大小皇帝岛一日游 |
| specRound |
String |
32 |
|
演出的场次 |
8:00 |
| num |
int |
11 |
必须 |
预订数量,如果品类是接机、送机、单次用车、包车预订数量可以大于1,表示此sku(车型)预定多辆车。注意:如果不同车型则需要多个子订单(SubOrderInfo),包车订单目前只支持包1天,不支持包多天 |
2 |
| skuId |
String |
128 |
必须 |
商家系统的 sku 编码 |
S03z7ygko |
| price |
int |
11 |
必须 |
商家系统sku单价,单位分 |
1320 |
| tripStartDate |
Date |
|
必须 |
出行开始日期,格式yyyy-MM-dd |
2017-12-12 |
| tripEndDate |
Date |
|
|
出行结束日期,格式yyyy-MM-dd |
2017-12-13 |
| totalFee |
int |
11 |
必须 |
子订单总金额,单位分。totalFee = price * num |
1320 |
| travellers |
TravellerInfo[] |
|
|
出行人信息 |
|
| transferInfo |
TransferInfo |
|
如果品类是接机、送机、单次用车、包车,必须 |
接送机、用车、包车信息 |
|
| status |
OrderStatusEnum |
|
订单详情接口会返回该字段 |
子订单状态 |
|
| refunds |
RefundInfo[] |
|
如果是订单详情接口,并且子订单有退款,会返回该字段 |
子订单关联的退款信息 |
|
| vouchers |
String[] |
|
订单详情接口会返回该字段 |
目前只支持回传确认码 |
["yx9wzpwr", "yx9wyz1r"] |
| appointmentTime |
String |
|
|
预约时间,精确到分钟 |
12:00 |
| bookingNo |
String |
|
|
商家系统自定义bookingNo |
|
passengerCount |
int |
5 |
选填 |
乘客数 注意:该字段不能小于等于0 |
1 |
luggageCount |
int |
5 |
选填 |
行李数 注意:该字段不能小于等于0 |
3 |
UserInfo 分销端买家信息
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| name |
String |
64 |
|
用户在分销商系统的唯一标识 |
zhangsan |
| phone |
String |
64 |
|
用户电话 |
13888888888 |
| email |
String |
32 |
|
用户邮箱 |
37777@xx.com |
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| cnName |
String |
32 |
|
联系人中文名 |
张三 |
| enName |
String |
32 |
|
联系人英文名 |
zhangsan |
| gender |
GenderEnum |
|
|
性别枚举 |
1 |
| email |
String |
32 |
|
联系人邮箱 |
377733@xx.com |
| mobileCode |
String |
16 |
|
联系人手机区号 |
+86 |
| mobile |
String |
32 |
|
联系人手机号 |
15911028222 |
| foreignAreaCode |
String |
16 |
|
联系人境外手机区号 |
+86 |
| foreignMobile |
String |
32 |
|
联系人境外手机号 |
1-626-780-7552 |
| postAddress |
String |
512 |
|
完整的收货地址,包含省、市、区 |
xx省 xx市 xx区 xx东路138号 |
| zipCode |
String |
16 |
|
收货地址邮编 |
310002 |
| qq |
String |
32 |
|
联系人 QQ |
37773312 |
| wechatNo |
String |
32 |
|
联系人微信 |
37773312 |
TravellerInfo 出行人信息
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| enName |
String |
64 |
|
英文姓名,与护照一致 |
zhangsan |
| cnName |
String |
64 |
|
中文姓名 |
张三 |
| birthday |
String |
16 |
|
出生日期,格式yyyy-MM-dd |
1983-09-09 |
| height |
int |
11 |
|
身高,单位cm,不能超过300cm |
176 |
| weight |
int |
11 |
|
体重,单位kg,不能超过500kg |
65 |
| age |
int |
11 |
|
年龄,不能超过100岁 |
|
| gender |
GenderEnum |
|
|
性别枚举 |
1 |
| mobileCode |
String |
32 |
|
手机号区号 |
86 |
| mobile |
String |
32 |
|
手机号 |
13888888888 |
| foreignMobileCode |
String |
32 |
|
境外手机区号 |
87 |
| foreignMobile |
String |
32 |
|
境外手机号 |
1-626-780-7552 |
| email |
String |
32 |
|
邮箱 |
3777331@xx.com |
| nationCode |
String |
32 |
|
国籍二字码,请参考 https://en.wikipedia.org/wiki/ISO3166-1alpha-2 |
CN |
| credentialNo |
String |
64 |
|
证件号码 |
1 |
| credentialType |
CredentialTypeEnum |
|
|
证件类型枚举 |
1 |
| qq |
String |
32 |
|
QQ 号码 |
37773312 |
| wechatNo |
String |
32 |
|
微信号码 |
37773312 |
| extendAttribute |
String |
512 |
|
预留,KV 对儿形式的个性化出行人信息,多个用英文半角分号隔开 |
k1:v1;k2:v2 |
TransferInfo 接送信息
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| flightNo |
String |
64 |
如果品类是接机、送机,必须 |
航班号 |
CA123 |
| terminal |
String |
64 |
|
航站楼 |
|
| serviceType |
int |
11 |
如果品类是接机、送机,必须 |
服务类型, 1-接机 2-送机 |
1 |
| arrivalVisa |
int |
11 |
如果服务类型是接机,必须 |
是否需要落地签 0-否 1-是 |
1 |
| pickUpHour |
int |
11 |
必须 |
出发时间,小时(0 到 24) |
10 |
| pickUpMinute |
int |
11 |
必须 |
出发时间,分钟(0 到 60) |
20 |
| pickUpInfo |
LocationInfo |
|
必须 |
出发地点信息 |
|
| dropOfInfo |
LocationInfo |
|
如果品类是接机、送机、单次用车,必须 |
送达地点信息 |
|
LocationInfo 地点信息
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| name |
String |
512 |
必须 |
地点名称 |
RAMKHAMHANG SOI 170 , MINBURI 8 , Bangkok 10510 Thailand, Bangkok, Thailand,注意,建议使用英文 |
| tel |
String |
32 |
|
地点的联系电话,包含区号 |
+0066 2 917 5212 |
| address |
String |
512 |
|
地点的详细地址 |
RAMKHAMHANG SOI 170 , MINBURI 8 , Bangkok 10510 Thailand, Bangkok, Thailand |
| lat |
String |
32 |
|
地点的纬度,建议传入 |
12.921165 |
| lng |
String |
32 |
|
地点的经度,建议传入 |
100.859942 |
RefundInfo 退款信息
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaRefundId |
String |
32 |
|
分销商系统的退款单号 |
186593816746070 |
| refundId |
int |
11 |
必须 |
商家系统的退款单号 |
1865938167 |
| refundStatus |
RefundStatusEnum |
|
必须 |
商家系统退款状态 |
1 |
| refundAmount |
int |
11 |
必须 |
退款金额,单位分 |
13200 |
| refundNum |
int |
11 |
|
退款数量,没有数量时表示只退部分金额,不退数量 |
1 |
| refuseReason |
String |
64 |
当退款状态为拒绝时,必须 |
拒绝理由 |
已经发货了,不能退款 |
返回结果
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaOrderId |
String |
64 |
必须 |
分销商系统主订单号 |
12312321 |
| orderId |
String |
64 |
必须 |
商家系统主订单号 |
23112 |
| status |
OrderStatusEnum |
|
|
订单状态 |
1 |
| orderItems |
OrdeItem[] |
|
如果下单结果同步返回了已确认的订单状态,并且该产品有字符型的确认码,可通过该节点返回 |
子订单信息 |
|
OrderItem 下单结果中的子订单信息
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaSubOrderId |
String |
64 |
必须 |
分销子订单号 |
192278240912472 |
| voucherCodes |
String[] |
|
|
字符型的确认码 |
["yx9wzpwr", "yx9wyz1r"] |
| voucherStreams |
String[] |
|
|
base64 后的 pdf 数据流 |
["eyJvcmRlckl0ZW1zIjpbeyJvcmRlkiOjEsByaFVUzAxTzAwZDIwIn0"] |
请求示例
{
"otaId": 1711,
"method": "trade.create",
"sign": "7b064dad507c266a161ffc73c53dcdc5",
"timestamp": 1520590361,
"body": "ewoJImN1cnJlbmN5IjogIkNOWSIsCgkib3RhT3JkZXJJZCI6ICJvcGVuYXBpLXRlc3QtMSIsCgkidXNlckluZm8iOiB7CgkJIm5hbWUiOiAic3VwZXJkYWRhIgoJfSwKCSJjb250YWN0SW5mbyI6IHsKCQkiY25OYW1lIjogIui+vui+viIsCgkJImVuTmFtZSI6ICJkYWRhIiwKCQkibW9iaWxlIjogIjE1OTExMDI4MjEyIiwKCQkiZW1haWwiOiAiMzc3NzMzMTJAcXEuY29tIiwKCQkicXEiOiAiMzc3NzMzMTIiLAoJCSJ3ZWNoYXRObyI6ICJ3eDM3NzczMzEyIgoJfSwKCSJyZW1hcmsiOiAi5b+r54K55Y+R6LSn5ZGXIiwKCSJzdWJPcmRlcnMiOiBbCgkJewoJCQkib3RhU3ViT3JkZXJJZCI6ICJvcGVuYXBpLXRlc3QtMS0xIiwKCQkJInByb2R1Y3ROYW1lIjogIuWkp+W6t+WuneS4gOaXpea4uCIsCgkJCSJudW0iOiAzLAoJCQkic2t1SWQiOiAiU3lwbmo1ZWQxIiwKCQkJInByaWNlIjogMTIwMDAsCgkJCSJ0cmlwU3RhcnREYXRlIjogIjIwMTgtMDMtMjYiLAoJCQkidG90YWxGZWUiOiAzNjAwMCwKCQkJInRyYXZlbGxlcnMiOiBbCgkJCQl7CgkJCQkJImVuTmFtZSI6ICJ6aGFuZ3NhbiIsCgkJCQkJImNuTmFtZSI6ICLlvKDkuIkiLAoJCQkJCSJnZW5kZXIiOiAxLAoJCQkJCSJtb2JpbGVDb2RlIjogIjg2IiwKCQkJCQkibW9iaWxlIjogIjE1OTExMDI4ODc3IiwKCQkJCQkiZW1haWwiOiAiMTIzMTIzMTIyM0BxcS5jb20iLAoJCQkJCSJjcmVkZW50aWFsTm8iOiAiYXNkZmFzZDIzNDI0MjMiLAoJCQkJCSJjcmVkZW50aWFsVHlwZSI6IDEKCQkJCX0sCgkJCQl7CgkJCQkJImVuTmFtZSI6ICJsaXNpIiwKCQkJCQkiY25OYW1lIjogIuadjuWbmyIsCgkJCQkJImdlbmRlciI6IDEsCgkJCQkJIm1vYmlsZUNvZGUiOiAiODYiLAoJCQkJCSJtb2JpbGUiOiAiMTg2OTk4ODc3NjYiLAoJCQkJCSJlbWFpbCI6ICI0MjM0MjM0MkBxcS5jb20iLAoJCQkJCSJjcmVkZW50aWFsTm8iOiAiMjM0YXNkZmEiLAoJCQkJCSJjcmVkZW50aWFsVHlwZSI6IDEKCQkJCX0sCgkJCQl7CgkJCQkJImVuTmFtZSI6ICJ3YW5nd3UiLAoJCQkJCSJjbk5hbWUiOiAi546L5q2mIiwKCQkJCQkiZ2VuZGVyIjogMiwKCQkJCQkibW9iaWxlQ29kZSI6ICI4NiIsCgkJCQkJIm1vYmlsZSI6ICIxMzg4ODk5Nzc2NiIsCgkJCQkJImVtYWlsIjogIjIzNHNkZmRzQHFxLmNvbSIsCgkJCQkJImNyZWRlbnRpYWxObyI6ICJhc2RmYWFkZiIsCgkJCQkJImNyZWRlbnRpYWxUeXBlIjogMQoJCQkJfSwKCQkJXQkJCQoJCX0KCV0KfQ=="
}
返回成功的示例
{
"code": "SUCCESS",
"data": {
"orderId": "195069960801321",
"otaOrderId": "openapi-test-2",
"status": 1,
"orderItems": [
{
"otaSubOrderId": "openapi-test-22",
"voucherCodes": [
"yx9wzpwr",
"yx9wyz1r"
],
"voucherStreams": [
"eyJvcmRlckl0ZW1zIjpbeyJvcmRlkiOjEsByaFVUzAxTzAwZDIwIn0="
]
}
]
},
"msg": "成功",
"requestId": "80abbe9ceebd4115894bec220906f7ad",
"success": true
}
返回错误的示例
{
"code": "SKU_NOT_EXIST_ERROR",
"msg": "sku 编码错误",
"requestId": "a0b60b0e3a734da79ce7662e58fbc593",
"success": false
}
订单详情
接口说明
- OTA 可通过该接口获取商家系统中的订单详情。
- 接口名称:trade.detail
- 请求限制,同一账户每分钟100次
传入参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaOrderId |
String |
64 |
是 |
分销商主订单号 |
186598365062226 |
返回结果
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaOrderId |
String |
64 |
必须 |
分销商系统主订单号 |
186598365065298 |
| orderId |
String |
64 |
必须 |
商家系统主订单号 |
186598365065298 |
| otaId |
int |
11 |
必须 |
由商家系统分配的分销商唯一标识 |
10067 |
| status |
OrderStatusEnum |
必须 |
|
主订单状态 |
1 |
| remark |
String |
256 |
|
预订备注 |
请尽快发货 |
| subOrders |
SubOrderInfo[] |
|
必须 |
子订单信息 |
|
| createTime |
Date |
|
必须 |
创建时间,格式yyyy-MM-dd HH:mm:ss |
2017-12-13 13:40:32 |
请求示例
{
"otaId": 1711,
"method": "trade.detail",
"sign": "7b064dad507c266a161ffc73c53dcdc5",
"timestamp": 1520590361,
"body": "ewoJIm90YU9yZGVySWQiOiAib3BlbmFwaS10ZXN0LTEiCn0="
}
返回成功的示例
{
"code": "SUCCESS",
"data": {
"contactInfo": {
"cnName": "达达",
"email": "37773312@qq.com",
"enName": "dada",
"foreignAreaCode": "",
"foreignMobile": "",
"gender": 0,
"mobile": "15911028212",
"mobileCode": "",
"postAddress": "",
"qq": "",
"wechatNo": "wx37773312",
"zipCode": ""
},
"createTime": "2018-03-12 11:41:57",
"currency": "CNY",
"orderId": "195069960801321",
"otaId": 1711,
"otaOrderId": "openapi-test-2",
"remark": "快点发货呗",
"status": 1,
"subOrders": [
{
"num": 3,
"otaSubOrderId": "openapi-test-1-2",
"price": 12000,
"refunds": [],
"skuId": "Sypnj5ed1",
"specRound": "",
"status": 1,
"totalFee": 36000,
"travellers": [
{
"cnName": "张三",
"credentialNo": "asdfasd2342423",
"credentialType": 1,
"email": "1231231223@qq.com",
"enName": "zhangsan",
"foreignMobile": "",
"foreignMobileCode": "",
"gender": 1,
"height": 0,
"mobile": "15911028877",
"mobileCode": "86",
"nationCode": "",
"qq": "",
"wechatNo": "",
"weight": 0
},
{
"cnName": "李四",
"credentialNo": "234asdfa",
"credentialType": 1,
"email": "42342342@qq.com",
"enName": "lisi",
"foreignMobile": "",
"foreignMobileCode": "",
"gender": 1,
"height": 0,
"mobile": "18699887766",
"mobileCode": "86",
"nationCode": "",
"qq": "",
"wechatNo": "",
"weight": 0
},
{
"cnName": "王武",
"credentialNo": "asdfaadf",
"credentialType": 1,
"email": "234sdfds@qq.com",
"enName": "wangwu",
"foreignMobile": "",
"foreignMobileCode": "",
"gender": 2,
"height": 0,
"mobile": "13888997766",
"mobileCode": "86",
"nationCode": "",
"qq": "",
"wechatNo": "",
"weight": 0
}
],
"tripEndDate": "2018-03-26",
"tripStartDate": "2018-03-26",
"vouchers": [
"6pgg1rpv",
"zkyq5gd1",
"npzx51kv"
]
}
]
},
"msg": "成功",
"requestId": "e6be5968caca4b99bfdd18cd10816b46",
"success": true
}
返回错误的示例
{
"code": "ORDER_NOT_EXISTS",
"msg": "订单号不存在",
"requestId": "df890c70f6fb4b4eaab0659e99634c90",
"success": false
}
添加订单备注
接口说明
- 分销商系统调用该接口,将
OP添加的订单备注同步到商家系统。
- 接口名称:trade.memo.add
传入参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaOrderId |
String |
64 |
必须 |
分销商主订单号 |
123456 |
| sellerMemo |
String |
1024 |
必须 |
备注内容 |
尽快发货 |
返回结果
请求示例
{
"otaId": 1711,
"method": "trade.memo.add",
"sign": "7b064dad507c266a161ffc73c53dcdc5",
"timestamp": 1520590361,
"body": "ewoJIm90YU9yZGVySWQiOiAib3BlbmFwaS10ZXN0LTIiLAoJInNlbGxlck1lbW8iOiAi5bC95b+r5Y+R6LSnIgp9"
}
返回成功的示例
{
"code": "SUCCESS",
"msg": "成功",
"requestId": "fb4b7bdb68554678a2354426b4abee10",
"success": true
}
返回错误的示例
{
"code": "API_PARAM_ERROR",
"msg": "备注内容不能为空",
"requestId": "6fa4c7ff34fb4e20973bfd3dc0916936",
"success": false
}
修改订单申请(预留,暂不支持)
接口说明
- 分销商系统可通过该接口修改订单信息,包括
联系人信息、出行人信息等信息。
- 接口名称,trade.modify
传入参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaModifyId |
String |
64 |
|
分销端修改申请单号 |
1122 |
| otaOrderId |
String |
64 |
必须 |
分销商主订单号 |
186602279019573 |
| otaSubOrderId |
String |
64 |
必须 |
分销商子订单号 |
186602279019573 |
| contactInfo |
ContactInfo |
|
如果要修改联系人信息,必须 |
联系人信息 |
|
| travellers |
TravellerInfo[] |
|
如果要修改出行人信息,必须 |
出行人信息 |
|
| trasferInfo |
TransferInfo |
|
如果要修改接送信息,必须 |
接机、用车、包车信息 |
|
返回结果
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaModifyId |
String |
64 |
|
分销端修改申请单号 |
1122 |
| modifyId |
int |
11 |
必须 |
商家系统修改申请单号 |
121223 |
| modifyStatus |
ModifyStatusEnum |
|
必须 |
修改申请单状态 |
1 |
返回结果示例
{
"code": "SUCCESS",
"msg": "请求成功",
"data": {
"otaModifyId": "1122",
"modifyId": 121223,
"modifyStatus": 1
},
"requestId": "d0d438e1b7a311e7a4c064006a34ea1e"
}
退款接口
接口说明
- 分销商系统调用该接口发起退款,如果返回结果中的退款状态为
退款中,商家系统后续通过回调接口通知退款单的处理状态。
- 接口名称,trade.refund.apply
- 注意:
- 已取消的订单再次接收到退款申请,返回取消成功。
. 当商家系统的订单状态为『预订中』、『预订失败』、『取消中』、『取消成功』、『订单完成』时,拒绝接收取消申请。
. 当所有的退款申请都被处理后,商家系统才可以再次发起退款申请。
请求参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| orderId |
String |
64 |
必须 |
供应商系统主订单号 |
185867378022470 |
| otaOrderId |
String |
64 |
必须 |
分销商主订单号 |
185867378022470 |
| otaSubOrderId |
String |
64 |
如果是整单退款,可以不传,默认全部子订单申请退款 |
分销商子订单号 |
185867378022471 |
| otaRefundId |
String |
64 |
必须 |
分销商退款单号 |
185867378022474 |
| refundNum |
int |
11 |
|
要取消的数量 |
1 |
| refundAmount |
int |
11 |
如果是整单退款,可以不传,默认是子订单的全部金额 |
退款金额,单位分 |
1000 |
返回结果
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaOrderId |
String |
64 |
必须 |
分销商主订单号 |
187028174920793 |
| otaSubOrderId |
String |
64 |
必须 |
分销商子订单号 |
187028174920793 |
| otaRefundId |
String |
64 |
|
分销商退款单号 |
187028174920793 |
| refundStatus |
RefundStatusEnum |
|
必须 |
商家系统退款单状态 |
0 |
请求示例
{
"otaId": 1711,
"method": "trade.refund.apply",
"sign": "7b064dad507c266a161ffc73c53dcdc5",
"timestamp": 1520590361,
"body": "ewoJIm9yZGVySWQiOiAiMTk0ODMxMDM5MTc3NzY5IiwKCSJvdGFPcmRlcklkIjogIm9wZW5hcGktdGVzdC0xIiwKCSJvdGFTdWJPcmRlcklkIjogIm9wZW5hcGktdGVzdC0xLTEiLAoJIm90YVJlZnVuZElkIjogIm9wZW5hcGktdGVzdC1yZWZ1bmQtMSIsCgkicmVmdW5kQW1vdW50IjogIjEwMDAiCn0="
}
返回结果示例,请求成功
{
"code": "SUCCESS",
"data": {
"otaOrderId": "openapi-test-1",
"otaRefundId": "openapi-test-refund-1",
"otaSubOrderId": "openapi-test-1-1",
"refundStatus": 0
},
"msg": "成功",
"requestId": "f7b5bfec8e9044fcb6506d3b57ad2e94",
"success": true
}
返回结果示例,请求异常
{
"code": "REFUND_FORBIDDEN_ERROR",
"msg": "分销退款单号:openapi-test-refund-1,当前订单状态:预订中,不可以申请退款。",
"requestId": "643f998979794b5fb36460cce16e0cd4",
"success": false
}
退款单查询
接口说明
- 分销商通过该接口拉取商家系统的退款处理状态。
- 接口名称,trade.refund.query
传入参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaRefundId |
String |
64 |
必须 |
分销商退款单号 |
187028174920793 |
返回结果
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaRefundId |
String |
64 |
|
分销商退款单号 |
187028174920793 |
| refundId |
int |
11 |
必须 |
商家系统的退款单号 |
187028174920793 |
| refundStatus |
RefundStatusEnum |
|
必须 |
商家系统退款单状态 |
0 |
| refundAmount |
int |
11 |
必须 |
退款金额,单位分 |
13200 |
| refundNum |
int |
11 |
|
退款数量 |
1 |
| refuseReason |
String |
64 |
当退款状态为拒单时,必须 |
拒绝理由 |
已经发货了,不能退款 |
请求示例
{
"otaId": 1711,
"method": "trade.refund.query",
"sign": "7b064dad507c266a161ffc73c53dcdc5",
"timestamp": 1520590361,
"body": "ewoJIm90YVJlZnVuZElkIjogIm9wZW5hcGktdGVzdC1yZWZ1bmQtMSIKfQ=="
}
返回成功示例
{
"code": "SUCCESS",
"data": {
"otaRefundId": "openapi-test-refund-1",
"refundAmount": 1000,
"refundId": 121,
"refundNum": 0,
"refundStatus": 0,
"refuseReason": ""
},
"msg": "成功",
"requestId": "e767e6f45cb5488db364f2bc191cd4f4",
"success": true
}
返回失败示例
{
"code": "REFUND_ORDER_NOT_EXISTS",
"msg": "退款单不存在",
"requestId": "ca287a64b29548d6b3f187984d652bba",
"success": false
}
分销商系统提供的接口
- 请分销商按照文档上的格式开发接口,并告知商家系统接口地址。
- 分销商提供的接口请求方式均为
POST,传入参数和返回参数与商家系统提供的接口格式一致,分销商可以按照同样的规则做好接口鉴权。
- 在请求参数中商家系统会传入
requestId,分销商接口在响应结果中将该参数原样返回即可。
- 如果回调接口返回了错误,商家系统会发起重试,请做好接口的幂等性判断。
订单状态回调接口
- 商家系统接单或拒单时,通过该接口通知到分销商。
- 接口名称,
trade.callback.orderstatus
传入参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaOrderId |
String |
64 |
必须 |
分销商主订单号 |
187028174920793 |
| otaSubOrderId |
String |
64 |
必须 |
分销商子订单号 |
187028174920793,已废弃 |
| otaSubOrderIds |
String[] |
|
必须 |
分销商子订单号集合 |
["187028174920793", "187028174920794"]已废弃 |
| orderId |
String |
64 |
必须 |
商家系统主订单号 |
187028174920793 |
| syncStatus |
int |
11 |
必须 |
同步状态 1-预订成功 2-预订失败 |
1 |
| voucherCodes |
String[] |
|
|
子订单关联的字符型的确认码 |
["yx9wzpwr", "yx9wyz1r"]已废弃 |
| voucherStreams |
String[] |
|
|
base64 后的 pdf 文件数据流 |
["eyJvcmRlckl0ZW1zIjpbeyJvcmRlkiOjEsByaFVUzAxTzAwZDIwIn0="]已废弃 |
| subOrders |
OrderSubItem[] |
|
必须 |
预订子订单详情,当syncStatus=1时,存在 |
- |
| vouchers |
VoucherDetail[] |
|
必须 |
预订子订单详情,当syncStatus=1时,存在 |
- |
VoucherDetail
VoucherCodeDetail
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| code |
String |
|
必须 |
skuCode或addonCode |
|
| otaSubOrderNo |
String |
|
必须 |
代理商系统的子订单号 |
|
| voucherCodes |
String[] |
|
必须 |
确认码 注意:当voucherCodeType为ONE_CODE_PER_ORDER时,所有子订单的voucherCodes相同 |
|
OrderSubItem
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaSubOrderId |
String |
64 |
必须 |
分销商子订单号 |
187028174920793 |
| voucherCodes |
String[] |
|
|
子订单关联的字符型的确认码 |
["yx9wzpwr", "yx9wyz1r"] |
| voucherStreams |
String[] |
|
|
base64 后的 pdf 文件数据流 |
["eyJvcmRlckl0ZW1zIjpbeyJvcmRlkiOjEsByaFVUzAxTzAwZDIwIn0="] |
返回结果示例
{
"otaOrderId": "187028174920793",
"orderId": "360086990446621",
"syncStatus": 1,
"subOrders": [
{
"otaSubOrderId": "187028174920793-1",
"voucherCodes": [
"yx9wzpwr",
"yx9wyz1r"
],
"voucherStreams": [
"eyJvcmRlckl0ZW1zIjpbeyJvcmRlkiOjEsByaFVUzAxTzAwZDIwIn0="
]
},
{
"otaSubOrderId": "187028174920793-2",
"voucherCodes": [
"yx9wzpwa",
"yx9wyz1a"
],
"voucherStreams": [
"eyJvcmRlckl0ZW1zIjpbeyJvcmRlkiOjEsByaFVUzAxTzAwZDIwIn0="
]
}
]
}
返回结果
返回结果示例
{
"code": "SUCCESS",
"msg": "请求成功",
"data": {},
"requestId": "d0d438e1b7a311e7a4c064006a34ea1e"
}
退款状态回调接口
- 接口名称,
trade.callback.refundstatus
传入参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaOrderId |
String |
64 |
必须 |
分销商主订单号 |
18702817220793 |
| orderId |
String |
64 |
必须 |
商家系统主订单号 |
18702817492 |
| otaRefundId |
String |
64 |
必须 |
分销商退款单号 |
1870281749224234 |
| syncStatus |
int |
11 |
必须 |
退款状态同步标识 1-退款成功 2-退款失败 |
2 |
| reason |
String |
256 |
退款失败理由 |
已经发货了,不能退款 |
|
返回参数
返回参数示例
{
"code": "SUCCESS",
"msg": "请求成功",
"data": {},
"requestId": "d0d438e1b7a311e7a4c064006a34ea1e"
}
修改订单申请回调接口(预留,暂不支持)
- 接口名称,trade.callback.modifystatus
- 供应商最终确认订单信息修改结果时,通过回调接口通知分销商。
- 接口名称,
trade.callback.modifystatus
传入参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaModifyId |
int |
11 |
|
分销商修改订单信息申请单号 |
1122 |
| modifyId |
String |
64 |
必须 |
供应商修改订单信息申请单号 |
187029305594969 |
| modifyStatus |
ModifyStatusEnum |
|
必须 |
修改申请处理状态 |
1 |
返回参数
返回参数示例
{
"code": "SUCCESS",
"msg": "请求成功",
"data": {},
"requestId": "d0d438e1b7a311e7a4c064006a34ea1e"
}
订单核销回调接口
- 供应商通过该接口通知分销商订单的核销状态。
- 接口名称,
trade.callback.consumestatus
传入参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaOrderId |
String |
64 |
必须 |
分销商主订单号 |
187029305594969 |
| otaSubOrderId |
String |
64 |
如果只是核销子订单,必须(如果不传入,代表所有子订单全部已核销) |
分销商子订单号 |
187029305594969 |
| num |
int |
11 |
如果只是核销了子订单的部分数量,必须(如果不传入,代表子订单的全部商品已核销) |
核销数量 |
2 |
返回参数
返回参数示例
{
"code": "SUCCESS",
"msg": "请求成功",
"data": {},
"requestId": "d0d438e1b7a311e7a4c064006a34ea1e"
}
分销商订单详情
- 商家系统通过该接获取分销商订单信息。
- 接口名称,
trade.order.detail
请求参数
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| otaOrderId |
String |
64 |
|
分销商主订单号 |
1234567 |
返回结果
| 参数 |
类型 |
长度 |
是否必须 |
描述 |
示例 |
| currency |
String |
8 |
必须 |
币种代码,请参考,https://zh.wikipedia.org/wiki/ISO_4217 |
CNY |
| otaOrderId |
String |
64 |
必须 |
分销商主订单号 |
187028174920793 |
| orderId |
String |
64 |
|
商家系统主订单号 |
187028174920793 |
| userInfo |
UserInfo |
|
|
分销商系统中的用户信息 |
|
| contactInfo |
ContactInfo |
|
|
联系人信息 |
|
| remark |
String |
256 |
|
|
预订备注 |
| subOrders |
SubOrderInfo[] |
|
|
分销商子订单信息 |
|
| createTime |
Date |
|
必须 |
订单创建时间 |
2017-09-10 13:23:23 |
返回结果示例
{
"code": "SUCCESS",
"msg": "请求成功",
"data": {
"otaOrderId": "20170301000001",
"orderId": "201703010000012",
"userInfo": {},
"contactInfo": {},
"remark": "买家留言",
"subOrders": [],
"createTime": "2017-10-09 13:59:22"
},
"requestId": "d0d438e1b7a311e7a4c064006a34ea1e"
}
枚举类型
ApiCodeEnum 接口返回码枚举
成功
系统相关
| 枚举值 |
描述 |
说明 |
| OTA_ACCOUNT_ERROR |
OTA 账户错误 |
|
| SIGN_ERROR |
签名校验错误 |
|
| TIMESTAMP_ERROR |
时间戳错误 |
|
| PARSE_JSON_ERROR |
JSON 解析错误 |
|
| API_METHOD_ERROR |
错误的接口名称 |
|
| API_PARAM_ERROR |
业务参数校验错误 |
通过返回报文中的 msg 查看具体参数 |
| UNKNOW_ERROR |
未知错误 |
|
下单相关
| 枚举值 |
描述 |
说明 |
| SKU_EMPTY_ERROR |
没有传入商家系统 sku 编码 |
|
| SKU_NOT_EXIST_ERROR |
不存在的商家 sku 编码 |
|
| SKU_INVENTORY_ERROR |
商家系统 sku 库存不足 |
|
| BOOKING_CONFIG_ERROR |
不满足预订配置 |
|
| CREDIT_NOT_ENOUGH_ERROR |
额度不足 |
|
| SKU_PRICE_ERROR |
传入价格和实际价格不符 |
|
查询相关
| 枚举值 |
描述 |
说明 |
| ORDER_NOT_EXISTS |
订单号不存在 |
|
| REFUND_ORDER_NOT_EXISTS |
退款单不存在 |
|
取消/修改相关
| 枚举值 |
描述 |
说明 |
| REFUND_AMOUNT_ERROR |
退款金额错误 |
|
| REFUND_NUM_ERROR |
退款数量错误 |
|
| REFUND_FORBIDDEN_ERROR |
该订单不允许退款 |
|
| MODIFY_FORBIDDEN_ERROR |
该订单不允许修改 |
|
OrderStatusEnum 订单状态枚举
| 枚举值 |
描述 |
| 1 |
订单已支付,预订中 |
| 2 |
预订成功 |
| 3 |
预订失败 |
| 4 |
订单完成 |
| 5 |
取消中 |
| 6 |
取消失败 |
| 7 |
取消成功 |
| 8 |
订单关闭 |
CategoryEnum 品类枚举
| 枚举值 |
描述 |
| 1 |
观光日游 |
| 2 |
体验日游 |
| 3 |
景点门票 |
| 4 |
演出赛事 |
| 5 |
美食 |
| 6 |
接机 |
| 7 |
送机 |
| 8 |
包车 |
| 9 |
单次用车 |
RefundStatusEnum 退款状态
| 枚举值 |
描述 |
| 0 |
退款中 |
| 1 |
退款成功 |
| 2 |
退款失败 |
ModifyStatusEnum 订单修改状态
| 枚举值 |
描述 |
| 0 |
修改中 |
| 1 |
修改成功 |
| 2 |
修改失败 |
CredentialTypeEnum 证件类型枚举
| 枚举值 |
描述 |
| 1 |
身份证 |
| 2 |
护照 |
| 3 |
港澳通行证 |
| 4 |
台湾通行证 |
GenderEnum 性别枚举
TravellerTypeEnum 出行人类型枚举
| 枚举值 |
描述 |
| 1 |
成人 |
| 2 |
儿童 |
| 3 |
婴儿 |
| 4 |
老人 |
VoucherTypeEnum 确认单类型枚举
| 枚举值 |
描述 |
| CODE |
确认码(含确认单) |
| FILE |
只有确认单 |
| LINK |
链接 |
VoucherCodeTypeEnum 确认单类型枚举
| 枚举值 |
描述 |
| ONE_CODE_PER_ORDER |
一单一码 |
| ONE_CODE_PER_PERSON |
一人一码 |
注意事项
下单
1.您传入的货币必须和供应商与您的结算币种相同,否则会造成下单失败。
2.下单时传入的sku单价及总价,需要和供应商给您的报价一致,如果供应商变更价格,您也需要及时同步更新,否则会造成下单失败。
3.子订单总价=子订单商品单价*数量
4.为了避免重复下单,分销商的订单号不能重复。如果只有一个子订单,则可以和主订单号一样。
5.请确认下单时该商品的预定配置信息,例如:需要出行人的邮箱、电话、接送酒店等。如果信息缺失,则会返回信息缺失提示。
退款/取消
1.需传入正确的分销商订单号,否则无法完成退款请求。
2.当前可退数量=预定数量-已退款数量。当所有数量全部取消后,则认为该订单整体取消了。api支持部分退款。
3.当订单状态已经是最终状态或初始状态,则不允许发起退款。
4.已经消费/核销的订单,不允许退款。
5.传入的退款金额需大于0元。