How to calculate your true Shopify profit margin (with the spreadsheet template most brands need)
Shopify shows revenue. Ad platforms show ROAS. Neither shows your real Shopify profit margin. Here's the operator's formula, the spreadsheet schema, and where the leaks hide.
Most Shopify operators we talk to can quote their revenue to the dollar and their ROAS to the second decimal. Ask what their net margin was last month and you get a pause, a guess, and "I'd have to check with the bookkeeper."
That gap is where brands die. Not from a bad product — from running on numbers that look like profit and aren't.
A brand we worked with last quarter: $2M trailing-twelve revenue, 35% gross margin on the line sheet, 25% ad spend. Their dashboard said "comfortably profitable." When we rebuilt their P&L per order, 30% of orders were losing money — small AOV orders into expensive shipping zones, with full ad attribution, paid via BNPL at 5.99%. The brand wasn't unprofitable overall, but a third of its volume was actively destroying enterprise value, and the founder didn't know.
This is a hub piece on how to calculate your true Shopify profit margin — order-level, country-level, monthly P&L. The formula, the spreadsheet structure most brands need, and the failure modes of every shortcut we've seen.
Why Shopify Analytics and your ad dashboards won't get you there
Two reasons:
- Shopify Analytics is a revenue tool, not a profit tool. It does not know your COGS unless you've populated it perfectly per variant (almost no one has), it does not see your ad spend, it does not pull gateway fees correctly, and it averages shipping cost rather than reporting per-order. The "Net sales" number is real revenue net of discounts and refunds — it is not net profit.
- Meta, Google, TikTok and Pinterest each report ROAS in their own attribution model. Add them up and you'll over-count by 20–60%. ROAS is a media efficiency metric, not a margin metric. Two stores with the same 3.0× blended ROAS can have wildly different net margins depending on COGS, shipping, returns, and gateway mix.
To get to a real number you have to do something neither tool does: combine revenue, COGS, fulfillment, fees, refunds, and ad spend at the order grain, then aggregate up. That's the work.
Step 1 — Get revenue right (gross, net, and what to actually use)
Three numbers commonly get called "revenue":
- Gross sales = sum of (price × quantity) before any reductions.
- Net sales = gross sales − discounts − returns. Shopify reports this.
- Net revenue = net sales − sales tax − shipping income (depending on policy).
For margin work, start from net sales and treat shipping income as a separate line that nets against shipping cost. Sales tax is not your money. Never use gross sales for margin math.
Where Shopify Analytics misleads: the default "Total sales" view includes shipping and tax. If you forecast margin off that, you'll over-state net sales by 8–14% on most stores. Switch to the "Net sales" custom report and pin it as default.
Step 2 — Get COGS right (and the part everyone misses)
Per-order COGS is not just the line item cost on your supplier invoice. It's:
COGS_per_order = Σ (item_unit_cost × quantity)
+ packaging_cost
+ pick_pack_labor
+ inbound_freight_amortized
The four pieces:
- Item unit cost — your landed cost from the supplier, in your reporting currency, at a sensible exchange rate (recompute quarterly).
- Packaging cost — outer box, mailer, void fill, tape, branded inserts. On a $50 AOV brand we've seen this run $1.20–$2.40. It is not negligible.
- Pick/pack labor — internal hourly labor or 3PL pick-pack-per-order fee. Typical 3PL is $2.50–$4.00 per order in 2026.
- Inbound freight — the per-unit cost of getting product from factory to warehouse, amortized over sell-through. Frequently ignored. Brands importing from Asia routinely have $0.40–$1.10 per unit of inbound freight that never shows up on the line sheet's gross margin.
If you maintain unit costs by hand inside Shopify variants, you'll get this wrong as soon as a supplier price changes. This is where Ecombone Inventory earns its keep — it stores landed cost (item + freight + duty) per variant per period and feeds that into the profit calculation.
The discipline: every SKU has a landed unit cost (item + freight + duty), and every order picks up a fulfillment cost (packaging + pick/pack). Both are COGS, both belong on the order.
Step 3 — Shipping cost, per order, never averaged
The most common mistake we see: brands take "total shipping spend last month / orders shipped" and apply that flat number to every order. That hides the entire cross-zone margin question.
A $50 sweater into Zone 2 might cost $6.20. The same sweater into Zone 8 (or international) might cost $14.80. Average them and every order looks like $9.50. Reality: half your orders are massively margin-positive, half are barely break-even or worse.
Pull shipping cost per order from your carrier or shipping platform (ShipStation, Shippo, EasyPost, Shopify Shipping) and match it back to the Shopify order ID. If you can't get per-order, get per-zone-tier — but don't accept a single average.
Track shipping income separately (what the customer paid). Net the two. Shipping is rarely a profit center for DTC; the goal is to keep it from being a leak.
Step 4 — Gateway and BNPL fees (small per order, large at scale)
Each payment method has its own fee structure. Sample 2026 numbers (varies by region):
| Method | Typical fee |
|---|---|
| Shopify Payments (US) | 2.4–2.9% + $0.30 |
| PayPal | 3.49% + $0.49 |
| Klarna / Afterpay (BNPL) | 4.99–6.99% + $0.30 |
| Shop Pay Installments | ~5.99% |
| Amex (variable) | 3.5–3.9% |
On a $50 order with a 2.9% gateway: $1.75. With Klarna at 5.99%: $3.30. Across 5,000 orders/month, you're at $7,500–$16,500 of gateway fees, and BNPL mix shift alone can move net margin by 0.6–1.4 points.
Pull actual fees from Shopify Payouts, PayPal Activity, and your BNPL provider. Don't assume — BNPL takes a higher cut and adoption has only grown.
Step 5 — Returns and refunds (the line that hits margin twice)
A return doesn't just reduce revenue. It hits you for:
- The refunded revenue (already net out of net sales).
- The original outbound shipping (gone, not refunded by carrier).
- Inbound return shipping (if you offered free returns).
- Re-pick / re-shelve labor ($3–6 per return).
- Restocking only at "saleable" condition — damaged stock is a write-off.
On the worksheet, leave net sales net-of-refund (Shopify reports it that way) and add a "return cost" line that captures the residual outbound + inbound shipping + handling that doesn't come back when the revenue does. On a brand with an 18% return rate, this line alone is 2–4 points of margin.
If your return rate is north of 12%, push it down before optimizing anything else. We wrote about that here: how to reduce return rates on Shopify.
Step 6 — Ad spend, the line that decides everything
This is where ROAS thinking goes to die. A few hard rules:
- Use platform-reported spend, not platform-reported attributed revenue. Spend is a fact. Attributed revenue is a model (and three platforms claim the same conversion).
- Use blended ROAS / MER, not platform ROAS, for net-margin work. MER = total revenue / total ad spend across all platforms. It's the only metric that doesn't double-count.
- Don't allocate ad spend per order using platform attribution. Use first-touch UTM at the order level if you have it, otherwise allocate by channel mix at the day level.
- Include all paid spend. Influencer fees, affiliate payouts, agency retainers, creative production — those are marketing cost too, and belong in the same bucket.
The shortcut for operators who want one number: MER. If your MER is 3.2× and your contribution margin (after COGS, shipping, fees, returns) is 38%, your contribution profit before fixed cost is Revenue × (0.38 − 1/3.2) = Revenue × 0.067. That's 6.7%. Below your fixed cost? You're losing money to grow. Above? You're compounding.
Operators running multi-platform paid media without a blended view almost universally over-spend on the cheapest-attributing channel. The clean fix is per-order attribution + ad-platform spend in one place — the core of Ecombone Profit Tracker.
Step 7 — Country and channel breakdown (where the leaks hide)
The aggregate margin number lies. The order-level numbers, aggregated by country and channel, tell the truth.
A typical pattern from real Shopify data:
| Country | Orders | AOV | Gross margin % | Ship cost / order | Net margin % |
|---|---|---|---|---|---|
| United States | 8,200 | $74 | 62% | $7.10 | 11.4% |
| Canada | 1,450 | $69 | 60% | $14.20 | 3.1% |
| United Kingdom | 980 | $58 | 55% | $11.80 | -1.8% |
| Germany | 410 | $61 | 56% | $13.40 | 0.4% |
| Australia | 280 | $82 | 60% | $19.60 | -2.2% |
The aggregate looks fine. The UK and Australia are losing money on every order. The brand was subsidizing those markets out of US contribution profit and didn't know. Either raise prices and shipping floors there, or stop paid acquisition there.
You will not see this in Shopify Analytics or Meta Ads Manager. You see it when you grind the per-order P&L and group by country. That single view has fixed more margin in our portfolio than any creative test we've run.
The formula, in one place
Net Sales = Gross Sales − Discounts − Returns
Contribution Margin $ = Net Sales − COGS − Shipping Out − Gateway Fees − Return Costs
Contribution Margin % = Contribution Margin $ / Net Sales
Net Profit = Contribution Margin $ − Ad Spend − Fixed Costs
Net Margin % = Net Profit / Net Sales
Two layers, on purpose. Contribution margin tells you whether the next order makes money before you decide what to spend on ads. Net margin tells you whether the business made money after marketing and overhead.
If your contribution margin is below 35%, you don't have a paid-acquisition business — you have a structural product-cost problem. Fix that before scaling spend.
What "good" looks like in 2026
For DTC physical-product brands at $1M–$10M GMV, rough operator benchmarks:
| Metric | Struggling | OK | Good | Excellent |
|---|---|---|---|---|
| Gross margin % | < 50% | 50–60% | 60–70% | > 70% |
| Contribution margin % | < 25% | 25–35% | 35–45% | > 45% |
| MER (blended ROAS) | < 2.5× | 2.5–3.5× | 3.5–5× | > 5× |
| Net margin % | < 0% | 0–5% | 5–12% | > 12% |
5–15% net margin is normal for a healthy DTC brand at this scale. Above 15% usually means under-investing in growth (or category-leading product margin). Below 5% is fragile — one shipping rate hike or Meta CPM spike and you're underwater.
The single most useful KPI you don't track yet: % of orders with a positive contribution margin. Healthy DTC brands sit at 92%+. Anything below 85% means a structural problem in shipping zones, discount stacking, or BNPL mix. Compute it once. It usually changes how you think about discount codes forever.
The spreadsheet template (build it once, replace it later)
Here's the worksheet schema we hand to operators doing this for the first time.
Tab 1 — Orders (one row per order)
order_id | Shopify order ID
order_date | YYYY-MM-DD
country | shipping country
channel | utm_source / first-touch
gross_sales | sum of line item price × qty
discount | discount applied
net_sales | gross_sales − discount
shipping_income | what the customer paid for shipping
sales_tax | excluded from margin math
item_cogs | Σ landed_cost × qty
packaging_cost | per-order packaging
pick_pack_cost | 3PL fee or internal labor
shipping_cost_out | actual carrier cost
gateway_method | shopify_payments | paypal | klarna | etc
gateway_fee | actual fee from payout
refund_amount | if refunded
return_cost | residual ship + handling on returns
contribution_margin | net_sales − item_cogs − packaging − pickpack − shipping_out − gateway − return_cost
contribution_pct | contribution_margin / net_sales
Tab 2 — Ad spend (one row per platform per day)
date | YYYY-MM-DD
platform | meta | google | tiktok | pinterest | influencer | affiliate
campaign | optional
spend | actual spend in reporting currency
attributed_revenue | platform-reported (informational only)
Tab 3 — Monthly P&L (rolls up Tabs 1 + 2)
month
net_sales | sum from Tab 1
total_cogs | sum item_cogs + packaging + pickpack
total_shipping_out | sum shipping_cost_out (− shipping_income)
total_gateway_fees | sum gateway_fee
total_return_costs | sum return_cost
contribution_margin | net_sales − cogs − shipping − gateway − returns
contribution_margin_pct | contribution_margin / net_sales
ad_spend | sum from Tab 2
fixed_costs | rent, salaries, software, agencies
net_profit | contribution_margin − ad_spend − fixed_costs
net_margin_pct | net_profit / net_sales
Pivot Tab 1 by country, channel, and month for the breakdowns. That's the entire P&L most $1–10M brands need.
The pulls you need to set up:
- Shopify Orders export (CSV) → daily.
- Shipping cost export from your carrier/3PL → daily.
- Shopify Payouts / PayPal / Klarna fee reports → monthly.
- Meta / Google / TikTok / Pinterest spend exports → daily.
Done properly, you'll know your real net margin. You'll also lose 6–10 hours a month moving CSVs and reconciling order IDs.
Why most brands stop using their spreadsheet within 90 days
We've watched a lot of these spreadsheets get built and almost all of them die. The failure modes are predictable:
- CSV imports break. Meta renames a column, the formula chokes, the operator misses a week, the week becomes a month.
- UTMs change. A new campaign goes out without UTMs, attribution breaks, the spreadsheet disagrees with the platform, trust collapses.
- COGS goes stale. A supplier raises prices in February. The spreadsheet still has January costs in May. Every order looks 4 points more profitable than it is.
- Refunds land in the next month. The "January P&L" you computed in February gets revised in April when refunds and disputes settle, and nobody updates the file.
- Founder time evaporates. The spreadsheet is the founder's job. The founder is the founder. The spreadsheet loses.
This is a tooling problem, not a discipline one. Manual reconciliation of order-level financial data across five SaaS tools is a full-time job, and you should not have a full-time analyst at $2M revenue.
Build the spreadsheet anyway. Even if you replace it later, the act of building it once teaches you which numbers move your business. The brands that "skip ahead" to a tool without ever doing the manual reconciliation never internalize the math, and end up trusting a dashboard they don't actually understand.
Where Profit Tracker fits in
We're building Ecombone Profit Tracker because we ran the spreadsheet ourselves, watched it die, and decided the calculation deserved to be a product. It pulls Shopify orders + COGS, all four ad platforms (Meta, Google, TikTok, Pinterest), Shopify Payouts and BNPL fees, refunds, and shipping costs into one model at the order grain — and gives you contribution margin and net margin views by country, channel, and month in real time.
It's coming soon on the Shopify App Store. Pricing will start at $19/mo (Basic), $49 (Plus), $99 (Pro) — designed to cost less than the analyst-hours the spreadsheet eats.
But build the spreadsheet first. Even just the order-level tab for one month. The first time you sort by contribution_pct ascending and see the orders losing you money — that's the moment you stop running your business on revenue and start running it on profit.
That's the whole job.
Related articles
Triple Whale alternatives for Shopify brands under $5M GMV
An honest, operator-led look at Triple Whale alternatives for sub-$5M Shopify brands. Pricing, simplicity, profit clarity — where Triple Whale fits, and where it doesn't.
LTV/CAC ratio explained: the unit economics every Shopify founder should know
What LTV/CAC actually means, how to compute it correctly (and the trap most founders fall into), what's a healthy ratio, and how payback period changes everything.
eCommerce profit margin benchmarks by industry (2026)
What's a 'good' net margin in eCommerce? Honest benchmarks by category — apparel, beauty, home, food, electronics, jewelry — with the gross-vs-net gap most founders ignore.