先说结论:EDI 940 945 warehouse 3PL 这套报文,核心就一句话——940 是货主给 3PL 仓库的发货指令,945 是仓库回给货主的实发确认。一个管"该发什么",一个管"实际发了什么"。对账对不上,问题十有八九不在拣选,而在报文。940 里的一个字段错,945 回来就全错,后面开票、对账、赔付跟着全错。这个坑我见过三次,每次都是上线之后才发现。
940 和 945 各管什么,先分清
很多人把 940 和 945 当成一对"发货通知",这是第一个误解。940 是指令,是货主的系统发给 3PL 仓库的:发什么货、发多少、发给谁、走哪家承运商。仓库收到 940,时效时钟才开始走——按合同约定的口径,3PL 的履约时效从接受 940 的那一刻算起。945 是结果,是仓库发完货之后回给货主的:实际发了多少、差了多少、承运商信息是什么。945 还会往下喂给 856 ASN,货主的收货方就靠它提前知道货要来了。
报文结构上,记住几个段就够了。940 的头是 W05,行明细是 W01,路由信息在 W66 里。945 的头是 W06,行明细 W12 里带三组数:订了多少、发了多少、差了多少,承运商数据在 W27 和 N9 里。GS01 功能标识上,940 是 OW,945 是 SW。这几个代码不用背,但排错的时候要会看——看到 W12 里的差异数不为零,先别喊仓库发错货,先看差异原因码写的是什么。
还有两个常被混进来的报文。997 是功能确认,只证明"对方收到了你的报文",不代表对方接受了你的指令。943 和 944 是一对,管库存转移的发货和收货确认。947 管库存调整通知。把这张表贴在项目群里,能少一半扯皮:
| 报文 | 方向 | 干什么 | 常见误解 |
|---|---|---|---|
| 940 | 货主 → 仓库 | 发货指令:发什么、发多少、发给谁 | 当成"通知一下",发完就不管了 |
| 945 | 仓库 → 货主 | 实发确认:实际发了多少、差多少 | 当成发票依据,直接拿去开票 |
| 997 | 双方互发 | 确认报文收到 | 当成业务接受,收到 997 就以为对方同意了 |
| 943 / 944 | 仓库 → 货主 / 反向 | 库存转移的发货 / 收货确认 | 和 945 混用,转移单当成销售单对账 |
| 947 | 仓库 → 货主 | 库存调整通知 | 调整了不通知,货主库存永远对不上 |
940 发之前,先过这张清单
上线前夜 checklist 里,940 这一项我每次都单独列出来。因为 940 是上游,940 错了,下游全是返工。发之前逐项核对:
- 订单号是不是货主系统里的唯一号,同一个订单有没有发过两次 940。
- 每个行明细的商品编码、数量、单位,是不是和货主的订单一致。单位错了最要命——箱和件混了,仓库按箱拣,货发出去十几倍。
- 收货地址、联系方式有没有完整。地址缺了楼层和电话,承运商送不到,退件的成本货主和 3PL 互相推。
- W66 路由段有没有写清承运商和服务方式。只写承运商名字不写服务方式,仓库不知道该走陆运还是空运。
- 取件时间窗口有没有写。有一次项目,货主的系统发 940 带了承运商代码,W66 里却没写取件时间窗口,仓库按默认班次备货,司机到仓时货还没打包好,白跑一趟。这个坑我见过三次,每次都是 W66 里少了一行。
- 特殊要求有没有单独标出来:温控、串号、批次、效期。藏在备注自由文本里的要求,仓库系统读不到,等于没写。
清单上的每一项都要能定位到报文里的具体段,不是"大概对了"。对模糊表达零容忍——"尽快发货"不是指令,"按合同执行"不是路由。940 里写不下的要求,要么改映射,要么走合同附件,别指望仓库的人去猜。
945 回来怎么对账:三组数对齐
945 一到,对账就开始了。对账不是"看总数差不多就行",是三组数逐行对齐:940 里订了多少、945 里实际发了多少、发票上开了多少。W12 里的差异数就是这三组数之间缝合的地方。
举个例子。一张单订了 120 箱,仓库实发 118 箱,差异 2 箱,差异原因写的是库存短缺。这时候货主该按 118 箱开票,按 118 箱收客户的钱,短缺的 2 箱走补发或者退款流程。如果货主按 940 的 120 箱开了票,客户收到 118 箱,拒付那 2 箱的钱,财务再回头找仓库要说法——这场官司从一开始就打错了方向。945 是实发确认,发票应该跟着 945 走,不是跟着 940 走。
这里是 EDI 940 945 对账最容易被忽略的一层:945 不是越快越好,发错的 945 比晚发的更贵。一家 3PL 为了抢时效,发货刚出库就发 945,结果承运商揽收时发现两箱破损扣下了,货实际没走成。货主拿着 945 做了收货预期,客户那边也排了上架人手,最后货没到,945 还得作废重发。先发错的 945,比晚发正确的 945 贵得多。我的做法是:945 只在承运商揽收确认之后发,宁可晚一拍,不发错一单。

异常重传:最容易翻车的地方
报文异常分三种,每种的处理方式不一样。第一种,997 没回来:对方可能没收到,也可能收到了但确认报文丢了。先查传输记录,别急着重发。第二种,997 回来了但带错误码:报文结构有问题,按错误码修映射,重发。第三种,997 回来了、结构也对,但业务上对方不认:比如仓库说这个订单号已经发过货了,拒绝重复处理。这时候重发 940 一百遍也没用,要先解决业务问题。
重传有三条铁律。第一,永远不要原样重发同一份报文。每一份重发的报文都要用新的控制号,并在报文里引用原来的订单和原报文,让对方系统能认出这是重发而不是新单。第二,重发之前先查对方有没有已经处理过原报文。原报文其实已经进了仓库系统,你又重发一份一模一样的 940,仓库会当成两个订单拣两次货。第三,数量变了一定要走变更流程,不要偷偷重发一份改了数量的 940 覆盖。覆盖式重发在对方系统里留不下痕迹,对账的时候谁也说不清到底以哪份为准。
还有一个常见翻车点:945 重发。945 发错了,正确做法是发一份更正版的 945,差异数写清楚,原因码写明白,而不是把原 945 撤回当作没发过。货主的系统可能已经拿原 945 生成了 856 ASN,发给了收货方。撤回解决不了下游已经扩散出去的数据,只有更正版能把账扳回来。
上线前夜 checklist:940/945 这一页
项目上线前夜,我会把这页 checklist 打印出来,逐项打勾。少一项都不上线:
- 940 和 945 的映射表,货主和 3PL 双方签字确认过,不是只有实施方自己看过。
- W66 路由段、取件窗口、特殊要求,三种字段各做过至少一轮真实报文测试,不是只测了" happy path"。
- 997 超时未回的告警有人值班,告警发到具体的人,不是发到一个没人看的群。
- 差异数不为零的 945,货主财务知道怎么处理,补发和退款的流程有人认领。
- 重传流程写进操作手册:谁有权重发、重发前查什么、重发后怎么通知对方。
- 945 的触发点定死在承运商揽收确认之后,不是出库那一刻。
EDI 940 945 这套东西,技术上不难,难在双方对同一份报文的理解一致。货主觉得"我发了就是你收到了",仓库觉得"我回了 945 就是你认账了",中间差的那一层,就是上线前夜 checklist 上这些看起来啰嗦的确认项。把这些确认项做实了,940/945 才能从"经常出问题的地方"变成"不用操心的地方"。
作者:林晓|WMS 实施顾问











