DEV Community

Lin Xi
Lin Xi

Posted on

A Checkout Button Is Not a Payment Flow



A pricing page can feel finished when its Buy button opens checkout. The harder question is what tells the product to deliver what was sold.

Four handoffs

Separate the offer, checkout session, payment confirmation, and fulfillment. A flow is broken if the offer says monthly but checkout charges annually, or if payment succeeds while the account stays on a free plan.

Verify payment on the server

Do not mark an order paid because a buyer reached the return page. A browser redirect is a page visit, not a payment record. For Stripe, verify the provider event and use webhooks for fulfillment. The handler must be safe when the same notification arrives more than once.

Test the awkward paths

  • Cancel checkout: return safely, with no paid message and no access.
  • Delayed confirmation: show pending, not premature success.
  • Duplicate notification: keep one order and one entitlement.
  • Declined payment: explain the failure and allow a safe retry.

Run these cases in a sandbox. Complete a payment, close the browser before the return page loads, then cancel, decline, and replay the notification. Check the buyer message, order state, and actual entitlement each time.

Sources: https://docs.stripe.com/checkout/fulfillment?payment-ui=stripe-hosted and https://docs.stripe.com/testing

Disclosure: This article was drafted with AI assistance and reviewed for technical accuracy by the author.

Top comments (0)