Every payments project begins with the same sentence: "we just need a simple invoice tool." The word "just" is doing the heaviest lifting in that sentence, and it is about to throw its back out.
On a healthcare platform we built billing that started exactly there. It became a real payments system: connected Stripe accounts, card and ACH, and an invoice state machine with every unglamorous state. Draft, sent, unpaid, partially paid, refunded, voided, disputed. Eight states, and each one is a place money can quietly go wrong.
The demo is a button. The product is everything after it.
Anyone can charge a card on the happy path. The job is what happens when the network times out after the charge succeeds but before your server hears back. Did the customer pay? Do you retry? If you retry wrong, you charge them twice, and now you have a refund, an apology, and a trust problem that costs more than the sale.
What "simple" billing actually contains
- An invoice state machine that survives partial payments without losing the plot.
- Idempotency keys, so a retry does not become a second charge.
- Webhook handling that is correct even when webhooks arrive late, twice, or out of order.
- Reconciliation that ties your numbers to Stripe's numbers to the penny.
- Disputes and refunds as first-class states, not as a support ticket and a sigh.
Why correctness beats speed here
You can ship a fast payments feature or a correct one. In healthcare and finance the correct one is the only one that counts, because the cost of a double charge is not a bug ticket. It is a refund, a chargeback fee, and a customer who now reads every invoice you send with one eyebrow up. We shipped this one on a tight deadline without cutting the safety corners, which is the only acceptable way to be fast about money.
When you do not need any of this
If a hosted checkout link covers your entire flow, take the link and go build something else. You do not need a custom payments system to sell one thing at one price to one kind of buyer. Call us when the flow grows a second party, a second currency, or a second way to go wrong. That is when "just an invoice tool" stops being just anything.