Saltar al contenido principal

Valores escalados

Para manejar transacciones con diferentes niveles de precisión, Fee Engine utiliza un formato de escala para representar valores monetarios. Este enfoque garantiza consistencia entre monedas fiat y criptomonedas por igual. La fórmula es sencilla:
VALUE * 10^-SCALE

Ejemplo: comprar un café (BRL)

Un café comprado por R$ 5.50 se representa en la API como BRL 550|2:
550 × 10^-2 = 5.50 BRL

Ejemplo: transferir Bitcoin (BTC)

Una transferencia de 0.00123456 BTC aparece como BTC 123456|8:
123456 × 10^-8 = 0.00123456 BTC
Este formato garantiza cálculos precisos, independientemente de la moneda.

Reglas de cálculo de tarifas

Cada tarifa utiliza un applicationRule para definir cómo se calcula. Puedes elegir entre tres tipos de reglas:
ConsejoPuedes combinar diferentes reglas en un único paquete para ajustarse a tu caso de uso.
Dos campos adicionales afectan el cálculo de tarifas:
  • El campo isDeductibleFrom define cómo se realizará el cálculo en relación con el campo referenceAmount, lo que significa que es posible especificar si la tarifa debe deducirse del valor inicial o neto de la transacción.
  • priority determina el orden en que se aplica cada tarifa.

maxBetweenTypes

Aplica el valor mayor entre una tarifa fija y una basada en porcentaje. Utiliza los campos referenceAmount e isDeductibleFrom para determinar el resultado. Ejemplo
  • Valor de tarifa fija: R$ 5.
  • Tarifa porcentual: 2%.
  • Monto de referencia: R$ 1,000.
rate = 1,000 * 0.02 = 20
Dado que R20>R 20 > R 5, se aplica la tarifa basada en porcentaje. En formato de escala:
CampoValor BrutoEscalaValor Escalado
value (Flat)5.002500
value (Percent)0.0222
referenceAmount1,000.002100000

flatFee

Aplica un monto de tarifa fija a la transacción, dependiendo de referenceAmount e isDeductibleFrom. Ejemplo
  • Valor fijo: R$ 15.
  • Monto de referencia: R$ 115.
  • Escala: 2.
isDeductibleFromFórmulaTarifa Total
falsereferenceAmount + valueR$ 130.00
truereferenceAmount - valueR$ 100.00
En formato de escala:
CampoValor BrutoEscalaValor Escalado
value15.0021500
referenceAmount115.00211500
TotalFee130.00 / 100.00213000 / 10000

percentual

Aplica una tarifa como porcentaje del monto de referencia. Ejemplo
  • Valor: 30%.
  • Monto de referencia: R$ 389.50.
  • Escala: 2.
isDeductibleFromFórmulaTarifa Total
falsereferenceAmount * valueR$ 116.85
truereferenceAmount - (referenceAmount * value)R$ 272.65
En formato de escala:
CampoValor BrutoEscalaValor Escalado
value3020.30
referenceAmount389.50238950
TotalFee116.85 / 272.65211685 / 27265

División de tarifas

Cuando una transacción involucra múltiples cuentas de origen, las tarifas se dividen proporcionalmente entre ellas.

Ejemplo

  • Monto total: R$ 4,000.00.
  • Tarifa fija: R$ 15.00.
  • Impuesto: 4%.
  • isDeductibleFrom: false.
Contribuciones de origen:
  • @account1: R$ 1,000.
  • @account2: R$ 1,000.
  • @account3: R$ 1,600.
  • @account4: R$ 400.

Porcentaje de participación

Fórmula: (Monto de Cuenta ÷ Monto Total) × 100
  • @account1: 25%.
  • @account2: 25%.
  • @account3: 40%.
  • @account4: 10%.

División de tarifa fija

ConsejoFórmula: tarifa fija × porcentaje de participación
Cuenta%Porción de TarifaTotal con Tarifa
@account125%R$ 3.75R$ 1,003.75
@account225%R$ 3.75R$ 1,003.75
@account340%R$ 6.00R$ 1,606.00
@account410%R$ 1.50R$ 401.50

Impuesto proporcional

ConsejoFórmula: monto de account × porcentaje de impuesto
CuentaPorción de ImpuestoTotal con Impuesto
@account1R$ 40.00R$ 1,040.00
@account2R$ 40.00R$ 1,040.00
@account3R$ 64.00R$ 1,664.00
@account4R$ 16.00R$ 416.00

Monto final por Cuenta

ConsejoFórmula: principal + tarifa + impuesto
CuentaPrincipalPorción de TarifaPorción de ImpuestoTotal Final
@account1R$ 1,000R$ 3.75R$ 40.00R$ 1,043.75
@account2R$ 1,000R$ 3.75R$ 40.00R$ 1,043.75
@account3R$ 1,600R$ 6.00R$ 64.00R$ 1,670.00
@account4R$ 400R$ 1.50R$ 16.00R$ 417.50

Validación de división de tarifas

Para garantizar la exactitud:
  • El porcentaje de participación debe totalizar 100%.
  • La división de tarifas debe igualar la tarifa fija original.
  • El impuesto debe totalizar el 4% de la transacción.
  • Total final = monto original + tarifas + impuesto → R4,000seconvierteenR 4,000 se convierte en R 4,175.00.

Exenciones de tarifas: reglas y jerarquía

Por monto de transacción

Usa minimumAmount y maximumAmount para definir cuándo las tarifas deben aplicarse. Por ejemplo: Si el rango es R0300,unatransaccioˊndeR 0–300, una transacción de R 301 no activará tarifas.

Por cuenta

El sistema verifica waivedAccounts. Si el origen está listado, está exento de tarifas.
ConsejoJerarquía: Monto -> Cuenta.

Ejemplo mixto: exenciones de tarifas y división de tarifas

Veamos un ejemplo de un paquete que incluye cuentas con exenciones de tarifas y requiere dividir las tarifas proporcionalmente.

Escenario

Estamos procesando una transacción de R$ 4,000, que incluye:
  • Una tarifa fija de R$ 16.
  • Un impuesto IOF del 6% a deducir.

División en el lado del origen

Cuenta de Origen%Valor Proporcional
@account115%R$ 600
@account235%R$ 1,400
@account340%R$ 1,600
@account410%R$ 400

División en el lado del destino

Cuenta de Destion%
@donation125%
@donation225%
@donation325%
@donation425%
Request
{
   "segmentId":"0196255c-4434-70c0-bf91-6af2effa8cb8",
   "ledgerId":"0196255b-735e-7988-8ad5-ee36a318a50c",
   "transaction":{
      "chartOfAccountsGroupName":"TARIFAS",
      "description":"Teste FEE",
      "send":{
         "asset":"BRL",
         "value":400000,
         "scale":2,
         "source":{
            "from":[
               {
                  "account":"@account1",
                  "share":{
                     "percentage":15
                  }
               },
               {
                  "account":"@account2",
                  "share":{
                     "percentage":35
                  }
               },
               {
                  "account":"@account5",
                  "share":{
                     "percentage":40
                  }
               },
               {
                  "account":"@account6",
                  "share":{
                     "percentage":10
                  }
               }
            ]
         },
         "distribute":{
            "to":[
               {
                  "account":"@donation1",
                  "share":{
                     "percentage":25
                  }
               },
               {
                  "account":"@donation2",
                  "share":{
                     "percentage":25
                  }
               },
               {
                  "account":"@donation3",
                  "share":{
                     "percentage":25
                  }
               },
               {
                  "account":"@donation4",
                  "share":{
                     "percentage":25
                  }
               }
            ]
         }
      }
   }
}
Response
{
    "segmentId": "0196255c-4434-70c0-bf91-6af2effa8cb8",
    "ledgerId": "0196255b-735e-7988-8ad5-ee36a318a50c",
    "transaction": {
        "chartOfAccountsGroupName": "FEES",
        "description": "FEE Teste",
        "metadata": {
            "packageAppliedID": "01962565-8d57-737b-abfa-84c3a15eeb15"
        },
        "send": {
            "asset": "BRL",
            "value": 401600,
            "scale": 2,
            "source": {
                "from": [
                    {
                        "account": "@account1",
                        "amount": {
                            "asset": "BRL",
                            "value": 60000,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_DEBIT",
                        "metadata": null
                    },
                    {
                        "account": "@account2",
                        "amount": {
                            "asset": "BRL",
                            "value": 140000,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_DEBIT",
                        "metadata": null
                    },
                    {
                        "account": "@account3",
                        "amount": {
                            "asset": "BRL",
                            "value": 161280,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_DEBIT",
                        "metadata": null
                    },
                    {
                        "account": "@account4",
                        "amount": {
                            "asset": "BRL",
                            "value": 40320,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_DEBIT",
                        "metadata": null
                    }
                ]
            },
            "distribute": {
                "to": [
                    {
                        "account": "@feeaccount1",
                        "amount": {
                            "asset": "BRL",
                            "value": 24000,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_CREDIT",
                        "metadata": null
                    },
                    {
                        "account": "@donation1",
                        "amount": {
                            "asset": "BRL",
                            "value": 94000,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_CREDIT",
                        "metadata": null
                    },
                    {
                        "account": "@donation2",
                        "amount": {
                            "asset": "BRL",
                            "value": 94000,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_CREDIT",
                        "metadata": null
                    },
                    {
                        "account": "@donation3",
                        "amount": {
                            "asset": "BRL",
                            "value": 94000,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_CREDIT",
                        "metadata": null
                    },
                    {
                        "account": "@donation4",
                        "amount": {
                            "asset": "BRL",
                            "value": 94000,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_CREDIT",
                        "metadata": null
                    },
                    {
                        "account": "@feeaccount2",
                        "amount": {
                            "asset": "BRL",
                            "value": 1600,
                            "scale": 2
                        },
                        "chartOfAccounts": "PIX_CREDIT",
                        "metadata": null
                    }
                ]
            }
        }
    }
}
Lo que debes notar aquí:
  • El IOF se configura con "isDeductibleFrom": true, lo que significa que se deducirá del monto a distribuir. Su “priority”: 1 lo convierte en la primera tarifa a aplicar.
  • La Tarifa Administrativa tiene "isDeductibleFrom": false, lo que significa que se agrega al monto de la transacción. Su "priority": 2 significa que se aplica después del IOF.

Desglose de los cálculos de tarifas

Cuenta de Origen%Valor ProporcionalTarifa AdminMonto de Transferencia Final
@account115%R$ 600ExentoR$ 600
@account235%R$ 1,400ExentoR$ 1,400
@account340%R$ 1,600R$ 12.80R$ 1,612.80
@account410%R$ 400R$ 3.20R$ 403.20
Solo las cuentas no exentas (@account1 y @account2) se les cobra la tarifa administrativa fija de R$ 16, proporcionalmente:
  • Total sujeto a tarifa: R1,600+R 1,600 + R 400 = R$ 2,000.
  • Porción de @account1: 1,600 / 2,000 = 80% → 16 × 0.8 = R$ 12.80.
  • Porción de @account2: 400 / 2,000 = 20% → 16 × 0.2 = R$ 3.20.
Estos montos de tarifas se agregan a la porción de cada participante, por lo que el valor total de SEND aumenta de R4,000aR 4,000 a **R 4,016**.

¿Y qué pasa con el IOF?

Dado que el IOF es una deducción, se resta de cada cuenta de destino proporcionalmente a su porción.
Cuenta de Destino%Valor BrutoIOF (6%)Valor Neto Recibido
@donation125%R$ 1,000R$ 60R$ 940
@donation225%R$ 1,000R$ 60R$ 940
@donation325%R$ 1,000R$ 60R$ 940
@donation425%R$ 1,000R$ 60R$ 940
Los montos de tarifas se envían a las cuentas de destino definidas en los campos creditAccount.

Manejo de decimales repetitivos

Cuando encontramos un decimal repetitivo (ej. 0.333333…), usamos la misma lógica de redondeo que las cuotas de tarjetas de crédito: ajustar un solo centavo en el primer (o mayor) valor para garantizar que el total final sea exacto, sin desviación de redondeo entre cuentas. En nuestro caso, cada “cuota” es una cuenta participante, por lo que el ajuste garantiza que todo se equilibre perfectamente.