ConectIQ · documentação
Ver markdown

Integração — guia para o desenvolvedor

Este documento é tudo o que você precisa para integrar uma plataforma de vendas ao UTM Intelligence. Não é preciso conhecer o sistema por dentro.

Painel: https://utmfy.hnvag0.easypanel.host

Ao final da integração, cada venda que entrar vai:

  1. aparecer no painel em segundos, já atribuída à campanha/anúncio que a gerou;
  2. disparar notificação no celular do dono (push), Telegram, Discord ou e-mail.

Visão geral

São duas peças independentes. Você pode fazer só a primeira e o sistema já funciona — a segunda é o que permite saber de qual anúncio veio cada venda.

PeçaO que fazOnde vive
1. Webhook de vendasManda a venda para o sistemaServidor da plataforma de checkout
2. Script de rastreamentoIdentifica o visitante e guarda a origemPágina de vendas do cliente

Onde pegar as credenciais

No painel, em Configurações → Instalação:

CredencialFormatoPara que serve
Chave pública32 caracteresVai no script de rastreamento (pode ficar exposta)
Chave secreta48 caracteresVai na URL do webhook e na API. Nunca exponha no navegador.

Parte 1 — Webhook de vendas

Endpoint

POST https://utmfy.hnvag0.easypanel.host/webhook/generic/{CHAVE_SECRETA}
Content-Type: application/json

Responde 200 {"ok":true} imediatamente e processa em segundo plano — a venda aparece no painel em poucos segundos. Se receber qualquer coisa diferente de 200, reenvie.

Corpo da requisição

{
  "order_id": "PED-12345",
  "status": "approved",
  "payment_method": "pix",
  "currency": "BRL",

  "total": 497.00,
  "fee": 44.68,
  "cost": 40.00,

  "product": {
    "id": "curso-completo",
    "name": "Curso Completo"
  },

  "customer": {
    "email": "cliente@email.com",
    "name": "Maria Silva",
    "country": "BR"
  },

  "tracking": {
    "vid": "8f14e45f-ceea-467a-9d1a-2f3b4c5d6e7f",
    "sid": "3c59dc04-8e88-4c04-9f31-b2f0e1a2c3d4",
    "utm_source": "facebook",
    "utm_medium": "cpc",
    "utm_campaign": "Black Friday",
    "utm_content": "criativo-video-01",
    "click_id": "IwAR3xK9..."
  },

  "items": [
    { "id": "curso-completo", "name": "Curso Completo", "quantity": 1, "price": 497.00 },
    { "id": "bump-planilhas", "name": "Planilhas",      "quantity": 1, "price": 47.00, "is_bump": true }
  ],

  "created_at": "2026-08-01T14:32:10-03:00",
  "approved_at": "2026-08-01T14:32:45-03:00"
}

Campos

CampoObrigatórioObservação
order_idsimID do pedido na sua plataforma. É a chave de idempotência.
statussimVer tabela de status abaixo.
totalsimNa unidade da moeda: 497.00 = R$ 497,00. Ver aviso abaixo.
payment_methodnãopix, credit_card, boleto, debit_card, paypal…
currencynãoPadrão BRL.
feenãoTaxa do gateway. Entra no cálculo de lucro.
costnãoCusto do produto. Entra no cálculo de lucro.
product.id / product.namenãoAlimenta o ranking de produtos.
customer.emailnãoUsado para reconhecer o comprador entre dispositivos.
tracking.*nãoVer Parte 2. É o que liga a venda ao anúncio.
items[]nãoDetalhe por item; use is_bump para order bumps.
created_at / approved_atnãoISO 8601 ou timestamp Unix. Padrão: agora.

⚠️ O erro mais comum: valor em centavos

total é lido na unidade da moeda. 497.00 e 497 são ambos R$ 497,00 — não R$ 4,97.

Se a sua plataforma trabalha em centavos, divida por 100 antes de enviar: "total": 49700 seria interpretado como R$ 49.700,00.

Status aceitos

EnvieSignificadoSinônimos aceitos
approvedPagamento confirmadopaid, completed, succeeded, aprovado, pago
pendingAguardando pagamento(padrão quando não reconhecido)
refusedRecusadodeclined, failed, recusado
refundedReembolsadorefund, estornado, reembolsado
chargebackContestaçãodispute
canceledCanceladocancelled, cancelado
expiredExpiradoexpirado

Só approved conta como faturamento.

Idempotência e ciclo de vida

Reenvie o mesmo order_id a cada mudança de status. O sistema atualiza o pedido existente em vez de duplicar.

Fluxo típico de um Pix:

1. Pix gerado    → {"order_id":"PED-1","status":"pending",  "total":497.00}
2. Pix pago      → {"order_id":"PED-1","status":"approved", "total":497.00}
3. Reembolso     → {"order_id":"PED-1","status":"refunded", "total":497.00}

Duas proteções que você não precisa implementar do seu lado:

Assinatura (recomendado)

Para o sistema recusar requisições forjadas, configure um segredo compartilhado e envie o HMAC do corpo cru:

X-Signature: hmac_sha256(corpo_cru_da_requisicao, SEGREDO)
$body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$signature = hash_hmac('sha256', $body, $segredo);
// envie $body como corpo e $signature no header X-Signature

Sem segredo configurado no painel, a verificação é ignorada — útil em testes.

Testando

curl -X POST "https://utmfy.hnvag0.easypanel.host/webhook/generic/SUA_CHAVE_SECRETA" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "TESTE-001",
    "status": "approved",
    "payment_method": "pix",
    "total": 497.00,
    "product": { "id": "teste", "name": "Produto de Teste" },
    "customer": { "email": "teste@exemplo.com" }
  }'

Esperado: {"ok":true}, e em poucos segundos a venda aparece no painel com o alerta/push correspondente.


Parte 2 — Rastreamento e atribuição

Sem esta parte, todas as vendas aparecem como tráfego direto. Com ela, você sabe qual anúncio pagou cada venda.

Passo 1 — Instalar o script na página de vendas

<script src="https://utmfy.hnvag0.easypanel.host/track.js?k=SUA_CHAVE_PUBLICA" defer></script>

Sozinho, ele já:

Passo 2 — Levar os identificadores até o webhook

É o passo que fecha o ciclo. Existem três cenários — use o que se aplica:

Cenário A — O checkout é uma plataforma externa (Hotmart, Kiwify…)

O script já anexa utmi_vid e utmi_sid na URL do checkout. Configure a plataforma para repassar esses parâmetros no webhook, no campo de rastreamento que ela oferecer (sck, src, tracking, custom_fields…):

"tracking": { "vid": "<utmi_vid recebido>", "sid": "<utmi_sid recebido>" }

Cenário B — Checkout próprio

Leia os identificadores no navegador e envie junto com o pedido:

const ids = utmi('ids');       // { vid: "...", sid: "..." }
const utms = utmi('params');   // { utm_source: "...", fbclid: "...", ... }

fetch('/api/criar-pedido', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ ...dadosDoPedido, tracking: { ...ids, ...utms } })
});

Guarde tracking junto do pedido no seu banco e repasse no webhook.

Cenário C — Não dá para passar nada

Envie ao menos o e-mail do comprador em customer.email. O sistema tenta casar com um visitante conhecido (funciona inclusive entre celular e desktop).

Se a venda chegar antes do rastreamento, o sistema guarda os identificadores e corrige a atribuição sozinho minutos depois. Você não precisa controlar essa ordem.

Eventos opcionais

Melhoram o funil e a detecção de queda de conversão:

utmi('track', 'initiate_checkout');                   // entrou no checkout
utmi('track', 'lead', { origem: 'formulario' });      // lead capturado
utmi('track', 'add_to_cart', {}, 197.00);             // com valor
utmi('identify', 'cliente@email.com');                // liga o visitante ao e-mail

Ou sem JavaScript, por atributo:

<button data-utmi-event="clicou_comprar">Comprar agora</button>

initiate_checkout também é detectado automaticamente em links cuja URL contenha checkout, carrinho, pagamento ou pay..


Parte 3 — API (opcional)

Base https://utmfy.hnvag0.easypanel.host/api/v1 · Header Authorization: Bearer {CHAVE_SECRETA}

EndpointUso
POST /ordersCriar/atualizar venda sem webhook (mesmo corpo da Parte 1)
POST /ad-spendImportar investimento do Meta/Google Ads (lote de até 5.000 linhas)
GET /metricsMétricas consolidadas do período
GET /rankingRanking por anúncio, campanha, produto, origem…
GET /ordersListar vendas
GET /healthMonitoramento (sem autenticação)

Importar gasto de mídia é o que habilita ROAS, ROI, CAC e a lista de anúncios que estão queimando verba:

curl -X POST "https://utmfy.hnvag0.easypanel.host/api/v1/ad-spend" \
  -H "Authorization: Bearer SUA_CHAVE_SECRETA" \
  -H "Content-Type: application/json" \
  -d '{ "rows": [{
        "date": "2026-08-01", "source": "facebook",
        "campaign_id": "1202100001", "campaign_name": "Black Friday",
        "ad_id": "1202100001-ad1", "ad_name": "Criativo A",
        "spend": 450.00, "impressions": 38000, "clicks": 620
      }] }'

Idempotente por dia + anúncio: reenviar o mesmo dia atualiza, não duplica.

Referência completa em API.md.


Códigos de resposta

CódigoO que significaO que fazer
200RecebidoNada
401Chave inválidaConferir a chave secreta na URL/header
404Gateway não registradoUsar /webhook/generic/…
422Corpo inválidoLer o campo error da resposta
429Excesso de requisiçõesAguardar e reenviar
5xxFalha do servidorReenviar — o sistema é idempotente

Checklist de entrega


Perguntas frequentes

A venda apareceu como "direct". Por quê? Nenhum identificador chegou no tracking. Confira o Cenário A/B da Parte 2. Aguarde alguns minutos: se o rastreamento chegar depois, o sistema corrige sozinho.

Posso mandar o mesmo pedido várias vezes? Sim — é o comportamento esperado. A chave é o order_id.

O valor apareceu errado (100× maior ou menor). Unidade do total. Envie 497.00, não 49700.

Preciso do script se o checkout é externo? Sim. É ele que identifica o visitante antes de a venda existir. Sem ele, não há como saber de qual anúncio veio.

Reembolso desconta do faturamento? Sim. Reenvie o mesmo order_id com status: "refunded".