The Hotmart sale reaching Meta as Purchase, with the campaign that brought it
The checkout belongs to Hotmart, the pixel is yours, and the sale happens on a domain your pixel never sees. Without the link between the session and the webhook, Meta is left without the event that matters most. This is the path that brings the sale back to Meta as Purchase — with value, product and the right campaign.

Every producer who advertises on Meta and sells on Hotmart has the same hole: the page is theirs, the checkout is Hotmart’s, and the Purchase event the algorithm needs happens on a domain where their pixel does not run. Hotmart offers its own pixel on checkout, and it helps — but the Purchase leaving there knows nothing about the session that started on your site, nor about the person you already knew.
The full path has four steps, and each can fail silently. We explained the design in CAPI for info products with external checkout; here the focus is what happens to the SALE, from the webhook to Events Manager.
Step 1: the marker in the checkout link
When the person clicks “buy”, the pixel injects a session identifier into the checkout link, in the tracking field Hotmart returns in the webhook (sck or xcod). It is the only deterministic thread between the visit and the purchase. Two cautions that only showed up by measuring: the field is cut at 283 characters, and if the identifier is at the end it is the victim — 56% of markers arrived unreadable in a real account until we moved the identifier to the start.
Step 2: the webhook arrives, and it is not the only one
Hotmart notifies the purchase by webhook within seconds. But the same sale also arrives through the periodic API sync, hours later, with another stamp. If the Purchase event goes out on both paths, Meta receives the same sale twice — and without an equal event_id it counts two. The rule that works: the webhook fires; the sync only emits what the webhook MISSED. In a large account we measured 47% rewriting of the same sale before applying this.
PURCHASE_COMPLETE arrives days after PURCHASE_APPROVED, for the same transaction. Filtering both as “sale” sends each purchase twice.
Step 3: resolve the person
With the marker, the purchase matches the session: campaign, ad set, ad, fbc, fbp, everything the page knew. Without the marker (copied link, another device, cut marker), identity remains: the buyer’s e-mail looked up in the lead graph. We measured both paths in one account: 69.9% by marker, 19.6% by identity, 10.5% unattributed. It is the ruler of sales attribution in two paths.
Step 4: build the Purchase
| CAPI field | Where it comes from in Hotmart | Caution |
|---|---|---|
| value | The transaction’s price_value | It is the full price. The commission is something else and does not go to Meta |
| currency | price_currency_code | A sale in USD or EUR needs the right currency, not converted |
| content_ids / content_name | product_id / product_name | Enables Purchase per product in Ads Manager |
| order_id | transaction_id | It is the dedup key on Meta’s side |
| em / ph / fn / ln | The webhook’s buyer | Always present: 100% coverage on Purchase |
| fbc / fbp / external_id | The matched session, or the person’s last known | It is what ties the purchase to the ad |
| event_time | The transaction’s order_date | Never the processing time: a reprocessed purchase would fall outside the 7 days |
The status filter deserves its own line: only APPROVED and COMPLETE are sales; an expired PIX or a printed boleto sent as Purchase is a false conversion training the wrong algorithm. And subscription renewal is your decision — sending it as Purchase inflates return; not sending it hides real revenue. We wrote about it in renewal counted as a new sale.
What shows up in Events Manager
Purchase with “website” origin (not “server”, even though it leaves the server — see action_source), high match quality because e-mail and phone are always present, and campaign attribution on most sales. When the gap between what Meta credits and what Hotmart bills grows, the culprit is almost always one of the four steps — and the delivery audit says which.
In CrazyLeads the pixel injects the marker, the Hotmart source receives the webhook and the sync with novelty-only emission, the resolver matches the person by both paths, and the Meta delivery builds the Purchase with the fields in the table, deduplicated by transaction, with the attribution the session had.