The Android Developer Challenge is back! Submit your idea before December 2.

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.3'
}

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.

Cómo establecer conexión con Google Play

Antes de poder realizar solicitudes con la 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. Además, debes llamar a setListener() pasando una referencia a PurchasesUpdatedListener a fin de recibir actualizaciones sobre las compras iniciadas tanto por tu app como 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 puedan realizarse más solicitudes.

  3. Anula el método de devolución de llamada onBillingServiceDisconnected() y, luego, implementa una política de reintento propia a fin de administrar 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. BillingClient debe llamar al método startConnection() para reiniciar la conexión antes de realizar solicitudes adicionales.

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. Si quieres buscar detalles de productos integrados en la aplicación en Google Play, llama a querySkuDetailsAsync(). Cuando lo hagas, pasa una instancia de SkuDetailsParams que especifique una lista de strings de ID de producto y un objeto SkuType. Este objeto SkuType puede ser tu SkuType.INAPP para productos únicos o productos entregados como recompensa, o bien 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 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 ejemplo:

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 getResponseCode() para obtener el código de respuesta. Si la solicitud es correcta, el código de respuesta será BillingResponse.OK. Puedes consultar la lista de los demás códigos de respuesta posibles de Google Play en BillingClient.BillingResponse.

Si se produce un error, puedes usar getDebugMessage() para ver el mensaje asociado.

En la Biblioteca de Facturación Google Play, se almacenan los resultados de la Búsqueda 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 obtener 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 tu app entre en el flujo de facturación, llama a isFeatureSupported() para verificar que el dispositivo admita los productos que quieres vender. Si quieres ver la lista de los tipos de producto, consulta BillingClient.FeatureType.

Para iniciar la solicitud de compra en tu app, llama al método launchBillingFlow() desde el procesamiento de IU. Pasa una referencia a un objeto BillingFlowParams que incluya los datos relevantes a fin de 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). Si quieres 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

El método launchBillingFlow() muestra uno de los tantos códigos de respuesta enumerados en BillingClient.BillingResponse. Google Play llama al método 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(), como se mostró en la sección Cómo conectarse con Google Play.

Debes implementar el método onPurchasesUpdated() para administrar los posibles códigos de respuesta. En el siguiente fragmento de código, se 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. En el caso de 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 consumibles, usa consumeAsync(), que se encuentra en la API del cliente.
  • En el caso de los 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 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.purchaseState === 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.getPurchaseState() == 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 las 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.getPurchaseState() a fin de determinar si el estado de la compra es PURCHASED o PENDING. Ten en cuenta que deberás 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() a fin de obtener la lista de productos sin consumir asociados con el usuario y, luego, llama a getPurchaseState() para cada objeto Purchase que se muestre.
  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.purchaseState == PurchaseState.PURCHASED) {
        // Grant the item to the user, and then acknowledge the purchase
    } else if (purchase.purchaseState == 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.getPurchaseState() == PurchaseState.PURCHASED) {
        // Acknowledge purchase and grant the item to the user
    } else if (purchase.getPurchaseState() == 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 los productos consumibles, consumeAsync() toma 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);

En el caso de los productos que no se consumen, acknowledgePurchase() toma 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

Siempre debes verificar que el estado de la compra sea PURCHASED y revisar los otros detalles que recibe tu app en onPurchasesUpdated() antes de permitir que el usuario acceda a ella.

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 Suscripciones y compras de la API de Google Play Developer a fin de realizar una solicitud GET y obtener los detalles de la 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. En el campo linkedPurchaseToken de un recurso Purchases.subscriptions, se 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. A fin de 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 ofuscar el código de tu app mediante R8 o ProGuard. Si lo haces, 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 obtener 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 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 Play almacenará los resultados de la Búsqueda en una List de objetos Purchase.

Si quieres ver la lista, llama a getPurchasesList() en el PurchasesResult. Luego, puedes llamar a diferentes métodos del objeto Purchase para ver la información relevante de un artículo, como la hora o el estado de la 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 los canjes que pueda haber hecho el usuario cuando la app no estaba en ejecución. Además, si un usuario realiza una compra mientras la app está en ejecución y esta no la capta por algún motivo, de igual manera 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() y pasar el tipo de compra y un PurchaseHistoryResponseListener a fin de administrar el resultado de la Búsqueda.

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 venció, se canceló o se consumió la compra. Usa queryPurchases() siempre que sea posible (ya que utiliza la caché local), en lugar de queryPurchaseHistoryAsync(). Si usas queryPurchaseHistoryAsync(), también puedes combinarla con un botón Actualizar, lo que permite a los usuarios actualizar su lista de compras.

En el siguiente código, se muestra cómo 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: