No Google Play Billing, ITEM_ALREADY_OWNED corresponde ao código de resposta 7. Isso significa que o Google Play considera que a assinatura ou o produto de compra única informado em launchBillingFlow() já pertence ao usuário. Informações de compra desatualizadas no dispositivo também podem gerar essa resposta inesperadamente. Em apps Android que usam a Google Play Billing Library, a primeira ação mais segura é chamar queryPurchasesAsync() para o tipo de produto aplicável. Não conceda direitos nem repita a tentativa com base apenas no código 7.

O que significa o código de resposta 7 ITEM_ALREADY_OWNED

BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED tem o valor numérico 7, conforme confirmado pela referência da API BillingResponseCode. Ele pode ser retornado por meio de BillingResult quando launchBillingFlow() é chamado para uma assinatura ou um produto de compra única que já pertence à conta do Google Play.

Há duas ramificações principais no diagnóstico:

  • Propriedade legítima: o Google Play informa uma compra ativa que o app deve reconhecer e não pode processar duas vezes.
  • Estado de compra desatualizado no Google Play: as informações de compra no dispositivo ainda não refletem o estado mais recente do backend, fazendo com que o código 7 apareça mesmo quando uma consulta atualizada não indica que o item pertence ao usuário.

O app também pode estar oferecendo um produto que já pertence ao usuário, e parâmetros incorretos em launchBillingFlow() podem fazer esse erro aparecer. A resposta, por si só, não comprova um estado atual PURCHASED. Use o resultado da consulta de compras e os registros de direitos do app para tomar essa decisão.

Consulte as compras para diferenciar propriedade de um estado desatualizado do Google Play

Quando se aplica: use esta opção primeiro após receber ITEM_ALREADY_OWNED em um fluxo de compra de assinatura ou produto de compra única.

Pré-requisitos: o BillingClient deve estar conectado, e o app precisa saber se consultará uma assinatura ou um produto de compra única. Na Billing Library 8.x, use a forma atual queryPurchasesAsync(QueryPurchaseParams, ...); a sobrecarga antiga baseada em string foi removida.

  1. Chame queryPurchasesAsync() após o resultado de código 7. A referência da API BillingClient documenta a API atual do cliente.
  2. Examine as compras atualizadas para localizar o produto envolvido no fluxo que falhou.
  3. Se o produto for retornado como pertencente ao usuário, verifique o estado da compra e reconcilie-o com o direito existente. Pare de oferecer o produto para compra.
  4. Se o resultado atualizado não mostrar que o produto pertence ao usuário, siga a ramificação de cache desatualizado descrita abaixo e permita no máximo uma nova tentativa.

Resultado esperado: o app identifica uma compra cuja propriedade foi confirmada ou um estado atualizado no qual o produto não é informado como pertencente ao usuário.

Risco e reversão: o risco é baixo porque esta é uma operação de leitura e reconciliação. Não é necessário excluir registros locais nem limpar os dados da Google Play Store. Se a propriedade for confirmada, interrompa o fluxo de compra e qualquer nova tentativa pendente.

Reconcilie a propriedade no Google Play com o estado dos direitos no app

Quando se aplica: use esta opção quando a consulta atualizada confirmar a propriedade ou quando a interface de compra e os registros de direitos do cliente ou do backend do app estiverem divergentes.

Pré-requisitos: o app deve ter o resultado atualizado da compra no Google Play e acesso aos dados de direitos no cliente ou no backend que ele normalmente utiliza. Os detalhes da implementação do backend são específicos de cada app e devem ser verificados de acordo com o próprio projeto de processamento seguro do app.

  1. Compare a compra atualizada no Google Play com os registros atuais de direitos no cliente e no backend do app.
  2. Conceda ou mantenha o acesso somente após verificar o estado aplicável da compra. Torne o processamento idempotente para que a mesma compra observada pelo cliente e pelo backend não conceda o direito duas vezes.
  3. Oculte ou desative as opções de compra de assinaturas e produtos de compra única não consumíveis que já pertencem ao usuário.
  4. No caso de produtos consumíveis, mantenha a opção de compra indisponível até que o consumo seja confirmado.
  5. Mantenha o estado de propriedade exibido sincronizado com o Google Play e com a fonte oficial de direitos do app.

Resultado esperado: um produto que realmente pertence ao usuário tem o direito correto e não é oferecido novamente, enquanto um produto que não pertence ao usuário não é tratado incorretamente como comprado.

Risco e reversão: o risco é baixo se nenhum direito for concedido apenas com base no código 7. Reative um produto somente quando o direito correspondente não estiver mais ativo ou, no caso de um consumível, depois da confirmação do consumo. Não exclua registros locais de direitos como substituto para a reconciliação.

Quando uma nova tentativa é apropriada após ITEM_ALREADY_OWNED

Quando se aplica: repita a tentativa somente quando queryPurchasesAsync() tiver atualizado o estado da compra e o resultado ainda não indicar que o produto pertence ao usuário.

Pré-requisitos: a consulta de compras já deve ter sido concluída, a propriedade deve continuar sem confirmação e o app não pode ter concedido direitos com base na resposta de erro.

  1. Somente nessa ramificação sem propriedade confirmada, trate a resposta inicial de código 7 como um possível sinal para atualizar o cache.
  2. Confirme que o resultado atualizado da compra não inclui o produto como pertencente ao usuário.
  3. Repita launchBillingFlow() uma vez, usando uma lógica simples de nova tentativa.
  4. Interrompa o processo se a propriedade for confirmada ou se essa única nova tentativa não recuperar o fluxo.

Resultado esperado: uma compra bloqueada apenas por informações desatualizadas no dispositivo pode prosseguir após a atualização. A maioria das respostas de código 7 não deve ser tratada como transitória.

Risco e reversão: o risco é baixo quando a nova tentativa fica restrita à condição documentada. Não há reversão destrutiva. Interrompa imediatamente se a propriedade for confirmada e não crie um ciclo de novas tentativas imediatas, repetidas, exponenciais ou indefinidas. Essa sequência segue as orientações do Google para recuperação de ITEM_ALREADY_OWNED.

Confirme ou consuma a compra de acordo com o tipo de produto

A confirmação e o consumo não são intercambiáveis. A operação correta depende de o produto ser uma assinatura, um produto de compra única não consumível ou um produto de compra única consumível.

Confirme assinaturas e produtos não consumíveis

Quando se aplica: use a confirmação para assinaturas e produtos não consumíveis que devem continuar pertencendo ao usuário.

Pré-requisitos: o estado da compra é PURCHASED, o direito correspondente já foi concedido e a compra ainda não foi confirmada.

  1. Verifique o estado PURCHASED.
  2. Conceda o direito sem duplicar qualquer processamento que já tenha sido realizado.
  3. Confirme a compra assim que possível depois de conceder o direito.
  4. Use acknowledgePurchase() no processamento feito apenas pelo cliente ou a Google Play Developer API em um backend seguro.

Resultado esperado: a assinatura ou o produto não consumível verificado continua pertencendo ao usuário e deixa de ser oferecido para compra.

Risco e reversão: o risco é baixo. Se a compra já tiver sido confirmada, não execute outra ação de confirmação. Nunca consuma uma assinatura ou um produto não consumível para eliminar o código 7.

Consuma produtos consumíveis antes de permitir uma nova compra

Quando se aplica: use o consumo somente para um produto criado intencionalmente para ser comprado várias vezes.

Pré-requisitos: o item do catálogo deve ser consumível, e o direito referente à compra atual já deve ter sido concedido.

  1. Verifique a compra e conceda o benefício consumível.
  2. Consuma a compra com consumeAsync() no processamento feito apenas pelo cliente ou com Purchases.products:consume em um backend seguro.
  3. Confirme o consumo antes de exibir o produto como disponível para uma nova compra.
  4. Evite o processamento duplicado se a mesma compra for observada mais de uma vez.

Resultado esperado: o usuário recebe o benefício consumível atual, e o produto somente se torna elegível para uma compra posterior após o consumo.

Risco e reversão: o risco é baixo quando a classificação no catálogo está correta. O consumo não deve ocorrer antes da concessão do benefício. Se a compra já tiver sido consumida, não repita o processamento apenas porque um resultado de propriedade foi observado novamente.

Valide a recuperação sem conceder acesso duas vezes

Quando se aplica: use este procedimento em um ambiente de teste do Google Play depois de implementar consultas de propriedade, reconciliação de direitos, filtragem de produtos, nova tentativa condicional e o caminho correto de confirmação ou consumo.

Pré-requisitos: uma conta de testador de licença deve estar presente no dispositivo Android, o app deve ter sido instalado usando essa conta e o testador precisa conseguir observar as caixas de diálogo de compra do Google Play e o estado dos direitos no app.

  1. Faça uma compra de teste com a conta de testador de licença.
  2. Verifique se a consulta atualizada da compra, o direito no app, o registro no backend e a interface de compra estão consistentes.
  3. No caso de uma assinatura ou de um produto não consumível, confirme a compra dentro da janela de três minutos do testador de licença; caso contrário, a compra de teste será reembolsada.
  4. No caso de um produto consumível, confirme que o benefício é concedido antes do consumo e que o item somente aparece para nova compra depois de ser consumido.
  5. Use o Play Billing Lab quando precisar acelerar a renovação de assinaturas ou as alterações de estado.
  6. Repita a atualização normal do estado de compras do app e confirme que callbacks duplicados ou o processamento no backend não concedem o direito duas vezes.
  7. Confirme que uma assinatura ou um produto não consumível pertencente ao usuário não apresenta mais uma opção de compra ativa e que a lógica de nova tentativa é interrompida após a única tentativa documentada.

Resultado esperado: a propriedade, os direitos, a confirmação ou o consumo e o estado da interface de compra permanecem consistentes, sem processamento duplicado.

Risco e reversão: o risco é baixo no ambiente de teste designado. Cancele a compra de teste ou permita que ela expire ou seja reembolsada conforme as regras de teste aplicáveis. Não use compras de clientes em produção para testes destrutivos.

Não use a limpeza dos dados da Google Play Store, a exclusão de direitos locais, novas tentativas repetidas ou o consumo sem verificação como correções principais. Essas ações não comprovam a propriedade com segurança e podem ocultar uma falha na reconciliação de direitos.

Limite de versão e implementação: este guia usa a Billing Library 8.x e a terminologia atual das APIs compatíveis. O momento exato da atualização de um cache desatualizado varia entre dispositivos e versões da Google Play Store, enquanto a classificação de produtos e a reconciliação no backend continuam específicas de cada app e exigem verificação no nível da implementação.