跳至正文

集成与 ERP

Magento 与 SAP 集成:真正会出问题的地方

库存偏差、价格不一致、订单同步缺口,以及决定一套 Magento 与 SAP 集成能否扛住负载的主数据设计判断。

Magento 与 SAP 集成:真正会出问题的地方

Danny Khow,联合创始人兼董事总经理阅读约 7 分钟

Magento 与 SAP 的集成,很少坏在连接层。它们坏,是因为没有人逐个字段地决定过:哪个系统拥有事实,以及当两者在促销期间的凌晨三点各执一词时,应该发生什么。

在 Adobe Commerce 与 SAP 之间传递一段报文,是已经被解决的问题。默认没有被解决的,是归属、顺序、失败处理与对账。Bridzia 在 Adobe Commerce 上投入了 14 年,为零售客户构建过覆盖财务、库存与仓储模块的 Magento 与 SAP 集成,而几乎每一个项目上都会冒出同一份简短的失败清单。以下就是它们,以及如何在设计阶段就把它们排除掉。

库存偏差:前台店铺与仓库不再一致

运营发现网站显示还有四件,仓库却说一件都没有了。两个彼此独立的成因,被归咎到同一个「缺陷」上。

第一个是:SAP 里的库存数字并不是可售数字。某个工厂或存储地点的非限制库存,并不是一个前台店铺可以对外承诺的数量。在两者之间,还夹着针对未清交货的分配量、冻结与质检库存、在途货物,以及供应链团队保留的任何安全库存。把原始数量同步过去,等于在用一个从来就不是拿来销售的数字对外报价。

第二个是:两个系统在不同的时刻扣减库存。Adobe Commerce 在订单下达时预留数量;SAP 通常在交货过账、发货完成时才减少库存,而那可能是几小时之后。在这个时间窗内,两边的数字合理地不一致,而一次简单粗暴的同步,会用一个陈旧的仓库数字覆盖掉一个正确的预留。

绕开它的办法,是把「可售数量」定义为一条明确的公式,与供应链团队达成一致,并在 SAP 侧完成计算。前台店铺只接收一个数字,自己不做任何算术。以较高频率发布增量,再以较慢的周期发布一次完整快照;给每一条消息打上来源时间戳或序列号,对乱序到达的消息直接丢弃而不是应用它。然后在开工之前就决定:可售库存为零时是阻止结账,还是生成缺货订单——因为在 SAP 里,这是两条不同的订单流程。

价格:SAP 拥有价格,前台店铺拥有促销

通常的安排是:SAP 是价格的记录系统,而市场部需要 SAP 一无所知的促销价。这套安排一直可行,直到两个系统开始写入同一个字段——从那一刻起,价格就会按照没人解释得清的节奏,在两个数值之间来回跳动。

价格不是一个值。它至少是三个:SAP 拥有的基础价、购物者看到的促销价(Magento 的目录规则、购物车规则、阶梯与客户组价格),以及随订单实际收取的价格。把这三者分开,冲突就消失了。SAP 只写入基础价属性;Magento 的规则引擎在其之上计算一切,并且从不回写。订单随后携带按行的价格与实收总额,SAP 接受它们,而不是依据条件记录重新计算。如果财务坚持要复核,那就商定一个容差,以及一套针对超出容差行项的处理流程——否则每一笔促销订单都会变成一次人工例外。

这件事中不那么光鲜的另一半是四舍五入。两个在小数精度、舍入方向与税额计算顺序(按行还是按单)上不一致的系统,迟早会算出相差一分钱的总额——而在财务模块里,一分钱足以让一张凭证被拒绝。在架构阶段就把精度、舍入与计税基数定死,然后用您能构造出的最糟糕的购物车去测试:一个按百分比计算的整单折扣,分摊到多种不同税率的商品上,最上面再加一行打了折的运费。

订单同步缺口:只存在于其中一个系统里的订单

两份完全相同的打印订单文件并排放在办公桌上,其中一份略微压住另一份,一支笔横放在两份文件之上。
危险的失败不是一个干净利落的报错。而是那次超时——它让订单只存在于一个系统里,然后又被重试成了两笔。

一笔订单下达了,向 SAP 的传输失败。显而易见的那个版本很好办:明确的报错、一条告警、一次重试。危险的版本是含混不清。请求在 SAP 已经创建凭证之后才超时,于是订单在那边存在,而前台店铺并不知道。盲目重试,您就有了两张销售订单,它们会变成两次交货和两张发票,在三周后由财务人工去拆解。

在这里,幂等不是可选项。给每一笔订单都发送一个稳定的外部参考号,通常就是 Magento 的订单编号,并让 SAP 侧在创建任何东西之前,先检查是否已存在带该参考号的凭证。如果已经存在,就返回它的凭证号,而不是再建一张。这样重试就在构造上是安全的,而这正是您敢于积极重试的前提。

同样重要的一点是:不要在结账请求内部传输订单。把它写入一个发件箱,与提交订单的那个数据库事务在同一事务中完成,再由一个后台工作进程去传输。结账从此不再依赖 ERP 是否可用,而每一笔订单都获得了明确的状态:已排队、已发送、已确认并带回凭证号,或者失败并带上原因。如果您无法用一条查询回答「哪些订单还没进 SAP」,那您拥有的不是一套同步模型,而是一份侥幸。

让故障变得更糟的重试

重试逻辑引发的事故,大致和它预防的一样多。造成大部分伤害的是两种写法:立即以固定间隔重试的循环——一旦队列积压,它会把一次短暂的接口故障变成一场自己造成的拒绝服务;以及对一条永远不可能成功的消息无限重试——它把一个「毒药」报文停在队首,堵住后面的一切。

正确的做法是给失败分类。网络超时、锁竞争与接口临时不可用,都是可重试的:使用带随机抖动的指数退避,并设置硬性的尝试次数上限。而校验类失败——比如缺失的客户主数据、无效的物料,或者已关闭的记账期间——将永远以同样的方式失败,因此要把它们送进死信队列,连同原始报文与真实的错误文本一并保留,并通知到人。再加一个熔断器,让队列在某个接口明显宕机时退避,并在它恢复时以受控的速率排空积压。在顺序重要的地方保持顺序——通常是按实体而不是一条全局序列——这样一次取消就永远不会赶超它所取消的那笔订单。

主数据:在另一侧并不存在的那条记录

多数被拒绝的订单,其实是穿着集成外衣的主数据问题。一个在 Magento 中创建、却从未针对该销售组织在 SAP 中扩展的商品。一位没有对应账户的客户。一处计量单位不匹配——前台店铺按单件销售,而销售单位是十二件一箱。一种没有映射到任何凭证类型的配送方式。

按对象而不是按系统来决定归属。实践中,SAP 拥有物料主数据、基础价、库存与客户的财务身份;Magento 拥有商品描述、图片、分类、SEO 元数据、评价与陈列。然后把这个归属真正执行下去。一次夜间的 ERP 推送,悄无声息地覆盖掉手写的文案与元描述,是这一类问题中最令人沮丧的缺陷:它安静地摧毁真实的工作成果,而 SEO 团队要在数周之后才发现。

维护一张明确的映射表,以稳定标识符为键,而不是靠 SKU 做字符串匹配——因为 SKU 会被改名、会变换大小写。同时决定:只存在于一侧的记录该怎么处理,是静默跳过、在报表中标记,还是禁止销售。把这件事做错的代价不只在账目上。通过 EC Intelligence 建立的客户分层、弃购挽回流程与站内个性化,都会继承集成产出的结果,于是同步了一半的订单,会以错误的顾客终身价值数字和瞄错方向的营销活动重新浮现。

节奏:批量还是准实时,不是一个决定

仓库传送带上,单个纸箱在一条通道中稳定前行,一侧则停着一板装载完毕、等待按计划收货的托盘。
节奏是按对象做的决定,不是按整套集成做的决定。订单随发生随流转;完整的商品与价格加载,则按 ERP 当初就按其容量设计的计划执行。

问这套集成应该是实时还是批量,是个错误的问题,因为答案因对象而异。

事件驱动

订单、取消、发货与状态变更,以及快速动销商品的库存变动。在这里,延迟的代价是用超卖和客服工单来计量的。

定时调度

完整的商品主数据、完整的库存快照、价目表加载、发票与贷项凭证。假装这些批量操作是事件,就会在一个 ERP 当初根本没有按此容量设计的夜间窗口内,产生数以万计的消息。

准实时是有代价的,而这个代价由 ERP 团队用接口吞吐量、表锁与后台作业窗口来支付。在设计任何东西之前,先与他们就数据量达成一致。一场在午夜为数万个 SKU 重新定价的活动,必须以受控批次的形式抵达,而不是化作一场与订单传输争抢同一份容量的消息风暴。

对账:多数集成从来没有构建过的那项工作

每一套集成都会漂移。承认这一点,然后去构建探测器,而不是去否认它。一个可行的基线是:每晚对活跃商品目录中的可售库存与基础价做一次比对,差异在商定容差之内自动修正,超出则告警。再加上一项每日的订单级检查,比对两侧的笔数与金额,列出没有对应 ERP 凭证的前台订单,以及反过来的情况。

产出必须是一份由指定的人来读的简短报告,而不是又一个日志文件。平时总是空白的报告,一旦不空,才会被注意到。

只在负载之下才会出现的失败模式

以上一切在正常数据量下都成立,而它们也总是只在正常数据量下被测试过。有意思的失败发生在大促期间:队列深度增长得比工作进程排空的速度更快,而库存刷新排在一次批量价格推送的后面。要对集成本身做压力测试,而不只是对前台店铺;并且提前决定好,当容量吃紧时先牺牲什么。通常输掉的是库存刷新频率,而不是订单传输。

与之相关的一项纪律,是把 ERP 挡在请求路径之外:加入购物车、结账与下单,其中任何一步都不应该去等待一个不受您控制的系统。Bridzia 维护 Guardian Malaysia 的 Adobe Commerce 平台已超过八年,其间的一次改版让站点性能提升了 200%、销售额增长了 10%——而那种量级的页面速度,与在顾客路径上做同步 ERP 调用是不相容的。

销售渠道又叠加了第二层同步,因为 Shopee、Lazada 与 TikTok Shop 各自持有自己那一份关于库存与订单的视图。这正是 Bridzia 自研的渠道同步技术 WOW Sync 存在的意义,而一份过往项目记录讲述了这一侧如何与门店和仓库库存拼接起来。

到底是什么决定了它扛不扛得住

逐字段的归属,达成一致并形成文档。一条可售库存公式,在一个地方计算。每个价格字段只有一个写入方。以稳定外部参考号为键的幂等订单传输。把重试分为可重试与终止两类,并配一个有人盯着的死信队列。按对象选定的节奏。从第一天就在运行的对账,而不是在第一个糟糕的月份之后才补上。

这些没有一样是光鲜的,而所有这些在架构阶段决定,都比在用户验收测试阶段决定便宜。在一次 Adobe Commerce 项目中,集成是订单一旦开始流转之后最难更改的那一部分。

Bridzia 从吉隆坡出发,为亚洲各地的零售与快消品牌构建并维护 Adobe Commerce(Magento) 平台,已交付超过 100 个项目。如果您正在筹划一次 SAP 集成,或者正在弄清一套现有集成为何总是漂移,欢迎与我们联系

继续阅读

相关文章

更多关于平台、集成,以及买家如何发现品牌的内容。

有项目正在筹划?