34

I have gone through the Play Billing Library https://developer.android.com/google/play/billing/billing_library_overview You must acknowledge all purchases within three days. Failure to properly acknowledge purchases results in those purchases being refunded. The process is doesn't provide any clarity how to acknowledge purchases. This is what i tried Is this the correct way to do it. Thanks in Advance

@Override


 public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
        if(billingResult.getResponseCode()== BillingClient.BillingResponseCode.OK&&purchases!=null){
            Toast.makeText(this, "Purchase Successful", Toast.LENGTH_SHORT).show();
            for(Purchase purchase:purchases){
                handlePurchase(purchase);
            }
        }else if(billingResult.getResponseCode()== BillingClient.BillingResponseCode.USER_CANCELED){
            Toast.makeText(this, "Purchase Cancelled", Toast.LENGTH_SHORT).show();
        }else if(billingResult.getResponseCode()== BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED){
            Toast.makeText(this, "Already Purchased", Toast.LENGTH_SHORT).show();
        } else{
            Toast.makeText(this, billingResult.getDebugMessage(), Toast.LENGTH_SHORT).show();
        }



    //in handlePurchase()
 if(!purchase.isAcknowledged())
{ 
          AcknowledgePurchaseParams acknowledgePurchaseParams
                    = AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .setDeveloperPayload(purchase.getDeveloperPayload())
                    .build();

            client.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
                @Override
                public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
                    if(billingResult.getResponseCode()== BillingClient.BillingResponseCode.OK){
                        Toast.makeText(RemoveAdsActivity.this, "Purchase Acknowledged", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
Muntasir Aonik
  • 1,800
  • 1
  • 9
  • 22
Surya Ganesh
  • 492
  • 1
  • 6
  • 15
  • Hey Surya! I am implementing in app purchase. But unable to do so. Can you please provide me a working code of in app purchase only. just a billing manager and how do you call launchBillingFlow and how do you acknowledge it – Efrain Sanjay Adhikary Sep 24 '19 at 09:27

2 Answers2

50

It mentions acknowledging purchases near half way through that link. There are different ways to acknowledge the purchase depending on the type.

 private BillingClient mBillingClient = BillingClient.newBuilder(mActivity).setListener(this).build();

//For non-consumables:
mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener());

//For Consumables: 
client.consumeAsync(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);

The link I posted includes a sample on how to handle subscriptions.

UPDATE

Here's how to acknowledge both non-consumable and consumable purchases, staring with non-consumable:

First, create the AcknowledgePurchaseParams Class object. For this you need the purchase token which you should be able to get easily as you should be calling this in your onPurchasesUpdated method or another method that you passed purchase to after onPurchasesUpdated:

AcknowledgePurchaseParams acknowledgePurchaseParams =
            AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();

Next create your listener that will be used as the second parameter. This will allow you to do something after the purchase is acknowledged. I am displaying a snackbar message in this example (As per worbel's comment you can, and probably should, check the result of this billingResult):

AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = new AcknowledgePurchaseResponseListener() {
        @Override
        public void onAcknowledgePurchaseResponse(BillingResult billingResult) {              

            getMessage("Purchase acknowledged");               
        }

    };

With these created, use your BillingClient to call the acknowledgePurchase method:

mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);

The purchase should be successfully acknowledged.

This uses acknowledgePurchase for non-consumable items.

Consumable purchases

This is similar only what they are called is changed - See the explanation for what they are in the above example:

First parameter - Params - set-up:

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

Second parameter - Listener - set-up:

    ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            getMessage("Purchase acknowledged");
        }
    }

Now use your BillingClint and consumeAsync:

mBillingClient.consumeAsync(consumeParams, consumeResponseListener);
COYG
  • 1,538
  • 1
  • 16
  • 31
  • 2
    Thanks it's useful.I was able to purchase and acknowledge but billingClient.queryPurchasesList().getPurchasesList(); is returning null.Can you help me with this? – Surya Ganesh Jun 13 '19 at 20:27
  • 1
    I see no method for `queryPurchasesList()` should this not be, `BillingClient.queryPurchase(skuType).getPurchasesList();` ? – COYG Jun 14 '19 at 00:55
  • 1
    Yes, You are right.What might be the reason for that? – Surya Ganesh Jun 14 '19 at 06:14
  • @SuryaGanesh I updated the answer to show a more extended example for future reference – COYG Jul 03 '19 at 16:39
  • This is so frustrating. I keep getting response code 3. Google Play In-app Billing API version is less than 9. I am using the latest version of the billing library. My test phone is up to date. I am at a loss. – paul_f Jul 17 '19 at 11:56
  • May be somebody knows how to cansel acknowledge test purchase? – brucemax Sep 17 '19 at 15:52
  • What to do if purchase.getPurchaseToken() is returning null sometimes? – Cícero Moura Oct 23 '19 at 19:47
  • 3
    onAcknowledgePurchaseResponse(BillingResult billingResult) you should check is result OK – Wrobel Nov 08 '19 at 14:03
  • What do you do if the result is not OK? Do you retry? How many times, you can't keep the user there forever? I can't see the Acknowledge status of an order on the Order console in google play :-( – Pieter Mar 11 '20 at 06:11
  • @Pieter maybe try a few other times with a 1 second gap between attempts for a max of three seconds then let the user know to try again later if it doesn't work after that. If the purchase is acknowledged in your code it will be acknowledged on google play. – COYG Mar 11 '20 at 06:21
  • Thank you @COYG. I was also thinking of checking for acknowledge on the app startup and try there as well and hope that the user starts the app a few times in the 3 days that I have to acknowledge the payment. Not sure exactly what the reason for this acknowledge step is after the user purchased the item. It would have also helped if one could see the acknowledge status on the orders console and perhaps acknowledge it from there as well. – Pieter Mar 11 '20 at 07:35
  • 1
    For the subscription, it was explained in the Developer.android. But, how to declare the variables : BillingClient client = ... AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = Shall it be the same as the one Consumable acknowledge. Or it has another way to do so. ? – ama989 May 03 '20 at 05:10
  • 1
    @CíceroMoura it is null in case in network issues or billingClient.isInitialized() is false – Duna Oct 07 '20 at 17:15
  • I have a quuestion, 1. if the acknowledge is false, does it refund the purchase after 3 days? 2. Does the purchase acknowledgement is always true for a successful purchase 3. What does it mean consumable and non-consumable purchase. (INAPP purchase will comes under consumable or non-consumable) – sejn Oct 09 '21 at 09:36
0

If you are new and using billing library 4.0.0 then above codes will not work since now all billing process has been put in background thread so make sure you do not call any ui updating code during billing process.

Use:

purchase.getSkus.contains("sku here");

instead of

purchase.getSku.equals("sku here");
Elikill58
  • 4,050
  • 24
  • 23
  • 45