sirius·manual do time
Tecnologia · Tracking

Rastrear uma página de venda externa → Meta + CRM

Playbook pra instrumentar qualquer landing page de venda (fora do nosso domínio) com tracking limpo: lead no CRM, eventos no pixel/GA4 e venda confirmada server-side, sem duplicar nada.

← voltar pros guias

Para quem é: quem monta tracking de lançamento (tech/tráfego). O que você consegue ao final: um funil onde a pessoa deixa o contato, vira lead no CRM, e quando compra o sistema marca a venda no CRM e manda o Purchase pro Meta — tudo automático e sem evento duplicado.

Mapa de eventos 1 · Instrumentar a LP 2 · Popup → CRM 3 · Venda → CRM + Meta 4 · Webhook do gateway 5 · Deploy 6 · Testar Armadilhas

Visão geral e mapa de eventos

O fluxo tem três camadas, cada uma disparando os eventos certos:

LP de venda  ──(popup)──►  CRM (lead)  ──►  checkout  ──(webhook)──►  CRM (comprou) + Meta (Purchase)
  PageView                  Lead                          InitiateCheckout         Purchase
  ViewContent                                                                      (server-side)
EventoDispara quandoOnde
PageViewCarregou qualquer páginaPixel base no <head>
ViewContentCarregou a LP de vendaNo load da LP
LeadSubmit do popup (lead real, antes do checkout)Dentro do JS do popup
InitiateCheckoutSegue do popup pro checkoutAntes do redirect
PurchaseCompra confirmadaServer-side (CAPI), via webhook do gateway — fonte única
Regra de ouro: Purchase só server-side, nunca no navegador. É o que evita o erro nº1 (Purchase duplicado/triplicado).

1Instrumentar a página de venda

Se a LP é HTML estático (ou está num domínio que não é o nosso), ela não herda o GTM/pixel do tema. Instala manual:

No submit do popup, antes de mandar pro CRM:

if (typeof fbq === 'function') fbq('track','Lead');           // lead real
await fetch(CRM_ENDPOINT, { method:'POST', keepalive:true, ... });
if (typeof fbq === 'function') fbq('track','InitiateCheckout'); // vai pro checkout
window.location.href = qs ? CHECKOUT + '?' + qs : CHECKOUT;

keepalive:true garante que o POST completa mesmo com o redirect logo em seguida.


O popup posta nome/e-mail/WhatsApp + UTM pra um handler serverless (função na Vercel) com o token do CRM escondido no servidor. O handler faz, no GHL:

  1. Upsert do contato (dedup por e-mail/telefone). Mandar firstName+lastName, não só name.
  2. Tag de forma aditiva (POST /contacts/{id}/tags) — o contacts/upsert SUBSTITUI o conjunto de tags, então tag no upsert apaga as outras.
  3. Oportunidade no 1º estágio da pipeline. Anti-duplicata: se já existe opp do contato nessa pipeline, reusa (não rebaixa).
Por que capturar antes do checkout: quem desiste no checkout já está no CRM como lead, pronto pra régua de recuperação. Sem isso, não há o que recuperar.

3Venda → CRM + Meta (a peça central)

O gateway (Eduzz, Hotmart, etc.) chama um segundo handler no webhook da venda. Quando a venda é aprovada e é do produto certo, ele:

Escopo de segurança: o handler só age se a venda for do produto certo (id configurado) ou o contato já estiver no funil — pra não criar oportunidade pra compra de outro produto do mesmo gateway.

Payload mínimo do Purchase pro Meta CAPI:

POST https://graph.facebook.com/v21.0/<PIXEL_ID>/events?access_token=<TOKEN>
{
  "data":[{
    "event_name":"Purchase",
    "event_time": <unix>,
    "event_id":"pur_eduzz_comport_<transaction_id>",   // dedup
    "action_source":"website",
    "user_data":{ "em":[sha256(email)], "ph":[sha256(fone)] },  // hash SHA-256
    "custom_data":{ "value": <valor>, "currency":"BRL" }
  }]
}

4Configurar o webhook (caso Eduzz)

Na conta produtora do Eduzz, em console.eduzz.com/webhook/configs (menu WEBHOOK → Configurações), criar uma config nova:

Armadilha que pagamos

O payload do Eduzz v3 chega FLAT — o objeto da fatura direto na raiz ({ id, status, buyer:{email,name,cellphone}, items:[{productId}], price:{value} }), sem o envelope { event, data } que a documentação mostra. Se o handler detectar v3 só pela presença de event, ele ignora a venda. Detecte pela presença de buyer/items e desembrulhe data se vier.

O módulo de apps/dev-token (pra registrar via API) pode estar bloqueado pra conta — a UI de Configurações resolve igual e manda o mesmo formato v3.


5Deploy e variáveis

Handlers na Vercel (projeto dashboard). Deploy: npx vercel --prod. Variáveis de ambiente típicas:

VarPra quê
<GATEWAY>_POSTBACK_TOKENguarda do ?token=
<GATEWAY>_PRODUCT_IDreconhece compra direta do produto certo
token do MetaCAPI (system user com permissão no pixel)
token do CRM (PIT)scoped à location certa
Armadilha que pagamos

Variável marcada como sensitive no Vercel não volta no vercel env pull (vem vazia). Guarde o valor num lugar seguro fora do Vercel (ex: ~/.config/sirius/). E atenção: se rotacionar o token, atualize a URL no webhook do gateway — senão o webhook real começa a tomar 401 mesmo tendo passado no teste antes.


6Testar de ponta a ponta

  1. Crie uma oferta de teste de R$5 (mesmo produto) pra não gastar. O handler lê o valor do webhook, então registra um Purchase de R$5.
  2. Passe pela LP: preencha o popup → confirme o lead no CRM (estágio 1, tag de lead).
  3. Pague os R$5 → confirme no CRM que subiu pra "Comprou" + tag comprou, e no Meta Events Manager que chegou 1 Purchase (evento de servidor/CAPI, com alguns minutos de atraso).
  4. Reembolse → confirme a oportunidade marcada como perdida.
Armadilhas de teste

Armadilhas que a gente já pagou (resumo)


Documentos relacionados


Resumo em 1 minuto

  1. LP: pixel + GA4 (property certa) no head; ViewContent no load; UTM lida e repassada.
  2. Popup: Lead + POST pro handler → upsert + tag aditiva + oportunidade no CRM; depois InitiateCheckout e redirect.
  3. Venda: webhook do gateway → handler dispara Purchase CAPI (dedup por event_id) + tag comprou + avança oportunidade.
  4. Webhook Eduzz: configurar na UI, eventos paid/refunded/canceled, URL com ?token=; payload vem flat.
  5. Testar com R$5, conferir CRM + Meta Events Manager; 200 não é prova.