---
title: "Таймер пейвола"
description: "Используйте таймер пейвола Adapty для повышения конверсий и создания ощущения срочности."
---

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

  <img src="/assets/shared/img/87de83a-Timer_withou_text.webp"
  style={{
    border: 'none', /* border width and color */
    width: '200px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

:::warning

Таймеры пейвола доступны только в [новом Paywall Builder](adapty-paywall-builder), который работает с iOS, Android и React Native SDK версии 3.0 и выше, а также с Flutter и Unity SDK версии 3.3.0 и выше. Устаревший Paywall Builder с Adapty SDK v2.x и ниже не поддерживает функцию таймера пейвола.

:::

Вы можете настроить текст до и после таймера, чтобы создать нужное сообщение, например: «Предложение истекает через: 10:00 сек.»

  <img src="/assets/shared/img/f1be626-timer_example.webp"
  style={{
    border: 'none', /* border width and color */
    width: '200px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

1. Добавьте таймер как отдельный элемент на пейвол или внутрь другого элемента пейвола, например карточки.

2. Настройте параметры таймера: формат и разделитель, начальное значение, текст до и после (если нужно), цвет, шрифт, отступы и т. д.

  <img src="/assets/shared/img/e83e891-timer.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

## Режим таймера \{#timer-mode\}

Вы можете управлять поведением таймера при просмотре пейвола пользователем с помощью параметра **Timer mode**. Три стандартных режима работают «из коробки» — просто выберите нужный вариант из выпадающего списка:

| Режим | Описание |
| ------------------------------------- | ------------------------------------------------------------ |
| **Reset timer on every paywall view** | Таймер сбрасывается каждый раз, когда пользователь видит пейвол, и каждый раз начинает с начального значения. |
| **Reset timer on every app launch**   | Таймер запускается при первом показе пейвола пользователю и продолжает отсчёт на переднем плане или в фоне вплоть до перезапуска приложения. Если пользователь несколько раз видит пейвол в одной сессии, он видит тот же обратный отсчёт. После закрытия приложения таймер сбрасывается и при следующем запуске начинает заново. |
| **Keep timer across app launches**    | Таймер запускается при первом показе пейвола и продолжает отсчёт на переднем плане или в фоне, даже если приложение закрыто. Пользователь будет видеть один и тот же таймер каждый раз, когда возвращается на пейвол, независимо от перезапусков приложения или пейвола. |
| **Developer defined**                 | Вы можете настроить любой таймер напрямую в коде мобильного приложения. Начните с ввода **Timer ID**, а затем используйте его в коде, как описано в разделе [Как настроить таймеры, определяемые разработчиком, в мобильном приложении](paywall-timer#how-to-set-up-developer-defined-timers-in-your-mobile-app), чтобы сконфигурировать таймер под свои нужды. |

## Что происходит, когда таймер заканчивается? \{#what-happens-when-the-timer-ends\}

Вы можете настроить, что произойдёт по истечении таймера. Может, показать другой экран с новой возможностью? Или открыть другой пейвол? Это потребует немного кода, но с нашей документацией вы легко справитесь.

1. Включите переключатель **Trigger custom action when the timer runs out**.

   
     <img src="/assets/shared/img/timer-action-on.webp"
     style={{
       border: '1px solid #727272', /* border width and color */
       width: '700px', /* image width */
       display: 'block', /* for alignment */
       margin: '0 auto' /* center alignment */
     }}
   />
   

2. Введите ID действия, которое нужно запустить, в поле **Timer action ID**.

   
     <img src="/assets/shared/img/timer-action-id.webp"
     style={{
       border: '1px solid #727272', /* border width and color */
       width: '700px', /* image width */
       display: 'block', /* for alignment */
       margin: '0 auto' /* center alignment */
     }}
   />
   
   
3. Используйте этот ID действия в приложении, чтобы определить, что должно произойти по окончании таймера. Обращайтесь с ним как с любым другим пользовательским действием — это описано в нашем руководстве **Handling Events: Actions** для [iOS](ios-handling-events#user-generated-events) и [Android](android-handling-events#user-generated-events).

## Как настроить таймеры, определяемые разработчиком, в мобильном приложении? \{#how-to-set-up-developer-defined-timers-in-your-mobile-app\}

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

<Tabs groupId="current-os" queryString> <TabItem value="swift" label="Swift" default>

```Swift showLineNumbers
@MainActor
struct AdaptyTimerResolverImpl: AdaptyTimerResolver {
    func timerEndAtDate(for timerId: String) -> Date {
        switch timerId {
        case "CUSTOM_TIMER_6H":
            Date(timeIntervalSinceNow: 3600.0 * 6.0) // 6 hours
        case "CUSTOM_TIMER_NY":
            Calendar.current.date(from: DateComponents(year: 2025, month: 1, day: 1)) ?? Date(timeIntervalSinceNow: 3600.0)
        default:
            Date(timeIntervalSinceNow: 3600.0) // 1 hour
        }
    }
}
```

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

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

</TabItem> <TabItem value="kotlin" label="Kotlin" default> 

```kotlin showLineNumbers

...

val customTimers = mapOf(
    "CUSTOM_TIMER_NY" to Calendar.getInstance(TimeZone.getDefault()).apply { set(2025, 0, 1) }.time, // New Year 2025
)
val timerResolver = AdaptyUiTimerResolver { timerId ->
    customTimers.getOrElse(timerId, { Date(System.currentTimeMillis() + 3600 * 1000L) /* in 1 hour */ } )
}
```

В этом примере `CUSTOM_TIMER_NY` — это **Timer ID** таймера, определяемого разработчиком, который вы задали в дашборде Adapty. `timerResolver` обеспечивает динамическое обновление таймера с правильным значением — например, `13д 09ч 03м 34с` (вычисляется как время окончания таймера, например Новый год, минус текущее время).

</TabItem> <TabItem value="java" label="Java" default> 

```JAVA showLineNumbers

...

Map<String, Date> customTimers = new HashMap<>();
customTimers.put(
        "CUSTOM_TIMER_NY",
        new Calendar.Builder().setTimeZone(TimeZone.getDefault()).setDate(2025, 0, 1).build().getTime()
);
AdaptyUiTimerResolver timerResolver = new AdaptyUiTimerResolver() {
    @NonNull
    @Override
    public Date timerEndAtDate(@NonNull String timerId) {
        Date date = customTimers.get(timerId);
        return date != null ? date : new Date(System.currentTimeMillis() + 3600 * 1000L); /* in 1 hour */
    }
};
```

В этом примере `CUSTOM_TIMER_NY` — это **Timer ID** таймера, определяемого разработчиком, который вы задали в дашборде Adapty. `timerResolver` обеспечивает динамическое обновление таймера с правильным значением — например, `13д 09ч 03м 34с` (вычисляется как время окончания таймера, например Новый год, минус текущее время).

</TabItem> <TabItem value="flutter" label="Flutter" default> 

```dart showLineNumbers
try {
      final view = await AdaptyUI().createPaywallView(
        paywall: paywall,
        customTags: ...,
        customTimers: {
          'CUSTOM_TIMER_6H': DateTime.now().add(const Duration(seconds: 3600 * 6)),
          'CUSTOM_TIMER_NY': DateTime(2025, 1, 1), // New Year 2025
        },
        preloadProducts: ...,
      );
    } 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`: время, оставшееся в 6-часовом периоде, который начался, когда пользователь открыл пейвол.

</TabItem> 

<TabItem value="unity" label="Unity (C#)" default> 

```csharp showLineNumbers
var parameters = new AdaptyUICreateViewParameters()
  .SetCustomTimers(
    new Dictionary<string, DateTime> {
      { "CUSTOM_TIMER_6H", DateTime.Now.AddHours(6) }, // 6 hours
      { "CUSTOM_TIMER_NY", new DateTime(2025, 1, 1) } // New Year 2025
    }
  )

AdaptyUI.CreateView(paywall, parameters, (view, error) => {
  // handle the result
});
```

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

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

</TabItem> 

 <TabItem value="rn" label="React Native (TS)" default> 

```typescript showLineNumbers
let customTimers = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) }
//and then you can pass it to createPaywallView as follows:
view = await createPaywallView(paywall, { customTimers })
```

В этом примере `CUSTOM_TIMER_NY` — это **Timer ID** таймера, определяемого разработчиком, который вы задали в дашборде Adapty. `timerResolver` обеспечивает динамическое обновление таймера с правильным значением — например, `13д 09ч 03м 34с` (вычисляется как время окончания таймера, например Новый год, минус текущее время).

 </TabItem> 
 </Tabs>