Recordatorio: A partir del 2 de agosto de 2022, todas las apps nuevas deben usar la Biblioteca de Facturación 4 o versiones posteriores. A partir del 1 de noviembre de 2022, todas las actualizaciones de apps existentes deberán usar la versión 4 o posterior de la Biblioteca de Facturación. Más información.

Guía de migración de la Biblioteca de Facturación Google Play 4 a 5

En este tema, se describe la migración de la Biblioteca de Facturación Google Play 4 a la Biblioteca de Facturación Google Play 5 y el uso de las nuevas capacidades de suscripción.

Resumen

La Biblioteca de Facturación Google Play 5 introdujo planes básicos y ofertas de suscripción. Estas funciones amplían las formas en las que puedes vender suscripciones y reducen la complejidad de integración en comparación con las versiones anteriores.

Con Play Developer Console o la API de Play Developer puedes configurar una sola suscripción con varios planes básicos, cada uno con varias ofertas. Las ofertas de suscripción tienen modelos de precios y opciones de elegibilidad flexibles. Puedes crear ofertas durante todo el ciclo de vida de la suscripción con una variedad de planes prepagados y de renovación automática. Para obtener más información, consulta la guía de integración.

Pasos de la migración

Actualiza la Biblioteca de Facturación Google Play

Reemplaza la dependencia existente de la Biblioteca de Facturación Play por la versión actualizada en el archivo build.gradle de la app.

dependencies {
    def billingVersion = "5.0.0"

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

Tu proyecto debería compilarse de inmediato, incluso si no modificaste ninguna llamada a los métodos, ya que integramos la retrocompatibilidad con la Biblioteca de Facturación Play 5. Sin embargo, el concepto de SKU se considera obsoleto.

Cómo inicializar el cliente de facturación y cómo establecer una conexión con Google Play

Los primeros pasos para iniciar compras desde una app para Android son los mismos:

Cómo mostrar productos disponibles para comprar

Para obtener todas las ofertas que puede comprar un usuario, haz lo siguiente:

  • Reemplaza SkuDetailsParams con QueryProductDetailsParams.
  • Cambia la llamada BillingClient.querySkuDetailsAsync() para usar BillingClient.queryProductDetailsAsync().

Ten en cuenta que los resultados de la búsqueda ahora son ProductDetails en lugar de SkuDetails. Cada elemento ProductDetails contiene la información sobre el producto (ID, título, tipo, etc.). En el caso de los productos de suscripción, ProductDetails incluye un List<ProductDetails.SubscriptionOfferDetails>, que es la lista de los detalles de la oferta de suscripción. En el caso de los productos de compra única, ProductDetails contiene un ProductDetails.OneTimePurchaseOfferDetails. Se pueden usar para decidir qué ofertas mostrar a los usuarios.

En el siguiente ejemplo, se muestra cómo podría verse tu app antes y después de realizar estos cambios:

Antes

Kotlin

val skuList = ArrayList<String>()

skuList.add("up_basic_sub")

val params = SkuDetailsParams.newBuilder()

params.setSkusList(skuList).setType(BillingClient.SkuType.SUBS)

billingClient.querySkuDetailsAsync(params.build()) {
    billingResult,
    skuDetailsList ->
    // Process the result
}

Java

List<String> skuList = new ArrayList<>();

skuList.add("up_basic_sub");

SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();

params.setSkusList(skuList).setType(SkuType.SUBS);

billingClient.querySkuDetailsAsync(params.build(),
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(BillingResult billingResult,
                List<SkuDetails> skuDetailsList) {
            // Process the result.
        }
    }
);

Después

Kotlin

val productList =
    listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("up_basic_sub")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )

val params = QueryProductDetailsParams.newBuilder().setProductList(productList)

billingClient.queryProductDetailsAsync(params.build()) {
    billingResult,
    productDetailsList ->
    // Process the result
}

Java

ImmutableList<Product> productList = ImmutableList.of(Product.newBuilder()
                                            .setProductId("up_basic_sub")
                                            .setProductType(ProductType.SUBS)
                                            .build());

QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
    .setProductList(productList)
    .build();

billingClient.queryProductDetailsAsync(
        params,
        new ProductDetailsResponseListener() {
                public void onProductDetailsResponse(BillingResult billingResult, List<ProductDetails> productDetailsList) {
                    // Process the result
                }
        }
);

La devolución de llamada de queryProductDetailsAsync muestra un List<ProductDetails>. Cada elemento ProductDetails contiene la información sobre el producto (ID, título, tipo, etc.). La principal diferencia es que los productos de suscripción ahora contienen un List<ProductDetails.SubscriptionOfferDetails> con todas las ofertas disponibles para el usuario.

Debido a que las versiones anteriores de la Biblioteca de Facturación Play no son compatibles con los nuevos objetos (suscripciones, planes básicos, ofertas, etc.), el nuevo sistema convierte cada SKU de suscripción en una sola oferta y plan básico retrocompatible. Los productos de compra única disponibles también se transfieren a un objeto ProductDetails. Se puede acceder a los detalles de la oferta de un producto de compra única con el método getOneTimePurchaseOfferDetails().

Cómo iniciar el flujo de compra de la oferta

Iniciar un flujo de compra de una oferta es muy similar a iniciar un flujo para un SKU. Para iniciar una solicitud de compra con la versión 5, haz lo siguiente:

  • En lugar de usar SkuDetails para BillingFlowParams, usa ProductDetailsParams.
  • Los detalles de la oferta se pueden obtener con el objeto SubscriptionOfferDetails.

Para comprar un producto con la oferta seleccionada del usuario, obtén el offerToken de la oferta seleccionada y pásalo al objeto ProductDetailsParams.

Una vez que hayas creado un objeto BillingFlowParams, el proceso para iniciar el flujo de facturación con el BillingClient es el mismo.

En los siguientes ejemplos, se muestra cómo se vería tu app antes y después de realizar estos cambios:

Antes

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;
// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
val billingFlowParams = BillingFlowParams.newBuilder()
                            .setSkuDetails(skuDetails)
                            .build()

val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

Java

// An activity reference from which the billing flow will be launched.
Activity activity = ...;
// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)
        .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

Después

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;
// Retrieve a value for "productDetails" by calling queryProductDetailsAsync()
// Get the offerToken of the selected offer
val offerToken = productDetails.subscriptionOfferDetails?.get(selectedOfferIndex)?.offerToken

val productDetailsParamsList =
    listOf(
        BillingFlowParams.ProductDetailsParams.newBuilder()
            .setProductDetails(productDetails)
            .setOfferToken(offerToken)
            .build()
    )
val billingFlowParams =
    BillingFlowParams.newBuilder()
        .setProductDetailsParamsList(productDetailsParamsList)
        .build()

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

Java

// Retrieve a value for "productDetails" by calling queryProductDetailsAsync()
// Get the offerToken of the selected offer
String offerToken = productDetails
                     .getSubscriptionOfferDetails()
                     .get(selectedOfferIndex)
                     .getOfferToken();
// Set the parameters for the offer that will be presented
// in the billing flow creating separate productDetailsParamsList variable
ImmutableList<ProductDetailsParams> productDetailsParamsList =
        ImmutableList.of(
                 ProductDetailsParams.newBuilder()
                     .setProductDetails(productDetails)
                     .setOfferToken(offerToken)
                     .build()
        );

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

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

Cómo procesar las compras

El procesamiento de compras con la Biblioteca de Facturación Google Play 5 sigue siendo similar a las versiones anteriores.

Para extraer todas las compras activas que pertenecen al usuario y buscar compras nuevas, haz lo siguiente:

  • En lugar de pasar un valor de BillingClient.SkuType a queryPurchasesAsync(), pasa un objeto QueryPurchasesParams que contenga un valor BillingClient.ProductType.

En los siguientes ejemplos, se muestra cómo se vería tu app antes y después de realizar estos cambios:

Antes

Kotlin

billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS) {
    billingResult,
    purchaseList -> {
        // Process the result
    }
}

Java


billingClient.queryPurchasesAsync(
    BillingClient.SkuType.SUBS,
    new PurchasesResponseListener() {
        public void onQueryPurchasesResponse(
                BillingResult billingResult,
                List&lt;Purchase> purchases) {
            // process the result
        }
    }
);

Después

Kotlin

billingClient.queryPurchasesAsync(
    QueryPurchasesParams.newBuilder()
        .setProductType(BillingClient.ProductType.SUBS)
        .build()
) { billingResult, purchaseList ->
    // Process the result
}

Java

billingClient.queryPurchasesAsync(
    QueryPurchasesParams.newBuilder().setProductType(ProductType.SUBS).build(),
    new PurchasesResponseListener() {
        public void onQueryPurchasesResponse(
                BillingResult billingResult,
                List<Purchase> purchases) {
            // Process the result
        }
    }
);

No cambiaron los pasos para administrar las compras fuera de la app ni las transacciones pendientes.

Cómo administrar el estado de la suscripción

Si tienes un componente de administración de estado de suscripciones en tu backend que verifica el estado y administra las compras de suscripción, deberás usar la API de Subscription Purchases. Para obtener detalles sobre los cambios en versiones anteriores, consulta la guía sobre las nuevas funciones de suscripción de mayo de 2022.