sample report

a list of names, a reason, and a fix.

This is the report, rendered from the reference run: 120 Stripe customers against 134 rows in public.subscribers, six disagreements, three critical, with every identifier changed. Nothing here is locked; this is what the full audit looks like.

Sample report120 Stripe customers · 134 app rows

read-only
compared
254
matched
248
critical
3
high
2
of these, unreported
2
6 customers where Stripe and your app disagree.
Paid, no access2 days
priya@saltandthistle.shopaccess: yes→access: no
Paid, no access2 days
jordan@driftwoodgoods.comaccess: yes→access: no
Paid, no access2 days
theo@kettleandvine.coaccess: yes→access: no
Canceled, still active25 days
nora@thistlewickcandles.comaccess: no→access: yes
Refunded, still active7 days
owen@fernandflint.storeaccess: no→access: yes
Paying, no app row9 days
mabel@thegoodloaf.shopaccess: yes→no row

cus_Qf3kT9x2LmN8vRboth sides

Stripe

subscription
active
price
pro · $49.00
period_end
1 Oct 2026
latest_invoice
paid · 3 Sep
refunds
none

public.subscribers

subscribed
false
plan
null
stripe_customer_id
null
subscription_end
null
row created
3 Sep 04:02

Repair the webhook, then backfill this customer

filled in with your real data
A customer paid in Stripe but my app never gave them access. Customer priya@saltandthistle.shop (cus_Qf3kT9x2LmN8vR) has an active Stripe subscription, but in my public.subscribers table their subscribed says they do not have access.

This is almost always the Stripe webhook. Please check, in this order:

1. Is there a webhook endpoint registered in Stripe, and does its URL match a route that actually exists in this app right now? A deploy that renames or moves the route leaves the old URL registered and failing.
2. Does the handler subscribe to checkout.session.completed AND customer.subscription.updated? Missing the second one means renewals and plan changes never land.
3. Does the handler await the database write before returning 200? If it returns first, Stripe sees success while the write silently fails, and there is nothing in the Stripe dashboard to tell you.
4. Is the webhook signing secret the one from this endpoint, in this Stripe mode? A test-mode secret on a live endpoint fails every signature check.

After fixing the handler, backfill this specific customer: in public.subscribers, find the row where stripe_customer_id = 'cus_Qf3kT9x2LmN8vR' and set subscribed to true.

Do not change anything else about how access is granted.
Run your own free scanTwo minutes, read-only, no card.