Documentação da API de Webhooks - Corvex

Visão Geral

A API de Webhooks da Corvex permite que você receba notificações em tempo real sobre eventos importantes do seu sistema de checkout, como criação de pedidos, confirmação de pagamentos e carrinhos abandonados.

Os eventos de pedido seguem um formato padronizado. O evento de carrinho abandonado compartilha a mesma filosofia de integração (campos de cliente, itens, UTMs), mas inclui campos específicos do checkout em andamento.


Autenticação

Todos os webhooks podem incluir uma assinatura HMAC-SHA256 no header X-Webhook-Signature para validação de integridade.

Validação da Assinatura

const crypto = require('crypto');

function validateWebhookSignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(JSON.stringify(payload));
  const expectedSignature = hmac.digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Exemplo de uso
const isValid = validateWebhookSignature(
  request.body,
  request.headers['x-webhook-signature'],
  'seu-secret-aqui'
);

Eventos Disponíveis

A Corvex suporta os seguintes eventos de webhook:

EventoNome do EventoDescrição
Pedido Criadocorvex.order.createdDisparado quando um pedido é criado (pagamento pendente)
Pedido Pagocorvex.order.paidDisparado quando um pagamento é confirmado
Pedido Canceladocorvex.order.cancelledDisparado quando um pedido é cancelado/recusado
Pedido Reembolsadocorvex.order.refundedDisparado quando um pedido é reembolsado
Carrinho Abandonadocorvex.cart.abandonedDisparado quando um visitante abandona o checkout sem finalizar o pagamento

Nota: O evento corvex.order.pending existe apenas para uso interno do sistema e não é configurável nem enviado aos endpoints dos lojistas.


Estrutura do Payload

Eventos de Pedido

Os eventos de pedido (corvex.order.*) seguem a estrutura abaixo:

Payload Base (Pedidos)

{
  "id": "string (UUID)",
  "event": "string",
  "amount": "number",
  "status": "string",
  "method": "string",
  "client": {
    "doc": "string",
    "name": "string",
    "email": "string",
    "phone": "string"
  },
  "items": [
    {
      "id": "string (UUID)",
      "name": "string",
      "price": "number",
      "quantity": "number",
      "externalRef": "string",
      "orderBump": "boolean",
      "gift": "boolean"
    }
  ],
  "address": {
    "city": "string | null",
    "state": "string | null",
    "number": "string | null",
    "street": "string | null",
    "zipcode": "string | null",
    "complement": "string | null",
    "neighborhood": "string | null"
  },
  "utm": {
    "ttp": "string",
    "ttclid": "string",
    "source": "string",
    "medium": "string",
    "campaign": "string",
    "content": "string",
    "term": "string",
    "page": {
      "url": "string",
      "referrer": "string"
    }
  },
  "checkout_query_params": "object | null",
  "timestamp": "string (ISO 8601)",
  "paidAt": "string (ISO 8601) | null",
  "pix_code": "string | null",
  "pageOrderDetails": "string | null"
}

Detalhamento dos Campos

Campos Principais

CampoTipoObrigatórioDescrição
idstring (UUID)SimID único do pedido no sistema Corvex
eventstringSimNome do evento (ex: corvex.order.paid)
amountnumberSimValor total do pedido em reais (formato decimal)
statusstringSimStatus do pedido (ver tabela abaixo)
methodstringSimMétodo de pagamento (ver tabela abaixo)
timestampstring (ISO 8601)SimData e hora de criação do pedido
paidAtstring (ISO 8601)NãoData e hora de confirmação do pagamento (apenas eventos corvex.order.paid)
pix_codestringNãoCódigo PIX copia-e-cola. Enviado em qualquer evento de pedido quando method é pix e o código estiver disponível
pageOrderDetailsstringNãoURL da página de pagamento PIX com QR Code. Enviada quando method é pix e a loja tiver domínio configurado

Status do Pedido

ValorDescrição
pendingAguardando pagamento
paidPagamento confirmado
refusedPagamento recusado/cancelado
refundedReembolsado
waiting_paymentAguardando confirmação do pagamento

Método de Pagamento

ValorDescrição
pixPIX
cardCartão de crédito/débito
bankslipBoleto bancário
unknownMétodo desconhecido

Objeto client

CampoTipoObrigatórioDescrição
docstringSimDocumento do cliente no formato TIPO:NÚMERO (ex: CPF:12345678900)
namestringSimNome completo do cliente
emailstringSimE-mail do cliente
phonestringSimTelefone do cliente (com DDI, ex: 5511999999999)

Array items

CampoTipoObrigatórioDescrição
idstring (UUID)SimID único do item no sistema
namestringSimNome do produto
pricenumberSimPreço unitário do item em reais
quantitynumberSimQuantidade do item
externalRefstringSimReferência externa (ID do produto na loja integrada)
orderBumpbooleanSimIndica se é um order bump
giftbooleanSimIndica se é um produto grátis/gift

Objeto address (Opcional)

CampoTipoDescrição
citystring | nullCidade do cliente
statestring | nullEstado (UF) do cliente
numberstring | nullNúmero do endereço
streetstring | nullRua/Logradouro
zipcodestring | nullCEP do cliente
complementstring | nullComplemento do endereço
neighborhoodstring | nullBairro

Objeto utm (Opcional)

CampoTipoDescrição
ttpstringTikTok Pixel Parameter
ttclidstringTikTok Click ID
sourcestringFonte do tráfego (ex: google, facebook)
mediumstringMeio do tráfego (ex: cpc, organic)
campaignstringNome da campanha
contentstringConteúdo da campanha
termstringTermo de busca
pageobjectInformações da página
page.urlstringURL da página
page.referrerstringURL de referência

Objeto checkout_query_params (Opcional)

Parâmetros extras enviados no checkout. Estrutura dinâmica baseada nos atributos do checkout.

Mapeamento evento → status no payload

Evento configurávelCampo event no payloadCampo status típico
ORDER_CREATEDcorvex.order.createdpending
ORDER_PAIDcorvex.order.paidpaid
ORDER_CANCELLEDcorvex.order.cancelledrefused
ORDER_REFUNDEDcorvex.order.refundedrefunded
CART_ABANDONEDcorvex.cart.abandonedabandoned

Campos condicionais (importante)

Nem todos os campos aparecem em todos os envios. Trate ausência ou null com segurança:

CampoQuando é enviado
addressQuando há dados de endereço no pedido/lead
utmQuando há UTMs capturadas no checkout
checkout_query_paramsQuando o checkout possui atributos extras
paidAtApenas em corvex.order.paid
pix_codeQuando method é pix e o pedido possui código PIX
pageOrderDetailsQuando method é pix e a loja possui domínio ativo configurado
store (carrinho)Quando os dados da loja estão disponíveis no checkout

Formato do client.doc

  • Pedidos: TIPO:NÚMERO (ex.: CPF:12345678900)
  • Pode ser "N/A" se o documento não estiver disponível no momento do envio
  • Carrinho abandonado: null quando o CPF não foi informado; quando informado, no formato CPF:NÚMERO

Carrinho Abandonado (corvex.cart.abandoned)

Quando o evento é disparado

O webhook de carrinho abandonado é enviado quando um visitante sai do checkout sem concluir o pagamento. A detecção ocorre após um período de graça de 90 segundos desde a desconexão do visitante no checkout. O evento é entregue via HTTP para webhooks da loja configurados com CART_ABANDONED.

O evento não é disparado se:

  • O visitante reconectar ao checkout dentro do período de graça
  • O lead já tiver finalizado o pagamento (checkPayment = true)
  • O lead não tiver dados mínimos de contato: (nome + telefone) ou (nome + e-mail)

Payload do Carrinho Abandonado

{
  "id": "string (UUID)",
  "leadId": "string (UUID)",
  "checkoutId": "string (UUID)",
  "event": "corvex.cart.abandoned",
  "amount": "number",
  "status": "abandoned",
  "url_checkout": "string",
  "client": {
    "doc": "string | null",
    "name": "string",
    "email": "string | null",
    "phone": "string | null"
  },
  "items": [
    {
      "id": "string (UUID)",
      "name": "string",
      "price": "number",
      "quantity": "number",
      "sku": "string | null",
      "image": "string | null"
    }
  ],
  "address": {
    "city": "string | null",
    "state": "string | null",
    "number": "string | null",
    "street": "string | null",
    "zipcode": "string | null",
    "complement": "string | null",
    "neighborhood": "string | null"
  },
  "utm": {
    "source": "string",
    "medium": "string",
    "campaign": "string",
    "content": "string",
    "term": "string"
  },
  "cart": {
    "abandonedAt": "string (ISO 8601)",
    "createdAt": "string (ISO 8601)",
    "checkoutDurationSeconds": "number"
  },
  "store": {
    "id": "string (UUID)",
    "name": "string",
    "slug": "string"
  },
  "timestamp": "string (ISO 8601)"
}

Campos específicos do carrinho abandonado

CampoTipoObrigatórioDescrição
idstring (UUID)SimID do checkout (carrinho)
leadIdstring (UUID)SimID do lead associado ao visitante
checkoutIdstring (UUID)SimID do checkout abandonado
eventstringSimSempre corvex.cart.abandoned
amountnumberSimValor total do carrinho em reais
statusstringSimSempre abandoned
url_checkoutstringSimURL para o visitante retomar a compra
cart.abandonedAtstring (ISO 8601)SimData e hora em que o abandono foi detectado
cart.createdAtstring (ISO 8601)SimData e hora de criação do checkout
cart.checkoutDurationSecondsnumberSimTempo total (em segundos) que o visitante permaneceu no checkout
storeobjectNãoDados da loja (id, name, slug)

Diferenças em relação aos eventos de pedido

AspectoEventos de pedidoCarrinho abandonado
idID do pedidoID do checkout
methodMétodo de pagamentoNão enviado (pagamento não iniciado ou não concluído)
paidAtPresente em corvex.order.paidNão aplicável
leadIdNão enviadoEnviado
url_checkoutNão enviadoEnviado (link de recuperação)
statuspending, paid, etc.Sempre abandoned

Exemplos de Payloads

Exemplo 1: Pedido Criado (corvex.order.created)

{
  "id": "f7542077-5b0b-4b4a-9283-8cd16fc70b96",
  "event": "corvex.order.created",
  "amount": 274.32,
  "status": "pending",
  "method": "pix",
  "client": {
    "doc": "CPF:00000000000",
    "name": "Cliente Teste",
    "email": "[email protected]",
    "phone": "5511999999999"
  },
  "items": [
    {
      "id": "ca9715eb-1e57-462a-9266-b0ce884c2993",
      "name": "Nome do Produto",
      "price": 274.32,
      "quantity": 1,
      "externalRef": "05da5a8d-6347-4c7c-a784-cc3a2fdafa05",
      "orderBump": false,
      "gift": false
    }
  ],
  "address": {
    "city": "São Paulo",
    "state": "SP",
    "number": "165",
    "street": "Rua de Teste",
    "zipcode": "00000000",
    "complement": null,
    "neighborhood": "Moca"
  },
  "utm": {
    "ttp": "01KET6P10HCF9EW5SBHZ6MZY7C_.tt.0",
    "ttclid": "",
    "source": "direct",
    "medium": "web",
    "campaign": "direct",
    "content": "",
    "term": "",
    "page": {
      "url": "http://localhost:3000/pay/426785fd-8140-4d43-b845-9d9005758f82",
      "referrer": ""
    }
  },
  "checkout_query_params": {
    "product": "panelas-cookover",
    "variant": "9-pecas"
  },
  "pix_code": "00020126580014br.gov.bcb.pix0136123e4567-e89b-12d3-a456-4266141740005204000053039865405274.325802BR5925Minha Loja6009SAO PAULO62070503***6304ABCD",
  "pageOrderDetails": "https://minhaloja.com.br/pay/426785fd-8140-4d43-b845-9d9005758f82/pix-success?payment=f7542077-5b0b-4b4a-9283-8cd16fc70b96",
  "timestamp": "2026-01-12T23:16:08.198Z"
}

Exemplo 2: Pedido Pago (corvex.order.paid)

{
  "id": "f7542077-5b0b-4b4a-9283-8cd16fc70b96",
  "event": "corvex.order.paid",
  "amount": 274.32,
  "status": "paid",
  "method": "pix",
  "client": {
    "doc": "CPF:00000000000",
    "name": "Cliente Teste",
    "email": "[email protected]",
    "phone": "5517991301328"
  },
  "items": [
    {
      "id": "ca9715eb-1e57-462a-9266-b0ce884c2993",
      "name": "Jogo de Panelas Cookover 9 Peças (indução e gás)",
      "price": 274.32,
      "quantity": 1,
      "externalRef": "05da5a8d-6347-4c7c-a784-cc3a2fdafa05",
      "orderBump": false,
      "gift": false
    }
  ],
  "address": {
    "city": "São José do Rio Preto",
    "state": "SP",
    "number": "165",
    "street": "Rua Alcides Cardoso Treme",
    "zipcode": "15045464",
    "complement": null,
    "neighborhood": "Residencial Ana Célia"
  },
  "utm": {
    "ttp": "01KET6P10HCF9EW5SBHZ6MZY7C_.tt.0",
    "ttclid": "",
    "source": "direct",
    "medium": "web",
    "campaign": "direct",
    "content": "",
    "term": "",
    "page": {
      "url": "http://localhost:3000/pay/426785fd-8140-4d43-b845-9d9005758f82",
      "referrer": ""
    }
  },
  "checkout_query_params": {
    "product": "panelas-cookover",
    "variant": "9-pecas"
  },
  "pix_code": "00020126580014br.gov.bcb.pix0136123e4567-e89b-12d3-a456-4266141740005204000053039865405274.325802BR5925Minha Loja6009SAO PAULO62070503***6304ABCD",
  "pageOrderDetails": "https://minhaloja.com.br/pay/426785fd-8140-4d43-b845-9d9005758f82/pix-success?payment=f7542077-5b0b-4b4a-9283-8cd16fc70b96",
  "timestamp": "2026-01-12T23:16:08.198Z",
  "paidAt": "2026-01-12T23:20:15.543Z"
}

Exemplo 3: Pedido com Múltiplos Itens

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "event": "corvex.order.paid",
  "amount": 599.90,
  "status": "paid",
  "method": "card",
  "client": {
    "doc": "CPF:12345678900",
    "name": "Maria Silva",
    "email": "[email protected]",
    "phone": "5511987654321"
  },
  "items": [
    {
      "id": "item-1-uuid",
      "name": "Produto Principal",
      "price": 499.90,
      "quantity": 1,
      "externalRef": "prod-123",
      "orderBump": false,
      "gift": false
    },
    {
      "id": "item-2-uuid",
      "name": "Order Bump - Garantia Estendida",
      "price": 100.00,
      "quantity": 1,
      "externalRef": "bump-456",
      "orderBump": true,
      "gift": false
    }
  ],
  "address": {
    "city": "São Paulo",
    "state": "SP",
    "number": "123",
    "street": "Avenida Paulista",
    "zipcode": "01310100",
    "complement": "Apto 45",
    "neighborhood": "Bela Vista"
  },
  "timestamp": "2026-01-12T10:00:00.000Z",
  "paidAt": "2026-01-12T10:05:30.000Z"
}

Exemplo 4: Carrinho Abandonado (corvex.cart.abandoned)

{
  "id": "426785fd-8140-4d43-b845-9d9005758f82",
  "leadId": "a8f3c2d1-9e4b-4a7c-8d6f-1b2e3c4d5e6f",
  "checkoutId": "426785fd-8140-4d43-b845-9d9005758f82",
  "event": "corvex.cart.abandoned",
  "amount": 274.32,
  "status": "abandoned",
  "url_checkout": "https://minhaloja.com.br/checkout/426785fd-8140-4d43-b845-9d9005758f82",
  "client": {
    "doc": "CPF:12345678900",
    "name": "Cliente Teste",
    "email": "[email protected]",
    "phone": "5511999999999"
  },
  "items": [
    {
      "id": "ca9715eb-1e57-462a-9266-b0ce884c2993",
      "name": "Jogo de Panelas Cookover 9 Peças",
      "price": 274.32,
      "quantity": 1,
      "sku": "PANELAS-9PC",
      "image": "https://cdn.exemplo.com/produtos/panelas.jpg"
    }
  ],
  "address": {
    "city": "São Paulo",
    "state": "SP",
    "number": "165",
    "street": "Rua de Teste",
    "zipcode": "01310100",
    "complement": null,
    "neighborhood": "Bela Vista"
  },
  "utm": {
    "source": "instagram",
    "medium": "cpc",
    "campaign": "retargeting-carrinho",
    "content": "story-anuncio",
    "term": ""
  },
  "cart": {
    "abandonedAt": "2026-01-12T23:18:30.000Z",
    "createdAt": "2026-01-12T23:10:00.000Z",
    "checkoutDurationSeconds": 510
  },
  "store": {
    "id": "56869340-7696-4908-9f75-5dcc1ada91d5",
    "name": "Minha Loja",
    "slug": "minha-loja"
  },
  "timestamp": "2026-01-12T23:18:30.000Z"
}

Configuração de Webhooks

Endpoint de Configuração

Para configurar um webhook, você precisa criar um registro de webhook na API da Corvex. Consulte a documentação da API REST para mais detalhes sobre como criar e gerenciar webhooks.

Eventos Configuráveis

Ao configurar um webhook, você deve especificar quais eventos deseja receber. Os eventos disponíveis são:

  • ORDER_CREATED - Recebe eventos corvex.order.created
  • ORDER_PAID - Recebe eventos corvex.order.paid
  • ORDER_CANCELLED - Recebe eventos corvex.order.cancelled
  • ORDER_REFUNDED - Recebe eventos corvex.order.refunded
  • CART_ABANDONED - Recebe eventos corvex.cart.abandoned

Esses são os únicos eventos enviados no formato documentado nesta página (payload flat com corvex.*).

Eventos exibidos no dashboard (legado)

O painel pode listar eventos adicionais (SUBSCRIPTION_*, PAYMENT_*, etc.). Eles não fazem parte desta API pública e, quando ativos, usam um formato interno legado:

{
  "event": "SUBSCRIPTION_CREATED",
  "data": { },
  "timestamp": "ISO 8601",
  "webhookId": "uuid",
  "storeId": "uuid"
}

Para novas integrações, use apenas os cinco eventos listados acima.

Headers HTTP

Todos os webhooks são enviados com os seguintes headers:

Content-Type: application/json
User-Agent: Corvex-Webhook/1.0
X-Webhook-Signature: <hmac-sha256-signature> (se configurado)

Considerações Importantes

Timeout

Os webhooks têm um timeout de 10 segundos. Se sua API não responder dentro desse período, o webhook será marcado como falhado.

Retry

A Corvex não realiza retries automáticos de webhooks. Se um webhook falhar, você precisará implementar sua própria lógica de retry se necessário.

Idempotência

Todos os webhooks incluem um campo id único. Para eventos de pedido, id é o ID do pedido. Para carrinho abandonado, id é o ID do checkout. Recomendamos implementar idempotência no seu sistema usando a combinação event + id + leadId (para carrinhos abandonados) para evitar processamento duplicado.

Ordem dos Eventos

A ordem dos eventos não é garantida. Um evento corvex.order.paid pode chegar antes de um corvex.order.created em alguns casos raros. Sempre use o campo timestamp para determinar a ordem cronológica correta.

Valores Nulos

Alguns campos opcionais podem ser null. Sempre valide a presença de campos opcionais antes de usá-los.


Testando Webhooks

Teste pelo dashboard

No painel Dashboard → Webhooks, abra um webhook e use Enviar teste para disparar um payload de exemplo no formato documentado nesta página. O envio usa a URL e o secret configurados no webhook e registra o resultado nos logs de teste.

Usando ngrok (Desenvolvimento Local)

# 1. Instalar ngrok
npm install -g ngrok

# 2. Iniciar seu servidor local na porta 3000
npm run dev

# 3. Expor seu servidor local
ngrok http 3000

# 4. Use a URL do ngrok como URL do webhook
# Exemplo: https://abc123.ngrok.io/webhook

Exemplo de Endpoint de Recepção (Node.js/Express)

const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

app.post('/webhook', (req, res) => {
  const payload = req.body;
  const signature = req.headers['x-webhook-signature'];
  const secret = 'seu-secret-aqui'; // Deve vir das variáveis de ambiente

  // Validar assinatura (opcional, mas recomendado)
  if (signature) {
    const hmac = crypto.createHmac('sha256', secret);
    hmac.update(JSON.stringify(payload));
    const expectedSignature = hmac.digest('hex');
    
    if (signature !== expectedSignature) {
      return res.status(401).json({ error: 'Invalid signature' });
    }
  }

  // Processar o webhook
  console.log('Evento recebido:', payload.event);
  console.log('Pedido ID:', payload.id);
  console.log('Status:', payload.status);

  // Implementar idempotência
  // Verificar se já processou este pedido/evento

  // Processar o evento
  switch (payload.event) {
    case 'corvex.order.created':
      console.log('Pedido criado:', payload.id);
      break;
    case 'corvex.order.paid':
      console.log('Pedido pago:', payload.id);
      break;
    case 'corvex.order.cancelled':
      console.log('Pedido cancelado:', payload.id);
      break;
    case 'corvex.order.refunded':
      console.log('Pedido reembolsado:', payload.id);
      break;
    case 'corvex.cart.abandoned':
      console.log('Carrinho abandonado:', payload.id, 'lead:', payload.leadId);
      // Enviar e-mail/SMS de recuperação usando payload.url_checkout
      break;
  }

  // Sempre retornar 200 OK rapidamente
  res.status(200).json({ received: true });
});

app.listen(3000, () => {
  console.log('Servidor ouvindo na porta 3000');
});

Referências

Suporte

Para dúvidas ou problemas com webhooks, entre em contato com o suporte da Corvex.


Changelog

Versão 1.1.2 (2026-07-14)

  • Webhook HTTP de corvex.cart.abandoned implementado para URLs configuradas com CART_ABANDONED
  • Documentação alinhada com campos condicionais, mapeamento evento/status e eventos legado do dashboard
  • Payload de teste inclui pix_code e pageOrderDetails em todos os eventos com method: pix

Versão 1.1.1 (2026-07-14)

  • Webhooks de pedido com method: pix passam a incluir pix_code (copia-e-cola) quando disponível
  • Webhooks de pedido com method: pix incluem pageOrderDetails (URL da página de pagamento PIX) quando a loja tem domínio ativo
  • Payload de teste do dashboard alinhado ao formato real da documentação

Versão 1.1.0 (2026-07-13)

  • Adicionado evento corvex.cart.abandoned (configurável via CART_ABANDONED)
  • Documentação do payload de carrinho abandonado com campos leadId, url_checkout e cart.checkoutDurationSeconds
  • Critérios de disparo e período de graça de 90 segundos

Versão 1.0.0 (2026-01-12)

  • Implementação inicial da API de Webhooks
  • Eventos: corvex.order.created, corvex.order.paid, corvex.order.cancelled, corvex.order.refunded
  • Suporte a assinatura HMAC-SHA256
  • Payload padronizado para todos os eventos
  • Inclusão de dados completos (endereço, UTMs, checkout_query_params)

Última atualização: 2026-07-14 (v1.1.2)