How to integrate Google Play in-app purchase Billing Library Programmatically into your Android App

In this article, I will show you how to integrate In-App Purchase for Subscription of Google Play in-app purchase Billing Library version 5+ into your Android App. in this tutorial I will follow the google official documentation

What will be required –

  • Android Studio to write this code
  • Google Play Console Account
  • A published App
  • Device or Emulator For Test

 Step 1

Add the Google Play Billing Library dependency to your app’s build.gradle file as shown:

dependencies {
    def billing_version = "5.0.0"

    implementation "com.android.billingclient:billing:$billing_version"
}

Step 2

Initialize a BillingClient with PurchasesUpdatedListener in the onCreate method

billingClient = BillingClient.newBuilder(this)
                .enablePendingPurchases()
                .setListener(
                        new PurchasesUpdatedListener() {
                            @Override
                            public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List list) {
                               if(billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK && list !=null) {
                                   for (Purchase purchase: list){
                                       verifySubPurchase(purchase);
                                   }
                               }
                            }
                        }
                ).build();

        //start the connection after initializing the billing client
        establishConnection();

 

Step 3

Establish a connection With Google Play API

void establishConnection() {

       billingClient.startConnection(new BillingClientStateListener() {
           @Override
           public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
               if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                   // The BillingClient is ready. You can query purchases here.
                   showProducts();
               }
           }

           @Override
           public void onBillingServiceDisconnected() {
               // Try to restart the connection on the next request to
               // Google Play by calling the startConnection() method.
               establishConnection();
           }
       });
   }

 

Step 4

Show the products and make them available to Purchase

@SuppressLint("SetTextI18n")
    void showProducts() {

        ImmutableList productList = ImmutableList.of(
                //Product 1 = index is 0
                QueryProductDetailsParams.Product.newBuilder()
                .setProductId("sub_premium")
                .setProductType(BillingClient.ProductType.SUBS)
                .build(),

                //Product 2 = index is 1
                QueryProductDetailsParams.Product.newBuilder()
                .setProductId("test_id_shar")
                .setProductType(BillingClient.ProductType.SUBS)
                .build()

        );

        QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
                .setProductList(productList)
                .build();

        billingClient.queryProductDetailsAsync(
                params,
                (billingResult, productDetailsList) -> {
                    // Process the result
                    for (ProductDetails productDetails : productDetailsList) {
                        if (productDetails.getProductId().equals("sub_premium")) {
                            List subDetails = productDetails.getSubscriptionOfferDetails();
                            assert subDetails != null;
                            Log.d("testOffer",subDetails.get(0).getOfferToken());
                            txt_price.setText(subDetails.get(0).getPricingPhases().getPricingPhaseList().get(0).getFormattedPrice()+" Per Month");
                            txt_price.setOnClickListener(view -> {
                                launchPurchaseFlow(productDetails);
                            });
                        }

                        if (productDetails.getProductId().equals("test_id_shar")) {
                            List subDetails = productDetails.getSubscriptionOfferDetails();
                            assert subDetails != null;
                            Log.d("testOffer",subDetails.get(1).getOfferToken());
                            offer_btn.setText(subDetails.get(1).getPricingPhases().getPricingPhaseList().get(0).getFormattedPrice()+" Per Month");
                            offer_btn.setOnClickListener(view -> {
                                launchPurchaseFlow(productDetails);
                            });
                        }
                    }
                }
        );

    }

 

Step 5

Launch the purchase flow

void launchPurchaseFlow(ProductDetails productDetails) {
       assert productDetails.getSubscriptionOfferDetails() != null;
       ImmutableList productDetailsParamsList =
               ImmutableList.of(
                       BillingFlowParams.ProductDetailsParams.newBuilder()
                               .setProductDetails(productDetails)
                               .setOfferToken(productDetails.getSubscriptionOfferDetails().get(0).getOfferToken())
                               .build()
               );
       BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
               .setProductDetailsParamsList(productDetailsParamsList)
               .build();
       BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
   }

 

Step 6

Process the purchases and Verify Payment

void verifySubPurchase(Purchase purchases) {

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

        billingClient.acknowledgePurchase(acknowledgePurchaseParams, billingResult -> {
            if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                //user prefs to set premium
                Toast.makeText(StoreActivity.this, "You are a premium user now", Toast.LENGTH_SHORT).show();
                //Setting premium to 1
                // 1 - premium
                // 0 - no premium
                prefs.setPremium(1);
            }
        });

        Log.d(TAG, "Purchase Token: " + purchases.getPurchaseToken());
        Log.d(TAG, "Purchase Time: " + purchases.getPurchaseTime());
        Log.d(TAG, "Purchase OrderID: " + purchases.getOrderId());
    }

 

Step 7

Handling pending transactions

protected void onResume() {
        super.onResume();
        billingClient.queryPurchasesAsync(
                QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS).build(),
                (billingResult, list) -> {
                    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        for (Purchase purchase : list) {
                            if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED && !purchase.isAcknowledged()) {
                                verifySubPurchase(purchase);
                            }
                        }
                    }
                }
        );

    }

 

Step 8

Check Subscription, run this code while the app starting(the best way will be to use this below code inside your splash screen Activity)

void checkSubscription(){

    billingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener((billingResult, list) -> {}).build();
    final BillingClient finalBillingClient = billingClient;
    billingClient.startConnection(new BillingClientStateListener() {
        @Override
        public void onBillingServiceDisconnected() {

        }

        @Override
        public void onBillingSetupFinished(@NonNull BillingResult billingResult) {

            if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
                finalBillingClient.queryPurchasesAsync(
                        QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS).build(), (billingResult1, list) -> {
                    if (billingResult1.getResponseCode() == BillingClient.BillingResponseCode.OK){
                         Log.d("testOffer",list.size() +" size");
                         if(list.size()>0){
                             prefs.setPremium(1); // set 1 to activate premium feature
                             int i = 0;
                             for (Purchase purchase: list){
                                 //Here you can manage each product, if you have multiple subscription
                                 Log.d("testOffer",purchase.getOriginalJson()); // Get to see the order information
                                 Log.d("testOffer", " index" + i);
                                 i++;
                             }
                         }else {
                             prefs.setPremium(0); // set 0 to de-activate premium feature
                         }
                    }
                });

            }

        }
    });
}

if you want a video tutorial about Integrating the Google Play Billing Library check our YouTube Channel. you will find more awesome tutorials

Related blog posts