Breaking News

Create an In-App Purchases in Android

Create an In-App Purchases in Android

In this post, we will learn about how to create In-App Purchases in the Android app.




We will create an In-App Purchases in Android with Google Play Billing Library 

Note: For In-App Purchases you have to upload a signed APK to Alpha, Beta, or Publish section in Google Play Console (Drafts are not supported). Also, create a Tester in that Alpha release to test your account with a Test Purchase.

In this post, we learn about 
  • Creating In-App Purchases in the Android app.
  • Managed and UnManaged Product
  • Consume a Managed Product (so that you can buy again the same product with the same account).
  • Acknowledge a product.
  • Give Data to the user after purchase successfully.
  • Generate a Signed app and upload it to Alpha Testing.
  • Add Testers for Alpha Testing.

Firstly, we create an In-App Purchase in Android and in that we cover remaining topics.

For that, create a Managed Product in Google Play Console.


  • Open Google Play Console
  • Click on Store Presence
  • Click on In-App Products
  • Click on Managed Product
In-App Purchases in Google Play Console
In-App Purchases in Google Play Console

  • Create a Managed Product
  • Fill your Product_id, Product_name, Product_Description, and change to Active and then set a price for your product.
Create a Managed Product
Create a Managed Product

Make In-App product active and Set price
Make In-App product active and Set price

When you successfully create a Managed product then  

Open your Android Studio project and add Google Play Billing Library.

app-level build.gradle
 implementation 'com.android.billingclient:billing:2.2.0'  

Then add permissions in AndroidManifest.xml
 <uses-permission android:name="android.permission.INTERNET" />  
 <uses-permission android:name="com.android.vending.BILLING" />  

Then Create a Billing activity in your project and add below code in it.

Billing.java
 import androidx.annotation.Nullable;  
 import androidx.appcompat.app.AppCompatActivity;  
 import android.os.Bundle;  
 import android.view.View;  
 import android.widget.Button;  
 import android.widget.TextView;  
 import android.widget.Toast;  
 import com.android.billingclient.api.BillingClient;  
 import com.android.billingclient.api.BillingClientStateListener;  
 import com.android.billingclient.api.BillingFlowParams;  
 import com.android.billingclient.api.BillingResult;  
 import com.android.billingclient.api.ConsumeParams;  
 import com.android.billingclient.api.ConsumeResponseListener;  
 import com.android.billingclient.api.Purchase;  
 import com.android.billingclient.api.PurchasesUpdatedListener;  
 import com.android.billingclient.api.SkuDetails;  
 import com.android.billingclient.api.SkuDetailsParams;  
 import com.android.billingclient.api.SkuDetailsResponseListener;  
 import java.util.ArrayList;  
 import java.util.List;  
 public class Billing extends AppCompatActivity implements PurchasesUpdatedListener {  
   Button buy_btn;  
   TextView tv;  
   BillingClient billingClient;  
   List<String> skulist = new ArrayList<>();  
   String product = "my_test_product_12";  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_billing);  
     buy_btn = findViewById(R.id.buy_button_1);  
     tv = findViewById(R.id.tv);  
     billingClient = BillingClient.newBuilder(Billing.this).enablePendingPurchases().setListener(new PurchasesUpdatedListener() {  
       @Override  
       //This method starts when user buys a product  
       public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> list) {  
         if(list != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK)  
         {  
           for(Purchase purchase : list)  
           {  
             handlepurchase(purchase);  
           }  
         }  
         else  
         {  
           if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED)  
           {  
             Toast.makeText(Billing.this, "Try Purchasing Again", Toast.LENGTH_SHORT).show();  
           }  
           else  
           {  
             if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED)  
             {  
               Toast.makeText(Billing.this, "Already Purchased", Toast.LENGTH_SHORT).show();  
               //We recover that method by consuming a purchase so that user can buy a product again from same account.  
             }  
           }  
         }  
       }  
     }).build();  
     billingClient.startConnection(new BillingClientStateListener() {  
       @Override  
       public void onBillingSetupFinished(BillingResult billingResult) {  
         if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK)  
         {  
           Toast.makeText(Billing.this, "Successfully connected to Billing client", Toast.LENGTH_SHORT).show();  
         }  
         else  
         {  
           Toast.makeText(Billing.this, "Failed to connect", Toast.LENGTH_SHORT).show();  
         }  
       }  
       @Override  
       public void onBillingServiceDisconnected() {  
         Toast.makeText(Billing.this, "Disconnected from the Client", Toast.LENGTH_SHORT).show();  
       }  
     });  
     skulist.add(product);  
     final SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();  
     params.setSkusList(skulist).setType(BillingClient.SkuType.INAPP);  //Skutype.subs for Subscription  
     buy_btn.setOnClickListener(new View.OnClickListener() {  
       @Override  
       public void onClick(View view) {  
         billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {  
           @Override  
           public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> list) {  
             if(list != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK)  
             {  
               for(final SkuDetails skuDetails : list)  
               {  
                 String sku = skuDetails.getSku(); // your Product id  
                 String price = skuDetails.getPrice(); // your product price  
                 String description = skuDetails.getDescription(); // product description  
 //method opens Popup for billing purchase  
                 BillingFlowParams flowParams = BillingFlowParams.newBuilder()  
                     .setSkuDetails(skuDetails)  
                     .build();  
                 BillingResult responsecode = billingClient.launchBillingFlow(Billing.this,flowParams);  
               }  
             }  
           }  
         });  
       }  
     });  
   }  
   private void handlepurchase(Purchase purchase) {  
     try {  
       if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {  
         if (purchase.getSku().equals(product)) {  
           ConsumeParams consumeParams = ConsumeParams.newBuilder()  
               .setPurchaseToken(purchase.getPurchaseToken())  
               .build();  
           ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {  
             @Override  
             public void onConsumeResponse(BillingResult billingResult, String s) {  
               Toast.makeText(Billing.this, "Purchase Acknowledged", Toast.LENGTH_SHORT).show();  
             }  
           };  
           billingClient.consumeAsync(consumeParams, consumeResponseListener);  
           //now you can purchase same product again and again  
           //Here we give coins to user.  
           tv.setText("Purchase Successful");  
           Toast.makeText(this, "Purchase Successful", Toast.LENGTH_SHORT).show();  
         }  
       }  
     }  
     catch (Exception e)  
     {  
       Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();  
     }  
   }  
   @Override  
   public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> list) {  
     Toast.makeText(this, "onPurchases Updated", Toast.LENGTH_SHORT).show();  
   }  
 }  

In this, we create an In-App Purchases and then Consume a purchase and then give coins to users.

activitybilling.xml
 <?xml version="1.0" encoding="utf-8"?>  
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:app="http://schemas.android.com/apk/res-auto"  
   xmlns:tools="http://schemas.android.com/tools"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   android:orientation="vertical"  
   tools:context=".Billing">  
   <Button  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:text="Buy"  
     android:padding="10dp"  
     android:id="@+id/buy_button_1"/>  
   <TextView  
     android:padding="10dp"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:text="Purchase"  
     android:id="@+id/tv"  
     android:textSize="18sp"/>  
 </LinearLayout>  

After that, we generate a Signed Bundle and upload it to Google Play Console under Alpha Testing Mode.

For that, In Android studio, Click on Build -> Generate Signed Bundle and create a bundle or APK.


Generate Signed Bundle From Android Studio
Generate Signed Bundle From Android Studio


Then open Google Play Console 

  • Open your App or create one.
  • Click on Release Management from the left menu.
  • Then click on App releases
App Releases in Google Play Console
App Releases in Google Play Console
  • Then Click on Alpha Testing
Alpha Testing in Google Play Console
Alpha Testing in Google Play Console

  • Click on Create release
  • Upload your Apk and save and review.
  • Click on Manage testers and add your email id.
After Your App successfully uploaded to Google Play console then install your app from Play Store from your Test Account and then click on the Buy button and then purchase your product with test card.

Thanks


Follow us for more posts like this, 
Subscribe Harpreet studio on Youtube  
Like Harpreet Studio on Facebook  
Follow me on Instagram 

1 comment: