物流一站式單號查詢之快遞鳥API接口(附Demo源碼)

連載篇提前看

物流一站式單號查詢之快遞鳥API接口

物流一站式查詢之TrackingMore篇

物流一站式查詢之順豐接口篇

物流一站式查詢之快遞100

前情提要

     前三篇中,我們已經從註冊、申請接口、調用接口、聯調開發、部署上線等一系列角度對比過幾家不同的物流平台,今天我們再來瞧一瞧快遞鳥這個物流平台,我們會今天從

全流程的快速梳理一遍,另外,我還會就在我對接API過程中,遇到的一些常見問題特別備註一下,希望給後面用到的朋友有個參考幫助~

     閱讀完本篇內容,你可以利用快遞鳥平台做出如下項目(文末有源碼地址),當然,如果你覺得看圖不過癮,那就勞駕看官自己體驗一下:點我在線體驗

註冊認證賬號

 1.進入快遞鳥官網 ,點擊右上角免費註冊按鈕,點我直接去官網

 

2.註冊賬號

3.註冊成功後,會自動跳轉到後台,可以看到首頁面板中 個人信息部分,有未認證提示,可按需進行認證

 

申請服務

1.申請服務這塊也是在首頁控制面板中,產品服務區域查看,可點擊立即開通,進入服務詳情頁,按需開通即可

 

2.開通後的服務,可在左側菜單《我的產品服務》中查看到

 

 3.點進具體的服務詳情,可以看到服務訂單使用量情況,30天使用趨勢圖,以及可以設置餘量提醒等等

技術對接

官網API

1.點擊官網API接口菜單,進入快遞鳥API詳情介紹頁

2.我們可以看到API大致分為三大類:下單類接口、查詢類接口、增值類接口

 

3.以即時查詢為例,點擊即時查詢API後,我們可以看到右側有對此接口的描述、應用場景介紹、功能說明、使用流程、API參數、接入流程以及Demo下載 。(等不及了的小夥伴 可以直接去看Demo)

 

 4.我們看到功能說明中,此接口可以免費500/日對外開放

 

5.在API參數那塊要注意,每個不同的請求,都對應一個接口指令,這個指令不能錯

另外,在快遞鳥公司官網的接口文檔菜單中,我們可以看到為我們提供了以下文檔信息

 其中,建議如果有小夥伴要接入快遞鳥,可以優先着重查看下接口說明文檔,裏面對請求報文、數據傳輸格式,請求參數以及返回字段等都有詳細的描述說明。

我們先來看看報文的規範如下:

報文及報文編碼

報文格式: Json 格式
請求方法的編碼格式(utf-8): “application/x-www-form-urlencoded;charset=utf-8”
交互協議上統一用 UTF-8, 避免傳遞中文數據出現亂碼。

接口數據包結構

 

 

 Json示例

string used = "1237100";//僅作為示例ID, 不可用來實際使用
//加密私鑰, 由快遞鳥提供
string keyValue = "56da2cf8-c8a2-44b2-b6fa-476cd7d1ba17";//僅作為示例Key, 不可用來實際使用
//請求地址
string url = "//api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";
//2-json
string DataType = "2";
//字符編碼採用UTF-8
string charset = "UTF-8";
//JSON字符串string
string jsonStr ="{\"OrderCode\":\"\",\"ShipperCode\":\"SF\",\"LogisticCode\":\"118461988807\"}";
//把(jsonStr+APIKey)進行MD5加密, 然後Base64編碼, 最後 進行URL(utf-8)編碼 datasign = HttpUtility.UrlEncode(base64(MD5(jsonStr + keyValue, "UTF-8"),"UTF-8"), Encoding.UTF8); //請求報文參數 string PostStr = "RequestType=1002&EBusinessID= used &RequestData=jsonStr&DataSign= datasign&DataType=DataType"; //通訊協議使用Https協議Post請求方式 string post = this.DoPost(url, PostStr);

系統及參數

 

 簽名說明

快遞鳥和第三方電子商務公司系統進行對接, 有一定的安全機制。 採用 IP 認證加簽名的方式對接,具體方案如下:
1.防止數據被篡改

在 POST 請求中會傳遞 個必須(R)參數 

RequestData==數據內容(URL 編碼:UTF-8)
EBusinessID==用戶 ID
RequestType=請求指令類型
DataSign== 數據內容簽名: 把(請求內容(未編碼)+ApiKey)進行 MD5 加密, 然後 Base64
編碼, 最後進行 URL(utf-8)編碼
DataType==2(返回數據類型為 json)

 

註:
DataSign 生成後, 對方接收到數據後, 以同樣的算法進行簽名(推送接口 RequestType 
101/102 不需要進行 URL 編碼), 生成摘要, 對比兩者的摘要是否相同, 如果不同, 說明傳
遞過程中發生數據篡改。 

 2.調用接口的身份認證

註冊成為快遞鳥用戶後, 會生成對應的用戶 ID 和 APIKey, 用戶 ID 相當於用戶名,APIKey相當於密碼。

假設

RequestData (JSON)內容為:
{'OrderCode':'','ShipperCode':'SF','LogisticCode':'118954907573'}
經過 URL(UTF-8)編碼的內容為:
%7b%27OrderCode%27%3a%27%27%2c%27ShipperCode%27%3a%27SF%27%2c%2
7LogisticCode%27%3a%27118954907573%27%7d;
EBusinessID=1237100【示例 ID, 不可用來實際使用】
APIKey=56da2cf8-c8a2-44b2-b6fa-476cd7d1ba17【示例 Key, 不可用來實際使用】

那麼DataSign簽名的內容為

{'OrderCode':'','ShipperCode':'SF','LogisticCode':'118954907573'}56da2cf8-c8a2-44b2-b6
fa-476cd7d1ba17
經過 md5 和 base64 後的內容就為:
OWFhM2I5N2ViM2U2MGRkMjc4YzU2NmVlZWI3ZDk0MmE=,
在經過 URL(UTF-8)編碼的內容為:
OWFhM2I5N2ViM2U2MGRkMjc4YzU2NmVlZWI3ZDk0MmE%3d
最終要發送的數據為:
RequestType=1002&EBusinessID=1237100&RequestData
=%7b%27OrderCode%27%3a%27%27%2c%27ShipperCode%27%3a%27SF%27%2c%
27LogisticCode%27%3a%27118954907573%27%7d&DataSign
=OWFhM2I5N2ViM2U2MGRkMjc4YzU2NmVlZWI3ZDk0MmE%3d&DataType=2

接收方收到數據後,獲得EBusinessID 和 RequestData 和 DataSign 等這幾個數據。 接收方對 EBusinessID 得到 APIKey, RequestData+APIKey 的數據進行md5 和 base64 後的內容就為 

OWFhM2I5N2ViM2U2MGRkMjc4YzU2NmVlZWI3ZDk0MmE= 
接收方判斷簽名後的數據跟傳遞過來的 DataSign 是否一致, 如果一致進行業務操作, 如果不一致返回錯誤。

C#版電商Sign簽名範例:

View Code 

代碼實現

 好了,有了以上的接口基礎,我們可以開始直接擼碼了,我們這裡環境使用到的是.NET Core 3.1版本。我們先以自動識別快遞單號接口為例,可實現如下效果。

當我們輸入申通快遞單號時,左側快遞公司下拉框會自動識別到當前快遞公司為申通,中通亦是如此。

那如何實現呢,我們話不多說,開整(默認看到這裡的小夥伴 有編程基礎,有建基礎項目的能力,跳過基礎步驟)。

根據接口描述:該接口僅對運單號做出識別,識別可能屬於的一家或多家快遞公司。

我們定義出如下Model,僅供參考

public class RecognitionModel
    {
        /// <summary>
        /// 用戶Id
        /// </summary>
        public string EBusinessID { get; set; }

        /// <summary>
        /// 物流單號
        /// </summary>
        public string LogisticCode { get; set; }

        /// <summary>
        /// 成功與否
        /// </summary>
        public bool Success { get; set; }

        /// <summary>
        /// 失敗原因
        /// </summary>
        public string Code { get; set; }

        /// <summary>
        /// 快遞公司
        /// </summary>
        public List<_Shipper> Shippers { get; set; }
    }

    public class _Shipper
    {
        public string ShipperCode { get; set; }

        public string ShipperName { get; set; }
    }

我們需要一個服務,來實現我們根據運單號獲取一個或多個快遞公司的功能,推薦使用異步編程

public async Task<RecognitionModel> getExpressCompany(string expressNumber)
{
   string requestData = "{'LogisticCode':'"+expressNumber+"'}";
   var result= await BaseAction(requestData, ((int)QueryType.ExpressRecognition).ToString());
   return result == null ? new RecognitionModel() : JsonConvert.DeserializeObject<RecognitionModel>(result);
}

其中,BaseAction用於所有的基礎請求,我們需要傳入請求數據和請求接口類型即可

    public async Task<string> BaseAction(string requestData,string type)
        {
            return await Task.Run(() =>
            {
                Dictionary<string, string> param = new Dictionary<string, string>
                {
                    {"RequestData", HttpUtility.UrlEncode(requestData, Encoding.UTF8)},
                    {"EBusinessID", expressConfig.BusinessID},
                    {"RequestType", type}
                };
                string dataSign = Encryption.encrypt(requestData, expressConfig.AppKey, "UTF-8");
                param.Add("DataSign", HttpUtility.UrlEncode(dataSign, Encoding.UTF8));
                param.Add("DataType", "2");
                string result = HttpHelper.sendPost(apiConfig.Logistics_Trajectory_API, param);
                return result;
            });
        }

上述代碼中Encryption類為自定義類,類中包含了Sign簽名方法、字符串MD5加密方法以及對內容的Base64編碼,該類如下:

View Code

 這樣,我們的代碼就寫的差不多了,我們來調試看看究竟能否獲取成功:

 從圖中可以看出,最終result 返回了正確的識別結果,這樣,我們的自動識別api到這裡算已經對接成功了,下面我們再來看一看即時查詢API對接上有何不同。

同樣的,我們需要定義一個服務來實現獲取物流軌跡的功能,看接口文檔描述,我們需要傳入快遞公司編碼和快遞單號,我們從支持的公司編碼表中看到

 常見的快遞物流公司編碼格式都在此。那我們的服務 就可以很快定義出來了,如下:

public async Task<string> getOrderTracesByJson(string expressNumber, string expressCode,string sfNumber, QueryType queryType = QueryType.MonitorQuery)
        {
            var type = typeof(QueryType).GetEnmList().FirstOrDefault(m => m.Name == queryType.GetEnmName())?.Value;
            return await Task.Run(async () =>
            {
                string requestData = expressCode != "SF"
                    ? "{'OrderCode':'','ShipperCode':'" + expressCode + "','LogisticCode':'" + expressNumber + "'}"
                    : "{'OrderCode':'','ShipperCode':'" + expressCode + "','LogisticCode':'" + expressNumber +
                      "','CustomerName':'" + sfNumber + "'}";
                
                var result = await BaseAction(requestData,type);
                return result;
            });
        }

註:上述對expressCode有個判斷,是否為順豐,若為順豐,按照快遞鳥接口文檔所述,需要另外多傳入一個CustomerName的參數,參數內容為收件人/寄件人手機號尾數後四位。

 我們只需要寫一個獲取方法,復用我們的BaseAction即可,我們來調試看看獲取情況:

最終,我們再返回的result中看到了返回的物流信息。這樣,我們就得到了自己所需要的數據,

ps:除了國內常見的快遞公司,快遞鳥還支持國內外眾多快遞公司,具體詳情可以查看快遞公司編碼表

 

聯調測試

在開發過程中,需要不斷對服務中的代碼進行測試,嘗嘗要判斷一些不同的情況,比如:快遞單號錯誤、快遞公司選擇錯誤等等諸如此類的問題

 

常見問題

 這裡列舉的常見問題,一部分是我在對接過程中遇到的,如果大家在對接過程中,也有此類問題,可以參考參考。

1.關於順豐查詢輸入手機尾號的問題,若某一單號此前沒有查詢過物流信息,輸入錯誤手機尾號,將不會返回任何物流信息,若此前查詢過,輸入錯誤的手機尾號,返回的將是緩存數據,看圖說話

 

註:上圖中進行了三次查詢,第一次輸入順豐單號,用0000手機尾號(錯誤的號碼)查詢,結果為暫無物流顯示,第二次採用正確的7517手機尾號查詢,結果返回正確的物流數據,第三次採用9999(錯誤的號碼)查詢,結果返回的是緩存第一次查詢後的物流數據(不會更新)

2、快遞編碼表中的順豐速運和中通快遞,在快遞單號識別API中 返回的名字是不一致的

 3.免費接口僅支持四家主流快遞的查詢(申通、圓通、百世、天天),不支持其他主流快遞查詢。

項目源碼

git源碼下載: //github.com/XiaoYong666/KdAPI_Demo

在線演示://kdn.fuyue.xyz/

小結

今天通過快遞單號自動識別接口和即時查詢接口快速的熟悉了一遍快遞鳥平台接口對接方式 和一些注意點。通過快遞鳥官網API接口和接口文檔我們可以看到,此平台接口內容比較詳細,給出的介入案例也豐富多樣,有C#、Java、PHP等多語言版本。同時還有QQ技術支持群和VIP專屬對接專員,感覺還是比較貼心省事的,諮詢問題 響應也是比較及時。整個流程下來 還是比較輕鬆的。希望通過這篇文章給需要對接物流的小夥伴帶來一些幫助,如果有問題,歡迎私信或加我QQ~

      全文完!