0

I have set up in-app billing on an Android app (java). When I call launchBillingFlow on the BillingClient:

        BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                .setSkuDetails(skuDetails)
                .build();
        BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
            //the system displays the Google Play purchase screen
        } else {
            Log.e(TAG, "Billing failed: + " + billingResult.getDebugMessage());
        }

This is what my onPurchasesUpdated (from PurchasesUpdatedListener) looks like:

    @Override
    public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
                && purchases != null) {
            for (Purchase purchase : purchases) {
                for (String sku : purchase.getSkus()) {
                    if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
                        if (skuConsumables.contains(sku)) {
                            handlePurchaseConsumable(purchase);
                        } else if (skuNonconsumables.contains(sku)) {
                            handlePurchaseNonconsumable(purchase);
                        }
                    }
                }

            }
        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
            // Handle an error caused by a user cancelling the purchase flow.
            billingServiceListener.receivePurchaseError();
        } else {
            // Handle any other error codes.
            billingServiceListener.receivePurchaseError();
        }
    }

onPurchasesUpdated is called six times, each time with a responseCode of OK. Twice onPurchasesUpdated is called with zero purchases, that's fine. What I am confused about is how to deal with the four times onPurchasesUpdated is called with one purchase. And it seems as though each of these four purchase objects are indistinguishable - the same packageName, acknowledged, orderId, productId, purchaseState, purchaseToken, etc.

To complicate things, for consumable in-app billing, (these are consumable) I am then calling ConsumeResponseListener and onConsumeResponse is also returning four times, each time with responseCode of OK.

private void handlePurchaseConsumable(Purchase purchase) {

        ConsumeParams consumeParams =
                ConsumeParams.newBuilder()
                        .setPurchaseToken(purchase.getPurchaseToken())
                        .build();

        ConsumeResponseListener listener = new ConsumeResponseListener() {
            @Override
            public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                    // Handle the success of the consume operation.

                }
            }
        };
        billingClient.consumeAsync(consumeParams, listener);
    }

Is this behaviour seen by others? I am using static responses while in development, could this be the reason? If people are seeing this, how do you deal with this - do you keep track of what purchase you have attempted, and then when the first response is returned do you register that the purchase was successful and ignore subsequent times that onPurchasesUpdated returns a purchase if you weren't expecting a payment? Though I've seen that Android permits cash purchases with enablePendingPurchases, so that can't be a solution...

1 Answer 1

0

This can happen for 2 reasons.

  1. if you are using an outdated version of the google-billing API.
  2. if you forgot to destroy the billing client at the finish of the activity.
3
  • 1. I am using 4.0.0. [newline]. 2. I only have one activity (use fragments) Feb 18 at 15:05
  • I mean, if you're start connection more than one time called, then make sure that you have to destroy it before a new connection with billingClient.endConnection().
    – EAS
    Feb 19 at 5:22
  • Thanks for your comments. billingClient.startConnection is only called once, and onBillingSetupFinished is only triggered once with a responseCode of OK. I know this because I log to the console when these two events occur. Feb 19 at 15:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.