> ## 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. O uso em produção exige configuração cuidadosa e disciplina operacional.

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

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

***

Uma estrutura de pacotes bem organizada facilita 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.
</Tip>

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

***

O Fees Engine oferece um [endpoint estimate](/pt/reference/products/midaz/v2/estimate-fee-calculation) 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 fornecer pré-visualizações precisas.
* **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>
  O [endpoint calculate](/pt/reference/products/midaz/v2/estimate-fee-calculation) seleciona automaticamente o pacote mais adequado. O endpoint estimate exige um `packageId` específico, dando controle total sobre qual pacote testar.
</Note>

## 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.

<Warning>
  O Fees Engine exige **Midaz v3.x.x** ou posterior. O formato `amount` + `scale` da v2.x.x não é compatível. Atualize o Midaz antes de fazer o deploy do Fees Engine.
</Warning>

## 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.

* **Não dependa da exclusão definitiva** de pacotes de tarifas em produção. Transações históricas podem referenciar pacotes excluídos para fins de conciliação.
* **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](/pt/products/midaz/midaz-environment-variables) 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

***

Antes de atualizar o Fees Engine:

* Consulte a [tabela de compatibilidade de versões](/pt/platform/deploy/midaz-version-compatibility) para confirmar a compatibilidade com a sua versão do Midaz Core.
* Sempre atualize **o Midaz Core primeiro** e depois o Fees Engine.
* 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 os procedimentos de atualização, consulte o [guia de atualização do Helm](/pt/platform/deploy/midaz/midaz-upgrade-guide).

## 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](/pt/products/midaz/security-recommendations) da plataforma, que abrangem:

* Segmentação de rede e arquitetura Zero Trust
* Gestão e rotação de segredos (incluindo `LICENSE_KEY` e 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](/pt/platform/access-manager)
* 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. Deixe o limite superior da última faixa aberto. 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.
</Tip>

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

***

Pacotes de manutenção oferecem suporte a três tipos de alvo com perfis de escala diferentes:

| Tipo de alvo  | Escala             | Caso de uso                                          |
| ------------- | ------------------ | ---------------------------------------------------- |
| `segmentId`   | 100.000+ contas    | Níveis padrão (PF, PJ, premium)                      |
| `portfolioId` | Milhares de contas | Portfólios empresariais (PME, Corporate, Enterprise) |
| `aliases`     | Até 100 contas     | Contas nomeadas específicas                          |

Escolha o tipo de alvo que corresponda à sua escala operacional. Se você perceber que está listando centenas de aliases, migre para um segmento ou 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. Executar novamente para o mesmo período produz os mesmos resultados.
* **Verifique as respostas de erro** para o pacote e o recurso específicos que falharam. Causas comuns: `ledgerId` inválido, API do Midaz inacessível ou pacotes de cobrança desabilitados.
* **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.
