Get help with your SDK implementation.
Recently active
I have created a consumable product and it works so far. Now when the user wants to purchase the same consumable product again, it gives it to them wether they paid again or not because their entitlement exists? How do I fix this? here is the code I have: if let package = self.offering?.availablePackages[packageNumber] { Purchases.shared.purchase(package: package) { (transaction, customerInfo, error, userCancelled) in print("user cancelled: transaction", userCancelled) if customerInfo?.entitlements["gems (consumable)"]?.isActive == true { // Unlock that great "pro" content } else { print("Error for payment", error) } } }
I am buying a subscription on a device connected to my computer. The expirationDateMillis returned by the SDK is wrong. It is the same date the subscription was done. According to the docs, shouldn't this be the date, when the subscription expires?Looking at this"originalPurchaseDate": "2023-05-08T13:11:37Z","expirationDate": "2023-09-13T07:00:58Z" this is wrong. TheoriginalPurchaseDate should be Sep 13 2023 (when I subscribed) and theexpirationDate should be a month ahead in the future (thus Oct 13 2023). Additionally, originalAppUserId is "$RCAnonymousID:5933b0b7733a400fbc2f60b38733a23f" eventhough I do a await Purchases.logIn(userId);. I expect that to be my Apps user id?!try { await Purchases.logIn(userId); const {customerInfo} = await Purchases.purchasePackage(pckage); const activeEntitlementInfo = customerInfo.entitlements.active[ REVENUE_CAT_SUBSCRIPTIONS_ENTITLEMENT_IDENTIFIER ]; if (typeof activeEntitlementInfo !== 'undefined') { const {expirationDateMillis
I have following scenario in my app: Each file creation should be an in-app purchase. I have an entitlement “create a new file” User buys this entitlements User creates a new file After that I want to take this entitlement back from the user so that next time they will need to purchase “new file” againIs that possible or I have a wrong understanding of how it works? Thanks!
Hello. I want functionality in my iOS widgets to only be available for subscribers and it’s not clear at all to me how to accomplish that.This page describes how to “enable data sharing between the main app and extensions”. So I’m assuming, but am not 100% sure, that means that Purchases.configure would be called by both the main and the widgets. And since they share a UserDefaults area they’ll know the same things. The SwiftUI Magic Weather app doesn’t seem to have widgets so I have nothing to go on. If this is correct where do I call Purchases.configure from the extension? The @main struct for WidgetBundle doesn’t seem to use a .init like a standard struct for a SwiftUI View. Maybe in an .onAppear attached to the WidgetEntryView? I also have another question. In the scenario where the subscription expired BUT it auto-renewed would calling Purchases.shared.customerInfo() be sufficient for checking entitlements or is it a requirement to call Purchases.shared.getCustomerInfo instead?
I’m currently using v5.6.6 and want to use 6.x with absolutely minimal changes.Is it possible to simply upgrade to 6.x or are code changes and even changes in Google Play subscription setup needed?I’ve read the guide here https://www.revenuecat.com/docs/android-native-5x-to-6x-migration but still I’m not sure if I can simply use the newer SDK if I’m fine not using the new capabilities.
Hello,Testflight subscription window takes around 10 seconds to pop-up on all devices; we also tried it on high performance phones such as iphone 12,13,X.Is this a chronical issue? We read some entries who share the same problem but could not yet find the solution. We will appreciate having your earliest reply.Thanks in advance.
Context: Playstore & Flutter.I have created 3 base plans (monthly, half-yearly, annually) in a subscription in Playstore.The monthly base plan is marked as “Backwards compatible” and the others not marked.In my app, only the monthly plan is showing up. I’m using internal testing to test the app and base plan created 3 days ago.How to show both plans?
Hi, Im trying to test staging and production apps separately on iOS. To do this, I created separate targets with separate bundle ids. I then followed the guidelines here:Since I only need to test locally on device and on the simulator, I created a StoreKit configuration test file and downloaded the cert. I then created a separate project in RC with the staging app bundle ID (I already had one with my production app), the app secret from AppStoreConnect, the Storekit cert, and the products setup to match the Storekit configuration file.I’ve double checked to ensure that in the bundleID matches the bundleID in XCode. I’ve also checked to ensure that the products setup match the products in the StoreKit config file. But, when I try to complete a purchase in my staging app, I get the following errorERROR: 💰 Product purchase for '(product' failed with error: Error Domain=RevenueCat.ErrorCode Code=8 "The receipt is not valid."If I click the button a second time it tells me I have already ma
In swift when I sign out and then try to purchase a subscription again it fails with a generic store error. Yet in the underlying error there is more data: Error: Optional(STORE_PROBLEM)Message: There was a problem with the App Store.Underlying Error: Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x2833c8ea0 {Error Domain=ASDServerErrorDomain Code=3532 "You’re currently subscribed to this." UserInfo={NSLocalizedDescription=You’re currently subscribed to this.}}} Purchases.ErrorCode is of no use and I couldn’t figure out the magic incantation to get to the useful bit. Any ideas? thanks
I can see in docs how to make Purchases with Kotlin like this:Purchases.sharedInstance.purchaseWith( PurchaseParams.Builder(this, aPackage).build(), onError = { error, userCancelled -> /* No purchase */ }, onSuccess = { storeTransaction, customerInfo -> if (customerInfo.entitlements["my_entitlement_identifier"]?.isActive == true) { // Unlock that great "pro" content } })But how can I can the attribute of (aPackage) on line.2? Please answer with code if possible.N.B: I have a 1 monthly subscription and I need to make when click on a button it directly opens Google default Paywall to make the purchase. So any other way to achieve this threw RevenueCat is appreciated.
Hi,I’ve just added RevenueCat and am trying to do some local testing with storekit. I’ve:Linked all the App secret and server to server notifications Created a storekit file synced with app store connect Added all storekit and other certificates in revenuecat Run the app connected to storekitWhen the app runs, I can call getOfferings and getCustomerInfo, and purchase the offering. When I purchase the offering, the transaction shows up in XCode, and my app gets a notification that customerInfo was updated, and I have the active entitlement.My issue is that I can’t seem to test anything past that. If I refund the purchase in Xcode, or delete the transactions, they are removed from Xcode but getCustomerInfo is never updated. RevenueCat keeps telling me the user is subscribed, even though they are NOT subscribed anymore. In fact, I can call purchase again and purchase the app, even though I was already entitled. There is some issue where RevenueCat does not realize that the subscription wa
a user deletes the app and data off their device. They previously purchased some non-consumable items. The reinstall. I run syncPurchases one time in the app delegate. I get this error ERROR: 🍎‼️ The receipt is missing.I expected it to return the non-consumable entitlements in the customerinfo. Any idea what I am doing wrong?
I am using custom promo codes for users of my app. My server checks if the code a user has entered is valid and if so, it sends a request to revenuecat, as stated in the documentation: const options = { method: 'POST', headers: {accept: 'application/json', 'content-type': 'application/json'}};fetch('https://api.revenuecat.com/v1/subscribers/app_user_id/entitlements/entitlement_identifier/promotional', options) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.error(err));My code is waiting for a “Subscriber” response, to check, if the promotional entitlement was successful. This all works fine, however it often takes around 60 seconds until I receive a response, varying between 10 and 60 seconds. Am I doing something wrong in my code, or is this behaviour expected? Thanks so much already in advance!
Hi guys,I'm configuring all products for my app. I have all of them imported from google play and my entitlements configured.In the docs you say that offerings are optional, but that's not true, because the sdk can't get product data without offerings and packages. I'm using unity sdk.What's the point of this? If I already have the products, I should be able to get all the data of each specific product, even if I don't have any offering.But right now, for me to get the products data and display them on muy app, I have to create an offering and a package for each product. And to be honest that's horrible, because I'm just duplicating products into packages for no reason at all, and also because the UI to attach products to packages it's very very bad, specially if you have lot's of products.So, is there in the roadmap and update to fix this?If not, at least update your documentation that you HAVE to have products, offerings and packages for revenuecat to work at it should.Thanks!
In this scenario, users have subscribed to a service using the same Gmail or Apple email on their mobile devices but have logged in with different email addresses and passwords on each device. The objective is to restrict access to the subscription service to only one user at any given time, while preventing others from using the same Gmail or Apple email on multiple devices. To address this, implementing robust user authentication mechanisms, allowing only one active session per user, implementing session timeouts, providing user notifications, offering account management options, and communicating a clear subscription policy are key strategies to ensure that only one user can utilize the subscription at any given time.
First I want to thank you for the great platform! What happens if an anonymous user purchases on device A, then restores (still as an anonymous user, but presumably with a different anonymous user ID) on device B? The docs say, that if my app “Does not have any login mechanism and only relies on RevenueCat anonymous App User IDs.”, I should choose “transfer purchases”.I want to make sure, that in the case described above, the user has access to the purchase on their Devices A and B (both logged in with the same App Store User that performed the original purchase on device A).So will device A lost access to subscription? Or both devices will have access to the subscription?if so, does this mean that one person can buy a subscription with one account and distribute it?What happens if an anonymous user purchases on device A, then restores (still as an anonymous user, but presumably with a different anonymous user ID) on device B and then restores to device A again?Thank you
In Android, a method called "showInAppMessages" was added from PBL4.https://developer.android.com/google/play/billing/subscriptions#in-app-messagingThis feature allows users to receive notifications once a day during a grace or account suspension period and request payment method corrections within the app.This feature allows developers to restore a certain percentage of users who unintentionally cancel their subscription back to purchasing status.Is there no method in the RevenueCat SDK that calls an equivalent of this method?Or is it possible to use this method while coexisting with the SDK by implementing and calling it natively?
Hello all,I have a question about how often I should call getCustomerInfo(). I am setting up RevenueCat in my SwiftUI application like so, based on the Magic Weather SwiftUI sample app @MainActorpublic class RevenueCatSingleton: NSObject, ObservableObject { public static let shared = RevenueCatSingleton() @Published public var customerInfo: CustomerInfo? { didSet { isUserPremium = customerInfo?.entitlements["plus"]?.isActive == true || customerInfo?.entitlements["mega"]?.isActive == true || customerInfo?.entitlements["epic"]?.isActive == true if customerInfo?.entitlements["epic"]?.isActive == true { currentUserSubscriptionLevel = .epic } else if customerInfo?.entitlements["mega"]?.isActive == true { currentUserSubscriptionLevel = .mega } else if customerInfo?.entitlements["plus"]?.isActive == true { currentUserSubscriptionLevel = .plus } } } @Published public var isUserPremium = false @Published public var currentUserSubscription
The function Purchases.getCustomerInfo() takes anywhere from 3 to 10 minutes to pull data for the first time the app is installed from TestFlight after upgrading to RevenueCat 4.25.9 ( react-native-purchases@6.6.5 ).It works as expected when installing from Xcode directly on device and using a Sandbox user. Not sure if there is an issue in production, but I’m afraid to make a release because of this. Anyone else encountering this problem?
In our test, SDK sometimes crashed. It is a bug of SDK confidently.All information in attachment.
Hey all,I recently created a Paywall for my main offering, and installed v4.26.1 via SPM. RevenueCat and RevenueCatUI dependencies installed correctly. I am using UIKit, not SwiftUI.When I follow the instructions to present an RC paywall from my view controller, the app tries to present something, but the paywall isn’t there. The view controller just gets dimmed and unresponsive. I’m connected to the internet on the test device, and I made the paywall VC an instance variable just in case it was getting garbage collected. Nothing works … any help here would be invaluable.
I have a React Native app for iOS and Android and I want to show users a yearly subscription option with a 1 week free trial:I don’t want to show different users different options I don’t want to do something different on Android vs iOS I don’t want discounts or promos So far I have:RevCat SDK installed and getting offerings My IAP created on the App Store And on the Play StoreBut I am just so so so lost. The offerings returned, as a json string, is literally 18768 characters long (without any whitespace), and nowhere in this monstrosity can I find:The actual name of my thing* properly included that I can use. ‘product.title’ is wrong. I’m working on Android first and this appends the name of the app. ‘serverDescription’ seems to not be meant for user facing use? And that’s it. hundreds and hundreds of fields...no name? This is despite the fact that I’ve inputted the name of my product in at least four different places (in Google Play, in my product display name, in my offering des
I've been working on adding Stripe Checkout to my existing app (both Android and iOS) for web checkout. Now I need to add a 'Manage Subscription' button within the app for users to easily navigate to where they can manage their subscription.I tested subscribing a user with Stripe but the managementUrl returns null. Is this the expected behavior?If so, it would be nice to make that clear in the documentation.I have a function which I call to create a Customer Portal Session for the purpose of redirecting users to manage their subscription. I'd be curious to know what is the type of link returned if there is one for the Stripe case because I thought we should be generating a Portal Session through our own backend.
Hello, I’m struggling with the RevenueCat update from 5.x to 6.4.0 on Android. I have currently a method to load the weekly subscription, however product doesn’t have subscriptionPeriod any longer. fun loadWeeklyProduct(onPackageLoaded: (Package?) -> Unit) { Purchases.sharedInstance.getOfferingsWith( { error -> // An error occurred }) { offerings -> val annualProduct = offerings.current?.availablePackages?.firstOrNull { item -> item.product.subscriptionPeriod == "P1W" } onPackageLoaded(annualProduct) }}And with this other method I would check if they still are eligible for Trial. Sadly product also no longer has any freeTrialPeriod. private fun fillTrialOrNormal(it: Package) { val hasFreeTrial = !it.product.freeTrialPeriod.isNullOrEmpty() Utilities().checkTrialUsedUp(it.product.sku, hasFreeTrial) { trialUsedUp -> var title = "" var header = "" if (trialUsedUp) { title = "
It’s pretty clear in the docs that iOS offer codes don’t function very well. I think I can handle the scenario manually in a pretty simple way. I’m thinking I’ll have a “redeem” screen in my app where a user can input a code, and that code & the app user id will get fired off in a request to a cloud function that will validate that all is correct, and then utilize the “Grant Promotional Entitlement” feature through the RevenueCat v1 API. Pros to this approach:• Allows me to have more custom scenarios (I would like to sell bulk licenses to businesses outside of app stores and their employees could redeem this way through the app, flexible free trials like 6 months free, awarding free product to influencers, etc.)• Seems like it would work a lot more reliably than the native sheet. Cons:• Reporting is a little funky since I would have a lot of folks with the ‘rc_promo’ active sku’s, so I may have to keep track of the redeemed codes in a different way as well. (Mostly) indie dev here
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.