Skip to main content

Transaction, Settlement, Split, and Refund

Transaction

A Transaction represents a financial agreement between two or more Accounts — a process, not a direct money movement. It orchestrates Participants (Accounts with a specific role, like "buyer" or "seller"), follows a Workflow Version, and eventually results in a Settlement.

Settlement is not Payout — read this before assuming money moves immediately

Settlement never "sends funds" by itself. What executeSettlement() genuinely does, always, regardless of policy: it computes the Fee, applies the Split, and turns each Participant's share into a real economic obligation — a Payable/Receivable owed to that beneficiary. Whether that obligation is paid out immediately or later is a completely separate decision, controlled by PayoutPolicy:

  • Under PayoutPolicy.Immediate (the common case, and what every worked example on this site uses) — Settlement itself triggers real execution the same moment: under Self-Custody, this means building a SigningRequest and one ExecutionLeg per beneficiary (see Self-Custody), never a direct Ledger credit.
  • Under PayoutPolicy.Threshold/Scheduled/Manual — the beneficiary's share becomes a Payable (an accrued, owed-but-not-yet-paid balance, readable via getPayableSummary) and is only actually paid out later, when a PayoutBatch executes. A PayoutBatch can only be created with trigger = Manual through the public API todayThresholdCrossed and Scheduled exist in the domain model but have no public route to trigger them yet; don't build an integration that assumes either is available.

A Payable (what a beneficiary is owed) is never the same thing as an on-chain balance. Under Self-Custody, once a beneficiary's ExecutionLeg confirms, the money has genuinely left the platform's custody — sent to that beneficiary's own registered ExecutionDestination, an address outside Ishtaran entirely. There is nothing left in the Ledger to hold as an Available balance for that beneficiary; the platform instead records Delivered, cumulative history of what was actually paid (getPayableSummary().paid), never confused with a spendable Ledger balance.

Broadcasting a beneficiary's ExecutionLeg — or the Platform Fee's own leg — costs real network resources (e.g. TRON Energy/Bandwidth). That cost is charged separately from the Platform Fee, to a NetworkCostPayerAccount registered once per Organization/AssetNetwork (see Self-Custody) — without one, the first real Settlement with anything to pay out fails before it builds a SigningRequest. Platform Fee and Network Execution Fee are two different, independently-tracked numbers — never assume the Fee shown on a Settlement already includes network cost, and never assume network cost is fixed (it's quoted fresh, per broadcast). See Network Execution for who actually supplies that resource (CUSTOMER_RESOURCES vs ISHTARAN_RESOURCES) and how to fund it the first time.

Partial Settlement

A Partial Settlement releases only part of a Transaction's reserved value in one call, keeping the rest reserved for a later call. Every Settlement is balanced in the Ledger — the distributed sum never exceeds the reserved balance for that call, and calling it repeatedly on the same Transaction reconciles to exactly the same totals as one single call for the full amount.

Split

The Split defines how a value is distributed among multiple Participants at Settlement time — percentages or fixed amounts, never summing to more than the total settled.

Fee and Pricing Policy

The Platform Fee is the value charged by the platform on a Settlement, calculated according to the Pricing Policy configured for the Organization/Application. The platform's own fee follows the same domain model as customers — no special financial path. This is distinct from the Network Execution Fee described above — never the same number, never derived from one another.

Refund and Reversal

A Refund returns, fully or partially, a value already settled or reserved to an originating Participant — an economic reversal inside the Ledger (a new compensating entry, via a Reversal; an entry is never deleted). A Refund does not, and cannot, "undo" a transaction that already confirmed on-chain — there is no such mechanism, on any blockchain. What Refund actually reverses is the platform's own economic bookkeeping of who owes what.

Workflow is optional

Settlement itself has no technical dependency on Workflow state — executeSettlement() checks only the Transaction's own status (Reserved/PartiallySettled), never a Workflow Rule or Transition. A Workflow is a genuinely optional way to model your own product's lifecycle (see Workflows) and orchestrate when you decide to call executeSettlement() — it is never a gate the platform itself enforces.

Routes