If you use a hosted payment page like Stripe Checkout, the safest architecture is:

  1. Create an internal order before redirecting.
  2. Redirect the user to the hosted checkout URL.
  3. Use webhooks as the source of truth for fulfillment.
  4. Let the frontend poll order status after return.

This avoids race conditions and ensures users still get entitlements even if they close the tab before the success page loads.

Why This Pattern Works

Hosted checkout redirects are excellent for UX and compliance, but redirects are not guaranteed delivery signals.

A webhook is the reliable signal. The redirect page is only a user-facing state page.

End-to-End Sequence

Stripe checkout flow sequence diagram

High-Level Components

Frontend App

  • Shows plans or packs.
  • Calls backend to create checkout session.
  • Redirects user to hosted checkout.
  • On return page, checks order status and polls while pending.

Backend API

  • Authenticates user.
  • Creates internal order (pending) before payment.
  • Creates hosted checkout session.
  • Verifies webhook signature and fulfills idempotently.
  • Exposes order status endpoint.

Database

  • Plans or packs catalog.
  • orders table/collection.
  • processed_webhook_events for idempotency.
  • User entitlement/credits balance.

API Shape

POST /checkout-session

Request:

{ "planId": "pro_monthly" }

Response:

{ "orderId": "...", "checkoutUrl": "..." }

POST /order-status

Request:

{ "orderId": "..." }

or

{ "sessionId": "..." }

Response:

{ "orderId": "...", "status": "pending|paid|failed|canceled" }

POST /payment-webhook

Stripe calls this endpoint. The backend verifies signature and fulfills idempotently.

Production Checklist

  • Verify webhook signatures with raw request body.
  • Store processed webhook event IDs (idempotency).
  • Create internal order before checkout session creation.
  • Enforce order ownership checks on status API.
  • Keep plan pricing authoritative on backend/DB (never trust client amount).
  • Make fulfillment webhook-driven, not redirect-driven.
  • Add retry-safe entitlement logic (grant once).

Final Takeaway

Treat the hosted checkout redirect as UX, and the webhook as truth.

That single decision makes your billing flow robust, auditable, and far less fragile in real-world conditions.