Register now for Android Dev Summit 2019!

Cómo usar la Biblioteca de Facturación Google Play

En este documento se explica cómo agregar Facturación Google Play a tu app a través de la Biblioteca de Google Play. En particular, aquí se describe en detalle cómo agregar la función Facturación Google Play que tienen en común todos los tipos de productos integrados en la aplicación: productos únicos, productos entregados como recompensa y suscripciones. Para obtener información sobre cómo agregar funciones específicas de productos integrados en la aplicación, consulta los documentos que se encuentran al final de esta página.

Antes de seguir leyendo, haz lo siguiente:

  1. Lee la Descripción general de Facturación Google Play para familiarizarte con términos y conceptos importantes.
  2. Configura los productos integrados en la aplicación mediante Google Play Console:

Información sobre los fragmentos de código

En esta guía, se usan fragmentos de código de la app de ejemplo Trivial Drive versión 2. Este ejemplo muestra cómo usar la Biblioteca de Facturación Google Play para implementar productos integrados en la aplicación en un juego de conducción. En la app, se muestra cómo detallar los productos disponibles, iniciar un flujo de compra, registrar el consumo de productos y todo lo que necesitas saber para agregar Facturación Google Play a tu app. En la figura 1, se muestra la pantalla de inicio de esta app:

Figura 1: Pantalla de inicio de la app de Trivial Drive

Pasos para agregar Facturación Google Play en una app

Sigue los pasos detallados en las secciones que se incluyen a continuación para agregar Facturación Google Play a tu app.

Actualiza las dependencias de tu app

Agrega la siguiente línea a la sección de dependencias del archivo build.gradle de tu app:

dependencies {
    ...
    implementation 'com.android.billingclient:billing:2.0.1'
}

Para asegurarte de usar la versión actual de la Biblioteca de Facturación Google Play, consulta las notas de la versión de la Biblioteca de Facturación Google Play.

Conéctate a Google Play

Antes de poder realizar solicitudes de Facturación Google Play, primero debes establecer una conexión con Google Play. Para ello, haz lo siguiente:

  1. Llama a newBuilder() para crear una instancia de BillingClient. También debes llamar a setListener(), lo que pasa una referencia a PurchasesUpdatedListener para recibir actualizaciones sobre las compras iniciadas por tu app y por Google Play Store.

  2. Establece una conexión con Google Play. El proceso de configuración es asíncrono, y debes implementar un BillingClientStateListener para recibir una devolución de llamada una vez que se complete la configuración del cliente y se puedan hacer más solicitudes.

  3. Anula el método de devolución de llamada de onBillingServiceDisconnected() para implementar una política de reintento propia que controle las pérdidas de conexión con Google Play en caso de que el cliente las experimente. Por ejemplo, el BillingClient puede perder su conexión si el servicio de Google Play Store se está actualizando en segundo plano. El BillingClient debe llamar al método startConnection() para reiniciar la conexión antes de realizar más solicitudes.

En la siguiente muestra de código, se ve cómo iniciar una conexión y comprobar que está lista para usar:

Kotlin

lateinit private var billingClient: BillingClient
...
billingClient = BillingClient.newBuilder(context).setListener(this).build()
billingClient.startConnection(object : BillingClientStateListener {
   override fun onBillingSetupFinished(billingResult: BillingResult) {
       if (billingResult.responseCode == BillingResponse.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

private BillingClient billingClient;
...
billingClient = BillingClient.newBuilder(activity).setListener(this).build();
billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() == BillingResponse.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.
    }
});

Busca detalles de productos integrados en la aplicación

Los ID de productos únicos que creaste cuando configuraste los productos integrados en la aplicación se usan para buscar de manera asíncrona en Google Play los detalles de esos productos. Para buscar detalles de los productos integrados en la aplicación en Google Play, llama a querySkuDetailsAsync(). Cuando llames a este método, pasa una instancia de SkuDetailsParams que especifique una lista de strings de ID de productos y un SkuType. El SkuType puede ser SkuType.INAPP para productos únicos o entregados como recompensa, o bien SkuType.SUBS para suscripciones.

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

Kotlin

val skuList = ArrayList<String>()
skuList.add("premium_upgrade")
skuList.add("gas")
val params = SkuDetailsParams.newBuilder()
params.setSkusList(skuList).setType(SkuType.INAPP)
billingClient.querySkuDetailsAsync(params.build(), { billingResult, skuDetailsList ->
    // 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.
        }
    });

En tu app, debes conservar tu propia lista de ID de producto. Para hacerlo, combina la lista con tu APK o búscala desde tu propio servidor de backend seguro.

Llama a BillingResult#getResponseCode() para obtener el código de respuesta. Si la solicitud es correcta, el código de respuesta será BillingResponse.OK. Para ver la lista de los otros códigos de respuesta posibles de Google Play, consulta BillingClient.BillingResponse.

Si ocurre un error, puedes usar BillingResult#getDebugMessage() para consultar el mensaje de error asociado.

En la Biblioteca de Facturación Google Play, se almacenan los resultados de las búsquedas en una List de objetos SkuDetails. Luego, puedes llamar a diferentes métodos en cada uno de los objetos SkuDetails de la lista para consultar la información relevante acerca de un producto integrado en la aplicación, como el precio o la descripción. Para ver la información de detalles del producto disponible, consulta la lista de métodos en la clase SkuDetails.

El siguiente ejemplo muestra cómo recuperar los precios de productos integrados en la aplicación usando el objeto SkuDetails que se obtiene con el fragmento de código anterior:

Kotlin

if (result.responseCode == BillingResponse.OK && skuDetailsList != null) {
    for (skuDetails in skuDetailsList) {
        val sku = skuDetails.sku
        val price = skuDetails.price
        if ("premium_upgrade" == sku) {
            premiumUpgradePrice = price
        } else if ("gas" == sku) {
            gasPrice = price
        }
    }
}

Java

if (result.getResponseCode() == BillingResponse.OK && skuDetailsList != null) {
   for (SkuDetails skuDetails : skuDetailsList) {
       String sku = skuDetails.getSku();
       String price = skuDetails.getPrice();
       if ("premium_upgrade".equals(sku)) {
           premiumUpgradePrice = price;
       } else if ("gas".equals(sku)) {
           gasPrice = price;
       }
   }
}

Recuperar el precio de un producto es un paso importante que debe llevarse a cabo antes de que un usuario pueda realizar una compra, ya que el precio varía para cada usuario según su país de origen. En la app de Trivial Drive, se muestran todos los productos integrados en la aplicación como una lista, como se ve en la figura 2:

Figura 2: La pantalla de productos integrados en la aplicación de Trivia Drive

Ofertas coherentes

Cuando ofrezcas un SKU con descuento, Google Play también mostrará el precio original del SKU para que puedas indicarles a los usuarios que están recibiendo un descuento. Te recomendamos que uses getPrice() para mostrarle el precio con descuento al usuario y getOriginalPrice() para mostrar el precio original del artículo.

SkuDetails incluye dos métodos para recuperar el precio del SKU original:

Habilita la compra de un producto integrado en la aplicación

Es posible que algunos teléfonos Android tengan una versión anterior de la app de Google Play Store que no es compatible con determinados tipos de producto, como las suscripciones. Por lo tanto, antes de que la app entre en el flujo de facturación, llama a isFeatureSupported() para verificar que el dispositivo admita los productos que quieres vender. Para ver la lista de tipos de producto, consulta BillingClient.FeatureType.

Para iniciar la solicitud de compra desde tu app, llama al método launchBillingFlow() desde el procesamiento de IU. Pasa una referencia a un objeto BillingFlowParams que incluya los datos relevantes para completar la compra, como el ID de producto (skuId) del artículo y el tipo de producto (SkuType.INAPP para un producto único o un producto entregado como recompensa, o bien SkuType.SUBS para una suscripción). Para obtener una instancia de BillingFlowParams, usa la clase BillingFlowParams.Builder:

Kotlin

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

Java

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

Cuando llamas al método launchBillingFlow(), el sistema muestra la pantalla de compra de Google Play. En la figura 3, se ve la pantalla de compra de un producto único:

Figura 3: Pantalla de compra de Google Play para un producto único

En la figura 4, se muestra la pantalla de compra de una suscripción:

Figura 4: Pantalla de compra de Google Play para una suscripción

Con el método launchBillingFlow(), se muestra uno de varios de los códigos de respuesta detallados en BillingClient.BillingResponse. Google Play llama al método onPurchasesUpdated() para mostrar 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(), como se mostró antes en la sección Conéctate a Google Play.

Debes implementar el método onPurchasesUpdated() para manejar los posibles códigos de respuesta. El siguiente fragmento de código muestra cómo anular el método onPurchasesUpdated():

Kotlin

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

Las compras realizadas correctamente generan una pantalla de éxito de Google Play similar a la de la figura 5.

Figura 5: Pantalla de confirmación de Google Play

Las compras que se realizan correctamente también generan un token de compra, que es un identificador único que representa al usuario y el ID del producto integrado en la aplicación que se compró. Tus apps pueden almacenar el token de compra a nivel local o, en el mejor caso, pasarlo al servidor de backend seguro, donde se puede usar para verificar la compra y prevenir fraudes. El token de compra es único para todas las compras únicas y los productos entregados como recompensa. Sin embargo, como las suscripciones se compran una vez y se renuevan automáticamente en un período de facturación regular, el token de compra para suscripciones es el mismo para cada período de facturación.

Además, al usuario le llega por correo electrónico un recibo de la operación con un ID de pedido o un ID único de la transacción. Los usuarios reciben un correo electrónico con un ID de pedido único para las compras correspondientes a productos únicos, así como para la compra inicial de la suscripción y las renovaciones automáticas posteriores. Puedes usar el ID de pedido para administrar los reembolsos en Google Play Console. Para obtener más información, consulta Cómo visualizar y reembolsar los pedidos y suscripciones de tu app.

Reconoce una compra

Si usas la versión 2.0 o más reciente de la Biblioteca Facturación Google Play, debes confirmar todas las compras en un plazo de tres días. Si no se confirman las compras correctamente, se reembolsarán los cargos.

Google Play admite la compra de productos desde adentro de la app (integrados en la aplicación) y fuera de ella. Para que Google Play garantice una experiencia de compra coherente, sin importar dónde compre tu producto el usuario, debes confirmar todas las compras que tengan el estado SUCCESS recibidas mediante la Biblioteca de Facturación Google Play tan pronto como sea posible después de otorgar autorización al usuario. Si no confirmas una compra en un plazo de tres días, el usuario recibirá automáticamente un reembolso y Google Play revocará la compra. Para las transacciones pendientes, no se aplica el plazo de tres días cuando el estado de la compra es PENDING. En su lugar, empieza cuando la compra pasó al estado SUCCESS.

Para confirmar una compra, usa uno de los siguientes métodos:

  • En el caso de productos para usuarios finales, usa consumeAsync(), que se encuentra en la API del cliente.
  • Para productos que no se consumen, usa acknowledgePurchase(), que se encuentra en la API del cliente.
  • También hay un método acknowledge() nuevo disponible en la API del servidor.

Para las suscripciones, debes confirmar cualquier compra que tenga un token de compra nuevo. Eso quiere decir que se deben confirmar todas las compras iniciales, los cambios de planes y los registros nuevos de facturación, pero no es necesario que confirmes las renovaciones posteriores. Para determinar si es necesario confirmar una compra, puedes consultar el campo de confirmación en la compra.

El objeto Purchase ahora incluye un método isAcknowledged(), que indica si se confirmó una compra. Además, la API del servidor ahora incluye valores booleanos de confirmación para Product.purchases.get() y Product.subscriptions.get(). Antes de confirmar una compra, usa esos métodos para determinar si ya se confirmó.

En este ejemplo, se muestra cómo confirmar la compra de una suscripción:

Kotlin

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

fun handlePurchase() {
    if (purchase.state === PurchaseState.PURCHASED) {
        // Grant entitlement to the user.
        ...

        // Acknowledge the purchase if it hasn't already been acknowledged.
        if (!purchase.isAcknowledged) {
            val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.purchaseToken)
                    .build()
            client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener)
        }
     }
}

Java

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

void handlePurchase(Purchase purchase) {
    if (purchase.getState() == PurchaseState.PURCHASED) {
        // Grant entitlement to the user.
        ...

        // Acknowledge the purchase if it hasn't already been acknowledged.
        if (!purchase.isAcknowledged()) {
            AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
            client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
        }
    }
}

Prueba la confirmación de compras con verificadores de licencia

En el caso de las compras realizadas por verificadores de licencias, el intervalo de confirmación es más corto. En lugar de tres días, las compras se reembolsan y se revocan cuando no se confirman dentro de los cinco minutos.

Cómo admitir transacciones pendientes

Cuando implementas una solución de Facturación Google Play, debes admitir compras en las que se requieren acciones adicionales antes de otorgar autorización. Por ejemplo, un usuario puede elegir comprar tu producto integrado en la aplicación en una tienda física con dinero en efectivo. Eso significa que la transacción se completa fuera de tu app. En ese caso, deberías otorgar autorización solo después de que el usuario haya completado la transacción.

Para habilitar compras pendientes, llama a enablePendingPurchases() cuando se inicialice la app. Ten en cuenta que si no llamas a enablePendingPurchases(), no podrás crear una instancia de la Biblioteca de Facturación Google Play.

Usa el método Purchase.getState() para determinar si el estado de la compra es PURCHASED o PENDING. Ten en cuenta que debes otorgar autorización solo cuando el estado sea PURCHASED. Para consultar los cambios de estado, haz lo siguiente:

  1. Cuando inicies la app, llama a BillingClient.queryPurchases() para obtener la lista de productos sin consumir asociados con el usuario y, luego, llama a getState() para cada objeto Purchase obtenido.
  2. Implementa el método onPurchasesUpdated() para responder a los cambios en los objetos Purchase.

A continuación, se incluye un ejemplo que muestra cómo podrías manejar las transacciones pendientes:

Kotlin

fun handlePurchase(purchase: Purchase) {
    if (purchase.state == PurchaseState.PURCHASED) {
        // Grant the item to the user, and then acknowledge the purchase
    } else if (purchase.state == PurchaseState.PENDING) {
        // Here you can confirm to the user that they've started the pending
        // purchase, and to complete it, they should follow instructions that
        // are given to them. You can also choose to remind the user in the
        // future to complete the purchase if you detect that it is still
        // pending.
    }
}

Java

void handlePurchase(Purchase purchase) {
    if (purchase.getState() == PurchaseState.PURCHASED) {
        // Acknowledge purchase and grant the item to the user
    } else if (purchase.getState() == PurchaseState.PENDING) {
        // Here you can confirm to the user that they've started the pending
        // purchase, and to complete it, they should follow instructions that
        // are given to them. You can also choose to remind the user in the
        // future to complete the purchase if you detect that it is still
        // pending.
    }
}

Prueba las transacciones pendientes con verificadores de licencia

Para comprobar las transacciones pendientes, puedes usar verificadores de licencia. Además de dos tarjetas de crédito de prueba, los verificadores de licencia tienen acceso a dos instrumentos de prueba para formas de pago demoradas que se completan o cancelan automáticamente después de unos minutos.

Mientras pruebas tu aplicación, debes verificar que no otorgue autorización ni reconozca la compra de inmediato después de comprar con cualquiera de esos dos instrumentos. Cuando se realiza una compra con el instrumento de prueba que completa la operación automáticamente, debes verificar que la aplicación otorgue autorización y confirme la compra una vez que esta se completa.

Cuando se realiza una compra con el instrumento de prueba que cancela la operación automáticamente, debes verificar que la aplicación no otorgue autorización, ya que no se completó una compra correctamente.

Vincula una carga útil de desarrollador

Puedes vincular una string arbitraria o una carga útil de desarrollador a las compras. Sin embargo, ten en cuenta que solo puedes vincular una carga útil de desarrollador cuando se confirma o consume la compra. La carga útil de desarrollador en AIDL es distinta, ya que allí se puede especificar cuando se inicia el flujo de compra.

En el caso de productos que se pueden consumir, consumeAsync() requiere un objeto ConsumeParams que incluya un campo con carga útil de desarrollador, como se muestra en el siguiente ejemplo:

Kotlin

val client: BillingClient = ...
val listener: ConsumeResponseListener = ...

val consumeParams =
    ConsumeParams.newBuilder()
        .setPurchaseToken(/* token */)
        .setDeveloperPayload(/* payload */)
        .build()

client.consumeAsync(consumeParams, listener)

Java

BillingClient client = ...
ConsumeResponseListener listener = ...

ConsumeParams consumeParams =
    ConsumeParams.newBuilder()
        .setPurchaseToken(/* token */)
        .setDeveloperPayload(/* payload */)
        .build();

client.consumeAsync(consumeParams, listener);

Para productos que no se consumen, acknowledgePurchase() requiere un objeto AcknowledgePurchaseParams que incluya un campo con carga útil de desarrollador, como se muestra en el siguiente ejemplo:

Kotlin

val client: BillingClient = ...
val listener: AcknowledgePurchaseResponseListener = ...

val acknowledgePurchaseParams =
    AcknowledgePurchaseParams.newBuilder()
        .setPurchaseToken(/* token */)
        .setDeveloperPayload(/* payload */)
        .build()

client.acknowledgePurchase(acknowledgePurchaseParams, listener)

Java

BillingClient client = ...
AcknowledgePurchaseResponseListener listener = ...

AcknowledgePurchaseParams acknowledgePurchaseParams =
    AcknowledgePurchaseParams.newBuilder()
        .setPurchaseToken(/* token */)
        .setDeveloperPayload(/* payload */)
        .build();

client.acknowledgePurchase(acknowledgePurchaseParams, listener);

Para acceder a una carga útil de desarrollador, llama a getDeveloperPayload() en el objeto Purchase correspondiente.

Solo puedes consumir o confirmar una compra con el estado PURCHASED.

Verifica una compra

Debes verificar que el estado de compra sea PURCHASED, además de los detalles de compra que tu app recibe en onPurchasesUpdated() antes de otorgarle acceso al usuario a lo que haya adquirido.

Verifica una compra en un servidor

Cuando implementas la lógica de verificación de compra en un servidor, proteges tu app de atacantes que intentan aplicar ingeniería inversa en tu archivo APK e inhabilitan su lógica de verificación. Para verificar los detalles de compra en un servidor de backend seguro, completa siguientes los pasos:

  1. Desde tu app, envía el token de compra y la credencial de cuenta de usuario al servidor de backend seguro. Este debería poder asociar la compra con el usuario después de que se complete correctamente la verificación.

  2. Luego de obtener el token de la app, haz lo siguiente:

    1. Usa la sección de Suscripciones y compras de la API de desarrolladores de Google Play para realizar una solicitud GET y obtener los detalles de compra de Google Play (Purchases.products para la compra de productos únicos o de productos otorgados como recompensa, o bien Purchases.subscriptions para una suscripción). La solicitud GET incluye el nombre del paquete de app, el ID de producto y un token (token de compra).

    2. Google Play muestra los detalles de compra.

    3. El servidor de backend seguro verifica que el ID de pedido sea un valor único que no represente una compra anterior.

    4. El servidor de backend seguro usa la credencial de cuenta de usuario que recibe en el paso 1 para asociar el token de compra con el usuario de la instancia de la app en la que se hizo la compra.

    5. (opcional) Si estás validando una suscripción y esta se actualizará, pasará a una versión anterior, o bien el usuario se volvió a suscribir antes del vencimiento, consulta el campo linkedPurchaseToken. El campo linkedPurchaseToken en un recurso Purchases.subscriptions incluye el token de la compra "original" o anterior. Para obtener más información sobre linkedPurchaseToken, consulta Purchases.subscriptions.

    6. El producto integrado en la aplicación se pone a disposición del usuario.

Verifica una compra en un dispositivo

Aunque no puedas ejecutar tu propio servidor, puedes validar los detalles de compra en tu app de Android.

Para ayudarte a garantizar la integridad de la información de la transacción que se envía a tu aplicación, Google Play firma una string JSON que contiene los datos de respuesta de una compra. Para crear esta firma, Google Play usa la clave privada que está asociada a tu aplicación en Play Console. Play Console genera un par de claves RSA para cada aplicación. Para obtener esa respuesta JSON, debes usar el método getOriginalJson() en la clase Purchase.

La clave pública RSA con codificación en base64 generada por Google Play tiene formato X.509 subjectPublicKeyInfo DER SEQUENCE de codificación binaria. Es la misma clave pública que se usa con las licencias de Google Play.

Cuando tu aplicación recibe esta respuesta firmada, puedes usar la sección de la clave pública de tu par de claves RSA para verificar la firma. Cuando llevas a cabo la verificación de firmas, puedes detectar respuestas alteradas o falsificadas.

Debes ocultar la clave pública de Google Play y el código de Facturación Google Play a fin de que sea difícil para un atacante aplicar ingeniería a los protocolos de seguridad y a otros componentes de la aplicación. Como mínimo, te recomendamos ejecutar una herramienta de ocultamiento como Proguard en tu código. Si usas Proguard para ocultar tu código, debes agregar la siguiente línea a tu archivo de configuración de Proguard:

-keep class com.android.vending.billing.**

Después de ocultar la clave pública de Google Play y el código de Facturación Google Play, estará todo listo para que tu app valide detalles de compra. Cuando tu app verifica una firma, asegúrate de que su clave haya firmado los datos JSON incluidos en esa firma.

Mantén las compras actualizadas

Es posible que se pierda el registro de las compras que hace un usuario. A continuación, se incluyen dos escenarios que muestran que tu app podría dejar de seguir las compras y la importancia de buscar las compras.

Controla las fallas del servidor

  1. Un usuario compra un producto único, como gasolina adicional para un juego de conducción.
  2. La app envía un token de compra al servidor de backend seguro para su verificación.
  3. El servidor no funciona en ese momento.
  4. La app reconoce que el servidor no funciona y envía una notificación al usuario sobre el problema con la compra.
  5. La app para Android vuelve a enviar el token de compra al servidor de backend seguro y finaliza la compra no bien se restaura el servidor.
  6. La app actualiza el contenido.

Controla varios dispositivos

  1. Un usuario compra una suscripción en su teléfono Android.
  2. La app envía un token de compra al servidor de backend seguro para su verificación.
  3. El servidor verifica el token de compra.
  4. La app actualiza el contenido.
  5. El usuario pasa a una tablet Android para usar la suscripción.
  6. La app en el dispositivo nuevo realiza una consulta para obtener una lista actualizada de las compras.
  7. La app reconoce la suscripción y otorga acceso a ella en la tablet.

Busca compras almacenadas en caché

Para recuperar información sobre las compras realizadas por un usuario desde tu app, llama a queryPurchases() con el tipo de compra (SkuType.INAPP o SkuType.SUBS) en BillingClient, como se muestra en el siguiente código de ejemplo:

Kotlin

val purchasesResult: PurchasesResult =
        billingClient.queryPurchases(SkuType.INAPP)

Java

PurchasesResult purchasesResult = billingClient.queryPurchases(SkuType.INAPP);

Google Play muestra las compras que se hicieron desde la cuenta de usuario con la que se accedió al dispositivo. Si se aprueba la solicitud, la Biblioteca de Facturación Google Play almacenará los resultados de la búsqueda en una List de objetos Purchase.

Para obtener la lista, llama a getPurchasesList() en el PurchasesResult. Luego, puedes llamar a diferentes métodos en el objeto Purchase para consultar la información relevante de un elemento, como la hora o el estado de compra. Para ver los tipos de información sobre detalles de productos disponibles, consulta la lista de métodos en la clase Purchase.

Deberías llamar a queryPurchases() al menos dos veces en tu código:

  • Llama a queryPurchases() cada vez que se inicie tu app para restaurar todas las compras que haya hecho un usuario desde la última vez que se detuvo la app.
  • Llama a queryPurchases() en tu método onResume(), porque un usuario puede hacer una compra cuando tu app está en segundo plano (por ejemplo, canjear un código promocional en la app de Google Play Store).

Llamar a queryPurchases() cuando se inicia y reanuda la app garantiza que se descubran todas las compras y canjes que pueda haber hecho el usuario mientras no se estaba ejecutando la app. Además, si un usuario realiza una compra mientras la app está en ejecución y esta no la capta por alguna razón, de todos modos advertirá la compra la próxima vez que se reanude la actividad y llame a queryPurchases().

Busca las compras más recientes

El método queryPurchases() usa una caché de la app de Google Play Store sin iniciar una solicitud de red. Si necesitas consultar la compra más reciente que hizo el usuario para cada ID de producto, puedes usar queryPurchaseHistoryAsync(). Como resultado, el tipo de compra y un PurchaseHistoryResponseListener manejan el resultado de la consulta.

queryPurchaseHistoryAsync() muestra un objeto PurchaseHistory que incluye información sobre la compra más reciente que hizo el usuario para cada ID de producto, incluso si se venció, canceló o consumió la compra. Cuando sea posible, usa queryPurchases(), ya que utiliza la caché local, en lugar de queryPurchaseHistoryAsync(). Si usas queryPurchaseHistoryAsync(), también puedes combinarla con un botón de Actualizar, que les permite a los usuarios actualizar su lista de compras.

El siguiente código muestra cómo puedes anular el método onPurchaseHistoryResponse():

Kotlin

billingClient.queryPurchaseHistoryAsync(SkuType.INAPP, { billingResult, purchasesList ->
   if (billingResult.responseCode == BillingResponse.OK && purchasesList != null) {
       for (purchase in purchasesList) {
           // Process the result.
       }
   }
})

Java

billingClient.queryPurchaseHistoryAsync(SkuType.INAPP,
                                         new PurchaseHistoryResponseListener() {
    @Override
    public void onPurchaseHistoryResponse(BillingResult billingResult,
                                          List<Purchase> purchasesList) {
        if (billingResult.getResponseCode() == BillingResponse.OK
                && purchasesList != null) {
            for (Purchase purchase : purchasesList) {
                // Process the result.
            }
         }
    }
});

Próximos pasos

Después de permitirles a los usuarios comprar tus productos, debes aprender a manejar escenarios de productos específicos: