- Покупки в Android приложении — Play Billing Library
- Android in-app purchases, часть 1: конфигурация и добавление в проект
- Создание подписки/покупки
- Сравнение процесса покупки с App Store Connect
- Получение списка продуктов в приложении
- Про Adapty
- Android In-app Billing: от мобильного приложения до серверной валидации и тестирования
- Зачем вообще это нужно?
- Часть 1: Регистрация приложения в консоли Google Play и создание списка покупок
- Часть 2: Интеграция Android in-app billing в мобильном приложении
- Часть 3: Валидация покупок и подписок на сервере
- Вместо заключения
Покупки в Android приложении — Play Billing Library
И как это до сих пор на Хабре нет статьи об этом? Не дело, надо исправлять.
Есть 2 способа добавить In-App покупки в Android-приложение — старый и новый. До 2017 года все пользовались библиотекой от anjlab, но с июня 2017 года ситуация изменилась, Google выпустила собственную библиотеку для внутренних покупок и подписок — Play Billing Library. Сейчас последний считается стандартом.
Play Billing Library это очень просто.
Добавьте разрешение в манифесте.
Создайте инстанс BillingClient и начните соединение.
В метод onPurchasesUpdated() мы попадаем когда покупка осуществлена, в методе onBillingSetupFinished() можно запросить информацию о товарах и покупках.
Запросить информацию о товарах. Поместите querySkuDetails() в onBillingSetupFinished().
В коде вы могли заметить понятие SKU, что это? SKU — от английского Stock Keeping Unit (идентификатор товарной позиции).
Теперь в mSkuDetailsMap у нас лежит вся информация о товарах (имя, описание, цена), зарегистрированных в Play Console данного приложения (об этом позже). Обратите внимание на эту строку skuList.add(mSkuId);, здесь мы добавили id товара из Play Console, перечислите здесь все товары, с которыми вы хотите взаимодействовать. У нас товар один —sku_id_1.
Все готово к тому, чтобы выполнить запрос на покупку. Передаем id товара. Запустите этот метод, например, по клику на кнопку.
Теперь, запустив этот метод, вы увидите вот такое диалоговое окно (прим. картинки из Интернета).
Теперь если пользователь купит товар — его ему надо предоставить. Добавьте метод payComplete() и осуществите в нем действия, предоставляющие доступ к купленному товару. Например, если пользователь покупал отключение рекламы, сделайте в этом методе так, чтобы реклама больше не показывалась.
Все хорошо, но если пользователь перезапустит приложение, наша программа ничего не знает о покупках. Надо запросить информацию о них. Сделайте это в onBillingSetupFinished().
В purchasesList попадает список всех покупок, сделанных пользователем.
Делаем проверку: если товар куплен — выполнить payComplete().
Готово. Осталось это приложение опубликовать в Play Console и добавить товары. Как добавить товар: Описание страницы приложения > Контент для продажи > Создать ограниченный контент.
Примечание 1: Вы не сможете добавить товар пока не загрузите билд приложения в Play Console.
Примечание 2: Чтобы увидеть диалоговое окно о покупке, вам надо загрузить билд в Play Console, добавить товар и подождать какое-то время (
30 минут — 1 час — 3 часа), пока товар обновится, только после этого появится диалоговое окно и можно будет осуществить покупку.
Примечание 3: Ошибка Please fix the input params. SKU can’t be null — товар в Play Console еще не успел обновиться, подождите.
Примечание 4: Вы можете столкнуться с ошибкой Error «Your transaction cannot be completed», в логах как response code 6 пока будете тестировать. По каким причинам это происходит мне точно неизвестно, но по моим наблюдениям это происходит после частых манипуляций с покупкой и возвратом товара. Чтобы это починить перейдите в меню банковских карт и передобавьте вашу карту. Как этого избежать? Добавьте ваш аккаунт в Play Console в качестве тестировщика и покупайте только с тестовой карточки.
(Кстати, на Хабре работает система донейтов по кнопке под статьёй — прим. модератора).
Источник
Android in-app purchases, часть 1: конфигурация и добавление в проект
Всем привет, меня зовут Влад и я разработчик Android SDK для обработки платежей в мобильных приложениях в Adapty.
Внутренние покупки и в частности подписки являются наиболее популярным способом монетизировать приложение. С одной стороны, подписка дает разработчику возможность постоянно развивать контент и продукт, с другой стороны, благодаря им пользователь получает более высокое качество приложения в целом. Внутренние покупки облагаются 30% комиссией, но если пользователь подписан больше года или приложение зарабатывает меньше $1М в год, то комиссия составляет 15%.
Это первая статья из серии, посвящённой работе с внутренними покупками на Android. В этой серии мы охватываем темы от создания in-app purchases до серверной верификации платежей:
Android in-app purchases часть 1: конфигурация и добавление в проект. — Вы тут
В этой статье мы разберём, как:
создавать продукты в Google Play Console;
конфигурировать подписки: указывать длительность, стоимость, пробные периоды;
получать список продуктов в приложении.
Создание подписки/покупки
Перед тем, как мы начнем, убедитесь, что
Вы подписали все соглашения и готовы работать.
Перейдем к делу, а именно создадим наш первый продукт.
Переходим в наш аккаунт разработчика и выбираем нужное приложение.
Дальше в левом меню ищем секцию Продукты, выбираем Подписки и жмем на Создать Подписку.
Дальше попадаем в конфигуратор подписки, разберем важные вещи.
Создаем ID, который потом используем в приложении. Хорошо, когда в ID мы кодируем период подписки и какую-то еще полезную информацию. Это позволяет создавать продукты в одном стиле, чтобы в будущем было проще анализировать статистику по покупкам.
Название подписки, как пользователь ее увидит в магазине.
Описание подписки, пользователь тоже это увидит.
Скроллим ниже и выбираем период подписки, в нашем случае это неделя, и конфигурируем стоимость.
Обычно вы задаете цену в базовой валюте аккаунта, а система автоматически переводит цены в разные валюты разных стран. Но вы также можете поправить цену в конкретной стране вручную.
Обратите внимание, что Google сразу указывает налог в каждой стране, это очень круто, а в App Store Connect такого нет.
Скроллим ниже и опционально выбираем:
Бесплатный пробный период.
Начальная цена. Промо-предложение на первые периоды оплаты.
«Льготный период». То есть, если у пользователя проблема с оплатой, сколько дней вы продолжаете давать ему премиум доступ.
Возможность подписаться заново из Play Market, а не из приложения, после отмены подписки.
Сравнение процесса покупки с App Store Connect
Несмотря на то, что подписки значительно лучше монетизируются на iOS, админка Play Console выглядит намного удобнее. Она работает быстрее, лучше и проще структурирована, качественно локализована.
Сам процесс создания продукта предельно упрощен. Здесь мы описали, как создавать продукты на iOS.
Получение списка продуктов в приложении
После создания продуктов перейдем к созданию архитектуры в приложении для приема и обработки покупок. В целом процесс следующий:
Подключаем платежную библиотеку.
Разрабатываем структуру класса для взаимодействия с продуктами из Google Play.
Реализуем все методы обработки покупки.
Подключаем серверную верификацию покупки.
В этой части разберем первые два пункта.
Подключим Billing Library к проекту:
На момент написания статьи актуальной версией является 4.0.0. Вы можете в любой момент заменить ее на другую версию.
Создадим класс-обертку, который будет инкапсулировать логику взаимодействия с Google Play, и проинициализируем в нем BillingClient из библиотеки Billing Library. Назовем такой класс BillingClientWrapper.
Наш класс будет реализовывать интерфейс PurchasesUpdatedListener. Мы сразу переопределим его метод onPurchasesUpdated(billingResult: BillingResult, purchaseList: MutableList
?) , который вызывается после совершения покупки, но саму реализацию опишем уже в следующей статье.
Google рекомендует, чтобы одновременно было не больше одного активного соединения BillingClient’а с Google Play, чтобы колбэк о совершенной покупке не вызывался несколько раз. Для этого целесообразно иметь единственный экземпляр BillingClient в классе-синглтоне. Класс в примере выше сам по себе синглтоном не является, но мы можем провайдить его с помощью dependency injection (например, используя Dagger или Koin) таким образом, чтобы в один момент времени существовало не больше одного экземпляра.
Для совершения любого запроса с помощью Billing Library нужно, чтобы у BillingClient’а в момент запроса было активное соединение с Google Play, но в какой-то момент оно может быть утеряно. Для удобства напишем обертку, чтобы любой запрос выполнялся только при активном соединении.
Чтобы получить продукты, нам нужно знать их идентификаторы, которые мы задавали в маркете. Но для запроса этого недостаточно, нужно указать еще и тип продуктов (подписки или разовые покупки), поэтому общий список продуктов мы можем получить только путем «склеивания» результатов двух запросов.
Так как запрос на продукты асинхронный, нам нужен колбэк, в котором мы получим либо список продуктов, либо ошибку. Billing Library при ошибке возвращает один из определенных в ней BillingResponseCode, а также debugMessage. Создадим интерфейс колбэка и модель для ошибки:
Напишем приватный метод для получения данных о продуктах конкретного типа, а также публичный метод, который «склеит» результаты от двух запросов и вернет итоговый список продуктов или ошибку.
Таким образом мы получили информацию о продуктах (SkuDetails), где есть локализованные названия, цены, тип продукта, а для подписок еще и период платежа, а также информация о начальной цене и пробном периоде (если доступно данному пользователю). Финальный класс выглядит так:
На этом все, в следующих статьях мы расскажем о реализации покупок, тестировании и обработке ошибок.
Про Adapty
Как видите, в процессе добавления покупок в приложения на Android много нюансов. Если использовать готовые библиотеки, всё будет проще. Советую познакомиться с Adapty — SDK для in-app покупок. Он не только упрощает работу по добавлению покупок:
Встроенная аналитика позволяет быстро понять основные метрики приложения.
Когортный анализ отвечает на вопрос, как быстро сходится экономика.
А/Б тесты увеличивают выручку приложения.
Интеграции с внешними системами позволяют отправлять транзакции в сервисы атрибуции и продуктовой аналитики.
Промо-кампании уменьшают отток аудитории.
Open source SDK позволяет интегрировать подписки в приложение за несколько часов.
Серверная валидация и API для работы с другими платформами.
Познакомьтесь подробнее с этими возможностями, чтобы быстрее внедрить подписки в своё приложение и улучшить конверсии.
Источник
Android In-app Billing: от мобильного приложения до серверной валидации и тестирования
Всем привет! Недавно передо мной встала задача интегрировать биллинг в наш сервис, и, хотя изначально задача казалась довольно простой, в результате это вылилось в исследование длиной в месяц времени, кучу нервов и открытий. Результатом стало понимание того, что, несмотря на огромное количество документации, не все можно найти простым запросом в Google (а в некоторых местах документация предлагает откровенный бред, о чем я еще расскажу далее).
В результате биллинг от Google Play был успешно интегрирован в наш сервис, валидация покупок и подписок на серверной стороне работает. Кому стало интересно — добро пожаловать под кат: здесь будет полное описание всего, начиная от регистрации покупок в консоли управления Google Play, и заканчивая работой с подписками на своем бекенде.
Для начала коротко о пациенте. Я буду разбирать по кусочкам Google Play In-App Billing V3 а также облачный Android Publisher API, который и поможет нам как с валидацией покупок, так и при работе с подписками. Также не обойдем стороной Консоль управления Google Play — она тоже нам понадобится.
Зачем вообще это нужно?
Если у вас клиент-серверное приложение — то без валидации на сервере вам не обеспечить защиту от пиратства. И хотя можно просто валидировать цифровую подпись покупки на сервере, у запроса на Android Publisher API метода есть некоторые дополнительные возможности. Во-первых, вы можете получить информацию о покупке или подписке в любое время без привязки к устройству пользователя, а, во-вторых, вы можете получить более детальную информацию о подписках и управлять ими (отменять, откладывать и т. п.). К примеру, если вы хотите отобразить дату следующего платежа как в Google Play Music:
То вы можете получить ее только запросом на Android Publisher API.
Полный flow при интеграции биллинга таков:
1. Регистрация приложения в консоли Google Play и создание списка покупок.
2. Интеграция Android in-app billing в мобильном приложении.
3. Валидация покупок и подписок на сервере.
Часть 1: Регистрация приложения в консоли Google Play и создание списка покупок
Зайдите в Консоль управления Google Play (если у вас нет аккаунта — зарегистрируйте его за $25) и создайте ваше первое приложение. Начнем с того момента, когда ваше приложение уже зарегистрировано.
1. Есть ваше приложение не было ранее загружено — подпишите ваше приложение вашим release-сертификатом и загрузите его в закрытое альфа-или бета тестирование.
All Applications / Ваше Приложение / APK / Alpha(Beta) Testing
2. Создайте список тестирования и активируйте его для выбранного вами (Alpha или Beta) типа тестирования.
3. Добавьте в этот список email-ы Google-аккаунтов, которые будет тестировать биллинг. Например, ваш личный email, с помощью которого вы вошли в Google Play на своем устройстве.
Внизу будет ссылка Opt-in URL: по этой ссылке нужно перейти всем пользователям, которые будут тестировать биллинг (и самому тоже), и согласиться на тестирование. Без этого вы не сможете совершать покупки в альфа/бета версии.
4. Перейдите во вкладку Settings / Account Details, найдите раздел LICENSE TESTING и в поле Gmail accounts with testing access добавьте те же email-ы, что и в прошлом шаге. Теперь с этих аккаунтов вы можете тестировать покупки — за них не будет взыматься плата.
Добавить метод оплаты все же придется — сам диалог покупки потребует этого, однако когда вы непострудственно увидите кнопку купить в приложении — будет указано, что это тестовая покупка.
5. Добавьте тестовые покупки в ваше приложение. Для этого пройдите в All Applications / Ваше Приложение / In-app Products и нажмите Add new product. Можете добавить одну покупку (Managed product) и одну подписку (Subscription). В качестве product id можно использовать что-то в стиле com.example.myapp_testing_inapp1 и com.example.myapp_testing_subs1 для покупки и подписки соответственно Нужно как минимум добавить название и описание, установить цену для продукта, выбрать страны, где он доступен (можете выбрать все), для подписки также выбрать период, и активировать продукт. После этого он станет доступен через некоторое время.
ВАЖНО: вы должны опубликовать приложение (как минимум в alpha/beta), иначе покупки работать не будут.
Коротко о типах покупок
1. Managed product (inapp) — одноразовая покупка. После покупки пользователем становится владельцем покупки навсегда, но также такая покупка может быть «использована» (consume) — например, для начисления каких то бонусов. После использования покупка исчезает и ее можно совершить еще раз.
2. Subscription (subs) — подписка. После активации у пользователя снимается определенная сумма раз в определенный период. Пока пользователь платит — подписка активна.
Когда наши покупки будут активированы — мы сможем получить информацию о них непосредственно в мобильном приложении (название, описание, цена в локальной валюте) а также совершить покупку.
Часть 2: Интеграция Android in-app billing в мобильном приложении
Для начала выполним некоторые манипуляции, чтобы работать с биллинг-сервисом в нашем приложении.
Скопируем файлик IInAppBillingService.aidl в наш проект:
IInAppBillingService.aidl это файл Android Interface Definition Language (AIDL), который определяет интерфейс взаимодействия с сервисом In-app Billing Version 3. Вы будете использовать этот интерфейс для выполнения биллинг-запросов с помощью IPC-вызовов.
Чтобы получить файл AIDL:
Откройте Android SDK Manager.
В SDK Manager найдите и раскройте секцию Extras.
Выберите Google Play Billing Library.
Нажмите Install packages чтобы выполнить установку.
Перейдите в папку src/main вашего проекта и создайте папку с именем aidl.
Внутри этот папки создайте пакет com.android.vending.billing.
Скопируйте файл IInAppBillingService.aidl из папки %anroid-sdk%/extras/google/play_billing/ в только что созданный пакет src/main/aidl/com.android.vending.billing
Добавим разрешение в манифест:
И в месте, где мы собираемся совершать покупки, подключимся к сервису:
Теперь можно приступать к работе с покупками. Получим список наших покупок из сервиса с описанием и ценами:
С помощью этого метода мы можем загрузить данные о доступных покупках.
Теперь мы можем прямо из приложения получить список покупок и информацию про них. Цена будет указана в той валюте, в которой пользователь будет платить. Эти методы надо вызывать в фоновом потоке, так как сервис в процессе может загружать данные с серверов Google. Как использовать эти данные — на ваше усмотрение. Вы можете отобразить цены и названия продуктов из полученного списка, а можете названия и цены указать в ресурсах приложения.
Самое время теперь что-то купить!
Отдельно хочется сказать про dataSignature. Пример ее проверки есть тут, но если ваша покупка валидируется на сервере — то это лишний шаг.
Также может быть полезной возможность получить информацию о уже совершенных покупках:
Это тоже нужно выполнять из фонового потока. Здесь вернется список покупок, которые мы совершили ранее. Также можно получить и список активных подписок.
Следующий шаг — использование покупки. Имеется в виду, что вы начисляете пользователю что-то за покупку, а сама покупка пропадает, давая таким возможность совершить покупку еще раз.
После этого вы уже не сможете прочитать данные о покупке — она будет недоступна через getPurchases().
Здесь наши возможности по использованию биллинга непосредственно на устройстве заканчиваются.
Часть 3: Валидация покупок и подписок на сервере
Это самая интересная часть, над которой я бился дольше всего. Все примеры будут на java, для которой Google предоставляет готовую библиотеку для работы со своими сервисами.
Библиотеки и для других языков можно поискать здесь. Документация по Google Publisher API находится тут, в контексте текущей задачи нас интересуют Purchases.products и Purchases.subscriptions.
По сути, главная проблема, с которой я столкнулся, это описание способа авторизации. Даже по самому описанию он выглядит как пятая нога у коня, но проблема не в том, что он не работает, а в том, что он в корне не верный для нашей задачи. Просьба к знатокам не кидаться в меня камнями: OAuth предназначен для работы с ресурсами клиента, в нашем же случае backend-сервис обращается за данными биллинга нашего собственного приложения.
И вот тут нам на помощь приходит IAM (Identy Access Management). Нам нужно создать проект в Google Cloud Console и зайти во вкладку Credentials, выбрать Create credentials → Service account key.
Заполните данные так, как показано на картинке:
Service account: New service account
Service account name: имя на выбор
Role: не выбирайте, она сейчас не нужна
Key type: JSON
Нажимаете Create. Вылезет окошко с предупреждением Service account has no role. Соглашается, выбираем CREATE WITHOUT ROLE. Вам автоматически загрузится JSON-файл с данными для авторизации аккаунта. Сохраните этот файл — в будущем он понадобится для того, чтобы авторизоваться на Google-сервисах.
Теперь возвращаемся на вкладку Credentials нашего проекта и видим внизу список Service account keys. Справа кнопка Manage service accounts — нажимаем на нее и видим:
myaccount@project-name.iam.gserviceaccount.com — это и есть id нашего аккаунта. Копируем его и идем в Google Play Developer Console → Settings → User Accounts & Rights и выбираем Invite new user.
Вставляем id аккаунта в поле Email, добавляем наше прилождение и ставим галочку напротив View financial reports.
Нажимаем Send Invitation. Теперь мы можем использовать наш JSON-файл для авторизации и Google API и доступа к данным покупок и подписок нашего приложения.
Следующий шаг — нужно активировать Google Play Developer API для нашего проекта. Идем в Google Developer Console → Library и ищем Google Play Developer API. Открываем его и нажимаем Enable.
Последний шаг настройки — идем в Google Play Developer Console → Settings → API Access.
В списке находим наш проект (на картинке выше это Google Play Android Developer, но там должно быть имя вашего проекта) и нажимаем Link.
Теперь перейдем к разработке серверной части
Как вы будете хранить JSON-файл с приватными данными IAM-аккаунта оставим на ваше усмотрение. Импортируйте Google Play Developer API в ваш проект (mavencentral) и реализуем проверку.
Данные о покупке нужно отправить с нашего приложения на сервер. Сама реализация проверки на сервере выглядит вот так:
Таким образом мы получаем возможность получить данные о нашей покупке непосредственно от Google, потому пропадает необходимость в проверке подписи. Более того, для подписок вы можете получить намного больше информации, чем непосредственно через IInAppBilligService в мобильном приложении.
В качестве параметров запроса нам нужны:
- packageName — имя пакета приложения (com.example.myapp)
- productId — идентификатор продукта (com.example.myapp_testing_inapp1)
- token — уникальный токен покупки, который вы получили в мобльном приложении:
Детали по ProductPurchase и SubscriptionPurchase описаны в документации, не будем на них останавливаться.
Вместо заключения
Сначала казавшаяся простой задача по интеграции биллинга в наш сервис превратилась в путешествие через документацию, гуглинг и бессилие (OAuth, ты прекрасен), так как про использование IAM для целей доступа в документации ни слова. Серьезно, они предлагают вбить руками какой-то руками состряпанный URL в вашем браузере, добавить origin для редиректа в консоли управления проектом, и все это для того, чтобы получить одноразовый токен, который надо руками передать на сервер, после чего использовать весь флоу OAuth для получения доступа к данным биллинга. Это не говоря о том, что если вы не успеете использовать refresh-token, то вам придется получать новый токен — руками. Согласитесь — это звучит как полный бред для backend-сервиса, который должен работать без вмешательства человека.
Я надеюсь, что этой статьей помогу кому-то сэкономить немного времени и нервов.
Источник