Увеличьте интеграцию Play Billing

1. Обзор

Оптимизируйте свои потоки доходов и уверенно запускайте свое приложение с помощью этой лабораторной работы по интеграции Play Billing Library от Google Play. Эта структурированная лабораторная работа проведет вас через настройку, тестирование и реализацию надежной обработки покупок, позволяя вам поддерживать ваши цели монетизации и предоставлять более бесперебойный пользовательский опыт.

Мы поможем вам настроить уведомления разработчиков в реальном времени (RTDN) и Play Billing Lab для подписок и одноразовых продуктов для ваших приложений и игр. Вы узнаете, как сократить отток подписчиков; защититься от мошенничества и злоупотреблений; протестировать пограничные случаи; смоделировать, воспроизвести и устранить потенциальные проблемы; и поэкспериментировать с предложениями и изменениями цен, не влияя на пользователей.

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

Предпосылки

Чему вы научитесь

  • Как правильно управлять жизненным циклом покупок, чтобы оптимизировать рост с помощью методов повышения конверсии покупок и удержания клиентов
  • Как настроить уведомления для разработчиков в режиме реального времени (RTDN) с помощью Google Cloud Pub/Sub, которые затем можно использовать для реализации кампаний по возврату клиентов и других стратегий управления жизненным циклом
  • Как настроить приемник на вашем внутреннем сервере для безопасной обработки уведомлений с точным отслеживанием и предоставлением прав для снижения непреднамеренных возвратов средств или рисков мошенничества и злоупотреблений
  • Как протестировать интеграцию и смоделировать ошибки с помощью Play Billing Lab, чтобы улучшить пользовательский опыт и сократить затраты на разработку

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

  • Доступ к учетной записи разработчика Play для вашего приложения в Google Play Console
  • Доступ к вашему проекту Google Cloud Platform с включенным Google Play Developer API
  • Внутренний сервер для управления учетными записями и правами для вашего приложения Android.
  • Лицензируйте тестировщиков, зарегистрированных для вашего приложения в Play Developer Console
  • Play Billing Lab установлен на вашем тестовом устройстве

2. Стратегии монетизации подписок и разовых покупок

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

Обычный процесс покупки при единовременной покупке или подписке будет включать несколько этапов:

  1. Пользователь просматривает товары для покупки.
  2. Запустите процесс покупки, чтобы пользователь мог завершить покупку и оплату.
  3. Уведомите свой сервер о совершенной покупке
  4. Подтвердите покупку на вашем сервере.
  5. Предоставьте контент пользователю.
  6. Подтвердите доставку контента. Для потребляемых продуктов потребляйте покупку в подходящее время, чтобы пользователь мог купить товар снова.

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

Уведомления разработчиков в режиме реального времени (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, выполните следующие действия:

  1. Прочитайте руководство по подписке Cloud Pub/Sub, чтобы ознакомиться с тем, как настроить подписку как push-подписку или pull-подписку . В этой кодовой лаборатории мы будем работать с pull-подпиской, которая требует, чтобы ваш защищенный внутренний сервер инициировал запросы к серверу Cloud Pub/Sub для получения сообщений.
  1. Чтобы создать подписку, следуйте инструкциям в разделе «Добавление подписки» .

Предоставьте права на публикацию по вашей теме

Cloud Pub/Sub требует предоставления вам прав Google Play для публикации уведомлений по вашей теме.

  1. Откройте Google Cloud Console .
  2. Выберите свой проект, затем найдите « Pub/Sub» в строке поиска и перейдите на страницу конфигурации Pub/Sub. Search and land on the Pub/Sub config page
  3. Найдите свою тему и откройте настройки разрешений. Open the permission setting
  4. Нажмите ДОБАВИТЬ ГЛАВНОГО , чтобы добавить учетную запись службы google-play-developer-notifications@system.gserviceaccount.com и предоставить ей роль издателя Pub/Sub . Add the service account google-play-developer-notifications@system.gserviceaccount.com, and grant it the role of Pub/Sub Publisher
  5. Нажмите «Сохранить» , чтобы завершить настройку темы. Click Save to complete the topic set up.

Включите RTDN для вашего приложения

Узнайте, как настроить уведомления разработчиков в режиме реального времени (RTDN), чтобы значительно улучшить интеграцию Play Billing. Вы можете повысить надежность покупок с помощью персонализированных сообщений, а также предотвратить мошенничество и злоупотребления, чтобы улучшить общую рентабельность инвестиций.

RTDN обеспечивают немедленные обновления сервер-сервер напрямую из Google Play для ключевых событий, таких как продление подписки, новые покупки и проблемы с оплатой. Они помогают вашим бэкэнд-системам автоматически синхронизироваться с реальным статусом прав пользователя, выходя за рамки ограничений на стороне клиента и позволяя вам реагировать мгновенно и соответствующим образом.

Как включить уведомления разработчиков в режиме реального времени для вашего приложения:

  1. Откройте Google Play Console .
  2. Выберите свое приложение.
  3. Перейдите в раздел Монетизация с Play > Настройка монетизации .
  4. Прокрутите страницу до раздела «Уведомления разработчиков в режиме реального времени» .
  5. Установите флажок Включить уведомления в реальном времени .
  6. В поле Название темы введите полное название темы Cloud Pub/Sub, которое вы настроили ранее. Название темы должно быть в формате projects/{project_id}/topics/{topic_name}, где project_id — уникальный идентификатор вашего проекта, а topic_name — название темы, созданной ранее.
  7. Нажмите Отправить тестовое сообщение , чтобы отправить тестовое сообщение. Выполнение тестовой публикации помогает убедиться, что все настроено и сконфигурировано правильно. Если тестовая публикация прошла успешно, отображается сообщение о том, что тестовая публикация прошла успешно. Если вы прикрепили подписку на эту тему, вы должны получить тестовое сообщение. Для подписки pull перейдите к подписке в Cloud Console, нажмите Просмотреть сообщения и продолжите получать сообщения. Вам следует подтвердить получение любого сообщения, которое вы получили, чтобы избежать повторной доставки Cloud Pub/Sub. Для подписки push проверьте, доставлено ли тестовое сообщение на вашу конечную точку push. Успешный код ответа будет служить сообщением подтверждения. Если публикация не удалась, отображается ошибка. Убедитесь, что имя темы указано правильно и что учетная запись службы google-play-developer-notifications@system.gserviceaccount.com имеет доступ Pub/Sub Publisher к теме.
  8. Выберите, какие типы уведомлений вы хотите получать.
  • Получайте уведомления о подписках и всех аннулированных покупках — получайте уведомления разработчиков в режиме реального времени, связанные с подписками и аннулированными покупками. Вы не будете получать уведомления о единовременных покупках продуктов.
  • Получайте все уведомления о подписках и одноразовых продуктах — получайте уведомления обо всех событиях подписки и аннулированных покупках. Вы также будете получать события одноразовой покупки продукта, такие как ONE_TIME_PRODUCT_PURCHASED и ONE_TIME_PRODUCT_CANCELED . Подробнее об этих событиях покупки см. в разделе Жизненный цикл одноразовой покупки.

a266e5dec5c93cd8.png

  1. Нажмите Сохранить изменения .

Теперь вы завершили уведомления разработчиков в реальном времени для вашего приложения, предоставляя вам инструменты для решения распространенных проблем, таких как отток пользователей через сообщения о возврате или мошенничество и злоупотребления. В следующем разделе мы создадим подписчика на вашем защищенном сервере бэкэнда для потребления сообщений, отправленных в вашу тему 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. Вам следует сделать следующее на вашем сервере бэкэнда:

  1. Разберите purchaseToken из сообщения Pub/Sub. Вам следует вести учет всех значений purchaseToken для всех покупок.
  2. Убедитесь, что значение purchaseToken для текущей покупки не совпадает ни с одним из предыдущих значений purchaseToken . purchaseToken является глобально уникальным, поэтому вы можете безопасно использовать это значение в качестве первичного ключа в вашей базе данных.
  3. Используйте конечную точку purchases.products:get в API разработчика Google Play, чтобы подтвердить в Google, что покупка является законной.
  1. Если покупка является законной и не использовалась в прошлом, вы можете смело предоставить право на внутриигровой элемент или подписку.
  2. Вы должны предоставить право только тогда, когда состояние покупки — PURCHASED , и убедитесь, что правильно обрабатываете PENDING покупки. Вы можете найти больше информации в разделе Обработка ожидающих транзакций .

Следующий пример кода создает API-клиент для API разработчика Google Play. Мы будем использовать его для выполнения вызовов 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 в API разработчика Google Play.

 /* 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 в API разработчика Play с вашего защищенного внутреннего сервера, чтобы потребить потребляемый продукт или подтвердить непотребляемый продукт.

В AndroidPublisherHelper добавьте следующие методы для вызова purchases.products:consum или 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 Lab из Play Store или ознакомиться с разделом Тестирование интеграции для получения дополнительной информации о тестировании с Play Billing Lab.

Используйте Play Billing Lab для тестирования BillingResponseCode

Это обычная проблема — тестировать все потоки BillingResponseCode при интеграции вашего приложения с Play Billing Library, поскольку у вас нет особого контроля над коммуникацией между Play Store и бэкэндом Play. Функция Response Simulator в приложении Play Billing Lab позволяет вам настраивать ответы кодов ошибок для Play Billing Library для тестирования различных сложных сценариев ошибок.

Например, вы реализовали логику в своем приложении для использования покупки после того, как ваше приложение обнаружит успешную покупку. Вы хотели бы протестировать сценарий, в котором ваше приложение не смогло использовать покупку из-за сбоя сети, а приемник RTDN на вашем внутреннем сервере принимает сообщение и правильно обрабатывает покупку. Вы можете использовать Response Simulator для моделирования сценария для вашего тестирования. Ниже приведены шаги для тестирования с помощью Response Simulator от Play Billing Lab.

Тест с помощью симулятора реакции

При тестировании с помощью Response Simulator ваше приложение будет связываться с Play Billing Lab, чтобы получить код ответа, который вы настроили в Response Simulator Play Billing Lab.

Включить тестирование переопределения биллинга для библиотеки Play Billing

Чтобы включить связь между Response Simulator и вашим приложением, вы должны сначала включить тестирование переопределений выставления счетов для Play Billing Library из вашего приложения. Для этого добавьте следующие теги метаданных в файл 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 Response Simulator.

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

Моделирование ошибок библиотеки Play Billing

Чтобы провести тестирование с имитацией ошибок Play Billing Library, сначала настройте код ответа в приложении Play Billing Lab, а затем выполните тестирование в своем приложении.

Настройте код ответа

  1. Войдите в приложение Play Billing Lab с учетной записью тестера лицензий для вашего приложения. На следующем рисунке показана панель инструментов Play Billing Lab, включая карточку Response Simulator .

Воспроизведение панели мониторинга Billing Lab с помощью симулятора Response

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

c841baa4c96bf306.png

  1. Выберите код ответа для API Play Billing Library, которые вы хотите протестировать. Чтобы смоделировать ошибку для покупки-потребления, выберите код ошибки для API consumeAsync . Ваш выбор автоматически сохраняется. Теперь Response Simulator готов отправить выбранные коды ответа в ваше приложение.

Протестируйте свое приложение

Теперь вы можете протестировать свое приложение, чтобы убедиться, что все работает так, как ожидалось в настроенном сценарии ошибки. Откройте свое приложение и запустите метод API Play Billing Library. Если ваше приложение выполняет вызов consumeAsync для потребления покупки, ваше приложение получит код ошибки, который вы только что настроили. Вы можете проверить, правильно ли работает ваше приложение, по коду ошибки и правильно ли ваш внутренний сервер обрабатывает покупку.

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

Узнайте больше о тестировании с помощью Play Billing Lab или посетите Справочный центр для получения дополнительной информации о тестировании внутриигрового биллинга с помощью License Testers .

9. Поздравляю!

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

Используя уведомления разработчиков в режиме реального времени и сопутствующее приложение Play Billing Lab , вы можете заблаговременно реагировать на события жизненного цикла покупки как для разовых покупок , так и для подписок .

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

Завершив эту лабораторную работу, вы приобретете навыки управления всем процессом покупки и тщательного тестирования своей реализации с помощью Play Billing Lab, что обеспечит бесперебойный пользовательский опыт и максимально увеличит ваш потенциал монетизации в Google Play.