On a live-cam platform, the media session and the money are two state machines running in parallel, and they drift. A dropped connection, a stalled player, a double-submitted tip, or a retried webhook each desynchronise what the viewer experienced from what the ledger charged. The symptom is always a support dispute: “I was charged for a private show that disconnected after thirty seconds.”
The mechanism
Media state is ephemeral and high-frequency; money state must be durable and exact. Private per-minute billing links them: the meter advances while a private session is live, and stops when it ends. The failure modes are all at the boundary between the two:
- The session ends but the meter keeps advancing (connection dropped, edge kept serving).
- The meter stops but the session continues (billing service unreachable, viewer watches free).
- A retried event charges twice (non-idempotent operation).
- A refund or chargeback lands after the money moved, with no record to reconcile against.
The design principle is to make money state authoritative and derive it from durable, idempotent events rather than from live media signals.
Separate money from ephemeral chat
Chat, reactions, presence, and typing indicators are high-volume, low-value, and lossy by design — a dropped chat message is acceptable. Money is not. Do not put financial events on the same lossy, best-effort channel as chat. Use a durable, ordered, at-least-once stream for anything that moves value (tips, private-session start/stop, purchases, payouts) and keep chat separate. This lets you tune the chat path for latency and the money path for correctness independently.
Token and wallet ledgers
Model value as a ledger of immutable entries, not a mutable balance. A balance is a derived sum; the ledger is the truth. Each entry records actor, amount, reason, timestamp, and a unique idempotency key. This gives you:
- Replayability — rebuild any balance from the entries.
- Auditability — answer a dispute with the exact sequence of events.
- Idempotency — a duplicate event is rejected by key, not applied twice.
- Refunds and adjustments as new entries, never edits to history.
Wallets (prepaid balance) and token grants (promotional or per-session credits) both fit this model. Keep performer payouts on the same ledger so the two sides of every transaction reconcile.
Per-minute private billing
Meter private sessions with explicit start and stop events, each carrying the session ID and an idempotency key. Advance the meter on a server-side timer, not on viewer heartbeat alone, so a network blip does not bill phantom minutes or grant free ones. Define and document the rules that always cause disputes:
- Grace period after a drop before the session is considered ended.
- Rounding — bill in whole minutes, seconds, or blocks, stated up front.
- Free preview and minimum-duration rules.
- Concurrency — what happens if the same viewer opens two sessions.
Record the reason for every meter change. “Session ended by viewer at T”, “session ended by grace timeout at T”, “session terminated by performer” are different events and must be distinguishable in the ledger.
Idempotent operations
Every value-moving operation must be safe to retry. Use client-supplied or server-generated idempotency keys, store the result of the first successful application, and return the stored result for duplicates. This applies to:
- Tips and purchases submitted from a flaky mobile client.
- Webhooks from a payment provider (which retry by design).
- Session start/stop events crossing service boundaries.
- Payout and adjustment jobs.
Without idempotency, retries double-charge or double-pay; with it, the ledger stays exact regardless of transport behaviour.
Reconciliation and reserves
Reconciliation is a scheduled job that compares your ledger against the payment provider’s settlement records and flags any divergence for human review. Run it daily, and alert on unmatched entries rather than silently adjusting. Keep a reserve for chargebacks and refunds: adult transactions carry elevated dispute rates, and a reserve turns a surprise loss into a planned cost. Feed the reserve from settled volume and report it alongside payouts so performers and finance see the same picture.
What good looks like
- Value events on a durable, ordered stream, separate from chat.
- Immutable ledger entries with idempotency keys; balances derived, never edited.
- Explicit, reasoned meter events with documented rounding and grace rules.
- Daily reconciliation against provider settlement, with a chargeback reserve.
How to prove it
Replay a week of ledger entries and confirm every balance rebuilds exactly, then simulate duplicate webhooks and dropped sessions and confirm no double-charge and no free minutes. Contact us if you want the media and money paths exercised together on a controlled slice.
Related reading
- Live-cam site for the product context.
- Why live-cam latency feels broken for the session mechanics that feed the meter.
- Onlyfans clone for the creator-payout model.