代理通多渠道SWITCH直连接入标准API
- 除接口认证外,其他所有接口均可以自由选择是否开发,接口在代理通中均为可视化,随时在代理通中联调测试看效果;
- 接口支持国内和海外产品;
- 随时创建酒店,创建房型,随时上下线各渠道;
- 支持ctrip,Qunar ,B2B,众多分销渠道;向下兼容ctrip标准API接入接口,兼容qunar直连接入接口;
- 支持订单在线联通酒店Ebooking,FAX,Email,PMS等;
版本更新
| 最新版本 | 文档更新日期 | 更新内容 |
|---|---|---|
| 2.0.23 | 2024-07-22 | 新增特殊要求是否满足操作选项,参考7.3订单操作接口 |
| 2.0.22 | 2024-06-26 | 新增小修改修改项目,参考7.2获取订单详情接口 |
| 2.0.21 | 2024-04-24 | 系统内所有售卖房型数据类型由int类型更改为long类型 |
| 2.0.20 | 2023-06-16 | 接口地址迁移到新域名,原域名持续到六月底下线,测试环境域名更改:由http://apiproxy-fws.ctripqa.com/apiproxy/soa2/13353 更改为:http://m.fat.ctripqa.com/restapi/soa2/13353 生产环境域名更改:由http://switch.vipdlt.com/apiproxy/soa2/13353更改为:http://m.ctrip.com/restapi/soa2/13353 |
| 2.0.19 | 2022-12-01 | 4.2 获取酒店房型静态信息接口,床型,网络,吸烟信息转到物理房型,售卖房型上的已非100%准确 |
| 2.0.18 | 2022-10-01 | 床型全部迁移到子物理房型,售卖房型不再支持床型属性:5.3 创建房型/5.7 更新RateCode接口 |
| 2.0.17 | 2022-06-20 | 6.9 推送Ctrip渠道每日规则,功能复制6.1中的CtripSellRule,注意:有频率限制 |
| 2.0.16 | 2022-05-25 | 5.3 创建房型/5.7 更新RateCode接口 中国境内不允许使用床型属性,其他参考 2.0.14版更新 |
| 2.0.15 | 2022-04-25 | 3.2 创建酒店接口中的酒店标签减至4个 |
| 2.0.14 | 2022-01-06 | 床型迁移到子物理房型,售卖房型不再支持床型属性:5.3 创建房型/5.7 更新RateCode接口 床型属性值会被过滤,不能再通过接口维护,第一批受影响的国家id:30(俄罗斯),32(菲律宾),43(荷兰),9(阿联酋),55(老挝),3(新加坡),260(文莱达鲁萨兰国),1(中国) |
| 2.0.13 | 2022-01-20 | 5.6 设置房型房态共享与库存共享功能下线,如需可到后台按房型设置,也可按供应商级别或酒店级别设置,入口在【渠道】模块 |
| 2.0.13 | 2022-01-20 | 7.2 获取订单详情接口/7.3 订单操作接口/7.4 发单接口 请求需要转成新版请求,具体见接口说明 |
| 2.0.12 | 2022-01-01 | 6.1 推送数据接口中的礼盒字段移除,不再支持(当前无获取礼盒接口,本也设置不了);设置礼盒相关到可视化后台 |
| 2.0.11 | 2021-12-14 | 3.3 获取子酒店接口新增查询条件及页码限制,请及时调整 1) 查询条件增加cityID,限制页码最大为300(当前页码>300时,并不返回数据) 2) 增加多子酒店查询条件 hotelIDs,同时替换原单酒店字段hotelID |
| 2.0.10 | 2021-12-10 | 4.2 创建子酒店接口必须传酒店资源标签,具体见接口说明 |
| 2.0.9 | 2021-12-01 | 5.3 创建房型接口,5.7修改房型ratecode接口,宾客类型字段,海外专用字段applicabilityInfo废弃,与国内字段applicabilityList通用 |
| 2.0.8 | 2021-11-25 | 文档迁移到站点,请全面了解 |
开发流程
通读文档,了解当前有哪些接口及接口功能是什么,每周了解是否有更新。下面是简单流程说明,不清楚的在技术支持群中提出,或向业务咨询。
| 序号 | 接口 | 描述 |
|---|---|---|
| 1 | 申请供应商id,及使用接口的认证帐号,联系业务申请:测试环境见认证信息部分,直接使用 | |
| 2 | 2.1获取国家列表接口, 2.2获取城市接口 |
获取支持的国家与城市 |
| 3 | 3.1 获取母酒店列表 | 按城市获取母酒店,母酒店是携程系统所有的酒店信息备份,自行匹配出要上线的母酒店id与母酒店名称; 如果查不到所需母酒店,联系业务增加 |
| 4 | 3.2 创建子酒店接口 | 用母酒店id,与供应商id,创建出唯一的子酒店id,子酒店与母酒店,供应商id 自动绑定 ,且只能创建一次 |
| 5 | 3.3 获取子酒店接口 | 按供应商分页获取子酒店,自行匹配 |
| 6 | 3.4 设置子酒店售卖渠道 3.5 设置子酒店最晚预订时间 |
设置酒店各渠道售卖状态及最晚预订时间等,渠道为Ctrip/Qunar/ChannelA/B2B |
| 7 | 4.1 获取母物理房型列表 | 用子酒店id,获取母酒店的母物理房型,如果获取不到所需,联系业务新增 |
| 8 | 4.2 获取酒店房型静态信息列表 | 用子酒店id,获取子酒店的子物理房型/售卖房型信息,缓存接口,需要等待。新建子酒店一般没有房型信息,先创建子物理房型,售卖房型后,再来获取 |
| 9 | 4.3 新增子物理房型 | 用母酒店id,母物理房型id,与子酒店id,为子酒店创建子物理房型,几个id自动绑定 ,相同的属性值组合只能创建一次 |
| 10 | 4.4 更新子物理房型 | 取得子物理房型信息后,想修改的话,有部分信息可以修改;不支持的可联系业务 |
| 11 | 5.3 创建售卖房型 | 用子酒店id,子物理房型id,创建售卖房型,只能创建一次,id之间自动绑定;创建时所需属性值见接口说明 |
| 12 | 5.5 更改售卖房型渠道名称 | 售卖房型创建后,名称由 子物理房型名称与属性值名称拼接而成,Ctrip渠道改名称只能通过修改属性,其他渠道可接口更改(Qunar/ChannelA/B2B) |
| 13 | 5.7 更新售卖房型RateCode属性 | 修改属性值 |
| 14 | 5.6 设置房型库存房态共享 | 房型有Ctrip/Qunar/ChannelA/B2B分销渠道,如果库存,房态想保持统一,设置共享,就不用各渠道都设置一遍了 |
| 15 | 5.8 更新房型售卖规则 | 有Ctrip/Qunar/ChannelA/B2B分销渠道,售卖房型的房型级别上的默认售卖规则,注意Ctrip渠道还有每日上的动态售卖规则,且以每日上的为准 |
| 16 | 5.9 获取房型售卖规则(上下线状态,售卖币种) | 获取售卖规则,当前只支持上下线状态与币种,其他到后台界面查看 |
| 17 | 6.1/6.7/6.9 直连推送报价等数据接口 | 为售卖房型各渠道推送房价,房量,房态,及每日动态售卖规则 |
| 18 | 6.2~6.6 | 可分别获取6.1推送的各种数据 |
| 19 | 6.7 推送房型Ctrip渠道每日入住限制 | Ctrip渠道每日入住限制,例如可不可入住,可不可离店,最多入住几天 |
| 20 | 7.1 订单变化通知接口 | 价态量推送好后,联系技术支持群,找人帮忙创建订单,此接口可拉取新订,修改,取消单等,只有简单信息 |
| 21 | 7.2 订单详情接口 | 获取订单详情 |
| 22 | 7.3 订单操作接口 | 接单,拒单等操作 |
| 23 | 7.4 发单接口 | 把订单信息发送到酒店接口 |
接口认证
- 此接口为代理通提供,请求返回参数均为json格式内容
- 请求接口url统一(接口地址 = url + /接口名称):
- 请求头部(代理通分销接口基于http协议开发,请求头部信息统一放入HttpHander交互处理):
timestamp:时间戳(System.currentTimeMillis(),注:与当前时间相比,前后时间差 < 30秒,单位:毫秒 )
signature: MD5加密串(加密算法是 md5(base64),可参考下文中的demo)
加密验证逻辑:signature=Md5(supplierID+timestamp+interfacekey).toUpperCase()
说明:
interfacekey:密钥Key;
supplierID:供应商ID,int类型;
参数拼接是字符串拼接加密之后转大写
各环境地址:
| 环境 | 接口地址 | 用户和key |
|---|---|---|
| 测试环境 | http://m.fat.ctripqa.com/restapi/soa2/13353/接口名 | 接口测试公用ID和key: supplierID=16551 Key=072729ca-9774-4543-8da5-31bac0c35ecc 由于网络安全原因,外网无法访问可视化页面,请自行通过接口进行联调,无法确认的信息可在联调群中提出。 |
| 生产环境 | http://m.ctrip.com/restapi/soa2/13353/接口名 | 商务OK后,可生成对应key;(已合作有对应ID,key找商务生成) 可视化页面:www.vipdlt.com 各自的用户名密码 |
Md5(base64)算法工具:
http://www.cmd5.com/hash.aspx
参考:https://blog.csdn.net/sxzlc/article/details/74127268
java 加密示例
public class demo {
private static final String uri="http://m.fat.ctripqa.com/restapi/soa2/13353/";
private static final int supplierID=16551;
private static final String key="072729ca-9774-4543-8da5-31bac0c35ecc";
public static void main(String[] args) {
try {
CloseableHttpClient client = null;
CloseableHttpResponse response = null;
try {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> data = new HashMap<String, Object>();
Map<String, Object> requestor = new HashMap<String, Object>();
requestor.put("invoker","demo");
requestor.put("operatorName","demo");
requestor.put("opClientIP","127.0.0.1");
requestor.put("userID",1);
requestor.put("languageType","CN");
data.put("requestor", requestor);
data.put("supplierID", supplierID);
//获取timestamp
String timestamp=String.valueOf(System.currentTimeMillis());
//计算signature
String tmp=String.valueOf(supplierID)+String.valueOf(System.currentTimeMillis())+key;
MessageDigest md5 = MessageDigest.getInstance("MD5");
BASE64Encoder base64en = new BASE64Encoder();
String signature=base64en.encode(md5.digest(tmp.getBytes("utf-8"))).toUpperCase();
//组装http请求数据
HttpPost httpPost = new HttpPost(uri + "getdltcountrylist");
httpPost.setHeader(HTTP.CONTENT_TYPE, "application/json");
httpPost.setHeader("timestamp", timestamp);
httpPost.setHeader("signature", signature);
httpPost.setEntity(new StringEntity(objectMapper.writeValueAsString(data),
ContentType.create("text/json", "UTF-8")));
client = HttpClients.createDefault();
response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
System.out.println(httpPost);
System.out.println("request timestamp:"+timestamp);
System.out.println(result);
} finally {
if (response != null) {
response.close();
}
if (client != null) {
client.close();
}
}
} catch (Exception e) {
}
}
}
C# 加密示例
namespace demo
{
public class demo
{
public void test()
{
int supplierID=16551;
string key="072729ca-9774-4543-8da5-31bac0c35ecc";
string uri = "http://m.fat.ctripqa.com/restapi/soa2/13353/";
string requestBody="{\"requestor\":{\"invoker\":\"demo\",\"operatorName\":\"demo\",\"opClientIP\":\"127.0.0.1\",\"userId\":1,\"languageType\":\"CN\"},\"supplierID\":16551}";
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri + "getdltcountrylist");
//获取timestamp
string timestamp = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000).ToString();
//计算signature
string tmp = supplierID.ToString() + timestamp + key;
string signature = MD5ToBase64(tmp).ToUpper();
Encoding encoding = Encoding.UTF8;
byte[] byteArray = Encoding.UTF8.GetBytes(requestBody);
string responseData = String.Empty;
req.Method = "POST";
req.ContentType = "application/json";
req.ContentLength = byteArray.Length;
SetHeaderValue(req.Headers, "timestamp", timestamp);
SetHeaderValue(req.Headers, "signature", signature);
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), encoding))
{
responseData = reader.ReadToEnd();
}
System.Diagnostics.Debug.WriteLine("timestamp:" + timestamp);
System.Diagnostics.Debug.WriteLine("signature:" + signature);
System.Diagnostics.Debug.WriteLine(responseData);
}
}
public static void SetHeaderValue(WebHeaderCollection header, string name, string value)
{
var property = typeof(WebHeaderCollection).GetProperty("InnerCollection",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (property != null)
{
var collection = property.GetValue(header, null) as NameValueCollection;
collection[name] = value;
}
}
public static string MD5ToBase64(string source)
{
byte[] b = System.Text.Encoding.UTF8.GetBytes(source);
b = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(b);
string sign= System.Convert.ToBase64String(b);
return sign;
}
}
}
Python 加密示例
def demo():
param={
"uri":"http://m.fat.ctripqa.com/restapi/soa2/13353/",
"supplierID":16551,
"key":"072729ca-9774-4543-8da5-31bac0c35ecc"
}
requestbody={
"requestor":
{"invoker": "demo",
"operatorName": "demo",
"opClientIP": "127.0.0.1",
"userId": 1,
"languageType": "CN"
},
"supplierID": 16551
}
//获取timestamp
timestamp = int(round(time.time() * 1000))
//计算signature
tmp = str(param.get('supplierID'))+str(timestamp)+param.get('key')
signature = getsign(tmp)
headers = {
"Content-Type":"application/json",
"timestamp": str(timestamp),
"signature": signature
}
response = requests.post(url=param.get('uri')+'getdltcountrylist', headers=headers, data=json.dumps(requestbody))
print('timestamp:'+str(timestamp))
print('signature:'+signature)
print(response.json())
def getsign(strs):
md5 = hashlib.md5()
md5.update(strs.encode("utf-8"))
b = md5.digest()
result = str(base64.b64encode(b), 'utf-8').upper()
return result
demo()
Postman的模拟请求示例:

代码请求注意加头部校验:

附录
- 酒店房型逻辑关系

- 语言代码
| Code | 含义 |
|---|---|
| en-us | 英文 |
| zh-cn | 中文 |
- 币种Code
| Code | 币种 |
|---|---|
| AFN | 阿富汗尼 |
| AMD | 亚美尼亚德拉姆 |
| ARS | 阿根廷比索 |
| AUD | 澳大利亚元 |
| AZM | 阿塞拜疆马纳特 |
| AZN | 阿塞拜疆马纳特 |
| BHD | 巴林第纳尔 |
| BRL | 巴西里尔 |
| BWP | 博茨瓦纳普拉 |
| BYR | 白俄罗斯卢布 |
| CAD | 加拿大元 |
| CHF | 瑞士法郎 |
| CLP | 智利比索 |
| COP | 哥伦比亚比索 |
| CRC | 哥斯达黎加科朗 |
| CVE | 佛得角群岛埃斯库多 |
| CZK | 捷克克朗 |
| DKK | 丹麦克朗 |
| DZD | 阿尔及利亚第纳尔 |
| EGP | 埃及镑 |
| EUR | 欧元 |
| FJD | 斐济元 |
| GBP | 英镑 |
| GEL | 格鲁吉亚拉里 |
| GHS | 加纳塞地 |
| GTQ | 危地马拉格查尔 |
| HKD | 港币 |
| IDR | 印尼盾 |
| INR | 印度卢比 |
| IRR | 伊朗里亚尔 |
| ISK | 冰岛克朗 |
| JOD | 约旦第纳尔 |
| JPY | 日元 |
| KRW | 韩元 |
| KWD | 科威特第纳尔 |
| KZT | 哈萨克斯坦 |
| LKR | 斯里兰卡卢比 |
| LSL | 莱索托洛蒂 |
| MAD | 摩洛哥道拉姆 |
| MDL | 摩尔多瓦列伊 |
| MGA | 马达加斯加阿里亚里 |
| MOP | 澳门元 |
| MXN | 墨西哥比索 |
| MYR | 马来西亚林吉特 |
| MZN | 莫桑比克新梅蒂卡尔 |
| NAD | 纳米比亚元 |
| NGN | 尼日利亚奈拉 |
| NOK | 挪威克朗 |
| NZD | 新西兰元 |
| OMR | 阿曼里亚尔 |
| PGK | 巴布亚基纳 |
| PHP | 菲律宾比索 |
| PKR | 巴基斯坦卢比 |
| PLN | 波兰兹罗提 |
| QAR | 卡塔尔里亚尔 |
| CNY | 人民币 |
| RON | 罗马尼亚列伊 |
| RUB | 俄罗斯卢布 |
| SAR | 沙特里亚尔 |
| SEK | 瑞典克朗 |
| SGD | 新加坡元 |
| SZL | 斯威士兰里兰吉尼 |
| THB | 泰株 |
| TRY | 土耳其里拉 |
| TWD | 新台币 |
| TND | 突尼斯第纳尔 |
| UAH | 乌克兰格里夫纳 |
| USD | 美元 |
| VND | 越南盾 |
| WST | 萨摩亚塔拉 |
| XAF | 中非共同体法郎 |
| XOF | 西非法郎 |
| XPF | 太平洋法郎 |
| ZAR | 南非兰特 |