play-billing-samples
play-billing-samples copied to clipboard
Google play billing purchase result shows empty list after a successful purchase in the google play billing library (Native android)
Google play billing purchase result shows empty list after a successful purchase in the google play billing library.
While purchase the product it returning the list as expected. After navigating to the two screens and if I check the go-to purchase screen again the Purchase list is empty for the same app.
Why the purchase list is empty after navigating to the screen?
Using billing library version 4.0.0
initially check purchase is done:
if (billingClient.isReady()) {
Purchase.PurchasesResult purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
List<Purchase> purchases = purchasesResult.getPurchasesList();
if (purchases.size() > 0) {
for (Purchase pur : purchases) {
String thisSku = pur.getSkus().get(0);
if (thisSku.equals(AD_REMOVAL_SKU)) {
return true;
}
}
}
billingClient = BillingClient.newBuilder(context).enablePendingPurchases().setListener(purchasesUpdatedListener).build();
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
LogUtils.LOGI(TAG, "Billing service connected.");
int responseCode = billingResult.getResponseCode();
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
LogUtils.LOGI(TAG, "Billing service connected with error.");
dispatchOnError(IABHELPER_ERROR);
return;
}
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Log.d(TAG, "onBillingSetupFinished: " + responseCode + " " + debugMessage);
Log.d(TAG, "debugMessage ==: " + debugMessage);
isIABSetupDone = true;
end = System.currentTimeMillis();
LogUtils.LOGI(TAG, String.format("binding took %d ms", (end - start)));
}
}
@Override
public void onBillingServiceDisconnected() {
LogUtils.LOGI(TAG, "Billing service disconnected.");
billingClient.endConnection();
billingClient = null;
}
});
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> list) {
// To be implemented in a later section.
LogUtils.LOGI(TAG, "billingResult on billingResult" + billingResult.getResponseCode());
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null) {
Toast.makeText(context.getApplicationContext(), list.toString(), Toast.LENGTH_LONG).show();
Toast.makeText(context.getApplicationContext(), billingResult.toString(), Toast.LENGTH_LONG).show();
Purchase info = list.get(0);
for (Purchase purchase : list) {
Purchase.PurchasesResult purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
if (info.getSkus().get(0).equals(AdsRemovalHelper.SKU)) {
ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build();
LogUtils.LOGI(TAG, "Consume params ===" + consumeParams);
billingClient.consumeAsync(consumeParams, new ConsumeResponseListener() {
@Override
public void onConsumeResponse(BillingResult billingResult, String s) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK ) {
LogUtils.LOGI(TAG, "Consume String ===" + consumeParams);
Toast.makeText(context.getApplicationContext(), purchase.getSkus().toString(), Toast.LENGTH_LONG).show();
}
}
});
}
} else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING) {
LogUtils.LOGI(TAG, "ConsumeString ===" );
} else if (purchase.getPurchaseState() == Purchase.PurchaseState.UNSPECIFIED_STATE) {
LogUtils.LOGI(TAG, "Consume S11111tring ===" );
}
}}
The example does not work with version 4, most likely the reason is BillingDataSource 'queryPurchases(java.lang.String)' is deprecate
Necessary queryPurchasesAsync
private List<Purchase> getPurchases(String[] skus, String skuType) {
Purchase.PurchasesResult pr = billingClient.queryPurchases(skuType);
Who knows how to decide?
@gusevmaksim I have an issue for billing.
I have found that if I make the purchase in the billing library v4, it not returning the purchase list. (Here using the v4 also, i have received the mail for the successful purchase)
But If I make the purchase using the old AIDL, the queryPurchase or queryPurchaseAsync returning the expected purchase list.(Here using the AIDL also, i have received the mail for the successful purchase)
Did you know any reason behind this?
No, it doesn't work
What do you mean it does not work?
This means I made the purchase using the old one (i.e) the production app and then checked the same app with the new code locally. Here I can able to see the purchaseList.
But If I make the purchase using the old AIDL, the queryPurchase or queryPurchaseAsync returning the expected purchase list.(Here using the AIDL also, i have received the mail for the successful purchase)
This function does not work /** * Used internally to get purchases from a requested set of SKUs. This is particularly important * when changing subscriptions, as onPurchasesUpdated won't update the purchase state of a * subscription that has been upgraded from. * * @param skus skus to get purchase information for * @param skuType sku type, inapp or subscription, to get purchase information for. * @return purchases */ private List<Purchase> getPurchases(String[] skus, String skuType) { Purchase.PurchasesResult pr = billingClient.queryPurchases(skuType);
@gusevmaksim Can you confirm, is it mandatory to handle the backend server to consumeresponse to process the purchase?
Okay Thanks. I have modified to queryPurchasesAsync method as per the doc. But there also, the purchase list is empty for the purchases which I have bought using the billing v4 apps.
I only added the consumeresponses and not make this to save in the backend. Is this making to fail the purchase list empty for the v4 purchased apps.
Note: Here as well the app which I have make the purchased before are returning the purchase list expected.
@jesphinpt Give that a try: https://stackoverflow.com/questions/67783059/android-billing-4-0-0-no-purchase-result-queryskudetailsasync/68742003#68742003
Library version 5.1.0. queryPurchasesAsync
still not working. Returns empty list no matter what I do.
Leaving this here just in case it saves someone some time. I was having the same issue with queryPurchasesAsync
but the issue was my phone was not connected to the internet.
Library version 5.1.0. When using Device A to initiate a delayed payment purchase and then switch to Device B to use queryPurchasesAsync, it will still return an empty list.
I'm using Billing Library v6.0.1
Calling:
billingClient.queryPurchasesAsync( QueryPurchasesParams.newBuilder() .setProductType(BillingClient.ProductType.SUBS) .build(), this )
inside my BillingClientLifecycle and I'm getting an empty list only intermittently on one device, this device has only one Google account logged in on the Play store.
And on my other device, which has multiple google accounts logged in on the Play store[including the one from device one], I am always getting an empty list.
I also found this question on SO that mentions getting an empty list when more than one account is logged in to Play store
I use com.android.billingclient:billing:6.1.0
, queryPurchasesAsync
will intermittently receive an empty list, even if the purchase has been successful. This usually happens a few days after the purchase is successful. Please fix this as soon as possible!
I use com.android.billingclient:billing:6.1.0, queryPurchasesAsync returns an empty list always. There are subscription products on play console. Please fix the issue.