Ir para o conteúdo

8.1. Visão Geral

Especificação — em construção

Os serviços descritos nesta área ainda não estão disponíveis.

🧾 Descrição

O VeTrust envia notificações via WebHook para informar sobre mudanças de estado nas operações de crédito: conclusão de simulação, resultado da análise, registro da proposta, formalização e movimentação de parcelas.

Assinar os eventos é o que tira a sua integração do polling. As operações assíncronas descritas em 1.3. Operações Assíncronas todas concluem por webhook.

A entrega é tentada com retry exponencial com jitter em caso de falhas transitórias, e cada disparo carrega uma chave de idempotência que permite deduplicar entregas repetidas com segurança.


🔔 Tipos de Eventos

Slug (tipoEvento) Página Quando é disparado
credito.simulacao.concluida 8.2 O cálculo da simulação da proposta é concluído
credito.simulacao.falhou 8.2 O cálculo é recusado pela bancarizadora
credito.analise.concluida 8.3 O motor de crédito devolve o resultado, aprovado ou não
credito.proposta.enviada 8.4 A proposta entra em envio à bancarizadora
credito.proposta.registrada 8.4 A proposta é registrada e a CCB é numerada
credito.proposta.falhou 8.4 O registro é recusado
credito.assinatura.aguardando 8.4 A formalização começa e os assinantes são notificados
credito.contrato.formalizado 8.4 A formalização se conclui e o contrato fica ativo
credito.contrato.cancelado 8.4 A operação é cancelada
credito.parcela.cobranca_registrada 8.5 Uma cobrança é emitida para a parcela
credito.parcela.liquidada 8.5 Uma parcela é baixada
credito.contrato.liquidado 8.5 A última parcela em aberto é baixada

Uma mesma configuração de webhook pode estar inscrita em um ou mais tipos de evento. Todos os eventos inscritos são entregues na mesma URL — use o campo tipoEvento (ou o header X-Event-Type) para rotear o processamento.


📦 Envelope Padrão

Todos os eventos compartilham o mesmo envelope. O conteúdo específico fica em dados.

{
  "idWebhook": "019e0892-8d99-778c-9fa5-47bd07cd9ffb",
  "tipoEvento": "credito.analise.concluida",
  "dataHora": "2026-08-20T13:22:40.512Z",
  "grupoEconomico": "MeuGrupo",
  "dados": { },
  "etiquetas": null
}

🧾 Detalhamento dos Campos do Envelope

Campo Tipo Descrição
idWebhook string (GUID) Identificador único do disparo. Use para deduplicação. Também enviado no header X-Idempotency-Key
tipoEvento string Slug do evento. Sempre ASCII. Também no header X-Event-Type
dataHora string (ISO 8601, UTC) Momento em que o evento foi gerado
grupoEconomico string Grupo econômico que originou o evento
dados object Payload específico do tipo de evento
etiquetas object / null Pares chave/valor para extensão. Em disparos reais vem null; em disparos de teste vem preenchido

🔐 Autenticação

O VeTrust envia a requisição já autenticada conforme o modo de autenticação configurado:

Tipo Valor Headers/Body adicionados Observações
SemAutenticacao 1 nenhum Use apenas em endpoints protegidos por outra camada
ApiKey 2 X-Api-Key: <segredo> Chave fixa, simples e amplamente compatível
Basic 3 Authorization: Basic base64(clientId:clientSecret) Padrão HTTP Basic
BearerTokenFixo 4 Authorization: Bearer <segredo> Token estático configurado uma vez
OAuth2 5 Authorization: Bearer <token> obtido via client_credentials O VeTrust busca o token antes de enviar
ClientIdClientSecret 6 X-Client-Id e X-Client-Secret Headers separados

A URL de envio precisa ser HTTPS. Configurações com http:// são recusadas.


✍️ Assinatura HMAC (opcional, recomendada)

Quando o webhook é configurado com um segredo HMAC, o VeTrust assina cada disparo com HMAC-SHA256 sobre o corpo bruto da requisição e envia o hash no header:

X-Webhook-Signature: sha256=<hex_lowercase>

Validação no consumidor (Node.js)

const crypto = require('crypto');

function validarAssinatura(corpoBruto, headerAssinatura, segredo) {
  const esperado = crypto
    .createHmac('sha256', segredo)
    .update(corpoBruto, 'utf8')
    .digest('hex');

  const recebido = (headerAssinatura || '').replace(/^sha256=/, '');
  return crypto.timingSafeEqual(
    Buffer.from(esperado, 'hex'),
    Buffer.from(recebido, 'hex')
  );
}

Validação no consumidor (C#)

using System.Security.Cryptography;
using System.Text;

bool ValidarAssinatura(string corpoBruto, string headerAssinatura, string segredo)
{
    using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(segredo));
    var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(corpoBruto));
    var esperado = Convert.ToHexString(hash).ToLowerInvariant();
    var recebido = (headerAssinatura ?? string.Empty).Replace("sha256=", string.Empty);
    return CryptographicOperations.FixedTimeEquals(
        Encoding.UTF8.GetBytes(esperado),
        Encoding.UTF8.GetBytes(recebido));
}

Importante: valide a assinatura sobre o corpo bruto recebido, antes de qualquer parsing JSON. Frameworks que reformatam JSON antes da validação causam mismatch.


📨 Headers Padrão

Header Exemplo Descrição
Content-Type application/json; charset=utf-8 Sempre JSON UTF-8
X-Idempotency-Key 019e0892-8d99-778c-9fa5-47bd07cd9ffb Mesmo valor de idWebhook no envelope
X-Event-Type credito.analise.concluida Slug do evento, útil para roteamento
X-Webhook-Signature sha256=fa1be9... Presente apenas quando há segredo HMAC configurado
Authorization ou afins depende do modo Ver tabela de autenticação

🔁 Retry e Entrega

A entrega é considerada bem-sucedida quando o consumidor responde com status HTTP 2xx.

Em caso de falha transitória (5xx, 408, 429, timeout, DNS, conexão recusada), há retry exponencial com jitter. Os demais erros 4xx não são retentados.

Tentativa Delay aproximado
1 imediato
2 ~1s + jitter
3 ~2s + jitter
4 ~4s + jitter
5 ~8s + jitter

Após 5 tentativas sem sucesso, o disparo é registrado como falho e não é mais retentado automaticamente.

Responda 2xx assim que receber, idealmente em menos de 5 segundos, e processe de forma assíncrona. Processamento pesado dentro do handler leva a timeout e retry desnecessário.


🪞 Idempotência

Como retries podem entregar a mesma notificação mais de uma vez, o consumidor deve deduplicar usando o idWebhook (ou o header X-Idempotency-Key).

Padrão recomendado:

  1. Ao receber, persista idWebhook em uma tabela com unique constraint.
  2. Se o INSERT falhar com violação de unicidade, retorne 200 OK sem reprocessar.
  3. Senão, processe normalmente.

⏱️ A ordem das entregas não é garantida

Dois eventos da mesma proposta podem chegar fora de ordem. Não construa a sua máquina de estados a partir da sequência de recebimento.

Padrão recomendado: ao receber um evento, consulte o recurso (GET /credito/propostas/{id} ou GET /credito/contratos/{id}) e reconcilie com o estado atual. Use o evento como gatilho, não como fonte da verdade.


🛠️ Configuração

🔗 Endpoints

Método URL
GET /webhooks
POST /webhooks
GET /webhooks/{idWebhook}
PUT /webhooks/{idWebhook}
DELETE /webhooks/{idWebhook}
POST /webhooks/{idWebhook}/teste
GET /webhooks/{idWebhook}/disparos

📤 Criar configuração

{
  "url": "https://meusistema.com.br/webhooks/vetrust",
  "tiposEvento": [
    "credito.analise.concluida",
    "credito.proposta.registrada",
    "credito.contrato.formalizado",
    "credito.parcela.liquidada"
  ],
  "tipoAutenticacao": 2,
  "apiKey": "sua-chave-secreta",
  "segredoHmac": "minimo-16-caracteres",
  "ativo": true
}
Campo Tipo Obrigatório Descrição
url string Sim URL de destino. HTTPS obrigatório
tiposEvento array Sim Um ou mais slugs dos eventos desejados
tipoAutenticacao integer Sim Ver tabela de autenticação
apiKey / clientId / clientSecret / token / urlAutenticacao string Condicional Conforme o modo escolhido
segredoHmac string Não Mínimo 16 caracteres. Recomendado
ativo boolean Não true por padrão

🧪 Disparo de teste

curl -X POST "https://api.vehub.com.br/webhooks/019e0892-8d99-778c-9fa5-47bd07cd9ffb/teste" \
  -H "Authorization: Bearer {seu_token}" \
  -H "GrupoEconomico: {seu_grupo_economico}"

Envia um payload realístico do tipo de evento configurado, com identificadores fictícios e a etiqueta isTeste = "true" no envelope. É single-shot, sem retry.

Prepare o seu consumidor para identificar etiquetas.isTeste === "true" e ramificar o processamento durante as validações.

📜 Logs de disparo

curl -X GET "https://api.vehub.com.br/webhooks/019e0892-8d99-778c-9fa5-47bd07cd9ffb/disparos?pagina=1&quantidade=50" \
  -H "Authorization: Bearer {seu_token}" \
  -H "GrupoEconomico: {seu_grupo_economico}"

Cada tentativa de envio fica registrada com data, número da tentativa, duração, status HTTP, sucesso/falha, headers e payload enviados, resposta recebida, e a flag de teste.


🕒 Observações

  • Todos os timestamps estão em UTC (ISO 8601 com Z).
  • Os payloads usam camelCase.
  • Os eventos não transportam dados sensíveis do tomador além do necessário para identificar a operação. Para a ficha completa, consulte a proposta.