Search code examples
androidin-app-purchasein-app-billing

In app billing: isn't it possible to undo purchase?


I implemented android in app billing, uploaded it in developer console for alpha tests, created an item (one time product for premium version) and tested on my device. Everything worked, but I wanted to test a second time with same device - isn't it possible to undo purchase?

What I tried:

  • I canceled the purchased item in developer console --> nothing happened on my device, BillingClient.getPurchaseList still returned my premium purchase
  • I cleared cache with ad command "adb shell pm clear com.android.vending" --> and now it's getting strange:

First, I thought it works and BillingClient.queryPurchases().getPurchaseList didn't return any purchase and my app behaviour changed correctly to basic version. But if I try to buy the item one more time to test the purchase flow again, it says "item already owned". Isn't there any possibility testing it again??

Another strange thing I absolutely don't understand: I didn't do anything, openend my app a few hours later again and it is marked as premium again. What does that mean? Is in a problem in test account or can that also happen in real (canceled) purchases??

Thanks a lot for your help!


Solution

  • If you want to allow an item to be purchased multiple times (i.e in-game currency), you should consume it before buying it again, otherwise the IAB library will return the "Item already owned" error.

    To reset a purchase you can use BillingClient#consumeAsync(String purchaseToken).

    To get the purchaseToken of a purchase, use BillingClient#queryPurchaseHistoryAsync, this will return the list of current purchases.

    If you want to consume all purchases for debugging purposes, you can just use the following code:

    client.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP, new PurchaseHistoryResponseListener() {
                        @Override
                        public void onPurchaseHistoryResponse(int responseCode, List<Purchase> purchasesList) {
                            if (purchasesList != null && !purchasesList.isEmpty()) {
                                for (Purchase purchase : purchasesList) {
                                    client.consumeAsync(purchase.getPurchaseToken(), new ConsumeResponseListener() {
                                        @Override
                                        public void onConsumeResponse(int responseCode, String purchaseToken) {
                                            if (responseCode == BillingResponse.OK) {
                                              //Item consumed, you may repurchase it now
                                            } else {
                                                // Error, item not consumed. See responseCode for more info
                                            }
                                        }
                                    });
                                }
                            }
                        }
                    });
    

    Trying to clear cache won't fix the problem because as soon as the IAP library resyncs with GPlay, it will remember the purchases associated with the account of the current user.