В этом документе описывается, как обрабатывать события жизненного цикла подписки, такие как продление и истечение срока действия. Он также описывает дополнительные функции подписки, такие как предложение акций и разрешение вашим пользователям управлять своими подписками.
Если вы не настроили продукты подписки для своего приложения, см . раздел Создание и настройка продуктов .
Обзор подписок
Подписка — это повторяющаяся транзакция, которая предоставляет пользователям определенные права. Права представляют собой набор преимуществ, к которым пользователи могут получить доступ в течение определенного периода времени. Например, подписка может предоставлять пользователю право на премиум-доступ.
С помощью базовых планов и предложений вы можете создать несколько конфигураций для одного и того же продукта подписки. Например, вы можете создать вводное предложение для пользователей, которые никогда не подписывались на ваше приложение. Аналогично вы можете создать предложение по обновлению для пользователей, которые уже подписаны.
Подробный обзор подписных продуктов, базовых планов и предложений см. в документации в Справочном центре Play Console .
Библиотека Play Billing поддерживает следующие типы подписок:
Подписка на один элемент - в этом типе один элемент соответствует одному праву. Например, подписка на музыкальный потоковый сервис.
Подписка с дополнениями — в этом типе одна покупка может иметь несколько отдельных прав, объединенных в одну покупку. Например, подписка на потоковую передачу музыки и видеоподписка. Для получения информации, касающейся подписки с дополнениями, см. Подписки с дополнениями .
Интеграция предоплаченных планов
Предоплаченные планы не продлеваются автоматически по истечении срока действия. Чтобы продлить подписку без перерыва, пользователь должен пополнить предоплаченный план для той же подписки.
Для пополнений запустите поток выставления счетов так же, как и при первоначальной покупке. Вам не нужно указывать, что покупка является пополнением.
Пополнения предоплаченных планов всегда используют режим замены CHARGE_FULL_PRICE
, и вам не нужно устанавливать этот режим явно. С пользователя немедленно взимается плата за полный расчетный период, и его право продлевается на срок, указанный в пополнении.
После пополнения счета следующие поля в объекте результата Purchase
обновляются для отражения последней покупки пополнения:
- Идентификатор заказа
- Время покупки
- Подпись
- Купить токен
- Признано
Следующие поля Purchase
всегда содержат те же данные, что и в исходной покупке:
- Имя пакета
- Состояние покупки
- Продукция
- Автоматическое продление
Подтверждение предоплаченной покупки
Подобно автоматически продлеваемым подпискам, вы должны подтвердить предоплаченные планы после покупки. Как первоначальная покупка, так и любые пополнения должны быть подтверждены. Для получения дополнительной информации см. Обработка покупок .
Поскольку срок действия предоплаченного плана может быть коротким, важно подтвердить покупку как можно скорее.
Предоплаченные планы сроком на одну неделю и более должны быть подтверждены в течение трех дней.
Предоплаченные планы с длительностью менее одной недели должны быть подтверждены в течение половины длительности плана. Например, у разработчиков есть 1,5 дня, чтобы подтвердить трехдневный предоплаченный план.
Интеграция подписок в рассрочку
Подписка в рассрочку — это тип подписки, при котором пользователи оплачивают подписку несколькими частями в течение определенного периода времени, а не вносят всю стоимость подписки авансом.
Дополнительные соображения по подписке в рассрочку:
- Доступность в странах : Функция подписки в рассрочку доступна только в Бразилии, Франции, Италии и Испании (уточните последнюю информацию о доступности в консоли).
- Установка цены : При установке цены на подписку с рассрочкой платежа на Консоли цена представляет собой ежемесячную сумму платежа. Это, в сочетании с установленным периодом обязательств, генерирует общую сумму для подписки на экране покупки.
- Период обязательств : Общая продолжительность первоначального обязательства по подписке, в течение которого требуются ежемесячные платежи. Например, если базовый план имеет 15-месячный период обязательств, пользователь будет делать 15 ежемесячных платежей в течение этого периода.
- Продления : В контексте подписок с рассрочкой платежа «продление» означает завершение периода обязательств, либо первоначального периода обязательств, либо последующего периода обязательств. После первоначальной регистрации первое продление происходит по завершении всего первоначального периода обязательств. Последующие продления происходят после выполнения каждого последующего периода обязательств. Типы продления для подписок с рассрочкой платежа могут быть «автоматически продлевается ежемесячно» или «автоматически продлевается на тот же срок». Для «автоматически продлевается ежемесячно» нет последующих обязательств, и план ведет себя как ежемесячная подписка, где каждая ежемесячная плата за подписку представляет собой продление.
- Расчетный период : в контексте подписок с рассрочкой платежа это относится к повторяющемуся интервалу, через который производятся отдельные платежи, как указано в базовом плане.
- Изменение плана против изменения цены : для изменения цены и отмены обязательство является твердым. Это означает, что если пользователь хочет отменить или разработчик хочет изменить цену, изменение вступает в силу в конце периода обязательства. Для изменения плана обязательство не является твердым. Это означает, что изменение плана не должно ждать до конца периода обязательства, оно вступает в силу либо немедленно, либо на следующую дату платежа в зависимости от установленного режима замены.
- Изменение плана подписки в рамках одной и той же подписки : изменение плана с рассрочки на базовый план без рассрочки для того же продукта не допускается.
Уведомления разработчика в режиме реального времени (RTDN) : RTDN
SUBSCRIPTION_CANCELLATION_SCHEDULED
отправляется немедленно после отмены, инициированной пользователем, когда платежи остаются на период действия обязательств. Отмена находится в ожидании и вступит в силу только в конце периода действия обязательств. Затем, если пользователь не восстановит подписку, RTDNSUBSCRIPTION_CANCELED
иSUBSCRIPTION_EXPIRED
отправляются в конце периода действия обязательств.Выплаты/Реализация дохода : Выплаты разработчикам будут происходить по мере того, как пользователи будут вносить ежемесячные платежи, на тех же условиях, что и для всех других подписок. Разработчикам не выплачивается авансом, когда пользователь подписывается на подписку с рассрочкой платежа.
Пропущенные платежи : если пользователь не вносит какие-либо платежи по подписке в рассрочку, ни Google, ни Разработчик не будут пытаться взыскать какие-либо такие пропущенные или непогашенные платежи с пользователя, за исключением того, что Google может периодически повторять платеж в течение любого применимого Льготного периода или периода удержания счета в соответствии со своей обычной практикой повторных платежей. Google не будет нести ответственности перед Разработчиком за любые оставшиеся неоплаченные платежи в рассрочку.
Доступность библиотеки Play Billing : Поле
installmentDetails
доступно только для PBL 7 и более поздних версий. Для PBL 5 и более поздних версий подписка на рассрочку возвращается с помощьюqueryProductDetails()
, но подписка не будет включать подробную информацию о рассрочке, такую как количество подтвержденных платежей по плану.
Используйте глубокие ссылки, чтобы позволить пользователям управлять подпиской
Ваше приложение должно включать ссылку на экране настроек или предпочтений, позволяющую пользователям управлять своими подписками, которую вы можете интегрировать в естественный внешний вид вашего приложения.
Вы можете включить глубокую ссылку из своего приложения в центр подписок Google Play для неистекших подписок, которые вы можете определить с помощью поля subscriptionState
ресурса подписки . Исходя из этого, существует несколько способов, с помощью которых вы можете сделать глубокую ссылку в центр подписок Play Store.
Ссылка на центр подписок
Используйте следующий URL-адрес, чтобы направить пользователей на страницу, на которой отображаются все их подписки, как показано на рисунках 1 и 2:
https://play.google.com/store/account/subscriptions


Эта глубокая ссылка может быть полезна пользователю, чтобы восстановить отмененную подписку из центра подписок Play Store.
Ссылка на конкретную страницу управления подпиской (рекомендуется)
Чтобы напрямую перейти на страницу управления для неистекшей подписки, укажите имя пакета и productId
связанный с купленной подпиской. Чтобы программно определить productId
для существующей подписки, запросите бэкэнд вашего приложения или вызовите BillingClient.queryPurchasesAsync()
для получения списка подписок, связанных с определенным пользователем. Каждая подписка содержит соответствующий productId
как часть информации о статусе подписки. Каждый объект SubscriptionPurchaseLineItem
, связанный с покупкой подписки, содержит значение productId
связанное с подпиской, которую пользователь приобрел в этой строке.
Используйте следующий URL-адрес, чтобы направить пользователей на определенный экран управления подпиской, заменив «your-sub-product-id» и «your-app-package» на productId
и имя пакета приложения соответственно:
https://play.google.com/store/account/subscriptions?sku=your-sub-product-id&package=your-app-package
После этого пользователь может управлять способами оплаты и получать доступ к таким функциям, как отмена, повторная подписка и приостановка.
Разрешить пользователям повышать, понижать или изменять свою подписку
Вы можете предоставить существующим подписчикам различные возможности по изменению их тарифного плана, чтобы лучше соответствовать их потребностям:
- Если вы продаете несколько уровней подписки, например «базовые» и «премиум» подписки, вы можете разрешить пользователям переключать уровни, приобретая другой базовый план или предложение подписки.
- Вы можете разрешить пользователям изменять текущий расчетный период, например, переходить с ежемесячного на годовой план.
- Вы также можете разрешить пользователям переключаться между тарифными планами с автоматическим продлением и предоплатой.
Вы можете поощрять любые из этих изменений, предоставляя предложения по подписке, чтобы предоставить скидку соответствующим пользователям. Например, вы можете создать предложение, предоставляющее скидку 50% на первый год при переходе с ежемесячного на годовой план, и ограничить это предложение для пользователей, подписанных на ежемесячный план, которые не приобрели это предложение. Более подробная информация о критериях соответствия предложениям доступна в Help Center
На рисунке 3 показан пример приложения с тремя различными планами:

Ваше приложение может отображать экран, аналогичный рисунку 3, предоставляя пользователям возможность изменить подписку. Во всех случаях пользователям должно быть ясно, какой у них текущий план подписки и какие возможности у них есть для его изменения.
Когда пользователи решают повысить, понизить или изменить свою подписку, вы указываете режим замены , который определяет, как применяется пропорциональная стоимость текущего оплаченного расчетного периода и когда происходит изменение прав.
Режимы замены
В следующей таблице перечислены доступные режимы замены и примеры использования, а также количество платежей, которые считаются оплаченными.
Режим замены | Описание | Пример использования | Обязательные платежи, зарегистрированные как оплаченные (для замены подписки в рассрочку) |
| Подписка немедленно повышается или понижается. Любое оставшееся время корректируется на основе разницы в цене и зачисляется в счет новой подписки путем переноса даты выставления следующего счета. Это поведение по умолчанию. | Перейдите на более дорогой уровень без немедленной дополнительной оплаты. | 0 |
| Подписка обновляется немедленно, а цикл выставления счетов остается прежним. Разница в цене за оставшийся период затем взимается с пользователя. Примечание: эта опция доступна только для обновления подписки, при котором цена за единицу времени увеличивается. | Перейдите на более дорогой тарифный план, не меняя дату выставления счета. | 1 |
| Подписка немедленно повышается или понижается, и с пользователя немедленно взимается полная стоимость нового права. Оставшаяся стоимость предыдущей подписки либо переносится на то же право, либо пропорционально распределяется по времени при переключении на другое право. Примечание: Если новая подписка имеет бесплатную пробную версию или ознакомительное предложение, с пользователя взимается плата в размере 0 долларов США или стоимости ознакомительного предложения (в зависимости от того, что применимо) на момент повышения или понижения уровня подписки. | Переход с более короткого на более длительный расчетный период. | 1 (Примечание: 0, если новая подписка имеет бесплатную пробную версию.) |
| Подписка немедленно повышается или понижается, и новая цена взимается при продлении подписки. Цикл выставления счетов остается прежним. | Перейдите на более высокий уровень подписки, сохранив оставшийся бесплатный период. | 0 |
| Подписка повышается или понижается только при ее продлении, но новая покупка оформляется немедленно и содержит следующие два элемента:
Примечание: для подписок с рассрочкой платежа смена плана происходит в начале следующей даты платежа. | Понижение до менее дорогого уровня. | 1 |
Чтобы узнать больше о различных вариантах повышения или понижения цен на услуги по допродаже и возврату средств, ознакомьтесь с руководством по предложениям и акциям.
Установите режим замены для покупки
Вы можете использовать различные режимы замены для различных типов переходов подписки, основываясь на своих предпочтениях и бизнес-логике. В этом разделе объясняется, как установить режим замены для изменения подписки и какие ограничения применяются.
Повторная подписка или смена плана в пределах одной подписки
Вы можете указать режим замены по умолчанию в консоли Google Play. Этот параметр позволяет вам выбрать, когда взимать плату с текущих подписчиков, если они приобретают другой базовый план или предложение для той же подписки или повторно подписываются после отмены. Доступные параметры: Charge immediately (немедленная оплата), эквивалент CHARGE_FULL_PRICE
полная оплата) и Charge at the next billing date (на следующую дату выставления счета) , эквивалент WITHOUT_PRORATION
учета прореживания). Это единственные соответствующие режимы замены при переключении базовых планов в пределах одной подписки.
Например, если вы реализуете предложение по возврату для того же плана после того, как пользователь отменил подписку, но до окончания подписки, вы можете обработать новую покупку как обычную покупку, не указывая никаких значений в SubscriptionUpdateParams
. Система использует режим замены по умолчанию, настроенный вами в подписке, и автоматически обрабатывает переход плана со старой покупки на новую покупку.
Переключайте планы между подписками или отменяйте режим замены по умолчанию
Если пользователь меняет подписные продукты (покупает другую подписку) или если вы по какой-либо причине хотите переопределить режим замены по умолчанию, вы указываете пропорциональную ставку во время выполнения как часть параметров потока покупки.
Чтобы правильно указать SubscriptionUpdateParams
как часть конфигурации потока покупок во время выполнения, обратите внимание на следующие ограничения:
- При повышении, понижении или инициировании переключения с той же подписки на предоплаченный план с предоплаченного плана, плана с автоматическим продлением или плана рассрочки единственным разрешенным режимом замены является
CHARGE_FULL_PRICE
. Если указать любой другой режим замены, покупка не будет выполнена, и пользователю будет показана ошибка. - При переключении планов в пределах одной подписки на автоматически продлеваемый план с предоплаченного плана или с автоматически продлеваемого плана допустимыми режимами пропорционального распределения являются
CHARGE_FULL_PRICE
иWITHOUT_PRORATION
. Если указать любой другой режим пропорционального распределения, покупка не будет выполнена, и пользователю будет показана ошибка. - Изменение тарифных планов в рамках одного и того же продукта подписки с базового плана с рассрочкой платежа на базовый план без рассрочки не допускается.
Примеры и варианты поведения замены
Чтобы понять, как работает каждый режим пропорционального распределения, рассмотрим следующий сценарий:
У Сэмвайза есть подписка на онлайн-контент из приложения Country Gardener. У него есть ежемесячная подписка на версию контента Tier 1 , которая содержит только текст. Эта подписка стоит ему $2 в месяц и возобновляется первого числа месяца.
15 апреля Сэмвайз решил перейти на годовую версию подписки Tier 2 , которая включает в себя видеообновления и стоит 36 долларов в год .
При обновлении подписки разработчик выбирает режим пропорционального распределения. В следующем списке описывается, как каждый режим пропорционального распределения влияет на подписку Samwise:
WITH_TIME_PRORATION
Подписка уровня 1 Сэмвайза заканчивается немедленно. Поскольку он заплатил за полный месяц (с 1 по 30 апреля), но обновился в середине периода подписки, половина месячной подписки ($1) применяется к его новой подписке. Однако, поскольку эта новая подписка стоит $36 в год, кредитный баланс в $1 оплачивает только 10 дней (с 16 по 25 апреля); поэтому 26 апреля с него взимается $36 за новую подписку и еще $36 26 апреля каждого следующего года.
Вам следует вызвать PurchasesUpdatedListener
вашего приложения в момент успешной покупки, и вы сможете получить новую покупку как часть вызова queryPurchasesAsync()
. Ваш бэкэнд немедленно получает уведомление разработчика в реальном времени SUBSCRIPTION_PURCHASED
.
CHARGE_PRORATED_PRICE
Этот режим можно использовать, поскольку цена подписки уровня 2 за единицу времени (36 долл. США/год = 3 долл. США/месяц) больше цены подписки уровня 1 за единицу времени (2 долл. США/месяц). Подписка уровня 1 Сэмвайза заканчивается немедленно. Поскольку он заплатил за целый месяц, но использовал только половину, половина месячной подписки (1 долл. США) применяется к его новой подписке. Однако, поскольку эта новая подписка стоит 36 долл. США/год, оставшиеся 15 дней стоят 1,50 долл. США; поэтому с него взимается разница в 0,50 долл. США за его новую подписку. 1 мая с Сэмвайза взимается 36 долл. США за его новый уровень подписки и еще 36 долл. США 1 мая каждого следующего года.
Вам следует вызвать PurchasesUpdatedListener
вашего приложения в момент успешной покупки, и вы сможете получить новую покупку как часть вызова queryPurchasesAsync()
. Ваш бэкэнд немедленно получает уведомление разработчика в реальном времени SUBSCRIPTION_PURCHASED
.
WITHOUT_PRORATION
Подписка Сэмвайза уровня 1 немедленно повышается до уровня 2 без дополнительной платы, а 1 мая с него взимается 36 долларов за новый уровень подписки и еще 36 долларов 1 мая каждого последующего года.
Вам следует вызвать PurchasesUpdatedListener
вашего приложения в момент успешной покупки, и вы сможете получить новую покупку как часть вызова queryPurchasesAsync()
. Ваш бэкэнд немедленно получает уведомление разработчика в реальном времени SUBSCRIPTION_PURCHASED
.
DEFERRED
Подписка уровня 1 Сэмвайза продлится до истечения срока ее действия 30 апреля. 1 мая вступит в силу подписка уровня 2 , и с Сэмвайза будет взиматься плата в размере 36 долларов США за новый уровень подписки.
Вам следует вызвать PurchasesUpdatedListener
вашего приложения в момент успешной покупки, и вы сможете получить новую покупку как часть вызова queryPurchasesAsync()
. Ваш бэкэнд немедленно получает уведомление разработчика в реальном времени SUBSCRIPTION_PURCHASED
. Вам следует обработать покупку так же, как вы обрабатывали бы любую другую новую покупку в этот момент. В частности, убедитесь, что вы подтвердили новую покупку. Обратите внимание, что startTime
новой подписки заполняется в момент вступления в силу замены, что происходит, когда истекает срок действия старой подписки. В этот момент вы получаете SUBSCRIPTION_RENEWED
RTDN для нового плана подписки. Подробнее о поведении ReplacementMode.DEFERRED
читайте в разделе Обработка отложенной замены .
CHARGE_FULL_PRICE
Подписка уровня 1 Сэмвайза заканчивается немедленно. Его подписка уровня 2 начинается сегодня, и с него взимается 36 долларов. Поскольку он заплатил за полный месяц, но использовал только половину, половина месячной подписки (1 доллар) применяется к его новой подписке. Поскольку эта новая подписка стоит 36 долларов в год, он получит 1/36 часть года, добавленную к его периоду подписки (~10 дней). Таким образом, следующий платеж Сэмвайза составит 1 год и 10 дней с сегодняшнего дня за 36 долларов. После этого с него будет взиматься 36 долларов каждый последующий год.
При выборе режима пропорционального распределения обязательно ознакомьтесь с нашими рекомендациями по замене .
Запуск изменений подписки в приложении
Ваше приложение может предложить пользователям обновление или понижение, используя те же шаги, что и при запуске потока покупки . Однако при обновлении или понижении вам необходимо предоставить данные для текущей подписки, будущей (обновленной или пониженной) подписки и режима замены для использования, как показано в следующем примере:
Котлин
val offerToken = productDetails .getSubscriptionOfferDetails(selectedOfferIndex) .getOfferToken() val billingParams = BillingFlowParams.newBuilder().setProductDetailsParamsList( listOf( BillingFlowParams.ProductDetailsParams.newBuilder() .setProductDetails(productDetails) .setOfferToken(offerToken) .build() ) ).setSubscriptionUpdateParams( BillingFlowParams.SubscriptionUpdateParams.newBuilder() .setOldPurchaseToken("old_purchase_token") .setSubscriptionReplacementMode( BillingFlowParams.ReplacementMode.CHARGE_FULL_PRICE ) .build() ).build() billingClient.launchBillingFlow( activity, billingParams ) // ...
Ява
String offerToken = productDetails .getSubscriptionOfferDetails(selectedOfferIndex) .getOfferToken(); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList( ImmuableList.of( ProductDetailsParams.newBuilder() // fetched via queryProductDetailsAsync .setProductDetails(productDetails) // offerToken can be found in // ProductDetails=>SubscriptionOfferDetails .setOfferToken(offerToken) .build())) .setSubscriptionUpdateParams( SubscriptionUpdateParams.newBuilder() // purchaseToken can be found in Purchase#getPurchaseToken .setOldPurchaseToken("old_purchase_token") .setSubscriptionReplacementMode(ReplacementMode.CHARGE_FULL_PRICE) .build()) .build(); BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams); // ...
Рекомендации по замене
В следующей таблице показаны различные сценарии пропорционального распределения, а также наши рекомендации для каждого сценария:
Сценарий | Рекомендуемый режим замены | Результат |
---|---|---|
Переход на более дорогой уровень | CHARGE_PRORATED_PRICE | Пользователь получает доступ немедленно, сохраняя тот же расчетный период. |
Понижение до менее дорогого уровня | DEFERRED | Пользователь уже оплатил более дорогой уровень, поэтому он сохраняет доступ до следующей даты выставления счета. |
Обновление во время бесплатной пробной версии, сохранение пробной версии | WITHOUT_PRORATION | Пользователь переходит на более высокий уровень на оставшийся срок пробного периода без дополнительной платы. |
Обновление во время бесплатной пробной версии — прекращение доступа к бесплатной пробной версии | CHARGE_PRORATED_PRICE | Пользователь получает доступ к новому уровню немедленно, оставшаяся стоимость бесплатной пробной версии переносится. Переносимая стоимость рассчитывается на основе цен базового плана. |
Обработка покупок по изменению подписки
Изменения плана являются новыми покупками для всех условий и целей, и они должны быть обработаны и подтверждены как таковые после успешного завершения потока выставления счетов. В дополнение к надлежащей обработке новой покупки, вам необходимо удалить покупку, которая заменяется.
Поведение в приложении такое же, как и для любой новой покупки. Ваше приложение получает результат новой покупки в PurchasesUpdatedListener
, а новая покупка доступна в queryPurchasesAsync
.
API разработчика Google Play возвращает linkedPurchaseToken
в ресурсе подписки , когда покупка заменяет существующую. Обязательно сделайте недействительным токен, предоставленный в linkedPurchaseToken
, чтобы гарантировать, что старый токен не будет использоваться для получения доступа к вашим услугам. См. разделы Обновления, понижения и повторные регистрации для получения информации об обработке покупок обновлений и понижений.
Когда вы получите новый токен покупки, выполните ту же процедуру проверки, что и при проверке нового токена покупки . Обязательно подтвердите эти покупки с помощью BillingClient.acknowledgePurchase()
из библиотеки Google Play Billing Library или Purchases.subscriptions:acknowledge
из API разработчика Google Play.
Обработка отложенной замены
Режим отложенной замены позволяет пользователю использовать оставшиеся права по старому плану, прежде чем приступить к использованию нового плана.
При использовании ReplacementMode.DEFERRED для новой покупки queryPurchasesAsync()
возвращает новый токен покупки после потока покупки, который остается связанным со старым продуктом до тех пор, пока отложенная замена не произойдет в следующую дату продления, после чего новый продукт возвращается.
Раньше вы могли добиться такого пользовательского опыта с помощью устаревшего ProrationMode.DEFERRED
, но ProrationMode.DEFERRED
устарел с Play Billing Library 6. Ознакомьтесь со следующей таблицей, чтобы понять, в чем разница в поведении:
Время | ProrationMode.DEFERRED (устарело) | ReplacementMode.DEFERRED |
Сразу после успешного завершения процесса покупки (приложение) | Право на старый план сохраняется до следующей даты продления. Чтобы гарантировать, что приложение выдает правильное право, Новый токен покупки не обнаружен, поэтому на данном этапе его обработка невозможна. | Новый токен покупки обнаружен, поэтому его следует обработать на этом этапе, принимая во внимание, когда должна произойти замена. |
Сразу после успешного завершения процесса покупки (бэкэнд) | SUBSCRIPTION_PURCHASED RTDN не отправляется после потока покупки. Бэкэнд еще не уведомлен о новой покупке. | SUBSCRIPTION_PURCHASED RTDN со старым product_id отправляется сразу после процесса покупки для нового токена покупки. Вызов метода purchases.subscriptionsv2.get с новым токеном покупки возвращает покупку, имеющую «startTime», указывающий время покупки с двумя позициями :
SUBSCRIPTION_EXPIRED отправлено для старого токена покупки. При вызове метода purchases.subscriptionsv2.get со старым токеном покупки он отображается как просроченный (право на старый план переносится на новую покупку на оставшееся время). |
При замене - первое продление после покупки (приложение) | Новый токен покупки теперь обнаружен, поэтому его следует обработать . | Новая покупка должна была быть обработана уже после успешного завершения процесса покупки, поэтому приложению не нужно предпринимать никаких специальных действий, кроме проверки предоставления соответствующего права. |
При замене - первое продление после покупки (бэкэнд) | Теперь новая покупка может быть обработана и подтверждена после отправки первого RTDN SUBSCRIPTION_RENEWED. | Новая покупка была обработана и подтверждена, когда SUBSCRIPTION_PURCHASED RTDN был отправлен для нового токена покупки и записан как «startTime». При использовании ReplacementMode.DEFERRED первые обновления следуют стандартному поведению любого другого обновления, и вам не нужно обрабатывать специальную логику для замен, когда происходит это событие. При вызове метода purchases.subscriptionsv2.get с новым токеном покупки возвращается покупка с двумя позициями :
|
Отныне вместо устаревшего ProrationMode.DEFERRED следует использовать ReplacementMode.DEFERRED, поскольку он обеспечивает такое же поведение в отношении изменений прав, но предлагает способ управления покупкой, который больше соответствует поведению для других новых покупок.
Управление клиентами
Используя уведомления разработчиков в режиме реального времени, вы можете определить в режиме реального времени, когда пользователь решает отменить подписку. Когда пользователь отменяет подписку, но до истечения срока ее действия, вы можете отправить ему push-уведомления или сообщения в приложении, чтобы попросить его повторно подписаться.
После того, как пользователь отменил подписку, вы можете попытаться вернуть его обратно либо в своем приложении, либо через Play Store. В следующей таблице описаны различные сценарии подписки вместе с соответствующими действиями по отмене и требованиями к приложению.
До истечения срока подписки | После истечения срока подписки | |||
В приложении | В магазине Play | В приложении | В магазине Play | |
Функция Winback | Подписка в приложении | Восстановить | Подписка в приложении | Подписаться повторно |
Пользователь проходит процесс оформления заказа | Да | Нет | Да | Да |
Подписка пользователя остается связанной с тем же артикулом. | Пользователь может зарегистрироваться на тот же или другой артикул. | Да | Пользователь может зарегистрироваться на тот же или другой артикул. | Да |
Создает новый токен покупки | Да | Нет | Да | Да |
Включено по умолчанию | Нет | Да, поддержка требуется для всех разработчиков | Нет | Приложения без Billing Library 2.0+: Нет Приложения с Billing Library 2.0+: Да. Разработчики могут отказаться в консоли. |
Когда с пользователя взимается плата | При использовании того же артикула: конец текущего расчетного периода. При использовании другого артикула: зависит от режима пропорционального распределения. | Конец текущего расчетного периода | Немедленно | Немедленно |
Требуется реализация | Предоставьте пользовательский интерфейс для повторной регистрации в вашем приложении | Обнаружение изменения состояния подписки Глубокая ссылка на Play Store | Предоставьте пользовательский интерфейс для повторной регистрации в вашем приложении | Обработка покупок вне приложения |
До истечения срока подписки — в приложении
Для подписок, которые были отменены, но еще не истекли, вы можете разрешить подписчикам восстановить свою подписку в вашем приложении, применив тот же процесс покупки продукта в приложении, что и для новых подписчиков. Убедитесь, что ваш пользовательский интерфейс отражает, что у пользователя есть существующая подписка. Например, вы можете захотеть отобразить текущую дату истечения срока действия подписки пользователя и повторяющуюся цену с помощью кнопки «Повторная активация» .
В большинстве случаев вам следует предложить пользователю ту же цену и артикул, на которые он уже был подписан, а именно:
- Инициируйте новую покупку подписки с тем же артикулом.
- Новая подписка заменяет старую и возобновляется в тот же срок действия. Старая подписка сразу же помечается как истекшая.
- Например, у Ахилла есть подписка на Example Music App, и подписка истекает 1 августа. 10 июля он повторно подписывается на месячную подписку по той же цене в месяц. Новая подписка пропорционально распределяется с оставшимся кредитом, немедленно активируется и по-прежнему возобновляется 1 августа.
Если вы хотите предложить другую цену, например, новую бесплатную пробную версию или скидку за возврат товара, вы можете вместо этого предложить пользователю другой артикул:
- Инициируйте обновление или понижение версии с другим SKU, используя режим замены
WITHOUT_PRORATION
. - Новая подписка заменяет старую и возобновляется в ту же дату истечения срока действия. С пользователя взимается стоимость нового SKU, включая любые вводные цены, в исходную дату истечения срока действия. Если старая подписка была создана с использованием запутанного идентификатора учетной записи, этот же идентификатор должен быть передан в
BillingFlowParams
для обновлений и понижений. - Например, Achilles имеет подписку на пример Music App, и подписка должна истекать 1 августа. 10 июля он переосмысливает годовую подписку с вступительной ценой. Новая подписка сразу же активна, и пользователь взимает вступительную цену 1 августа.
- Если вы решите включить бесплатную пробную или вступительную цену в свой Winback Sku, убедитесь, что пользователь имеет право, не позволяя Unful One Free Trial Per App Box в консоли Google Play, которая ограничивает пользователя получением одного бесплатного пробного приложения.
Когда вы получаете токен покупки, обработайте покупку так же, как с новой подпиской. Кроме того, API Google Play Developer возвращает linkedPurchaseToken
в ресурсе подписки. Обязательно не согласны с токеном, предоставленным в linkedPurchaseToken
, чтобы убедиться, что старый токен не используется для получения доступа к вашим услугам.
До истечения срока действия подписки - в игровом магазине
В то время как подписка отменена, но все еще активна, пользователи могут восстановить подписку в центре подписки Google Play, нажав ResubScribe (ранее восстановление ). Это сохраняет такую же подписку и токен покупки.

Для получения дополнительной информации о восстановлении подписок см. В реставрации .
После истечения срока подписки - в приложении
Вы можете позволить подписчикам с истечением срок действия подписчиков в вашем приложении, применяя тот же поток покупки продукта в приложении, что и для новых подписчиков. Обратите внимание на следующее:
- Чтобы предложить пользователям скидку, вы, возможно, захотите предложить идентификатор продукта со специальными ценами для вашей подписки, также называемой Winback Sku . Вы можете предоставить предложение в своем приложении, или вы можете уведомить пользователя о предложении за пределами приложения, например, в электронной почте.
- Чтобы запустить подписку Winback, запустите поток покупок в вашем приложении Android, используя библиотеку Google Play Billing. Это тот же процесс, что и при новой подписке, но вы можете определить SKU, доступный для пользователя.
- Если вы решите включить бесплатную пробную или вступительную цену в свой Winback Sku, убедитесь, что пользователь имеет право, не позволяя Unful One Free Trial Per App Box в консоли Google Play, которая ограничивает пользователя получением одного бесплатного пробного приложения.
- Если пользователь повторно переписывается на одну и ту же SKU, он больше не имеет права на бесплатные испытания или вступительную цену. Убедитесь, что ваш пользовательский интерфейс отражает это.
Когда вы получаете токен покупки, обработайте покупку так же, как с новой подпиской. Вы не получите linkedPurchaseToken
в ресурсе подписки.
После истечения срока действия подписки - в игровом магазине
Если они включены, пользователи могут переопределить в одном и том же SKU в течение одного года после истечения срока действия, нажав повторную подписку в центре подписок Google Play. Это генерирует новую подписку и токен покупки.

Перезаботная подписка считается покупкой вне приложения, поэтому обязательно следите за лучшими практиками для обработки покупок, совершенных вне вашего приложения .
Продвигайте свою подписку
Вы можете создать коды продвижения, чтобы дать выбранным пользователям расширенную бесплатную пробную пробную версию для существующей подписки. Чтобы узнать больше, см . Промо -коды .
Для бесплатных испытаний Google Play проверяет, что у пользователя есть действительный способ оплаты, прежде чем начать бесплатную пробную версию. Некоторые пользователи могут рассматривать эту проверку в качестве удержания или платы за свой способ оплаты. Это удержание или заряд является временным, а впоследствии отменяется или возвращается.
После того, как пробный период заканчивается, метод оплаты пользователя взимается за полную сумму подписки.
Если пользователь отменяет подписку в любое время во время бесплатной пробной версии, подписка остается активной до конца судебного разбирательства, и они не взимаются, когда заканчивается бесплатный пробный период.
Отменить, возвращать или отменить
Вы можете использовать API разработчика Google Play для отмены , возврата или отозвания подписки. Эта функциональность также доступна в консоли Google Play .
- Отмена : Пользователи могут отменить подписку в Google Play. Вы также можете предоставить пользователям возможность отменить в вашем приложении или на вашем веб -сайте. Ваше приложение должно обрабатывать эти отмены, как описано при отмене .
- Возврат : Когда вы возвращаетесь, пользователь может продолжать использовать подписку. Возврат может использоваться, если, например, была техническая ошибка, которая мешала пользователю получить доступ к вашему продукту, но ошибка была разрешена. Обратите внимание, что для возврата больше, чем самый последний платеж, или если вы хотите выпустить частичный возврат средств, вы должны использовать консоль Google Play.
- Revoe : Когда вы отозваетесь, пользователь немедленно теряет доступ к подписке. Это можно использовать, если, например, была техническая ошибка, которая мешала пользователю получить доступ к вашему продукту, и пользователь не хочет продолжать использовать продукт. Ваше приложение должно обрабатывать эти отмены, как описано при от Revocations .
Следующая таблица иллюстрирует различия между отменой, возвратом и отменой.
Остановка обновления | Возврат денег | Отменить доступ | |
Отмена | Да | Нет | Нет |
Возвращать деньги | Нет | Да | Нет |
Отозвать | Да | Да | Да |
Отложить выставление счетов за подписчика
Вы можете продвинуть следующую дату выставления счетов для автопроизводного абонента с помощью Purchases.subscriptions:defer
от API разработчика Google Play. В течение периода отсрочки пользователь подписывается на ваш контент с полным доступом, но не взимается. Дата продления подписки обновляется, чтобы отразить новую дату.
Для предоплаченных планов вы можете использовать API DEFER BILLING, чтобы отложить время истечения.
Отложенный биллинг позволяет сделать следующее:
- Предоставьте пользователям бесплатный доступ в качестве специального предложения, например, предоставление одной недели бесплатно для покупки фильма.
- Дайте бесплатный доступ к клиентам в качестве жеста доброй воли.
Счета может быть отложены всего за один день и на один год за вызов API. Чтобы отложить выставление счетов еще дальше, вы можете снова позвонить в API, прежде чем появится новая дата выставления счетов.
Например, у Дарси ежемесячная подписка на онлайн -контент для приложения для рыбалки Quarterly. Обычно она выставляется в 1,25 фунтов стерлингов в первом из каждого месяца. В марте она участвовала в онлайн -опросе для издателя приложений. Издатель вознаграждает ее шестью свободными неделями, откладывая следующий платеж до 15 мая, который составляет шесть недель после того, как ее ранее запланированная дата выставления счетов 1 апреля. Дарси не взимается в течение апреля или начала мая и все еще имеет доступ к контенту. 15 мая ей взимают плату за подписку в 1,25 фунтов стерлингов за месяц. Ее следующая дата обновления сейчас 15 июня.
При отложении вы можете уведомить пользователя по электронной почте или в приложении, чтобы уведомить их о том, что их дата выставления счета изменилась.
Обработка оплаты снижается
Если есть проблемы с оплатой с продлением подписки, Google периодически пытается продлить подписку в течение некоторого времени, прежде чем отменить. Этот период восстановления может состоять из льготного периода, за которым следует период удержания учетной записи. В течение этого времени Google отправляет пользовательские электронные письма и уведомления, предлагающие им обновить свой способ оплаты.
После снижения оплаты подписка входит в льготный период , если он настроен. В течение льготного периода вы должны убедиться, что пользователь по -прежнему имеет доступ к правам подписки.
После того, как любой льготный период закончился, подписка входит в период удержания учетной записи . Во время удержания учетной записи вы должны убедиться, что пользователь не имеет доступа к правам подписки.
Вы можете указать продолжительность периода изящного базового плана и удерживаемого аккаунта в консоли Google Play. Указание длины меньше, чем значения по умолчанию, может уменьшить количество подписок, возмещенных после снижения платежей.
Чтобы максимизировать вероятность восстановления подписки во время снижения платежей, вы можете сообщить своему пользователю о проблеме оплаты и попросить его исправить.
Вы можете сделать это самостоятельно, как описано в разделе «Период» и «Удерживание учетной записи» , либо вы можете реализовать API обмена сообщениями в приложении, где Google показывает сообщение пользователям в вашем приложении.
Обмен сообщениями в приложении
Если вы включили обмен сообщениями в приложении с InAppMessageCategoryId.TRANSACTIONAL
, Google Play покажет обмен сообщениями пользователей в течение периода изящества и удержания учетной записи один раз в день и предоставит им возможность исправить свой платеж, не выходя из приложения.

Мы рекомендуем вам позвонить в этот API всякий раз, когда пользователь открывает приложение, чтобы определить, следует ли отображаться сообщение.
Если пользователь успешно восстановил свою подписку, вы получите код ответа SUBSCRIPTION_STATUS_UPDATED
вместе с токеном покупки. Затем вам следует использовать этот токен покупки, чтобы позвонить в API разработчика Google Play и обновить состояние подписки в вашем приложении.
Интегрировать обмен сообщениями в приложении
Чтобы показать сообщения в приложении для пользователя, используйте BillingClient.showInAppMessages()
.
Вот пример запуска потока обмена сообщениями в приложении:
Котлин
val inAppMessageParams = InAppMessageParams.newBuilder() .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL) .build() billingClient.showInAppMessages(activity, inAppMessageParams, object : InAppMessageResponseListener() { override fun onInAppMessageResponse(inAppMessageResult: InAppMessageResult) { if (inAppMessageResult.responseCode == InAppMessageResponseCode.NO_ACTION_NEEDED) { // The flow has finished and there is no action needed from developers. } else if (inAppMessageResult.responseCode == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) { // The subscription status changed. For example, a subscription // has been recovered from a suspend state. Developers should // expect the purchase token to be returned with this response // code and use the purchase token with the Google Play // Developer API. } } })
Ява
InAppMessageParams inAppMessageParams = InAppMessageParams.newBuilder() .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL) .build(); billingClient.showInAppMessages(activity, inAppMessageParams, new InAppMessageResponseListener() { @Override public void onInAppMessageResponse(InAppMessageResult inAppMessageResult) { if (inAppMessageResult.responseCode == InAppMessageResponseCode.NO_ACTION_NEEDED) { // The flow has finished and there is no action needed from developers. } else if (inAppMessageResult.responseCode == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) { // The subscription status changed. For example, a subscription // has been recovered from a suspend state. Developers should // expect the purchase token to be returned with this response // code and use the purchase token with the Google Play // Developer API. } } });
Обработка подписки в ожидании транзакций
Ожидающие транзакции могут произойти при первоначальной покупке, пополнении, обновлении или понижении. Покупка подписки начинается с состояния SUBSCRIPTION_STATE_PENDING
до перехода на SUBSCRIPTION_STATE_ACTIVE
. Если транзакция истек или отменена пользователем, она переходит на SUBSCRIPTION_STATE_PENDING_PURCHASE_EXPIRED
. Вы должны и должны обновить право пользователя только после завершения транзакции.
Изменение состояния подписки на первоначальную покупку с ожидающими транзакциями проста. Ваше приложение получает Purchase
в PENDING
состоянии, когда пользователь инициирует ожидающую транзакцию. Когда транзакция завершена, ваше приложение снова получает Purchase
с обновлением штата для PURCHASED
. Сообщение SubscriptionNotification
с типом SUBSCRIPTION_PURCHASED
покупается вашему клиенту RTDN. Следуйте нормальному процессу, чтобы проверить покупку, предоставьте пользователю доступ к контенту и подтвердите покупку. Если транзакция истекает или отменяется, сообщением SubscriptionNotification
с типом SUBSCRIPTION_PENDING_PURCHASE_CANCELED
отправляется вашему клиенту RTDN. В таких случаях пользователь никогда не должен был получить доступ к контенту.
Пополнение, обновление или понижение с ожидающими транзакциями включает в себя изменения состояния как для старых, так и для новых подписок. Когда пользователь инициирует ожидаемую пополнение, обновление или транзакцию понижения, ваше приложение получает Purchase
для старой подписки с объектом PendingPurchaseUpdate
. В настоящее время пользователь все еще владеет старой подпиской и еще не получил новую подписку. Вызов getProducts()
и getPurchaseToken()
на объекте PendingPurchaseUpdate
возвращает идентификаторы продукта и токен покупки новой подписки. Когда транзакция будет завершена, ваше приложение получает Purchase
с токеном покупки верхнего уровня для новой подписки и состояния, установленного для PURCHASED
. Сообщение SubscriptionNotification
с типом SUBSCRIPTION_PURCHASED
покупается вашему клиенту RTDN. Только в настоящее время вы должны заменить старый токен покупки новым токеном покупки и обновить доступ пользователя к контенту. Если транзакция истекает или отменяется, сообщением SubscriptionNotification
с типом SUBSCRIPTION_PENDING_PURCHASE_CANCELED
отправляется вашему клиенту RTDN. В таких случаях пользователь все еще должен иметь доступ к содержанию старой подписки.