Información sobre las suscripciones

En este tema, se describe cómo controlar los eventos del ciclo de vida de las suscripciones, como las renovaciones y los vencimientos. También se describen funciones de suscripción adicionales, como ofrecer promociones y permitir que los usuarios administren sus propias suscripciones.

Si no configuraste los productos de suscripción para tu app, consulta Cómo crear y configurar tus productos.

Descripción general de las suscripciones

Una suscripción representa un conjunto de beneficios a los que los usuarios pueden acceder durante un período específico. Por ejemplo, una suscripción podría permitir que un usuario acceda a un servicio de transmisión de música.

Puedes tener varias suscripciones dentro de la misma app, ya sea para representar diferentes conjuntos de beneficios o diferentes niveles de un solo conjunto de beneficios (por ejemplo, los niveles "Plata" y "Oro").

Con los planes básicos y las ofertas, puedes crear varias configuraciones para el mismo producto de suscripción. Por ejemplo, puedes crear una oferta de lanzamiento para los usuarios que nunca se suscribieron a tu app. Del mismo modo, puedes crear una oferta de actualización para los usuarios que ya están suscritos.

Para obtener una descripción general detallada de los productos de suscripción, los planes básicos y las ofertas, consulta la documentación del Centro de ayuda de Play Console.

Integración de los planes prepagados

Los planes prepagados no se renuevan automáticamente después de su vencimiento. Para extender el derecho de suscripción sin interrupciones, el usuario debe recargar un plan prepagado de la misma suscripción.

Para las recargas, inicia el flujo de facturación como lo harías con la compra original. No es necesario que indiques que una compra es una recarga.

Las recargas de planes prepagados siempre usan el modo de reemplazo CHARGE_FULL_PRICE, y no necesitas configurar este modo de forma explícita. Al usuario se le cobra de inmediato por un período de facturación completo, y su derecho se extiende por el tiempo especificado en la recarga.

Después de una recarga, se actualizan los siguientes campos del objeto de resultado Purchase para reflejar la compra de recarga más reciente:

  • ID de pedido
  • Hora de la compra
  • Firma
  • Token de compra
  • Aceptado

Los siguientes campos de Purchase siempre contienen los mismos datos que se encuentran en la compra original:

  • Nombre de paquete
  • Estado de la compra
  • Productos
  • Renovación automática

Confirmación de compra prepaga

Al igual que con las suscripciones de renovación automática, debes confirmar los planes prepagados después de la compra. Se deben confirmar tanto la compra inicial como las recargas de dinero. Para obtener más información, consulta Cómo procesar las compras.

Debido a las posibles duraciones breves del plan prepagado, es importante que confirmes la compra lo antes posible.

Los planes prepagados con una duración de una semana o más deben confirmarse en un plazo de tres días.

Los planes prepagados con una duración menor a una semana deben confirmarse en la mitad de la duración del plan. Por ejemplo, los desarrolladores tienen 1.5 días para confirmar un plan prepagado de tres días.

Usa vínculos directos para permitir que los usuarios administren una suscripción

Tu app debe incluir un vínculo a una pantalla de configuración o preferencias que les permita a los usuarios administrar sus suscripciones, el cual puedes incorporar a su apariencia natural.

Puedes incluir un vínculo directo desde tu app al centro de suscripciones de Google Play para las suscripciones no vencidas. Para determinarlo, usa el campo subscriptionState del recurso de suscripción. En función de esto, existen varias formas de establecer vínculos directos con el centro de suscripciones de Play Store.

Usa la siguiente URL para dirigir a los usuarios a la página que muestra todas sus suscripciones, como se muestra en las figuras 1 y 2:

https://play.google.com/store/account/subscriptions
La pantalla de suscripciones de Play Store muestra el estado de todas las suscripciones de un usuario que factura Google Play.
Figura 1: La pantalla de suscripciones de Play Store muestra el estado de todas las suscripciones de un usuario que factura Google Play.


Presiona una suscripción para ver detalles adicionales.
Figura 2: Presiona una suscripción para ver detalles adicionales.

Este vínculo directo podría ser útil para ayudar a un usuario a restablecer una suscripción cancelada desde el centro de suscripciones de Play Store.

Para crear un vínculo directo a la página de administración de una suscripción no vencida, indica el nombre del paquete y el productId asociados con la suscripción comprada. Para determinar de manera programática el productId de una suscripción existente, consulta el backend de tu app o llama a BillingClient.queryPurchasesAsync() para obtener una lista de suscripciones asociadas con un usuario en particular. Cada suscripción contiene el productId correspondiente como parte de la información de estado de la suscripción. Cada objeto SubscriptionPurchaseLineItem asociado con la compra de una suscripción contiene el valor productId relacionado con la suscripción que el usuario compró en esa línea de pedido.

Usa la siguiente URL para dirigir a los usuarios a una pantalla de administración de suscripciones específica. Para ello, reemplaza "your-sub-product-id" y "your-app-package" por productId y el nombre del paquete de la app, respectivamente:

https://play.google.com/store/account/subscriptions?sku=your-sub-product-id&package=your-app-package

Luego, el usuario puede administrar sus formas de pago y acceder a funciones como la cancelación, la resuscripción y la pausa.

Permite que los usuarios actualicen su suscripción, la cambien o regresen a una versión anterior

Puedes proporcionarles a los suscriptores existentes varias opciones para cambiar su plan de suscripción para satisfacer mejor sus necesidades:

  • Si vendes varios niveles de suscripción, como suscripciones básicas y premium, puedes permitir que los usuarios cambien de nivel comprando una oferta o un plan básico de suscripción diferente.
  • Puedes permitir que los usuarios cambien su período de facturación actual, por ejemplo, de un plan mensual a uno anual.
  • También puedes permitir que cambien entre planes prepagados y de renovación automática.

Puedes fomentar cualquiera de estos cambios proporcionando ofertas de suscripción para ofrecer un descuento a los usuarios que cumplen con los requisitos. Por ejemplo, puedes crear una oferta que proporcione un descuento del 50% durante el primer año cuando se cambia de un plan mensual a uno anual y limitarla a los usuarios suscritos a un plan mensual que no compraron esta oferta. Para obtener más información sobre los criterios de elegibilidad de la oferta, consulta el Centro de ayuda.

En la figura 3, se muestra una app de ejemplo con tres planes diferentes:

Esta app tiene tres niveles de suscripción.
Figura 3: Esta app tiene tres niveles de suscripción.

Tu app podría mostrar una pantalla similar a la de la figura 3 y brindar a los usuarios opciones para cambiar su suscripción. En todos los casos, debe quedar claro para los usuarios cuál es su plan de suscripción actual y qué opciones tienen para cambiarlo.

Si los usuarios deciden actualizar su suscripción, cambiarla o regresar a una versión inferior, deberás especificar un modo de reemplazo que determine cómo se aplicará el valor prorrateado del período de facturación pagado vigente y cuándo se producirá cualquier cambio de derecho.

Modos de reemplazo

En la siguiente tabla, se detallan los modos de reemplazo disponibles y ejemplos de uso.

Modo de reemplazo

Descripción

Ejemplo de uso

WITH_TIME_PRORATION

La suscripción se actualiza o se cambia a una versión inferior de inmediato. El tiempo restante se ajusta en función de la diferencia de precio y se atrasa la siguiente fecha de facturación para acreditarlo a la nueva suscripción. Este es el comportamiento predeterminado.

Actualizar a un nivel más costoso sin tener que realizar pagos adicionales inmediatos

CHARGE_PRORATED_PRICE

La suscripción se actualiza de inmediato, y el ciclo de facturación sigue siendo el mismo. Luego se le cobra al usuario la diferencia de precio del período restante.

Nota: Esta opción solo está disponible para una actualización de suscripción, en la que el precio por unidad de tiempo aumenta.

Actualizar a un nivel más costoso sin cambiar la fecha de facturación

CHARGE_FULL_PRICE

Se actualiza la suscripción o cambia a una versión inferior al instante, y al usuario se le cobra el precio total por el nuevo derecho de inmediato. El valor restante de la suscripción anterior se transfiere al mismo derecho o se prorratea para cuando se cambie a un derecho diferente.

Nota: Si la nueva suscripción tiene una prueba gratuita o una oferta de lanzamiento, al usuario se le cobrará USD 0 o el precio de la oferta de lanzamiento, lo que corresponda, al momento de actualizar la suscripción o cambiar a una versión inferior.

Actualizar de un período de facturación más corto a uno más largo

WITHOUT_PRORATION

Se actualiza la suscripción o cambia a una versión inferior de inmediato, y se cobra el precio nuevo cuando esta se renueva. El ciclo de facturación no cambia.

Actualizar a un nivel de suscripción superior sin perder el período gratuito restante

DEFERRED

La suscripción se actualiza o cambia a una versión inferior solo cuando se renueva, pero la compra nueva se emite de inmediato con una fecha de inicio en el futuro para el nuevo derecho, de modo que el desarrollador pueda permitir que los usuarios realicen cambios adicionales si lo desean. Por ejemplo, pueden regresar al plan original o iniciar un nuevo cambio de plan diferido.

Cambiar a un nivel inferior más económico

Para obtener más información sobre las diferentes aplicaciones de la venta incremental y la recuperación de usuarios de las ofertas de actualización o cambio a una versión inferior, lee la guía sobre ofertas y promociones.

Configura el modo de reemplazo para una compra

Puedes usar diferentes modos de reemplazo para los distintos tipos de transiciones de suscripción, según tus preferencias y lógica empresarial. En esta sección, se explica cómo configurar un modo de reemplazo para un cambio en una suscripción y las limitaciones que se aplican.

Permite que el usuario vuelva a suscribirse o cambie de plan dentro de la misma suscripción

Puedes especificar un modo de reemplazo predeterminado en Google Play Console. Esta configuración te permite elegir cuándo hacer el cobro a los suscriptores actuales si compran una oferta o un plan básico diferente por la misma suscripción o si se vuelven a suscribir después de una cancelación. Las opciones disponibles son Cobro inmediato, que equivale a CHARGE_FULL_PRICE, y Cobro en la próxima fecha de facturación, que equivale a WITHOUT_PRORATION. Estos son los únicos modos de reemplazo relevantes cuando se cambia el plan básico dentro de la misma suscripción.

Por ejemplo, si implementas una oferta de recuperación para el mismo plan después de que el usuario cancela, pero antes de que finalice la suscripción, puedes procesar la compra nueva como una compra normal sin indicar ningún valor en SubscriptionUpdateParams. El sistema usa el modo de reemplazo predeterminado que configuraste en la suscripción y maneja automáticamente la transición del plan de la compra anterior a la nueva.

Permite que el usuario cambie de plan entre suscripciones o anule el modo de reemplazo predeterminado

Si el usuario cambia de productos (compra una suscripción distinta) de suscripción, o si quieres anular el modo de reemplazo predeterminado por algún motivo, especifica la tasa de prorrateo durante el tiempo de ejecución como parte de los parámetros del flujo de compra.

Para proporcionar correctamente SubscriptionUpdateParams como parte de la configuración del flujo de compra del tiempo de ejecución, ten en cuenta las siguientes restricciones:

  • Cuando actualizas una suscripción, cambias a una versión inferior o haces un cambio de la misma suscripción a un plan prepagado de un plan prepagado o con renovación automática, el único modo de prorrateo permitido es CHARGE_FULL_PRICE. Si especificas cualquier otro modo de prorrateo, la compra falla y se muestra un error al usuario.
  • Cuando cambies de plan dentro de la misma suscripción a un plan con renovación automática de un plan prepagado o con renovación automática, los modos de prorrateo válidos serán CHARGE_FULL_PRICE y WITHOUT_PRORATION. Si especificas cualquier otro modo de prorrateo, la compra falla y se muestra un error al usuario.

Ejemplos y comportamientos del reemplazo

Para comprender cómo funciona cada modo de prorrateo, piensa en la siguiente situación:

Pedro tiene una suscripción al contenido en línea de la app de Country Gardener. Tiene una suscripción mensual a la versión de Nivel 1 del contenido, que es solo de texto. Esta suscripción le cuesta USD 2 por mes y se renueva el primer día del mes.

El 15 de abril, Pedro eligió actualizar a la versión anual de la suscripción de Nivel 2, que incluye actualizaciones de video y tiene un costo de USD 36 por año.

Al actualizar la suscripción, el desarrollador selecciona un modo de prorrateo. En la siguiente lista, se describe la forma en que cada modo de prorrateo modifica la suscripción de Pedro:

WITH_TIME_PRORATION

La suscripción de Pedro al Nivel 1 finaliza de inmediato. Dado que pagó un mes completo (del 1 al 30 de abril), pero realizó la actualización a mitad del período de suscripción, se aplica la mitad de la suscripción mensual (USD 1) a su nueva suscripción. Sin embargo, como la nueva suscripción tiene un costo de USD 36 por año, se paga el saldo de crédito de USD 1 solo durante 10 días (del 16 al 25 de abril); por lo tanto, se le cobran USD 36 el 26 de abril por una nueva suscripción y otros USD 36 el 26 de abril de cada año siguiente.

Deberías llamar al PurchasesUpdatedListener de tu app apenas la compra se realiza correctamente, y puedes recuperar la compra nueva como parte de una llamada queryPurchasesAsync(). Tu backend recibe de inmediato una notificación para desarrolladores en tiempo real SUBSCRIPTION_PURCHASED.

CHARGE_PRORATED_PRICE

Se puede usar este modo porque el precio de suscripción al Nivel 2 por unidad de tiempo (USD 36 por año = USD 3 por mes) es mayor que el precio de suscripción al Nivel 1 por unidad de tiempo (USD 2 por mes). La suscripción de Pedro al Nivel 1 finaliza de inmediato. Dado que pagó un mes completo, pero utilizó solamente la mitad, se aplica la mitad de la suscripción mensual (USD 1) a su nueva suscripción. Sin embargo, como la nueva suscripción tiene un costo de USD 36 por año, los 15 días restantes cuestan USD 1.50, por lo que se le cobra la diferencia de USD 0.50 por su suscripción nueva. El 1 de mayo, se le cobran a Pedro USD 36 por el nuevo nivel de suscripción y otros USD 36 el 1 de mayo de cada año siguiente.

Deberías llamar al PurchasesUpdatedListener de tu app apenas la compra se realiza correctamente, y puedes recuperar la compra nueva como parte de una llamada queryPurchasesAsync(). Tu backend recibe de inmediato una notificación para desarrolladores en tiempo real SUBSCRIPTION_PURCHASED.

WITHOUT_PRORATION

La suscripción al Nivel 1 de Pedro se actualiza inmediatamente al Nivel 2 sin cargo adicional, y se le cobran USD 36 el 1 de mayo por su nuevo nivel de suscripción y USD 36 el 1 de mayo de cada año siguiente.

Deberías llamar al PurchasesUpdatedListener de tu app apenas la compra se realiza correctamente, y puedes recuperar la compra nueva como parte de una llamada queryPurchasesAsync(). Tu backend recibe de inmediato una notificación para desarrolladores en tiempo real SUBSCRIPTION_PURCHASED.

DEFERRED

La suscripción de Pedro al Nivel 1 continúa hasta su vencimiento el 30 de abril. El 1 de mayo, entra en vigencia la suscripción al Nivel 2, y se le cobran USD 36 a Pedro por su nuevo nivel de suscripción.

Deberías llamar al PurchasesUpdatedListener de tu app apenas la compra se realiza correctamente, y puedes recuperar la compra nueva como parte de una llamada queryPurchasesAsync(). Tu backend recibe de inmediato una notificación para desarrolladores en tiempo real SUBSCRIPTION_PURCHASED. Debes procesar la compra de la misma manera que lo harías con cualquier otra compra nueva en ese momento. En especial, asegúrate de reconocer la compra nueva. Ten en cuenta que el startTime de la suscripción nueva se completa en el momento en que el reemplazo entra en vigencia, lo que sucede cuando vence la suscripción anterior. En ese momento, recibirás una RTDN de SUBSCRIPTION_RENEWED para el nuevo plan de suscripción. Obtén más información sobre el comportamiento de ReplacementMode.DEFERRED en Controla el reemplazo diferido.

CHARGE_FULL_PRICE

La suscripción de Pedro al Nivel 1 finaliza de inmediato. Su suscripción al Nivel 2 comienza hoy, y se le cobran USD 36. Dado que pagó un mes completo, pero utilizó solamente la mitad, se aplica la mitad de la suscripción mensual (USD 1) a su nueva suscripción. Como la nueva suscripción tiene un costo de USD 36 por año, se agrega a la 1/36 del año adicional a su período de suscripción (aproximadamente 10 días). Por lo tanto, el próximo cargo de Pedro sería de 1 año y 10 días a partir de hoy por USD 36. Luego, se le cobrarán USD 36 cada año.

Cuando elijas un modo de prorrateo, asegúrate de revisar nuestras recomendaciones de reemplazo.

Activa los cambios de suscripción en la app

Tu app puede usar los mismos pasos que para iniciar un flujo de compra para ofrecerles a los usuarios que actualicen su suscripción o que la cambien a una versión inferior. Sin embargo, cuando actualices o cambies a una versión inferior, deberás proporcionar los detalles de la suscripción actual, la suscripción futura (actualizada o de una versión inferior) y el modo de reemplazo que se usará, como se muestra en el siguiente ejemplo:

Kotlin

val offerToken = productDetails
        .getSubscriptionOfferDetails(selectedOfferIndex)
        .getOfferToken()

val billingParams = BillingFlowParams.newBuilder().setProductDetailsParamsList(
       listOf(
           BillingFlowParams.ProductDetailsParams.newBuilder()
               .setProductDetails(productDetails)
               .setOfferToken(offerToken)
               .build()
       )
       ).setSubscriptionUpdateParams(
           BillingFlowParams.SubscriptionUpdateParams.newBuilder()
               .setOldPurchaseToken("old_purchase_token")
               .setSubscriptionReplacementMode(
                 BillingFlowParams.ReplacementMode.CHARGE_FULL_PRICE
               )
               .build()
       ).build()

billingClient.launchBillingFlow(
    activity,
    billingParams
   )
// ...

Java

String offerToken = productDetails
    .getSubscriptionOfferDetails(selectedOfferIndex)
    .getOfferToken();

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        ImmuableList.of(
            ProductDetailsParams.newBuilder()
                // fetched via queryProductDetailsAsync
                .setProductDetails(productDetails)
                // offerToken can be found in
                // ProductDetails=>SubscriptionOfferDetails
                .setOfferToken(offerToken)
                .build()))
    .setSubscriptionUpdateParams(
        SubscriptionUpdateParams.newBuilder()
            // purchaseToken can be found in Purchase#getPurchaseToken
            .setOldPurchaseToken("old_purchase_token")
            .setSubscriptionReplacementMode(ReplacementMode.CHARGE_FULL_PRICE)
            .build())
    .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
// ...

Recomendaciones sobre el reemplazo

En la siguiente tabla, se muestran diferentes situaciones de prorrateo junto con lo que recomendamos para cada situación:

Situación Modo de reemplazo recomendado Resultado
Actualización a un nivel más costoso CHARGE_PRORATED_PRICE El usuario recibe acceso de inmediato y mantiene el mismo período de facturación.
Cambio a una versión inferior con un nivel menos costoso DEFERRED El usuario ya pagó el nivel más costoso, por lo que seguirá teniendo acceso hasta la próxima fecha de facturación.
Actualización durante una prueba gratuita (se mantiene la prueba) WITHOUT_PRORATION El usuario mantiene el acceso a la prueba gratuita, pero se actualiza a un nivel superior durante el resto de la prueba.
Actualización durante una prueba gratuita (finaliza el acceso a la prueba gratuita) CHARGE_PRORATED_PRICE El usuario recibe acceso al nuevo nivel de inmediato, pero ya no tiene una prueba gratuita.

Controla las compras de cambios de suscripción

Los cambios de plan son compras nuevas para todos los términos y propósitos, y deben procesarse y confirmarse como tales después de que el flujo de facturación se completa de forma correcta. Además de procesar la compra nueva de forma adecuada, debes retirar la compra que se reemplazará.

El comportamiento en la app es el mismo que el de cualquier compra nueva. Tu app recibe el resultado de la compra nueva en tu PurchasesUpdatedListener, y la compra nueva está disponible en queryPurchasesAsync.

La API de Google Play Developer muestra un linkedPurchaseToken en el recurso de suscripción cuando una compra reemplaza una existente. Asegúrate de invalidar el token proporcionado en linkedPurchaseToken para garantizar que no se use el anterior para acceder a tus servicios. Para descubrir cómo administrar las compras de actualizaciones o cambios a versiones inferiores, consulta Actualizaciones, cambios a versiones inferiores y registros de usuarios suscritos anteriormente.

Cuando recibas el nuevo token de compra, sigue el mismo proceso de verificación que con la verificación de un nuevo token de compra. Asegúrate de confirmar estas compras con BillingClient.acknowledgePurchase() de la Biblioteca de Facturación de Google Play o Purchases.subscriptions:acknowledge de la API de Google Play Developer.

Controla el reemplazo diferido

Con el modo de reemplazo diferido, puedes permitir que un usuario agote el derecho restante del plan anterior antes de comenzar con el plan nuevo.

Cuando usas ReplacementMode.DEFERRED para una compra nueva, queryPurchasesAsync() muestra un token de compra nuevo después del flujo de compra que permanece asociado con el producto anterior hasta que se realiza el reemplazo diferido en la siguiente fecha de renovación, después de la cual se devuelve el producto nuevo.

Antes, podías lograr esta experiencia del usuario con ProrationMode.DEFERRED, que ya es obsoleto. ProrationMode.DEFERRED dejó de estar disponible con la Biblioteca de Facturación Play 6. Consulta la siguiente tabla para comprender en qué se diferencia el comportamiento:

Hora

ProrationMode.DEFERRED (obsoleto)

ReplacementMode.DEFERRED

Inmediatamente después de que el flujo de compra se realiza de manera correcta (app)

PurchasesUpdatedListener se invoca después de la compra con el estado que indica si se realizó correctamente la actualización o el cambio a una versión inferior.

El derecho al plan anterior continuará hasta la próxima fecha de renovación. Para garantizar que la app otorgue el derecho adecuado, queryPurchasesAsync() muestra un objeto Purchase con el token de compra original y el derecho original hasta que se produce el reemplazo.

El nuevo token de compra no aparece, por lo que no se puede procesar en este momento.

PurchasesUpdatedListener se invoca después de la compra con el estado que indica si se realizó correctamente la actualización o el cambio a una versión inferior.

queryPurchasesAsync() muestra inmediatamente la compra con el token de compra nuevo y el derecho original asociado.

Como se muestra el nuevo token de compra, se debe procesar teniendo en cuenta cuándo se llevará a cabo el reemplazo.

Inmediatamente después de que el flujo de compra se realiza de manera correcta (backend)

La RTDN de SUBSCRIPTION_PURCHASED no se envía después del flujo de compra. El backend aún no tiene conocimiento de la nueva compra.

La RTDN de SUBSCRIPTION_PURCHASED con el product_id anterior se envía inmediatamente después del flujo de compra del nuevo token de compra.

Llamar al método purchases.subscriptionsv2.get con el nuevo token de compra muestra una compra con un "startTime" que indica el tiempo de compra con dos líneas de pedido:

  • Uno que representa el derecho anterior y tiene un "expiryTime" en el futuro. No se renovará el derecho anterior y tiene un DeferredItemReplacement que contiene el producto del derecho nuevo. Esto indica que habrá un reemplazo pendiente del derecho anterior cuando venza.
  • Uno que representa el derecho de compra reciente. No tiene ningún valor establecido para 'expiryTime'.

Se envió SUBSCRIPTION_EXPIRED para el token de compra anterior. Cuando llamas al método purchases.subscriptionsv2.get con el token de compra anterior, aparece como vencido (el derecho del plan anterior se transfiere a la compra nueva durante el tiempo restante).

En reemplazo: Primera renovación después del flujo de compra (app)

queryPurchasesAsync() muestra un objeto Purchase nuevo con el token de compra y el derecho nuevos.

Ahora aparece el nuevo token de compra, por lo que se debería procesar.

queryPurchasesAsync() muestra inmediatamente la compra con el token de compra nuevo y el derecho nuevo asociado.

La compra nueva ya debería haberse procesado cuando el flujo de compra se completó correctamente, por lo que la app no debería realizar ninguna acción especial además de asegurarse de que se otorgue el derecho adecuado.

En reemplazo: Primera renovación después del flujo de compra (backend)

Ahora se puede procesar y confirmar la nueva compra cuando se envía la primera RTDN de SUBSCRIPTION_RENEWED.

Se puede usar el linkedPurchaseToken en el recurso de suscripción para determinar qué usuario de tu backend de suscripción, si corresponde, debe actualizarse con el nuevo derecho.

Se procesó y confirmó la compra nueva cuando se envió la RTDN de SUBSCRIPTION_PURCHASED para el nuevo token de compra y se registró como "startTime".

Con ReplacementMode.DEFERRED, las primeras renovaciones siguen el comportamiento estándar de cualquier otra renovación, y no necesitas administrar una lógica especial para los reemplazos cuando ocurre este evento.

Cuando se llama al método purchases.subscriptionsv2.get con el nuevo token de compra, se muestra una compra con dos líneas de pedido:

  • Uno que representa el derecho anterior, con un "expiryTime" en el pasado y sin un valor establecido para DeferredItemReplacement.
  • Uno que representa el derecho nuevo, con un "expiryTime" en el futuro y la marca auto_renewing_enabled activada.

A partir de ahora, se debe usar ReplacementMode.DEFERRED en lugar del ProrationMode.DEFERRED obsoleto, ya que presenta el mismo comportamiento respecto de los cambios de derechos, pero ofrece una forma de administrar la compra que es más coherente con los comportamientos para otras compras nuevas.

Administra a tus clientes

Con las notificaciones para desarrolladores en tiempo real, puedes detectar en tiempo real cuando un usuario decide cancelar. Cuando un usuario cancela una suscripción, pero lo hace antes de que venza, puedes enviarle notificaciones push o mensajes desde la app para pedirle que se vuelva a suscribir.

Cuando un usuario cancela la suscripción, puedes intentar recuperarlo en tu app o a través de Play Store. En la siguiente tabla, se describen varias situaciones de suscripción, junto con las acciones de recuperación asociadas y los requisitos de la app:

Antes del vencimiento de la suscripción Después del vencimiento de la suscripción
En la app En Play Store En la app En Play Store
Función de recuperación Suscripción integrada en la app Restablecer Suscripción integrada en la app Volver a suscribirse
El usuario pasa por el flujo de confirmación de la compra No
La suscripción de usuario sigue asociada al mismo SKU El usuario puede registrarse en el mismo SKU o en uno distinto El usuario puede registrarse en el mismo SKU o en uno distinto
Se crea un token de compra nuevo No
Se habilita de forma predeterminada No Sí, todos los desarrolladores deben habilitar esta función No

En apps que no cuentan con la Biblioteca de Facturación 2.0 o versiones posteriores: No

En apps que cuentan con la Biblioteca de Facturación 2.0 o versiones posteriores: Sí. Los desarrolladores pueden inhabilitar la función en Play Console.

Cuándo se le cobra al usuario

Si se usa el mismo SKU: al final del período de facturación actual

Si se usa un SKU distinto: en función del modo de prorrateo

Al final del período de facturación actual De inmediato De inmediato
Implementaciones requeridas Proporcionar una IU para registrarse de nuevo en tu app

Detectar cambios en el estado de la suscripción

Vínculo directo a Play Store

Proporcionar una IU para registrarse de nuevo en tu app Administrar las compras realizadas fuera de la app

Antes del vencimiento de la suscripción (en la app)

En el caso de las suscripciones canceladas que aún no se vencieron, puedes permitir que los suscriptores las restablezcan dentro de tu app usando el mismo flujo de compra de productos integrados en la aplicación que utilizas para suscriptores nuevos. Asegúrate de que la IU indique que el usuario ya tiene una suscripción. Por ejemplo, podrías mostrar la fecha de vencimiento y el precio recurrente actuales del usuario junto al botón Reactivar.

La mayoría de las veces, lo recomendable es ofrecerle al usuario el mismo precio y SKU que los de la suscripción actual, como se muestra a continuación:

  • Inicia una compra de suscripción nueva con el mismo SKU.
  • La nueva suscripción reemplaza a la anterior y se renueva en la misma fecha de vencimiento. La suscripción anterior se marca inmediatamente como vencida.
  • Por ejemplo, Aquiles tiene una suscripción a App de Música de Ejemplo, que vence el 1 de agosto. El 10 de julio, vuelve a suscribirse a la opción de un mes por el mismo precio mensual. La nueva suscripción se prorratea con el crédito restante, se activa inmediatamente y se renueva el 1 de agosto.

Si deseas ofrecer un precio diferente (como otra prueba gratuita o un descuento de recuperación), puedes brindarle al usuario un SKU distinto de la siguiente manera:

  • Inicia una actualización o el cambio a una versión inferior con un SKU diferente usando el modo de reemplazo WITHOUT_PRORATION.
  • La nueva suscripción reemplaza a la anterior y se renueva en la misma fecha de vencimiento. En esta fecha, se le cobra al usuario el precio del nuevo SKU, que incluye el precio de lanzamiento. Si la suscripción anterior se creó con un ID de cuenta ofuscado, ese mismo ID se debe pasar a BillingFlowParams para actualizaciones y cambios a versiones inferiores.
  • Por ejemplo, Aquiles tiene una suscripción a App de Música de Ejemplo, que vence el 1 de agosto. El 10 de julio, vuelve a suscribirse a un plan anual a un precio de lanzamiento. La nueva suscripción se activa de inmediato y se le cobra al usuario el precio de lanzamiento el 1 de agosto.
  • Si decides incluir una prueba gratuita o un precio de lanzamiento en tu SKU de recuperación, asegúrate de que el usuario sea apto. Para ello, desmarca la casilla Permitir una prueba gratuita por app en Google Play Console, que evita que el usuario obtenga más de una prueba gratuita por app.

Cuando recibas el token de compra, procesa la compra como lo harías con una suscripción nueva. Además, la API de Google Play Developer muestra un linkedPurchaseToken en el recurso de suscripción. Asegúrate de invalidar el token proporcionado en linkedPurchaseToken a fin de garantizar que no se use el anterior al acceder a tus servicios.

Antes del vencimiento de la suscripción (en Play Store)

Mientras la suscripción cancelada siga activa, los usuarios pueden hacer clic en Volver a suscribirse (que antes era Restablecer) para restablecerla en el centro de suscripciones de Google Play. Esto mantiene el mismo token de suscripción y compra.

En la sección de suscripciones en la app de Google Play Store, aparece una suscripción cancelada con un botón para volver a suscribirse.
Figura 8: En la sección Cuenta > Suscripciones de la app de Google Play Store, se muestra una suscripción cancelada y el botón Volver a suscribirse.

A fin de obtener más información para restablecer suscripciones, consulta Restablecimientos.

Después del vencimiento de la suscripción (en la app)

A fin de permitir que los usuarios con suscripciones vencidas se vuelvan a suscribir dentro de tu app, puedes usar el mismo flujo de compra de productos integrados en la aplicación que utilizas para los suscriptores nuevos. Ten en cuenta lo siguiente:

  • A fin de ofrecer un descuento, es posible que quieras proporcionar un ID de producto con precios especiales para tu suscripción, también llamado SKU de recuperación. Puedes proporcionar la oferta en tu app o notificar al usuario sobre ella fuera de la app, como también por correo electrónico.
  • Para iniciar una suscripción de recuperación, inicia el flujo de compra en tu app para Android con la Biblioteca de Facturación Google Play. Este es el mismo proceso que con una suscripción nueva, pero puedes determinar el SKU que está disponible para el usuario.
  • Si decides incluir una prueba gratuita o un precio de lanzamiento en tu SKU de recuperación, asegúrate de que el usuario sea apto. Para ello, desmarca la casilla para permitir una prueba gratuita por app en Google Play Console, que evita que el usuario obtenga más de una prueba gratuita por app.
  • Si el usuario vuelve a suscribirse al mismo SKU, ya no será apto para obtener pruebas gratuitas ni precios de lanzamiento. Asegúrate de que esto figure en la IU.

Cuando recibas el token de compra, procesa la compra como lo harías con una suscripción nueva. No recibirás un linkedPurchaseToken en el recurso de suscripción.

Después del vencimiento de la suscripción (en Play Store)

Si se habilita esta opción, los usuarios pueden volver a suscribirse al mismo SKU durante un año después del vencimiento haciendo clic en Volver a suscribirse en el centro de suscripciones de Google Play. Esto genera un nuevo token de compra y suscripción.

sección de suscripciones en la app de Google Play Store, en la que aparece una suscripción cancelada y vencida junto a los botones quitar y volver a suscribirse.
Figura 9: En la sección Cuenta > Suscripciones de la app de Google Play Store, se muestra una suscripción cancelada y vencida con los botones Volver a suscribirse y Quitar.

La nueva suscripción no se considera una compra realizada dentro de la app, por lo que debes asegurarte de seguir las prácticas recomendadas para manejar las compras que se realizan fuera de la app.

Promociona tu suscripción

Puedes crear códigos promocionales a fin de otorgarles a determinados usuarios una prueba gratuita extendida para una suscripción existente. Para obtener más información, consulta Códigos promocionales.

En el caso de las pruebas gratuitas, Google Play verifica que el usuario tenga una forma de pago válida antes de comenzar una. Es posible que algunos usuarios vean esta verificación como una retención o cargo en su forma de pago. Esta retención o cargo es temporal y luego se revierte o reembolsa.

Cuando finaliza el período de prueba, se cobra el importe total de la suscripción mediante la forma de pago del usuario.

Si un usuario cancela una suscripción en cualquier momento durante la prueba gratuita, la suscripción permanece activa hasta el final de la prueba y no se le cobra cuando finaliza el período de prueba gratuito.

Cancela, reembolsa o revoca suscripciones

Puedes usar la API de Google Play Developer para cancelar, reembolsar o revocar una suscripción. Esta funcionalidad también está disponible en Google Play Console.

  • Cancelar: Los usuarios pueden cancelar una suscripción en Google Play. También puedes proporcionar una opción para que los usuarios la cancelen en tu app o en tu sitio web. Tu app debe controlar estas cancelaciones como se describe en Cancelaciones.
  • Reembolsar: Cuando realizas un reembolso, el usuario puede seguir usando la suscripción. Los reembolsos se pueden usar si, por ejemplo, se produjo un error técnico que impidió que el usuario accediera a su producto, pero se resolvió. Ten en cuenta que, para recibir un reembolso superior al pago más reciente, o si quieres emitir un reembolso parcial, debes usar Google Play Console.
  • Revocar: Cuando llevas a cabo una revocación, el usuario pierde el acceso a la suscripción de inmediato. Se puede usar si, por ejemplo, se produjo un error técnico que impidió que el usuario accediera a su producto, y no desea seguir usando el producto. Tu app debe controlar estas cancelaciones como se describe en Revocaciones.

En la siguiente tabla, se muestran las diferencias entre cancelar, reembolsar y revocar.

Detiene la renovación Reembolsa dinero Revoca el acceso
Cancelar No No
Reembolsar No No
Revocar

Aplaza la facturación de un suscriptor

Puedes aplazar la próxima fecha de facturación de un suscriptor con renovación automática mediante Purchases.subscriptions:defer de la API de Google Play Developer. Durante el período de diferimiento, el usuario está suscrito a tu contenido con acceso completo, pero no se le cobra. Se actualiza la fecha de renovación de la suscripción para reflejar la nueva fecha.

En el caso de los planes prepagados, puedes usar la API para aplazar la facturación para diferir la fecha de vencimiento.

La facturación diferida te permite hacer lo siguiente:

  • Ofrecer a los usuarios acceso gratuito como una oferta especial, por ejemplo, dar una semana gratis para comprar una película.
  • Puedes dar acceso gratuito a los clientes como gesto de buena voluntad.

La facturación puede diferirse de tan solo un día y hasta un año por llamada a la API. Para posponer aún más la facturación, puedes volver a llamar a la API antes de que llegue la nueva fecha de facturación.

Como ejemplo, Darcy tiene una suscripción mensual a contenido en línea para la app de Fishing Quarterly. Por lo general, se le factura GBP 1.25 el primer día de cada mes. En marzo, participó en una encuesta en línea para el publicador de la aplicación. El publicador la recompensa con seis semanas gratis y pospone el próximo pago hasta el 15 de mayo, que son seis semanas después de la fecha de facturación programada para el 1 de abril. A Darcy no se le cobra abril ni el comienzo de mayo, y sigue teniendo acceso al contenido. El 15 de mayo, se le cobra la tarifa habitual de suscripción mensual de GBP 1.25. Su próxima fecha de renovación es el 15 de junio.

Es posible que desees notificar al usuario por correo electrónico o en la app que se cambió la fecha de facturación.

Controla los rechazos de pagos

Si hay problemas con el pago de una renovación de suscripción, Google intentará renovar la suscripción periódicamente durante un tiempo antes de cancelarla. Este período de recuperación puede consistir de un período de gracia seguido de un período de suspensión de la cuenta. Durante este tiempo, Google envía correos electrónicos y notificaciones al usuario para pedirle que actualice su forma de pago.

Cuando se rechaza el pago, la suscripción ingresa en un período de gracia, si hay uno configurado. Durante ese período, debes asegurarte de que el usuario siga teniendo acceso a los derechos de suscripción.

Una vez finalizado el período de gracia, la suscripción entra en un período de suspensión de la cuenta. Durante esta etapa, debes asegurarte de que el usuario no tenga acceso a los derechos de suscripción.

Puedes especificar la duración del período de gracia de cada plan básico con renovación automática y la suspensión de la cuenta en Google Play Console. Especificar una duración inferior a los valores predeterminados podría reducir la cantidad de suscripciones recuperadas después de un rechazo de pago.

Para maximizar la probabilidad de recuperación de una suscripción durante el rechazo de un pago, puedes informar al usuario la situación y solicitarle que resuelva el problema.

Puedes hacerlo por tu cuenta, como se describe en las secciones sobre período de gracia y suspensión de la cuenta, o puedes implementar la API de mensajes desde la app a través de la cual Google muestra un mensaje a los usuarios en tu app.

Mensajes desde la app

Si habilitaste los mensajes desde la app con InAppMessageCategoryId.TRANSACTIONAL, Google Play les mostrará a los usuarios la mensajería durante el período de gracia y la suspensión de la cuenta una vez al día, y les proporcionará una de corregir su pago sin salir de la app.

Barra de notificaciones que notifica al usuario para que resuelva su problema de pago
Figura 20: Barra de notificaciones que notifica al usuario para que resuelva su problema de pago

Te recomendamos que llames a esta API cada vez que el usuario abra la app para determinar si el mensaje debe mostrarse.

Si el usuario recuperó su suscripción correctamente, recibirás un código de respuesta SUBSCRIPTION_STATUS_UPDATED junto con un token de compra. Luego, debes usar este token de compra para llamar a la API de Google Play Developer y actualizar el estado de la suscripción en tu app.

Cómo integrar los mensajes desde la app

Para mostrar mensajes desde la app al usuario, usa BillingClient.showInAppMessages().

El siguiente es un ejemplo de cómo activar el flujo de mensajes desde la app:

Kotlin

val inAppMessageParams = InAppMessageParams.newBuilder()
        .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL)
        .build()

billingClient.showInAppMessages(activity,
        inAppMessageParams,
        object : InAppMessageResponseListener() {
            override fun onInAppMessageResponse(inAppMessageResult: InAppMessageResult) {
                if (inAppMessageResult.responseCode == InAppMessageResponseCode.NO_ACTION_NEEDED) {
                    // The flow has finished and there is no action needed from developers.
                } else if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) {
                    // The subscription status changed. For example, a subscription
                    // has been recovered from a suspend state. Developers should
                    // expect the purchase token to be returned with this response
                    // code and use the purchase token with the Google Play
                    // Developer API.
                }
            }
        })

Java

InAppMessageParams inAppMessageParams = InAppMessageParams.newBuilder()
        .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL)
        .build();

billingClient.showInAppMessages(activity,
        inAppMessageParams,
        new InAppMessageResponseListener() {
            @Override
            public void onInAppMessageResponse(InAppMessageResult inAppMessageResult) {
                if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.NO_ACTION_NEEDED) {
                    // The flow has finished and there is no action needed from developers.
                } else if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) {
                    // The subscription status changed. For example, a subscription
                    // has been recovered from a suspend state. Developers should
                    // expect the purchase token to be returned with this response
                    // code and use the purchase token with the Google Play
                    // Developer API.
                }
            }
        });