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

