Blog

Cenário: a conciliação que não fechava por um centavo.

Cenário construído para estudo, não o incidente de uma empresa específica. A forma se repete o suficiente pra valer como exercício, e a causa raiz é sempre mais interessante que o sintoma.

O sintoma

O relatório diário de conciliação acusa diferença de R$ 0,01 entre o total do gateway e o total interno. Todo dia útil. Às vezes um centavo, às vezes três.

Alguém do financeiro fazia o ajuste manual e seguia. Virou rotina, e depois de um tempo ninguém mais achava estranho.

Catorze meses assim.

Por que ninguém investigou

Três razões que se combinam, e todas são humanas.

O valor é irrelevante. Ninguém pede prioridade pra um centavo.

Existe um jeito de contornar. O ajuste manual leva dois minutos, e o problema fica resolvido todo dia.

E o alerta perdeu significado. Como ele disparava sempre, virou ruído. Um alerta que dispara todo dia deixa de ser alerta e vira parte da paisagem.

Esse terceiro ponto é o que realmente custa. Não é o centavo: é que o mecanismo criado pra detectar problema financeiro tinha sido desligado na prática.

A investigação

Quando alguém finalmente olha, a hipótese óbvia é arredondamento em split de pagamento. Dividir R$ 100 entre três vendedores gera 33,33 três vezes e sobra um centavo.

Só que a diferença aparecia também em dias sem nenhum pagamento dividido.

O que se descobre olhando as transações uma a uma: a diferença aparecia sempre em transações com estorno parcial.

O fluxo era este. O cliente compra por R$ 149,90, com taxa de 3,49%, que dá R$ 5,23 depois de arredondar. Líquido de R$ 144,67.

O cliente pede estorno de metade. O sistema calculava a taxa proporcional sobre o valor estornado: 3,49% de R$ 74,95, arredondado, R$ 2,62.

E o gateway calculava diferente: ele estornava a diferença entre a taxa total e a taxa da parte que permaneceu. R$ 5,23 menos R$ 2,61, que dá R$ 2,62 em alguns casos e R$ 2,61 em outros, dependendo de qual metade caía com o centavo.

Duas fórmulas defensáveis. Resultados que divergem em um centavo, de forma imprevisível.

O erro estrutural

O bug não é a fórmula. É que existiam duas fórmulas.

O sistema recalculava a taxa em vez de usar o valor que o gateway informava. Isso significa que ele estava mantendo uma opinião própria sobre um número que não era dele.

Toda vez que dois sistemas calculam independentemente o mesmo valor a partir de regras parecidas, eles vão divergir. Não é questão de se: é questão de quando e de quanto.

A regra que evita a categoria inteira: quem é dono do número informa, quem consome registra. Nunca recalcula.

A correção

Três mudanças.

Usar o valor informado. O campo de taxa passou a vir do payload do gateway, gravado como recebido. O cálculo interno continuou existindo, e virou estimativa antes da confirmação, claramente marcada como tal.

Separar estimado de realizado.

alter table payment
  add column fee_estimated_minor bigint,
  add column fee_actual_minor bigint;

Duas colunas, e o relatório usa a segunda. A primeira serve pra mostrar ao vendedor antes da liquidação, e a diferença entre elas virou uma métrica útil por si só.

Uma conta de ajuste no ledger. Diferenças residuais legítimas passaram a ter destino explícito, com lançamento próprio, em vez de sumirem. Como escrevi em ledger imutável, o resto nunca desaparece por arredondamento: ele vai pra algum lugar nomeado.

O que se descobre no meio

Ao investigar os catorze meses, aparece o que sempre aparece: outra coisa.

Duas transações com divergência de valor cheio, não de centavo. Cobranças que existiam no gateway e não no sistema, de clientes que pagaram e nunca receberam o produto.

Elas estavam escondidas no meio do ruído. Como o alerta disparava todo dia por causa do centavo, ninguém olhava a lista de divergências, e as duas grandes tinham entrado na mesma lista.

Esse é o custo real do alerta que vira paisagem. Não é o centavo: é o que ele estava escondendo.

O que fica

Alerta que dispara sempre não é alerta. Se algo dispara todo dia e a resposta padrão é ignorar, ou o limiar está errado ou existe um problema real não resolvido. Não existe terceira opção.

Divergência pequena e persistente é sinal de premissa divergente, não de erro de cálculo. Erro de cálculo dá diferença grande e óbvia. Premissa divergente dá diferença pequena e teimosa.

E “a gente ajusta na mão” é uma decisão. Ela precisa ter dono e prazo, senão vira o processo permanente que ninguém lembra por que existe.

Sobre o desenho de uma conciliação que separa ruído de sinal, escrevi em conciliação financeira automatizada.

← Voltar pro blog