Fee Engine Calculations

The Fee Engine plugin automates the calculation, allocation, and exemption of fees in transactions. It ensures accuracy, traceability, and compliance—while giving you the flexibility to model complex business rules.


Scaled Values


To handle transactions with different levels of precision, the Fee Engine uses a scale format to represent monetary values. This approach ensures consistency across fiat and cryptocurrencies alike.

The formula is straightforward:

VALUE * 10^-SCALE

Example: Buying a coffee (BRL)

A coffee bought for R$ 5.50 is represented in the API as BRL 550|2:

550 × 10^-2 = 5.50 BRL

Example: Transferring Bitcoin (BTC)

A transfer of 0.00123456 BTC appears as BTC 123456|8:

123456 × 10^-8 = 0.00123456 BTC

This format guarantees precise calculations—regardless of currency.


Fee Calculation Rules


Each fee uses an applicationRule to define how it's calculated. You can choose from three rule types:

💡

Tip

You can combine different rules in a single package to match your use case.

Two additional fields affect fee calculation:

  • The isDeductibleFrom field defines how the calculation will be made in relation to the referenceAmount field, meaning it is possible to specify whether the fee should be deducted from the initial or net value of the transaction.
  • priority determines the order in which each fee is applied.

maxBetweenTypes

Applies the higher value between a flat and a percentage-based fee. It uses the referenceAmount and isDeductibleFrom fields to determine the result.

Example

  • Flat fee value: R$ 5
  • Percentual fee: 2%
  • Reference amount: R$ 1,000
rate = 1,000 * 0.02 = 20

Since R$ 20 > R$ 5, the percentage-based fee is applied.

In scale format:

FieldRaw ValueScaleScaled Value
value (Flat)5.002500
value (Percent)0.0222
referenceAmount1,000.002100000

flatFee

Applies a fixed fee amount to the transaction, depending on referenceAmount and isDeductibleFrom.

Example

  • Fixed value: R$ 15
  • Reference amount: R$ 115
  • Scale: 2
isDeductibleFromFormulaTotal Fee
falsereferenceAmount + valueR$ 130.00
truereferenceAmount - valueR$ 100.00

In scale format:

FieldRaw ValueScaleScaled Value
value15.0021500
referenceAmount115.00211500
TotalFee130.00 / 100.00213000 / 10000

percentual

Applies a fee as a percentage of the reference amount.

Example

  • Value: 30%
  • Reference amount: R$ 389.50
  • Scale: 2
isDeductibleFromFormulaTotal Fee
falsereferenceAmount * valueR$ 116.85
truereferenceAmount - (referenceAmount * value)R$ 272.65

In scale format:

FieldRaw ValueScaleScaled Value
value3020.30
referenceAmount389.50238950
TotalFee116.85 / 272.65211685 / 27265

Fee Splitting


When a transaction involves multiple source accounts, fees are split proportionally among them.

Example

  • Total amount: R$ 4,000.00
  • Fixed fee: R$ 15.00
  • Tax: 4%
  • isDeductibleFrom: false

Source contributions:

  • @account1: R$ 1,000
  • @account2: R$ 1,000
  • @account3: R$ 1,600
  • @account4: R$ 400

Participation %

Formula: (Account Amount ÷ Total Amount) × 100

  • @account1: 25%
  • @account2: 25%
  • @account3: 40%
  • @account4: 10%

Fixed Fee Split

Formula: Fixed Fee × Participation %

Account%Fee ShareTotal w/ Fee
@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

Proportional Tax

💰

Formula: Account Amount × Tax %

AccountTax ShareTotal w/ Tax
@account1R$ 40.00R$ 1,040.00
@account2R$ 40.00R$ 1,040.00
@account3R$ 64.00R$ 1,664.00
@account4R$ 16.00R$ 416.00

Final Amount per Account

🧮

Formula: Principal + Fee + Tax

AccountPrincipalFee ShareTax ShareFinal Total
@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

Fee Splitting Validation

To ensure correctness:

  • Participation % must total 100%
  • The fee split must equal the original fixed fee
  • Tax must total 4% of the transaction
  • Final total = original amount + fees + tax
    → R$ 4,000 becomes R$ 4,175.00

Fee Exemptions: Rules & Hierarchy


By Transaction Amount

Use minimumAmount and maximumAmount to define when fees should apply. For example: If the range is R$ 0–300, a transaction of R$ 301 won’t trigger fees.


By Account

The system checks waivedAccounts. If the source is listed, it’s exempt from fees.

⚖️

Hierarchy: Amount → Account


Mixed Example: Fee Exemptions and Fee Splitting


Let’s look at an example of a package that includes accounts with fee exemptions and requires splitting fees proportionally.

Scenario

We’re processing a transaction of R$ 4,000, which includes:

  • A fixed fee of R$ 16.
  • An IOF tax of 6% to be deducted.

Split on the source side

Source Account%Proportional Value
@account115%R$ 600
@account235%R$ 1,400
@account340%R$ 1,600
@account410%R$ 400

Split on the destination side

Destination Account%
@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
                    }
                ]
            }
        }
    }
}

What to note here:

  • The IOF is set with "isDeductibleFrom": true, meaning it will be deducted from the amount to be distributed. Its "priority": 1 makes it the first fee to be applied.
  • The Administrative Fee has "isDeductibleFrom": false, meaning it gets added to the transaction amount. Its "priority": 2 means it’s applied after the IOF.

Breaking down the fee calculations

Source Account%Proportional ValueAdmin FeeFinal Transfer Amount
@account115%R$ 600ExemptR$ 600
@account235%R$ 1,400ExemptR$ 1,400
@account340%R$ 1,600R$ 12.80R$ 1,612.80
@account410%R$ 400R$ 3.20R$ 403.20

Only the non-exempt accounts (@account1 and @account2) are charged the fixed R$ 16 admin fee, proportionally:

  • Total subject to fee: R$ 1,600 + R$ 400 = R$ 2,000
  • Share of @account1: 1,600 / 2,000 = 80% → 16 × 0.8 = R$ 12.80
  • Share of @account2: 400 / 2,000 = 20% → 16 × 0.2 = R$ 3.20

These fee amounts are added to each participant’s share, so the total SEND value increases from R$ 4,000 to R$ 4,016.


And what about the IOF?

Since the IOF is a deduction, it’s subtracted from each destination account proportionally to their share.

Destination Account%Gross ValueIOF (6%)Net Value Received
@donation125%R$ 1,000R$ 60R$ 940
@donation225%R$ 1,000R$ 60R$ 940
@donation325%R$ 1,000R$ 60R$ 940
@donation425%R$ 1,000R$ 60R$ 940

The fee amounts are sent to the destination accounts defined in the creditAccount fields.


Handling repeating decimals


When we hit a repeating decimal (e.g. 0.333333...), we use the same rounding logic as credit card installments: adjust a single cent in the first (or highest) value to ensure the final total is exact, with no rounding drift across accounts.

In our case, each “installment” is a participating account — so the adjustment ensures everything balances perfectly.