Participe do evento ⁠#Android11: apresentação de lançamento da versão Beta no dia 3 de junho.

Usar a Google Play Billing Library

Este documento explica como adicionar o Google Play Faturamento ao seu app usando a biblioteca do Google Play. Especificamente, este documento aborda como adicionar a funcionalidade do Google Play Faturamento, comum a produtos de aquisição única e assinaturas. Para saber como adicionar funcionalidades específicas de produto ao seu app, consulte os documentos listados no fim desta página.

Antes de ler esta página, siga estas etapas:

  1. Leia a Visão geral do Google Play Faturamento para se familiarizar com conceitos e termos importantes.
  2. Configurar produtos no aplicativo usando o Google Play Console:
  3. Se você estiver integrado ao Google Play Faturamento usando AIDL, consulte o guia de migração da AIDL para a biblioteca do Google Play Faturamento e tenha uma visão geral de alto nível das etapas necessárias para migrar da AIDL para a biblioteca do Google Play Faturamento.

Etapas para adicionar o Google Play Faturamento a um app

Siga as etapas nas seções abaixo para adicionar o Google Play Faturamento ao seu app.

Atualizar as dependências do app

Adicione a seguinte linha à seção de dependências do arquivo build.gradle do app:

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

Se você estiver usando o Kotlin, o módulo KTX da Play Billing Library será compatível com extensões e corrotinas do Kotlin que possibilitam escrever Kotlin idiomático na sua solução do Play Faturamento. Para incluir essas extensões no seu projeto, adicione as seguintes dependências ao arquivo build.gradle do seu app:

dependencies {
        ...
        // be sure to also include the core dependency
        implementation 'com.android.billingclient:billing:2.1.0'
        implementation 'com.android.billingclient:billing-ktx:2.1.0'
    }
    

Consulte as Notas da versão da Google Play Billing Library para garantir que você está usando a versão atual dessa biblioteca.

Conectar ao Google Play

Antes de enviar solicitações ao Google Play Faturamento, você precisa estabelecer uma conexão com o Google Play da seguinte forma:

  1. Chame newBuilder() para criar uma instância de BillingClient. Você também precisa chamar setListener(), transmitindo uma referência a um PurchasesUpdatedListener para receber atualizações sobre compras iniciadas pelo seu app, bem como aquelas iniciadas pela Google Play Store.

  2. Estabeleça uma conexão com o Google Play. O processo de configuração é assíncrono, e é necessário implementar um BillingClientStateListener para receber um callback assim que a configuração do cliente for concluída e estiver pronta para fazer mais solicitações.

  3. Modifique o método de callback onBillingServiceDisconnected() e implemente sua política de nova tentativa para gerenciar as conexões perdidas com o Google Play, caso o cliente perca a conexão. Por exemplo, o BillingClient pode perder a conexão se o serviço da Google Play Store estiver sendo atualizado em segundo plano. O BillingClient precisa chamar o método startConnection() para reiniciar a conexão antes de fazer outras solicitações.

A amostra de código a seguir demonstra como iniciar uma conexão e verificar se ela está pronta para uso:

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 ==  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

    private BillingClient billingClient;
    ...
    billingClient = BillingClient.newBuilder(activity).setListener(this).build();
    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.
        }
    });
    

Consultar detalhes de produtos no aplicativo

Os IDs de produto exclusivos que você criou ao configurar os produtos no aplicativo são usados em consultas assíncronas do Google Play por detalhes do produto. Para consultar detalhes do produto no aplicativo no Google Play, chame querySkuDetailsAsync(). Ao chamar esse método, transmita uma instância de SkuDetailsParams que especifique uma lista de strings de ID do produto e um SkuType. O SkuType pode ser SkuType.INAPP para produtos de aquisição única ou SkuType.SUBS para assinaturas.

Para gerenciar o resultado da operação assíncrona, você também precisa especificar um listener que implemente a interface SkuDetailsResponseListener. Em seguida, você pode modificar onSkuDetailsResponse(), que notifica o listener no fim da consulta, conforme ilustrado pela amostra de código a seguir.

Kotlin

    fun querySkuDetails() {
        val skuList = ArrayList<String>()
        skuList.add("premium_upgrade")
        skuList.add("gas")
        val params = SkuDetailsParams.newBuilder()
        params.setSkusList(skuList).setType(SkuType.INAPP)
        val skuDetailsResult = withContext(Dispatchers.IO) {
            billingClient.querySkuDetails(params.build())
        }
        // 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.
            }
        });
    

Seu app precisa ter uma lista própria de IDs de produto, o que pode ser feito criando a lista com seu APK ou consultando-a no seu servidor de back-end seguro.

Chame getResponseCode() para recuperar o código de resposta. Se a solicitação for concluída, o código de resposta será BillingResponse.OK. Para ver uma lista de outros possíveis códigos de resposta do Google Play, consulte BillingClient.BillingResponse.

Se ocorrer um erro, você poderá usar getDebugMessage() para ver a mensagem de erro associada.

A Google Play Billing Library armazena os resultados de consulta em uma List de objetos SkuDetails. Depois disso, você pode chamar uma variedade de métodos em cada um dos objetos SkuDetails da lista para ver informações relevantes sobre um produto no aplicativo, como o preço ou a descrição. Para ver as informações de detalhes do produto disponíveis, consulte a lista de métodos na classe SkuDetails.

O exemplo a seguir mostra como recuperar os preços de produtos no aplicativo usando o objeto SkuDetails retornado pelo snippet 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;
           }
       }
    }
    

Acessar o preço de um produto é uma etapa importante antes de um usuário poder fazer uma compra, já que o preço é diferente para cada país de origem.

Ofertas consistentes

Quando você oferece um SKU com desconto, o Google Play também retorna o preço original do SKU para que você possa mostrar aos usuários que eles estão recebendo um desconto. Recomendamos que você use getPrice() para mostrar o preço com desconto para o usuário e getOriginalPrice() para mostrar o preço original do item.

SkuDetails contém dois métodos para recuperar o preço original do SKU:

Ativar a compra de um produto no aplicativo

Alguns smartphones Android podem ter uma versão do app Google Play Store que é mais antiga e não oferece compatibilidade com certos tipos de produto, por exemplo, assinaturas. Portanto, antes que seu app acesse o fluxo de faturamento, chame isFeatureSupported() para verificar se o dispositivo é compatível com os produtos que você quer vender. Para ver uma lista de tipos de produto, consulte BillingClient.FeatureType.

Para dar início a uma solicitação de compra no seu app, chame o método launchBillingFlow() na linha de execução de IU. Transmita uma referência a um objeto BillingFlowParams que contém os dados relevantes para concluir a compra, como o ID do produto (skuId) do item e o tipo de produto (SkuType.INAPP para um produto de aquisição única ou SkuType.SUBS para uma assinatura). Para receber uma instância de BillingFlowParams, use a classe 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);
    

Quando você chama o método launchBillingFlow(), o sistema exibe a tela de compra do Google Play. A Figura 3 mostra uma tela de compra para um produto de aquisição única:

Figura 3. Tela de compra do Google Play para um produto de aquisição única.

A Figura 4 mostra uma tela de compra para uma assinatura:

Figura 4. Tela de compra do Google Play para uma assinatura.

O método launchBillingFlow() retorna um dos vários códigos de resposta listados em BillingClient.BillingResponse. O Google Play chama o método onPurchasesUpdated() para entregar o resultado da operação de compra a um listener que implementa a interface PurchasesUpdatedListener. O listener é especificado usando o método setListener(), conforme demonstrado anteriormente na seção Conectar ao Google Play.

É necessário implementar o método onPurchasesUpdated() para gerenciar possíveis códigos de resposta. O snippet de código a seguir mostra como modificar o 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.
        }
    }
    

Compras concluídas geram uma tela de sucesso do Google Play semelhante à da Figura 5:

Figura 5. Tela de sucesso do Google Play.

As compras concluídas também geram um token de compra, que é um identificador exclusivo representando o usuário e o ID do produto comprado. Os apps podem armazenar o token de compra localmente ou, de preferência, passá-lo para seu servidor de back-end seguro, onde ele pode ser usado para verificar as compras e proteger contra fraudes. O token de compra é exclusivo para cada compra de produtos de aquisição única. No entanto, como as assinaturas são compradas uma vez e renovadas automaticamente em um período de faturamento regular, o token de compra de assinaturas permanece o mesmo para cada período de faturamento.

O usuário também recebe por e-mail um comprovante da transação, contendo o ID do pedido ou um ID exclusivo para a transação. Os usuários recebem um e-mail com um ID de pedido exclusivo para cada compra de produtos de aquisição única, assim como para a compra de assinatura inicial e as renovações automáticas subsequentes. É possível usar o ID do pedido para gerenciar reembolsos no Google Play Console. Para ver mais detalhes, consulte Ver e reembolsar pedidos e assinaturas do seu app.

Confirmar uma compra

Se você usa a Google Play Billing Library 2.0 ou uma versão mais recente, precisa confirmar todas as compras em até três dias. Se as compras não forem confirmadas corretamente, elas serão reembolsadas.

O Google Play é compatível com a compra de produtos dentro ou fora do seu app. Para que o Google Play garanta uma experiência de compras consistente, onde quer que o usuário compre seu produto, você precisa confirmar todas as compras recebidas pela Google Play Billing Library que tenham um estado SUCCESS assim que possível depois de conceder a titularidade ao usuário. Se você não confirmar uma compra em até três dias, o usuário receberá um reembolso automaticamente, e o Google Play revogará a compra. Para transações pendentes, o prazo de três dias não se aplica quando a compra está no estado PENDING. Em vez disso, ele começa quando a compra passa para o estado SUCCESS.

É possível confirmar uma compra usando um dos seguintes métodos:

  • Para produtos consumíveis, use consumeAsync(), encontrado na API do cliente.
  • Para produtos não consumíveis, use acknowledgePurchase(), encontrado na API do cliente.
  • Um novo método acknowledge() também está disponível na API do servidor.

Para assinaturas, você precisa confirmar todas as compras que tiverem um novo token de compra. Isso quer dizer que todas as compras iniciais, mudanças de plano e novas assinaturas precisam ser confirmadas, mas você não precisa confirmar as renovações subsequentes. Para determinar se uma compra precisa ser confirmada ou não, você pode verificar o campo de confirmação na compra.

O objeto Purchase inclui um método isAcknowledged() que indica se uma compra foi confirmada. Além disso, a API do servidor inclui valores booleanos de confirmação para Product.purchases.get() e Product.subscriptions.get(). Antes de confirmar uma compra, use esses métodos para determinar se ela já foi confirmada.

Este exemplo mostra como confirmar uma compra de assinatura:

Kotlin

    val client: BillingClient = ...
    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)
                val ackPurchaseResult = withContext(Dispatchers.IO) {
                   client.acknowledgePurchase(acknowledgePurchaseParams.build())
                }
            }
         }
    }
    

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

Testar a confirmação de compra com testadores de licença

Para compras feitas por testadores de licença, o período de confirmação é menor. Em vez de três dias, as compras são reembolsadas e revogadas se não forem confirmadas em cinco minutos.

Compatibilidade com transações pendentes

Ao implementar uma solução do Google Play Faturamento, você precisa oferecer compatibilidade com compras em que mais ações são necessárias antes de conceder a titularidade. Por exemplo, um usuário pode escolher comprar seu produto em uma loja física com dinheiro. Isso significa que a transação é concluída fora do seu app. Em casos como esse, você precisa conceder a titularidade somente após o usuário ter concluído a transação.

Para ativar compras pendentes, chame enablePendingPurchases() ao inicializar o app. Se você não chamar enablePendingPurchases(), não será possível instanciar a Google Play Billing Library.

Use o método Purchase.getPurchaseState() para determinar se o estado de compra é PURCHASED ou PENDING. Observe que você precisa conceder titularidade apenas quando o estado for PURCHASED. Para verificar as mudanças de status, faça o seguinte:

  1. Ao iniciar o app, chame BillingClient.queryPurchases() para recuperar a lista de produtos não consumidos associados ao usuário e chame getPurchaseState() em cada objeto Purchase retornado.
  2. Implemente o método onPurchasesUpdated() para responder a mudanças em objetos Purchase.

Veja um exemplo que demonstra como controlar transações pendentes:

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

Testar transações pendentes com testadores de licença

As transações pendentes podem ser testadas com testadores de licença. Além dos dois cartões de crédito de teste, os testadores de licença têm acesso a dois instrumentos de teste para formas de pagamento atrasadas, que são concluídas automaticamente ou canceladas depois de alguns minutos.

Ao testar seu aplicativo, verifique se ele não concede titularidade ou confirma a compra imediatamente depois de feita com qualquer um desses dois instrumentos. Ao fazer uma compra com o instrumento de teste de conclusão automática, verifique se seu aplicativo concede titularidade ou confirma a compra depois que ela é concluída.

Ao fazer uma compra com o instrumento de teste de cancelamento automático, verifique se seu aplicativo não concede titularidade, já que nenhuma compra foi concluída.

Anexar um payload do desenvolvedor

É possível anexar uma string arbitrária ou um payload do desenvolvedor às compras. No entanto, o payload do desenvolvedor só pode ser anexado quando a compra é confirmada ou consumida. Ele é diferente do payload do desenvolvedor em AIDL, em que o payload podia ser especificado no lançamento de um fluxo de compra.

Para produtos consumíveis, o consumeAsync() aceita um objeto ConsumeParams que inclui um campo de payload do desenvolvedor, conforme mostrado no exemplo a seguir.

Kotlin

    val client: BillingClient = ...
    fun consumePurchase() {
        val consumeParams =
            ConsumeParams.newBuilder()
                .setPurchaseToken(/* token */)
                .setDeveloperPayload(/* payload */)
                .build()
        val consumeResult = withContext(Dispatchers.IO) {
            client.consumePurchase(consumeParams)
        }
    }
    

Java

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

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

    client.consumeAsync(consumeParams, listener);
    

Para produtos não consumíveis, o acknowledgePurchase() aceita um objeto AcknowledgePurchaseParams que inclui um campo de payload do desenvolvedor, como mostrado no exemplo a seguir.

Kotlin

    val client: BillingClient = ...
    fun acknowledgePurchase() {
        val acknowledgePurchaseParams =
            AcknowledgePurchaseParams.newBuilder()
                .setPurchaseToken(/* token */)
                .setDeveloperPayload(/* payload */)
                .build()
        val ackPurchaseResult = withContext(Dispatchers.IO) {
            client.acknowledgePurchase(acknowledgePurchaseParams)
        }
    }
    

Java

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

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

    client.acknowledgePurchase(acknowledgePurchaseParams, listener);
    

Para acessar um payload do desenvolvedor, chame getDeveloperPayload() no objeto Purchase correspondente.

Você só pode consumir ou confirmar uma compra no estado de compra PURCHASED.

Verificar uma compra

Antes de dar ao usuário acesso ao que ele comprou, é necessário verificar se o estado de compra é PURCHASED, assim como outros detalhes da compra que seu app recebe em onPurchasesUpdated().

Verificar uma compra em um servidor

Ao implementar a lógica de verificação de compra em um servidor, você pode proteger seu app contra invasores que tentarem aplicar engenharia reversa no seu arquivo APK e desabilitar a lógica de verificação. Para verificar detalhes de compra em um servidor de back-end seguro, siga as etapas a seguir.

  1. No seu app, envie o token de compra e a credencial da conta do usuário para seu servidor de back-end seguro. O servidor de back-end seguro precisa associar a compra ao usuário depois que a verificação for bem-sucedida.

  2. Depois de receber o token do app:

    1. Use a parte Assinaturas e compras da API Google Play Developer para realizar uma solicitação GET e recuperar os detalhes da compra no Google Play (Purchases.products para uma compra de produto de aquisição única ou Purchases.subscriptions para assinaturas). A solicitação GET inclui o nome do pacote do app, o ID do produto e o token de compra.

    2. O Google Play retorna os detalhes da compra.

    3. O servidor de back-end seguro verifica se o ID do pedido tem um valor exclusivo que não representa uma compra anterior.

    4. O servidor de back-end seguro usa a credencial da conta do usuário recebida na etapa 1 para associar o token de compra ao usuário da instância do app em que a compra foi feita.

    5. (opcional) Se você estiver validando uma assinatura e ela estiver recebendo um upgrade, um downgrade ou se o usuário refez a assinatura antes do término do período de carência, verifique o campo linkedPurchaseToken. O campo linkedPurchaseToken em um recurso Purchases.subscriptions contém o token da compra anterior ou "original". Para saber mais sobre linkedPurchaseToken, consulte Purchases.subscriptions.

    6. O produto no aplicativo é disponibilizado para o usuário.

Verificar uma compra em um dispositivo

Se não for possível executar seu próprio servidor, ainda será possível validar detalhes de compra no seu app para Android.

Para ajudar a garantir a integridade das informações de transação enviadas ao seu app, o Google Play assina a string JSON, que contém os dados de resposta de uma compra. O Google Play usa a chave privada associada ao seu app no Play Console para criar essa assinatura. O Play Console gera um par de chaves RSA para cada app. Você recebe essa resposta JSON usando o método getOriginalJson() dentro da classe Purchase.

A chave pública RSA codificada com Base64 que é gerada pelo Google Play está no formato codificado binário X.509 subjectPublicKeyInfo DER SEQUENCE. Essa é a mesma chave pública usada na licença do Google Play.

Quando seu aplicativo receber essa resposta assinada, você poderá usar a parte da chave pública do seu par de chaves RSA para verificar a assinatura. Ao realizar a verificação de assinatura, você pode detectar respostas adulteradas ou com spoofing.

Você precisa ofuscar sua chave pública do Google Play e seu código do Google Play Faturamento para dificultar o uso de engenharia reversa em protocolos de segurança e outros componentes de aplicativo por parte de invasores. No mínimo, recomendamos que você ofusque o código do seu app usando o R8 ou ProGuard. Se você fizer isso, adicione a seguinte linha ao seu arquivo de configuração do ProGuard:

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

Depois de ofuscar sua chave pública do Google Play e seu código do Google Play Faturamento, seu app estará pronto para validar detalhes de compras. Quando seu app verifica uma assinatura, os dados JSON contidos nessa assinatura precisam estar assinados pela chave do app.

Manter as compras atualizadas

É possível perder o controle de quais compras um usuário fez. Aqui estão dois cenários em que seu app pode perder o controle das compras e em que a consulta de compras é importante.

Lidar com falhas no servidor

  1. Um usuário compra um produto de aquisição única, como combustível extra para um jogo de carros.
  2. O app envia o token de compra para o servidor de back-end seguro para a verificação.
  3. O servidor está temporariamente fora do ar.
  4. O app reconhece que o servidor está fora do ar e notifica o usuário que há um problema com a compra.
  5. O app para Android tenta enviar novamente o token de compra para o servidor de back-end seguro e conclui a compra assim que o servidor é restaurado.
  6. O app libera o conteúdo.

Lidar com vários dispositivos

  1. Um usuário compra uma assinatura no smartphone Android.
  2. O app envia o token de compra para o servidor de back-end seguro para a verificação.
  3. O servidor verifica o token de compra.
  4. O app libera o conteúdo.
  5. O usuário muda para um tablet Android para usar a assinatura.
  6. O app do novo dispositivo consulta uma lista atualizada de compras.
  7. O app reconhece a assinatura e concede acesso a ela no tablet.

Consultar compras em cache

Para recuperar informações sobre compras que um usuário faz pelo seu app, chame queryPurchases() com o tipo de compra (SkuType.INAPP ou SkuType.SUBS) no BillingClient, como mostrado no seguinte exemplo:

Kotlin

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

Java

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

O Google Play retorna as compras feitas pela conta de usuário conectada ao dispositivo. Se a solicitação for concluída, a Google Play Billing Library armazenará os resultados da consulta em uma List de objetos Purchase.

Para recuperar a lista, chame getPurchasesList() no PurchasesResult. Depois disso, você pode chamar vários métodos no objeto Purchase para ver informações relevantes sobre o item, como o estado ou a data da compra. Para ver os tipos de informação de detalhes do produto disponíveis, consulte a lista de métodos na classe Purchase.

É necessário chamar queryPurchases() pelo menos duas vezes no seu código:

  • Chame queryPurchases() sempre que seu app for iniciado para restaurar qualquer compra feita desde a última interrupção do app.
  • Chame queryPurchases() no seu método onResume(), porque um usuário pode fazer uma compra quando seu app estiver em segundo plano, como no resgate de um código promocional no app da Google Play Store.

Chamar queryPurchases() na inicialização e na retomada do app garante que ele encontre todas as compras e os resgates que o usuário pode ter feito enquanto o app não estava em execução. Além disso, se um usuário fizer uma compra com o app em execução e ela não for detectada por algum motivo, o app ainda encontrará essa compra na próxima vez que a atividade for retomada e chamar queryPurchases().

Consultar compras mais recentes

O método queryPurchases() usa um cache do app Google Play Store sem iniciar uma solicitação de rede. Se você precisar verificar a compra mais recente feita pelo usuário para cada ID de produto, poderá usar queryPurchaseHistoryAsync(), transmitindo o tipo de compra e um PurchaseHistoryResponseListener para gerenciar o resultado da consulta.

queryPurchaseHistoryAsync() retorna um objeto PurchaseHistory que contém informações sobre a compra mais recente feita pelo usuário para cada ID de produto, mesmo que essa compra tenha expirado, esteja cancelada ou tenha sido consumida. Use queryPurchases() sempre que possível, porque ele usa o cache local, em vez de queryPurchaseHistoryAsync(). Se estiver usando queryPurchaseHistoryAsync(), você também poderá combiná-lo com um botão Atualizar, permitindo que os usuários atualizem a lista de compras.

O código a seguir demonstra como modificar o método onPurchaseHistoryResponse().

Kotlin

    val billingClient: BillingClient = ...
    fun queryPurchaseHistory() {
        val purchaseHistoryResult = withContext(Dispatchers.IO) {
            billingClient.queryPurchaseHistory(skuType)
        }
        // 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.
                }
             }
        }
    });
    

A seguir

Depois de permitir que usuários comprem seus produtos, você precisará saber como abranger cenários específicos de produtos: