A serial founder and YC alum who’s raised over $100M across multiple startups said:
“I pay more to Stripe than I do to myself, and they can’t even tell me how much I earn in a simple way. I had to hire a full-time person who reconciles our database with theirs because Stripe doesn’t provide real-time data—let alone notify us when a payment attempt fails. Stripe cancels customer subscriptions automatically after three failed attempts. We lose the customer. We lose the revenue.”
Over the past few weeks, I’ve spoken with dozens of exceptional founder-engineers to listen to their frustrations. Stripe has done extraordinary work to liberate developers from the bureaucratic nightmare that payments used to be. They replaced PDFs with APIs. They turned a tangled mess of financial plumbing into a sleek developer experience. Startups, as a species, owe a huge debt to Stripe.
However, payments and billing are not the same problem. Billing is what happens after a payment is attempted, and is still a disaster.
There’s a moment in every engineer’s career when they realize something they assumed was simple is, in fact, unbelievably complicated. If you’ve ever implemented payments or billing, you’ve had this realization firsthand. At first, it seems straightforward. Customers pay, businesses charge, and Stripe’s API has documentation that rivals the Codex Sinaiticus - how hard can it be? Then, you start actually building it.
What you discover isn’t just complexity; it’s structural decay. Payments, despite being critical infrastructure for nearly every business, are built on layers of abstraction that were never meant to communicate with each other. It’s not a coherent system - it’s an archeological dig through financial tech spanning decades. Each layer is a relic from a different era, built with a different set of assumptions. No universal source of truth, no perfect API, no clean handoff. Who ends up untangling it? Engineers.
A founder reacting to Theo’s video on how Stripe is broken:
“My non-technical co-founder keeps asking me how payments and subscriptions can be so difficult when literally everybody does them. I just shrug.”
Most engineering work is invisible to the outside world, but payments take this to another level. If you get it right, no one notices. The system works, invoices go out, revenue gets collected, and everything hums along. If you get it wrong - if a webhook fails, if a card is declined, if a customer is overcharged, if a usage-based plan isn’t metered correctly - it’s an emergency. It’s the engineer who takes the heat.
The worst part? The burden isn’t evenly distributed. When sales or marketing needs new pricing models, they dream it up and drop it into Slack. Engineering is where that idea collides with reality. Reality is brutal.
Consider the humble webhook. Stripe alone has 258 webhook event types. Many overlap or have subtle differences in meaning. It’s easy to map these incorrectly to significant milestones in your application. For example, when a charge attempt for a Stripe Payment Intent fails, it may not terminally mark the intent as failed, but it will mark the charge as failed. Which event should you listen for?
Similarly, on successful checkout, Stripe redirects the customer to your redirect URL with the payment intent ID. But it also sends a webhook notification. How do you make sure you don’t send two “Welcome” emails or credit their balance twice? Without protection from this complexity, even the simplest MVP needs idempotency strategies from day one to avoid duplicate billing issues.
A Redditor described their experience messing up their webhook integration:
“I was wondering why the hell our users were subscribing twice. Turns out, failed webhooks meant they weren’t being marked as subscribed at all. Stripe said ‘subscribed,’ our app said ‘not subscribed.’ Nightmare.”
Every SaaS company eventually encounters some species of the genus Payments Bug: subscriptions out of sync, invoices with missing line items, silent charge failures, mismatched revenue numbers. Engineers who work on billing don’t just write code - they become part-time forensic accountants, reconciling records between their database and their processor’s.
Roughly speaking, a startup’s billing pains come in three stages: