DHL 原生请求头示意
原程序通常把请求直接发到 DHL 域名,并携带 DHL 自己的认证头。
POST /orders HTTP/1.1
Host: api-eu.dhl.com
Content-Type: application/json
DHL-API-Key: <DHL_API_KEY>
DHL-API-Secret: <DHL_API_SECRET>
{ ... }先看改动量,再决定是走 DHL compat 低改动迁移,还是一步切到 SendLabel 统一接口。
| 项目 | DHL 原生接口 | SendLabel API | 客户程序需要改什么 |
|---|---|---|---|
| 鉴权 | 直接使用 DHL 的 API Key / Secret / 原生认证头。 | 改为使用 SendLabel API Key,可通过 `Authorization: Bearer <API_KEY>` 等方式传递。 | 必须改请求头和密钥管理方式。 |
| Base URL | 请求 DHL 官方域名。 | 改为请求 SendLabel 域名。 | 必须替换基础域名;建议在配置层单独抽出。 |
| 接口路径 | 按 DHL 原生 Shipping API 的 orders / labels / senders / manifests 组织。 | 优先走 SendLabel 的 DHL compat 路由;新项目也可直接走统一接口 `/api/v1/shipments/import`。 | 至少要调整路径映射。 |
| 出单请求体 | 字段名、嵌套层级和部分枚举遵循 DHL 原生规范。 | 兼容路由会尽量贴近 DHL,但仍会做 SendLabel 侧标准化。 | 通常只需做小幅字段核对;若依赖原始嵌套细节,需要补映射层。 |
| 单次请求多票 | 客户程序可能一次提交多票。 | 当前 DHL compat `orders` 更适合单票镜像迁移;若需要批量,建议改走统一接口。 | 如果原程序强依赖一请求多票,需要拆成逐票调用或切统一接口。 |
| 标签返回 | 可能直接依赖 DHL 返回的 label 文档方式。 | API 客户更适合直接取 `labelBase64`,也支持后续通过标签接口下载。 | 如果原程序假设一定拿到 PDF 文件流,需要补一个 decode 或下载步骤。 |
| Sender 管理 | 直接使用 DHL 账户里的 sender 配置。 | 改为使用 SendLabel sender 体系,但提供 compat sender 接口降低迁移成本。 | 通常需要同步或重建 sender,并调整默认 sender 的设置方式。 |
| Manifest 语义 | 部分客户按 DHL 账户维度理解 manifest。 | SendLabel 当前更偏向客户作用域/本系统作用域的 manifest 视角。 | 如果客户依赖整账号级 manifest 汇总,需要重新确认业务预期。 |
| 地址校验 | 客户可能把原始地址直接交给 DHL。 | SendLabel 会做地址标准化、拆分和必要校验。 | 可能会更早暴露地址问题;建议把错误提示透传给 ERP/WMS。 |
| 错误处理 | 代码里可能直接依赖 DHL 原始错误码和原始响应字段。 | 兼容层错误现在采用双轨结构:尽量保留 DHL 风格字段,同时附加统一的 `sendlabelError` 方便标准化解析。 | 如果客户程序 hardcode 了 DHL 原始错误字段,需要调整;推荐优先读取 `sendlabelError`,保留对原生字段的兼容兜底。 |
| 幂等与重试 | 很多客户只是网络超时后直接重试。 | 建议显式使用 `Idempotency-Key`,由 SendLabel 统一处理重复请求。 | 强烈建议把幂等键纳入 ERP/WMS 请求模型。 |
| 计费与发票 | 原来可能完全由客户与 DHL 自行结算。 | 切到 SendLabel 后,API 出单会进入 SendLabel 的余额/信用额度/周结开票体系。 | 客户侧需要接受新的对账与开票口径,尤其是周结或额度触发开票。 |
| Pickup / Postnumber / Tracking | 部分客户把这些能力与 Shipping 默认绑定理解。 | 这些仍然是需要单独确认的产品线能力,不应和 Shipping 出单混为一谈。 | 如果客户原程序依赖这些接口,要单独确认权限和测试路径。 |
| 原 DHL 接口 | 推荐 SendLabel 接口 | 头部变化 | 请求变化 | 响应变化 | 改代码强度 |
|---|---|---|---|---|---|
| POST DHL orders | POST /api/compat/dhl-parcel-de/orders | 把 DHL 原生认证头改为 SendLabel API Key 认证。 | 主体结构大体可沿用,但当前镜像版只支持单票;如果原来一次传多票,要拆单或改走统一接口。 | 返回会带 SendLabel 兼容信息与本系统订单语义,不应只按 DHL 原始字段解析。 | 中 |
| GET DHL labels | GET /api/compat/dhl-parcel-de/labels | 同样改为 SendLabel API Key。 | 查询参数建议改为 `shipment` / `shipmentNumber` / `trackingNumber` 或 `orderId`。 | 默认拿到的是 PDF 文件流;如果原程序改成走统一接口,也可以改用 `labelBase64`。 | 低 |
| GET/POST DHL manifests | GET/POST /api/compat/dhl-parcel-de/manifests | 改为 SendLabel API Key。 | 可继续按日期或 shipmentNumber 查询,但它是客户作用域,不是整个 DHL 账号维度。 | 返回的 manifest 文档和映射关系仍可用,但要重新确认业务上是否需要账号级总表。 | 中 |
| GET/POST DHL senders | GET/POST /api/compat/dhl-parcel-de/v1/senders | 改为 SendLabel API Key。 | 需要把客户原本在 DHL 账号里的 sender 迁到 SendLabel sender 体系。 | 响应更偏向 SendLabel 内部 sender 记录,不建议假设其主键与 DHL 原始 sender 标识一致。 | 中 |
| POST DHL default sender | POST /api/compat/dhl-parcel-de/v1/senders/default | 改为 SendLabel API Key。 | 默认发件人不再是 DHL 账号里的默认值,而是 SendLabel Key / 客户侧默认 sender。 | 返回按 SendLabel 侧默认 sender 生效。 | 低 |
| POST DHL batch shipment creation | POST /api/v1/shipments/import | 改为 SendLabel API Key,并建议强制带 `Idempotency-Key`。 | 需要从 DHL 原生结构迁到 SendLabel 统一结构,包括 `carrier`、`shipments[]`、地址与 parcel 字段。 | 响应会变成统一 import 结果模型,包含 `results[]`、执行模式、可能的 `labelBase64` 或本地 orderId。 | 高 |
POST /orders HTTP/1.1
Host: api-eu.dhl.com
Content-Type: application/json
DHL-API-Key: <DHL_API_KEY>
DHL-API-Secret: <DHL_API_SECRET>
{ ... }POST /api/compat/dhl-parcel-de/orders HTTP/1.1
Host: api.sendlabel.example
Authorization: Bearer <SENDLABEL_API_KEY>
Content-Type: application/json
Idempotency-Key: erp-order-20260623-10001
{ ... }POST /api/v1/shipments/import HTTP/1.1
Host: api.sendlabel.example
Authorization: Bearer <SENDLABEL_API_KEY>
Content-Type: application/json
Idempotency-Key: erp-order-20260623-10001
{ ... }{
"profile": "STANDARD_GRUPPENPROFIL",
"shipments": [
{
"product": "V01PAK",
"billingNumber": "22222222220101",
"refNo": "ERP-10001",
"shipper": {
"name1": "ACME GmbH",
"addressStreet": "Musterstrasse",
"addressHouse": "12",
"postalCode": "53113",
"city": "Bonn",
"country": "DE"
},
"consignee": {
"name1": "Max Mustermann",
"addressStreet": "Hauptstrasse",
"addressHouse": "8",
"postalCode": "10115",
"city": "Berlin",
"country": "DE"
},
"details": {
"weight": {
"uom": "kg",
"value": 1.2
}
}
}
]
}{
"profile": "STANDARD_GRUPPENPROFIL",
"shipments": [
{
"product": "V01PAK",
"billingNumber": "22222222220101",
"refNo": "ERP-10001",
"shipper": {
"name1": "ACME GmbH",
"addressStreet": "Musterstrasse",
"addressHouse": "12",
"postalCode": "53113",
"city": "Bonn",
"country": "DE"
},
"consignee": {
"name1": "Max Mustermann",
"addressStreet": "Hauptstrasse",
"addressHouse": "8",
"postalCode": "10115",
"city": "Berlin",
"country": "DE"
},
"details": {
"weight": {
"uom": "kg",
"value": 1.2
}
}
}
]
}{
"carrier": "dhl",
"service": "parcel_de",
"shipments": [
{
"shipper": {
"name": "ACME GmbH",
"address1": "Musterstrasse 12",
"postalCode": "53113",
"city": "Bonn",
"countryCode": "DE"
},
"recipient": {
"name": "Max Mustermann",
"address1": "Hauptstrasse 8",
"postalCode": "10115",
"city": "Berlin",
"countryCode": "DE"
},
"parcel": {
"weightKg": 1.2
},
"references": {
"customerReference": "ERP-10001"
},
"options": {
"labelFormat": "pdf"
}
}
]
}{
"results": [
{
"ok": true,
"carrier": "dhl",
"orderId": "ord_123456",
"trackingNumber": "00340434161234567890",
"labelBase64": "<base64-pdf>",
"executionMode": "sync"
}
]
}curl -X POST "https://api.sendlabel.example/api/compat/dhl-parcel-de/orders" \
-H "Authorization: Bearer <SENDLABEL_API_KEY>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: erp-order-20260623-10001" \
--data @dhl-compat-order.jsoncurl -X POST "https://api.sendlabel.example/api/v1/shipments/import" \
-H "Authorization: Bearer <SENDLABEL_API_KEY>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: erp-order-20260623-10001" \
--data @sendlabel-unified-order.jsoncurl -L "https://api.sendlabel.example/api/compat/dhl-parcel-de/labels?trackingNumber=00340434161234567890" \
-H "Authorization: Bearer <SENDLABEL_API_KEY>" \
--output label.pdf| 文件名 | 用途 | 对应接口 |
|---|---|---|
| dhl-compat-order.json | 给 compat 单票出单示例使用,尽量保留原 DHL 风格字段。 | POST /api/compat/dhl-parcel-de/orders |
| sendlabel-unified-order.json | 给 unified import 示例使用,适合准备统一 UPS / DHL 模型的客户。 | POST /api/v1/shipments/import |
| label.pdf | compat 标签下载示例的输出文件名,方便联调时直接落盘检查。 | GET /api/compat/dhl-parcel-de/labels |
| DHL 常见字段 | SendLabel compat | SendLabel unified | 说明 |
|---|---|---|---|
| shipments[0].product | shipments[0].product | service | compat 可基本沿用;切 unified 时要改成 SendLabel 的服务标识。 |
| shipments[0].billingNumber | shipments[0].billingNumber | not passed by customer in most cases | compat 下通常仍可保留;unified 一般不要求客户再直接传 DHL 计费号。 |
| shipments[0].refNo | shipments[0].refNo | shipments[0].references.customerReference | 客户自定义参考号建议保留,但 unified 下字段层级会变化。 |
| shipments[0].shipper.name1 | shipments[0].shipper.name1 | shipments[0].shipper.name | compat 保持原样;unified 会收敛成更通用的名字字段。 |
| shipments[0].shipper.addressStreet + addressHouse | shipments[0].shipper.addressStreet + addressHouse | shipments[0].shipper.address1 | unified 更适合单行地址;如原程序分街道/门牌,需要在映射层合并。 |
| shipments[0].consignee.* | shipments[0].consignee.* | shipments[0].recipient.* | 收件人对象在 unified 中会改名为 `recipient`。 |
| shipments[0].details.weight.value | shipments[0].details.weight.value | shipments[0].parcel.weightKg | 重量字段会从 DHL 的嵌套结构变成更直接的 parcel 模型。 |
| label response document | PDF stream from labels endpoint | results[0].labelBase64 | 如果 ERP/WMS 想省一次下载请求,unified 更适合直接读取 base64 标签。 |
| native DHL error fields | compat response + SendLabel wrapper | unified import result/errors | 不要再只按 DHL 原始错误字段写死解析,最好统一做一层适配。 |
{
"shipments": [
{
"shipmentNo": "00340434161234567890",
"shipmentLabel": {
"format": "PDF",
"data": "<base64-pdf>"
},
"status": {
"statusCode": 2000,
"statusText": "OK"
}
}
]
}{
"orderId": "ord_123456",
"trackingNumber": "00340434161234567890",
"labelBase64": "<base64-pdf>",
"Compatibility": {
"provider": "DHL",
"route": "/api/compat/dhl-parcel-de/orders"
}
}{
"results": [
{
"ok": true,
"carrier": "dhl",
"service": "parcel_de",
"orderId": "ord_123456",
"trackingNumber": "00340434161234567890",
"labelBase64": "<base64-pdf>",
"executionMode": "sync"
}
]
}