Payment webhooks arrive out of order, sometimes twice, and occasionally not at all. GetMeChai's ledger had to be idempotent from day one, or creator balances would eventually drift from reality.
Every incoming webhook is written to an events table keyed by Razorpay's event id before any balance mutation happens. If the same event id arrives twice, the second write is a no-op, which makes replays and retries safe by construction.
Balances themselves are never mutated directly. They're derived by summing the events table, so a bug in the derivation logic can be fixed and replayed against history instead of leaving corrupted state behind.