Lembrete: a partir de 2 de agosto de 2022, todos os novos apps vão precisar usar a versão 4 ou mais recente da Biblioteca Faturamento. A partir de 1º de novembro de 2022, todas as atualizações de apps já existentes vão precisar usar a versão 4 ou mais recente da Biblioteca Faturamento. Saiba mais.

Guia de migração da versão 4 para a versão 5 da Biblioteca Google Play Faturamento

Este artigo descreve como migrar da versão 4 para a versão 5 da Biblioteca Google Play Faturamento e como usar os novos recursos de assinatura.

Visão geral

A Biblioteca Google Play Faturamento 5 introduz planos básicos e ofertas de assinaturas. Esses recursos aumentam as possibilidades de venda de assinaturas e reduzem a complexidade de integração em comparação a versões anteriores.

Com o Play Console ou a API Play Developer, é possível configurar uma única assinatura com vários planos básicos, cada um com várias ofertas. As ofertas de assinatura têm modelos de preços e opções de qualificação flexíveis. Você pode criar ofertas no ciclo de vida da assinatura usando vários planos pré-pagos e de renovação automática. Para ver mais informações, consulte o guia de integração.

Etapas da migração

Atualizar a Biblioteca Play Faturamento

No arquivo build.gradle do app, substitua a dependência da Biblioteca Play Faturamento existente pela versão atualizada.

dependencies {
    def billingVersion = "5.0.0"

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

O projeto vai ser criado imediatamente, mesmo que você não tenha modificado nenhuma chamada para métodos, porque a Biblioteca Play Faturamento 5 oferece compatibilidade com versões anteriores. No entanto, é importante notar que o conceito de SKU foi descontinuado.

Como inicializar o cliente de faturamento e estabelecer uma conexão com o Google Play

As primeiras etapas necessárias para lançar compras em um app Android continuam as mesmas:

Como mostrar os produtos disponíveis para compra

Para acessar todas as ofertas disponíveis para compra para os usuários, faça o seguinte:

  • Substitua SkuDetailsParams por QueryProductDetailsParams.
  • Troque a chamada para BillingClient.querySkuDetailsAsync() por BillingClient.queryProductDetailsAsync().

Agora, os resultados da consulta serão ProductDetails, em vez de SkuDetails. Cada item ProductDetails contém as informações sobre o produto, como ID, título, tipo, entre outros. Para produtos por assinatura, ProductDetails contém um List<ProductDetails.SubscriptionOfferDetails>, que é a lista de detalhes da oferta de assinatura. Para produtos de compra única, ProductDetails contém um ProductDetails.OneTimePurchaseOfferDetails. Essas funções podem ser usadas para decidir quais ofertas vão aparecer para os usuários.

O exemplo a seguir mostra como o app pode ficar antes e depois dessas mudanças.

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

Depois

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

O callback para queryProductDetailsAsync retorna uma List<ProductDetails>. Cada item ProductDetails contém as informações sobre o produto, como ID, título, tipo, entre outros. A principal diferença é que os produtos por assinatura agora também têm uma List<ProductDetails.SubscriptionOfferDetails>, que inclui todas as ofertas disponíveis para o usuário.

Como as versões anteriores da Biblioteca Play Faturamento não oferecem suporte aos novos objetos, como assinaturas, planos básicos, ofertas, entre outros, o novo sistema converte cada SKU de assinatura em uma única oferta ou plano básico compatível com versões anteriores. Os produtos de compra única disponíveis também são transferidos para um objeto ProductDetails. Os detalhes da oferta de um produto de compra única podem ser acessados com o método getOneTimePurchaseOfferDetails().

Como iniciar o fluxo de compra da oferta

O processo para iniciar um fluxo de compra de uma oferta é muito parecido com o utilizado para iniciar um fluxo de um SKU. Para iniciar uma solicitação de compra na versão 5, faça o seguinte:

  • Em vez de usar SkuDetails para BillingFlowParams, use ProductDetailsParams.
  • Use o objeto SubscriptionOfferDetails para acessar os detalhes da(s) oferta(s).

Para comprar um produto com a oferta selecionada pelo usuário, acesse o offerToken dela e transmita-o para o objeto ProductDetailsParams.

Depois de criar um objeto BillingFlowParams, a inicialização do fluxo de faturamento com BillingClient continua a mesma.

O exemplo a seguir mostra como o app poderá ficar antes e depois dessas mudanças.

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)

Depois

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

Como processar compras

Na Biblioteca Google Play Faturamento 5, o processamento de compras continua semelhante às versões anteriores.

Para extrair todas as compras ativas de um usuário e consultar novas compras, faça o seguinte:

  • Em vez de transmitir um valor BillingClient.SkuType para queryPurchasesAsync(), transmita um objeto QueryPurchasesParams contendo um valor BillingClient.ProductType.

O exemplo a seguir mostra como o app pode ficar antes e depois dessas mudanças.

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

Depois

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

As etapas para gerenciar compras fora do app e transações pendentes não mudaram.

Como gerenciar o status de uma assinatura

Caso haja um componente de gerenciamento de status de assinaturas no back-end que verifica o status e gerencia as compras de assinaturas, será necessário usar a API Subscription Purchases. Para ver mais informações sobre o que mudou em relação às versões anteriores, consulte o guia de novos recursos de assinatura de maio de 2022.