Learn how to easily add in-app purchases to your mobile app and boost revenue with our step-by-step guide.

Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Why In-App Purchases Matter
In-app purchases (IAPs) have become the backbone of mobile app monetization, offering a way to generate revenue without disrupting the user experience with ads or requiring upfront payment. When implemented thoughtfully, they can transform a free app into a sustainable business while enhancing user satisfaction.
Both platforms handle IAPs differently, so let's break down the implementation process for each:
Setting Up Your Products
For both platforms, you'll need to create unique product IDs (like "com.yourapp.premium.monthly") that you'll reference in your code.
Apple's StoreKit framework handles everything IAP-related on iOS. Here's how to implement it:
1. Basic Setup
import StoreKit
class IAPManager: NSObject {
// Shared instance for singleton pattern
static let shared = IAPManager()
// Product identifiers
let productIDs = ["com.yourapp.premium.monthly", "com.yourapp.removeads"]
// Available products fetched from App Store
var products = [SKProduct]()
// Observer for tracking transactions
private var purchaseObserver: Any?
override init() {
super.init()
// Setup transaction observer
purchaseObserver = SKPaymentQueue.default().add(self)
}
}
2. Fetch Available Products
func fetchProducts() {
let request = SKProductsRequest(productIdentifiers: Set(productIDs))
request.delegate = self
request.start()
}
// Delegate method to receive products
extension IAPManager: SKProductsRequestDelegate {
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
self.products = response.products
// Handle invalid product identifiers
if !response.invalidProductIdentifiers.isEmpty {
print("Invalid product IDs: \(response.invalidProductIdentifiers)")
}
}
}
3. Make a Purchase
func purchase(product: SKProduct) {
// Check if user can make payments
guard SKPaymentQueue.canMakePayments() else {
// Handle case where user can't make payments
return
}
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
}
1. Setup Dependencies
Add the Google Play Billing Library to your app's build.gradle:
dependencies {
implementation 'com.android.billingclient:billing:5.0.0'
}
2. Initialize the Billing Client
class BillingManager(private val activity: Activity) {
private lateinit var billingClient: BillingClient
init {
setupBillingClient()
}
private fun setupBillingClient() {
billingClient = BillingClient.newBuilder(activity)
.setListener { billingResult, purchases ->
// Process purchases here
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
handlePurchase(purchase)
}
}
}
.enablePendingPurchases()
.build()
// Connect to Google Play
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
// The billing client is ready. You can query purchases here.
queryAvailableProducts()
}
}
override fun onBillingServiceDisconnected() {
// Try to reconnect
}
})
}
}
3. Query Products and Make Purchases
private fun queryAvailableProducts() {
val params = QueryProductDetailsParams.newBuilder()
.setProductList(
listOf(
QueryProductDetailsParams.Product.newBuilder()
.setProductId("premium_subscription")
.setProductType(BillingClient.ProductType.SUBS)
.build(),
QueryProductDetailsParams.Product.newBuilder()
.setProductId("remove_ads")
.setProductType(BillingClient.ProductType.INAPP)
.build()
)
)
.build()
billingClient.queryProductDetailsAsync(params) { billingResult, productDetailsList ->
// Store product details for later use
}
}
fun purchase(productDetails: ProductDetails) {
val productDetailsParamsList = listOf(
BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
.build()
)
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.build()
billingClient.launchBillingFlow(activity, billingFlowParams)
}
If you're building with React Native, several libraries simplify IAP implementation across both platforms:
// Using react-native-iap
import { initConnection, getProducts, requestPurchase } from 'react-native-iap';
// Product IDs for both platforms
const productIds = Platform.select({
ios: ['com.yourapp.premium'],
android: ['premium_subscription']
});
// Initialize connection to store
await initConnection();
// Get product details
const products = await getProducts({ productIds });
// Purchase a product
try {
await requestPurchase({
sku: products[0].productId,
// For subscriptions on Android:
// andDangerouslyFinishTransactionAutomaticallyIOS: false
});
// Handle successful purchase
} catch (error) {
// Handle purchase error
}
Never trust the client for purchase verification. Always validate receipts on your server to prevent fraud.
Here's a simplified server-side validation example:
// Server-side receipt validation (Node.js example)
async function verifyAppleReceipt(receiptData) {
const endpoint = process.env.NODE_ENV === 'production'
? 'https://buy.itunes.apple.com/verifyReceipt'
: 'https://sandbox.itunes.apple.com/verifyReceipt';
const response = await fetch(endpoint, {
method: 'POST',
body: JSON.stringify({
'receipt-data': receiptData,
'password': process.env.SHARED_SECRET // Your App-Specific Shared Secret
})
});
const validation = await response.json();
// Check status and process receipt data
if (validation.status === 0) {
// Valid receipt - update user entitlements in your database
return true;
}
return false;
}
While the technical implementation is crucial, successful IAPs also depend on:
The most successful apps treat IAPs not as mere money-makers but as extensions of the user experience. When users make a purchase, they're investing in your product—make sure it feels worthwhile.
Remember that a thoughtfully implemented IAP system should be:
When implemented well, in-app purchases create that rare win-win: users get enhanced value, and your app gets the revenue it needs to thrive.
Explore the top 3 in-app purchase use cases to boost your mobile app’s revenue and user engagement.
A straightforward value exchange where users pay once to access exclusive content or features within your app. This model creates a clear separation between free and premium tiers without recurring billing complexity.
Digital items users purchase and "use up" within your app, requiring repurchase when depleted. Examples include in-game currency, extra lives, boosters, or temporary power-ups that enhance the user experience.
Recurring payment model granting users continuous access to premium features, content updates, or services for a fixed period (typically monthly or annually), automatically renewing until canceled.
From startups to enterprises and everything in between, see for yourself our incredible impact.
Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â