国际快递查询接口
国际快递查询接口的需求量很大,例如一些跨境电商B2C网站、快递查询APP、快递柜、跨境物流公司等都会需要用到国际快递接口。
目前市面上的快递接口,以国内快递居多,有些虽然号称支持多家国际快递和国际邮政,但实际调用时,由于国际快递网站变化较多,所以经常出现不稳定的情况。这里我要介绍的是trackingmore的国际快递接口,他们一直专做国际快递,支持的380家快递也绝大部分是国外的邮政与快递公司,所以提供的接口也非常可靠。
国际快递特性(含国际邮政)
1.可在两个网站查询到信息:属于万国邮联的国际邮政单号,可以分别在发件国家邮政官网与目的国家邮政官网查询到数据。相对而言,国内快递一般只需要在一个网站查询数据。
2.海关问题:国际包裹是跨国包裹,需要通过两国的海关查验,有时候会被海关扣押,进而导致时效不如国内快递稳定。
3.运输时间长:国际邮政包裹相对国际快递价格便宜很多,所以运输时间也慢,甚至会需要1到2个月才能签收。
4.多语言问题:由于包裹是跨国的,必然会涉及多语言问题,国内客户需要看到的是中文信息,而国外客户希望看到的是当地语言的物流信息。
国际快递API特性(trackingmore)
1.包含发件国与目的国的数据:Trackingmore的API中包含的参数有 origin_info(发件国物流信息)和destination_info(目的国物流信息),所以通过该接口可以让用户看到最为完整的物信息。
2.智能识别快递状态:当检测到包裹在海关停滞,或者包裹被退回等信息,Trackingmore会返回“exception”(可能异常)的状态,帮助用户第一时间发现异常件,从而尽早处理。
3.按照单号个数计费:由于国际包裹的运输时间很长,完整的运输周期可能需要两个月,而每天至少需要查询两次以上。所以按照查询单号个数计费而不是按照API调用次数计费,是最为良心的计费方式。
4.多语言API:针对不同的快递商,可以按照语言返回不同的结果。包含中文、英文、日语、印度语、阿拉伯语等等。
对接示例
这里以Trackingmore为例,不同的接口的对接方式比较类似,都需要注册,并生成自己的API key。以下以Trackingmore的实时查询API为例。
接口支持的消息接收方式为HTTP POST
请求方法的编码格式为 utf-8
请求body部分的参数的数据格式为json 格式
接口参数
接口请求地址
http://api.trackingmore.com/v2/trackings/realtime
请求头部信息参数
参数名称 | 类型 | 说明 | 是否必须 |
|
|
定义请求头部的数据格式 | 是 |
|
string | Trackingmore 后台获取的API | 是 |
请求body参数说明
参数说明 | 类型 | 说明 | 是否必须 |
|
string | 查询快递的快递单号 | 是 |
|
string | trackingmore定义的快递商简码,比如china ems 就是china-ema | 是 |
carrier_code 参数是trackingmore 自己定义的快递商家的简码,具体的可以在这里查看。
还有需要注意的就是body部分这两个参数需要时json数据格式。大概样子就是这样的
1 {
2 "tracking_number": "LK664578623CN", 3 "carrier_code": "china-ems" 4 }
返回参数定义
参数名称 | 参数类型 | 参数说明 | 是否一定要返回该项值 |
code |
数字 | 返回码 | 成功返回200,失败有其他队列的错误码 |
type | string | 接口类型 | 成功返回Success |
message | string | 返回信息说明 | 成功返回Succes,失败返回队列的错误信息 |
data | json | 查询到的物流信息 | 成功返回物流信息,失败返回空 |
其他的状态响应简码可以在这里看到。
返回示例
{
"meta": { "code": 200, "type": "Success", "message": "Success" }, "data": { "items": [{ "id": "442f798ea35749e7605d1a73d4181a01", "tracking_number": "RE113184005HK", "carrier_code": "hong-kong-post", "status": "transit", "original_country": "Hong Kong [CN]", "destination_country": "Colombia", "itemTimeLength": null, "origin_info": { "weblink": "http:\/\/www.hongkongpost.hk\/", "phone": "852 2921 2222", "carrier_code": "hong-kong-post", "trackinfo": [{ "Details": "CO", "StatusDescription": "The item ( RE113184005HK ) left Hong Kong for its destination on 10-Oct-2015 ", "Date": "2015-10-09 00:00" }] }, "destination_info": { "weblink": "http:\/\/www.4-72.com.co\/", "phone": "(57-1) 4722000", "carrier_code": "colombia-post", "trackinfo": [{ "Date": "2015-10-22 20:52", "StatusDescription": "DIGITALIZADO", "Details": "CTP.CENTRO A" }, { "Date": "2015-10-22 17:02", "StatusDescription": "Registro de entrega exitosa", "Details": "" }, { "Date": "2015-10-22 16:55", "StatusDescription": "ENTREGADO", "Details": "CD.MONTEVIDEO" }, { "Date": "2015-10-22 09:31", "StatusDescription": "REASIGNADO", "Details": "CD.NORTE" }, { "Date": "2015-10-22 08:52", "StatusDescription": "REASIGNADO", "Details": "CD.NORTE" }, { "Date": "2015-10-22 02:39", "StatusDescription": "En proceso", "Details": "CTP.CENTRO A" }, { "Date": "2015-10-21 16:36", "StatusDescription": "En proceso", "Details": "CTP.CENTRO A" }, { "Date": "2015-10-20 06:29", "StatusDescription": "Envío Recibido en la oficina de cambio internacional", "Details": "COBOGC" }] } }] } }
JAVA接口对接示例
String urlStr =null; String requestData="{\"tracking_number\": \"RQ958152738CN\",\"carrier_code\":\"china-ems\"}"; String result = new Tracker().orderOnlineByJson(requestData,urlStr,"realtime"); package trackingMore; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Tracker { /** Apikey*/ private String Apikey="Apikey you get from trackingMore"; /** * Json */ public String orderOnlineByJson(String requestData,String urlStr,String type) throws Exception{ //---headerParams Map headerparams = new HashMap(); headerparams.put("Trackingmore-Api-Key", Apikey); headerparams.put("Content-Type", "application/json"); //---bodyParams List bodyParams = new ArrayList(); String result =null; if(type.equals("post")){ String ReqURL="http://api.trackingmore.com/v2/trackings/post"; bodyParams.add(requestData); result=sendPost(ReqURL, headerparams , bodyParams,"POST"); }else if(type.equals("get")){ String ReqURL="http://api.trackingmore.com/v2/trackings/get"; String RelUrl = ReqURL+urlStr; result=sendPost(RelUrl, headerparams , bodyParams,"GET"); }else if(type.equals("batch")){ String ReqURL="http://api.trackingmore.com/v2/trackings/batch"; bodyParams.add(requestData); result=sendPost(ReqURL, headerparams , bodyParams,"POST"); }else if(type.equals("codeNumberGet")){ String ReqURL="http://api.trackingmore.com/v2/trackings"; String RelUrl = ReqURL+urlStr; result=sendGet(RelUrl, headerparams,"GET"); }else if(type.equals("codeNumberPut")){ String ReqURL="http://api.trackingmore.com/v2/trackings"; bodyParams.add(requestData); String RelUrl = ReqURL+urlStr; result=sendPost(RelUrl, headerparams , bodyParams,"PUT"); }else if(type.equals("codeNumberDelete")){ String ReqURL="http://api.trackingmore.com/v2/trackings"; String RelUrl = ReqURL+urlStr; result=sendGet(RelUrl, headerparams ,"DELETE"); }else if(type.equals("realtime")){ String ReqURL="http://api.trackingmore.com/v2/trackings/realtime"; bodyParams.add(requestData); result=sendPost(ReqURL, headerparams , bodyParams,"POST"); } return result; } private String sendPost(String url, Map headerParams , List bodyParams,String mothod) { OutputStreamWriter out = null; BufferedReader in = null; StringBuilder result = new StringBuilder(); try { URL realUrl = new URL(url); HttpURLConnection conn =(HttpURLConnection) realUrl.openConnection(); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod(mothod); for (Map.Entry entry : headerParams.entrySet()) { conn.setRequestProperty(entry.getKey(), entry.getValue()); } conn.connect(); out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); StringBuffer sbBody = new StringBuffer(); for (String str : bodyParams) { sbBody.append(str); } out.write(sbBody.toString()); out.flush(); 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{ try{ if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch(IOException ex){ ex.printStackTrace(); } } return result.toString(); } public static String sendGet(String url, Map headerParams,String mothod ) { String result = ""; BufferedReader in = null; try { String urlNameString = url; URL realUrl = new URL(urlNameString); HttpURLConnection connection =(HttpURLConnection) realUrl.openConnection(); connection.setRequestMethod(mothod); for (Map.Entry entry : headerParams.entrySet()) { connection.setRequestProperty(entry.getKey(), entry.getValue()); } connection.connect(); Map> map = connection.getHeaderFields(); for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } in = new BufferedReader(new InputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("Exception " + e); e.printStackTrace(); } finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } }