Facturation via l’application Android: l’état d’achat rest «acheté» après l’annulation de la commande

Je teste actuellement mon mécanisme de facturation InApp (à l’aide de l’API InApp Billing version 3, prenant donc l’exemple de TrivialDrive comme référence).

J’ai un élément géré, qui est la mise à niveau vers la version premium.

Maintenant, l’achat de l’article avec mon compte de test fonctionne, mais lorsque j’annule la commande complète dans Google Checkout par la suite, mon code m’indique toujours que l’article a été acheté et qu’il est donc compatible avec les fonctionnalités premium.

Voici comment je vérifie l’achat dans ma MainActivity. Je ne sauvegarde pas l’état d’achat localement quelque part, comme je l’ai compris, avec l’API de facturation v3, vous pouvez demander des achats ad hoc selon les besoins.

@Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); iabHelper = new IabHelper(this, Helper.getPKey()); iabHelper.enableDebugLogging(true); iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { @Override public void onIabSetupFinished(IabResult result) { Log.d("IAB", "SETUP FINISHED"); if(!result.isSuccess()) { Log.d("IAB", "SETUP NOT OK"); return; } else Log.d("IAB", "SETUP OK"); iabHelper.queryInventoryAsync( new QueryInventoryFinishedListener() { @Override public void onQueryInventoryFinished(IabResult result, Inventory inv) { Log.d("IAB", "Query inventory finished."); if (result.isFailure()) { Log.d("IAB","Failed to query inventory: " + result); return; } Log.d("IAB", "Query inventory was successful."); // Do we have the premium upgrade? boolean mIsPremium = inv.hasPurchase(Helper.premiumSku); Purchase p = inv.getPurchase(Helper.premiumSku); if(p != null) Log.d("IAB PURCHASE STATE", IabHelper.getResponseDesc(p.getPurchaseState())); else Log.d("IAB PURCHASE STATE", "Purchase is null"); Log.d("IAB", "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM")); } } ); } }); } 

Je continue à obtenir getPurchaseState = 0, ce qui signifie que vous avez acheté, même une heure après avoir annulé la commande. Pourquoi?

Je sais que c’est un an, mais aucune des réponses / astuces présentées ne m’a aidé, alors j’ai pensé append ma solution.

Tout d’abord, je rencontrais le même problème. À savoir, fait un achat test, annulé, toujours reçu un état d’achat indiquant l’achat valide.

Ce que j’ai oublié, c’est que j’ai récemment basculé le champ “Réponse du test de licence” dans le volet des parameters de la console développeur Google Play de “RESPOND_NORMALLY” à “LICENSED”

Après le retour à «RESPOND_NORMALLY», l’état d’achat de l’achat annulé a été correctement retourné en tant que tel.

Donc, vous voudrez peut-être vérifier cela avant d’essayer d’attendre des jours

Après avoir attendu environ 12 heures et avoir essayé tout ce qui était suggéré ici, j’étais toujours confronté au même problème. Ce qui a fait l’affaire pour moi était la commande adb suivante:

adb shell pm clear com.android.vending

Étape 1. Attendez environ 10 minutes. Jusqu’à ce que vous voyez la “commande annulée” a été livrée. dans votre portefeuille Google

Sep 15 11:28 Annulé La commande a été livrée.

Sep 15 11:18 Annulé Vous avez annulé cette commande. Raison: demande du client pour annuler.

Étape 2. Déconnectez votre compte Google de test sur le périphérique, puis reconnectez-vous.

Au moins cela a résolu mon problème.

Ce problème se produit également lors de l’utilisation de l’application sur un autre périphérique avec le même compte. L’article n’est pas reçu comme acheté jusqu’à ce que l’appareil soit redémarré, même après les heures. Si vous essayez d’acheter à nouveau, la boîte de dialog google wallet indique “élément déjà possédé”. Le code de retour de iabHelper est toujours “annulé par l’utilisateur” car la réponse réelle de l’activité d’achat n’est pas restituée, mais simplement écrite dans le journal de débogage.

 else if (resultCode == Activity.RESULT_CANCELED) { logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode)); result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled."); if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null); } 

Donc, il n’est pas possible de réagir à cette boîte de dialog de facturation Google, car nous obtenons toujours le même résultat IABHELPER_USER_CANCELED, même si la boîte de dialog disait “élément déjà possédé”.

Modifier:

Je le répare avec ceci:

 else if (resultCode == Activity.RESULT_CANCELED) { logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode)); if(responseCode == 7) result = new IabResult(BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED, "Item already owned."); else result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled."); if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null); } 

Donc maintenant, si la réponse de la boîte de dialog de facturation est 7 comme “Article déjà possédé”, je le signale à mon interlocuteur.

Ce que vous pouvez utiliser, c’est le champ autoRenewing des données d’achat. Selon la documentation :

autoRenewing: Indique si l’abonnement se renouvelle automatiquement. Si true, l’abonnement est actif et se renouvellera automatiquement à la prochaine date de facturation. Si false, indique que l’utilisateur a annulé l’abonnement .

Et ce champ est mis à jour immédiatement après l’annulation.

Si je vois correctement le code de référence dans l’échantillon sortingvial est faux, ce qui serait dommage pour le projet de référence officiel pour la facturation dans l’application.

si achat == null, cela signifie simplement qu’il n’a jamais été acheté. Pour obtenir la vraie information, vous devez appeler

 purchase.getPurchaseState() 

selon ici

purchaseState L’état d’achat de la commande. Les valeurs possibles sont 0 (acheté), 1 (annulé), 2 (remboursé) ou 3 (expiré, pour les achats par abonnement uniquement).

C’est déjà bien répondu dans les documents officiels de Google. Copier les mots ici.

Lorsque l’utilisateur annule un abonnement, Google Play n’offre pas de remboursement pour le cycle de facturation en cours. Au lieu de cela, il permet à l’utilisateur d’accéder à l’abonnement annulé jusqu’à la fin du cycle de facturation en cours, moment auquel il met fin à l’abonnement. Par exemple, si un utilisateur achète un abonnement mensuel et l’annule le 15e jour du cycle, Google Play considérera l’abonnement comme valide jusqu’à la fin du 30e jour (ou un autre jour, selon le mois).

Cela devrait tout expliquer. getPurchase() restituera toujours les données d’achat jusqu’à la fin du cycle d’abonnement en cours.

J’ai trouvé la section suivante dans la documentation (IAB API v2), mais je ne suis pas sûr que cela puisse être utilisé pour IAB API v3. La diffusion peut néanmoins être envoyée.

“… votre application peut recevoir une intention de diffusion IN_APP_NOTIFY lorsque Google Play reçoit une notification de remboursement de Google Wallet. Dans ce cas, Google Play envoie un message IN_APP_NOTIFY à votre application. Votre application peut gérer ce message de la même manière que les réponses. un message REQUEST_PURCHASE initié par l’application pour que votre application reçoive finalement un message PURCHASE_STATE_CHANGED contenant des informations sur l’élément remboursé.Les informations de remboursement sont incluses dans la chaîne JSON qui accompagne l’intention de diffusion PURCHASE_STATE_CHANGED. la chaîne est définie sur 2. ”

à partir de: http://developer.android.com/google/play/billing/v2/api.html#billing-action-notify