1. Введение
В этом практическом занятии вы сосредоточитесь на создании разового продукта, интеграции вашего приложения с Play Billing Library (PBL) и анализе причин отказа от покупок.
Примечание : Для успешного выполнения этого практического задания вам необходим доступ к функции « Множественные варианты покупки и предложения для разовых продуктов ». Эта функция находится в программе раннего доступа (EAP). Продукты и функции в рамках EAP доступны «как есть» и могут иметь ограниченную поддержку. Чтобы получить доступ к функции EAP, отправьте запрос, используя форму заявки на участие в программе EAP для разовых продуктов . Однако, если вы хотите понять только, как анализировать отказы от покупок с помощью кодов ответов Play Billing, перейдите непосредственно к разделу «Анализ отказов от покупок» этого практического задания.
Аудитория
Данный практический курс предназначен для разработчиков Android-приложений, использующих библиотеку Play Billing Library (PBL) или желающих использовать PBL для монетизации своих разовых продуктов.
Что вы узнаете...
- Как создавать разовые продукты в консоли Google Play.
- Как интегрировать ваше приложение с PBL.
- Как обрабатывать разовые закупки расходных и нерасходных товаров в PBL.
- Как анализировать снижение количества покупок.
Что вам понадобится...
- Доступ к консоли Google Play возможен только с учетной записью разработчика. Если у вас нет учетной записи разработчика, вам необходимо ее создать .
- Пример приложения для этого практического занятия, который вы можете скачать с 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 есть пакеты других приложений, убедитесь, что имя пакета, которое вы указываете для демонстрационного приложения, уникально.
Примечание : При сборке тестового приложения создается только APK-файл, который можно использовать для локального тестирования. Однако при запуске приложения товары и цены не загружаются, поскольку они не были настроены в Play Console, что вы сделаете позже в этом практическом занятии. - Сгенерируйте подписанный пакет приложения для Android.
Следующий шаг — загрузка пакета Android-приложения в Google Play Console.
3. Создайте разовый продукт в Play Console.
Для создания разовых продуктов в Google Play Console необходимо иметь приложение в Play Console. Создайте приложение в Play Console, а затем загрузите ранее созданный подписанный пакет приложения.
Создайте приложение
Для создания приложения:
- Войдите в консоль Google Play , используя свою учетную запись разработчика.
- Нажмите «Создать приложение» . Откроется страница создания приложения .
- Введите название приложения, выберите язык по умолчанию и другие сведения о приложении.
- Нажмите «Создать приложение» . Это создаст приложение в консоли Google Play.
Теперь вы можете загрузить подписанный пакет приложения-образца.
Загрузите подписанный пакет приложения.
- Загрузите подписанный пакет приложения во внутренний тестовый трек Google Play Console . Только после загрузки вы сможете настроить функции монетизации в Play Console.
- Нажмите «Тестирование и выпуск» > «Тестирование» > «Внутренний выпуск» > «Создать новый выпуск» .
- Введите название релиза и загрузите подписанный файл пакета приложения.
- Нажмите «Далее» , а затем «Сохранить и опубликовать» .
Теперь вы можете создавать свои разовые продукты.
Создайте разовый продукт
Для создания разового продукта:
- В консоли Google Play в левом навигационном меню перейдите в раздел «Монетизация через Play» > «Продукты» > «Разовые продукты» .
- Нажмите «Создать разовый продукт» .
- Введите следующие данные о товаре:
- Идентификатор товара: Введите уникальный идентификатор товара. Введите
one_time_product_01. - (Необязательно) Теги: Добавьте соответствующие теги.
- Название: Введите название товара. Например,
Product name. - Описание: Введите описание товара. Например,
Product description. - (Необязательно) Добавьте изображение значка: Загрузите значок, представляющий ваш продукт.
- Идентификатор товара: Введите уникальный идентификатор товара. Введите
- Нажмите «Далее» .
- Добавьте вариант покупки и настройте его региональную доступность. Для разового продукта необходим как минимум один вариант покупки, который определяет способ предоставления права пользования, его цену и региональную доступность. В этом практическом задании мы добавим стандартный вариант покупки для продукта. В разделе « Варианты покупки» введите следующие данные:
- Идентификатор варианта покупки: Введите идентификатор варианта покупки. Например,
buy. - Тип покупки: Выберите «Купить» .
- (Необязательно) Теги: Добавьте теги, относящиеся к данному варианту покупки.
- (Необязательно) Нажмите «Дополнительные параметры» , чтобы настроить дополнительные параметры. В рамках данного практического занятия вы можете пропустить настройку дополнительных параметров.
- Идентификатор варианта покупки: Введите идентификатор варианта покупки. Например,
- В разделе «Доступность и цены» нажмите «Установить цены» > «Массовое редактирование цен» .
- Выберите пункт «Страна/регион» . Это выберет все регионы.
- Нажмите «Продолжить» . Откроется диалоговое окно для ввода цены. Введите 10 долларов США и нажмите «Применить» .
- Нажмите «Сохранить» , а затем « Активировать» . Это создаст и активирует опцию покупки.
Для целей данного практического занятия создайте 3 дополнительных разовых продукта со следующими идентификаторами:
- расходный_продукт_01
- расходный_продукт_02
- расходный_продукт_03
В демонстрационном приложении используются указанные идентификаторы продуктов. Вы можете указать другие идентификаторы продуктов, в этом случае вам потребуется изменить демонстрационное приложение, чтобы оно использовало указанный вами идентификатор продукта.
Откройте демонстрационное приложение в Google Play Console и перейдите в раздел «Монетизация через Play» > «Продукты» > «Разовые продукты» . Затем нажмите «Создать разовый продукт» и повторите шаги с 3 по 9.
Видео о создании одноразового продукта
В приведенном ниже видеоролике показаны этапы создания одноразового продукта, описанные ранее.
4. Интеграция с проблемно-ориентированным обучением.
Теперь мы рассмотрим, как интегрировать ваше приложение с библиотекой Play Billing (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
Этот код ошибки означает, что покупка не может быть завершена из-за проблемы с платежным провайдером пользователя или выбранным им способом оплаты. Например, срок действия кредитной карты пользователя истек или пользователь находится в стране, где не поддерживается эта система. Этот код не указывает на ошибку в самой системе Play Billing.
Вероятные причины | Какие действия вы можете предпринять? |
|
|
Повторные попытки для кодов ошибок ответа
Эффективные стратегии повторных попыток для устранения ошибок, связанных с Play Billing Library (PBL), различаются в зависимости от контекста, например, при взаимодействии пользователя в рамках сессии (например, во время покупки) или при фоновых операциях (например, при запросе информации о покупках после возобновления работы приложения). Важно внедрять эти стратегии, поскольку некоторые значения BillingResponseCode указывают на временные проблемы, которые можно решить повторной попыткой, в то время как другие являются постоянными и не требуют повторных попыток.
Для ошибок, возникающих во время сеанса пользователя , рекомендуется использовать простую стратегию повторных попыток с установленным максимальным количеством попыток, чтобы минимизировать сбои в работе пользователя. И наоборот, для фоновых операций , таких как подтверждение новых покупок, которые не требуют немедленного выполнения, рекомендуется использовать экспоненциальную задержку .
Подробную информацию о конкретных кодах ответов и соответствующих рекомендуемых стратегиях повторной попытки см. в разделе «Обработка кодов ответов BillingResult» .
6. Дальнейшие шаги
- Узнайте, как максимально эффективно использовать интеграцию с системой оплаты за использование приложения .
- Не забудьте следовать передовым методам проверки и обработки покупок в вашей защищенной серверной части, как только пользователи начнут приобретать эти товары.
Справочная документация
7. Поздравляем!
Поздравляем! Вы успешно создали новый разовый продукт в консоли Google Play, протестировали коды ответов платежных систем и проанализировали отказы от покупок.
Опрос
Мы очень ценим ваши отзывы об этом практическом занятии. Пожалуйста, уделите несколько минут заполнению нашего опроса.