The Argument, Up Front.
The moment a product sells the same thing through more than one channel, it acquires a question most teams never consciously answer: when a customer opens the app, who decides what they are entitled to? This whitepaper argues that the answer belongs inside the product, in a subscription entitlement architecture that holds exactly one authoritative record of what a customer currently owns, with every billing channel treated as a source that reconciles into it rather than as an authority that answers on its behalf. The Prayer Mission implementation is the evidence: a subscription sold through Stripe on the web and through Apple and Google billing in-app, resolving to one entitlement state across four surfaces.
Separate two things that are routinely conflated, because the conflation is the root of everything downstream. Payment is an event that happened in someone else's system. Entitlement is a current state in yours. Products that treat the second as a lookup of the first inherit every limitation of every channel they sell through, and there is no integration that fixes it, because the channels are not modelling the same thing.
Four patterns account for most multi-channel commerce architecture and this whitepaper rejects all four: the channel as source of truth, branching everywhere instead of at a seam, tuning a parameter that cannot be tuned, and shipping breadth without a way in.
Five principles resolve it. Entitlement is yours and billing is theirs. Choose the seam, then separate completely. Model reconciliation as a process rather than a function. Expose the parameter you cannot tune. And recognise that breadth creates two debts, both architectural.
NewAgeSysIT built this architecture for Prayer Mission under the strategic advisory guidance of Giovanni Livia, as a multi-surface subscription platform rather than a product with two payment integrations bolted to it.
One note on the evidence base. Prayer Mission is a faith community platform, and that is the last time the context appears in this document. The architecture below would be identical for a fitness app, a news product or a game, because the argument is about billing rails.
The Question Most Products Answer by Accident.
The moment a product sells the same thing through more than one channel, it acquires a question most teams never consciously answer: when a customer opens the app, who decides what they are entitled to? Answer it by accident and the answer becomes whichever system was asked last.
Payment
An event that happened in someone else's system at a moment in the past
Entitlement
A current state in yours
Payment and entitlement are different objects. Payment is an event that happened in someone else's system at a moment in the past. Entitlement is a current state in yours. Products that treat the second as a lookup of the first inherit every limitation of every channel they sell through, and they inherit it permanently.
The channels cannot be made to agree, and this is not an integration problem. Renewal, upgrade, downgrade, grace period, refund and expiry semantics differ between a card processor and an app store, and neither is aware the other exists. Google's own billing documentation defines five distinct replacement modes for a mid-cycle plan change, each resolving the billing date and the charge differently, and recommends a different one for upgrades than for downgrades. Apple's billing grace period runs six days on weekly subscriptions and sixteen on monthly or longer, and it is opt-in, requiring server notification handling to work at all. Google Play has offered grace periods since 2018, configurable by the developer, followed by an account hold state that suspends access while retries continue. These are not variations on one model. They are different models, and no adapter reconciles them into agreement, because agreement is not available.
This is where the distinction from supplier architecture matters, and it is worth its own paragraph. A data supplier answers a question you asked. You can ignore the answer, re-request it, or replace the supplier. A billing rail asserts a fact about money that has already moved, and it will not accept correction. Apple decides whether a renewal happened; your system's opinion is not sought and cannot be entered. Reconciling authorities is a harder problem than sourcing inputs, and conflating the two is precisely how teams under-scope this work.
The commercial case. The user-visible failure is what makes the commercial case. A customer pays on the web, opens the phone, sees a paywall, and either pays twice or contacts support. Both outcomes cost more than the subscription earns. The second arrives with a refund request attached, and the first arrives with one shortly afterwards.
Invisible when it works. And it is invisible when it works. This architecture produces nothing a user can see. It is only ever noticed in its absence, which is why it is chronically under-resourced and why it is worth writing about rather than filing in a backlog.
So the question is not how to integrate two billing systems. It is where the authoritative answer lives. Section 04 sets out what has to be true for it to live in your system.
| Behaviour | Apple App Store | Google Play | Direct card processor |
|---|---|---|---|
| Mid-cycle upgrade | Handled by the store, on its own terms | Five replacement modes, each with different billing-date behaviour | Merchant configures proration |
| Downgrade | Store-determined timing | Deferred to next renewal is the recommended mode | Merchant-determined |
| Failed payment | Opt-in grace period, six or sixteen days by term | Configurable grace period, then account hold | Merchant sets retry and dunning |
| Refunds | Issued by the store, often without merchant involvement | Issued by the store | Issued by the merchant |
| Who decides | The store | The store | You |
| Can you correct it | No | No | Yes |
The final two rows are the architecture. Everything above them is detail.
Sources
- Google Play billing documentation, Subscriptions (developer.android.com/google/play/billing/subscriptions). Defines the replacement modes for mid-cycle plan changes, including CHARGE_PRORATED_PRICE, WITHOUT_PRORATION, CHARGE_FULL_PRICE and DEFERRED, each resolving billing date and charge differently, with Google recommending different modes for upgrades than for downgrades.
- Google Play grace period and account hold. Grace period configurable by the developer, available since 2018, followed by an account hold state suspending access while retries continue.
- Apple billing grace period. Introduced September 2019, opt-in rather than opt-out, enabled in App Store Connect, running six days on weekly subscriptions and sixteen on monthly or longer, and requiring server notification handling to function.
Got Problems? Let Us Help You With the Right Solution
Four Patterns That Let the Channel Decide.
Four patterns account for most multi-channel commerce architecture, and each one hands a decision to something outside the product that the product should have been making itself.
The Channel as Source of Truth
Entitlement is resolved by querying whichever billing system the user is currently in front of, or by checking a receipt at launch.
Access becomes platform-dependent. A subscription bought on the web is invisible to the app, because the app asks the app store and the app store has never heard of it. The product holds no opinion about what the customer owns, so it has none to defend when the customer disagrees.
The second-order failure arrives later and hurts more. With no internal state there is nothing to reconcile a refund, a chargeback or a failed renewal against, and no way to answer a support question except by comparing two dashboards by eye. Support cost scales with customers. The architecture cost would not have.
The reframe is one sentence. The billing rail knows what was paid. Only your system can know what the customer is entitled to now, because only your system knows about all of the payments. Teams reach this conclusion eventually, usually while scoping a second commerce surface and discovering the first one has no state to build on.
Branching Everywhere Instead of at a Seam
Where one flow serves two materially different processes, a cart carrying both physical and digital goods for instance, the difference is handled with conditionals distributed through the whole flow.
Every subsequent change has to be made in both branches, and the branches drift. A discount rule, a tax change or a refund path gets implemented for one and forgotten for the other, and the bug surfaces in the less-travelled branch weeks later, reported by a customer rather than a test.
The alternative is one experience up to a deliberately chosen seam, then separation that is clean and total. Seam placement is the skill: too early and you have two products, too late and you have conditionals everywhere. The right seam is the last point at which both paths genuinely want the same thing.
Tuning a Parameter That Cannot Be Tuned
A single default is chosen for a variable that behaves differently across the user base, a search radius, a page size, a notification frequency, and then tuned in response to complaints.
Tuning toward one population moves it away from another. A geolocation radius that returns a useful list in a dense city returns an empty screen in the countryside, and no single value serves both. The complaints do not stop, they change sender.
The resolution generalises, which is what makes it the most portable idea in this section: when one parameter cannot serve two populations, expose it as a control rather than tuning it. The user knows which population they are in. The product does not, and never will. One discipline attaches to this: an exposed parameter the user does not understand is worse than a bad default, so the exposure has to come with a comprehensible frame.
Shipping Breadth Without a Way In
A platform grows to many modules, each individually justified, with navigation as the only orientation mechanism.
Breadth that reads as capability on a feature list reads as confusion on first open. A new user cannot tell which of eight sections is the one they want, and the failure shows up as abandonment rather than a support ticket, which makes it nearly invisible to the team that caused it.
Breadth creates a second and separate debt, and it is worth naming as a different problem rather than the same one. A platform with many modules needs an operations surface covering the full operational set, or every routine change becomes a developer request. A client who must file a ticket to change a price does not own their product. Both debts are architectural rather than cosmetic, and both are typically discovered after launch.
| Pattern | What it hands away | Where it breaks | What it costs |
|---|---|---|---|
| Channel as source of truth | The decision about what a customer owns | Access becomes platform-dependent | Duplicate purchases and support contacts, both scaling with customers |
| Branching everywhere | The boundary between two processes | Branches drift, changes land in one | Bugs in the less-travelled path |
| Tuning an untunable parameter | The judgement only the user can make | Serving one population badly to serve another | Silent churn in the population you tuned away from |
| Breadth without a way in | Orientation, and operational control | First open, and every routine change | Abandonment, and permanent vendor dependency |
Five Principles for Entitlement You Actually Control.
A durable subscription entitlement architecture holds exactly one authoritative answer to what a customer currently owns, inside the product, with every billing channel treated as a source that reconciles into it rather than as an authority that answers on its behalf.
What follows is product-agnostic. An architect building a fitness app, a news product or a game could implement it without ever seeing the evidence in Section 05.
Architecture Diagram
One Entitlement Record, and Where Each Principle Applies
Stripe, on the web
Apple and Google, in-app
The next channel
The Entitlement Record
iOS · Android · Website · Admin panel
One flow to a chosen seam
Then total separation, physical and digital fulfilment apart
The untunable parameter is exposed
The user knows which population they are in
Orientation and operations layers
The two debts breadth creates
Entitlement Is Yours, Billing Is Theirs
One entitlement record per account, owned by the product, expressing what the customer may do right now. Payments are events that update it. They are never consulted to answer it.
Implementing this requires an entitlement model defined in the product's own vocabulary, tier, status, period end, source, and an adapter per rail translating that rail's events into changes on it. The rail's identifiers are stored for reconciliation. Its semantics never enter the model. That second half is the discipline that gets skipped under deadline, because storing a vendor's status value directly is faster and looks harmless until the second vendor arrives with a different vocabulary.
What it buys is that access becomes platform-independent, support can answer a question from one place, and a third channel later is an adapter rather than a re-architecture.
Then the economic argument, which persuades a founder rather than an engineer. The alternative's cost arrives as duplicate purchases and support contacts, both of which scale with customers. The architecture cost does not scale with anything. It is paid once, early, while there is still only one channel and nothing yet to reconcile, which is exactly when it is hardest to justify and cheapest to do.
Choose the Seam, Then Separate Completely
Where one flow serves two materially different processes, pick a single point of divergence and make the separation total after it.
Implementing this means a shared model up to the seam and genuinely independent handling beyond it, with no shared conditional logic downstream. There is a clean test: if a change to one path requires reading the other, the seam is in the wrong place.
What it buys is one experience for the customer and two processes that can evolve independently, the only arrangement that stays maintainable as both grow. The general rule: the correct seam is the last point at which both paths genuinely want the same thing. Before that, sharing is free. After it, sharing is debt.
Model Reconciliation as a Process, Not a Function
Where an external authority can assert facts you cannot overrule, reconciliation is a continuous system with its own state, failure modes and observability. It is not a translation function called at purchase time.
This is where the distinction drawn in Section 02 pays off, so state it plainly. A supplier you query can be re-queried or replaced. A billing authority tells you something already happened and will not accept correction. Your system therefore has to be able to receive an assertion that contradicts its current state and resolve it deterministically, which is a different design problem from fetching an answer.
Implementing it requires four things, and every one of them is something teams add after the incident that taught them it was needed: webhook or notification ingestion per rail, idempotent handling because rails retry, an explicit precedence rule for conflicting assertions, and a scheduled reconciliation job that catches what the event stream dropped. Event streams drop things. That is not a defect to be fixed, it is a property to be designed around.
What it buys is an entitlement state that stays correct through renewals, upgrades, refunds and expiry across every rail, including the cases nobody tested, because the system is built to converge rather than to be right first time.
Name the property this produces, because it is the most quotable idea in this document. This work is invisible when it succeeds and only ever noticed when it fails. That asymmetry is the reason it is chronically under-resourced, and the reason it belongs in an architecture decision rather than a backlog item.
Expose the Parameter You Cannot Tune
When one setting cannot serve two populations, make it a user control rather than choosing a default that serves one badly.
Implementing this requires a legible frame for the control, a sensible starting value, and persistence so the user sets it once. Exposure without comprehensibility is worse than a poor default, because it transfers a decision to someone not given the information to make it.
What it buys is that the product stops being tuned for an average user who does not exist, and the population it previously served badly stops churning silently.
It generalises past geolocation to page size, notification frequency, refresh rate and content filtering thresholds. Anywhere the right value is a property of the user's situation rather than of the product, the control belongs to the user.
Breadth Creates Two Debts, Both Architectural
Every module added to a platform incurs an orientation debt to users and an operations debt to whoever runs it, and neither is paid off by navigation.
The orientation layer is an in-product assistant or equivalent that can answer where something is and how it works. On a many-module platform that is the difference between a new user exploring and a new user leaving, and an in-product assistant is usually cheaper than the redesign teams reach for instead.
The operations layer is an admin surface covering the full operational set, so routine content, pricing and moderation changes never require a developer.
Be honest about the trade-off. Both layers are real build cost that ships no user-visible feature, and on a three-module product neither is warranted. The argument is about where the threshold sits, not that everyone crosses it.
At a Glance
The Five Principles
-
01
Entitlement is yours, billing is theirs.
Where the answer lives
-
02
Choose the seam, then separate completely.
The same discipline, on fulfilment
-
03
Model reconciliation as a process, not a function.
What keeps it correct
-
04
Expose the parameter you cannot tune.
What breadth costs
-
05
Breadth creates two debts, both architectural.
What breadth costs
Giovanni Livia, Independent AI & Software Solutions Consultant | Implementation by NewAgeSysIT
Principle 1 decides where the answer lives and Principle 3 keeps it correct over time. Together they are the whole entitlement argument. Principle 2 is the same discipline applied to fulfilment rather than billing. Principles 4 and 5 are about what breadth costs once the commerce works. A product with 1 but not 3 is correct on the day it launches and wrong within a quarter.
Two Rails, Two Fulfilment Paths, One Account State.
NewAgeSysIT implemented this architecture for Prayer Mission, a community platform spanning iOS, Android, a responsive website and a web admin panel, carrying an in-app store and a subscription tier, under the strategic advisory guidance of Giovanni Livia.
It is a faith community platform, and that is the only time the context appears here. Everything below would be identical for any subscription community product. The full client narrative and delivery detail are published in the Prayer Mission case study.
Step one
Subscribes on the website, through Stripe
Step two
Opens the app on a phone, signed in to the same account
Result
The features are simply there. No second paywall, no duplicate purchase, no support ticket.
Principles 1 and 3 in practice, and the core evidence. A subscription bought on the website runs through Stripe. The same subscription bought on a phone runs through Apple's or Google's in-app purchase system. Both produce one outcome: an active entitlement on the account, unlocking the same features regardless of where the money moved. The platform holds one authoritative subscription state and reconciles both sources into it rather than asking either of them what the customer owns. The brief describes this as the most technically demanding part of the build, which is the correct assessment and also the reason it is the thesis of this document rather than a line in a feature list.
The user-visible proof. Someone who subscribes on the website and then opens the app simply has the features. No second purchase, no support ticket.
What that sentence conceals. It is worth being precise about what that sentence conceals, because the brevity is the whole point. Behind it sit an adapter per rail, idempotent handling of retried notifications, a precedence rule for the case where a rail asserts something the account record contradicts, and a scheduled pass that catches whatever the event stream dropped. None of it is visible in the outcome, and the outcome is the only part anyone will ever describe.
Principle 2 in practice. The store sells physical goods and digital downloads through one browse, one cart and one checkout, with the paths separating completely at the point of purchase: address capture and delivery for physical, immediate unlock plus a permanent re-download entitlement in order history for digital.
Principle 4 in practice. The location-based finder exposes the distance threshold as a user-facing control rather than shipping a fixed radius, so results stay useful at any population density. The user knows whether they are in a city. The product does not.
Principle 5 in practice. An in-product assistant can explain how a feature works or where a section lives, across a platform of eight functional areas. Alongside it, an admin panel covers the full operational surface, content, missions, store products, pricing, categories, moderation, notifications and analytics, so the client's own team runs the platform without a developer.
The stack, compressed. React Native with TypeScript shipping iOS and Android from one codebase including tablet layouts, with native modules where needed, over a NestJS backend on Node.js using MongoDB and MySQL, running on AWS.
Full delivery detail and the client narrative are published in the Prayer Mission case study. This whitepaper borrows the evidence. The case study owns the story.
Client Story
Read the full Prayer Mission case study
Delivery detail, the complete technology stack and the client narrative.
Invisible When It Works, Which Is the Point.
The defining property of this architecture is that it produces no observable event. Nothing happens, no second paywall, no duplicate charge, no support ticket, and the absence is the result.
| Evidence | Conventional | Built | Principle tested |
|---|---|---|---|
| Entitlement across channels | Access resolved by asking whichever billing system the user is in front of | One authoritative subscription state, both rails reconcile into it | Principles 1 and 3 |
| Cross-channel experience | Subscribe on web, hit a paywall in the app, pay twice or contact support | Subscribe anywhere, open anywhere, the features are simply there | The user-visible consequence of the above |
| Storefront architecture | Conditional logic for goods type distributed through the purchase flow | One cart and checkout, paths separating completely at the point of purchase | Principle 2 |
| Geolocation under varying density | A fixed radius tuned toward one population | Distance threshold exposed as a user-facing control | Principle 4 |
| Operator independence | Routine content and pricing changes filed as developer requests | Admin surface covering the full operational set | Principle 5, operations half |
The first two rows are the argument, and the relationship between them is the useful part. The first is an architectural fact and the second is the only part of it a customer could ever perceive, precisely because it is the part where nothing happens. That is an awkward thing to sell and a good reason to document it.
The fourth row is the smallest in scope and the most portable. Exposing a threshold rather than tuning it is a two-day decision that applies to page size, notification frequency and refresh rate just as well as to distance.
The third and fifth rows evidence something different from the first two, and it is worth separating. Rows one and two are about correctness: the system either holds one authoritative state or it does not. Rows three and five are about cost of change over time, in the codebase and in the client relationship respectively. A clean fulfilment seam and a complete admin surface both look like polish on launch day and both turn out to be the difference between a product that can be modified and one that requires its vendor for every modification.
What the whole table supports is an entitlement model that stayed correct across two billing systems with incompatible semantics, on a shipped product spanning four surfaces.
Now state plainly what this does not support. There is no measurement of subscription conversion, duplicate-purchase rate, support-contact volume or revenue. The architecture is evidenced. Its commercial effect is not, and this document does not claim it.
One figure would close that gap and it is worth naming which. Support contacts relating to subscription access, or duplicate purchases, ideally as a rate. That is the number this architecture exists to drive toward zero, and it is the only metric that would demonstrate the result rather than describe it. It is also commercially unremarkable, so a client can share it without hesitation.
The boundary condition matters here more than in most papers in this series, because the argument is easy to over-apply. This architecture earns its cost the moment a product sells through a second channel, and not before. A product selling through one rail should hold entitlement internally anyway, on general principle, but the reconciliation apparatus described in Principle 3 is genuine overhead until the second rail exists. Building it early is foresight only if the second channel actually arrives.
Six Decisions Made Before the Second Channel.
Six decisions determine whether a second sales channel is an adapter or a rebuild. All six are cheap while there is still only one channel, which is exactly when nobody is thinking about them.
| # | Decision | What to weigh |
|---|---|---|
| 1 | Where entitlement state lives | Internal from the start, or resolved against the billing system |
| 2 | Whether rail semantics may enter the model | Faster now, coupled to a vendor's vocabulary permanently |
| 3 | How conflicting assertions resolve | Define precedence before two systems disagree |
| 4 | Event-driven, polled, or both | Webhooks are fast and lossy; reconciliation is slow and complete |
| 5 | Where the fulfilment seam sits | The last point at which both paths want the same thing |
| 6 | Whether orientation and operations layers are warranted | Real cost, no user-visible feature, genuinely optional below a threshold |
1. Where entitlement state lives.
Internal from the start, or resolved against the billing system. Internal costs a model and an adapter at a moment when you have one channel and nothing to reconcile, which makes it feel like over-engineering. Resolving against the channel costs nothing now and costs a rebuild the day a second channel appears. This is the decision the whole architecture turns on, and deferring it does not keep it open, because by then the resolution logic is distributed through the product.
2. Whether rail semantics may enter the model.
Storing a rail's status values directly is faster and couples your entitlement model to that vendor's vocabulary permanently. Translating at the adapter costs a mapping per rail and keeps the model yours. The coupling is invisible while you have one rail, which is precisely why it survives review, and expensive the moment you add the second.
3. How conflicting assertions resolve.
Two rails can assert contradictory states, and so can a rail and your own record after a failed webhook. Define precedence and a convergence path before either situation occurs. Retrofitting it means reconciling divergent history rather than defining a rule, which is data archaeology with a customer waiting on the other end.
4. Event-driven, polled, or both.
Webhooks are fast and lossy. Scheduled reconciliation is slow and complete. Most production systems need both, and the usual sequence is that teams build the first, discover the gap during an incident, and add the second under pressure. Building both up front costs little more than building one. That said, there is a legitimate webhooks-only answer at low volume with tolerant failure modes, and pretending otherwise would be selling rather than advising.
5. Where the fulfilment seam sits.
Too early and you have two products. Too late and you have conditionals throughout. The right seam is the last point at which both paths genuinely want the same thing, and it is much cheaper to move while the second path is still hypothetical than after it has shipped. The deferral cost here is unusual in that it compounds silently: each conditional added before the seam is settled is another place the eventual separation has to reach, and nobody is counting them.
6. Whether orientation and operations layers are warranted.
Both ship no user-visible feature and both are genuinely unnecessary on a small product. The threshold is not module count. It is whether a new user can tell where to start, and whether the client can change a price without you. If the answer to both is yes, skip them.
Two of these six have legitimate answers in either direction. Decision 6 is unwarranted on most products, and Decision 4 has a defensible webhooks-only answer at low volume. Saying so is what should make the other four credible. If you want a cost frame before settling any of them, the app development cost estimator gives a working range, and QA consulting is the right instrument once the reconciliation design exists, because reconciliation is mostly tested through failure cases nobody writes by default.
Speak With Our Consultant
Partners
Pressure-test your architecture before you commit to a data model. Work directly with Giovanni and Bibin to validate your technology direction, align the platform with business goals, and make confident decisions that reduce risk and accelerate outcomes.
Request an Architecture Consultation
Five Insights From the Prayer Mission Build, Each Independently Quotable.
A billing channel knows what was paid. Only your system can know what a customer is entitled to now, because only your system knows about all of the payments. Prayer Mission holds one authoritative subscription state that both Stripe and app store billing reconcile into, so a subscriber who buys on one surface and opens another simply has the features.
Reconciling authorities is a harder problem than sourcing inputs, and conflating the two is how teams under-scope it. A data supplier answers a question and can be re-queried or replaced. A billing rail asserts that money has already moved and will not accept correction, which is why reconciliation belongs in the architecture as a continuous process with its own state rather than as a function called at checkout.
Where one flow serves two materially different processes, choose a single seam and separate completely after it rather than branching throughout. The correct seam is the last point at which both paths genuinely want the same thing, which for a storefront carrying physical and digital goods is the moment of purchase.
When one parameter cannot serve two populations, expose it rather than tune it. A fixed search radius that works in a dense city returns an empty screen in the countryside, and no default resolves that, but the user always knows which situation they are in and the product never does.
The most valuable commerce engineering produces no observable event: no second paywall, no duplicate charge, no support ticket. Work that is only ever noticed when it fails is chronically under-resourced for exactly that reason, which is why entitlement architecture belongs in a design decision rather than in a backlog.
From Architecture to Implementation.
NewAgeSysIT is a custom software development and AI solutions company in Princeton, NJ, specialising in subscription and in-app commerce architecture, multi-surface consumer platforms, community products, and full-cycle development across mobile, web and cloud.
Founded by Johny John, NewAgeSysIT has delivered software across community platforms, wellbeing, logistics, automotive, healthcare and fintech. Recent work is in the client portfolio.
The company works closely with Giovanni Livia, Independent AI & Software Solutions Consultant, strategic advisor, who helps business leaders scope and sequence platform initiatives before connecting them with NewAgeSysIT for implementation.
Selling Through More Than One Channel?
If you sell the same thing through more than one channel, or plan to, request an architecture consultation with Giovanni Livia to settle where entitlement lives before the second channel forces the answer.
Read the full implementation narrative in the Prayer Mission case study.
newagesysit.com | [email protected] | 1-609-331-9194 | 4390 US-1, Suite 110, Princeton, NJ 08540