...

пятница, 25 июля 2014 г.

Проверяем валидность внутриигровых покупок через Google API

Проблема и решение




Я думаю многие знают что такое Freedom. Для тех кто не знает — это приложение под Android, позволяющее делать внутриигровые покупки в других приложениях без траты денег.

Описание:

Вам надоели предложения в играх и программах что-то купить(расширения, монетки и т.п.)? Покупайте их бесплатно с помощью Freedom!

Пользоваться очень просто: устанавливаете, запускаете (первый запуск может занять какое-то время — до нескольких минут), тапаете по приложению — оно запускается. После этого оно возможно пройдёт проверку лицензии, а при покупке из приложения Вы сможете расплачиваться фэйковой карточкой.





Ссылка на статью автора: http://ift.tt/RJ20vX

Я до определенной поры игнорировал этот прискорбный факт, тем более что я в какой-то степени согласен с автором, что те кто пользуются этим софтом и так врядли бы купили что-то у меня в игре. Но новый проект над которым мы работаем должен стать мультиплеерным. А это значит, что читеры получат реальное преимущество перед обычными игроками, что меня не особо радует.

Покурив вечером мануалы по Google API я решил соорудить собственную проверку валидности покупок. Т.к. мы используем Unity3D + Prime31 IAP, пришлось их немного обработать напильником, чтобы они начали выдавать purchase token.



Для меня архитектура этого дела выглядит вот так:



Два веб-сервера нужны для того чтобы отделить логику работы конкретной игры от проверки валидности покупки, которая общая для всех игр.


Алгоритм такой:



  1. Клиент совершает покупку и получает токен

  2. Клиент делает запрос на веб сервер его игры, передавая токен и тип покупки

  3. Веб сервер игры делает запрос к серверу лицензий

  4. Сервер лицензий делает запрос к Google API

  5. В случае успешного ответа, веб сервер игры начисляет игровую валюту и отправляет клиенту результат


Техническая часть




Про веб сервер игры я писать не буду, так как это выходит за рамки этой статьи.

Сервер лицензий написан на Django. Для тех кто желает написать велосипед самостоятельно — в конце статьи есть куски кода на питоне.

GitHub source: http://ift.tt/1za2gVT


Установка



Создаем виртуальное окружение, клонируем проект и устанавливаем зависимости

virtualenv .
git clone http://ift.tt/1t0QHA0 project
source ./bin/activate
pip install -r ./project/req.txt


Создаем аккаунт и генерируем ключи




  1. Идем на http://ift.tt/1xZWWnD

  2. Создаем новый проект, например «Payment check»

  3. Переходим в Project -> APIS & AUTH -> APIs и включаем Google Play Android Developer API

  4. Идем в Project -> APIS & AUTH -> Credentials, нажимаем Create new Client ID и создаем новый Service Account

  5. Запоминаем e-mail, генерируем и скачиваем новый P12 ключ

  6. Переименуйте его в key.p12 и положите в директорию keys в корне проекта

  7. Перейдите в http://ift.tt/1ktmHqf раздел Настройки -> Аккаунты и права доступа

  8. Нажмите Пригласить пользователя и введите e-mail сервисного аккаунта, который вы создали в пункте 4-5

  9. Дайте этому пользователю права Финансы


Проверка



Все что написано ниже запускается в тестовом режиме, если вы хотите использовать Django в боевых условиях, то есть отдельные статьи как это настроить. Например вот: http://ift.tt/1qkwymX

./manage.py runserver 0.0.0.0:8000




Пример запроса:

http://host:8000/license?package=<package_name>&sku=<product_id>&service=<account>&key=<key>&token=<token>




, где:


  • package — название пакета вашего приложения, например: net.solargames.dungeonexplorer2

  • product_id — идентификатор вашей внутриигровой покупки, например: net.solargames.dungeonexplorer2.gold

  • service — e-mail вашего сервисного аккаунта из пункта 5 выше

  • key — название файла с ключом без расширения, в примере был «key»

  • token — токен покупки, выдается гуглом при совершении покупки на устройстве




Ответ в случае успешной покупки:

<?xml version="1.0" encoding="UTF-8"?><result consumptionState="1" purchaseState="0" purchaseTime="1405003881937" status="0" />




и если кто-то подсунул неверный токен

<?xml version="1.0" encoding="UTF-8"?><result message="Invalid Value" status="1" />




отличаются статусом, в случае успеха он равен нулю.
Тут разобраны внутренности проекта, для тех кому интересно

Кишки



Для работы требуется Google API Python Client, для удобства я статично добавил его в проект.

Линк: http://ift.tt/1t0QKfb

Вся магия содержится в одной маленькой функции:



from oauth2client.client import SignedJwtAssertionCredentials
from apiclient.discovery import build

credentials = SignedJwtAssertionCredentials(
service,
key_content,
scope='http://ift.tt/1bQZPfW')

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)


Внутри result лежит dict с параметрами покупки. В случае ошибки возникнет Exception с довольно скудным описанием проблемы




This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий