Purchase does not expect the application to read raw provider objects directly for product behavior.
Instead, the runtime produces normalized customer state:
customer snapshots, current subscription state, purchase grant state, entitlement snapshots, and credit wallet state.
Why this matters
Provider objects are not an application model. They are transport objects with provider-specific lifecycle semantics.
Your app needs a simpler answer to questions like:
what this customer currently owns, which offer is active, which entitlements should be granted, how many credits are available, and whether a cancellation is scheduled or already effective.
Snapshot flow
- Checkout or webhook workflows write durable rows
- Provider events are normalized into commercial events
- Projection services refresh customer state
- The app reads a normalized snapshot
Entitlements
Purchase treats entitlements as derived commercial state rather than UI-only flags.
That gives you one place to reason about:
feature access, quota ceilings, reset windows, and balance display.
App-owned responsibility
Purchase computes commercial state, but your application still decides how to enforce it. For example:
request authorization, feature gating in product code, usage metering, and customer messaging.
This separation keeps the billing runtime reusable without forcing product logic into the SDK.
What this buys you
Instead of joining provider objects and local patches by hand, application code can ask focused questions:
what subscriptions are active, what one-time grants still apply, what entitlements are enabled, and how many credits remain.
That is the difference between a payment integration and a usable commercial runtime.