Google In-App Billing V3

Mariano Matayoshi

Hi! Today, I will be trying to make it easier to integrate, or at least understand, Google In-app Billing for consumable products, like coins, gems or whatever you like.

I had to read multiple times the documentation to fully understand how the flow of a purchase should be managed. The difficult part for me was, when to call consumePurchase .

This post is an attempt to make your integration of the Google In-App Billing easier.

As I understood it, the purchase of a consumable product that can be bought several times has five steps.

  1. Create the product
    Follow this to create the product, take into account that Product Type has to be Managed product.
  2. Purchase the item
    This action is very will documented here.
    Take into account that after every purchase the product is disabled to be bought, the only way to enable the product again is to call the consumePurchase method. But lets not go ahead.
    When the checkout flow finishes, you will get information about the purchased item. Using the productId, purchaseToken and orderID you must validate the purchase.
  3. Validating purchase
    There are two ways of validating the purchase, the safest is using a server. Make a request to the server with the productId, purchaseToken and orderID. Then in the server you must hit to Google at this endpoint. Note: the request requires to be authenticated with the scope.
  4. Consume the purchase
    I was not sure about if in my case I have to consume the purchase, but like we are talking about consumable products, like coins, we must do it in order that user can buy as many coins as he want.
    As I understand we should separte the Managed products in three categories:
    a) Consumable items, that can be bought N times, like coins, one after another, despite of not being used.
    b) Consumable items, that can be bought N times, like a magic potion, but cannot be bought one after another, it has to be used to be bought again.
    c) Non-Consumable items, like a super cool hat for you character.
    You have to call the consumePurchase method only if you want to enabled again the purchase of a product for that user. And like we are in the case a, we must call this method.
  5. Assign the coins
    Finally, if consumePurchase is successfull you must add the coins to the user. To do that you must make a request to the API with the orderId and the purchaseToken in order to add more coins to the user.

Something that I do not mention explicity is the information you need to save in the database. In my case I am saving the purchases and the coins of the user.

In the step three, every time after a validation happens I create a Purchase with the corresponding attributes, orderId, purchaseToken, productId, state and the raw data returned by

The state can be one of the following pending, approved, consumed or cancelled.

Meaning of each state of a Purchase:

  1. Consumed, it was paid and consumed
  2. Approved, the Purchase was paid but not consumed.
  3. Pending, not paid nor consumed.
  4. Cancelled, the Purchase was paid but refunded the money.

So after getting the purchase information, I set the state of the purchase according to the purchaseState and consumptionState. If the purchaseState == 0 is true then the purchase is approved, so the state of the Purchase in my DB is approved, if it is different from zero then it’s cancelled. Although if the request fails or the it doesn’t return a 200, the state of the Purchase will be pending.

Then, in the step five, after the successfull response of consuming the purchase, the front hits the API with the orderId and the purchaseToken. The API verifies that the Purchase related to the orderId was not consumed (consumed == false), then get the purchase again from google. If it is consumed, i.e. the consumptionState == 1 is true, I update the Purchase‘s state in the DB as consumed and add the coins to the user.

Well, that’s all! If you have any doubt feel free to ask or write to me!

You can follow me on Twitter, StackOverflow, LinkedIn or Github :)

Mariano Matayoshi (

Mariano Matayoshi

Written by

Love to share my knowledge with friends and co-workers. Self-Taught. Devops enthusiast. Shortcuts and startup culture lover. Always learning and improving.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade