Android подписка in app

Android in-app purchases, часть 2: инициализация и обработка покупок

Это вторая статья из нашего цикла о реализации покупок на Android. В первой статье мы рассказывали о том, как создавать продукты в Google Play Console, сконфигурировать подписки и получить список продуктов в приложении. Cоветую познакомиться и с остальными:

Android in-app purchases, часть 2: инициализация и обработка покупок. — Вы тут

В прошлой части мы создали класс-обертку для работы с Billing Library:

Класс-обертка для работы с Billing Library

Перейдем дальше к реализации покупки и дополним наш класс.

Создание экрана с подписками

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

На данном этапе для примера мы сделали упрощённый вариант пейволла:

Итак, на нашем пейволле располагаются следующие элементы:

Набор кнопок для инициализации процесса покупки. На них указаны основные свойства продуктов: название и цена в местной валюте.

Кнопка восстановления прошлых покупок. Этот элемент необходим для всех приложений, в которых используются подписки либо non-consumable покупки.

Доработка кода для отображения информации о продуктах

В нашем примере четыре продукта:

две автовозобновляемые подписки («premium_sub_month» и «premium_sub_year»);

продукт, который нельзя купить повторно, — non-consumable (“unlock_feature”);

продукт, который можно покупать много раз, — consumable (“coin_pack_large”).

Для упрощения примера будем использовать Activity, в которую заинжектим BillingClientWrapper из предыдущей статьи, и layout с жестко заданным количеством кнопок для покупки.

Для удобства добавим словарь, где ключом является sku продукта, а значением — соответствующая кнопка на экране.

Объявим метод для отображения продуктов в UI, опираясь на логику из предыдущей статьи:

product.price — это уже отформатированная строка с указанием местной валюты для данного аккаунта, здесь никакое дополнительное форматирование не нужно; остальные поля в объекте класса SkuDetails также приходят уже с учетом локализации.

Запуск процесса покупки

Для проведения покупки необходимо вызвать метод launchBillingFlow() из главного потока приложения.

Добавим для этого метод purchase() в BillingClientWrapper :

У метода launchBillingFlow() нет колбэка, ответ вернется в метод onPurchasesUpdated() . Помните, мы в прошлой статье его объявили, но оставили на потом? Вот сейчас он нам понадобится.

Метод onPurchasesUpdated() вызывается при каком-либо результате после взаимодействия пользователя с диалогом покупки. Это может быть успешная покупка, отмена покупки (пользователь закрыл диалог, в этом случае приходит код BillingResponseCode.USER_CANCELED) или же какая-то другая ошибка.

По аналогии с интерфейсом OnQueryProductsListener из предыдущей статьи, объявим в классе BillingClientWrapper интерфейс OnPurchaseListener , с помощью которого будем получать либо покупку (объект класса Purchase — о кейсе, когда он может быть null даже в случае успеха, расскажем в следующей статье), либо ошибку, которую мы также объявляли в предыдущей статье:

И реализуем его в PaywallActivity:

Добавим логику в onPurchaseUpdated():

Если purchaseList не пустой, для начала для каждой покупки делаем проверку, что ее purchasedState равен PurchaseState.PURCHASED, потому что покупки также могут быть отложенными, и в этом случае флоу на данном этапе прекращается. Далее, согласно документации, нужно сделать серверную верификацию покупки, о ней мы расскажем в следующих статьях. После этого надо предоставить пользователю доступ к контенту и сообщить об этом в Google. Если не сообщить, то через три дня покупка автоматически отменится. Интересно, что это характерно только для Google Play, в то время как на iOS такого нет. Сообщить о предоставлении доступа к контенту можно двумя способами:

В случае с consumable-продуктом вместо него нужно вызвать метод consumeAsync() , который под капотом делает acknowledge, а заодно дает возможность покупать этот продукт повторно. Это можно сделать только с помощью Billing Library: Google Play Developer API почему-то не предоставляет возможность делать это на бэкенде. Любопытно, что, в отличие от Google Play, в App Store и в AppGallery свойство consumable за продуктом жестко определено на уровне App Store Connect и AppGallery Connect соответственно. Справедливости ради, замечу, что консьюмить такие продукты из AppGallery нужно всё-таки явно.

Напишем методы для acknowledge и consume, а также две версии метода processPurchase() — в случае, когда у нас есть свой бэкенд и когда его нет.

Без серверной верификации:

С серверной верификацией:

Подробнее о серверной верификации покупок мы расскажем в одной из следующих статей.

Во втором примере acknowledge, конечно, тоже можно было сделать на клиенте, но так как здесь у нас есть бэкенд, всё, что можно сделать на бэке, лучше отдать бэку. Что касается ошибок на acknowledge и consume, их нельзя игнорировать, потому что если ни одно из этих действий не произойдет в течение трёх дней после того, как покупка получила статус PurchaseState.PURCHASED, она отменится, а пользователю вернут средства. Поэтому, если мы не можем это сделать на бэкенде, и даже после нескольких повторных попыток всё еще получаем ошибку, самый надежный способ — получать текущие покупки пользователя в каком-нибудь методе жизненного цикла, например в onStart() или onResume(), и пытаться повторить в надежде, что пользователь в течение трёх дней зайдет в наше приложение при работающем интернете :).

Читайте также:  Фоторедактор айфон для андроид

Таким образом, текущая версия класса BillingClientWrapper будет выглядеть так:

Вы могли задаться вопросом, почему кнопки активны для всех продуктов, независимо от того, покупал их пользователь или нет. Или что будет, если купить обе подписки: заменит ли вторая первую или они обе будут сосуществовать. Всё это в следующих статьях 🙂

Про Adapty

Он не только упрощает работу по добавлению покупок:

Встроенная аналитика позволяет быстро понять основные метрики приложения.

Когортный анализ отвечает на вопрос, как быстро сходится экономика.

А/Б тесты увеличивают выручку приложения.

Интеграции с внешними системами позволяют отправлять транзакции в сервисы атрибуции и продуктовой аналитики.

Промо-кампании уменьшают отток аудитории.

Open source SDK позволяет интегрировать подписки в приложение за несколько часов.

Серверная валидация и API для работы с другими платформами.

Познакомьтесь подробнее с этими возможностями, чтобы быстрее внедрить подписки в своё приложение и улучшить конверсии.

Источник

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 для работы с другими платформами.

Познакомьтесь подробнее с этими возможностями, чтобы быстрее внедрить подписки в своё приложение и улучшить конверсии.

Источник

Как внедрить in-app подписки в Android-приложения: советы и рекомендации

С каждым годом требования к in-app подпискам в мобильных приложениях в App Store и Google Play меняются, становится все сложнее учесть их с первого раза и не получить серию реджектов, тем самым откладывая релиз порой на несколько месяцев. Если про требования для App Store уже достаточно много публикаций (см. здесь или здесь), то с правилами in-app подписок для Google Play все еще иногда возникают вопросы.

Мы, команда из Центрального Маркетинга Mail.ru Group, решили разобраться в этом подробнее и поделиться рекомендациями по внедрению in-app подписок. По нашему наблюдению, нередко пользователи оставляют большое количество негативных отзывов (и, как следствие, у приложения снижается рейтинг), где уточняют будет ли списываться сумма за полную версию продукта ежемесячно или единоразово, как отменить подписку, в какой именно момент спишутся деньги, почему деньги продолжают списываться и другие подобные вопросы. А поддержка и вовсе иногда может не справляться с объемом запросов.

И вот, в апреле 2020 года Google обновил требования к платным in-app подпискам и обязал любые новые приложения или обновления приложений, опубликованные после 16 апреля 2020 года соответствовать требованиям последней версии Правил программы для разработчиков. Согласно данным правилам, приложениям, которые были опубликованы до 16 апреля 2020 года предоставляется 60 дней с этой даты, чтобы начать соответствовать новым требованиям, то есть до 16 июня 2020 года.

Мы уверены, что новые меры платных in-app подписок в Google Play помогут сделать условия получения услуг для пользователя более прозрачными, а также построить более доверительные отношения между пользователем и разработчиком. Мы подробно изучили данные требования, проанализировали более 100 случайных приложений и хотим поделиться своим опытом и рекомендациями с читателями.

    Старайтесь указывать, что оплата за платную in-app подписку будет списываться каждый расчетный период

Иногда пользователи уточняют у разработчиков, будет ли списана сумма единоразово или же за каждый расчетный период. Если в вашем приложении есть обе модели: единоразовая оплата (т.е. «навсегда») и платная in-app подписка, лучше указать, что в первом случае оплата происходит только один раз, а во втором — за каждый расчетный период.

Ниже мы привели пример реализации, где четко прописаны условия оплаты разных in-app покупок.

Не забудьте проверить отображение цены на экране in-app подписки

Убедитесь, что вы указываете именно ту сумму, которая спишется со счета пользователя единоразово. Например, нарушением может считаться, если на годовой подписке, стоимостью $49 вы покажете только цену в $4 в месяц.

Если полная стоимость подписки явно не выделена на экране, пользователь может не понять, что при оформлении подписки будет списано не $4, а $49.

Ниже мы привели два примера реализации: слева — указана цена за год, справа — указана цена за 1 месяц в опции про 12, что команда ревьюеров может счесть за нарушение.


Добавьте информацию о предложении и условиях использования in-app подписки

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

Читайте также:  Android studio gradle singing report

Может считаться нарушением, если на экране с предложением подписки отсутствует кнопка «Закрыть». Несмотря на то, что на Android устройствах можно вернуться на предыдущий экран по нажатию на системную кнопку «Назад», на экране с предложением об in-app стоит выделять данную опцию отдельно. Мы замечали, что некоторые разработчики отображают эту кнопку только спустя несколько секунд нахождения на экране, что также может ввести пользователя в заблуждение.

Ниже приведен пример, где на экране отсутствует возможность закрыть окно, что может считаться нарушением.

Кстати, несколько приложений при нажатии на кнопку «Закрыть» показывают особенное «one-time» предложение, что может повысить конверсию в покупку. Примеры реализации ниже:


Проверьте приложение на мислид с бесплатной пробной версией

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

Ниже приведен пример, где за предложением «Попробовать бесплатно» отсутствуют какие-либо условия.

Кстати, однажды на одном из наших UX-тестирований выяснилось, что для собственного спокойствия пользователи хотели бы видеть дополнительную информацию о конкретной дате, когда спишутся деньги. Например, такие фразы как «Не переживайте! Средства будут списаны не ранее 01/08», или «Вы можете отменить подписку в любое время» внушают доверие пользователям и они охотнее оформляют пробную версию.
А если у вас вводная цена? Подумайте о том, как лучше рассказать о ее условиях

Например, если обычная стоимость подписки $4,99 в месяц, но для большего привлечения новых пользователей вы предлагаете первые три месяца за $1, стоит заранее проинформировать об этом пользователя.
Расскажите о правилах отмены in-app подписки

Советуем убедиться, что ваше предложение раскрывает информацию об отмене и управлении in-app подпиской. Согласно правилу Google Play, при отмене купленной в приложении in-app подписки возврат средств за текущий расчетный период не производится, но контент остается доступным на протяжении текущего расчетного периода. После in-app подписка будет отменена и повторных списаний не будет.
А также, не забываем про добавление возможности восстановить покупки

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

Со своей стороны, Google также ввел новшества, чтобы напрямую предоставлять пользователям более полную информацию о платных in-app подписках. Например, теперь пользователи получают электронные письма до того, как закончится бесплатная пробная версия или ознакомительная цена, или когда будет автоматически продлена долгосрочная подписка на 3, 6 или 12 месяцев. Также придет напоминание, что удаление приложения не приведет к автоматической отмене подписки.
И, конечно же, важна локализация условий использования и предоставления предложения

Если ваше приложение локализовано на различные языки, то мы рекомендуем позаботиться и о локализации правил и условий использования in-app подписки.

Ниже мы привели такой пример из приложения. А по ссылке вы найдете локализацию условий одного из наших приложений на 12 языков.

Заключение

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

Также у разработчиков появилось несколько новых точек оптимизации in-app подписок в приложении. Уже сейчас доступна возможность уменьшить процент отмены подписок благодаря опции «преимущества». При намерении отменить оплату у пользователя появится экран с перечислением тех самых преимуществ, которые разработчик указал в специальном поле в настройках товара в Google Play Console. Кроме того, есть возможность генерировать кастомные промокоды на расширенную версию приложения. В отличие от текущих одноразовых промокодов, новые промокоды могут быть активированы сразу несколькими пользователями. Это позволит специалистам сферы маркетинга использовать кастомные промокоды в рекламных кампаниях для более эффективного привлечения пользователей.

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

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

Источник

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