The Startup
Published in

The Startup

Some Things We Learned While Implementing in-app Purchase in Android

We looked at our apps and found some cool features that would be good to monetize for people who want something extra, without affecting our app normal functionality. So we decided to add in-app purchases in our apps and with that, we learned some things, the hard way (by looking up stuff on stack overflow and weird forums).

To show you some of the challenges we’ll use Habit Coach as an example, which is available in Google Play if you want to check it out and leave us feedback.

You need to add licensed testers

This took some time to figure out. Everything was put into place, Billing was set up according to the docs, but when we tried to test it this happened:

And with some errors in the logcat:

W/BillingHelper: Couldn’t find purchase lists, trying to find single data. W/BillingHelper: Received a bad purchase data.
W/BillingHelper: Couldn’t find single purchase data as well.

After some hours of searching why we got this error, turns out you need to add the email you are signed in on the Google Play app from your phone to the licensed testers list. And you can do that in the Google Play Console. On the page with all apps you can find Settings ->License Testing. Here you add the email address, press Enter, and save your changes.

Invalidating a purchase to test it again

This applies to products that the user can buy only once. This means that you don’t consume the purchase. More on consumption later.

In this case, after you make a purchase, if you will try to purchase it again you will receive an error saying that you already own this item.

How do you get past that?

You refund the purchase from Google Play Console. But there’s a catch. When you refund it you will have to remove the entitlement for that product, or the user will still get the error that it already owns the item.

For that, you go into Order Management from Google Play Console main menu and select the Order you just made from your app. (If it’s a test order it will say Test: in front of the product name). Then in order details, you click refund and a screen with some options for a refund like the one below will appear.

In this screen, make sure to check the Remove entitlement box, so the user will no longer own the product in his Google Account. After you click refund you will be able to make a purchase again for the given product.

Handling products that user can buy more than once

In some cases, you might want to have products that the user can buy more than once. For example, in our app, the user can buy multiple routines from the coach. So we need to handle that.

To make this work, the trick is to consume the product after the purchase. This way, if the product is consumed user will be able to buy it again.

And another cool thing about that is that you can test it how many times you want without doing the refund bit from earlier.

For that, you can use the consumeAsync() method from the billing API, which also handles the acknowledgment automatically. According to the docs:

Consumes a given in-app product. Consuming can only be done on an item that’s owned, and as a result of consumption, the user will no longer own it.

Consumption is done asynchronously and the listener receives the callback specified upon completion.

Warning! All purchases require acknowledgement. Failure to acknowledge a purchase will result in that purchase being refunded. For one-time products ensure you are using this method which acts as an implicit acknowledgement


These are the thing that made us struggle while integrating the Billing API, but in the end we made it work. If you know any tricky bits while integrating in-app purchase leave a comment below and share this with others if you liked it.




Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +756K followers.

Recommended from Medium

How to delete a record from Firestore on a RecylerView left/right swipe?

How I Wrote an Intelligent RecyclerView Adapter with Effective Searching

Top 5 Flutter Packages that you must know

Essentials: Move your app to Huawei AppGallery with these simple steps!

Working with Use Case ln App Development

MaterialTimePicker as an upgrade of TimePickerDialog

Introducing Luch — a New Library for BLE Beacon Scans on Android

Improve android app/screen launch times using LazyLifecycle callbacks.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


We are Android Developers.

More from Medium

Getting started on Android App Development

Google I/O 22: Android Keynote

From learning Java to publishing my first app on Play Store (with Resources)

Android — Intercept POST form data inside of WebView