> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Boas práticas do Fees Engine

> Siga as boas práticas do Fees Engine para nomear pacotes, definir prioridades de tarifas, segmentar clientes e rodar configurações de produção com auditabilidade completa.

O Fees Engine controla como você calcula, aplica e acompanha as tarifas.

Essas recomendações complementam a [visão geral do Fees Engine](https://docs.lerian.studio/pt/products/midaz/fees/fees-engine-overview.md) e o guia de [mecânica de cálculo](https://docs.lerian.studio/pt/products/midaz/fees/fee-engine-calculation.md).

## 1. Projete pacotes de tarifas com nomenclatura e segmentação claras

***

Uma estrutura de pacotes bem organizada torna mais fácil manter, depurar e auditar a configuração de tarifas ao longo do tempo.

* **Use nomes descritivos** que reflitam o contexto de negócio (por exemplo, "pix-transfer-standard", "wire-premium-segment").
* **Segmente por produto e grupo de clientes** usando `segmentId`. Isso permite aplicar regras de tarifas diferentes para diferentes níveis de clientes sem criar pacotes conflitantes.
* **Mantenha os pacotes focados**. Um pacote que tenta cobrir cenários demais fica difícil de testar e manter. Prefira vários pacotes focados a um único pacote que faz tudo.
* **Documente a estrutura de pacotes** internamente. À medida que o número de pacotes cresce, uma referência clara de onde cada pacote se aplica evita configurações incorretas.

## 2. Defina as prioridades de tarifas com cuidado

***

Quando um pacote contém várias tarifas, o campo `priority` determina a ordem de execução. Um erro aqui pode gerar cálculos incorretos.

* **A prioridade 1 deve sempre usar `referenceAmount: originalAmount`**. O engine aplica essa regra.
* **Tarifas com `isDeductibleFrom: true` também devem usar `referenceAmount: originalAmount`**. Tarifas dedutíveis sempre se aplicam ao valor total da transação.
* **A prioridade deve ser única dentro de um pacote**. O engine rejeita prioridades duplicadas.
* **Pense nas dependências entre tarifas**. Se uma tarifa ajusta o valor da transação e outra tarifa deve ser calculada sobre o valor ajustado, use `referenceAmount: afterFeesAmount` com um número de prioridade maior. Se a segunda tarifa deve referenciar o valor original, use `originalAmount`.

> [!TIP]
>
> Em caso de dúvida, comece com uma configuração simples (uma ou duas tarifas por pacote) e valide os resultados usando o endpoint estimate antes de adicionar complexidade.

## 3. Sempre faça a estimativa antes de aplicar tarifas em produção

***

O Fees Engine oferece um [endpoint estimate](https://docs.lerian.studio/pt/reference/products/midaz/v2/estimate-fee-calculation.md) que permite pré-visualizar os cálculos de tarifas sem gravar nada no ledger.

Use a estimativa para:

* **Validar novos pacotes** antes de ativá-los. Confirme que os valores calculados correspondem aos resultados esperados em diferentes valores de transação.
* **Testar casos extremos**: transações com valor zero, valores limite nos limiares de `minimumAmount` e `maximumAmount`, e contas isentas.
* **Pré-visualizar tarifas para os usuários**. Se o seu produto mostra as tarifas antes da confirmação, use o endpoint estimate para pré-visualizar a tarifa de um pacote. Uma estimativa não lê as atribuições de planos de tarifas, então ela não pré-visualiza a tarifa de um plano de tarifas.
* **Depurar resultados inesperados**. Se uma tarifa calculada não corresponder ao esperado, faça a estimativa da mesma transação com um `packageId` específico para isolar o problema.

> [!NOTE]
>
> Uma transação v2 seleciona automaticamente o pacote correspondente. O endpoint estimate exige um `packageId` específico, então você escolhe qual pacote testar.

## 4. Gerencie as isenções explicitamente

***

O Fees Engine oferece suporte a dois tipos de isenção: por **faixa de valor da transação** e por **conta**.

* **Faixas de valor** (`minimumAmount`, `maximumAmount`): definem a janela de valor da transação na qual as tarifas se aplicam. Transações fora dessa faixa ficam isentas. Use isso para limiares promocionais ou precificação por faixas.
* **Contas isentas** (`waivedAccounts`): contas específicas isentas de tarifas dentro de um pacote. Use isso para contas internas, contas de funcionários ou acordos de parceria.

Boas práticas para isenções:

* **Mantenha as listas de contas isentas curtas e revisadas**. Listas grandes ficam difíceis de auditar. Revise periodicamente quais contas estão isentas e por quê.
* **Documente o motivo de negócio** de cada isenção nos seus registros internos.
* **Teste os limites das isenções**. Se a sua faixa é R$ 0–300, garanta que as transações de exatamente R$ 300 e R\$ 301 se comportem como esperado.

## 5. Use valores numéricos corretos

***

Expresse todos os valores financeiros no Fees Engine como **strings**, usando o tipo `numeric`. Isso evita os erros de precisão de ponto flutuante comuns na aritmética decimal.

```json theme={null}
"value": "12.50"
```

* Sempre envie os valores como strings, mesmo números inteiros (por exemplo, `"100"` e não `100`).
* Nunca use tipos de ponto flutuante para cálculos monetários na camada de integração.
* O engine ajusta automaticamente as divisões de tarifas com dízimas periódicas (por exemplo, R\$ 10 divididos entre 3 contas) para manter os totais do ledger exatos.

## 6. Use exclusão lógica para auditabilidade

***

Quando você exclui um pacote de tarifas, o Fees Engine o marca com um timestamp `deletedAt` em vez de removê-lo do banco de dados. Isso preserva a trilha de auditoria das transações históricas que referenciaram esse pacote.

* **Revise periodicamente** os pacotes excluídos se o banco de dados crescer significativamente. Estratégias de arquivamento ajudam a gerenciar o armazenamento sem perder a capacidade de auditoria.

## 7. Monitore o processamento de tarifas em produção

***

As tarifas são processadas dentro do processo do ledger do Midaz. Use a configuração compartilhada de OpenTelemetry do ledger e os endpoints de integridade para observar o processamento de tarifas. Consulte [Variáveis de ambiente](https://docs.lerian.studio/pt/products/midaz/midaz-environment-variables.md) para a configuração aceita.

Em produção:

* **Monitore os endpoints de integridade do ledger** e seus traces e logs.
* **Configure alertas** para latência alta sustentada ou erros nos cálculos de tarifas.
* **Monitore o deploy configurado do MongoDB**: uso do connection pool, espaço em disco e integridade da replicação.
* **Revise o uso de recursos dos pods do ledger** em relação aos padrões de tráfego e ao comportamento de autoscaling.

## 8. Mantenha as versões compatíveis

***

O Fees roda dentro do processo do ledger do Midaz, então ele é atualizado junto com o Midaz e tem a mesma versão. Antes de atualizar o Midaz:

* Consulte a [tabela de compatibilidade de versões](https://docs.lerian.studio/pt/products/midaz/midaz-version-compatibility.md) para os componentes que você roda com o Midaz.
* Faça backup dos dados do MongoDB e dos valores do Helm antes de qualquer atualização importante.
* Teste a atualização em um ambiente de staging antes de aplicá-la em produção.

Para as notas de atualização de cada versão do chart, consulte as [notas de atualização do chart do Midaz](https://github.com/LerianStudio/helm/tree/main/charts/midaz/docs).

## 9. Revise as recomendações de segurança

***

O Fees Engine processa dados financeiros e se integra às operações do ledger do Midaz. Confirme que o seu deploy segue as [Recomendações de segurança](https://docs.lerian.studio/pt/products/midaz/security-recommendations.md) da plataforma, que abrangem:

* Segmentação de rede e arquitetura Zero Trust
* Gestão e rotação de segredos (incluindo credenciais de banco de dados)
* Aplicação de TLS 1.2 ou superior para todas as comunicações
* Configuração de RBAC via [Access Manager](https://docs.lerian.studio/pt/platform/access-manager.md)
* Gestão de patches e varredura de vulnerabilidades

## 10. Projete pacotes de cobrança com escopo claro

***

Cada pacote de cobrança deve representar uma cobrança única e bem definida. Evite agrupar precificações não relacionadas em um único pacote.

* **Separe pacotes por rota de transação**. Um pacote para cobrança de Pix e um pacote para cobrança de boleto são mais claros do que um único pacote que tenta lidar com os dois.
* **Use rótulos descritivos** que incluam o tipo de cobrança e o alvo: "Cobrança Mensal de Envio Pix (Nível Padrão)" é melhor do que "Pacote de Cobrança 1".
* **Um único tipo de `accountTarget` por pacote de manutenção**. Não é possível combinar `segmentId`, `portfolioId` e `aliases` no mesmo pacote. Se você precisar de alvos diferentes, crie pacotes separados. Uma única chamada a `/billing/calculate` avalia todos os pacotes ativos.

## 11. Escreva os termos comerciais com base no volume por rota

***

O cálculo de volume conta as transações por rota de transação em todo o ledger. A cota gratuita, as faixas e as faixas de desconto se aplicam a esse total no nível da rota.

* **Defina os limiares como volume de rota.** "As primeiras 100 transações na rota `pix-send` são gratuitas" mapeia diretamente para um pacote. Escreva o contrato nos mesmos termos em que o engine cobra.
* **Divida as rotas para dividir as contagens.** Um pacote por rota de transação mantém cada fluxo com sua própria cota, faixas e descontos.

## 12. Planeje as cotas gratuitas e as faixas de desconto com cuidado

***

O Fees Engine avalia as cotas gratuitas e os descontos em uma ordem específica:

1. O engine subtrai a cota gratuita da contagem total para obter a contagem faturável.
2. O engine precifica a contagem faturável. Para pacotes com faixas, ele cobra cada unidade faturável pela taxa da única faixa correspondente (precificação por volume, não progressiva).
3. O engine aplica uma faixa de desconto ao valor bruto, escolhida com base na contagem **total** (antes de a cota gratuita ser subtraída).

Considerações de design:

* **As cotas gratuitas são reiniciadas a cada período de cobrança**. Defina o valor com base no seu acordo comercial por período (mensal, semanal ou diário), não vitalício.
* **As faixas são intervalos de volume, não fatias**. Uma contagem faturável de 1.750 dentro de uma faixa de 501–2.000 precifica todas as 1.750 unidades pela taxa dessa faixa. Cruzar o limite de um intervalo muda a taxa para todo o volume, então os limites das faixas podem alterar a cobrança de forma abrupta.
* **Cubra toda contagem faturável positiva.** Se a contagem faturável for positiva e nenhuma faixa contiver esse valor, o cálculo falha para esse pacote. Com duas ou mais faixas, a API rejeita lacunas e exige um limite superior aberto na última faixa. Comece a primeira faixa em 1 (uma contagem faturável igual a zero gera um valor zero e um payload vazio, sem consulta a nenhuma faixa).
* **As faixas de desconto são limiares cumulativos**, não intervalos, e apenas uma se aplica: o maior `minQuantity` que a contagem total alcança. Se você definir descontos em 200 e 400 transações, um cliente com 500 transações recebe o desconto de 400+, não os dois.
* **Preste atenção às duas contagens diferentes.** A precificação usa a contagem faturável (depois da cota gratuita); o desconto usa a contagem total (antes dela).

> [!TIP]
>
> Use cálculos de teste com contagens de transações conhecidas para validar a configuração de faixas e descontos antes de habilitar o pacote em produção.

## 13. Dimensione os alvos de contas de manutenção adequadamente

***

Pacotes de manutenção oferecem suporte a três tipos de alvo:

| Tipo de alvo | Caso de uso |
| - | - |
| `segmentId` | Níveis padrão (PF, PJ, premium) |
| `portfolioId` | Portfólios empresariais (PME, Corporate, Enterprise) |
| `aliases` | Contas nomeadas específicas, no máximo 100 |

Para mais de 100 contas, use um segmento ou um portfólio no Midaz.

## 14. Trate falhas de cobrança com nova execução

***

O cálculo de cobrança segue uma política tudo ou nada. Se algum pacote falhar, o engine não retorna nenhum resultado.

* **Implemente lógica de nova tentativa** no seu orquestrador. O cálculo é stateless, então uma nova tentativa é segura. Uma nova tentativa reflete o ledger no momento em que roda.
* **Verifique as respostas de erro** para o pacote que falhou. A mensagem mostra o ID e o rótulo dele. Uma causa comum é um pacote de volume cujas faixas não cobrem a contagem faturável.
* **Separe os cálculos de volume e de manutenção** se um tipo tiver sucesso de forma consistente enquanto o outro falha. Chame `/billing/calculate` com `"type": "volume"` e `"type": "maintenance"` de forma independente para isolar falhas.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.