【分享】電商網站快速對接物流快遞鳥單號查詢 API 介面申請案例
1.快遞查詢API介面
對於現在的網上購物,“我買的東西發到哪了?”這是每個買家越來越關心的問題,“我商城的物流資訊跟蹤服務客戶的體驗效果還滿意嗎?”這是每個賣家越來越操心的問題,因為在現代社會中,人們不僅僅在乎商品本身的價值,而且在乎甚至更在乎服務的價值體現!
而目前快遞查詢API的模式有兩種,一種是即時查詢,也就是說發出請求就會返回資料;另一種是訂閱查詢, 當所訂閱的快遞單號有物流資訊的跟新時就會返回資料,不需要發出請求。目前在國內快遞查詢API介面做得好的有快遞鳥、菜鳥等。
今天我們主要分享的就是快遞鳥快遞單號查詢介面的對接指南,快遞單號查詢介面對接的應用場景有很多,很多場景會遇到,最主要的就是電商網站使用者開啟“我的訂單”時呼叫此 API 顯示物流資訊詳情,電商管理後臺的物流系統,客服在對賬前查詢所有運單的簽收狀態,並追蹤問題,電商平臺對商家物流管控,要求必須在多久快遞必須發出要看到攬件狀態,多久必須收到貨物看到簽收狀態,根據這些狀態對商家管控從而提升使用者的整體滿意度。
對接使用流程
-
註冊快遞鳥賬號並申請認證
-
快遞鳥根據單號和快遞公司查詢到物流軌跡狀態
-
快遞鳥將查詢到的物流軌跡狀態反饋給電商平臺或 ISV 服務商
-
電商平臺或 ISV 服務商接收資料並實時處理做資料展示或應用
快遞鳥功能非常強大,免費,可以隨時查詢快遞軌跡,也可以推送快遞狀態,很強大很方便。直接上實現程式碼。直接上程式碼:這是開發的快遞鳥推送的快遞資訊介面,接收資料處理資料。這裡 method 一定要 post
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 |
@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; |
這裡是個工具類,提供靜態方法。KdniaoUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 |
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=
"
;
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();
} }
|
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945342/viewspace-2666558/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 常用快遞單號物流查詢介面通用API(JAVA快遞鳥對接)APIJava
- 快遞鳥物流單號查詢API的的用途和對接分析案例API
- 快遞鳥物流單號識別查詢API介面的的用途和對接分析案例API
- 免費常用快遞單號物流通用API查詢介面(JAVA快遞鳥對接)APIJava
- 常用快遞單號查詢api介面對接案例(快遞鳥api)API
- 物流快遞單號查詢介面種類及快遞鳥對接方法
- 順豐快遞單號查詢API介面demo免費對接【快遞鳥API】API
- 快遞鳥api介面實現訂閱物流軌跡單號查詢功能對接呼叫API
- 物流快遞單號查詢介面種類及對接方法
- 快遞物流單號識別查詢api介面呼叫對接demo使用方法API
- 第三方物流快遞單號查詢跟蹤api介面對接API
- 物流一站式單號查詢之快遞鳥API介面(附Demo原始碼)API原始碼
- 基於快遞鳥的快遞物流查詢介面
- 關於物流公司呼叫快遞單號查詢API介面的示例API
- 從申請到呼叫:全國快遞物流查詢 API 使用教程API
- PHP 快遞查詢介面,快遞鳥物流查詢 API 的二次封裝. 輕輕鬆鬆呼叫它PHPAPI封裝
- 實現快遞單號物流資訊介面APIAPI
- 快寶物流查詢API介面API
- 快遞物流查詢介面通用demo
- 快遞物流查詢API有什麼作用?API
- 快遞物流查詢類API介面推薦,含跨境物流、物流軌跡地圖等API地圖
- 快遞鳥查詢訂單例項單例
- .netcore 寫快遞100的快遞物流資訊查詢介面NetCore
- 快遞查詢 API 介面:讓物流資訊一目瞭然API
- 新增發快遞上門取件的介面-快遞鳥預約上門取件API對接API
- 線上分享批次查詢快遞物流的工具
- 案例:模擬京東快遞單號的查詢效果
- springBoot + 工廠模式 實現 快遞鳥、順豐和快遞100的物流查詢Spring Boot模式
- 全自動多介面快遞查詢工具 批量查詢中通、圓通等快遞物流資訊
- 線上查詢物流詳情,支援極兔、申通、順豐等快遞批量查詢
- 全國快遞物流 API 實現快遞單號自動識別的原理解析API
- 對接快遞100&聚水潭APIAPI
- 全國快遞物流查詢API,毫秒級響應、超高及時性API
- 想要批次查詢快遞,怎麼操作可以一鍵快速查詢物流資訊
- 快遞的旅行日記 - 深度挖掘快遞物流地圖軌跡查詢API 的使用場景地圖API
- 自動查詢並分析快遞的物流狀態
- 怎麼使用電腦查詢快遞物流資訊,極兔有什麼平臺支援查詢
- 電商小白該選擇怎樣的快遞查詢工具?