In app purchase android как

In-App Purchase в Android приложениях

1. Что это такое и зачем это нужно?

In-App Purchase, грубо говоря, представляет собой сервис покупки виртуальных товаров внутри приложения (например игровой валюты, новых уровней, игровых предметов и т.д.). Применяется он в основном в играх, в тех случаях, когда встает вопрос о необходимости заработка на своем творении, а распространять его платно не особо хочется (или нет смысла).

2. In-App Purchase в андроид-приложениях

Когда я столкнулся с необходимостью использования in-app purchase в разрабатываемой игре, было очень трудно найти подробную русскоязычную информацию о том, как прикрутить данный сервис к своей игре. Наиболее хорошо сервис был описан в одной из статей Хабра, но мне бы хотелось показать свое видение по данному вопросу. Поэтому решил сам написать небольшой мануал по подключению сервиса к приложению.

Для начала неплохо было бы разобраться с тем, как это все работает.

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

Предполагается, что у вас уже есть аккаунт разработчика на Android Market.

Для того, чтобы работать с системой покупок внутри приложения нам понадобится файл с названием IMarketBillingService.aidl. Найти его можно в примере приложения по работе с in-app purchase, который в свою очередь является скачиваемым компонентом Android SDK. Запустите Android SDK and AVD Manager и выберете Available Packages. Далее необходимо будет выбрать Third party add-ons -> Google Inc. add-ons -> Google Market Billing package.

Теперь необходимо из скаченного примера скопировать в свой проект файл IMarketBillingService.aidl. Важно, чтобы он лежал в com.android.vending.billing. После этого в манифесте добавляем расширение: .

В примере приложения кроме вышеописанного файла есть также несколько реализованных классов для работы с системой платежей. Копируем их в свой проект. Что собой представляет каждый из них:

BillingReceiver – получает все асинхронные ответы с маркета и отправляет их далее в BillingService;
BillingService – отправляет запросы на маркет;
Consts – содержит все константы примера приложения;
Dungeons – обеспечивает UI и отображает историю совершенных покупок;
PurchaseDatabase – локальная база данных;
PurchaseObserver – наблюдение за изменениями, связанными с покупками;
ResponseHandler – обновление базы данных и UI;
Security – обеспечение безопасности;
Base64 и Base64DecoderException – кодирование из двоичной системы в base64. Необходимы для функционирования класса Security.

В классе Security ищем строку:
String base64EncodedPublicKey = “…”
и вписываем сюда свой PublicKey, полученный при регистрации аккаунта на Android Market.

В классе Dungeons ищем список товаров, которые предполагается продавать, и меняем их на свои. При этом, товары должны быть залиты в Android Market и опубликованы (само приложение при этом публиковать не обязательно – в случае его тестирования, однако надо не забыть добавить себя (или кого-то другого) в разработчики (делается в настройках профиля)). Далее дописываем интерфейс и в принципе приложение готово.

Однако стоит позаботиться о безопасности. Лучший способ обеспечения безопасности покупок – использование соответствующего сервиса на сервере. После того, как пользователь совершил покупку товара, маркет пришлет JSON строку с информацией о купленном товаре:
< "nonce" : 1836535032137741465,
«orders» :
< "notificationId" : "android.test.purchased",
«orderId» : «transactionId.android.test.purchased»,
«packageName» : «com.example.dungeons»,
«productId» : «android.test.purchased»,
«developerPayload» : «bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ»,
«purchaseTime» : 1290114783411,
«purchaseState» : 0 >
>
и подпись для проверки подлинности запроса.

Читайте также:  Android режим не беспокоить избранные контакты

На серверной части приложения нужно выполнить проверку вернувшейся строки с помощью подписи и вашего ключа (шифрование RSA) и вернуть результат проверки клиенту. Для этого есть небольшая открытая библиотека, написанная на php, я использовал ее.

Более подробно о безопасности при работе с in-app purchase написано тут.

Источник

Android In-app purchasing: платное отключение рекламы в своём приложении

Много раз уже просили написать статью о том, как в приложении реализовать платное отключение рекламы. По In-app уже были статьи на хабре. Правда, они старую версию API рассматривали. В принципе, новая версия не особо то и отличается от старой. Была похожая статья, но там больше именно про отображение рекламы рассказывалось, а второй части статьи мы так и не увидели. Как оказалось, многим до сих пор интересен этот вопрос, решил написать как это реализовать в своём приложении.

In-App Purchase представляет собой сервис покупки виртуальных товаров внутри приложения (например игровой валюты, новых уровней и т.д.). Применяется он в основном в играх, в тех случаях, когда встает вопрос о необходимости заработка на своем творении.

В данной статье рассмотрю как можно использовать In-App Purchase для отключения рекламы в своём приложении.

Реклама в приложении

В принципе, можно взять любую площадку. Возьмём, к примеру AdMob. Я для удобства обычно подобные вещи в обёртки запихиваю, чтобы при смене площадки, если потребуется, почти ничего не пришлось менять. Обёртки для рекламной площадки должны реализовывать интерфейс:

Тогда обёртка для AdMob будет выглядеть примерно так:

Тогда инициализация рекламы будет такой:

При такой реализации в случае смены площадки, мы просто создадим инстанс другого класса. Для работы вам нужен лишь ID_приложения. который получите после создания в приложения в админке Admob.

In-app purchasing или внутренние платежи в приложениях

Для того, чтобы работать с системой покупок необходим файл IMarketBillingService.aidl. Лежит он в /user/android-sdk-linux/extras/google/play_billing директории с SDK. Положить файлик надо в com.android.vending.billing пакет вашего приложения.

О типах покупок можно почитать тут. Нас интересую восстанавливаемые покупки, то есть те, что привязываются к аккаунту и повторно их уже не купить. Если вы удалите приложение и постановите заново, то покупка будет восстановлена. В нашем случае, после покупки отключения рекламы, реклама больше не будет беспокоить пользователя. Это касается и других устройств: если пользователь залогиниться на другом устройство под своим аккаунтом, то в приложение будет восстановлена покупка и реклама будет отключена.

Для работы необходимо добавить разрешение в AndroidManifest.xml:

Очень помогает официальная документация и пример из SDK.

Необходимо определить ключик в приложении – PublicKey, полученный при регистрации аккаунта на Android Market
Определяем IabHelper и инициализируем. Если удачно, то пытаемся восстановить покупки.

mGotInventoryListener – слушатель для восстановления покупок.

Теперь надо, собственно, саму покупку реализовать:

SKU_ADS_DISABLE – идентификатор товара, который вы создали в адмике Google Play. mPurchaseFinishedListener – слушатель:

Стоит отдельно поговорить о методе по верификации:

Сейчас нет никакой проверки покупок, но в реальном приложении вы должны сверять полученные данные с той сгенерированой строкой, что вы отправили в запросе на покупку. Проверять это надо на своём стороннем сервере. Для обычно приложения или офф-лайн игры это может и не критично, но для он-лайн игры это очень важно.

В принципе всё, теперь при запуске приложения просиходит проверка настроек (куда мы сохранили, что отключили рекламу):

После чего реклама уже не будет показываться.

Тестирование покупок

Сейчас довольно удобно тестировать своё приложение. Можно залить .apk как альфа/бета версию и опубликовать. При этом можно назначить группу в Google+, которая будет иметь возможность к тестированию. Если вы публикуете альфа или бета версию приложения, то в маркете она не появится, иметь доступ будет только эта группа.

Читайте также:  Как форматировать флэш андроид

Тестеры смогут осуществлять покупки. Деньги будут списываться без комиссии и будут возвращены после 15 минут после покупки. Так что, не беспокойтесь. Вот только у вас не получится протестировать приложение, если ваш аккаунт на устройстве и аккаунт издателя один и тот же =/

Полностью рабочий пример можете посмотреть на гитхабе.

Источник

In-app purchasing или внутренние платежи в приложениях для Android

О чем это вообще?

С версией приложения Android Market 2.3.0 для разработчиков приложений для платформы Android открылась возможность предоставлять пользователям платежи внутри самих приложений. Теперь можно продавать уровни и артефакты, видео, музыку, плагины и прочее, пользуясь лишь встроенными средствами платформы. Давайте увидим, как это можно сделать.

Что нам понадобится?

Как обычно, любимая IDE, Android SDK и пример приложения.
Так же будет полезным представлять себе, что такое Service, BroadcastReceiver и, конечно, Activity.

Так же нам понадобится разрешение в файле манифеста —

, без него ничего не заработает.

Как это в принципе работает?

Работает все через сервис в приложении Android Market. Он умеет посылать запросы на получение деталей определенной вещи, которую хочет купить пользователь, на покупку, получать ответы о успехе или неудачи покупки, и прочее. Вся информация о вещах, которые вы продаете, должна быть заведена через Консоль Разработчика для конкретного приложения. Как только мы получили сигнал об успешной покупке, мы можем начать грузить с нашего сервера контент.

Как все это устроено?

На сервере в маркете хранится информация о вещах, которые можно купить. С сервером взаимодействует клиентское приложение маркета. С ним взаимодействует наше приложение.

Наше приложение будет состоять как минимум из:

  1. BillingService. Это сервис, который связан с приложением маркета, и отправляет ему всю информацию об операциях и получает на них ответы, в случае, если они синхронные.
  2. BillingReceiver. Получает асинхронные ответы от приложения маркета.
  3. PurchaseObserver. Сущность, которая будет оповещать UI об изменениях состояния покупок.

Какие сообщения мы отсылаем маркету?

Вначале нам нужно соединить наш BillingService с приложением маркета для того, чтобы вызывать метод sendBillingRequest сервиса MarketBillingService. Интерфейс сервиса описан в файле IMarketBillingService.aidl, его можно скачать отсюда, а положить надо в com.android.vending.billing пакет вашего приложения. IDE должна сразу же сгенерить IMarketBillingService.java файл, который нам понадобиться для вызова вышеупомянутого метода.

Сам метод принимает параметр Bundle, в котором и хранится вся информация. Самой важной является параметр с ключом «BILLING_REQUEST». Он определяет тип запроса. Они бывают:

• CHECK_BILLING_SUPPORTED – проверка доступности in-app billing.
• REQUEST_PURCHASE – запрос покупки.
• GET_PURCHASE_INFORMATION – получение информации об изменении состояния покупки.
• CONFIRM_NOTIFICATIONS – подтверждение факта получение уведомления от приложения маркета.
• RESTORE_TRANSACTIONS – восстановление транзакций по уже купленным вещам.

Какие получаем ответы?

Метод синхронно возвращает ответ, который тоже представляет из себя Bundle. В нем лежит:

• RESPONSE_CODE — код ответа
• PURCHASE_INTENT — PendingIntent , для того, чтобы запустить активти покупки.
• REQUEST_ID – идентификатор посланного запроса

В случае асинхронных ответов(получаемых через BillingReceiver), в них лежит следующее:

• com.android.vending.billing.RESPONSE_CODE
Код ответа. Маркет подтверждает успех или неудачу посылки запроса.

• com.android.vending.billing.IN_APP_NOTIFY
Оповещение о том, что статус покупки изменился. После этого сообщения нужно отправлять запрос с типом GET_PURCHASE_INFORMATION , чтобы получить инфу.

• com.android.vending.billing.PURCHASE_STATE_CHANGED
А тут приходит детальная информация о покупке. Она включает в себя nonce, список заказов, с указанием идентификаторов продуктов, их состояний и проч.

Последовательность при покупке будет такая:

1. Посылаем REQUEST_PURCHASE
2. Получаем синхронный ответ
3. Запускаем Activity покупки(также встроенную в приложение маркета)
4. Получаем асинхронное сообщение IN_APP_NOTIFY
5. Посылаем GET_PURCHASE_INFORMATION
6. Получаем синхронный ответ
7. Получаем асинхронный ответ PURCHASE_STATE_CHANGED
8. Отправляем CONFIRM_NOTIFICATIONS
9. Получаем синхронный ответ

Читайте также:  Titan quest android билды

А может, посмотрим лучше на код?

Итак, основные моменты в коде:

1. Коннект к маркету.

В onCreate() в BillingService пишем:

try <
boolean bindResult = getApplicationContext().bindService(
new Intent( «com.android.vending.billing.MarketBillingService.BIND» ),
this ,
Context.BIND_AUTO_CREATE);
if (bindResult) <
Log.i(TAG, «Service bind successful.» );
> else <
Log.e(TAG, «Could not bind to the MarketBillingService.» );
>
> catch (SecurityException e) <
Log.e(TAG, «Security exception: » + e);
>

//И чуть ниже:
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) <
Log.i(TAG, «MarketBillingService connected.» );
marketService = IMarketBillingService.Stub.asInterface(iBinder);
runPendingRequests();
>

* This source code was highlighted with Source Code Highlighter .

2. Отправка запросов.

В примере приложения создана иерархия классов для запросов и это правильно. Самая главная вещь в них – это отложенная отправка. Дело в том, что bindService происходит асинхронно, а значит ссылку на MarketBillingService мы получаем гораздо позже, чем кончается onCreate(), и даже позже, чем пытаемся в первый раз выполнить запросы. Поэтому делаем так:

/**
* Run the request, starting the connection if necessary.
*
* @return this request if the request was not executed in order to queue it.
*/
public final AbstractRequest runRequest() <
if (runIfConnected()) <
return null ;
>
return this ;
>

/**
* Try running the request directly if the service is already connected.
*
* @return true if the request ran successfully; false if the service
* is not connected or there was an error when trying to use it
*/
public boolean runIfConnected() <
if (service.isConnected()) <
try <
requestId = run();
if (requestId >= 0) <
service.addRequest(requestId, this );
>
return true ;
> catch (MyException e) <
onException(e);
>
>
return false ;
>

* This source code was highlighted with Source Code Highlighter .

Возвращение запроса нужно, чтобы запомнить его в списке ожидающих отправки запросов в сервисе. Потом, когда мы получим ссылку на MarketBillingService в onServiceConnected(), мы все запросы попробуем отправить еще раз.

3. Оповещение UI

В BillingService будем хранить ссылку на некую сущность, которая хранит в себе Handler от нашего UI. Тогда по получении ответов можно будет делать следующее:

private void notifyGui( int messageId, PurchasedItem item) <
if (observer != null ) <
observer.notifyGui(messageId, item);
> else <
// пошлем здесь оповещение в NotificationBar
>
>

* This source code was highlighted with Source Code Highlighter .

Важно: не забывать обнулять observer сервиса из своей Activity при выходе из нее и восстанавливать эту ссылку. Делается это так:

@Override
protected void onUserLeaveHint() <
if (billingService != null ) <
unbindService( this );
billingService.resetEventDispatcher();
billingService = null ;
>
super.onUserLeaveHint();
>

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) <
//Connected to BillingService
if (componentName.getShortClassName().equals(serviceClassName)) <
billingService = ((BillingService.LocalBinder) iBinder).getService();
billingService.setObserver( new PurchaseObserver());
try <
billingService.checkBillingAvailability();
> catch (MyException e) <
Log.e(TAG, «Billing unavailable» , e);
Toast.makeText( this , «Billing unavailable» , Toast.LENGTH_LONG).show();
>
>
>

* This source code was highlighted with Source Code Highlighter .

4. Запуск Activity покупки.

Загляните в PurchaseObserver класс примера. Там есть метод public void startBuyPageActivity(PendingIntent pendingIntent, Intent intent). PendingIntent – это то, что мы получили ответом от маркета. А Intent – просто new Intent().
Что же этот метод делает?
На самом деле в этот класс передается инстанс вашей Activity. Дальше от нее через reflection происходит попытка получить метод startInstentSender. Этот метод появился только в Android 2.0. Если он есть, то метод вызывается, и Activity запускается в стеке Activity нашего приложения. Если же метод не найден, то происходит старт Activity в отдельном стеке.

А как же безопасность?

Вопрос безопасности – тема отдельной статьи, и так уже много. В примере приложения за безопасность отвечает класс Security. Скажу только, что верифицировать покупки нужно не в приложении(как это сделано в примере), а на собственном сервере, дабы не давать логику проверки в руки потенциальных обладателей apk.

Источник

Оцените статью