"customer_id": "STOtest001", // 客戶編碼
"order_id": "ORD202306300001", // 客戶訂單號(hào)(唯一)
"sender": {
"name": "張三",
"mobile": "13800138000",
"province": "浙江省",
"city": "杭州市",
"district": "濱江區(qū)",
"address": "網(wǎng)商路699號(hào)"
},
"receiver": {
"name": "李四",
"mobile": "13900139000",
"province": "廣東省",
"city": "深圳市",
"district": "南山區(qū)",
"address": "科技園科技中一路"
},
"cargo": {
"name": "手機(jī)配件",
"weight": "0.5", // 公斤
"volume": "", // 可選
"count": "1"
},
"service_type": "標(biāo)準(zhǔn)快遞", // 服務(wù)類型
"pay_type": "SHIPPER", // 付款方式: SHIPPER(寄付) / CONSIGNEE(到付)
"need_tracking_info": "1" // 是否需要在響應(yīng)中返回面單HTML
}

簽名生成Python示例:

import hashlib
import urllib.parse
import json

def generate_sto_sign(params, secret_key):
# 1. 過(guò)濾系統(tǒng)參數(shù)(如sign, method等)和空值參數(shù)
filtered_params = {k: v for k, v in params.items() if v is not None and v != '' and not k.startswith('stc_')}
# 2. 按參數(shù)名ASCII碼升序排序
sorted_keys = sorted(filtered_params.keys())
# 3. 拼接鍵值對(duì)
query_string = ''
for key in sorted_keys:
value = str(filtered_params[key])
# 關(guān)鍵:對(duì)鍵和值進(jìn)行URL編碼(注意申通通常要求使用RFC 3986編碼)
encoded_key = urllib.parse.quote(key, safe='')
encoded_value = urllib.parse.quote(value, safe='')
query_string += f"{encoded_key}{encoded_value}"
# 4. 拼接密鑰
sign_string = secret_key + query_string + secret_key
# 5. MD5計(jì)算并轉(zhuǎn)為大寫
md5 = hashlib.md5()
md5.update(sign_string.encode('utf-8'))
return md5.hexdigest().upper()

# 示例參數(shù)
params = {
"method": "stc.order.waybill.apply",
"customer_id": "STOtest001",
"order_id": "ORD202306300001",
"timestamp": "20230630120000",
# ... 其他業(yè)務(wù)參數(shù)
}
secret_key = "YourSecretKey123456"

sign = generate_sto_sign(params, secret_key)
params['sign'] = sign # 將簽名加入請(qǐng)求參數(shù)

Node.js 請(qǐng)求示例:

const axios = require('axios');
const crypto = require('crypto');
const qs = require('querystring');

async function createSTOWaybill() {
const baseUrl = 'https://gateway.sto.cn/router/rest';
const customerId = 'STOtest001';
const secretKey = 'YourSecretKey123456';
const method = 'stc.order.waybill.apply';

// 1. 構(gòu)建業(yè)務(wù)參數(shù)
const businessParams = {
order_id: ORDER_${Date.now()}, sender: JSON.stringify({ name: "發(fā)貨人", mobile: "13800000000", province: "上海", city: "上海市", district: "浦東新區(qū)", address: "張江高科技園區(qū)" }), receiver: JSON.stringify({ name: "收貨人", mobile: "13900000000", province: "浙江", city: "杭州市", district: "余杭區(qū)", address: "阿里巴巴西溪園區(qū)" }), cargo: JSON.stringify({ name: "電子產(chǎn)品", weight: "1.2", count: "1" }), service_type: "標(biāo)準(zhǔn)快遞", pay_type: "SHIPPER", need_tracking_info: "1" }; // 2. 構(gòu)建系統(tǒng)參數(shù) const systemParams = { method: method, customer_id: customerId, timestamp: new Date().toISOString().replace(/[-:T.]/g, '').slice(0, 14), // YYYYMMDDHHmmss format: 'json', v: '1.0' }; // 3. 合并參數(shù)并生成簽名 const allParams = {...systemParams, ...businessParams}; const sign = generateStoSign(allParams, secretKey); allParams.sign = sign; // 4. 發(fā)送請(qǐng)求 try { const response = await axios.post(baseUrl, qs.stringify(allParams), { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }); console.log('運(yùn)單創(chuàng)建成功:', response.data); return response.data; } catch (error) { console.error('運(yùn)單創(chuàng)建失敗:', error.response?.data || error.message); throw error; } } function generateStoSign(params, secretKey) { // 過(guò)濾并排序參數(shù) const filtered = Object.keys(params) .filter(key => params[key] !== null && params[key] !== undefined && params[key] !== '') .sort() .map(key => ${encodeRFC3986(key)}=${encodeRFC3986(params[key])}); const stringToSign = filtered.join('&'); const signString = ${secretKey}${stringToSign}${secretKey}; return crypto.createHash('md5') .update(signString, 'utf8') .digest('hex') .toUpperCase(); } function encodeRFC3986(str) { return encodeURIComponent(str) .replace(/%20/g, '+') .replace(/[!'()*]/g, c => %${c.charCodeAt(0).toString(16).toUpperCase()}); } // 執(zhí)行運(yùn)單創(chuàng)建 createSTOWaybill();

3. 物流軌跡實(shí)時(shí)查詢

核心接口: stc.trace.query
作用: 根據(jù)運(yùn)單號(hào)查詢包裹的實(shí)時(shí)物流狀態(tài)和運(yùn)輸歷史軌跡。

關(guān)鍵請(qǐng)求參數(shù):

{
"customer_id": "STOtest001",
"tracking_number": "773123456789" // 申通運(yùn)單號(hào)
}

響應(yīng)數(shù)據(jù)結(jié)構(gòu)示例:

{
"success": true,
"data": {
"tracking_number": "773123456789",
"order_id": "ORD202306300001",
"latest_status": "派送中",
"latest_time": "2023-06-30 14:30:00",
"traces": [
{
"time": "2023-06-30 14:30:00",
"description": "【杭州濱江公司】的派件員【王師傅 138****1234】正在派件",
"location": "杭州濱江公司"
},
{
"time": "2023-06-30 09:15:00",
"description": "快件已到達(dá)【杭州轉(zhuǎn)運(yùn)中心】",
"location": "杭州轉(zhuǎn)運(yùn)中心"
},
{
"time": "2023-06-29 20:45:00",
"description": "快件已從【深圳南山網(wǎng)點(diǎn)】發(fā)出,下一站【杭州轉(zhuǎn)運(yùn)中心】",
"location": "深圳南山網(wǎng)點(diǎn)"
},
{
"time": "2023-06-29 18:20:00",
"description": "【深圳南山網(wǎng)點(diǎn)】已收件",
"location": "深圳南山網(wǎng)點(diǎn)"
}
]
}
}

4. 網(wǎng)點(diǎn)/服務(wù)查詢

接口示例:

5. 路由訂閱(Webhook)

核心機(jī)制: 并非單一接口,而是一種推送模式。
作用: 開(kāi)發(fā)者需要在申通平臺(tái)配置回調(diào)URL。當(dāng)運(yùn)單狀態(tài)發(fā)生重要變更時(shí),申通服務(wù)器會(huì)主動(dòng)向該URL推送最新的物流事件信息。比輪詢更實(shí)時(shí)高效。

推送數(shù)據(jù)示例:

POST /your/callback/url HTTP/1.1
Content-Type: application/json

{
"event": "TRACE_UPDATE", // 事件類型
"tracking_number": "773123456789",
"current_status": "SIGNED", // 最新?tīng)顟B(tài)碼 (簽收)
"current_description": "已簽收,簽收人:前臺(tái)",
"current_time": "2023-06-30 16:05:00",
"signature": "...", // 用于驗(yàn)證推送來(lái)源合法性的簽名
"timestamp": "20230630160500"
}

處理注意事項(xiàng):

四、高級(jí)應(yīng)用與最佳實(shí)踐

1. 面單模板定制

2. 錯(cuò)誤處理與重試機(jī)制

3. 性能優(yōu)化

4. 安全規(guī)范

五、典型應(yīng)用場(chǎng)景

  1. 電商平臺(tái):
  1. ERP/WMS系統(tǒng):
  1. 跨境電商SaaS:
  1. 線下門店/微商:

六、挑戰(zhàn)與注意事項(xiàng)

  1. 文檔與規(guī)范: 快遞公司的API文檔質(zhì)量可能參差不齊,更新也可能滯后。遇到問(wèn)題時(shí),積極聯(lián)系技術(shù)支持或查閱社區(qū)經(jīng)驗(yàn)至關(guān)重要。
  2. 網(wǎng)絡(luò)穩(wěn)定性: 快遞公司數(shù)據(jù)中心的網(wǎng)絡(luò)穩(wěn)定性可能不如大型云廠商,需要做好調(diào)用失敗和重試的準(zhǔn)備。建議設(shè)置合理的超時(shí)時(shí)間(如連接超時(shí)3s,讀超時(shí)10s)
  3. 字段兼容性: 不同快遞公司的接口字段命名、格式要求(如地址分級(jí)、電話號(hào)碼格式)可能不同。在對(duì)接多家快遞時(shí),設(shè)計(jì)良好的適配層(Adapter)是關(guān)鍵。
  4. 測(cè)試沙箱: 充分利用測(cè)試環(huán)境進(jìn)行充分的功能、性能和異常測(cè)試。測(cè)試環(huán)境的業(yè)務(wù)規(guī)則(如地址校驗(yàn)、下單限制)可能與生產(chǎn)環(huán)境略有差異。
  5. 簽約與費(fèi)率: API接入通常需要與申通簽署正式合作協(xié)議,明確結(jié)算方式(月結(jié)/預(yù)付)和運(yùn)費(fèi)費(fèi)率。技術(shù)對(duì)接完成不代表可以立即發(fā)業(yè)務(wù)件。
  6. 合規(guī)性: 確保用戶隱私數(shù)據(jù)(收寄件人信息)的收集、傳輸、存儲(chǔ)和使用符合《個(gè)人信息保護(hù)法》等相關(guān)法規(guī)要求。

七、總結(jié)

申通快遞API為開(kāi)發(fā)者打開(kāi)了將專業(yè)物流能力快速集成到各類應(yīng)用系統(tǒng)的大門。從自動(dòng)化下單打單,到實(shí)時(shí)精準(zhǔn)的物流追蹤,再到數(shù)據(jù)驅(qū)動(dòng)的運(yùn)營(yíng)分析,API的價(jià)值貫穿于物流管理的全鏈條。

成功集成的關(guān)鍵在于:透徹理解API文檔與簽名機(jī)制、編寫健壯的錯(cuò)誤處理與重試邏輯、嚴(yán)格遵守安全規(guī)范、充分利用測(cè)試環(huán)境進(jìn)行驗(yàn)證、并針對(duì)具體業(yè)務(wù)場(chǎng)景進(jìn)行合理的設(shè)計(jì)與優(yōu)化。 當(dāng)克服了文檔、網(wǎng)絡(luò)、兼容性等挑戰(zhàn)后,申通快遞API將成為提升業(yè)務(wù)效率和用戶體驗(yàn)的強(qiáng)大助推器。

在萬(wàn)物互聯(lián)的時(shí)代,API是連接服務(wù)的橋梁,而物流API正是連接虛擬訂單與現(xiàn)實(shí)交付的核心紐帶。 掌握申通快遞API,意味著你的應(yīng)用具備了打通商業(yè)閉環(huán)“最后一公里”的關(guān)鍵能力。

上一篇:

2025年國(guó)內(nèi)十大快遞物流API排名:圓通快遞、中通快遞、申通快遞領(lǐng)銜

下一篇:

中通快遞API技術(shù)評(píng)測(cè):高效易用與場(chǎng)景化能力的平衡之道
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)