Donation Platforms
Per-project fund tracking with automatic fee splitting and consolidated revenue.
Donation Platforms
Modeling a donation platform requires strict tracking of funds dedicated to specific projects while ensuring the platform's fees are correctly accounted for.
Using split transfers, a single donation is atomically divided into the project's funds and the platform's fee — each tracked as its own transfer from the very first moment.
Entity Structure
| Account | Purpose |
|---|---|
@world | External payment source |
Project A - Funds | Donations held for Project A |
Platform Revenue | Consolidated platform fees |
User Bank Account | External payout destination |
Visual Flow
A $100 donation with a 5% platform fee, split at the time of donation:
The fee is separated at donation time — not after. This means the project balance always reflects the actual available amount, and there's a clear audit trail of every fee.
Implementation
Receive Donation with Fee Split
A single POST /transfers with a split array. The $100 is atomically divided:
{
"ledger_id": "...",
"debit_account_id": "world_account_id",
"amount": 10000,
"code": 10,
"split": [
{ "account_id": "project_a_funds_id", "amount": 9500 },
{ "account_id": "platform_revenue_id", "amount": 500 }
],
"metadata": {
"project_id": "proj_123",
"donor_id": "user_456"
}
}Each leg gets its own transfer ID — the project balance is immediately $95 (not $100 minus a later deduction).
Payout to Project Owner
When the campaign ends, move the project funds to the user's bank account:
{
"ledger_id": "...",
"debit_account_id": "project_a_funds_id",
"credit_account_id": "user_bank_id",
"amount": 9500,
"code": 30
}Key Benefits
- Accurate project balance: The project account always shows the real available amount (after fees), not a gross total that needs adjustment later.
- Per-project fee tracking: Query transfers on
platform_revenue_idfiltered by project metadata to see exactly how much each project contributed to revenue. - Atomic split: The donation either splits correctly or fails entirely — no orphaned fee records.
- Simple payout: When the campaign ends, the project balance is the exact payout amount.