電商網站物流快遞單號查詢 API 介面申請案例

  • 2019 年 10 月 4 日
  • 筆記

場景需求描述

電商平台及 ISV 商家對物流 api 介面的需求有很多,今天我們主要分享的就是快遞鳥快遞單號查詢介面的對接指南,快遞單號查詢介面對接的應用場景有很多,很多場景會遇到,最主要的就是電商網站用戶打開「我的訂單」時調用此 API 顯示物流資訊詳情,電商管理後台的物流系統,客服在對賬前查詢所有運單的簽收狀態,並追蹤問題,電商平台對商家物流管控,要求必須在多久快遞必須發出要看到攬件狀態,多久必須收到貨物看到簽收狀態,根據這些狀態對商家管控從而提升用戶的整體滿意度。

對接使用流程

  1. 註冊快遞鳥帳號並申請認證
  2. 快遞鳥根據單號和快遞公司查詢到物流軌跡狀態
  3. 快遞鳥將查詢到的物流軌跡狀態回饋給電商平台或 ISV 服務商
  4. 電商平台或 ISV 服務商接收數據並實時處理做數據展示或應用

快遞鳥功能非常強大,免費,可以隨時查詢快遞軌跡,也可以推送快遞狀態,很強大很方便。直接上實現程式碼。直接上程式碼:這是開發的快遞鳥推送的快遞資訊介面,接收數據處理數據。這裡 method 一定要 post

@RequestMapping(value = "tuisong",method=RequestMethod.POST)      @ResponseBody      public Map<String,Object> tuisong(String RequestData,String RequestType,String DataSign) {           RequestData=Encodes.unescapeHtml(RequestData);           Map<String,Object> result=new HashMap<String,Object>();          //判斷是從快遞鳥進入          if(!(RequestType.equals("101") && KdniaoUtils.isFromKdniao(RequestData, DataSign))){              result.put("Success",false);              result.put("Reason","不是快遞鳥推送來的數據。");              return result;          }          JSONObject jsonObj=new JSONObject(RequestData);           result.put("EBusinessID",jsonObj.getString("EBusinessID"));           result.put("UpdateTime",jsonObj.getString("PushTime"));           try {               JSONArray jsonArray=jsonObj.getJSONArray("Data");               List<Ship> shipList=Lists.newArrayList();               Ship ship=null;               for(int i=0;i<jsonArray.length();i++){                  jsonObj=jsonArray.getJSONObject(i);                   if(!jsonObj.getBoolean("Success")){                       continue;                   }                   ship=new Ship();                   ship.setExpress(ErpUtils.getExpressByKdniao(jsonObj.getString("ShipperCode")));                   ship.setExpressNo(jsonObj.getString("LogisticCode"));                   String state=jsonObj.getString("State");                   ship.setStatus(KdniaoUtils.getShipStatus(state));                   if(ship.getStatus().equals(Ship.STATUS_SIGN)){                       JSONArray array=jsonObj.getJSONArray("Traces");                       JSONObject obj=array.getJSONObject(array.length()-1);                       String time=obj.getString("AcceptTime");                       ship.setSignTime(DateUtils.parseDate(time,"yyyy-MM-dd HH:mm:ss"));                   }                   shipList.add(ship);                }               shipService.updateStatus(shipList);               result.put("Success", true);           }catch (Exception e) {               result.put("Success", false);               result.put("Reason ", "解析數據失敗。");               e.printStackTrace();           }          return result;              
public class KdniaoUtils {      //DEMO      public static void main(String[] args) throws UnsupportedEncodingException, Exception {      }      //電商 ID      private static String EBusinessID="1283391";      //電商加密私鑰,快遞鳥提供,注意保管,不要泄漏      private static String AppKey="9df9507a-62fa-47f3-9227-bdd02b95ccf1";      //請求 url      private static String ReqURL="http://api.kdniao.cc/Ebusiness/EbusinessOrderHandle.aspx";      public static Map<String,String> StateMap=new HashMap<String,String>();      static{          StateMap.put("0", "沒有記錄");          StateMap.put("1", "已攬收");          StateMap.put("2", "運輸途中");          StateMap.put("201", "到達目的城市");          StateMap.put("3", "已簽收");          StateMap.put("4", "問題件");      }      //             物流狀態: 0-無軌跡,1-已攬收,2-在途中 201-到達派件城市,3-簽收,4-問題件      public static int getShipStatus(String state){          switch (state){             case "0":                 return Ship.STATUS_SHIPPED;             case "1":                 return Ship.STATUS_SHIPPED;             case "2":                 return Ship.STATUS_ONTHEWAY;             case "201":                 return Ship.STATUS_PAISONG;             case "3":                 return Ship.STATUS_SIGN;             case "4":                 return Ship.STATUS_DIFFICULT;              default:                  return Ship.STATUS_SHIPPED;          }      }      /**       * 快遞物流軌跡跟蹤       * @param ship       * @return       */      public static Map<String, Object> trace(Ship ship){          Map<String, Object> map = new HashMap<String, Object>();          try {              String result=getOrderTracesByJson(ship.getExpress().getKdniao(),ship.getExpressNo());              JSONObject dataJson = new JSONObject(result);              if(dataJson.getBoolean("Success")){                  map.put("errCode",0);                  String state=dataJson.getString("state");                  map.put("status",getShipStatus(state));                  map.put("statusName",StateMap.containsKey(state)?StateMap.get(state):state);                  JSONArray list = (JSONArray) dataJson.get("Traces");                  if(list!=null&&list.length()>0) {                      List<Map<String, String>> dataList = new ArrayList<Map<String, String>>();                      for (int i = 0; i < list.length(); i++) {                          JSONObject dataMapJson = (JSONObject) list.get(i);                          Map<String, String> dataMap = new HashMap<String, String>();                          dataMap.put("time", dataMapJson.getString("AcceptTime"));// 每條跟蹤資訊的時間                          dataMap.put("content", dataMapJson.getString("AcceptStation"));// 每條跟綜資訊的描述                          dataList.add(dataMap);                      }                      map.put("dataList", dataList);                  }              }else{                  map.put("errCode",1);                  map.put("errMsg", dataJson.getString("Reason"));              }          } catch (Exception e) {              map.put("errMsg","快遞介面調用出錯。");              e.printStackTrace();          }          return map;      }      /**       * 發送訂閱資訊       */      public static Map<String, Object> subscribe(Ship ship){          Map<String, Object> map = new HashMap<String, Object>();          try {              String result=orderTracesSubByJson(ship.getExpress().getKdniao(),ship.getExpressNo());              JSONObject dataJson = new JSONObject(result);              if(dataJson.getBoolean("Success")){                  map.put("success", true);              }else{                  map.put("success", false);                  map.put("errMsg", dataJson.getString("Reason"));              }          } catch (Exception e) {              map.put("errMsg","快遞介面調用出錯。");              e.printStackTrace();          }          return map;      }      /**       * Json 方式 查詢訂單物流軌跡       * @throws Exception       */      public static 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;      }      /**       * Json 方式  物流資訊訂閱       * @throws Exception       */      public static String orderTracesSubByJson(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", "1008");          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;      }      /**       * 判斷是否從快遞鳥進入的推送數據       * @param RequestData       * @param DataSign       * @return       */      public static boolean isFromKdniao(String RequestData,String DataSign){          try {              return encrypt(RequestData, AppKey, "UTF-8").equals(DataSign);          } catch (UnsupportedEncodingException e) {              e.printStackTrace();          } catch (Exception e) {              e.printStackTrace();          }          return false;      }      /**       * MD5 加密       * @param str 內容       * @param charset 編碼方式       * @throws Exception       */      @SuppressWarnings("unused")      private static 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 static String base64(String str, String charset) throws UnsupportedEncodingException{          String encoded = base64Encode(str.getBytes(charset));          return encoded;      }      @SuppressWarnings("unused")      private static 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 static 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 static 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', '+', '/' };      private 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();      }  }