Apple guideline 3.1.1 and Google Play Billing Policy both require that all digital goods sold within an app — subscriptions, consumables, non-consumables — are transacted exclusively through the platform's official billing API (StoreKit on iOS, Play Billing Library on Android). Routing a digital goods purchase through Stripe, Paddle, PayPal, or any other third-party processor via a webview or external link is not a gray area: it results in immediate rejection and, for repeat violations, developer account termination. Apple has removed apps and banned developer accounts for this specific violation. The business impact is severe: an app rejected during review has zero revenue until resubmitted, a process that takes days to weeks and requires removing the violating payment flow entirely.
Critical because violation results in immediate App Store rejection and potential permanent developer account termination with no warning period.
Remove any Stripe, Paddle, or other third-party payment flows used for digital goods and replace them with StoreKit (iOS) or Play Billing Library (Android). The fastest cross-platform path is RevenueCat, which wraps both platform SDKs and handles receipt validation server-side.
npm install react-native-purchases
npx pod-install
// React Native — purchase via RevenueCat
import Purchases from 'react-native-purchases';
const { customerInfo } = await Purchases.purchasePackage(pkg);
if (customerInfo.entitlements.active['premium']) {
unlockPremium();
}
For Expo projects: npx expo install expo-iap. For Flutter: add in_app_purchase: ^3.2.0 to pubspec.yaml. Physical goods and real-world services (delivery, rides, hotel bookings) are exempt — only digital goods require the platform store.
app-store-iap-subscriptions.iap-integration.storekit-billingcriticalimport StoreKit in Swift files, StoreKit.Product.purchase() or SKPaymentQueue references, or an approved SDK wrapper (react-native-iap, expo-iap, react-native-purchases for RevenueCat, adapty, react-native-qonversion, in_app_purchase Flutter plugin). For Android: look for BillingClient in Kotlin, or the same approved wrappers. In React Native, check files in src/lib/iap/, src/services/iap.ts, src/hooks/useIAP.ts, or equivalent. In Flutter, check lib/services/iap_service.dart or similar. The critical failure pattern is a digital goods purchase flow routed through a third-party web payment processor (Stripe, Paddle, PayPal, LemonSqueezy, etc.) via an in-app webview or Linking.openURL() to a checkout page — this is one of the most severe guideline violations and results in immediate rejection and potential developer account termination."Stripe checkout URL opened via Linking.openURL() in src/screens/UpgradeScreen.tsx when user taps 'Go Premium' — Apple guideline 3.1.1 violation" or "No StoreKit or Play Billing integration found despite app displaying locked premium features"npm install react-native-purchases
npx pod-install
// AppDelegate.swift (iOS)
Purchases.configure(withAPIKey: "appl_xxxxx")
// MainApplication.kt (Android)
Purchases.configure(this, "goog_xxxxx")
// React Native
import Purchases from 'react-native-purchases';
const { customerInfo } = await Purchases.purchasePackage(package);
expo-iap:
npx expo install expo-iap
in_app_purchase:
# pubspec.yaml
dependencies:
in_app_purchase: ^3.2.0