Question

Google Play non-consumable purchase handling

  • 7 June 2023
  • 5 replies
  • 597 views

Userlevel 1
Badge +6

My app has two modes, offline and online. The offline mode (which doesn’t require users to log in) offers users a non-consumable, while the online mode (which requires users to log in) offers subscriptions.

 

RevenueCat handles the subscriptions part well. However, for the non-consumable part it’s a bit confusing. I’ve read multiple posts here 

 and 

 saying that RC will always CONSUME the products. 

 

However, Google’s Billing Library offers two ways to handle non-subscriptions products, one is to acknowledge, another way is to consume (https://developer.android.com/google/play/billing/integrate#non-consumable-products and https://developer.android.com/google/play/billing/integrate#consumable-products). By calling ` BillingClient.acknowledgePurchase()`, it ensures that it’s treated as non-consumable so that when user tries to purchase this again, Google Play will prompt an error saying “You’ve already owned this item”. By calling `BillingClient.consumeAsync`, it will therefore be treated as consumable and Google Play allows users to purchase this item more than once.

 

My question is that why does RC have to always “consume” instead of “acknowledge” this purchase?

 

Also, RC doesn’t provide a way to refund consumables from dashboard, so when we refund the purchase from Google Play, user’s `CustomerInfo` is not updated, this means there is no way we can know if the purchase is still valid. However, if RC provides an option to `acknowledge` instead of `consume`, at least we can rely on Google Play Billing’s api to know that this purchase has been refunded. (`BillingClient.queryPurchasesAsync` will not return non-consumable purchases that have been refunded)


5 replies

Userlevel 4
Badge +6

Hi @william_O,

These are all good questions - our current method of consuming all purchases from Google can definitely be a limitation for non-consumables, and one that we’re looking into different solutions for. We actually consume and acknowledge non-consumables, but the effect is the same in that they can’t be returned from .queryPurchases and they won’t get an error that they’ve already purchased the item.

The solution from the second community post that you linked is still a good one - setting up your non-consumable inside an entitlement of it’s own. This entitlement will unlock forever, and you can check customerInfo to see if that entitlement is active before showing them the non-consumable product for purchase.

Regarding refunds - we do allow and detect refunds for non-consumable transactions, but we can’t detect refunds for consumable transactions. You mentioned both so I just wanted to clarify!

Userlevel 1
Badge +3

The fundamental problem here is that by consuming purchases you are changes the underlying state of the product on Google Play. This is a problem because what if you want to roll back from RC back to a native solution? All of a sudden your products are not consumed and you have to try to go through the Purchase History instead.

 

I’m struggling to set up RevenueCat. Calling queryPurchases for my test user is returning all products (supposed to be non-consumables that have been refunded) as active, even though none of them are. I’m guessing that RC is falsely considering them as active, perhaps because of this “consumed” issue. It’s very frustrating.

Badge +2

Just want to say, I got burned BADLY by this. About a year a go. I had lots of acknowledgement of the severity from RC people, But also it seemed like they couldn’t change it without causing other unwanted side effects.  

That’s why I have stayed away from RC.

It is quite tempting but payment is the most important part of App and you are relying on third party for it.

Badge

I want to integrate fully but this limitation is holding me back for now

Reply