Skip to content

Stripe fulfillment bugThe payment went through in Stripe, but the account was never upgraded

The charge is in your Stripe Dashboard, yet the user still sees the free plan. Stripe did its part. Your app never ran the step that grants access. Here’s where it usually breaks, or hand it over at a fixed price.

Short answer

Most often, the upgrade only runs on the success page after checkout. Stripe says you can’t rely on that page, because customers don’t always reach it. Grant access from a webhook instead, and check the webhook’s delivery log in the Dashboard for failed deliveries.

Where it breaks, and the fix

  1. 01

    The upgrade runs only on the success page

    If the customer closes the tab or loses connection after paying, the success page never loads and nothing upgrades them. Stripe calls webhooks required for subscriptions and for payment methods that succeed later. Handle checkout.session.completed and check that the session’s payment_status isn’t unpaid before granting access. For delayed methods, also handle checkout.session.async_payment_succeeded. For subscriptions, grant access on invoice.paid once the subscription status is active.

  2. 02

    The webhook never arrives or fails

    Open the endpoint in the Dashboard and look at its event deliveries. Check the endpoint is subscribed to the events you handle, is publicly reachable, accepts POST and doesn’t redirect, since Stripe counts a redirect as a failure. A test-mode endpoint never sees live payments. In live mode Stripe retries a failed delivery for up to 3 days, so fix it and resend the event.

  3. 03

    The handler can’t tell which user paid, or times out

    If the handler can’t match the payment to a user in your database, it has nothing to upgrade. Pass your user ID as client_reference_id (or in metadata) when you create the Checkout Session, and read it back from the event. Return a 2xx response quickly, before slow work, so the delivery doesn’t time out. Stripe can send the same event more than once, so make the upgrade safe to run twice.

Checked against the vendor’s docs on : Stripe docs: Fulfill orders (Checkout); Stripe docs: Using webhooks with subscriptions; Stripe docs: Receive Stripe events in your webhook endpoint; Stripe API: Create a Checkout Session (client_reference_id).

Rather hand it over?

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

Related: Stripe webhook signature error

Questions

More on this error

How do I upgrade the customers who already paid?

Fix the handler first. Then resend the missed events from the endpoint’s delivery log in the Dashboard, which works for up to 15 days after each event, or run a one-off script that grants access to every paying customer who doesn’t have it.

Which event should grant access?

For a one-time Checkout payment, checkout.session.completed once the session’s payment_status isn’t unpaid, plus checkout.session.async_payment_succeeded if you accept payment methods that succeed later. For subscriptions, Stripe says to grant access on invoice.paid once the subscription is active, and to remove access when the subscription becomes canceled or unpaid.

Why did some customers get upgraded twice or charged twice?

Double upgrades come from Stripe sending the same event more than once and the handler running it each time. Log the event IDs you’ve processed and skip repeats. Double charges are a different bug, often a checkout button that creates a new session on every click.

Can you fix it for me?

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way.

A different error?

Describe it and get a written quote

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; we reply by email, usually within one business day.