Fee packages: per-transaction workflow
Fee packages apply charges synchronously when you create a v2 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 - The ID of a transaction route, when you need route-level matching.
- segmentId - The ID of the segment the source accounts belong to, when you need segment-level matching.
- metadataSelector - Metadata pairs that the transaction must carry, when you need metadata-level matching.
- Ledger scope - The request URL identifies which ledger records the transaction; do not send
ledgerIdin the package body. - Minimum and maximum amount - Optional thresholds for fee application.
- routeFrom / routeTo - Define how each fee moves across accounting flows.
- List Packages - List all packages created.
- Retrieve a Package - Retrieve information of a specific package.
- Update a Package - Update the information of a specific package.
- Delete a Package - Soft-delete a package.
(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 through the v2 transaction API, for example with the Create a Transaction using the v2 direct model endpoint. Only v2 transactions apply fees, including the direct and hold items of a v2 batch. To match a route-scoped package, send the transaction route ID inrouteId. Midaz reads the segment from the source accounts.
Step 4 - The Fees Engine kicks in
Fees Engine runs in-process when Midaz creates the transaction. It evaluates whether a package applies, based on:- transactionRoute, when configured
- segmentId, when configured
- metadataSelector, when configured
- Ledger scope from the request URL
- Minimum and maximum amount
- waivedAccounts, when configured for fee exemptions
Fees Engine selects at most one package per transaction: the most specific match. Each
metadataSelector pair makes a package more specific. When two packages match equally, Midaz refuses the transaction with error 0198.Step 5 - Check for exemptions
The system checks:- If the transaction amount is outside the allowed range.
- If every source account is waived.
@external/<asset>) that Midaz adds to a cross-ledger transaction never pays a fee.
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
isDeductibleFromto set whether it adds or deducts the fee. - Routes fees to the correct
creditAccountwith the configuredrouteFromandrouteTo. - Returns the full transaction result along with the
packageAppliedIDin 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
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.
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.
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.
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, a charge per Pix sent with tiered pricing:Step 2: Trigger billing calculation
CallPOST /v2/organizations/{organization_id}/ledgers/{ledger_id}/billing/calculate with the billing period. The URL identifies the ledger. The engine evaluates every enabled billing package in the ledger, limited to the type you send.
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 atransactionPayload ready to send to Midaz.
Each result includes:
- The billing package that generated it.
- The calculated amounts.
- A transaction payload with
source.from(debit entries) anddistribute.to(credit entries). - Structured audit metadata for traceability.
Step 4: Execute charges
Send eachtransactionPayload to Midaz via POST /v1/organizations/{organization_id}/ledgers/{ledger_id}/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. A re-run for the same period reflects the ledger at the time of the re-run.
Managing billing packages
Use these endpoints to manage existing billing packages:GET /v2/organizations/{organization_id}/ledgers/{ledger_id}/billing-packages: List all billing packages.GET /v2/organizations/{organization_id}/ledgers/{ledger_id}/billing-packages/{id}: Retrieve a specific billing package.PATCH /v2/organizations/{organization_id}/ledgers/{ledger_id}/billing-packages/{id}: Update a billing package (label,description,enableonly).DELETE /v2/organizations/{organization_id}/ledgers/{ledger_id}/billing-packages/{id}: Soft-delete a billing package.

