facebook-ads meta-ads shopify attribution capi

Facebook Ads Not Matching Shopify Sales? Here's Why (And How to Fix It)

Detectly Team

You spent $2,000 on Facebook Ads this week. Ads Manager says you got 45 purchases and $6,750 in revenue. Nice — that’s a 3.3x ROAS.

You open Shopify. Total revenue for the week: $5,200 from 38 orders. And that includes orders from email, organic, and other channels.

So either Facebook is inventing sales, or something is very wrong with your tracking. The truth, as usual, is somewhere in between — and understanding the gap is critical for making smart spending decisions.

Why Facebook Reports More Sales Than Shopify

Reason 1: View-Through Conversions

This is the single biggest reason for the discrepancy. By default, Meta counts a conversion if someone saw your ad (without clicking it) and then purchased within 1 day.

Think about how many people scroll past your ad in their feed without clicking. If even a fraction of those people buy from your store that day — through a Google search, a direct visit, or an email — Meta counts all of those as ad-driven conversions.

For stores running broad awareness campaigns with high impressions, view-through conversions can represent 30-60% of Meta’s total reported conversions.

Quick check: In Ads Manager, add columns for “1-day click” and “7-day click” conversions alongside the default total. The difference between the default total and the click-only numbers is your view-through volume.

Reason 2: Meta’s Attribution Window Is Wider

Meta’s default attribution is 7-day click / 1-day view. If someone clicked your ad last Sunday and purchased this Saturday, Meta counts it. Shopify’s analytics might attribute that Saturday purchase to whatever the customer’s last interaction was — maybe a direct visit or a Google search.

These timing differences also mean that daily totals will rarely match. Meta counts conversions based on when the ad interaction happened, while Shopify counts them based on when the order was placed.

Reason 3: Statistical Modeling (Post-iOS 14)

After iOS 14.5 introduced App Tracking Transparency, Meta lost visibility into a large portion of conversions. To compensate, Meta uses Aggregated Event Measurement (AEM) and statistical modeling to estimate conversions it can’t directly observe.

In plain English: Meta is guessing for a percentage of your conversions. The model is trained on data from users who do allow tracking, and it extrapolates to estimate what opted-out users are doing. Sometimes this estimate is close to reality. Sometimes it significantly overshoots.

You’ll notice this particularly if your audience skews toward iPhone users. The higher your iOS traffic percentage, the more Meta relies on modeling.

Reason 4: Cross-Device Attribution

Meta has a significant advantage here — it can track users across devices through their Facebook/Instagram login. If someone clicks your ad on their phone and buys on their desktop, Meta can connect those dots (as long as the user is logged in on both devices).

Shopify can’t do this. It sees two separate sessions from two different devices. The order gets attributed to whatever brought the customer to the desktop session.

This is one area where Meta’s number might actually be more accurate than Shopify’s — the conversion really was influenced by the ad, even if it happened on a different device.

Reason 5: Duplicate and Modeled Events

If your Conversions API (CAPI) and pixel are both firing, and deduplication isn’t set up correctly, Meta might be double-counting some conversions. This is more common than you’d think, especially if the pixel fires on the thank-you page and CAPI fires on the same event without matching event IDs.

What Is the Conversions API (CAPI) and Does It Help?

CAPI is Meta’s server-side tracking solution. Instead of relying solely on the browser pixel (which gets blocked by ad blockers, cookie restrictions, and iOS privacy features), CAPI sends conversion data directly from your server to Meta.

How CAPI Helps

  • Bypasses ad blockers — Server-side events can’t be blocked by browser extensions
  • More reliable data — Not dependent on browser cookies or JavaScript execution
  • Better optimization — More complete data helps Meta’s algorithm optimize your campaigns better

How CAPI Doesn’t Help (With This Problem)

CAPI improves the accuracy of Meta’s data, but it doesn’t solve the fundamental attribution disagreement. Meta still uses its own attribution windows and still counts view-through conversions. CAPI means Meta sees more real conversions (fewer are lost to tracking limitations), but it can also mean Meta reports even more conversions than before — widening the gap with Shopify.

CAPI is absolutely worth setting up. It improves Meta’s ad delivery optimization, which usually means better performance. Just don’t expect it to make the numbers match.

Setting Up CAPI for Shopify

Shopify has a built-in integration with Meta’s CAPI through the Facebook & Instagram sales channel. To set it up:

  1. Install the Facebook & Instagram sales channel in Shopify
  2. Connect your Facebook Business account
  3. Enable the Conversions API in the channel settings
  4. Shopify will send server-side events (Purchase, AddToCart, etc.) to Meta automatically

For more control, some merchants use apps or custom implementations that provide better event matching and deduplication.

Practical Steps to Reconcile Your Data

Step 1: Adjust Attribution Windows in Ads Manager

Switch your Ads Manager reporting to show 7-day click only (exclude view-through). This gives you a more conservative number that’s closer to what Shopify sees.

To do this:

  1. Go to Ads Manager
  2. Click ColumnsCustomize Columns
  3. Search for “Results” and select the 7-day click attribution window
  4. Compare this to your default view

The 7-day click number won’t match Shopify exactly, but the gap should be much smaller.

Step 2: Use UTM Parameters on Every Ad

This is the most important thing you can do. Add UTM parameters to every Facebook ad URL:

?utm_source=facebook&utm_medium=cpc&utm_campaign={{campaign.name}}&utm_content={{ad.name}}&utm_term={{adset.name}}

Meta’s dynamic parameters (the {{campaign.name}} syntax) automatically populate with your actual campaign, ad set, and ad names.

When a customer clicks your ad and buys, the UTM data tells you definitively that the order came from a specific Facebook campaign. No modeling, no attribution windows — just a direct, first-party data trail from click to purchase.

Step 3: Capture UTMs on Shopify Orders

UTM parameters only help if you actually save them on the order. By default, Shopify doesn’t do this.

You need either:

  • A custom code solution that captures UTMs and passes them to Shopify via cart attributes
  • An app like Detectly that automatically captures UTMs and writes them to order metafields

With order-level UTM data, you can export your orders and calculate real revenue from Facebook ads — not Meta’s modeled estimate, but actual orders from actual clicks.

Step 4: Calculate Your “Meta Discount Factor”

Over a 30-day period, compare:

  • Meta’s reported revenue from Facebook Ads
  • UTM-attributed revenue from orders tagged with utm_source=facebook

The ratio between these two numbers is your Meta discount factor. For most stores, Meta over-reports by 20-50%. Once you know your factor, you can mentally adjust Meta’s numbers in real-time.

For example, if Meta says a new campaign is getting 4x ROAS but your discount factor is 35%, your real ROAS is probably closer to 2.6x. Still good — but a very different picture.

Step 5: Set Up a Weekly Reconciliation

Build a simple routine:

  1. Every Monday, pull your Meta Ads Manager data for the previous week
  2. Pull your Shopify orders with UTM data for the same period
  3. Compare total attributed revenue by campaign
  4. Note which campaigns have the biggest gaps (these need the most scrutiny)
  5. Make scaling/cutting decisions based on the UTM-attributed numbers, not Meta’s numbers

This takes 30 minutes per week and can save you thousands in wasted ad spend.

What About Google Ads?

Google Ads has a similar issue, though typically less severe. Google uses data-driven attribution by default, which can attribute conversions to clicks from multiple days prior. Google also uses modeled conversions for users who have limited tracking.

The same principles apply: use UTM parameters, capture them on orders, and compare to Google’s reported numbers. Most merchants find Google over-reports by 10-25%, less than Meta but still significant.

The Real Solution: First-Party Data

All of these attribution disagreements stem from the same root cause: ad platforms use probabilistic, model-based attribution, while what you actually need is deterministic, order-level data.

UTM parameters are first-party data. They travel with the click, survive across pages, and can be captured directly on the order. They’re not affected by iOS privacy changes, ad blockers, or cookie restrictions.

The merchants who figure this out early — who build systems to capture UTM data on every order — have a significant competitive advantage. They know their real ROAS, they know which campaigns actually work, and they make spending decisions based on reality rather than platform estimates.

Whether you use a spreadsheet, a custom solution, or an app like Detectly, the important thing is to start. The gap between your Facebook Ads dashboard and your bank account is too big to ignore.

Ready to see your true ROAS?

Detectly tracks every UTM, attributes every Shopify order, and shows you which channels actually drive revenue.