1. Обзор
Оптимизируйте свои потоки дохода и уверенно запускайте свое приложение с помощью этого практического руководства по интеграции Play Billing Library от Google Play. Это структурированное руководство проведет вас через настройку, тестирование и внедрение надежной обработки покупок, что позволит вам достичь ваших целей монетизации и обеспечить более удобный пользовательский интерфейс.
Мы поможем вам настроить уведомления для разработчиков в режиме реального времени (RTDN) и Play Billing Lab для подписок и разовых продуктов для ваших приложений и игр. Вы узнаете, как снизить отток подписчиков; защититься от мошенничества и злоупотреблений; тестировать нестандартные сценарии; моделировать, воспроизводить и устранять потенциальные проблемы; а также экспериментировать с предложениями и изменениями цен без ущерба для пользователей.
В итоге вы будете готовы внедрять стратегии по возвращению клиентов, быстро решать проблемы интеграции, повышать рентабельность инвестиций, обеспечивать высококачественный пользовательский опыт и уверенно запускать приложение и его обновления.
Предварительные требования
- Знание базовой интеграции Play Billing Library
- Знание разработки приложений для Android (Java)
Что вы узнаете
- Как правильно управлять жизненным циклом покупок, чтобы оптимизировать рост, используя методы повышения конверсии и удержания клиентов.
- Как настроить уведомления для разработчиков в режиме реального времени (RTDN) с помощью Google Cloud Pub/Sub, которые затем можно использовать для реализации кампаний по возвращению клиентов и других стратегий управления жизненным циклом продукта.
- Как настроить приемник на вашем бэкэнд-сервере для безопасной обработки уведомлений с точным отслеживанием и определением прав доступа, чтобы снизить риски непреднамеренных возвратов средств, мошенничества и злоупотреблений.
- Как протестировать интеграцию и смоделировать ошибки с помощью Play Billing Lab, чтобы улучшить пользовательский опыт и снизить затраты на разработку.
Что вам понадобится
- Получите доступ к учетной записи разработчика Play для вашего приложения в Google Play Console.
- Доступ к вашему проекту на платформе Google Cloud Platform с включенным API разработчика Google Play.
- Серверная часть для обработки учетных записей и прав доступа для вашего Android-приложения.
- В консоли разработчика Play зарегистрированы тестировщики лицензий для вашего приложения.
- Приложение Play Billing Lab установлено на вашем тестовом устройстве.
2. Стратегии монетизации подписок и разовых покупок
При продаже цифровых продуктов через приложение успешная стратегия монетизации должна учитывать весь пользовательский опыт, как при разовых покупках, так и при подписках. Бесперебойный пользовательский опыт может повысить готовность к покупке и снизить отток клиентов.
Типичный процесс покупки — разовая покупка или подписка — включает в себя несколько этапов:
- Пользователь просматривает товары для покупки.
- Запустите процесс оформления покупки, чтобы пользователь мог завершить покупку и оплату.
- Сообщите официанту о завершении покупки.
- Подтвердите покупку на своем сервере.
- Предоставьте пользователю контент.
- Подтвердите доставку контента. В случае с расходными товарами, употребите покупку в подходящее время, чтобы пользователь мог приобрести товар снова.
Интеграция внутри приложения позволяет запускать процессы покупки и управлять пользовательским опытом, но крайне важно поддерживать актуальность информации о приобретаемых пользователями правах доступа в бэкэнде. Это важно для отслеживания покупок и управления другими аспектами пользовательского опыта, такими как кроссплатформенные права доступа.
Уведомления разработчиков в режиме реального времени (RTDN) — отличный способ отслеживать различные этапы жизненного цикла покупки и могут эффективно использоваться как инструмент отслеживания эффективности в режиме реального времени, так и инструмент для реализации стратегий по возвращению абонентов.
Например: Допустим, пользователь только что приобрел новый товар или пропустил платеж, и подписка перешла в льготный период. С помощью подходящего RTDN вы можете практически в режиме реального времени определить изменение статуса пользователя и принять соответствующие меры, либо еще больше вовлекая пользователя в процесс покупки, либо отправляя ему напоминания по электронной почте о необходимости обновить платежные данные для продолжения подписки.
RTDN также являются отличным способом добавить дополнительные элементы управления на стороне сервера, чтобы помочь вам управлять покупками даже в случае проблем с клиентским устройством пользователя. Допустим, пользователь успешно совершил покупку и получил подтверждение от Google, но его устройство теряет сетевое соединение до того, как ваше приложение получит уведомление о покупке через обработчик покупок. С помощью RTDN вы получите независимое уведомление через свой сервер, что позволит вам распознать покупку и предоставить пользователю право на покупку независимо от проблемы с клиентским устройством, обеспечивая надежный процесс покупки.
Подробнее обо всех поддерживаемых в настоящее время типах RTDN можно узнать здесь . Каждый тип RTDN сигнализирует об отдельном статусе покупки. Крайне важно реализовать соответствующие механизмы обработки, чтобы обеспечить надлежащую обработку в соответствии с вашими сценариями использования. В этом практическом занятии мы рассмотрим пример обработки сообщения RTDN на вашем защищенном бэкэнд-сервере, включая получение сообщения, проверку покупки и предоставление права доступа соответствующему пользователю, когда пользователь успешно завершит покупку в вашем приложении. Далее мы покажем, как настроить RTDN для вашего приложения.
3. Настройте уведомления для разработчиков в режиме реального времени (RTDN)
Уведомления для разработчиков в режиме реального времени (RTDN) используют Google Cloud Pub/Sub , позволяя мгновенно реагировать на изменения состояния покупки. Cloud Pub/Sub — это полностью управляемый сервис обмена сообщениями в режиме реального времени, который можно использовать для отправки и получения сообщений между независимыми приложениями. Google Play использует Cloud Pub/Sub для публикации push-уведомлений по темам, на которые вы подписаны.
Для включения RTDN необходимо сначала настроить Cloud Pub/Sub, используя собственный проект Google Cloud Platform (GCP), а затем включить уведомления для вашего приложения. Если вы не знакомы с GCP и Cloud Pub/Sub, см. руководство по быстрому запуску .
Создать тему
Чтобы начать получать уведомления, необходимо создать тему , в которую Google Play будет публиковать уведомления. Для создания темы следуйте инструкциям в разделе «Создание темы» .
Создать подписку Pub/Sub
Для получения сообщений, опубликованных в определенной теме, необходимо создать подписку Pub/Sub на эту тему. Для создания подписки Pub/Sub выполните следующие действия:
- Ознакомьтесь с руководством по настройке подписки Cloud Pub/Sub, чтобы понять, как настроить подписку: как подписку с отправкой сообщений (push subscription) или подписку с получением сообщений (pull subscription) . В этом практическом занятии мы будем работать с подпиской с получением сообщений, которая требует от вашего защищенного бэкэнд-сервера инициировать запросы к серверу Cloud Pub/Sub для получения сообщений.
- Чтобы создать подписку, следуйте инструкциям в разделе «Добавить подписку» .
Предоставьте права на публикацию по вашей теме.
Для работы Cloud Pub/Sub необходимо предоставить Google Play права на публикацию уведомлений в вашей теме.
- Откройте консоль Google Cloud .
- Выберите свой проект, затем введите в строку поиска " Pub/Sub" и перейдите на страницу настроек Pub/Sub.

- Найдите свою тему и откройте настройки прав доступа.

- Нажмите «ДОБАВИТЬ ОСНОВНОГО ПОЛЬЗОВАТЕЛЯ» , чтобы добавить учетную запись службы
google-play-developer-notifications@system.gserviceaccount.comи предоставить ей роль издателя/подписчика .
- Нажмите «Сохранить» , чтобы завершить настройку темы.

Включите RTDN для вашего приложения.
Научитесь настраивать уведомления для разработчиков в режиме реального времени (RTDN), чтобы значительно улучшить интеграцию с Play Billing. Вы сможете повысить надежность покупок благодаря персонализированным сообщениям, а также предотвратить мошенничество и злоупотребления, что улучшит общую рентабельность инвестиций.
RTDN обеспечивают мгновенное обновление данных между серверами непосредственно из Google Play для ключевых событий, таких как продление подписки, новые покупки и проблемы с оплатой. Они помогают вашим внутренним системам автоматически синхронизироваться с реальным статусом прав пользователей, преодолевая ограничения на стороне клиента и позволяя вам мгновенно и адекватно реагировать.
Как включить уведомления для разработчиков в режиме реального времени для вашего приложения:
- Откройте консоль Google Play .
- Выберите приложение.
- Перейдите в раздел «Монетизация через Play» > «Настройка монетизации» .
- Прокрутите страницу до раздела «Уведомления для разработчиков в режиме реального времени» .
- Установите флажок «Включить уведомления в режиме реального времени» .
- В поле «Имя темы» введите полное имя темы Cloud Pub/Sub, которое вы настроили ранее. Имя темы должно быть в формате projects/{project_id}/topics/{topic_name}, где project_id — это уникальный идентификатор вашего проекта, а topic_name — имя темы, созданной ранее.
- Нажмите «Отправить тестовое сообщение» , чтобы отправить тестовое сообщение. Выполнение тестовой публикации помогает убедиться в правильности настройки всего процесса. Если тестовая публикация прошла успешно, отобразится сообщение об успешном завершении. Если вы подключили подписку к этой теме, вы должны получить тестовое сообщение. Для подписки типа «запрос» перейдите к подписке в Cloud Console, нажмите «Просмотреть сообщения» и перейдите к отправке сообщений. Вам следует подтвердить каждое полученное сообщение, чтобы избежать повторной доставки Cloud Pub/Sub. Для подписки типа «отправка» проверьте, доставлено ли тестовое сообщение на вашу конечную точку отправки. Код успешного ответа будет служить подтверждением. Если публикация не удалась, отобразится ошибка. Убедитесь, что имя темы указано правильно и что учетная запись службы
google-play-developer-notifications@system.gserviceaccount.comимеет доступ издателя Pub/Sub к этой теме. - Выберите, какие типы уведомлений вы хотели бы получать.
- Получайте уведомления о подписках и всех аннулированных покупках — получайте уведомления от разработчиков в режиме реального времени, касающиеся подписок и аннулированных покупок. Вы не будете получать уведомления о разовых покупках продуктов.
- Получайте все уведомления о подписках и разовых покупках — уведомления обо всех событиях, связанных с подписками и аннулированными покупками. Вы также будете получать уведомления о событиях, связанных с разовыми покупками товаров, таких как
ONE_TIME_PRODUCT_PURCHASEDиONE_TIME_PRODUCT_CANCELED. Подробнее об этих событиях см. в разделе «Жизненный цикл разовых покупок».

- Нажмите «Сохранить изменения» .
Теперь вы завершили настройку уведомлений для разработчиков в режиме реального времени для вашего приложения, предоставив инструменты для решения распространенных проблем, таких как отток пользователей с помощью сообщений для возврата, а также мошенничество и злоупотребления. В следующем разделе мы создадим подписчика на вашем защищенном бэкэнд-сервере для получения сообщений, отправляемых в вашу тему Cloud Pub/Sub.
4. Получать уведомления
Для обеспечения наилучшего пользовательского опыта в вашем приложении крайне важно поддерживать актуальность информации о статусе покупок на вашем бэкэнд-сервере. Например, когда пользователь успешно совершает покупку с оплатой в приложении, контент должен быть доставлен на его аккаунт как можно скорее.
Для этого необходимо своевременно обнаруживать и обрабатывать завершение покупки. Play Billing Library предоставляет несколько способов обнаружения покупок в вашем приложении. После обнаружения завершенной покупки ваше приложение должно уведомить ваш бэкэнд-сервер о проверке покупки, предоставить контент нужному пользователю, а затем уведомить Google о том, что покупка обработана. Однако может случиться так, что ваше приложение не обнаружит покупку своевременно по разным причинам. Например, пользователь может совершить успешную покупку и получить подтверждение от Google, но его устройство потеряет сетевое соединение до того, как ваше приложение получит уведомление через интерфейс Play Billing Library. RTDN предоставляет дополнительные средства управления на стороне сервера, которые помогут вам управлять покупками даже при возникновении проблем с клиентским устройством пользователя. RTDN гарантирует независимые уведомления на ваш сервер при изменении статуса покупки, позволяя вам распознавать изменения статуса покупки практически мгновенно по второму пути, независимо от потенциальных проблем с клиентом, обеспечивая более надежный процесс покупки.
В этом разделе вы создадите подписчика для получения сообщений, отправляемых в вашу тему Cloud Pub/Sub, используя клиентские библиотеки Cloud Pub/Sub . Эти библиотеки доступны на различных языках программирования. В следующих разделах мы добавим в подписчика функции проверки покупки, предоставления прав доступа нужному пользователю и подтверждения/получения покупки на сервере. Для этого практического занятия мы используем Java.
Каждая публикация в тему Cloud Pub/Sub содержит одно поле данных, закодированное в формате Base64.
{
"message": {
"attributes": {
"key": "value"
},
"data": "eyAidmVyc2lvbiI6IHN0cmluZywgInBhY2thZ2VOYW1lIjogc3RyaW5nLCAiZXZlbnRUaW1lTWlsbGlzIjogbG9uZywgIm9uZVRpbWVQcm9kdWN0Tm90aWZpY2F0aW9uIjogT25lVGltZVByb2R1Y3ROb3RpZmljYXRpb24sICJzdWJzY3JpcHRpb25Ob3RpZmljYXRpb24iOiBTdWJzY3JpcHRpb25Ob3RpZmljYXRpb24sICJ0ZXN0Tm90aWZpY2F0aW9uIjogVGVzdE5vdGlmaWNhdGlvbiB9",
"messageId": "136969346945"
},
"subscription": "projects/myproject/subscriptions/mysubscription"
}
После декодирования данных, закодированных в формате base64, уведомление DeveloperNotification будет содержать следующие поля:
{
"version": string,
"packageName": string,
"eventTimeMillis": long,
"oneTimeProductNotification": OneTimeProductNotification,
"subscriptionNotification": SubscriptionNotification,
"voidedPurchaseNotification": VoidedPurchaseNotification,
"testNotification": TestNotification
}
Для получения более подробной информации обратитесь к справочнику по уведомлениям разработчиков в режиме реального времени .
Ниже приведён пример кода NotificationReceiver для вашего защищённого бэкэнд-сервера, предназначенного для обработки сообщений Pub/Sub. Для аутентификации в Центре управления безопасностью настройте учетные данные приложения по умолчанию (см. раздел «Настройка аутентификации для локальной среды разработки») .
import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
import java.util.Base64;
import org.json.JSONObject;
/** Real-time developer notifications receiver. */
public class NotificationReceiver {
private NotificationReceiver() {}
/*
* Receive notification messages from the subscription.
*
* @param projectId The project ID of your Google Cloud Project.
* @param subscriptionId The subscription ID of the subscriber to the pub/sub topic.
*/
public static void receiveNotificationMessages(String projectId, String subscriptionId) {
ProjectSubscriptionName subscriptionName =
ProjectSubscriptionName.of(projectId, subscriptionId);
try {
Subscriber subscriber =
Subscriber.newBuilder(subscriptionName, new NotificationMessageReceiver()).build();
// Start the subscriber.
subscriber.startAsync().awaitRunning();
subscriber.awaitTerminated();
} catch (IllegalStateException e) {
System.out.println("Subscriber stopped: " + e);
}
}
static class NotificationMessageReceiver implements MessageReceiver {
@Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
// Decode the data into a String from the message data field.
String jsonString = new String(Base64.getDecoder().decode(message.getData().toStringUtf8()));
// Parse the String into a JSON object.
JSONObject messageJson = new JSONObject(jsonString);
// Fetch the value for certain fields.
String version = messageJson.getString("version");
String packageName = messageJson.getString("packageName");
System.out.println("version: " + version);
System.out.println("packageName: " + packageName);
// Validate the purchase and grant the entitlement as needed.
// More details in the following sections.
// ......
// Acknowledge the message to avoid repeated delivery.
consumer.ack();
}
}
}
Теперь у вас есть приемник уведомлений, который обрабатывает сообщения, отправленные в вашу тему Cloud Pub/Sub, на вашем защищенном бэкэнд-сервере. В следующих разделах мы рассмотрим лучшие практики обработки сообщений RTDN на вашем бэкэнд-сервере.
5. Добавьте идентификаторы пользователей в процесс покупки в вашем приложении.
Когда ваш сервер получает сообщение RTDN об обновлении статуса покупки, ему необходимо знать, какой пользователь совершил покупку, чтобы обработать её, например, доставить контент нужному пользователю. Этого можно добиться, добавив любые имеющиеся у вас идентификаторы пользователя, совершившего покупку, используя параметр obfuscatedAccountId при запуске процесса покупки в вашем приложении. Примером идентификатора может быть зашифрованная версия логина пользователя в вашей системе. Установка этого параметра может помочь Google выявлять мошенничество . Кроме того, это поможет вам убедиться, что покупки приписываются правильному пользователю, как обсуждалось в разделе «Предоставление прав пользователям» .
Ниже приведены примеры кода для присвоения идентификатора пользователя при запуске процесса покупки в приложении путем установки параметра obfuscatedAccountId .
// An activity reference from which the billing flow will be launched.
Activity activity = ...;
// A user identifier, e.g. an obfuscated user id in your system.
String obfuscatedAccountId = ...;
ImmutableList<ProductDetailsParams> productDetailsParamsList =
ImmutableList.of(
ProductDetailsParams.newBuilder()
// retrieve a value for "productDetails" by calling queryProductDetailsAsync()
.setProductDetails(productDetails)
// set the offer token to specify the offer to purchase when applicable, e.g., subscription products
// .setOfferToken(offerToken)
.build()
);
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.setObfuscatedAccountId(obfuscatedAccountId)
.build();
// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
Как вы увидите в следующем разделе, идентификатор пользователя, заданный в процессе покупки, будет включен в покупку и может быть использован для предоставления прав соответствующему пользователю.
6. Проверяйте покупки перед предоставлением прав.
В этом разделе мы рассмотрим лучшие практики проверки покупок перед предоставлением прав доступа на вашем защищенном серверном сервере.
После того, как пользователь совершит разовую покупку продукта, подписчик Pub/Sub на вашем защищенном бэкэнд-сервере получит сообщение Pub/Sub. Вам следует выполнить следующие действия на вашем бэкэнд-сервере:
- Проанализируйте значение
purchaseTokenиз сообщения Pub/Sub. Вам следует вести учет всех значенийpurchaseTokenдля всех покупок. - Убедитесь, что значение
purchaseTokenдля текущей покупки не совпадает ни с одним из предыдущих значенийpurchaseToken.purchaseTokenявляется глобально уникальным, поэтому вы можете безопасно использовать его в качестве первичного ключа в вашей базе данных. - Используйте конечную точку purchases.products:get в API разработчиков Google Play, чтобы подтвердить Google легитимность покупки.
- Если покупка совершена законно и ранее не использовалась, вы можете смело предоставить право на получение внутриигрового предмета или подписки.
- Предоставлять права следует только тогда, когда состояние покупки —
PURCHASED, и необходимо корректно обрабатыватьPENDINGпокупки. Дополнительную информацию можно найти в разделе «Обработка ожидающих транзакций» .
Приведённый ниже пример кода создаёт API-клиент для Google Play Developer API. Мы будем использовать его для выполнения API-запросов позже.
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisherScopes;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
/** Helper class to initialize the publisher APIs client library. */
public class AndroidPublisherHelper {
/* Your application name */
private static final String APPLICATION_NAME = "YourApplicationName";
/* Load credentials from a JSON key file. Replace with the actual path to your downloaded service
* account key file.
*/
private static final String RESOURCES_CLIENT_SECRETS_JSON =
"/path/to/your/service_account_key.json";
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
/* The API client */
private static final AndroidPublisher ANDROID_PUBLISHER = init();
/**
* Performs all necessary setup steps for running requests against the API.
*
* @return the {@link AndroidPublisher} service
*/
private static AndroidPublisher init(){
try {
// Authorization.
Credential credential =
GoogleCredential.fromStream(
AndroidPublisherHelper.class.getResourceAsStream(RESOURCES_CLIENT_SECRETS_JSON))
.createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
// Set up and return API client.
return new AndroidPublisher.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(ApplicationConfig.APPLICATION_NAME)
.build();
} catch (GeneralSecurityException | IOException ex) {
throw new RuntimeException("fail to initialize the publisher APIs client library", ex);
}
}
}
Затем мы добавляем логику для выполнения вызова API и модифицируем ранее созданный приемник для проверки покупки и предоставления прав доступа соответствующему пользователю.
В AndroidPublisherHelper добавьте следующий метод для получения объекта ProductPurchase из конечной точки Purchases.products:get в Google Play Developer API.
/* Fetch the ProductPurchase for the one-time product purchase from
* Purchases.products.get endpoint in the Google Play Developer API
*/
public static ProductPurchase executeProductPurchasesGet(
String packageName, String sku, String purchaseToken) {
try {
ProductPurchase productPurchase =
ANDROID_PUBLISHER.purchases().products().get(packageName, sku, purchaseToken).execute();
return productPurchase;
} catch (IOException ex) {
log.error("Exception was thrown while getting a product purchase", ex);
// It is recommended to apply some retry mechanism, such as exponential backoff, to fetch the purchase in case of transient failures.
return null;
}
}
В компоненте NotificationMessageReceiver проверьте покупку и предоставьте право доступа соответствующему пользователю в вашей системе на основе данных, содержащихся в уведомлении. Для предотвращения дублирования обработки необходимо постоянно отслеживать purchaseToken на вашем сервере.
@Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
// Decode the data into a String from the message data field.
String jsonString = new String(Base64.getDecoder().decode(message.getData().toStringUtf8()));
// Parse the String into a JSON object.
JSONObject messageJson = new JSONObject(jsonString);
// Fetch the value for certain fields.
String version = messageJson.getString("version");
String packageName = messageJson.getString("packageName");
// Process notification data based on your business requirements.
// Process oneTimeProductNotification in the message.
JSONObject oneTimeProductNotificationJson =
messageJson.getJSONObject("oneTimeProductNotification");
if (oneTimeProductNotificationJson != null) {
String purchaseToken = oneTimeProductNotificationJson.getString("purchaseToken");
String sku = oneTimeProductNotificationJson.getString("sku");
int notificationType = oneTimeProductNotificationJson.getInt("notificationType");
if (notificationType == 1) {
// ONE_TIME_PRODUCT_PURCHASED - A one-time product was successfully purchased by a user.
// Verify that the purchaseToken value does not match any previous purchaseToken values in
// your backend system to avoid duplicate processing.
......
// Fetch the ProductPurchase from Purchases.products.get endpoint
ProductPurchase productPurchase =
AndroidPublisherHelper.executeProductPurchasesGet(packageName, sku, purchaseToken);
if (productPurchase != null && productPurchase.getPurchaseState() == 0) {
// The purchase is valid and in PURCHASED state.
// The account Id set in the App when launching the billing flow.
String obfuscatedExternalAccountId = productPurchase.getObfuscatedExternalAccountId();
// Grant the entitlement to the correct account for obfuscatedExternalAccountId in your
// system.
......
}
}
// Process subscriptionNotification in the message.
JSONObject subscriptionNotificationJson = messageJson.getJSONObject("subscriptionNotification");
if (subscriptionNotificationJson != null) {
......
}
// Process other notification data in the message as needed.
......
}
// Acknowledge the message to avoid repeated delivery.
consumer.ack();
}
7. Уведомите Google о том, что покупка обработана.
После предоставления права на использование продукта, вам следует уведомить Google о завершении покупки, вызвав конечные точки purchases.products:consume или purchases.products:acknowledge в Play Developer API со своего защищенного бэкэнд-сервера, чтобы использовать продукт, который можно использовать, или подтвердить использование продукта, который нельзя использовать.
В AndroidPublisherHelper добавьте следующие методы для вызова purchases.products:consume или purchases.products:acknowledge в API разработчиков Google Play.
/* Consume the one-time product purchase by calling
* Purchases.products.consume endpoint in the Google Play Developer API
*/
public static void executeProductPurchasesConsume(
String packageName, String sku, String purchaseToken) {
try {
ANDROID_PUBLISHER
.purchases().products().consume(packageName, sku, purchaseToken).execute();
} catch (IOException ex) {
log.error("Exception was thrown while consuming a product purchase", ex);
// It is recommended to apply some retry mechanism, such as exponential backoff, to ensure the purchase is correctly consumed in case of transient failures.
}
}
/* Acknowledge the one-time product purchase by calling
* Purchases.products.acknowledge endpoint in the Google Play Developer API
*/
public static void executeProductPurchasesAcknowledge(
String packageName, String sku, String purchaseToken) {
try {
ANDROID_PUBLISHER
.purchases().products().acknowledge(packageName, sku, purchaseToken, new ProductPurchasesAcknowledgeRequest()).execute();
} catch (IOException ex) {
log.error("Exception was thrown while acknowledging a product purchase", ex);
// It is recommended to apply some retry mechanism, such as exponential backoff, to ensure the purchase is correctly acknowledged in case of transient failures.
}
}
В NotificationMessageReceiver используйте приобретенный расходуемый продукт или подтвердите покупку нерасходуемого продукта после предоставления права доступа на вашем бэкэнд-сервере.
@Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
......
String obfuscatedExternalAccountId = productPurchase.getObfuscatedExternalAccountId();
// Grant the entitlement to the correct account for obfuscatedExternalAccountId in your
// system.
......
// If the product is a consumable product, consume the purchase.
AndroidPublisherHelper.executeProductPurchasesConsume(packageName, sku, purchaseToken);
// Or if the product is a non-consumable product, acknowledge the purchase.
// AndroidPublisherHelper.executeProductPurchasesAcknowledge(packageName, sku, purchaseToken);
......
}
Подтверждение покупки необходимо, поскольку оно уведомляет Google Play о том, что пользователю предоставлено право на совершение покупки. Подтверждать покупку следует сразу после предоставления права на её совершение.
Отличная работа! Вы успешно интегрировали систему уведомлений для разработчиков в режиме реального времени, обеспечив надежную обработку покупок, как показано в этом практическом примере. Теперь, чтобы убедиться, что все работает идеально, давайте изучим Play Billing Lab — удобный инструмент, разработанный для тестирования вашей интеграции с Play Billing.
8. Протестируйте с помощью Play Billing Lab.
Для уверенного запуска необходимо тестировать интеграцию на протяжении всего процесса разработки. Play Billing Lab — это бесплатное приложение для Android, которое помогает разработчикам тестировать интеграцию с платежной системой Google Play, предоставляя простой и удобный способ тестирования функций Play Billing, ускорения интеграции и более уверенного запуска.
Play Billing Lab предлагает различные функции тестирования, помогающие проверить разные сценарии, в том числе:
- Измените страну воспроизведения в Play Billing Lab и примените настройки к своему тесту. Это позволит тестировать пользовательские интерфейсы в разных странах/регионах независимо от того, где физически находится тестировщик.
- Протестируйте пробные или ознакомительные предложения несколько раз с одной и той же учетной записью.
- Протестируйте изменение цен на подписку, не затрагивая других активных подписчиков.
- Имитация кода ответа библиотеки Play Billing для тестирования в различных сценариях ошибок.
- Ускорьте продление подписки для ускорения тестирования.
- Протестируйте с использованием реальных способов оплаты , чтобы обойти определенные сигналы риска, связанные с процессом покупки.
Мы постоянно добавляем новые возможности тестирования в приложение Play Billing Lab. Вы можете скачать и установить Play Billing Lab из Play Store или ознакомиться с информацией о тестировании с помощью Play Billing Lab в разделе «Тестирование интеграции ».
Используйте Play Billing Lab для тестирования BillingResponseCode.
Тестирование всех потоков BillingResponseCode при интеграции вашего приложения с библиотекой Play Billing — распространенная проблема, поскольку у вас мало контроля над взаимодействием между Play Store и бэкэндом Play. Функция симулятора ответов в приложении Play Billing Lab позволяет настроить ответы с кодами ошибок для библиотеки Play Billing, чтобы протестировать различные сложные сценарии ошибок.
Например, вы реализовали в своем приложении логику, которая обрабатывает покупку после того, как приложение подтвердит ее успешное совершение. Вы хотите протестировать сценарий, когда ваше приложение не смогло обработать покупку из-за сбоя сети, и RTDN-приемник на вашем бэкэнд-сервере получает сообщение и корректно обрабатывает покупку. Для моделирования этого сценария в рамках тестирования вы можете использовать Response Simulator. Ниже описаны шаги по тестированию с помощью Play Billing Lab Response Simulator.
Тестирование с помощью симулятора отклика
При тестировании с помощью Response Simulator ваше приложение будет взаимодействовать с Play Billing Lab для получения кода ответа, который вы настроили в Play Billing Lab Response Simulator.
Включите тестирование переопределений платежей для библиотеки Play Billing.
Для обеспечения связи между симулятором ответов и вашим приложением необходимо сначала включить тестирование переопределения платежей для библиотеки Play Billing в вашем приложении. Для этого добавьте следующие метатеги в файл AndroidManifest.xml вашего приложения.
<manifest ... >
<application ... >
...
<meta-data
android:name="com.google.android.play.largest_release_audience.NONPRODUCTION"
android:value="" />
<meta-data
android:name="com.google.android.play.billingclient.enableBillingOverridesTesting"
android:value="true" />
</application>
</manifest>
Создайте своё приложение, используя обновлённый файл AndroidManifest.xml . Теперь ваше приложение готово к работе в симуляторе ответов Play Billing Lab.
При развертывании приложения в производственной среде после тестирования следует либо использовать отдельный файл AndroidManifest.xml , не содержащий эти метатеги, либо убедиться, что эти теги удалены из файла AndroidManifest.xml .
Имитация ошибок библиотеки Play Billing.
Для тестирования с использованием смоделированных ошибок библиотеки Play Billing сначала настройте код ответа в приложении Play Billing Lab, а затем выполните тест в своем приложении.
Настройте код ответа
- Войдите в приложение Play Billing Lab, используя учетную запись тестировщика лицензий для вашего приложения. На следующем изображении показана панель управления Play Billing Lab, включая карточку симулятора ответа .

- Чтобы перейти к экрану «Симулятор реагирования», нажмите кнопку «Управление» на карточке «Симулятор реагирования».
- При появлении запроса разрешите уведомления от Play Billing Lab, чтобы видеть статус подключения вашего приложения.
- Включите переключатель «Имитировать ответ библиотеки Play Billing», если он еще не включен.

- Выберите код ответа для API библиотеки Play Billing, который вы хотите протестировать. Чтобы имитировать ошибку при совершении покупки, выберите код ошибки для API
consumeAsync. Ваши настройки будут сохранены автоматически. Теперь симулятор ответов готов отправить выбранные коды ответов в ваше приложение.
Протестируйте своё приложение
Теперь вы можете протестировать свое приложение, чтобы убедиться, что все работает должным образом в настроенном сценарии ошибки. Откройте приложение и вызовите метод API библиотеки Play Billing. Если ваше приложение выполнит вызов consumeAsync для оплаты покупки, оно получит код ошибки, как вы только что настроили. Вы можете проверить, правильно ли работает ваше приложение при получении кода ошибки и корректно ли ваш сервер обрабатывает покупку.
После завершения тестирования просто выключите переключатель «Имитировать ответ библиотеки Play Billing», чтобы остановить имитацию ответа.
Узнайте больше о тестировании с помощью Play Billing Lab или посетите Справочный центр, чтобы получить дополнительную информацию о тестировании внутриигровых покупок с помощью License Testers .
9. Поздравляем!
Вы завершили этот практический урок и теперь готовы стратегически оптимизировать монетизацию вашего приложения, чтобы улучшить пользовательский опыт, повысить удовлетворенность пользователей, конверсию покупок и снизить отток подписчиков.
Благодаря уведомлениям разработчиков в режиме реального времени и сопутствующему приложению Play Billing Lab вы можете заблаговременно отслеживать события жизненного цикла покупки как для разовых покупок , так и для подписок .
С помощью этих инструментов вы сможете эффективно внедрять привлекательные стратегии по возвращению клиентов, быстро решать проблемы интеграции и, в конечном итоге, улучшать пользовательский опыт и потоки доходов, чтобы уверенно запустить свое приложение или игру.
Пройдя этот практический курс, вы получите навыки управления всем процессом покупки и сможете тщательно протестировать свою реализацию с помощью Play Billing Lab, обеспечивая бесперебойную работу для пользователей и максимизируя потенциал монетизации в Google Play.