# Pay-to-View: RevenueCat Removed — Migrating to Direct IAP + Stripe ## Overview We've removed **RevenueCat** as the middleman for in-app purchases. The backend now verifies purchases **directly** with Apple App Store and Google Play APIs. Stripe remains unchanged for web payments. --- ## What Changed (Backend) - **RevenueCat service and webhook removed entirely** - New `IapVerificationService` verifies purchases directly with: - **Apple** — App Store Server API v2 - **Google** — Google Play Developer API v3 - New webhook endpoints: - `POST /client/v1/webhooks/apple-appstore` — Apple App Store Server Notifications V2 - `POST /client/v1/webhooks/google-play` — Google Play Real-Time Developer Notifications (Pub/Sub) - Old `/client/v1/webhooks/revenuecat` endpoint is **removed** --- ## What Mobile Needs to Change ### 1. Remove RevenueCat SDK Remove the RevenueCat SDK from both iOS and Android apps entirely. ### 2. Use Native IAP | Platform | Use Instead | |----------|------------| | iOS | **StoreKit 2** (native Apple framework) | | Android | **Google Play BillingClient** (native Google library) | ### 3. Update the API Request **Endpoint:** `POST /client/v1/pay-to-view/mobile-purchase` (unchanged) #### Old Request Body (RevenueCat): ```json { "payToViewProductId": "ptv_abc123", "transactionId": "1000000123456789", "appUserId": "rc_user_id_here", "entityId": "encoded_entity_id", "provider": 2, "price": 4.99, "currency": "USD" } ``` #### New Request Body: ```json { "payToViewProductId": "ptv_abc123", "transactionId": "1000000123456789", "entityId": "encoded_entity_id", "provider": 2, "price": 4.99, "currency": "USD", "storeProductId": "com.gjirafa.video.product_123", "purchaseToken": "google_purchase_token_here" } ``` #### Changes: | Field | Status | Notes | |-------|--------|-------| | `appUserId` | **REMOVED** | No longer needed (was RevenueCat user ID) | | `storeProductId` | **NEW** | The product ID from the store (Apple product ID or Google SKU) | | `purchaseToken` | **NEW** | **Google only** — from `Purchase.getPurchaseToken()`. Not needed for Apple. | ### 4. Per-Platform Details #### Apple (provider: 2) - Use **StoreKit 2** to handle purchases - After a successful purchase, get `Transaction.id` → send as `transactionId` - Send the Apple product identifier as `storeProductId` - `purchaseToken` is **not needed** (leave null or omit) #### Google (provider: 3) - Use **Google Play BillingClient** to handle purchases - After a successful purchase: - `Purchase.getOrderId()` → send as `transactionId` - The SKU / product ID → send as `storeProductId` - `Purchase.getPurchaseToken()` → send as `purchaseToken` --- ## Webhook Configuration Needed These webhook URLs need to be configured in the respective developer consoles: ### Apple App Store Server Notifications V2 - Go to **App Store Connect → App → General → App Information** - Set **Server Notification URL** to: `https://{api-domain}/client/v1/webhooks/apple-appstore` ### Google Play Real-Time Developer Notifications - Go to **Google Play Console → App → Monetization setup** - Configure **Real-time developer notifications** with a Pub/Sub topic - Set up a **Pub/Sub push subscription** pointing to: `https://{api-domain}/client/v1/webhooks/google-play?token={webhook_token}` --- ## Summary | Before (RevenueCat) | After (Direct IAP) | |---------------------|-------------------| | RevenueCat SDK on mobile | Native StoreKit 2 / BillingClient | | RevenueCat API for verification | Direct Apple/Google API verification | | Single `/revenuecat` webhook | Separate `/apple-appstore` and `/google-play` webhooks | | `appUserId` in request | `storeProductId` + `purchaseToken` in request |