Question

customerInfo not returning from Purchases.purchasePackage(package) - but purchase goes through

  • 21 January 2024
  • 3 replies
  • 49 views

Badge +1

Hi all, 

I have implemented RevenueCat with my expo / react native project however I am running into a reoccurring issue where ‘customerInfo’ is not returning from my Purchases call. 

 

I am testing in sandbox and only on IOS (using my iphone on a dev server through expo). Maybe 1 in 20 attempts ‘customerInfo’ is returned from my purchase function. Otherwise the purchase function runs, makes the purchase (I receive all of the typical IOS messages regarding the purchase being successful and can see it listed in my sandbox account on the phone) but the customerInfo object is never returned, and the rest of my code just hangs. 

 

I have tested the purchases by removing the async call - obviously not ideal allowing access to the user before the purchase is made, but for testing everything works. The purchase is made and the user is logged in.. so I am not sure why I am not receiving the customerInfo object.

 

Hoping for some assistance or an idea if I am handling the config or purchase incorrectly.  

 

Just to recap, I am running the purchase function from revenuecat, waiting for customerInfo to return, then unlocking access to my app for the user. The issue is the purchase is successfully made but customerInfo is never returned, which prevents my app from creating a user on our own server and allowing access. 

 

I have tried all sorts of methods to validate customerInfo and check for any active entitlements, but the issue is that the customerInfo object is rarely ever returned and I cannot find any pattern when it does work. 

 

Thank you!

 

const APIKeys = {

apple: "appl_xxxxxxxxxx",

};

 

useEffect(() => {

const setup = async () => {

 

Purchases.setLogLevel(Purchases.LOG_LEVEL.DEBUG);

 

Purchases.configure({

apiKey: APIKeys.apple,

appUserID: signUpFormInfo.appUserID 

});

 

try {

const offerings = await Purchases.getOfferings();

if (offerings.current !== null && offerings.current.availablePackages.length !== 0) {

setCurrentOffering(offerings.current.availablePackages);

} else {

alert('An error occurred while getting your available memberships. Please try again.');

}

} catch (e) {

console.log(e);

alert('An error occurred while getting your available membership. Please try again.');

}

};

 

setup()

}, [signUpFormInfo]);

 

 

const purchasedPackage = async (packageId) => {

 

try { const { customerInfo } = await Purchases.purchasePackage(packageId)

 

// this is where i run into my issue - customerInfo is not returned so the code hangs here

 

if (typeof customerInfo.entitlements.active['pro'] !== "undefined") {

// create user on my server then log them in

} } catch (e) {

if (!e.userCancelled) {

showError(e);

} }

 


3 replies

Userlevel 3
Badge +6

Hey @jeffrey-connell-7489c5 ,

 

You can respond to any changes in CustomerInfo by conforming to an optional delegate method, purchases:receivedUpdated:. This will fire whenever we receive a change in CustomerInfo on the current device and you should expect it to be called at launch and throughout the life of the app. CustomerInfo updates are not pushed to your app from the RevenueCat backend, updates can only happen from an outbound network request to RevenueCat.

 

Depending on your app, it may be sufficient to ignore the delegate and simply handle changes to customer information the next time your app is launched. Or throughout your app as you request new CustomerInfo objects.

 

You are safe to call getCustomerInfo() multiple times throughout your apps lifecycle. This is since the SDK updates and caches the latest CustomerInfo when the app becomes active. The SDK caches the user's subscription information to reduce your app's reliance on the network. Users who unlock entitlements will be able to access them even without an internet connection. The SDK will update the cache if it's older than 5 minutes, but only if you call getCustomerInfo(), make a purchase, or restore purchases, so it's a good idea to call getCustomerInfo() any time a user accesses premium content.

 

Let me know if that helps!

Badge +1

@Michael Fogel I am trying to return customerInfo from the original purchase call when the user is at my paywall and makes a subscription purchase

try {

const { customerInfo } = await Purchases.purchasePackage(packageId)

 

I want to take customerInfo and then verify the object to ensure the customers purchase went through before allowing access to my app and creating their profile on my server. 

 

I am not calling this when the user logs in - just when they are making their initial subscription purchase. 

 

My problem is after calling Purchases.purchasePackage(packageId) the purchase is made in sandbox on and shows active on my device, however the user is not created in revenuecat sandbox and nothing is returned from the Purchases.purchasePackage call to validate so I can give the user access to my app. 

 

Userlevel 3
Badge +6

When you say that the user is not created in RevenueCat after the purchase has been made, what do you mean exactly? Is the app user ID of the user no longer showing in RC? The app user ID would need to be available before the purchase goes through, so that user should still be available in this case. 

 

I recommend checking out the guides below and making sure that users are being identified properly as well as the purchase is going through properly.​​​​​​:

 

Let me know if that helps! 

Reply