Hello, in this tutorial, I will show you how to use the Google Play Billing Library to start selling IN-APP products on your apps.
Hello, in this tutorial, I will show you how to use the Google Play Billing Library to start selling IN-APP products on your apps.
We will go over:
Download Source Code to Project:
https://codeible.com/coursefiles/googleplayinapp
Adding the Google Play Billing Library
To begin, go to the Manifests file and add the INTERNET permission.
Then go to the app’s build.gradle file, implement the Google Play Billing Library, and sync the project.
Setup for Testing
Go to the Build tab at the top and Generate a Signed App Bundle.
Once the process is complete, go to the Google Play Console and set up for testing. Go to play.google.com/console.
https://play.google.com/console
On the left, under “Setup,” go to “License testing” and add your testing account.
Then go to the “All apps” page and click on the “Create app” button to create the console for your app.
When you’re in your app’s console page, scroll down until you find the Internal testing tab on the left.
Click on the “Create new release“ button and upload the app bundle.
When the upload is finished, scroll down and give the release a name. Save the changes, click on “Review release,” and then ”Start rollout to Internal testing”.
When the release is created, click on the Testers tab and add the testing account that you added earlier in License Testing.
The next step we need to do to, is to have an emulator that supports Google Play. Open the Android Virtual Device Manager.
If your emulators do not have the Play Store icon next to it, you’ll need to create one that does.
Click on the "Create Virtual Device..." button and select the emulator with the Play Store icon.
Opt-in as a Tester
Start the emulator.
The last step we need to do is to opt-in as a tester.
Click on the ”Copy Link.”
Open the Chrome app on the Emulator. Paste the link in the address bar and then accept the invite to test the app.
Adding In-App Products
To add IN-APP products to your app, go to your app’s console page and scroll down until you see the Monetize section on the left.
Click on the “Create product” button on the right.
The Product ID is a unique name for the product. It cannot be changed or reused in another item once it is created.
The name and description are used to describe the item so users would know what they’ll be getting.
For the price, click on “Set price” and enter a price for the item.
Click on “Apply prices,” “Save,” and then “Activate“ to complete the process.
If we go back to the In-app products page, the new item should be there.
Repeat the steps one more time so you’ll have at least 2 products for this tutorial.
Displaying the Items
Now that we have some items, let’s see how we can display in our app.
Now that we have our BillingClient, create a method call connectToGooglePlayBilling().
It takes in a BillingClientStateListener that is used to check if we have connected to the Google Play Billing System.
It is advisable that we restart the connection if we have been disconnected. Call the connectToGooglePlayBilling() method inside the onBillingServiceDisconnected() callback to reconnect.
The onBillingSetupFinished() callback is used to let us know what the current connection state we’re in. If the response code we received from the billingResult object is OK, it means we have connected to the Google Play Billing System.
To get the products that we have added in the Google Play Console, create a method call getProductDetails() and then call it inside the onBillingSetupFinished() callback.
Inside the getProductDetails() method, create a List call productIds and add the product id for each product you have in the Google Play Console.
Once you have the list of products ids, call querySkuDetailsAsync() from the billingClient to actually get the product information.
billingClient.querySkuDetailsAsync()
It takes 2 arguments, the first asks for a SkuDetailsParams.
Call setSkusList() to add the list and call setType() to set the type.
Then insert the query object into the querySkuDetailsAsync() method.
Now that we retrieved the products’ information we can display it so users can see it.
Rename the TextView id to itemName and the button to itemPrice.
Go back to the MainActivity file. In the SkuDetailsReponse() callback, create a reference to the TextView and Button.
Since we only have 1 item, create a single SkuDetails variable and get the first item in the list. Then set the text of the TextView by getting the title and the Button by getting the price.
If we run the app, we should see the item.
Launching the Purchase Flow
Now that we have a way for users to see the item. We want them to be able to purchase it.
We want to launch the Purchase Flow UI so users can choose how to pay when they click on the button.
Use the newBuilder() and build() methods from BillingFlowParams to create the one.
If we run the app, and click on the item, a purchase flow UI should come up.
Verifying the Purchase with Back-end
Now let’s see how we can verify the purchase when the user pays for the item.
First make sure that the there was a successful purchase. Check if we got an OK response code and then check if the purchase list is not empty inside the onPurchasesUpdated() callback.
if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK &&
To verify if the purchases are real requires 2 steps.
The second step is to verify the purchase using a back-end server.
Begin by creating a Cloud Functions project.
Creating a Cloud Functions Project
Go to console.firebase.google.com. Sign in with your Google account and create a project. If you do not have a Google account, go to accounts.google.com/signup to create an account and then go back to Firebase.
console.firebase.google.com
accounts.google.com/signup
Once you have created a project, make sure you have node and the firebase-tools installed on your computer.
node -v
firebase --version
If you do not have them installed, go to nodejs.org and follow the steps to install node.
nodejs.org
For firebase-tools, run npm install -g firebase-tools after you have node installed.
npm install -g firebase-tools
When you have node and firebase-tools installed, create a folder where it is easy to locate. Open a terminal for that directory and log into firebase.
firebase login
Afterwards, initialize Firebase Cloud Functions using the firebase init command.
firebase init
Select the Firebase project you have for the app and continue.
Once Cloud Functions is set, open the project in a code editor. Expand the functions folder and go to the index.js file.
Type exports, then use the dot operator to name the function and assign a request handler function to it.
Now that we have the purchase information in a JSON object, we need to connect to Firestore and check if the token was used or not.
Inside the validate function, create an instance of Firestore by taking the admin object and calling the firestore() function.
Result represents the document that was retrieve from Firestore. We can use the exists property to check if there was a document with the same purchase token.
If there is, send a the purchase information back to let the app know that it was not a valid purchase token.
This is all we have to do to validate the purchase.
firebase deploy --only functions
Make sure your Firebase project is upgraded to the Blaze plan before executing the command or you will not be able to deploy the function.
Once the deployment is completed, go to the Firebase console. In the Functions tab, you should see the function in the system.
Copy the Request URL for the function, and paste it inside your Android project so we have it. We’ll need to use it to send data back and forth between the server and the app.
The idea is to call the function in the server using the Request URL, and when the server is done doing whatever it needs, it’ll send message back to let us know whether or not the purchase was valid.
Implementing Volley
To communicate with Cloud Functions using the Request URL, go to the app’s build gradle file and implement Volley.
Go back to the MainActivity file and create a new method call verifyPurchase() with a purchase object parameter.
Inside the method create a String variable for the Request URL.
String requestUrl = "https://us-central1-playbillingtutorial.cloudfunctions.net/verifyPurchases"
If we take a look at Cloud Functions, we are trying to get the purchaseToken, purchaseTime, and orderId from an object call query.
To add data to the query object, we need to add a question mark (?) symbol at the end of the URL to represent the start of the query parameter. For each set of data, we need to insert a key and value pair and separate each set with a ampersand (&)symbol.
Make sure that the name of each key is identical to what you defined in the JSON object in Cloud Functions.
Now that we have our Request Setup, we need to send it to the server.
Remember to call the verifyPurchase() method inside the onPurchasesUpdated() callback.
If we run the app, and purchase the item, it should be uploaded to Firestore.
Go to the Firebase Console. Change the Firestore rules to true so we can read and write data.
If we run the app, and purchase the item, it should be uploaded to Firestore.
If we try to purchase the item again, we’ll get an error.
Acknowledging the Purchases
Go back to the verifyPurchase() method. Inside the response listener callback, create a JSONObject using the response from the server.
Then use an If statement to check if the isValid property is true. It if is, we can start acknowledging the purchase.
To use acknowledgePurchase(), create a AcknowledgePurchaseParams object using newBuilder() and build() from AcknowledgePurchaseParams.
Next, grab the billingClient and call acknowledgePurchase().
Inside the response listener, check if the result was OK. If it is, we need to put the logic to notify and give the item to the user. For now, we’ll use a Toast message.
If we run the app and purchase the item again, it will get acknowledged. If you are still getting the “You already own this item” error, wait a few minutes for it to reset and try again.
Unlocking the Item
Now let’s see how we can acknowledge consumables. Go back to the getProductDetails() method and replace the old item with a new one.
billingClient.consumeAsync()
Inside the response listener, check if the result was OK. If it is, we need to put the logic to notify and give the item to the user. For now, we’ll use a Toast message again.
If we run the app, we can purchase the item multiple times.
Handling Purchases That Were Made While the App is Closed
This is all we need to do to verify the purchases. But as best practice, we should not rely solely on the onPurchasesUpdated() callback. This is because the callback will only be available when the app is opened.
Use the BillingResult object and check if the status was OK. Inside the if statement, iterate through all the purchases that were made and check if the state was purchased and not yet acknowledged. If it was not acknowledged, we want to verify the purchase.
That is all for this tutorial. If you find this helpful, please give it a like, share, and subscribe to support the channel.