Settlement items are the bridge between accounting records (ledger entries ) and actual money movements. While ledger entries record what should happen financially, settlement items track what actually happened—when money moved, how it moved, and to where.
What are settlement items?
A settlement item is a clearing link that applies a portion (or all) of a ledger entry to a real settlement operation. Each settlement item represents an actual money movement:
PIX payment to a merchant’s bank account
Internal transfer between accounts
Invoice payment for monthly costs
Boleto payment for settlements
Entity relationships
Core attributes
Each settlement item contains:
ledger_entry_id : Which ledger entry is being settled
settled_amount : How much of the entry is being settled (in cents)
settlement_date : When the money actually moved (date-only format: YYYY-MM-DD)
method : How the money moved (PIX, internal transfer, etc.)
status : Current state of the settlement
operation_id : External reference (transaction ID, transfer ID, etc.)
affiliation_bank_account_id : Destination bank account (if applicable)
Settlement methods
Rinne supports multiple settlement methods:
PIX Instant payments to merchant bank accounts (D+0)
Internal transfer Transfers between Rinne accounts (organization fees)
Invoice Monthly invoices for platform/provider costs
Boleto Bank slip payments for settlements
Settlement status lifecycle
Settlement items follow a state machine with strict transition rules:
Valid transitions
PENDING → PROCESSING : Settlement initiated
PENDING → PAID : Instant settlement (PIX)
PENDING → FAILED : Settlement failed immediately
PROCESSING → PAID : Settlement completed
PROCESSING → FAILED : Settlement failed during processing
Terminal states
PAID : Settlement completed successfully (no further transitions)
FAILED : Settlement failed permanently (no further transitions)
PIX settlement flow
For PIX transactions, Rinne creates settlement items immediately after the transaction is approved:
1. Transaction settlement
The main transaction amount is settled instantly:
{
"ledger_entry_id" : "le_merchant_tx_credit" ,
"settled_amount" : 10000 ,
"settlement_date" : "2025-01-15" ,
"method" : "PIX" ,
"status" : "PAID" ,
"operation_id" : "trx_456" ,
"affiliation_bank_account_id" : "ba_merchant_account"
}
The settlement_date field is returned in date-only format (YYYY-MM-DD) without time information, representing the calendar day when the settlement occurred.
The provider’s corresponding debit is also settled:
{
"ledger_entry_id" : "le_provider_tx_debit" ,
"settled_amount" : 10000 ,
"settlement_date" : "2025-01-15" ,
"method" : "INTERNAL_TRANSFER" ,
"status" : "PAID" ,
"operation_id" : "trx_456"
}
2. Organization fee settlement
Organization fees are settled via internal transfer:
{
"ledger_entry_id" : "le_merchant_fee_debit" ,
"settled_amount" : 250 ,
"settlement_date" : "2025-01-15" ,
"method" : "INTERNAL_TRANSFER" ,
"status" : "PENDING" ,
"operation_id" : "internal_transfer_789"
}
When the internal transfer completes, the status updates to PAID.
Platform and provider costs remain outstanding for monthly invoice settlement:
{
"ledger_entry_id" : "le_platform_cost_credit" ,
"outstanding_amount" : 100 ,
"settled" : false
}
Ledger entry updates
When settlement items are created or updated, the corresponding ledger entries are automatically updated:
Outstanding amount calculation
outstanding_amount = amount - Σ ( settled_amount from non - FAILED settlement items )
Settlement status
settled = ( outstanding_amount === 0 )
fully_settled_at = settled ? now () : null
last_clearing_at = most_recent_settlement_date
Example progression
Initial state (after ledger entry creation):
{
"id" : "le_merchant_fee_debit" ,
"amount" : 250 ,
"outstanding_amount" : 250 ,
"settled" : false ,
"fully_settled_at" : null ,
"last_clearing_at" : null
}
After settlement item creation (PAID):
{
"id" : "le_merchant_fee_debit" ,
"amount" : 250 ,
"outstanding_amount" : 0 ,
"settled" : true ,
"fully_settled_at" : "2025-01-15T10:35:00Z" ,
"last_clearing_at" : "2025-01-15T10:35:00Z"
}
Partial settlements
Settlement items support partial settlements, where a ledger entry is settled in multiple operations:
// First settlement: R$50 of R$100
{
"ledger_entry_id" : "le_123" ,
"settled_amount" : 5000 ,
"method" : "PIX" ,
"status" : "PAID"
}
// Second settlement: R$30 of R$100
{
"ledger_entry_id" : "le_123" ,
"settled_amount" : 3000 ,
"method" : "PIX" ,
"status" : "PAID"
}
// Third settlement: R$20 of R$100
{
"ledger_entry_id" : "le_123" ,
"settled_amount" : 2000 ,
"method" : "PIX" ,
"status" : "PAID"
}
The ledger entry tracks the total:
{
"id" : "le_123" ,
"amount" : 10000 ,
"outstanding_amount" : 0 ,
"settled" : true
}
Refund settlements
Refund settlements follow the same pattern as transaction settlements:
Transaction refund
{
"ledger_entry_id" : "le_merchant_refund_debit" ,
"settled_amount" : 5000 ,
"settlement_date" : "2025-01-15" ,
"method" : "PIX" ,
"status" : "PAID" ,
"operation_id" : "refund_456"
}
Organization fee refund
{
"ledger_entry_id" : "le_merchant_fee_refund_credit" ,
"settled_amount" : 125 ,
"settlement_date" : "2025-01-15" ,
"method" : "INTERNAL_TRANSFER" ,
"status" : "PAID" ,
"operation_id" : "internal_transfer_890"
}
Idempotency
Settlement item creation is idempotent. If settlement items already exist for a ledger entry and operation ID, Rinne skips creation:
// Check for existing settlement items
const existingItems = await findSettlementItemsByLedgerEntryIdAndOperationId (
ledgerEntryId ,
operationId
);
// Calculate total settled amount (excluding FAILED)
const totalSettled = existingItems
. filter ( item => item . status !== 'FAILED' )
. reduce (( sum , item ) => sum + item . settled_amount , 0 );
// Skip if already fully settled
if ( totalSettled >= ledgerEntry . amount ) {
return ; // Already settled
}
Settlement invariants
Rinne enforces strict invariants for settlement items:
Settlement bounds
Σ ( settled_amount ) ≤ ledger_entry . amount
You cannot settle more than the original ledger entry amount.
Outstanding accuracy
ledger_entry . amount = Σ ( settled_amount ) + outstanding_amount
The sum of settled amounts plus outstanding amount must equal the original amount.
Non-negative outstanding
Outstanding amounts can never be negative.
Settlement status consistency
settled = true ⟺ outstanding_amount = 0
A ledger entry is settled if and only if the outstanding amount is zero.
Complete settlement example
Here’s a complete example showing how a R$100 PIX transaction is settled:
1. Ledger entries created
{
"merchant_credit" : {
"amount" : 10000 ,
"outstanding_amount" : 10000 ,
"settled" : false
},
"organization_fee_debit" : {
"amount" : 250 ,
"outstanding_amount" : 250 ,
"settled" : false
}
}
2. Settlement items created
{
"merchant_settlement" : {
"ledger_entry_id" : "merchant_credit" ,
"settled_amount" : 10000 ,
"method" : "PIX" ,
"status" : "PAID"
},
"fee_settlement" : {
"ledger_entry_id" : "organization_fee_debit" ,
"settled_amount" : 250 ,
"method" : "INTERNAL_TRANSFER" ,
"status" : "PENDING"
}
}
3. Ledger entries updated
{
"merchant_credit" : {
"amount" : 10000 ,
"outstanding_amount" : 0 ,
"settled" : true ,
"fully_settled_at" : "2025-01-15T10:30:00Z"
},
"organization_fee_debit" : {
"amount" : 250 ,
"outstanding_amount" : 0 ,
"settled" : true ,
"fully_settled_at" : "2025-01-15T10:35:00Z"
}
}
Key principles
Actual movements Track real money movements, not just accounting
State machine Strict status transitions prevent invalid states
Race-safe Two-step creation prevents race conditions
Idempotent Safe to retry settlement operations
Next steps