stripe says paid.
your app says free.

We read both records on every run and tell you exactly where they disagree: who is affected, what caused it, and what to paste into your coding tool to fix it.

No account, no card. The free scan shows three findings; the $49 audit shows them all.

your report

Last scan 3 Sep, 04:02 · 254 compared, 248 matched

compared
254
matched
248
critical
3
high
2
of these, unreported
2
elapsed
1.4s
6 customers where Stripe and your app disagree.
Paid, no access3 Sep
priya@saltandthistle.shop cus_Qf3kT9x2LmN8vRactive · pro · $49→subscribed = false
Paid, no access3 Sep
jordan@driftwoodgoods.com cus_R2tKp8vXn4WsQmactive · pro · $49→subscribed = false
Paid, no access4 Sep
theo@kettleandvine.co cus_Nx6Lm3QpT9vRk4active · pro · $49→subscribed = false
Canceled, still activelocked · unlocks in the full audit
Canceled, still activelocked · unlocks in the full audit

nine ways it breaks. 5 are reported by nobody.

Every row below is a documented failure from founder write-ups or Stripe's own docs. The ones marked “no one” never produce a support ticket, because the customer gets something for free and has no reason to write in. Fixing only what customers complain about will never surface them.

stripe · who paid
app · who has access
sam@northlight.ioactive · pro
subscribed: true
maya@lumen.shopactive · pro
subscribed: false
ken@fold.devactive · basic
subscribed: true
mira@corvidsupply.comactive · pro
subscribed: true
lea@setpoint.cotrialing
subscribed: true
paid, no access3 customers since 3 Sep · 12 events undelivered
3 days
Stripe retries a failed webhook, then stops.
$15
US dispute fee, plus $15 again if you contest and lose.
0
Writes we ever make, to Stripe or to your database.
The app tells Stripe the payment saved, then the save fails right after
stripe believespaid
your app believesfree
reported bythe customer
The app crashes on the notification and is never fixed; Stripe gives up after 3 days
stripe believespaid
your app believesfree
reported byno one
The address Stripe sends notifications to changed during a deploy, and nobody updated it
stripe believespaid
your app believesfree, every signup since
reported byweeks later
The app is never told when someone cancels
stripe believescanceled
your app believespro
reported byno one
A refund is issued by hand in Stripe, and the app is never told
stripe believesrefunded
your app believespro
reported byno one
Checkout finishes, but the payment is never linked back to the right customer
stripe believespaid, unknown user
your app believesno row at all
reported bythe customer
The subscription was created by hand in Stripe instead of through checkout
stripe believespaid
your app believesnothing
reported byno one
A database permission rule quietly blocks the app's own save
stripe believespaid
your app believesfree
reported bythe customer
A plan change made in Stripe's billing portal never reaches the app
stripe believesenterprise
your app believesstarter
reported byno one

The break happens after delivery succeeds. Webhook monitoring tools can confirm that Stripe reached your app. None of them checks whether the customer actually got access.

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

The reference run, on a real Lovable schema: 120 Stripe customers, 134 rows in public.subscribers. Six disagreements, one diagnosis.

Sample report120 Stripe customers · 134 app rows

read-only
compared
254
matched
248
critical
3
high
2
of these, unreported
2
elapsed
1.4s
Every row above is a customer or event where Stripe and the app disagree. Here is one, both sides, and the prompt that fixes it.

priya@saltandthistle.shop · both sides

Stripe

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

public.subscribers

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

fix prompt

filled in with your real data
My Stripe webhook endpoint at /api/stripe/webhook is not receiving
events. In the Stripe dashboard the endpoint shows failed deliveries.

Check that the route exists at that path in production, that it
verifies the signature with the live secret, and that it writes
stripe_customer_id and subscribed = true to public.subscribers
before returning 200.

Return 500 on write failure so Stripe retries.

you paste one prompt. we read one table. that's the whole surface we get.

If your app was built with Lovable, Bolt or Replit, you paste one prompt into the builder. It adds a small, read-only page that lists one table, locked with a secret key we give you. We read that page and nothing else. Delete the key from your project and our access ends on the spot.

striperead-only
customer
priya@saltandthistle.shop
subscription
active · pro
last payment
$49 · 3 Sep

A restricted key with read permission only.

your appread-only
customer
priya@saltandthistle.shop
subscribed
false

A read-only page your builder adds, one table.

entitledcompares
Paid, no accesspriya@saltandthistle.shop
What we read: email, plan, and one access field. What we write back: nothing.

what we see, per customer

  • Email or Stripe customer id, to match the two sides
  • The one column that decides access
  • Plan name and renewal date, if you map them

what we never see

  • Any other column in your table
  • Password hashes or access tokens
  • Payment details, from your app or from Stripe

stripe restricted key

  • CustomersRead
  • SubscriptionsRead
  • ChargesRead
  • DisputesRead
  • EventsRead
  • Products & Pricesoptional: only used to compare plan names, skip it and everything else still runs
  • Account (name only)optional: shown once to confirm which account connected, skip it and we just won't show the name

Read access only, never write. When you paste the key we check it has these permissions, and we refuse a full secret key outright, so you cannot hand us more access by mistake.

Only the columns you chose

The prompt tells your builder to return just the columns you picked: customer id, email, and the one field that says whether they have access. Connect your own database instead and we can read those same columns and nothing else.

Read-only on both sides

We only ever ask for data, we never send changes. The Stripe key has no write permission, and a database connection is opened read-only with a login that can only read one table, so even a bug on our side could not change anything.

One fixed IP address

Every read comes from 161.35.64.36. If your database can limit connections by address, allow only this one, and a leaked password is useless from anywhere else.

Your keys are locked away from the website

Keys you give us are encrypted before they are saved. The website itself cannot decrypt them; only the separate process that runs your scans can.

Delete removes everything, at once

One button on your report deletes your keys, your scan results and all history immediately. Nothing is kept for later.

We never read payment methods

No card or bank details from Stripe, and nothing like that from your app. The prompt tells your builder to leave out payment details, passwords and login tokens.

Using your own Postgres (Supabase, Neon, RDS)?+

Only if your app runs on a database you manage yourself, rather than a Lovable Cloud project. Run this in your own SQL editor: nothing here is run for you, and it grants a role that can only read the one table you name.

create role drift_reader with login password '••••••••';
grant connect on database postgres to drift_reader;
grant usage   on schema public     to drift_reader;
grant select  on public.subscribers to drift_reader;

-- required, or the reader sees zero rows
-- and the scan is silently wrong
create policy drift_reader_read on public.subscribers
  for select to drift_reader using (true);

most people just need to fix one bad week.

So the main offer is a one-time audit with seven days of re-runs to prove the fix landed. The annual plan is for people who would rather stop thinking about it: about the price of two audits, for a full year of daily runs.

Free scan
$0
one run

Finding out whether there is a problem at all. Three findings shown, no account.

Run a free scan
Audit
$49
once, 7 days of re-runs

You just got a confused email and need to know how many more there are. Every finding, every fix prompt, CSV export.

Start with a free scan

Choose Audit from your report.

Watch
$99
per year, daily runs

You would rather not learn about the next one from a chargeback. Daily runs, an email only when something changes, a year of history.

Start with a free scan

Choose Watch from your report.

Running several apps, each its own Stripe account? Email us and we will set it up by hand. support@entitled.dev

Every plan starts the same way: two minutes to connect, read-only on both sides, no card until you want the full audit.

Prices exclude VAT where it applies; it is added at checkout.

questions

What if it finds nothing?

Then the report says so: "Stripe and your app agree on every customer." You paid nothing, and now you know.

I'm not technical, can I do this?

Yes. If your app was built with Lovable, Bolt or Replit, you paste one prompt into the builder. It adds a small read-only page, and you paste its address and a key back here. No terminal and no code. Only apps on their own Postgres database need one short copy-and-paste step in the database console.

How long does it take?

About two minutes to connect. The first scan usually finishes in under a minute once it starts running.

Does it change anything in Stripe or my app?

No. We only read. The Stripe key has no write permission and the connection to your app is read-only, so there is nothing we could change, even by mistake.

What happens to my data after?

Delete your report and everything tied to it (your keys, scan results and history) is removed immediately. Apart from that, resolved findings are cleaned up automatically once they pass your plan's history window: 7 days on Audit, a year on Watch.

someone paid you today. did they get in?

Two minutes, read-only, no card. Three findings free.