Status da verificação · 23/06/2026
form_submit_trial dispara no cadastro · Lead no navegador
(GA4, Google Ads, Meta Pixel)
Divisão de responsabilidade
Quem cuida de quê
A Hub3Ps cuida de toda a camada de mídia. Do lado do produto, precisamos de três pontos de contato, detalhados abaixo.
| Camada | Hub3Ps | Produto JurIA |
|---|---|---|
| Tags no navegador (GA4, Pixel, Google Ads) | Pronto | - |
| Consentimento de cookies (LGPD) | Pronto | - |
| Parâmetros propagados da LP até o /register | Pronto | - |
| Container GTM na página de cadastro | Pronto | Instalado · validado ✓ |
| Sinal de cadastro no navegador | - | Ponto 1 · validado ✓ |
| Envio da venda à Meta (CAPI) | Fornece código + token | Publica e roda no Supabase |
| Persistência dos identificadores de origem | - | Ponto 1 |
| Webhook do Stripe (pagamento e upgrade) | - | Ponto 2 |
Pontos de integração
Dois contatos entre o produto e a mídia: cadastro e venda
Os trechos de código são exemplos de referência e podem ser adaptados ao stack do produto.
Carregar o container GTM no /register Validado · 23/06
O container do Google Tag Manager precisa estar na página de cadastro. É ele que escuta o sinal do Ponto 1 e aciona as tags de navegador (Pixel, GA4, Google Ads).
GTM-WHQGLTXC está
carregando no /register (checado no Tag Assistant). O
snippet abaixo fica só como referência.
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-WHQGLTXC');</script>
<!-- End Google Tag Manager -->
<!-- logo apos a abertura do body: -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WHQGLTXC"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
Cadastro do trial concluído
No sucesso do cadastro em /register, o tracking precisa
de dois sinais: um no navegador (alimenta Pixel, GA4 e Google Ads) e
a persistência dos identificadores de origem no registro do
escritório (usados depois, na venda). O event_id é o
que casa navegador e servidor sem duplicar a conversão.
event_id é reaproveitado no envio server-side,
então precisa ser gerado uma vez e guardado.
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'form_submit_trial',
event_id: crypto.randomUUID(), // unico por cadastro
value: 199,
currency: 'BRL',
plan: 'trial', // sempre 'trial' no cadastro
area: '<segmento>' // trabalhista | previdenciario | contencioso (vem da LP/campanha)
});
{
event_id, // o mesmo gerado no push acima
gclid, fbclid, // vem da URL de entrada
utm_source, utm_medium, utm_campaign,
utm_content, utm_term,
area // &area=... vindo da LP por segmento
}
// a LP ja propaga esses parametros ate o /register;
// do lado do produto, basta le-los da URL e gravar.
event,
event_id, value, currency,
plan. area vem da LP/campanha, não do form.
form_submit_trial dispara sozinho com os campos acima, e
o registro do escritório guarda event_id +
gclid/fbclid/utm +
area.
Pagamento e upgrade (webhook do Stripe)
Quando o Stripe confirma uma assinatura paga ou um upgrade, essa venda precisa chegar à Meta (CAPI) — é o que liga a venda de volta ao anúncio que a originou.
O que o envio precisa levar: os dados da venda
(value, currency, plan) mais
os identificadores guardados no Ponto 1 (event_id,
gclid/fbclid/utm) e o e-mail
com hash SHA-256. O mesmo event_id do navegador entra
aqui para a Meta deduplicar.
Segue abaixo um código sugerido da edge function (Supabase) e o token — fique à vontade para adaptar ao stack de vocês. O Google Ads Offline fica para a fase futura (foco atual no Meta).
{
event: 'trial_to_paid', // ou 'upgrade_plan'
event_id: 'sub_1Pxxxx', // id estavel, ex: assinatura Stripe
value: 199,
currency: 'BRL',
plan: 'basic', // Basic / Pro / Enterprise
email_sha256: '...', // hash do e-mail
gclid: '...', fbclid: '...',
utm_source: '...', utm_medium: '...', utm_campaign: '...',
utm_content: '...', utm_term: '...'
}
// supabase/functions/meta-capi/index.ts // Recebe a venda e envia a Meta via Conversions API. import { createHash } from "node:crypto"; const PIXEL_ID = "1009120801605718"; const TOKEN = Deno.env.get("META_CAPI_TOKEN"); // secret no Supabase const ENDPOINT = `https://graph.facebook.com/v20.0/${PIXEL_ID}/events`; const sha256 = (v) => createHash("sha256").update(v.trim().toLowerCase()).digest("hex"); Deno.serve(async (req) => { const s = await req.json(); // venda + identificadores do Ponto 1 const body = { data: [{ event_name: "Purchase", // trial_to_paid / upgrade_plan event_time: Math.floor(Date.now() / 1000), event_id: s.event_id, // mesmo do navegador -> dedup action_source: "website", user_data: { em: s.email ? [sha256(s.email)] : undefined, fbc: s.fbc, fbp: s.fbp, client_ip_address: s.client_ip, client_user_agent: s.user_agent, }, custom_data: { value: s.value, currency: s.currency, plan: s.plan }, }], }; const r = await fetch(`${ENDPOINT}?access_token=${TOKEN}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); return new Response(await r.text(), { status: r.status }); });
META_CAPI_TOKEN), nunca no código. Confidencial.
event_id do cadastro, e o Events Manager mostra o
evento processado.
Dois detalhes que sustentam tudo
Deduplicação. O
event_id compartilhado entre
navegador e servidor faz a Meta entender uma conversão vinda de duas
fontes como uma só. No Google Ads, quando o Offline entrar (fase
futura), a venda passa só por ele, sem tag concorrente no navegador.
Atribuição. Os identificadores (gclid, fbclid,
utm) gravados no Ponto 1 são
lidos de volta no Ponto 2. Sem essa persistência, a venda acontece
dias depois e não há como ligá-la à campanha de origem.
Fase futura
Fora do escopo agora — registrado para não se perder
Nada aqui bloqueia o início; entram quando a operação estiver rodando e validada. Mantidos fora dos pontos acima de propósito, para não atrapalhar a implementação atual.
first_login. Sinal de ativação (primeiro acesso) enviado ao GA4. É analítico, não otimiza lance — entra quando formos medir qualidade de lead.
Lead via CAPI + dedup. No início o Lead
(form_submit_trial) vai só pelo navegador (Pixel). O
envio por servidor e a deduplicação Pixel × CAPI entram depois.
Google Ads Offline. Foco atual é o Meta. O Offline (auth da API do Google Ads) entra quando o Google receber verba relevante.