Dans Google Play Billing, ITEM_ALREADY_OWNED correspond au code de réponse 7. Cela signifie que Google Play considère que l’abonnement ou le produit ponctuel transmis à launchBillingFlow() est déjà détenu. Des informations d’achat obsolètes sur l’appareil peuvent également provoquer cette réponse de manière inattendue. Dans les applications Android utilisant la bibliothèque Google Play Billing, la première mesure la plus sûre consiste à appeler queryPurchasesAsync() pour le type de produit concerné. N’accordez aucun droit d’accès et ne relancez pas l’opération sur la seule base du code 7.
Signification du code de réponse 7 ITEM_ALREADY_OWNED
BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED a pour valeur numérique 7, comme le confirme la documentation de référence de l’API BillingResponseCode. Ce code peut être renvoyé par l’intermédiaire de BillingResult lorsque launchBillingFlow() est appelé pour un abonnement ou un produit ponctuel déjà détenu par le compte Google Play.
Deux pistes de diagnostic principales sont possibles :
- Produit réellement détenu : Play signale un achat actif que l’application doit reconnaître et ne doit pas attribuer deux fois.
- État d’achat Play obsolète : les informations d’achat présentes sur l’appareil ne reflètent pas encore le dernier état du serveur. Le code 7 apparaît alors même si, après actualisation, la requête n’indique plus que le produit est détenu.
L’application peut aussi proposer un produit déjà détenu, et des paramètres incorrects transmis à launchBillingFlow() peuvent faire apparaître cette erreur. La réponse ne prouve pas à elle seule que l’achat est actuellement à l’état PURCHASED. Appuyez-vous sur le résultat de la requête d’achats et sur les données de droits d’accès de l’application pour prendre cette décision.
Interroger les achats pour distinguer un produit détenu d’un état Play obsolète
Quand utiliser cette méthode : appliquez-la en premier après avoir reçu ITEM_ALREADY_OWNED lors du parcours d’achat d’un abonnement ou d’un produit ponctuel.
Conditions préalables : BillingClient doit être connecté, et l’application doit savoir si elle interroge les achats d’un abonnement ou d’un produit ponctuel. Avec la version 8.x de la bibliothèque Billing, utilisez la forme actuelle queryPurchasesAsync(QueryPurchaseParams, ...) ; l’ancienne surcharge fondée sur une chaîne de caractères a été supprimée.
- Appelez
queryPurchasesAsync()après avoir reçu le code 7. La documentation de référence de l’API BillingClient décrit l’API cliente actuelle. - Dans les achats actualisés, recherchez le produit concerné par l’échec du parcours d’achat.
- Si le produit est indiqué comme détenu, vérifiez son état d’achat et rapprochez-le du droit d’accès existant. Ne proposez plus ce produit à l’achat.
- Si le résultat actualisé n’indique pas que le produit est détenu, suivez la procédure ci-dessous pour l’état obsolète et n’autorisez pas plus d’une nouvelle tentative.
Résultat attendu : l’application identifie soit un achat détenu et vérifié, soit un état actualisé dans lequel le produit n’est pas signalé comme détenu.
Risques et retour en arrière : le risque est faible, car cette opération se limite à lire et à rapprocher des données. Elle ne nécessite ni suppression des enregistrements locaux ni effacement des données du Google Play Store. Si la propriété est confirmée, interrompez le parcours d’achat et toute nouvelle tentative en attente.
Rapprocher les données de propriété Play des droits d’accès de l’application
Quand utiliser cette méthode : utilisez-la lorsque la requête d’achats actualisée confirme que le produit est détenu, ou lorsque l’interface d’achat et les données de droits d’accès du client ou du serveur de l’application ne concordent pas.
Conditions préalables : l’application doit disposer du résultat d’achat Play actualisé et avoir accès aux données de droits d’accès côté client ou côté serveur qu’elle utilise habituellement. Les détails de l’implémentation côté serveur sont propres à chaque application et doivent être vérifiés par rapport à son propre modèle de traitement sécurisé.
- Comparez l’achat Play actualisé aux données actuelles de droits d’accès côté client et côté serveur.
- N’accordez ou ne maintenez l’accès qu’après avoir vérifié l’état d’achat applicable. Rendez l’attribution idempotente afin qu’un même achat observé par le client et par le traitement côté serveur ne soit pas accordé deux fois.
- Masquez ou désactivez les options d’achat des abonnements et des produits ponctuels non consommables déjà détenus.
- Pour les produits consommables, maintenez l’option d’achat indisponible jusqu’à ce que la consommation soit confirmée.
- Veillez à ce que l’état de propriété affiché reste synchronisé avec Play et avec la source de référence de l’application pour les droits d’accès.
Résultat attendu : un produit réellement détenu dispose du droit d’accès approprié et n’est plus proposé à l’achat, tandis qu’un produit non détenu n’est pas considéré à tort comme acheté.
Risques et retour en arrière : le risque est faible si aucun droit d’accès n’est accordé sur la seule base du code 7. Ne réactivez un produit que lorsque le droit correspondant n’est plus actif ou, pour un produit consommable, lorsque la consommation est confirmée. Ne supprimez pas les données locales de droits d’accès pour remplacer le rapprochement.
Dans quel cas effectuer une nouvelle tentative après ITEM_ALREADY_OWNED
Quand utiliser cette méthode : ne réessayez que lorsque queryPurchasesAsync() a actualisé l’état d’achat et que le résultat n’indique toujours pas que le produit est détenu.
Conditions préalables : la requête d’achats doit être terminée, la propriété doit rester non confirmée et l’application ne doit avoir accordé aucun droit d’accès à partir de la réponse d’erreur.
- Uniquement dans cette branche où le produit n’est pas détenu, considérez la première réponse de code 7 comme un possible signal d’actualisation du cache.
- Confirmez que le résultat d’achat actualisé ne contient pas le produit en tant que produit détenu.
- Relancez une seule fois
launchBillingFlow()au moyen d’une logique de nouvelle tentative simple. - Arrêtez si la propriété est confirmée ou si cette unique nouvelle tentative ne rétablit pas le parcours.
Résultat attendu : un achat bloqué uniquement par des informations obsolètes sur l’appareil peut aboutir après l’actualisation. La plupart des réponses de code 7 ne doivent pas être considérées comme temporaires.
Risques et retour en arrière : le risque est faible lorsque la nouvelle tentative est limitée à la condition documentée. Aucun retour en arrière destructif n’est nécessaire. Arrêtez immédiatement si la propriété est confirmée et ne créez pas de boucle de tentatives immédiates, répétées, exponentielles ou indéfinies. Cette procédure suit les recommandations de Google pour la récupération après ITEM_ALREADY_OWNED.
Confirmer ou consommer l’achat selon le type de produit
La confirmation et la consommation ne sont pas interchangeables. L’opération appropriée dépend du type de produit : abonnement, produit ponctuel non consommable ou produit ponctuel consommable.
Confirmer les abonnements et les produits non consommables
Quand utiliser cette méthode : utilisez la confirmation pour les abonnements et les produits non consommables qui doivent rester détenus.
Conditions préalables : l’achat est à l’état PURCHASED, le droit d’accès correspondant a été accordé et l’achat n’a pas déjà été confirmé.
- Vérifiez l’état
PURCHASED. - Accordez le droit d’accès sans reproduire une attribution déjà effectuée.
- Confirmez l’achat dès que possible après avoir accordé le droit d’accès.
- Utilisez
acknowledgePurchase()pour un traitement effectué uniquement côté client, ou l’API Google Play Developer sur un serveur sécurisé.
Résultat attendu : l’abonnement ou le produit non consommable vérifié reste détenu et n’est plus proposé à l’achat.
Risques et retour en arrière : le risque est faible. Si l’achat a déjà été confirmé, n’effectuez aucune autre action de confirmation. Ne consommez jamais un abonnement ou un produit non consommable pour faire disparaître le code 7.
Consommer les produits consommables avant un nouvel achat
Quand utiliser cette méthode : utilisez la consommation uniquement pour un produit conçu pour être acheté plusieurs fois.
Conditions préalables : l’article du catalogue doit être un produit consommable, et l’avantage associé à l’achat en cours doit déjà avoir été accordé.
- Vérifiez l’achat et accordez l’avantage consommable.
- Consommez l’achat avec
consumeAsync()pour un traitement effectué uniquement côté client, ou avecPurchases.products:consumesur un serveur sécurisé. - Confirmez la consommation avant de présenter de nouveau le produit comme disponible à l’achat.
- Empêchez toute attribution en double si le même achat est observé plusieurs fois.
Résultat attendu : l’utilisateur reçoit l’avantage consommable correspondant à l’achat en cours, et le produit ne redevient admissible à un achat ultérieur qu’après sa consommation.
Risques et retour en arrière : le risque est faible si la classification du catalogue est correcte. La consommation ne doit pas précéder l’attribution de l’avantage. Si l’achat a déjà été consommé, ne répétez pas l’attribution au seul motif qu’un résultat de propriété est observé de nouveau.
Valider la récupération sans accorder deux fois l’accès
Quand utiliser cette méthode : effectuez cette validation dans un environnement de test Google Play après avoir mis en œuvre les requêtes de propriété, le rapprochement des droits d’accès, le filtrage des produits, la nouvelle tentative conditionnelle et le parcours de confirmation ou de consommation approprié.
Conditions préalables : un compte de testeur de licence doit être présent sur l’appareil Android, l’application doit être installée à l’aide de ce compte et le testeur doit pouvoir observer les boîtes de dialogue d’achat Play ainsi que l’état des droits d’accès dans l’application.
- Effectuez un achat test avec le compte de testeur de licence.
- Vérifiez que la requête d’achats actualisée, les droits d’accès de l’application, l’enregistrement côté serveur et l’interface d’achat concordent.
- Pour un abonnement ou un produit non consommable, confirmez l’achat dans le délai de trois minutes applicable aux testeurs de licence ; sinon, l’achat test est remboursé.
- Pour un produit consommable, vérifiez que l’avantage est accordé avant la consommation et que l’article ne redevient disponible à l’achat qu’après celle-ci.
- Utilisez Play Billing Lab lorsque vous devez accélérer le renouvellement d’un abonnement ou modifier son état.
- Répétez l’actualisation normale de l’état d’achat de l’application et vérifiez que les rappels en double ou le traitement côté serveur n’accordent pas deux fois le droit d’accès.
- Vérifiez qu’un abonnement ou un produit non consommable déjà détenu ne présente plus d’option d’achat active et que la logique de nouvelle tentative s’arrête après l’unique tentative documentée.
Résultat attendu : la propriété, les droits d’accès, la confirmation ou la consommation et l’état de l’interface d’achat restent cohérents, sans attribution en double.
Risques et retour en arrière : le risque est faible dans l’environnement de test prévu à cet effet. Annulez l’achat test ou laissez-le expirer ou être remboursé conformément aux règles de test applicables. N’utilisez pas les achats de clients en production pour effectuer des tests destructifs.
N’utilisez pas l’effacement des données du Play Store, la suppression des droits d’accès locaux, les tentatives répétées ou la consommation sans vérification comme solutions principales. Ces actions ne permettent pas d’établir la propriété de manière sûre et peuvent masquer un défaut de rapprochement des droits d’accès.
Limites de version et d’implémentation : ce guide utilise la version 8.x de la bibliothèque Billing et la terminologie actuelle des API compatibles. Le délai exact d’actualisation d’un cache obsolète varie selon l’appareil et la version du Play Store. La classification des produits et le rapprochement côté serveur restent propres à chaque application et nécessitent une vérification au niveau de l’implémentation.

