Learn more about RevenueCat and talk about it with the community.
Recently active
TLDR; Only configure with a known ID, and never call logout to prevent anonymous IDs. Why does the SDK use Anonymous App User IDs?Anonymous App User IDs are generated when the SDK is configured without a provided known ID. App User IDs are used to make sure the subscription that RevenueCat is tracking gets associated with the correct user. Anonymous App User IDs are always prefixed with $RCAnonymousID: which can be useful for working with anonymous users on your server. Many apps use a combination of anonymous App User IDs and their own known App User IDs which provides flexibility in their user purchase flows. However, some applications are intended only to be used while using a known App User ID, without anonymous users at all. In that case, unintentionally creating Anonymous App User IDs can cause unwanted issues for developers and end users. To never see anonymous IDs, you need to make sure to do the following. Only Configure the SDK with a known user IDThe most frequent place that
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?
While using RevenueCat you may come across an error that has an HTTP status of 429 and a response body that looks like this:{ "code": 7638, "message": "There is another request in flight trying to perform the same action."}While a 429 Too Many Requests HTTP status code is frequently associated with rate limits, RevenueCat usually returns this error if multiple API requests were made simultaneously that are trying to update a single resource in the system.For example, if you make a POST /receipts request and a GET /subscribers request for the same user at the same time, the GET /subscribers request will try to update the receipt with Apple/Google but it’s already being updated by the POST /receipt, so RevenueCat will block one of the requests to prevent data race conditions.The solution to this is to simply retry the failed request a few seconds later, which will give RevenueCat a chance to complete any in-progress operation.
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
If you get a 403 error status, “Secret API keys should not be used in your app.” error message, or “7243” error code when making HTTP requests to the RevenueCat API, you are probably using the wrong API key, or using a private API key when you should be using a public API key.Double-check for any typos and make sure the API key matches the one in your dashboard.The following RevenueCat REST API endpoints require using a public API key:GET /subscribers POST /attributes POST /attribution GET /offerings POST /receiptsYou can find your public API key by following this guide: https://docs.revenuecat.com/docs/authentication#obtaining-api-keys Make sure to use the correct public API key - for example, if you're sending an iOS receipt to RevenueCat using POST /receipts, use the public API key for your iOS app (which will look like appl_xxxxxx).
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
We've recently noticed an issue with some our Android users, that we are not able to display the trial period for them. We get this information from SkuDetails.freeTrialPeriod, and parse that value.However, for these users, SkuDetails.freeTrialPeriod is returning an empty string (even though the corresponding SKU has a trial period configured in Play Console); we are not able to reproduce this issue using this same SKU locally.We're curious to hear if anyone else also uses this information, and if they've noticed anything strange lately? Or if there is any other way of reliably getting this info?We've also created this issue in the official issue tracker: https://issuetracker.google.com/issues/219799769
WWDC '22 Announcements What features are you the most excited about?Which topics would you like to learn more about? 'Dub Dub,' as we like to call it, has left us excited and busy as we deep dive into all the changes and upgrades. We would love to hear your thoughts on the newly-released features and upgrades to help us create content & product that’s relevant and interesting to you.. Some questions for you: 1. New StoreKit 2 properties and APIs - As mentioned in our blog post, you will receive these upgrades with the updated SDKs. Q: Is there anything that you’re specifically looking forward to, and could you share examples of how this might be useful to your app? 2. New App Store Connect API for in-app purchases. Q: As this could potentially enhance the RevenueCat experience for you, are there any pain points that it would solve for you specifically? 3. StoreKit testing improvements. Q: What are your biggest roadblocks regarding testing? 4. SKAdNetwork 4.0. Q: Would you li
My question is not as much a technical question as it is a user experience question. I have not read all the dev documents yet regarding GourpIds etc.We have an app for schools. Currently we have implemented subscriptions for iOS and Android. We think we can get much more users and revenue if we rather implement a group subscription where the school can create an account, subscribing and manage users on that account through some we console.I’m not sure how one would go about doing this using the subscription services provided with the Playstore and Apple, unless I’m missing something.Would one perhaps go the stripe route? And how do you go the stripe route and not get you app banned from the app store because you are not using Google’s or Apples service.It’s not that we want to bypass their service, I just don’t know how to use there service in an extremely user friendly way to implement such a group subscription. When I say user friendly I mean for instance, you don’t want to for
Hi,How can I configure a free subscription / version in RevenueCat that is an extra IAP item? This item should be available for free for one week. And what do I need to configure on Appstoreconnect? introductory offer?So the goal should be that the customer can test the app one week for free and after the one week he gets the view again where he is asked to close the subscription.
Hi folks,I know that Stripe can automatically send billing error emails. So if Stripe tries to charge a user’s card but it doesn’t work, Stripe can automatically email the user, asking them to update their card. This is simply configured in my Stripe settings. Do Apple or Google do this automatically as well? If not, I assume this is a good time to use RC’s billing_error event to trigger a customer email? Where would I direct them to? Tell them to open up their app store and update their payment method on file? Is there a link I can use to get them there, or is it that all I can do is tell them the steps?Thanks! Toby
Hi folks, I was recently contacted and told that I can submit a claim in this class action law suit. Of course, I assume most communications like this to be a scam. But I’ve heard respectable news sources talk about this. I think I’ve even heard @david talk about it on SubClub. They’re not asking for sensitive info and it looks legit. Have y’all submitted a claim? Have you heard of this specific case? Is it a scam? Here’s the link: https://smallappdeveloperassistance.com/ Thanks, Toby
This is massively helpful for us - hugely appreciate you putting it in. Have a great weekend!
Hi y’all,I’ve been thinking about business models for an app I’m working on.Let’s say that I’m selling specialized photo filters. And you can choose from a library of them, a sort of marketplace.My first thought was to use tokens/coins. You buy 300 coins with an in-app purchase, and then you can spend 100 coins to buy a filter. That sort of thing.Would a subscription model make sense here? I would, in fact, be selling content that I could update. And it would keep me from needing to track tokens per individual user.I don’t know, would a subscription model be the right fit?
Hi, would be great if we could have some sort of notification on when a user makes a purchase like Stripe does. This helps wanting to further improve the product as users subscribe and is good morale booster to keep going.maybe need an app for this? A revenuecat app on ios/android with an overview of the dashboard would be helpful as currently I pin a shortcut to my iPhone desktop.
I have a fitness app (Max reHIT Workout) and my current method of offering a free trial is to let people have access to 5 fully functional workouts free, forever.There's are two ads: an interstitial ad and a banner ad.If you want access to all 20+ workouts, lots of extra features, and go ad free , you can buy a yearly subscription for $5.99.You do not have to enter a free trial period with CC because I absolutely hate that approach.I'd like to increase conversions. Two methods I'm considering:Have a completely functional system without ads for 5 workouts. I figure if you've used the app 5 times and you don't want to buy, you'll probably never convert. A complication is this requires the user to login because i use cloudkit to store data for cross device access. After 5 workouts if they choose not to convert I revert back to a limit of 5 workouts with ads. Of course they can subscribe any time. I hope they realize the value ad of the extra features and workouts. Similar to 1, but the t
I'm posting our experience to help clarify the (Apple) IAP release process for any other new developers.Our app (v1) was live on the App Store with one IAP, a yearly subscription. Yesterday we were approved to release v2, plus were approved for a new monthly subscription IAP. We released the app almost immediately after approval. After about 20 minutes, the new version was visible in the App Store.However, after downloading the app, we noticed that only the original annual subscription was showing up in the app. The new monthly IAP was not listed. After checking everything out (see below), we decided to wait it out before any real debugging. This morning, the app was listing both annual and monthly IAPs. So, apparently it takes some time, measured in hours, for Apple to 'activate' the SKProducts. NOTE: While the new IAP was unavailable in the app, the App Store listing was actually displaying both the annual and monthly options under: Information In-App Purchases (Yes)
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.