---
title: "Temporizador de paywall"
description: "Usa la función de temporizador de paywall de Adapty para aumentar las conversiones y crear urgencia."
---

El temporizador del paywall es una herramienta ideal para promocionar ofertas especiales y de temporada con límite de tiempo. Sin embargo, es importante tener en cuenta que este temporizador no está vinculado a la validez de la oferta ni a la duración de la campaña. Es simplemente una cuenta regresiva independiente que parte del valor que tú configures y disminuye hasta cero. Cuando el temporizador llega a cero, no ocurre nada: simplemente se queda en cero.

  <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
Los temporizadores de paywall solo están disponibles en el [nuevo Paywall Builder](adapty-paywall-builder), que funciona con los SDKs de iOS, Android y React Native versión 3.0 o superior, y los SDKs de Flutter y Unity versión 3.3.0 o superior. El Paywall Builder heredado con el SDK de Adapty v2.x o anterior no es compatible con la funcionalidad de temporizadores de paywall.

:::

Puedes personalizar el texto antes y después del temporizador para crear el mensaje que quieras, por ejemplo: "La oferta termina en: 10:00 seg."

  <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. Añade un temporizador como elemento independiente en un paywall o dentro de otro elemento del paywall, como una tarjeta.

2. Configura los ajustes del temporizador: formato y separador, valor inicial, texto antes y después (si lo necesitas), color, fuente, espaciado, etc.

  <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 */
  }}
/>

## Modo del temporizador \{#timer-mode\}

Puedes controlar el comportamiento del temporizador cuando los usuarios lo ven mediante el parámetro **Timer mode**. Hay 3 modos estándar que funcionan sin configuración adicional: simplemente selecciona la opción que necesites en la lista desplegable:
| Modo                                  | Descripción                                                  |
| ------------------------------------- | ------------------------------------------------------------ |
| **Reset timer on every paywall view** | El temporizador se reinicia cada vez que el usuario ve el paywall, comenzando desde el valor inicial cada vez. |
| **Reset timer on every app launch**   | El temporizador comienza la primera vez que el usuario ve el paywall y sigue contando en primer plano o en segundo plano hasta que se reinicia la aplicación. Si el usuario ve el paywall varias veces en la misma sesión, verá el mismo temporizador en cuenta regresiva. Una vez que se cierra la aplicación, el temporizador se reinicia, y la próxima vez que se abra la aplicación, el temporizador vuelve a empezar desde el principio. |
| **Keep timer across app launches**    | El temporizador comienza la primera vez que el usuario ve el paywall y sigue contando en primer plano o en segundo plano, incluso si se cierra la aplicación. El usuario verá el mismo temporizador cada vez que vuelva al paywall, independientemente de los reinicios de la aplicación o del paywall. |
| **Developer defined**                 | Puedes configurar cualquier temporizador que necesites directamente en el código de tu aplicación. Empieza introduciendo un **Timer ID** y luego úsalo en tu código tal como se explica en la sección [Cómo configurar temporizadores definidos por el desarrollador en tu aplicación](paywall-timer#how-to-set-up-developer-defined-timers-in-your-mobile-app) para configurar el temporizador como prefieras. |
## ¿Qué ocurre cuando termina el temporizador? \{#what-happens-when-the-timer-ends\}

Puedes personalizar qué sucede cuando se agota el temporizador. ¿Mostrar otra pantalla con una nueva oportunidad? ¿O quizás un paywall diferente? Requiere algo de código, pero con nuestra documentación lo resolverás sin problema.

1. Activa el toggle **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. Introduce el ID de la acción que quieres activar en el campo **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. Usa este ID de acción en tu app para definir qué debe ocurrir cuando el temporizador termine. Trátalo como cualquier otra acción personalizada, tal como se explica en nuestra guía **Manejo de Eventos: Acciones** para [iOS](ios-handling-events#user-generated-events) y [Android](android-handling-events#user-generated-events).
## ¿Cómo configurar temporizadores definidos por el desarrollador en tu app? \{#how-to-set-up-developer-defined-timers-in-your-mobile-app\}

Para usar temporizadores personalizados en tu app, crea un objeto que siga el protocolo `AdaptyTimerResolver`. Este objeto define cómo debe renderizarse cada temporizador personalizado. Si lo prefieres, puedes usar directamente un diccionario `[String: Date]`, ya que ya cumple con este protocolo. Aquí tienes un ejemplo:

<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
        }
    }
}
```
En este ejemplo, `CUSTOM_TIMER_NY` y `CUSTOM_TIMER_6H` son los **Timer ID**s de los temporizadores definidos por el desarrollador que configuraste en el Adapty Dashboard. El `timerResolver` garantiza que tu app actualice dinámicamente cada temporizador con el valor correcto. Por ejemplo:

- `CUSTOM_TIMER_NY`: El tiempo restante hasta el final del temporizador, como el día de Año Nuevo.
- `CUSTOM_TIMER_6H`: El tiempo restante en un período de 6 horas que comenzó cuando el usuario abrió el paywall.

</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, // Año Nuevo 2025
)
val timerResolver = AdaptyUiTimerResolver { timerId ->
    customTimers.getOrElse(timerId, { Date(System.currentTimeMillis() + 3600 * 1000L) /* en 1 hora */ } )
}
```
En este ejemplo, `CUSTOM_TIMER_NY` es el **Timer ID** del temporizador definido por el desarrollador que configuraste en el Adapty Dashboard. El `timerResolver` garantiza que tu aplicación actualice dinámicamente el temporizador con el valor correcto, como `13d 09h 03m 34s` (calculado como la hora de finalización del temporizador, por ejemplo, el día de Año Nuevo, menos la hora actual).

</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); /* en 1 hora */
    }
};
```
En este ejemplo, `CUSTOM_TIMER_NY` es el **Timer ID** del temporizador definido por el desarrollador que configuraste en el Adapty Dashboard. El `timerResolver` garantiza que tu app actualice dinámicamente el temporizador con el valor correcto, como `13d 09h 03m 34s` (calculado como la hora de fin del temporizador, por ejemplo el Año Nuevo, menos la hora actual).

</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
    }
```
En este ejemplo, `CUSTOM_TIMER_NY` y `CUSTOM_TIMER_6H` son los **Timer ID**s de los temporizadores definidos por el desarrollador que configuraste en el Adapty Dashboard. El `timerResolver` garantiza que tu aplicación actualice dinámicamente cada temporizador con el valor correcto. Por ejemplo:

- `CUSTOM_TIMER_NY`: El tiempo restante hasta el final del temporizador, como el Año Nuevo.
- `CUSTOM_TIMER_6H`: El tiempo restante en un período de 6 horas que comenzó cuando el usuario abrió el paywall.

</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 horas
      { "CUSTOM_TIMER_NY", new DateTime(2025, 1, 1) } // Año Nuevo 2025
    }
  )

AdaptyUI.CreateView(paywall, parameters, (view, error) => {
  // manejar el resultado
});
```
- En este ejemplo, `CUSTOM_TIMER_NY` y `CUSTOM_TIMER_6H` son los **Timer ID**s de los temporizadores definidos por el desarrollador que configuraste en el Adapty Dashboard. El `timerResolver` garantiza que tu app actualice dinámicamente cada temporizador con el valor correcto. Por ejemplo:

  - `CUSTOM_TIMER_NY`: El tiempo restante hasta el fin del temporizador, como el día de Año Nuevo.
  - `CUSTOM_TIMER_6H`: El tiempo restante en un período de 6 horas que comenzó cuando el usuario abrió el paywall.

</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 })
```

En este ejemplo, `CUSTOM_TIMER_NY` es el **Timer ID** del temporizador definido por el desarrollador que configuraste en el Adapty Dashboard. El `timerResolver` garantiza que tu app actualice dinámicamente el temporizador con el valor correcto, como `13d 09h 03m 34s` (calculado como el tiempo de finalización del temporizador, por ejemplo el Año Nuevo, menos el tiempo actual).

 </TabItem>
 </Tabs>