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

# Mejores prácticas

> Aplica mejores prácticas de configuración, operación e integración para desplegar y usar el Fees Engine en producción con reglas trazables y escalables.

Fees Engine controla cómo calculas, aplicas y rastreas las tarifas. El uso en producción exige configuración cuidadosa y disciplina operacional, porque la precisión y la auditabilidad no son negociables.

Estas recomendaciones complementan el [resumen de Fees Engine](/es/midaz/fees/fees-engine-overview) y la guía de [mecánicas de cálculo](/es/midaz/fees/fee-engine-calculation).

## 1. Diseña paquetes de tarifas con nombres claros y segmentación

***

Los paquetes de tarifas son la base de tu lógica de tarifas. Una estructura de paquetes bien organizada facilita el mantenimiento, la depuración y la auditoría de tu configuración de tarifas a lo largo del tiempo.

* **Usa nombres descriptivos** que reflejen el contexto de negocio (ej., "pix-transfer-standard", "wire-premium-segment").
* **Segmenta por producto y grupo de clientes** usando `segmentId`. Esto te permite aplicar diferentes reglas de tarifas a diferentes niveles de clientes sin crear paquetes en conflicto.
* **Mantén los paquetes enfocados**. Un paquete que intenta cubrir demasiados escenarios se vuelve difícil de probar y mantener. Prefiere múltiples paquetes enfocados sobre uno que lo haga todo.
* **Documenta la estructura de tus paquetes** internamente. A medida que la cantidad de paquetes crece, una referencia clara de qué paquete aplica dónde previene errores de configuración.

## 2. Configura las prioridades de tarifas con cuidado

***

Cuando un paquete contiene múltiples tarifas, el campo `priority` determina el orden de ejecución. Equivocarse en esto puede producir cálculos incorrectos.

* **La prioridad 1 siempre debe usar `referenceAmount: originalAmount`**. El motor lo aplica.
* **Las tarifas con `isDeductibleFrom: true` también deben usar `referenceAmount: originalAmount`**. Las tarifas deducibles se aplican entonces siempre al valor total de la transacción.
* **La prioridad debe ser única dentro de un paquete**. El motor rechaza las prioridades duplicadas.
* **Piensa en las dependencias de tarifas**. Si una tarifa ajusta el valor de la transacción y otra tarifa debe calcularse sobre el valor ajustado, usa `referenceAmount: afterFeesAmount` con un número de prioridad mayor. Si la segunda tarifa debe referir al valor original, usa `originalAmount`.

<Tip>
  En caso de duda, comienza con una configuración simple (una o dos tarifas por paquete) y valida los resultados usando el endpoint de estimación antes de agregar complejidad.
</Tip>

## 3. Siempre estima antes de aplicar tarifas en producción

***

Fees Engine proporciona un [endpoint de estimación](/es/reference/midaz/plugins/fees-engine/simulate-fees) que te permite previsualizar los cálculos de tarifas sin escribir nada en el ledger.

Usa la estimación para:

* **Validar nuevos paquetes** antes de activarlos. Confirma que los valores calculados coincidan con tus resultados esperados en diferentes montos de transacción.
* **Probar casos límite**: transacciones de monto cero, valores límite en los umbrales de `minimumAmount` y `maximumAmount`, y cuentas exentas.
* **Previsualizar tarifas para usuarios**. Si tu producto muestra tarifas antes de la confirmación, usa el endpoint de estimación para proporcionar previsualizaciones precisas.
* **Depurar resultados inesperados**. Si una tarifa calculada no coincide con las expectativas, estima la misma transacción con un `packageId` específico para aislar el problema.

<Note>
  El [endpoint de cálculo](/es/reference/midaz/plugins/fees-engine/calculate-fees) selecciona automáticamente el paquete que mejor coincide. El endpoint de estimación requiere un `packageId` específico, dándote control total sobre qué paquete probar.
</Note>

## 4. Gestiona las exenciones de forma explícita

***

Fees Engine soporta dos tipos de exenciones: por **rango de monto de transacción** y por **cuenta**.

* **Rangos de monto** (`minimumAmount`, `maximumAmount`): Definen la ventana de valor de transacción en la que aplican las tarifas. Las transacciones fuera de este rango están exentas. Usa esto para umbrales promocionales o precios escalonados.
* **Cuentas exentas** (`waivedAccounts`): Cuentas específicas exentas de tarifas dentro de un paquete. Usa esto para cuentas internas, cuentas de empleados o acuerdos de asociación.

Mejores prácticas para exenciones:

* **Mantén las listas de cuentas exentas cortas y revisadas**. Las listas grandes se vuelven difíciles de auditar. Revisa periódicamente qué cuentas están exentas y por qué.
* **Documenta la razón de negocio** de cada exención en tus registros internos.
* **Prueba los límites de exención**. Si tu rango es R$ 0–300, asegúrate de que las transacciones de exactamente R$ 300 y R\$ 301 se comporten como se espera.

## 5. Habilita y ajusta el caché para rendimiento

***

Fees Engine almacena en caché los paquetes de tarifas en memoria para reducir las consultas a la base de datos durante alto tráfico.

Configura el caché mediante variables de entorno:

```yaml theme={null}
fees:
  configmap:
    PACKAGE_CACHE_ENABLED: "true"
    PACKAGE_CACHE_TTL_SECONDS: "600"
```

* **`PACKAGE_CACHE_ENABLED`** (predeterminado: `true`): Habilita o deshabilita el caché de paquetes.
* **`PACKAGE_CACHE_TTL_SECONDS`** (predeterminado: `180`): Tiempo de vida en segundos antes de que el motor actualice los paquetes en caché desde la base de datos.

Recomendaciones:

* **Mantén el caché habilitado en producción**. Reduce significativamente la latencia para procesamiento de transacciones de alto volumen.
* **Ajusta el TTL según tu frecuencia de cambios**. Si actualizas paquetes frecuentemente, usa un TTL más corto (ej., 60–120 segundos). Si los paquetes son estables, el valor predeterminado de 180 segundos es apropiado.
* **Ten en cuenta el retraso del caché**. Después de actualizar un paquete, el cambio puede tardar hasta el TTL configurado en propagarse. Si necesitas efecto inmediato, reinicia el servicio o reduce temporalmente el TTL.

## 6. Usa valores numéricos correctos

***

Expresa todos los valores financieros en Fees Engine como **strings** usando el tipo `numeric`. Esto previene errores de precisión de punto flotante que son comunes con aritmética decimal.

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

* Siempre envía valores como strings, incluso números enteros (ej., `"100"` no `100`).
* Nunca uses tipos de punto flotante para cálculos monetarios en tu capa de integración.
* Ten en cuenta que el motor ajusta automáticamente las divisiones de tarifas con decimales periódicos (ej., R\$ 10 dividido entre 3 cuentas) para mantener los totales del Ledger exactos.

<Warning>
  Fees Engine requiere **Midaz v3.x.x** o posterior. El formato `amount` + `scale` de v2.x.x no es compatible. Actualiza Midaz antes de desplegar Fees Engine.
</Warning>

## 7. Usa soft delete para auditabilidad

***

Cuando eliminas un paquete de tarifas, Fees Engine lo marca con un timestamp `deletedAt` en lugar de eliminarlo de la base de datos. Esto preserva la pista de auditoría para transacciones históricas que referenciaron ese paquete.

* **No dependas del hard delete** para paquetes de tarifas en producción. Las transacciones históricas pueden referenciar paquetes eliminados para conciliación.
* **Revisa periódicamente** los paquetes eliminados si tu base de datos crece significativamente. Las estrategias de archivado pueden ayudar a gestionar el almacenamiento sin perder capacidad de auditoría.

## 8. Monitorea Fees Engine en producción

***

Fees Engine soporta OpenTelemetry para trazas y métricas. Habilítalo para obtener visibilidad del rendimiento y comportamiento de los cálculos de tarifas.

```yaml theme={null}
fees:
  configmap:
    ENABLE_TELEMETRY: "true"
    OTEL_RESOURCE_SERVICE_NAME: "plugin-fees"
```

En producción:

* **Monitorea los endpoints de salud**. Fees Engine expone `/health` para verificaciones de readiness y liveness (puerto predeterminado: 4002).
* **Configura alertas** para latencia alta sostenida en cálculos de tarifas, lo que puede indicar contención en la base de datos o mala configuración del caché.
* **Monitorea MongoDB**: uso del pool de conexiones, espacio en disco y salud de replicación. El valor predeterminado de `MONGO_MAX_POOL_SIZE` es 100.
* **Revisa el uso de recursos de los pods** según tus patrones de tráfico y comportamiento de autoescalado.

## 9. Mantén las versiones compatibles

***

Antes de actualizar Fees Engine:

* Consulta la [tabla de compatibilidad de versiones](/es/platform/plugins/midaz-version-compatibility) para confirmar compatibilidad con tu versión de Midaz Core.
* Siempre actualiza **Midaz Core primero**, luego Fees Engine.
* Haz respaldo de tus datos de MongoDB y valores de Helm antes de cualquier actualización mayor.
* Prueba la actualización en un entorno de staging antes de aplicarla en producción.

Para procedimientos de actualización, consulta la [guía de actualización de Helm](/es/platform/helm/midaz/midaz-upgrade-guide).

## 10. Revisa las recomendaciones de seguridad

***

Fees Engine procesa datos financieros e integra con operaciones del Ledger de Midaz. Asegúrate de que tu despliegue siga las [Recomendaciones de seguridad](/es/midaz/security-recommendations) de la plataforma, que cubren:

* Segmentación de red y Arquitectura Zero Trust
* Gestión y rotación de secretos (incluyendo `LICENSE_KEY` y credenciales de base de datos)
* Aplicación de TLS 1.2+ para todas las comunicaciones
* Configuración de RBAC vía [Access Manager](/es/platform/access-manager/access-manager)
* Gestión de parches y escaneo de vulnerabilidades

## 11. Diseña billing packages con alcance claro

***

Cada billing package debe representar un cargo único y bien definido. Evita empaquetar precios no relacionados en un solo paquete.

* **Paquetes separados por ruta de transacción**. Un paquete para facturación de Pix y un paquete para facturación de boletos son más claros que un solo paquete que intente manejar ambos.
* **Usa etiquetas descriptivas** que incluyan el tipo de facturación y el objetivo: "Pix Send Monthly Billing — Standard Tier" es mejor que "Billing Package 1".
* **Un tipo de `accountTarget` por paquete de mantenimiento**. No puedes combinar `segmentId`, `portfolioId` y `aliases` en el mismo paquete. Si necesitas diferentes objetivos, crea paquetes separados — una sola llamada a `/billing/calculate` evalúa todos los paquetes activos.

## 12. Escribe términos comerciales sobre el volumen por ruta

***

El cálculo por volumen cuenta transacciones por ruta de transacción en todo el ledger. La cuota gratuita, los niveles y los niveles de descuento se aplican a ese total por ruta.

* **Expresa los umbrales como volumen por ruta.** "Las primeras 100 transacciones en la ruta `pix-send` son gratuitas" se traduce directamente a un paquete. Escribe el contrato en los mismos términos con los que el motor cobra.
* **Separa rutas para separar conteos.** Un paquete por ruta de transacción mantiene cada flujo con su propia cuota, sus niveles y sus descuentos.

## 13. Planifica cuotas gratuitas y niveles de descuento con cuidado

***

Fees Engine evalúa las cuotas gratuitas y los descuentos en un orden específico:

1. El motor resta la cuota gratuita del conteo total para obtener el conteo facturable.
2. El motor aplica precios al conteo facturable — en paquetes escalonados cobra cada unidad facturable a la tarifa del único nivel que coincide (precio por volumen, no graduado).
3. El motor aplica un nivel de descuento al monto bruto, elegido contra el conteo **total** (antes de restar la cuota gratuita).

Consideraciones de diseño:

* **Las cuotas gratuitas se reinician cada período de facturación**. Establece el valor basándote en tu acuerdo comercial por período (mensual, semanal o diario), no de por vida.
* **Los niveles son brackets de volumen, no porciones**. Un conteo facturable de 1,750 contra un nivel 501–2,000 cobra las 1,750 unidades a la tarifa de ese nivel. Cruzar el límite de un bracket cambia la tarifa de todo el volumen, así que los límites de nivel pueden mover la factura de forma brusca.
* **Cubre todo conteo facturable positivo.** Si el conteo facturable es positivo y el rango de ningún nivel lo contiene, el cálculo falla para ese paquete. Deja abierto el límite superior del último nivel. Empieza el primer nivel en 1 — un conteo facturable de cero produce un monto cero y un payload vacío sin una búsqueda de nivel.
* **Los niveles de descuento son umbrales acumulativos**, no rangos, y solo se aplica uno: el `minQuantity` más alto que alcanza el conteo total. Si defines descuentos en 200 y 400 transacciones, un cliente con 500 transacciones obtiene el descuento de 400+ — no ambos.
* **Atiende los dos conteos distintos.** El precio usa el conteo facturable (después de la cuota gratuita); el descuento usa el conteo total (antes de ella).

<Tip>
  Usa cálculos de prueba con conteos de transacciones conocidos para validar tu configuración de niveles y descuentos antes de habilitar el paquete en producción.
</Tip>

## 14. Dimensiona los objetivos de cuentas de mantenimiento apropiadamente

***

Los paquetes de mantenimiento soportan tres tipos de objetivo con diferentes perfiles de escala:

| Tipo de objetivo | Escala            | Caso de uso                                           |
| ---------------- | ----------------- | ----------------------------------------------------- |
| `segmentId`      | 100,000+ cuentas  | Niveles estándar (PF, PJ, premium)                    |
| `portfolioId`    | Miles de cuentas  | Portfolios empresariales (PME, Corporate, Enterprise) |
| `aliases`        | Hasta 100 cuentas | Cuentas específicas nombradas                         |

Elige el tipo de objetivo que coincida con tu escala operacional. Si te encuentras listando cientos de aliases, migra a un segmento o portfolio en Midaz en su lugar.

## 15. Maneja fallos de facturación con re-ejecución

***

El cálculo de facturación sigue una política de todo-o-nada. Si algún paquete falla, el motor no devuelve resultados.

* **Construye lógica de reintentos** en tu orquestador. El cálculo no tiene estado — re-ejecutarlo para el mismo período produce los mismos resultados.
* **Revisa las respuestas de error** para identificar el paquete y recurso específico que falló. Causas comunes: `ledgerId` inválido, API de Midaz inaccesible o billing packages deshabilitados.
* **Separa los cálculos de volumen y mantenimiento** si un tipo tiene éxito consistentemente mientras el otro falla. Llama a `/billing/calculate` con `"type": "volume"` y `"type": "maintenance"` de forma independiente para aislar los fallos.
