AdOptify LogoAdOptify
Acessar painel

Integrações

API de Vendas da AdOptify

Voltar para Configurações

Escolha o guia certo para o seu caso. Em cada aba há um botão para copiar a spec e colar em uma IA (ChatGPT, Cursor, Claude).

Envio genérico (Custom)

Uso pessoal / da sua operação: você tem um app, checkout próprio ou oferta e quer conectar só o seu projeto à AdOptify. Não é para disponibilizar a integração a todos os usuários de uma plataforma.

Parceiro (gateway / plataforma)

Uso para os seus clientes: você é um gateway ou plataforma e quer que eles conectem a AdOptify pelo seu painel (cada anunciante com o próprio token). Não é integração só para uso interno seu.

Implementar com IA

Para IA / LLM

Copie a spec deste guia e peça para a IA implementar o envio Custom no seu app ou checkout.

Prompt sugerido: "Implemente o envio genérico AdOptify Custom seguindo este spec à risca."

Este guia é para você se…

  • Tem um sistema próprio, funil ou oferta e quer rastrear suas vendas na AdOptify.
  • A integração fica no seu backend — não precisa que outros usuários da sua plataforma usem.
  • Você gera o token Custom no painel AdOptify e envia POST para /api/track/{PROJECT_ID}.

Se você é um gateway e quer que seus clientes conectem a AdOptify, use a aba Gateway — Parceiro.

1. Formato da Requisição
Gere a credencial, copie o endpoint exibido no painel e envie requisições HTTPS.

1.1 - Endpoint

Utilize sempre a URL de webhook mostrada em Integrações > Webhooks. Ela já contém o Project ID.

POST https://app.adoptify.com.br/api/track/{PROJECT_ID}

1.2 - Headers

HeaderDescriçãoExemplo
Content-TypeSempre application/jsonapplication/json
x-api-keyToken salvo em Integrações > Webhooks (plataforma "Custom")KVRxalfMiBfm8Rm1nP5YxfwYzArNsA0VLeWC
AuthorizationOpcional. Também aceita Bearer <token> se preferir.Bearer KVRxalfMiBfm8Rm1nP5YxfwYzArNsA0VLeWC

A chave pode ser gerada no painel. Para máxima segurança, revogue e regenere tokens que não forem mais usados.

1.3 - Payload

Use JSON. Estrutura inspirada em plataformas de checkout para facilitar a adaptação.

1.3.1 - Body

{
  "orderId": "string",
  "platform": "string",
  "paymentMethod": ["credit_card","boleto","pix","paypal","free_price"],
  "status": ["waiting_payment","paid","refused","refunded","chargedback"],
  "createdAt": "YYYY-MM-DD HH:MM:SS",
  "approvedDate": "YYYY-MM-DD HH:MM:SS | null",
  "refundedAt": "YYYY-MM-DD HH:MM:SS | null",
  "customer": Customer,
  "products": Product[],
  "trackingParameters": TrackingParameters,
  "pageUrl": "string | null",
  "checkoutUrl": "string | null",
  "commission": Commission,
  "isTest": false
}

products pode ter vários itens: produto principal e order bumps. O valor total da venda é a soma de priceInCents * quantity de todos os itens (quando não informar commission.totalPriceInCents ou totalPriceInCents na raiz). O nome exibido da venda é derivado da concatenação dos nomes de todos os produtos.

1.3.2 - Customer

{
  "name": "string",
  "email": "string",
  "phone": "string | null",
  "document": "CPF/CNPJ | null",
  "country": "ISO 3166-1 alpha-2",
  "ip": "string | null"
}

1.3.3 - Product

{
  "id": "string",
  "name": "string",
  "title": "string | null",
  "type": "main | orderbump",
  "planId": "string | null",
  "planName": "string | null",
  "quantity": number,
  "priceInCents": number
}

Use name ou title para o nome do produto. type opcional: main (produto principal) ou orderbump. Múltiplos itens em products permitem enviar produto principal e order bumps no mesmo pedido.

1.3.4 - TrackingParameters

{
  "utm_source": "string | null",
  "utm_medium": "string | null",
  "utm_campaign": "string | null",
  "utm_content": "string | null",
  "utm_term": "string | null",
  "src": "string | null",
  "sck": "string | null",
  "visitorId": "string | null",
  "fbclid": "string | null",
  "gclid": "string | null",
  "ttclid": "string | null",
  "msclkid": "string | null",
  "fbc": "string | null",
  "fbp": "string | null"
}

Também aceitos como alias na raiz: tracking, utms ou metadata (mesma estrutura). Se não enviar UTMs explícitas, informe pageUrl ou checkoutUrl na raiz com a query string intacta.visitorId deve ser o adoptify_visitor_id gerado pelo script AdOptify no navegador — essencial para enriquecer telefone/fbc/fbp no CAPI quando o webhook omitir esses campos.

1.3.5 - Commission

{
  "totalPriceInCents": number,
  "gatewayFeeInCents": number,
  "userCommissionInCents": number,
  "currency": "BRL | USD | EUR | GBP | ARS | CAD | ..."
}

currency = moeda em que o cliente pagou (ISO-4217). Veja a seção 2.4 — Moedas.

2. Descrição dos Parâmetros
Campos obrigatórios e regras para validação.

2.1 - Autenticação

Acesse Integrações > Webhooks e adicione um segredo com a plataforma Custom (Genérico). Você pode:

  • Inserir manualmente um valor forte (mínimo recomendado: 32 caracteres).
  • Gerar automaticamente clicando no botão "Gerar" disponibilizado na própria interface.

É possível criar múltiplos tokens (ex.: um por ambiente). Guarde-os em local seguro — o dashboard apenas exibe o valor uma vez.

2.2 - Body

  • orderId: identificador único do pedido no seu sistema. Obrigatório — sem ele a AdOptify gera um ID temporário unrecognized_* e prejudica a deduplicação no CAPI.
  • platform: nome da sua plataforma (use PascalCase). É usado para logs e para identificar tokens específicos.
  • paymentMethod e status: seguem os enums mostrados acima.
  • customer.email e customer.phone: enviados (hasheados) ao CAPI da Meta/Google/TikTok. Telefone vazio = pior Event Match Quality.
  • products: array de produtos. Pode incluir produto principal e order bumps (vários itens). O valor total da venda é a soma de priceInCents * quantity de todos os itens, exceto se informar commission.totalPriceInCents ou totalPriceInCents na raiz. O nome exibido da venda é a concatenação dos nomes (name ou title) de todos os produtos.
  • createdAt / approvedDate / refundedAt: formato UTC YYYY-MM-DD HH:MM:SS.
  • isTest: se true, a AdOptify valida o payload, mas não salva a venda (ideal para homologação).
  • trackingParameters: parâmetros de rastreamento. Envie UTMs sempre que possível. src e sck são usados no Rastreio 4.0. visitorId é o ID gerado pelo script AdOptify (adoptify_visitor_id no navegador).
  • pageUrl / checkoutUrl: URL completa do checkout com query string (alternativa quando UTMs não vêm em campos separados).

2.3 - Rastreamento e atribuição

Para a venda aparecer com campanha no dashboard, a AdOptify tenta atribuir nesta ordem:

  1. UTMs em trackingParameters (ou aliases tracking, utms, metadata).
  2. UTMs extraídas de pageUrl / checkoutUrl.
  3. UTMs decodificadas de sck / src na URL.
  4. Last-click por visitorId ou customer.email (últimos 30 dias, requer script AdOptify na landing).

Se nenhuma estratégia encontrar origem, a venda fica sem campanha (orgânica). Para melhor resultado, envie UTMs e mantenha o e-mail do cliente preenchido.

Enrichment CAPI via visitorId: o script AdOptify captura telefone/e-mail/fbc/fbp no browser. Se o webhook vier com trackingParameters.visitorId e omitir telefone/fbc/fbp, a AdOptify pode completar esses campos no envio server-side (perfil do visitante, 30 dias). Sem visitorId, esse enrichment não roda — o webhook precisa enviar customer.phone e os click IDs.

2.4 - Moedas (Custom, Meta, Google e TikTok)

  • Envie commission.currency na moeda real do checkout (ex.: USD se o cliente pagou em dólar).
  • A venda é gravada com o valor e a moeda do payload.
  • O dashboard converte para a moeda do projeto AdOptify nos relatórios.
  • Meta / TikTok: o valor vai para o pixel/dataset (não para uma conta específica). O mesmo pixel pode ser usado por várias contas (USD e BRL). Por isso a AdOptify envia a moeda da venda; o Gerenciador de Anúncios converte por conta na aba de valor de conversão.
  • Google Ads: o upload é por conta Ads (customer_id). A AdOptify converte o valor para a moeda da conta Google linkada usada no envio.
  • Exemplo Meta: checkout USD 49,90 → CAPI envia 49.90 USD ao pixel; conta BRL e conta USD que usam esse pixel veem o valor convertido pela Meta.

2.5 - Segurança e rate limits

  • Requisições sem token ou com token inválido retornam 401/403 imediatamente.
  • Bloqueamos IPs com 5 falhas consecutivas em menos de 2 minutos.
  • Tokens podem ser revogados pelo próprio usuário a qualquer momento.
  • Envie sempre via HTTPS. Nunca exponha tokens no frontend.
3. Exemplos Práticos
Baseados nos cenários mais comuns.
3.1

Pix gerado e pago

POST https://app.adoptify.com.br/api/track/{PROJECT_ID}
Headers:
  x-api-key: KVRxalfMiBfm8Rm1nP5YxfwYzArNsA0VLeWC
Body:
{
  "orderId": "8e40b27e-0118-4699-8587-e892beedb403",
  "platform": "GlobalPay",
  "paymentMethod": "pix",
  "status": "waiting_payment",
  "createdAt": "2024-07-26 14:35:13",
  "approvedDate": null,
  "refundedAt": null,
  "customer": {
    "name": "Marcos Goncalves Rodrigues",
    "email": "marcosgonrod@hotmail.com",
    "phone": "19936387209",
    "document": "29672656599",
    "country": "BR",
    "ip": "61.145.134.105"
  },
  "products": [{
    "id": "53d5ce96-a548-4c7b-a0bc-da8bfa0f9294",
    "name": "Óleo de Motor",
    "planId": null,
    "planName": null,
    "quantity": 1,
    "priceInCents": 8000
  }],
  "trackingParameters": {
    "utm_source": "FB",
    "utm_campaign": "CAMPANHA_2|413591587909524",
    "utm_medium": "CONJUNTO_2|498046723566488",
    "utm_content": "ANUNCIO_2|504346051220592",
    "utm_term": "Instagram_Feed",
    "visitorId": "8f3c2a1b-4d5e-6789-abcd-ef0123456789",
    "fbclid": "IwAR0exampleFbclid",
    "fbc": "fb.1.1710000000000.IwAR0exampleFbclid",
    "fbp": "fb.1.1710000000000.1234567890"
  },
  "commission": {
    "totalPriceInCents": 10000,
    "gatewayFeeInCents": 400,
    "userCommissionInCents": 9600,
    "currency": "BRL"
  },
  "isTest": false
}

Para informar o pagamento, envie novamente o mesmo pedido alterando status para paid e preenchendo approvedDate.

3.2

Cartão de crédito pago e reembolsado

POST https://app.adoptify.com.br/api/track/{PROJECT_ID}
Headers:
  x-api-key: JHTbglkQnUhz7Tk2oQ4ZyuVYxBsOpC1XNdYD
Body:
{
  "orderId": "b101ea20-72c7-473d-bcc4-416fe4d8f3be",
  "platform": "GlobalPay",
  "paymentMethod": "credit_card",
  "status": "paid",
  "createdAt": "2024-07-15 13:30:14",
  "approvedDate": "2024-07-15 13:30:14",
  "refundedAt": null,
  "customer": {
    "name": "Lucas Pereira Barros",
    "email": "lucaspbarros@gmail.com",
    "phone": "21996972147",
    "document": "24883871428",
    "country": "US",
    "ip": "242.53.157.167"
  },
  "products": [
    { "id": "ab341a39", "name": "T-shirt", "planId": "plan_tshirt", "planName": "Winter T-shirts", "quantity": 1, "priceInCents": 3500 },
    { "id": "8d7eb04c", "name": "Pants", "planId": "plan_pants", "planName": "Winter Pants", "quantity": 1, "priceInCents": 4000 }
  ],
  "trackingParameters": {
    "utm_source": "FB",
    "utm_campaign": "CAMPANHA_5|761832537749495",
    "utm_medium": "CONJUNTO_5|636393136432792",
    "utm_content": "ANUNCIO_5|525916699209785",
    "utm_term": "Facebook_Mobile_Feed"
  },
  "commission": {
    "totalPriceInCents": 7500,
    "gatewayFeeInCents": 375,
    "userCommissionInCents": 7125,
    "currency": "USD"
  }
}

Para registrar o reembolso, envie o mesmo JSON trocando status para refunded e preenchendo refundedAt.

4. Perguntas Frequentes
Como gerar a credencial?

Dashboard > Integrações > Webhooks > Segredos. Adicione uma linha com plataforma "Custom" (ou o nome desejado) e salve.

Como sei se o envio funcionou?

Requisições válidas retornam { success: true }. Você também verá a venda no menu Resumo em segundos.

Posso testar sem sujar meus relatórios?

Sim. Envie "isTest": true. Validamos o payload e devolvemos sucesso, mas não registramos a venda.

Há algum limite?

Limites seguem o plano contratado. Cada requisição passa por rate limiting e validação de token para evitar abuso.

A venda chegou, mas ficou orgânica (sem campanha). O que fazer?

Verifique se o payload inclui trackingParameters com UTMs ou pageUrl/checkoutUrl com a query string intacta. Confirme que o script AdOptify está na landing e que customer.email está preenchido. Se usar apenas fallback por e-mail ou visitorId, o visitante precisa ter passado pela landing rastreada nos últimos 30 dias.

O Facebook mostra EMQ baixo / sem telefone / sem fbc. É bug da AdOptify?

Quase sempre o webhook chegou sem customer.phone, fbc/fbp ou visitorId. O script sozinho não preenche o Purchase CAPI sem visitorId. Envie telefone no payload e, idealmente, visitorId + cookies Meta.

Envio em USD com projeto/conta em BRL — o que acontece?

A venda é gravada em USD. O dashboard converte para a moeda do projeto. Meta/TikTok recebem USD no pixel (moeda da venda). Google Ads recebe na moeda da conta Ads linkada (com câmbio se necessário).