Integração

Webhooks

A FINAUTON avisa o seu backend quando algo acontece com um cliente. O mesmo conteúdo existe no feed com cursor, para contingência.

Entrega

O FINAUTON envia POST para a URL https que você registrou, com o evento no corpo.

Cabeçalhos
POST https://seu-backend.example/webhooks/finauton
content-type: application/json
user-agent: FINAUTON-Webhooks/1
x-finauton-event-id: 6ac66671f825906d709f2d9b
x-finauton-event-type: automation.updated
x-finauton-timestamp: 1791400000
x-finauton-signature: t=1791400000,v1=<hex HMAC-SHA256>
Corpo
{
  "eventId": "6ac66671f825906d709f2d9b",
  "eventType": "automation.updated",
  "occurredAt": "2026-10-07T15:34:09.405Z",
  "principalId": "<seu parceiro>",
  "tenantId": "TENANT_A",
  "externalUserId": "cli-1001",
  "data": {
    "providerId": "BINANCE",
    "strategyId": "FUTURES_MAIN_V1",
    "strategyVersion": "1.0.0",
    "enabled": true,
    "risk": {
      "leverage": 3,
      "maxMarginPerTradeUsd": 10,
      "maxConcurrentTrades": 1,
      "maxDailyLossUsd": 10
    },
    "runtime": "ROUTING"
  }
}

Validar toda entrega

  1. HMAC-SHA256 com o segredo do webhook sobre "<t>.<corpo cru>"; compare em tempo constante.
  2. Recuse se |agora − t| > 300 s.
  3. Grave o eventId (deduplicação) antes de responder 2xx.
  4. Responda rápido e processe depois.
import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyFinautonWebhook(rawBody: string, signatureHeader: string, secret: string): boolean {
  const m = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(signatureHeader ?? '');
  if (!m) return false;
  const t = Number(m[1]);
  if (Math.abs(Date.now() / 1000 - t) > 300) return false;          // janela de 5 minutos
  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest();
  const got = Buffer.from(m[2], 'hex');
  return got.length === expected.length && timingSafeEqual(got, expected);
}

Reenvio

Falhou (resposta não-2xx ou 10 s sem resposta) → nova tentativa com o mesmo eventId: 1 min, 2, 4… até 6 h, 12 tentativas. Seu endpoint fora do ar nunca afeta execução, posições ou cobrança. Para recuperar o que perdeu, use o feed:

Tipos de evento e o que fazer

EventoQuandoNo seu app
client.updatedcliente criado, suspenso, reativado, estratégiasatualizar o cadastro
provider.connectedconexão concluída na página hospedada"Corretora conectada" → levar ao passo de risco
provider.connect_failedconexão falhoumostrar o motivo e oferecer tentar de novo
provider.disconnectedconexão revogadaavisar o cliente
provider.access_losta corretora recusou a credencialpedir para reconectar (posições seguem protegidas)
automation.updatedautomação ligada/pausadaatualizar a tela de operação
position.opened · position.updated · position.closedposição aberta, alterada, fechadanotificar / atualizar
protection.degradedstop/alvo não confirmados na corretoraalerta para o cliente e para o backoffice
statement.created · statement.adjustedextrato fechado ou ajustadoatualizar resultados
obligation.creatednova faturaavisar o cliente e mostrar "Pagar"
obligation.paidfatura paga e confirmadamarcar como paga na SUA tela
commercial.grace · commercial.suspended · commercial.reactivatedcarência, suspensão, reativação por cobrançaavisar o cliente