Skip to main content
Fees Engine applies per-transaction fees and calculates periodic billing charges. This guide covers both workflows: fee packages (per-transaction) and billing packages (per-period).
Not sure which to use? Fee packages apply charges at transaction time. Billing packages calculate charges over a period (daily or monthly) for your orchestrator to execute. You can use both simultaneously.

Fee packages: per-transaction workflow


Fee packages apply charges synchronously when you create a transaction. This section shows the process, from fee setup to results.

Step 1 - Create your fee packages

First, set up fee packages that define how the engine applies fees. Use the Create a Package endpoint. Each package contains a set of fee rules and matching criteria. You can tailor packages to different ledgers, segments, and transaction routes with these fields:
  • transactionRoute - Identifies the nature of the transaction, when you need route-level matching.
  • segmentId - Groups customers or product types, when you need segment-level matching.
  • ledgerId - Defines which ledger records the transaction.
  • Minimum and maximum amount - Optional thresholds for fee application.
  • routeFrom / routeTo - Define how each fee moves across accounting flows.
This flexibility lets you apply distinct fees per scenario, from account-based setups to value-based. Managing Packages The following endpoints are also available for you to manage the packages:

(optional) Step 2 - Run an estimation

To preview how a fee package behaves before you commit a real transaction, use the Estimate Transaction Fees endpoint. This estimation helps validate:
  • Which fee rules apply.
  • How the package will behave with the given values.
  • Whether any exemptions apply.

Step 3 - Create a transaction

Once you set the packages, create the transaction with the create a transaction endpoint. Include ledgerId and any configured matching fields, such as transactionRoute or segmentId, so the engine can evaluate the right package.

Step 4 - The Fees Engine kicks in

Fees Engine automatically calls the Calculate Fees for a Package endpoint. It evaluates whether a package applies, based on:
  • transactionRoute, when configured
  • segmentId, when configured
  • ledgerId
  • Minimum and maximum amount
  • waivedAccounts, when configured for fee exemptions
Fees Engine selects only one package per transaction.

Step 5 - Check for exemptions

The system checks:
  • If the transaction amount is outside the allowed range.
  • If the source account is exempt.
If either condition is true, Fees Engine applies no fees and the transaction proceeds normally.

Step 6 - Fee calculation and application

If a package applies, Fees Engine:
  • Calculates fee values based on the selected applicationRule.
  • Applies fees proportionally across accounts if needed.
  • Uses isDeductibleFrom to set whether it adds or deducts the fee.
  • Routes fees to the correct creditAccount with the configured routeFrom and routeTo.
  • Returns the full transaction result along with the packageAppliedID in the metadata.

Step 7 - Ledger updates

Once Fees Engine calculates the fees, the Transactions component takes over. It processes:
  • Debits from source accounts
  • Credits to fee destinations
  • Fee breakdown per route and account
The ledger stores every movement for full traceability and auditability.

Step 8 - Review and confirm

After execution, you can:
  • Inspect the final transaction and amounts per account.
  • Confirm which fee package applied.
  • Verify all fee movements via metadata and ledger records.

Why estimate a transaction?


Estimations let you preview how a specific fee package behaves, without running a real transaction or writing to the ledger. Use estimations when:
  • You want to test a specific package.
  • You debug fee rules or thresholds.
  • You want to validate exemptions, value ranges, or proportional splits.
  • You need a preview before you create a real transaction.
  • You build an interface and want to show estimated fees.
Fees Engine provides the Estimate Transaction Fees endpoint for this purpose. You pass a packageId, and the endpoint returns what would happen if it applied that exact package.

What do you get with an estimation?

  • A full estimation of the fee rules.
  • Which accounts the engine would charge.
  • How the engine would split the fee.
  • No impact on the ledger.
Use estimations when you’re not ready to commit the transaction, or want to give your users a clear fee preview.

Common errors


Fees Engine validates every request for consistency and correct fee logic. Below are the most frequent issues you might see when you create packages or process transactions.
Want the full list of error codes? You’ll find it in the Fees Engine error list page in the API reference.

Billing packages: per-period workflow


Billing packages calculate charges based on accumulated transaction volume or per-account maintenance over a billing period. Unlike fee packages, your orchestrator triggers billing. It decides when to calculate and executes the resulting charges.

Step 1 — Create billing packages

Set up billing packages that define your periodic charge rules. Each package is either volume or maintenance type. Volume package example — charge per Pix sent with tiered pricing:
Maintenance package example — monthly fee per active PF account:

Step 2 — Trigger billing calculation

Call POST /v1/billing/calculate with the ledger ID and billing period. The engine evaluates all active billing packages matching the criteria.
The period field supports three formats: YYYY-MM (monthly), YYYY-Www (weekly, e.g., 2026-W13), and YYYY-MM-DD (daily). The type field is optional. Use "volume" or "maintenance" to restrict the calculation to one type. Omit it to calculate both types in a single call.

Step 3 — Receive calculation results

The engine returns an array of results. Each result contains a transactionPayload ready to send to Midaz. Each result includes:
  • The billing package that generated it.
  • The calculated amounts with full breakdown (tiers applied, discounts, free quota subtracted).
  • A transaction payload with source.from (debit entries) and distribute.to (credit entries).
  • Structured audit metadata for traceability.

Step 4 — Execute charges

Send each transactionPayload to Midaz via POST /transactions/json to create the actual billing transactions. This step is your orchestrator’s responsibility — Flowker, a cron job, or any other system.
The billing engine calculates and returns results. It does not create transactions in Midaz. Your orchestrator controls when and how it executes charges.

Step 5 — Review and reconcile

After executing the charges:
  • Verify the created transactions in Midaz match the billing calculation results.
  • Use the audit metadata in each result for reconciliation.
  • The billing calculation is stateless — you can re-run it for the same period to verify results.

Managing billing packages

Use these endpoints to manage existing billing packages:
  • GET /v1/billing-packages — List all billing packages.
  • GET /v1/billing-packages/:id — Retrieve a specific billing package.
  • PATCH /v1/billing-packages/:id — Update a billing package (label, description, enable only).
  • DELETE /v1/billing-packages/:id — Soft-delete a billing package.
If any package fails during calculation, the entire operation fails and returns no partial results. Billing calculation follows an all-or-nothing policy. Fix the failing package and re-execute.