Skip to main content
Ledger entries are the foundation of Rinne’s financial accounting system. Every monetary movement in the platform—whether a transaction, fee, cost, or refund—is recorded as immutable ledger entries following double-entry bookkeeping principles.

What are ledger entries?

A ledger entry is an immutable accounting record that represents a single monetary movement. Each entry contains:
  • Amount: The monetary value (always positive, stored in cents)
  • Operation: Either CREDIT (money received) or DEBIT (money owed/paid)
  • Type: The economic subject (what the money represents)
  • Owner: Who the entry belongs to (company, platform, or provider)
  • Payment date: When the money is expected to move
Ledger entries are always created in balanced pairs or groups called posting sets, where the sum of all credits equals the sum of all debits.

Entity relationships

Core concepts

Posting sets

A posting set is a balanced group of ledger entries created by a single business event (like a transaction approval). Every posting set must net to zero:
Σ(credits) = Σ(debits)
This ensures the integrity of the double-entry accounting system.

Pair tokens

Ledger entries are linked in pairs using a pair_token. Each pair represents a complete accounting transaction with one CREDIT and one DEBIT entry. For example:
  • Merchant receives R100(CREDIT)ProviderpaysR100 (CREDIT) ↔ Provider pays R100 (DEBIT)

Owner types

Ledger entries can belong to three types of owners:
  • COMPANY: Organizations and merchants in your platform
  • PLATFORM: Rinne platform itself
  • PROVIDER: Payment providers (e.g., Celcoin)

Ledger entry types

Transaction processing

When a transaction is approved, Rinne creates four pairs of ledger entries:
The main transaction amount owed to the merchant.Example: R$100 PIX transaction
  • Merchant: R$100 CREDIT (receives money)
  • Provider: R$100 DEBIT (pays merchant)
Commercial fee owed to the organization (parent company).Example: 2.5% fee on R$100 transaction
  • Merchant: R$2.50 DEBIT (pays fee)
  • Organization: R$2.50 CREDIT (receives fee)
Processing fee owed to Rinne platform.Example: 1.0% cost on R$100 transaction
  • Organization: R$1.00 DEBIT (pays cost)
  • Platform: R$1.00 CREDIT (receives cost)
Service fee owed to the payment provider.Example: R$0.12 fixed cost
  • Platform: R$0.12 DEBIT (pays cost)
  • Provider: R$0.12 CREDIT (receives cost)

Refund processing

When a refund is processed, Rinne creates similar pairs but with reversed operations:
Main refund amount returned to customer.Example: R$50 refund
  • Merchant: R$50 DEBIT (returns money)
  • Provider: R$50 CREDIT (processes refund)
Fee returned to the merchant for the refund.Example: 2.5% fee refund on R$50
  • Merchant: R$1.25 CREDIT (receives fee back)
  • Organization: R$1.25 DEBIT (returns fee)
Platform cost for performing the refund operation.Example: 1.0% refund cost on R$50
  • Organization: R$0.50 DEBIT (pays refund cost)
  • Platform: R$0.50 CREDIT (receives refund cost)
Provider cost for performing the refund operation.Example: R$0.12 fixed refund cost
  • Platform: R$0.12 DEBIT (pays refund cost)
  • Provider: R$0.12 CREDIT (receives refund cost)

Complete transaction example

Here’s a complete R$100 PIX transaction with all ledger entries:
{
  "posting_set": {
    "id": "ps_123",
    "event_name": "transaction.status-changed",
    "created_at": "2025-01-15T10:30:00Z"
  },
  "ledger_entries": [
    // 1. Transaction pair (R$100)
    {
      "owner_type": "COMPANY",
      "owner_id": "merchant_123",
      "amount": 10000,
      "operation": "CREDIT",
      "type": "TRANSACTION"
    },
    {
      "owner_type": "PROVIDER",
      "owner_id": "celcoin",
      "amount": 10000,
      "operation": "DEBIT",
      "type": "TRANSACTION"
    },
    // 2. Organization fee pair (R$2.50)
    {
      "owner_type": "COMPANY",
      "owner_id": "merchant_123",
      "amount": 250,
      "operation": "DEBIT",
      "type": "ORGANIZATION_FEE"
    },
    {
      "owner_type": "COMPANY",
      "owner_id": "org_456",
      "amount": 250,
      "operation": "CREDIT",
      "type": "ORGANIZATION_FEE"
    },
    // 3. Platform cost pair (R$1.00)
    {
      "owner_type": "COMPANY",
      "owner_id": "org_456",
      "amount": 100,
      "operation": "DEBIT",
      "type": "PLATFORM_COST"
    },
    {
      "owner_type": "PLATFORM",
      "owner_id": "RINNE",
      "amount": 100,
      "operation": "CREDIT",
      "type": "PLATFORM_COST"
    },
    // 4. Provider cost pair (R$0.12)
    {
      "owner_type": "PLATFORM",
      "owner_id": "RINNE",
      "amount": 12,
      "operation": "DEBIT",
      "type": "PROVIDER_COST"
    },
    {
      "owner_type": "PROVIDER",
      "owner_id": "celcoin",
      "amount": 12,
      "operation": "CREDIT",
      "type": "PROVIDER_COST"
    }
  ]
}
Balance verification:
  • Credits: R100+R100 + R2.50 + R1.00+R1.00 + R0.12 = R$103.62
  • Debits: R100+R100 + R2.50 + R1.00+R1.00 + R0.12 = R$103.62 ✓

Settlement tracking

Each ledger entry tracks its settlement status:
  • outstanding_amount: How much is still unsettled
  • settled: Whether the entry is fully settled
  • fully_settled_at: When it became fully settled
  • last_clearing_at: Most recent settlement
Ledger entries start with outstanding_amount = amount and settled = false. As settlement items are created, the outstanding amount decreases until the entry is fully settled.

Payment dates and installments

Payment date calculation

Payment dates are calculated based on the transaction approval date and payment method:
  • PIX: Same day (D+0)
  • Debit card: Next day (D+1)
  • Credit card: 30 days later (D+30)

Installment support

For credit card transactions with installments, Rinne creates separate ledger entries for each installment:
{
  "installment": 1,
  "total_installments": 3,
  "amount": 3334,
  "payment_date": "2025-01-15"
},
{
  "installment": 2,
  "total_installments": 3,
  "amount": 3333,
  "payment_date": "2025-02-15"
},
{
  "installment": 3,
  "total_installments": 3,
  "amount": 3333,
  "payment_date": "2025-03-15"
}

Precision and rounding

Rinne uses sophisticated rounding strategies to ensure financial accuracy:

Floor + remainder distribution

When dividing amounts across installments, Rinne uses floor division with remainder distribution to prevent zero amounts:
// Example: R$1.00 (100 cents) split into 3 installments
const n = 3; // installments
const amount = 100; // cents

// Installment 1: floor(100/3) + (1 <= 100%3 ? 1 : 0) = 33 + 1 = 34 cents
// Installment 2: floor(100/3) + (2 <= 100%3 ? 1 : 0) = 33 + 0 = 33 cents
// Installment 3: floor(100/3) + (3 <= 100%3 ? 1 : 0) = 33 + 0 = 33 cents
// Total: 34 + 33 + 33 = 100 cents ✓

Balancing adjustments

After generating all ledger entries, Rinne applies balancing adjustments to the first installment to ensure exact totals:
  1. Calculate expected totals (transaction amount, fees, costs)
  2. Calculate actual totals from generated entries
  3. Apply differences to first installment entries
This ensures that Σ(installments) = expected_total exactly.

Immutability and corrections

Ledger entries are immutable once created. You cannot modify the core fields:
  • amount
  • operation
  • type
  • owner information
  • payment_date
  • business linkages (transaction_id, refund_id, etc.)
If a correction is needed, create new ledger entries in a new posting set to represent the correction.

Key principles

Double-entry

Every posting set must balance: credits = debits

Immutable

Core fields cannot be changed after creation

Precise

Sophisticated rounding ensures exact totals

Traceable

Full audit trail from creation to settlement

Next steps