В этом документе рассказывается, как интегрировать контент для однократных покупок с библиотекой Play Платежей. Также в ней рассказывается, как добавить различные способы покупки и предложения, связанные с контентом, оплачиваемым однократно.
Для контента, оплачиваемого однократно, можно настроить несколько способов покупки и предложений. Например, для одного и того же контента для однократных покупок можно настроить способ покупки "Купить" и предложение с предзаказом.
Требования
Чтобы настроить несколько предложений для контента для однократных покупок, используйте API queryProductDetailsAsync(). Устаревший API querySkuDetailsAsync() не поддерживается. Информацию о том, как использовать queryProductDetailsAsync() и версию launchBillingFlow(), которая принимает ProductDetailsParams в качестве входных данных, можно найти в разделе Этапы переноса.
Запрашивать информацию о товарах
Если для контента для однократных покупок настроено несколько предложений или способов покупки, объект ProductDetails, возвращаемый методом queryProductDetailsAsync(), может содержать несколько вариантов покупки или аренды для одного контента для однократных покупок. Чтобы получить список всех подходящих предложений для каждого объекта ProductDetails, используйте метод getOneTimePurchaseOfferDetailsList(). В списке будут только предложения и варианты покупки, доступные пользователю. Ваш код в методе onProductDetailsResponse() должен обрабатывать возвращенные предложения.
Запуск сценария оплаты
Чтобы начать запрос о покупке из приложения, вызовите метод launchBillingFlow() из основного потока приложения. Этот метод принимает ссылку на объект BillingFlowParams, который содержит соответствующий объект ProductDetails, полученный в результате вызова queryProductDetailsAsync(). Чтобы создать объект BillingFlowParams, используйте класс BillingFlowParams.Builder. Обратите внимание, что при создании объекта BillingFlowParams необходимо задать токен предложения, соответствующий предложению, выбранному пользователем.
В примере ниже показано, как запустить процесс покупки контента, оплачиваемого однократно, с несколькими предложениями.
Java
// An activity reference from which the billing flow will launch. Activity activity = ...; ImmutableList<ProductDetailsParams> productDetailsParamsList = ImmutableList.of( ProductDetailsParams.newBuilder() // retrieve a value for productDetails by calling queryProductDetailsAsync() .setProductDetails(productDetails) // to get an offer token, call // ProductDetails.getOneTimePurchaseOfferDetailsList() for a list of offers // that are available to the user .setOfferToken(selectedOfferToken) .build() ); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build(); // Launch the billing flow BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
offerToken можно найти в OneTimePurchaseOfferDetails. Когда вы показываете предложение пользователю, убедитесь, что параметры сценария оплаты настроены с правильным токеном предложения, который можно получить с помощью метода oneTimePurchaseOfferDetails.getOfferToken().
Предложения и способы покупки
Способ покупки позволяет определить, как пользователь получает доступ к контенту, его цену и регион, в котором он доступен. У одного продукта может быть несколько способов покупки, которые могут отличаться ценой в разных регионах.
В Google Play поддерживаются следующие способы покупки контента, оплачиваемого однократно:
- Способ покупки "Купить"
- Способ покупки "Взять напрокат"
Предложения – это схемы ценообразования, которые можно создавать для контента для однократных покупок. Например, вы можете создать предложение со скидкой на контент для однократных покупок.
В Google Play поддерживаются следующие предложения для контента для однократных покупок:
- Предложение с предзаказом (поддерживается только для способа покупки "Купить")
- Предложение со скидкой (поддерживается для способов покупки "Купить" и "Взять напрокат")
Способ покупки "Купить"
Способ покупки "Купить" означает обычное приобретение контента. У него есть необязательное поле legacyCompatible, которое указывает, будет ли этот способ покупки доступен в более старых версиях библиотеки Play Платежей (7 или более ранних), не поддерживающих новую модель. Для обеспечения обратной совместимости хотя бы один способ покупки должен быть отмечен как совместимый с устаревшими версиями.
Интеграция с PBL вариантов покупки и аренды выполняется одинаково. Чтобы узнать, как интегрировать способ покупки "Купить" с библиотекой Google Play Платежей, прочитайте статью Как интегрировать способ покупки "Взять напрокат" с библиотекой Google Play Платежей.
Способ покупки "Взять напрокат"
Прокат позволяет пользователям получить доступ к контенту для однократных покупок на определенный период времени. Вы можете указать срок проката и срок действия. В этом документе описано, как интегрировать способ покупки "Аренда" с библиотекой Google Play Платежей.
Как интегрировать способ покупки "Взять напрокат" с библиотекой Google Play Платежей
В этом разделе рассказывается, как интегрировать способ покупки "Аренда" с библиотекой Google Play Платежей. Предполагается, что вы знакомы с начальными этапами интеграции библиотеки Google Play Платежей, например добавлением зависимости PBL в приложение, инициализацией BillingClient и подключением к Google Play. В этом разделе рассматриваются аспекты интеграции библиотеки Google Play Платежей, относящиеся к варианту покупки "Аренда".
Чтобы настроить товары, доступные для аренды, вам нужно будет использовать новый сервис monetization.onetimeproducts Play Developer API или интерфейс Play Developer Console. Чтобы использовать сервис, можно напрямую вызывать REST API или использовать клиентскую библиотеку Java.
Запустите процесс покупки для варианта "Взять напрокат".
Чтобы запустить процесс покупки для предложения аренды, выполните следующие действия:
Получите метаданные способа покупки "Взять напрокат", используя метод
ProductDetails.oneTimePurchaseOfferDetails.getRentalDetails().В примере ниже показано, как получить метаданные для покупки с правом аренды:
Java
billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { public void onProductDetailsResponse( BillingResult billingResult, QueryProductDetailsResult productDetailsResult) { // check billingResult // … // process productDetailsList returned by QueryProductDetailsResult for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) { for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails : productDetails.getOneTimePurchaseOfferDetailsList()) { // Checks if the offer is a rent purchase option. if (oneTimePurchaseOfferDetails.getRentalDetails() != null) { // process the returned RentalDetails OneTimePurchaseOfferDetails.RentalDetails rentalDetails = oneTimePurchaseOfferDetails.getRentalDetails(); // Get rental period in ISO 8601 format. String rentalPeriod = rentalDetails.getRentalPeriod(); // Get rental expiration period in ISO 8601 format, if present. if (rentalDetails.getRentalExpirationPeriod() != null) { String rentalExpirationPeriod = rentalDetails.getRentalExpirationPeriod(); } // Get offer token String offerToken = oneTimePurchaseOfferDetails.getOfferToken(); // Get the associated purchase option ID if (oneTimePurchaseOfferDetails.getPurchaseOptionId() != null) { String purchaseOptionId = oneTimePurchaseOfferDetails.getPurchaseOptionId(); } } } } } });
Запустите сценарий оплаты.
Чтобы начать запрос на покупку из приложения, вызовите метод
launchBillingFlow()из основного потока приложения. Этот метод принимает ссылку на объектBillingFlowParams, который содержит объектProductDetails, полученный при вызовеqueryProductDetailsAsync(). Чтобы создать объектBillingFlowParams, используйте классBillingFlowParams.Builder. Обратите внимание, что при создании объектаBillingFlowParamsнеобходимо указать токен предложения, выбранного пользователем. Если пользователь может оформить прокат, он получит предложение с RentalDetails и offerId вqueryProductDetailsAsync().В примере ниже показано, как запустить сценарий оплаты:
Kotlin
// An activity reference from which the billing flow will be launched. val activity : Activity = ... val productDetailsParamsList = listOf( BillingFlowParams.ProductDetailsParams.newBuilder() // retrieve a value for productDetails by calling queryProductDetailsAsync() .setProductDetails(productDetails) // Get the offer token: // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList() // for a list of offers that are available to the user. // b. For subscriptions, call ProductDetails.getSubscriptionOfferDetails() // for a list of offers that are available to the user. .setOfferToken(selectedOfferToken) .build() ) val billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build() // Launch the billing flow val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)
Java
// An activity reference from which the billing flow will be launched. Activity activity = ...; ImmutableList<BillingFlowParams.ProductDetailsParams> productDetailsParamsList = ImmutableList.of( BillingFlowParams.ProductDetailsParams.newBuilder() // retrieve a value for "productDetails" by calling queryProductDetailsAsync() .setProductDetails(productDetails) // Get the offer token: // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList() // for a list of offers that are available to the user. // b. For subscriptions, call ProductDetails.getSubscriptionOfferDetails() // for a list of offers that are available to the user. .setOfferToken(selectedOfferToken) .build() ); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build(); // Launch the billing flow BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
offerTokenможно найти вOneTimePurchaseOfferDetails. Когда вы показываете пользователю предложение, убедитесь, что параметры платежного процесса настроены с правильным токеном предложения, который можно получить с помощью методаoneTimePurchaseOfferDetails.getOfferToken().
Предзаказ
Предзаказ позволяет настроить контент для однократных покупок так, чтобы пользователи могли приобрести его до выпуска. При оформлении предзаказа пользователь соглашается заплатить за товар в день его выпуска. Оплата не будет взиматься, если до этой даты он отменит предзаказ. В дату выпуска с покупателя списываются средства, и Play уведомляет его по электронной почте о выпуске товара.
В этом документе описано, как интегрировать предложение покупки по предзаказу в библиотеку Play Платежей.
Как интегрировать предложение с предзаказом в PBL
В этом разделе описывается, как интегрировать предложение с предзаказом с библиотекой Google Play Billing Library (PBL). Предполагается, что вы знакомы с начальными этапами интеграции библиотеки Google Play Платежей, например добавлением зависимости PBL в приложение, инициализацией BillingClient и подключением к Google Play. В этом разделе рассматриваются аспекты интеграции PBL, относящиеся к предзаказу.
Запуск процесса покупки для предложения с предзаказом
Чтобы запустить процесс покупки для предложения с предзаказом, выполните следующие действия:
Получите метаданные предложения предзаказа, используя метод
ProductDetails.oneTimePurchaseOfferDetails.getPreorderDetails(). В примере ниже показано, как получить метаданные предложения с предзаказом:Java
billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { public void onProductDetailsResponse( BillingResult billingResult, QueryProductDetailsResult productDetailsResult) { // check billingResult // … // process productDetailsList returned by QueryProductDetailsResult for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) { for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails : productDetails.getOneTimePurchaseOfferDetailsList()) { // Checks if the offer is a preorder offer. if (oneTimePurchaseOfferDetails.getPreorderDetails() != null) { // process the returned PreorderDetails OneTimePurchaseOfferDetails.PreorderDetails preorderDetails = oneTimePurchaseOfferDetails.getPreorderDetails(); // Get preorder release time in millis. long preorderReleaseTimeMillis = preorderDetails.getPreorderReleaseTimeMillis(); // Get preorder presale end time in millis. long preorderPresaleEndTimeMillis = preorderDetails.getPreorderPresaleEndTimeMillis(); // Get offer ID String offerId = oneTimePurchaseOfferDetails.getOfferId(); // Get the associated purchase option ID if (oneTimePurchaseOfferDetails.getPurchaseOptionId() != null) { String purchaseOptionId = oneTimePurchaseOfferDetails.getPurchaseOptionId(); } } } } } });
Запустите сценарий оплаты.
Чтобы отправить запрос о покупке из приложения, вызовите метод
launchBillingFlow()из основного потока приложения. Этот метод принимает ссылку на объектBillingFlowParams, который содержит объектProductDetails, полученный при вызове queryProductDetailsAsync(). Чтобы создать объектBillingFlowParams, используйтеBillingFlowParams.Builder class. Обратите внимание, что при создании объектаBillingFlowParamsнеобходимо указать токен, соответствующий выбранному пользователем специальному предложению. Если пользователь соответствует условиям предзаказа, он получит его с PreorderDetails и offerId в методеqueryProductDetailsAsync().В примере ниже показано, как запустить сценарий оплаты:
Java
// An activity reference from which the billing flow will launch. Activity activity = ...; ImmutableList productDetailsParamsList = ImmutableList.of( ProductDetailsParams.newBuilder() // retrieve a value for productDetails by calling queryProductDetailsAsync() .setProductDetails(productDetails) // to get an offer token, call // ProductDetails.getOneTimePurchaseOfferDetailsList() for a list of offers // that are available to the user .setOfferToken(selectedOfferToken) .build() ); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build(); // Launch the billing flow BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
Значение
offerTokenможно найти вOneTimePurchaseOfferDetails. Когда вы показываете пользователю предложение, убедитесь, что параметры платежного процесса настроены с правильным токеном предложения, который можно получить с помощью методаoneTimePurchaseOfferDetails.getOfferToken().
Скидка
В этом разделе описывается, как настроить скидки на контент, оплачиваемый однократно.
В предложении со скидкой на контент для однократных покупок можно настроить четыре параметра:
Цена со скидкой. Указывается в процентах или в абсолютном значении.
Доступность в странах или регионах. Указывает, доступно ли предложение контента, оплачиваемого однократно, в определенной стране или регионе.
Лимит покупки (необязательно). Укажите, сколько раз пользователь может воспользоваться одним и тем же предложением. Если пользователь превысит лимит на покупки, он не сможет воспользоваться предложением.
Ограниченный период времени (необязательно). Укажите период времени, в течение которого действует предложение. Вне этого периода времени предложение будет недоступно для покупки.
Как получить информацию о цене со скидкой
Для предложения со скидкой можно получить процент скидки или абсолютную скидку.
Пример 1. Получение процентной скидки для предложения со скидкой
В следующем примере показано, как получить полную цену предложения со скидкой и размер скидки в процентах. Обратите внимание, что информация о скидке в процентах возвращается только для предложений со скидкой.
Java
billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { public void onProductDetailsResponse( BillingResult billingResult, QueryProductDetailsResult productDetailsResult){ // check billingResult // … // process productDetailsList returned by QueryProductDetailsResult for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) { for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails : productDetails.getOneTimePurchaseOfferDetailsList()) { long discountedOfferPriceMicros = oneTimePurchaseOfferDetails.getPriceAmountMicros(); // process the returned fullPriceMicros and percentageDiscount. if (oneTimePurchaseOfferDetails.getFullPriceMicros() != null) { long fullPriceMicros = oneTimePurchaseOfferDetails.getFullPriceMicros(); } if (oneTimePurchaseOfferDetails.getDiscountDisplayInfo() != null) { long percentageDiscount = oneTimePurchaseOfferDetails .getDiscountDisplayInfo() .getPercentageDiscount(); } // … } } } });
Пример 2. Получение абсолютной скидки для специального предложения
В следующем примере показано, как получить исходную полную цену предложения со скидкой и абсолютную скидку в микроединицах. Обратите внимание, что абсолютная скидка в микродолларах возвращается только для предложений со скидкой. Для предложения скидки необходимо указать абсолютную или процентную скидку.
Java
billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { public void onProductDetailsResponse( BillingResult billingResult, QueryProductDetailsResult productDetailsResult) { // check billingResult // … // process productDetailsList returned by QueryProductDetailsResult for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) { for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails : productDetails.getOneTimePurchaseOfferDetailsList()) { long discountedOfferPriceMicros = oneTimePurchaseOfferDetails.getPriceAmountMicros(); // process the returned fullPriceMicros and absolute DiscountAmountMicros. if (oneTimePurchaseOfferDetails.getFullPriceMicros() != null) { long fullPriceMicros = oneTimePurchaseOfferDetails.getFullPriceMicros(); } if (oneTimePurchaseOfferDetails.getDiscountDisplayInfo() != null) { long discountAmountMicros = oneTimePurchaseOfferDetails .getDiscountDisplayInfo() .getDiscountAmount() .getDiscountAmountMicros(); } // … } } } });
Как узнать, в течение какого времени действует предложение
Чтобы узнать, в течение какого времени действует предложение, используйте метод OneTimePurchaseOfferDetails.getValidTimeWindow(). Этот объект содержит время начала и окончания временного интервала в миллисекундах.
В примере ниже показано, как получить действительный временной интервал для предложения.
Java
billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { public void onProductDetailsResponse( BillingResult billingResult, QueryProductDetailsResult productDetailsResult) { // check billingResult // … // process productDetailsList returned by QueryProductDetailsResult for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) { for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails : productDetails.getOneTimePurchaseOfferDetailsList()) { if (oneTimePurchaseOfferDetails.getValidTimeWindow() != null) { // process the returned startTimeMillis and endTimeMillis. ValidTimeWindow validTimeWindow = oneTimePurchaseOfferDetails.getValidTimeWindow(); long startTimeMillis = validTimeWindow.getStartTimeMillis(); long endTimeMillis = validTimeWindow.getEndTimeMillis(); // … } } } } });
Ограниченное количество на уровне предложения со скидкой
Вы можете указать максимальное количество товаров на уровне предложения со скидкой. Пример
- У компании Super screensavers есть два предложения для заставок: заставка по обычной цене и заставка со скидкой.
- Для заставки не задано ограниченное количество.
- В заставке со скидкой для максимального количества предложений установлено значение 3.
- Для заставки не задано максимальное количество, поэтому пользователи могут покупать ее неограниченно.
- У пользователя есть одна заставка со скидкой, и он планирует купить ещё одну, используя эту заставку.
- При получении доступных предложений значение LimitedQuantityInfo для заставки с вариантом покупки равно null, а оставшееся количество для заставки со скидкой – 2.
В примере ниже показано, как получить ограниченное количество товаров на уровне предложения со скидкой:
Java
billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { public void onProductDetailsResponse( BillingResult billingResult, QueryProductDetailsResult productDetailsResult) { // check billingResult // … // process productDetailsList returned by QueryProductDetailsResult for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) { for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails : productDetails.getOneTimePurchaseOfferDetailsList()) { if (oneTimePurchaseOfferDetails.getLimitedQuantityInfo() != null) { // process the returned maximumQuantity and remainingQuantity. LimitedQuantityInfo limitedQuantityInfo = oneTimePurchaseOfferDetails.getLimitedQuantityInfo(); int maximumQuantity = limitedQuantityInfo.getMaximumQuantity(); int remainingQuantity = limitedQuantityInfo.getRemainingQuantity(); // … } } } } });
Когда пользователи используют максимальное количество погашений для специального предложения, оно не возвращается методом getOneTimePurchaseOfferDetailsList().
Рассчитать лимит на использование
В следующем примере показано, как получить информацию об ограниченном количестве товаров, на которые распространяется скидка. Вы можете узнать максимально допустимое количество и оставшееся количество для текущего пользователя. Обратите внимание, что ограничение количества можно задавать как для расходуемых, так и для нерасходуемых товаров, оплачиваемых однократно. Эта функция поддерживается только на уровне предложения.
Google Play вычитает количество товаров, которыми уже владеет пользователь, из максимально допустимого количества, которое вы указали. При подсчете количества принадлежащих пользователю товаров Google Play учитывает использованные и ожидающие покупки. Покупки, которые были отменены, возвращены или по которым был выполнен возврат платежа, не учитываются в количестве приобретенного контента. Пример:
Суперзаставки позволяют настроить предложение со скидкой, в котором можно купить только одну заставку.
Пользователь покупает одну из заставок со скидкой. Если пользователь попытается купить вторую заставку со скидкой, произойдет ошибка и
PurchasesUpdatedListenerполучит код ответа ITEM_UNAVAILABLE.Пользователь запрашивает возврат средств за первоначально приобретенную заставку со скидкой и получает его. Пользователь пытается купить одну из заставок со скидкой, и покупка будет успешной.
Требования к стране и региону
Вы можете выбрать страны или регионы, в которых пользователям будет доступно предложение или скидка на способ покупки. Google Play будет оценивать соответствие пользователей требованиям на основе страны, указанной в Google Play. Если вы настроите региональную доступность для предложения, оно будет возвращаться в составе getOneTimePurchaseOfferDetailsList(), только если пользователь находится в целевой стране или регионе. В противном случае предложение не будет включено в список, возвращаемый при вызове queryProductDetailsAsync().
Теги специальных предложений
В примере ниже показано, как получить теги, связанные со специальным предложением.
Java
billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { public void onProductDetailsResponse( BillingResult billingResult, QueryProductDetailsResult productDetailsResult) { // check billingResult // … // process productDetailsList returned by QueryProductDetailsResult for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) { for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails : productDetails.getOneTimePurchaseOfferDetailsList()) { // process the returned offer tags. ImmutableList<String> offerTags = oneTimePurchaseOfferDetails.getOfferTagsList(); // … } } } });
Наследование тегов специальных предложений
Теги можно задавать для товаров, способов покупки и скидок. Предложения со скидкой наследуют теги от предложения, связанного с вариантом покупки. Если теги предложений указаны на уровне товара, то теги предложений товара наследуются как предложениями вариантов покупки, так и предложениями скидок.
Например, у компании "Суперзаставки" есть два предложения для заставки: покупка заставки и заставка со скидкой.
- У заставки Суперспасибо есть тег предложения товара
SSProductTag. - У заставки с вариантами покупки есть тег предложения
SSPurchaseOptionTag. - У заставки со скидкой есть тег предложения
SSDiscountOfferTag.
В этом примере метод oneTimePurchaseOfferDetails.getOfferTagsList() для предложения способа покупки возвращает значения SSProductTag и SSPurchaseOptionTag. Для предложения со скидкой метод возвращает SSProductTag, SSPurchaseOptionTag и SSDiscountOfferTag.