Friday afternoon
Ledgerloop sells subscriptions. POST /v1/charges is the last call in its checkout, and about 18% of the month's revenue goes through it.
On Friday a mobile carrier dropped responses for eleven seconds. The apps retried, as apps do: 240 charge requests went out a second time, and 17 customers were charged twice. Support refunded $1,860 that afternoon. Finance held the settlement export for two hours while they worked out which charges were real.
The API took every retry at face value. Nothing in a request tells it "I've already been here", so a retry and a new payment look the same.
What you're changing
Make the endpoint safe to retry. The request and response shapes stay as they are, and so does the charge path behind them; clients depend on both. Leave the payment provider alone, and don't build a durable multi-region ledger here.
What the starter gives you
The API runs locally with an in-memory charge store. make load replays Friday on a small scale: forty concurrent attempts at one checkout, then a line saying how many charges came out of it. Run it once before you change anything.
The local setup only measures what happens at the request boundary. Where the idempotency record would live in production, what happens to it on a restart or a second instance, and how you'd reconcile with the provider go in your README.