快递查询接口API
快递查询接口是指快递查询网对外开放的应用程序接口,开发人员能够通过调用该接口与快递查询网进行交互,并基于该接口开发自己的快递查询应用程序。目前比较常用的接口有快递鸟、快递100、快递网等。
应用场景
电商网站用户打开“我的订单”时调用此API显示物流信息详情;或者是电商管理后台的物流系统,客服在对账前查询所有运单的签收状态,并追踪问题。
快递查询接口分类
物流轨迹查询接口有即时查询和订阅查询两种,即时是请求即返回数据,订阅则是订阅快递单号到接口,有物流轨迹更新则全量返回数据。
快递鸟即时接口可以查询3000次,3000以上接订阅接口,统一接口模式接入,常用快递均支持查询,还有订阅接口、在线下单接口、电子面单接口,接口均不收取费用, 没有要求用户添加外链,支持418家国内外快递物流查询。
快递100每天可以免费查询2000次,超过2000次收费,每次0.06~0.1元不等,如果查询的量大的话可以降低费用,免费的接口有几家常用快递不支持接口模式,只支持 htmlAPI,要求用户添加外链,支持300多家国内外快递物流查询。
快递网每天可以免费查询500次,超过500次收费,每次0.05元,只有即时查询和订阅推送接口,要求用户添加外链,支持395家国内外快递物流查询。
对接说明
不同公司的快递查询接口接入类似,都需要注册http://www.kdniao.com/ServiceApply.aspx ,申请账号获取KEY和ID,如果是订阅接口需要技术联调。以快递鸟及时查询接口接入为例。
根据快递单号和快递公司编码查询物流轨迹信息。接口需要指定快递单号的快递公司编码,格式不对或则编码错误都会返失败的信息。如:EMS物流单号应选择快递公司编码(EMS)查看快递公司编码返回的物流跟踪信息按照发生的时间升序排列。
接口支持的消息接收方式为HTTP POST
请求方法的编码格式(utf-8):"application/x-www-form-urlencoded;charset=utf-8"
API地址:http://api.kdniao.cc/Ebusiness/EbusinessOrderHandle.aspx
请求系统级参数
参数名称 | 类型 | 说明 | 必须要求 |
---|---|---|---|
RequestData | String | 请求内容需进行URL(utf-8)编码。请求内容JSON或XML格式,须和DataType一致。 | R |
EBusinessID | String | 商户ID,请在我的服务页面查看。 | R |
RequestType | String | 请求指令类型:1002 | R |
DataSign | String | 数据内容签名:把(请求内容(未编码)+AppKey)进行MD5加密,然后Base64编码,最后进行URL(utf-8)编码。详细过程请查看Demo。 | R |
DataType | String | 请求、返回数据类型:1-xml,2-json;默认为xml格式 | O |
请求内容字段定义
参数 | 类型 | 说明 | 必须要求 |
---|---|---|---|
OrderCode | String | 订单编号 | O |
ShipperCode | String | 快递公司编码 | R |
LogisticCode | String | 物流单号 | R |
返回参数定义
参数名称 | 类型 | 说明 | 必须要求 | |
---|---|---|---|---|
EBusinessID | String | 用户ID | R | |
OrderCode | String | 订单编号 | O | |
ShipperCode | String | 快递公司编码 | R | |
LogisticCode | String | 物流运单号 | R | |
Success | Bool | 成功与否 | R | |
Reason | String | 失败原因 | O | |
State | String | 物流状态:2-在途中,3-签收,4-问题件 | R | |
Traces | ||||
Trace | AcceptTime | String | 时间 | R |
AcceptStation | String | 描述 | R | |
Remark | String | 备注 | O |
Java调用示例
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import
- java.io.OutputStreamWriter;
- import
- java.io.UnsupportedEncodingExcept
- ion;
- import
- java.net.HttpURLConnection;
- import java.net.URL;
- import java.net.URLEncoder;
- import
- java.security.MessageDigest;
- import java.util.HashMap;
- import java.util.Map;
- /**
- *
- * 快递鸟物流轨迹即时查询接口
- *
- * @技术QQ群: 456320272
- * @see:
- http://www.kdniao.com/YundanChaxu
- nAPI.aspx
- * @copyright: 深圳市快金数据技术
- 服务有限公司
- *
- * DEMO中的电商ID与私钥仅限测试使
- 用,正式环境请单独注册账号
- * 单日超过500单查询量,建议接入
- 我方物流轨迹订阅推送接口
- *
- * ID和Key请到官网申请:
- http://www.kdniao.com/ServiceAppl
- y.aspx
- */
- public class KdniaoTrackQueryAPI
- {
- //DEMO
- public static void main
- (String[] args) {
- KdniaoTrackQueryAPI api = new
- KdniaoTrackQueryAPI();
- try {
- String
- result =
- api.getOrderTracesByJson("ANE",
- "210001633605");
- System.out.print(result);
- } catch
- (Exception e) {
- e.printStackTrace();
- }
- }
- //电商ID
- private String
- EBusinessID="请到快递鸟官网申请
- http://www.kdniao.com/ServiceAppl
- y.aspx";
- //电商加密私钥,快递鸟提
- 供,注意保管,不要泄漏
- private String AppKey="请
- 到快递鸟官网申请
- http://www.kdniao.com/ServiceAppl
- y.aspx";
- //请求url
- private String
- ReqURL="http://api.kdniao.cc/Ebus
- iness/EbusinessOrderHandle.aspx";
- /**
- * Json方式 查询订单物流轨迹
- * @throws Exception
- */
- public String
- getOrderTracesByJson(String
- expCode, String expNo) throws
- Exception{
- String
- requestData=
- "{'OrderCode':'','ShipperCode':'"
- + expCode + "','LogisticCode':'"
- + expNo + "'}";
- Map<String,
- String> params = new
- HashMap<String, String>();
- params.put
- ("RequestData", urlEncoder
- (requestData, "UTF-8"));
- params.put
- ("EBusinessID", EBusinessID);
- params.put
- ("RequestType", "1002");
- String
- dataSign=encrypt(requestData,
- AppKey, "UTF-8");
- params.put
- ("DataSign", urlEncoder(dataSign,
- "UTF-8"));
- params.put
- ("DataType", "2");
- String
- result=sendPost(ReqURL, params);
- //根据公司业务处
- 理返回的信息......
- return result;
- }
- /**
- * XML方式 查询订单物流轨迹
- * @throws Exception
- */
- public String
- getOrderTracesByXml() throws
- Exception{
- String
- requestData= "<?xml version=
- "1.0" encoding="utf-8" ?>"+
- "<Content>"+
- "<OrderCode></OrderCode>"+
- "<ShipperCode>SF</ShipperCode>"+
- "<LogisticCode>589707398027</Logi
- sticCode>"+
- "</Content>";
- Map<String,
- String> params = new
- HashMap<String, String>();
- params.put
- ("RequestData", urlEncoder
- (requestData, "UTF-8"));
- params.put
- ("EBusinessID", EBusinessID);
- params.put
- ("RequestType", "1002");
- String
- dataSign=encrypt(requestData,
- AppKey, "UTF-8");
- params.put
- ("DataSign", urlEncoder(dataSign,
- "UTF-8"));
- params.put
- ("DataType", "1");
- String
- result=sendPost(ReqURL, params);
- //根据公司业务处
- 理返回的信息......
- return result;
- }
- /**
- * MD5加密
- * @param str 内容
- * @param charset 编码方式
- * @throws Exception
- */
- @SuppressWarnings
- ("unused")
- private String MD5(String
- str, String charset) throws
- Exception {
- MessageDigest md =
- MessageDigest.getInstance("MD5");
- md.update
- (str.getBytes(charset));
- byte[] result =
- md.digest();
- StringBuffer sb = new
- StringBuffer(32);
- for (int i = 0; i <
- result.length; i++) {
- int val = result
- [i] & 0xff;
- if (val <= 0xf) {
- sb.append
- ("0");
- }
- sb.append
- (Integer.toHexString(val));
- }
- return sb.toString
- ().toLowerCase();
- }
- /**
- * base64编码
- * @param str 内容
- * @param charset 编码方式
- * @throws
- UnsupportedEncodingException
- */
- private String base64
- (String str, String charset)
- throws
- UnsupportedEncodingException{
- String encoded =
- base64Encode(str.getBytes
- (charset));
- return encoded;
- }
- @SuppressWarnings
- ("unused")
- private String
- urlEncoder(String str, String
- charset) throws
- UnsupportedEncodingException{
- String result =
- URLEncoder.encode(str, charset);
- return result;
- }
- /**
- * 电商Sign签名生成
- * @param content 内容
- * @param keyValue Appkey
- * @param charset 编码方式
- * @throws
- UnsupportedEncodingException
- ,Exception
- * @return DataSign签名
- */
- @SuppressWarnings
- ("unused")
- private String encrypt
- (String content, String keyValue,
- String charset) throws
- UnsupportedEncodingException,
- Exception
- {
- if (keyValue !=
- null)
- {
- return
- base64(MD5(content + keyValue,
- charset), charset);
- }
- return base64
- (MD5(content, charset), charset);
- }
- /**
- * 向指定 URL 发送POST方法的
- 请求
- * @param url 发送请求的 URL
- * @param params 请求的参数集
- 合
- * @return 远程资源的响应结果
- */
- @SuppressWarnings
- ("unused")
- private String sendPost
- (String url, Map<String, String>
- params) {
- OutputStreamWriter out =
- null;
- BufferedReader in = null;
- StringBuilder result =
- new StringBuilder();
- try {
- URL realUrl = new
- URL(url);
- HttpURLConnection
- conn =(HttpURLConnection)
- realUrl.openConnection();
- // 发送POST请求必须设
- 置如下两行
- conn.setDoOutput
- (true);
- conn.setDoInput
- (true);
- // POST方法
- conn.setRequestMethod("POST");
- // 设置通用的请求属性
- conn.setRequestProperty("accept",
- "*/*");
- conn.setRequestProperty
- ("connection", "Keep-Alive");
- conn.setRequestProperty("user-
- agent",
- "Mozilla/4.0
- (compatible; MSIE 6.0; Windows NT
- 5.1;SV1)");
- conn.setRequestProperty
- ("Content-Type", "application/x-
- www-form-urlencoded");
- conn.connect();
- // 获取URLConnection
- 对象对应的输出流
- out = new
- OutputStreamWriter
- (conn.getOutputStream(), "UTF-
- 8");
- // 发送请求参数
- if (params != null) {
- StringBuilder param = new
- StringBuilder();
- for
- (Map.Entry<String, String> entry
- : params.entrySet()) {
- if(param.length()>0){
- param.append("&");
- }
- param.append(entry.getKey());
- param.append("=");
- param.append(entry.getValue());
- //System.out.println
- (entry.getKey
- ()+":"+entry.getValue());
- }
- //System.out.println
- ("param:"+param.toString());
- out.write(param.toString());
- }
- // flush输出流的缓冲
- out.flush();
- // 定义BufferedReader
- 输入流来读取URL的响应
- in = new
- BufferedReader(
- new
- InputStreamReader
- (conn.getInputStream(), "UTF-
- 8"));
- String line;
- while ((line =
- in.readLine()) != null) {
- result.append
- (line);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- //使用finally块来关闭输出
- 流、输入流
- finally{
- try{
- if(out!=null){
- out.close();
- }
- if(in!=null){
- in.close();
- }
- }
- catch(IOException
- ex){
- ex.printStackTrace();
- }
- }
- return result.toString();
- }
- private static char[]
- base64EncodeChars = new char[] {
- 'A', 'B', 'C', 'D', 'E',
- 'F', 'G', 'H',
- 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U',
- 'V', 'W', 'X',
- 'Y', 'Z', 'a', 'b', 'c',
- 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k',
- 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's',
- 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0',
- '1', '2', '3',
- '4', '5', '6', '7', '8',
- '9', '+', '/' };
- public static String
- base64Encode(byte[] data) {
- StringBuffer sb = new
- StringBuffer();
- int len = data.length;
- int i = 0;
- int b1, b2, b3;
- while (i < len) {
- b1 = data[i++] &
- 0xff;
- if (i == len)
- {
- sb.append
- (base64EncodeChars[b1 >>> 2]);
- sb.append
- (base64EncodeChars[(b1 & 0x3) <<
- 4]);
- sb.append("==");
- break;
- }
- b2 = data[i++] &
- 0xff;
- if (i == len)
- {
- sb.append
- (base64EncodeChars[b1 >>> 2]);
- sb.append
- (base64EncodeChars[((b1 & 0x03)
- << 4) | ((b2 & 0xf0) >>> 4)]);
- sb.append
- (base64EncodeChars[(b2 & 0x0f) <<
- 2]);
- sb.append("=");
- break;
- }
- b3 = data[i++] &
- 0xff;
- sb.append
- (base64EncodeChars[b1 >>> 2]);
- sb.append
- (base64EncodeChars[((b1 & 0x03)
- << 4) | ((b2 & 0xf0) >>> 4)]);
- sb.append
- (base64EncodeChars[((b2 & 0x0f)
- << 2) | ((b3 & 0xc0) >>> 6)]);
- sb.append
- (base64EncodeChars[b3 & 0x3f]);
- }
- return sb.toString();
- }
- }