Recordatorio: A partir del 2 de agosto de 2021, todas las apps nuevas deben usar la Biblioteca de Facturación 3 o versiones posteriores. A partir del 1 de noviembre de 2021, todas las actualizaciones de las apps existentes deben usar la Biblioteca de Facturación 3 o versiones posteriores. Obtén más información.

Cómo integrar la biblioteca de Facturación Google Play a la app

En este tema, se describe cómo integrar la biblioteca de Facturación Google Play a la app para comenzar a vender productos. Antes de leer este tema, asegúrate de ajustar la configuración de Google Play. Para hacerlo, sigue los pasos que se indican en Preparación.

En este tema, se incluyen ejemplos de código basados en las apps de muestra oficiales en GitHub. Consulta los recursos adicionales para obtener una lista completa de las apps de muestra y otros recursos que puedes usar durante la integración.

Duración de una compra

Este es un flujo de compra típico para una compra única o una suscripción.

  • Muéstrale al usuario lo que puede comprar.
  • Inicia el flujo de compra para que el usuario acepte la compra.
  • Verifica la compra en el servidor.
  • Proporciona contenido al usuario y confirma la transmisión del contenido. Opcionalmente, marca el artículo como consumido para que el usuario pueda volver a comprarlo.

Las suscripciones se renuevan automáticamente hasta que se cancelen. Una suscripción puede pasar por los siguientes estados:

  • Activa: El usuario está en regla y tiene acceso a la suscripción.
  • Cancelada: El usuario la canceló, pero aún tiene acceso hasta el vencimiento.
  • En período de gracia: El usuario tuvo un problema con el pago, pero aún tiene acceso. Mientras tanto, Google vuelve a intentar procesar la forma de pago.
  • En espera: El usuario tuvo un problema con el pago y ya no tiene acceso. Mientras tanto, Google vuelve a intentar procesar la forma de pago.
  • Detenida: El usuario detuvo su acceso y no podrá acceder hasta que lo reanude.
  • Vencida: El usuario canceló la suscripción y perdió el acceso a esta. Se considera que el usuario desertó luego del vencimiento.

ID de pedido y tokens de compra

Google Play hace un seguimiento de los productos y las transacciones mediante los ID de pedido y los tokens de compra.

  • Un token de compra es una string que representa el derecho de un usuario a adquirir un producto en Google Play. Indica que un usuario de Google tiene derecho a un producto específico representado por un SKU. Puedes usar el token de compra con la API de Google Play Developer.
  • Un ID de pedido es una string que representa una transacción financiera en Google Play. Esta string se incluye en un recibo que se envía por correo electrónico al comprador. Puedes usar el ID de pedido para administrar los reembolsos en los informes de ventas y pagos.

Los ID de pedido se crean cada vez que se produce una transacción financiera. Los tokens de compra se generan solo cuando el usuario completa un flujo de compra.

  • En el caso de los productos únicos, con cada compra se crea un nuevo token de compra. La mayoría de las compras también generan un nuevo ID de pedido. La excepción ocurre cuando no se le cobra al usuario, como se describe en Códigos promocionales.
  • Para las suscripciones, una compra inicial crea un token de compra y un ID de pedido. El token de compra se mantiene igual para cada período de facturación continuo, y se emite un nuevo ID de pedido. Las actualizaciones, los cambios a versiones anteriores, los reemplazos y los registros nuevos crean ID de pedido y tokens de compra nuevos.

En el caso de las suscripciones, debes tener en cuenta lo siguiente:

  • Las actualizaciones, los cambios a versiones anteriores y otros flujos de compra de suscripciones generan tokens de compra que deben reemplazar a un token de compra anterior. Debes invalidar los tokens de compra que aparecen en el campo linkedPurchaseToken de la API de Google Play Developer. Para obtener más información, consulta Cómo implementar linkedPurchaseToken de forma correcta para evitar duplicar suscripciones.
  • Los números de pedido para las renovaciones de suscripciones contienen un número entero adicional que representa una instancia de renovación específica. Por ejemplo, un ID de pedido de suscripción inicial puede ser GPA.1234-5678-9012-34567, y los ID de pedido posteriores serán GPA.1234-5678-9012-34567..0 (primera renovación), GPA.1234-5678-9012-34567..1 (segunda renovación), y así sucesivamente.

Manejo de errores

La Biblioteca de Facturación Google Play muestra errores como BillingResult. Un BillingResult contiene un BillingResponseCode, que clasifica los posibles errores relacionados con la facturación que pueden ocurrir en tu app. Por ejemplo, si recibes un código de error SERVICE_DISCONNECTED, la app debería volver a inicializar la conexión con Google Play. Además, un BillingResult contiene un mensaje de depuración, que sirve para diagnosticar errores durante el desarrollo.

Cómo conectarse a Google Play

El primer paso para integrar el sistema de facturación de Google Play es agregar la biblioteca a tu app e inicializar una conexión.

Cómo agregar la dependencia de la Biblioteca de Facturación Google Play

Agrega la dependencia de la biblioteca de Facturación Google Play al archivo build.gradle de la app como se muestra a continuación:

dependencies {
    def billing_version = "3.0.0"

    implementation "com.android.billingclient:billing:$billing_version"
}

Si usas Kotlin, el módulo KTX de la Biblioteca de Facturación Play es compatible con las extensiones y corrutinas de Kotlin, y permite la escritura de Kotlin cuando usas la Biblioteca de Facturación Google Play. Para incluir estas extensiones en tu proyecto, agrega la siguiente dependencia al archivo build.gradle de la app como se muestra a continuación:

dependencies {
    def billing_version = "3.0.0"

    implementation "com.android.billingclient:billing-ktx:$billing_version"
}

Cómo inicializar un BillingClient

Una vez que agregues una dependencia en la Biblioteca de Facturación Google Play, deberás inicializar una instancia de BillingClient. BillingClient es la interfaz principal para la comunicación entre la biblioteca de Facturación Google Play y el resto de la app. BillingClient proporciona métodos de conveniencia, tanto síncronos como asíncronos, para muchas operaciones de facturación comunes.

Para crear un BillingClient, usa newBuilder(). Para recibir actualizaciones sobre compras, también debes llamar a setListener() y pasar una referencia a PurchasesUpdatedListener. Este objeto de escucha recibe actualizaciones de todas las compras de tu app.

Kotlin

private val purchasesUpdatedListener =
   PurchasesUpdatedListener { billingResult, purchases ->
       // To be implemented in a later section.
   }

private var billingClient = BillingClient.newBuilder(activity)
   .setListener(purchasesUpdatedListener)
   .enablePendingPurchases()
   .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // To be implemented in a later section.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(activity)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .build();

Cómo establecer una conexión con Google Play

Después de crear un BillingClient, debes establecer una conexión con Google Play.

Para conectarte a Google Play, llama a startConnection(). El proceso de conexión es asíncrono. Debes implementar un BillingClientStateListener para recibir una devolución de llamada una vez que se complete la configuración del cliente y esté lista para realizar más solicitudes.

También debes implementar la lógica de reintento a fin de controlar las pérdidas de conexión con Google Play. Para implementar la lógica de reintento, anula el método de devolución de llamada onBillingServiceDisconnected() y asegúrate de que BillingClient llame al método startConnection() para volver a conectarse a Google Play antes de realizar más solicitudes.

En el siguiente ejemplo, se muestra cómo iniciar una conexión y probar que esté lista para usarse:

Kotlin

billingClient.startConnection(object : BillingClientStateListener {
    override fun onBillingSetupFinished(billingResult: BillingResult) {
        if (billingResult.responseCode ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    override fun onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
})

Java

billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});

Cómo mostrar productos disponibles para comprar

Después de establecer una conexión con Google Play, podrás consultar los productos disponibles y mostrarlos a los usuarios. Para hacer búsquedas en Google Play relacionadas con los detalles de productos integrados en la aplicación, llama a querySkuDetailsAsync(). La consulta de detalles de SKU es un paso importante antes de mostrar los productos a los usuarios, ya que muestra información localizada sobre los productos. Para las suscripciones, asegúrate de que la visualización de tus productos cumpla con todas las políticas de Play.

Cuando llames a querySkuDetailsAsync(), pasa una instancia de SkuDetailsParams que especifique una lista de strings de ID de producto creadas en Google Play Console, junto con un objetoSkuType. El objeto SkuType puede ser SkuType.INAPP para productos únicos o SkuType.SUBS para suscripciones.

Para administrar el resultado de la operación asíncrona, también debes especificar un objeto de escucha que implemente la interfaz de SkuDetailsResponseListener. Luego, puedes anular onSkuDetailsResponse(), que notifica al objeto de escucha cuando finaliza la consulta, como se muestra en el siguiente ejemplo:

Kotlin

fun querySkuDetails() {
    val skuList = ArrayList<String>()
    skuList.add("premium_upgrade")
    skuList.add("gas")
    val params = SkuDetailsParams.newBuilder()
    params.setSkusList(skuList).setType(SkuType.INAPP)
    val skuDetailsResult = withContext(Dispatchers.IO) {
        billingClient.querySkuDetails(params.build())
    }
    // Process the result.
}

Java

List<String> skuList = new ArrayList<> ();
skuList.add("premium_upgrade");
skuList.add("gas");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(BillingResult billingResult,
                List<SkuDetails> skuDetailsList) {
            // Process the result.
        }
    });

La biblioteca de Facturación Google Play almacena los resultados de búsqueda en una List de objetos SkuDetails. Luego, puedes llamar a diferentes métodos de cada objeto SkuDetails de la lista para ver información relevante de un producto integrado en la aplicación, como el precio o la descripción. Para ver información detallada del producto disponible, consulta la lista de métodos de la clase SkuDetails.

Antes de poner un artículo en venta, verifica que el usuario no lo tenga. Si el usuario todavía tiene un producto consumible en su biblioteca de artículos, debe consumirlo antes de volver a comprarlo.

Antes de ofrecer una suscripción, verifica que el usuario no esté suscrito.

Cómo iniciar el flujo de compra

Para iniciar una solicitud de compra desde la app, llama al método launchBillingFlow() del subproceso principal de la app. Este método toma una referencia para un objeto BillingFlowParams que contiene el objeto SkuDetails relevante obtenido de la llamada a querySkuDetailsAsync(). Para crear un objeto BillingFlowParams, usa la clase BillingFlowParams.Builder.

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;

// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
val flowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)
        .build()
val responseCode = billingClient.launchBillingFlow(activity, flowParams).responseCode

Java

// An activity reference from which the billing flow will be launched.
Activity activity = ...;

// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)
        .build();
int responseCode = billingClient.launchBillingFlow(activity, billingFlowParams).getResponseCode();

// Handle the result.

El método launchBillingFlow()BillingClient.BillingResponseCode muestra uno de los códigos de respuesta que se indican en . Asegúrate de verificar este resultado para garantizar que no haya errores al iniciar el flujo de compra. Un BillingResponseCode de OK indica un inicio exitoso.

En una llamada exitosa a launchBillingFlow(), el sistema muestra la pantalla de compra de Google Play. En la figura 1, se muestra una pantalla de compra de un producto único:

La pantalla de compra de Google Play muestra un producto único disponible para la compra
Figura 1: La pantalla de compra de Google Play muestra un producto único disponible para la compra

Google Play llama a onPurchasesUpdated() para enviar el resultado de la operación de compra a un objeto de escucha que implementa la interfaz PurchasesUpdatedListener. El objeto de escucha se especifica con el método setListener() cuando inicializas a tu cliente.

Debes implementar onPurchasesUpdated() para controlar los códigos de respuesta posibles. En el siguiente ejemplo, se muestra cómo anular onPurchasesUpdated():

Kotlin

override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
   if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) {
       for (purchase in purchases) {
           handlePurchase(purchase)
       }
   } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) {
       // Handle an error caused by a user cancelling the purchase flow.
   } else {
       // Handle any other error codes.
   }
}

Java

@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
    if (billingResult.getResponseCode() == BillingResponseCode.OK
        && purchases != null) {
        for (Purchase purchase : purchases) {
            handlePurchase(purchase);
        }
    } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
        // Handle an error caused by a user cancelling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

Si la compra es exitosa, se generará una pantalla de compra exitosa de Google Play similar a la figura 2.

Pantalla de compra exitosa de Google Play
Figura 2: Pantalla de compra exitosa de Google Play

Una compra exitosa también genera un token de compra, es decir, un identificador único que representa al usuario y al ID del producto integrado en la aplicación que compró. Las apps pueden almacenar el token de compra de forma local, aunque recomendamos pasarlo a tu servidor de backend seguro, donde podrás verificar la compra y protegerte contra el fraude. Este proceso se describe más detalladamente en la siguiente sección.

Además, el usuario recibe un correo electrónico con un comprobante de la operación, que incluye un ID de pedido o ID único de la transacción. Los usuarios reciben un correo electrónico con un ID de pedido único por cada compra de producto único, así como por la compra de la suscripción inicial y las renovaciones automáticas posteriores. Puedes usar el ID de pedido para administrar los reembolsos en Google Play Console.

Cómo procesar las compras

Una vez que un usuario completa una compra, tu app debe procesarla. En la mayoría de los casos, la app recibe notificaciones de las compras realizadas a través del PurchasesUpdatedListener, pero hay casos en los que la app llama a BillingClient.queryPurchases() para obtener la información, como se describe en Cómo buscar compras.

Tu app debe procesar una compra de la siguiente manera:

  1. Verifica la compra.
  2. Proporciona contenido al usuario y confirma la transmisión del contenido. Opcionalmente, marca el artículo como consumido para que el usuario pueda volver a comprarlo.

Para verificar una compra, primero confirma que el estado de compra sea PURCHASED. Si la compra figura como PENDING, debes procesarla según se describe en Cómo administrar las transacciones pendientes. En el caso de las compras recibidas de onPurchaseUpdated() o queryPurchases, también debes verificar la compra para asegurarte de que sea legítima antes de que la app otorgue los derechos al producto. Para obtener información sobre cómo verificar correctamente una compra, consulta Cómo verificar las compras antes de otorgar derechos.

Una vez que verifiques la compra, tu app estará lista para otorgarle derechos al usuario. Después de otorgar los derechos, la app debe confirmar la compra. Esta confirmación le informa a Google Play que otorgaste derechos para la compra.

El proceso para otorgar derechos y confirmar la compra depende de si la compra es por un producto no consumible, por uno consumible o por una suscripción.

En el caso de los consumibles, el método consumeAsync() cumple con el requisito de confirmación e indica que tu app le otorgó derechos al usuario. Este método también permite que la app vuelva a habilitar el producto único para la compra.

Para indicar que se consumió un producto único, llama a consumeAsync() e incluye el token de compra que Google Play debe poner a disposición para volver a comprar. También debes pasar un objeto que implemente la interfaz de ConsumeResponseListener. Este objeto controla el resultado de la operación de consumo. Puedes anular el método onConsumeResponse(), que la biblioteca de Facturación Google Play llama cuando la operación finaliza.

El siguiente ejemplo muestra el consumo de un producto mediante el token de compra asociado:

Kotlin

fun handlePurchase(purchase: Purchase) {
    // Purchase retrieved from BillingClient#queryPurchases or your PurchasesUpdatedListener.
    val purchase : Purchase = ...;

    // Verify the purchase.
    // Ensure entitlement was not already granted for this purchaseToken.
    // Grant entitlement to the user.

    val consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build()

    billingClient.consumeAsync(consumeParams, { billingResult, outToken ->
        if (billingResult.responseCode == BillingResponseCode.OK) {
            // Handle the success of the consume operation.
        }
    })
}

Java

void handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchases or your PurchasesUpdatedListener.
    Purchase purchase = ...;

    // Verify the purchase.
    // Ensure entitlement was not already granted for this purchaseToken.
    // Grant entitlement to the user.

    ConsumeParams consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build();

    ConsumeResponseListener listener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                // Handle the success of the consume operation.
            }
        }
    };

    billingClient.consumeAsync(consumeParams, listener);
}

Para confirmar las compras de productos no consumibles, usa BillingClient.acknowledgePurchase() de la biblioteca de facturación o Product.Purchases.Acknowledge de la API de Google Play Developer. Antes de confirmar una compra, la app debe verificar si ya se confirmó mediante el método isAcknowledged() en la biblioteca de Facturación Google Play o el campo acknowledgementState en la API de Google Developers.

En el siguiente ejemplo, se muestra cómo confirmar una compra mediante la biblioteca de Facturación Google Play:

Kotlin

val client: BillingClient = ...
val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ...

fun handlePurchase() {
    if (purchase.purchaseState === PurchaseState.PURCHASED) {
        if (!purchase.isAcknowledged) {
            val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.purchaseToken)
            val ackPurchaseResult = withContext(Dispatchers.IO) {
               client.acknowledgePurchase(acknowledgePurchaseParams.build())
            }
        }
     }
}

Java

BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...

void handlePurchase(Purchase purchase) {
    if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
        if (!purchase.isAcknowledged()) {
            AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
            client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
        }
    }
}

Las suscripciones se controlan de manera similar a como se controlan los productos no consumibles. Puedes corroborar la confirmación de una suscripción mediante BillingClient.acknowledgePurchase() de la biblioteca de Facturación Google Play o Purchases.Subscriptions.Acknowledge de la API de Google Play Developer. Se deben confirmar todas las compras de suscripciones iniciales. Las renovaciones de suscripciones no necesitan confirmarse. Para obtener más información sobre cuándo se deben confirmar las suscripciones, consulta el tema Cómo vender suscripciones.

Cómo buscar las compras

Utilizar objetos de escucha para las actualizaciones de compra con un PurchasesUpdatedListener no es suficiente para garantizar que tu app procese todas las compras. Es posible que la app no esté al tanto de todas las compras que realizó un usuario. A continuación, se indican algunas situaciones en las que la app podría perder el registro de las compras o desconocerlas:

  • Problemas de red durante la compra: Un usuario realiza una compra exitosa y recibe la confirmación de Google, pero su dispositivo pierde la conexión de red antes de recibir la notificación de la compra a través del PurchasesUpdatedListener.
  • Varios dispositivos: Un usuario compra un artículo en un dispositivo y, luego, espera ver el elemento cuando cambia de dispositivo.
  • Administración de compras realizadas fuera de la app: Algunas compras, como los canjes de promociones, se pueden realizar fuera de la app.

Para resolver estas situaciones, asegúrate de que la app llame a BillingClient.queryPurchases() en los métodos onResume() y onCreate() a fin de garantizar que todas las compras se procesen correctamente como se describe en Cómo procesar las compras..

Cómo manejar las compras realizadas fuera de la app

Algunas compras, como los canjes de promociones, pueden realizarse fuera de la app. Cuando un usuario realiza una compra fuera de tu app, espera que esta muestre un mensaje desde la app o use algún tipo de mecanismo de notificación para informarle que recibió y procesó correctamente la compra. Algunos mecanismos aceptables son los siguientes:

  • Mostrar una ventana emergente en la app.
  • Enviar el mensaje a una casilla de mensajes integrada en la app e indicar claramente que hay un mensaje nuevo en la casilla.
  • Usar un mensaje de notificación del SO.

Ten en cuenta que la app puede estar en cualquier estado cuando reconozca la compra. Incluso es posible que se realice la compra sin que la app esté instalada. Los usuarios esperan recibir la compra cuando reanuden la app, sin importar el estado en el que se encuentre.

Debes poder detectar las compras independientemente del estado en el que se encuentre la app cuando se realice la compra. Sin embargo, hay algunas excepciones en las que es aceptable no notificar de inmediato al usuario que se recibió el elemento. Por ejemplo:

  • Durante la parte de acción de un juego, ya que mostrar un mensaje puede distraer al usuario. En este caso, debes notificar al usuario una vez finalizada la acción.
  • Durante las escenas cinemáticas, ya que mostrar un mensaje puede distraer al usuario. En este caso, debes notificar al usuario después de que termine la escena.
  • Durante el instructivo inicial y las partes de configuración del juego. Te recomendamos notificar a los usuarios nuevos sobre la recompensa inmediatamente después de que abran el juego o durante la configuración inicial del usuario. Sin embargo, es aceptable esperar hasta que la secuencia principal del juego esté disponible para notificar al usuario.

Siempre ten en cuenta al usuario en el momento de decidir cuándo y cómo notificar sobre las compras realizadas fuera de la app. Cada vez que un usuario no recibe una notificación de inmediato, es posible que se confunda y deje de usar la app, e incluso se comunique con el servicio de atención al usuario o se queje en las redes sociales.

Cómo administrar las transacciones pendientes

Google Play admite transacciones pendientes o transacciones que requieren uno o más pasos adicionales entre el momento en que un usuario inicia una compra y el momento en que se procesa la forma de pago de la compra. Tu app no debe otorgar derechos a estos tipos de compras hasta que Google te notifique que la forma de pago del usuario se cobró correctamente.

Por ejemplo, un usuario puede crear una compra PENDING de un elemento integrado en la app si elige la forma de pago en efectivo. Luego, el usuario puede elegir una tienda física en la que completará la transacción y recibirá un código mediante notificación y correo electrónico. Cuando el usuario llega a la tienda física, puede canjear el código con el cajero y pagar en efectivo. Luego, Google les notifica al usuario y a ti que se recibió dinero en efectivo. Posteriormente, la app puede otorgar derechos al usuario.

Para habilitar las compras pendientes, llama a enablePendingPurchases() como parte de la inicialización de tu app.

Cuando la app reciba una compra nueva, ya sea a través del PurchasesUpdatedListener o como resultado de una llamada a queryPurchases(), usa el método getPurchaseState() para determinar si el estado de compra es PURCHASED o PENDING. Ten en cuenta que debes otorgar derechos solamente si el estado es PURCHASED. Si la app se está ejecutando cuando el usuario completa la compra, se vuelve a llamar a PurchasesUpdatedListener, y PurchaseState ahora será PURCHASED. En este punto, la app puede procesar la compra con el método estándar para procesar compras únicas. La app también debe llamar a queryPurchases() en los métodos onResume() y onCreate() para controlar las compras que pasaron al estado PURCHASED mientras no se estaba ejecutando.

La app también puede usar notificaciones para desarrolladores en tiempo real con compras pendientes mediante objetos de escucha de OneTimeProductNotifications. Cuando la compra pasa de PENDING a PURCHASED, tu app recibe una notificación de ONE_TIME_PRODUCT_PURCHASED. Si se cancela la compra, la app recibe una notificación de ONE_TIME_PRODUCT_CANCELED. Esto puede suceder si el cliente no completa el pago en el plazo requerido. Si recibes estas notificaciones, puedes usar la API de Google Play Developer, que incluye un estado PENDING para Purchases.products.