1. Введение
В этой лабораторной работе вы сосредоточитесь на создании одноразового продукта, интеграции своего приложения с Play Billing Library (PBL) и анализе причин прекращения покупок.
Аудитория
Эта лабораторная работа предназначена для разработчиков приложений для Android, которые используют библиотеку Play Billing Library (PBL) или хотят использовать PBL для монетизации своих одноразовых продуктов.
Чему вы научитесь...
- Как создавать одноразовые продукты в Google Play Console.
- Как интегрировать ваше приложение с PBL.
- Как обрабатывать единовременные закупки расходных и нерасходных товаров в PBL.
- Как проанализировать отказы от покупок.
Что вам понадобится...
- Доступ к Google Play Console через учётную запись разработчика. Если у вас нет учётной записи разработчика, вам необходимо её создать .
- Пример приложения для этой лабораторной работы, который можно загрузить с GitHub .
- Android Studio .
2. Создайте пример приложения
Пример приложения разработан как полнофункциональное приложение для Android, имеющее полный исходный код, демонстрирующий следующие аспекты:
- Интеграция приложения с PBL
- Получить одноразовые продукты
- Запуск потоков закупок для одноразовых продуктов
- Сценарии покупки, которые приводят к следующим ответам по счетам:
-
BILLING_UNAVAILABLE
-
USER_CANCELLED
-
OK
-
ITEM_ALREADY_OWNED
-
В следующем демонстрационном видео показано, как будет выглядеть и вести себя пример приложения после его развертывания и запуска.
Предварительные условия
Перед сборкой и развертыванием примера приложения выполните следующие действия:
- Создайте аккаунт разработчика в Google Play Console . Если у вас уже есть аккаунт разработчика, пропустите этот шаг.
- Создайте новое приложение в Play Console . При создании приложения вы можете указать любое имя для примера приложения.
- Установить Android Studio .
Строить
Целью этого этапа сборки является создание подписанного файла пакета приложения Android для примера приложения.
Чтобы создать пакет приложения Android, выполните следующие действия:
- Загрузите пример приложения с GitHub .
- Соберите пример приложения . Перед сборкой измените имя пакета примера приложения, а затем выполните сборку. Если в Play Console есть пакеты других приложений, убедитесь, что имя пакета, указанное для примера приложения, уникально.
Примечание : при сборке примера приложения создаётся только APK-файл, который можно использовать для локального тестирования. Однако при запуске приложения не будут загружены товары и цены, поскольку они не настроены в Play Console, что мы сделаем далее в этой практической работе. - Создайте подписанный пакет приложений для Android.
Следующий шаг — загрузить пакет приложения Android в Google Play Console.
3. Создайте одноразовый продукт в Play Console.
Для создания одноразовых продуктов в Google Play Console необходимо иметь приложение в Play Console. Создайте приложение в Play Console, а затем загрузите ранее созданный подписанный пакет приложений.
Создать приложение
Чтобы создать приложение:
- Войдите в Google Play Console , используя свою учетную запись разработчика.
- Нажмите «Создать приложение» . Откроется страница «Создать приложение» .
- Введите название приложения, выберите язык по умолчанию и другие сведения, связанные с приложением.
- Нажмите «Создать приложение» . Это создаст приложение в Google Play Console.
Теперь вы можете загрузить подписанный пакет примера приложения.
Загрузите подписанный пакет приложения
- Загрузите подписанный комплект приложений во внутреннюю тестовую версию Google Play Console . Только после загрузки вы сможете настроить функции монетизации в Play Console.
- Нажмите Тестирование и выпуск > Тестирование > Внутренний выпуск > Создать новый выпуск .
- Введите название релиза и загрузите подписанный файл пакета приложения.
- Нажмите кнопку «Далее» , а затем нажмите кнопку «Сохранить и опубликовать» .
Теперь вы можете создавать свои одноразовые продукты.
Создать одноразовый продукт
Чтобы создать одноразовый продукт:
- В консоли Google Play в левом навигационном меню выберите Монетизация с Play > Продукты > Разовые продукты .
- Нажмите Создать одноразовый продукт .
- Введите следующие данные о продукте:
- ID продукта: Введите уникальный ID продукта. Введите
one_time_product_01
. - (Необязательно) Теги: добавьте соответствующие теги.
- Имя: Введите название продукта. Например,
Product name
. - Описание: Введите описание продукта. Например,
Product description
. - (Необязательно) Добавьте изображение значка: загрузите значок, представляющий ваш продукт.
- ID продукта: Введите уникальный ID продукта. Введите
- Нажмите «Далее» .
- Добавьте вариант покупки и настройте его региональную доступность. Для одноразового продукта требуется как минимум один вариант покупки, который определяет способ предоставления права, его цену и региональную доступность. В этой лабораторной работе мы добавим стандартный вариант покупки для продукта. В разделе «Вариант покупки» введите следующие данные:
- Идентификатор варианта покупки: введите идентификатор варианта покупки. Например,
buy
. - Тип покупки: выберите «Купить» .
- (Необязательно) Теги: добавьте теги, относящиеся к этому варианту покупки.
- (Необязательно) Нажмите «Дополнительные параметры» , чтобы настроить дополнительные параметры. В рамках этой практической работы настройку дополнительных параметров можно пропустить.
- Идентификатор варианта покупки: введите идентификатор варианта покупки. Например,
- В разделе Доступность и цены нажмите Установить цены > Массовое редактирование цен .
- Выберите опцию «Страна/регион» . Будут выбраны все регионы.
- Нажмите «Продолжить» . Откроется диалоговое окно для ввода цены. Введите 10 долларов США и нажмите «Применить» .
- Нажмите «Сохранить» , а затем нажмите «Активировать» . Это создаст и активирует возможность покупки.
Для целей этой лабораторной работы создайте 3 дополнительных одноразовых продукта со следующими идентификаторами продуктов:
- расходный_продукт_01
- расходный_продукт_02
- расходный_продукт_03
Пример приложения настроен на использование этих идентификаторов продуктов. Вы можете указать другие идентификаторы продуктов. В этом случае вам придётся изменить пример приложения, чтобы использовать предоставленный вами идентификатор продукта.
Откройте пример приложения в Google Play Console и перейдите в раздел «Монетизация с Play» > «Продукты» > «Разовые продукты» . Затем нажмите «Создать разовый продукт» и повторите шаги с 3 по 9.
Видео создания одноразового продукта
В следующем видео-примере показаны одноразовые этапы создания продукта, описанные ранее.
4. Интеграция с PBL
Теперь мы рассмотрим, как интегрировать ваше приложение с библиотекой Play Billing Library (PBL) . В этом разделе описываются основные этапы интеграции и приводятся фрагменты кода для каждого из них. Вы можете использовать эти фрагменты в качестве руководства для реализации интеграции.
Чтобы интегрировать ваше приложение с PBL, выполните следующие действия:
- Добавьте зависимость Play Billing Library к примеру приложения.
dependencies { val billing_version = "8.0.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
- Инициализируйте BillingClient . BillingClient — это клиентский SDK, который находится в вашем приложении и взаимодействует с библиотекой Play Billing. В следующем фрагменте кода показано, как инициализировать клиент для выставления счетов.
protected BillingClient createBillingClient() { return BillingClient.newBuilder(activity) .setListener(purchasesUpdatedListener) .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()) .enableAutoServiceReconnection() .build(); }
- Подключитесь к Google Play. Следующий фрагмент кода показывает, как подключиться к Google Play.
public void startBillingConnection(ImmutableList<Product> productList) { Log.i(TAG, "Product list sent: " + productList); Log.i(TAG, "Starting connection"); billingClient.startConnection( new BillingClientStateListener() { @Override public void onBillingSetupFinished(BillingResult billingResult) { if (billingResult.getResponseCode() == BillingResponseCode.OK) { // Query product details to get the product details list. queryProductDetails(productList); } else { // BillingClient.enableAutoServiceReconnection() will retry the connection on // transient errors automatically. // We don't need to retry on terminal errors (e.g., BILLING_UNAVAILABLE, // DEVELOPER_ERROR). Log.e(TAG, "Billing connection failed: " + billingResult.getDebugMessage()); Log.e(TAG, "Billing response code: " + billingResult.getResponseCode()); } } @Override public void onBillingServiceDisconnected() { Log.e(TAG, "Billing Service connection lost."); } }); }
- Получите информацию о разовом продукте. После интеграции приложения с PBL необходимо получить информацию о разовом продукте. Следующий фрагмент кода показывает, как получить информацию о разовом продукте в вашем приложении.
Извлечениеprivate void queryProductDetails(ImmutableList<Product> productList) { Log.i(TAG, "Querying products for: " + productList); QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder().setProductList(productList).build(); billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { @Override public void onProductDetailsResponse( BillingResult billingResult, QueryProductDetailsResult productDetailsResponse) { // check billingResult Log.i(TAG, "Billing result after querying: " + billingResult.getResponseCode()); // process returned productDetailsList Log.i( TAG, "Print unfetched products: " + productDetailsResponse.getUnfetchedProductList()); setupProductDetailsMap(productDetailsResponse.getProductDetailsList()); billingServiceClientListener.onProductDetailsFetched(productDetailsMap); } }); }
ProductDetails
дает вам ответ, подобный следующему:{ "productId": "consumable_product_01", "type": "inapp", "title": "Shadow Coat (Yolo's Realm | Play Samples)", "name": "Shadow Coat", "description": "A sleek, obsidian coat for stealth and ambushes", "skuDetailsToken": "<---skuDetailsToken--->", "oneTimePurchaseOfferDetails": {}, "oneTimePurchaseOfferDetailsList": [ { "priceAmountMicros": 1990000, "priceCurrencyCode": "USD", "formattedPrice": "$1.99", "offerIdToken": "<--offerIdToken-->", "purchaseOptionId": "buy", "offerTags": [] } ] }, { "productId": "consumable_product_02", "type": "inapp", "title": "Emperor Den (Yolo's Realm | Play Samples)", "name": "Emperor Den", "description": "A fair lair glowing with molten rock and embers", "skuDetailsToken": "<---skuDetailsToken--->", "oneTimePurchaseOfferDetails": {}, "oneTimePurchaseOfferDetailsList": [ { "priceAmountMicros": 2990000, "priceCurrencyCode": "USD", "formattedPrice": "$2.99", "offerIdToken": "<--offerIdToken-->", "purchaseOptionId": "buy", "offerTags": [] } ] }
- Запустите процесс выставления счетов.
public void launchBillingFlow(String productId) { ProductDetails productDetails = productDetailsMap.get(productId); if (productDetails == null) { Log.e( TAG, "Cannot launch billing flow: ProductDetails not found for productId: " + productId); billingServiceClientListener.onBillingResponse( BillingResponseCode.ITEM_UNAVAILABLE, BillingResult.newBuilder().setResponseCode(BillingResponseCode.ITEM_UNAVAILABLE).build()); return; } ImmutableList<ProductDetailsParams> productDetailsParamsList = ImmutableList.of( ProductDetailsParams.newBuilder().setProductDetails(productDetails).build()); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build(); billingClient.launchBillingFlow(activity, billingFlowParams); }
- Обнаружение и обработка покупок. На этом этапе вам необходимо:
- Подтвердите покупку
- Предоставить право пользователю
- Уведомить пользователя
- Уведомить Google о процессе покупки
private void handlePurchase(Purchase purchase) { // Step 1: Send the purchase to your secure backend to verify the purchase following // https://developer.android.com/google/play/billing/security#verify // Step 2: Update your entitlement storage with the purchase. If purchase is // in PENDING state then ensure the entitlement is marked as pending and the // user does not receive benefits yet. It is recommended that this step is // done on your secure backend and can combine in the API call to your // backend in step 1. // Step 3: Notify the user using appropriate messaging. if (purchase.getPurchaseState() == PurchaseState.PURCHASED) { for (String product : purchase.getProducts()) { Log.d(TAG, product + " purchased successfully! "); } } // Step 4: Notify Google the purchase was processed. // For one-time products, acknowledge the purchase. // This sample app (client-only) uses billingClient.acknowledgePurchase(). // For consumable one-time products, consume the purchase // This sample app (client-only) uses billingClient.consumeAsync() // If you have a secure backend, you must acknowledge purchases on your server using the // server-side API. // See https://developer.android.com/google/play/billing/security#acknowledge if (purchase.getPurchaseState() == PurchaseState.PURCHASED && !purchase.isAcknowledged()) { if (shouldConsume(purchase)) { ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build(); billingClient.consumeAsync(consumeParams, consumeResponseListener); } else { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); billingClient.acknowledgePurchase( acknowledgePurchaseParams, acknowledgePurchaseResponseListener); } } }
5. Анализируйте отказы от покупок
До сих пор в рамках практического занятия ответы Play Billing были сосредоточены на ограниченном количестве сценариев, таких как USER_CANCELLED , BILLING_UNAVAILABLE , OK и ITEM_ALREADY_OWNED . Однако Play Billing может возвращать 13 различных кодов ответов , которые могут быть вызваны различными реальными факторами.
В этом разделе подробно описываются причины ошибок USER_CANCELLED
и BILLING_UNAVAILABLE
, а также предлагаются возможные корректирующие действия, которые можно предпринять.
Код ошибки ответа USER_CANCELED
Этот код ответа указывает на то, что пользователь отказался от пользовательского интерфейса процесса покупки, не завершив ее.
Вероятные причины | Какие действия вы можете предпринять? |
|
|
Код ошибки ответа BILLING_UNAVAILABLE
Этот код ответа означает, что покупка не может быть завершена из-за проблемы с платёжным провайдером пользователя или выбранным им способом оплаты. Например, срок действия кредитной карты пользователя истёк или пользователь находится в стране, не поддерживаемой Google Play. Этот код не указывает на ошибку в самой системе оплаты Play Billing.
Вероятные причины | Какие действия вы можете предпринять? |
|
|
Стратегии повторных попыток для кодов ошибок ответа
Эффективные стратегии повторных попыток для устранимых ошибок в библиотеке Play Billing Library (PBL) различаются в зависимости от контекста, например, от взаимодействия пользователя в сеансе (например, во время покупки) до фоновых операций (например, запроса покупок при возобновлении работы приложения). Важно реализовать эти стратегии, поскольку некоторые значения BillingResponseCode
указывают на временные проблемы, которые можно устранить повторной попыткой, в то время как другие являются постоянными и не требуют повторных попыток.
Для ошибок, возникающих во время сеанса пользователя , рекомендуется использовать простую стратегию повторных попыток с заданным максимальным количеством, чтобы минимизировать помехи в работе пользователя. Напротив, для фоновых операций , таких как подтверждение новых покупок, которые не требуют немедленного выполнения, рекомендуется экспоненциальная задержка .
Подробную информацию о конкретных кодах ответов и соответствующих им рекомендуемых стратегиях повторных попыток см. в разделе Обработка кодов ответов BillingResult .
6. Дальнейшие шаги
- Узнайте, как максимально эффективно интегрировать биллинговые функции в ваши игры .
- Не забывайте следовать рекомендациям по проверке и обработке покупок в вашей защищенной системе, как только пользователи начнут покупать эти продукты.
Справочные документы
7. Поздравляем!
Поздравляем! Вы успешно создали новый одноразовый продукт в Google Play Console, протестировали коды ответов на платежи и проанализировали отказы от покупок.
Опрос
Мы очень ценим ваши отзывы об этой лабораторной работе. Уделите несколько минут и пройдите наш опрос.