---
title: "Получение пейволов Paywall Builder и их конфигурации в Flutter SDK"
description: "Узнайте, как получать PB-пейволы в Adapty для улучшенного управления подписками в Flutter."
---

После того как вы [создали визуальную часть пейвола](adapty-paywall-builder) с помощью нового Paywall Builder в дашборде Adapty, его можно отобразить в мобильном приложении. Первый шаг — получить пейвол, связанный с плейсментом, и его конфигурацию представления, как описано ниже.

:::warning
Новый Paywall Builder работает с Flutter SDK версии 3.3.0 и выше.
:::

Обратите внимание: этот раздел посвящён пейволам, настроенным через Paywall Builder. Если вы реализуете пейволы вручную, обратитесь к разделу [Получение пейволов и продуктов для пейволов с Remote Config в мобильном приложении](fetch-paywalls-and-products-flutter).

:::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-flutter) в своё мобильное приложение.
</details>

## Получение пейвола, созданного в Paywall Builder \{#fetch-paywall-designed-with-paywall-builder\}

Если вы [создали пейвол с помощью Paywall Builder](adapty-paywall-builder), вам не нужно самостоятельно заниматься его отрисовкой в коде приложения. Такой пейвол содержит и то, что должно отображаться, и то, как именно это должно выглядеть. Тем не менее вам нужно получить его идентификатор через плейсмент, конфигурацию представления и затем показать пейвол в приложении.

Для максимальной производительности важно получить пейвол и его [конфигурацию представления](flutter-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder) как можно раньше — чтобы изображения успели загрузиться до того, как пользователь увидит пейвол.

Чтобы получить пейвол, используйте метод `getPaywall`:

```dart showLineNumbers
try {
  final paywall = await Adapty().getPaywall(placementId: "YOUR_PLACEMENT_ID", locale: "en");
  // the requested paywall
} on AdaptyError catch (adaptyError) {
  // handle the error
} catch (e) {
}
```

Параметры:

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

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

| Параметр | Описание |
| :-------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Paywall   | Объект [`AdaptyPaywall`](https://pub.dev/documentation/adapty_flutter/latest/adapty_flutter/AdaptyPaywall-class.html) со списком идентификаторов продуктов, идентификатором пейвола, Remote Config и рядом других свойств. |

## Получение конфигурации представления пейвола, созданного в Paywall Builder \{#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder\}

:::important
Убедитесь, что в Paywall Builder включён переключатель **Show on device**. Если он выключен, конфигурация представления не будет доступна для получения.
:::

После загрузки пейвола проверьте, содержит ли он `ViewConfiguration` — это означает, что пейвол создан с помощью Paywall Builder. Наличие `ViewConfiguration` определяет способ отображения пейвола. Если она есть — обрабатывайте как пейвол Paywall Builder; если нет — [обрабатывайте как пейвол с Remote Config](present-remote-config-paywalls-flutter).

```dart showLineNumbers

try {
  final view = await AdaptyUI().createPaywallView(
        paywall: paywall,
      );
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

Получив представление, [отобразите пейвол](flutter-present-paywalls).

## Получение пейвола для аудитории по умолчанию (ускоренный способ) \{#get-a-paywall-for-a-default-audience-to-fetch-it-faster\}

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

Для этого можно использовать метод `getPaywallForDefaultAudience`, который загружает пейвол указанного плейсмента для аудитории **All Users**. Однако рекомендованный подход — использовать метод `getPaywall`, как описано в разделе [Получение пейвола, созданного в Paywall Builder](flutter-get-pb-paywalls#fetch-paywall-designed-with-paywall-builder) выше.

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

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

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

Если вы готовы принять эти ограничения ради ускорения загрузки, используйте метод `getPaywallForDefaultAudience` следующим образом. В противном случае придерживайтесь метода `getPaywall`, описанного [выше](#fetch-paywall-designed-with-paywall-builder).
:::

```dart showLineNumbers
try {
    final paywall = await Adapty().getPaywallForDefaultAudience(placementId: 'YOUR_PLACEMENT_ID');
} on AdaptyError catch (adaptyError) {
    // handle error
} catch (e) {
    // handle unknown error
}
```

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

| Параметр | Обязательность | Описание |
|---------|--------|-----------|
| **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>Подробнее о кодах локалей и рекомендациях по их использованию — в разделе [Локализации и коды локалей](localizations-and-locale-codes).</p> |
| **fetchPolicy** | по умолчанию: `.reloadRevalidatingCacheData` | <p>По умолчанию SDK пытается загрузить данные с сервера, а в случае ошибки возвращает кэшированные данные. Мы рекомендуем этот вариант, поскольку он гарантирует актуальность данных.</p><p></p><p>Однако если у ваших пользователей нестабильное интернет-соединение, рассмотрите вариант `.returnCacheDataElseLoad`: он вернёт кэшированные данные, если они есть. В таком случае данные могут быть не самыми свежими, но загрузка будет быстрее вне зависимости от качества соединения. Кэш регулярно обновляется, поэтому его безопасно использовать в рамках сессии для снижения числа сетевых запросов.</p><p></p><p>Обратите внимание: кэш сохраняется при перезапуске приложения и очищается только при переустановке или ручной очистке.</p> |

## Настройка пользовательских ресурсов \{#customize-assets\}

Чтобы кастомизировать изображения и видео в пейволе, используйте пользовательские ресурсы (custom assets).

Главные изображения и видео имеют предопределённые идентификаторы: `hero_image` и `hero_video`. В наборе пользовательских ресурсов вы обращаетесь к этим элементам по их идентификаторам и настраиваете их поведение.

Для остальных изображений и видео необходимо [задать пользовательский идентификатор](custom-media) в дашборде Adapty.

Например, можно:

- Показывать разные изображения или видео разным пользователям.
- Показывать локальное превью-изображение, пока загружается основное удалённое изображение.
- Показывать превью-изображение перед воспроизведением видео.

:::important
Для использования этой функции обновите Flutter SDK Adapty до версии 3.8.0 или выше.
:::

Пример того, как передать пользовательские ресурсы через простой словарь:

```dart

final customAssets = {
    // Show a local image using a custom ID
    'custom_image': AdaptyCustomAsset.localImageAsset(
        assetId: 'assets/images/image_name.png',
    ),

    // Show a local video with a preview image
    'hero_video': AdaptyCustomAsset.localVideoAsset(
        assetId: 'assets/videos/custom_video.mp4',
    ),
};

try {
    final view = await AdaptyUI().createPaywallView(
        paywall: paywall,
        customAssets: <CUSTOM_ASSETS>,
        preloadProducts: preloadProducts,
        );
    } on AdaptyError catch (e) {
        // handle the error
    } catch (e) {
// handle the error
}
```

:::note
Если ресурс не найден, пейвол вернётся к внешнему виду по умолчанию.
:::

## Настройка таймеров, заданных разработчиком \{#set-up-developer-defined-timers\}

Чтобы использовать пользовательские таймеры в мобильном приложении, создайте объект, реализующий протокол `AdaptyTimerResolver`. Этот объект определяет, как должен отображаться каждый пользовательский таймер. При желании можно напрямую использовать словарь `[String: Date]`, поскольку он уже соответствует этому протоколу. Пример:

```dart showLineNumbers

try {
  final view = await AdaptyUI().createPaywallView(
        paywall: paywall,
        customTimers: {
          'CUSTOM_TIMER_6H': DateTime.now().add(const Duration(seconds: 3600 * 6)),
          'CUSTOM_TIMER_NY': DateTime(2025, 1, 1), // New Year 2025
        },
      );
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

В этом примере `CUSTOM_TIMER_NY` и `CUSTOM_TIMER_6H` — это **Timer ID** таймеров, заданных разработчиком в дашборде Adapty. `timerResolver` обеспечивает динамическое обновление каждого таймера с правильным значением. Например:

- `CUSTOM_TIMER_NY`: время до окончания таймера, например до Нового года.
- `CUSTOM_TIMER_6H`: оставшееся время шестичасового периода, начавшегося с момента открытия пейвола пользователем.