3

Some of my users tell me that my app forgets the purchased subscriptions every now and then. It works for 3-4 days and then it forgets them. This is a very important issue as users might suspect fraud. I am using billing library 4.0.0 and I have implemented the billing logic as per Google's guidelines.

From what I have gathered it happens when for some reason the billing service connection is interrupted. (Play Store is updating for example)

I have managed to replicate this scenario the following way

- Disable internet connection
- Clearing Play Store app data
- Fresh launch of my app.
- Call billingClient.startConnection()
    onBillingSetupFinished called with responseCode BILLING_UNAVAILABLE
    user sees -> The app says "no subscription purchased"

- Enable internet connection
- re-initialize BillingClient.
    onBillingSetupFinished called with responseCode OK. billingClient.isReady() returns true. 
- Call billingClient.queryPurchasesAsync() and billingClient.querySkuDetailsAsync().
    onSkuDetailsResponse is called with the skuDetailsList filled with all the proper data. However:
    onQueryPurchasesResponse is called with empty purchase list -> Again user sees "no subscriptions purchased"

Important If at this point I open Play Store it shows the purchased subscriptions. But the app still gets an empty purchases list.

If I keep calling billingClient.startConnection() or billingClient.queryPurchasesAsync() at some point after about 10 minutes one attempt will succeed and return a non empty purchases list.

Is it possible to tell Play Store to refresh its subscription data for my app? How can someone handle this scenario gracefully ?

Anonymous
  • 4,470
  • 3
  • 36
  • 67
  • You can try preserving the purchase state in local storage like `DataStore` or `EncryptedSharedPreferences`. – Darshan Dec 20 '21 at 07:02
  • @DarShan Yes I thought about that and I might eventually do it if no better solution is found. But that is basically a hack to go around something that should be working properly and isn't. The correct solution would be to have the billing logic work as it should relying only on BillingClient. – Anonymous Dec 20 '21 at 09:53
  • Unfortunately no. I just handled it manually. When I successfully get purchases I save them locally with a timestamp. When I get a scenario where local purchases are not empty but the billing client returns an empty list, I trust the local data as long as they are not too old. By the time the local data "expires" the billing client should have returned to a working state. And I keep retrying to refresh purchases every 1 minute for 20 minutes max when that scenario is detected – Anonymous Feb 17 '22 at 01:50
  • Could be related to this question https://stackoverflow.com/questions/76162703/google-play-billing-querypurchasesasync-querypurchasehistoryasync-return-empty – ProjectDelta Aug 24 '23 at 13:40

2 Answers2

1

You need to call acknowledgePurchase for every purchase.
See the official docs and the article for more details.

sdex
  • 3,169
  • 15
  • 28
  • Yes I know, I am doing that. The billing flow is implemented as per Google's guidelines. The problem appears when for some reason Play Store cannot respond with the correct data for some reason. After a few retries or some time passes it eventually returns the correct data. But that is a problem for the app and the users – Anonymous Dec 20 '21 at 09:50
0

Worked for me!

BillingClient billingClient = ...;

billingClient must be ready -> billingClient.isReady() == true;

So, always call billingClient.queryProductDetailsAsync(...) from

                @Override
                public void onBillingSetupFinished(BillingResult billingResult) {
                    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        // The BillingClient is ready. You can query purchases here.
                        queryProductDetails();
                        queryPurchases();
                    }
                }

when initialize the billingClient connection! Keep it up :)

Andrij
  • 218
  • 2
  • 8