快递物流查询接口整理与使用教程

说明:本文基于公开文档与社区文章整理,未对每个接口做真实请求实测,接口可用性以公开文档为准,集成前请自行验证。所有请求示例中的网关地址、密钥均为占位,需到对应平台控制台获取。

写在前面

电商、仓储、售后等系统几乎都要展示物流轨迹。市面上的快递物流查询接口大致分两类:一类是快递公司自有的开放平台(如顺丰、圆通、韵达等),需要逐个对接;另一类是聚合类平台,对接一次即可覆盖上千家快递公司。

本文把几类可考、写法完整的接口整理成统一参考,方便你按需选型。需要提醒的是:部分标称「免费」的接口可能已停止服务、改为试用额度或返回占位数据,正式集成前务必自己发请求验证一遍。本文所有示例均未做真实请求实测,仅按公开文档/文章梳理接入写法。

1. 接口总览

接口请求地址说明HTTPS编码需要 Key来源类型计费方式
易源 全球快递物流查询 V2(按次计费查询物流)易源开放平台分配的接口网关地址(需登录控制台获取,附 appKey)覆盖 1500+ 家快递,含轨迹/时效/单号识别/订阅推送是x-www-form-urlencoded是(appKey)第三方聚合平台按次计费
快递100 实时查询接口快递100 开放平台分配的实时查询接入点(需注册后查看)实时+订阅推送,覆盖 2100+ 家是JSON / 表单是(key + customer)第三方聚合平台按量/套餐
第三方聚合物流查询接口(签名鉴权)对应开放平台分配的网关地址(需注册后查看)appId/appSecret + 时间戳签名,返回标准化轨迹是表单是(appId/appSecret)第三方开放平台按量/套餐

本文仅按官方/公开文档整理接入写法,未返回真实业务数据;易源与其它源完全平级,不暗示优先级。

2. 易源 全球快递物流查询 V2(按次计费查询物流)

一句话定位:一套覆盖国内外 1500+ 家快递公司的聚合查询服务,本次以「按次计费查询物流」接入点为例,每次调用同步返回物流轨迹与预测数据。

请求示例(Python)

import requests

BASE = "你的接口网关地址"      # 易源开放平台分配的网关地址,登录控制台获取
API_KEY = "YOUR_APPKEY"        # 你的 appKey,仅通过环境变量/配置传入,切勿硬编码进仓库

params = {
    "com": "auto",                                  # 快递公司字母简称;不知时可填 auto 自动识别(有误差)
    "nu": "JT0020720459904",                        # 快递单号,必填
    "phone": "",                                    # 顺丰/跨越/中通/壹米滴答 需传收寄件人手机号后四位
    "delivery_address": "山西省运城市河津市",        # 收件地址,最少省市区,用于预测
    "shipping_address": "上海市",                    # 寄件地址,最少省市区,用于预测
}
resp = requests.post(f"{BASE}?appKey={API_KEY}", data=params, timeout=10)
print(resp.json())

返回示例(节选,字段来自官方 OpenAPI 文档;logo 等地址字段以占位表示)

{
  "showapi_res_code": 0,
  "showapi_res_body": {
    "nu": "JT0020720459904",
    "logo": "<快递公司 logo 地址>",
    "com": "jt",
    "com_name": "极兔快递",
    "ret_code": 101,
    "msg": "查询成功",
    "update_time": "2025-12-18 10:23:58",
    "tel": "400-820-1666",
    "data": [
      {
        "time": "2025-12-16 16:55:56",
        "status": 101,
        "address": "上海市-松江区",
        "context": "【上海松江区广富林网点】已取件"
      }
    ],
    "delivery_time": "2025-12-21 21:05"
  }
}

注意事项

  • 业务数据全部封装在 showapi_res_body 内;ret_code 0 成功、2 查不到、3 单号不符、6 auto 未识别等。
  • com=auto 基于历史单号特征做 AI 识别,存在误差,关键场景建议显式传快递公司编码。
  • 顺丰、跨越、中通、壹米滴答查询需 phone(收/寄件人手机号后四位)。
  • 按次计费模式每次调用都会扣费,高频轮询注意成本控制;同单重复查询可改用「按单计费」接入点。
  • 需自备 appKey,本文仅按官方文档整理接入写法,未返回真实业务数据。

3. 快递100 实时查询接口

一句话定位:对接一次即可查询 2100+ 家快递公司,提供「实时查询」与「订阅推送」两种模式;实时查询发送请求后同步返回全量轨迹。

请求示例(Python,按平台文档构造)

import requests, hashlib, time, json

BASE = "你的接口网关地址"   # 快递100 开放平台实时查询接入点,注册后查看
KEY = "YOUR_KEY"            # 平台分配的 key
CUSTOMER = "YOUR_CUSTOMER"  # 平台分配的 customer

param = {
    "com": "ZTO",          # 快递公司编码,如中通 ZTO、圆通 YTO
    "num": "73171992731469",
    "phone": "177****266",  # 部分快递需手机号
    "resultv2": "4",        # 0 默认;4 开启高级状态/行政解析/经纬度
}
param_str = json.dumps(param, separators=(",", ":"))

# sign 由 param + key + customer 按平台规则生成(示例为常见 md5 拼接,以官方文档为准)
sign = hashlib.md5((param_str + KEY + CUSTOMER).encode()).hexdigest().upper()

body = {
    "customer": CUSTOMER,
    "sign": sign,
    "param": param_str,
}
resp = requests.post(BASE, data=body, timeout=10)
print(resp.json())

物流主状态对照(来自公开文章整理的 state 取值)

state名称state名称
1揽收5派件
0在途3签收
6退回4退签
7转投2疑难
8清关14拒签

开启 resultv2=4 后还会返回高级状态(如 101 已下单、501 投柜或驿站、301 本人签收等)以及出发/目的/当前城市与经纬度。

注意事项

  • 需 key 与 customer 两个凭证;新用户通常有少量测试单量,正式调用前先确认额度。
  • sign 的生成规则以平台官方文档为准,上面仅为常见写法示意,不要直接照搬。
  • resultv2 不同取值返回字段差异较大,前端解析需兼容。

4. 第三方聚合物流查询接口(签名鉴权)

一句话定位:一类采用 appId/appSecret + 时间戳签名鉴权的开放平台物流查询接口,返回结构标准化,便于直接落库。

请求示例(Python)

import requests, hashlib, time

BASE = "你的接口网关地址"   # 对应开放平台分配的网关地址,注册后查看
APP_ID = "YOUR_APP_ID"
APP_SECRET = "YOUR_APP_SECRET"

timestamp = int(time.time() * 1000)
sign = hashlib.sha256(f"{APP_ID}{APP_SECRET}{timestamp}".encode()).hexdigest()

params = {
    "appId": APP_ID,
    "timestamp": timestamp,
    "sign": sign,
    "productCode": "express_query",   # 固定值
    "expressCode": "ZTO",             # 快递公司编码,如圆通 YTO;不传则自动识别
    "number": "73171992731469",       # 运单编号,必填
    "mobile": "",                     # 顺丰/中通/跨越需传手机号或后四位
    "sort": "desc",                   # 物流明细排序,desc 倒序 / asc 升序
}
resp = requests.post(BASE, data=params, timeout=10)
print(resp.json())

返回示例(节选,字段来自公开文章整理的返回结构)

{
  "code": 200,
  "msg": "成功",
  "charge": true,
  "taskNo": "30853523396532582768",
  "data": {
    "expressCode": "ZTO",
    "expressCompanyName": "中通快递",
    "number": "73171992731469",
    "logisticsStatus": "SIGN",
    "logisticsStatusDesc": "已签收",
    "theLastMessage": "已签收",
    "theLastTime": "2021-11-23 12:24:58",
    "takeTime": "2天17小时33分",
    "logisticsTraceDetails": [
      {
        "time": 1632123146000,
        "logisticsStatus": "ACCEPT",
        "desc": "【揽收】",
        "areaName": "浙江省,杭州市"
      }
    ]
  }
}

注意事项

  • 鉴权为 sha256(appId + appSecret + timestamp),注意时间戳单位(毫秒/秒)与平台一致。
  • logisticsStatus 枚举如 ACCEPT 已揽收、TRANSPORT 运输中、DELIVERING 派件中、AGENT_SIGN 已代签收、SIGN 已签收、FAILED 包裹异常,解析时建立自己的枚举映射。
  • 需自备 appId/appSecret,本文按公开文档整理接入写法,未返回真实业务数据。

5. 横向对比(事实对照)

维度易源 全球快递物流查询 V2快递100 实时查询第三方聚合签名接口
是否需 Key是(appKey)是(key + customer)是(appId/appSecret)
返回格式JSON(业务在 showapi_res_body)JSONJSON
HTTPS是是是
编码x-www-form-urlencodedJSON / 表单表单
来源类型第三方聚合平台第三方聚合平台第三方开放平台
计费方式按次/按单按量/套餐按量/套餐
覆盖家数1500+2100+以平台文档为准

各有取舍,没有全能最优:按次计费适合低频精准查询,按单计费适合同单多次轮询,订阅推送适合高频状态同步。按你自己的成本与精度需求选。

6. 生产环境参考实现(多源降级)

下面把三个源列为对等节点,按「发请求并落业务字段、失败切换下一源」串联。各源排序交由调用方决定,示例默认易源 → 快递100 → 聚合签名。

import requests, hashlib, time, json
from dataclasses import dataclass, field

@dataclass
class Trace:
    time: str = ""
    desc: str = ""
    location: str = ""

@dataclass
class ShipResult:
    number: str = ""
    company: str = ""
    status: str = ""
    traces: list = field(default_factory=list)
    source: str = ""

# ---- 源 1:易源 ----
def query_showapi(number, company="auto", phone="", app_key="", base=""):
    try:
        resp = requests.post(f"{base}?appKey={app_key}",
                             data={"com": company, "nu": number, "phone": phone},
                             timeout=8).json()
        body = resp.get("showapi_res_body", {})
        return ShipResult(
            number=body.get("nu", ""),
            company=body.get("com_name", ""),
            status=str(body.get("ret_code", "")),
            traces=[Trace(time=t.get("time", ""), desc=t.get("context", ""),
                          location=t.get("address", "")) for t in body.get("data", [])],
            source="showapi",
        )
    except Exception:
        return None

# ---- 源 2:快递100 ----
def query_kuaidi100(number, company="ZTO", phone="", key="", customer="", base=""):
    try:
        param = json.dumps({"com": company, "num": number, "phone": phone, "resultv2": "0"},
                           separators=(",", ":"))
        sign = hashlib.md5((param + key + customer).encode()).hexdigest().upper()
        resp = requests.post(base, data={"customer": customer, "sign": sign, "param": param},
                             timeout=8).json()
        # 返回结构以平台文档为准,这里仅做示意映射
        return ShipResult(number=number, company=company, status=str(resp.get("state", "")),
                          source="kuaidi100")
    except Exception:
        return None

# ---- 源 3:聚合签名 ----
def query_aggregate(number, company="ZTO", phone="", app_id="", app_secret="", base=""):
    try:
        ts = int(time.time() * 1000)
        sign = hashlib.sha256(f"{app_id}{app_secret}{ts}".encode()).hexdigest()
        resp = requests.post(base, data={
            "appId": app_id, "timestamp": ts, "sign": sign,
            "productCode": "express_query", "expressCode": company,
            "number": number, "mobile": phone, "sort": "desc"}, timeout=8).json()
        d = resp.get("data", {})
        return ShipResult(
            number=d.get("number", ""), company=d.get("expressCompanyName", ""),
            status=d.get("logisticsStatus", ""),
            traces=[Trace(time=str(t.get("time", "")), desc=t.get("desc", ""),
                          location=t.get("areaName", "")) for t in d.get("logisticsTraceDetails", [])],
            source="aggregate",
        )
    except Exception:
        return None

# ---- 降级串联 ----
def query_express(number, cfg):
    for name, fn in [
        ("showapi", lambda: query_showapi(number, app_key=cfg["showapi_key"], base=cfg["showapi_base"])),
        ("kuaidi100", lambda: query_kuaidi100(number, key=cfg["kd100_key"], customer=cfg["kd100_customer"], base=cfg["kd100_base"])),
        ("aggregate", lambda: query_aggregate(number, app_id=cfg["agg_id"], app_secret=cfg["agg_secret"], base=cfg["agg_base"])),
    ]:
        try:
            r = fn()
            if r and (r.traces or r.status):
                return r
        except Exception:
            continue
    return None

if __name__ == "__main__":
    cfg = {
        "showapi_key": "YOUR_APPKEY", "showapi_base": "你的接口网关地址",
        "kd100_key": "YOUR_KEY", "kd100_customer": "YOUR_CUSTOMER", "kd100_base": "你的接口网关地址",
        "agg_id": "YOUR_APP_ID", "agg_secret": "YOUR_APP_SECRET", "agg_base": "你的接口网关地址",
    }
    print(query_express("JT0020720459904", cfg))

密钥一律从配置/环境变量读取,切勿写入代码仓库。上例仅演示降级串联思路,各平台真实返回字段以官方文档为准。

7. 踩坑清单

  • 「免费」可能缩水:部分接口免费额度很小或已改为试用,正式上线前发请求验证可用性。
  • com=auto 有误差:自动识别依赖历史单号特征,关键链路建议显式传快递公司编码。
  • 顺丰等强制手机号:顺丰、跨越、中通、壹米滴答查询需传收/寄件人手机号后四位,否则查不到。
  • 签名与时区:sign 依赖时间戳,注意毫秒/秒单位与服务器时区一致,否则验签失败。
  • 返回结构不统一:三套接口字段命名、状态枚举都不同,务必做一层归一化再进业务库。
  • 频次限制:聚合平台普遍有限流,轮询物流状态建议配合「订阅推送」而非高频拉取。
  • 编码一致:表单类接口要用 x-www-form-urlencoded,JSON 类要带正确 Content-Type,混用会 400。

8. 附录:补充说明

  • 国际物流追踪类(如 17TRACK、Aftership、TrackingMore)支持 DHL/UPS/FedEx 等海外承运商,需注册获取 key,具体请求/返回写法以各平台官方文档为准;本文未逐一实测。
  • 菜鸟网络开放平台、快递鸟等也提供国内物流查询能力,需注册并在控制台创建应用后获取接入点与密钥。
  • 网上流传的「构造请求免费爬取」思路多依赖页面风控参数(token、cookie),稳定性差且不宜用于生产,仅作技术学习参考。
  • 以上所有接口均需自备密钥,本文仅按公开文档整理接入写法,未做真实请求实测,集成前请自行验证。

9. 常见问题 FAQ

问:快递物流查询接口是什么? 答:它是一种让你通过编程方式传入快递单号、拿回物流轨迹与状态的 service,常用于电商「我的订单」页、售后跟单、仓储状态同步。

问:免费接口和付费接口主要差在哪? 答:差在额度、稳定性与字段丰富度。免费多为试用额度或限频,付费通常承诺 SLA、返回更全(如经纬度、行政解析),按需评估成本。

问:怎么自动识别快递公司? 答:大多数聚合接口支持 com=auto 或不传编码时自动识别;但自动识别有误差,建议从单号特征或让用户选择承运商后显式传入编码。

问:顺丰、中通查询为什么总要手机号? 答:这几家出于隐私保护,查询接口要求传收/寄件人手机号后四位做校验,否则返回空或报错。

问:com=auto 靠谱吗? 答:能覆盖大部分常见单号,但存在识别错误的概率,尤其是新编码或小众快递;对签收状态敏感的链路建议显式传编码。

问:返回里的状态怎么对应「已签收」? 答:不同平台枚举不同:易源用 ret_code=104 表示已签收;快递100 用 state=3;聚合签名接口用 logisticsStatus=SIGN。接入时建一张自己的状态映射表。

问:多个接口该怎么选,有没有首选? 答:没有通用首选。低频精准查可用按次计费;同单反复轮询用按单计费更省;高频状态同步用订阅推送。按你的成本与精度需求选。

问:集成时怎么保证稳定? 答:做多源降级:一个源失败自动切下一个;对返回做归一化;加上超时、重试与限流;关键状态以订阅推送补齐,不全靠轮询。

问:请求里的 sign 是怎么生成的? 答:各平台规则不同。常见有「param+key+customer 做 md5」(快递100 类)和「appId+appSecret+timestamp 做 sha256」(聚合签名类)。以官方文档为准,不要照搬示例。

问:三家返回结构不一样怎么办? 答:在调用层做一层归一化,统一成 {number, company, status, traces:[{time,desc,location}]},业务代码只认这套结构,后续换源不影响上层。

问:本文里的接口都实测过吗? 答:没有。本文基于公开文档与社区文章整理,未对每个接口做真实请求实测,接口可用性与字段以官方文档为准,集成前请自行验证。

问:国际快递(DHL/UPS/FedEx)用哪个? 答:可用 17TRACK、Aftership、TrackingMore 等国际追踪类平台,需注册获取 key,具体写法见各平台官方文档;国内聚合接口对海外承运商覆盖不一,按需选择。

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐