Every few weeks a founder forwards me an Ads Manager screenshot and asks why the agency is celebrating. The number on the screen is real. It is also not the number their accountant will recognise at the end of the month. Facebook Ads ROAS is useful for campaign optimisation, but it is not automatically your business ROAS. Ads Manager divides attributed purchase value by ad spend. Your real number starts from confirmed revenue after cancellations, failed deliveries, returns, and duplicate attribution. If margins matter, go one step further and calculate contribution after variable costs.
The mistake is not using Meta’s number. The mistake is treating it as the final financial truth.
Three returns, three different decisions
Keep these measures separate.
Platform ROAS
Meta-attributed purchase value ÷ Meta ad spend
Use it to compare campaigns inside the same account, with the same attribution settings and data quality.
Collected ROAS
revenue actually collected from Meta-attributed orders ÷ Meta ad spend
Use it to decide whether the advertising produced bankable revenue.
Contribution ROAS
collected revenue minus variable order costs ÷ Meta ad spend
Use it to judge profitability. Variable costs may include product cost, payment fees, shipping subsidy, fulfilment, and return handling.
Do not label all three “ROAS” in one report without qualification.
Why Ads Manager and finance disagree
The leaks are rarely exotic. A purchase event fires the instant someone taps buy, then the order gets cancelled an hour later and the pixel never hears about it. In COD markets the order exists but no cash ever changes hands at the door. Returns and refunds arrive while the original conversion value sits untouched in the dashboard. Meta and another channel both raise a hand for the same sale. Events ship the list price, or double-count, or send the wrong currency entirely. And even when every event is clean, platform ROAS still says nothing about gross margin or fulfilment cost.
The larger the operational gap between “order placed” and “cash retained,” the less useful platform ROAS becomes as a scaling metric. Here is the part most agencies will not say out loud: a fair number of them quietly prefer that you never reconcile, because the platform number is the one that keeps renewing the retainer.
The duplicate-attribution leak is the one people underestimate, so make it concrete. In an anonymised KSA e-commerce account, four platforms between them claimed SAR 14.2M in sales. The store actually banked SAR 11.5M. Plenty of that gap is the usual cancellations and returns, but a measurable slice — about 4% of what the platforms claimed — was simply the same order being counted twice, because Meta and Google both raised a hand for one sale. If you add up what each platform reports and treat the total as revenue, you are paying to optimise toward a number that double-counts itself. The fix is to deduplicate against one source of truth, the order record, before you trust any platform's ROAS. The mechanics of doing that across channels are in reconciling Meta, CRM, and collected revenue.
A reconciliation workflow
Run this by order ID, not by percentages alone.
- Export Meta-attributed orders for the reporting period.
- Match them to your commerce, CRM, or order-management system.
- Assign a final status: paid, delivered, cancelled, returned, refunded, or unresolved.
- Use the collected amount, not the original basket value.
- Remove duplicates and document attribution rules.
- Divide confirmed collected revenue by Meta spend.
- Add variable costs if the decision is about profit.
- Feed final outcomes back to the platform where your setup permits it.
If order-level matching is not yet possible, report the platform number and an explicitly labelled estimate. Do not present an estimate as reconciled fact.
Feed outcomes back with the Conversions API
Reconciliation tells you the truth after the fact. The Conversions API (CAPI) is how you put that truth back into Meta so the algorithm optimises toward it. Browser pixel events get thinner every year — ad blockers, iOS prompts, cleared cookies — so a server-side CAPI feed is now the reliable spine of Meta measurement. Send the purchase event from your server with the same event ID as the pixel, so Meta deduplicates the two into one.
The upgrade most accounts skip is the second send. When an order is cancelled, returned, or — in COD — never collected, upload that outcome as an offline or refund event so the platform stops treating the original purchase as banked revenue. For lead campaigns the equivalent is an offline conversion: when a lead becomes a qualified opportunity or a closed sale in your CRM, push that event back with its value. Optimise toward the confirmed outcome and Meta's bidding starts chasing revenue instead of order confirmations that evaporate at the door.
Two practical guardrails. Match your event value to collected revenue, not basket value, or you train the model on money you never keep. And watch event match quality: the more identifiers you send — hashed email, phone, click ID — the better Meta can attribute the outcome you fed it, which is exactly what the CRM match below depends on.
Matching Meta orders to your CRM
The whole method rests on one join: linking each Meta-attributed order or lead to a row in your CRM or order system. Do it on the most stable key you have. Order ID is best; failing that, match on hashed email or phone plus timestamp, and keep Meta's click ID (fbclid / the _fbc cookie) on the record so lead-form submissions can be traced back to the campaign that produced them.
Watch the match rate — the share of platform-reported conversions you can tie to a real CRM record. A low rate means a chunk of your reported ROAS is unverifiable, so treat the unmatched portion as an estimate rather than folding it into collected revenue. Unmatched records usually point at a fixable tracking gap: a broken UTM handoff, a checkout that drops the order ID, or a CRM that never captures the lead source.
This is the join behind the cleanest number I can point to publicly. On a Saudi e-commerce account, matching orders back to the CRM reconciled 2.3M SAR of ad spend against 11.5M SAR of collected revenue — a verified 5.0×, not a platform-reported figure. The full teardown is in the KSA ROAS reconciliation case.
A real COD example
In an anonymised mobile-commerce case, platform reporting showed 4.1× gross ROAS. After delivery outcomes were considered, delivered ROAS was 1.9×, with a 33% COD return rate. The delivery-outcome breakdown is published in the mobile-commerce COD case.
The point is not that Meta was “wrong.” Meta measured attributed order value. The business needed delivered revenue. Reporting 4.1× and 1.9× side by side made the gap visible and changed the scaling decision.
This example should not be transferred as a benchmark. Return rates, margins, delivery performance, and attribution differ by business.
A worked contribution example
Delivered ROAS tells you what landed. It still does not tell you what you kept. Walk a single month all the way to contribution with round numbers, kept deliberately simple to show the arithmetic rather than to model any specific store.
Say a store spends 100,000 in a month and the platform reports 500,000 in attributed sales: a 5× platform ROAS that looks excellent on the call. Reconcile by order and the collected figure is 380,000 once cancellations, returns, and a couple of duplicate-attributed orders are removed. That is a 3.8× collected ROAS, still healthy.
Now subtract the variable cost of actually fulfilling those collected orders. Suppose product cost is 45% of collected revenue (171,000), payment and shipping run 12% (45,600), and return handling on the bounced orders adds 15,000. Variable costs total 231,600. Contribution is 380,000 − 231,600 = 148,400, against 100,000 of ad spend: a 1.48× contribution ROAS. Before any overhead, every 1 spent on ads returned about 0.48 in contribution margin.
The staircase is the point. The same campaign reads as 5×, 3.8×, and 1.48× depending on which question you are answering, and only the last one tells you whether spending more makes you money. Plug in your real margins and the shape holds even when the numbers move.
Score lead quality, not lead volume
Everything above assumes an e-commerce order, but the same gap opens wider on lead-generation accounts. Meta will report a low cost per lead all day, and cost per lead tells you nothing about whether those leads close. Report two numbers here too: leads generated, and leads that turned into qualified pipeline or collected revenue. A campaign with an enviable cost per lead can be your worst campaign once the sales team stops returning the calls.
Score leads instead of counting them. Tag each lead in the CRM with a stage — raw, contacted, qualified, closed — and a value, then send those stages back to Meta as offline conversions so bidding optimises toward the qualified end of the funnel. Judged on cost-per-qualified-lead and closed revenue, a lead campaign often looks nothing like the same campaign judged on cost-per-form. That closed-loop scoring is the reporting discipline behind my Facebook ads for US lead generation work, where the deliverable is qualified pipeline and CRM-tracked revenue rather than a screenshot of cheap leads.
Diagnose the gap before changing campaigns
Use the pattern to find the operational cause.
- High platform ROAS, low delivery: inspect COD confirmation, address quality, courier performance, and audience intent.
- High purchases, low collected value: inspect discounting, partial refunds, and event-value accuracy.
- Strong collected ROAS, weak contribution: inspect margin, product mix, shipping subsidy, and fulfilment cost.
- Meta and analytics both claim the sale: define a deduplication and attribution rule.
- Lead campaign with poor revenue: send qualification and closed-sale outcomes back to reporting.
Creative is not always the first fix. Sometimes the ad is successfully attracting orders that the operation cannot convert into cash.
The deduplication rule is worth spelling out, because it is the one most teams hand-wave. Pick a single attribution model and a single source of truth, then resolve every order to exactly one channel inside that source before any platform total is summed. In practice that means joining each platform's reported orders to your order record by order ID and keeping one owner per order, not adding four dashboards together and hoping the overlap is small. When you cannot get order-level data from a channel, treat its number as an estimate and label it, rather than letting it inflate a total it is silently double-counting.
A two-number reporting template
Every Meta report I send states two numbers on the same row, never one. The platform figure earns its place — it is how you optimise inside the account — but it always sits next to the number finance recognises. A workable monthly template looks like this:
- Ad spend — what actually left the account.
- Platform result — Meta-attributed purchase value or leads, at your stated attribution window.
- Collected outcome — revenue reconciled through the CRM, or qualified leads confirmed in it.
- Platform ROAS vs collected ROAS — both ratios, side by side, so the gap is impossible to miss.
- Match rate — the share of the platform result you could verify against a real record.
- Unresolved — anything you could not match, named as an estimate rather than buried in the total.
The format is the discipline. A stakeholder who sees a 5× platform ROAS and a 3.8× collected ROAS on the same line asks sharper questions than one handed a single triumphant figure. For US teams running Meta for lead generation, the same template swaps collected revenue for qualified pipeline — the service version of this reporting ships it as a standing deliverable.
A weekly Meta ROAS checklist
- Is the reporting window consistent?
- Is currency correct?
- Are purchase events deduplicated?
- Are cancelled and returned orders identifiable?
- Is COD delivery status available?
- Is collected revenue imported or reconciled?
- Are new and returning customers separated where useful?
- Is margin known before budget increases?
- Is attribution overlap documented?
- Does the report name unresolved data?
When to scale
Scale only when:
- collected or qualified outcomes remain healthy across a meaningful period;
- fulfilment and sales capacity can absorb more volume;
- the margin survives at the expected acquisition cost;
- the result is not dependent on one creative or a reporting anomaly;
- the downside rule is defined before spend increases.
For the general reporting framework across channels, read why marketing dashboards lie. For a GCC paid-growth operating model, see AI performance marketing.
Next step
If Ads Manager looks profitable but finance disagrees, audit your Meta revenue tracking with a systems diagnostic. We map the whole trail — pixel to CAPI to CRM to collected cash — before you scale, so the platform number and the revenue you actually bank finally sit on the same page.