Pular para o conteúdo principal
Webhooks permitem comunicação em tempo real entre o Matcher e sistemas externos. Este guia aborda notificações de eventos de saída e callbacks de resolução de entrada.

Visão geral


O Matcher permite comunicação bidirecional via webhook:
  • Webhooks de saída: O Matcher notifica sistemas externos quando eventos ocorrem
  • Callbacks de entrada: Sistemas externos notificam o Matcher quando ações são tomadas
Quando algo acontece no Matcher, como uma nova exceção ou uma correspondência concluída, ele envia um evento para os endpoints configurados. Sistemas externos como JIRA ou ServiceNow podem então enviar callbacks para atualizar o status da exceção ou fechar itens automaticamente. Esse fluxo bidirecional mantém suas ferramentas sincronizadas sem intervenção manual.
Matcher Webhooks Callbacks

Eventos de saída


O Matcher emite eventos quando ações significativas ocorrem no processo de reconciliação.

Eventos disponíveis

EventoGatilhoUso típico
ingestion.completedImportação de arquivo concluídaMonitoramento de pipeline de dados
ingestion.failedImportação de arquivo falhouAlertas de erro
match.createdNova correspondência propostaRegistro de auditoria
match.confirmedCorrespondência aprovadaAtualizações downstream
match.rejectedCorrespondência recusadaGatilhos de investigação
match.force_matchedCorrespondência forçada manual aplicadaTrilha de auditoria, fluxos de aprovação
match.unmatchedCorrespondência revertida manualmenteTrilha de auditoria, rastreamento de correções
match_run.startedJob de correspondência automática iniciadoMonitoramento de jobs
match_run.completedJob de correspondência automática concluídoMonitoramento de jobs, relatórios
match_run.failedJob de correspondência automática falhouAlertas de erro
exception.createdNova exceçãoCriação de tickets
exception.assignedExceção atribuídaNotificação de usuário
exception.escalatedExceção escaladaAlertas de gerenciamento
exception.resolvedExceção resolvidaSincronização de status
exception.sla_warningSLA se aproximandoAlertas proativos
exception.sla_breachSLA excedidoGatilhos de escalação
context.closedPeríodo de reconciliação fechadoGatilhos de relatórios

Estrutura do payload de evento

Todos os eventos seguem uma estrutura consistente:
{
 "id": "evt_001",
 "type": "exception.created",
 "timestamp": "2024-01-20T10:30:00Z",
 "version": "1.0",
 "tenant_id": "tenant_001",
 "context_id": "ctx_abc123",
 "data": {
 // Dados específicos do evento
 },
 "metadata": {
 "correlation_id": "req_xyz789",
 "source": "matching_engine"
 }
}

Payloads de eventos


Ingestioncompleted

Disparado quando um lote de transações é importado com sucesso.
{
  "id": "evt_ing_001",
  "type": "ingestion.completed",
  "timestamp": "2024-01-20T10:30:00Z",
  "data": {
    "job_id": "job_imp_001",
    "source_id": "src_bank456",
    "source_name": "Chase Bank",
    "file_name": "statement_january.csv",
    "summary": {
      "total_rows": 1250,
      "imported": 1240,
      "duplicates_skipped": 8,
      "validation_errors": 2
    },
    "duration_seconds": 45,
    "started_at": "2024-01-20T10:29:15Z",
    "completed_at": "2024-01-20T10:30:00Z"
  }
}

Matchconfirmed

Disparado quando uma correspondência é aprovada (automática ou manual).
{
  "id": "evt_mtch_001",
  "type": "match.confirmed",
  "timestamp": "2024-01-20T10:30:01Z",
  "data": {
    "match_id": "match_001",
    "confidence": 100,
    "rule_id": "rule_exact001",
    "rule_name": "Exact Match",
    "confirmation_type": "AUTO",
    "transactions": [
      {
        "id": "txn_bank_001",
        "source_name": "Chase Bank",
        "amount": 1000.0,
        "currency": "USD",
        "date": "2024-01-15"
      },
      {
        "id": "txn_ledger_001",
        "source_name": "Main Ledger",
        "amount": 1000.0,
        "currency": "USD",
        "date": "2024-01-15"
      }
    ],
    "variance": {
      "amount_diff": 0,
      "date_diff_days": 0
    }
  }
}

Exceptioncreated

Disparado quando uma nova exceção é identificada.
{
  "id": "evt_exc_001",
  "type": "exception.created",
  "timestamp": "2024-01-20T10:30:00Z",
  "data": {
    "exception_id": "exc_001",
    "severity": "HIGH",
    "reason": "NO_MATCH_FOUND",
    "reason_details": "No matching transaction found within tolerance",
    "transaction": {
      "id": "txn_bank_999",
      "source_id": "src_bank456",
      "source_name": "Chase Bank",
      "external_id": "BANK-2024-999",
      "amount": 15000.0,
      "currency": "USD",
      "date": "2024-01-15",
      "reference": "Wire transfer #7890"
    },
    "candidates": [
      {
        "transaction_id": "txn_ledger_777",
        "confidence": 55,
        "rejection_reason": "Below 60% threshold"
      }
    ],
    "sla": {
      "due_at": "2024-01-21T10:30:00Z",
      "hours_remaining": 24
    }
  }
}

Exceptionresolved

Disparado quando uma exceção é resolvida.
{
  "id": "evt_exc_002",
  "type": "exception.resolved",
  "timestamp": "2024-01-20T14:30:00Z",
  "data": {
    "exception_id": "exc_001",
    "resolution": {
      "type": "FORCE_MATCH",
      "match_id": "match_forced_001",
      "resolved_by": "user_123",
      "notes": "Verified: amount difference is bank wire fee"
    },
    "time_to_resolution": {
      "hours": 4,
      "within_sla": true
    }
  }
}

Matchforcematched

Disparado quando um usuário força manualmente uma correspondência entre transações.
{
  "id": "evt_force_001",
  "type": "match.force_matched",
  "timestamp": "2024-01-20T14:30:00Z",
  "data": {
    "match_id": "match_forced_001",
    "exception_id": "exc_001",
    "forced_by": "user_123",
    "reason": "Amount difference is documented bank fee",
    "notes": "Verified with bank statement showing $250 wire fee deducted",
    "transactions": [
      {
        "id": "txn_bank_999",
        "source_name": "Chase Bank",
        "amount": 15000.0,
        "currency": "USD",
        "date": "2024-01-15"
      },
      {
        "id": "txn_ledger_777",
        "source_name": "Main Ledger",
        "amount": 15250.0,
        "currency": "USD",
        "date": "2024-01-14"
      }
    ],
    "variance": {
      "amount_diff": 250.0,
      "amount_variance_percent": 1.67,
      "date_diff_days": 1
    },
    "requires_approval": true,
    "approval_threshold": 10000.0
  }
}
Eventos de correspondência forçada são comumente usados para acionar fluxos de aprovação quando a variação excede os limites da empresa.

Matchunmatched

Disparado quando uma correspondência previamente confirmada é revertida.
{
  "id": "evt_unmatch_001",
  "type": "match.unmatched",
  "timestamp": "2024-01-20T15:45:00Z",
  "data": {
    "match_id": "match_001",
    "unmatched_by": "user_456",
    "reason": "Incorrect match - transactions belong to different invoices",
    "notes": "Bank txn is for Invoice #1234, ledger txn is for Invoice #5678",
    "original_match": {
      "confirmed_at": "2024-01-15T10:00:00Z",
      "confirmed_by": "system",
      "confidence": 85,
      "rule_name": "Tolerance Match"
    },
    "transactions": [
      {
        "id": "txn_bank_001",
        "source_name": "Chase Bank",
        "amount": 1000.0,
        "currency": "USD"
      },
      {
        "id": "txn_ledger_001",
        "source_name": "Main Ledger",
        "amount": 1005.0,
        "currency": "USD"
      }
    ],
    "action": {
      "exceptions_created": [
        "exc_new_001",
        "exc_new_002"
      ],
      "status": "Both transactions returned to unmatched pool"
    }
  }
}
Desfazer uma correspondência confirmada cria novas exceções para ambas as transações e dispara uma entrada completa no log de auditoria.

Matchruncompleted

Disparado quando uma execução de correspondência automática ou manual é concluída.
{
  "id": "evt_run_001",
  "type": "match_run.completed",
  "timestamp": "2024-01-20T06:05:23Z",
  "data": {
    "run_id": "run_001",
    "context_id": "ctx_abc123",
    "context_name": "Daily Bank Reconciliation",
    "trigger": "SCHEDULED",
    "started_at": "2024-01-20T06:00:00Z",
    "completed_at": "2024-01-20T06:05:23Z",
    "duration_seconds": 323,
    "statistics": {
      "transactions_processed": 1250,
      "matches_found": 1180,
      "matches_confirmed": 1120,
      "matches_pending_review": 60,
      "exceptions_created": 70,
      "by_confidence": {
        "high_90_100": 1120,
        "medium_60_89": 60,
        "low_0_59": 0
      }
    },
    "performance": {
      "transactions_per_second": 3.87,
      "avg_rule_evaluation_ms": 12.5
    }
  }
}

Slawarning / slabreach

Disparado quando os limites de SLA são atingidos.
{
  "id": "evt_sla_001",
  "type": "exception.sla_warning",
  "timestamp": "2024-01-20T18:30:00Z",
  "data": {
    "exception_id": "exc_001",
    "severity": "HIGH",
    "sla": {
      "due_at": "2024-01-21T10:30:00Z",
      "hours_remaining": 16,
      "percent_remaining": 25
    },
    "assigned_to": "user_123",
    "escalation_path": [
      "user_manager",
      "user_director"
    ]
  }
}

Segurança de webhooks


Verificação de assinatura

Todas as entregas de webhook incluem um cabeçalho de assinatura para verificação:
X-Matcher-Signature: sha256=abc123...
X-Matcher-Timestamp: 1705758600
Processo de verificação:
  1. Concatene timestamp e body: {timestamp}.{body}
  2. Calcule HMAC-SHA256 usando o secret do webhook
  3. Compare com o cabeçalho de assinatura
Exemplo (Node.js):
const crypto = require('crypto');

function verifyWebhook(payload, signature, timestamp, secret) {
 const signedPayload = `${timestamp}.${payload}`;
 const expectedSignature = crypto
 .createHmac('sha256', secret)
 .update(signedPayload)
 .digest('hex');

 return `sha256=${expectedSignature}` === signature;
}
Exemplo (Python):
import hmac
import hashlib

def verify_webhook(payload, signature, timestamp, secret):
 signed_payload = f"{timestamp}.{payload}"
 expected = hmac.new(
 secret.encode(),
 signed_payload.encode(),
 hashlib.sha256
 ).hexdigest()
 return f"sha256={expected}" == signature

Lista de permissão de IP

O Matcher envia webhooks a partir de faixas de IP específicas:
52.1.2.0/24
52.1.3.0/24
Configure seu firewall para permitir essas faixas.

Requisitos de TLS

  • Mínimo TLS 1.2
  • Certificado SSL válido obrigatório
  • Certificados autoassinados não são suportados em produção

Lógica de retry


Entregas de webhook com falha são retentadas com backoff exponencial.

Política de retry padrão

TentativaAtrasoEspera total
1Imediato0s
25 segundos5s
330 segundos35s
42 minutos2m 35s
510 minutos12m 35s
61 hora1h 12m 35s

Configuração de retry personalizada

{
  "retry": {
    "max_attempts": 5,
    "initial_delay_seconds": 10,
    "max_delay_seconds": 3600,
    "backoff_multiplier": 2
  }
}

Condições de retry

Retries ocorrem para:
  • Respostas HTTP 5xx
  • Timeouts de conexão
  • Falhas de resolução DNS
Sem retry para:
  • Respostas HTTP 4xx (exceto 429)
  • Certificados SSL inválidos
  • Webhook desabilitado

Melhores práticas


Sempre verifique a assinatura HMAC antes de processar payloads de webhook. Isso previne requisições falsificadas.
Retorne uma resposta 2xx dentro de 5 segundos. Processe o evento de forma assíncrona se necessário.
Eventos podem ser entregues mais de uma vez. Use o ID do evento para deduplicação.
Configure alertas para taxas de falha de webhook. Investigue falhas persistentes prontamente.
Inscreva-se apenas nos eventos que você precisa. A filtragem reduz ruído e carga de processamento.
Use o endpoint de teste para verificar se seu handler de webhook funciona corretamente antes de habilitar em produção.

Próximos passos