Start a project
Blog

Where subscription fraud actually happens, and how to close it

There is a category of subscription bypass that requires no skill: an app asks the device whether the user has purchased, the device is modified to say yes, and the app unlocks. It works because the trust boundary was drawn in the wrong place. The device is not a trustworthy source of truth about money.

Fixing it is not complicated, but it changes how you model entitlement, so it is much cheaper to do at the start.

The question the app should ask

A naive implementation asks: did this purchase succeed? A correct one asks the server: is this user entitled to this tier right now? The difference is where the answer comes from.

In the correct version, a purchase completes on the device, the receipt goes to your server, your server verifies it directly with Apple or Google, and only then is the user's entitlement recorded. The app reads entitlement from your backend. A modified device can lie to the app all it likes, but it cannot make your server's conversation with Apple return a receipt that does not exist.

Entitlement is a state, not an event

The most common design mistake is treating a purchase as a one-time event that flips a flag. Subscriptions are not events. They renew, lapse, enter grace periods after a failed payment, get refunded, get upgraded mid-cycle and get cancelled with time remaining.

Model entitlement as a current state with an expiry, derived from the store's view of the subscription. Then "is this user entitled" is a question with a correct answer at every moment, including the awkward ones. A boolean flag set at purchase time cannot represent a user who cancelled last week but paid through the end of the month, and that user is entitled.

Webhooks are how you learn about the rest

Most subscription events happen when the user is nowhere near your app. A renewal at 3am, a card that fails, a refund granted by Apple support. Both stores will notify your server if you let them, and that notification stream is what keeps entitlement accurate.

Two practical requirements. The endpoint must be idempotent, since notifications can arrive more than once, and processing a renewal twice must not extend a subscription twice. And it must be verified, since an unauthenticated endpoint that grants entitlement is a gift to anyone who finds it.

Refunds are the case people forget

A user can get a refund from the store without touching your app. If you do not process that, you have a user with full access who has paid nothing, and you will not find out. Handle the refund notification and revoke entitlement, and decide deliberately what happens to content or data created during the refunded period.

Grandfathering, decided once

Price changes are inevitable. Existing subscribers keep their original price by default on both stores unless you deliberately migrate them, which is usually what you want and occasionally not. The important part is to decide explicitly, configure it, and document it, rather than discovering your intent by observing what happened.

Because entitlement lives on your server as a tier and an expiry rather than a price, this stays a store configuration question and does not leak into your application logic.

One layer over two stores

Apple and Google differ in receipt formats, notification shapes and terminology. Writing against both directly means two implementations of the same logic, drifting apart. We route both through one entitlement layer with server-side verification, so the app asks one question and the answer means the same thing regardless of where the user paid.

That is also what makes cash-on-delivery coexist sensibly in the same product for markets where card adoption is low: a different way of becoming entitled, converging on the same entitlement model. We build this as part of payments and subscriptions work, and the first question we ask any existing implementation is where the entitlement decision is made. If the answer is the device, that is where we start.

All articles
Start here

Tell us what you need.

One paragraph is enough. You'll get a straight answer on whether it's a fit, roughly what it takes, and what happens next.

Reply within one business day NDA on request Fixed-price quotes, no hourly billing
Company
NeedBridge LLC
Registered
United States
Studio
Morocco