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 headerX-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:
- Ao receber, persista
idWebhookem uma tabela com unique constraint. - Se o
INSERTfalhar com violação de unicidade, retorne 200 OK sem reprocessar. - 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 |
|---|---|
/webhooks | |
/webhooks | |
/webhooks/{idWebhook} | |
/webhooks/{idWebhook} | |
/webhooks/{idWebhook} | |
/webhooks/{idWebhook}/teste | |
/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.