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.
- Chame
queryPurchasesAsync()após o resultado de código 7. A referência da API BillingClient documenta a API atual do cliente. - Examine as compras atualizadas para localizar o produto envolvido no fluxo que falhou.
- 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.
- 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.
- Compare a compra atualizada no Google Play com os registros atuais de direitos no cliente e no backend do app.
- 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.
- 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.
- No caso de produtos consumíveis, mantenha a opção de compra indisponível até que o consumo seja confirmado.
- 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.
- Somente nessa ramificação sem propriedade confirmada, trate a resposta inicial de código 7 como um possível sinal para atualizar o cache.
- Confirme que o resultado atualizado da compra não inclui o produto como pertencente ao usuário.
- Repita
launchBillingFlow()uma vez, usando uma lógica simples de nova tentativa. - 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.
- Verifique o estado
PURCHASED. - Conceda o direito sem duplicar qualquer processamento que já tenha sido realizado.
- Confirme a compra assim que possível depois de conceder o direito.
- 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.
- Verifique a compra e conceda o benefício consumível.
- Consuma a compra com
consumeAsync()no processamento feito apenas pelo cliente ou comPurchases.products:consumeem um backend seguro. - Confirme o consumo antes de exibir o produto como disponível para uma nova compra.
- 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.
- Faça uma compra de teste com a conta de testador de licença.
- Verifique se a consulta atualizada da compra, o direito no app, o registro no backend e a interface de compra estão consistentes.
- 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.
- 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.
- Use o Play Billing Lab quando precisar acelerar a renovação de assinaturas ou as alterações de estado.
- 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.
- 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.

