快递公司接入快递100订阅推送接口
一、名词解释
订阅:快递100向快递公司发起的跟踪运单的请求
推送:快递公司向快递100发起的运单路由信息变更通知
key:快递公司和快递100约定一个密钥,用于数据签名和验证身份,不在网络上传播
md5:标准摘要算法,各开发语言均有实现
二、订阅请求
快递100在希望快递公司跟踪某个运单的时候,会向快递公司发起订阅请求,订阅请求采用HTTP Form POST方式提交到快递公司指定的url上,假设快递公司接受订阅的url是:http://www.xxxx.com/track/order.do
请求头
名称 | 类型 | 默认值 |
---|---|---|
Content-Type | string | application/x-www-form-urlencoded |
请求体
名称 | 是否必填 | 类型 | 说明 |
---|---|---|---|
key | 是 | string | 快递公司和快递100约定一个密钥,用于数据签名和验证身份,不在网络上传播 |
customer | 是 | string | kuaidi100,参数用于声明身份,表示订阅请求来自快递100,为验证签名提供依据 |
sign | 是 | string | 签名,用于验证身份,按MD5 (param +t+key)的顺序进行MD5加密,不需要加上“+”号 |
param | 是 | param | 由其他字段拼接 |
param数据结构
名称 | 是否必填 | 类型 | 说明 |
---|---|---|---|
company | 是 | string | 快递公司编码,少量快递公司支持多品牌 |
code | 是 | string | 快递单号 |
operator | 是 | string | 操作类型,order表示订阅,repush表示请求快递公司发起一次全量重推 |
callback | 是 | string | 回调地址,用于接收推送数据,在推送时需提供,不多于32字节的文本 |
订阅过程相当于向快递公司提交如下格式的form:
< form action = " http://www.xxxx.com/track/order.do "
method = "post" >
<
input type = "hidden"
name = "param"
value = "json参数" / >
<
input type = "hidden"
name = "sign"
value = "md5" / >
<
input type = "hidden"
name = "customer"
value = "kuaidi100" / >
<
/form>
其中,param参数为json格式,如Demo所示:
{
// 快递公司编码,少量快递公司支持多品牌
"company": "xxxx",
//订阅的快递单号
"code": "12345678",
//操作:order表示订阅,repush表示请求快递公司发起一次全量重推
"operator": "order",
// 回调参数,快递100需要的附加参数,在推送时需提供,不多于32字节的文本
"callback": "123468121"
}
补充说明
Operator:order:表示正常订阅,快递100对一单会发起一次正常订阅请求;repush:当快递100由于某种原因数据不完整的时候,期望快递公司收到该请求后发起一次全量推送用于覆盖历史推送数据,较少出现,用于疑难问题处理。
三、订阅应答
针对快递100的订阅请求,快递公司通过http请求的response以json文本方式的应答
字段 | 类型 | 说明 | 备注 |
---|---|---|---|
result | boolean | 提交结果 | true提交成功,false失败 |
returnCode | string | 返回编码 | |
message | string | 返回报文描述 |
应答示例
{
//订阅的结果:true表示成功,false表示失败
"result": "true",
//推送的结果状态
"returnCode": "200",
//对应状态的文本描述
"message": "成功",
}
信息代码含义
信息代码 | 信息内容描述 | 快递100需要做的操作 |
---|---|---|
200 | 成功 | |
400 | 数据不完整 | 补充数据,重新订阅 |
500 | 请求格式错误 | 程序有问题,需要调整 |
501 | 服务器错误 | 30分钟后尝试 |
502 | 重复订阅 | 理解为订阅成功 |
503 | 验证签名失败 | 请使用正确的KEY |
504 | 单号错误 | 更正单号 |
507 | 查询异常 |
四、推送请求
在快递公司收到来自快递100的推送请求后,快递公司会持续跟踪对应的快递单,在路由信息变化时会及时通过回调方式向快递100推送数据
请求头
名称 | 类型 | 默认值 |
---|---|---|
Content-Type | string | application/x-www-form-urlencoded |
请求体
名称 | 是否必填 | 类型 | 说明 |
---|---|---|---|
sign | 是 | string | 签名,用于验证身份,按MD5 (param +t+key)的顺序进行MD5加密,不需要加上“+”号 |
company | 是 | string | 快递公司编码 |
param | 是 | param | 由其他字段拼接 |
param数据结构
名称 | 是否必填 | 类型 | 说明 |
---|---|---|---|
watchStatus | 是 | string | 包裹跟踪状态:normal:跟踪,stop:结束,abort:中止(3天无结果) |
operation | 是 | string | 推送操作状态:append:扩展,override:覆盖 |
status | 是 | string | 包裹运输状态,0在途、1揽收、2疑难、3签收、4退签、5派件、6退回、7转单、8结算 |
company | 是 | string | 快递公司编码 |
code | 是 | string | 快递单号 |
callback | 是 | string | 快递公司的订阅请求地址 |
Θdetail | |||
id | 是 | string | 标识路由状态的顺序ID |
context | 是 | string | 快递最新路由信息 |
time | 是 | string | 当前路由信息时间:yyyy-mm-dd hh:mm:ss |
location | 是 | string | 包裹位置:使用正确的中文行政区划地名,最好包含省、地、县 |
operator | 是 | string | 操作人 |
tel | 是 | string | 操作人电话 |
快递公司推给快递100的数据时,相当于向快递100提交如下格式的form:
< form action = " http://www.kuaidi100.com/callback.do"
method = "post" >
<
input type = "hidden"
name = "param"
value = "json参数" / >
<
input type = "hidden"
name = "sign"
value = "md5" / >
<
input type = "hidden"
name = "company"
value = "xxxx" / >
<
/form>
parma格式如下:
{
// 包裹跟踪状态:normal:跟踪,stop:结束,abort:中止(3无结果)。
"watchStatus": "normal",
// 推送操作状态:append:扩展,override:覆盖
"operation": "append",
// 包裹运输状态,0在途、1揽收、2疑难、3签收、4退签、5派件、6退回、7转单、8结算
"status": 0,
// 快递公司编码,少量快递公司支持多品牌
"company": "xxxx",
// 运单号
"code": "123456789012",
// 回调参数,源自订阅请求
"callback": "123468121", //这么的Callback值为快递公司的订阅请求地址
// 路由信息
"detail": [{
// 标识路由状态的顺序ID
"id": 5,
// 最新路由信息
"context": "装件入车",
// 原先的description会被服务器拦截,所以统一换成context
// 时间:yyyy-mm-ddhh:mi:ss
"time": "2012-08-28 17:22:33",
// 包裹位置:使用正确的中文行政区划地名,最好包含省、地、县。
"location": "湖北,武汉,汉正街",
// 操作人(可选)
"operator": "张三",
// 操作人电话(可选)
"tel": "13877777777"
}, {
// 标识路由状态的顺序ID
"id": 6,
// 最新路由信息
"context": "发往广东深圳",
// 时间:yyyy-mm-ddhh:mi:ss
"time": "2012-08-28 17:33:19",
// 包裹位置:使用正确的中文行政区划地名,最好包含省、地、县。
"location": "湖北,武汉,汉正街",
// 操作人(可选)
"operator": "张三",
// 操作人电话(可选)
"tel": "13877777777"
}]
}
说明:
①增量推送可包含1条以上的路由信息。
②id为路由信息的序号,从0开始,要求连续,快递100以id做为推送信息是否连续完整的判断依据。
③watchstatus:normal:正常跟踪;stop:快递单已经完结,签收,退签或者结算;abort:中止(3无结果),快递公司持续3天未发现该单,快递公司侧停止跟踪
④operation:append:声明这次操作是增量,跟随历史推送内容;override:声明这次推送采用的是全量,需要覆盖历史推送内容。
### 运单状态(status)说明
状态值 | 名称 | 含义 |
---|---|---|
0 | 在途 | 快件处于运输过程中 |
1 | 揽件 | 快件已由快递公司揽收 |
2 | 疑难 | 快递100无法解析的状态,或者是需要人工介入的状态,比方说收件人电话错误 |
3 | 签收 | 正常签收 |
4 | 退签 | 货物退回发货人并签收 |
5 | 派件 | 货物正在进行派件 |
6 | 退回 | 货物正处于返回发货人的途中 |
7 | 转投 | 货物已转交给其他快递公司代为投递 |
8 | 结算 | COD货到付款完成结算 |
五、推送应答
针对快递公司推送,快递100通过http请求的response以json文本方式的应答
字段 | 类型 | 说明 | 备注 |
---|---|---|---|
result | boolean | 提交结果 | true提交成功,false失败 |
returnCode | string | 返回编码 | |
message | string | 返回报文描述 |
应答示例
{
//订阅的结果:true表示成功,false表示失败
"result": "true",
//推送的结果状态
"returnCode": "200",
//对应状态的文本描述
"message": "成功",
}
信息代码含义
信息代码 | 信息内容描述 | 快递公司需要做的操作 |
---|---|---|
200 | 成功 | |
300 | 用户取消订阅 | 取消推送 |
400 | 数据不完整 | 请以override模式重发完整结果 |
500 | 请求格式错误 | 程序有问题,需要调整 |
501 | 服务器错误 | 30分钟后尝试 |
六、Abort推送请求
由于快递100发起的订阅在快递公司一侧有可能不存在,为了避免快递公司这边错误的历史数据积压,如果在订阅后72小时内,快递公司没有检测到对应的快递单,则认为订阅超时,向快递100发起一次推送,通知快递100该单已经abort,param格式如下:
名称 | 是否必填 | 类型 | 说明 |
---|---|---|---|
watchStatus | 是 | string | 包裹跟踪状态:normal:跟踪,stop:结束,abort:中止(3天无结果) |
company | 是 | string | 快递公司编码 |
code | 是 | string | 快递单号 |
callback | 是 | string | 回调地址 |
reasonCode | 是 | string | 推送原因代码 |
reasonMessage | 是 | string | 推送原因消息说明 |
请求示例
{
"watchStatus": "abort",
"company": "xxxx",
"code": "123456789012",
"callback": "123468121",
"reasonCode": "123468121",
"reasonMessage": "123468121",
}
七、Abort推送应答
与正常推送相同
八、Stop推送请求
由于快递公司有可能在签收以后再发生状态变动,故允许单独的stop消息,快递100收到stop消息后,该订单的数据将退出系统,请求param格式如下:
名称 | 是否必填 | 类型 | 说明 |
---|---|---|---|
watchStatus | 是 | string | 包裹跟踪状态:normal:跟踪,stop:结束,abort:中止(3天无结果) |
company | 是 | string | 快递公司编码 |
code | 是 | string | 快递单号 |
callback | 是 | string | 回调地址 |
reasonCode | 是 | string | 推送原因代码 |
reasonMessage | 是 | string | 推送原因消息说明 |
请求示例
{
"watchStatus": "stop",
"company": "xxxx",
"code": "123456789012",
"callback": "123468121",
"reasonCode": "123468121",
"reasonMessage": "123468121",
}
九、Stop推送应答
与正常推送相同
十、补充说明
字符集问题
统一使用UTF-8字符集。
全量推送与增量推送问题
如果在推送应答中,快递100回复400,说明路由信息ID不连续,期望快递公司能给予全量刷新,快递公司一侧在收到400答复后,尽快再发起一次针对这一单的override推送。
推送失败的处理
由于网络原因或者服务器原因,快递公司发起的推送可能收不到应答或者应答code不是200,此时,快递公司一侧间隔半个小时进行再次推送,连续重试3次,3次都失败则放弃推送。
系统维护约定
0点至6点为系统维护时间,这期间推送业务暂停。
性能问题
http请求超时时间设置为10秒,2秒内为正常,推送或者订阅尽可能分散并发,并发数量双方协商。
呆滞单处理
快递公司部分单如果已经有路由信息了,但长期不变化(比方说30天以上)的时候,应及时发送abort并关闭。
关于repush
为了简化开发,重推采用了订阅接口,重推采用异步模式,即快递公司收到重推请求以后,不要求实时返回结果,而是尽快安排一次针对该单的推送,且推送的时候采用override模式进行覆盖重推。