Checking the validity of in-game purchases through the Google API

    Problem and Solution

    I think many people know what Freedom is. For those who don’t know, this is an Android application that allows you to make in-game purchases in other applications without spending money.

    Are you tired of offers in games and programs to buy something (extensions, coins, etc.)? Buy them for free with Freedom!
    It is very simple to use: install, launch (the first launch may take some time - up to several minutes), tap on the application - it starts. After that, it will probably pass a license check, and when you purchase from the application, you can pay with a fake card.

    Link to the author’s article:

    I have for some time ignored this unfortunate fact, especially since I somewhat agree with the author that those who use this software would hardly buy something from me in Game. But the new project we are working on should become multiplayer. And this means that cheaters will get a real advantage over ordinary players, which does not make me very happy.
    Having smoked Google API manuals in the evening, I decided to build my own check of the validity of purchases. Because we use Unity3D + Prime31 IAP, I had to process them a bit with a file so that they begin to issue a purchase token.

    For me, the architecture of this case looks like this:

    Two web servers are needed to separate the logic of a particular game from the validation of the purchase, which is common to all games.

    The algorithm is as follows:
    1. Customer makes a purchase and receives a token
    2. The client makes a request to the web server of his game, passing the token and type of purchase
    3. The game web server makes a request to the license server
    4. License Server makes a request to the Google API
    5. In case of a successful response, the game’s web server calculates the game currency and sends the result to the client

    Technical part

    I will not write about the game’s web server, as this is beyond the scope of this article.
    The license server is written in Django. For those who want to write a bike on their own - at the end of the article there are pieces of code in python.

    GitHub source:


    Create a virtual environment, clone the project and install the dependencies

    virtualenv .
    git clone project
    source ./bin/activate
    pip install -r ./project/req.txt

    Create an account and generate keys

    1. Go to
    2. Create a new project, for example, “Payment check”
    3. Go to Project -> APIS & AUTH -> APIsand turn onGoogle Play Android Developer API
    4. Go to Project -> APIS & AUTH -> Credentials, click Create new Client IDand create a new oneService Account
    5. Remember e-mail, generate and download a new P12 key
    6. Rename it to key.p12 and put it in the directory keysin the root of the project
    7. Go to sectionНастройки -> Аккаунты и права доступа
    8. Click Пригласить пользователяand enter the e-mail of the service account that you created in paragraph 4-5
    9. Give this user rights Финансы


    All that is written below is launched in test mode, if you want to use Django in a combat environment, that is, separate articles on how to configure this. For example, here:

    ./ runserver

    Request example:


    • package - the name of the package of your application, for example: net.solargames.dungeonexplorer2
    • product_id - identifier of your in-game purchase, for example:
    • service - e-mail of your service account from paragraph 5 above
    • key - the name of the file with the key without the extension, in the example was “key”
    • token - purchase token, issued by Google when making a purchase on the device

    Answer in case of successful purchase:

    and if someone slipped the wrong token

    differ in status, if successful, it is zero.

    Here the insides of the project are disassembled, for those who are interested

    The Google API Python Client is required for work, for convenience I statically added it to the project.

    All magic is contained in one small function:
    from oauth2client.client import SignedJwtAssertionCredentials
    from apiclient.discovery import build
    credentials = SignedJwtAssertionCredentials(
    http = httplib2.Http()
    http = credentials.authorize(http)
    service = build("androidpublisher", "v1.1", http=http)
    result = service.inapppurchases().get(packageName=package, productId=sku, token=token).execute(http=http)

    Inside resultis a dict with purchase options. In case of an error, an Exception will be thrown with a rather meager description of the problem.

    Also popular now: