What is contribution margin?
Contribution margin is what is left of an order's revenue after the costs that scale directly with it: the cost of the goods sold, the shipping it cost you to fulfil, and — for marketplace orders — the fees the marketplace reports against the order. It excludes fixed overhead — rent, salaries, software — on purpose: it answers "does selling one more of this make money," not "is the business profitable," which is a separate, larger question (net operating profit).
Formula
contribution margin % = (net revenue − COGS − shipping cost − payment fees − marketplace fees) ÷ net revenue
Worked example
A product line sells for €50,000 of gross revenue, with €2,000 of order-level discounts applied (net revenue €48,000), all sold through your own store. Cost of goods sold is €22,000 and shipping cost allocated to those orders is €3,000; there are no marketplace fees. Contribution margin is €48,000 − €22,000 − €3,000 = €23,000, or 47.9% of net revenue.
How Saldo Metrics computes it
canonical.v_contribution_margin is the line-item-grain source every other margin
figure in the product rolls up from, counting completed sales only — cancelled
orders, and orders refunded in full, are excluded, which is the intended
definition of a countable sale across the app. For each order line it takes
line_revenue_base, subtracts that
line's pro-rata share of the order's discount (allocated_order_discount_base), the
resolved unit cost from cost_source_record times quantity (line_cogs_base — the
highest-trust confirmed cost record valid on the order date), and that line's pro-rata
share of the order's shipping cost, any marketplace order fees the platform
reports, and the order's payment fee (allocated_overhead_base). The payment fee
comes from the merchant's own fee rules — a percentage plus a fixed amount per
payment method, optionally by country and date range — priced against every order.
The shipping cost comes from the merchant's own carrier tiers, priced by carrier,
weight, destination and order value.
An order whose shipping cost no tier matches, or whose payment fee no rule
matches, is treated exactly like an order with no confirmed product cost: its
margin is unknown, not zero. contribution_margin_base is NULL for every
line of that order (not just a partial figure with the missing charge silently
read as free), the same order-grain rule described below for a missing product
cost. This is deliberate: an org with no carrier tiers or no fee rules
configured yet would otherwise show an inflated margin on every order until it
finishes that setup. A platform-fulfilled marketplace order (FBA and
equivalents) is not affected by the shipping leg of this rule — its shipping
cost is already captured as a marketplace fee, not a merchant carrier charge —
and a marketplace order's payment fee is always a resolved 0 (its referral
commission already includes payment processing), never "missing." All
four inputs are *_base (EUR) columns: every margin figure is arithmetic on amounts
already converted to euros at the ECB rate for the transaction's own date, so no
metric is computed from mixed currencies. Displaying that figure in a non-euro
currency is a separate, final step applied to the finished number at one as-of rate.
Two populations read off this figure. The per-product, per-brand, per-category and
per-supplier rollups below stay on v_contribution_margin's net-sale population.
The P&L, net operating profit, order-level and SKU-level net profit, the store,
channel and geo-opportunity margin and cost-coverage breakdowns, the
v_country_revenue view, and order accounting's own margin column all instead read
v_contribution_margin_all, which also books orders refunded in full — the shipping
and marketplace fees those orders cost you were already spent and are not coming back,
so leaving them out would erase real cost from exactly the figure meant to catch it,
without erasing the revenue it earned. The revenue-by-country widget is not one of
them: it reads order accounting filtered to net sales, so its margin covers net-sale
orders only.
Two rollups aggregate that line-grain view to the grain their keys need:
v_product_margin (top_margin_products, worst_margin_products,
product_margin_pct) and v_brand_margin (brand_margin, brand_margin_pct).
category_margin and supplier_margin group v_contribution_margin directly by each
product's primary category or primary supplier, so they follow the dashboard's period
and store filters. Each sums margin and net revenue at its grain and divides. avg_margin_pct is the
average of v_product_margin.margin_pct across every product; margin_total_30d sums
contribution_margin_base directly from v_contribution_margin over the trailing 30
days.
A refund is netted against the order it came from, not the month it happened in. When
goods actually come back, both the revenue and the cost of those units reverse — so a
March order refunded in April still corrects March's figure, because that is the sale
being unwound. Shipping and marketplace fees are not reversed: you already spent them
getting the order out, refunded or not. A refund with nothing returned — a goodwill
credit for a damaged box, say — reverses only the revenue; the goods are still gone,
so their cost stays charged. That distinction runs on the number of units the
platform reports as returned, not on the refund amount: v_refund_reversal reads
that count off each refund event, and when a platform cannot report one, the cost
stays charged rather than being guessed, with the line marked
refund_quantity_unknown so it can be told apart from an ordinary one.
Why it matters
Revenue tells you what sold. Contribution margin tells you what selling it was worth — a bestseller with thin margin can contribute less to the business than a slower mover with a healthy one. Reprice, delist and product-mix recommendations are all built on this figure, not on revenue.
Common mistakes
- Reading contribution margin as net profit. It excludes fixed overhead by design — a business can have healthy contribution margin on every order and still lose money if overhead outgrows it. Net operating profit is the figure that includes overhead.
- Comparing margin % across products at very different price points without checking absolute margin too — a low-price, high-margin-% item can contribute less cash than a higher-price item at a lower percentage.
- Trusting a margin figure with a high missing-cost rate. A line with no
confirmed cost record has no margin at all — it drops out of margin totals rather
than counting at a COGS of zero — so a product with incomplete cost data is
measured on its costed lines only. The same applies at order grain to an
unresolved shipping cost or payment fee: it nulls out the margin for every
line of that order, not just the missing charge.
v_contribution_marginexposes the combined reason per line asmissing_cost, and the specific one asmissing_product_cost/missing_shipping_cost/missing_payment_fee;v_product_marginrolls the combined flag up per product asany_missing_cost. See also the shipping-cost coverage and payment-fee coverage panels in org settings, which report how many orders are still unresolved and why. - Comparing this month's figure against the same month on the P&L. The two date refunds differently on purpose — this figure corrects the order that was refunded, the P&L books the refund in the month the credit note cleared — so they can disagree on a month with late refunds. See net operating profit.
Where you see this in the app
Dashboard, in the average margin KPI and the top/worst margin product tables; and the brand, category and supplier margin breakdowns across the app's profitability views.