结论
多币种店铺算成本,有一类费用是没有天然币种的:平台月费、软件订阅、共享广告、仓库固定开销。它们不属于任何一个币种,但你必须把它们摊到每个店、每个订单上。
摊的时候要折算,折算要用汇率,而汇率得先选一个币种。
如果系统选币种的规则是「这个月结算额最大的那个」,你就麻烦了。
那个月越南店卖得好,整批共享费用就按越南盾的汇率折。人民币店的成本跟着变——变的不是它的生意,是它邻居的生意。
现象:什么都没改,成本率跳了
有一阵子我盯着一个店看,连续三个月的成本率大概稳在一个区间。第四个月突然往上跳了一截。
第一反应是查采购价。没变。查物流。没变。查平台费。也没变。
然后我把那个月的费用明细拉出来逐行看,发现异常全部集中在共享费用那几行——就是那些不属于具体订单、按月摊的那种。而这几行的金额本身没错,错的是它们折算成人民币用的那个汇率。
那个汇率,是越南盾的。
代价:你会在错误的店上做决定
单看一个月,成本率跳两个点,你会以为是季节性波动,忍了。
连着几个月,你会开始做一个真实的决定:这个店是不是不赚钱,要不要关掉。
而真相是:这个店的成本率有一部分是「上个月越南店卖得好不好」的函数。你拿它跟另一个店比,比的不是运营效率,是两个店的规模在互相污染对方的账。
这类错误最贵的地方在于它看起来完全正常。没有 NULL,没有负数,没有对不上的合计。每一行都算得出来,加起来也对,就是不该这么算。
根因:把「选一个币种」当成了技术细节
共享费用要摊,就得有个记账币种。这件事在系统里通常被当成一个实现细节,用最简单的规则解决:取金额最大的那个币种的汇率。
这个规则在单币种场景下永远正确,所以它从来没被质疑过。一旦混币种,它就变成一个隐式的、随生意波动而变化的参数——你的账本里多了一个没人声明过的变量。
更麻烦的是它有三层:
- 选币种用了一个规则(比如「最大结算额」);
- 取汇率用了一个日期(月初?月末?结算日?);
- 分摊计算又可能在中途做一次单位换算和四舍五入。
这三层任何一层不一致,结果都会错,而且错得很平滑——不会跳变,不会有异常值,只会每个月差一点点,直到某个月你偶然发现。
怎么自查(三步,能定位到行)
第一步:把汇率钉死,重算一遍。
拿最近三个月,把共享费用的折算汇率统一替换成一个固定值(随便哪个,只要一致),重算。如果差异全部集中在共享费用那几行,问题就锁定了,不用再往下猜。
第二步:看这个汇率是不是每个月在换币种。
把三个月里共享费用实际使用的汇率列出来,看它们是不是来自不同币种。如果是,说明选币种的规则在跟着生意波动跑。
第三步:看分摊链上是不是同一套币种。
同一笔共享费用,分子(这笔钱多少)、分母(按什么权重摊)、结果(每单摊到多少),这三处必须都在同一个币种域里。任意一处换了币种,或者中途来回折了一次,数字就会漂。这一条最容易漏,因为三处往往写在三个不同的地方。
可以直接抄走的三条
- 共享费用必须显式指定记账币种,并且把「用了哪个汇率、取哪一天」写进数据里。 不要让它每次重算时重新选一次——那等于让结果依赖当月的生意结构。汇率是行级事实,不是平台常量。
- 分摊链上的分子、分母、结果,必须声明同一个币种域。 写代码时把这三处的币种当成一个参数传下去,而不是各自去查。
- 不要在单位换算处逐单四舍五入。 几千单各舍一次,合计能漂出几十块;这个误差会伪装成「分摊没摊平」,让你去查一个不存在的问题。要舍就在最后一步舍一次。
边界
单币种平台不存在这个问题,一分钱都不会差。
多币种但共享费用占比很小的(比如只占营收的零点几个百分点),影响可以忽略,不值得为它改架构。
真正需要在意的是:共享费用占比高 + 多币种 + 要跨店比较。三个条件同时成立时,这个坑一定会咬你,而且是在你做关店决策的那个月咬。
这一类坑有个共同点:系统替你做了一个选择,但没告诉你它做了。
上一篇那笔「退款管理费」也是——它替你选了「这笔钱算退款」,其实不是。下一篇讲域名:它替你选了「到期会自动续」,其实不会。