Money
Entry fees on Sideout are held, split and paid out by Purse, the competition platform underneath it. This page walks one real payment from a card through to a payout, and shows the arithmetic that has to hold at every step. It is the part of the system that Lucra calls security and payments infrastructure.
Two independent descriptions of the same money. The rail knows what it moved; the ledger knows what players are owed. An invariant compares them every fifteen minutes and takes the platform to a failing health check if they ever disagree.
Deposited
$325.00
Every funded deposit, gross.
Withdrawn
$25.00
Every funded withdrawal.
Held in custody
$300.00
Deposited less withdrawn.
Ledger says owed
$300.00
The external settlement account.
Custody and the ledger agree exactly, to the cent, across every payment that has funded.
There is no account of currency USD anywhere in Purse, and the database cannot express one. Dollars sit in custody at the payment provider; the ledger records each player’s claim on them in CREDIT, one unit to one cent. A test asserts that the asset enum has exactly two values and that even the database owner is refused a USD account. That is the compliance boundary written as something that runs.
$200.00 moving across the rail. Each step below is a row written when it happened, in a table the application can insert into and cannot update or delete.
The payment exists; the rail has not been asked yet.
The issuer is holding the funds. Nothing has been taken.
Authorized on the rail for 20000 cents.
The money is taken and the wallet is credited.
Captured on visa ending 4242.
Ledger entry je_01a1a0dc-4616-70bc-947b-d144cc517520
The funds reached the merchant account.
A cash contest takes its rake off the top, as a separate journal entry posted immediately before settlement. Everything left is divided by the prize structure. Because the fee is its own entry, the settlement can only ever distribute the net pool, and the two invariants that check settlement arithmetic did not have to be weakened to allow it.
The fee is its own journal entry, posted before the settlement, so the settlement only ever distributes the net pool. Rounding is down, so the remainder stays with the players rather than being created out of nothing.
The platform fee account’s balance. An invariant proves it equals the sum of every fee entry that credited it, and that each of those debited its own contest’s escrow and no one else’s.
Interchange and processing, a cost rather than revenue. Cards run at 2.9% plus 30¢; a bank debit is a flat 80¢, which is why the instrument a player chooses changes what the platform keeps.
A payments layer is only worth anything for what it does when something goes wrong. These are live rows, not illustrations.
$6.66 declined as card_declined. The payment row exists, its trail records both steps, and nothing touched the ledger: a payment that never funded carries no journal entry, and the database enforces that pairing rather than trusting the service to remember.
$25.00 approved and on its way. The claim left the wallet at approval, before the cash moved, because that is when the player stopped being owed it. ACH takes about 48 hours to confirm, and only then does this become paid.
Read from the provider seam at request time, so the interface cannot drift from what the rail will actually do.
Refused on purpose
A brand that is merely missing from an enum fails as a validation error nobody can act on. These are present, refused, and carry a reason a player can be shown; the database refuses them too, so the rule survives a bug in the service.