通用说明 #
通用说明 #
厦门航空为满足开发者的业务诉求,将厦航业务能力以api形式开放出来,提供给取得开发者资质的开发者使用。在得到厦门航空授权后,第三方平台开发者可以通过调用厦航开放的接口能力,为第三方平台提供服务。
接入说明 #
开发者可以通过国际标准的 OAuth2.0 授权机制(可参考OAuth2.0协议标准 (opens new window)),在用户授权的情况下,得到用于换取用户相关信息的令牌。在拿到用户的授权令牌后,通过调用用户授权的相关信息接口,访问用户资源。
scope:开发者可以在授权请求中包含一个或者多个用户授权作用域(scope),一个scope包含若干个开放平台接口。建议:为了产品体验考虑请按需请求需要的scope,过多的授权范围容易导致用户放弃授权。
接入方式 #
标准OAuth2.0授权流程 #
- 跳转厦航OAuth授权登录页(详见 “用户授权获取授权码” )
- 用户使用厦航账号进行登录
- 用户确认授权信息给请求方
- 拿到授权码 auth_code
- 使用 auth_code 换取 access_token (详见 “使用授权码获取授权访问令牌” )
- 带着 access_token 访问授权的资源
用户直接授权流程 #
- 用户提供凭证信息
- 请求方对凭证信息进行加密,调用厦航接口获取授权码(详见 ”默认授权获取授权码“ )
- 使用 auth_code 换取 access_token (详见 “使用授权码获取授权访问令牌” )
- 带着 access_token 访问授权的资源
短信验证码授权授权流程 #
- 用户输入手机号
- 请求方对调用厦航接口给用户手机号发送短信
- 用户输入短信验证码,调用厦航接口获取授权码(详见 ”短信验证码授权获取授权码“ )
- 使用 auth_code 换取 access_token (详见 “使用授权码获取授权访问令牌” )
- 带着 access_token 访问授权的资源
接口说明 #
用户授权获取授权码 #
请求地址: https://oauth-test.xiamenair.com/common/oauth/authorize
请求方式: GET
请求参数
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| response_type | 表示要求返回授权码,值只能为“authorization_code” | true | string | code |
| client_id | 厦航分配给开发者的应用ID | true | string | xxx_client |
| redirect_uri | 授权回调地址,需与申请的授权回调地址一致。建议回调地址使用https | true | string | http://www.xmair.com (opens new window) |
| scope | 应用授权作用域。多个用“+”分隔 | true | string | web |
| state | 不可猜测的随机字符串,该参数可用于防止跨站请求伪造(CSRF)攻击。 此参数将在授权后重定向回第三方时包含此值,建议第三方带上该参数,开发者可用此参数验证请求有效性。 | true | string | oauth |
| language | 授权页语言,缺省(或zh-cn)为中文简体版,en为英文版。 | false | string | zh-cn |
请求示例(浏览器访问)
https://oauth-test.xiamenair.com/common/oauth/authorize?response_type=authorization_code&client_id=xxx_client&redirect_uri=http://www.xmair.com&scope=ecip-user/usrInfo.member.read&state=oauth
公共响应参数(以下接口同)(公共响应参数不适用本接口的:用户允许授权时响应示例、用户禁止授权时的响应示例)
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| code | 返回码,见“返回码说明” | true | string | 200 |
| errStr | 见“返回码说明” | true | string | INVALID_PARAM |
| message | 返回码描述。见“返回码说明” | true | string | success |
| data | 数据内容 | false | 见“data中的响应参数” | |
| next | 需下一步操作的提示。当需要下一步操作时,有返回值 | false | string | two-step auth with msg_code |
| traceId | 链路id | false | string |
响应参数说明
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| auth_code | 一次性授权码,用于换取访问令牌,有效期600秒 | true | string | ef8dbc11-dba5-3d5e-bafd-0b72cc35c1f7 |
| state | 不可猜测的随机字符串,如果有传递改参数,会返回该参数 | false | string |
用户允许授权时的响应示例
REDIRECT_URI?code=ef8dbc11-dba5-3d5e-bafd-0b72cc35c1f7&state=oauth
用户禁止授权时的响应示例
REDIRECT_URI?error=access_denied&error_description=User denied access&state=oauth
重定向URI无效或不匹配的响应示例
{
"code": "400",
"errStr": "INVALID_URI",
"message": "重定向URI与注册的重定向URI不匹配",
"data": null,
"next": null,
"traceId": "string"
}
短信验证码授权获取授权码 #
请求地址: 接入API后获取
请求方式: POST
请求参数
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| client_id | 厦航分配给开发者的应用ID | true | string | xxx_client |
| client_secret | 厦航分配给开发者的密码 | true | string | 123456abcdefd1a3a093f667cde4ee37 |
| scope | 应用授权作用域。ecip-user/usrInfo.brief.read:查询厦航用户简要信息;ecip-user/usrInfo.member.read查询厦航会员信息;多个scope使用“+"分隔 | true | string | ecip-user/usrInfo.brief.read+ecip-user/usrInfo.member.read |
| response_type | 值只能为“code” | true | string | code |
| credential_type | 凭证类型,phone_info:手机号。msg_code:短信验证码+验证码追踪凭据 | true | string | phone_info(初次调用该接口时传此类型) msg_code(当进行短信验证时传此类型) |
| credential | 用户凭证:手机号。 短信凭证:短信验证码+验证码追踪凭据 | true | string | 传输时,json串需进行(加密方式联系开发人员获取) |
凭证类型 为 msg_code 的credential内容(需进行加密传输):
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| msg_code | 短信验证码 | true | string | 111111 |
| trace_credential | 短信验证码追踪凭据 | true | string | 123456789 |
请求示例
{
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"scope": "SCOPE1+SCOPE2",
"response_type": "code",
"credential_type": "phone_info",
"credential": "ENCRYPT_STR"
}
凭证类型 为 msg_code 的credential内容明文示例
{
"msg_code": "MSG_CODE",
"trace_credential": "TRACE_CREDENTIAL"
}
公共响应参数(以下接口同)
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| code | 返回码。成返回200 | true | string | 200 |
| errStr | 见“返回码说明” | true | string | INVALID_PARAM |
| message | 返回码描述。成功返回success | true | string | success |
| data | 数据内容 | false | 见“data中的响应参数” | |
| traceId | 链路id | false | string |
data中相关响应参数
| 参数名称 | 参数说明 | 数据类型 | 示例值 |
|---|---|---|---|
| next | 需下一步操作的提示。当需要下一步操作时,有返回值(如果有,则需要带上短信验证码等参数再次调用该接口以获取auth_code) | string | msg_code |
| trace_credential | 短信验证码追踪凭据(有next才会返回) | string | 123456789 |
| auth_code | 授权码,用于换取访问令牌,有效期600秒(在没有next的时候才会返回) | string | ef8dbc11-dba5-3d5e-bafd-0b72cc35c1f7 |
授权成功的响应示例
{
"code": "200",
"errStr": null,
"message": "success",
"data": {
"auth_code": "AUTH_CODE"
},
"next": null,
"traceId": "string"
}
或:
{
"code": "200",
"errStr": null,
"message": "success",
"data": {
"next": "msg_code",
"trace_credential": "TRACE_CREDENTIAL"
},
"next": null,
"traceId": "string"
}
异常示例
{
"code": "500",
"errStr": "UNKNOWN_ERROR",
"message": "未知错误,请稍后重试",
"data": null,
"next": null,
"traceId": "string"
}
默认授权获取授权码 #
请求地址: 接入API后获取
请求方式: POST
请求参数
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| client_id | 厦航分配给开发者的应用ID | true | string | xxx_client |
| client_secret | 厦航分配给开发者的密码 | true | string | 123456abcdefd1a3a093f667cde4ee37 |
| scope | 应用授权作用域。ecip-user/usrInfo.brief.read:查询厦航用户简要信息;ecip-user/usrInfo.member.read查询厦航会员信息;多个scope使用“+"分隔 | true | string | ecip-user/usrInfo.brief.read+ecip-user/usrInfo.member.read |
| response_type | 值只能为“code” | true | string | code |
| credential_type | 凭证类型,base_info:用户姓名+证件+证件类型+手机号。msg_code:短信验证码+验证码追踪凭据 | true | string | base_info(初次调用该接口时传此类型) msg_code(当进行短信验证时传此类型) |
| credential | 用户凭证:用户姓名+证件+证件类型+手机号。 短信凭证:短信验证码+验证码追踪凭据 | true | string | 传输时,json串需进行(加密方式联系开发人员获取) |
凭证类型 为 base_info 的credential内容(需进行加密传输):
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| user_name | 用户姓名 | true | string | 李某某 |
| cert_no | 用户证件号码 | true | string | 440000000000000000 |
| cert_type | 用户证件类型。01:身份证;02:护照; 07:港澳居住证;08:台湾居住证;99:其他证件 | true | string | 01 |
| tel_no | 用户手机号码 | true | string | 13900000000 |
凭证类型 为 msg_code 的credential内容(需进行加密传输):
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| msg_code | 短信验证码 | true | string | 111111 |
| trace_credential | 短信验证码追踪凭据 | true | string | 123456789 |
| need_update | 是否需要更新手机号标识 | false | boolean | true(只有在用户是否要更新手机号时才传此参数) |
请求示例
{
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"scope": "SCOPE1+SCOPE2",
"response_type": "code",
"credential_type": "base_info",
"credential": "ENCRYPT_STR"
}
凭证类型 为 base_info 的credential内容明文示例
{
"user_name": "USER_NAME",
"cert_no": "CERT_NO",
"cert_type": "01",
"tel_no": "TEL_NO"
}
凭证类型 为 msg_code 的credential内容明文示例
{
"msg_code": "MSG_CODE",
"trace_credential": "TRACE_CREDENTIAL",
"need_update": true
}
公共响应参数(以下接口同)
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| code | 返回码。成返回200 | true | string | 200 |
| errStr | 见“返回码说明” | true | string | INVALID_PARAM |
| message | 返回码描述。成功返回success | true | string | success |
| data | 数据内容 | false | 见“data中的响应参数” | |
| traceId | 链路id | false | string |
data中相关响应参数
| 参数名称 | 参数说明 | 数据类型 | 示例值 |
|---|---|---|---|
| next | 需下一步操作的提示。当需要下一步操作时,有返回值(如果有,则需要带上短信验证码等参数再次调用该接口以获取auth_code) | string | msg_code |
| trace_credential | 短信验证码追踪凭据(有next才会返回) | string | 123456789 |
| need_update | 判断是否询问用户是否需要更新手机号码(有next才会返回) | boolean | true |
| auth_code | 授权码,用于换取访问令牌,有效期600秒(在没有next的时候才会返回) | string | ef8dbc11-dba5-3d5e-bafd-0b72cc35c1f7 |
授权成功的响应示例
{
"code": "200",
"errStr": null,
"message": "success",
"data": {
"auth_code": "AUTH_CODE"
},
"next": null,
"traceId": "string"
}
或:
{
"code": "200",
"errStr": null,
"message": "success",
"data": {
"next": "msg_code",
"trace_credential": "TRACE_CREDENTIAL",
"need_update": true
},
"next": null,
"traceId": "string"
}
异常示例
{
"code": "500",
"errStr": "UNKNOWN_ERROR",
"message": "未知错误,请稍后重试",
"data": null,
"next": null,
"traceId": "string"
}
使用授权码获取授权访问令牌 #
请求地址:接入API后获取
请求方式 POST
请求参数
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| client_id | 厦航分配给开发者的应用ID | true | string | xxx_client |
| client_secret | 厦航分配给开发者的密码 | true | string | 123456abcdefd1a3a093f667cde4ee37 |
| grant_type | 授权类型,值只能为“authorization_code” | true | string | authorization_code |
| code | 第1步返回的auth_code(授权码),用于换取访问令牌 | true | string | ef8dbc11-dba5-3d5e-bafd-0b72cc35c1f7 |
请求示例
{
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"grant_type": "authorization_code",
"code": "AUTH_CODE"
}
公共响应参数(同上:公共响应参数)
data中相关响应参数
| 参数名称 | 参数说明 | 数据类型 | 示例值 |
|---|---|---|---|
| access_token | 接口调用凭证 | string | a7652522-74cf-49da-9176-44b8fdf69c3d |
| expires_in | 请求返回的access_token过期时间,以秒为单位,有效期2小时 | string | 7200 |
| refresh_token | refresh令牌 | string | e04ace34-59df-4d36-961f-61fa5aedb117 |
| refresh_token_expires_in | refresh_token过期时间,以秒为单位,有效期30天 | string | 2592000 |
| user_id | 此参数为厦航用户在对应client_id下的唯一标识 | string | 49EBD3FEC4084FE19F4B46638668E0E7 |
| scope | 用户授权的作用域。auth_offer:查询厦航会员价产品;auth_order:创建订单;多个“,"分隔 | string | auth_offer,auth_order |
成功时的响应示例
{
"code": "200",
"errStr": null,
"message": "success",
"data": {
"access_token": "ACCESS_TOKEN",
"expires_in": 7200,
"refresh_token": "REFRESH_TOKEN",
"refresh_token_expires_in": 2592000,
"user_id": "USER_ID",
"scope": "auth_offer,auth_order"
},
"next": null,
"traceId": "string"
}
异常示例
{
"code": "500",
"errStr": "UNKNOWN_ERROR",
"message": "未知错误,请稍后重试",
"data": null,
"next": null,
"traceId": "string"
}
刷新访问令牌 #
当access_token超时后,可以使用refresh_token进行刷新。refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权。
请求地址:接入API后获取
请求方式 POST
请求参数
| 参数名称 | 参数说明 | 是否必须 | 数据类型 | 示例值 |
|---|---|---|---|---|
| client_id | 厦航分配给开发者的应用ID | true | string | xxx_client |
| client_secret | 厦航分配给开发者的密码 | true | string | 123456abcdefd1a3a093f667cde4ee37 |
| grant_type | 授权类型,值只能为“refresh_token” | true | string | refresh_token |
| refresh_token | 刷新令牌。通过该令牌可以刷新access_token | true | string | e04ace34-59df-4d36-961f-61fa5aedb117 |
请求示例
{
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"grant_type": "refresh_token",
"refresh_token": "REFRESH_TOKEN"
}
公共响应参数(同上:公共响应参数)
data中相关的响应参数
| 参数名称 | 参数说明 | 数据类型 | 示例值 |
|---|---|---|---|
| access_token | 接口调用凭证 | string | a7652522-74cf-49da-9176-44b8fdf69c3d |
| expires_in | 请求返回的access_token过期时间,以秒为单位,有效期2小时 | string | 7200 |
| refresh_token | refresh令牌 | string | e04ace34-59df-4d36-961f-61fa5aedb117 |
| refresh_token_expires_in | refresh_token过期时间,以秒为单位,有效期30天 | string | 2592000 |
成功响应示例
{
"code": "200",
"errStr": null,
"message": "success",
"data": {
"access_token": "ACCESS_TOKEN",
"expires_in": 7200,
"refresh_token": "REFRESH_TOKEN",
"refresh_token_expires_in": 2592000,
"user_id" : "USER_ID"
},
"next": null,
"traceId": "string"
}
异常示例
{
"code": "500",
"errStr": "UNKNOWN_ERROR",
"message": "未知错误,请稍后重试",
"data": null,
"next": null,
"traceId": "string"
}
返回码说明 #
/authorize
| code | errStr | message | 解决方案 |
|---|---|---|---|
| 200 | success | ||
| 201 | INVALID_PARAM | 参数非法,如参数缺失(具体见返回的提示信息) | 检查请求参数 |
| 201 | INVALID_PARAM | 参数非法,如参数缺失 | 传入与契约一致的参数 |
| 201 | INVALID_PARAM | 参数非法,客户端参数缺失 | 传入正确的客户端id和客户端secret |
| 201 | INVALID_PARAM | 客户端账号密码不匹配 | 传入正确的客户端id和客户端secret |
| 201 | INVALID_PARAM | 客户端信息有误 | 客户端不存在,传入正确的客户端id和客户端secret |
| 201 | INVALID_PARAM | 参数非法,用户凭证类型缺失 | 传入正确的用户凭证类型 |
| 201 | INVALID_PARAM | 参数非法,用户凭证类型错误 | 传入正确的用户凭证类型 |
| 201 | INVALID_PARAM | 参数非法,用户凭证信息缺失 | 传入正确的用户凭证信息 |
| 201 | INVALID_PARAM | 参数非法,凭证中的用户基本信息缺失 | 传入正确的用户基本信息 |
| 201 | INVALID_PARAM | 参数非法,凭证中的英文姓名格式错误 | 传入正确的用户英文姓名 |
| 201 | INVALID_PARAM | 参数非法,授权范围缺失 | 传入正确的授权范围 |
| 201 | INVALID_PARAM | 参数非法,授权范围不在被允许的范围内 | 传入正确的授权范围 |
| 400 | BUSINESS_ERROR | 未获得第三方用户信息 | |
| 400 | BUSINESS_ERROR | 解密用户凭证信息错误,请稍后重试 | 检查请求的用户凭证信息,重新尝试 |
| 401 | UNSUPPORTED_RESPONSE_TYPE | 不支持此方法获取授权代码 | 检查请求参数 |
| 500 | UNKNOWN_ERROR | 未知错误,请稍后重试 | 稍后重试 |
/authorizeByMsg
| code | errStr | message | 解决方案 |
|---|---|---|---|
| 200 | success | ||
| 201 | INVALID_PARAM | 参数非法,如参数缺失(具体见返回的提示信息) | 检查请求参数,传入与契约一致的参数 |
| 201 | INVALID_PARAM | 参数非法,客户端参数缺失 | 传入正确的客户端id和客户端secret |
| 201 | INVALID_PARAM | 客户端账号密码不匹配 | 传入正确的客户端id和客户端secret |
| 201 | INVALID_PARAM | 客户端信息有误 | 客户端不存在,传入正确的客户端id和客户端secret |
| 201 | INVALID_PARAM | 参数非法,用户凭证类型缺失 | 传入正确的用户凭证类型 |
| 201 | INVALID_PARAM | 参数非法,用户凭证类型错误 | 传入正确的用户凭证类型 |
| 201 | INVALID_PARAM | 参数非法,用户凭证信息缺失 | 传入正确的用户凭证信息 |
| 201 | INVALID_PARAM | 参数非法,凭证中的用户基本信息缺失 | 传入正确的用户基本信息 |
| 201 | INVALID_PARAM | 参数非法,授权范围缺失 | 传入正确的授权范围 |
| 201 | INVALID_PARAM | 参数非法,授权范围不在被允许的范围内 | 传入正确的授权范围 |
| 400 | BUSINESS_ERROR | 该手机号找不到有效会员 | 引导用户注册会员 |
| 400 | BUSINESS_ERROR | 该手机号具有超过2个的有效会员 | 引导用户注册会员(注册后会自动引导用户确认手机号) |
| 400 | BUSINESS_ERROR | 一次性凭证无效或已失效 | 由于操作超时(5分钟有效期),需要重新发送短信 |
| 400 | BUSINESS_ERROR | 短信验证码验证失败 | 用户输入的短信验证码错误,引导用户重新输入 |
| 401 | UNSUPPORTED_RESPONSE_TYPE | 不支持此方法获取授权代码 | 检查请求参数 |
| 500 | UNKNOWN_ERROR | 未知错误,请稍后重试 | 稍后重试 |
/token
| code | errStr | message | 解决方案 |
|---|---|---|---|
| code | errStr | message | 解决方案 |
| 401 | invalid_client | 客户端账号密码不匹配 | 传入正确的客户端id和客户端secret |
| 401 | invalid_client | 给定的客户端ID与经过身份验证的客户端不匹配 | 传入正确的客户端id和客户端secret |
| 401 | invalid_client | 未经授权的授权类型 | 传入正确的客户端id和客户端secret以及授权的授权范围 |
| 400 | invalid_scope | 无效的授权范围 | 传入正确的授权范围 |
| 400 | invalid_scope | 授权范围为空,或请求的授权范围不允许 | 传入正确的授权范围 |
| 400 | invalid_request | 缺少授权类型 | 传入正确的授权类型 |
| 400 | invalid_request | 缺少授权码 | 传入正确的授权码 |
| 400 | invalid_grant | 无效的授权码 | 传入正确的授权码 |
| 400 | invalid_grant | 回调地址不匹配 | 传入正确的回调地址 |
| 400 | invalid_request | 缺少 refresh_token | 传入正确的 refresh_token |
| 400 | unsupported_grant_type | 不支持的授权类型 | 传入正确的授权类型 |
| 401**** | 具体见返回的提示信息 | 具体见返回的提示信息 | |
| 500 | SERVER_ERROR | 服务异常 | 请重新尝试 |