Overview
StoreKit 2 (iOS) and Google Play Billing Library (Android) are the native APIs for implementing in-app purchases on their respective platforms. Both have undergone significant modernization in recent years. StoreKit 2 replaced the original StoreKit framework with a Swift-native async/await API, while Play Billing Library 7.x brought improvements to subscription management and purchase verification.
This guide covers both APIs side by side, highlighting their similarities and differences.
StoreKit 2 (iOS)
Setup
- App Store Connect: Create your app, then navigate to Subscriptions or In-App Purchases to define products
- Xcode: Add the "In-App Purchase" capability to your target
- StoreKit Configuration File (optional): Create a local StoreKit configuration file for testing without App Store Connect
Fetching Products
let productIDs = ["com.app.monthly", "com.app.yearly"]
let products = try await Product.products(for: productIDs)
Products contain localized pricing, description, and subscription information. Always use the store-provided price for display.
Making a Purchase
let result = try await product.purchase()
switch result {
case .success(let verification):
let transaction = try checkVerified(verification)
// Deliver content
await transaction.finish()
case .userCancelled:
break
case .pending:
// Transaction requires approval (Ask to Buy)
break
}
Checking Entitlements
for await result in Transaction.currentEntitlements {
let transaction = try checkVerified(result)
// User owns this product
}
StoreKit 2 automatically manages the transaction history. You can check entitlements at any time without maintaining local state.
Server Verification
StoreKit 2 transactions are JWS (JSON Web Signature) tokens signed by Apple. You can verify them:
- On-device: Using Apple's root certificate
- Server-side: Using the App Store Server API to validate and retrieve transaction history
The App Store Server API provides endpoints for transaction lookup, subscription status, refund history, and consumption reporting.
Google Play Billing Library 7.x (Android)
Setup
- Google Play Console: Create products under Monetization > Products > In-App Products or Subscriptions
- build.gradle: Add the dependency
com.android.billingclient:billing:7.x - AndroidManifest.xml: Add
com.android.vending.BILLINGpermission
Connecting and Querying
Initialize BillingClient with a PurchasesUpdatedListener, call startConnection(), then use queryProductDetailsAsync() to fetch product information. Products are defined by product ID and type (INAPP or SUBS).
Making a Purchase
Build BillingFlowParams with the selected ProductDetails and offerToken, then call launchBillingFlow(activity, params). The result arrives in your PurchasesUpdatedListener.
Acknowledging Purchases
All purchases must be acknowledged within 3 days, or they are automatically refunded. Use acknowledgePurchase() for subscriptions and non-consumables, or consumeAsync() for consumables.
Server Verification
Use the Google Play Developer API:
purchases.subscriptionsv2.getfor subscription statuspurchases.products.getfor one-time purchases- Set up RTDN (Real-Time Developer Notifications) via Google Cloud Pub/Sub for webhooks
Cross-Platform Comparison
| Feature | StoreKit 2 | Play Billing 7.x |
|---|---|---|
| Language | Swift (async/await) | Kotlin/Java |
| Transaction Format | Signed JWS | Purchase token |
| Entitlement Check | Transaction.currentEntitlements | queryPurchasesAsync() |
| Acknowledgment | transaction.finish() | acknowledgePurchase() |
| Unacknowledged Timeout | Redelivered on next launch | Refunded after 3 days |
| Server Notifications | App Store Server Notifications v2 | RTDN (Pub/Sub) |
| Local Testing | StoreKit Configuration File | License testing / billing testing |
Cross-Platform Frameworks
For apps targeting both platforms, several frameworks abstract the differences:
- RevenueCat: Most popular. Handles both platforms with a unified API and server-side receipt validation
- Adapty: Similar to RevenueCat with paywall A/B testing
- react-native-iap: React Native library wrapping both native APIs
- purchases_flutter (RevenueCat): Flutter plugin for cross-platform billing
Related Topics
- In-App Purchase Guide - IAP types, integration overview, and validation concepts
- RevenueCat Integration Guide - Using RevenueCat to simplify cross-platform billing
- IAP Sandbox Testing - Testing purchases in sandbox and test environments