Share and explore knowledge and tips relating to RevenueCat and subscriptions.
Recently active
If you plan to have an app that is offline, then there is some information on RevenueCat’s end that you should be aware of.A network connection is required to make a purchase and communicate with RevenueCat, but the subscription status is cached on the device as long as needed via CustomerInfo. This way you can still check for a user’s entitlements so they can continue to access your app’s content. When offline, the current state of the subscription will be preserved until it can be re-synced with RevenueCat (e.g. if they're subscribed, they'll remain subscribed).The app user id and CustomerInfo are cached, and CustomerInfo will be returned while offline forever if the user never goes online, unless something happens that invalidates the cache. The offerings do not persist between app launches, so you will need to cache this data and display them yourself when the app is offline. See our caching docs here for more information.If you do not want users to have access to their subscriptio
We’re on a pro plan and because of RevenueCat’s unstable system we’re unable to track some of the events and I reached their support 2 times but still no response for days. We’re going to replace you guys ASAP. No thanks for your bad services
We are testing sync mechanism of REST API (PLAY_STORE, SANDBOX). We found that if a renewal webhook is not sent, and when we GET https://api.revenuecat.com/v1/subscribers/{app_user_id}, the same renewal webhook notificaiton is sent immediately. I can’t find any information about whether delayed webhooks would be sent after calling REST API. Is this coincidence or a normal behavior of RevenueCat?
I am using RevenueCat for my subscriptions, but on Android, the offerings only include the monthly subscription plan and not the annual one. Could you please check to determine whether the issue lies in our setup or with RevenueCat
Hey Revenue Cat users - I’m new to RevenueCat, but I’m creating an app that is all local storage, and currently doesn’t have any authentication. I want users to be able to try the app, but then pay a one-time flat fee to keep using it.Has anyone else built apps with this kind of use case for payment? It’s a flutter app, so it should be cross-platform. I want to have as minimal as possible of work for users.Are there any great docs on the revenue cat website (or elsewhere) detailing this kind of use case?
Include refunds / refund info. Refunds should also appear in transactions Paginate transactions page so we can view more
What features are you the most excited about?What would you like to learn more about?Many updates and changes have been introduced during Google I/O 22 and our team is busy deep diving into these topics and prioritizing them according to your needs. We would love to hear your thoughts and needs on these features. New Subscription Model - is it all clear what that means or would you rather we just take care of it? Play Console – how does your setup look after the changes? does this create an opportunity for your app? Flexible Offers - would you see yourself making a use of this? Prepaid plans - does this solve an issue for you? would you like to learn more about the payment landscape of recurring payments? Play Index - do you see yourself using the index moving forwards? If so, what kinds of communications would you expect from RevenueCat?Excited to hear from you!
So I had this error message on my Android testing of my Flutter app (iOS worked like a champ) and worked through the troubleshooting steps provided by RevenueCat support, (https://community.revenuecat.com/sdks-51/why-are-offerings-or-products-empty-124), (BTW some of these screens need updating please, particularly because this is a popular post), I even got Google Play Store support involved (the portal is soooo convoluted) and after about two weeks of getting one email response per day, at my wits end, I engaged the chat service. A chat support person in Google told me in five minutes that I could only make my app release ‘ACTIVE’ in the Closed Testing if … my Managed Publishing state was ON!I didn’t know what that was, then they explained:them: Kindly go to your app's Publishing Overview section on you Play Consoleme: kthem: Then, click the "Turn off Managed Publishing" button.them: Once you've turned it off, kindly wait for the changes to be reflected on your Play Console.and then,
Got an email from Google Play asking me to disclose more information regarding RevenueCat:Your app is uploading users' Primary Account information to https://api.revenuecat.com without disclosing it in the privacy policy in Play Console. My app currently offers In-app purchases. I’m looking for Privacy Policies examples. Thanks!
HelloWhen I fetch products and offerings using RevenueCat react native js library, it says that price is 1.99 for in-app purchase, but when a customer makes a purchase apple shows that price is $2.49 (user’s country is Ghana). The price on app store is set to Tier 2: $2.49 (developer’s account is from Ghana too), but it looks like it depends on user’s settings on the device. Is there a way to fetch actual price based on user’s country? Or revenue cat always returns price for USA (1.99) and I have to manually detect user’s country and convert it?
Hi everyone, I was wondering what the best way is to set up different pricing in different countries. Example:High Price Tier: e.g. USA: 9.99 USD per monthMedium Price Tier: e.g. Germany: 7.99 USD (converted from EUR) per monthLow Price Tier: e.g. Brazil: 3.99 USD (converted from EUR) per month What is the best way to do this? Also, it would be nice to run separate experiments for each tier.Is the best way to set up different revenuecat offerings and have the app handle the selection of which offering is chosen based on the country? How would it be possible to run revenuecat pricing experiments then?Are there any best practices? Thank you already in advance. Cheers,Ben
Hello, I’ve manage to create an offer in the RC Dashboard and in the Google Play console that is attached to existing product (annual subscription). The offer includes free trial. When I call the getOfferings method and select the specific offer and try to purchase, the offer does not include the free trial I’ve previously attached. Any help here?
Hi there!How can I renew my subscription on the web? I want to be able to renew my expired subscription with just one button. For payments I use stripe checkout client only
RevenueCat’s promotional entitlement feature allows you to grant an entitlement to any of your customers directly from RevenueCat. These are the predefined durations allowed:Duration Description daily 24 hour access three_day 72 hour access weekly 7 day access monthly 1 month (31-day) access two_month 2 month (61-day) access three_month 3 month (92-day) access six_month 6 month (183-day) access yearly 1 year (365-day) access lifetime 200 year access To grant a promotional entitlement with a custom duration (for example, 5 days,) set the start time in the past so that the end time lands when you need. So for example if you want to grant a promotional entitlement for just one hour, grant a daily promotional (which is 24 hours) but set the start time to 23 hours in the past. The end time will then be 1 hour in the future.
I am planning to offer a subscription that includes a certain number of consumable “tokens” per billing period. For example, maybe you get up to 20 tokens per month for $1/month, or 50 tokens for $2/month.But if the user exhausts their tokens before next month, it should be possible to either buy more tokens, and/or, upgrade to a higher plan level.I was wondering if anyone had suggestions for the best way to accomplish this with RevenueCat.
I have an app working where we sell renewing subscriptions. I am trying to implement a new use case, we would be selling for some users a one time purchase that gives them access for 20 months. I was thinking about implementing it as a non consumable IAP, with an entitlement attached, so that when the user buys this product, they get access to the app. But I'd still have to remove the entitlement when the time is up. I could do that in the backend, but I don't see a method in the API to remove an entitlement. How would you implement this? Is there a best practice to link an entitlement to a non consumable IAP with an arbitrary expiration date?
There is good explanation on how upgrades/downgrades work on the Revenuecat blog here. I however seem to be missing the case where the user upgrades in terms of a level and lowering the duration (at the section Upgrading Service Levels there is a description of moving to a higher level and a longer duration). As an example: Example> A user has a current subscription with 10GB of storage and with a 1 year duration.> The user now wants 25GB with 1 month duration. My question here is twofold:How do we configure levels, as my naive assumption would be that 25GB would be in a higher level than 10GB, independent of duration? If my assumption is correct how do we get around the situation where the following happens:Allowing the user to move to a higher level with shorter duration may results in a large refund and subsequently to earlier cancelation of any overall. I assume this is not something we want. What is the best approach to handling this case?
Hello, Our product has multiple subscription groups built out but they have the same entitlements. It made sense at the time given iOS functionality but has led to a lot of problems where customers have purchased duplicate subscriptions. Going forward we want to move people to one subscription group to make sure customers don’t accidentally sign up twice. Has anyone dealt with this before? Are there any best practices for consolidating subscription groups? If not consolidate, is there a way for people to “upgrade” between subscription groups and cancel their current plan at the same time? Thanks
Google’s new policy needs apps to cancel subscriptions. I am not using any backend (Firebase only). The REST API needs a secret key to do the cancellation which I shouldn’t include in my app’s code.So how can I do this?
Hi! It’s a very minor UI issue, but can be very helpful!During the initial integration and testing I am usually having 10+ tabs of RC open. It’s really hard for me to know which ones are docs and which ones are the platform. I was wondering if you guys can change the favicon (maybe by a hue-shade or something). That would help me easily navigate to the app without clicking on 5 random tabs to find an app page to copy or change a setting/value. ;) Note that project name is not always there (e.g. “Overview | RC”) so it’s a little bit of a guess work and reading.Thanks!
The use case is simple. Let’s take my React Native iOS app as an example:A user who has already purchased a “Premium” subscription in my app goes to their iPhone Settings and unsubscribes Now they open my app and goes to the “Subscription” page to check the status My subscription page says that their sub is active AND will renew at date X, even if I run the getPurchaseInfo() again My user gets confused/angry and contacts my supportHow can I avoid the above? I’m new to RC and have just been playing around in the Sandbox environment. RC docs says certain attributes, like the “willRenew” could take multiple hours to sync. I have activated Platform Server Notifications but at least in Sandbox it seems like the info I get back from getPurchaseInfo()How can I avoid these delays and caches and whatnot, and always be sure that everything is updating instantly and the data is accurate and “fresh”?I asked the RC support about this, and they just copy/pasted the first two paragraphs of the “Webho
This is so frustrating that the customer list export is a .GZ file….If you are on a PC you are unable to view the file, you must convert it to CSV. Every time the file is converted, its gets corrupted and data goes missing (regardless of what conversion method you used)This is so annoying because the only way to review and analyze the customer list export data is by asking my friend with a Mac to download it and upload it to google sheets for me.Can there PLEASE be a way to download the data via CSV so all users (regardless of comp) can access it?
Hello,I am trying to convert a paid app into subscription, but I am facing a situation which I need help. I know I can detect the active subscriptions via active entitlements:!customerInfo!.entitlements.active.isEmptyand detect if any entitlements are not active then lock the premium version for example. But I am converting a paid app into subscription, so I detect if the user is purchased the app before and unlock it using customerInfo.originalApplicationVersion. That creates a conflict situation, I am unlocking the pro features for previous users and then there is no active subscription for that user in customerInfo, so the in this code:@Published var customerInfo: CustomerInfo? {didSet {if !customerInfo!.entitlements.active.isEmpty {print("UNLOCK PRO VERSION")} else {print("LOCK PRO VERSION")}}}I lock pro version for a user that hasn’t any subscription, it conflicts for previous user who bought the app. So I am looking for an API to lock the pro features only if the subscription is
Hello, First of all I want to thank you for this great framework. My app has been downloaded more that 20K, now I am about to release the the new update, and also, I have read this article.Just have a question, my new update version for both app version and build is 11.0, so I need to detect if the originalApplicationVersion of previous users (who bought the app) is less than 11 the app should unlock the premium version. So I am doing it like this, and I was wondering am I doing it right?First setup configurations:init() { Purchases.logLevel = .debug Purchases.configure( with: Configuration.Builder(withAPIKey: "appl_mj*****") .with(usesStoreKit2IfAvailable: true) .build() ) Purchases.shared.delegate = PurchasesDelegateHandler.shared }and then detecting it using delegate:func purchases(_ purchases: Purchases, receivedUpdated customerInfo: CustomerInfo) { SubscriptionManager.shared.customerInfo = customerInfo if let version = Double(customerInfo.originalApplicationVe
I am having an issue with getting information from RevenueCat products and customer info. I have followed the guidelines step by step, but the delegate returns empty!First, configuring the SDK:@mainstruct ProjectApp: App { init() { Purchases.logLevel = .debug Purchases.configure( with: Configuration.Builder(withAPIKey: "PUBLIC_API_KEY") .with(usesStoreKit2IfAvailable: true) .build() ) Purchases.shared.delegate = PurchasesDelegateHandler.shared } . . .and then handling delegates using PurchasesDelegateHandler just like the official's sample demo:class PurchasesDelegateHandler: NSObject, ObservableObject { static let shared = PurchasesDelegateHandler()}extension PurchasesDelegateHandler: PurchasesDelegate { func purchases(_ purchases: Purchases, receivedUpdated customerInfo: CustomerInfo) { SubscriptionManager.shared.customerInfo = customerInfo print(purchases) print(customerInf
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.