---
title: "Получение пейволов и продуктов для пейволов с Remote Config в Android SDK"
description: "Получайте пейволы и продукты в Adapty Android SDK для монетизации пользователей."
---

Перед отображением пейволов с Remote Config и кастомных пейволов необходимо получить информацию о них. Обратите внимание, что этот раздел посвящён пейволам с Remote Config и кастомным пейволам. Если вы используете пейволы, созданные в Paywall Builder, обратитесь к разделу [Получение пейволов Paywall Builder и их конфигурации](android-get-pb-paywalls).

:::tip

Хотите увидеть реальный пример интеграции Adapty SDK в мобильное приложение? Посмотрите наши [примеры приложений](sample-apps) — они демонстрируют полную настройку: отображение пейволов, совершение покупок и другие базовые функции.

:::

<details>
   <summary>Перед тем как начать получать пейволы и продукты в мобильном приложении (нажмите, чтобы раскрыть)</summary>

   1. [Создайте продукты](create-product) в дашборде Adapty.

2. [Создайте пейвол и добавьте в него продукты](create-paywall) в дашборде Adapty.

3. [Создайте плейсменты и добавьте пейвол в плейсмент](create-placement) в дашборде Adapty.

4. [Установите Adapty SDK](sdk-installation-android) в своём мобильном приложении.
</details>

## Получение информации о пейволе \{#fetch-paywall-information\}

В Adapty [продукт](product) объединяет товары из App Store и Google Play. Эти кросс-платформенные продукты добавляются в пейволы, которые отображаются в нужных плейсментах мобильного приложения.

Чтобы показать продукты, нужно получить [пейвол](paywalls) из одного из ваших [плейсментов](placements) с помощью метода `getPaywall`.

:::important
**Не хардкодьте идентификаторы продуктов.** Единственный ID, который можно захардкодить, — это идентификатор плейсмента. Пейволы настраиваются удалённо, поэтому количество продуктов и доступные офферы могут меняться в любой момент. Ваше приложение должно обрабатывать эти изменения динамически: если сегодня пейвол возвращает два продукта, а завтра три — покажите все три без изменений в коде.
:::

<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers
Adapty.getPaywall("YOUR_PLACEMENT_ID", locale = "en") { result ->
    when (result) {
        is AdaptyResult.Success -> {
            val paywall = result.value
            // the requested paywall
        }
        is AdaptyResult.Error -> {
            val error = result.error
            // handle the error
        }
    }
}
```
</TabItem>
<TabItem value="java" label="Java" default>

```java showLineNumbers
Adapty.getPaywall("YOUR_PLACEMENT_ID", "en", result -> {
    if (result instanceof AdaptyResult.Success) {
        AdaptyPaywall paywall = ((AdaptyResult.Success<AdaptyPaywall>) result).getValue();
        // the requested paywall
      
    } else if (result instanceof AdaptyResult.Error) {
        AdaptyError error = ((AdaptyResult.Error) result).getError();
        // handle the error
      
    }
});
```
</TabItem>
</Tabs>

| Параметр | Наличие | Описание |
|---------|--------|-----------|
| **placementId** | обязательный | Идентификатор [плейсмента](placements). Это значение вы указали при создании плейсмента в дашборде Adapty. |
| **locale** | <p>опциональный</p><p>по умолчанию: `en`</p> | <p>Идентификатор [локализации пейвола](add-remote-config-locale). Ожидается языковой код, состоящий из одного или нескольких подтегов, разделённых символом минус (**-**). Первый подтег — язык, второй — регион.</p><p></p><p>Например: `en` означает английский, `pt-br` — бразильский португальский.</p><p></p><p>Подробнее о кодах локалей и рекомендациях по их использованию читайте в разделе [Локализации и коды локалей](android-localizations-and-locale-codes).</p> |
| **fetchPolicy** | по умолчанию: `.reloadRevalidatingCacheData` | <p>По умолчанию SDK пытается загрузить данные с сервера и возвращает кешированные данные в случае ошибки. Мы рекомендуем этот вариант, поскольку он гарантирует актуальность данных для ваших пользователей.</p><p></p><p>Если вы считаете, что ваши пользователи работают с нестабильным интернетом, рассмотрите вариант `.returnCacheDataElseLoad` — он возвращает кешированные данные, если они есть. В таком случае пользователи могут не получить самые свежие данные, зато загрузка будет быстрее вне зависимости от качества соединения. Кеш регулярно обновляется, поэтому его безопасно использовать в течение сессии для сокращения сетевых запросов.</p><p></p><p>Обратите внимание: кеш сохраняется после перезапуска приложения и очищается только при переустановке или вручную.</p><p></p><p>Adapty SDK хранит пейволы в двух слоях: регулярно обновляемый кеш, описанный выше, и [резервные пейволы](android-use-fallback-paywalls). Для ускорения загрузки используется CDN, а в случае его недоступности — отдельный резервный сервер. Эта система обеспечивает актуальность пейволов и надёжность даже при слабом интернете.</p> |
| **loadTimeout** | по умолчанию: 5 сек | <p>Ограничивает таймаут этого метода. При его достижении возвращаются кешированные данные или локальный резервный вариант.</p><p></p><p>Обратите внимание: в редких случаях метод может завершиться чуть позже указанного в `loadTimeout` значения, поскольку операция может включать несколько запросов под капотом.</p> |

Не хардкодьте идентификаторы продуктов! Поскольку пейволы настраиваются удалённо, доступные продукты, их количество и специальные офферы (например, бесплатные пробные периоды) могут меняться. Убедитесь, что ваш код корректно обрабатывает такие ситуации.  
Например, если изначально вы получаете 2 продукта, приложение должно отобразить 2 продукта. Если потом вы получите 3 продукта, приложение должно показать все 3 без изменений в коде. Захардкодить нужно только идентификатор плейсмента.

Параметры ответа:

| Параметр | Описание |
| :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Paywall   | Объект [`AdaptyPaywall`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/) со списком идентификаторов продуктов, идентификатором пейвола, Remote Config и рядом других свойств. |

## Получение продуктов \{#fetch-products\}

Получив пейвол, можно запросить массив продуктов, соответствующих ему:

<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers
Adapty.getPaywallProducts(paywall) { result ->
    when (result) {
        is AdaptyResult.Success -> {
            val products = result.value
            // the requested products
        }
        is AdaptyResult.Error -> {
            val error = result.error
            // handle the error
        }
    }
}
```
</TabItem>
<TabItem value="java" label="Java" default>

```java showLineNumbers
Adapty.getPaywallProducts(paywall, result -> {
    if (result instanceof AdaptyResult.Success) {
        List<AdaptyPaywallProduct> products = ((AdaptyResult.Success<List<AdaptyPaywallProduct>>) result).getValue();
        // the requested products
      
    } else if (result instanceof AdaptyResult.Error) {
        AdaptyError error = ((AdaptyResult.Error) result).getError();
        // handle the error
      
    }
});
```
</TabItem>
</Tabs>

Параметры ответа:

| Параметр | Описание |
| :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Products  | Список объектов [`AdaptyPaywallProduct`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall-product/) с идентификатором продукта, названием, ценой, валютой, длительностью подписки и другими свойствами. |

При создании собственного дизайна пейвола вам, скорее всего, понадобятся свойства объекта [`AdaptyPaywallProduct`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall-product/). Ниже перечислены наиболее часто используемые из них, а полный список доступен в документации по ссылке.

| Свойство | Описание |
|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Title** | Для отображения названия продукта используйте `product.localizedTitle`. Локализация основана на стране, выбранной пользователем в сторе, а не на локали устройства. |
| **Price** | Для отображения цены в локализованном виде используйте `product.price.localizedString`. Локализация основана на настройках локали устройства. Цену в виде числа можно получить через `product.price.amount` — значение указывается в местной валюте. Символ валюты доступен через `product.price.currencySymbol`. |
| **Subscription Period** | Для отображения периода (например, неделя, месяц, год и т. д.) используйте `product.subscriptionDetails?.localizedSubscriptionPeriod`. Локализация основана на локали устройства. Для программного получения периода подписки используйте `product.subscriptionDetails?.subscriptionPeriod`. Из него можно получить enum `unit` с длиной периода (DAY, WEEK, MONTH, YEAR или UNKNOWN), а `numberOfUnits` вернёт количество единиц периода. Например, для квартальной подписки `unit` будет равен `MONTH`, а `numberOfUnits` — `3`. |
| **Introductory Offer** | Чтобы показать бейдж или другой индикатор наличия introductory offer, используйте свойство `product.subscriptionDetails?.introductoryOfferPhases`. Это список, который может содержать до двух фаз скидки: фазу бесплатного пробного периода и фазу вводной цены. Каждый объект фазы содержит следующие полезные свойства:<br/>• `paymentMode`: enum со значениями `FREE_TRIAL`, `PAY_AS_YOU_GO`, `PAY_UPFRONT` и `UNKNOWN`. Бесплатные пробные периоды относятся к типу `FREE_TRIAL`.<br/>• `price`: цена со скидкой в виде числа. Для бесплатных пробных периодов здесь будет `0`.<br/>• `localizedNumberOfPeriods`: строка, локализованная с учётом локали устройства, описывающая длительность оффера. Например, для трёхдневного пробного периода здесь будет `3 days`.<br/>• `subscriptionPeriod`: отдельные параметры периода оффера. Работает так же, как описано в предыдущем разделе.<br/>• `localizedSubscriptionPeriod`: отформатированный период подписки скидки для локали пользователя. |

## Ускорение загрузки пейвола с помощью пейвола для аудитории по умолчанию \{#speed-up-paywall-fetching-with-default-audience-paywall\}

Как правило, пейволы загружаются почти мгновенно, и беспокоиться об ускорении этого процесса не нужно. Однако если у вас много аудиторий и пейволов, а пользователи работают с медленным интернетом, загрузка может занимать больше времени, чем хотелось бы. В таких ситуациях может быть полезно отображать пейвол по умолчанию, чтобы не оставлять экран пустым.

Для этого используйте метод `getPaywallForDefaultAudience`, который загружает пейвол указанного плейсмента для аудитории **All Users**. Важно понимать, что рекомендуемый подход — использовать метод `getPaywall`, как описано в разделе [Получение информации о пейволе](fetch-paywalls-and-products-android#fetch-paywall-information) выше.

:::warning
Почему мы рекомендуем использовать `getPaywall`

Метод `getPaywallForDefaultAudience` имеет несколько существенных недостатков:

- **Возможные проблемы с обратной совместимостью**: если вам нужно показывать разные пейволы для разных версий приложения (текущей и будущих), вы можете столкнуться с трудностями. Придётся либо проектировать пейволы с поддержкой текущей (устаревшей) версии, либо мириться с тем, что пользователи на старых версиях могут видеть неотображаемые пейволы.
- **Потеря таргетинга**: все пользователи будут видеть один пейвол, созданный для аудитории **All Users**, — то есть вы теряете персонализированный таргетинг (по странам, маркетинговой атрибуции или собственным пользовательским атрибутам).

Если вы готовы принять эти недостатки ради ускорения загрузки пейволов, используйте метод `getPaywallForDefaultAudience` как описано ниже. В противном случае придерживайтесь метода `getPaywall`, описанного [выше](fetch-paywalls-and-products-android#fetch-paywall-information).
:::

<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers
Adapty.getPaywallForDefaultAudience("YOUR_PLACEMENT_ID", locale = "en") { result ->
    when (result) {
        is AdaptyResult.Success -> {
            val paywall = result.value
            // the requested paywall
        }
        is AdaptyResult.Error -> {
            val error = result.error
            // handle the error
        }
    }
}
```
</TabItem>
<TabItem value="java" label="Java" default>

```java showLineNumbers
Adapty.getPaywallForDefaultAudience("YOUR_PLACEMENT_ID", "en", result -> {
    if (result instanceof AdaptyResult.Success) {
        AdaptyPaywall paywall = ((AdaptyResult.Success<AdaptyPaywall>) result).getValue();
        // the requested paywall
      
    } else if (result instanceof AdaptyResult.Error) {
        AdaptyError error = ((AdaptyResult.Error) result).getError();
        // handle the error
      
    }
});
```
</TabItem>
</Tabs>

:::note
Метод `getPaywallForDefaultAudience` доступен начиная с версии Android SDK 2.11.3.
:::

| Параметр | Наличие | Описание |
|---------|--------|-----------|
| **placementId** | обязательный | Идентификатор [плейсмента](placements). Это значение вы указали при создании плейсмента в дашборде Adapty. |
| **locale** | <p>опциональный</p><p>по умолчанию: `en`</p> | <p>Идентификатор [локализации пейвола](add-remote-config-locale). Ожидается языковой код, состоящий из одного или нескольких подтегов, разделённых символом минус (**-**). Первый подтег — язык, второй — регион.</p><p></p><p>Например: `en` означает английский, `pt-br` — бразильский португальский.</p><p></p><p>Подробнее о кодах локалей и рекомендациях по их использованию читайте в разделе [Локализации и коды локалей](android-localizations-and-locale-codes).</p> |
| **fetchPolicy** | по умолчанию: `.reloadRevalidatingCacheData` | <p>По умолчанию SDK пытается загрузить данные с сервера и возвращает кешированные данные в случае ошибки. Мы рекомендуем этот вариант, поскольку он гарантирует актуальность данных для ваших пользователей.</p><p></p><p>Если вы считаете, что ваши пользователи работают с нестабильным интернетом, рассмотрите вариант `.returnCacheDataElseLoad` — он возвращает кешированные данные, если они есть. В таком случае пользователи могут не получить самые свежие данные, зато загрузка будет быстрее вне зависимости от качества соединения. Кеш регулярно обновляется, поэтому его безопасно использовать в течение сессии для сокращения сетевых запросов.</p><p></p><p>Обратите внимание: кеш сохраняется после перезапуска приложения и очищается только при переустановке или вручную.</p> |