Implementing In-App Billing for Android

Google provides an easy to use library that is able to handle the payment and querying tasks and shields away lots of the complexity behind it. In this article I present how I implemented the In-App billing functionality for my Live Wallpaper and how I solved the problems that I faced.

To be able to offer an In-App product, it has to be configured within the Play Store:

Screen Shot 2016-01-20 at 05.38.01

The Buy-Activity

To give the user a chance to buy the in-app product, I created aBuyPremiumActivity. This Activity shows a text that explains what advantages the premium version has, the price of the app and a button to actually buy it:

purchasepage

 

Initializing the In-App Billing API

The first task when starting this Activity is to query the Billing API to return the price for the app. This is done while initializing the API:

The PUBLIC_KEY constant contains the public key for your App you can find in the Google Play Developer Console. Google suggest to split this string, rearrange and recombine it again during runtime to not make it too easy for hackers to extract out your key from just getting the strings out of your APK file.

The SKU_NAME_PREMIUM contains the id that you gave your In-App item in the Google Play Developer Console. But when testing your In-App Payment, you should use the String “android.test.purchased” (or another one of the available static test-SKUs). In these cases, you will always get a predefined response when you buy something in your app. This is really useful when testing your Payment implementation. But note, that later, when you query the products a customer owns, this test flag will not stay for long. I encountered, that after some time this gets reset and the app will think the item has never been bought.

Integrating the In-App Library into the project

The IabHelper class comes from the Google In-App Billing sample project. Together with all the other classes in the same package, it is a powerful helper library when working with In-App Payment. The sample project can be downloaded using the SDK Manager is located in the directory Android-SDK/extras/google/play_billing/samples/TrivialDrive.

When integrating this library into you project, make sure you…

  • Copy the file Android-SDK/extras/google/play_billing/IInAppBillingService.aidlusing the exact same package to your project
  • Copy all the classes under Android-SDK/extras/google/play_billing/samples/TrivialDrive/src/com/example/android/trivialdrivesample/util/* – but here you are free to change the package names.

Of course you need to add the BILLING right to your AndroidManifest.xml file to enable the billing:

Testing Payments

If you are intensive testing your In-App payment, you will want to do the payment lots of times in a row while fixing bugs – no time to wait until the flag gets reset automatically. To be able to buy the in-app item again, you have to consume it. To do so, use the following code:

Replace PACKAGE_NAME in the code above with the package name of your app.

I placed another button next to the “buy me” with this code to easily do a buy / consume / buy / consume flow while testing the payment implementation.

The Purchase Flow

This is how I implemented the buying process:

Don’t forget to cleanup after ourselves when the BuyActivity ends:

Check if the user has bought the In-App Item

So far, this offered a way for the user to see the price and buy our In-App item. Now I have to make sure, that the customer gets a value for his purchase. I have to determine at each start of the application, whether the customer owns the In-App item to decide to run the demo or the premium version of the app.

On a successful purchase flow, I save a flag “premium = true” to the shared preferences to indicate, that the user owns the app. While this may seem sufficient at first, it has several drawbacks:

  • A rooted user can just change the xml file containing the shared preferences data and so switch the app to think its a premium version without paying for it.
  • When a customer switches his phone or reinstalls the app after deleting it, he has lost his premium status although Google still thinks the customer still owns it and refuses a re-buying of the item.

To circumvent these drawbacks, I have to check with Google Play Store each time the app starts whether the customer owns the In-App Item that indicates the premium version of the app. This check is done asynchronously again – it may take up to a second until we get a response. I have to wait for the results before I can show the final User Interface, because which interface is shown depends on the result of the check.

To not block the UI while waiting for the results, I places another Activity in front of all the others. This Activity starts the In-App product check and on its completion, launches the demo or the premium Activity, depending on the results.

After the check is completed, I update the shared preferences value to reflect the correct premium/demo state. The reason is: All other parts of the app can now just use this flag and do not need to bother with the payment API.

Now all the necessary elements for the In-App payment are implemented. Users can buy the In-App Item that represents the premium version of the app. On every start of the app (in my case: the Settings Dialog), Google is asked for the products the user owns and the premium state of the app is set accordingly. The state is copied over to a shared preferences entry to let all other parts of the App access this information easily.

Should the customer decide to give back his purchase, the ownership of the customer for the InApp item will vanish, and so the premium state of the app on its next launch.

I hope this post helped you in implementing your own In-App Billing implementation. If you have any questions or comments, I’d be glad if you’d share this article or leave a message in the comments section below. (from here)

Comments are closed, but trackbacks and pingbacks are open.