Tutorial: How to Implement In-app Billing in Android – Part 2

Part 1 of this article was my guide on how to get started with in-app purchases in Android. It was published in July 2014. Finally, here is part 2.

Part 1 covered the operational side of things: defining in-app products, application keys, etc. In this article, I will offer some suggestions on how to adapt the TrivialDrive code for your own app. The code provided with TrivialDrive is very well structured and we all can learn a lot from it. Most of the hard work is done in classes inside the util package of TrivialDrive. Without that package, the MainActivity would be much more difficult. The changes I suggest below are refinements on what is in the MainActivity provided by the Google team.

For my own work, I made the transition from the in-app purchases of the TrivialDrive sample app (Figure 1, left) to the purchases of my space war app (Figure 2, right).



Adapting the Code for Your Own App

In this section, I will describe how I have adapted the code to an app I am working on. I will use the TrivialDrive app code to illustrate what I did, rather than using code from my space war app. The advantage of that is that I can provide the source code of a completely working app for you to try out and work with. If you want to have that code installed while you work, download the source code from here: zip file of finished sample for part 2.

Assuming you have gone through Part 1, you have a working copy of the TrivialDrive app. Make a copy of the whole app and make sure the copy compiles cleanly. Check the project preferences and be sure you are using a new version of Android (5 or higher).

The sample code that I provide starts with a package name of “com.wglxy.example.trivialdrive2”. Rename the project package. You need to do this because every app that gets published must have a unique package name. Then go into the AndroidManifest.xml file and change the package there too. You will also have to fix the line in MainActivity that imports the R class. Change that line so it gets R from your new package. (Note: the screenshots I include below are from Eclipse. I have not yet switched over to Android Studio.)


I restructured the code in anticipation of building an app that might have more than one activity that deals with in-app products. I added several extra classes. One is a Constants class and another is a superclass (IabActivity) where I put code needed by all of the activities that do in-app billing transactions.

Constants are in a Constants.java file. The values are the id strings that you define in the Google Play Developer Console, in the section for in-app products. The values for this demo app are shown below. For your own app, you would add constants for your own set of products.

// In-app billing constants

// SKUs for our products: the premium upgrade (non-consumable)
// and gas (consumable)
public static final String SKU_PREMIUM = "premium2";
public static final String SKU_GAS = "gas2";

// SKU for our subscription (infinite gas)
public static final String SKU_INFINITE_GAS = "infinite_gas2";

Class IabActivity is a new class I added. I added it so I would have one place for the new code I added to support in-app billing. Because IAB code makes requests asynchronously, it is fairly complicated. If your app has only a single activity or you have only one activity where all in-app purchases are made, you won’t necessarily need a superclass.  I chose to add a subclass to reduce the amount of duplicate code in the subclasses. (That’s what I meant when I said earlier that my changes are a refinement of the original code.)

IabActivity bridges the gap between the generic, reusable code provided in the trivialdrive2.util package. IabActivity holds constants, variables, and methods that are specific to the application.

Let’s have a look at the different sections of the IabActivity class.

Variables Section of IabActivity

// Does the user have the premium upgrade?
 protected boolean mIsPremium = false;

// Does the user have an active subscription to the 
// infinite gas plan?
 protected boolean mSubscribedToInfiniteGas = false;

These variables indicate which items have been purchased. In TrivialDrive, you can upgrade your car to use premium gas. Another one of the purchases you can make is a subscription for unlimited gas. The regular gas that you purchase is a consumable item. That means that its purchase affects the state of the app as soon as the purchase  goes through. The state variables related to regular gas are in MainActivity.

Listeners section of IabActivity

A lot of work gets done inside the IabHelper class in the util package of TrivialDrive. For that to work, we need some Listener objects.

 * mGotInventoryListener - Listener that's called when we finish 
 * querying the items and subscriptions we own.
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = 
   new IabHelper.QueryInventoryFinishedListener() {
      public void onQueryInventoryFinished
                   (IabResult result, Inventory inventory) {
 * mConsumeFinishedListener - Listener that's called when 
 * consumption of the purchase item finishes
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = 
   new IabHelper.OnConsumeFinishedListener() {
      public void onConsumeFinished
                     (Purchase purchase, IabResult result) {
 * mPurchaseFinishedListener - Listener that's called when a 
 * purchase is finished
   mPurchaseFinishedListener = 
      new IabHelper.OnIabPurchaseFinishedListener() {
         public void onIabPurchaseFinished 
                       (IabResult result, Purchase purchase) {

Most of the work associated with an in-app purchase is done by code in the util package. Asynchronous calls are made there. The listeners defined in the Listeners section define the callback methods for those calls. I will say more about these listeners below.

IabHelper variable in IabActivity

  * This variable holds the value of an IabHelper object.
private IabHelper pIabHelper;

The most important class in the TrivialDrive util package is IabHelper. As stated in its comment section, IabHelper “provides convenience methods for inapp billing. You can create one instance of this class for your application and use it to process inapp billing operations”. You will see how that is done below.

Methods section of IabActivity

There are quite a few methods in the IabActivity superclass. Some of them are there to support the activity lifecycle and to make in-app purchases. Others are just there for convenience. Subclasses can make use of them and the Listener methods use them too.

// Methods for the Activity lifecycle
@Override protected void onActivityResult 
             (int requestCode, int resultCode, Intent data);
@Override protected void onCreate(Bundle savedInstanceState);
@Override public void onDestroy ();

// Methods for in-app purchases
protected void launchInAppPurchaseFlow 
                 (Activity a, String sku);
protected void launchSubscriptionPurchaseFlow 
                 (Activity a, String sku);
protected void launchInAppPurchaseFlow 
                 (Activity a, String sku, String itemType);
void onIabPurchaseFailed (IabHelper h, int errorNum);
boolean verifyDeveloperPayload(Purchase p);
protected void setupIabHelper 
                (final boolean showListedSkus, 
                 final boolean showErrors);
// Methods to help with setup and consuming items. 
void onIabConsumeItemFailed (IabHelper h);
void onIabConsumeItemSucceeded 
       (IabHelper h, Purchase purchase, IabResult result);
void onIabSetupFailed (IabHelper h);
void onIabSetupSucceeded 
       (IabHelper h, IabResult result, Inventory inventory);
// Miscellaneous methods
protected void alert(String message);
protected void complain(String message);
public void toast (int stringId);
public void toast (String msg);

Rather than explain all of these on their own, let’s take a look at the MainActivity class and see how these superclass methods are used.

Handling Purchases in MainActivity

In the TrivialDrive sample app, there is a single class, MainActivity, which uses in-app billing code. It can serve as a model for how purchases can be done in an app.

A purchase in TrvialDrive starts when the user touches one of the purchase buttons. The three buttons are “Buy Gas”, “Upgrade My Car”, and “Get Infinite Gas”. They are shown in the figure below. For those buttons to work, there is a fair amount of set up work that has to be done. There is code to handle the button clicks and to react to the asynchronous calls, which are made by the IabHelper class in the util package and by the IabActivity class.


When the user touches a button, like the “Buy Gas” button, a call is made to a method that is defined in class IabActivity.

launchInAppPurchaseFlow (this, SKU_GAS);

The value of the util package, the IabHelper class, and the IabActivity class is obvious. Look how simple the code is. That’s an indication of a good design. To understand how it works, we will look at the method and at the set up needed for it to work.

Let’s start with the onCreate method of the MainActivity. Method onCreate is a good place to get everything set up and check to see what purchases have already been made.

@Override public void onCreate(Bundle savedInstanceState) {

 // Start setup of in-app billing.
 // (Note that the work is done using methods in superclass
 // IabActivity. The original code had all the code here.)
 setupIabHelper (true, true);

 // Set a variable for convenient access
 // to the iab helper object.
 mHelper = getIabHelper ();

 // load game data
 updateUi ();

 // enable debug logging
 // (For a production application, you would set this to false).

The onCreate method looks pretty simple, but that is because most of the work is being done inside the setupIabHelper method of IabActivity. If you look inside IabActivity’s setupIabHelper method (next figure below), you will see that it creates an IabHelper object and then uses it to set up connections to a service that is running to handle in-app billing. When set up completes, note how the listener builds up a list of products to check on.

protected void setupIabHelper (final boolean showListedSkus, 
                               final boolean showErrors) {

setShowIabErrors (showErrors);
try {

 String base64EncodedPublicKey 
         = "--- YOUR APPLICATION KEY GOES HERE ---";

 // Create the helper, passing it our context
 // and the public key to verify signatures with
 IabHelper ih = new IabHelper(this, base64EncodedPublicKey);
 setIabHelper (ih); // sets pIabHelper

 // Start setup. This is asynchronous.
 ih.startSetup(new IabHelper.OnIabSetupFinishedListener() {
 public void onIabSetupFinished(IabResult result) {
  if (!result.isSuccess()) {
   if (pShowIabErrors)
    complain ("Problem setting up in-app billing: " + result);
   onIabSetupFailed (getIabHelper ());

  // IAB is fully set up. Get an inventory of stuff we own.
  // Build up a list of the SKUs so other parts of
  // of the app can get information on prices.
  ArrayList<String> skusToBeListed = null;
  if (showListedSkus) {
   skusToBeListed = new ArrayList<String> ();
   skusToBeListed.add (SKU_PREMIUM);
   skusToBeListed.add (SKU_GAS);
   skusToBeListed.add (SKU_INFINITE_GAS);
              (true, skusToBeListed, mGotInventoryListener);

} catch (Throwable ex) {



Notice the asynchronous query for information at the end. That method expects a listener for the last argument. We have one already set up in mGotInventoryListener. If you read the code for that listener, you will see that basically all it is doing is checking the result and calling either onIabSetupSucceeded or onIabSetupFailed. It is in method onIabSetupSucceeded (in IabActivity) where the checks are made.

The implementation of onIabSucceeded in IabActivity is shown below. This is the code in the superclass, so all subclasses benefit from the standard handling of set up. See how it checks on each of the three products in the app.  It takes immediate action for premium and infinite gas. Those two products are not consumable, which means users only have to purchase them one time. Once purchased, the user has them forever. For that to work, the code in onCreate has to check to if they have already been purchased. For those two products, it sets two global variables.

From class IabActivity:

void onIabSetupSucceeded (IabHelper h, 
                          IabResult result, Inventory inventory) {
 // Check for the in-app purchases of items.
 // (Do this here in the superclass so we write it only once.
 // Note that several global variables are set here.)

 // Do we have the premium upgrade?
 Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM);
 mIsPremium = (premiumPurchase != null 
               && verifyDeveloperPayload(premiumPurchase));

 // Do we have the infinite gas plan?
 Purchase infiniteGasPurchase = 
 mSubscribedToInfiniteGas = (infiniteGasPurchase != null &&

 // Check for gas delivery
 // -- if we own gas, we should fill up the tank immediately
 Purchase gasPurchase = inventory.getPurchase(SKU_GAS);
 if (gasPurchase != null 
     && verifyDeveloperPayload(gasPurchase)) {
    pIabHelper.consumeAsync (gasPurchase, 


The third item, regular gas, is consumable. That means it can be used up and the user might have to purchase it multiple times, over the course of the game or sessions that a user has with the app. Since the gas item is consumable, the onCreate code initiates the operation to consume the item. That’s another asynchronous call that goes through the IabHelper object.

It’s not shown here, but if you check the definition of mConsumeFinishedListener, you will see how a successful call results in a callback to the onIabConsumeItemSucceeded method. I did it that way so the MainActivity, which is a subclass of IabActivity, could do its own special handling for consuming that item. That is shown below.

In MainActivity:

 * Called when consumption of a purchase item succeeds.
 * SKU_GAS is the only consumable item. 
 * So this is the place where the tank is filled.

void onIabConsumeItemSucceeded 
       (IabHelper h, Purchase purchase, IabResult result) {
 super.onIabConsumeItemSucceeded (h, purchase, result);

 // Update the state of the app and the ui
 // to show the item we purchased and consumed.
 String purchaseSku = purchase.getSku (); 
 if (purchaseSku.equals(SKU_GAS)) {
 if (result.isSuccess()) {
    // successfully consumed, so we apply the effects 
    // of the item in our game world's logic.
    // That means filling the gas tank a bit.
    mTank = mTank == TANK_MAX ? TANK_MAX : mTank + 1;
    alert ("You filled 1/4 tank. Your tank is now "
           + String.valueOf(mTank) + "/4 full!");
 } else {
   complain("Error while consuming regular gas: " + result);



The tank is filled up some and then the user interface is updated.

(I have to admit that as I write this explanation now that I am not completely sure that the way I have broken this code down is ideal. In my real app, it worked out pretty well to have the extra methods (like onIabConsumeItemSucceeded). Anyway, it’s always a good thing to reflect on the code you build and be open to restructuring it. What I was after was more common code in a superclass. That’s a good thing if it saves you work in your subclasses. So, that is something for you to think about in your own app.)

Initiating Purchases in MainActivity

Let’s go back to the point where a purchase starts and examine it in more detail.  A purchase begins when the user touches one of the purchase buttons.


For the “Buy Gas” the following code in MainActivity runs:

public void onBuyGasButtonClicked(View arg0) {
 if (mTank >= TANK_MAX) {
 complain("Your tank is full. Drive around a bit!");

 // Set up to show and wait screen.
 // Launch the gas purchase UI flow.
 launchInAppPurchaseFlow (this, SKU_GAS);


It changes the user interface to show the wait screen, and then it launches the in-app purchase flow, using method launchInAppPurchaseFlow in superclass IabActivity.

protected void launchInAppPurchaseFlow (Activity a, String sku) {
 launchInAppPurchaseFlow (a, sku, 

protected void launchInAppPurchaseFlow 
                 (Activity a, String sku, String itemType) {
 IabHelper h = getIabHelper ();
 if (h != null) {
    h.launchPurchaseFlow (a, sku, itemType, RC_PURCHASE_REQUEST,
                          mPurchaseFinishedListener, "");

Notice that the real work gets done in IabHelper, the class defined in the util package. Basically, it is setting up an Intent so an activity can be started to do the work. The return code RC_PURCHASE_REQUEST is defined in IabActivity, as is the onActivityResult method. The onActivityResult method in IabActivity runs when the second activity completes. As you see below, it lets the IabHelper do the work.

@Override protected void onActivityResult 
                           (int requestCode, 
                            int resultCode, Intent data) {
 switch (requestCode) {

 // Handle the purchase request here.
 if (pIabHelper != null) {
  // The interesting work is done in IabHelper class.
  // See its handleActivityResult method.
  if (!pIabHelper.handleActivityResult 
                   (requestCode, resultCode, data)) {
   // Not handled by the helper, so let other code do it.
   super.onActivityResult (requestCode, resultCode, data);


So much goes on in IabHelper. That’s a good thing for you me. We are left with a small number of places in our own activities where we have to react to in-app purchase requests. Also note that onActivityResult is defined in IabActivity rather than MainActivity. In an app with more than one activity doing in-app purchase calls, that works out well. There only has to be the one definition because the code does not change. MainActivity, and any future activities, are a little easier to implement and understand.

If you work through the rest of the code (below), you will see how two more of the handlers defined in IabActivity initiate more asynchronous calls and then make callbacks to some success and failure methods that are easily implemented in MainActivity. The two methods are onConsumeItemSucceeded and onConsumeItemFailed.

   = new IabHelper.OnIabPurchaseFinishedListener() {
 public void onIabPurchaseFinished 
              (IabResult result, Purchase purchase) {
   if (purchase.getSku().equals (SKU_PREMIUM)) {
     pIabHelper.consumeAsync (purchase, mConsumeFinishedListener);
   } else if (purchase.getSku().equals (SKU_GAS)) {
     pIabHelper.consumeAsync (purchase, mConsumeFinishedListener);
   } else if (purchase.getSku().equals (SKU_INFINITE_GAS)) {
     pIabHelper.consumeAsync (purchase, mConsumeFinishedListener);

   = new IabHelper.OnConsumeFinishedListener() {
 public void onConsumeFinished
  (Purchase purchase, IabResult result) {
 if (result.isSuccess ()) {
  synchronized (pIabHelper) {
   onIabConsumeItemSucceeded (pIabHelper, purchase, result);
 } else {
  complain ("Did not handle purchase: " 
            + purchase + " result: " + result);
  onIabConsumeItemFailed (pIabHelper);

The other two buttons are not much different than what I have shown for the “Buy Gas” button. Work through those, too, so you will have a complete understanding of consumable and non-consumable in-app products.

Additional Changes Needed for Your Own App

I have already talked about your own products sku strings. Once you have defined those in the Android Developer Console, you would update those in the Constants class.

In method setupIabHelper of IabActivity, there is a line you have to change so the code knows the application key for your app. Be sure to do that. Without it, your app will not be able to tie your product sku strings with the information you entered in the Android Developer Console.

protected void setupIabHelper
 (final boolean showListedSkus, final boolean showErrors) {

 String base64EncodedPublicKey = "YOUR APPLICATION KEY GOES HERE";


The image below (from Part 1 of this article) shows where to look for the public key. It is the very long string that is blurred out and highlighted with the orange text.


There is a method in the TrivialDrive sample code named “verifyDeveloperPayload”. It is there to ensure that all purchase attempts are valid. I have not implemented this method for my app, but at some point, I should, and you should too. Very good guidance has been provided by the author of the sample app, Bruno Oliveira.

boolean verifyDeveloperPayload(Purchase p) {

String payload = p.getDeveloperPayload();

 * TODO: verify that the developer payload of the purchase 
 * is correct. It will be
 * the same one that you sent when initiating the purchase.
 * WARNING: Locally generating a random string when 
 * starting a purchase and
 * verifying it here might seem like a good approach, 
 * but this will fail in the
 * case where the user purchases an item on one device 
 * and then uses your app on
 * a different device, because on the other device 
 * you will not have access to the
 * random string you originally generated.
 * So a good developer payload has these characteristics:
 * 1. If two different users purchase an item, 
 * the payload is different between them,
 * so that one user's purchase can't be replayed to another user.
 * 2. The payload must be such that you can verify it even 
 * when the app wasn't the
 * one who initiated the purchase flow 
 * (so that items purchased by the user on
 * one device work on other devices owned by the user).
 * Using your own server to store and verify developer 
 * payloads across app installations is recommended.

return true;

Source Code

The source code for the modified TrivialDrive app can be found at the wglxy.com website. Click here: zip file of finished sample for part 2.


The sample TrivialDrive app provided by Google is very well done. There is so much to learn from it. Thanks go to Bruno Oliveira from Google.


How To Implement In-App Billing in Android – Part 1 – the first part of my blog article. Be sure to read it for details about setting up you in-app products, packaging your app, and release your app.

Preparing Your In-App Billing Application – the primary reference with the TrivialDrive example from the Google team.

Android Fragment for an Item in a Store – A sample app that shows how to build a store listing for products. Also see the follow-up article on store items.

Double Star app – This is my space war app. It includes in-app products. If you’d to see how all the pieces for in-app billing came together, please try the game.

About Bill Lahti

Bill Lahti is a software engineer building mobile applications and knowledge management solutions. Two of his interests are writing for this blog and building Android apps, with strategy games being an area of particular interest.
This entry was posted in Android and tagged , , , , . Bookmark the permalink.

12 Responses to Tutorial: How to Implement In-app Billing in Android – Part 2

  1. Pingback: Tutorial: How to Implement In-app Billing in Android – Part 1 | More Is Not Always Better

  2. Arun Badole says:

    Thanks for this nice tutorial.

  3. doz says:

    Nice Tutorial. Thanks
    Please, I have a very important question. I am a little new to all this and I would like to know, what happens when the activity is loaded in the absence of network? Or are yo assuming that there must always be network when its loaded? If not, how then does the activity do all the server connections in the onCreate method? Please I need your answer urgently.

    • Bill Lahti says:

      The demo program originated with the Android team. The code handles errors. As you study the code, you will see various places (e.g. onIabSetupFailed) that do something reasonable when errors occur. Sometimes you see very nice messages, like the following image:
      no connection message

      Other times, the messages are not as nice, but remember that this is a demo program. As you build your app, you should make sure you account for all the ways it can fail, and then make sure the error handling you provide helps your users understand what went wrong.

      • dosky0 says:

        Thanks for the reply.
        I understand what you mean. But, when the activity is initially loaded, does it need Internet? Or do you need to press the buy button before it does?

      • Bill Lahti says:

        You can structure your app one of two ways: (1) allow the user to do something, even if the internet is not available; (2) force the user to connect first before doing anything. I am finding for my work, and I think most people would agree, that it’s best to allow your user to do as much useful work (or game play) as they can when they are not connected. Wait until they take an action that requires the internet before you try to connect. That is particularly important with in-app purchases, which are, for the most part, optional.

        This particular demo program follows checks to see if it has a connection when the user presses the “buy gas” button. It is a very simple example, but it shows best practice for checking for connection problems and informing the user when there are problems. With that as a guide, you should be able to do a good job with your own app.

  4. Alex says:

    Hi, great tut, very helpful! Thank you very much! Just one question – I am getting the message “cannot resolve method update(Ui);” which used in mainactivity several times. Do I miss something? Even Google didnt help.

    • Bill Lahti says:

      All the calls in the example look like “updateUi ()”. Your message text is different: “update (Ui)”. Does that explain the error? Or did you mistype the message text?
      Are you working with the original sample code or are you in your own code now? You might have forgotten to defined “updateUi”.

      • Alex says:

        Thanks for your reply. Yeah, updateUi(); I got it right in the code but mispelled in my question above. Where is this method defined?

      • Bill Lahti says:

        Method updateUi is defined in MainActivity. When you write your app, you might have one or more classes that are like MainActivity. Anything that changes on the screen as a result of starting or completing an in-app purchase would be changed in updateUi.

  5. Kieran says:

    i’m completely confused about this. sorry any chance you can explain the .R references in google’s Trivial Drive. what is it and am i meant to change it?
    in your example trivialdrive2 you import “import com.wglxy.example.trivialdrive2.R;” it but i cant see that in the file explorer view

    • Bill Lahti says:

      The R class is generated for you automatically as Android processes the resources files in folders like res/values and res/layout. In the example app, the R references are to ids defined in layout files, drawable objects, and strings. The two import lines in MainActivity and IabActivity are actually not needed since the R resources are already accessible within the package. I should have removed them. Remove them and you should that the sample app classes still compile.

      For your own app, you will have your own R class generated for you for the layouts, drawables, etc. that you define.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s