Подписка с дополнениями позволяет объединять несколько продуктов по подписке, которые можно покупать, оплачивать и управлять ими вместе. Существующие подписки из вашего каталога товаров можно легко предлагать в качестве дополнений без каких-либо предварительных настроек или дополнительной конфигурации. Вы можете запустить процесс покупки с несколькими существующими продуктами по подписке и продавать их в качестве дополнений.
Соображения
При использовании функции подписки с дополнительными модулями следует учитывать следующие моменты:
Подписка с дополнительными модулями поддерживается только для базовых тарифных планов с автоматическим продлением.
Все товары в покупке должны иметь одинаковый период регулярной оплаты. Например, нельзя оформить годовую подписку с дополнительными услугами, оплачиваемыми ежемесячно.
В рамках подписки с возможностью приобретения дополнительных товаров можно добавить максимум 50 позиций.
Эта функция недоступна в регионах Индии ( IN ) и Южной Кореи ( KR ).
Интеграция с библиотекой Play Billing.
В этом разделе описывается, как интегрировать функцию подписки с дополнениями в библиотеку Play Billing Library (PBL). Предполагается, что вы знакомы с начальными шагами интеграции PBL, такими как добавление зависимости PBL в ваше приложение , инициализация BillingClient и подключение к Google Play . Этот раздел посвящен аспектам интеграции PBL, специфичным для подписки с дополнениями.
Запустить процесс покупки
Чтобы запустить процесс покупки подписки с дополнительными модулями, выполните следующие шаги:
Получите все элементы вашей подписки, используя метод
BillingClient.queryProductDetailsAsync.Установите объект
ProductDetailsParamsдля каждого товара.Объект
ProductDetailsParamsсодержит какProductDetails, указывающий на тип подписки, так иofferTokenвыбирающий конкретныйbase planилиofferподписки.Укажите подробные сведения о товаре в методе
BillingFlowParams.Builder.setProductDetailsParamsList. КлассBillingFlowParamsопределяет детали процесса закупки.В следующем примере показано, как запустить процесс выставления счетов за подписку, включающую несколько товаров:
Java
BillingClient billingClient = …; // ProductDetails obtained from queryProductDetailsAsync(). ProductDetailsParams productDetails1 = ...; ProductDetailsParams productDetails2 = ...; ArrayList
productDetailsList = new ArrayList<>(); productDetailsList.add(productDetails1); productDetailsList.add(productDetails2); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsList) .build(); billingClient.launchBillingFlow(billingFlowParams);
Правила, применимые к товарам, приобретаемым в рамках покупки.
- Чтобы гарантировать, что даты продления дополнительных услуг в конечном итоге совпадут с датами продления базовой услуги, Google Play может взимать пропорциональную плату после любых пробных или ознакомительных периодов ценообразования.
- Соответствие условиям предложения будет оцениваться отдельно для каждого товара.
Обработка закупок
Обработка подписки с дополнениями аналогична обработке отдельной покупки подписки, как описано в разделе «Интеграция библиотеки Google Play Billing в ваше приложение» . Единственное отличие заключается в том, что пользователь может получить несколько прав доступа за одну покупку. Покупка подписки с дополнениями возвращает несколько элементов, которые можно получить с помощью Purchase.getProducts() в библиотеке Google Play Billing, а затем из списка lineItems в методе purchases.subscriptionsv2.get API разработчика Google Play .
Изменяйте подписки с помощью дополнений.
Любые изменения вашей подписки с дополнительными модулями приводят к повышению или понижению уровня подписки. Для получения дополнительной информации см. раздел «Повышение или понижение уровня подписки» .
Для изменения или восстановления существующей покупки подписки с дополнениями в вашем приложении необходимо вызвать API launchBillingFlow с дополнительными параметрами и выполнить следующие действия:
- Всегда вызывайте метод
setOldPurchaseToken, используя токен покупки текущей подписки. - Для обновления, понижения или изменения тарифного плана товара вызовите метод
SubscriptionProductReplacementParams.setReplacementMode, чтобы указать, как следует обрабатывать изменение тарифного плана между старым и новым приобретенным товаром. В противном случае этот параметр устанавливать не нужно. - Если базовый элемент не изменяется, вы все равно можете вызвать метод
SubscriptionProductReplacementParams.setSubscriptionReplacementMode, чтобы применить определенное поведение замены. Правила, применимые в этом случае, см. в разделе «Повторная подписка или смена плана в рамках одной подписки» . - Новые дополнительные услуги будут применены немедленно, с пропорциональной оплатой для согласования даты следующего продления с базовым пунктом подписки.
- Удаленные дополнения истекут по окончании текущего расчетного периода.
- При запуске процесса выставления счетов вам потребуется указать все активные элементы подписки с дополнениями, за исключением тех, которые необходимо удалить, а также любые новые дополнения.
В следующем примере показано, как вызвать API launchBillingFlow при изменении существующей покупки подписки с дополнениями:
Java
BillingClient billingClient = …; int replacementMode =…; // ProductDetails obtained from queryProductDetailsAsync(). ProductDetailsParams productDetails1 = ...; ProductDetailsParams productDetails2 = ...; ProductDetailsParams productDetails3 = ...; ArrayListnewProductDetailsList = new ArrayList<>(); newProductDetailsList.add(productDetails1); newProductDetailsList.add(productDetails1); newProductDetailsList.add(productDetails1); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setSubscriptionUpdateParams( SubscriptionUpdateParams.newBuilder() .setOldPurchaseToken(purchaseTokenOfExistingSubscription) // No need to set if change does not affect the base item. .setSubscriptionReplacementMode(replacementMode) .build()) .setProductDetailsParamsList(productDetailsList) .build(); billingClient.launchBillingFlow(billingFlowParams);
Сценарии изменения подписки
В таблице ниже перечислены различные сценарии изменения подписки с дополнительными модулями и соответствующее поведение.
При использовании SubscriptionProductReplacementParams
| Существующие товары | Модифицированные товары | Нужно ли задавать режим замены в параметре SubscriptionProductReplacementParams? | Поведение |
|---|---|---|---|
| А (базовый элемент), В | А (базовый элемент) | Да (используйте KEEP_EXISTING ) |
|
| А | А (базовый элемент), В | Да (используйте KEEP_EXISTING для A) |
|
| А (базовый элемент), В | А (базовый элемент), С | Да (используйте KEEP_EXISTING для A) |
|
| А (базовый элемент), В | B (базовый элемент) | Нет | А. Планируется отложенный выдворение. |
| А (базовый элемент), В | C (базовый элемент) | Да |
|
| А (базовый элемент), В | C (базовый элемент), B | Да |
|
| А (базовый элемент), В | C (базовый элемент), D | Да |
|
| А (базовый элемент), В | А (базовый элемент), С | Да |
|
| А (базовый элемент), В, С | D (базовый элемент), B, C | Да |
|
При использовании SubscriptionUpdateParams
| Существующие товары | Модифицированные товары | Нужно ли указывать информацию для замены? | Поведение |
|---|---|---|---|
| А (базовый элемент), В | А (базовый элемент) | Нет |
|
| А | А (базовый элемент), В | Нет |
|
| А (базовый элемент), В | А (базовый элемент), С | Нет |
|
| А (базовый элемент), В | B (базовый элемент) | Нет | А. Планируется отложенный выдворение. |
| А (базовый элемент), В | C (базовый элемент) | Да |
|
| А (базовый элемент), В | C (базовый элемент), B | Да | Замена A на C зависит от setSubscriptionReplacementMode (устарело в PBL 8.1). |
| А (базовый элемент), В | C (базовый элемент), D | Да |
|
Уведомления для разработчиков в режиме реального времени
Поле subscriptionId отсутствует в RTDN для покупок подписки с дополнениями, содержащими несколько прав на элементы. Вместо этого вы можете использовать API разработчиков Play, чтобы получить информацию о покупке и увидеть связанные с ней права на элементы.
Изменение цен для существующих подписчиков
Изменение цен на подписку для существующих подписчиков, приобретающих дополнительные модули, аналогично изменению цен на отдельную подписку, как описано в разделе «Изменение цен на подписку» . Однако существуют некоторые ограничения и функциональные различия, описанные в этом разделе.
Прекратить существование устаревшей ценовой группы
Завершение подписки на устаревшую группу подписчиков также влияет на подписку с дополнительными покупками. Действуют следующие правила:
Все неподтвержденные повышения цен должны иметь тот же срок действия, что и новая цена. Если для товара в подписке с дополнительными покупками предусмотрено повышение цены, которое еще не подтверждено пользователем, любое новое повышение цены для других товаров в покупке будет игнорироваться, если оно не приведет к тому же сроку действия новой цены, что и существующее повышение цены в состоянии «НЕПОДТВЕРЖДЕНО» . После подтверждения пользователем повышения цены все последующие изменения цен будут зарегистрированы. Пользователи могут принять только все неподтвержденные повышения цен одновременно.
Пример:
- Рассмотрим подписку с дополнительными услугами (пункты A и B), которая продлевается 7-го числа каждого месяца.
- Цена на товар А постепенно снижается с 7 до 10 долларов, и ожидается, что повышение цены вступит в силу 7 июля.
- Новая ценовая политика для товара B, предусматривающая повышение цены с 5 до 6 долларов, начнётся 2 июня. Поскольку добровольное повышение цены начнётся через 37 дней после перехода на новую ценовую политику, самое раннее повышение цены для товара B произойдёт 7 августа.
В этом сценарии, пока пользователь не подтвердит изменение цены товара A (пока оно не перейдет в состояние CONFIRMED ), изменение цены товара B не регистрируется для данной покупки подписки, и SubscriptionPurchaseV2 не возвращает подробную информацию об изменении цены товара B. После подтверждения пользователем изменения цены товара A, начинается изменение цены товара B. Пользователь получает информацию о повышении цены товара B только после подтверждения повышения цены товара A.
В электронном письме от Google Play содержится список всех товаров, цены на которые повышаются или понижаются в тот же день.
Отменить подписку с дополнительными модулями
Пользователи могут отменить всю покупку подписки с дополнениями в Центре подписок Play, но отменить всю покупку подписки с дополнениями можно только с помощью API разработчиков Google Play.
Если подписка отменяется без предварительного аннулирования, ни один из приобретенных товаров не будет автоматически продлен, но пользователь продолжит иметь доступ к соответствующим товарам, включая любые бесплатные пробные периоды, до окончания соответствующего расчетного периода.
Отмена и возврат средств за подписки с дополнительными модулями.
Ниже приведены некоторые правила отмены подписки и возврата средств:
Используйте Play Console для оформления возврата средств в зависимости от суммы конкретного заказа без аннулирования доступа к подписке.
Вызовите
orders.refund, чтобы полностью вернуть пользователю средства за определённую подписку, не отзывая при этом доступ к подписке.Вызовите метод
purchases.subscriptionsv2.revoke, чтобы немедленно отозвать доступ ко всем элементам подписки. С помощью этого API вы можете:Отозвать доступ ко всем товарам и предоставить пропорциональный возврат средств.
При аннулировании подписки с дополнительными услугами с использованием пропорционального возврата средств, возврат будет произведен за последний заказ каждого товара с пропорциональной суммой, рассчитанной исходя из времени, оставшегося до следующего продления подписки.
Отозвать доступ ко всем элементам и произвести полный возврат средств .
Доступ к отдельному товару будет аннулирован с полным возвратом средств за этот товар.
Отмена подписки на отдельные элементы с дополнительными модулями.
Чтобы отменить отдельные элементы подписки с дополнениями, не отменяя всю покупку целиком, вызовите метод purchases.subscriptionsv2.revoke , установив поле ItemBasedRefund в RevocationContext . В поле ItemBasedRefund можно указать productId элемента, который следует отменить и за который необходимо вернуть деньги.
Поле ItemBasedRefund можно задать для покупок, содержащих один или несколько товаров с автоматическим продлением подписки.
- Если после отмены товара, указанного в
ItemBasedRefundв подписке останутся активные товары, будет отменен только этот товар, и средства будут полностью возвращены без изменения статуса подписки. - Если после отмены товара, указанного в
ItemBasedRefund, в подписке не осталось активных товаров, товар отменяется, производится полный возврат средств, а подписка аннулируется.
Соображения
- При использовании функции
ItemBasedRefundможно аннулировать только один товар за раз. Запрос может быть вызван несколько раз, если необходимо аннулировать разные товары. - Если покупка подписки находится в одном из состояний «платеж отклонен», или товар, указанный в
ItemBasedRefundотсутствует в вашей собственности или срок его действия истек, отказ от товара блокируется. - Функция уменьшения количества товаров не поддерживается в предоплаченной подписке.
Отсрочка выставления счетов
Вы можете перенести следующую дату выставления счета для подписки с дополнениями, используя метод Purchases.subscriptionsv2:defer .
При отсрочке подписки с дополнительными модулями все элементы подписки откладываются на тот же срок. В течение периода отсрочки пользователь сохраняет полный доступ ко всем элементам, но плата за них не взимается. Дата продления для всех элементов обновляется на новую дату.
Это может быть полезно для рекламных акций или жестов доброй воли по отношению к клиентам. Отсрочку платежа можно установить на срок от одного дня до одного года за один вызов API. Вы можете вызывать API несколько раз, чтобы продлить отсрочку до наступления новой даты выставления счета.
При выполнении этого действия срабатывает уведомление для разработчиков в режиме реального времени SUBSCRIPTION_DEFERRED .
Срок действия товара истекает при отклонении платежа.
При покупке подписки с дополнительными модулями, продление некоторых услуг может потребовать обновления только части прав на использование отдельных элементов, не затрагивая элементы с более поздней датой истечения срока действия.
Независимо от того, какие товары включены в продление подписки, если платеж за продление будет отклонен, общая сумма покупки подписки перейдет в льготный период, и учетная запись будет заблокирована, как описано в следующей документации.
выбор периода восстановления
Поскольку льготный период сам по себе предоставляет пользователю право на продление, при покупке подписки с дополнительными услугами платеж за продление отклоняется, выбирается товар с минимальным льготным периодом среди всех активных товаров, и для данного продления применяется его льготный период и период блокировки учетной записи в качестве периода восстановления.
К активным элементам относятся элементы, которые были активны при покупке подписки с дополнениями непосредственно перед попыткой продления, исключаются любые вновь добавленные элементы (которые станут доступны только после восстановления подписки), а также любые элементы, которые перестали быть активными из-за удаления или отказа в продлении.
Применяется настройка блокировки счета для товара с выбранным минимальным льготным периодом. Если минимального льготного периода несколько, но периоды блокировки счета разные, применяется самый длительный период блокировки счета.
Льготный период
Если платеж за продление подписки отклонен, подписка переходит в состояние льготного периода. В течение льготного периода пользователь будет иметь доступ ко всем активным товарам из предыдущего периода продления. После окончания льготного периода, если способ оплаты не будет исправлен, вся подписка будет заблокирована. Если в течение льготного периода истекает срок действия каких-либо других товаров, после восстановления подписки после отклонения платежа будет предпринята новая попытка списания средств за эти товары.
блокировка счета
Пока подписка заблокирована, доступ ко всем товарам и услугам по подписке приостанавливается до возврата платежа.
Если подписка, заблокированная в учетной записи, будет восстановлена, покупка подписки продолжит существовать в текущем виде. Если подписка не будет восстановлена, товары, по которым платеж был отклонен, истекут, а доступ к другим товарам будет возобновлен на оставшийся период их выставления счетов.
Пример:
У пользователя есть подписка на базовый план My Base, которая продлевается 1-го числа каждого месяца, а затем 15 августа он добавляет дополнительный план за 10 долларов в месяц с семидневным бесплатным пробным периодом. Ни для одного из этих пунктов не установлен льготный период, и для обоих предусмотрен 30-дневный период блокировки аккаунта.
22 августа с пользователя списывается 2,90 доллара США (10*9/31) пропорционально до 31 августа, но срок действия способа оплаты пользователя истекает раньше, и 22 августа платеж по подписке отклоняется.
Когда подписка блокируется из-за отказа в оплате, пользователь теряет доступ ко всем товарам и услугам, включенным в подписку с дополнительными опциями. Оставшееся время для товаров, которые не продлеваются, будет возвращено пользователю после снятия блокировки подписки, либо в случае возврата или отмены платежа.
В предыдущем примере подписка блокируется на аккаунте 22 августа.
Если учетная запись будет восстановлена 25 августа, до более поздней даты продления подписки 1 сентября, пользователь в тот же день получит доступ как к базовому тарифному плану , так и к дополнительному тарифному плану . Следующая дата выставления счета будет перенесена на 4 сентября.
Если учетная запись не будет восстановлена в течение 30 дней, подписка аннулируется 21 сентября, пользователь теряет доступ к дополнительному тарифному плану и возобновляет доступ к базовому тарифному плану до 30 сентября.
В этом примере необходимо получить обновленное expiryTime для ВСЕХ элементов подписки с дополнениями, поскольку для некоторых элементов право на использование может возобновиться после истечения льготного периода и блокировки учетной записи.
Финансовая отчетность и сверка
Используйте отчет «Доходы» , чтобы сопоставить ваши активные подписки с транзакциями в Play Store. Каждая позиция транзакции имеет идентификатор заказа. Если покупки включают несколько товаров, отчеты «Доходы» и «Предполагаемые продажи» будут содержать отдельные строки для каждой транзакции, такие как списание средств, комиссия, налог и возврат средств для каждого задействованного товара.
Для отображения панелей мониторинга в Play Console:
В разделе «Финансовая отчетность» консоли представлены статистические данные о доходах с разбивкой по статьям.
Управление заказами отражает покупку подписки с дополнительными услугами и отображает подробный список приобретенных товаров. В разделе управления заказами вы можете отменить, аннулировать или полностью вернуть деньги за покупку пользователя.