В этом руководстве описывается, как интегрировать API для предоставления альтернативного биллинга с возможностью выбора пользователем в вашем приложении.
Настройка библиотеки Play Billing
Добавьте зависимость Play Billing Library в ваше приложение для 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.
}
val 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 без возможности выбора пользователем.
Страна игры пользователя — поддерживаемая страна | Страна, в которой находится пользователь, не поддерживается. | |
|---|---|---|
enableUserChoiceBilling вызывается во время настройки BillingClient | Пользователь видит пользовательский выбор UX | Пользователь видит стандартный пользовательский интерфейс биллинговой системы Google Play |
enableUserChoiceBilling не вызывается во время настройки BillingClient | Пользователь видит стандартный пользовательский интерфейс биллинговой системы Google Play | Пользователь видит стандартный пользовательский интерфейс биллинговой системы 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 using queryProductDetailsAsync.
.setProductDetails(productDetailsNewPlan)
// offerIdToken can be found in
// ProductDetails=>SubscriptionOfferDetails.
.setOfferToken(offerTokenNewPlan)
.build()
)
)
.setSubscriptionUpdateParams(
BillingFlowParams.SubscriptionUpdateParams.newBuilder()
.setOriginalExternalTransactionId(externalTransactionId)
.build()
)
.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 using 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() // Fetched using queryProductDetailsAsync .setProductDetails(productDetailsNewPlan) // offerIdToken can be found in // ProductDetails=>SubscriptionOfferDetails. .setOfferToken(offerTokenNewPlan) .build() ) ) .setSubscriptionUpdateParams( BillingFlowParams.SubscriptionUpdateParams.newBuilder() // purchaseToken can be found in // Purchase#getPurchaseToken .setOldPurchaseToken(oldToken) .setReplaceProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE) .build() ) .build() val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)Ява
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList( ImmutableList.of( ProductDetailsParams.newBuilder() // Fetched using queryProductDetailsAsync .setProductDetails(productDetailsNewPlan) // offerIdToken can be found in // ProductDetails=>SubscriptionOfferDetails. .setOfferToken(offerTokenNewPlan) .build() ) ) .setSubscriptionUpdateParams( SubscriptionUpdateParams.newBuilder() // purchaseToken can be found in // Purchase#getPurchaseToken .setOldPurchaseToken(oldToken) .setReplaceProrationMode(BillingFlowParams.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() , как описано в разделе «Запуск выбранного пользователем потока биллинга» .
Тестирование альтернативного биллинга
Для тестирования интеграции альтернативных систем оплаты следует использовать тестировщиков лицензий. Вам не будут выставлены счета за транзакции, инициированные аккаунтами тестировщиков лицензий. Подробнее о настройке тестировщиков лицензий см. в разделе Тестирование внутриигрового биллинга с лицензированием приложений .
Следующие шаги
После завершения интеграции внутри приложения вы готовы интегрировать свой бэкэнд .