A conciliação assistida aproxima um débito bancário observado de um título a pagar do ERP, mostra a evidência e registra a decisão de um revisor autorizado. O resultado é um ajuste analítico na reserva do diagnóstico, guardado à parte do título.
A Malvo não dá baixa no ERP. Uma confirmação não altera o título, não grava nada no sistema do parceiro e não aumenta o caixa observado. Os eventos payment_match.* informam o estado na Malvo e não ordenam baixa. Se você registrar a baixa no ERP a partir de payment_match.confirmed, faça isso por decisão própria e devolva o payment_match_id na liquidação da próxima carga (veja payment_match_id).

Chaves do módulo

As rotas existem com CONSOLIDATED_INTELLIGENCE_ENABLED e OBLIGATION_IMPORTS_ENABLED ligadas, junto com as de títulos. Todas nascem desligadas.

Candidatos

Um débito é candidato quando, ao mesmo tempo:
  • é de conta BANK de uma fonte vinculada ao perfil, com consentimento AUTHORISED e a permissão ACCOUNTS_TRANSACTIONS_READ;
  • tem, na API Contas, creditDebitType = DEBITO e completedAuthorisedPaymentType = TRANSACAO_EFETIVADA. LANCAMENTO_FUTURO e TRANSACAO_PROCESSANDO ficam de fora;
  • está em BRL, não é transferência entre contas próprias, não é estorno nem foi estornado e não está em revisão de representação.
O título candidato está ativo na fotografia, é payable, em BRL, open ou partially_settled, com valor em aberto maior que zero. A janela é civil em America/Sao_Paulo, do vencimento menos 7 dias ao vencimento mais 30 dias, inclusive. Ela não desloca o vencimento.

Evidência e estado inicial

Sem valor exato e sem documento ou referência, não há sugestão: nome, valor ou data isolados não comprovam pagamento. Quando um débito ou um título tem mais de um candidato e o par não é o único melhor dos dois lados, todos ficam review_required (ambiguous_candidates), com as alternativas em alternatives. Não há percentual de probabilidade. Ausência de candidato não prova que o título está em aberto na realidade. divergences lista o que enfraquece a evidência: counterparty_missing e amount_exceeds_outstanding.

Estados

O payment_match_id é estável: a mesma sugestão (mesmo débito e mesmo título) mantém o id e ganha version nova quando a evidência muda. Sugestão que deixa de ser candidata sai da lista (withdrawn: true). Rejeição e reversão guardam uma impressão digital da evidência: o par não volta como sugestão enquanto ela for a mesma. review_reason diz por que a correspondência está em revisão:

Rotas

GET /financial-profiles/{id}/payment-matches?state=&obligation_id=&transaction_id=&include_withdrawn=&page=&pageSize=

Reavalia candidatos e confirmações e lista as correspondências, paginadas. A reavaliação lê só o banco da Malvo: não chama instituição nem dispara sincronização. reserves traz, por título com alocação ativa, o valor em aberto do ERP, o ajuste aplicável e a reserva efetiva. Valor fora da lista responde 400 VALIDATION_ERROR.
Correspondências 200

GET /financial-profiles/{id}/payment-matches/{matchId}

Uma correspondência, com as alocações e o efeito de cada uma na reserva. Correspondência de outro perfil ou aplicação responde 404 NOT_FOUND.
Correspondência confirmada 200

POST /financial-profiles/{id}/payment-matches/{matchId}/confirm

Confirma a correspondência com alocações explícitas.
Confirmar

POST /financial-profiles/{id}/payment-matches/{matchId}/reject

Rejeita uma sugestão com motivo. A rejeição não muda reserva e o par não volta como sugestão sem mudança material de evidência.
Rejeitar

POST /financial-profiles/{id}/payment-matches/{matchId}/reverse

Reverte a confirmação (target: "confirmation", padrão) ou só a absorção (target: "absorption"). Reverter a confirmação desativa as alocações: o débito fica livre de novo e a reserva volta ao valor do ERP. Reverter a absorção devolve a correspondência para revisão (absorption_reversed).
Reverter

Decisões

As três ações exigem:
  • a permissão payment_matches.review da aplicação, desligada por padrão; o dono ou um admin do time concede no console;
  • o header Idempotency-Key (^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$);
  • version (a versão atual da correspondência), actor (até 128 caracteres) e reason (até 500).
allocations, difference_reason e resolution só valem no confirm; target só no reverse. transaction_version e obligation_version_id vêm do GET. A resposta 200 é a correspondência atualizada, no formato do GET. Reenvio com a mesma chave e o mesmo corpo devolve 200 com o estado atual, sem novo efeito.

Alocações

Uma confirmação pode ter várias alocações: parte de um débito, vários débitos para um título ou um débito para vários títulos. Ela precisa incluir o débito ou o título da sugestão.
  • Valor decimal positivo com 2 a 4 casas; par débito-título sem repetição.
  • A soma das alocações ativas de um débito, em todas as correspondências, vai até o valor do débito.
  • A soma das alocações ativas e ainda não absorvidas de um título vai até o valor em aberto do ERP.
  • Débito com sobra depois da confirmação exige difference_reason: juros, multa, desconto ou tarifa não são distribuídos em silêncio.
A confirmação é serializada por perfil. Dois revisores que disputam o mesmo débito são atendidos em série: o segundo recebe 409 e nada é gravado. O mesmo pagamento nunca é reservado duas vezes.

Erros

Nenhuma recusa muda alocação, reserva ou estado.
409 MATCH_VERSION_CONFLICT

Efeito na reserva

Uma sugestão não muda valores. Uma confirmação só reduz a reserva quando o débito já está refletido na posição bancária usada. A posição é o updateDateTime do saldo da API Contas, nunca o horário em que a Malvo recebeu o dado. reserve_effect.position_reference e position_at identificam o saldo usado, para o corte ser verificável. A reserva efetiva do título é o valor em aberto do ERP menos os ajustes aplicados, nunca menor que zero:
reserves com confirmação aplicada

Absorção pela origem

Quando uma carga nova do ERP é ativada, cada título que ganhou versão e tem alocação confirmada ainda não absorvida passa por esta ordem, registrada em absorption_basis:
  1. explicit_reference: alguma liquidação da versão nova traz o payment_match_id. Absorve sem revisão.
  2. inferred_exact (com FINANCIAL_PROFILE_INFERRED_ABSORPTION_ENABLED): uma única correspondência confirmada com uma única alocação, nenhuma em revisão no título, primeira versão nova em até 30 dias da confirmação, valor em aberto reduzido exatamente pelo alocado (ou título settled com aberto anterior igual ao alocado), liquidação nova única com o mesmo valor e settled_at igual ou posterior ao débito, sem mudança de valor original, vencimento, moeda ou contraparte, sem reabertura nem cancelamento, e débito na mesma versão confirmada.
  3. manual_review: qualquer outro caso. A correspondência vai para review_required com o motivo e o ajuste fica suspenso: a reserva volta a ser o valor em aberto do ERP, sem subtrair de novo e sem ficar negativa.
Carga com o título igual não mexe na correspondência. Título que sai da fotografia mantém a alocação (a ausência não prova baixa) e o débito continua consumido. As cargas de exemplo estão no contrato v1.

Revisão depois da absorção

Uma correspondência confirmada que foi para revisão aceita confirm com resolution:
  • absorbed: a baixa do ERP é esse pagamento; as alocações ficam com absorption_basis: "manual_review";
  • keep: o pagamento ainda não está no ERP; as alocações seguem ativas, desde que não passem do novo valor em aberto.
O corpo repete as alocações confirmadas (mesmos pares e valores) com as versões atuais.
Resolver revisão

Estorno, correção e revogação

A cada consulta, as confirmações são conferidas contra a transação atual. Débito que sumiu, deixou de ser efetivado ou mudou de versão vai para review_required e o ajuste fica suspenso. A revogação da fonte bancária retira as sugestões e manda as confirmações para revisão (source_revoked). O histórico de decisões é imutável e continua consultável.

Eventos

Cada transição publica um evento payment_match.* (veja Eventos financeiros). O evento traz ids, estado, versão e motivo, sem valores. Busque os valores na API.

Retenção

Sugestões não confirmadas e rejeições ficam 90 dias desde a última mudança. Confirmações ficam com o perfil. A trilha de auditoria (payment_match.confirmed, rejected, reversed) não guarda valores, e nenhum valor vai para log.

Base normativa

  • API Contas do Open Finance Brasil 2.5.1 (api_accounts_-_open_finance_brasil/2.5.1.yaml, lido em 12/10/2026): creditDebitType (DEBITO), completedAuthorisedPaymentType (TRANSACAO_EFETIVADA, LANCAMENTO_FUTURO, TRANSACAO_PROCESSANDO), transactionAmount com padrão ^\d{1,15}\.\d{2,4}$ e AccountBalancesData.updateDateTime como posição.
  • Contrato obligations.v1: liquidações com payment_match_id e decimais textuais.
  • IN BCB nº 615/2025, art. 1º e 3º, e Manual de APIs v7.0, seção 5.2, item V: a conciliação não faz chamada a instituição.
  • Lei nº 13.709/2018 (LGPD), art. 6º, 7º, 15, 16 e 18, e a política de retenção da Malvo aprovada em 10/10/2026.
  • PRD v1.3, seções 10 e 14 (FR-033; AC-036, AC-039 a AC-047 e AC-055 a AC-057). A janela e os níveis de evidência são o ponto de partida do PRD e serão calibrados com os parceiros.