月底利润被运费和手续费吃掉?Medusa 成本核算与利润分析完全指南
【免费下载链接】medusaThe world's most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusa
月底对账时,一个熟悉的场景:流水不错,毛利却被运费、支付手续费、仓储费悄悄削薄,账面上看不出问题,落袋的钱却总差一截。症结往往不是卖得贵不贵,而是成本没算清——商品成本、运营开销、利润三条线混在一起,谁在亏钱都说不明。
开源电商平台 Medusa 的定价模块(PricingModule)把商品价格这件事拆得很细:基础价、价格列表、价格规则各司其职,算完商品侧的成本与售价,再配合订单模块把运费、税费、支付费用归到每笔订单上,利润才有得算、有得看。下面按"一笔订单从产生到算出利润"的链路,把这条路走一遍。
一笔订单里,钱到底怎么流
先把账本框架搭起来。一单成交,钱和成本分三块走:
- 商品侧:售价(可能经过价格列表、促销调整)、商品成本、税费
- 履约侧:运费、仓储、打包耗材
- 通道侧:支付手续费、退款损耗
Medusa 里这三块分别由定价模块(@medusajs/pricing)、履约模块、支付模块承接。成本核算的关键,是让每一笔钱都能落到某一块里,而不是全摊进"其他支出"。
定价模块如何算清商品成本
定价模块的核心入口在 packages/modules/pricing/src/services/pricing-module.ts,服务类PricingModuleService对外的主要动作就是calculatePrices:给定一组价格集合(price set)和上下文,返回最终命中的价格。
它内部遵循一条明确的取舍逻辑:
- 命中OVERRIDE 类型的价格列表时,直接用列表价;多个 OVERRIDE 同时命中,取最低
- 命中SALE 类型的价格列表时,取列表价与默认价中的较低者
- 都没有命中,落到默认价(即商品上登记的基准价)
这套规则的意义在于:算利润时,"原价"和"实售价"是两码事。OVERRIDE 决定了客户真实参照价,SALE 决定了成交底价,calculatePrices把二者区分开返回,后续算毛利时就不会把促销让利误当成商品成本。
价格规则(price rule)支持按客户组、区域等属性匹配,比如给德国、丹麦区域或 VIP 客户组挂不同的价格。仓库里的集成测试 calculate-price.spec.ts 就用"两个区域 + 两个客户组"的矩阵反复验证了这套匹配逻辑,可以当作理解商品成本结构的现成样例。而真正执行 SQL 级价格匹配的是 packages/modules/pricing/src/repositories/pricing.ts 中的calculatePrices仓储方法,它负责把规则属性展开成数据库查询,找出全部候选价格。
一句话概括商品成本结构的算法:基准价定成本锚点,价格列表定售价区间,calculatePrices 定最终成交值。
把隐性运营开销翻出来
商品成本算清后,剩下最难的是运营开销——它们不像进货单那样自带金额,散落在订单的各个字段里。
固定成本与变动成本,先分家
| 类别 | 典型科目 | 特征 |
|---|---|---|
| 固定成本 | 服务器/云托管、订阅服务、人力 | 与单量无关,按月刚性支出 |
| 变动成本 | 运费、支付手续费、包装材料、仓储耗材 | 随每笔订单发生,可归因到具体 SKU |
分家的价值在于:固定成本决定盈亏平衡点(要卖多少单才回本),变动成本决定单笔毛利(这一单赚不赚钱)。两类混在一起,调定价时就会踩空。
从订单数据里把变动成本捞出来
Medusa 的订单模块把每笔订单的运费(fulfillment)、税费(tax)、支付相关金额都结构化挂在订单对象上,按订单或按 SKU 聚合,就能得到"每单变动成本"。做法是:
- 按时间段拉取已支付订单
- 从每单里取运费、支付手续费、商品采购成本
- 按 SKU 摊分(多件订单按金额占比拆)
- 得到每个商品的"变动成本单价"
固定成本则按月单独记账:云托管、人员、软件订阅,摊到月销量上就是"每单固定成本分摊"。两步做完,任何一笔订单的毛利都能写成:成交价 − 商品成本 − 变动成本 − 固定成本分摊。
单品利润和整体利润,分别怎么看
单品利润:找到该调价的商品
单品利润直接用calculatePrices的输出做:
单品毛利 = 实售价(OVERRIDE/SALE 命中后的值) − 商品成本 − 该 SKU 的变动成本单价
把全店 SKU 按毛利率排个序,头部和尾部的处理方向完全不同:尾部长期为负的,要么提价、要么换供应商、要么下架;头部且走量大的,优先保障库存。这一步的价值是把"感觉哪款不赚钱"变成一张可执行的清单。
整体利润:报表只看三行
整体层面不需要多复杂,三行数字就够决策:
- 收入行:成交价合计(剔除退款)
- 成本行:商品成本 + 变动成本 + 固定成本分摊
- 利润行:两行相减,再和上月对比
Medusa 的利润分析逻辑本质就是这两次聚合,数据源全部来自订单和定价模块,不需要额外财务系统。云托管版本(Medusa Cloud)则把这些报表直接做成后台页面,适合不想自己写聚合逻辑的商家。
三步上手:配置、录数、对账
第 1 步:拉代码并安装依赖
git clone https://gitcode.com/GitHub_Trending/me/medusa cd medusa yarn install这是 monorepo,定价模块在packages/modules/pricing,主应用入口packages/medusa已通过 packages/medusa/src/modules/pricing.ts 把它注册为内置模块,开箱即用。
第 2 步:配置定价模块
- 在商品/变体上登记默认价(即成本锚点之外的基准售价)
- 需要分层售价时,建价格列表:批发客户用 OVERRIDE,大促用 SALE,各配好生效规则和时段
- 按区域或客户组给价格列表挂匹配规则(
rules字段)
第 3 步:对账与调优
每月固定时间跑一次三行报表:单品毛利率排序找异常 SKU,整体利润环比看趋势。发现运费占比抬升,先查履约方案;手续费占比抬升,看是否该切换支付通道。成本核算不是一次性动作,节奏比精度更重要。
写在最后
成本核算这件事,Medusa 没有替你记账,但它把价格规则、订单结构、模块边界都收拾利索了,剩下的只是按"商品侧、履约侧、通道侧"把数归位,再让固定与变动成本各归各账。账清了一件事就会变:调价、选品、砍品类,都可以拿数字说话,而不是凭手感。先把calculatePrices这条链路跑通,再往外扩,成本这件事就没有想象中那么吓人。
【免费下载链接】medusaThe world's most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusa
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考