- Products can change with pricing, packaging, or platform.
- Entitlements should stay stable and human-readable.
- The cleanest access layer checks entitlements everywhere, not products directly.
Definitions used in this guide
The SKU a customer purchases on Apple, Google Play, or Stripe, such as ios_monthly_pro.
The app capability unlocked by one or more products, such as pro.
The billing system that processes the payment, such as the App Store, Google Play, or Stripe.
What does products vs entitlements subscriptions mean in plain English?
The easiest way to understand the difference is this: products describe how the store sells, while entitlements describe what the customer can use. A yearly web plan and a monthly App Store plan can both grant the same entitlement.
Products are the specific items customers buy. Entitlements are the access rules your app enforces after purchase. Keep them separate and access management becomes much simpler.
The simplest explanation is usually the most durable one in production. If a concept cannot be explained clearly to engineering, support, and product, the implementation tends to fracture later because each team starts using a different mental model.
| Store product | Entitlement unlocked | Why the split helps |
|---|---|---|
ios_monthly_pro | pro | Monthly and annual products can share one access key. |
ios_yearly_pro | pro | Price changes do not force code changes. |
stripe_team | team | Web checkout can unlock the same feature set as mobile. |
Why does this matter for paid apps?
Separating the two lets marketing run promotions, billing teams test packaging, and product teams launch new platforms without rewriting premium checks everywhere.
For subscription apps, that flexibility is operationally important. The more pricing experiments or platform surfaces you add, the more painful SKU-coupled code becomes.
For paid apps, these concepts matter because they sit directly on the line between billing truth and customer experience. A small modeling mistake can turn into access bugs, confusing support responses, or misleading reporting weeks later.
What model should developers use instead?
Model access with stable entitlement keys, then let many products point to those keys. That creates a single place to reason about premium access, grace period rules, and future plan migrations.
A user who purchases stripe_monthly_pro on the web and later restores access inside the iOS app should still resolve to pro. The app should not care which billing system delivered it.
The better model is usually the one that keeps application logic stable while pricing, packages, and payment rails change around it. That is what makes the concept operationally useful instead of merely correct in theory.
- Create products per store and billing cadence.
- Create entitlements per access promise.
- Use customer identity to attach those together across rails.
What do teams usually get wrong?
Teams usually create complexity when they let catalog structure leak directly into feature-gating logic.
When teams get this wrong, the damage tends to show up as drift: naming drift, access drift, reporting drift, or support drift. The app still works, but every change becomes harder to reason about because the model no longer matches the product promise cleanly.
- Creating one feature flag per product ID.
- Using billing cadence names like monthly or annual as if they were access levels.
- Forgetting that web and mobile users may still be the same customer.
How does this show up in a real stack?
In a real stack, this concept has to survive more than one platform and more than one team. Product wants stable language, engineering wants predictable checks, support wants readable states, and finance wants reliable classification. A strong model lets all four groups describe the same customer reality without translation.
That is why the production test is so useful: imagine a user who buys on one rail, upgrades later, asks support a month from now, and hits a bug in between. If the concept still explains what should happen at each step, the model is strong enough to keep.
- Use one shared name for the concept across docs, code, and support language.
- Test the model against web and mobile, not only one surface.
- Prefer mappings and derived state over hard-coded SKU or plan strings.
What should the team align on before implementation?
Before writing more code, align on the definition, the ownership, and the failure mode. Decide what this concept means in plain English, which system is allowed to change it, and what the product should do when the state is missing or delayed.
That small alignment step saves weeks of cleanup later because pricing, support, analytics, and feature gating all inherit the same interpretation from the start.
- Create products per store and billing cadence.
- Create entitlements per access promise.
- Use customer identity to attach those together across rails.
- Agree which customer questions this concept must answer in production.
How do you keep the model clean over time?
The first version of a clean model is not the hard part. Keeping it clean as pricing, experiments, and platforms change is the real discipline. Teams should review names, mappings, and access checks whenever the catalog changes so the concept remains stable while packaging evolves.
A useful rule is that customer-facing promises and code-facing checks should change more slowly than products and promotions. If the opposite is happening, the model is probably leaking commercial noise into application logic.
- Review mappings whenever you add plans, bundles, or promotions.
- Keep support language aligned with the same model used in code and docs.
- Audit places where raw SKU or plan names slipped back into application logic.
Frequently asked questions
Can multiple products unlock multiple entitlements?
Yes. The mapping can be many-to-many. The key is keeping the access model intentional instead of accidental.
What should I name an entitlement?
Name it after the access promise, such as pro, team, or lifetime, not after the store SKU.
Does this apply to one-time purchases too?
Yes. Non-consumable purchases can also unlock entitlements; the pattern is not limited to auto-renewing subscriptions.
Does Crossdeck work across iOS, Android, and web?
Yes. Crossdeck is designed around one customer timeline across Apple, Google Play, Stripe, and web or mobile product events, so the same entitlement and revenue model can travel across surfaces.
What should I do after reading this guide?
Use the CTA in this article to start free or go straight into read products and entitlements docs so you can turn the concept into a verified implementation.
Take this into the product
Use the entitlement docs to design the stable access layer first, then attach products from every rail behind it.