Skip to content

Ledger cash flow

Every paid operation in core (payin, payout, dispute, refund) carries transaction and commission amount. The merchant always pays a single commission amount, but that amount is not kept in one place — it is split between the platform, (optionally) the trader that processed the transaction, and (optionally) a referral agent.

Balances move between wallets as entries, and every entry has a debit_wallet_id (source), credit_wallet_id (target) and operation_code. Each wallet tracks two figures:

  • available — funds that can be spent.
  • held — funds reserved (e.g. during a hold) but not yet settled.

ReactivePay owns a special system profile, identified by profiles.wallet_type = 100. It is a normal profile with normal wallets, one per currency, but it plays a unique role: it is the clearing account for all commission.

When a transaction is approved, the merchant’s full commission_amount is paid into the system wallet, and the system wallet immediately forwards the trader’s and agent’s shares out.

  • The provider share (commission_provider_amount) is the trader’s earnings for processing the transaction. It is forwarded to the trader’s income/profit wallet (not its main wallet) only for a trader-sourced transaction. When there is no trader, this field is still populated on the feed, but no entry moves it, so the amount stays on the system wallet as platform revenue.
  • The agent share (agent_commission_amount) is a referral cut, paid to the agent’s commissional wallet.
  • Whatever remains is the platform’s revenue.
revenue = commission_amount − commission_provider_amount(trader) − agent_commission_amount

For a payout that is inside its trader hold period (amount_in_hold > 0), the provider commission is not forwarded at confirm time — it is deferred until the trader_payout_hold_period time runs out. Until then, the provider share is still sitting on the system wallet, so the system wallet’s net is commission_amount − agent_commission_amount and only drops to the final residual once the time runs out.

The tables below describe the expected net change to each wallet’s available and held for a given transaction type and status.

Notation:

  • A = target_amount (transaction amount)
  • C = commission_amount (merchant commission)
  • Cp = commission_provider_amount (trader/provider commission)
  • Ca = agent_commission_amount (agent commission)

The merchant pays the transaction amount and the commission.

Type Status available held
PayinRequest approved / refunded A − C 0
init / declined 0 0
PayoutRequest init −A − C A + C
approved −A − C 0
declined 0 0
DisputeRequest approved A − C 0
init / declined 0 0
RefundRequest init −A − C A + C
approved −A − C 0
declined 0 0

The clearing account. held is always 0. Since the provider share only used for a trader-sourced transaction, the table uses:

Cp* = Cp when transaction is trader
Cp* = 0 otherwise
Type Status available held
PayinRequest approved / refunded C − Cp* − Ca 0
init / declined 0 0
PayoutRequest approved (amount_in_hold = 0) C − Cp* − Ca 0
approved (amount_in_hold > 0) C − Ca 0
init / declined 0 0
DisputeRequest approved C − Cp* − Ca 0
init / declined 0 0
RefundRequest approved C − Ca 0
init / declined 0 0

Refund operation is not supported by trader

The trader fronts the transaction amount.

Type Status available held
PayinRequest init −A A
approved −A 0
declined / refunded 0 0
PayoutRequest approved (amount_in_hold > 0) 0 A
approved (amount_in_hold = 0) A 0
init / declined 0 0
DisputeRequest init −A A
approved −A 0
declined 0 0

Receives the provider commission.

Type Status available held
PayinRequest approved Cp 0
otherwise 0 0
PayoutRequest approved (amount_in_hold > 0) 0 0
approved (amount_in_hold = 0) Cp 0
otherwise 0 0
DisputeRequest approved Cp 0
otherwise 0 0

When a payout is inside its trader hold period (amount_in_hold > 0), the provider commission has not been credited yet, so the expected change is 0.

Receives the agent commission, regardless of transaction type.

Status available held
approved Ca 0
otherwise 0 0