RevenueCat vs StoreKit 2 vs Play Billing: What Devs Choose
Updated 19 Oct 2026 7 min readFrom the communitySubscriptions
On this page· 8
Every subscription app ships on top of one of three billing stacks: Apple's StoreKit 2, Google's Play Billing Library, or a wrapper such as RevenueCat that sits above both. The choice is rarely about the purchase sheet itself; it is about who validates the receipt, who keeps the entitlement in sync across devices and platforms, and how much of your revenue you are willing to pay for not doing that work.
What each layer actually does
StoreKit 2 is Apple's native framework. It returns every transaction as a JSON Web Signature that the device verifies, exposes Transaction.currentEntitlements as the source of truth for what a user owns, and streams renewals, refunds and revocations through Transaction.updates. On the server side, Apple provides the App Store Server API (transaction history, subscription statuses) and App Store Server Notifications V2 for real-time events, replacing the deprecated verifyReceipt endpoint 2.
Play Billing is Google's equivalent on Android. The client library handles the purchase flow; the Play Developer API (purchases.subscriptionsv2:get) and Real-time Developer Notifications (RTDN) do the server-side part. Google is explicit that your backend, not your app, should verify the purchase token, grant the entitlement, acknowledge the purchase and, if validation fails, revoke it 3. Unacknowledged purchases are automatically refunded after three days, which is one of the most common ways a native Android integration silently loses money 3.
RevenueCat wraps both, plus Amazon, Stripe and web billing, behind one SDK and one entitlements model. Its own docs describe the core as entitlements and subscription status, charts, experiments, paywalls, and "events and integrations" that forward normalised subscription data to analytics and marketing tools 5. It also answers Apple's refund consumption requests and Google's refund-review prompts on your behalf 6.
RevenueCat pricing in October 2026
RevenueCat's public pricing page currently lists one standard plan: free until the app reaches $2,500 in Monthly Tracked Revenue (MTR), then 1% of what you track, with all features included 1. Enterprise is "custom pricing & usage" with volume discounts, dedicated support and SLAs 1. The Growth Tools bundle (paywalls, web-to-app funnels, A/B/n testing) is listed separately, also at 1% of MTR on what you track 1. The pricing page does not define MTR in the version we fetched; the "What is MTR?" FAQ entry was empty, so whether MTR is measured before or after the store's commission is unconfirmed from the page itself, although the FAQ wording implies pre-platform-cut revenue 1.
For scale: an app doing $20,000 MTR pays RevenueCat roughly $200 a month on top of Apple's or Google's commission, which for Apple is 30% in a subscriber's first year, 15% after that, or 15% throughout under the Small Business Program 2.
Server-side validation without a wrapper
Going native does not mean skipping the server. On iOS, a backend should accept the signed transaction (or the originalTransactionId), verify the JWS chain, and subscribe to Server Notifications V2 for DID_RENEW, EXPIRED, REFUND and DID_FAIL_TO_RENEW 2. The App Store Server API's "Get All Subscription Statuses" endpoint is Apple's recommended way to check whether a subscription is active, in billing retry or in a grace period 2.
On Android, the equivalent loop is: store the purchaseToken as a unique key, call subscriptionsv2:get, grant only on PURCHASED, acknowledge immediately from the server, invalidate any linkedPurchaseToken after an upgrade or downgrade, and poll the Voided Purchases API for refunds and chargebacks you must claw back 3,4. Google also recommends attaching an obfuscatedAccountId so Play can map transactions to your user and block suspicious ones before they complete 3.
None of this is hard in isolation. The cost is owning two notification formats, two status models and two sets of edge cases that both vendors keep extending 8.
Cross-platform entitlements
The strongest argument for a wrapper is a user who pays on iPhone and opens the Android app. RevenueCat keys entitlements to an app user ID, so a backend asks "does user X have premium?" rather than "does this Apple ID or Google account have a live token?" 5. Doing the same natively means your own identity service has to link the Apple appAccountToken and Google obfuscatedAccountId to the same user, and reconcile when the two stores disagree. One Hacker News commenter built exactly this in-house and reports it "works very well," but it is a project, not a weekend 9.
When going native is enough
The community consensus is consistent across Hacker News and the Apple Developer Forums: if your app is iOS-only, has no server-side content, and you are comfortable with StoreKit 2's on-device entitlement stream, you do not need a third party. One HN commenter argued in December 2025 that "recent StoreKit changes this year close a lot of the remaining gap" and that RevenueCat's position "can only get worse" as Apple and Google improve first-party tooling 9. Apple's own StoreKit views (SubscriptionStoreView) now cover the paywall UI that was once a RevenueCat selling point, although developers still ask whether the automatic style satisfies App Review's value-disclosure rule 8.
The counter-argument is operational. The same forums are full of threads on sandbox products not loading, offer-code sheets accepting codes for the wrong tier, and commitmentExpiresDate misbehaving in sandbox 8. A wrapper does not fix Apple's bugs, but someone else writes the workaround and the dashboard.
Our rule of thumb: go native if you are single-platform and under roughly $2,500 MTR (where RevenueCat is free anyway, so the question is lock-in, not cost), or if your backend must already be the entitlement authority. Use a wrapper if you ship on both stores, sell lifetime or consumable products alongside subscriptions, or need churn and cohort charts without building them.
Migration pain points from community reports
Moving existing subscribers onto RevenueCat, or off it, is where most of the complaints live. RevenueCat's migration guide says the preferred path is importing stored Apple receipts and Google purchase tokens server-side; if you never stored them, you are limited to a client-side syncPurchases that only reaches users who open the updated app 5. Google purchases that expired more than 60 days earlier cannot be imported, and charts will have gaps unless you buy a historical import 5. The guide also warns against calling syncPurchases on every launch because it "can unintentionally alias customers together" 5.
The RevenueCat Community's SDK forum over the last year shows the same themes: restore purchases returning empty on iOS and on Google Play for non-consumables, ITEM_ALREADY_OWNED errors with nothing to restore, and breakage after the forced upgrade to SDK 9 for Google's Billing Library 8 requirement 7. On the other side, a March 2026 HN thread called RevenueCat "super difficult and time-consuming" to integrate and complained that AI coding assistants struggle with it, while others reported shipping entirely AI-built integrations via RevenueCat's MCP server 10.
What developers are asking
- "Is StoreKit 2 alone enough for an indie iOS app?" Yes, if you are single-platform and verify on device or against the App Store Server API 2.
- "Does RevenueCat charge on gross or net?" The pricing page says 1% of MTR above $2,500 and does not define MTR unconfirmed 1.
- "How do I keep entitlements in sync across iOS and Android?" Either a wrapper keyed on your user ID, or your own mapping of
appAccountTokenandobfuscatedAccountId3. - "Why were my Android purchases refunded automatically?" Unacknowledged purchases refund after three days; acknowledge from the server 3.
- "Can I migrate later?" Yes, but only if you stored receipts and tokens; otherwise you depend on users opening the app 5.
- "Will Apple shut down StoreKit 1?" Developers are asking on the forums; Apple has not announced a date 8.
How this shows up in the charts
Billing stack is invisible to the ranking algorithms, but it shapes what we see. Apps that handle grace periods and billing retry properly keep subscribers through card failures, which protects the revenue that feeds the Top Grossing lists. RevenueCat's 2026 report notes that involuntary billing failures cause 31% of Google Play cancellations against 14% on the App Store, so Android integrations that skip account-hold handling leak proportionally more 11. The report also shows only 17.3% of new subscription apps reach $1,000 in monthly revenue within two years, which is below the free tier of every wrapper, so for most apps the billing choice is about engineering time, not fees 11.
Sources
- RevenueCat — Pricing
- Apple Developer — Auto-renewable subscriptions (commission, offers, grace period)
- Android Developers — Verify purchases before granting entitlements (security guidance)
- Android Developers — Subscription lifecycle (grace period, account hold, resubscribe)
- RevenueCat Docs — Migrating existing subscriptions
- RevenueCat Docs — Refunds
- RevenueCat Community — SDKs forum (restore and sync threads)
- Apple Developer Forums — StoreKit tag
- Hacker News — RevenueCat discussion (harmonic18374, Dec 31, 2025)
- Hacker News — RevenueCat setup complaint (sbari, Mar 24, 2026)
- RevenueCat — State of Subscription Apps 2026