Qeasy Cloud
Get Started

对接 ERP 踩过的 6 个坑:字段名会骗人,成功也会说谎

· 高金凤· AI Financial Reconciliation· 11 views· 8 min read
ERP接口对接字段映射推送失败

摘要:ERP 对接失败的原因,很少是「不会调接口」。多数是把文档当成了事实:字段名以为抄对了、请求体以为放进去了、返回成功以为成了。这篇把 6 类反复出现的坑按现场还原,每类给出识别方法和防御动作,并说明重试、限速、人工补偿这三道防线各自的边界。 关键词:ERP 对接踩坑、金蝶云星空接口、用友集成、SAP 集成、推送失败排查

一、最贵的一句话:文档上就是这么写的

一个真实的对接现场。接口调通了,测试环境跑了几十笔都正常。上线第一天,第一张单推送失败,报错是一个看不懂的字段校验错误。

排查三个小时,原因很小:文档里字段写的是 FBillNo,实际接口要的是 FBillNo 之外还有一层 FEntity,而我们的代码把整张单平铺着送过去了。

这类坑最伤人的地方在于它不可预判:测试环境能过,说明业务逻辑是对的;但测试用例覆盖不到「结构层级」和「字段语义」这两种错误,它们只在上线后真实单据上暴露。

把常见坑归纳一下,基本是六类。前五类都发生在「你以为你抄对了」,第六类发生在「你以为你成功了」。

二、命名类:大小写、会话标识、备注名

坑一:字段名大小写与文档不一致。 文档里写 FNumber,代码里写 Fnumber,看起来一样,实际是两个键。有些接口对大小写宽容,有些直接忽略这个字段——不报错,只是数据没进去。这比报错更难查,因为请求成功、响应成功,只有你回头核对单据时才发现某个字段是空的。

识别方法:不要凭肉眼比对,把请求体字段清单和单据回读字段清单做一次机器比对。防御动作:请求体字段名集中在一个映射表里,不在业务代码里散写。

坑三:会话标识的大小写。 这类接口通常要先拿会话或用票据,票据字段名在不同版本里大小写不同。表现是「偶尔鉴权失败」,因为在某些调用路径下用的是缓存票据,缓存里那份是对的,新建的那份是错的。排查时容易怀疑到网络或并发,其实只是键名拼错了。

坑五:备注字段名与文档不符。 备注、摘要这类字段最容易被写错,因为它们在文档里通常有多个近义名(说明、备注、摘要、附言),而实际接口只认其中一个。表现是备注全部为空,但单据主体正常——于是没人发现,直到业务说「这张单看不出是哪批货」。

这三类的共同点是:它们不会让请求失败,只会让数据悄悄缺失。所以真正的防御不是小心,是回读校验——推完必须读回来比一次,不相等的字段要报出来。

三、结构类:请求体必须嵌套一层

坑二:请求体必须嵌套一层。

这是最典型的一种。文档给的示例是「表头字段 + 表体数组」,但示例的 JSON 是缩进展示的,很多人照着写成了平铺结构。接口收到之后不会报「结构不对」,而是把表头字段当成未知字段忽略,只处理了表体。

结果:单据生成了,但单据上的关键信息(日期、往来单位、单据类型)全是空的或者默认值。这种单据在系统里是「有效」的,能审核、能记账,只是内容不对。等到财务发现金额不对,已经过去几天。

集成转换骨架:表头与表体的层级映射关系

防御动作:把请求体结构写成模板(表头一层、表体一层、字段映射一层),用模板渲染而不是手工拼 JSON。模板还有个好处:换平台只换模板,不动代码。

四、语义类:那个字段其实是另一张单的

坑四:供应商字段其实是应付单的。

这个坑的杀伤力最大,因为它看起来完全正常。你在做应收方向,看到接口里有个「供应商」字段,想当然认为它可以填客户,或者认为它用于备注来源。实际上这个字段属于应付方向的单据结构,在应收单据里传它,要么被拒绝,要么被当成另一个维度存进去,造成对账时金额挂在错误的往来单位上。

这类坑的根源是把「字段存在」当成「字段属于我」。一个接口往往同时服务多个单据类型,字段表是并集,不是交集。

识别方法:拿真实的、已审核的单据做回读,看每个字段的取值来源。防御动作:字段表按单据类型分别维护,不要共用一张全量表。

五、语义类之二:成功也会说谎

坑六:成功响应不等于业务成功。

很多 ERP 接口在业务校验失败时,HTTP 状态仍然是 200,只在响应体里返回一个业务状态码或错误列表。如果你的代码只判断 HTTP 状态,就会把失败当成功,继续推进后续流程——推送日志里一片绿色,实际单据一张没生成。

这个坑最阴的地方是延迟暴露:当天看不出问题,月底对账发现少了几十张单,回头查日志全是成功。

正确做法是双判定:HTTP 层判定通信成功,业务层判定单据是否真的生成、状态是否真的正确。两者都过才算成功。业务层判定的最可靠方式是回读:按单据编号或业务订单号反查,确认存在且关键字段一致。

这一条也是我们做推送设计时最先定下的规矩:一次推送的结果不是「请求返回什么」,而是「单据在对方系统里处于什么状态」。轻易云的转换与推送链路里,成功与否以回读状态为准,HTTP 状态只用来决定要不要重试。

六、三道防线:重试、限速、补偿

坑认全了,还得有防线,否则每次都要人守着。

第一道:自动重试。 只对「可重试错误」重试——网络超时、对方限流、临时不可用。参数错误、字段校验失败这类重试一万次也不会成功,必须直接判失败并报警。重试用指数退避,次数不宜多,三到五次足够;间隔从秒级起,避免连续冲击对方。

第二道:限速。 批量推送时最容易出事。对方接口能承受的并发和频率通常远低于你的处理速度,不限速的结果是被限流、被临时封禁,甚至影响当天其他业务的推送。做法是给推送队列设一个固定速率,宁可慢一点,也要稳。速率起步按每分钟几十次,再根据对方文档和实际响应调整。

第三道:人工补偿。 有些失败是自动处理不了的:单据已存在、期间已关闭、对方数据被人工改过。这类必须落到一个人工队列里,有明确的责任人和处理时限,不能只在日志里留一行红字。

集成中心架构:推送队列、重试、限速与人工补偿队列

三道防线的边界要写清楚:哪些错误自动重试、哪些直接失败、哪些进人工队列。模糊的边界会导致两个后果——该重试的没重试,或者该人工的反复重试把对方的额度耗光。

七、日志该留什么

推送日志不是给开发看的调试输出,是给财务和审计看的证据。所以要留四样东西:

一是请求的时间、单据标识、目标系统,让任何一笔都能被定位;二是请求体的关键字段快照(不是全量,全量太大且可能含敏感信息);三是响应体原文和业务状态码,区分「通信失败」和「业务失败」;四是重试次数与最终结果。

有这四样,月底谁问「这张单为什么没推到」都能在两分钟内回答。只留一行「推送失败」,等于没留。

集成带来的业务价值:从人工补单到流程可控

这也是我们把集成转换做成独立一层的原因:转换规则、推送、重试、失败处置各自有位置,出问题能定位到层,而不是在一段几百行的脚本里找。轻易云的做法是把「结构映射」和「业务判定」拆开,映射错了改模板,判定错了改规则,互不牵连。

八、上线前的一张自检表

六个坑讲完,落到能执行的东西上。下面这张表建议在上线前逐项过一遍,每项都要有「谁确认、证据在哪」,不要只在会上说一遍。

检查项判定标准谁确认
字段名一致性请求体字段清单与单据回读字段清单机器比对,差异为零集成开发
请求体层级表头 / 表体 / 映射三层结构与模板一致,不用手工拼 JSON集成开发
会话票据键名新建与缓存两条路径都能鉴权成功集成开发
字段归属每个字段标注所属单据类型,跨方向字段不共用实施顾问
备注类字段推送后回读,备注不为空实施顾问
成功判定业务层回读通过才算成功,HTTP 200 不算集成开发
重试白名单可重试错误有明确清单,清单外一律不重试集成开发
限速配置推送队列有固定速率,压力测试下不触发对方限流集成开发
人工队列有责任人、有处理时限、有每日清理机制财务经理
日志四要素时间、单据标识、请求快照、响应原文齐全集成开发

这张表的价值在于把「经验」变成「检查」:六个坑里任何一个没人认领,都会在上线后以故障的形式重新出现。

顺带说一句顺序:先做回读,再做重试。很多团队反过来,先把重试写得花团锦簇,结果回读没做,失败了也发现不了,重试只是在重复错误。回读是地基,重试是加固。这张表也不该只在上线前用一次——每次换接口版本、换平台、换对接人,都值得重新过一遍,因为坑的形状会变,底层的判断标准不变。

九、给顾问的四条动作

第一,把字段表按单据类型分开维护,别再用一张全量表去套所有方向。供应商字段的坑,本质就是这张表没分开。

第二,推送成功一律以回读为准。HTTP 200 只说明对方收到了,不说明对方办成了。

第三,重试范围先写清楚再写代码:可重试错误用白名单,不在白名单里的一律不重试。

第四,留一个有人负责的人工补偿队列。凡是「自动处理不了」的失败,都应该有人知道、有人管、有时限。

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/reconciliation/14-7-erp-integration-pitfalls

Comments