Ledger e splits
Como um pagamento é dividido entre vendedor, parceiro, markup da plataforma e a taxa de 0,50 %, e como cada unidade é lançada.
Última atualização 27 de out. de 2026
A cascata de taxas
computeFees() (domain/fee-engine.ts) é o único lugar onde os valores são divididos. Ele trabalha nas unidades base inteiras do token (bigint), nunca em floats, e POST /api/v1/crypto/quote retorna exatamente o que ele calcula. Cada componente é uma porcentagem do valor base (o preço em USD da invoice), arredondado para baixo:
processing fee = base × 50 bps (CRYPTO_PLATFORM_FEE_BPS, per-org override possible)
markup = base × markup_percent (the platform's own cut, 0–20 %)
partner_i = base × splits[i].percent
fee_payer CUSTOMER: total = base + processing fee + markup; seller net = base − Σ partners
fee_payer MERCHANT: total = base; seller net = base − fee − markup − Σ partners
invariant: seller net + Σ partners + markup + processing fee = total (the seller absorbs rounding)A invoice mínima é de 1,00 USD; o USD corresponde 1 : 1 à stablecoin.
Exemplo prático: 90 / 10 / 2 / 0,50
Uma licença de 100,00 USD vendida pela Halden Type na plataforma, com a Kerning Weekly (um parceiro) ficando com 10 %, um markup de 2 % da plataforma e o comprador pagando as taxas:
{ "amount": "100.00", "fee_payer": "CUSTOMER", "markup_percent": 2,
"merchant": "halden_type", "splits": [{ "account": "kerning_weekly", "percent": 10 }] }| Quem | Valor |
|---|---|
| Halden Type (líquido do vendedor) | 90.00 |
| Kerning Weekly (parceiro) | 10.00 |
| Markup da plataforma | 2.00 |
| Taxa de processamento Aliquot (0,50 %) | 0.50 |
O comprador paga (total) | 102.50 USDT |
Depois que o transfer é confirmado, uma única transação balanceada no ledger (invoice:<id>:settlement) o lança:
| Conta | Débito | Crédito |
|---|---|---|
ASSET:ONCHAIN_CUSTODY:POLYGON_AMOY:USDT | 102.50 | |
LIABILITY:MERCHANT_SETTLEMENT:<halden_type>:POLYGON_AMOY:USDT | 90.00 | |
LIABILITY:PARTNER_PAYABLE:<kerning_weekly>:POLYGON_AMOY:USDT | 10.00 | |
LIABILITY:PARTNER_PAYABLE:<platform>:POLYGON_AMOY:USDT | 2.00 | |
REVENUE:PLATFORM_PROCESSING_FEE:POLYGON_AMOY:USDT | 0.50 |
O recibo do checkout desenha o mesmo corte na barra de split (vendedor · markup · taxa; as participações dos parceiros não são mostradas ao comprador), e a aba Ledger da invoice no dashboard mostra essas linhas com uma verificação "Balanced". Com fee_payer: "MERCHANT" o comprador paga 100.00 e a taxa e o markup saem da parte de 90.00 do vendedor (87.50 líquido).
Um pagamento a mais adiciona um crédito em LIABILITY:REFUND_ESCROW:<invoice> pelo excedente; veja Refunds.
Regras do ledger
- Código de conta =
TYPE:NAME[:holder]:NETWORK:CURRENCY. Cada rede e cada token têm suas próprias contas, então os saldos nunca misturam chains ou moedas; o gas é lançado na moeda nativa (EXPENSE:ONCHAIN_GAS:…:POL). - Os saldos só mudam por meio de postings construídos pelas factories em
domain/ledger.ts(settlement, escrow, sweep, payout lock / complete / release, refund, funding do operador). Cada um tem uma chave de idempotência determinística; lançá-lo de novo é um replay seguro. - O banco de dados garante a contabilidade: débitos iguais a créditos por transação, rede e moeda (um trigger deferido verificado no commit), as linhas do journal são append-only, e o saldo de uma conta nunca pode ficar abaixo de zero (
CHECK). Um saque a descoberto faz rollback de todo o posting e aparece como409 INSUFFICIENT_BALANCE. - O ledger não tem foreign keys para organizações: a contabilidade precisa sobreviver à exclusão de um tenant. As leituras são sempre filtradas por organização.
Onde o dinheiro está on chain
O endereço de depósito recebe o pagamento. O job sweep do worker (a cada 15 s) move os depósitos confirmados para a hot wallet (índice 0), abastecendo antes o depósito com gas nativo; o ledger move ONCHAIN_CUSTODY → HOT_WALLET e lança o gas. Payouts e refunds são enviados a partir da hot wallet, nunca acima do seu saldo on-chain menos os envios ainda não minerados.
Endpoints de leitura: GET /api/v1/crypto/balances?mode= (disponível e bloqueado por conta × rede × token), GET /api/v1/crypto/ledger/transactions, GET /api/v1/crypto/ledger/accounts, GET /api/v1/crypto/overview.