需求背景

当前 DHL 小包业务中,系统存在以下现象:
已成功派送的包裹,在 DHL 后台显示为“无订单数据(Sendung ohne Auftragsdaten)”
实际情况为:
我方未向 DHL 传输订单数据
但包裹已提前到达 DHL 处理中心
DHL 在“无订单数据”的情况下,仍完成了分拣与派送
经与 DHL 沟通确认:
DHL 侧存在一个“订单数据接收时间点”
若包裹在该时间点前已到达处理中心:
DHL 无法将包裹与订单数据匹配
最终形成“无订单数据但完成派送”的记录
面单返回 ≠ 订单数据已传输给 DHL

在 DHL 切换 REST API 之前:
曾存在类似 FedEx Close 的机制
系统会定时、定点向承运商推送一批订单数据
年中切换 REST 后:
该能力未被保留或补齐

需求内容

新增一套 类似 FedEx Close 的 DHL 小包“订单数据确认 / 集中传输”机制,确保:
DHL 能在包裹进入作业前或最晚在节点时:
完整接收到订单数据
系统可明确判断:
订单是否已进入 DHL 正式作业与计费链路

新增 DHL Close / Manifest 推送服务
在现有流程基础上,补充以下能力:
创建面单

获取 Tracking Number

包裹贴标 & 集货

【新增】POST /shipping/v4/manifest(订单数据确认/推送)

生成 DSM / Manifest

司机取件 / 网点交接

开发设计

dhl官网文档

https://developer.dhl.com/api-reference/parcel-de-shipping-post-parcel-germany-v2#operations-tag-Manifests
中文翻译:

推送接口:

post : https://api-eu.dhl.com/parcel/de/shipping/v2/manifests

{
    "profile": "STANDARD_GRUPPENPROFIL",
    "shipmentNumbers": [
        "00340434622320454990"
    ]
}

系统流程设计

  1. 推送数据:预报的单据跟踪号
  2. 推送时间/节点:
    • 2.1 方案一:DHL交运发货?交运发货能确定一批单据真正发货(推送时间、跟踪号数据由交运决定)
    • 2.2 方案二:参考历史逻辑,每三十分钟定时处理,查询时间范围内(前一天~当前时间)的指定物流产品(配置)订单跟踪号(已出库,但是未推送的),进行数据推送
    • 走方案一更符合流程规范(在确定交运发货触发,需要仓储配合),走方案二更敏捷,存在推送不及时、漏数据
  3. channel-public 项目对接好 Manifests 接口
  4. 暂定方案二推送则:在 task 新建定时任务,通过config确定哪些dhl下的物流产品,查询前一天~当前时间,并且订单状态=已出库的单据跟踪号,调用 Manifests 接口推送数据,记录到系统DHL表
--- 新建dhl-rest推送记录表
CREATE TABLE `dhl_close_record` (
  `record_id` int NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `order_id` int NOT NULL COMMENT '订单ID',
  `order_code` varchar(32) NOT NULL COMMENT '订单号',
  `tracking_number` varchar(64) NOT NULL COMMENT '跟踪号',
  `push_time` datetime NOT NULL COMMENT '推送时间',
  `response_status` varchar(255) DEFAULT NULL COMMENT '响应状态',
  `response_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '响应消息',
  PRIMARY KEY (`record_id`) USING BTREE,
  KEY `idx_order_code` (`order_code`) USING BTREE,
  KEY `idx_tracking_number` (`tracking_number`) USING BTREE,
  KEY `idx_push_time` (`push_time`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='DHL-close(Manifests)记录表';

---- 查询单据
SELECT o.order_id AS documentId, o.order_code AS documentCode, o.order_type AS documentType, o.customer_code AS customerCode,
            o.warehouse_id AS warehouseId, w.warehouse_code AS warehouseCode, o.sm_code AS smCode,
            IF( oa.otn_type = 0, oa.sub_tracking_number, oa.tracking_number ) AS trackingNumber
        FROM
            orders o
        INNER JOIN warehouse w ON w.warehouse_id = o.warehouse_id
        INNER JOIN order_operation_time oot ON oot.order_id = o.order_id
        AND oot.ship_time BETWEEN #{startTime} AND #{endTime}
        INNER JOIN order_attached oa ON oa.order_id = o.order_id AND oa.oat_type = 3
        INNER JOIN wpglb_lms.shipping_method sm ON sm.sm_code = o.sm_code
        INNER JOIN wpglb_lms.service_provider sp ON sp.sp_id = sm.sp_id
        WHERE o.order_status = 8 AND sp.sp_code IN
        <foreach collection="spCodeList" item="item" separator="," open="(" close=")">
            #{item}
        </foreach>
作者:黄天文  创建时间:2026-01-08 16:05
最后编辑:黄天文  更新时间:2026-03-03 10:08