O problema: o webhook não sabe quem clicou no anúncio
O checkout da Hotmart fica em outro domínio (pay.hotmart.com). Ele não lê os cookies da sua landing page e o webhook de compra só traz os dados do checkout: comprador, valor e transação.
Só que cada rede precisa de um identificador que nasce no navegador, na sua página:
- Meta:
fbc(clique no anúncio) efbp(navegador), além de IP e user agent. - Google Ads:
gclid(clique no anúncio). - GA4:
client_idega_session_id, para a compra cair no mesmo usuário e na mesma sessão que veio da campanha. - LinkedIn:
li_fat_id(clique no anúncio).
A Hotmart só devolve 3 parâmetros livres no webhook: src, sck e xcod. Não cabe tudo isso.
A solução: um ID só no checkout + Stape Store
Em vez de tentar enfiar todos os IDs na URL do checkout, mandamos só um: o ID do visitante (cookie user-id). O resto fica guardado no servidor.
- Em todo
page_view, o GTM Server grava no Stape Store (um banco de dados da Stape) um documento com o ID do visitante e os identificadores daquela pessoa:client_id,ga_session_id,fbp,fbc,gclid,li_fat_id, IP e user agent. - O site coloca o mesmo ID do visitante no parâmetro
xcoddo link do checkout. - A Hotmart devolve o
xcodno webhook, emdata.purchase.origin.xcod. - No webhook, o GTM Server busca no Stape Store o documento com esse ID e entrega cada identificador para a tag certa.
Dica: o evento é server-side, mas os IDs de clique sempre nascem no navegador. O Stape Store é a ponte entre a visita e a compra.
Arquitetura
user-id)xcod = user-idxcodGostou? No curso Dominando o Rastreamento você aprende o server-side do zero.
Conhecer o cursoO que você precisa antes de começar
- GTM Server-Side na Stape, com o Data Client ativo e o power-up User ID ligado (ele cria o cabeçalho
x-stape-user-id). - Stape Store disponível no seu plano da Stape.
- GA4 enviando eventos para o seu GTM Server (o
page_viewprecisa passar pelo servidor). - Acesso de produtor na Hotmart para cadastrar webhooks.
- Pixel e token da Conversions API da Meta, ID de métricas do GA4 e acesso de administrador ao Google Ads.
Passo 1
Gravar o ID do visitante num cookie (Cookie Monster)
O power-up User ID da Stape envia em toda requisição o cabeçalho x-stape-user-id, um ID estável do navegador. Precisamos dele também no navegador, para mandar no checkout.
- No GTM Server, crie a variável 2.04
x-stape-user-id: tipo Cabeçalho da solicitação, nomex-stape-user-id. - Adicione o modelo Cookie Monster (stape-io) e crie a tag: cookie
user-id, valor{{2.04 x-stape-user-id}}, validade 31536000 (1 ano), domínio auto, HttpOnly desmarcado. - Acionador:
page_view.
Atenção: o HttpOnly precisa ficar desmarcado. Se marcar, o JavaScript do site não consegue ler o cookie para colocar no xcod.
Passo 2
Gravar os IDs no Stape Store (page_view)
Variáveis de apoio no GTM Server:
- 7.05 ED
client_id: Dados do evento, chaveclient_id. - 7.06 ED
ga_session_id: Dados do evento, chavega_session_id. - 7.02 cookie
_fbpe 7.03 cookie_fbc: Valor do cookie. - 7.04 cookie
_li_fat_id: Valor do cookie. - 7.07
gclid: Tabela RegEx sobre{{00.02 page_location}}, padrão.*[?&]gclid=([^&#]+).*e saída$1. - 2.05
ip_overrideeuser_agent: Dados do evento.
Tag Stape Store Writer (modelo da stape-io):
- Document ID:
{{2.04 x-stape-user-id}}, o mesmo valor do cookieuser-id. - Merge document keys: marcado.
- Skip null or undefined values: marcado.
- Add Timestamp: marcado.
- Custom Data:
client_id,ga_session_id,fbp,fbc,gclid,li_fat_id,ipeuser_agent, cada um com a sua variável. - Acionador:
page_viewcom a condiçãox-stape-user-iddiferente de undefined.
Dica: o Merge com Skip null é o que segura a atribuição. O gclid chega só na primeira página. Nas próximas visitas ele vem vazio e, sem essas duas opções, você apagaria o ID do clique.
Passo 3
Mandar o user-id no xcod do checkout
No site, todo link do checkout da Hotmart precisa sair com xcod igual ao cookie user-id. Se o seu site usa links normais da Hotmart, uma tag HTML personalizada no GTM Web resolve, disparando em All Pages:
<script>
(function () {
function getUserId() {
var m = document.cookie.match(/(?:^|; )user-id=([^;]+)/);
return m ? decodeURIComponent(m[1]) : '';
}
function decorate(a) {
var uid = getUserId();
if (!uid || !a || a.href.indexOf('pay.hotmart.com') === -1) return;
var u = new URL(a.href);
u.searchParams.set('xcod', uid);
a.href = u.toString();
}
document.querySelectorAll('a[href*="pay.hotmart.com"]').forEach(decorate);
document.addEventListener('click', function (e) {
var a = e.target.closest && e.target.closest('a[href*="pay.hotmart.com"]');
if (a) decorate(a);
}, true);
})();
</script>Atenção: na primeira página da visita o cookie user-id só existe depois que o servidor responde ao page_view. Por isso o script também decora o link no clique, e não só no carregamento.
Dica: se o botão de compra monta a URL do checkout por código (formulário, função própria), coloque o xcod nesse código, lendo o cookie user-id na hora de montar a URL. Deixe o src e o sck livres para as suas UTMs.
Passo 4
Cadastrar o webhook na Hotmart (um só)
- Na Hotmart, vá em Ferramentas > Webhook (API e notificações) e crie uma configuração na versão 2.0.0.
- Evento: Compra aprovada.
- URL:
https://SEU-SERVER/hotmart-compra - Copie o
hottok. Ele é a trava de segurança do acionador.
Um webhook só alimenta as quatro redes. O Data Client recebe o JSON e os campos ficam aninhados, então as variáveis usam o caminho completo (ex.: data.buyer.email).
Gostou? No curso Dominando o Rastreamento você aprende o server-side do zero.
Conhecer o cursoPasso 5
Variáveis do webhook e da busca no Stape Store
Dados do evento (webhook da Hotmart):
- 6.01 email →
data.buyer.email - 6.02 transaction →
data.purchase.transaction - 6.03 value →
data.purchase.price.value - 6.04 currency →
data.purchase.price.currency_value - 6.05 cidade →
data.buyer.address.city - 6.06 país →
data.buyer.address.country_iso - 6.08 xcod (user-id) →
data.purchase.origin.xcod - 6.09 first_name e 6.10 last_name →
data.buyer.first_name/data.buyer.last_name - 6.11 event →
event - 6.12 phone →
data.buyer.checkout_phone - 6.13 state →
data.buyer.address.state - 6.14 zipcode →
data.buyer.address.zipcode - 6.15 product name →
data.product.name - 6.16 product id →
data.product.id
Stape Store Lookup (uma variável por campo):
- Lookup type: Document ID =
{{6.08 xcod (user-id)}}. - Document Path: o campo que você quer (
client_id,ga_session_id,fbp,fbc,gclid,li_fat_id,ip,user_agent). - Store response: marcado, para fazer uma leitura só no banco por webhook.
- Nomes usados na aula: 8.01 Store client_id até 8.08 Store user_agent.
Passo 6
Acionador com 3 travas
Evento personalizado .* (regex), disparando quando TODAS as condições forem verdadeiras:
- Request Path é igual a
/hotmart-compra x-hotmart-hottoké igual aohottokda sua conta- 6.11 event é igual a
PURCHASE_APPROVED
Atenção: se você tem tags "All Events" no servidor (GA4 ou Meta disparando em todos os eventos), coloque esse acionador como exceção nelas. Sem isso, o webhook vira um evento estranho no GA4 e no Pixel.
Passo 7
Meta: tag Facebook Conversion API
Modelo Facebook Conversion API (stape-io):
- Event Name: Purchase (padrão). Action Source: website.
- Pixel ID e Access Token: as suas constantes.
- Server Event Data:
event_id={{6.02 transaction}}eevent_source_url= a URL do checkout. - User Data: em, ph, fn, ln, ct, st, zp e country vêm do webhook (a tag aplica o hash).
external_id={{6.08 xcod}}. - Do Stape Store:
fbc={{8.04}},fbp={{8.03}},client_ip_address={{8.07}}eclient_user_agent={{8.08}}. - Custom Data: value, currency, order_id, content_name, content_ids e content_type = product.
- Generate _fbp: desmarcado (o webhook não tem navegador para receber cookie).
Dica: o event_id com o número da transação evita compra duplicada se a Hotmart reenviar o webhook. Se o Pixel da Hotmart também envia Purchase, use o mesmo critério ou desligue um dos dois.
Passo 8
GA4: a compra no mesmo usuário e na mesma sessão
Tag Google Analytics: GA4 (nativa do servidor):
- ID de métricas: o seu G-XXXX. Nome do evento:
purchase. - Parâmetros de evento:
client_id={{8.01 Store client_id}},ga_session_id={{8.02 Store ga_session_id}},ip_override={{8.07}},user_agent={{8.08}},transaction_id={{6.02}},value={{6.03}},currency={{6.04}}.
O client_id é o que liga a compra ao usuário que veio do anúncio. O ga_session_id coloca a compra na sessão de origem, com a mesma origem/mídia e campanha. Sem eles, o GA4 cria um usuário novo e a compra aparece como direta (not set).
Atenção: o transaction_id deduplica compras no GA4. Use sempre o número da transação da Hotmart.
Gostou? No curso Dominando o Rastreamento você aprende o server-side do zero.
Conhecer o cursoPasso 9
Google Ads: Data Manager API
A tag nativa de conversão do Google Ads no servidor não funciona com webhook, porque depende do contexto do navegador. Para webhook, o caminho é a Data Manager API, com o modelo "Google Data Manager API Conversion Events" (stape-io).
- No Google Ads: Metas > Conversões > Nova ação de conversão > Importar (outras fontes / offline). Anote o ID da ação de conversão.
- Na Stape: no seu container, abra Connections > Google Data Manager e faça login com a conta Google que acessa o Google Ads.
- Na tag: Event Type = Conversion, Authentication = Stape, Product = Google Ads, Operating Customer ID e Customer ID = o ID da conta sem traços, Conversion Event ID = o ID anotado no item 1.
- Conversion Information: Transaction ID =
{{6.02}}, Currency ={{6.04}}, Conversion Value ={{6.03}}. - User Data: e-mail, telefone, nome, sobrenome, país e CEP do webhook (enhanced conversions).
- Ad Identifiers:
gclid={{8.05 Store gclid}}, user agent ={{8.08}}e IP ={{8.07}}.
Dica: mesmo quando o gclid não chega (outro aparelho, Safari com restrição), o e-mail e o telefone com hash ainda permitem que o Google case a conversão.
Bônus — LinkedIn no mesmo webhook
A tag LinkedIn Conversion API da aula anterior entra no mesmo acionador /hotmart-compra. A única mudança é o LinkedIn First Party Ads Tracking UUID, que passa a ser {{8.06 Store li_fat_id}}, buscado no Stape Store, em vez do xcod.
Passo 10
Testar e validar
- Abra o modo Visualizar do GTM Server e navegue pela landing page com
?gclid=teste123na URL. - Confira se a tag Stape Store Writer disparou e, no painel da Stape (Store), se o documento com o seu
user-idtem os campos. - Clique no botão de compra e confira se a URL da Hotmart saiu com
xcodigual ao cookieuser-id. - Envie um teste do webhook (ou faça uma compra de teste) com esse
xcode veja as variáveis 8.xx preenchidas. - Confira as respostas: Meta (Gerenciador de Eventos > Testar eventos), GA4 (DebugView ou Tempo real) e Google Ads (Diagnóstico da ação de conversão, pode levar horas).
- Só então publique o contêiner.
Erros mais comuns
- Cookie
user-idcom HttpOnly: o site não consegue ler o cookie e oxcodsai vazio. - Writer sem Merge ou sem Skip null: a segunda visita apaga o
gclide ofbcda primeira. - Esquecer a exceção nas tags All Events: o webhook vira evento no GA4 e no Pixel.
- Duas fontes de Purchase: n8n, Pixel da Hotmart e esta tag enviando a mesma compra. Escolha uma ou deduplique pelo
event_id. - Tag nativa de conversão do Google Ads no webhook: não registra. Use a Data Manager API.
- GA4 sem
client_id: a compra vira um usuário novo e a atribuição se perde. - Documento não encontrado no Store: a pessoa comprou em outro aparelho ou o
xcodnão passou. Os eventos ainda vão com e-mail e telefone com hash.
Próximo passo
Quer dominar o rastreamento do zero ao server side?
No curso Dominando o Rastreamento são 53 aulas em 9 módulos: GTM, GA4, Meta CAPI, server-side, CTWA no WhatsApp e dashboard próprio. O mesmo raciocínio desta aula, aplicado de ponta a ponta.
Baixe o passo a passo em PDF
Versão em PDF com todos os passos, o código e os nossos contatos — para seguir com calma no seu projeto.
Precisa de ajuda para implementar? Fale com a gente