
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.
Description:
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: habrahabr.ru/post/163547
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:
- Customer makes a purchase and receives a token
- The client makes a request to the web server of his game, passing the token and type of purchase
- The game web server makes a request to the license server
- License Server makes a request to the Google API
- 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: github.com/Agasper/django-google-play-check-payment
Installation
Create a virtual environment, clone the project and install the dependencies
virtualenv .
git clone https://github.com/Agasper/django-google-play-check-payment.git project
source ./bin/activate
pip install -r ./project/req.txt
Create an account and generate keys
- Go to console.developers.google.com/project
- Create a new project, for example, “Payment check”
- Go to
Project -> APIS & AUTH -> APIs
and turn onGoogle Play Android Developer API
- Go to
Project -> APIS & AUTH -> Credentials
, clickCreate new Client ID
and create a new oneService Account
- Remember e-mail, generate and download a new P12 key
- Rename it to key.p12 and put it in the directory
keys
in the root of the project - Go to play.google.com/apps/publish section
Настройки -> Аккаунты и права доступа
- Click
Пригласить пользователя
and enter the e-mail of the service account that you created in paragraph 4-5 - Give this user rights
Финансы
Check
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: habrahabr.ru/post/226419
./manage.py runserver 0.0.0.0:8000
Request example:
http://host:8000/license?package=&sku=&service=&key=&token=
where:
- package - the name of the package of your application, for example: net.solargames.dungeonexplorer2
- product_id - identifier of your in-game purchase, for example: net.solargames.dungeonexplorer2.gold
- 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.
Link: code.google.com/p/google-api-python-client/source/browse
All magic is contained in one small function:
Inside
Guts
The Google API Python Client is required for work, for convenience I statically added it to the project.
Link: code.google.com/p/google-api-python-client/source/browse
All magic is contained in one small function:
from oauth2client.client import SignedJwtAssertionCredentials
from apiclient.discovery import build
credentials = SignedJwtAssertionCredentials(
service,
key_content,
scope='https://www.googleapis.com/auth/androidpublisher')
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
result
is a dict with purchase options. In case of an error, an Exception will be thrown with a rather meager description of the problem.