Roteamento de eventos para múltiplas plataformas: fan-out server-side de conversões
Arquitetura de fan-out server-side: um evento de conversão canônico roteado para Meta, Google, TikTok e outras APIs com mapeamento, dedupe e entrega confiável.
Neste artigo
O problema: N plataformas, um só evento real#
Quem anuncia em várias plataformas ao mesmo tempo — Meta, Google, TikTok, Pinterest, LinkedIn, Snapchat, e por aí vai — enfrenta um problema de multiplicação. Cada plataforma tem sua própria Conversions API, com nomes de evento diferentes, formatos de payload diferentes, campos de match diferentes e regras de deduplicação diferentes. A tentação é implementar cada uma isoladamente: um trecho de código que fala com o Meta, outro com o Google, outro com o TikTok. O resultado é um emaranhado frágil, onde uma mudança no checkout precisa ser replicada em N lugares, e onde é fácil um evento sair para uma plataforma e não para outra.
A abordagem madura inverte isso: você define um evento de conversão canônico — a representação neutra e completa do que aconteceu — e um roteador de fan-out que traduz esse evento canônico para o formato de cada plataforma de destino e o entrega com garantias. Uma fonte de verdade, muitos destinos.
O evento canônico: a fonte de verdade#
O evento canônico é um objeto interno, independente de qualquer plataforma, que captura tudo que é relevante sobre a conversão:
- Identidade — email, telefone,
external_iddo usuário, em claro no objeto canônico (o hashing acontece na tradução para cada plataforma, porque cada uma tem sua exigência de normalização). - Sinais de clique — todos os click ids capturados:
fbclid,gclid/wbraid/gbraid,ttclid,epik,sc_click_id,rdt_cid,msclkid. Você guarda todos porque não sabe, na hora do clique, por qual plataforma o usuário veio; e um usuário pode ter sido tocado por várias. - Contexto — IP do cliente, user-agent, URL, referrer, timestamp real da conversão.
- Dados da conversão — tipo (compra, lead, cadastro), valor, moeda, itens,
order_id. - Identificador de deduplicação — um id estável gerado no servidor (o ID do pedido ou um ULID atrelado), que vira a chave de dedupe em todas as plataformas.
Esse objeto nasce no momento da conversão real — no handler do webhook de pagamento aprovado — e é ele que o roteador consome.
O roteador de fan-out: um evento, muitos destinos#
O roteador é o componente que recebe o evento canônico e, para cada plataforma configurada, faz três coisas: mapeia, normaliza/hasheia e entrega.
Mapeamento de eventos#
Cada plataforma nomeia os eventos de forma diferente. Uma compra é Purchase no Meta, conversion/purchase no Google, CompletePayment no TikTok, checkout no Pinterest, PURCHASE no Snapchat. O roteador mantém uma tabela de mapeamento do tipo canônico para o nome de cada plataforma. Adicionar uma plataforma é adicionar uma linha nessa tabela e um tradutor, não reescrever o checkout.
O mapeamento também cobre os campos: value/currency viram custom_data.value/custom_data.currency no Meta, conversion_value/currency_code no LinkedIn, e assim por diante. Centralizar isso num tradutor por plataforma mantém a lógica de negócio (quando e por que a conversão aconteceu) separada da lógica de integração (como cada plataforma quer ouvir).
Normalização e hashing por plataforma#
Cada plataforma exige seus próprios campos de match e sua própria forma de hash. O roteador, ao traduzir, seleciona os click ids relevantes (o fbclid só interessa ao Meta, o ttclid só ao TikTok) e hasheia a PII conforme a regra de cada destino. A normalização precede o hash sempre, e precisa ser consistente com o que o pixel/tag de cada plataforma faz no navegador — senão a deduplicação por identidade quebra.
Entrega com deduplicação#
O id estável de deduplicação do evento canônico é propagado para o campo de dedupe de cada plataforma: event_id no Meta/TikTok/Snapchat, conversion_id no Reddit, event_id no Pinterest e no LinkedIn. Como o mesmo valor também foi passado ao pixel/tag no navegador de cada plataforma, o fan-out server-side deduplica corretamente contra os disparos client-side.
Entrega confiável e independência entre destinos#
Aqui mora o ponto mais importante da arquitetura: a falha de uma plataforma não pode afetar as outras nem travar a conversão. Se a API do TikTok está fora do ar, o evento ainda precisa chegar ao Meta e ao Google, e o webhook de pagamento não pode ficar pendurado esperando.
O padrão da casa é o outbox com fan-out desacoplado:
- O handler do webhook, na mesma transação em que confirma o pedido, grava o evento canônico numa fila persistente (outbox). A resposta ao gateway retorna imediatamente.
- Um worker lê o evento canônico e cria uma entrega por plataforma — cada uma um item independente de trabalho, com seu próprio estado (pendente, enviado, falho).
- Cada entrega é processada isoladamente, com retry e backoff próprios. Se o TikTok falha, seu item entra em retry; o item do Meta, que teve sucesso, é marcado como enviado e não é reprocessado.
Essa independência por destino é o que evita o efeito dominó. Nenhuma plataforma lenta ou fora do ar contamina as demais, e nenhuma conversão se perde.
Idempotência e a garantia de não duplicar#
Com retries por plataforma, a idempotência é obrigatória. Duas defesas:
- Estado por entrega com CAS atômico. Cada item de entrega é marcado como enviado com uma atualização condicional (só marca se ainda estava pendente). Um retry que corre em paralelo não gera dois envios.
- Id de deduplicação estável na própria plataforma. Mesmo que um envio duplicado escape, o
event_id/conversion_idestável faz a plataforma de destino deduplicar. É a rede de segurança de segunda camada.
Nunca use timestamp como id de dedupe, e nunca gere um id novo a cada tentativa — o id precisa ser derivado do pedido e ser estável entre reprocessamentos.
Observabilidade do fan-out#
Rotear para N plataformas sem observabilidade é voar às cegas. O mínimo:
- Métrica por plataforma e por status. Quantos eventos enviados, quantos falharam, latência de cada API. Uma queda de sucesso numa plataforma específica salta aos olhos.
- Trace por evento. Cada evento canônico carrega um
trace_idque acompanha todas as suas entregas, para que você reconstrua o caminho de uma conversão específica pelos logs. - Alertas. Taxa de falha acima do limite numa plataforma dispara alerta — geralmente denuncia token expirado, mudança de contrato da API ou payload que regrediu.
- Reconciliação. Periodicamente, compare o número de conversões reportado a cada plataforma com os pedidos pagos. Divergência sistemática numa plataforma isola o problema.
Consentimento e privacidade no fan-out#
Rotear um evento para muitas plataformas amplia a responsabilidade de privacidade: cada destino recebe dados de identidade do usuário. O roteador é o lugar certo para aplicar o consentimento de forma centralizada. O evento canônico carrega o estado de consentimento do usuário (quais finalidades foram autorizadas), e o roteador decide, por plataforma, se e o que enviar.
Alguns princípios:
- Respeite o Consent Mode e equivalentes. Se o usuário não consentiu com publicidade, o roteador não deve enviar match keys de identidade para plataformas de anúncio, ou deve enviar em modo restrito conforme a política de cada uma.
- Minimize por destino. Nem toda plataforma precisa de todos os campos. Envie a cada uma só o que ela usa para casar, reduzindo a superfície de dados compartilhados.
- Hash é pseudonimização, não anonimização. O email hasheado ainda é um dado pessoal. Trate os hashes com o mesmo cuidado do dado em claro no que toca a consentimento e retenção.
Centralizar essa decisão no roteador é o que evita o pior cenário — uma plataforma recebendo dados que o usuário não autorizou porque a regra de consentimento foi implementada em um lugar e esquecida em outro.
Onde o roteador roda: server-side tagging ou serviço próprio#
Há dois caminhos comuns para materializar o fan-out:
- Contêiner de server-side tagging (sGTM ou equivalente). Um contêiner server-side recebe o evento e dispara tags para cada plataforma. Reduz o esforço de integração e centraliza a configuração, mas herda o modelo de tag e pode complicar a implementação do padrão "só na conversão real" se estiver acoplado ao fluxo do navegador.
- Serviço de conversão próprio. Um backend seu, com o outbox e os tradutores, que nasce do webhook de pagamento. Dá controle total sobre quando o evento é gerado e sobre a independência entre destinos, ao custo de mais código para manter.
A escolha depende da maturidade da equipe. O que não muda é o desenho lógico: um evento canônico gerado na conversão real, traduzido por plataforma, entregue com dedupe e independência. Seja num contêiner, seja num serviço, esses invariantes precisam valer.
Testando um roteador de fan-out#
Um roteador que fala com muitas APIs precisa de uma estratégia de teste à altura:
- Teste unitário de cada tradutor. Dado um evento canônico, o tradutor produz o payload exato que a plataforma espera, com os campos mapeados e hasheados corretamente.
- Ferramentas de teste de eventos de cada plataforma. Antes de produção, envie eventos de teste para cada destino e confirme o formato e o match, sem sujar os números reais.
- Teste de independência. Simule a indisponibilidade de uma plataforma e verifique que as outras entregas seguem e que o evento da plataforma falha entra em retry sem se perder.
- Teste de idempotência. Force um reprocessamento e confirme que nenhuma plataforma recebe a conversão duas vezes.
O padrão da casa se preserva no fan-out#
Todo o valor do modelo canônico depende de ele nascer no lugar certo: no momento da conversão real. O evento entra no outbox quando o pagamento é confirmado, não quando o usuário clica em comprar. Assim, todas as plataformas — sem exceção — recebem a conversão só quando ela é verdadeira. O fan-out não é uma forma de espalhar intenção; é uma forma de espalhar fatos confirmados para todos os destinos de uma vez, com dedupe e entrega garantida.
Vantagens de manutenção#
Além da robustez, o modelo canônico + roteador traz ganho operacional enorme:
- Adicionar uma plataforma é escrever um tradutor e uma linha de mapeamento, sem tocar no checkout nem nas outras integrações.
- Mudar o checkout afeta só a construção do evento canônico; todos os destinos herdam a mudança automaticamente.
- Testar fica mais simples: você valida o evento canônico uma vez e cada tradutor isoladamente.
- Auditar é direto: o evento canônico registrado é a prova do que aconteceu, e o log de entregas mostra para onde foi.
Checklist#
- Evento canônico definido, neutro de plataforma, com todos os click ids e a identidade.
- Evento nasce no webhook de pagamento confirmado (conversão real).
- Tabela de mapeamento canônico para o nome/campo de cada plataforma.
- Hashing e normalização por plataforma, consistentes com o pixel/tag.
- Id de dedupe estável propagado para todas as plataformas e para os pixels.
- Outbox com uma entrega independente por plataforma, retry e backoff próprios.
- Idempotência por CAS atômico e id estável.
- Observabilidade: métrica por plataforma, trace por evento, alerta e reconciliação.
Roteamento de eventos bem arquitetado transforma a complexidade de N plataformas num problema tratável: uma fonte de verdade, muitos tradutores, entrega independente e garantida. É a forma de crescer o mix de mídia sem multiplicar a fragilidade — e de garantir que cada plataforma, da maior à mais nichada, receba a conversão real no momento certo.