Your Meta pixel was already installed. That was the problem.
A Shopify store came to me ready to launch paid. Google and Meta, feed live, budget approved, everyone impatient. The Meta pixel was already installed and firing healthy volume, which in a pre-launch audit reads like good news. One less thing on the punch list.
It was counting completed product configurations as purchases.
The store sells a configurable product, so a third-party customization app lets customers build what they want before they buy. When a customer finished configuring, the app fired a completion event, and somewhere in the wiring that event was mapped to Meta's purchase event. On top of that, purchases were double-counting.
Meta draws this line clearly. Its documentation on standard and custom events defines standard events as a fixed set of actions Meta itself specifies, with custom events available for the actions a business defines on its own. A finished configuration is a real milestone worth tracking. There is a mechanism built for exactly that. It just is not Purchase.
Nobody made a mistake, exactly. The app was built to report its own completion. The wiring was in place, it was firing, and nobody had ever asked it what it thought a purchase was.
An empty pixel is a problem you can see
If the pixel had not been installed, we would have installed it. Ten minutes of work, no ambiguity, nothing to diagnose.
A pixel that fires the wrong event is worse, because it produces numbers. Numbers get read as evidence. In a pre-launch check, a pixel showing volume is the thing that gets a green check and moves the meeting along.
Now think about what happens if that campaign launches. Advantage+ Shopping allocates budget by predicting which impressions lead to conversions, using the conversion data it receives. Feed it configurator completions and it does its job flawlessly against the wrong target. It finds people who like building things. It gets better at finding them over time, because that is what it is for.
Meanwhile Meta's reported ROAS runs high, inflated by an event that happens far more often than a purchase and inflated again by the duplicates. Meta looks like the strongest channel in the account. It earns more budget. The budget goes toward finding more people who configure and leave.
The report is not just wrong. It is wrong in the direction that makes you spend more on the wrong thing. And every week it runs, the case for spending more gets stronger.
Nothing is verified until three surfaces agree
The check that caught this is not clever. It is just done rather than assumed.
Start with the platform of record. On a Shopify store, the order is the order. Shopify's own record is the count, and every other number in the stack is a claim about that count. This part has to be settled before anything else, because "which system is authoritative for a purchase" is not a question you can answer after the fact, in a meeting, while looking at three dashboards that disagree.
Then place a real transaction and watch what each surface records.
Shopify shows one order. GA4 should show one purchase event, with the same value, at the same time. Meta Events Manager should show one purchase, same value, same time. Ad platforms should attribute at most one.
Two surfaces cannot settle an argument. If Shopify says one and Meta says three, you know they disagree and nothing more. Bring in GA4 and the shape of the disagreement starts naming its own cause. Duplicates in one place and not another point somewhere different than duplicates in both. An event with the right name at the wrong moment points somewhere different than an event with the wrong name entirely.
On this account, GA4 was installed too. It was not configured properly, which is the same lesson wearing different clothes. Present is not configured. Firing is not correct.
Source of truth comes before feedback loop
There are two jobs here and they only work in one order.
The first is establishing which system is authoritative for a purchase, and getting every other surface to agree with it. The second is closing the loop back to the ad platforms, so the thing they optimize toward is the thing you decided was real.
Do the second without the first and you have not built a measurement system. You have automated the transmission of a number nobody validated, to algorithms that will act on it faster and more literally than any human would.
That is the part clients find hardest to sit through. The plumbing work is invisible, it produces no impressions, and it delays the thing everyone actually wants. But the alternative is not launching sooner. The alternative is launching on a signal you did not check, and finding out what it was teaching your campaigns after you have paid for the lesson.
Why this cannot wait until after launch
There is a version of this objection that sounds reasonable: launch now, fix the tracking in a couple of weeks, sort out reporting later.
That works when the reporting layer is only a reporting layer. Under a manual search campaign with human-set bids, bad measurement costs you accuracy. You make worse decisions, but you make them, and fixing the data later restores your ability to decide.
Performance Max and Advantage+ are not that. They consume the conversion signal directly and allocate against it. The signal is not a report you read afterward. It is an instruction you are issuing continuously. So a wrong signal is not an inaccuracy sitting in a dashboard. It is weeks of budget spent training a model toward the wrong outcome.
And correcting it later does not undo that. Google's guidance on changing conversion goals, written for Search and Shopping, says Smart Bidding needs one to two conversion cycles to relearn after any change to conversion goals or actions, even when the underlying action stays the same. Nothing in that logic gets gentler when the campaign type also chooses placements, audiences, and creative from the same signal. The spend that trained the model on the wrong event is gone, and the retraining comes out of the same budget.
What good looks like before launch
Before a dollar moves, four things should be true.
The product data is correct and complete, because neither platform can sell what it cannot see properly. The conversion layer has one authoritative source and one event per real purchase, with values attached. Identity and consent are handled, so that as much of the truth as possible survives the trip to the platform. And there is an agreed baseline, so that "working" means something specific rather than whatever the platform reports.
That is two to four weeks of work on most stores, and none of it is fun. It is also the entire difference between a campaign you can steer and a campaign you can only watch.
If you are getting ready to put real budget behind a Shopify store, the pixel firing is not the finish line. It is the thing to go verify first. That verification, and the measurement foundation under it, is most of what my ecommerce performance work actually is.
If you are about to launch and you are not certain what your conversion events are counting, tell me what you're working on and I will tell you what to check first.