Get help with your SDK implementation.
Recently active
OnRestoreComplete on paywall did not trigger. I purchased the lifetime item(ads removal) Reinstalled the app Attemp to restore purchase under the same sandbox account a loading indicator shows, but nothing happened after that, no success or failure message restarting the app will restore the purchase A custom button that calls Purchases.restorePurchases works properly, but the button on paywall doesn’t
When a new user signs up in my app, I register this using the `logIn()` method from the SDK. They do not have made a purchase yet. The problem is that they don’t come up in the customers list. Also not in the ‘Non-subscription’ list. Also not after 24h, because I’m aware that the lists are not real-time.My app has a hard paywall, and I need to grant some people a plan to get them through, for beta testing. Why don’t these users show up in RevenueCat? I’m identifying them...
userA: purchased a subscriptionuserA then signs out and userB signs inif userB attempts to purchase a subscription, I want to show an alert saying ‘Please use a different apple id, this apple id is already associated with a different app account’ Now, how do I know if an apple id/play store account is already associated with a different appUserId? I need to know it before a user can trigger the Purchases.purchasePackage.The nearest solution I got is by receiving the RECEIPT_ALREADY_IN_USE but that happens after purchasing the package not before.
hi, onPurchaseCompleted (or any other event) is not fired. I present the paywall like:.sheet(isPresented: $showPaywall) { PaywallView(displayCloseButton: true) .onPurchaseCompleted { customerInfo in print("onPurchaseCompleted") }... .onRequestedDismissal() is only fired when I manually tap on close button on paywall. Im using 5.33.0 version. Im testing on my real device iPhone 15 pro max, ios 18.5. Alo does not work on simulator etc. I have removed lib, add it again, cleared cache... This is getting very annoying.some debug info are no requests currently running, starting request POST /v1/receiptsDEBUG: ℹ️ API request started: POST '/v1/receipts'DEBUG: ℹ️ API request completed: POST '/v1/receipts' (200)DEBUG: ℹ️ PostReceiptDataOperation: FinishedINFO: 💰 Finishing transaction '...' for product '...monthly'DEBUG: ℹ️ Serial request done: POST /v1/receipts, 0 requests left in the queueDEBUG: ℹ️ Sending updated Cus
Hi,Although I used to use it without any problems and was able to successfully pull product information from app store connect, I realized that it is not working now.What I’ve tried: Followed and applied all the instructions here: https://www.revenuecat.com/docs/service-credentials/itunesconnect-app-specific-shared-secret/app-store-connect-api-key-configuration Double checked all keys (issuer id, key id, vendor number) Created new app-store-connect api key with the app manager access and uploaded p8 file. waited at least 24hr. I set app specific shared secret by following https://www.revenuecat.com/docs/service-credentials/itunesconnect-app-specific-shared-secret I double checked my app bundle id Checked My in app purchase key is validated but app strore connect api still has an issue. I attached revenuecat and app store connect screenshots.Please help me to fix this.app store connect api
I went from using react-native-iap, due to losing a lot of money on refunds because of a purchase acknowledgment issue I couldn’t figure out.Came over to use RevenueCat, heard great things, setup account, it gave me all the check marks. Pulled in all my previous data, even refunded data. (which is EVERY purchase) I have a trivia game.Now products can’t be found.I have 1 subscription: Unlocks premium access, an “Everything Bundle” which unlocks everything in the app, always, forever, 1 price. Then I have individual IAPs for specific packs.[RevenueCat] ℹ️ Product not found: everythingbundle1 - Product Type: subs, Reason: PRODUCT_NOT_FOUND, Serialized doc ID: I imported all my products from Google Play Console, and they are set as Non-Consumable. (Photo for the one above below) But I don’t see why they are coming over as subs, even though they are setup as IAPs in google play console. I have offers setup and entitlements (Example of the same one)Every single IAP & Sub are all not abl
Hello to allBy the try {CustomerInfo customerInfo = await Purchases.getCustomerInfo();// access latest customerInfo} on PlatformException catch (e) {// Error fetching customer info}How is it possible to get which products that the customer purchased ? In my case, I have 2 consomables that are 10 and 50 games, I want to know which one that the customer purchased and in this case,,treat this information as a variable.Thanks for your helpVincent
Hello, Unfortunately I could not find any information in the docs or on GitHub if trials from Paddle can be used when building a custom paywall using the purchases-js SDK.Was wondering if I have something wrong in my setup or if this is just not supported at the moment. Trial is being returned as “null” even though I added it to Paddle for this price."subscription_options": { "base_option": { "base": { "cycle_count": 1, "period_duration": "P1Y", "price": { "amount": 4999, "amount_micros": 49990000, "currency": "EUR" } }, "id": "base_option", "intro_price": null, "price_id": "mypriceid", "trial": null } },
I'm using RN 0.74.5 and this is the first time I've put my app on the store, I've tested it on both a virtual machine and a real machine locally using xcode via the storekit config file, but why is there a question mark unversioned (image 1) but when I put it on Testlight, I can't get the Offerings (image 2)Do I need to add any API key in AppDelegate.mm? Can anyone help me?
I found google remove the “Query Purchase History” method recently, so Purchases.restorePurchasesWith not work on RevenueCat SDK 9.x.Any solution for SDK 9.X for user restore their purchase? https://developer.android.com/google/play/billing/query-purchase-history
I am completely lost on this one - posted already two times but somehow these posts are not showing up.Since I am completely stuck, all I can to is try again: I have already checked my setup multiple times and went through this guide (Why are offerings or products empty?) but I fail to see where I did my mistake.Is there any way for me to trouble shoot this issue?My staging environment has a released app which I installed via Google Play All my products IDs (SKU) exist and are active All SKUs are mirrored in RevenueCat The service account is happy products show up as active Bundle ID etc are fine - otherwise Firebase Authentication would not work either Checked my API keysI’ve checked with logcat but there’s nothing that would indicate an issue..Completely lost here :/
Let’s say I have a NavController with 5 pages, and 3 of them should be behind paywall - whenever the user navigates to those routes, i would like to show the paywall if needed (thankfully this is handled within the paywall composable itself) - but i don't want the composable behind the paywall to render/run at all.The documentation shows this: @OptIn(ExperimentalPreviewRevenueCatUIPurchasesAPI::class)@Composableprivate fun NavGraph(navController: NavHostController) { NavHost( navController = navController, startDestination = Screen.Main.route, ) { composable(route = Screen.Main.route) { MainScreen() PaywallDialog( PaywallDialogOptions.Builder() .setShouldDisplayBlock { !it.entitlements.active.isEmpty() } .setListener( object : PaywallListener { override fun onPurchaseCompleted(customerInfo: CustomerInfo, storeTransaction: StoreTransacti
We’ve noticed that some purchases of non-subscription items (not made through RevenueCat) are missing. Should we call restore together with configure every time the app launches, or could there be another reason for this? We’ve noticed that for some users, calling getCustomerInfo() after configure is either delayed or returns empty due to an error. Is there an alternative way to access the user’s subscription status without relying on Purchases.getCustomerInfo()?
We are using RevenueCat paywalls to show a PaywallFooterView using originalTemplatePaywallFooter() on our SwiftUI view. In iOS26 beta3 (haven’t tried previous betas) when the paywall footer is shown and you click on the “Continue” button to make a purchase, instead of showing the iOS dialog to finalize the purchase, the transaction fails and shows the following in the Xcode terminal: [Presentation] Attempt to present <UIAlertController: 0x113e85200> on <UIViewController: 0x114ae8800> (from <UIViewController: 0x114ae8800>) whose view is not in the window hierarchy. The same code works fine on iOS18 and below but in iOS26 beta3 I can’t make a purchase. I updated to the latest RC SDK 5.32.0 and the issue is still there. One wrinkle is that our SwiftUI view that shows the paywall footer is hosted inside a UIKit UIView, so I’m not sure if that is causing an issue or not for RC in the latest build.
I am building a mobile app with Flutter and when testing on IOS using TestFlight and sandbox, future subscriptions are tied to the original appID that purchased subscriptions on the device for the first time instead of the current appID that is logged in.For example, my app flow goes like this:1. The user signs in to an account.2. The program signs in to Purchases with the user ID that is tied to the account.3. The user buys a subscription.4. After the subscription expires the user signs out of the account or deletes the account, which also signs out of Purchases.5. The user signs in to a different account.6. The program signs in to Purchases with the user ID that is tied to the account.7. When they buy a subscription on the new account it gets linked to the old account appUserId instead of the new appUserId.8. On RevenueCat, the ID of the old account has no aliases and no merges and the new account ID does not show up, and instead, the purchases are listed under the old account ID ins
I’m using the flutter sdk and i can’t find a way to differentiate between renewing and non-renewing subscriptions on ios.
I am facing the following challenge: My app has a hard paywall, which means at the end of onboarding, users start a subscription with a 7-day free trial before. Everythink works perfectly well with the RC paywall: I just realized that I need to display a different paywall if the user has already used their single free trial. I stumbled upon the checkTrialOrIntroDiscountEligibility method, and have already created a second offering without the trial period configured. However I am lost how I can now call two different paywalls depending on the result of the method. Is it even possible to add a second View modifier (.presentPaywallIfNeeded) with the “no trial” entitlement in combination with checkTrialOrIntroDiscountEligibility?Just for my understanding: RC would automatically handle this case if I had not configured a components-based paywall, am I correct? Thank you in advance*
onReceived or onError call backs not triggering in getOfferings method, when i update my SDK version to 35 and increase some other libraries versions. so i am unable to get prices of offeringsPurchases.getSharedInstance().getOfferings(new ReceiveOfferingsCallback() { @Override public void onReceived(@NonNull Offerings offerings) { } @Override public void onError(@NonNull PurchasesError error) { }});
Hi folks,I’m building an Android app and trying to have 2 paywalls presented (that I have configured in Revneuecat) - one for when user is in trial period and one when trial is over. I'm trying to launch PaywallActivity with a specific offering in RevenueCat SDK 9.0.0, but it always shows the "current" offering from the dashboard instead of the offering I specify.*** Here is our code:```java// BillingManager.java - Method to launch paywall with specific offeringpublic void launchPaywall(String offeringIdentifier, BillingCallback callback) { // First get the offering object Purchases.getSharedInstance().getOfferings(new ReceiveOfferingsCallback() { @Override public void onReceived(Offerings offerings) { Offering targetOffering = offerings.get(offeringIdentifier); if (targetOffering != null) { // Launch PaywallActivity with specific offering Intent intent = new Intent(currentActivity, PaywallActivity.clas
Consider this scenario: the user account is only created in the database after the user subscribes.Since I don't have a user ID initially, I initialize the Web SDK like this:const appUserId = Purchases.generateRevenueCatAnonymousAppUserId();const purchases = Purchases.configure({ apiKey: WEB_BILLING_PUBLIC_API_KEY, appUserId,}); Once the user account is created, I need to associate the existing RevenueCat data (based on the anonymous appUserId) with the newly created user ID. Based on the docs, it looks like I can create a new customer using the new user ID and then use the transfer endpoint.Questions: If the destination appUserId doesn’t yet exist in RevenueCat, will the transfer endpoint create it automatically, or do I need to create it first? Is using the transfer endpoint the recommended approach for this use case? Or is there a better way to handle the transition from anonymous to identified user server side?
The old style paywall did display full screen on ios26 beta3, but the new style paywall does not. Attached image. struct OnboardingFlow: View { let purchases = PurchaseManager.shared var body: some View { VStack { if let offering = purchases.offering { PaywallView( offering: offering, displayCloseButton: true ) .ignoresSafeArea() } else { ProgressView() } } .task { await purchases.fetchOfferings() } }}
not getting any offerings and planson calling await Purchases.getOfferings(); its just keep loading logs: D/[Purchases] - DEBUG(29119): ℹ️ Cleaning previously sent tokensD/[Purchases] - DEBUG(29119): ℹ️ Tokens already posted: []D/[Purchases] - DEBUG(29119): ℹ️ Saving tokens []D/[Purchases] - DEBUG(29119): ℹ️ Tokens already posted: []D/[Purchases] - DEBUG(29119): ℹ️ No pending purchases to syncD/[Purchases] - DEBUG(29119): Request already scheduled with jitter delay, adding existing callbacks to unjittered request with key: BackgroundAwareCallbackCacheKey(cacheKey=[/subscribers/7r34LFyvZVP024pwpErDILSapda2], appInBackground=false)D/[Purchases] - DEBUG(29119): Billing connected with country code: IND/[Purchases] - DEBUG(29119): API request started: GET /subscribers/7r34LFyvZVP024pwpErDILSapda2/offeringsD/[Purchases] - DEBUG(29119): API request completed with status: GET /subscribers/7r34LFyvZVP024pwpErDILSapda2/offerings 304D/[Purchases] - DEBUG(29119): ℹ️ Requesting products from the s
Hey there,The user experience of loading the dynamic paywall is really ugly. You see all these skeleton loaders. Is there a way to avoid this? I rather have it have a short delay of 0.5s vs this weird experience.
I was testing a scenario when the user is on a subscription (e.g. monthly) and decides to purchase a lifetime access while subscribed. In this scenario:user has their monthly subscription that lasts until 31Jul for example (let's assume today is 11Jul) user purchased lifetime access -hen user goes to the settings and cancels their subscription which is still valid until 31Jul but won't renewNow I wanted to show a banner to the user that they must manually cancel their subscription (as far as I know we cannot do it on our own). For this I am checking the willRenew flag that I found inside the customerInfo.subscriptionsByProductIdentifier.What I noticed though during testing in Sandbox that the willRenew flag is not updated and couldn't get a confirmation on RevenueCat's forum if it's just a Sandbox issue or it's also not reliable in Production.I also considered using it together with the unsubscribeDetectedAt attribute, somehow like this:let hasNotCancelledActiveSubscription = customer.
Hello,we have implemented RevenueCat into our app.We are testing the app through TestFlight.Testers see the price for the US in USD in the paywall, while they should see the prices for Germany in EUR. On the Apple Payment screen the price shows correct in EUR.They are located in Germany, have a phone locale and everything set up in German, their App Store account is registered in Germany, and their added credit card is from Germany. No VPN and no previous activity in with US store accounts.We didn't change anything regarding locale in App Store Connect. We use the default US Localization.We are getting prices like this:func getOfferings() { Purchases.shared.getOfferings { offerings, error in if let error { print("Purchases: Error: \(error.localizedDescription)") return } // We are getting prices from availablePackages guard let packages = offerings?.current?.availablePackages else { return } for package in pac
Already have an account? Login
No account yet? Create an account
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.