Skip to content

Conciliação Bancária Automática

Documentação técnica do engine de conciliação que cruza confirmações do gateway com os pagamentos registrados no sistema.

Como Funciona (MVP)

Webhook do gateway ativo

  BankTransaction criada (status: UNMATCHED)

  ReconcilePaymentJob (Hangfire)

  Motor de Matching
   ├─ Regra 1: Gateway ID → MATCHED (100%)
   ├─ Regra 2: Valor exato + ≤3d → MATCHED (95%)
   ├─ Regra 3: Valor exato + ≤7d → MATCHED, flag revisar (80%)
   └─ Regra 4: Valor ±2% + ≤3d → DIVERGENT (60%)

  UNMATCHED / DIVERGENT → Fila de revisão manual

Fontes de Dados Bancários

Confirmação Automática via Gateway (MVP)

Quando o gateway ativo do tenant envia a confirmação de pagamento, o sistema:

  1. Atualiza a fatura para PAID
  2. Cria uma BankTransaction virtual com o gatewayId
  3. Executa a Regra 1 imediatamente (100% de confiança)

Esse fluxo cobre automaticamente todos os pagamentos processados pelo gateway configurado (PIX, cartão, boleto).

Import de Extrato OFX (Roadmap — pós-MVP)

Versão futura

A importação manual de extratos bancários em formato OFX/OFXXML será disponibilizada em versão pós-MVP. No MVP, a conciliação cobre apenas pagamentos confirmados via gateway.

No futuro, o tenant poderá fazer upload de um arquivo .ofx exportado pelo banco para conciliar pagamentos realizados fora do gateway (dinheiro, transferência direta, etc.).

Open Finance (Roadmap V2)

Conexão direta com a API do banco via certificado digital, eliminando a necessidade de qualquer importação manual.


Motor de Matching

O job ReconcilePaymentJob aplica as regras em ordem decrescente de confiança. A primeira regra que encontrar um match é utilizada.

Regra 1 — Gateway ID (confiança: 100%)

csharp
// A descrição da transação bancária contém o ID do gateway
transaction.Description.Contains(payment.GatewayId)

Aplicada a transações confirmadas pelo gateway ativo. Match definitivo, sem necessidade de revisão.

Regra 2 — Valor exato + data próxima (confiança: 95%)

csharp
transaction.Amount == payment.Amount
&& Math.Abs((transaction.Date - payment.PaidAt).TotalDays) <= 3

Match automático. Comum para transferências bancárias e pagamentos à vista.

Regra 3 — Valor exato + período estendido (confiança: 80%)

csharp
transaction.Amount == payment.Amount
&& Math.Abs((transaction.Date - payment.PaidAt).TotalDays) <= 7

Match automático com flag review_suggested = true. Aparece na fila de revisão pendente, mas não bloqueia o fluxo.

Regra 4 — Valor aproximado (confiança: 60%)

csharp
var diff = Math.Abs(transaction.Amount - payment.Amount) / payment.Amount;
diff <= 0.02
&& Math.Abs((transaction.Date - payment.PaidAt).TotalDays) <= 3

Status DIVERGENT. Revisão manual obrigatória. Comum em cobranças com taxa de conveniência ou IOF.


Revisão Manual

Listar pendentes de revisão

http
GET /bank-transactions?status=UNMATCHED,DIVERGENT&from=2026-05-01&to=2026-05-31

Response 200:
{
  "items": [
    {
      "id": "uuid",
      "date": "2026-05-10",
      "amount": 350.00,
      "description": "PIX RECEBIDO FULANO DE TAL",
      "status": "UNMATCHED",
      "suggestions": [
        {
          "paymentId": "uuid",
          "invoiceNumber": "CLI-2026-00098",
          "patientName": "Maria Silva",
          "amount": 350.00,
          "paidAt": "2026-05-10",
          "confidence": 0.95
        }
      ]
    }
  ],
  "total": 14
}

Conciliar manualmente

http
POST /bank-transactions/:txId/reconcile

{
  "paymentId": "uuid",
  "notes": "Confirmado via extrato PDF — mesma operação"
}

Ignorar transação

Para transações sem correspondência no sistema (ex: estorno interno):

http
POST /bank-transactions/:txId/ignore

{
  "reason": "Estorno interno processado fora do sistema"
}

Contas Bancárias

Cadastro

http
POST /bank-accounts

{
  "name": "Conta Principal",
  "bankCode": "341",
  "agency": "1234",
  "account": "56789-0",
  "type": "CHECKING"
}

Listagem

http
GET /bank-accounts

Response 200:
[
  {
    "id": "uuid",
    "name": "Conta Principal",
    "bankCode": "341",
    "bankName": "Itaú Unibanco",
    "balance": {
      "reconciled": 48500.00,
      "unreconciled": 2300.00
    }
  }
]

Relatório de Conciliação

http
GET /reports/reconciliation?from=2026-05-01&to=2026-05-31&bankAccountId=uuid

Response 200:
{
  "period": { "from": "2026-05-01", "to": "2026-05-31" },
  "bankAccountName": "Conta Principal",
  "totalTransactions": 312,
  "matched": 298,
  "divergent": 8,
  "unmatched": 6,
  "ignored": 0,
  "matchRate": "95.5%",
  "totalCredited": 48500.00,
  "totalReconciled": 46200.00,
  "pendingAmount": 2300.00,
  "divergentAmount": 180.00
}

Alertas Automáticos

EventoDestinatárioCanal
Transação sem match após 48hAdminE-mail + notificação in-app
Taxa de conciliação abaixo de 90% no períodoOwner + AdminE-mail
Valor divergente acima de R$ 100,00AdminNotificação in-app

Endpoints

MétodoEndpointPapel mínimoDescrição
GET/bank-accountsAdminListar contas bancárias
POST/bank-accountsAdminCadastrar conta bancária
GET/bank-transactionsAdminListar transações
GET/bank-transactions/:idAdminDetalhe da transação
POST/bank-transactions/:id/reconcileAdminConciliar manualmente
POST/bank-transactions/:id/ignoreAdminIgnorar transação
GET/reports/reconciliationAdminRelatório de conciliação

Segurança

  • Apenas roles Admin e Owner têm acesso ao módulo de conciliação
  • Toda ação manual é registrada no audit log com userId, timestamp e motivo
  • externalId garante idempotência no processamento das confirmações do gateway

Ver também

Desenvolvido com ❤️ pela equipe FastGivr.