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

En este tema, se describe cómo integrar la Biblioteca de Facturación Google Play a tu app para comenzar a vender productos.

Duración de una compra

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

  1. Muéstrale al usuario lo que puede comprar.
  2. Inicia el flujo de compra para que el usuario acepte la compra.
  3. Verifica la compra en tu servidor.
  4. Proporciona contenido al usuario.
  5. Confirma la entrega del contenido. En el caso de productos de consumo, procesa la compra de modo que el usuario pueda volver a comprar el artículo.

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

  • Activo: 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 intenta procesar el pago nuevamente.
  • En espera: El usuario tuvo un problema con el pago y ya no tiene acceso. Mientras tanto, Google intenta procesar el pago nuevamente.
  • Detenida: El usuario detuvo el acceso y no podrá acceder hasta que lo reanude.
  • Vencida: El usuario canceló la suscripción y perdió el acceso a ella. Se considera que el usuario desertó luego del vencimiento.

Cómo inicializar una conexión con Google Play

El primer paso para integrar el sistema de facturación de Google Play es agregar la Biblioteca de Facturación Google Play 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:

Groovy

dependencies {
    def billing_version = "7.0.0"

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

Kotlin

dependencies {
    val billing_version = "7.0.0"

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

Si usas Kotlin, el módulo KTX de la Biblioteca de Facturación Google Play es compatible con las extensiones y las corrutinas de Kotlin, y permite la escritura de código idiomático 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:

Groovy

dependencies {
    def billing_version = "7.0.0"

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

Kotlin

dependencies {
    val billing_version = "7.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. Ten en cuenta lo siguiente:

  • Te recomendamos tener una conexión BillingClient activa a la vez para evitar varias devoluciones de llamada PurchasesUpdatedListener para un solo evento.
  • Se recomienda iniciar una conexión para BillingClient cuando se inicia la app o pasa a primer plano para garantizar que la app procese las compras de forma oportuna. Esto se puede lograr con el ActivityLifecycleCallbacks registrado por registerActivityLifecycleCallbacks y escuchando onActivityResumed para inicializar una conexión cuando detectes por primera vez que se reanuda una actividad. Consulta la sección sobre el procesamiento de compras para obtener más detalles sobre por qué se debe seguir esta práctica recomendada. Además, recuerda finalizar la conexión cuando cierres la app.

Para crear un BillingClient, usa newBuilder. Puedes pasar cualquier contexto a newBuilder(), y BillingClient lo usará para obtener un contexto de aplicación. Eso significa que no debes preocuparte por las fugas de memoria. 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 que se realizan en tu app.

Kotlin

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

private var billingClient = BillingClient.newBuilder(context)
   .setListener(purchasesUpdatedListener)
   // Configure other settings.
   .build()

Java

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

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    // Configure other settings.
    .build();

Cómo conectarse a 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 para 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 buscar los productos disponibles y mostrarlos a los usuarios.

La consulta de detalles de productos es un paso importante antes de mostrar los productos a los usuarios, ya que devuelve información localizada sobre los productos. En el caso de suscripciones, asegúrate de que la visualización de tus productos cumpla con todas las políticas de Play.

Para buscar detalles de productos integrados en la app, llama a queryProductDetailsAsync.

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

Kotlin

val queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build()

billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
    billingResult,
    productDetailsList ->
      // check billingResult
      // process returned productDetailsList
}

Java

QueryProductDetailsParams queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build();

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
        public void onProductDetailsResponse(BillingResult billingResult,
                List<ProductDetails> productDetailsList) {
            // check billingResult
            // process returned productDetailsList
        }
    }
)

Cuando busques detalles de productos, pasa una instancia de QueryProductDetailsParams que especifique una lista de cadenas del ID del producto creadas en Google Play Console junto con un ProductType. El objeto ProductType puede ser ProductType.INAPP para productos únicos o ProductType.SUBS para suscripciones.

Cómo consultar con extensiones de Kotlin

Si usas extensiones de Kotlin, puedes llamar a la función de extensión queryProductDetails() para buscar los detalles del producto integrado en la app.

queryProductDetails() aprovecha las corrutinas de Kotlin para que no tengas que definir un objeto de escucha independiente. En cambio, la función se suspende hasta que se completa la consulta, y después puedes procesar el resultado:

suspend fun processPurchases() {
    val productList = listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("product_id_example")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )
    val params = QueryProductDetailsParams.newBuilder()
    params.setProductList(productList)

    // leverage queryProductDetails Kotlin extension function
    val productDetailsResult = withContext(Dispatchers.IO) {
        billingClient.queryProductDetails(params.build())
    }

    // Process the result.
}

En raras ocasiones, algunos dispositivos no admiten ProductDetails y queryProductDetailsAsync(), por lo general, debido a versiones desactualizadas de los Servicios de Google Play. Para garantizar la compatibilidad apropiada en este caso, obtén información sobre el uso de las funciones de retrocompatibilidad en la Guía de migración de la Biblioteca de Facturación Play 5.

Cómo procesar el resultado

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

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 procesar su compra antes de volver a comprarlo.

Antes de ofrecer una suscripción, verifica que el usuario no esté suscrito. Además, ten en cuenta lo siguiente:

  • queryProductDetailsAsync() devuelve los detalles del producto de suscripción, y se permite un máximo de 50 ofertas por suscripción.
  • queryProductDetailsAsync() solo devuelve ofertas para las que el usuario reúne los requisitos. Si el usuario intenta comprar una oferta para la que no reúne los requisitos (por ejemplo, si la app muestra una lista desactualizada de ofertas aptas), Play informa al usuario que no reúne los requisitos, y el usuario puede optar por comprar el plan básico.

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 ProductDetails relevante obtenido de la llamada a queryProductDetailsAsync. 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 = ...;

val productDetailsParamsList = listOf(
    BillingFlowParams.ProductDetailsParams.newBuilder()
        // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
        .setProductDetails(productDetails)
        // For One-time products, "setOfferToken" method shouldn't be called.
        // For subscriptions, to get an offer token, call ProductDetails.subscriptionOfferDetails()
        // for a list of offers that are available to the user
        .setOfferToken(selectedOfferToken)
        .build()
)

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build()

// Launch the billing flow
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

Java

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

ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
             // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // For one-time products, "setOfferToken" method shouldn't be called.
            // For subscriptions, to get an offer token, call
            // ProductDetails.subscriptionOfferDetails() for a list of offers
            // that are available to the user.
            .setOfferToken(selectedOfferToken)
            .build()
    );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

El método launchBillingFlow()BillingClient.BillingResponseCode devuelve 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 la pantalla de compra de una suscripción:

En la pantalla de compra de Google Play, se muestra una suscripción que está disponible para su compra
Figura 1: En la pantalla de compra de Google Play, se muestra una suscripción que está disponible para su 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 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) {
           // Process the purchase as described in the next section.
       }
   } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) {
       // Handle an error caused by a user canceling 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) {
            // Process the purchase as described in the next section.
        }
    } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
        // Handle an error caused by a user canceling 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 con más detalle en Cómo detectar y procesar compras.

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 indicar un precio personalizado

Si tu app puede distribuirse a usuarios de la Unión Europea, usa el método setIsOfferPersonalized() cuando llames a launchBillingFlow para informar a los usuarios que el precio de un artículo se personalizó mediante la toma de decisiones automatizada.

La pantalla de compra de Google Play que indica que el precio se personalizó para el usuario.
Figura 3. La pantalla de compra de Google Play indica que el precio se personalizó para el usuario.

Debes consultar el artículo 6 (1) (ea) CRD de la Directiva de Derechos de los Consumidores 2011/83/UE para determinar si el precio que ofreces a los usuarios es personalizado.

setIsOfferPersonalized() toma una entrada booleana. Cuando se establece en true, la IU de Play incluye la divulgación. Cuando es false, la IU omite la divulgación. El valor predeterminado es false.

Para obtener más información, consulta al Centro de ayuda al consumidor.

Cómo adjuntar identificadores de usuario

Cuando inicias el flujo de compra, tu app puede adjuntar cualquier identificador de usuario que tengas para el usuario que realiza la compra con obfuscatedAccountId o obfuscatedProfileId. Un ejemplo de identificador podría ser una versión ofuscada del acceso del usuario en tu sistema. La configuración de estos parámetros puede ayudar a Google a detectar fraudes. Además, puede ayudarte a garantizar que las compras se atribuyan al usuario correcto, como se explica en Cómo otorgar derechos a los usuarios.

Detecta y procesa compras

La detección y el procesamiento de una compra que se describen en esta sección se aplican a todos los tipos de compras, incluidas las compras fuera de la app, como los canjes de promociones.

Tu app detecta compras nuevas y compras pendientes completadas de una de las siguientes maneras:

  1. Cuando se llama a onPurchasesUpdated como resultado de que tu app llama a launchBillingFlow (como se explicó en la sección anterior) o si tu app se ejecuta con una conexión activa de la Biblioteca de Facturación cuando se realiza una compra fuera de tu app o se completa una compra pendiente. Por ejemplo, un miembro de la familia aprueba una compra pendiente en otro dispositivo.
  2. Cuando tu app llama a queryPurchasesAsync para consultar las compras del usuario.

En el caso del punto 1, se llamará automáticamente a onPurchasesUpdated para las compras nuevas o completadas, siempre que tu app esté en ejecución y tenga una conexión activa a la biblioteca de la Facturación Google Play. Si tu aplicación no se está ejecutando o no tiene una conexión activa a la biblioteca de Facturación Google Play, no se invocará a onPurchasesUpdated. Recuerda que se recomienda que tu app intente mantener una conexión activa mientras esté en primer plano para garantizar que reciba actualizaciones de compras oportunas.

En el caso del punto 2, debes llamar a BillingClient.queryPurchasesAsync() para asegurarte de que tu app procese todas las compras. Te recomendamos que lo hagas cuando tu app establezca una conexión correctamente con la biblioteca de Facturación Google Play (lo que se recomienda cuando se inicia la app o pasa a primer plano, como se explica en Cómo inicializar un BillingClient). Para ello, llama a queryPurchasesAsync cuando recibas un resultado correcto en onServiceConnected. Seguir esta recomendación es fundamental para controlar eventos y situaciones como los siguientes:

  • Problemas de red durante la compra: Un usuario puede realizar una compra exitosa y recibir la confirmación de Google, pero su dispositivo pierde la conexión de red antes de que el dispositivo y tu app reciban la notificación de la compra a través del PurchasesUpdatedListener.
  • Varios dispositivos: Un usuario puede comprar un artículo en un dispositivo y, luego, esperar 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.
  • Controla las transiciones de estado de compra: Un usuario puede completar el pago de una compra PENDIENTE mientras tu aplicación no se está ejecutando y esperar recibir la confirmación de que completó la compra cuando abra tu app.

Una vez que tu app detecte una compra nueva o completada, debe hacer lo siguiente:

  • Verifica la compra.
  • Otorgar contenido al usuario por las compras realizadas
  • Notifica al usuario.
  • Notificar a Google que tu app procesó las compras completadas

Estos pasos se analizan en detalle en las siguientes secciones, seguidas de una sección para resumir todos los pasos.

Verifica la compra

Tu app siempre debe verificar las compras para asegurarse de que sean legítimas antes de otorgar beneficios a un usuario. Para ello, sigue los lineamientos que se describen en Cómo verificar las compras antes de otorgar derechos. Solo después de verificar la compra, tu app debe continuar con el procesamiento y otorgar derechos al usuario, como se explica en la siguiente sección.

Otorga derechos al usuario

Una vez que tu app haya verificado una compra, puede seguir otorgándole el derecho al usuario y notificárselo. Antes de otorgar el derecho, asegúrate de que la app verifique que el estado de compra sea PURCHASED. Si la compra está en estado PENDIENTE, la app debe notificarle al usuario que aún debe completar acciones para completar la compra antes de que se otorgue el derecho. Otorga derechos solo cuando la compra cambie de PENDIENTE a EXITOSA. Puedes encontrar más información en Cómo administrar transacciones pendientes.

Si adjuntaste identificadores de usuario a la compra, como se explica en Cómo adjuntar identificadores de usuario, puedes recuperarlos y usarlos para atribuirlos al usuario correcto en tu sistema. Esta técnica es útil cuando se concilian compras en las que tu app puede haber perdido el contexto sobre para qué usuario es una compra. Ten en cuenta que las compras realizadas fuera de la app no tendrán estos identificadores configurados. En este caso, tu app puede otorgar el derecho al usuario que accedió o pedirle que seleccione una cuenta preferida.

Notifica al usuario

Después de otorgar los derechos al usuario, la app debe mostrar una notificación para confirmar que la compra se realizó correctamente. Esto garantiza que el usuario no se confunda sobre si la compra se completó correctamente, lo que podría provocar que deje de usar tu app, se comunique con el servicio de asistencia al usuario o se queje en las redes sociales. Ten en cuenta que tu app puede detectar actualizaciones de compras en cualquier momento durante el ciclo de vida de la aplicación. Por ejemplo, un padre o madre aprueba una compra pendiente en otro dispositivo. En ese caso, es posible que tu app deba retrasar la notificación al usuario hasta un momento adecuado. Estos son algunos ejemplos en los que sería apropiado retrasar la publicación:

  • Durante la parte de acción de un juego o las escenas cinemáticas, mostrar un mensaje puede distraer al usuario. En este caso, debes notificar al usuario una vez finalizada la acción.
  • Durante el instructivo inicial y las partes de configuración del juego. Por ejemplo, es posible que un usuario haya realizado una compra fuera de tu app antes de instalarla. 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. Si tu app requiere que el usuario cree una cuenta o acceda antes de otorgarle derechos, te recomendamos que le comuniques qué pasos debe completar para reclamar su compra. Esto es fundamental, ya que las compras se reembolsan después de 3 días si tu app no las procesó.

Cuando se notifica al usuario sobre una compra, Google Play recomienda los siguientes mecanismos:

  • Muestra un diálogo 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.

La notificación debe informar al usuario sobre el beneficio que recibió. Por ejemplo, "Compraste 100 monedas de oro". Además, si la compra fue el resultado de un beneficio de un programa como Play Pass, tu app se lo comunica al usuario. Por ejemplo, "Recibí los artículos. Acabas de recibir 100 gemas con Play Pass. Continúa". Cada programa puede tener orientación sobre el texto recomendado para mostrar a los usuarios y comunicar los beneficios.

Notifica a Google que se procesó la compra

Después de que tu app le otorgue derechos al usuario y le notifique que la transacción se realizó correctamente, debe notificarle a Google que la compra se procesó correctamente. Para ello, debes confirmar la compra, y esto se debe hacer en un plazo de tres días para garantizar que no se reembolse automáticamente y se revoque el derecho. En las siguientes secciones, se describe el proceso para confirmar diferentes tipos de compras.

Productos consumibles

En el caso de los productos de consumo, si la app tiene un backend seguro, te recomendamos que uses Purchases.products:consume para consumir compras de manera confiable. Asegúrate de que la compra no se haya consumido. Para ello, consulta el objeto consumptionState que aparece en el resultado de la llamada a Purchases.products:get. Si tu app es solo para clientes sin un backend, usa consumeAsync() de la biblioteca de Google Play Billing. Ambos métodos cumplen con el requisito de confirmación e indican que tu app le otorgó derechos al usuario. Estos métodos también permiten que tu app habilite el producto único correspondiente al token de compra de entrada para volver a comprar. Con consumeAsync(), 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 ilustra el consumo de un producto usando la Biblioteca de Facturación Google Play con el token de compra asociado:

Kotlin

    val consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build()
    val consumeResult = withContext(Dispatchers.IO) {
        client.consumePurchase(consumeParams)
    }

Java

    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);

Productos no consumibles

Para confirmar las compras de productos no consumibles, si la app tiene un backend seguro, te recomendamos que uses Purchases.products:acknowledge para confirmar compras de manera confiable. Para asegurarte de que no se haya confirmado la compra con anterioridad, consulta el elemento acknowledgementState del resultado de la llamada a Purchases.products:get.

Si tu app es solo para clientes, usa BillingClient.acknowledgePurchase() de la Biblioteca de Facturación Google Play. Antes de confirmar una compra, la app debe verificar si ya se confirmó a través del método isAcknowledged() en la Biblioteca de Facturación Google Play.

En el siguiente ejemplo, se muestra la confirmación de una compra con la Biblioteca de Facturación Google Play:

Kotlin

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

val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
    .setPurchaseToken(purchase.purchaseToken)
val ackPurchaseResult = withContext(Dispatchers.IO) {
     client.acknowledgePurchase(acknowledgePurchaseParams.build())
}

Java

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

AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
 client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);

Suscripciones

Las suscripciones se controlan de manera similar a como se controlan los productos no consumibles. Si es posible, usa Purchases.subscriptions.acknowledge de la API de Google Play Developer para confirmar la compra, de forma confiable, desde tu backend seguro. Para verificar que no se haya confirmado la compra con anterioridad, consulta el elemento acknowledgementState en el recurso de compra de Purchases.subscriptions:get. De lo contrario, puedes confirmar una suscripción con BillingClient.acknowledgePurchase() de la Biblioteca de Facturación Google Play después de verificar isAcknowledged(). 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.

Resumen

En el siguiente fragmento de código, se muestra un resumen de estos pasos.

Kotlin

fun handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify
.
    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

Java

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

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify

    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

Para verificar que tu app implementó correctamente estos pasos, puedes seguir la guía de pruebas.

Controla las transacciones pendientes

Google Play admite transacciones pendientes o que requieran 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 iniciar una transacción eligiendo una tienda física en la que pagará más tarde con dinero en efectivo. El usuario recibe un código a través de una notificación y un 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 le notifica al usuario y a ti que se recibió el pago. Posteriormente, la app puede otorgar derechos al usuario.

Llama a enablePendingPurchases() como parte de la inicialización de BillingClient para habilitar las transacciones pendientes de tu app. Tu app debe habilitar y admitir transacciones pendientes para productos únicos. Antes de agregar asistencia, asegúrate de comprender el ciclo de vida de la compra para las transacciones pendientes.

Cuando la app reciba una compra nueva, ya sea a través del PurchasesUpdatedListener o como resultado de una llamada a queryPurchasesAsync, usa el método getPurchaseState() para determinar si el estado de compra es PURCHASED o PENDING. Debes otorgar derechos solo si el estado es PURCHASED.

Si la app se está ejecutando y tienes una conexión activa a la Biblioteca de Facturación Play 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 detectar y procesar compras. La app también debe llamar a queryPurchasesAsync() en el método onResume() para controlar las compras que pasaron al estado PURCHASED mientras no se estaba ejecutando.

Cuando la compra pasa de PENDING a PURCHASED, tu cliente de real_time_developer_notifications recibe una notificación de ONE_TIME_PRODUCT_PURCHASED o SUBSCRIPTION_PURCHASED. Si se cancela la compra, recibirás una notificación de ONE_TIME_PRODUCT_CANCELED o SUBSCRIPTION_PENDING_PURCHASE_CANCELED. Esto puede suceder si el cliente no completa el pago en el plazo requerido. Ten en cuenta que siempre puedes usar la API de Google Play Developer para verificar el estado actual de una compra.

Cómo administrar compras de varias cantidades

Google Play, compatible con las versiones 4.0 y posteriores de la Biblioteca de Facturación Google Play, permite que los clientes compren, en una transacción, más artículos de un mismo producto integrado en la aplicación si especifican una cantidad en el carrito de compras. Se espera que la app administre compras de varias cantidades y otorgue derechos en función de la cantidad de compra especificada.

Para admitir las compras de varias cantidades, la lógica de aprovisionamiento de la app debe verificar una cantidad de artículos. Puedes acceder a un campo quantity desde una de las siguientes APIs:

Después de agregar lógica para controlar las compras de varias cantidades, deberás habilitar la función de varias cantidades para el producto correspondiente en la página de administración de productos integrados en la aplicación en Google Play Console.

Cómo consultar la configuración de facturación del usuario

getBillingConfigAsync() proporciona el país que usa el usuario para Google Play.

Puedes consultar la configuración de facturación del usuario después de crear un BillingClient. En el siguiente fragmento de código, se describe cómo realizar una llamada a getBillingConfigAsync(). Para controlar la respuesta, implementa BillingConfigResponseListener. Este objeto de escucha recibe actualizaciones de todas las consultas de configuración de facturación que se inician desde tu app.

Si el BillingResult que se muestra no contiene errores, puedes verificar el campo countryCode en el objeto BillingConfig para obtener el país de Play del usuario.

Kotlin

// Use the default GetBillingConfigParams.
val getBillingConfigParams = GetBillingConfigParams.newBuilder().build()
billingClient.getBillingConfigAsync(getBillingConfigParams,
    object : BillingConfigResponseListener {
        override fun onBillingConfigResponse(
            billingResult: BillingResult,
            billingConfig: BillingConfig?
        ) {
            if (billingResult.responseCode == BillingResponseCode.OK
                && billingConfig != null) {
                val countryCode = billingConfig.countryCode
                ...
            } else {
                // TODO: Handle errors
            }
        }
    })

Java

// Use the default GetBillingConfigParams.
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build();
billingClient.getBillingConfigAsync(getBillingConfigParams,
    new BillingConfigResponseListener() {
      public void onBillingConfigResponse(
          BillingResult billingResult, BillingConfig billingConfig) {
        if (billingResult.getResponseCode() == BillingResponseCode.OK
            && billingConfig != null) {
            String countryCode = billingConfig.getCountryCode();
            ...
         } else {
            // TODO: Handle errors
        }
      }
    });

Recordatorios de abandono del carrito en la página principal de Google Play Juegos (habilitados de forma predeterminada)

En el caso de los desarrolladores de juegos que monetizan a través de IAP, una forma en que las unidades de mantenimiento de existencias (SKU) que están activas en Google Play Console se pueden vender fuera de tu app es la función Recordatorio de abandono de carrito, que les sugiere a los usuarios que completen las compras que abandonaron anteriormente mientras exploran Google Play Store. Estas compras se realizan fuera de tu app, desde la página principal de Google Play Juegos en Google Play Store.

Esta función está habilitada de forma predeterminada para ayudar a los usuarios a retomar desde donde quedaron y a los desarrolladores a maximizar las ventas. Sin embargo, puedes inhabilitar esta función en tu app. Para ello, envía el formulario de inhabilitación de la función Cart Abandonment Reminder. Para conocer las prácticas recomendadas sobre cómo administrar los SKU en Google Play Console, consulta Cómo crear un producto integrado en la aplicación.

En las siguientes imágenes, se muestra el recordatorio de abandono del carrito que aparece en Google Play Store:

La pantalla de Google Play Store muestra un mensaje de compra para una compra abandonada anteriormente
Figura 2: La pantalla de Google Play Store muestra un mensaje de compra para una compra abandonada anteriormente.

La pantalla de Google Play Store muestra un mensaje de compra para una compra abandonada anteriormente
Figura 3: La pantalla de Google Play Store muestra un mensaje de compra para una compra abandonada anteriormente.