Lembrete: a partir de 2 de agosto de 2021, todos os novos apps precisarão usar a versão 3 ou mais recente da Biblioteca Play Faturamento. A partir do dia 1º de novembro de 2021, todas as atualizações de apps existentes precisarão usar a versão 3 ou mais recente da Biblioteca Play Faturamento. Saiba mais.

Integrar a biblioteca do Google Play Faturamento ao seu app

Este tópico descreve como integrar a biblioteca do Google Play Faturamento ao seu app para começar a vender produtos. Antes de ler este tópico, siga as etapas em Como se preparar para definir a configuração do Google Play.

Este tópico inclui exemplos de código baseados nos apps de exemplo oficiais no GitHub. Consulte recursos adicionais para ver uma lista completa de apps de exemplo e outros recursos que você pode usar durante a integração.

O ciclo de uma compra

Veja um fluxo de compra típico para uma compra única ou assinatura.

  • Mostre ao usuário o que ele pode comprar.
  • Inicie o fluxo de compra para que o usuário a aceite.
  • Verifique a compra no seu servidor.
  • Forneça conteúdo ao usuário e confirme a entrega do conteúdo. Opcionalmente, marque o item como consumido para que o usuário possa comprá-lo novamente.

As assinaturas são renovadas automaticamente até que sejam canceladas. Uma assinatura pode passar pelos seguintes estados:

  • Ativa: o usuário está em situação regular e tem acesso à assinatura.
  • Cancelada: o usuário cancelou, mas ainda tem acesso até o vencimento.
  • Em período de carência: o usuário teve um problema com o pagamento, mas ainda tem acesso enquanto o Google tenta executar a forma de pagamento novamente.
  • Suspensa: o usuário teve um problema com o pagamento e não tem mais acesso enquanto o Google tenta executar a forma de pagamento novamente.
  • Pausada: o usuário pausou e não tem acesso até retomar.
  • Vencida: o usuário cancelou e perdeu o acesso à assinatura. O usuário é considerado desligado na data do vencimento.

Tokens de compra e códigos de pedido

O Google Play monitora produtos e transações usando tokens de compra e códigos de pedido.

  • Um token de compra é uma string que representa a titularidade de um comprador quanto a um produto no Google Play. Ele indica que um usuário do Google tem a titularidade de um produto específico, que é representado por um SKU. É possível usar o token de compra com a API Google Play Developer.
  • Um código do pedido é uma string que representa uma transação financeira no Google Play. Essa string é incluída em um recibo enviado por e-mail ao comprador. É possível usar o código do pedido para gerenciar reembolsos usados em vendas e relatórios de pagamento.

Os códigos de pedido são criados sempre que ocorre uma transação financeira. Os tokens de compra são gerados somente quando um usuário conclui um fluxo de compra.

  • Para produtos de aquisição única, cada compra cria um novo token. A maioria das compras também gera um novo código do pedido. A exceção é quando o usuário não é cobrado, conforme descrito em Códigos promocionais.
  • Para assinaturas, uma compra inicial cria um token de compra e um código do pedido. Para cada período de faturamento contínuo, o token de compra permanece o mesmo, e um novo código do pedido é emitido. Upgrades, downgrades, substituições e novas inscrições criam novos tokens de compra e códigos de pedidos.

Para assinaturas, observe o seguinte:

  • Upgrades, downgrades e outros fluxos de compra de assinatura geram tokens de compra que precisam substituir um token anterior. É preciso invalidar os tokens de compra que aparecem no campo linkedPurchaseToken da API Google Play Developer. Para mais informações, consulte Como implementar o linkedPurchaseToken corretamente para evitar assinaturas duplicadas.
  • Os números de pedidos para renovações de assinatura contêm um número inteiro adicional que representa uma instância de renovação específica. Por exemplo, um código do pedido de assinatura inicial pode ser GPA.1234-5678-9012-34567, com códigos de pedido subsequentes sendo GPA.1234-5678-9012-34567..0 (primeira renovação), GPA.1234-5678-9012-34567..1 (segunda renovação) e assim por diante.

Tratamento de erros

A biblioteca do Google Play Faturamento retorna erros no formato de BillingResult. Um BillingResult contém um BillingResponseCode, que categoriza possíveis erros relacionados ao faturamento que seu app pode encontrar. Por exemplo, se você receber um código de erro SERVICE_DISCONNECTED, seu app precisará reinicializar a conexão com o Google Play. Além disso, um BillingResult contém uma mensagem de depuração, que é útil durante o desenvolvimento para diagnosticar erros.

Conectar ao Google Play

A primeira etapa para fazer integração do sistema de faturamento do Google Play é adicionar a biblioteca ao seu app e inicializar uma conexão.

Adicionar a dependência da biblioteca do Google Play Faturamento

Adicione a dependência da biblioteca do Google Play Faturamento ao arquivo build.gradle do seu app da seguinte forma:

dependencies {
    def billing_version = "3.0.0"

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

Se você usa o Kotlin, o módulo KTX da biblioteca do Google Play Faturamento tem compatibilidade com extensões e corrotinas de Kotlin que permitem escrever Kotlin idiomático ao usar a biblioteca do Google Play Faturamento. Para incluir essas extensões no projeto, adicione a seguinte dependência ao arquivo build.gradle do app, conforme mostrado:

dependencies {
    def billing_version = "3.0.0"

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

Inicializar um BillingClient

Depois de adicionar uma dependência à biblioteca do Google Play Faturamento, você precisa inicializar uma instância de BillingClient, que é a interface principal de comunicação entre a biblioteca do Google Play Faturamento e o restante do app. O BillingClient oferece métodos de conveniência, síncronos e assíncronos, para muitas operações de faturamento comuns.

Para criar um BillingClient, use newBuilder(). Para receber atualizações sobre compras, chame também setListener(), passando uma referência para um PurchasesUpdatedListener. Esse listener recebe atualizações para todas as compras no seu aplicativo.

Kotlin

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

private var billingClient = BillingClient.newBuilder(activity)
   .setListener(purchasesUpdatedListener)
   .enablePendingPurchases()
   .build()

Java

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

private BillingClient billingClient = BillingClient.newBuilder(activity)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .build();

Estabelecer uma conexão com o Google Play

Depois de criar um BillingClient, você precisa estabelecer uma conexão com o Google Play.

Para se conectar ao Google Play, chame startConnection(). O processo de conexã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.

Também é necessário implementar a lógica de nova tentativa para gerenciar as conexões perdidas com o Google Play. Para implementar essa lógica, modifique o método de callback onBillingServiceDisconnected() e verifique se o BillingClient chama o método startConnection() para se reconectar ao Google Play antes de fazer outras solicitações.

O exemplo a seguir demonstra como iniciar uma conexão e testar se ela está pronta para uso:

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

Mostrar produtos disponíveis para compra

Depois de estabelecer uma conexão com o Google Play, estará tudo pronto para você consultar seus produtos disponíveis e exibi-los aos usuários. Para consultar detalhes do produto no aplicativo no Google Play, chame querySkuDetailsAsync(). Consultar detalhes do SKU é uma etapa importante antes de exibir seus produtos para os usuários, já que retorna informações localizadas do produto. Para assinaturas, verifique se a exibição do produto segue todas as políticas do Google Play.

Ao chamar querySkuDetailsAsync(), transmita uma instância de SkuDetailsParams que especifique uma lista de strings de ID do produto criadas no Google Play Console 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 quando a consulta é concluída, conforme mostrado no seguinte exemplo:

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

A biblioteca do Google Play Faturamento 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.

Antes de oferecer um item para venda, verifique se o usuário ainda não tem o item. Se o usuário tiver um produto de consumo que ainda está na biblioteca de itens, ele precisará consumir o item antes de comprá-lo novamente.

Antes de oferecer uma assinatura, verifique se o usuário ainda não é assinante.

Iniciar o fluxo de compra

Para iniciar uma solicitação de compra no seu app, chame o método launchBillingFlow() na linha de execução principal do app. Esse método usa uma referência a um objeto BillingFlowParams que contém o objeto SkuDetails relevante recebido ao chamar querySkuDetailsAsync(). Para criar um objeto BillingFlowParams, use a classe BillingFlowParams.Builder.

Kotlin

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

// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
val flowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)
        .build()
val responseCode = billingClient.launchBillingFlow(activity, flowParams).responseCode

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();
int responseCode = billingClient.launchBillingFlow(activity, billingFlowParams).getResponseCode();

// Handle the result.

O método launchBillingFlow() retorna um dos vários códigos de resposta listados em BillingClient.BillingResponseCode. Verifique esse resultado para garantir que não houve erros ao iniciar o fluxo de compra. O BillingResponseCode OK indica um lançamento bem-sucedido.

Em uma chamada bem-sucedida para launchBillingFlow(), o sistema exibe a tela de compra do Google Play. A Figura 1 mostra uma tela de compra para um produto de aquisição única:

A tela de compra do Google Play mostra um produto de aquisição única
            disponível para compra
Figura 1. A tela de compra do Google Play mostra um produto de aquisição única disponível para compra.

O Google Play chama onPurchasesUpdated() para entregar o resultado da operação de compra a um listener que implementa a interface PurchasesUpdatedListener. O listener é especificado com o método setListener() ao inicializar o cliente.

Implemente onPurchasesUpdated() para gerenciar possíveis códigos de resposta. O exemplo a seguir mostra como modificar onPurchasesUpdated():

Kotlin

override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
   if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) {
       for (purchase in purchases) {
           handlePurchase(purchase)
       }
   } else if (billingResult.responseCode == BillingResponseCode.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() == BillingResponseCode.OK
        && purchases != null) {
        for (Purchase purchase : purchases) {
            handlePurchase(purchase);
        }
    } else if (billingResult.getResponseCode() == BillingResponseCode.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 conclusão de compra do Google Play semelhante à Figura 2.

Tela de conclusão de compra do Google Play
Figura 2. Tela de conclusão de compra do Google Play.

Uma compra bem-sucedida também gera um token de compra, que é um identificador exclusivo que representa o usuário e o ID do produto no aplicativo comprado. Seus apps podem armazenar o token de compra localmente, embora seja recomendável transmiti-lo para o servidor de back-end seguro, onde você pode verificar a compra e proteger contra fraudes. Esse processo é descrito mais detalhadamente na seção a seguir.

O usuário também recebe por e-mail um comprovante da transação, contendo o código do pedido ou um ID exclusivo para a transação. Os usuários recebem um e-mail com um código do pedido exclusivo para cada compra de produto 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.

Como processar compras

Depois que um usuário conclui uma compra, seu app precisa processá-la. Na maioria dos casos, o app é notificado sobre as compras por meio do PurchasesUpdatedListener. No entanto, há casos em que o app é informado para chamar BillingClient.queryPurchases(), conforme descrito em Como buscar compras.

Seu app precisa processar uma compra da seguinte maneira:

  1. Verifique a compra.
  2. Forneça conteúdo ao usuário e confirme a entrega do conteúdo. Opcionalmente, marque o item como consumido para que o usuário possa comprá-lo novamente.

Para verificar uma compra, primeiro confira se o estado é PURCHASED. Se a compra for PENDING, processe-a conforme descrito em Como processar transações pendentes. Para compras recebidas de onPurchaseUpdated() ou queryPurchases, verifique a compra para garantir a autenticidade antes que seu app conceda a titularidade. Para saber como verificar corretamente uma compra, consulte Verificar compras antes de conceder titularidade.

Depois da verificação da compra, seu app estará pronto para conceder a titularidade ao usuário. Depois de conceder a titularidade, o app precisa confirmar a compra. Essa confirmação informa ao Google Play que você concedeu titularidade na compra.

O processo para conceder a titularidade e confirmar a compra depende do tipo de compra, ou seja, se é de um produto de consumo ou não ou de uma assinatura.

Para produtos de consumo, o método consumeAsync() atende ao requisito de confirmação e indica que o app concedeu a titularidade ao usuário. Esse método também permite que o app disponibilize o produto de aquisição única novamente para compra.

Para indicar que um produto de aquisição única foi consumido, chame consumeAsync() e inclua o token de compra que o Google Play disponibilizará para a recompra. Você também precisa transmitir um objeto que implemente a interface ConsumeResponseListener. Esse objeto cuida do resultado da operação de consumo. É possível modificar o método onConsumeResponse(), que a biblioteca do Google Play Faturamento chama quando a operação é concluída.

O exemplo a seguir ilustra o consumo de um produto usando o token de compra associado:

Kotlin

fun handlePurchase(purchase: Purchase) {
    // Purchase retrieved from BillingClient#queryPurchases or your PurchasesUpdatedListener.
    val purchase : Purchase = ...;

    // Verify the purchase.
    // Ensure entitlement was not already granted for this purchaseToken.
    // Grant entitlement to the user.

    val consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build()

    billingClient.consumeAsync(consumeParams, { billingResult, outToken ->
        if (billingResult.responseCode == BillingResponseCode.OK) {
            // Handle the success of the consume operation.
        }
    })
}

Java

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

    // Verify the purchase.
    // Ensure entitlement was not already granted for this purchaseToken.
    // Grant entitlement to the user.

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

Para confirmar compras de produtos que não são de consumo, use BillingClient.acknowledgePurchase() da biblioteca de Faturamento ou Product.Purchases.Acknowledge da API Google Play Developer. Antes de confirmar uma compra, seu app precisa verificar se ela já foi confirmada usando o método isAcknowledged() na biblioteca do Google Play Faturamento ou o campo acknowledgementState na API Google Developer.

O exemplo a seguir mostra como confirmar uma compra usando a biblioteca do Google Play Faturamento:

Kotlin

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

fun handlePurchase() {
    if (purchase.purchaseState === PurchaseState.PURCHASED) {
        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) {
        if (!purchase.isAcknowledged()) {
            AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
            client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
        }
    }
}

As assinaturas são processadas de forma semelhante aos produtos que não são de consumo. Você pode confirmar uma assinatura usando BillingClient.acknowledgePurchase() da biblioteca do Google Play Faturamento ou Purchases.Subscriptions.Acknowledge da API Google Play Developer. Todas as compras de assinatura inicial precisam ser confirmadas. As renovações de assinatura não precisam de confirmação. Para mais informações sobre quando as assinaturas precisam ser confirmadas, consulte o tópico Vender assinaturas.

Como buscar compras

Ouvir atualizações de compra usando um PurchasesUpdatedListener não é suficiente para garantir que seu app processe todas as compras. É possível que seu app não esteja informado de todas as compras que um usuário fez. Veja alguns cenários em que seu app pode perder o controle ou não saber sobre compras:

  • Problemas de rede durante a compra: um usuário faz uma compra bem-sucedida e recebe a confirmação do Google, mas o dispositivo perde a conexão de rede antes que receba uma notificação da compra por meio de PurchasesUpdatedListener.
  • Vários dispositivos: um usuário compra um item em um dispositivo e espera vê-lo ao mudar de dispositivo.
  • Processamento de compras feitas fora do app: algumas compras, como resgates de promoções, podem ser feitas fora do app.

Para tratar dessas situações, verifique se o app chama BillingClient.queryPurchases() nos métodos onResume() e onCreate() para garantir que todas as compras sejam processadas conforme descrito em processamento de compras.

Como processar compras feitas fora do app

Algumas compras, como resgates de promoções, podem acontecer fora do app. Quando um usuário faz uma compra desse tipo, ele espera que o app mostre uma mensagem ou use algum tipo de mecanismo de notificação para informar que recebeu e processou corretamente a compra. Alguns mecanismos aceitáveis são os seguintes:

  • Mostrar um pop-up no aplicativo.
  • Entregar a mensagem a uma caixa de mensagens no aplicativo e informar claramente que há uma nova mensagem.
  • Usar uma mensagem de notificação do SO.

Lembre-se de que é possível que seu app esteja em qualquer estado quando reconhecer a compra. É possível até mesmo que ele não estivesse instalado quando a compra foi feita. Os usuários esperam receber a compra quando retomam o app, independentemente do estado em que ele está.

Você precisa detectar as compras, independentemente do estado em que app estava quando a compra foi feita. No entanto, há algumas exceções em que pode ser aceitável não notificar imediatamente o usuário de que o item foi recebido. Por exemplo:

  • Durante a parte de ação de um jogo, em que exibir uma mensagem pode distrair o usuário. Nesse caso, notifique-o após o término da ação.
  • Durante cenas, em que a exibição de uma mensagem pode distrair o usuário. Nesse caso, notifique o usuário após o término da cena.
  • Durante o tutorial inicial e as partes da configuração do usuário no jogo. Recomendamos que você notifique os novos usuários sobre o prêmio imediatamente depois que eles abrirem o jogo ou durante a configuração inicial do usuário. No entanto, é aceitável aguardar até que a sequência principal do jogo esteja disponível para enviar a notificação.

Sempre tenha em mente o usuário ao decidir quando e como notificá-lo sobre compras feitas fora do app. Sempre que um usuário não recebe uma notificação imediatamente, ele pode ficar confuso e parar de usar seu app, entrar em contato com o suporte ao usuário ou reclamar nas mídias sociais.

Como processar transações pendentes

O Google Play é compatível com transações pendentes, ou transações que exigem uma ou mais etapas adicionais entre o momento em que um usuário inicia uma compra e o processamento da forma de pagamento. Não conceda titularidade nesses tipos de compras até que o Google notifique você de que a cobrança foi feita na forma de pagamento do usuário.

Por exemplo, um usuário pode criar uma compra PENDING de um item no aplicativo escolhendo dinheiro como forma de pagamento. Em seguida, ele pode escolher uma loja física em que concluirá a transação e receberá um código por meio de notificação e e-mail. Quando o usuário chegar à loja física, ele poderá resgatar o código com o caixa e pagar com dinheiro. O Google notifica você e o usuário de que o dinheiro foi recebido. Então, seu aplicativo pode conceder a titularidade ao usuário.

Para ativar compras pendentes, chame enablePendingPurchases() como parte da inicialização do app.

Quando seu app recebe uma nova compra, pelo PurchasesUpdatedListener ou ao chamar queryPurchases(), use o método getPurchaseState() para determinar se o estado de compra é PURCHASED ou PENDING. Você precisa conceder titularidade apenas quando o estado é PURCHASED. Se o app estiver em execução quando o usuário concluir a compra, o PurchasesUpdatedListener será chamado novamente, e PurchaseState será PURCHASED. Nesse momento, seu app pode processar a compra usando o método padrão para processar compras únicas. O app também precisa chamar queryPurchases() nos métodos onResume() e onCreate() para processar compras que fizeram a transição para o estado PURCHASED enquanto o app não estava em execução.

Seu app também pode usar notificações do desenvolvedor em tempo real com compras pendentes ouvindo OneTimeProductNotifications. Quando a compra mudar de PENDING para PURCHASED, seu app receberá uma notificação ONE_TIME_PRODUCT_PURCHASED. Se a compra for cancelada, seu app receberá uma notificação ONE_TIME_PRODUCT_CANCELED. Isso poderá acontecer se o cliente não concluir o pagamento no prazo exigido. Ao receber essas notificações, você pode usar a API Google Play Developer, que inclui um estado PENDING para Purchases.products.