If you've ever seen Meta report a strong return while your Shopify numbers say something more modest, you're not looking at a bug. You're looking at two systems answering two different questions. This guide walks the exact mechanics, a worked example with real arithmetic, and the one number that actually decides whether a campaign is worth more budget.
Why ROAS is two numbers, not one
ROAS is just attributed revenue divided by ad spend. The spend side is the same everywhere. The revenue side is where the two platforms diverge, so the same campaign produces two honest ROAS figures.
Meta's revenue number answers: "How much revenue did my ads plausibly influence?" Shopify's answers: "How much revenue actually landed, and which channel touched it last?" Those are different questions, so expect different answers.
This is the same root cause behind the broader problem of Facebook ad sessions not matching Shopify and Meta conversions not matching Shopify. ROAS just inherits every one of those gaps and multiplies them through the revenue line.
The five things that inflate Meta's ROAS
View-through conversions
On the default seven-day-click plus one-day-view window, Meta claims credit for a purchase made within a day of someone merely seeing your ad, with no click at all. Shopify has no concept of a view — it only records a checkout. This is the single biggest inflator of Meta-over-Shopify numbers, and a twenty to thirty-five percent gap on the default window is considered normal (Vaizle, TrackBee).
Modeled conversions
When Meta can't directly observe a sale — a blocked pixel, an iOS opt-out, a declined cookie — it estimates the conversion with a machine-learning model and reports the estimate as though it were counted. Shopify never models. It reports only real, completed orders. So Meta's revenue can exceed observed events even when your tracking is perfect.
Different attribution models
Shopify defaults to last non-direct click: one hundred percent of an order's credit goes to whatever channel the buyer clicked last. Meta credits itself for anything inside its window. So one real order can show as one conversion in Shopify (to some other channel) and one conversion in Meta at the same time — both internally correct.
Click-date reporting
Meta reports a conversion on the date of the click that earned the credit, not the date of the purchase. A Monday click that converts Thursday shows up in Meta on Monday and in Shopify on Thursday. Compare single days and your ROAS will never line up; always compare on trailing seven-to-fourteen-day windows.
Revenue definitions
Many pixel setups pass only the product subtotal, while Shopify's "Total sales" adds shipping and tax. And when an order is refunded, Shopify cuts its revenue but Meta and GA4 usually keep the original conversion, so the platforms stay high after refunds while Shopify drops. If your conversion counts roughly match but the revenue doesn't, this is almost always why.
Won't the Conversions API fix this?
No — and this is the misconception nearly every vendor blog leans on. The Conversions API (CAPI) recovers lost events: purchases a blocked browser pixel never fired. That closes tracking gaps. It does nothing about the methodology gaps above — view-through, modeling, last-click versus window, click-date. Even flawless tracking leaves a structural gap.
Worse, if you run the pixel and CAPI together without a shared deduplication key, Meta counts the same purchase twice. Meta deduplicates only when both copies share an event_id and event_name and arrive within forty-eight hours of each other (Meta for Developers). A store showing Meta purchases at roughly double its Shopify orders almost always has a dedup misconfiguration, not real inflation. So if adding CAPI raised your ROAS, that's a red flag, not a win.
A worked example: one week, two ROAS figures
Say you sell a mug for $40 subtotal, plus $5 shipping and $4 tax, so $49 total per order. You spend $800 on Meta this week and drive 100 real orders.
Here's the ground truth: 55 buyers clicked your Meta ad within seven days, 15 only saw it within one day, 10 clicked a Google ad last, and 20 came via organic or direct. Eight buyers later refunded.
Meta Ads Manager reports about 78 purchases. That's 55 click-through plus 15 view-through, plus roughly 8 modeled conversions recovering buyers it couldn't observe. It passes the $40 subtotal only and doesn't subtract the 8 refunds, so it reports revenue around 78 × $40 = $3,120.
Meta ROAS = $3,120 ÷ $800 = 3.9x.
Shopify Analytics reports 100 orders, credited by last click. Only about 55 land on "Facebook" — the 15 view-through buyers clicked nothing, so Shopify files them under their real last referrer. If you credit Facebook's last-click revenue at 55 × $49 = $2,695, minus a share of refunds, call it roughly $2,470.
Shopify last-click ROAS = $2,470 ÷ $800 = 3.1x.
Same campaign, same week, same $800. One number says 3.9x, the other says 3.1x. Both are computed correctly. This is exactly the pattern behind Meta ad revenue not matching Shopify — the revenue line diverges before you ever divide by spend.
The number that actually decides the campaign
Here's what neither ROAS figure tells you: whether you made money. Return on ad spend ignores the cost of goods, the print cost, the transaction fees, and the refunds. On a print-on-demand mug, that stack eats most of the order.
Keep the example going. On each $49 order: the product and print cost is maybe $18, Shopify Payments takes roughly 2.9% plus 30¢ per transaction on the Basic plan (Webgility), which is about $1.72, and your blended ad cost is $800 ÷ 100 orders = $8 per order. That leaves $49 − $18 − $1.72 − $8 = $21.28 of contribution before refunds and overhead.
Now apply the 8 refunds across 100 orders, and the picture tightens further — those orders cost you product, fees, and ad spend but return no revenue. Suddenly the 3.9x on Meta and the 3.1x in Shopify both matter far less than that per-order profit line. That profit number, not any ROAS figure, is what decides whether you pour more into the campaign.
This is why chasing "which ROAS is right" is the wrong project. Both are directional signals. Profit per order is the decision variable, and it requires stitching ad spend, product cost, fees, and real Shopify revenue into one view — the whole point of reconciling your ecommerce data in the first place.
How to work with the gap instead of fighting it
Stop trying to force the two numbers to equal each other. They structurally can't. Instead:
Compare on trailing windows, never single days, to neutralize click-date reporting. Confirm you're comparing the same KPI — Shopify "Total sales" is not "Sales attributed to marketing," which is not Meta's "Purchase conversion value." Set the pixel to pass the same revenue components Shopify counts. And verify your pixel-plus-CAPI dedup so you're not double-counting.
Then judge campaigns on profit per order, computed from your own store's cost data, not on either platform's self-reported ROAS.
Where PodVector fits
PodVector connects your Shopify, Meta Ads, Google Ads, Printify, and Printful accounts and computes your true per-order profit — revenue minus product cost, print cost, fees, and ad spend — from live data. It isn't a dashboard you have to read; it's a system that does the reconciliation for you.
Victor, its AI employee, analyzes that combined data and proposes concrete moves. He reads your ad data to spot which campaigns actually turn a profit, but he does not touch your ad account — the actions he executes are Shopify-side, and only with your approval. He reads the numbers Meta and Shopify each report and hands you the one profit figure they both leave out.
If you want to see your real per-order profit instead of arguing with two ROAS numbers, start free with PodVector.
The same reconciliation logic applies well beyond ads — for instance, when you need to sync Etsy with Shopify and line up two sources of order truth.
FAQs
Why is my Facebook ROAS higher than my Shopify ROAS?
Because Meta counts view-through conversions, modeled conversions, and click-dated sales that Shopify doesn't. Meta credits itself for any purchase inside its attribution window, while Shopify only credits the last click on a completed order. A twenty to thirty-five percent gap between Meta purchases and Shopify orders is normal on the default window (Vaizle).
Which ROAS number should I trust?
Neither as gospel. Shopify's order count and total sales are the source of truth for how many sales happened and how much revenue came in. Meta's number is the best signal for how many of those sales its ads plausibly influenced. Use both directionally, and make budget decisions on profit per order.
Will fixing my pixel or adding CAPI make the numbers match?
No. Better tracking recovers lost events, but it can't close methodology gaps like view-through and last-click attribution. If adding CAPI actually raised your reported conversions, that usually means your pixel and server events aren't being deduplicated on a shared event_id, which Meta requires within a forty-eight-hour window (Meta for Developers).
Why does the gap look bigger on some days than others?
Meta reports conversions on the click date, not the purchase date, so a click today that converts in three days shifts revenue between days. Compare trailing seven-to-fourteen-day windows instead of single days and the gap steadies into a predictable ratio.
What's a better metric than ROAS for a print-on-demand store?
Profit on ad spend, or per-order contribution profit. ROAS ignores product cost, print cost, transaction fees, and refunds — the exact costs that decide whether a "profitable" campaign actually made money. Compute revenue minus all of those, per order, and steer by that.