Meta CAPI e Shopify: testar a identidade para deduplicação
Compare nome e ID entre representações de navegador e servidor no Shopify, teste retries e pedidos distintos e delimite o que depende da Meta.
Para testar a identidade usada na deduplicação entre navegador e servidor, compare o nome do evento e o identificador compartilhado do mesmo fato. Na abordagem documentada pela Meta, Pixel e CAPI precisam usar a combinação correspondente no mesmo Pixel, respeitando a janela de recebimento. A igualdade local verifica essa preparação; não comprova processamento externo.
Resumo: O mesmo pedido precisa produzir representações compatíveis no navegador e no servidor. Este tutorial usa dados sintéticos e o normalizador público Shopify da ClickTrail para verificar ID estável, nomes iguais, retries e pedidos distintos. O teste não executa Pixel, checkout ou CAPI. Consentimento, transporte do identificador e deduplicação observada na Meta continuam sendo verificações adicionais, não consequências automáticas de assertions aprovadas.
Por FunnelSheet. Revisão técnica: 15 de setembro de 2026. Conflito de interesse: a FunnelSheet desenvolve e divulga ClickTrail. Nenhuma loja ou conta de anúncios recebeu os eventos sintéticos deste exercício.
Qual combinação a Meta usa nesta abordagem?
A abordagem por identificador exige correspondência entre eventID do Pixel e event_id da CAPI, além do nome do evento. A documentação Meta especifica o mesmo Pixel ID e recebimento dentro de 48 horas para a combinação descrita. Não basta comparar o valor do pedido ou o e-mail do comprador.
Essas condições constam da documentação oficial de deduplicação de eventos Pixel e servidor, consultada em 15 de setembro de 2026. O exercício abaixo cobre a igualdade dos campos e uma representação local do destino. Não simula a janela, o transporte ou as decisões internas da Meta.
Este artigo trata especificamente da abordagem por ID de evento. A documentação também descreve outra abordagem com informações de cliente; ela não está implementada nem avaliada aqui. Misturar estratégias no teste tornaria difícil saber qual condição realmente foi verificada.
Comece verificando essa combinação antes de investigar contagens agregadas. Se os identificadores já divergem na construção, existe uma falha local concreta para corrigir. Se correspondem, avance para o transporte e a observação externa. O teste permanece limitado a representações em memória, sem prometer uma instalação completa de comércio eletrônico.
Como separar pessoa, pedido e evento?
A pessoa identifica quem compra; o pedido identifica a operação comercial; o evento identifica a ocorrência enviada. Um comprador pode fazer dois pedidos. Um pedido pode passar por checkout, compra e reembolso. Usar o e-mail como ID de todos esses fatos juntaria ocorrências diferentes.
O normalizador público Shopify da ClickTrail produz shopify_<id>_purchase a partir de order.id. Para o pedido sintético demo-12, a saída é shopify_demo-12_purchase. Repetir o mesmo objeto conserva essa identidade; trocar o pedido deve produzir outra.
| Conceito | Exemplo sintético | Uso no teste |
|---|---|---|
| Pessoa | Não incluída | Evitar dados desnecessários |
| Pedido | demo-12 |
Origem do identificador |
| Evento | shopify_demo-12_purchase |
Igualdade entre representações |
| Destino | demo-pixel |
Mesmo escopo local de comparação |
O ID precisa vir de uma associação confiável. Se o navegador enviar livremente um identificador de pedido ao servidor, a igualdade pode passar mesmo com uma associação falsa. O guia de preservação de contexto entre formulário e CRM explica por que transporte de um campo não prova a identidade de quem o forneceu.
O evento checkout_completed já fornece todo o fluxo?
Não. O evento checkout_completed informa uma conclusão de compra no contexto dos Web Pixels, mas sua existência não garante que o navegador disparou em toda compra nem que compartilhou o identificador com seu servidor.
A referência Shopify de checkout_completed informa que o evento pode ocorrer na primeira página de upsell e não voltar a ocorrer na página de agradecimento. Se a página necessária não carregar, o evento pode não disparar. A referência também distingue o ID do evento de cliente dos dados do checkout e do pedido.
O normalizador examinado recebe um objeto semelhante a um pedido, com campos como id, processed_at, total_price e note_attributes. Ele não assina eventos Web Pixels, não lê um checkout vivo e não cria o transporte entre navegador e webhook.
Assim, antes de integrar, defina como ambas as origens resolvem o mesmo pedido. Não suponha que event.id do Web Pixel equivale automaticamente a order.id no servidor. Em uma implementação com GTM, o mapeamento aprovado precisa transportar o identificador compartilhado até a configuração da tag, sem inventar uma nova taxonomia como efeito colateral.
Como executar o teste positivo e os casos negativos?
O teste abaixo usa a função pública do exemplo e monta uma representação local de navegador. Ele verifica o par de identidade, a repetição, um nome divergente, IDs divergentes e isolamento entre pedidos. Nenhum objeto é enviado para a Meta.
Salve como shopify-identidade.mjs e execute node shopify-identidade.mjs. O código completo foi executado em Node.js v24.15.0. A saída esperada é B12: identidade local OK; Meta não consultada.
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
// Fonte ClickTrail Examples, commit 0c792bf386fb04971ee1b347a5cfbc4acaab748e.
function normalizeShopifyPurchase(order = {}) {
const attrs = Object.fromEntries((order.note_attributes || []).map(x => [x.name, x.value]));
return {
event_name: 'Purchase',
event_time: Number(order.processed_at ? Date.parse(order.processed_at) / 1000 : 0),
event_id: `shopify_${order.id}_purchase`,
user_data: {
fbp: attrs.fbp, fbc: attrs.fbc,
em: order.email ? [createHash('sha256').update(order.email.trim().toLowerCase()).digest('hex')] : undefined
},
custom_data: {
value: Number(order.current_total_price || order.total_price || 0),
currency: order.currency || 'USD', order_id: String(order.id)
}
};
}
const order = {
id: 'demo-12', processed_at: '2026-09-15T08:00:00.000Z',
total_price: '25.00', currency: 'BRL', note_attributes: []
};
const server = { pixelId: 'demo-pixel', ...normalizeShopifyPurchase(order) };
// Representação sintética; não é uma chamada ao Pixel.
const browser = {
pixelId: 'demo-pixel', event: 'Purchase', eventID: 'shopify_demo-12_purchase'
};
function sameIdentity(b, s) {
return typeof b.eventID === 'string' && b.eventID.length > 0 &&
b.pixelId === s.pixelId && b.event === s.event_name && b.eventID === s.event_id;
}
assert(sameIdentity(browser, server));
assert.equal(server.custom_data.value, 25);
assert.equal(server.custom_data.currency, 'BRL');
assert.equal(server.event_time, Date.parse(order.processed_at) / 1000);
assert.equal(normalizeShopifyPurchase(order).event_id, server.event_id);
assert(!sameIdentity({ ...browser, eventID: 'divergente' }, server));
assert(!sameIdentity({ ...browser, event: 'Lead' }, server));
assert(!sameIdentity({ ...browser, pixelId: 'outro-pixel' }, server));
assert(!sameIdentity({ ...browser, eventID: undefined }, server));
const other = normalizeShopifyPurchase({ ...order, id: 'demo-13' });
assert.notEqual(other.event_id, server.event_id);
assert.equal(normalizeShopifyPurchase({}).event_id, 'shopify_undefined_purchase');
console.log('B12: identidade local OK; Meta não consultada');
O campo pixelId é metadado do comparador local, não um campo acrescentado ao contrato do payload CAPI. O código também deixa explícito um limite do normalizador: um pedido vazio gera identificador com undefined. Portanto, valide o objeto confiável antes de normalizar. A função auxiliar compara entradas sintéticas; não é um validador completo de eventos de produção.
O que retries e dois pedidos diferentes precisam demonstrar?
Um retry do mesmo fato deve conservar o ID; outro pedido deve mudar o ID. O teste verifica essas duas propriedades. Também mostra que Lead e Purchase não formam o mesmo par apenas por compartilhar um identificador textual.
Imagine dois pedidos hipotéticos do mesmo comprador, de R$ 25 cada. Eles precisam continuar distintos. Agora imagine duas tentativas de transmitir o primeiro pedido. Elas representam a mesma ocorrência. Usar valor, e-mail ou horário aproximado para decidir a diferença mistura identidade com heurística.
Não gere um UUID novo em cada tentativa de envio se sua intenção é reconhecer o mesmo evento. Gere ou derive a identidade na origem confiável e preserve-a durante o processamento. Registre tentativas separadamente: identidade da tentativa e identidade do fato respondem a perguntas diferentes.
A igualdade local não impede duas filas de transmitirem repetidamente. Uma implementação também precisa de política de retries, persistência e observação das respostas. O guia de verificação local de payloads de conversão ajuda a separar construção de dados e transporte, mesmo quando a origem não é Shopify.
Como verificar consentimento e minimizar os dados do teste?
O teste local pode funcionar sem informações de pessoa porque avalia identidade de evento. O fixture não fornece e-mail, telefone ou cookies. Isso mantém o diagnóstico concentrado na propriedade que está sendo testada e evita transformar um exemplo em coleta desnecessária.
O normalizador público sabe ler fbp, fbc e gerar hash de e-mail quando esses campos existem. Essa capacidade não decide se o uso está permitido. A função também não aplica um bloqueio de consentimento. Em uma integração, esse controle precisa existir na camada que coleta e envia, de acordo com a política configurada.
Para aceitar essa camada, proponha dois testes separados: permissão válida produz o evento esperado; recusa não produz as operações publicitárias proibidas pela política. Depois teste retirada, incluindo itens pendentes no servidor. Não considere a presença de um e-mail transformado em hash como prova de autorização ou anonimização completa.
Esses testes de navegador e servidor não foram executados aqui. A conclusão local permanece a mesma: os objetos sintéticos produzem identidades compatíveis. O exercício não inspeciona a configuração de privacidade de uma loja.
O que falta observar na Meta antes de afirmar deduplicação?
É necessário observar as duas origens no destino apropriado e conferir o processamento da combinação enviada. Registre o Pixel, o nome, o ID compartilhado, os horários de recebimento e as respostas pertinentes. Não transforme a aprovação do comparador em um recibo externo.
Em um ambiente de teste autorizado, o procedimento proposto é acompanhar a geração no navegador, a construção no servidor, o transporte e os diagnósticos disponíveis no Gerenciador de Eventos. Mantenha o evento identificado como teste conforme o mecanismo vigente do provedor. Não envie os identificadores fictícios deste artigo como conversões reais.
O diagnóstico precisa distinguir “servidor recebeu o pedido”, “provedor recebeu o evento” e “duas origens foram tratadas como o mesmo fato”. Uma contagem agregada isolada não explica qual par foi processado. Se não houver evidência suficiente desse último ponto, registre deduplicação externa como desconhecida.
O MCP local ClickTrail também não fornece essa observação: suas ferramentas de envio constroem payloads, e a consulta de status não acessa APIs de destino. O próximo passo é validar o transporte do ID entre as origens da sua loja antes de iniciar um ensaio externo controlado.