You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Not every coworking charge is booking-sized. Per-minute resource usage, printing, and meeting-room overage are too small and too frequent to settle individually on-chain — fees and latency would dominate the payment. Separately, some payments need to split across multiple recipients (platform fee, hub operator payout, referral reward) instead of going to one account. Both problems share the same solution: an internal ledger that batches value movement instead of transacting per event.
This is issue 6 of 7 in the payment track.
Objective
Build an internal double-entry credit ledger for high-frequency, low-value charges with periodic batch settlement to the on-chain rail, plus a configurable multi-party split engine usable both by ledger settlement and by ordinary #1570 payments.
Technical approach
Double-entry ledger: ledger_accounts (one per user, plus system accounts for platform fee/treasury) and append-only ledger_entries (debit/credit pairs that always balance to zero per transaction) — the correct primitive for many small movements with occasional settlement, and a natural audit trail for free.
Spend path: an internal POST /credits/charge (called by resource-usage features, not directly by end-users) debits a user's ledger balance synchronously and cheaply — no blockchain call in the hot path — with overdraft protection (reject on insufficient balance, or allow a documented small overdraft ceiling if graceful degradation is wanted).
Split engine: a RevenueSplitConfig (basis-point recipients) attachable to a Payment or a settlement batch, computed at settlement time and either written as ledger entries (internal) or executed as a multi-recipient on-chain transfer (external payouts). Validates that basis points sum to 100% and uses an explicit remainder-allocation rule (e.g. largest-remainder method) so rounding never loses or duplicates value.
Detailed scope
Ledger schema and service (debit/credit, balance query, overdraft policy).
Charge endpoint plus at least one real call site wired to it (the nearest existing metered feature).
Batch settlement job with admin visibility into pending/settled batches.
Split-config entity and calculation service, with rounding/remainder tests.
High-concurrency charges against the same account — ledger writes must be safe under concurrency (row-level locking or serializable transactions), never losing or double-applying an entry.
Overdraft race: two concurrent charges each individually valid against the last-known balance, but not both together — must not both succeed.
The settlement batch job crashes mid-run — must be resumable without double-settling entries already paid out (an idempotent per-entry settlement marker).
Split basis points don't sum to 10000 (config error) — rejected at configuration time, not discovered at settlement.
Rounding leaves a remainder across split recipients — deterministically allocated per the documented rule, never silently dropped or duplicated.
Depends on #1570 (payment funding a top-up), #1574 (on-chain settlement leg and its failure/retry patterns).
Acceptance criteria
Concurrency test: N simultaneous charges against a fixed starting balance never overdraw past the configured ceiling.
Split-calculation test: basis-point configs across varied amounts always sum exactly to the original amount, no lost or duplicated remainder.
The batch settlement job is safe to re-run mid-failure without double-paying any recipient (idempotency test).
An admin can view a settlement batch's full breakdown: entries in, recipients out, on-chain transaction references.
Definition of done
Ledger and split engine deployed; at least one real metered feature charges through it in staging; the settlement job is scheduled and observable; overdraft and rounding policies are documented.
Problem / Context
Not every coworking charge is booking-sized. Per-minute resource usage, printing, and meeting-room overage are too small and too frequent to settle individually on-chain — fees and latency would dominate the payment. Separately, some payments need to split across multiple recipients (platform fee, hub operator payout, referral reward) instead of going to one account. Both problems share the same solution: an internal ledger that batches value movement instead of transacting per event.
This is issue 6 of 7 in the payment track.
Objective
Build an internal double-entry credit ledger for high-frequency, low-value charges with periodic batch settlement to the on-chain rail, plus a configurable multi-party split engine usable both by ledger settlement and by ordinary #1570 payments.
Technical approach
ledger_accounts(one per user, plus system accounts for platform fee/treasury) and append-onlyledger_entries(debit/credit pairs that always balance to zero per transaction) — the correct primitive for many small movements with occasional settlement, and a natural audit trail for free.POST /credits/charge(called by resource-usage features, not directly by end-users) debits a user's ledger balance synchronously and cheaply — no blockchain call in the hot path — with overdraft protection (reject on insufficient balance, or allow a documented small overdraft ceiling if graceful degradation is wanted).RevenueSplitConfig(basis-point recipients) attachable to aPaymentor a settlement batch, computed at settlement time and either written as ledger entries (internal) or executed as a multi-recipient on-chain transfer (external payouts). Validates that basis points sum to 100% and uses an explicit remainder-allocation rule (e.g. largest-remainder method) so rounding never loses or duplicates value.Detailed scope
Important edge cases and failure scenarios
Dependencies
Depends on #1570 (payment funding a top-up), #1574 (on-chain settlement leg and its failure/retry patterns).
Acceptance criteria
Definition of done
Ledger and split engine deployed; at least one real metered feature charges through it in staging; the settlement job is scheduled and observable; overdraft and rounding policies are documented.