Search code examples
androidin-app-purchasein-app-billingandroid-inapp-purchase

How to acknowledge in-app purchases in android?


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();
                    }
                }
            });
        }

Solution

  • 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);