Payments code has a strange property: most of it is boring, and the boring parts are exactly where money goes missing. Webhook handlers, money arithmetic, reconciliation jobs — the unglamorous plumbing every team rebuilds, slightly wrong, at every company. After close to two decades working on payment systems, I kept running into the same three mistakes, each cheap to make and expensive to find. So I wrote three small, dependency-free, MIT-licensed tools that each fix one.
This post walks through the failure modes and the fixes. The code below is illustrative, but it mirrors what the tools actually do.
Failure mode 1: webhooks you can't actually trust
A webhook is an unauthenticated POST from the internet until you prove otherwise. The naive handler trusts the body. The slightly-better handler verifies a signature but still gets it wrong in two ways: it compares the signature with a normal string equality, which leaks timing information an attacker can exploit byte by byte, and it has no replay protection, so a captured-and-resent event is accepted again.
# Anti-pattern: trusts the payload, and == leaks timing.






