Android In-App-Billing Quick and Simple guide
If you are looking for a simple, quick and painless guide to implement in app purchase in your Android app, you have found the right place.
It is amazing how some key features in Android development are as important as annoying to implement. Even more annoying when the set up guides out there are lacking simplicity or common sense. Take that guide for example:

Thanks! But what if I want to sell… Hmmm… A hat?… Or no, guess what! A premium upgrade! Crazy idea I know!
Great for testing fake purchases, but nothing on buying your own specific products that come with a unique ID! I guess it’s fun for the reader to figure this out.
This one is better. Buy why is the author only giving portions of the code to add? And where should it be added? It’s like “hey, I know how to do it, so I will tell you 75% of it, because I am sure the other 25% will bring you a lot of joy and happiness to figure out yourself. Oh and also I love to change method names from the official Google doc. So when you use both code it’s a real delight“. And why several activities when you can only deal with one for your test?
I guess I am just being sarcastic. These guys are doing a good job at helping out the community. So kudos to them.
Of course the “official” guide from Google is more than 4 pages long. Of course. But guess what, it’s the best one out there though…
That’s why I wanted to give you a really simple, exhaustive and quick android in app billing, I hope it helps. I am assuming you use Eclipse. Also this guide only covers managed iap (selling an upgrade to get rid of ads for example, a very common micro transaction). Unmanaged iap is not very different, you only have to consume products and that’s super simple.
0: In app billing sample application
It is always good to have a proper example to mess with. It’s called TriviaDrive, it’s made by Google and it’s a good example to understand the basics, and to get some util files to copy in Eclipse (see step 8). Of course Google likes to make it complicated, by downloading the stuff through the Eclipse SDK manager. Perfect to loose the folder on your drive… What’s wrong with a good old zip file download?
Download the in app purchase test app here: TrivialDrive
1: Librairy
Add the Google lib into your src files. The official doc is not clear, so here is a great and simple guide to do it quickly without pain. Check this cool article out.
Your folder structure in Exlipse should look like this:
2: Product
Go to your Google Play console, upload your apk, but don’t publish the app. In the section In App Products, add a product with a specific ID (remember it for step 4). Put whatever you want for title and description, you can change it later. Save it and set it as active
3: Permission
Add this in your manifest:
<uses-permission android:name="com.android.vending.BILLING" />
4: Variables
Before the onCreate of your main activity, add these:
// Debug tag, for logging static final String TAG = "<name of your app or activity>"; // SKUs for our products: the premium upgrade (non-consumable) static final String SKU_PREMIUM = "<id of your product>"; // Does the user have the premium upgrade? boolean mIsPremium = false; // (arbitrary) request code for the purchase flow static final int RC_REQUEST = <whatever integer>; // The helper object IabHelper mHelper;
5: onCreate {}
In the onCreate of your main activity, add the following:
String base64EncodedPublicKey = "<your key>" you can find it in your Google Play console, in the API section. //It is recommended to add more security than just pasting it in your source code; mHelper = new IabHelper(this, base64EncodedPublicKey); Log.d(TAG, "Starting setup."); mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { public void onIabSetupFinished(IabResult result) { Log.d(TAG, "Setup finished."); if (!result.isSuccess()) { // Oh noes, there was a problem. Log.d(TAG, "Problem setting up In-app Billing: " + result); } // Hooray, IAB is fully set up! mHelper.queryInventoryAsync(mGotInventoryListener); } });
6: After the onCreate
After your onCreate, add this:
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() { public void onQueryInventoryFinished(IabResult result, Inventory inventory) { Log.d(TAG, "Query inventory finished."); if (result.isFailure()) { Log.d(TAG, "Failed to query inventory: " + result); return; } else { Log.d(TAG, "Query inventory was successful."); // does the user have the premium upgrade? mIsPremium = inventory.hasPurchase(SKU_PREMIUM); // update UI accordingly Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM")); } Log.d(TAG, "Initial inventory query finished; enabling main UI."); } }; IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() { public void onIabPurchaseFinished(IabResult result, Purchase purchase) { if (result.isFailure()) { Log.d(TAG, "Error purchasing: " + result); return; } else if (purchase.getSku().equals(SKU_PREMIUM)) { // give user access to premium content and update the UI } } }; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data); // Pass on the activity result to the helper for handling if (!mHelper.handleActivityResult(requestCode, resultCode, data)) { super.onActivityResult(requestCode, resultCode, data); } else { Log.d(TAG, "onActivityResult handled by IABUtil."); } }
7: onDestroy
Unbind the service ondestroy:
@Override public void onDestroy() { super.onDestroy(); if (mHelper != null) mHelper.dispose(); mHelper = null; }
8: Util files
At this point you must have a lot of red in your code. That’s fine, that’s because you have not added the util files yet. These are helper files you don’t need to modify. In the sample app I have provided in the step 0, go to the folder TrivialDrive\src\com\example\android\trivialdrivesample, copy the bunch of folders and paste them into your src/util folder. Make sure you edit the package names correctly according to your path.
You’re done. Just wait a couple of hours for Google Play to integrate the last version of your apk in its server.
Please leave a comment if there is a step missing, I’ll update my post. Also, sorry for the presentation, I know I should add a plugin to auto detect the code. I just didn’t take the time to do it :b
Once again, sorry for the rant against other tutorials. Most likely they are just trying do help you guys out there like I am. But sometimes, you end up on a tutorial where clearly the author hides some portions of the code just because he wants to “educate” readers to learn by themselves, go to amazon and buy a freakin 400 pages java book, and spend the week end having fun playing with the Eclipse settings. Well guess what, the Internet is based on shortcuts. That’s why I hope you’ll find this post useful.
Best tutorial ever
pretty awesome, amazing, and +1 for the writing style 🙂
I like the tutorial but i was having a little trouble with the UI updating and allowing my buttons to become enabled, i put the enabled method in the section where it said update ui here but its not updating with the android.test.purchased SKU i was wondering if maybe you can help me out a little? show me what im doing wrong?
At Last! Great information
Yup, that’ll do it. You have my apecrpiation.
Thanks for this. There is a repo for TrivialDrive, however, and it has bug fixes newer than your zip file.
https://code.google.com/p/marketbilling/source/browse/#git%2Fv3
Thank you for your demonstration of this topic. It is really helpful. Thank you very much 🙂
At last, somnoee who knows where to find the beef
Nice tutorial.
I’m looking for a tutorial that teach us how to dynamically download content from our sites after users purchase content instead of have them in the application itself.
Do you plan to make such kind of tutorial or do you know where can I find one?
Regards.
Hi Marcio, I am not sure that would go along the Play Store guidelines. User should be informed that content will be downloaded from a third party site before the transaction is made.