Mobile App Marketing Stack: Subscription Data, Tools and Release Tests

A subscription app’s marketing stack should establish who has access, what they paid, how they use the product and which action could help them next. Start with verified store or billing state and joinable app identities. Add product analytics, attribution and lifecycle tools for specific decisions. Keep entitlement, revenue, renewal intent and campaign credit separate so one misleading status cannot drive the whole customer experience.

Jafrin Akter AloLast updated 17 min read
On this page
A cobalt and white turnstile has a pink pivot and lime paddles, beside App Subscriptions: Check the State.

A customer can turn off auto-renewal and still have paid access. Another can enter a billing grace period without becoming a lost subscriber. A third can restore a purchase on a new device without generating another sale. If every tool receives only is_subscriber: true or false, those differences disappear.

The industry stack guide explains how the business model changes the architecture. This guide focuses on subscription apps and the joins between purchase handling, customer access, product behavior and growth.

Which jobs should the app stack perform?

Give each layer a defined question and owner. Start with the layers needed for a working purchase and customer experience; add analysis and activation capacity when a recurring decision justifies it.

Which jobs should the app stack perform?
JobGoverning evidenceImplementation choiceAcceptance question
Grant product accessVerified subscription or purchase state and product mappingDirect store integration or a subscription serviceDoes the correct account receive the promised access?
Record moneyValidated transactions and adjustmentsBilling ledger plus store or processor reportsDo purchases and refunds reconcile by currency and period?
Understand product valueDeliberate first-party eventsExisting event setup or product analyticsCan the team explain activation and retention behavior?
Evaluate acquisitionSpend, eligible attribution signals and commercial outcomesDirect reports or an MMPWhat decision does the attribution evidence support?
Help customers progressCurrent eligibility, product state and channel permissionsIn-app, push or email workflowsIs the message still relevant when it is sent?
Join recurring questionsStable identities and maintained cross-source modelsA warehouse when the need warrants itCan an owner explain the result and its gaps?

The important boundary is between an operating fact and a report about it. An attribution tool can credit a campaign for a renewal; it should not decide whether the renewal was valid. A messaging tool can react to a billing issue; it should not become the only place the app records access.

Use product analytics and app tracking implementation to connect those facts to the decisions your team actually makes. The deliverable should include the exception cases and operating owner, not just an SDK appearing in the build.

Where should subscription truth come from?

Use verified store or billing information, either directly or through a subscription service that maintains it. Treat notifications as inputs to a state and transaction model, not as commands to blindly toggle a customer’s access.

What do Apple’s subscription notifications mean?

Apple’s V2 notifications distinguish SUBSCRIBED, DID_RENEW, renewal-status changes, billing failures, grace-period expiry and refunds. Subtypes matter: AUTO_RENEW_DISABLED describes a renewal choice, while BILLING_RECOVERY describes a recovered renewal. REFUND_REVERSED differs from REFUND, and Family Sharing can produce access changes. Preserve type, subtype and the transaction context. Apple notification types

Verify signed data before accepting its contents. Apple’s server library provides signed-notification verification with the configured root certificates, environment and app identity. Production and sandbox configuration must remain distinct. A JSON payload that contains a plausible transaction ID is not verified evidence. Apple’s server library

For current access and history, Apple provides subscription-status and transaction-history APIs. Billing Grace Period is a configured way to retain access during recovery; a failed renewal alone does not identify the complete access decision. Apple subscription state and recovery

What does Google Play send through RTDN?

Google’s real-time developer notification tells you that purchase state changed. Google requires a Play Developer API call for the complete status and recommends checking the notification’s messageId for duplicates. Retain the purchase reference and package context needed to retrieve and reconcile the actual resource. Google RTDN reference

For auto-renewing Play subscriptions, voluntary cancellation can leave access valid until the returned expiry. Grace period retains entitlement; account hold removes it. Recovery and expiry require their corresponding state handling. Do not turn a cancellation notification into immediate revocation without checking the applicable state and expiry. Google subscription lifecycle

A later-arriving notification can describe an earlier event. Refresh authoritative state and preserve provenance instead of letting network arrival order decide which customer fact wins. Keep an exception path for a failed refresh; missing information is not a newly verified expiration.

Should you use RevenueCat or build the subscription layer yourself?

Use a service when its supported stores, identity model and operating behavior fit, and when maintaining those integrations yourself would distract from the product. Build directly when you need control the service does not provide and can own validation, lifecycle handling, recovery and ongoing platform changes.

RevenueCat entitlements map purchased products to an access level. Product attachment matters: a product can exist without granting the entitlement your app checks. Verify the mapping for every relevant product, tier and platform. RevenueCat entitlements

Should you use RevenueCat or build the subscription layer yourself?
ChoiceCan suitWork that remains yours
Direct store integrationA team with the engineering capacity and a clear need for controlVerification, state reconciliation, identity, monitoring and platform maintenance
RevenueCat or another evaluated subscription serviceA team wanting maintained purchase and entitlement infrastructureProduct mapping, app integration, identity decisions, permissions and customer tests
Existing service plus a warehouseRepeated questions joining billing, behavior and acquisitionCanonical models, freshness, reconciliation and downstream action rules

RevenueCat’s Pro pricing is free up to the stated USD 2,500 monthly tracked revenue threshold, then 1% of tracked revenue; custom arrangements are available. Check the exact account terms around the threshold rather than treating every quote as the same package. RevenueCat pricing

Monthly Tracked Revenue is distinct from MRR. It includes purchases and renewals, including non-subscription products, before store commission and taxes. RevenueCat’s example bills USD 26 for USD 2,600 of MTR: the percentage applies to the tracked amount, not only the USD 100 above the threshold. RevenueCat billing basis

For an illustrative USD 12,000 MTR cycle under that 1% basis, the service line is USD 120. It is not the full app stack cost: messaging, analytics, attribution, infrastructure, store or processor deductions and internal work remain separate. Compare the whole operating scope before deciding that building directly is cheaper.

RevenueCat lists integrations with analytics and lifecycle tools including Amplitude, Mixpanel, PostHog, Braze, Customer.io and OneSignal. An integration being listed does not prove that its event mapping, identity and feature scope fit your workflow. Test the actual destination behavior. Supported integrations

Which identity rules prevent access and messaging mistakes?

Keep person identity, store purchase identity, device destination and attribution identity distinct. Join them only through a supported, verified relationship.

A stable application account ID can connect the signed-in customer to analytics and lifecycle systems. A push token is a delivery destination, not the person’s primary identifier. An email address can change or be shared. A store purchase reference identifies a purchase relationship, not every human who might receive access through it.

RevenueCat creates an anonymous App User ID when one is not supplied; reinstalling can create a new one. Login, aliases and restores depend on the identity and restore behavior selected. RevenueCat recommends non-guessable custom IDs and advises against email or advertising identifiers as App User IDs. RevenueCat customer identity

Use the identity-merge guide for the analytics side. Do not assume that merging two analytics profiles transfers a store subscription, or that a restored purchase creates a second paying customer.

Which identity rules prevent access and messaging mistakes?
ScenarioRelationship to verifyFailure to prevent
Anonymous customer signs inIntended anonymous activity maps to the correct application accountOne shared ID joins unrelated customers
Existing customer reinstallsSupported restore and account mapping recover the intended accessNew anonymous profile is counted as another subscriber
Two app accounts use one deviceLogout and account switching update the right identities and destinationsThe next person sees the previous person’s state
One account uses several devicesSame account, separate delivery destinationsPerson-level audience and device billing counts are confused
Family or shared accessStore-supported access relationship remains distinct from the payerEvery beneficiary is treated as a separate purchase

Record the rule before choosing the SDK calls. Test with accounts that already have purchases as well as fresh installations. The clean new-user path rarely exposes the account-switching and restore problems that support later has to resolve.

Which events should the first implementation include?

Start with the events needed to explain one useful journey: arrival, onboarding, first value, purchase intent, verified purchase or trial, renewal state and relevant exceptions. Give each event a producer and a meaning.

Which events should the first implementation include?
Event familyAuthoritative producerWhat it should establish
First open and onboardingApproved application instrumentationThe measured app action occurred
Core value actionProduct system or app event contractThe customer completed a meaningful task
Paywall viewApplication or paywall implementationAn offer was shown, not purchased
Trial or purchase outcomeVerified store/billing integrationThe relevant product and purchase state exist
Renewal, billing issue and expiryVerified subscription state pipelineThe state changed with its correct effective context
Refund or reversalVerified monetary adjustment sourceA specific financial adjustment occurred

Use event names that survive app releases. A paywall click, a completed purchase and a successful renewal should not share one generic conversion name. Keep product, offer, currency, environment and source references with the appropriate records.

Choose one canonical producer for each monetary fact. If the app SDK, subscription service and backend all emit the same purchase into analytics, three green integrations can produce three times the revenue. Deduplicate transport retries separately from reconciling different producers that describe the same commercial transaction.

RevenueCat recommends idempotent webhook processing using its event ID and supports separate sandbox/production filtering. It also recommends refreshing customer information through its API when syncing state. Retries are finite, so a receiver needs monitoring and recovery rather than an assumption that every missed delivery will return forever. RevenueCat webhooks

Authenticate the actual delivery mechanism, record receipt durably and process it through the appropriate state or ledger path. Acknowledge only according to the receiver design you can recover. A transport success is not proof that analytics, entitlements and messaging have all consumed the update.

How should lifecycle messaging use subscription state?

Use current customer need and channel eligibility, with a final check close to dispatch. Renewal intent, current access and a successful payment should be separate inputs to the decision.

How should lifecycle messaging use subscription state?
Verified situationUseful customer actionIncorrect shortcut
Trial is active; first value is missingHelp complete the relevant taskRepeatedly push payment before the customer can use the product
Auto-renewal is disabled; access remains validRespect the choice and clarify remaining access where usefulDeclare the customer expired immediately
Payment recovery is in progress with valid grace accessProvide appropriate payment-recovery helpBlock access simply because a payment attempt failed
Access has expired after authoritative confirmationExplain the current state and permitted next stepContinue a paid-customer journey using stale eligibility
A refund or access reversal is confirmedUpdate the relevant monetary and access recordsTreat every adjustment as a new purchase

Those are workflow recommendations, not identical state names across stores. Apply the store or service’s actual entitlement rules, then decide which communication is appropriate. Do not infer that a marketing subscription grants permission for every transactional or promotional purpose.

Push delivery depends on app and operating-system eligibility. In-app content requires the customer to open the relevant experience. Email requires a usable address and the applicable permission and suppression handling. Store recovery notices can already be doing part of the job; coordinate your own messaging instead of creating several competing reminders.

Compare Braze and Customer.io or OneSignal’s pricing and billing units only after defining those requirements. A lower per-user headline is not useful if it uses a different population or omits the workflow you need.

Do not assume a server update instantly refreshes a device screen. RevenueCat’s CustomerInfo is cached, and updates reach the client through outbound requests rather than being pushed automatically from its backend. Test the refresh behavior at premium-content entry and after purchase or restore. Keep the supported offline behavior explicit. CustomerInfo and caching

When does an MMP or a warehouse earn its place?

Add an MMP when its maintained acquisition integrations, links, exports and operating support solve a problem your current setup cannot handle economically. Add a warehouse when important recurring questions need several sources and retained history. Neither should be a default purchase just because the app has launched.

Check what AppsFlyer charges per billed conversion before adding its subscription and usage assumptions to the stack budget.

The mobile attribution guide covers SKAdNetwork, AdAttributionKit, reporting delay and missing detail. Attribution credit does not establish incremental impact, and aggregate reports do not provide a verified person-level join just because your product database has an account ID.

Apple requires ATT permission for the cross-company tracking it defines; without authorization, the advertising identifier is zeroed. Hashed emails or fingerprinting do not provide a way around that boundary. Record the applicable OS, regional prompt behavior and permission outcome, then verify each SDK’s actual collection and forwarding. Apple privacy and data use

Use the MMP comparison to evaluate the required acquisition paths. A campaign report should identify its attribution method, window and maturity. Keep unavailable attribution as unavailable rather than assigning it to organic traffic or reconstructing a forbidden identity.

A warehouse can join permitted customer activity, validated financial records, message exposure and acquisition cost for a recurring cohort question. Use cohort retention definitions so install retention, product retention and paid retention do not become interchangeable labels.

For health or children’s apps, evaluate the data sent to each destination before enabling general SDK forwarding. Use the health-data analytics guide for health-specific decisions, and use the COPPA review for kids’ and education apps to check the child-data route, SDK collection and store-policy boundaries. An SDK’s technical ability to accept a field is not permission to transmit it.

How do you reconcile revenue without mixing environments or currencies?

Reconcile canonical purchases and adjustments over the same reporting period, then compare them with the applicable store or processor report. Keep currency, source and environment visible, and distinguish customer charges from net proceeds after deductions.

This original Python helper checks a normalized ledger export for a period you have already selected. Each entry needs a stable commercial entry_id within its store and app namespace. A refund or reversal needs its own canonical adjustment entry ID linked to the original purchase; reusing the purchase ID would correctly fail the duplicate-entry check. This helper supports only charges and negative refund entries, and rejects other kinds. Model reversals explicitly in your ledger rather than passing an unsupported kind to this example. Retries of the same entry must not be counted again. Do not substitute a webhook delivery ID for the underlying commercial entry. These are example fields, not a raw Apple, Google or RevenueCat payload schema.

Python
import re

def production_totals(entries):
    seen = set()
    totals = {}
    for row in entries:
        if row["environment"] not in ("production", "sandbox"):
            raise ValueError("unknown environment")
        if row["environment"] == "sandbox":
            continue
        keys = (row["store"], row["app_id"], row["entry_id"])
        if any(not isinstance(x, str) or not x.strip() for x in keys):
            raise ValueError("store, app and entry IDs are required")
        if keys in seen:
            raise ValueError("duplicate commercial entry")
        seen.add(keys)
        currency = row["currency"]
        if not isinstance(currency, str) or not re.fullmatch(r"[A-Z]{3}", currency):
            raise ValueError("use the agreed three-letter currency code")
        amount = row["amount_minor"]
        if type(amount) is not int:
            raise ValueError("amount_minor must be an integer")
        if row["kind"] not in ("charge", "refund"):
            raise ValueError("unsupported ledger entry kind")
        if row["kind"] == "charge" and amount < 0:
            raise ValueError("charge amount cannot be negative")
        if row["kind"] == "refund" and amount > 0:
            raise ValueError("refund amount cannot be positive")
        totals[currency] = totals.get(currency, 0) + amount
    return totals

The helper fails on duplicate commercial entries instead of silently choosing one. It does not validate store signatures, resolve identity, discover missing transactions, convert currency or calculate recognized accounting revenue. An empty result is not proof that the app earned no revenue. Its three-letter check is structural; the upstream contract must establish the valid currency and its minor-unit scale.

For a synthetic production export, two USD charges of 999 minor units and one refund of −999 produce USD 999 minor units, or USD 9.99. A separate EUR charge of 899 remains EUR 899 minor units. A sandbox charge is excluded. Adding USD and EUR integers into one total would be meaningless without a defined exchange-rate policy.

How do you reconcile revenue without mixing environments or currencies?
Reconciliation questionEvidence to compareReason totals can differ
Did every commercial entry arrive?Store or processor population against canonical entry keysMissing imports, duplicate producers or late adjustments
Is the period aligned?Effective event time, reporting window and timezoneDelivery occurred later than the underlying transaction
Are we comparing the same money?Gross charges, refunds, tax, commission and proceeds definitionsA customer charge is not the payout received
Is the population aligned?App, store, environment and currencySandbox activity or another app entered the report
Does access agree with the purchase history?Current entitlement and relevant transactionsRestore, family access, grace or promotional access differs from a new charge

A reconciled total still needs record-level coverage. Two missing charges and two duplicates can cancel numerically. Keep the exceptions visible and prove the selected population before using the result for acquisition payback or retention decisions.

What should one trial-to-renewal test prove?

A useful end-to-end fixture follows one account through product behavior, purchase state, access and messaging, then includes a failure and recovery. The following is a hypothetical Apple subscription path with a seven-day trial; it is not a reported customer result or a universal offer configuration.

What should one trial-to-renewal test prove?
StageState to verifyAnalytics and messaging consequence
Install and tracking refusalPermitted app identity exists; no unauthorized cross-company trackingRecord eligible product activity without inventing campaign identity
Signup and trialCorrect account receives the intended trial entitlementBegin useful onboarding once its eligibility is established
Paid renewal after trialVerified renewal and commercial recordRecord the paid outcome once and stop obsolete trial messaging
Later billing issue with graceCurrent access and recovery state reflect the configured grace policyOffer relevant recovery help without immediately treating access as expired
Successful recoveryVerified recovered renewal and refreshed entitlementStop unresolved-payment reminders and reconcile the money

Apple distinguishes grace-enabled billing failure from recovery through its type/subtype model. Use those distinctions in the fixture, but confirm current state before the customer action. A delayed earlier failure notification must not restart a reminder after recovery. Apple lifecycle notifications

Then run a separate Android fixture using Play’s actual states and purchase references. Do not relabel the Apple test and assume it proves Google behavior. Add reinstalls, account switching, refund reversal and repeated delivery to the release suite.

What changes for web purchases or apps without subscriptions?

For web purchases, connect the verified web billing account to the intended app identity and entitlement. RevenueCat Web supports its own billing engine, Stripe Billing and Paddle Billing, with different ownership of billing functions. Confirm the selected integration and current app-store rules before designing external purchase links or an in-app checkout route. Technical integration support is not blanket policy approval. RevenueCat Web

For a one-off purchase app, replace recurring-renewal analysis with the actual product model. A consumable purchase, a permanent unlock and a temporary pass have different access and restore requirements. Keep the verified purchase, refund and fulfillment relationship explicit. Do not apply subscription expiration logic to a permanent unlock merely because the analytics tool uses the same event name.

For an ad-funded app, revenue comes from the relevant advertising or mediation records and their eventual adjustments and payouts. Product events still explain engagement, but an impression event is not automatically a settled amount received. Reconcile the provider’s revenue definition and timing before comparing cohort acquisition cost with monetization.

Mixed models need both paths. A subscriber might also see ads or buy a one-off item. Name the revenue components and the customer treatment they permit, rather than forcing every record into one subscription flag. A maintained warehouse becomes useful when these combined questions recur and an owner can operate the model.

Which release checks should pass before growth spend increases?

Prove access, money, identity and messaging independently, then verify the complete customer path. Use the actual store sandbox and supported test tools for the native integration; a local ledger calculation cannot prove a purchase implementation works.

How the workflow fits together
Identify store or billing evidence and its environment. Unverified source or unresolved account holds the action until repaired. Verified evidence refreshes entitlement and canonical monetary state; stale or unreconciled records return to repair and source verification. Only a remaining relevant, permitted action proceeds; otherwise access remains correct and unnecessary messaging is suppressed.
Read diagram as text
  • Receive store or billing evidence and identify its environment to Verified source and intended account resolve?.
  • Verified source and intended account resolve? to Hold the action and resolve verification or identity: No.
  • Hold the action and resolve verification or identity to Receive store or billing evidence and identify its environment.
  • Verified source and intended account resolve? to Refresh entitlement and canonical monetary state: Yes.
  • Refresh entitlement and canonical monetary state to State is current and required records reconcile?.
  • State is current and required records reconcile? to Repair the gap and recheck authoritative state: No.
  • Repair the gap and recheck authoritative state to Receive store or billing evidence and identify its environment.
  • State is current and required records reconcile? to A relevant permitted customer action remains?: Yes.
  • A relevant permitted customer action remains? to Keep product access correct and suppress unnecessary messaging: No.
  • A relevant permitted customer action remains? to Perform the owned action and monitor its outcome: Yes
Open full diagram

Checklist

  • Product and entitlement mappings cover every intended store and tier.
  • Verified notifications and authoritative state are separated from raw transport events.
  • Production and sandbox records remain distinct throughout reporting and activation.
  • Cancellation, grace, hold, expiry, refund and recovery have explicit acceptance cases.
  • Login, reinstall, restore and account switching preserve the correct identity and access.
  • Each monetary fact has one canonical producer and a duplicate-control rule.
  • Ledger reconciliation preserves currency, period, coverage and adjustment definitions.
  • SDK behavior respects the relevant tracking and data-sharing decisions.
  • Messaging rechecks current need, channel eligibility and ownership near dispatch.
  • Missing deliveries, stale state and failed refreshes have an operator and recovery path.

Start with the $99 martech audit when subscription, analytics and messaging totals cannot be explained together. For an implementation, request a detailed product analytics and app integration scope with the stores, billing route, identity model and first customer journey. That scope makes the access, revenue and activation tests concrete.

Keep reading

Browse all Martech Strategy guides

Questions people ask

Can Firebase alone cover the first version of the app?

It may cover the initial product-event and diagnostic needs if those capabilities fit your questions. Firebase Analytics measures app usage and engagement. It does not remove the requirement to establish verified purchase state, entitlement and current customer eligibility. Start with the required workflow and evidence, then add another platform when it solves a recurring gap rather than duplicating the same events elsewhere.

Does canceling auto-renewal mean the customer has churned?

It can mean the customer intends not to renew, while access and the paid relationship continue through the valid period. Keep renewal intent, current entitlement and paid retention separate in reports. A later recovery or reversal can change the customer action again. Define which state your churn metric measures before comparing it with a vendor’s cancellation chart.

Does restoring a purchase create another revenue event?

Restoring access is not by itself evidence of another charge. Reconcile the store purchase relationship and the application identity, then preserve the commercial entry’s uniqueness. A new installation, alias or device can change the way a customer appears in analytics without creating a new sale. Test the restore path against both access and the monetary ledger.

Can we remove app access whenever the subscription API is unavailable?

An unavailable response is not proof of an expired entitlement. Use the supported cache and offline behavior of the selected implementation, with explicit limits and recovery handling. Keep new marketing actions on hold when their required state is uncertain. Test the outage and refresh paths so temporary connectivity problems do not silently become an invented cancellation or an unlimited access grant.

Should analytics revenue equal the store payout every month?

Only if the definitions and populations are aligned, which a raw comparison often fails to establish. Customer charges, refunds, taxes, commissions, currency conversion and settlement timing can produce different amounts. Reconcile commercial entries first, then bridge the relevant deductions and timing to proceeds. Preserve unresolved differences rather than forcing an analytics total to equal a payout by adjustment.

Sources

  1. Apple: App Store notification types.
  2. Apple: App Store Server Library for Python.
  3. Apple: Subscription status and billing recovery.
  4. Google Play: Real-time developer notifications.
  5. Google Play: Subscription lifecycle.
  6. RevenueCat: Entitlement mapping.
  7. RevenueCat: Pricing.
  8. RevenueCat: Monthly Tracked Revenue and billing.
  9. RevenueCat: Supported third-party integrations.
  10. RevenueCat: Customer identity.
  11. RevenueCat: Webhook delivery and state synchronization.
  12. RevenueCat: CustomerInfo and caching.
  13. Apple: Privacy and tracking requirements.
  14. RevenueCat: Web billing integrations.
  15. Google: Analytics for Firebase.
Portrait of Jafrin Akter Alo

Written by

Jafrin Akter Alo

Data Engineer and Co-founder at Martechdevs and Growth and Analytics Partners

Jafrin writes practical guides to marketing technology, customer data, analytics and AI workflows. Martechdevs is a Growth and Analytics Partners company.

View LinkedIn profile

Book a Free Call

Thirty minutes on your stack and what it needs. Free, and no pitch.

Thirty minutes, and you leave with a plan

We look at what you have, what it is costing you and what to do about it first.

  • 30 minutes
  • Video call, link on booking
  • No obligation

What we'll cover

  • Your current stack and where it hurts
  • Quick wins we can ship first
  • An integration roadmap
  • Timeline, scope and next steps

Calendar not loading? Open it in a new tab or email hello@martechdevs.com.