Meta ads not tracking purchases in your app? Here's why — and how to fix it
Updated July 10, 2026 · 7 min read
If your Meta ads aren't tracking purchases, it's almost always because the Purchase event never reaches Events Manager — not because the ad itself is broken. Somewhere between the tap in your app and Meta's servers, the signal is dropped.
There are seven common break points. Work through them top to bottom; the first one you hit is usually the culprit.
The seven most common causes
Ordered from most to least common in real app codebases:
- 1The Purchase event is never fired — the SDK call sits behind a paywall branch that the real purchase flow doesn't hit, or was never added at all.
- 2The event fires but with no value or currency, so Meta records it as a $0 conversion it can't optimize toward.
- 3iOS ATT: the user hasn't granted App Tracking Transparency permission, so the client-side SDK event is suppressed and nothing server-side backfills it.
- 4There's no Conversions API (CAPI) path — you rely on the client SDK alone, so any dropped client event is lost forever.
- 5The purchase is confirmed on your server (or in RevenueCat/Adapty) but that confirmation is never forwarded to Meta.
- 6Client and server both send the event but without a shared event ID, so Meta can't deduplicate and either double-counts or discards.
- 7The Pixel/dataset ID or access token is wrong, expired, or points at a different Meta dataset than your ad account uses.
How to confirm where it's breaking
Open Events Manager and watch the Test Events tab while you make a sandbox purchase. If nothing appears, the event isn't being sent at all (causes 1–4). If it appears but with $0 or no currency, it's cause 2. If it appears twice, it's a deduplication problem (cause 6).
Then check Event Match Quality on the Purchase event. A low score means the event is arriving but without enough identity parameters for Meta to attribute it to a click — common when only the client SDK fires and ATT is denied.
The durable fix: fire the event on both paths, deduplicated
Send the Purchase event from the client SDK (for the ATT-authorized case) and from your server via the Conversions API (for everything else), and stamp both with the same event ID so Meta counts it once.
Your server is the source of truth for money: fire the CAPI Purchase from wherever the purchase is actually verified — your webhook, or your RevenueCat/Adapty integration — not from an optimistic client callback that a crash can skip.
Frequently asked questions
Why are my Facebook ads not tracking app purchases?
Because the Purchase event isn't reaching Events Manager. The most common reasons are that the event is never fired, is fired without a value or currency, is suppressed on iOS because App Tracking Transparency was denied, or is sent only from the client with no Conversions API backup. Confirm by making a sandbox purchase while watching the Test Events tab.
Does iOS App Tracking Transparency stop purchase tracking?
It stops client-side tracking when the user denies permission. The Facebook SDK suppresses the event. A server-side Conversions API call is not subject to ATT and will still deliver the purchase to Meta, which is why relying on the client SDK alone loses most iOS conversions.
Why does Events Manager show my purchase as $0?
The event is firing without a value and currency parameter. Meta records the conversion but can't optimize toward revenue, so value-based bidding effectively sees nothing. Pass the real amount and ISO currency code on every Purchase event.
How do I stop Meta from double-counting purchases?
Send the same event ID from both the client SDK and the Conversions API for the same purchase. Meta uses that shared ID to deduplicate, counting one conversion instead of two.
Related guides
Not sure which of these is breaking your app?
Zoruko audits your app code for broken Meta and TikTok signal chains — free — and ships each fix as a pull request you review.
Run a free audit