Usar a Google Play Billing Library

Este documento explica como adicionar o Google Play Faturamento ao seu app usando a Biblioteca do Google Play. Mais especificamente, ele aborda como adicionar a funcionalidade do Google Play Faturamento comum a todos os tipos de produto no aplicativo: produtos concedidos como prêmio, de aquisição única e assinaturas. Para saber como adicionar funcionalidades específicas de produto ao seu app, leia 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. Configure produtos no aplicativo usando o Google Play Console:

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 seu app:

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

Para garantir que você esteja usando a versão atual da Google Play Billing Library, consulte as Notas da versão da Google Play Billing Library.

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 por 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 controlar conexões perdidas com o Google Play caso o cliente perca a conexão. Por exemplo, o BillingClient pode perder a conexão quando o serviço da Google Play Store está 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 == BillingResponse.OK) {
           // The BillingClient is ready. You can query purchases here.
       }
   }
   override fun onBillingServiceDisconnected() {
       // Try to restart the connection on the next request to
       // Google Play by calling the startConnection() method.
   }
})

Java

private BillingClient billingClient;
...
billingClient = BillingClient.newBuilder(activity).setListener(this).build();
billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() == BillingResponse.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});

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 únicos ou produtos concedidos como prêmio, ou SkuType.SUBS, para assinaturas.

Para controlar 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 na amostra de código a seguir.

Kotlin

val skuList = ArrayList<String>()
skuList.add("premium_upgrade")
skuList.add("gas")
val params = SkuDetailsParams.newBuilder()
params.setSkusList(skuList).setType(SkuType.INAPP)
billingClient.querySkuDetailsAsync(params.build(), { billingResult, skuDetailsList ->
    // Process the result.
})

Java

List<String> skuList = new ArrayList<> ();
skuList.add("premium_upgrade");
skuList.add("gas");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(BillingResult billingResult,
                List<SkuDetails> skuDetailsList) {
            // Process the result.
        }
    });

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

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

Se ocorrer um erro, você poderá usar getDebugMessage() para visualizar 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, por exemplo, preço ou descrição. Para ver as informações de detalhes de 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 do SKU original:

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 do tipo de produto (SkuType.INAPP, para um produto único ou produto concedido como prêmio, 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 processar possíveis códigos de resposta. O snippet de código a seguir mostra como substituir 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 e produtos concedidos como prêmio. 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 recibo da transação, contendo o código do pedido ou um código exclusivo para a transação. Os usuários recebem um e-mail com um código 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 código do pedido para gerenciar reembolsos no Google Play Console. Para ver mais detalhes, consulte Ver e reembolsar pedidos e assinaturas do seu app (link em inglês).

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, independentemente de onde o usuário compra 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 dentro de três dias, o usuário receberá um reembolso automaticamente, e o Google Play revogará a compra. Para transações pendentes, a janela de três dias não se aplica quando a compra está no estado PENDING. Em vez disso, ela 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 são consumíveis, use acknowledgePurchase(), localizado 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 = ...
val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ...

fun handlePurchase() {
    if (purchase.purchaseState === PurchaseState.PURCHASED) {
        // Grant entitlement to the user.
        ...

        // Acknowledge the purchase if it hasn't already been acknowledged.
        if (!purchase.isAcknowledged) {
            val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.purchaseToken)
                    .build()
            client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener)
        }
     }
}

Java

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

void handlePurchase(Purchase purchase) {
    if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
        // Grant entitlement to the user.
        ...

        // Acknowledge the purchase if it hasn't already been acknowledged.
        if (!purchase.isAcknowledged()) {
            AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
            client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
        }
    }
}

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

Para compras feitas por testadores de licença, a janela 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 foi concluída fora do seu app. Nessa situação, você deve conceder o direito 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 autorização 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 = ...
val listener: ConsumeResponseListener = ...

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

client.consumeAsync(consumeParams, listener)

Java

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

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

client.consumeAsync(consumeParams, listener);

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 = ...
val listener: AcknowledgePurchaseResponseListener = ...

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

client.acknowledgePurchase(acknowledgePurchaseParams, listener)

Java

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

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

client.acknowledgePurchase(acknowledgePurchaseParams, listener);

Para 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 fornecer ao usuário acesso ao que ele comprou, é necessário verificar se o estado de compra é PURCHASED e 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 produtos concedidos como prêmio, 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 código 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 ainda se o usuário assinou de novo 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 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 aplicativo 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 do app por parte de invasores. No mínimo, recomendamos que você ofusque o código do seu aplicativo usando 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, a chave do app precisa ter assinado os dados JSON contidos nessa assinatura.

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 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 a partir do seu app, chame queryPurchases() com o tipo de compra (SkuType.INAPP ou SkuType.SUBS) em BillingClient, como mostrado em o 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 bem-sucedida, a Google Play Billing Library armazenará os resultados da consulta em objetos List de 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ções 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 precisar verificar a compra mais recente feita pelo usuário para cada ID de produto, você poderá usar queryPurchaseHistoryAsync(), passando o tipo de compra e um PurchaseHistoryResponseListener para lidar com 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 do produto, mesmo que essa compra tenha expirado, sido cancelada ou consumida. Use queryPurchases() sempre que possível, pois ele usa o cache local, em vez de queryPurchaseHistoryAsync(). Se estiver usando queryPurchaseHistoryAsync(), você também poderá combiná-lo com um Atualizar, permitindo que os usuários atualizem a lista de compras.

O código a seguir demonstra como é possível substituir o método onPurchaseHistoryResponse().

Kotlin

billingClient.queryPurchaseHistoryAsync(SkuType.INAPP, { billingResult, purchasesList ->
   if (billingResult.responseCode == BillingResponse.OK && purchasesList != null) {
       for (purchase in purchasesList) {
           // Process the result.
       }
   }
})

Java

billingClient.queryPurchaseHistoryAsync(SkuType.INAPP,
                                         new PurchaseHistoryResponseListener() {
    @Override
    public void onPurchaseHistoryResponse(BillingResult billingResult,
                                          List<Purchase> purchasesList) {
        if (billingResult.getResponseCode() == BillingResponse.OK
                && purchasesList != null) {
            for (Purchase purchase : purchasesList) {
                // Process the result.
            }
         }
    }
});

Próximas etapas

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