Назад към всички

In-App Purchases

// Implement in-app purchases and subscriptions across iOS, Android, and Flutter with RevenueCat, paywalls, receipt validation, and subscription analytics.

$ git log --oneline --stat
stars:1,933
forks:367
updated:March 4, 2026
SKILL.mdreadonly
SKILL.md Frontmatter
nameIn-App Purchases
slugin-app-purchases
version1.0.0
descriptionImplement in-app purchases and subscriptions across iOS, Android, and Flutter with RevenueCat, paywalls, receipt validation, and subscription analytics.
metadata[object Object]

When to Use

User needs to implement in-app purchases, subscriptions, paywalls, or monetization flows. Agent handles native APIs (StoreKit 2, Google Play Billing), cross-platform SDKs (RevenueCat, Adapty, Qonversion), paywall design, server verification, and subscription analytics.

Quick Reference

TopicFile
iOS StoreKit 2storekit.md
Android Billinggoogle-play.md
Flutter packagesflutter.md
RevenueCat SDKrevenuecat.md
Platform comparisonplatforms.md
Server verificationserver.md
Paywall designpaywalls.md
Subscription metricsanalytics.md
Testing & sandboxtesting.md

Core Rules

1. Choose Your Architecture

ApproachWhen to UseTradeoff
Native onlySingle platform, full controlMore code, no cross-platform sync
RevenueCat/AdaptyCross-platform, fast launch1-2% fee, dependency
HybridNative + own backendFull control, more work

2. Platform SDKs (Managed)

PlatformPricingBest For
RevenueCatFree <$2.5k MTR, then 1%Most apps, best docs
AdaptyFree <$10k MTR, then 0.6%Cost-conscious, A/B paywalls
QonversionFree <$10k MTR, then 3%Simple setup
SuperwallPaywall-focusedPaywall A/B only
GlassfyFree <$10k, then 0.5%Budget option

3. Product Types

TypeiOSAndroidUse Case
ConsumableCredits, coins, lives
Non-consumableUnlock feature forever
Auto-renewableSubscriptions
Non-renewingSeason pass, time-limited

4. Server Verification is Non-Negotiable

Never trust client-side validation alone:

  • iOS: App Store Server API with JWS verification
  • Android: Google Play Developer API
  • RevenueCat: Webhooks + REST API

5. Handle All Transaction States

StateAction
PurchasedVerify → grant → finish
PendingWait, show pending UI
FailedShow error, don't grant
DeferredWait for parental approval
RefundedRevoke immediately
Grace periodLimited access, prompt payment
Billing retryMaintain access during retry

6. Subscription Lifecycle Events

Must handle all of these (native or via webhooks):

  • INITIAL_PURCHASE → grant access
  • RENEWAL → extend access
  • CANCELLATION → mark will-expire
  • EXPIRATION → revoke access
  • BILLING_ISSUE → prompt to update payment
  • GRACE_PERIOD → limited access window
  • PRICE_INCREASE → consent required (iOS)
  • REFUND → revoke + flag user
  • UPGRADE/DOWNGRADE → prorate

7. Restore Purchases Always

Required by App Store guidelines:

  • Prominent restore button
  • Works for logged-out users
  • Handles family sharing (iOS)
  • Cross-device sync

8. Paywall Best Practices

See paywalls.md for detailed patterns:

  • Show value before price
  • Anchor pricing (3 options, highlight middle)
  • Free trial prominent
  • Social proof if available
  • A/B test everything

9. Testing Strategy

EnvironmentiOSAndroid
Dev/DebugStoreKit Config fileLicense testers
SandboxSandbox accountsInternal testing
ProductionReal accountsProduction

Sandbox subscription times:

  • 1 week → 3 minutes
  • 1 month → 5 minutes
  • 1 year → 1 hour

10. App Store Guidelines

  • No external payment links (anti-steering)
  • Must use IAP for digital goods
  • Physical goods/services can use Stripe
  • Reader apps have exceptions
  • 15-30% commission applies

Common Traps

  • Testing with real money → use sandbox/test accounts
  • Not finishing transactions → auto-refund (Android 3 days)
  • Hardcoding prices → always fetch from store (regional pricing)
  • Missing transaction observer → lose purchases made outside app
  • No server verification → trivially bypassable
  • Ignoring grace period → users churn when they could recover
  • Poor paywall UX → kills conversion regardless of price
  • Not tracking metrics → can't optimize what you don't measure
  • Forgetting restore button → App Store rejection
  • Not handling family sharing → confused users