Computing POAS When COGS Varies by SKU

A blended-margin POAS hides which products actually pay for your ads. Here's how to compute POAS per order using line-item COGS so Meta and Google bid on real profit.
Quick answer
Compute POAS per order by summing (line revenue − line COGS − line discount) across each order's line items, then dividing by the order's attributed ad spend. Do not apply a single blended margin to the whole catalogue — when SKU margins range from 18% to 72%, a blended figure overpays for low-margin bestsellers and starves your high-margin SKUs of budget.
Computing POAS When COGS Varies by SKU
Calculating POAS using order-line-level COGS so per-SKU margin differences don't distort what you send back to ad platforms.
Most Shopify and WooCommerce stores compute POAS by multiplying revenue by an assumed gross margin (say 55%) and dividing by ad spend. That works when SKUs sit in a tight margin band. It breaks the moment your catalogue mixes a 20%-margin hero product with 65%-margin accessories — the blended number flatters the bestseller and hides which SKUs actually pay for the ads.
The fix is to compute profit at the order-line level: each line's revenue minus its own COGS minus its share of discounts and shipping, summed per order, divided by the ad spend attributed to that order. The output is a per-order POAS Meta and Google can ingest as a conversion value, so bidding optimises for real profit rather than disguised revenue.
If you sell a single SKU or a tight family with near-identical margins, blended POAS is fine. If you sell apparel with markdowns, beauty bundles, or electronics with accessories, blended POAS is misleading you in a specific direction: toward overspending on cheap-to-acquire, low-margin volume.
Why blended-margin POAS lies
Take an apparel store with a €40 graphic tee at 28% margin and a €120 jacket at 58% margin. Both sit in the same Performance Max asset group. Blended POAS at 45% margin tells you both products return €1.80 per €1 of ad spend.
Line-level POAS tells you the tee returns €0.92 and the jacket returns €2.40. The tee is unprofitable; the jacket is your business. The blended view averaged them into a green light.
The blended-margin trap
Google and Meta optimise toward whatever conversion value you send. If that value embeds a blended margin, the algorithm finds your cheapest-to-convert SKUs — which are almost always your lowest-margin ones. You scale, revenue grows, and contribution profit shrinks. This is the most common cause of 'we hit ROAS targets but the P&L looks worse'.
How to detect the distortion
Pull the last 90 days of paid orders and segment by SKU or product collection. For each segment, compute revenue, COGS, and contribution margin. If margin variance across your top 20 SKUs exceeds 15 percentage points, blended POAS is actively misreporting.
A faster signal: compare your top-10 SKUs by ad-attributed revenue against your top-10 by ad-attributed contribution margin. If the lists overlap by fewer than six SKUs, your ad platforms are bidding on the wrong winners. Our Contribution Margin Calculator handles the per-SKU breakdown if you don't have it in your data warehouse yet.
The line-level calculation
For each order: take every line item, multiply quantity by per-unit COGS to get line COGS, subtract from line revenue, then subtract a pro-rata share of order-level discounts and shipping cost. Sum line profits across the order. Divide by the ad spend attributed to that order through your platform's conversion API.
The output is one POAS number per order, ready to send to Meta CAPI or Google Enhanced Conversions as the conversion value. The platforms now bid toward orders that actually generate profit, not orders that look big at gross-revenue level. This is the same input the parent POAS metric uses — you're just feeding it cleaner data.
What 'good' looks like after the switch
Stores that move from blended to line-level POAS typically see reported POAS drop 10-25% in week one (because the old number was inflated) and then recover within 4-6 weeks as bidding shifts toward higher-margin SKUs. Contribution profit per €1 of ad spend rises 15-30% over the same window.
Feeding the number back to ad platforms
On Meta, send the per-order profit as the value parameter on the Purchase event via Conversions API — not gross revenue. On Google Ads, use Enhanced Conversions for Web with a custom conversion value that maps to your computed line-level profit. Set the bid strategy to Target ROAS, but understand the 'R' is now profit, so your target should be ≥1.0 (you want positive contribution), not 3-4x.
One operational warning: returns blow this math up if you don't reconcile. A 60%-margin apparel sale that comes back as a return becomes a −15% margin order once you account for return shipping and restock cost. Cover that case separately — see the page on how returns-heavy categories break POAS math — and decide whether you report POAS gross of returns or net of a rolling return-rate adjustment.
Frequently asked questions
Use the per-variant 'Cost per item' field on each Shopify product, then pull orders via the Admin API or a profit-reporting app that reads line-item cost. For each order, sum (line_price × quantity − line_cost × quantity − line_discount) and divide by the ad spend attributed to that order. Avoid Shopify's built-in 'profit' report for POAS — it doesn't attribute spend.
ROAS is revenue / ad spend; POAS is profit / ad spend. At the SKU level the gap widens because revenue is uniform per euro but profit ranges from negative (loss-leaders, deep markdowns) to 70%+ (high-margin accessories). SKU-level POAS is the version that actually predicts P&L impact.
Only as a temporary fallback. If your top 20 SKUs drive 80% of paid revenue (typical), compute line-level POAS for those and apply a blended assumption to the long tail. Don't blend across the whole catalogue when margin variance exceeds 15 points.
Allocate order-level discounts pro-rata across lines by line revenue share. A 10% sitewide discount on an order with a €40 tee and €120 jacket comes off as €4 from the tee line and €12 from the jacket line. Then subtract from line revenue before the COGS step.
Yes — Performance Max bids toward whatever value you send via Enhanced Conversions or the data feed's profit attribute. Send line-level profit as the conversion value and PMax will reallocate budget toward higher-margin SKUs within the same asset group, even without you restructuring campaigns.
Start with landed cost (supplier price + inbound shipping + duties) per SKU. Update quarterly. Even ±10% noise in COGS is better than a blended assumption that's structurally wrong across your whole catalogue. The Contribution Margin Calculator can help you sanity-check ranges.
Daily for the per-order conversion value sent to ad platforms (so bidding adapts). Weekly for the reporting view your team looks at. Monthly to reconcile against actual P&L and adjust COGS assumptions for any SKUs where landed cost has drifted.
Almost always in week one, by 10-25%. The blended number was inflated by averaging in your high-margin SKUs. The line-level number is the truth. Within 4-6 weeks of letting bidding adapt, absolute contribution profit per ad euro typically rises 15-30%.
Treat each bundle as its own SKU with its own bundle COGS (sum of component costs) and bundle price. For multi-buy promotions (buy 3 for €X), allocate the bundle price across lines proportionally and compute line profit normally. The math doesn't change; you just need a clean bundle-SKU definition.
Subtract net shipping (your fulfilment cost minus shipping revenue collected) from order profit before dividing by ad spend. If you offer free shipping above a threshold, the threshold orders absorb the full fulfilment cost — which is exactly why high-AOV orders sometimes have worse line-level POAS than expected.
Test ideas before you ship them
Run unlimited A/B tests, attach hypotheses to outcomes, and build a searchable archive of what works — and what doesn't.