Numeric values (string)
All financial values in Fees Engine must be expressed as a string, using the numeric type. This ensures high-precision decimal handling for assets like BRL or BTC, and prevents rounding errors during calculations, splits, or exemptions.
Important
- Required: Midaz v3.x.x (uses
numeric).
- Incompatible: Midaz v2.x.x (deprecated
amount + scale format).
Clients using Midaz v2.x.x must upgrade to v3.x.x to ensure proper integration and functionality with Fees Engine.
Example:
Billing periods
When triggering a billing calculation, you specify the time window through the period field. Fees Engine supports three formats:
| Format | Example | Window |
|---|
| Daily | 2026-03-15 | Start of that day → start of the next day (UTC) |
| Weekly | 2026-W13 | Monday 00:00 UTC of the ISO week → following Monday 00:00 UTC |
| Monthly | 2026-03 | First instant of the month → first instant of the next month (UTC) |
The engine uses the period to count qualifying transactions (for volume packages) or active accounts (for maintenance packages) within that exact window.
Weekly periods follow ISO 8601. Week numbering ranges from W01 to W52 (or W53 in years that have 53 ISO weeks). The week always starts on Monday.
Choose the granularity that matches your billing cycle. A prepaid card product billed daily would use 2026-03-15; a SaaS platform billed monthly would use 2026-03; a marketplace that settles weekly would use 2026-W13.
Fee calculation rules
Each fee uses an applicationRule to define how it’s calculated. You can choose from three rule types:
You can combine different rules in a single package to match your use case.
Other key fields:
isDeductibleFrom: defines if the fee is deducted from the sender or the receiver.
referenceAmount: either originalAmount or afterFeesAmount.
priority: defines the order of application. Priority 1 must always use originalAmount.
maxBetweenTypes
Applies whichever is greater: a flat or percentage-based fee.
Example
- Flat fee value: R$5.
- Percentual fee: 2%.
- Reference amount: R$1,000.
rate = 1000 * 0.02 = R$ 20.00
Since R 5, the percentage-based fee is applied.
flatFee
Applies a fixed fee amount. Behavior depends on isDeductibleFrom.
Example
- Flat fee: R$15.
- Reference amount: R$115.
isDeductibleFrom | Formula | Total Fee |
|---|
false | referenceAmount + fee | R$ 130.00 |
true | referenceAmount - fee | R$ 100.00 |
percentual
Applies a fee as a percentage of the reference amount.
Example
- Value: 30%.
- Reference amount: R$ 389.50.
isDeductibleFrom | Formula | Total Fee |
|---|
false | referenceAmount * value | R$ 116.85 |
true | referenceAmount - (referenceAmount * value) | R$ 272.65 |
Fee splitting
When a transaction has multiple source accounts, Fees Engine splits fees proportionally.
Example
- Total amount: R$4,000.00
- Fixed fee: R$15.00
- Tax: 4%
isDeductibleFrom: false
Participation %
Formula: (Account Amount ÷ Total Amount) × 100
| Account | Share | Amount |
|---|
| @account1 | 25% | R$ 1,000 |
| @account2 | 25% | R$ 1,000 |
| @account3 | 40% | R$ 1,600 |
| @account4 | 10% | R$ 400 |
Fixed fee distribution
Formula: fixed Fee × participation %
| Account | Fee Share | Total |
|---|
| @account1 | R$ 3.75 | R$ 1,003.75 |
| @account2 | R$ 3.75 | R$ 1,003.75 |
| @account3 | R$ 6.00 | R$ 1,606.00 |
| @account4 | R$ 1.50 | R$ 401.50 |
Proportional tax
Formula: account amount × tax %
| Account | Tax | Total w/ Tax |
|---|
| @account1 | R$ 40.00 | R$ 1,040.00 |
| @account2 | R$ 40.00 | R$ 1,040.00 |
| @account3 | R$ 64.00 | R$ 1,664.00 |
| @account4 | R$ 16.00 | R$ 416.00 |
Final amount per account
Formula: principal + fee + tax
| Account | Fee | Tax | Final Total |
|---|
| @account1 | R$ 3.75 | R$ 40.00 | R$ 1,043.75 |
| @account2 | R$ 3.75 | R$ 40.00 | R$ 1,043.75 |
| @account3 | R$ 6.00 | R$ 64.00 | R$ 1,670.00 |
| @account4 | R$ 1.50 | R$ 16.00 | R$ 417.50 |
Validations
- Total shares = 100%
- Fee split matches flat fee
- Tax split = 4%
- Total sent = 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 R0–300,atransactionofR 301 won’t trigger fees.
By account
The system checks waivedAccounts. If the source is listed, it’s exempt from fees.
Hierarchy: Value range check > then account exemption
Mixed example: fee exemptions and proportional 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.
- Only some accounts are subject to the fixed fee
- An IOF tax of 6% to be deducted.
Split on the source side
| Source Account | % | Proportional Value |
|---|
| @account1 | 15% | R$ 600 |
| @account2 | 35% | R$ 1,400 |
| @account3 | 40% | R$ 1,600 |
| @account4 | 10% | R$ 400 |
Fixed fee applied only to @account3 and @account4.
Result after Admin Fee (proportional)
| Account | Admin Fee | Total |
|---|
| @account1 | Exempt | R$ 600 |
| @account2 | Exempt | R$ 1,400 |
| @account3 | R$ 12.80 | R$ 1,612.80 |
| @account4 | R$ 3.20 | R$ 403.20 |
Total send value increases to R$4,016.
IOF deduction (recipient)
| Recipient | % | Gross | IOF (6%) | Net |
|---|
| @donation1 | 25% | R$ 1,000 | R$ 60 | R$ 940 |
| @donation2 | 25% | R$ 1,000 | R$ 60 | R$ 940 |
| @donation3 | 25% | R$ 1,000 | R$ 60 | R$ 940 |
| @donation4 | 25% | R$ 1,000 | R$ 60 | R$ 940 |
Fees are credited to the accounts defined in each fee’s creditAccount.
Repeating decimals
When a fee split results in repeating decimals (e.g., 0.3333…), Fees Engine automatically adjusts the first or largest value by a cent to ensure the total remains exact. This avoids rounding drift and keeps your ledger consistent.
Billing calculations
Billing packages use a different calculation model than fee packages. Instead of evaluating individual transactions, they aggregate data over a billing period and return charge payloads for your orchestrator to execute.
Billing supports three period formats: monthly (YYYY-MM), weekly (YYYY-Www, e.g., 2026-W13), and daily (YYYY-MM-DD).
Volume billing calculation
Volume billing counts transactions matching an eventFilter (transaction route + status) within the billing period, then applies pricing based on the configured model.
The calculation follows this order:
- Count qualifying transactions in the period.
- Subtract the
freeQuota from the total count.
- Apply pricing based on the
pricingModel (tiered or fixed).
- Apply discounts from
discountTiers if the total volume meets any threshold.
Tiered pricing
Each tier defines a quantity range and a unit price. The engine applies the corresponding price for each unit within each range.
Example: A billing package for boleto issuance with three tiers and a free quota of 50:
| Range | Unit price |
|---|
| 1–500 | R$ 1.20 |
| 501–2,000 | R$ 0.80 |
| 2,001+ | R$ 0.45 |
For a client that issued 1,800 boletos in the month:
- 50 exempt (free quota)
- 1,750 billable: 500 × R$ 1.20 + 1,250 × R$ 0.80 = R$ 1,600.00
- Discount tier applies (> 1,000 boletos → 5%): −R$ 80.00
- Total: R$ 1,520.00
Fixed pricing
A single unit price applies to all billable transactions regardless of volume. The free quota is still subtracted before calculation.
Example: R$ 0.10 per Pix sent, no free quota:
- 5,000 Pix transactions × R$ 0.10 = R$ 500.00
Count modes
The countMode field determines how transactions are grouped:
perRoute — Counts all matching transactions across the organization as a single total.
perAccount — Counts transactions per individual account and applies pricing independently to each.
Maintenance billing calculation
Maintenance billing charges a fixed amount per active account in the billing period. The engine resolves the target accounts, filters for active status, and generates a single transaction payload.
The result is a N:1 transaction:
- Each active account appears as a debit entry (
source.from) for the configured feeAmount.
- The
maintenanceCreditAccount receives the full total as a single credit entry (distribute.to).
Inactive, closed, or suspended accounts are excluded automatically.
Example: Monthly maintenance of R$ 9.90 for a segment with 12,000 active PF accounts:
- 12,000 entries in
source.from, each debited R$ 9.90
- 1 entry in
distribute.to credited R$ 118,800.00
All-or-nothing failure policy
If any billing package fails during a /billing/calculate call, the entire operation fails. No partial results are returned. The response includes which package and resource caused the failure, so you can fix and re-execute.
Each billing calculation result includes structured metadata with all parameters used — pricing model, tiers applied, free quota subtracted, discounts applied, and account counts. This provides complete traceability for reconciliation and audit.