先说结论:EDI 850 purchase order mapping(EDI 850 采购订单的字段映射)做砸了,锅从来不在 EDI 技术本身,而在三件事:映射表没跟买方对齐"日期"和"单位"的真实语义、异常报文发了没人看、对账脚本压根没写。这个坑我见过三次,剧本每次都一样,开头都是"系统都跑通了",结尾都是"错了两个月才发现"。
为什么 850 值得单独写一篇:它是整条采购 EDI 链的源头。买方(零售商、品牌方)用 850 下采购单,供应商回 855 确认,发货时发 856(ASN),最后 810 开票。四张单子里 850 是第一张,源头错一行,后面三张全跟着错。X12 850 的段其实就几个:BEG(单头:单号和日期)、N1(买卖双方代码)、PO1(行项目:物料、数量、单价)、CTT(汇总校验行数)。段不多,魔鬼全在段里面的限定词(qualifier)——同一个 DTM 段,限定词不同,日期的含义天差地别。
步骤一:先拿到 implementation guide,再动手映射
每个交易伙伴的 850 实现指南(implementation guide)都不一样,有的甚至同一个零售商不同事业部用不同版本。动笔建映射表之前,先把这三件事问清楚、写进文档:
- 日期语义:DTM 段的日期到底是"希望到货日""必须到货日"还是"最早可收货日"?口头确认不算数,要买方 EDI 联系人邮件回复。
- 单位代码表:EA、CS、PL、CA……对方用哪套?箱和件的换算关系谁维护?
- 必填段清单:哪些段缺了就直接拒收,哪些段缺了可以进人工队列?
步骤二:EDI 850 字段映射对照表,一个字段都不能含糊
这是整篇文章最值钱的一张表。左边是 850 的段和元素,右边落进 WMS 的字段,中间那列"备注"写的是我踩过的坑:
| 850 段/元素 | 含义 | 落入 WMS 字段 | 备注 |
|---|---|---|---|
| BEG03 | 采购单号 | purchase_order_no | 唯一键,重复报文靠它去重 |
| BEG05 | 单据日期 | order_date | 注意买方时区,跨时区项目必踩 |
| N1(BT) | 账单方代码 | buyer_code | BT 是 Bill-to,别和 ST 搞混 |
| N1(ST) | 收货方代码 | ship_to_code | 决定货进哪个仓,多仓项目关键字段 |
| PO101 | 行号 | line_no | 行取消、行变更全靠它定位 |
| PO102 | 订购数量 | ordered_qty | 必须和单位限定词一起读 |
| PO103/PO104 | 单位代码 | uom | EA/CS/PL,静默变更的重灾区 |
| PO105/PO106 | 单价 | unit_price | 对账金额的基准 |
| PO107/PO108 | 物料代码 | item_code | 买方料号和供应商料号要建对照表 |
| DTM(002 等) | 交期 | requested_date | 语义必须书面确认,见步骤一 |
| CTT01 | 总行数 | total_lines | 校验报文完整性,对不上就整单挂起 |
| REF | 参考号 | reference_no | 先进日志,不进业务表(见后面的反常识判断) |
步骤三:EDI 850 异常报文处理,先定流程再谈自动化
收到 850,第一件事是回 997 功能确认——注意,997 只确认"我收到了、语法没问题",不代表"我接受这张单"。业务校验不过,要走异常流程。异常就这几种,建表的时候把处理动作写死:
- 缺 PO1 行 / CTT 行数对不上 → 整单挂起,转人工,当天必须处理。
- 物料代码在对照表里找不到 → 行挂起,通知采购补对照,超时自动升级。
- 单位代码不在白名单 → 行挂起,先别急着映射,先问买方是不是改了代码表。
- 交期早于今天 → 挂起,可能是买方重发了历史单。
- 采购单号重复 → 直接丢弃并记日志,997 正常回(买方重发是常态,别重复建单)。

处理时限要写进实施文档:一般异常 4 小时内有人看,挂起整单的 2 小时内必须有人看。没写时限的异常流程等于没有流程。
步骤四:对账——三单匹配必须和映射表同一天上线
反常识的判断来了:很多项目把对账当成"二期优化",先让 850 跑起来再说。我的判断恰恰相反——对账脚本必须和映射表同一天上线。在我经手的 EDI 850 purchase order mapping 项目里,机器跑通不代表跑对:单位错、日期错、小数点错,这些错误静默得很,错了两个月才发现的项目我见过,盘库才对出来。
对账就做三单匹配,每天跑批:
- 850 的 ordered_qty(订了多少)
- 856 ASN 的 shipped_qty(发了多少)
- WMS 的 received_qty(实收了多少)
- 810 的 invoiced_qty(开了多少)
四个数两两对,差异超过阈值(比如数量差 1% 或金额差 50 美金,按客户定)就报警。报警要到人,不要只记日志——记日志的报警等于没报警。
两个真实的翻车现场
2025 年初,一家给大型商超供货的加州 3PL 仓。供应商的 850 里,PO1 的单位代码从 EA 悄悄改成了 CS,买方没通知。映射表还按老逻辑把数量直接写进 ordered_qty,结果 WMS 里这单的数量是实际的 12 倍(1 箱=12 件)。三天后拣货才发现货不够,紧急补单加空运,折腾了一周。教训:单位代码变更必须做监控——每天跑批比对单位代码的分布,出现新代码立刻报警,而不是等业务发现。
另一个是中西部一家食品分销仓。买方 850 的 DTM 段用的是"希望到货日",实施方按"必须到货日"理解,排了入库计划。供应商提前两天把冷藏车开到了,冷库没空位,车在门口等了一下午,司机差点把货拉走。这个坑的根子在步骤一:日期语义没有书面确认。口头说"就是交期"的那种,十次有九次两边想的不是一回事。
上线前夜 checklist
- 拿买方三份真实历史 850 报文做 replay 测试,别自己手造——手造的报文永远测不出真实世界的脏数据。
- 单位代码白名单、物料对照表、日期语义确认邮件,三样齐了才准上线。
- 997 回执监控:买方没收到 997 会重发,重发处理不好就是重复建单。
- 对账脚本跑起来,先跑一周历史数据,差异清零再开正式流量。
- 异常处理值班表:谁看、几小时内看、升级给谁,打印出来贴墙上。
EDI 850 的字段映射,技术难度从来不是最高的,难的是把"买方到底想说什么"这件事钉死。这也是为什么我总说:EDI 850 purchase order mapping 的成败,一半在映射表,一半在对账。明天就能做的一件事:把你现在对接的那个买方的 implementation guide 翻出来,检查 DTM 和单位代码那两页——八成有惊喜。
作者:林晓|WMS 实施顾问








