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: truetambién deben usarreferenceAmount: 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: afterFeesAmountcon un número de prioridad mayor. Si la segunda tarifa debe referir al valor original, usaoriginalAmount.
3. Siempre estima antes de aplicar tarifas en producción
Fees Engine proporciona un endpoint de estimación 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
minimumAmountymaximumAmount, 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
packageIdespecífico para aislar el problema.
El endpoint de cálculo 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.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.
- 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 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:
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.
- 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.
- Siempre envía valores como strings, incluso números enteros (ej.,
"100"no100). - 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.
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.
- Monitorea los endpoints de salud. Fees Engine expone
/healthpara 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_SIZEes 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 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.
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 de la plataforma, que cubren:
- Segmentación de red y Arquitectura Zero Trust
- Gestión y rotación de secretos (incluyendo
LICENSE_KEYy credenciales de base de datos) - Aplicación de TLS 1.2+ para todas las comunicaciones
- Configuración de RBAC vía 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
accountTargetpor paquete de mantenimiento. No puedes combinarsegmentId,portfolioIdyaliasesen el mismo paquete. Si necesitas diferentes objetivos, crea paquetes separados — una sola llamada a/billing/calculateevalú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-sendson 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:
- El motor resta la cuota gratuita del conteo total para obtener el conteo facturable.
- 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).
- El motor aplica un nivel de descuento al monto bruto, elegido contra el conteo total (antes de restar la cuota gratuita).
- 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
minQuantitymá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).
14. Dimensiona los objetivos de cuentas de mantenimiento apropiadamente
Los paquetes de mantenimiento soportan tres tipos de objetivo con diferentes perfiles de escala:
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:
ledgerIdinvá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/calculatecon"type": "volume"y"type": "maintenance"de forma independiente para aislar los fallos.

