物流一站式查詢之快遞100篇


連載篇提前看

物流一站式查詢之TrackingMore篇

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

物流一站式查詢之快遞100

前言

前兩篇我們已經講了TrackingMore和順豐接口的場景應用和對接示例,本篇,將會對項目中如何使用快遞100物流平台進行物流信息跟蹤的對接進行一個全面詳細的講解。同樣,我們會分為申請接入、物流信息訂閱、物流消息推送、物流消息查詢等幾個步驟分別講解。各位看官,請拿好你們的板凳和瓜子。我們要開始了,

接口申請

進入快遞100官網https://www.kuaidi100.com/ 

 在快遞接口(API)菜單中,我們可以看到接口申請這個菜單,點擊進去會有免費版和企業版兩種功能和資費介紹。

這里我們選擇企業版,點擊企業版,會要求填一些基本信息,我們按要求填完然后點擊提交申請即可。

申請之后,有客服會通過聯系方式聯系所填號碼,然后進行需求確認。這時候我們可以注冊一個快遞100的賬號

注冊完之后就可以進行登錄了,登錄之后在主頁面,就可以看到再快遞100平台中的賬戶余額情況,以及下面表格給出的可用的產品、服務等開通的狀態(具體開通流程和客服取得聯系之后他會協助你完成的),如下圖所示

開通各個接口是需要快遞100 那邊進行審核的,審核通過之后會發郵件出來,附件里面會帶有一些接口文檔,截圖如下:

其中 較為重要的是審核結果中會有一個分配好的Key密匙,請求接口的時候需要用到。所以需要妥善保管。

首先來看一下快遞100 給出的訂閱和推送的流向示意圖

 

物流訂閱

拿到接口文檔相關秘籍和查閱請求調用流程圖之后,我們便可以進行開發了,下面是物流訂閱的相關示例步驟:

2.1訂閱請求

發起方:本服務用戶,即貴公司

地址:http://www.kuaidi100.com/poll

通信協議:HTTP

請求類型:POST

字符集:utf-8

請求內容:

schema= json/xml             (或者xml,選擇json則推送也是json,選擇xml則推送也是xml,默認是json)

param=body

 

Body格式(json)

{

    "company":"yuantong",           //訂閱的快遞公司的編碼,一律用小寫字母,見章五《快遞公司編碼》

    "number":"12345678",            //訂閱的快遞單號,單號的最大長度是32個字符

    "from":"廣東省深圳市南山區",     //出發地城市

    "to":"北京市朝陽區",             //目的地城市,到達目的地后會加大監控頻率

    "key":"*********",              //授權碼,簽訂合同后發放

    "parameters":{

       "callbackurl":" http://www.您的域名.com/kuaidi?callbackid=...", //回調地址

       "salt":"any string",     //簽名用隨機字符串(可選)

"resultv2":"1"           //添加此字段表示開通行政區域解析功能(僅對開通簽收狀態服務用戶有效),見章3.1《推送請求》

    }

}

Body格式(xml)

<?xml version='1.0' encoding='UTF-8'?>

<orderRequest>

  <company>yuantong</company>       //訂閱的快遞公司的編碼,一律用小寫字母,見章五《快遞公司編碼》

  <number>123123123123</number>             //訂閱的快遞單號

  <from>北京市朝陽區東直門外大街</from>     //出發地城市

  <to>廣東省深圳市南山區科技園</to>         //目的地城市,到達目的地后會加大監控頻率

  <key>**********</key>                 //授權碼,簽訂合同后發放

  <parameters>

<callbackurl>http://www.你的域名.com/kuaidi/push?XXXXX=ZZZZ</callbackurl> //回調地址

<salt>any string</salt>            //簽名用隨機字符串(可選)

<resultv2>1</ resultv2>      //添加此字段表示開通行政區域解析功能(僅對開通簽收狀態服務用戶有效),見章3.1《推送請求》

  </parameters>

</orderRequest>

 

①根據訂閱請求文檔編寫請求方法,首先我們編寫兩個類,一個是快遞訂閱信息類,另一個是快遞100返回信息類

 /// <summary>
    /// 快遞訂閱信息
    /// </summary>
    public class KuaiDiInput
    {
        /// <summary>
        /// 快遞單號
        /// </summary>
        public string ExpressNumber;

        /// <summary>
        /// 快遞公司編號
        /// </summary>
        public string CompanyNumber;

        /// <summary>
        /// 收貨地址
        /// </summary>
        public string Address;

        /// <summary>
        /// 回調接口Url
        /// </summary>
        public string CallBackUrl;
    }
View Code
  /// <summary>
    /// 快遞100查詢公司返回信息
    /// </summary>
    public class KuaiDiOut
    {
        /// <summary>
        /// 快遞公司編碼
        /// </summary>
        public string comCode;

        /// <summary>
        /// 內部字段
        /// </summary>
        public string Id;

        /// <summary>
        /// 內部字段
        /// </summary>
        public string noCount;

        /// <summary>
        /// 內部字段
        /// </summary>
        public string noPre;

        /// <summary>
        /// 內部字段
        /// </summary>
        public string startTime;
    }
View Code

②編寫快遞100訂閱接口請求類 KuaiDi100,此類中包含的請求方法如下

/// <summary>
        /// 訂閱快遞單號
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static OperationResult Subscibe(KuaiDiInput input)
        {
            WebClient client = new WebClient();
            NameValueCollection postVars =
                new NameValueCollection();

            String param = "";
            param += "{";
            param += "\"company\":\"" + input.CompanyNumber + "\",";
            param += "\"number\":\"" + input.ExpressNumber + "\",";
            param += "\"from\":\"\",";
            param += "\"to\":\"" + TrimAddress(input.Address) + "\",";
            param += "\"key\":\"" + ConfigHelper.GetKey("SendKey") + "\",";
            param += "\"parameters\":{\"callbackurl\":\"" + input.CallBackUrl + "\"}";
            param += "}";
            postVars.Add("schema", "json");
            postVars.Add("param", param);

            byte[] byRemoteInfo = client.UploadValues("http://www.kuaidi100.com/poll", "POST", postVars);
            string output = Encoding.UTF8.GetString(byRemoteInfo).ToLower();
            if (GetValueFromJson(output, "result") != "true")
            {
                string message = GetValueFromJson(output, "message");
                if (message.IndexOf("重復訂閱") < 0)
                {
                    return new OperationResult(message);
                }
            }
            return new OperationResult();
        }
View Code

方法的返回值是自定義的一個 OperationResult類,當前框架業務操作結果 此類返回操作成功或者操作失敗,類部分內容如下:

 /// <summary>
    /// 框架業務操作結果
    /// </summary>
   public class OperationResult
    {
       /// <summary>
       /// 默認操作成功
       /// </summary>
       public OperationResult()
       {
           IsSuccess = true;
       }

       /// <summary>
       /// 以操作失敗信息實例操作結果
       /// </summary>
       /// <param name="failMessage">操作失敗信息</param>
       public OperationResult(string failMessage)
        {
            IsSuccess = false;
            FailMessage = failMessage;
        }
}
View Code

另外請求方法中的GetValueFromJson 方法是表示從Json字符串中取出某個值,再前兩篇文章中我們也提到過這個方法,這里再貼一下:

 /// <summary>
        /// 從json字符串中獲取字段值
        /// </summary>
        /// <param name="json">json字符串</param>
        /// <param name="field">要解析出值的字段</param>
        /// <returns></returns>
        private static string GetValueFromJson(string json, string field)
        {
            int start = json.IndexOf(field + "\":");
            start += field.Length + 2;
            int end = json.IndexOf(",", start);
            if (end < 0)
            {
                end = json.IndexOf("}", start);
            }
            return json.Substring(start, end - start).Trim('"');
        }
View Code

另外,請求方法中的地址我們使用了一個方法去除地址中的特殊字符,方法如下“:

/// <summary>
        /// 去除地址中的特殊字符
        /// </summary>
        /// <param name="address">地址</param>
        /// <returns></returns>
        private static string TrimAddress(string address)
        {
            if (String.IsNullOrEmpty(address))
            {
                return address;
            }
            return address.Replace("'", "").Replace("\\", "").Replace("/", "").Replace("\"", "").Replace("\n", "").Replace("\r", "").Replace("\t", "");
        }

這樣,我們請求方法就完成了,現在只剩下調用,一般項目中可以寫一個服務,定時查詢數據庫,根據一些特定條件篩選,然后進行接口調用。調用示例如下:

OperationResult result = KuaiDi100.Subscibe(new KuaiDiInput() { ExpressNumber = item.ExpressNumber, Address = item.Address, CompanyNumber = item.CompanyNumber, CallBackUrl = "此處是回調地址" });
if (result.IsSuccess)
{
  //訂閱成功,記錄一些狀態
}else
{
  //訂閱失敗,記錄一些狀態
}

訂閱返回的接口示例我們看一下

2.2訂閱返回

由快遞100直接通過訂閱請求的response返回。

返回格式(json):

{

    "result":"true",

    "returnCode":"200",

    "message":"提交成功"

}

返回格式(xml):

<?xml version='1.0' encoding='UTF-8'?>

<orderResponse>

  <result>true</result>

  <returnCode>200</returnCode>

  <message>訂閱成功</message>

</orderResponse>

 

result: "true"表示成功,false表示失敗

returnCode:

         200: 提交成功

         701: 拒絕訂閱的快遞公司

         700: 訂閱方的訂閱數據存在錯誤(如不支持的快遞公司、單號為空、單號超長等)

         600: 您不是合法的訂閱者(即授權Key出錯)

         500: 服務器錯誤(即快遞100的服務器出理間隙或臨時性異常,有時如果因為不按規范提交請求,比如快遞公司參數寫錯等,也會報此錯誤)

501:重復訂閱

訂閱成功后,我們再快遞100后台是可以看到訂閱記錄的,如下圖

 

物流推送

那推送就比較好處理了,推送即是 當物流信息有發生變化時,快遞100 就會向請求訂閱時所填的回調地址,發送此條變化的所有物流信息。推送請求示例如下(body太長了,這里就不貼出來了)

3.1推送請求

發起方:             快遞100

請求地址:        在訂閱請求中提供(即回調servlet的互聯網地址)

通信協議:        HTTP

請求類型:        POST

字符集:             utf-8

請求內容:       param=body或者param=body&sign=signvalue

 

 查看了推送請求之后,我們根據快遞100的推送請求,我們先寫出相關的返回結果模型ModPushRequest

/// <summary>
    /// 快遞100傳回快遞結果模型
    /// </summary>
    public class ModPushRequest
    {
        /// <summary>
        /// 監控狀態相關消息,如:3天查詢無記錄,60天無變化
        /// </summary>
        public string message { set; get; }

        /// <summary>
        /// 包括got、sending、check三個狀態,由於意義不大,已棄用,請忽略
        /// </summary>
        public string billstatus { set; get; }

        /// <summary>
        /// 監控狀態:polling:監控中,shutdown:結束,abort:中止,updateall:重新推送。
        /// 其中當快遞單為已簽收時status=shutdown,當message為“3天查詢無記錄”或“60天無變化時”status= abort ,對於stuatus=abort的狀度,需要增加額外的處理邏輯,詳見本節最后的說明
        /// </summary>
        public string status { set; get; }

        /// <summary>
        /// 最新查詢結果,全量,倒序(即時間最新的在最前)
        /// </summary>
        public ModLastResult lastResult { set; get; }
    }
View Code

其中 ModLastResult是 快遞100傳回快遞狀態模型如下

/// <summary>
    /// 快遞100傳回快遞狀態模型
    /// </summary>
    public class ModLastResult
    {
        /// <summary>
        /// 消息體,請忽略
        /// </summary>
        public string message { set; get; }

        /// <summary>
        /// 快遞單當前簽收狀態,包括0在途中、1已攬收、2疑難、3已簽收、4退簽、5同城派送中、6退回、7轉單等7個狀態
        /// </summary>
        public string state { set; get; }

        /// <summary>
        /// 快遞單明細狀態標記,暫未實現,請忽略
        /// </summary>
        public string condition { set; get; }

        /// <summary>
        /// 否簽收標記,明細狀態請參考state字段
        /// </summary>
        public string ischeck { set; get; }

        /// <summary>
        /// 快遞公司編碼,一律用小寫字母
        /// </summary>
        public string com { set; get; }

        /// <summary>
        /// 快遞單號
        /// </summary>
        public string nu { set; get; }

        /// <summary>
        /// 通訊狀態,請忽略
        /// </summary>
        public string status { set; get; }

        /// <summary>
        /// 快遞物流信息,時間到序
        /// </summary>
        public List<ModData> data { set; get; } 
    }
View Code

其中 ModData 是物流信息 如下

    /// <summary>
    /// 快遞100傳回快遞記錄模型
    /// </summary>
    public class ModData
    {
        /// <summary>
        /// 快遞物流內容
        /// </summary>
        public string context { set; get; }

        /// <summary>
        /// 快遞原始時間
        /// </summary>
        public string time { set; get; }

        /// <summary>
        /// 快遞格式化時間
        /// </summary>
        public string ftime { set; get; }
    }

有了推送模型,那此時我們要做的就是接收快遞100的請求數據即可,代碼如下:

        /// <summary>
        /// 更新訂單快遞信息
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        public ActionResult UpdateMessage(FormCollection form)
        {
            try
            {
                string json = form.Get("param");
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                //將Json字符串轉換為ModPushRequest類型對象
                ModPushRequest pustRequest = serializer.Deserialize<ModPushRequest>(json);
         //TODO
       }
       catch{}
      }

以上我們就將收到的數據成功轉換成了我們的模型數據,剩下的就是具體業務需求了,這個可以根據實際項目情況,做不同的處理。例如:TODO可以 先拿到返回的快遞單號

string number = pustRequest.lastResult.nu;

然后可以去查詢數據庫中找到此單號的訂單信息。再循環物流信息

 string senderMessage = "";
 string lastMessage = "";
 foreach (ModData item in pustRequest.lastResult.data)
  {
    //所有物流信息
    senderMessage += item.ftime + "   " + item.context + "<br/>";
  }
   if (pustRequest.lastResult.data.Count > 0)
   {
       //最近一條物流信息
       lastMessage = pustRequest.lastResult.data[0].ftime + "   " +
                     pustRequest.lastResult.data[0].context;
   }

然后可以再根據不同的物流返回狀態做不同的操作

 // 快遞單當前簽收狀態,包括0在途中、1已攬收、2疑難、3已簽收、4退簽、5同城派送中、6退回、7轉單等7個狀態
if (pustRequest.lastResult.state == "3")
{
    //TODO   
}
else if (pustRequest.lastResult.state == "4" || pustRequest.lastResult.state == "6")
{
   //TODO
}

溫馨提示,設計訂單表的時候,可以多加三個字段,一個字段是訂閱時間,一個是物流平台推送回來的時候推送時間,再一個是物流平台推送過來時的推送狀態。可以記錄用於后面物流數據分析。

 物流消息查詢

 

5、整體使用流程:

第一步,后台創建鏈接,調用:http://www.kuaidi100.com/applyurl?key=[]&com=[]&nu=[] ,調用后系統會返回一個url地址,如:http://www.kuaidi100.com/kuaidiresult?id=23

第二步:在要顯示結果的頁面添加一個iframe標簽,將上述結果url地址傳入該iframe標簽的的src值,即可在該頁面查看到結果(如果要實現系統自動地將結果url傳入iframe標簽的src,請參考下面第五章),iframe代碼示范:

<iframe name="kuaidi100" src="結果url地址" width="600" height="380" marginwidth="0" marginheight="0" hspace="0" vspace="0" frameborder="0" scrolling="no"></iframe>

 使用場景,項目中的訂單,我們一定不是每次都直接去調接口查詢,那樣太慢,效率也不高,只有部分,數據表中物流信息沒有且平台訂單不為空的時候,查詢物流信息時,我們需要去實時調用查詢接口,將數據返回出來。根據整體使用流程介紹,我們很容知道,是通過返回html綁定再iframe上實現的。實現如下:

前台頁面(傳入快遞公司對應的公司編碼和物流單號)

  ajaxGetContent("@Url.Action("ViewExpress")" + "?companyNumber=" + company + "&expressNumber=" + number, function (data) {
                var d = dialog({
                    title: '物流最新跟蹤',
                    content: data,
                    okValue: '確定',
                    ok: true,
                });
                d.show(obj);
            });

Action

 public ActionResult ViewExpress(string expressNumber, string companyNumber)
 {
            #region 快遞100 獲取方式
            string url = "http://www.kuaidi100.com/applyurl?key=我是key&com=" + companyNumber + "&nu=" +
                         expressNumber;
            //初始化獲取HTML動作
            GetHtmlFromUrl getHtml = new GetHtmlFromUrl(url);
            //獲取請求的url中html字符串
            getHtml.StartWork();
            //數據綁定
            ViewData.Model = getHtml.ResultHtml;
            #endregion
}

其中初始化html方法如下:

    /// <summary>
        /// 初始化一個獲取html動作
        /// </summary>
        /// <param name="requestUrl">要請求的url地址</param>
        public GetHtmlFromUrl(string requestUrl)
        {
            ArgumentChecker.ThrowExceptionWhenStringIsNullOrEmpty(requestUrl, "requestUrl");

            if (requestUrl.IndexOf("//") < 0)
            {
                requestUrl = "http://" + requestUrl;
            }
            RequestUrl = requestUrl;
        }    

獲取請求url地址的html字符串方法如下:

 /// <summary>
        /// 開始獲取請求url地址的html字符串
        /// </summary>
        public void StartWork()
        {            
            WebRequest request = WebRequest.Create(RequestUrl);
            using (WebResponse response = request.GetResponse())
            {
                using (Stream stream = response.GetResponseStream())
                {
                    using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.GetEncoding("UTF-8")))
                    {
                        ResultHtml = reader.ReadToEnd();
                    }
                }
            }
        }

返回的ViewExpress視圖如下

@model string
    <iframe name="kuaidi100" src="@Model" width="600" height="380" marginwidth="0" marginheight="0" hspace="0" vspace="0" frameborder="0" scrolling="no"></iframe>

這樣我們就按照文檔中所說的將返回html呈現出來了

返回結果說明:

提交請求后,快遞100會給您返回一個可以看到結果的url地址,如:http://www.kuaidi100.com/kuaidiresult?id=23 ,您直接訪問或用iframe頁調用該url(調用方法見后面第四章),即可以看到結果。效果:

 

 

特別提醒:

因為EMS、順豐和申通偶爾會不穩定, 不穩定時會先顯示驗證碼 (如下圖所示),所以請勿直接將這個頁面直接解析成JSON等形式,否則會出錯

 

 至此,我們在通過快遞100平台 完成了快遞訂閱、接收了快遞消息的推送以及我們自主通過快遞100接口查詢最新的物流信息。

 

到這里,三篇關於快遞接口的文章已經全部結束,文中給出的只是根據官方文檔要求,編寫的部分代碼,可能不盡完善,能夠優化的地方還有很多,大家能借鑒的地方借鑒一下就好~

 

     End!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM