# RevenueCat Cross-Platform Subscription: iOS + Android Tek SDK
RevenueCat, subscription management için de-facto cross-platform solution. iOS StoreKit 2 + Google Play Billing v7 aynı SDK ile — manual server-side validation gereksiz. Entitlement system, customer-level analytics, webhook'lar, experiment platform. $0-10k MRR free tier — indie ve startup için ideal. Bu yazı RevenueCat'in teknik entegrasyonunu, self-built alternative'le karşılaştırmasını ve production best practice'leri kapsar.
💡 Pro Tip: Eğer her ay $10k+ MRR ve IAP logic'i core business ise self-built. Altında RevenueCat — 3 günde setup, aylık saat maliyeti kurtarır.
İçindekiler
- RevenueCat Nedir
- Setup: iOS + Android
- Entitlement System
- Offerings ve Paywalls
- Customer Analytics
- Webhooks
- Self-Built vs RevenueCat
- Pricing Model
- Best Practices
RevenueCat Nedir
Subscription infrastructure as a service:
- Abstract iOS StoreKit + Google Play Billing
- Centralized customer & subscription state
- Cross-device restore
- Webhook system
- Experiment platform (A/B pricing)
- Dashboard analytics
Founded 2018, series C funded 2022, $50B+ tracked MRR (2026).
Setup: iOS + Android
iOS Setup
swift
1// Package.swift2.package(url: "https://github.com/RevenueCat/purchases-ios", from: "5.0.0")3 4// App start5import RevenueCat6 7@main8struct MyApp: App {9 init() {10 Purchases.logLevel = .debug11 Purchases.configure(withAPIKey: "public_api_key_here")12 }13 14 var body: some Scene {15 WindowGroup {16 ContentView()17 }18 }19}Purchase Flow (iOS)
swift
1struct PaywallView: View {2 @State private var offerings: Offerings?3 4 var body: some View {5 VStack {6 if let package = offerings?.current?.package(identifier: "monthly") {7 Button("Subscribe: \(package.storeProduct.localizedPriceString)") {8 Task {9 do {10 let result = try await Purchases.shared.purchase(package: package)11 if result.customerInfo.entitlements.active["pro"] != nil {12 // User is pro!13 }14 } catch { ... }15 }16 }17 }18 }19 .task {20 offerings = try? await Purchases.shared.offerings()21 }22 }23}Android Setup
kotlin
1// app/build.gradle.kts2dependencies {3 implementation("com.revenuecat.purchases:purchases:8.0.0")4}5 6// Application class7Purchases.configure(PurchasesConfiguration.Builder(context, "public_api_key").build())8 9// Purchase10Purchases.sharedInstance.purchase(11 PurchaseParams.Builder(activity, package).build(),12 callback = object : PurchaseCallback {13 override fun onCompleted(purchase: Purchase, customerInfo: CustomerInfo) {14 if (customerInfo.entitlements["pro"]?.isActive == true) {15 // User is pro!16 }17 }18 override fun onError(error: PurchasesError, userCancelled: Boolean) { }19 }20)Entitlement System
"Entitlement" = user'a verdiği permission. Product-agnostic.
RevenueCat dashboard:
- Product
pro_monthly→ Entitlementpro - Product
pro_yearly→ Entitlementpro - Product
lifetime→ Entitlementpro
Kod:
swift
1if let info = try? await Purchases.shared.customerInfo() {2 if info.entitlements["pro"]?.isActive == true {3 // Show pro features4 }5}Hangi product satın aldığı önemsiz — entitlement aktif mi değil mi?
Offerings ve Paywalls
Offerings = Pricing tier'larını dynamic olarak değiştirme. Kod deploy gerektirmez.
swift
1let offerings = try? await Purchases.shared.offerings()2 3// "current" = default group (dashboard'da set)4let current = offerings?.current5 6// Display packages7current?.availablePackages.forEach { package in8 print("\(package.identifier): \(package.storeProduct.localizedPriceString)")9}10 11// Lookup specific12let monthly = current?.package(identifier: "monthly")13let annual = current?.package(identifier: "annual")RevenueCat UI (Paywall)
2024'te RevenueCat Paywall SDK çıktı — Figma-like designer:
swift
1import RevenueCatUI2 3struct MyPaywallView: View {4 var body: some View {5 PaywallView()6 // Dashboard'dan design edilen paywall7 }8}A/B test paywall design'ları dashboard'dan.
Customer Analytics
Dashboard'da per-customer:
- Purchase history
- Entitlement status
- Revenue
- LTV
- Churn risk score
- Support ticket integration
Her user'ı individual olarak analyze edebilirsin.
Webhooks
Subscription lifecycle event'leri webhook ile backend'e:
typescript
1// Node.js webhook handler2app.post('/revenuecat-webhook', async (req, res) => {3 const event = req.body.event;4 5 switch (event.type) {6 case 'INITIAL_PURCHASE':7 await grantProAccess(event.app_user_id, event.product_id);8 break;9 case 'RENEWAL':10 await extendAccess(event.app_user_id);11 break;12 case 'CANCELLATION':13 await markCancelled(event.app_user_id);14 break;15 case 'REFUND':16 await revokeAccess(event.app_user_id);17 break;18 case 'EXPIRATION':19 await expireAccess(event.app_user_id);20 break;21 }22 23 res.status(200).send('OK');24});RevenueCat webhook'larını idempotent ve retry edilebilir design etmiş.
Self-Built vs RevenueCat
Faktör | Self-Built | RevenueCat |
|---|---|---|
Setup süresi | 2-4 hafta | 2-3 gün |
Platform count | iOS + Android ayrı | Tek SDK |
Server maintenance | Sürekli | Yok |
Cross-device restore | Manual | Native |
Edge case handling | Manual (refund, family, etc.) | Automatic |
Analytics | DIY | Built-in |
A/B testing | DIY (karmaşık) | Native |
Customer support | Manuel backend query | Dashboard'dan click |
Price | $0 | % of MRR (see pricing) |
Vendor lock-in | Yok | Export yetenek var ama zahmetli |
Pricing Model
RevenueCat tier'ları:
- Free: $0-2,500 MTR (monthly tracked revenue)
- Starter: 0.8% of tracked revenue (above $2,500 MTR) — 0.8% × $100k = $800/ay
- Grow: 1% tracked revenue, advanced features
- Enterprise: Custom, large volumes
Örnek:
- $5k MRR → $40/ay (0.8%) → profitable for RevenueCat pay over self-build
- $50k MRR → $400/ay — hala much cheaper than DevOps engineer time
- $500k MRR → $4k/ay — bu noktada self-build değerlendirilir
Best Practices
- User-facing product identifiers cross-platform aynı:
- iOS: pro_monthly_0999
- Android: pro_monthly_0999
- RevenueCat: pro_monthly entitlement
- Offerings via dashboard: Asla hardcode pricing
- Webhook idempotent: Same event ID → same result
- Customer merge (anonymous → logged-in):
Purchases.shared.logIn(userID)
- Attribution: Marketing attribution parametrelerini ekle (
setAttributes)
- Restore purchase:
Purchases.shared.restorePurchases()— App Store zorunlu
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
yaml
1Kullanılmalı eğer:2 - MRR < $50k (self-build maliyeti hala değer değil)3 - iOS + Android aynı codebase4 - Küçük team (< 5 dev)5 - A/B pricing experiment yapmayı planlıyorsun6 - Cross-device restore important7 - Developer time scarce8 9Self-build düşünülebilir eğer:10 - MRR > $50k (ekonomik)11 - Complex edge cases (B2B, enterprise custom pricing)12 - Strict vendor lock-in kaygısı13 - Full data ownership regulatorik gerekli14 - Core business = IAP (app = subscription)15 - DevOps team yeterli kapasitedeOkuyucu Ödülü
RevenueCat kullanmalı mısın? **External Resources:** - [RevenueCat docs](https://docs.revenuecat.com/) - [Purchases iOS SDK](https://github.com/RevenueCat/purchases-ios) - [Purchases Android SDK](https://github.com/RevenueCat/purchases-android) - [RevenueCat State of Subscription report](https://www.revenuecat.com/state-of-subscription-apps/) - [Jacob Eiting ProductHunt launch](https://www.producthunt.com/products/revenuecat)
Sonuç
RevenueCat $5M-$500k MRR range'inde optimal choice. Cross-platform SDK, entitlement system, offerings, webhooks — hepsi mature ve production-ready. Self-build değerlendir sadece çok büyük scale'de veya regulatorik reasons için. İndie + startup için "RevenueCat-first" standard. 3 günde setup, saatlerce zaman kurtarır.
*İlgili yazılar: StoreKit 2, Play Billing v7, $1M App Story.*

