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

# FAQ

> Encuentra respuestas a preguntas frecuentes sobre las APIs de Lerian, multi-tenancy, aislamiento en SaaS, paginación y configuración de la plataforma.

## APIs de Lerian

***

Esta sección responde preguntas comunes sobre las APIs de Lerian. Cubre comportamiento general, configuración y mejores prácticas en todos los servicios.

<Accordion title="¿Existe un número máximo de registros por página en los listados de API? ¿Puedo aumentar este límite?">
  Sí. El máximo por defecto es **100** registros por página. Este límite mantiene el rendimiento consistente y controla el volumen de datos en cada solicitud. Para aumentarlo, configura la variable de entorno `MAX_PAGINATION_LIMIT` en tu configuración de despliegue. La API acepta tamaños de página más grandes después de que reinicies la aplicación.

  **Importante**: Un tamaño de página mayor puede ralentizar los tiempos de respuesta, especialmente con grandes conjuntos de datos. Prueba en staging antes de cambiar producción.
</Accordion>

## Multi-tenancy y SaaS

***

Estas preguntas cubren el aislamiento de datos, el alcance de tenant y cómo funciona multi-tenancy en los despliegues de Lerian.

<AccordionGroup>
  <Accordion title="¿Mis datos están aislados de los de otros clientes en SaaS?">
    Sí. Cada tenant opera en una base de datos separada. La plataforma resuelve tu tenant a partir del JWT en cada solicitud y la dirige a tu base de datos aislada. No hay forma de acceder a los datos de otro tenant a través de la API. Más información sobre [multi-tenancy](/es/multi-tenancy).
  </Accordion>

  <Accordion title="¿Necesito pasar un ID de tenant en mis solicitudes de API?">
    No. El JWT access token que recibes durante la autenticación lleva el contexto de tu tenant. La plataforma lo resuelve automáticamente. No necesitas incluir un identificador de tenant en headers ni en el cuerpo de la solicitud.
  </Accordion>

  <Accordion title="¿Puedo tener múltiples Organizaciones bajo un solo tenant?">
    Sí. Un tenant puede contener múltiples Organizaciones. Cada Organización tiene sus propios Ledgers, cuentas y transacciones. La plataforma vincula todas a tu tenant automáticamente.
  </Accordion>

  <Accordion title="¿La API es diferente entre SaaS y despliegues autoalojados?">
    No. La superficie de API es idéntica: mismos endpoints, mismos payloads, mismas respuestas. Solo una cosa difiere. SaaS requiere autenticación en cada solicitud, y tu token delimita todas las operaciones a tu tenant.
  </Accordion>
</AccordionGroup>

## Midaz

***

Estas preguntas cubren Organizaciones, Ledgers, Cuentas, Transacciones y más en Midaz.

### Organizaciones

<AccordionGroup>
  <Accordion title="¿Las diferentes Organizaciones se comunican entre sí?">
    No. Cada Organización opera de forma independiente y no se comunica con otras.
  </Accordion>

  <Accordion title="¿Puedo usar una única licencia en múltiples Organizaciones?">
    No. Cada licencia se vincula a una Organización. Para dar soporte a múltiples Organizaciones, adquiere una licencia separada para cada una. La misma regla aplica a los Plugins.
  </Accordion>

  <Accordion title="¿Puede una Organización tener múltiples Plugins?">
    Sí. Una Organización puede tener más de un Plugin.
  </Accordion>

  <Accordion title="¿Puede una Organización tener múltiples Ledgers?">
    Sí. Una Organización puede gestionar múltiples Ledgers.
  </Accordion>

  <Accordion title="¿Puedo crear transacciones entre una Organización Padre y una Organización Hija?">
    Puedes crear una **Organización Padre** y una **Organización Hija**. Cada **Organización** mantiene su propio Ledger y opera de forma independiente. Las transacciones no pueden mover valor directamente entre Ledgers. Orquesta la transferencia con estos pasos:

    <Steps>
      <Step>
        En el Ledger de origen, crea una transacción de la cuenta original (**source**) a la **cuenta externa** del activo (distribute). Esto elimina el valor del Ledger de origen.
      </Step>

      <Step>
        En el Ledger de destino, **crea una segunda transacción**. El **source** es ahora la **cuenta externa** del activo, y el destino es la cuenta receptora (**distribute**).
      </Step>
    </Steps>

    Este patrón mueve valor entre Ledgers de diferentes Organizaciones de forma controlada.
  </Accordion>
</AccordionGroup>

### Ledgers

<AccordionGroup>
  <Accordion title="¿Los diferentes Ledgers se comunican entre sí?">
    No. Los Ledgers no se comunican directamente. Las transferencias entre Ledgers requieren orquestación.
  </Accordion>

  <Accordion title="¿Cómo puedo hacer transacciones entre Ledgers?">
    Debes orquestar el proceso y mover el monto a través de una Cuenta Externa. Esto involucra dos pasos:

    <Steps>
      <Step>
        Ledger A -> Cuenta Externa.
      </Step>

      <Step>
        Cuenta Externa -> Ledger B.
      </Step>
    </Steps>
  </Accordion>

  <Accordion title="¿Necesito un Ledger separado para cada Plugin?">
    No. Un único Ledger puede soportar múltiples Plugins. Por ejemplo, un Ledger puede manejar tanto Plugins de Exchange como de Pix.
  </Accordion>
</AccordionGroup>

### Activos

<AccordionGroup>
  <Accordion title="¿Puede un Activo vincularse a múltiples Cuentas?">
    No. Cada Activo se vincula a una única Cuenta. Cada Activo también se vincula a una Cuenta Externa. Midaz crea esa Cuenta Externa automáticamente cuando creas el Activo.
  </Accordion>

  <Accordion title="¿Qué tipos de Activos puedo usar?">
    Midaz admite varios tipos de Activos:

    * *currency*: Monedas fiduciarias tradicionales como BRL, USD y EUR.
    * *fiat*: Un tipo alternativo para monedas fiduciarias; como `currency`, el código del Activo debe seguir la norma ISO 4217.
    * *crypto*: Activos digitales como BTC, ETH y otras criptomonedas.
    * *commodities*: Bienes tangibles como oro, soja y petróleo.
    * *others*: Activos personalizados, incluyendo puntos de lealtad y valores tokenizados.
  </Accordion>
</AccordionGroup>

### Portafolios

<Accordion title="¿Cómo funciona un Portafolio?">
  Un **Portafolio** agrupa cuentas que pertenecen a la misma entidad (**CPF/CNPJ**). Por ejemplo, un CPF con dos valores diferentes de `segment_id` tiene dos valores de `account_id` correspondientes. Creas un Portafolio para ese CPF para vincular ambas cuentas bajo una única estructura. Esto facilita encontrar y gestionar las cuentas relacionadas.
</Accordion>

### Cuentas

<AccordionGroup>
  <Accordion title="¿Puede una Cuenta estar asociada con múltiples Activos?">
    No. Cada Cuenta se vincula a un único Activo. No puedes cambiar este vínculo.
  </Accordion>

  <Accordion title="¿Qué es una Cuenta Externa?">
    Una Cuenta Externa recibe fondos desde fuera del Ledger. Trae dinero al sistema.
  </Accordion>

  <Accordion title="¿Cómo puedo crear una Cuenta Externa?">
    Midaz crea una **Cuenta Externa** automáticamente cuando creas un Activo. Esta Cuenta Externa respalda todas las transacciones que entran y salen del Ledger.
  </Accordion>

  <Accordion title="¿Puede una Cuenta estar vinculada a varios Segmentos?">
    No. Cada cuenta (`account_id`) se vincula solo a un Segmento (`segment_id`).
  </Accordion>

  <Accordion title="¿Existe un límite en cuántas Cuentas puedo crear en Midaz?">
    No. Puedes crear tantas Cuentas como necesites. Midaz no impone ningún límite en el número de Cuentas.
  </Accordion>

  <Accordion title="¿Cuál es el proceso para agregar fondos a una cuenta o realizar un depósito usando dinero que proviene de fuera del entorno del Ledger (Midaz)?">
    El proceso de recarga de saldo funciona así:

    1. Cuando creas un Activo (por ejemplo, BRL) en el Ledger de Midaz, Midaz también crea una Cuenta Externa para ese Activo.
    2. Esta Cuenta Externa refleja los saldos que la institución mantiene fuera de Midaz. Esos saldos pueden estar en una cuenta PI, una cuenta de liquidación, una cuenta de reserva, o una cuenta bancaria tradicional o de pago.
    3. Para depositar fondos desde fuera del Ledger de Midaz en una cuenta de usuario, sigue estos pasos:
       * Crea una transacción con la Cuenta Externa como origen y las cuentas objetivo como destino.
       * Midaz debita la Cuenta Externa por el monto (por lo que se vuelve negativa) y acredita las cuentas de destino según los valores en el payload de la transacción.
  </Accordion>
</AccordionGroup>

### Transacciones

<AccordionGroup>
  <Accordion title="¿Cuál es la estructura mínima de una Transacción?">
    Una Transacción debe tener al menos dos Operaciones. Por ejemplo, una transferencia de R\$ 100 de la Cuenta A a la Cuenta B tiene dos operaciones:

    * **Operación 1:** Debitar R\$ 100 de la Cuenta A.
    * **Operación 2:** Acreditar R\$ 100 a la Cuenta B.
  </Accordion>

  <Accordion title="¿Es posible generar un recibo de transferencia en PDF que contenga los detalles de una transacción completada?">
    Lerian ofrece a los clientes varias formas de acceder a los recibos de transacciones:

    1. **Vía APIs** — Recupera los datos de la transacción a través de las APIs y luego genera un recibo visual en el formato que elijas.
    2. **Con el Reporter** — Extrae los datos de la transacción y crea recibos visuales personalizados.
    3. **A través del Console** — Accede a los datos de la transacción directamente en Lerian Console.
  </Accordion>
</AccordionGroup>

### Entidades

<Accordion title="¿Cómo puedo crear una Entidad?">
  La Entidad (`entity_id`) acepta IDs externos. Midaz no impone ninguna validación en este campo. Puedes usar los IDs que ya existen en tu base de datos e integrarlos en tu sistema.
</Accordion>

### Idempotencia

<AccordionGroup>
  <Accordion title="¿Qué sucede si no envío una clave de idempotencia?">
    Midaz trata la solicitud como nueva cada vez. Los reintentos pueden entonces crear operaciones duplicadas.
  </Accordion>

  <Accordion title="¿Puedo reutilizar una clave de idempotencia en diferentes endpoints?">
    No. Limita cada clave a una única operación y endpoint.
  </Accordion>

  <Accordion title="¿Qué sucede si cambio el TTL en un reintento?">
    Midaz usa solo el TTL de la primera solicitud. Un cambio posterior no tiene efecto.
  </Accordion>

  <Accordion title="¿La respuesta reproducida siempre será idéntica?">
    Sí. Para una solicitud completada, Midaz devuelve el mismo resultado que almacenó de la primera solicitud. También establece el header `X-Idempotency-Replayed` en `true`.
  </Accordion>

  <Accordion title="¿Cuál es el TTL predeterminado si no envío X-TTL?">
    El TTL predeterminado es de **300 segundos** (5 minutos). Envía el header `X-TTL` para definir un valor personalizado en segundos.
  </Accordion>
</AccordionGroup>

### Contabilidad en Midaz

<Accordion title="¿Cómo puedo reflejar mi propio Plan de Cuentas en Midaz?">
  Midaz te permite reflejar el **Plan de Cuentas** oficial de tu organización en la plataforma. Configuras dos características principales:

  * [Tipos de Cuenta](/es/midaz/accounts) — Crea las categorías lógicas de tu plan, como Activos, Pasivos, Ingresos y Gastos. Asígnalas a cuentas en tu Ledger. Cuando habilitas la función Tipos de Cuenta, el campo `type` en la API de Cuentas se vuelve obligatorio y debe coincidir con un valor registrado.
  * [Rutas Contables](/es/midaz/transaction-routing-entities) — Usa Rutas de Operación para validar cada pierna de una transacción. Por ejemplo, un débito debe provenir de una cuenta de tipo `user_wallet`. Usa Rutas Contables (el recurso `transactionRoute` en la API) para definir patrones completos de transacción que coincidan con tu lógica contable.

  Los Tipos de Cuenta y las Rutas Contables juntos hacen cumplir tus reglas contables a nivel de Ledger. Midaz valida y categoriza cada transacción según tu Plan de Cuentas. No codificas reglas en tu lógica de negocio.
</Accordion>

## Plugins

***

Los plugins extienden Midaz con integración y orquestación de procesos. Proporcionan abstracciones para que puedas enfocarte en tu modelo de negocio en lugar de lógica del sistema fuera de tu dominio.

Las preguntas siguientes cubren cómo funcionan los plugins, cómo los despliegas y las opciones disponibles.

<AccordionGroup>
  <Accordion title="¿Qué son los Plugins?">
    Los plugins son tecnologías que se integran en el Ledger de Midaz. Simplifican la integración y orquestación de procesos. Proporcionan abstracciones para que los clientes se enfoquen en su modelo de negocio. Los clientes no construyen ni gestionan lógica del sistema fuera de su dominio.
  </Accordion>

  <Accordion title="¿Pueden usarse los plugins sin Midaz?">
    No. Los plugins operan solo con Midaz. Proporcionan abstracciones específicas y orquestan transacciones basándose en la estructura del Ledger.
  </Accordion>

  <Accordion title="¿Cómo se distribuyen los plugins?">
    Después de que contratas un plugin, Lerian lo proporciona e instala en tu infraestructura (modelo on-premise), junto a tu instancia de Midaz. Las aplicaciones se conectan a cada plugin según su función.
  </Accordion>

  <Accordion title="¿Qué opciones de plugins ofrece Lerian?">
    Lerian proporciona dos tipos de plugins, agrupados por origen:

    * **Plugins Nativos:** Lerian desarrolla e integra estos plugins en el Ledger de Midaz. Lerian brinda soporte completo para ellos.
    * **Plugins de Marketplace:** Los socios de Lerian crean estos plugins para nichos de mercado específicos. Lerian ayuda a integrarlos en Midaz. Los socios los ofrecen y les dan soporte directamente.
  </Accordion>
</AccordionGroup>

## Fees Engine

***

Estas preguntas cubren el Fees Engine. Fees Engine es una capacidad con licencia de Midaz que se ejecuta dentro del proceso unificado del ledger.

### Conceptos Generales

<AccordionGroup>
  <Accordion title="¿Qué es el Fees Engine?">
    Fees Engine forma parte de **Midaz**. Se ejecuta en el proceso del ledger de Midaz para calcular tarifas de transacciones financieras. Configúralo y despliégalo con Midaz. Más información en la [descripción general del Fees Engine](/es/midaz/fees/fees-engine-overview). Opera en tres dominios principales:

    * **Paquetes de Tarifas (`/v1/packages`):** define las reglas de cobro por transacción (tarifa fija, porcentual, o el mayor entre ambos).
    * **Billing Packages (`/v1/billing-packages`):** define cobros periódicos por volumen de transacciones o por mantenimiento de cuentas.
    * **Cálculo y Estimación (`/v1/fees` y `/v1/estimates`):** endpoints para calcular tarifas en tiempo real o simular antes de confirmar.
  </Accordion>

  <Accordion title="¿Cómo se integra el Fees Engine en el ecosistema Lerian?">
    Fees Engine se ejecuta dentro del proceso del ledger de Midaz. Cuando se aplica un paquete de tarifas configurado, Midaz incorpora sus cálculos de tarifas en la transacción. Usa casos de uso de consulta del ledger en lugar de una conexión HTTP externa a Midaz.
  </Accordion>

  <Accordion title="¿Qué necesito enviar en cada solicitud al Fees Engine?">
    Cada solicitud requiere el header `X-Organization-Id` con el ID de tu organización en Midaz. Este header delimita la solicitud a una organización. Es específico del Fees Engine, no un identificador de tenant. La plataforma sigue resolviendo el contexto de tu tenant automáticamente desde el JWT. Cuando el plugin de autenticación está activo, también envías un Bearer token en el header `Authorization`.

    ```
    X-Organization-Id: <tu-organization-id>
    Authorization: Bearer <tu-token>
    ```
  </Accordion>

  <Accordion title="¿Qué base de datos utiliza el Fees Engine?">
    El Fees Engine usa **MongoDB** para almacenamiento. Las eliminaciones siguen el patrón de **soft-delete**. El Fees Engine no elimina los registros físicamente. En su lugar, los marca con `deletedAt`. Un registro eliminado no aparece en los listados, pero aún puedes auditarlo.
  </Accordion>

  <Accordion title="¿Cuál es la versión mínima de Midaz necesaria para usar el Fees Engine?">
    Necesitas **Midaz v3.6.0** o superior. El Fees Engine depende de APIs del módulo Transaction que Midaz añadió en la v3.6.0. Las versiones anteriores de Midaz no funcionan con el Fees Engine.
  </Accordion>
</AccordionGroup>

### Paquetes de Tarifas

<AccordionGroup>
  <Accordion title="¿Qué es un Paquete de Tarifas?">
    Un Paquete de Tarifas (`Package`) es un conjunto de reglas de cobro bajo un `feeGroupLabel`. Cada paquete se vincula a una **Organización + Ledger** y, opcionalmente, a un **Segment**. Un paquete puede contener varias tarifas (objetos `Fee`), cada una con su propia lógica de cálculo. Más información sobre [Paquetes de Tarifas](/es/midaz/fees/using-fee-engine).
  </Accordion>

  <Accordion title="¿Cómo crear un Paquete de Tarifas?">
    Envía un `POST /v1/packages` con el siguiente cuerpo. Consulta la [referencia de la API Create Package](/es/reference/midaz/plugins/fees-engine/create-package) para detalles completos.

    ```json theme={null}
    {
      "feeGroupLabel": "Tarifas Cuenta Digital",
      "ledgerId": "ldg_abc123",
      "segmentId": "seg_xyz456",
      "minimumAmount": "100.00",
      "maximumAmount": "50000.00",
      "transactionRoute": "PIX",
      "enable": true,
      "waivedAccounts": ["cuenta-exenta-1", "cuenta-exenta-2"],
      "fees": {
        "tarifa_admin": {
          "feeLabel": "Tarifa Administrativa",
          "calculationModel": {
            "applicationRule": "percentual",
            "calculations": [
              { "type": "percentage", "value": "1.50" }
            ]
          },
          "referenceAmount": "originalAmount",
          "priority": 1,
          "isDeductibleFrom": true,
          "creditAccount": "cuenta-ingresos-tarifas"
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="¿Se puede desactivar un paquete temporalmente?">
    Sí. Configura el campo `enable` en `false` cuando creas o actualizas el paquete. El Fees Engine omite un paquete desactivado durante el cálculo de tarifas, incluso cuando el contexto de la transacción coincide con su alcance.
  </Accordion>

  <Accordion title="¿Cómo funciona el alcance de un paquete (minimumAmount / maximumAmount)?">
    El Fees Engine aplica el paquete solo a transacciones cuyo valor esté dentro del rango `[minimumAmount, maximumAmount]`. Si el valor de la transacción queda fuera de este rango, el Fees Engine ignora el paquete.

    **Ejemplo:** Un paquete con `minimumAmount: 100` y `maximumAmount: 5000` cobra tarifas solo en transacciones entre 100 y 5.000.

    <Note>Si no defines `maximumAmount`, el paquete puede aplicarse sin límite superior. Verifica las reglas de validación de tu versión.</Note>
  </Accordion>

  <Accordion title="¿Puedo filtrar un paquete por ruta de transacción?">
    Sí. Configura el campo `transactionRoute` en el paquete. El Fees Engine considera entonces el paquete solo para transacciones con esa ruta, como `"PIX"`, `"TED"` o `"BOLETO"`.
  </Accordion>

  <Accordion title="¿Qué son los waivedAccounts?">
    Son aliases de cuentas que el paquete **exime** de tarifas. Si el remitente o destinatario de la transacción es una cuenta en `waivedAccounts`, el Fees Engine no aplica las tarifas del paquete a ella.

    ```json theme={null}
    "waivedAccounts": ["cuenta-vip", "cuenta-empleado"]
    ```

    Este paquete no cobra ninguna transacción que provenga de estas cuentas o se destine a ellas.
  </Accordion>

  <Accordion title="¿Los endpoints de listado tienen paginación?">
    Sí. Los endpoints de listado (`GET /v1/packages`, `GET /v1/billing-packages`) soportan los parámetros de query `limit` y `page` para paginación.

    ```
    GET /v1/packages?limit=20&page=2
    ```
  </Accordion>
</AccordionGroup>

### Modelos de Cálculo

<AccordionGroup>
  <Accordion title="¿Qué modelos de cálculo están disponibles?">
    El campo `applicationRule` dentro de `calculationModel` define cómo el Fees Engine calcula la tarifa. Consulta [Modelos de Cálculo](/es/midaz/fees/fee-engine-calculation) para detalles completos. Hay tres opciones:

    | Regla             | Descripción                                              |
    | ----------------- | -------------------------------------------------------- |
    | `flatFee`         | Tarifa fija en valor absoluto                            |
    | `percentual`      | Tarifa porcentual sobre el valor de referencia           |
    | `maxBetweenTypes` | Calcula flat y porcentual; aplica el **mayor** resultado |
  </Accordion>

  <Accordion title="¿Cómo configurar una tarifa fija (flatFee)?">
    Usa exactamente **1 cálculo** de tipo `flat`:

    ```json theme={null}
    "calculationModel": {
      "applicationRule": "flatFee",
      "calculations": [
        { "type": "flat", "value": "5.00" }
      ]
    }
    ```

    Esto cobra 5,00 fijos, independientemente del valor de la transacción.
  </Accordion>

  <Accordion title="¿Cómo configurar una tarifa porcentual (percentual)?">
    Usa exactamente **1 cálculo** de tipo `percentage`:

    ```json theme={null}
    "calculationModel": {
      "applicationRule": "percentual",
      "calculations": [
        { "type": "percentage", "value": "2.50" }
      ]
    }
    ```

    Esto cobra 2,5% sobre el valor de referencia de la transacción.
  </Accordion>

  <Accordion title="¿Cómo funciona maxBetweenTypes?">
    El `maxBetweenTypes` requiere **2 o más cálculos** que combinan `flat` y `percentage`. El Fees Engine calcula ambos y aplica el **mayor resultado**.

    **Ejemplo:** Tarifa mínima de 3,00 o 1% del valor — el que sea mayor:

    ```json theme={null}
    "calculationModel": {
      "applicationRule": "maxBetweenTypes",
      "calculations": [
        { "type": "flat", "value": "3.00" },
        { "type": "percentage", "value": "1.00" }
      ]
    }
    ```

    Para una transacción de 200: 1% = 2,00 vs. 3,00 fijo → cobra **3,00**.
    Para una transacción de 500: 1% = 5,00 vs. 3,00 fijo → cobra **5,00**.
  </Accordion>

  <Accordion title="¿Puedo mezclar múltiples porcentajes en maxBetweenTypes?">
    Sí. Puedes incluir cualquier combinación de `flat` y `percentage`. El Fees Engine evalúa todos y aplica el mayor. Ten en cuenta que `flatFee` y `percentual` requieren exactamente 1 cálculo. Solo `maxBetweenTypes` acepta 2 o más.
  </Accordion>
</AccordionGroup>

### Campos Importantes

<AccordionGroup>
  <Accordion title="¿Qué es referenceAmount y cómo afecta el cálculo?">
    El `referenceAmount` define **sobre qué valor** el Fees Engine calcula la tarifa:

    * `originalAmount`: el valor original de la transacción, **antes** de cualquier tarifa.
    * `afterFeesAmount`: el valor de la transacción **después** de que se apliquen las tarifas de mayor prioridad.

    <Note>La tarifa con `priority: 1` se ejecuta primero, por lo que **debe** usar `originalAmount`. No hay tarifas anteriores que considerar.</Note>
  </Accordion>

  <Accordion title="¿Qué es isDeductibleFrom y cuándo debo usarlo?">
    Cuando `isDeductibleFrom: true`, el Fees Engine deduce la tarifa del monto que envía el remitente. El destinatario recibe el monto descontado, y el remitente paga extra para cubrir el cargo.

    Cuando `false`, el Fees Engine cobra la tarifa **por separado**. El remitente envía el monto completo, y el Fees Engine debita la tarifa aparte.

    **Restricciones:**

    * `isDeductibleFrom: true` requiere `referenceAmount: originalAmount`
    * Si el tipo es `percentage`: el valor no puede exceder 100
    * Si el tipo es `flat`: el valor no puede exceder el `minimumAmount` del paquete
  </Accordion>

  <Accordion title="¿Cómo funciona el campo priority?">
    El `priority` define el **orden de ejecución** de las tarifas dentro de un paquete. El Fees Engine ejecuta primero los valores menores.

    * `priority: 1` → se ejecuta primero (obligatoriamente usa `originalAmount`)
    * `priority: 2` → se ejecuta después, puede usar `afterFeesAmount`

    Usa prioridades para encadenar tarifas. Por ejemplo, ejecuta una tarifa administrativa sobre el valor original. Luego ejecuta una tarifa de impuesto sobre el valor posterior a la tarifa administrativa.
  </Accordion>

  <Accordion title="¿Qué es creditAccount?">
    Es el alias de la cuenta en el ledger que recibe los ingresos de la tarifa. Cada tarifa puede tener un `creditAccount` diferente. Esto ayuda cuando diferentes tarifas pertenecen a centros de costo distintos.

    ```json theme={null}
    "creditAccount": "cuenta-ingresos-tarifas-admin"
    ```
  </Accordion>

  <Accordion title="¿Para qué sirven routeFrom y routeTo dentro de una tarifa?">
    Estos campos definen las rutas de las **patas contables** que genera el cobro de la tarifa. Son opcionales. Te permiten rastrear el origen y destino de los movimientos de tarifa en el ledger.
  </Accordion>
</AccordionGroup>

### Billing Packages

<AccordionGroup>
  <Accordion title="¿Qué son los Billing Packages?">
    Los Billing Packages son paquetes de cobro **periódico**, independientes del cálculo de tarifas por transacción. Consulta [ejemplos de Billing Packages](/es/midaz/fees/billing-package-examples) para casos de uso. Existen dos tipos:

    * **`volume`:** cobra según la **cantidad de transacciones** en un período, con precios escalonados (tiers).
    * **`maintenance`:** cobra una **tarifa fija por cuenta** en un alcance determinado.
  </Accordion>

  <Accordion title="¿Cuándo usar billing de tipo volume?">
    Usa el billing de volumen para cobrar a clientes según el **número de transacciones procesadas**. Es un modelo común en plataformas de pago con precios por volumen. Define escalones de precio (tiers) que se aplican a medida que el volumen crece.

    ```json theme={null}
    {
      "type": "volume",
      "eventFilter": {
        "transactionRoute": "PIX",
        "status": "approved"
      },
      "pricingModel": "tiered",
      "tiers": [
        { "minQuantity": 0, "maxQuantity": 1000, "unitPrice": "0.50" },
        { "minQuantity": 1001, "unitPrice": "0.30" }
      ],
      "assetCode": "BRL",
      "debitAccountAlias": "cuenta-cliente",
      "creditAccountAlias": "cuenta-ingresos-volumen"
    }
    ```

    <Note>El último tier debe ser **ilimitado** (sin `maxQuantity`). No puede haber brechas ni superposiciones entre tiers.</Note>
  </Accordion>

  <Accordion title="¿Cuándo usar billing de tipo maintenance?">
    Usa el billing de mantenimiento para cobrar una **tarifa fija periódica por cuenta**. Por ejemplo, cobra una mensualidad por cuenta activa. Especifica el alcance (`segmentId`, `portfolioId` o `aliases`) y el valor de la tarifa.

    ```json theme={null}
    {
      "type": "maintenance",
      "feeAmount": "15.00",
      "assetCode": "BRL",
      "maintenanceCreditAccount": "cuenta-ingresos-mantenimiento",
      "accountTarget": {
        "segmentId": "seg_clientes_premium"
      }
    }
    ```

    <Note>`accountTarget` debe tener exactamente **uno** de los tres campos: `segmentId`, `portfolioId` o `aliases` (máximo 100 aliases).</Note>
  </Accordion>

  <Accordion title="¿Cómo funcionan los tiers en el billing de volumen?">
    Los tiers definen el **precio unitario por escalón** a medida que el volumen aumenta. Las reglas son:

    1. Deben ser **contiguos** — sin brechas entre escalones (`minQuantity` del siguiente = `maxQuantity` del anterior + 1).
    2. No pueden tener **superposición**.
    3. El **último tier debe ser ilimitado** (sin `maxQuantity`).

    **Ejemplo de tiers correctos:**

    ```json theme={null}
    "tiers": [
      { "minQuantity": 0, "maxQuantity": 500, "unitPrice": "0.80" },
      { "minQuantity": 501, "maxQuantity": 2000, "unitPrice": "0.60" },
      { "minQuantity": 2001, "unitPrice": "0.40" }
    ]
    ```
  </Accordion>

  <Accordion title="¿Qué es freeQuota?">
    Es una **franquicia gratuita**. El Fees Engine no cobra un número determinado de transacciones antes de que se apliquen los tiers. Esto ayuda a los modelos de precios con un volumen mínimo incluido.

    **Ejemplo:** `freeQuota: 100` significa que el Fees Engine no cobra las primeras 100 transacciones del período.
  </Accordion>

  <Accordion title="¿Qué son los discountTiers?">
    Son escalones de descuento para el billing de volumen. Reducen el valor cobrado según criterios adicionales. Complementan la lógica de los `tiers` principales.
  </Accordion>

  <Accordion title="¿Qué es countMode en el billing de volumen?">
    Define **cómo el Fees Engine cuenta las transacciones**:

    * `perRoute`: cuenta transacciones por ruta (ej: total de PIX aprobados).
    * `perAccount`: cuenta transacciones por cuenta individualmente.
  </Accordion>
</AccordionGroup>

### Cálculo y Estimación de Tarifas

<AccordionGroup>
  <Accordion title="¿Cuál es la diferencia entre /v1/fees y /v1/estimates?">
    | Endpoint             | Cuándo usar                                                                                                                                                                                                                                                          |
    | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `POST /v1/fees`      | Calcular la tarifa **real** de una transacción en curso. El sistema busca automáticamente los paquetes aplicables según el ledger, segment, ruta y valor. Consulta la [referencia de la API Calculate Fees](/es/reference/midaz/plugins/fees-engine/calculate-fees). |
    | `POST /v1/estimates` | **Simular** la tarifa de un paquete específico antes de confirmar la transacción. Útil para mostrar al usuario final el costo antes de ejecutar. Consulta la [referencia de la API Simulate Fees](/es/reference/midaz/plugins/fees-engine/simulate-fees).            |
  </Accordion>

  <Accordion title="¿Cómo funciona /v1/fees?">
    El endpoint recibe los datos de la transacción. El sistema **busca automáticamente** los paquetes aplicables. Considera:

    * `ledgerId` — obligatorio
    * `segmentId` — opcional
    * `transactionRoute` — opcional
    * Valor de la transacción — comparado con `minimumAmount`/`maximumAmount` del paquete

    El Fees Engine calcula y retorna las tarifas de todos los paquetes correspondientes.
  </Accordion>

  <Accordion title="¿Cómo funciona /v1/estimates?">
    El endpoint `/v1/estimates` simula la tarifa de un **paquete específico** (`packageId`). No necesitas una transacción real. Funciona bien para:

    * Mostrar el costo estimado al usuario antes de la confirmación.
    * Probar configuraciones de paquetes recién creados.
    * Construir simuladores de tarifas en tu producto.
  </Accordion>

  <Accordion title="¿Puedo usar /v1/estimates en producción para mostrar tarifas al usuario final?">
    Sí. El `/v1/estimates` es un endpoint de solo lectura. No altera estado ni registra transacciones. Es seguro usarlo en flujos de UX para mostrar el costo antes de la confirmación.
  </Accordion>

  <Accordion title="¿Cómo calcular el billing?">
    Después de que configures los Billing Packages, llama a este endpoint:

    ```
    POST /v1/billing/calculate
    ```

    Este endpoint procesa las reglas configuradas y genera los cobros para el período. Consulta la [referencia de la API Calculate Billing](/es/reference/midaz/plugins/fees-engine/calculate-billing).
  </Accordion>
</AccordionGroup>

### Errores Comunes

<AccordionGroup>
  <Accordion title="&#x22;Priority 1 must use originalAmount&#x22; — ¿qué significa?">
    La tarifa con `priority: 1` debe tener `referenceAmount: "originalAmount"`. Es la primera tarifa en ejecutarse, por lo que no hay tarifas anteriores sobre las cuales basar el cálculo.

    **Corrección:**

    ```json theme={null}
    {
      "priority": 1,
      "referenceAmount": "originalAmount"
    }
    ```
  </Accordion>

  <Accordion title="&#x22;isDeductibleFrom requires originalAmount&#x22; — ¿cómo resolver?">
    Las tarifas con `isDeductibleFrom: true` solo pueden usar `referenceAmount: "originalAmount"`. Actualiza el campo:

    ```json theme={null}
    {
      "isDeductibleFrom": true,
      "referenceAmount": "originalAmount"
    }
    ```
  </Accordion>

  <Accordion title="&#x22;Flat fee value cannot exceed minimumAmount&#x22; — ¿por qué?">
    Cuando `isDeductibleFrom: true` y el tipo es `flat`, el valor de la tarifa no puede exceder el `minimumAmount` del paquete. Esto evita una tarifa mayor que el valor mínimo de la transacción.

    **Ejemplo:** Si `minimumAmount: 100`, la tarifa flat no puede exceder 100.
  </Accordion>

  <Accordion title="&#x22;Percentage value cannot exceed 100&#x22; — ¿cuándo ocurre?">
    Este error ocurre cuando `isDeductibleFrom: true`, el tipo es `percentage` y el valor supera 100. Una tarifa porcentual deducible del 100% anularía el valor de la transacción. Los valores superiores a 100 son inválidos.
  </Accordion>

  <Accordion title="&#x22;Tiers must be contiguous&#x22; — ¿cómo corregir?">
    Los tiers de billing de volumen deben cubrir todos los rangos sin brechas. Verifica que el `minQuantity` de cada tier sea exactamente `maxQuantity + 1` del tier anterior.

    ```json theme={null}
    // ❌ Incorrecto — brecha entre 500 y 600
    { "minQuantity": 0, "maxQuantity": 500, "unitPrice": "0.80" },
    { "minQuantity": 600, "unitPrice": "0.40" }

    // ✅ Correcto
    { "minQuantity": 0, "maxQuantity": 500, "unitPrice": "0.80" },
    { "minQuantity": 501, "unitPrice": "0.40" }
    ```
  </Accordion>

  <Accordion title="&#x22;Last tier must be unbounded&#x22; — ¿qué significa?">
    El último tier en el billing de volumen debe ser **sin límite superior** (sin `maxQuantity`). Esto mantiene un precio en las transacciones por encima del mayor rango definido.
  </Accordion>

  <Accordion title="&#x22;accountTarget must have exactly one of: segmentId, portfolioId, aliases&#x22;">
    En el billing de tipo `maintenance`, el campo `accountTarget` acepta solo **una** de las tres opciones. No combines campos:

    ```json theme={null}
    // ❌ Incorrecto
    "accountTarget": {
      "segmentId": "seg_abc",
      "portfolioId": "port_xyz"
    }

    // ✅ Correcto
    "accountTarget": {
      "segmentId": "seg_abc"
    }
    ```
  </Accordion>

  <Accordion title="¿El campo aliases en accountTarget tiene algún límite?">
    Sí. El campo `aliases` acepta un máximo de **100 aliases** por Billing Package de tipo `maintenance`.
  </Accordion>

  <Accordion title="&#x22;flatFee requires exactly 1 calculation of type flat&#x22;">
    El `applicationRule: "flatFee"` acepta exactamente 1 cálculo, y debe ser de tipo `flat`. No uses `percentage` con `flatFee`.

    ```json theme={null}
    // ✅ Correcto
    "calculationModel": {
      "applicationRule": "flatFee",
      "calculations": [{ "type": "flat", "value": "10.00" }]
    }
    ```
  </Accordion>

  <Accordion title="&#x22;percentual requires exactly 1 calculation of type percentage&#x22;">
    Como el `flatFee`, el `applicationRule: "percentual"` acepta exactamente 1 cálculo de tipo `percentage`.
  </Accordion>

  <Accordion title="&#x22;maxBetweenTypes requires 2 or more calculations&#x22;">
    El `maxBetweenTypes` requiere al menos 2 cálculos para funcionar — necesita valores para comparar. Proporciona al menos un `flat` y un `percentage`.
  </Accordion>

  <Accordion title="El paquete no se está aplicando a la transacción — ¿qué verificar?">
    Lista de verificación — consulta también [Mejores Prácticas](/es/midaz/fees/fees-engine-best-practices):

    * **`enable`:** ¿el paquete está activo (`enable: true`)?
    * **`ledgerId`:** ¿el paquete está vinculado al ledger correcto?
    * **`minimumAmount` / `maximumAmount`:** ¿el valor de la transacción está dentro del rango?
    * **`transactionRoute`:** si el paquete tiene `transactionRoute`, ¿la transacción usa la misma ruta?
    * **`segmentId`:** si el paquete está vinculado a un segmento específico, ¿la cuenta pertenece a él?
    * **`waivedAccounts`:** ¿la cuenta está listada como exenta?
  </Accordion>

  <Accordion title="¿Se puede recuperar un registro eliminado?">
    El Fees Engine hace soft-delete de los registros. Los marca con `deletedAt` y no los elimina de la base de datos. La API no expone endpoints de restauración por defecto. Contacta al equipo de Lerian si necesitas recuperar un registro eliminado. Para la lista completa de códigos de error, consulta la [referencia de Códigos de Error](/es/reference/midaz/plugins/fees-engine/fee-engine-error-list).
  </Accordion>
</AccordionGroup>
