Discussion and help from anything related to RevenueCat.
Recently active
Hiwhere can I find the documentation for PaywallView.currently I’m using it like this:PaywallView() .onRequestedDismissal { state = .paymentRequiredInfo } .onPurchaseCompleted { CustomerInfo in state = .ready } .onPurchaseFailure({ NSError in state = .error(StaticErrorMessage("Payment error")) })After Purchase is completed, callback method onPurchaseCompleted is not called. If I try to purchase again I’m getting “already purchased” dialog info.So my question are why onPurchaseCompleted is not called and where is the documentation for PaywallView.Regards
Hey, I have implemented the RevenueCat with my Expo / React Native app. Everything is working correctly except when I invoke the paywall, instead of my published one - I just see the default RevenueCat paywall. I checked logs and it looks like this: 09-27 21:38:21.900 3704 3704 E [Purchases]: Missing string localization for property with id: 'VFL_T8xgne', for locale: 'en_US'.09-27 21:38:21.900 3704 3704 E [Purchases]: Missing string localization for property with id: 'VFL_T8xgne', for locale: 'en_US'.09-27 21:38:21.900 3704 3704 E [Purchases]: Missing string localization for property with id: '0B1RuOuUwn', for locale: 'en_US'.09-27 21:38:21.900 3704 3704 E [Purchases]: Missing string localization for property with id: '0B1RuOuUwn', for locale: 'en_US'.09-27 21:38:21.900 3704 3704 E [Purchases]: Displaying default template due to validation errors.09-27 21:38:21.913 3704 3704 W [Purchases]: Could not process value for variable 'sub_offer_duration' for package '$rc_annual'.
I want to fetch state from API in addition to webhook handling, for improved resilience.My subscriptions are credits based, when there’s initial/renewal event, I assign a number of credits to the user.Not sure how to proceed with the transfer webhook event:The user installs the app on device A: they get id 1. The user subscribes. My backend has id 1 → 10 credits.The user installs the app on device B: they get id 2.Let’s say that the backend for some reason doesn’t receive or process the transfer webhook, so it’s not aware that id 1 → id 2Now device B, with its id 2, triggers a refresh from RevenueCat api: I get that id 2 has a subscription.Since I don’t have the old id, all I can do here is to create a new record for id 2 with 10 credits, as if it was a new user. Which is incorrect, because it’s effectively duplicating the credits for the user, who can now use 10 credits on device A and 10 credits on device B.How can I associate the subscription data to the old id? Also, is the whole r
My wife opened her installation of the app we are developing yesterday and was directed to the paywall page, even though she has an active subscription. I looked at it, very puzzled, and then decided to try the “restore” link in the paywall screen. After a couple of seconds a dialog box came up indicating the restore was successful and after dismissing it the app functioned as expected. My understanding was that the restore link is only necessary when installing the app on a new phone or other similar situation. This occurred under “normal” conditions. It was very confusing to her and I am worried about users encountering this who are not married to one of the developers. Can someone explain to me why this might occur and if there are any steps I can take to avoid it from happening under “normal” circumstances? Thank you.
I am building a Flutter app.I have a subscriptions offering which includes subscriptions.I also have a ‘credits’ offering which has one time purchase products which gives users different amount of credits.Is my understanding correct that I can create 2 paywalls for these 2 offerings? Can I add a link in these a paywalls which takes the user to the other paywall? E.g. a button saying “purchase credits w/o subscription” and “subscribe for better deals”. How can I do this?Thanks a lot for your help!
Hello RC Support:The issue described below is in the latest IOS SDK only. The android SDK does not have this issue. The crux of the issue is that presented_offering_id IS NOT matching the product_id and resulting incorrect understanding of which product the user actually purchased.I’ll explain this with an example.We have a few product_id = Plus , Gold, Platinum. The corresponding presented_offering_id also matches this: i.e. presented_offering_id = Plus , Gold, Platinum.As an example, In IOS when a user purchases a Gold offering on the paywall, we see the following INCORRECT response in the webhook events that we receive. Actual plan purchased by the user: GoldProduct_Id received via webhook: goldpresented_offering_id received via webhook: platinum. In Android, it is functioning properly:Actual plan purchased by the user: GoldProduct_Id received via webhook: goldpresented_offering_id received via webhook: gold. I can share event logs and more via email.
I am using the React Native SDK, and I am getting some PAYWALL_RESULT.ERROR back when users are shown the paywall.I have been searching for what this result means, but I haven’t been able to find many details about this specific error.All I can see is this line from the source code: “If an error happened during purchase/restoration.” I would like to know whether this indicates an error on RevenueCat’s side (such as the server sending 500s) or a store/user error (for example, problems processing the payment).Thanks!
Platform: React NativeSDK Version: react-native-purchases 8.11.6, react-native-purchases-ui 8.11.6Issue: Bold font weight not applying on Android V2 Paywalls (works perfectly on iOS) Problem DescriptionI have successfully configured custom fonts ("Nunito Sans") for V2 Paywalls and they work perfectly on iOS, but on Android the bold weight is not being applied - all text appears as regular weight even when elements are configured as bold in the RevenueCat dashboard. What Works ✅- Custom font "Nunito Sans" loads correctly on Android (showing custom font instead of system font)- All font weights work perfectly on iOS- Regular font weight displays correctly on Android What Doesn't Work ❌- Bold font weight on Android (appears as regular weight)- Text configured as bold in dashboard renders as regular on Android only Technical Configuration Environment- React Native: 0.76.9 (bare workflow, NOT Expo)- RevenueCat SDK: react-native-purchases 8.11.6- RevenueCat UI: react-native-purchases-ui 8.11
I’m facing an issue with RevenueCat integration in my app. On iOS Simulator, using StoreKit configuration, the purchase flow works correctly when I tap the purchase button. On a real iOS device (via TestFlight), tapping the purchase button does nothing — there is no response or error shown. On Android (both emulator and real device), everything works fine. So the problem only occurs on a real iOS device through TestFlight.Has anyone experienced this before? Why would the purchase button not trigger anything on TestFlight, even though it works in the simulator?Any guidance or suggestions on what I should check for iOS would be greatly appreciated.
Hello,I am a little bit confused on what timezone RC used in the dashboard.The first image shows a customer renewed the subscription at 02:06 PM UTCCustomer history for renewal However, when i click the event details for the renewal, it is showing 06:06 AM UTCRenewal event detailMeanwhile, my server log shows that the webhook triggered at 02:06 PM MYT (06:06 AM UTC)Could anyone confirm this behaviour? Thanks
I’m trying to replicate the “LTV per paying customers (unbounded)” metric in our data export.However, my results are consistently wrong in reporting LTV by more than 8% (standard deviation) compared to the “LTV per paying customers” chart in the dashboard.Could there be an error in my approach, or is it possible to extract the underlying account IDs from the dashboard’s “LTV per paying customers” chart for validation?cohort Mismatch in % 2025-01-31 5.10% 2025-02-28 4.16% 2025-03-31 2.65% 2025-04-30 -4.40% 2025-05-31 6.42% 2025-06-30 1.61% 2025-07-31 7.87% 2025-08-31 11.92% 2025-09-30 -5.34% WITH subscriptions AS ( SELECT MIN(start_date) as subscription_start_time, rc_original_app_user_id, MAX(CASE WHEN subscription_status = 'trial' THEN 1 ELSE 0 END) as had_a_trial, SUM(price_in_usd) as realized_ltv, store, subscription_status FROM {{ ref('int_store_transaction_id__renewal_number___w_account_label_filtered') }} WHERE subscriptio
Hi team,I’m trying to set up one-time products within the Android version of my app. I’ve set up the product (with a product id + purchase option in the Google Play Console), but the product simply will not import or show up as “Published” within my RevenueCat product catalog.This worked just fine with iOS and I ran into no issues. Only seeing this for Android, could be related to some of the recent changes Android made with one-time products? I’m using RevenueCat with React Native using Expo.
Dear RevenueCat Community,I am using the RevenueCat SDK in my Flutter application and have implemented App Tracking Transparency (ATT) permission on iOS. When the user grants permission, I call the method Purchases.collectDeviceIdentifiers() to obtain the device's IDFA. This value is correctly set and included in the events sent through the webhooks.In my Flutter app, users can purchase subscriptions using Stripe. For this, a web view is opened for the user to complete the payment. Once the purchase is completed and the user returns to the app, the app submit to this endpoint https://api.revenuecat.com/v1/receipts the subscription ids to upload the purchase to RevenueCat. This is how the user gains access to the app features after the purchase.To receive purchase events centrally in my backend, I have added a webhook in RevenueCat that reports Initial Purchase and Renewal events to my endpoint.I have observed the following: For purchases made within the app (IAP), the IDFA is correctly
We are implementing a gift code redemption feature for our app, integrating with Airtable for code validation and RevenueCat for entitlement management. The backend is built with Strapi (Node.js), and the app is Kotlin Multiplatform (Android & ios). We have two plans monthly and annual. **The Flow:** 1. User redeems a gift code in the app 2. App calls our backend `/api/grant-entitlement` endpoint 3. Backend validates the code in Airtable 4. Backend attempts to grant an entitlement via RevenueCat API **The Problem:** We are consistently encountering a **500 Internal Server Error** from our backend (`dev-api.myatlas-health.com/api/grant-entitlement`) when it tries to call the RevenueCat API. **Debugging Steps Taken:** 1. Initially attempted to use RevenueCat v2 grant endpoint with `expires_at` 2. Discovered that RevenueCat does not have a v2 grant endpoint (404 error) 3. Switched to RevenueCat v1 promotional endpoint: `/v1/subscribers/{userId}/entitlements/{entitlementId}/p
We are implementing a gift code redemption feature for our app, integrating with Airtable for code validation and RevenueCat for entitlement management. The backend is built with Strapi (Node.js), and the app is Kotlin Multiplatform (Android & ios). We have two plans monthly and annual.**The Flow:**1. User redeems a gift code in the app2. App calls our backend `/api/grant-entitlement` endpoint3. Backend validates the code in Airtable4. Backend attempts to grant an entitlement via RevenueCat API**The Problem:**We are consistently encountering a **500 Internal Server Error** from our backend (`dev-api.myatlas-health.com/api/grant-entitlement`) when it tries to call the RevenueCat API.**Debugging Steps Taken:**1. ✅ Initially attempted to use RevenueCat v2 grant endpoint with `expires_at`2. ❌ Discovered that RevenueCat does not have a v2 grant endpoint (404 error)3. ✅ Switched to RevenueCat v1 promotional endpoint: `/v1/subscribers/{userId}/entitlements/{entitlementId}/promotional`4. ❌
We are seeing very strange issue in our app where peopple are starting trial of $4.99 product and getting charged for $199 yearly product. We are not able to understand this issue. Is this superwall issue or apple? here is the video explaination - https://www.dropbox.com/scl/fi/9pbt5mvhg0eel46kchwx2/IssueRevenue.mov?rlkey=vlgi5ro274m9u8q0kavlkqm3y&st=yce7hqub&dl=0
I am currently integrating RevenueCat's Web Purchase Links into my Webflow project for handling subscriptions. According to the RevenueCat documentation, I need to append app_user_id as a query parameter to the purchase link to associate the purchase with the correct authenticated user.Here is the link format I am using: https://pay.rev.cat/sandbox/rim********dasa/?app_user_id=897274573489Any guidance or suggestions would be greatly appreciated!
Hello, I’m preparing for affiliate marketing and I’m testing how offer codes work. I created a test one and sent it to someone, and configured a webhook to intercept it.That worked, proved the code was introduced correctly, but I was hoping to be able to find that customer in the customer list by filtering “Latest offer type” is any of “Offer code” OR “Latest offer” IS “CODE REF”The report is empty. Is that expected? Is there a delay? NOTE: I have set up the Appstore Connect API key and everything requested in the app setup.
Hi RevenueCat team,All of my agreements and tax information are already set up and working. I also have other apps where In-App Purchases are working fine. However, with this new app I’m stuck because of Apple’s requirement:“Your first subscription must be submitted with a new app version. Create your subscription, then select it from the app’s In-App Purchases and Subscriptions section on the version page before submitting the version to App Review.”Because of this, I cannot send my IAP for review, and Apple is rejecting the submission under 2.1 - Performance - App Completeness with the note:We found that your in-app purchase products exhibited one or more bugs which create a poor user experience. Specifically, after selecting both weekly and yearly subscriptions an error message is displayed.Review device details:• Device type: iPhone 13 mini• OS version: iOS 26.0At the same time, I get this warning from RevenueCat:[RevenueCat] ⚠️ RevenueCat SDK is configured correctly, but contains
This code checks to see if a customer should be shown the paywall. let customerInfo = try await Purchases.shared.customerInfo(fetchPolicy: .fetchCurrent) let timeInterval = Date.now.timeIntervalSince(customerInfo.firstSeen) let ninetyDays: TimeInterval = 90 * 24 * 60 * 60 return timeInterval >= ninetyDaysThis check is returning false.On the RevenueCat dashboard for this user first seen was 27 June 2024. They never changed their App User ID. However they only seen the paywall today 17 September 2025. Which is much greater than the 90 days. What could be causing the delay in showing the paywall? I appreciate that the customerInfo could be cached but not for over a year.
I am getting the following crashes on Android using revenueCat KMP SDK. And it has increased recently. What could be the issue?The attached two files are of the PaywallState and Purchase click button codes Exception java.lang.IllegalStateException: at com.revenuecat.purchases.kmp.di.AndroidProviderKt.requireActivity (AndroidProvider.kt:83) at com.revenuecat.purchases.kmp.Purchases.purchase (Purchases.android.kt:275) at com.revenuecat.purchases.kmp.Purchases.purchase$default (Purchases.android.kt:266) at utils.PaywallState.purchaseSelectedPackage (PaywallState.kt:29) at pro.ui.paywall.PaywallScreenKt.PaywallScreen$lambda$41$lambda$40$lambda$39$lambda$26$lambda$25 (PaywallScreen.kt:230) at androidx.compose.foundation.ClickableNode.onPointerEvent-H0pRuoY (Clickable.kt:1018) at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass (HitPathTracker.kt:436) at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass (HitPathTracker.kt:422) at androidx.compose.ui.input.poin
Looking for a RevenueCat expert to implement our subscription management and in-app purchase system across iOS and Android applications. Need assistance with:SDK integration and configuration for both platforms Product setup with subscription tiers, trial periods, and pricing strategies Webhook implementation for real-time subscription events Analytics dashboard configuration for revenue tracking and cohort analysis Customer lifecycle management including churn prevention and win-back campaigns A/B testing setup for paywall optimization and conversion improvemen
Hi everyone,I have a mobile app that originally relied on $RCAnonymousIDs to manage subscriptions. Now, we’ve introduced mandatory signup, so I’m now working on migrating from anonymous IDs to our own custom user IDs.What’s not clear to me is the best way to handle the transition: How can I merge an existing custom user ID with the old $RCAnonymousID values already in the system? Should this be done via the API, or does the SDK handle it automatically? In some cases, the custom user ID is already listed as an alias of an anonymous ID. How can I “promote” the custom ID so it becomes the original_app_user_id instead of the anonymous one? Has anyone here gone through a similar migration? Any guidance on the best practices would be really helpful.Thanks!
Hi everyone,This is my first time using RevenueCat. I’ve updated an image header on paywall. however on my phone it shows low resolution. it looks perfectly fine on the paywall editor. I have tried PNG and JPG, different resolution, etc. Can somebody shed a light where I can take a look? RevenueCat SDK Xcode [5.39.0]thanks,Wai Hong
Hi everyone,I'm implementing subscription upgrades and downgrades for Android in my React Native app, using react-native-purchases version 9.4.1. I'm currently running into an issue while testing on a physical device using an internal test track.What is happening:When I try to upgrade or downgrade from an active subscription (e.g., "plus") to another plan (e.g., "pro" or "lite"), the purchase flow fails. On Upgrade, I receive the following error from Google Play Billing via adb logcat: [RevenueCat] 🤖‼️ BillingWrapper purchases failed to update: DebugMessage: Requested replacement mode is not supported for this request. ErrorCode: DEVELOPER_ERROR. On Downgrade, I get a more generic Unknown error.. My Implementation:I check if the user already has an active subscription, and if so, I pass a second argument to the purchasePackage call to handle the upgrade/downgrade. Here is a snippet of my code:TypeScript // Using "react-native-purchases": "9.4.1"import Purchases, { PurchasesPackage
Already have an account? Login
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.