В этом руководстве описывается, как интегрировать API-интерфейсы, чтобы предложить альтернативное выставление счетов по выбору пользователя в вашем приложении.
Настройка платежной библиотеки Play
Добавьте зависимость библиотеки платежей Play в свое приложение для Android. Чтобы использовать альтернативные API биллинга, вам необходимо использовать версию 5.2 или выше. Если вам необходимо перейти с более ранней версии, следуйте инструкциям в руководстве по переходу, прежде чем пытаться внедрить альтернативное выставление счетов.
Подключитесь к Google Play
Первые шаги в процессе интеграции такие же, как описано в руководстве по интеграции Google Play Billing , с некоторыми изменениями при инициализации BillingClient :
- Вам нужно вызвать новый метод, чтобы указать, что вы хотите предложить пользователю выбор вариантов выставления счетов:
enableUserChoiceBilling
. - Вам необходимо зарегистрировать
UserChoiceBillingListener
для обработки случаев, когда пользователь выбирает альтернативное выставление счетов.
В следующем примере демонстрируется инициализация BillingClient
с этими изменениями:
Котлин
val purchasesUpdatedListener =
PurchasesUpdatedListener { billingResult, purchases ->
// Handle new Google Play purchase.
}
val userChoiceBillingListener =
UserChoiceBillingListener { userChoiceDetails ->
// Handle alternative billing choice.
}
var billingClient = BillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases()
.enableUserChoiceBilling(userChoiceBillingListener)
.build()
Ява
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
// Handle new Google Play purchase.
}
};
private UserChoiceBillingListener userChoiceBillingListener = new UserChoiceBillingListener() {
@Override
public void userSelectedAlternativeBilling(
UserChoiceDetails userChoiceDetails) {
// Handle new Google Play purchase.
}
};
private BillingClient billingClient = BillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases()
.enableUserChoiceBilling(userChoiceBillingListener)
.build();
После инициализации BillingClient
вам необходимо установить соединение с Google Play , как описано в руководстве по интеграции.
Показать доступные продукты
Вы можете отображать доступные товары пользователю так же, как и при интеграции биллинговой системы Google Play. Когда ваш пользователь увидит продукты, доступные для покупки, и выберет один из них для покупки, запустите процесс выставления счетов по выбору пользователя, как описано в следующем разделе.
Запустите процесс выставления счетов по выбору пользователя
Запустите поток выставления счетов по выбору пользователя, вызвав launchBillingFlow()
. Это работает так же, как запуск процесса покупки с интеграцией биллинговой системы Google Play: вы предоставляете экземпляр ProductDetails
и offerToken
, соответствующий продукту и предложению, которое пользователь хочет приобрести. Если пользователь выбирает платежную систему Google Play, эта информация используется для продолжения процесса покупки.
Когда разработчики вызывают launchBillingFlow()
, биллинговая система Google Play выполняет следующую проверку:
- Система проверяет, является ли страна Google Play пользователя страной, поддерживающей альтернативное выставление счетов по выбору пользователя (т. е. поддерживаемой страной). Если страна Google Play пользователя поддерживается, Google Play проверяет, включено ли альтернативное выставление счетов, на основе конфигурации
BillingClient
.- Если включено альтернативное выставление счетов с выбором пользователя, в потоке покупок отображается UX выбора пользователя .
- Если альтернативный биллинг с выбором пользователя не включен, в процессе покупки отображается стандартный пользовательский интерфейс платежной системы Google Play без выбора пользователя.
- Если страна Google Play пользователя не является поддерживаемой страной, в процессе покупки отображается стандартный пользовательский интерфейс платежной системы Google Play без выбора пользователя.
Страна User's Play – поддерживаемая страна. | Страна User's Play не поддерживается. | |
---|---|---|
EnableUserChoiceBilling вызывается во время настройки BillingClient | Пользователь видит пользовательский интерфейс выбора пользователя | Пользователь видит стандартный UX биллинговой системы Google Play. |
EnableUserChoiceBilling не вызывается во время настройки BillingClient | Пользователь видит стандартный UX биллинговой системы Google Play. | Пользователь видит стандартный UX биллинговой системы Google Play. |
Обработка выбора пользователя
То, как вы обрабатываете остальную часть процесса покупки, зависит от того, выбрал ли пользователь платежную систему Google Play или альтернативную платежную систему.
Когда пользователь выбирает альтернативную платежную систему
Если пользователь выбирает альтернативную систему выставления счетов, Google Play вызывает UserChoiceBillingListener
, чтобы уведомить приложение о том, что ему необходимо запустить процесс покупки в альтернативной системе выставления счетов. В частности, вызывается метод userSelectedAlternativeBilling()
.
Токен внешней транзакции, предоставленный в объекте UserChoiceDetails
, представляет собой подпись для выбора пользователем входа в альтернативный поток выставления счетов. Используйте этот токен, чтобы сообщать о любой транзакции, возникшей в результате этого выбора, как описано в руководстве по интеграции с серверной частью .
UserChoiceBillingListener
должен выполнить следующие действия:
- Получите продукт или продукты, приобретаемые пользователем, чтобы их можно было представить в процессе покупки в альтернативной системе выставления счетов.
- Соберите строку, полученную в качестве токена внешней транзакции, и отправьте ее на серверную часть для ее сохранения. Позже это используется для сообщения о внешней транзакции в Google Play, если пользователь совершает эту конкретную покупку.
- Запустите альтернативный поток покупок застройщика.
Если пользователь совершает покупку с использованием альтернативной системы выставления счетов, вы должны сообщить об этой транзакции в Google Play, вызвав API разработчика Google Play со своей серверной части в течение 24 часов , предоставив externalTransactionToken
и дополнительные сведения о транзакции. Более подробную информацию см. в руководстве по интеграции с серверной частью .
В следующем примере показано, как реализовать UserChoiceBillingListener
:
Котлин
private val userChoiceBillingListener =
UserChoiceBillingListener { userChoiceDetails ->
// Get the products being purchased by the user.
val products = userChoiceDetails.products
// Send external transaction token to developer backend server
// this devBackend object is for demonstration purposes,
// developers can implement this step however best fits their
// app to backend communication.
devBackend.sendExternalTransactionStarted(
userChoiceDetails.externalTransactionToken,
user
)
// Launch alternative billing
// ...
// The developer backend handles reporting the transaction
// to Google Play's backend once the alternative billing
// purchase is completed.
}
Ява
private userChoiceBillingListener userChoiceBillingListener = new UserChoiceBillingListener() {
@Override
public void userSelectedAlternativeBilling(
UserChoiceDetails userChoiceDetails) {
// Get the products being purchased by the user.
List<Product> products =
userChoiceDetails.getProducts();
// Send external transaction token to developer backend server
// this devBackend object is for demonstration purposes,
// developers can implement this step however best fits their
// app to backend communication.
devBackend.sendExternalTransactionStarted(
userChoiceDetails.getExternalTransactionToken(),
user
);
// Launch alternative billing
// ...
// The developer backend handles reporting the transaction
// to Google Play's backend once the alternative billing
// purchase is completed.
}
};
Когда пользователь выбирает платежную систему Google Play
Если пользователь выбирает платежную систему Google Play, он продолжает совершать покупки через Google Play.
- Дополнительную информацию о том, как обрабатывать новые покупки в приложении через платежную систему Google Play, см. в разделе «Обработка покупок» в руководстве по интеграции библиотеки.
- Дополнительные инструкции по покупке подписки см. в разделе «Новые подписки» в руководстве по управлению подписками.
Обрабатывать изменения в подписке
Разработчикам, использующим альтернативный способ выставления счетов по выбору пользователя, покупки необходимо либо обрабатывать через платежную систему Google Play, либо сообщать о них с помощью externalTransactionId
, в зависимости от выбора пользователя. Изменения в существующих подписках, которые были обработаны посредством потока выбора пользователя, можно вносить через ту же систему выставления счетов до истечения срока их действия.
В этом разделе описывается, как обрабатывать некоторые распространенные сценарии изменения подписки.
Потоки обновления и понижения версии
Изменения плана подписки, включая процессы обновления и понижения версии, должны обрабатываться по-разному в зависимости от того, была ли подписка изначально куплена через систему выставления счетов Google Play или через альтернативную систему выставления счетов.
Дополнения, которые зависят от существующей подписки, используют один и тот же способ оплаты и согласовывают регулярные платежи, рассматриваются как обновления. Что касается других надстроек, пользователи должны иметь возможность выбирать, какую систему биллинга они хотят использовать. Инициируйте новый процесс покупки с помощью launchBillingFlow()
, как описано в разделе «Запуск процесса выставления счетов по выбору пользователя» .
Подписки, купленные через альтернативную систему биллинга
Для подписок, которые изначально были куплены через альтернативную систему выставления счетов разработчика после выбора пользователя, пользователи, запрашивающие обновление или понижение версии, должны пройти через альтернативную систему выставления счетов разработчика, не проходя повторный процесс выбора пользователя.
Для этого вызовите launchBillingFlow()
когда пользователь запрашивает обновление или понижение версии. Вместо указания объекта SubscriptionUpdateParams
в параметрах используйте setOriginalExternalTransactionId
, указав идентификатор внешней транзакции для исходной покупки. При этом экран выбора пользователя не отображается, поскольку выбор пользователя для исходной покупки сохраняется для обновлений и понижений версий. Вызов launchBillingFlow()
в этом случае генерирует новый токен внешней транзакции для транзакции, который вы можете получить из обратного вызова.
Котлин
// The external transaction ID from the current
// alternative billing subscription.
val externalTransactionId = //... ;
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(
listOf(
BillingFlowParams.ProductDetailsParams.newBuilder()
// Fetched via queryProductDetailsAsync.
.setProductDetails(productDetailsNewPlan)
// offerIdToken can be found in
// ProductDetails=>SubscriptionOfferDetails.
.setOfferToken(offerTokenNewPlan)
.build()
)
)
.setSubscriptionUpdateParams(
BillingFlowParams.SubscriptionUpdateParams.newBuilder()
.setOriginalExternalTransactionId(externalTransactionId)
.build()
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)
// When the user selects the alternative billing flow,
// the UserChoiceBillingListener is triggered.
Ява
// The external transaction ID from the current
// alternative billing subscription.
String externalTransactionId = //... ;
BillingFlowParams billingFlowParams =
BillingFlowParams.newBuilder()
.setProductDetailsParamsList(
ImmutableList.of(
ProductDetailsParams.newBuilder()
// Fetched via queryProductDetailsAsync.
.setProductDetails(productDetailsNewPlan)
// offerIdToken can be found in
// ProductDetails=>SubscriptionOfferDetails
.setOfferToken(offerTokenNewPlan)
.build()
)
)
.setSubscriptionUpdateParams(
SubscriptionUpdateParams.newBuilder()
.setOriginalExternalTransactionId(externalTransactionId)
.build()
)
.build();
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
// When the user selects the alternative billing flow,
// the UserChoiceBillingListener is triggered.
Когда обновление или понижение версии завершено в альтернативной системе выставления счетов, вам необходимо сообщить о новой транзакции, используя токен внешней транзакции, полученный в результате предыдущего вызова для покупки новой подписки.
Подписки, купленные через платежную систему Google Play.
Аналогичным образом, пользователям, которые приобрели текущую подписку через платежную систему Google Play после выбора пользователя, должен быть показан процесс обновления или понижения версии в платежной системе Google Play . В следующих инструкциях описано, как запустить процесс покупки для повышения или понижения уровня через платежную систему Google Play:
- Определите
offerToken
выбранного предложения для нового плана:
val offerTokenNewPlan = productDetailsNewPlan
.getSubscriptionOfferDetails(selectedOfferIndex)
.getOfferToken()
String offerTokenNewPlan = productDetailsNewPlan
.getSubscriptionOfferDetails(selectedOfferIndex)
.getOfferToken();
- Отправьте правильную информацию в платежную систему Google Play для обработки новой покупки, включая токен покупки для существующей подписки:
val billingFlowParams =
BillingFlowParams.newBuilder().setProductDetailsParamsList(
listOf(
BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetailsNewPlan)
.setOfferToken(offerTokenNewPlan)
.build()
)
)
.setSubscriptionUpdateParams(
BillingFlowParams.SubscriptionUpdateParams.newBuilder()
.setOldPurchaseToken(oldToken)
.setReplaceProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
.build()
)
.build()
BillingClient.launchBillingFlow(activity, billingFlowParams)
BillingFlowParams billingFlowParams =
BillingFlowParams.newBuilder()
.setProductDetailsParamsList(
ImmutableList.of(
ProductDetailsParams.newBuilder()
// Fetched via queryProductDetailsAsync
.setProductDetails(productDetailsNewPlan)
// offerIdToken can be found in
// ProductDetails=>SubscriptionOfferDetails.
.setOfferToken(offerTokenNewPlan)
.build()
)
)
.setSubscriptionUpdateParams(
SubscriptionUpdateParams.newBuilder()
// purchaseToken can be found in
// Purchase#getPurchaseToken
.setOldPurchaseToken("old_purchase_token")
.setReplaceProrationMode(ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
.build()
)
.build();
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
Эта покупка осуществляется в платежной системе Google Play, и ваше приложение получает вызов PurchasesUpdatedListener.onPurchaseUpdated
с результатом покупки. Если покупка прошла успешно, метод onPurchaseUpdated()
также получает информацию о новой покупке, а ваш сервер получает уведомление SUBSCRIPTION_PURCHASED
для разработчиков в режиме реального времени. При получении статуса новой покупки атрибут linkedPurchaseToken
ссылается на старую покупку подписки, поэтому вы можете удалить ее в соответствии с рекомендациями .
Отмена и восстановление подписки
Пользователи должны иметь возможность отменить подписку в любое время. Когда пользователь отменяет подписку, прекращение действия права может быть отложено до окончания оплаченного периода. Например, если пользователь отменяет ежемесячную подписку в середине месяца, он может продолжать пользоваться услугой в течение оставшихся примерно двух недель, пока его доступ не будет закрыт. В течение этого периода подписка по-прежнему технически активна, поэтому пользователь может пользоваться услугой.
Нередко пользователи решают отменить отмену в этот активный период. В этом руководстве это называется восстановлением . В следующих разделах описывается, как обрабатывать сценарии восстановления в альтернативной интеграции API выставления счетов.
Подписки, купленные через альтернативную систему биллинга
Если у вас есть идентификатор внешней транзакции для отмененной подписки, нет необходимости вызывать launchBillingFlow()
для восстановления подписки, поэтому его не следует использовать для этого типа активации. Если пользователь восстанавливает свою подписку, находясь в активном периоде отмененной подписки, в это время не происходит никаких транзакций; вы можете просто продолжать сообщать о продлении, когда текущий цикл истечет и произойдет следующее продление. Сюда входят случаи, когда пользователь получает кредит или специальную цену продления в рамках восстановления (например, рекламная акция, побуждающая пользователя продолжить подписку).
Подписки, купленные через платежную систему Google Play.
Как правило, пользователи могут восстановить подписки в платежной системе Google Play. Для отмененных подписок, которые изначально были приобретены в платежной системе Google Play, пользователь может отменить отмену, пока подписка активна, с помощью функции повторной подписки Google Play. В этом случае вы получаете уведомление разработчика в режиме реального времени SUBSCRIPTION_RESTARTED
на своем сервере, а новый токен покупки не выдается — исходный токен используется для продолжения подписки. Чтобы узнать, как управлять восстановлением в платежной системе Google Play, см. раздел «Восстановления» руководства по управлению подпиской.
Вы также можете запустить восстановление в платежной системе Google Play из приложения, вызвав launchBillingFlow()
. Подробную информацию о том, как это сделать, см. в разделе «До истечения срока действия подписки — в приложении» . В случае пользователей, прошедших процедуру выбора пользователя для исходной покупки (которая была отменена, но все еще активна), система автоматически определяет их выбор и отображает пользовательский интерфейс для восстановления этих покупок. Им предлагается подтвердить повторную покупку подписки через Google Play, но им не нужно повторно проходить процедуру выбора пользователя. В этом случае пользователю выдается новый токен покупки. Ваша серверная часть получает уведомление разработчика в режиме реального времени SUBSCRIPTION_PURCHASED
, а значение linkedPurchaseToken
для нового статуса покупки устанавливается, как и в случае обновления или понижения версии, со старым токеном покупки для отмененной подписки.
Повторные подписки
Если срок действия подписки полностью истекает, будь то из-за отмены или отклонения платежа без восстановления (удержание учетной записи с истекшим сроком действия), то пользователь должен повторно подписаться , если он хочет возобновить действие права.
Повторную подписку также можно включить через приложение, обработав ее аналогично стандартной регистрации. Пользователи должны иметь возможность выбирать, какую биллинговую систему они хотят использовать. В этом случае можно вызвать launchBillingFlow()
, как описано в разделе «Запуск потока выставления счетов по выбору пользователя» .
Протестируйте альтернативный способ оплаты
Тестеры лицензий следует использовать для проверки альтернативной интеграции биллинга. Вам не будет выставлен счет за транзакции, инициированные учетными записями тестировщиков лицензий. Дополнительные сведения о настройке тестеров лицензий см. в разделе Проверка выставления счетов в приложении с помощью лицензирования приложений .
Следующие шаги
Завершив интеграцию в приложении, вы готовы интегрировать свою серверную часть .