What result codes can be returned from BillingClient.launchBillingFlow()?

Viewed 1264

I'm using using Google's Billing Library 4. The documentation for BillingClient.launchBillingFlow says:

Initiates the billing flow for an in-app purchase or subscription.

It will show the Google Play purchase screen. The result will be delivered via the PurchasesUpdatedListener interface implementation set by BillingClient.Builder.setListener(PurchasesUpdatedListener).

The PurchasesUpdatedListener is passed a BillingResult object that contains a response code. However, the launchBillingFlow method also returns a BillingResult object. My question is, what response codes do I need to deal with in each place?

The documentation is, shall we say, less than clear, and also seems wrong. For launchBillingFlow, it says that the method returns a BillingResult with a code of BillingResponseCode.BILLING_CANCELED if the user cancels the purchase flow. However, my experiments show that code is actually delivered in a call to PurchasesUpdatedListener.onPurchasesUpdated.

Unfortunately, the source code for BillingClient isn't available, but I did decompile the library module. As far as I can tell, the call to launchBillingFlow can return the following result codes:

  • OK - when the flow successfully starts (and the user is shown Google's purchase screen).
  • SERVICE_DISCONNECTED - when the BillingClient isn't currently connected to Google Play on the device.
  • SERVICE_TIMEOUT - if the connection breaks during the attempt to launch the flow. (I think I read somewhere that this can happen if Google Play is being updated in the background.)
  • FEATURE_NOT_SUPPORTED - under various conditions where the BillingFlowParams don't match the current configuration of the BillingClient object.

There also seems to be a place in the decompiled code where certain error responses from the Google Play billing service are captured and returned here. Does anyone know what other response codes can be returned from a call to launchBillingFlow?

2 Answers

As per the my experience you can handle the result like mentioned below example :-

 this.mBillingClient = BillingClient.newBuilder(this).setListener(new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> list) {
      if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null) {
        for (Purchase purchase : list) {

          if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
            addPurchaseDetails(purchase);
            handlePurchase(purchase);

          }
        }
      } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
        Log.v("purchase", billingResult.getDebugMessage());
      }

Means you have to check :- billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null

And get the Purchase from the list and handle the purchase as per your need.

    for (Purchase purchase : list) {
       }

Also find the errors below :-  

public @interface BillingResponseCode {
        int SERVICE_TIMEOUT = -3;
        int FEATURE_NOT_SUPPORTED = -2;
        int SERVICE_DISCONNECTED = -1;
        int OK = 0;
        int USER_CANCELED = 1;
        int SERVICE_UNAVAILABLE = 2;
        int BILLING_UNAVAILABLE = 3;
        int ITEM_UNAVAILABLE = 4;
        int DEVELOPER_ERROR = 5;
        int ERROR = 6;
        int ITEM_ALREADY_OWNED = 7;
        int ITEM_NOT_OWNED = 8;
    }

First of all, thank you for your good question. As far as I researched, the values ​​listed below are available.

BillingClient.BillingResponseCode // all codes

int BILLING_UNAVAILABLE Billing API version is not supported for the type requested.

int DEVELOPER_ERROR Invalid arguments provided to the API.

int ERROR Fatal error during the API action.

int FEATURE_NOT_SUPPORTED Requested feature is not supported by Play Store on the current device.

int ITEM_ALREADY_OWNED Failure to purchase since item is already owned.

int ITEM_NOT_OWNED Failure to consume since item is not owned.

int ITEM_UNAVAILABLE Requested product is not available for purchase.

int OK Success.

int SERVICE_DISCONNECTED Play Store service is not connected now - potentially transient state.

int SERVICE_TIMEOUT The request has reached the maximum timeout before Google Play responds.

int SERVICE_UNAVAILABLE Network connection is down.

int USER_CANCELED User pressed back or canceled a dialog.

launchBillingFlow // return values for

The result of the launch billing flow operation. BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED if the user already owns the item being purchased, BillingClient.BillingResponseCode.ITEM_UNAVAILABLE if the item is not available to be purchased, and BillingClient.BillingResponseCode.USER_CANCELED if the user dismissed the purchase flow.

Update Answer

what are the possible return values when the call to launchBillingFlow() fails

  • ITEM_ALREADY_OWNED
  • ITEM_UNAVAILABLE
  • USER_CANCELED

what are the possible values when onPurchasesUpdated() is called (at the completion of the flow).

  • OK
  • ITEM_UNAVAILABLE
  • ITEM_ALREADY_OWNED
  • USER_CANCELED
  • ERROR launchBillingFlow Error
Related