Nenhum rotator selecionado
Selecione um rotator ao lado
ou clique em + Novo para criar.
Cada vez que alguém compra um produto seu na plataforma de afiliado, ela envia um aviso automático para a URL do webhook. Esse sistema recebe o aviso, lê os dados da compra (valor, e-mail, UTMs) e encaminha tudo automaticamente para o GA4 e para o Facebook CAPI. Você não precisa fazer nada além de cadastrar a URL uma vez.
Ferramentas → Webhooks → Adicionar webhook → cole a URL → selecione todos os eventos de compra.
Dica: adicione o Hottok no campo "Webhook Secret" dentro de ⚙️ Config → Webhook.
Conta → Webhooks → Adicionar → cole a URL. Para segurança, ative a assinatura e coloque o segredo no campo Kiwify Secret em ⚙️ Config.
Conta → Integrações → Webhooks → Nova URL. Selecione os eventos: Venda Concluída, Aguardando Pagamento, Reembolso.
Configurações → Webhooks → Adicionar Webhook. Cole a URL e marque os eventos de compra aprovada e estorno.
Configurações da conta → Integrações → Webhook / Postback. Cole a URL correspondente à plataforma.
Account Settings → My Site → Advanced Tools → Instant Notification URL (Clickbank) ou Account → Webhooks (Digistore). Cole a URL.
Em ⚙️ Config → Webhook, defina um Webhook Secret. Depois adicione
?secret=SUA_SENHA no final de cada URL que cadastrar nas plataformas.
Assim somente requisições com a senha correta serão aceitas.
Exemplo: https://seu-site.pages.dev/webhook/hotmart?secret=minhasenha123
&secret=SUA_SENHA quando configurar o Webhook Secret
Nenhum evento ainda. Configure os webhooks nas plataformas.
📊 Resumo
Abra a aba Analytics para carregar os dados.
ℹ️ Histórico armazenado por dia (TTL 13 meses). Clique em qualquer linha para filtrar. Configure taxas/custos na aba ⚙️ Config → 🧾 Custos & Impostos.
🇧🇷 Propriedade Brasil (BRL)
🌎 Propriedade Internacional (USD) opcional
Use quando você vende em dólares (Clickbank, Digistore24, afiliados internacionais). Crie uma propriedade GA4 separada — misturar BRL e USD na mesma propriedade distorce todos os relatórios de receita. As mesmas vendas chegam nesta propriedade com valores em USD.
Pixel padrão
Múltiplas BMs — PixelMap (roteado por utm_host)
Coloque o código no utm_host do anúncio (ex: C1_MOBILE).
O Worker roteia para o Pixel correto automaticamente.
Pixel padrão
Múltiplas contas — ttPixelMap (roteado por utm_host)
Mesmo padrão do Facebook: coloque o código no utm_host do anúncio (ex: C1_MOBILE).
O Worker roteia para o Pixel TikTok correto automaticamente.
Credenciais da API
Envio server-side de conversões direto para o Google Ads — mesmo princípio do Facebook CAPI.
Funciona quando o visitante chegou pela busca paga (Google gera um gclid na URL).
⚠️ Requer gclid na URL do anúncio — configure o auto-tagging no Google Ads.
Configure aqui para ver ROAS e ROI na aba Analytics → 💰 ROAS. Para uso próprio (suas contas), não requer aprovação de app — basta gerar os tokens.
Meta Ads (Facebook / Instagram)
TikTok Ads
Google Ads usa credenciais acima
As credenciais OAuth já estão no card "Google Ads Enhanced Conversions". Para puxar gastos de múltiplas contas, adicione os Customer IDs aqui. Deixe vazio para usar o mesmo Customer ID das conversões.
Para MCC: adicione o ID do Manager Account primeiro e os sub-IDs em seguida. Configure também o campo "Login Customer ID" se necessário.
Estes valores são usados para calcular Lucro, ROI e Margem no Resumo. Deixe em 0 qualquer campo que não se aplique.
Taxas de plataforma de checkout (% descontada por cada venda)
Impostos sobre vendas
Selecione seu tipo de empresa para preencher automaticamente a alíquota estimada:
Aplicado sobre o Faturamento Líquido
Impostos sobre anúncios
Ao pagar anúncios do Meta/Google com cartão de crédito brasileiro, incidem dois encargos adicionais sobre o valor cobrado:
Aplicado sobre Gastos com anúncios
Outros custos
Prorateado pelo período selecionado
Secret geral
O secret protege seu webhook contra envios não autorizados — qualquer requisição sem ele é rejeitada automaticamente.
Hotmart Hottok opcional
Kiwify Secret HMAC opcional
Os checkboxes ficam salvos no seu navegador.
campaign-hq) e clique em Create repository. Isso cria uma cópia 100% sua — todas as atualizações que você fizer ficam no seu repositório.public
campaign-hq.pages.dev
wrangler.toml no GitHub colocando os IDs copiados e faça push — a Cloudflare lê o arquivo automaticamente no próximo deploy.ADMIN_TOKEN · Valor: uma senha forte qualquer
localStorage por 30 dias. Cole no <head> de cada landing page.</body> — depois do script anterior.utm_lp injetado pelo rotator) chegam com a venda nos webhooks.utm_campaign para o nome do conjunto e utm_medium para o código da conta. O webhook mapeia automaticamente para utm_conj e utm_host. Para Kiwify e demais, use utm_conj/utm_ad/utm_host diretamente.https://pageswirl.pages.dev/webhook/PLATAFORMA?secret=SEU_SECRETA aba Webhooks já monta a URL certa com o seu secret preenchido.
</body> da LP — depois do script do Google Analytics (gtag.js).
<script>
(function () {
// ── Scroll depth + Tempo na página — Campaign HQ ──────────────
var SCROLL_THRESHOLDS = [25, 50, 75, 90]; // % da página
var TIME_THRESHOLDS = [30, 60, 120]; // segundos
var fired = {};
function fire(name, params) {
if (typeof gtag !== 'undefined') gtag('event', name, params);
}
// Scroll tracking
function onScroll() {
var scrolled = window.scrollY || document.documentElement.scrollTop;
var total = document.body.scrollHeight - window.innerHeight;
if (total <= 0) return;
var pct = Math.round((scrolled / total) * 100);
SCROLL_THRESHOLDS.forEach(function (t) {
if (!fired['s' + t] && pct >= t) {
fired['s' + t] = true;
fire('scroll_depth', { depth_percent: t, page: location.pathname });
}
});
}
window.addEventListener('scroll', onScroll, { passive: true });
// Tempo na página
TIME_THRESHOLDS.forEach(function (t) {
setTimeout(function () {
if (!fired['t' + t]) {
fired['t' + t] = true;
fire('time_on_page', { seconds: t, page: location.pathname });
}
}, t * 1000);
});
})();
</script>
depth_percent / seconds. Crie dimensões personalizadas no GA4 para segmentar.URL_DO_DOWNSELL pelo link da sua oferta de recuperação.
Cole antes do </body>.
<script>
(function () {
// ── Backfix — redireciona botão Voltar para downsell ──────────
var DOWNSELL_URL = 'URL_DO_DOWNSELL'; // ← substitua aqui
// Empurra um estado extra para o histórico
history.pushState({ backfix: true }, '', location.href);
window.addEventListener('popstate', function (e) {
// Empurra de volta para manter o visitante na página
history.pushState({ backfix: true }, '', location.href);
// Redireciona para o downsell
setTimeout(function () {
location.replace(DOWNSELL_URL);
}, 50);
});
})();
</script>
<head> de todas as páginas — LP e obrigado.
Substitua SEU_TIKTOK_PIXEL_ID pelo seu Pixel ID (encontrado em TikTok Events Manager).
<!-- TikTok Pixel Base Code -->
<script>
!function(w,d,t){
w.TiktokAnalyticsObject=t;
var ttq=w[t]=w[t]||[];
ttq.methods=['page','track','identify','instances','debug',
'on','off','once','ready','alias','group',
'enableCookie','disableCookie'];
ttq.setAndDefer=function(t,e){
t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}
};
for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);
ttq.instance=function(t){
for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)
ttq.setAndDefer(e,ttq.methods[n]);
return e
};
ttq.load=function(e,n){
var i='https://analytics.tiktok.com/i18n/pixel/events.js';
ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=i,
ttq._t=ttq._t||{},ttq._t[e]=+new Date,
ttq._u=ttq._u||{},n&&(ttq._u[e]=n);
var o=document.createElement('script');
o.type='text/javascript',o.async=!0,o.src=i+'?sdkid='+e+'&lib='+t;
var a=document.getElementsByTagName('script')[0];
a.parentNode.insertBefore(o,a)
};
ttq.load('SEU_TIKTOK_PIXEL_ID'); // ← substitua aqui
ttq.page();
}(window,document,'ttq');
</script>
<!-- End TikTok Pixel Base Code -->
order_id da URL e dispara o evento Purchase com o mesmo
eventID que o servidor já enviou via CAPI — evitando contagem dupla.
<script>
(function() {
// ── Deduplicação Facebook — Página de Obrigado ────────────────
// Lê o ID do pedido da URL (funciona com Hotmart, Kiwify, Eduzz, etc.)
var u = new URL(window.location.href);
var orderId = u.searchParams.get('transaction')
|| u.searchParams.get('order_id')
|| u.searchParams.get('invoice')
|| u.searchParams.get('cod')
|| u.searchParams.get('sale_code')
|| u.searchParams.get('transaction_id')
|| 'order-' + Date.now();
var utmAd = sessionStorage.getItem('utm_ad') || '';
var utmConj = sessionStorage.getItem('utm_conj') || '';
if (typeof fbq !== 'undefined') {
fbq('track', 'Purchase',
{ value: 0, currency: 'BRL', utm_ad: utmAd, utm_conj: utmConj },
{ eventID: orderId } // mesmo eventID que o servidor enviou via CAPI
);
}
})();
</script>
eventID = orderId é o segredo da deduplicação: o Facebook ignora o evento duplicado quando Pixel e CAPI mandam o mesmo ID. O webhook já envia o CAPI com esse ID — este script fecha o ciclo no lado do browser.eventID igual garante que o TikTok não duplique a conversão entre Pixel e Events API.
<script>
(function() {
// ── Deduplicação TikTok — Página de Obrigado ─────────────────
var u = new URL(window.location.href);
var orderId = u.searchParams.get('transaction')
|| u.searchParams.get('order_id')
|| u.searchParams.get('invoice')
|| u.searchParams.get('cod')
|| u.searchParams.get('sale_code')
|| u.searchParams.get('transaction_id')
|| 'order-' + Date.now();
if (typeof ttq !== 'undefined') {
ttq.track('PlaceAnOrder',
{ value: '0', currency: 'BRL', order_id: orderId },
{ eventID: orderId } // mesmo eventID que o servidor enviou via TikTok Events API
);
}
})();
</script>
🌀 Rotator distribui tráfego e injeta
utm_lp automático ·
📄 Scripts passam UTMs + fbclid + ttclid para o checkout ·
📡 Webhooks recebem vendas e disparam GA4 + Facebook CAPI + TikTok Events API ·
🎉 Scripts de dedup na página de obrigado eliminam contagem dupla.Para atualizar o sistema após qualquer mudança: basta fazer git push no GitHub — o deploy na Cloudflare acontece automaticamente em ~30 segundos.
utm_conj, utm_ad, utm_lp e utm_host.
utm_conj, utm_ad etc. não aparecem.purchasepurchase