Every team can hit its target while the business loses money on each order.
Export last week's paid orders from Shopify and sit them next to the ad platform's revenue number for the same dates. If finance cannot get from one file to the other without a side spreadsheet, the business is running two sets of maths and calling both of them success.
Picture three friends splitting a restaurant bill, each reading the price of their own main course off the menu. The menu prices are all correct, and the table still comes up short, because the drinks, the service charge, and the tip only appear on the receipt the waiter brings.
I call this the shared receipt. Contribution margin is that receipt: what remains on an order after every cost that moves with volume, written once where marketing, ecommerce, and operations all read the same total.
Introduction
This article teaches you to build a two-order contribution worksheet and run a weekly three-seat review so marketing and finance share one number. How ROAS is calculated, and why a 4x screenshot can still hide a loss after COGS and fees, already lives in Why Your Shopify Store Can Hit 4x ROAS and Still Lose Money.
Use The Real Cost of Running a Shopify Store for plan fees and app invoices. Use What Should I Do If My Shopify Revenue Is Plateauing? when revenue is flat and you need a constraint sequence. The job here is narrower: one order-level number, three seats at the same table.
Bring last week's ad export and last week's Shopify order CSV to the first session. If those two files cannot be joined on date and order name without a third mystery sheet, start there. The worksheet is the join, written down, so both teams can point at the same row in the same week instead of arguing from two exports.
Stress-test the inputs in the Unit Economics Simulator once the worksheet exists. If you need help standing the review up, book a discovery call.
Why do the dashboards look fine when cash does not?
ROAS tells you how much attributed revenue you bought per pound of media, while contribution margin tells you how much of the order is left after variable costs, and both can be true on the same Tuesday.
Shopify makes ad efficiency easy to screenshot and contribution hard to see, because the platform will not join COGS, shipping, refunds, and fees to a campaign ID for you. Someone in the business has to own that join, or each team keeps optimising the metric it can export in one click.
| Object | Who already sees it | What it cannot tell you |
|---|---|---|
| Campaign ROAS | Media buyer, ad platform | COGS, shipping, refunds, fees on those orders |
| Store conversion rate | Ecommerce, Shopify analytics | Whether the order was discounted into a loss |
| Payout / P&L | Finance, monthly | Which campaign or SKU caused this week's hole |
| Contribution per order | Nobody, until you build it | Nothing useful if the inputs are guessed |
The incentives explain the rest. Marketing is paid to hit ROAS, ecommerce is paid to hit conversion, and ops is paid to ship, while finance sees the remainder a month later. Without a shared worksheet, the only person who notices the collision is the person doing the VAT return.
Weekly contribution review
A monthly board pack arrives after the campaign has already spent. The shared receipt has to land in the same week as the spend, on the same SKUs, so the three seats can still change the next seven days.
What goes on the receipt?
Work on real orders rather than a model of an ideal customer. Pick one paid order and one organic order from the same week, the same product if you can, and fill each line:
- Gross: the amount the customer paid after shop discounts and before refunds
- COGS: the units on that order
- Discount value: any code or automatic discount that applied
- Shipping cost: what you paid, minus shipping the customer paid
- Payment fees: the fee on that tender
- Returns provision: the trailing return rate for that channel, not a hope
- Packaging: include it if you already track it
- Attributed ad cost: the paid order only, allocated by your current rule
- App or labour cost per order: include it only if you already measure it, and leave the cell blank rather than invent a figure
The remainder is contribution for that order. Two orders are only a sample, yet they are enough to show whether paid and organic live in different businesses.
Write the allocation rule next to the ad-cost line: last click, data-driven, or a simple spend divided by paid orders. Changing the rule later is fine; hiding the rule is how two teams keep "disagreeing" while using different files.
Repeat across a handful of SKUs, plus one more channel if you run more than one, because you are hunting for the largest leak rather than building a perfect cost-accounting system. A hero SKU that clears contribution and a gift-with-purchase add-on that does not should sit on the same sheet, so the meeting argues about a named row instead of a brand-level average.
If you already track app or labour cost per order, put that line on the sheet. The Hidden Cost of Running a Shopify Store When 12 Apps Quietly Eat Your Margins is the place to get that line honest. A blank cell is better than a rounded guess that everyone treats as fact.
Which cells do people fake?
COGS is the first one. If Shopify holds no COGS, pull it from the sheet finance already uses for stock, since guessing a margin percentage to finish the worksheet turns the meeting into theatre. A missing COGS cell is an honest blocker that purchasing can fill.
Attributed ad cost is the second. Until you have a proper model, pick one boring rule and write it next to the line: last week's campaign spend divided by paid orders in that campaign, or last click from your current ads export.
What breaks the comparison is a rule nobody wrote down, because two weeks built on different silent rules cannot be compared, and two teams using different files will keep arguing about the same orders. Write the rule in a cell finance can see, then leave it alone for at least two reviews so the rows stay comparable.
Returns are the third cell people tidy up. Use the trailing return rate for that channel, or a 90-day refund rate for that SKU if you have it, rather than last month's best week. A paid cohort that refunds at twice the organic rate will look fine on ROAS and still empty the till after the window closes.
Packaging and payment fees are smaller, and they still belong on the receipt if you already invoice them. Skip a line you cannot source. Do not invent a tidy number so the sheet looks complete.
Who sits at the table each week?
A monthly board pack cannot steer a campaign. Put 30 minutes on the calendar with three seats, media, ecommerce, and whoever owns fulfilment or the app list, all looking at the same worksheet and the same date range.
Run the agenda in this order:
- Paid versus organic contribution for last week
- The largest line that moved, whether that is discount rate, refunds, shipping, or CAC
- One change for the coming week, owned by one seat
- What will be true on the worksheet if that change worked
If ops is absent, shipping and app overhead stay someone else's problem and marketing keeps buying volume. If ecommerce is absent, discount experiments stay invisible to the P&L, and without media the meeting turns into a finance lecture with no lever to pull.
The output is a decision: keep spend, cut a cohort, change the offer, or change cost to serve. Keep a running note of it, then start next week by checking whether the worksheet moved the way the note said it would, testing one hypothesis at a time on the same rows.
Skip a new dashboard until that decision exists. A Looker tile that restates ROAS still leaves three people without a shared order row, so keep the receipt as a dated file with owners in the header, and only add another tool once the meeting already changes spend, offer, or cost to serve.
If last week's note said the sitewide code would come off and paid contribution stayed flat, look at the next largest line instead of restating the same hypothesis. Repeat purchase that is supposed to recover a thin first order belongs in Maximizing Customer Lifetime Value on Shopify Plus, and only after you have measured the recovery window you can actually fund.
What do you change first?
Once two weeks of worksheets exist, the largest leak usually names the next action, and the urge to "align everything" is worth resisting.
| Largest leak on the worksheet | Owner this week | Move |
|---|---|---|
| Ad cost per order vs organic | Media | Cut the cohort with high refunds or one-and-done buyers; do not raise budget |
| Discount value on paid orders | Ecommerce | Remove the default sitewide code; measure conversion at a thinner offer |
| Shipping subsidy | Ecommerce + ops | Raise threshold or stop free shipping on the SKUs that already lose money |
| Returns on paid vs organic | Media + ecommerce | Stop buying the audience; fix PDP honesty if the ad oversold the product |
| App / labour per order | Ops | Cut duplicate tools; do not treat this article as an integration rebuild |
Ad cost per order against organic belongs to media, who should cut the cohort with high refunds or one-and-done buyers before any budget rise. Discount value on paid orders belongs to ecommerce, who can remove the default sitewide code and measure conversion at a thinner offer. Shipping subsidy sits with ecommerce and ops together, who can raise the threshold or stop free shipping on SKUs that already lose money.
Returns on paid against organic need media and ecommerce, because the fix is to stop buying the audience or make the PDP honest where the ad oversold the product. App or labour cost per order belongs to ops, who can cut duplicate tools without turning this into an integration rebuild.
If paid contribution sits under your floor and the leak is audience quality, more creative tests will leave it there. A 20 percent code on every paid session means media cannot find better ROAS until the offer changes, and when the leak is cost to serve, cheaper clicks only buy more unprofitable parcels.
Name one owner for the move and one date you will look at the same row again. A leak with three owners and no date is how the receipt stays a conversation instead of a change.
Where does the floor go?
Set the floor in pounds per order on the same sheet as the orders: "Paid orders must clear £X contribution after the worksheet lines above before we increase daily spend." Fill X from the two-order exercise, then tighten it as more weeks come in.
When someone asks in Slack to raise the budget, the answer is whether last week's paid rows cleared X, which spares everyone a negotiation over a screenshot of ROAS.
Keep X visible in the same sheet as the orders, in a cell the media buyer can see without opening finance's monthly pack. A floor that lives in a slide deck from last quarter will lose to whoever has the latest Ads Manager screenshot.
Read the receipt before you order another round. A paid row that cleared X last week still needs this week's lines filled, because a new code, a carrier increase, or a refund spike can move the same SKU under the floor in seven days.
If the numbers exist and the weekly review does not, a discovery call is where we help you stand up the operating model before you scale.
Conclusion
Contribution margin holds when each team can use the same order-level number. The work is a worksheet on real orders and a weekly meeting that is allowed to change spend, offer, or cost to serve.
Build the two-order sheet, name the allocation rule, and put three seats in the same 30 minutes. Change the largest leak first, then check the receipt the following week before anyone orders another round of spend.
Model the same inputs in the Unit Economics Simulator. If the numbers are clear and the review still does not exist, book a discovery call and we will help you stand up the operating model before you scale.



