Payout Ledger

A payout monitor for a marketplace. It ingests Stripe-style webhooks, records every money movement in a double-entry ledger, reconciles against the payment provider, and alerts on failed or stuck payouts. Use the simulator below to send it duplicate, out-of-order and missing webhooks and watch what it does.

Source code · Design decisions · Schema and invariants

Needs attention
1
1 open alert, 0 open mismatches
Webhook events
20
All applied
Payouts
4
3 paid, 0 in flight, 1 failed
Owed to sellers
$108.00
Ledger sums to zero

Simulator

Each button sends a set of signed webhooks through the same endpoint and verification as real Stripe events. The simulated provider keeps its own record of what really happened, which is what reconciliation compares against.

Normal payout

A charge, a transfer to the seller and a payout that is paid. Every webhook arrives once, in order.

Duplicate delivery

The same flow, but every webhook is delivered twice.

Out-of-order delivery

The webhooks arrive in reverse: the payout is reported paid before the charge that funded it.

Dropped webhook

The provider marks the payout paid, but that final webhook never arrives.

Failed payout

The bank rejects the payout after it was sent.

Stuck payout

A payout went in transit three days ago and nothing has been heard since.

Retries waiting events, reconciles against the source, raises alerts. Also runs every 15 minutes.

Checks last ran 46 minutes ago: 12 objects compared.

Alerts

Raised while a condition holds, resolved when it stops.

  • Payout failed22 hours ago

    Payout of $108.00 to acct_sim_003 failed (account_closed). The amount was returned to the seller's balance.

    po_sim_f7d37e03

Reconciliation

Differences between the provider's record and the ledger.

No mismatches found.

Recent payouts

PayoutSellerAmountStatusChanged
po_sim_f7d37e03acct_sim_003$108.00Failed (account_closed)23 hours ago
po_sim_401b088dacct_sim_002$43.20Paid23 hours ago
po_sim_01c86900acct_sim_004$66.15Paid23 hours ago
po_sim_9939482dacct_sim_003$43.20Paid23 hours ago

Webhook inbox

Every event is stored once, then applied exactly once. Events that arrive before the funds they depend on wait here and are retried.

EventTypeResultReceived
evt_sim_f7d37e03_failedpayout.failedApplied22 hours ago
evt_sim_f7d37e03_in_transitpayout.updatedApplied22 hours ago
evt_sim_f7d37e03_pendingpayout.createdApplied22 hours ago
evt_sim_f7d37e03_transfertransfer.createdApplied22 hours ago
evt_sim_f7d37e03_chargecharge.succeededApplied22 hours ago
evt_sim_401b088d_paidpayout.paidApplied22 hours ago
evt_sim_401b088d_in_transitpayout.updatedApplied22 hours ago
evt_sim_401b088d_pendingpayout.createdApplied22 hours ago
evt_sim_401b088d_transfertransfer.createdApplied22 hours ago
evt_sim_401b088d_chargecharge.succeededApplied23 hours ago
evt_sim_01c86900_paidpayout.paidApplied23 hours ago
evt_sim_01c86900_in_transitpayout.updatedApplied23 hours ago
evt_sim_01c86900_pendingpayout.createdApplied23 hours ago
evt_sim_01c86900_transfertransfer.createdApplied23 hours ago
evt_sim_01c86900_chargecharge.succeededApplied23 hours ago