Discussion and help from anything related to RevenueCat.
Recently active
Background: My app stores user content. When it receives a TRANSFER webhook, it will move all owned content from the old account to the new account.On both IOS and Android, I get the expected behaviour when a logged in user restores a valid subscription: The entitlements are transferred to a the new account & a TRANSFER webhook is sent.The divergence comes when dealing with an expired subscription. IOSStepsCreate a subscription Cancel the subscription + wait for expiration Sign in on a different app account Press Restore purchasesOutcome: No entitlements in new app account, no TRANSFER web-hook sent AndroidStepsCreate a subscription Cancel the subscription + wait for expiration Sign in on a different app account Press Restore purchasesOutcome: No entitlements in new app account, TRANSFER web-hook is sent So for me, the Android case is wrong. Is there a reason for the inconsistency? Thanks,Jon
Hello,The steps I perform:1. Create a new user (the user appears in RevenueCat Dashboard).2. Grant entitlement to the user in the Dashboard.3. Run Purchases.restorePurchases() in the app (Flutter)4. Then Purchases.getCustomerInfo()The steps work perfectly in iOS: the customer info contains the entitlement.They doesn’t work on Android though. restorePurchase does not seem to account for the promo account given in the Dashboard: D/[Purchases] - DEBUG( 5926): ℹ️ Restoring purchasesW/[Purchases] - WARN( 5926): ⚠️ allowSharingPlayStoreAccount is set to false and restorePurchases has been called. This will 'alias' any app user id's sharing the same receipt. Are you sure you want to do this? More info here: https://errors.rev.cat/allowsSharingPlayStoreAccountD/[Purchases] - DEBUG( 5926): ℹ️ Querying purchase history for type subsE/libEGL ( 5926): called unimplemented OpenGL ES APID/EGL_emulation( 5926): app_time_stats: avg=1898.39ms min=4.90ms max=16965.74ms count=9D/[Purchases] - DEBUG( 592
So Ive built an EXPO app and have successfully managed to run development builds using sandbox environment for an app and tested purchase flows which all works fine. signed the paid agreements etc and set up my apple IAP and subscriptions properly. I’ve now tried to submit my app but I keep getting rejected due to: “Guideline 2.1 - Performance - App CompletenessWe found that your in-app purchase products exhibited one or more bugs which create a poor user experience. Specifically, there was no response when we tapped Unlock Now in Inspiration, Guests, and Budget. Please review the details and resources below and complete the next steps.Review device details:- Device type: iPhone 13 mini- OS version: iOS 18.5” Its very frustrating as it appears the issue is my IAPs have not been accepted/in review.The other issue I noticed before i submitted was that in testflight i was unable to trigger the paywalls, which I assumed was due to the IAP and subscriptions not being reviewed and accepted
I’ve implemented the RevenueCat SDK and tested the entire purchase journey using the TestFlight version of the app. Everything worked smoothly on iPhone (tested with different iPhones).However, my app was rejected, and upon reviewing the feedback and attached screenshot, I noticed the reviewers tested it on an iPad. I then tested the same TestFlight build on two iPads — both returned an error when calling getOfferings. The same code works correctly on iPhone but consistently falls into the catch block (at `….Purchases.getOfferings()) on iPad.SDK version: "@revenuecat/purchases-capacitor": "^9.2.1"Since it works on iPhone, we’re confident that the product identifiers and configurations are correct. We only test on real devices. StoreKit testing is not implemented, so simulator support is not expected and not needed. Tested devices: iPad (9th generation) – iPadOS 18.4.1 iPad (10th generation) – iPadOS 18.4.1 App Review test environment: iPad Air (5th generation) – iPadOS 18.4.1 In Ap
Hi everyone 👋I'm having an issue with the RevenueCat paywall UI on Android. I created a paywall design in the RevenueCat dashboard and linked it to my offering called "my_offering_identifier_is_here". Then, I'm showing the paywall like this:paywallActivityLauncher.launch(offeringIdentifier = "my_offering_identifier_is_here")The products show up correctly (so the offering ID seems to be working), but the paywall design is not the one I created. Instead, a default or unrelated layout is being displayed.Here’s what I’ve checked so far: The offering ID "my_offering_identifier_is_here" is correctly set and matches what I used in the dashboard. The paywall is published and active on RevenueCat. SDK is initialized and fetching offerings successfully. Has anyone run into this before?Is there something I'm missing to make sure the correct custom paywall design shows up?Any help would be appreciated 🙏
Hi guys! I'm integrating subscriptions in my Flutter app using RevenueCat. iOS case. I'm encountering an issue where the price shown on the paywall differs from the price shown at the actual App Store checkout. For example:* On the paywall, I show $59.99 (taken from `package.storeProduct.priceString`)* But when the user proceeds to the purchase, the App Store sheet shows $69.99 I'm not hardcoding any values — I use priceString from RevenueCat offerings.I use Flutter, but the issue happened on IOS only Questions:-Why might there be a mismatch between the price from on paywall and checkout? Thanks in advance for any insight!
When running eas build --profile dev-purchase --platform ios --local --clear-cachethe build process works but when trying to start the app and using the react-native-purchases sdk, I get the error: Import failed: `new NativeEventEmitter()` requires a non-null argument. The reason seems to be that the RNPurchases native module cannot be found. This only seems to happen when using eas build and on iOS. I have tried several of the latest react-native-purchases library versions. It seems to happen for every version. I already searched the internet for solutions and iterated with ChatGPT but am still facing the same issue. Is anyone aware of this and possibly has a solution?
I have added localization through RevenueCat which has updated the text content. I would like to change the main image for each language to help improve conversions by country. Is it possible to “localize” the image in addition to the text copy?
I have set an offering as default offering. When starting the app for the first time the default offering is loading correctly. After this I always get this error. The new default paywall I use is Paywalls v2. I do not try to load different offerings in my code just the standard default one. In Xcode I get the following warning WARN: ⚠️ Failed looking up localization, using fallback: en_DEWARN: Could not determine price format because price string is incompatible.
Hi, We are using Flutter SDK which utilizes Android SDK under the hood. We have an Offering set up with 6 packages.When requested through Purchases.getOfferings(), this offering has only 5 packages. As you can see, 2nd_monthly is missing in actionThis results in basic RevenueCat paywall being shown (which also contains only 5 packages) instead of our paywall. iOS app works just fine.
I’m using FlutterFlow’s built-in RevenueCat integration to create a custom paywall UI with two cards: one for the monthly plan and one for the yearly plan. The official docs only show how to configure a single subscription option (hard-coded) in the Purchase action. I need to: Let the user tap either the monthly or yearly card to select that plan. Then tap a single “Buy” button that initiates the RevenueCat purchase for the plan they selected. But in the Purchase action’s Package ID field I only see a way to bind one static package or choose “Package by Identifier,” and I don’t see how to point that at a dynamic App State or Action Output variable. I can’t figure out how to wire up my selectedPlan string (e.g. "myapp.monthly" or "myapp.yearly") into the Purchase action so it charges the correct plan.What have you tried so far? Created two tappable cards, each updating an App State selectedPlan string to either the monthly or yearly package identifier. Added a “Buy” button with Reve
I'm experiencing a timeout error (Error 32) from RevenueCat on iOS devices during app launch. The log says:“StoreKit 1 product request took longer than expected (30.17 seconds)”, and the app hangs or fails to load products.I've verified the product identifiers, my setup in App Store Connect, and that I'm using the latest SDK.Can you help confirm if this is a known issue, or if there's a specific best practice for fallback behavior?
I’m using the new beta paywalls. How do I get {{ product.relative_discount }} to render correctly for paywalls showing non-subscription packages? This question... indicates that this doesn’t seem to be supported? Surely this isn’t the case? Showing relative discounts is a pretty big deal for any paywall with multiple packages. Can someone point me in the correct direction to resolve this?
I think it should be made absolutely clear that restoring purchases on iOS does not work when using a .storekit file. At least I did not see this anywhere and spend a day on trying to get restore to work – until I switched to a scheme without a .storekit file.Maybe this is mentioned somewhere in the docs, but I did not see it.Thanks,Marc-André
The slow fetch product informations issue was resolved yesterday, but it is still very slow to buy an IAP in sandbox mode, my app was rejected because of this, since the reviewer failed to buy the IAP successfully. Please fix it ASAP!! It is very important to me!! Thanks.
Hi RevenueCat Community,I have a question regarding event data retrieval via the API.We know that when RevenueCat sends webhook notifications, each event payload includes a unique id for that specific event instance (e.g., INITIAL_PURCHASE, RENEWAL, etc.).My question is: Is there a way to use this unique event ID to directly query the RevenueCat API and retrieve the detailed data for that specific past event at a later time?For example, if I have an event ID like "evt_xxxxxxxxxxxxxx", is there an API endpoint similar to GET /events/{event_id} where I can fetch the details of this single event?I understand we can get a list of events associated with a customer through the /subscribers/{app_user_id} endpoint, and that webhooks provide event details at the time of occurrence. However, I'm specifically interested in whether it's possible to look up a single event's data using only its unique event ID after it has already been processed by our webhook system.Any clarification or guidance on
The Paywall Editor seems to have a bug right now where I can’t re-arrange elements by dragging the handle of the element on the left side. Is there any workaround to move things around?
Now, I may just be paranoid but ALL initiated purchases on my app in the last week ended in this “Purchase was cancelled” error, which to me, seems highly on unlikely for an app that used to get purchases every few days. I wonder whether users really cancelled all these purchases or is there something else going on here.{ "nativeStackAndroid": [], "userInfo": { "userCancelled": true, "code": 1, "underlyingErrorMessage": "Error updating purchases. DebugMessage: . ErrorCode: 1.", "readableErrorCode": "PurchaseCancelledError", "readable_error_code": "PurchaseCancelledError", "message": "Purchase was cancelled." }, "code": "1", "userCancelled": true}
Context:I'm currently using my own backend as the source of truth for subscription status. This is necessary since we have users who don’t go through the standard payment flow.While debugging an issue, I noticed the following behavior in the Customer History (see attached screenshot, customerId: user_01jtg9rmtwe6x8g96v43bcn2z3): A trial started event for pulso_suscripcion:pulso-anual occurred at 2025-05-05 01:29 PM UTC. However, the first time this webhook was delivered to my API was at 2025-05-05 07:49 PM UTC. This 6+ hour delay was the first attempt at delivery (not a retry), which likely caused a bug in my system logic (the user was able to subscribe again, so an expiration event then revoked its entitlement from my backend). Another point: I explicitly do not want Platform Server Notifications, as those were sending events tied to anonymous IDs. (https://community.revenuecat.com/sdks-51/after-purchase-new-alias-app-user-id-created-6098?tid=6098&fid=51, https://www.revenueca
While preparing my app for publishing on Google Play, I noticed that the Play Console requires paywalls to clearly display information about subscription auto-renewal and how users can manage or cancel their subscription.However, I couldn’t find any fields in the RevenueCat Paywall UI editor to add this required information directly. I want to make sure my app is compliant and avoid potential rejection.Would adding this info in the “Footer Link” > Terms of Service URL be sufficient for Play Console reviewers?Or is there another recommended way to include this content in the paywall?Here is my paywall UI; Also, one small extra question:On my paywall, the monthly subscription option shows a "%37 off" label.Is this calculated automatically by RevenueCat? If so, is there a way to disable or hide that label?
Every app download now gets a unique ID tied to the user’s Apple ID — perfect for things like offering one-time deals, detecting reinstalls, or even blocking repeat offenders. Will RevenueCat support this, or do we need to pull it directly from the device? Available starting iOS 16+More info: https://developer.apple.com/documentation/storekit/apptransaction/apptransactionid
I need some serious help as I think I messed things up with my latest code update. I use the Flutter SDK and this is what I do when the app starts up: configuration.purchasesAreCompletedBy = PurchasesAreCompletedByRevenueCat(); if (authService.currentUser != null) { configuration.appUserID = authService.currentUser!.uid; } await Purchases.configure(configuration); if (authService.currentUser != null) { if (authService.currentUser!.displayName != null) { Purchases.setDisplayName(authService.currentUser!.displayName!); } if (authService.currentUser!.email != null) { Purchases.setEmail(authService.currentUser!.email!); } } else { log.t('4. User is not logged in, setting app user ID to null'); configuration.appUserID = null; }The authService just checks if the user is logged in and if they are, it assigns the actual uid from the app to the user account so that I can find them quickly.However, I noticed with this code, m
Hello, I’m trying to configure my revenuecat project for development with Stripe, I already connect my stripe to revenuecat successfully, but in revenue cat when I try to add a Stripe product, it says “Product not found in live mode, it may exist as a test mode product”, and is right I want to add Stripe sandbox products, I don't want to test with live product, revenuecat is able to see the live ones, but not the ones that I created in the new Stripe sandbox or even Stripe Test mode. How can I create a test environment between revenuecat and stripe? Take in consideration that if I test with live products I can’t use Stripe fictitious credit cards, so is not an option.
Hello everyone,We’re looking to adopt the web purchase flow for our iOS app using RevenueCat. I’ve set up a Web Billing project and configured it for our default offering (see attached screenshot). My understanding is that, once everything is configured correctly, the `webCheckoutUrl` property should be populated for the relevant package when fetched via the SDK.However, I’m still seeing that `webCheckoutUrl` is `nil`. Is this likely due to a misconfiguration on my end, or am I misunderstanding how and when this property should be set?Any insights or suggestions would be greatly appreciated. Thank you!
One frustrating feature of RC is the bad user-experience with dev/prod projects and thus the dashboard.I think Clerk does this very well, allowing a single project with a dev/prod instance (picture 1). This makes things very easy to flip between the two, isolates sandbox data vs real data, and allows very clear separate API keys, management, etc. Example - Lets assume I have a very active project, post launch perhaps:If I wanted to test adding a new type of webhook for the firebase extension, without the risk of blowing up my firebase functions quota, I’d need to set up an entirely separate RC project, duplicate all the settings over (which is equally a painful process right now), update my local application with new API / public keys, just to test the addition of a single webhook event. I would *LOVE* to see a unified unified approach that really separated the environments, and the intent behind the data. I don’t believe the sandbox toggle is sufficient - here’s a RC example:The first
Already have an account? Login
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.