Question

Rationale behind non-consumable purchases on Google Play?

  • 1 January 2023
  • 4 replies
  • 59 views

Badge

I’m new to RevenueCat and am looking into how I can migrate my existing app’s non-consumable in-app purchases to RevenueCat.

I know this type of question has been asked several times, but none of the answers really answered my question

So far, I’ve looked at using syncPurchases() but as stated in the documentation:

Google Play Store does not provide an option to mark IAPs as consumable or non-consumable. RevenueCat's SDK will consume all Android IAPs upon purchase.

To replicate the behavior of a non-consumable IAP for Android users, you must ensure your user will not offered the IAP after the initial purchase. Failure to do so will enable the user to re-purchase the IAP.

 

...and sure enough, in initial testing, as soon as I call syncPurchases() all of the user’s in-app products are consumed and the Google Play Billing client no longer sees the purchases.

Regarding the first paragraph, when using the Google Play Billing API, we have the option to consume, or not consume the in-app purchase. All of my in-app purchases are one-time payments for lifetime access (i.e. non-consumable).

When migrating to a new service (e.g. RevenueCat), it’s very risky to allow that new service to modify historical purchase data that stretches back (in my case) over 10 years, because what happens if I want to roll back to pre-revenuecat logic? Now I would have to change how I detect purchases (maybe looking at Purchase history instead of active purchases).

Surely I should be able to mark a product as non-consumable, so that when syncPurchases() is called the product is not consumed, and so Google Play purchase data is not touched?

Regarding the second paragraph, I don’t understand it.

As a workaround, I suppose I could avoid using syncPurchases() altogether and just using the Billing library to manually grant promotional entitlements instead?


4 replies

Userlevel 1
Badge +4

Now I would have to change how I detect purchases (maybe looking at Purchase history instead of active purchases).

This is actually the currently recommended way to implement this.

 

Surely I should be able to mark a product as non-consumable, so that when syncPurchases() is called the product is not consumed, and so Google Play purchase data is not touched?

Unfortunately this is something that is not currently supported. I will pass this along to the team working in the area as a feature request.

 

As a workaround, I suppose I could avoid using syncPurchases() altogether and just using the Billing library to manually grant promotional entitlements instead?

This works too.

Badge

This is actually the currently recommended way to implement this.

But I really don’t want to modify the purchases as stored by Google Play Store. So I’m looking for a read-only solution. 

I just noticed `Purchases.finishTransactions`. What happens if I set that to `false`?

Unfortunately this is something that is not currently supported. I will pass this along to the team working in the area as a feature request.

Thanks, that would be much appreciated.

As a workaround, I suppose I could avoid using syncPurchases() altogether and just using the Billing library to manually grant promotional entitlements instead?

This works too.

What are the disadvantages of this?

Instead, I’m wondering if I can use RevenueCat more as a way to share entitlements between devices. So for example, on Android use Play Billing to make purchases (likewise use StoreKit on iOS) and grant the promotional entitlements as those events are detected. Querying purchases would involve querying the native platform as well as RevenueCat entitlements to grab purchases made on other platforms.

Is this feasible? Are there limits on how many promotional entitlements? Are there drawbacks - e.g. more difficult to detect fake purchases because of non-use of purchase tokens?

Userlevel 4
Badge +9

Hey there! Yousef’s out of the office for a while so I’m handling some of his tickets. Yes you can set Purchases.finishTransactions to false. In this case purchases will not be consumed by RevenueCat. But please test it on a test user first as this isn’t intended usage of that setting and you have specific needs so make sure it fits what you need. We’re happy to keep helping out and answering questions as needed.

Instead, I’m wondering if I can use RevenueCat more as a way to share entitlements between devices. So for example, on Android use Play Billing to make purchases (likewise use StoreKit on iOS) and grant the promotional entitlements as those events are detected. Querying purchases would involve querying the native platform as well as RevenueCat entitlements to grab purchases made on other platforms.

 

Yes, this is exactly the workaround we have recommended in the past. The biggest disadvantages are:

  1. No revenue tracking, metrics, etc. Promotional entitlements are “free” (essentially just overrides to subscription status.) You’d either want to rely on Google Play console or a third party metrics service.
  2. Promotional entitlements don’t automatically renew or follow cancel behavior of subscriptions, so you’ll have to grant new ones/delete old ones as the user’s subscription status changes. This doesn’t seem like an issue for you since you have only non-subscription products, but you may want to keep track of refunds.

It’s a manual process but has been used by other apps who use RevenueCat for other things, for example iOS but not Android (or an unsupported store like Recurly.) It is feasible - there no limits to number of promotional entitlements and there is a “lifetime” duration you can use - but of course this is non-trivial work, as you’d need to have a backend to keep RevenueCat up to date. It’s best if you’re using RevenueCat for something else (like iOS) and need to also use RevenueCat for Android one-time purchases too. Otherwise I wouldn’t recommend you do this for only Android, it’s probably easier at that point to handle purchasing and entitlement access yourself, use the finishTransactions workaround, or simply accept RevenueCat’s consuming behavior.

Badge

Thanks very much, this is very helpful.

I’m a little nervous to use Purchases.finishTransactions = false if it is unintended usage, as that means the behavior may change in future.

Generally speaking, it’s unintuitive that syncPurchases would modify (consume) the app store data. With any sort of sync, if there is no data on one end, you would simply expect the data to flow (unmodified) from the end with data to the end with no data. You would only expect app store data to be modified if the device had some more recent data that needed to be pushed to the app store.

Reply