A successful payment is not the same thing as a successful order.

For a SaaS product that generates a personalized file after checkout, fulfillment usually crosses several systems: the browser, your database, Stripe, a PDF renderer, object storage, an email provider, and a download endpoint. Any one of them can fail independently.

We recently hardened this flow for a document-generation product. The most useful lesson was to stop thinking of the webhook as “the function that sends the PDF” and start treating it as an event that advances a persisted state machine.

The fragile version

A tempting first implementation looks like this: