---
title: "Flujos de eventos"
description: "Descubre esquemas detallados de flujos de eventos de suscripción en Adapty. Aprende cómo se generan y envían los eventos de suscripción a las integraciones, lo que te ayuda a rastrear los momentos clave en el recorrido de tus clientes."
---

En Adapty, recibirás distintos eventos de suscripción a lo largo del ciclo de vida de un cliente en tu app. Estos flujos de suscripción describen los escenarios más habituales para ayudarte a entender qué eventos genera Adapty cuando los usuarios se suscriben, cancelan o reactivan suscripciones.

Ten en cuenta que Apple procesa los pagos de suscripción varias horas antes del inicio/renovación real. En los flujos siguientes, mostramos el inicio/renovación de la suscripción y el cargo al mismo tiempo para mantener los diagramas claros.
Además, los eventos relacionados con la misma acción ocurren de forma simultánea y pueden aparecer en tu **Event Feed** en cualquier orden, que podría diferir de la secuencia mostrada en nuestros diagramas.
## Ciclo de vida de una suscripción \{#subscription-lifecycle\}
### Flujo de compra inicial \{#initial-purchase-flow\}

Este flujo ocurre cuando un cliente compra una suscripción por primera vez sin período de prueba. En esta situación, se crean los siguientes eventos:

- **Subscription started**
- **Access level updated** para conceder acceso al usuario

Cuando llega la fecha de renovación de la suscripción, esta se renueva. En ese caso, se crean los siguientes eventos:

- **Subscription renewal** para iniciar un nuevo período de la suscripción
- **Access level updated** para actualizar la fecha de vencimiento de la suscripción y extender el acceso por otro período
Las situaciones en las que el pago no se realiza correctamente o el usuario cancela la renovación se describen en [Flujo de resultado por problema de facturación](event-flows#billing-issue-outcome-flow) y [Flujo de cancelación de suscripción](event-flows#subscription-cancellation-flow), respectivamente.

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

### Flujo de cancelación de suscripción \{#subscription-cancellation-flow\}

Cuando un usuario cancela su suscripción, se crean los siguientes eventos:

- **Subscription renewal canceled** para indicar que la suscripción sigue activa hasta el final del período actual, tras el cual el usuario perderá el acceso
- El evento **Access level updated** se crea para deshabilitar la renovación automática del nivel de acceso

Una vez que finaliza la suscripción, se activa el evento **Subscription expired (churned)** para marcar el fin de la suscripción.

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

Si se aprueba un reembolso, el siguiente evento reemplaza a **Subscription expired (churned)**:

- **Subscription refunded** para finalizar la suscripción y proporcionar detalles sobre el reembolso

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

En Stripe, una suscripción puede cancelarse de forma inmediata, saltándose el período restante. En ese caso, todos los eventos se crean simultáneamente:

- **Subscription renewal cancelled**
- **Subscription expired (churned)**
- **Access Level updated** para revocar el acceso del usuario
Si se aprueba un reembolso, también se activa el evento **Subscription refunded** cuando se aprueba.

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

### Flujo de reactivación de suscripción \{#subscription-reactivation-flow\}

Si un usuario cancela una suscripción, esta expira y luego vuelve a comprar la misma suscripción, se creará un evento **Subscription renewed**. Aunque haya un período sin acceso, Adapty lo trata como una única cadena de transacciones vinculadas por el `vendor_original_transaction_id`. Por eso, la recompra se considera una renovación.

Los eventos **Access level updated** se crearán dos veces:

- al finalizar la suscripción, para revocar el acceso del usuario
- al recomprar la suscripción, para conceder el acceso

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

### Flujo de pausa de suscripción (solo Android) \{#subscription-pause-flow-android-only\}

Este flujo aplica cuando un usuario pausa y luego reanuda una suscripción en Android.

Pausar una suscripción tiene efectos diferidos. Si un usuario pausa una suscripción antes de que se renueve, la suscripción sigue activa y el usuario mantiene el acceso de pago por el resto del período de facturación.
1. Cuando el usuario pausa una suscripción, se activa el evento **Subscription paused (Android only)**.
2. Al final del período de suscripción, Adapty activa el evento **Access level updated** para revocar el acceso del usuario.
3. Cuando el usuario reanuda la suscripción, se activan los siguientes eventos:

    - **Subscription renewed**
    - **Access level updated** para restablecer el acceso del usuario

Estas suscripciones pertenecerán a la misma cadena de transacciones, vinculadas con el mismo **vendor_original_transaction_id**.

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

## Flujos de prueba \{#trial-flows\}

Si usas períodos de prueba en tu app, recibirás eventos adicionales relacionados con ellos.
### Flujo de prueba con conversión exitosa \{#trial-with-successful-conversion-flow\}

El flujo más habitual ocurre cuando un usuario inicia una prueba, introduce una tarjeta de crédito y se convierte en suscriptor estándar al finalizar el período de prueba. En este caso, se crean los siguientes eventos en el momento en que comienza la prueba:

- **Trial started** para marcar el inicio de la prueba
- **Access level updated** para conceder acceso

El evento **Trial converted** se crea cuando comienza la suscripción estándar.

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

### Flujo de prueba sin conversión exitosa \{#trial-without-successful-conversion-flow\}

Si un usuario cancela la prueba antes de que se convierta en una suscripción, se crean los siguientes eventos en el momento de la cancelación:

- **Trial renewal cancelled** para deshabilitar la conversión automática de la prueba en una suscripción
- **Access level updated** para deshabilitar la renovación del acceso

El usuario mantendrá el acceso hasta el final del período de prueba, momento en el que se crea el evento **Trial expired** para marcar su fin.

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

### Reactivación de suscripción tras un período de prueba expirado \{#subscription-reactivation-after-expired-trial-flow\}

Si un período de prueba expira (por un problema de facturación o cancelación) y el usuario compra una suscripción posteriormente, se crean los siguientes eventos:

- **Access level updated** para conceder acceso al usuario
- **Trial converted**

Aunque haya un intervalo entre el período de prueba y la suscripción, Adapty vincula ambos mediante `vendor_original_transaction_id`. Esta conversión se trata como parte de una cadena de transacciones continua que comienza con un período de prueba de precio cero. Por eso se crea el evento **Trial converted** en lugar de **Subscription started**.

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

## Cambios de producto \{#product-changes\}

Esta sección recoge los cambios realizados en suscripciones activas, como actualizaciones, degradaciones o compras de un producto de otro grupo.
### Flujo de cambio inmediato de producto \{#immediate-product-change-flow\}

Cuando un usuario cambia de producto, el cambio puede aplicarse en el sistema de forma inmediata antes de que finalice la suscripción (principalmente en casos de mejora o sustitución de producto). En ese momento, al producirse el cambio de producto:
- El nivel de acceso cambia y se crean dos eventos **Access level updated**:
  1. Para retirar el acceso al primer producto.
  2. Para conceder acceso al segundo producto.
- La suscripción antigua finaliza y se emite un reembolso (se crea el evento **Subscription refunded** con `cancellation_reason` = `upgraded`). Ten en cuenta que no se crea ningún evento **Subscription expired (churned)**; el evento **Subscription refunded** lo reemplaza.
- La nueva suscripción comienza (se crea el evento **Subscription started** para el nuevo producto).

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

Si un usuario cambia a un plan inferior, la primera suscripción se mantendrá activa hasta el final del período pagado, y cuando termine, será reemplazada por la nueva suscripción de nivel inferior. En este caso, solo se creará de inmediato el evento **Access level updated** para deshabilitar la renovación automática del acceso. El resto de eventos se crearán en el momento en que se produzca el cambio real de suscripción:
- Se crea otro evento **Access level updated** para dar acceso al segundo producto.
- Se crea el evento **Subscription expired (churned)** para finalizar la suscripción del primer producto.
- Se crea el evento **Subscription started** para iniciar una nueva suscripción con el nuevo producto.

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

### Flujo de cambio de producto diferido \{#delayed-product-change-flow\}

También existe una variante en la que el usuario cambia el producto en el momento de la renovación de la suscripción. Esta variante es muy similar a la anterior: se creará un evento **Access level updated** de inmediato para desactivar la renovación automática del acceso del producto antiguo. El resto de eventos se crearán en el momento en que el usuario realice el cambio de suscripción y este quede registrado en el sistema:
- Se crea otro evento **Access level updated** para conceder acceso al segundo producto.
- Se crea el evento **Subscription expired (churned)** para finalizar la suscripción del primer producto.
- Se crea el evento **Subscription started** para iniciar una nueva suscripción con el nuevo producto.

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

## Flujo de resultados por problemas de facturación \{#billing-issue-outcome-flow\}

Si los intentos de convertir una prueba o renovar una suscripción fallan por un problema de facturación, lo que ocurre a continuación depende de si hay un período de gracia habilitado.

Con un período de gracia, si el pago tiene éxito, la prueba se convierte o la suscripción se renueva. Si falla, el store seguirá intentando cobrar al usuario por la suscripción y, si sigue fallando, el store terminará la prueba o suscripción por su cuenta.

Por lo tanto, en el momento del problema de facturación, se crean los siguientes eventos en Adapty:
- **Billing issue detected**
- **Entered grace period** (si el período de gracia está habilitado)
- **Access level updated** para mantener el acceso hasta el final del período de gracia

Si el pago se realiza correctamente después, Adapty registra un evento **Trial converted** o **Subscription renewed**, y el usuario no pierde el acceso.

Si el pago falla definitivamente y el store cancela la suscripción, Adapty genera estos eventos:

- **Trial expired** o **Subscription expired (churned)** con `cancellation_reason: billing_error`
- **Access level updated** para revocar el acceso del usuario

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

Sin un período de gracia, el período de reintento de facturación (el período en el que el store intenta cobrar al usuario de nuevo) comienza de inmediato.
Si el pago nunca se completa antes de que finalice el período de gracia, el flujo es el mismo: se crean los mismos eventos cuando el store termina la suscripción automáticamente:

- Evento **Trial expired** o **Subscription expired (churned)** con un `cancellation_reason` de `billing_error`

- **Access level updated** para revocar el acceso del usuario

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

## Flujos para compartir compras entre cuentas de usuario \{#sharing-purchases-across-user-accounts-flows\}
Cuando un <InlineTooltip tooltip="Customer User ID">[iOS](identifying-users#set-customer-user-id-on-configuration), [Android](android-identifying-users#setting-customer-user-id-on-configuration), [React Native](react-native-identifying-users#setting-customer-user-id-on-configuration), [Flutter](flutter-identifying-users#setting-customer-user-id-on-configuration), y [Unity](unity-identifying-users#setting-customer-user-id-on-configuration)</InlineTooltip> intenta restaurar o ampliar una suscripción ya vinculada a un <InlineTooltip tooltip="Customer User ID">[iOS](identifying-users#set-customer-user-id-on-configuration), [Android](android-identifying-users#setting-customer-user-id-on-configuration), [React Native](react-native-identifying-users#setting-customer-user-id-on-configuration), [Flutter](flutter-identifying-users#setting-customer-user-id-on-configuration), y [Unity](unity-identifying-users#setting-customer-user-id-on-configuration)</InlineTooltip> diferente, la configuración **Sharing paid access between user accounts** de Adapty controla cómo se gestiona el acceso. El flujo variará según la opción seleccionada.
:::note
Para las transacciones de Apple Family Sharing (`in_app_ownership_type=FAMILY_SHARED`), solo se activa el evento **Access level updated** — los eventos de suscripción por producto que aparecen a continuación no se generan. Consulta [Apple Family Sharing](apple-family-sharing) para ver la matriz completa de eventos.
:::

:::note
Si un usuario pulsa **Restore Purchases** pero ya tiene acceso en el mismo perfil, la restauración no hace nada y no se activan eventos de webhook. Los eventos de esta sección solo se activan cuando el acceso se transfiere realmente entre perfiles.
:::
Para ver de un vistazo qué eventos se disparan cuando un segundo perfil reclama una suscripción existente, usa esta matriz. Las secciones siguientes muestran el payload JSON completo de cada flujo.
| Evento | Habilitado (predeterminado) | Transferir acceso al nuevo usuario | Deshabilitado |
| --- | --- | --- | --- |
| Nuevo perfil: **Access level updated** (`is_active=true`) | Se activa | Se activa | No se activa |
| Perfil antiguo: **Access level updated** (`is_active=false`) | No se activa — ambos perfiles conservan el acceso | Se activa cuando el nuevo dispositivo identificado propaga la transacción | No se activa — el perfil original conserva el acceso |
| Campo `profiles_sharing_access_level` en el nuevo evento | Lista los demás perfiles que comparten el nivel de acceso | `null` | No aplicable — no se activa ningún evento |
Las renovaciones, reembolsos y vencimientos de una suscripción transferida siguen generando los eventos `subscription_renewed`, `subscription_refunded` y `subscription_expired` en el perfil que tenga el nivel de acceso en ese momento. El propio evento de transferencia no emite un evento `subscription_started`, ya que no se registra ninguna transacción nueva: solo cambia la atribución.

Para más detalles sobre cada modo, consulta la [referencia práctica](sharing-paid-access-between-user-accounts#practical-reference).
### Transferir el nivel de acceso al nuevo usuario \{#transfer-access-to-new-user-flow\}

La opción recomendada es transferir el nivel de acceso al nuevo usuario. Esto conserva el historial de transacciones del usuario original para mantener la coherencia en los análisis. Solo se crearán 2 eventos **Access level updated**:

1. para eliminar el acceso del primer usuario
2. para conceder acceso al segundo usuario

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

A continuación se explican los campos relacionados con la asignación y transferencia del nivel de acceso en los eventos generados en este escenario:

- **Usuario A: Nivel de acceso actualizado (se envía cuando el Usuario A compra una suscripción en la app)**
```json showLineNumbers
  {
    "profile_id": "00000000-0000-0000-0000-000000000000",
    "customer_user_id": UserA,
    "event_properties": {
      "profile_has_access_level": true,
    },
    "profiles_sharing_access_level": null
  }
  ```

- **Usuario A: Nivel de acceso actualizado (se envía cuando la app se reinstala y el Usuario B inicia sesión, revocando el acceso del Usuario A)**
```json showLineNumbers
  {
    "profile_id": "00000000-0000-0000-0000-000000000000",
    "customer_user_id": UserA,
    "event_properties": {
      "profile_has_access_level": false,
    },
    "profiles_sharing_access_level": null
  }
  ```

- **Usuario B: Nivel de acceso actualizado (enviado cuando el Usuario B inicia sesión y se concede el acceso)**

  ```json showLineNumbers
  {
    "profile_id": "00000000-0000-0000-0000-000000000001",
    "customer_user_id": UserB,
    "event_properties": {
      "profile_has_access_level": true,
    },
    "profiles_sharing_access_level": null
  }
  ```
### Flujo de acceso compartido entre usuarios \{#shared-access-between-users-flow\}
Esta opción permite que varios usuarios compartan el mismo nivel de acceso si su dispositivo está conectado con el mismo Apple/Google ID. Resulta útil cuando un usuario reinstala la app e inicia sesión con un correo diferente: seguirá teniendo acceso a su compra anterior. Con esta opción, varios usuarios identificados pueden compartir el mismo nivel de acceso. Aunque el nivel de acceso se comparte, todas las transacciones se registran bajo el <InlineTooltip tooltip="Customer User ID">ID de usuario original [iOS](identifying-users#set-customer-user-id-on-configuration), [Android](android-identifying-users#setting-customer-user-id-on-configuration), [React Native](react-native-identifying-users#setting-customer-user-id-on-configuration), [Flutter](flutter-identifying-users#setting-customer-user-id-on-configuration) y [Unity](unity-identifying-users#setting-customer-user-id-on-configuration)</InlineTooltip> para mantener el historial completo de transacciones y el análisis de datos.
Por lo tanto, solo se creará 1 evento: **Access level updated** para conceder acceso al segundo usuario.

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

A continuación se describen los campos relacionados con la asignación y el uso compartido del nivel de acceso en los eventos generados en este escenario:

**Usuario B: Access level updated (enviado cuando el Usuario B inicia sesión y se concede el acceso)**
```json showLineNumbers
  {
    "profile_id": "00000000-0000-0000-0000-000000000000",
    "customer_user_id": UserA,
    "event_properties": {
      "profile_has_access_level": true,
    },
    "profiles_sharing_access_level": [
      {
        "profile_id": "00000000-0000-0000-0000-000000000001,
        "customer_user_id": UserB
      }
    ]
  }
  ```
### Flujo de acceso no compartido entre usuarios \{#access-not-shared-between-users-flow\}
Con esta opción, solo el primer perfil de usuario que recibe el nivel de acceso lo conserva de forma permanente. Es ideal cuando las compras deben vincularse a un único <InlineTooltip tooltip="Customer User ID">[iOS](identifying-users#set-customer-user-id-on-configuration), [Android](android-identifying-users#setting-customer-user-id-on-configuration), [React Native](react-native-identifying-users#setting-customer-user-id-on-configuration), [Flutter](flutter-identifying-users#setting-customer-user-id-on-configuration), y [Unity](unity-identifying-users#setting-customer-user-id-on-configuration)</InlineTooltip>.

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