Erros Mais Comuns na Configuração do E-commerce Avançado no GA4

Receita zero, funil quebrado, purchase duplicado e atribuição no gateway: os erros de dataLayer e GA4 que destroem ROAS — e como corrigir.

Contexto

O DebugView mostra purchase. O CRM bateu a venda. No relatório de monetização, receita = 0. Ou o funil de checkout está vazio. Ou o Google Ads comemora ROAS 800% com conversões que não existem no OMS.

No Universal Analytics muita coisa “quase certa” ainda preenchia relatório. No GA4, e-commerce avançado é esquema rígido: nome do evento, tipagem de value/price, currency, transaction_id e array items. Desvio pequeno = falha silenciosa. O Smart Bidding não avisa que o sinal está podre — ele otimiza em cima do lixo.

Este post é a auditoria de sintomas para mídia e e-commerce. O contrato mínimo para engenharia está no Guia de Data Layer para Devs. Aqui o foco é: o que você vê no GA4/Ads, por que acontece e o que checar antes de culpar a campanha.

Problema

Sintoma no relatório Causa típica
purchase existe, receita 0 value/price como string ("89.99") ou sem currency ISO
Funil ecommerce vazio / drop-off cego addToCart, checkout_start ou schema UA em vez de snake_case GA4
Produto “fantasma” no carrinho SPA/listagens sem ecommerce: null entre pushes
Conversões > pedidos reais Thank-you no F5/back sem transaction_id
Compra atribuída a paypal.com / stripe.com Gateway fora da lista de exclusão de referrals
Canal Unassigned / (not set) em massa Consent Mode sem modelagem / CMP bloqueando IDs
Pedido B2B some Array items > 200 sem split

Se GA4 e faturamento nunca fecham, separe gap estrutural de buraco de implementação — ver GA4 vs CRM. Abaixo: os erros que mais aparecem em auditoria de loja.

Data Layer: estado, nomes e funil

Sem ecommerce: null

O GTM funde chaves entre pushes. Sem limpar o nó ecommerce, um view_item herda items do view_item_list anterior — produto fantasma, métricas inchadas, BigQuery contaminado depois.

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: 'view_item',
  ecommerce: {
    currency: 'BRL',
    value: 149.9,
    items: [{ item_id: 'SKU-100', item_name: 'Camiseta', price: 149.9, quantity: 1 }]
  }
});

Regra: todo evento ecommerce (lista, item, cart, checkout, purchase) começa com { ecommerce: null }.

Schema UA colado no GA4

Reaproveitar Enhanced Ecommerce do UA sem migrar parâmetros quebra monetização e Merchant:

UA (legado) GA4 (obrigatório) Se errar
id (pedido) transaction_id Sem dedup; refresh duplica venda
id (produto) item_id SKU solto; Merchant/relatórios quebram
name item_name Produto vira (not set)
revenue value Receita 0
category item_category Sem drill-down de categoria

“Use GA4 schema” no GTM é muleta de migração — não arquitetura permanente. Eventos event_category / event_action / event_label não substituem o Event Name canónico.

Funil com nome errado

O funil de comportamento de compra só fecha com nomes exatos (case-sensitive), entre outros:

view_itemadd_to_cartbegin_checkoutadd_shipping_infoadd_payment_infopurchase

checkout_start ou addToCart = etapa zerada na UI. Sem begin_checkout canónico, taxa de abandono do carrinho vira chute. Em checkout headless / pagamento off-site, a sessão pode morrer no retorno — o purchase precisa chegar com identidade costurada (client/session), não só um hit órfão.

Dinheiro: tipagem, moeda e desconto

String vs Number

value, price e quantity precisam ser números. "89.99" ou "89,99" passam no Tag Assistant como “evento ok” e morrem na agregação: purchase contado, Ecommerce revenue = 0. Ads em tROAS perde o sinal monetário e otimiza volume vazio.

Mitigação no GTM (enquanto eng não corrige a origem): Custom JavaScript com parseFloat limpo — mas a correção certa é Number no dataLayer (contrato em Data Layer).

currency no nível do evento

GA4 exige currency ISO 4217 (BRL, USD, EUR) em eventos com valor. Não use $ ou R$. Colocar moeda só dentro de items[] e omitir na raiz do evento = receita global zerada. Vale mesmo em loja 100% Brasil.

value, desconto, tax e shipping

O GA4 não calcula sozinho “price cheio − discount”. Regras práticas:

Campo Envio correto Erro comum
value (evento) Soma (price × qty) dos itens após descontos; sem tax/shipping Meter IVA/frete no value → ROAS inflado
price (item) Unitário com desconto daquele item Price cheio + discount → Item revenue distorcida
discount (item) Monetário por unidade (2.00), não 20% Percentual anula métrica de desconto
tax / shipping Parâmetros próprios do evento, fora do value de itens

transaction_id só com dígitos

IDs puramente numéricos (123456789) já causaram drop / “Transaction ID is not set” no pipeline. Prefira string com prefixo estável: T-123456789. Sem transaction_id, não há deduplicação confiável.

Exemplo mínimo de purchase saudável:

window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'T-1002741',
    currency: 'BRL',
    value: 279.8,
    shipping: 20,
    tax: 0,
    items: [
      { item_id: 'SKU-100', item_name: 'Camiseta', price: 129.9, quantity: 1 },
      { item_id: 'SKU-200', item_name: 'Calça', price: 149.9, quantity: 1 }
    ]
  }
});

Duplicação e atribuição

Thank-you que dispara de novo

Tag de purchase ligada só a pageview da página de obrigado: F5, back-forward ou reabrir o link = nova conversão. O GA4 deduplica pelo mesmo transaction_id + cliente numa janela curta — se o ID existir. Sem ID, ROAS de Ads pode inflar dezenas de pontos percentuais.

Corrija na origem (flag em sessionStorage / disparo único no backend) e confirme transaction_id em todo hit de compra.

Self-referral do gateway

Stripe, PayPal, PagSeguro, Mercado Pago, Adyen: o retorno do pagamento vira “nova sessão” com source = domínio do gateway se esses hosts não estiverem na lista de exclusão de referrals do GA4. Resultado clássico: last-click no processador; Google Ads / Meta perdem a conversão; “novos usuários” incham.

Admin → Data streams → Configure tag settings → List unwanted referrals (ou equivalente na UI atual): inclua os domínios dos gateways que você usa.

Unassigned e consentimento

Pico de Unassigned / (not set) depois do CMP muitas vezes não é “GTM quebrado” — é Consent Mode sem IDs até o aceite, com modelagem comportamental só se Advanced Consent estiver bem ligado. Antes de caçar tag, leia o estado do banner: Consent Mode v2.

PII vs UTM

Ao limpar e-mail/telefone da URL no GTM, não sobrescreva page_location nativo removendo a query inteira. Você apaga gclid, utm_*, fbclid e enterra mídia paga em organic. Limpe PII num parâmetro custom (ex. page_uri_clean); deixe a URL canônica intacta para o GA4.

Limite de 200 items (B2B)

O GA4 limita o array items a 200 por evento. Pedido atacado acima disso pode ser descartado. Listas (view_item_list) podem ser fatiadas em vários pushes. Em purchase, repetir o mesmo transaction_id nas fatias faz o GA4 deduplicar e anular pedaços — use sufixos (T-100-1, T-100-2) e reconcilie no warehouse.

O que fica fora deste checklist

Client-side puro perde fatia relevante com blockers e ITP — ver impacto de AdBlockers. Measurement Protocol / server-side sem client_id + session_id gera purchase órfão (Direct). BigQuery exige UNNEST em items/event_params; somar items.price no SQL errado multiplica receita. Isso é projeto de resiliência e dados — não o primeiro passo quando a loja ainda manda value como string.

Checklist de QA

# Verificação Feito quando...
1 Limpeza de estado Todo push ecommerce precedido de { ecommerce: null }
2 Nomes GA4 Funil em snake_case canónico; sem schema UA em parâmetros
3 Tipagem value/price Number; quantity Integer
4 Moeda currency ISO na raiz do evento
5 Receita value = itens pós-desconto; tax/shipping separados
6 Dedup transaction_id string estável; refresh não reenvia
7 Gateway Domínios de pagamento na exclusão de referrals
8 Consent / PII Banner ok; page_location não come gclid/UTM
9 DebugView Purchase com value > 0 e items coerentes com o pedido
10 Ads Conversão importada reflete value real (amostra vs OMS)

Próximo passo

Se monetização, funil e atribuição não batem com o que a loja fatura, o problema raramente é “só o lance”. É implementação: dataLayer, tipagem, dedup e exclusões.

Peça uma auditoria de tracking focada em e-commerce: mapeamos eventos do funil, validamos purchase ponta a ponta (Tag Assistant → DebugView → amostra vs OMS) e listamos o que é correção de schema versus o que já pede arquitetura server-side. Antes de mais um teste A/B de criativo, feche o buraco que alimenta o algoritmo.