Search Unity

Catch callback for non-consumables

Discussion in 'Unity IAP' started by Jojoba007, Aug 8, 2018.

  1. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    Hi, I'm new to IAP and using Unity for over a year now. I was wondering the following:

    I have implemented an IAP non-consumable button in Unity to remove the Ads. Now I was wondering
    how I can best check if someone has already bought the non-consumable product to remove the Ads.
    For example if they reinstall or wipe their phone how does the app know they already bought the non-consumable ad remover in my game?

    What is the best approach to check this? Is their maybe an example? I tried to find one but couldn't find a proper one. I read something about catching the callback? How would I do this?

    Regards Rob
     
  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    We don't currently provide inventory management for IAP. You would want to store this information locally, perhaps in PlayerPrefs. The callback for non-consumables is ProcessPurchase, the same callback that gets fired when the user makes the original purchase. For Google, this is done automatically during reinstall. For iOS, you would want to implement a Restore button https://docs.unity3d.com/Manual/UnityIAPRestoringTransactions.html
     
  3. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148

    Thanks so far for your reply.

    If I understand you correctly Unity IAP will check automatically if the purchase already has been done for that specific Google account? If so, then how would I check this so I can set it to PlayerPrefs? Where do I check it against?

    Sorry for my lack of understanding


    This is the code that is connected to my IAP Button:

    Code (CSharp):
    1.     // Button to remove Ads with IAP
    2.     public void OnPurchaseCompleted(Product product) {
    3.  
    4.         if (product != null) {
    5.             switch (product.definition.id) {
    6.                 case "didado.removeads":
    7.                     print("You have succesfully purchased the removal of Ads");
    8.                     break;
    9.                 default:
    10.                     print("Sorry, this product is not defined");
    11.                     break;
    12.  
    13.  
    14.             }
    15.         }
    16.  
    17.     }

    This is the code for showing ads:

    Code (CSharp):
    1.                 //ShowAd Unity ads
    2.                 if (Time.timeSinceLevelLoad > 6)
    3.                 {
    4.  
    5.                     int number = Random.Range(1, 10);
    6.  
    7.                     if (number == 8)
    8.                     {
    9.  
    10.                         musicManager.Pause();
    11.                         showAd();
    12.                     }
    13.                 }
    How would I check with the above if statement if the removal of ads has already been done for that specific user? Where do I compare my PlayerPrefs statement against? I know how PlayerPrefs work. And isn't it unsafe to use PlayerPrefs?
     
    Last edited: Aug 8, 2018
  4. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Correct PlayerPrefs is not the best solution, but could get you started with the right logic. You would save the purchase information in PlayerPrefs (or in other persistent local storage) where you currently have the line:

    print("You have succesfully purchased the removal of Ads");
    //save to local storage here.
     
    Jojoba007 likes this.
  5. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    Thx. But if I save to PlayerPrefs and the device its cache gets wiped (including PlayerPrefs), how would I still check in the logic if that specific user has bought the removal of ads before?
     
  6. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Test it and see! You don't need to check. During the Restore process after the app reinstall, the Purchase Complete should get triggered for that product. At that point you know they have bought removal of ads previously, and no local storage is needed. But during normal play with no app reinstall, PlayerPrefs would work for you.
     
    Jojoba007 likes this.
  7. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    Thanks so far.

    I got the following setup now:


    Code in awake:

    Code (CSharp):
    1.         if (SPrefs.HasKey("AdsBought"))
    2.         {
    3.  
    4.             AdsBought = SPrefs.GetInt("AdsBought");
    5.         }
    6.  


    Code for the IAP Button:

    Code (CSharp):
    1.     public void OnPurchaseCompleted(Product product) {
    2.  
    3.         if (product != null) {
    4.             switch (product.definition.id) {
    5.                 case "didado.removeads":
    6.                     print("You have succesfully purchased the removal of Ads");
    7.                     AdsBought = 1;
    8.                     SPrefs.SetInt("AdsBought", AdsBought);
    9.                     SPrefs.Save();
    10.  
    11.                     break;
    12.                 default:
    13.                     print("Sorry, this product is not defined");
    14.                     break;
    15.  
    16.  
    17.             }
    18.         }
    19.  
    20.     }
    21.  
    And the code to check if the Ad Remover product has been bought:

    Code (CSharp):
    1.                 if (Time.timeSinceLevelLoad > 6 && AdsBought != 1)
    2.                 {
    3.                     Debug.Log("AdsBought = " + AdsBought);
    4.  
    5.  
    6.                     int number = Random.Range(1, 10);
    7.  
    8.                     if (number == 8)
    9.                     {
    10.  
    11.                         Debug.Log("Number is now: " + number);
    12.  
    13.                         musicManager.Pause();
    14.                         showAd();
    15.                     }
    16.          
    17.              
    18.                 }

    So this will be enough? If I set it up like this will the Unity IAP PurchaseComplete automatically check If the non-consumable product has been bought before, for example after a phone wipe?
    I don't have to check in awake() or start() or something (if for example PlayerPrefs cache gets wiped)?
     
    Last edited: Aug 10, 2018
  8. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    No need to check. As mentioned, if you get the PurchaseComplete triggered, you know then that they have purchased before even without using PlayerPrefs at all.
     
    Jojoba007 likes this.
  9. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    Thanks so far

    In the editor everything seems to work and Ads are removed, but once in Google Play if we test this, the Money is charged but the Ads are still there. I'm not sure what the problem is.

    And do I need to check this with non-consumable purchase:
    Screenshot: http://prntscr.com/kh41i8
     
    Last edited: Aug 10, 2018
  10. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    What is the behavior during your testing when you select that option? Please provide steps to reproduce. Is this during reinstall of the game, or during a purchase after installation? Did you get your message "You have successfully purchased the removal of Ads". So you know, you can side load your app directly on your device using "apk install myfile.apk" or from Unity, after your initial upload to Google Play. It can speed up testing significantly. Also, please provide your device logs https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/
     
    Jojoba007 likes this.
  11. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    Got it partly working now.

    The following is happening:

    - Google Play Store Alpha tester person downloads the game
    - Removes Ads by using the Remove Ads IAP Button as a tester
    - Ads are correctly removed (also when he restarts the game)
    - De-installs the game from his device
    - Re-installs a new alpha build
    - Ads are back again

    What could cause this problem?
     
  12. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please provide the logs during reinstall. Are you getting your expected Debug.Log statements? Is this with our without the checkbox you mentioned? It should be checked.
     
    Jojoba007 likes this.
  13. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    The checkbox is checked.
    But has it maybe something to do that it is an alpha test and IAP purchases are in testmode? So in alpha Google Play mode if I remove the app en install a new alpha build IAP doesn't synchronise for that specific Google testers account?
    Is this maybe normal behavior in a Google Alpha test?
     
  14. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Testing on Google should work as expected. Please keep me posted on your progress and provide the requested information when you can.
     
    Jojoba007 likes this.
  15. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148

    Ok after an installation of a new version of the game the PlayerPrefs are wiped.
    adsBought doesn't have a value of 1 anymore, which should be in order to remove the Ads for that specific user after he re-installs the game.

    I now added this code to an empty GameObject named RestoreAdRemoval and added this to an IAP Listener in the main scene. But it doesn't run on the Android device. Still not sure how to correctly implement this.


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Purchasing;
    5.  
    6. public class RestoreAdRemoval : MonoBehaviour {
    7.  
    8.  
    9.     static IStoreController controller;
    10.  
    11.     int adsBought;
    12.  
    13.  
    14.     // Use this for initialization
    15.     void Start () {
    16.  
    17.     }
    18.  
    19.  
    20. #if UNITY_ANDROID
    21.     public void RemoveAdsIfAlreadyOwned()
    22.     {
    23.         foreach (Product product in controller.products.all)
    24.         {
    25.  
    26.  
    27.             if (product.hasReceipt)
    28.             {
    29.  
    30.                 if (!SPrefs.HasKey("AdsBought"))
    31.                 {
    32.                     adsBought = 1;
    33.                     SPrefs.SetInt("AdsBought", adsBought);
    34.                     SPrefs.Save();
    35.                 }
    36.             }
    37.         }
    38.      
    39.     }
    40.  
    41. #endif
    42. }
    This is the screenshot from the main scene with the IAP Listener: http://prntscr.com/khnh44
    In the main level I have the IAP Button.
     
    Last edited: Aug 12, 2018
  16. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    Anyone??
     
  17. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please provide the device logs here (not in a private message and please remove any private info) along with your analysis of the logs (look for your Debug.Log statements) and look for any exceptions such as Duplicate Transaction. I'm hoping to test this scenario with Codeless IAP later this week
     
    Jojoba007 likes this.
  18. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    Thank you so far. Ok, i’ll try.
     
  19. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    Hi Jeff, here is the log. I hope you can help me out, because i'm a bit stuck at the moment. Search the whole internet for a solution or an example script to check if a previous purchase has been made for android and save it to secured PlayerPrefs. ;):(

    I can see in the log the Purchase was failed due to Ïtem already owned". But I can also see a "DuplicateTransaction" event.

    Wat does this mean?

    Code (CSharp):
    1. 08-11 12:13:38.536 14534 14534 D ActivityThread: add activity client record, r= ActivityRecord{5ba164b token=android.os.BinderProxy@7b7c5c2 {dado.jumphero/com.unity3d.player.UnityPlayerActivity}} token= android.os.BinderProxy@7b7c
    2. 08-11 12:16:07.494 14534 14534 D ActivityThread: add activity client record, r= ActivityRecord{62c46e token=android.os.BinderProxy@2468804 {dado.jumphero/com.unity3d.ads.adunit.AdUnitActivity}} token= android.os.BinderProxy@24688
    3. 08-11 12:16:35.736 14534 14534 D ActivityThread: Remove activity client record, r= ActivityRecord{62c46e token=android.os.BinderProxy@2468804 {dado.jumphero/com.unity3d.ads.adunit.AdUnitActivity}} token= android.os.BinderProxy@246
    4. 08-11 12:16:49.751 14534 14534 D ActivityThread: add activity client record, r= ActivityRecord{88a96d0 token=android.os.BinderProxy@b624acd {ado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@b6
    5. 08-11 12:16:49.834 14534 14534 D ActivityThread: Remove activity client record, r= ActivityRecord{88a96d0 token=android.os.BinderProxy@b624acd {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@b6
    6. 08-11 12:16:52.865 14534 14534 D ActivityThread: add activity client record, r= ActivityRecord{e8dcd32 token=android.os.BinderProxy@3eaa294 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@3ea
    7. 08-11 12:16:52.925 14534 14534 D ActivityThread: Remove activity client record, r= ActivityRecord{e8dcd32 token=android.os.BinderProxy@3eaa294 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@3ea
    8. 08-11 12:16:54.405 14534 14534 D ActivityThread: add activity client record, r= ActivityRecord{560f439 token=android.os.BinderProxy@d91ca83 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@d91
    9. 08-11 12:16:54.459 14534 14534 D ActivityThread: Remove activity client record, r= ActivityRecord{560f439 token=android.os.BinderProxy@d91ca83 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@d9
    10. 08-11 12:16:55.085 14534 14534 D ActivityThread: add activity client record, r= ActivityRecord{7bfb02c token=android.os.BinderProxy@1c78a7e {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@1c78
    11. 08-11 12:16:55.172 14534 14534 D ActivityThread: Remove activity client record, r= ActivityRecord{7bfb02c token=android.os.BinderProxy@1c78a7e {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@1c78
    12. 08-11 12:17:03.286 14534 14534 D ActivityThread: add activity client record, r= ActivityRecord{a406b56 token=android.os.BinderProxy@b8da318 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@b8da
    13. 08-11 12:17:03.337 14534 14534 D ActivityThread: Remove activity client record, r= ActivityRecord{a406b56 token=android.os.BinderProxy@b8da318 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@b8d
    14. 08-11 12:17:07.144 14534 14534 D ActivityThread: add activity client record, r= ActivityRecord{e6133ad token=android.os.BinderProxy@8a617d7 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@8a617
    15. 08-11 12:17:07.203 14534 14534 D ActivityThread: Remove activity client record, r= ActivityRecord{e6133ad token=android.os.BinderProxy@8a617d7 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@8a61
    16. 08-11 12:18:58.545 14534 14534 D ActivityThread: add activity client record, r= ActivityRecord{a7ed260 token=android.os.BinderProxy@2a3cc92 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@2a3c
    17. 08-11 12:18:58.602 14534 14534 D ActivityThread: Remove activity client record, r= ActivityRecord{a7ed260 token=android.os.BinderProxy@2a3cc92 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@2a3c
    18. 08-11 12:21:18.357 14970 14970 D ActivityThread: add activity client record, r= ActivityRecord{5ba164b token=android.os.BinderProxy@7b7c5c2 {dado.jumphero/com.unity3d.player.UnityPlayerActivity}} token= android.os.BinderProxy@7b7c
    19. 08-11 12:21:56.982 14970 14970 D ActivityThread: add activity client record, r= ActivityRecord{d4eb76c token=android.os.BinderProxy@f9b5e72 {cdado.jumphero/com.unity3d.ads.adunit.AdUnitActivity}} token= android.os.BinderProxy@f9b5
    20. 08-11 12:22:16.124 14970 14970 D ActivityThread: Remove activity client record, r= ActivityRecord{d4eb76c token=android.os.BinderProxy@f9b5e72 {dado.jumphero/com.unity3d.ads.adunit.AdUnitActivity}} token= android.os.BinderProxy@f9b5
    21. 08-11 12:22:21.667 14970 14970 D ActivityThread: add activity client record, r= ActivityRecord{30d11ce token=android.os.BinderProxy@fe61693 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@fe61
    22. 08-11 12:22:21.749 14970 14970 D ActivityThread: Remove activity client record, r= ActivityRecord{30d11ce token=android.os.BinderProxy@fe61693 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@fe61
    23. 08-11 12:26:26.270 15558 15558 D ActivityThread: add activity client record, r= ActivityRecord{5ba164b token=android.os.BinderProxy@7b7c5c2 {dado.jumphero/com.unity3d.player.UnityPlayerActivity}} token= android.os.BinderProxy@7b7
    24. 08-11 12:27:09.574 15558 15558 D ActivityThread: add activity client record, r= ActivityRecord{3f2281f token=android.os.BinderProxy@d88f7d {dado.jumphero/com.unity3d.ads.adunit.AdUnitActivity}} token= android.os.BinderProxy@d88
    25. 08-11 12:27:44.288 15558 15558 I Unity   : onResume
    26. 08-11 12:27:44.311 15558 15578 D Unity   : SetWindow 0 0xdd254808
    27. 08-11 12:27:44.311 15558 15578 D Unity   : SetWindow 0 0xdd254808
    28. 08-11 12:27:44.314 15558 15558 I Unity   : windowFocusChanged: true
    29. 08-11 12:27:44.316 15558 15578 D Unity   : [EGL] Attaching window :0xdd254808
    30. 08-11 12:27:44.336 15558 15578 D Unity   : ANativeWindow: (1080/2160) RequestedResolution: (0/0) RenderingResolution: (0/0) EGLSurface: (1080/2160)
    31. 08-11 12:27:44.351 15558 15578 D Unity   : Sensor :        Accelerometer ( 1) ; 0.009577 / 0.00s ; accelerometer-kx023 / KIONIX
    32. 08-11 12:27:44.356 15558 15578 D Unity   : Choreographer available: Enabling VSYNC timing
    33. 08-11 12:27:44.393   625   813 E BufferQueueProducer: [dado.jumphero/com.unity3d.ads.adunit.AdUnitActivity#0] disconnect: not connected (req=1)
    34. 08-11 12:27:44.418   625   813 E BufferQueueProducer: [dado.jumphero/com.unity3d.ads.adunit.AdUnitActivity#0] disconnect: not connected (req=1)
    35. 08-11 12:27:44.510 15558 15558 D ActivityThread: Remove activity client record, r= ActivityRecord{3f2281f token=android.os.BinderProxy@d88 {dado.jumphero/com.unity3d.ads.adunit.AdUnitActivity}} token= android.os.BinderProxy@d88f
    36. 08-11 12:27:45.208 15558 15698 I UnityAds: com.unity3d.ads.api.Sdk.logInfo() (line:70) :: Closing Unity Ads ad unit
    37. 08-11 12:27:48.853 15558 15578 I Unity   : IAPButton.PurchaseProduct() with product ID: dado.adsremoved
    38. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    39. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    40. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.Logger:Log(LogType, Object)
    41. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.Debug:Log(Object)
    42. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.Purchasing.IAPButton:PurchaseProduct() (at D:\Unity Projects\Jump Hero\Jump Hero\Assets\Plugins\UnityPurchasing\script\IAPButton.cs:107)
    43. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.Events.InvokableCall:Invoke() (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:166)
    44. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.Events.UnityEvent:Invoke() (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:58)
    45. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.UI.Button:Press() (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\UI\Core\Button.cs:36)
    46. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.UI.Button:OnPointerClick(PointerEventData) (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\UI\Core\Button.cs:45)
    47. 08-11 12:27:48.853 15558 15578 I Unity   : UnityEngine.EventSystems.ExecuteEvents:Execute(IPointerClickHandler, BaseEventData) (at C:\buildslav
    48. 08-11 12:27:48.865 15558 15578 I UnityIAP: onPurchaseProduct: dado.adsremoved
    49. 08-11 12:27:48.865 15558 15578 I UnityIAP: ITEM TYPE:inapp
    50. 08-11 12:27:48.878 15558 15558 I Unity   : onPause
    51. 08-11 12:27:48.886 15558 15578 I Unity   : purchase({0}): dado.adsremoved
    52. 08-11 12:27:48.886 15558 15578 I Unity   : UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    53. 08-11 12:27:48.886 15558 15578 I Unity   : UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    54. 08-11 12:27:48.886 15558 15578 I Unity   : UnityEngine.Logger:Log(String, Object)
    55. 08-11 12:27:48.886 15558 15578 I Unity   : UnityEngine.Purchasing.PurchasingManager:InitiatePurchase(Product, String) (at /Users/stevenb/unity-src3/Extensions/UnityPurchasing/Runtime/Purchasing/PurchasingManager.cs:61)
    56. 08-11 12:27:48.886 15558 15578 I Unity   : UnityEngine.Purchasing.PurchasingManager:InitiatePurchase(String, String) (at /Users/stevenb/unity-src3/Extensions/UnityPurchasing/Runtime/Purchasing/PurchasingManager.cs:69)
    57. 08-11 12:27:48.886 15558 15578 I Unity   : UnityEngine.Purchasing.PurchasingManager:InitiatePurchase(String) (at /Users/stevenb/unity-src3/Extensions/UnityPurchasing/Runtime/Purchasing/PurchasingManager.cs:43)
    58. 08-11 12:27:48.886 15558 15578 I Unity   : UnityEngine.Purchasing.CodelessIAPStoreListener:InitiatePurchase(String) (at D:\Unity Projects\Jump Hero\Jump Hero\Assets\Plugins\UnityPurchasing\script\CodelessIAPStoreListener.cs:147)
    59. 08-11 12:27:48.886 15558 15578 I Unity   : UnityEngine.Purchasing.IAPButton:PurchaseProduct() (at D:\Unity Projects\Jump Hero\Jump Hero\Assets\Plugi
    60. 08-11 12:27:48.889 15558 15578 I UnityIAP: isUnityVrEnabled = false
    61. 08-11 12:27:48.912 15558 15578 D Unity   : Sensor :        Accelerometer ( 1) ; 0.009577 / 0.00s ; accelerometer-kx023 / KIONIX
    62. 08-11 12:27:48.935 15558 15558 I UnityIAP: Creating purchase activity
    63. 08-11 12:27:48.936 15558 15558 I UnityIAP: oldSkuMetadata is null
    64. 08-11 12:27:48.937 15558 15702 I UnityIAP: invoking callback
    65. 08-11 12:27:48.937 15558 15702 I UnityIAP: Constructing buy intent for dado.adsremoved, item type: inapp
    66. 08-11 12:27:48.950 15558 15558 D ActivityThread: add activity client record, r= ActivityRecord{2a1d559 token=android.os.BinderProxy@352fdd2 {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@352fd
    67. 08-11 12:27:48.961 15558 15702 I UnityIAP: onIabPurchaseFinished: false
    68. 08-11 12:27:48.961 15558 15702 I UnityIAP: Unable to buy item (response: 7:Item Already Owned)
    69. 08-11 12:27:48.962 15558 15702 I UnityIAP: Purchase response code:7
    70. 08-11 12:27:48.966 15558 15558 I Unity   : windowFocusChanged: false
    71. 08-11 12:27:48.996 15558 15558 I Unity   : windowFocusChanged: true
    72. 08-11 12:27:48.999 15558 15558 I Unity   : onResume
    73. 08-11 12:27:49.005 15558 15578 D Unity   : Sensor :        Accelerometer ( 1) ; 0.009577 / 0.00s ; accelerometer-kx023 / KIONIX
    74. 08-11 12:27:49.008 15558 15578 D Unity   : Choreographer available: Enabling VSYNC timing
    75. 08-11 12:27:49.035 15558 15558 I UnityIAP: onActivityResult
    76. 08-11 12:27:49.036 15558 15558 D ActivityThread: Remove activity client record, r= ActivityRecord{2a1d559 token=android.os.BinderProxy@352fd {dado.jumphero/com.unity.purchasing.googleplay.PurchaseActivity}} token= android.os.BinderProxy@352fd
    77. 08-11 12:27:49.078 15558 15578 I Unity   : onPurchaseFailedEvent({0}): comdidado.adsremoved
    78. 08-11 12:27:49.078 15558 15578 I Unity   : UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    79. 08-11 12:27:49.078 15558 15578 I Unity   : UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    80. 08-11 12:27:49.078 15558 15578 I Unity   : UnityEngine.Logger:Log(String, Object)
    81. 08-11 12:27:49.078 15558 15578 I Unity   : UnityEngine.Purchasing.PurchasingManager:OnPurchaseFailed(PurchaseFailureDescription) (at /Users/stevenb/unity-src3/Extensions/UnityPurchasing/Runtime/Purchasing/PurchasingManager.cs:137)
    82. 08-11 12:27:49.078 15558 15578 I Unity   : UnityEngine.Purchasing.JSONStore:OnPurchaseFailed(PurchaseFailureDescription, String)
    83. 08-11 12:27:49.078 15558 15578 I Unity   : UnityEngine.Purchasing.JSONStore:OnPurchaseFailed(String)
    84. 08-11 12:27:49.078 15558 15578 I Unity   : UnityEngine.Purchasing.<>c__DisplayClass6_0:<OnPurchaseFailed>b__0()
    85. 08-11 12:27:49.078 15558 15578 I Unity   : UnityEngine.Purchasing.Extension.UnityUtil:Update()
    86. 08-11 12:27:49.078 15558 15578 I Unity   :
    87. 08-11 12:27:49.078 15558 15578 I Unity   : (Filename: /Users/stevenb/unity-src3/Extensions/UnityPurchasing/Runtime/Purchasing/PurchasingManager.cs Line: 137)
    88. 08-11 12:27:49.078 15558 15578 I Unity   :
    89. 08-11 12:27:49.092 15558 15578 I Unity   : IAPButton.OnPurchaseFailed(Product UnityEngine.Purchasing.Product, PurchaseFailureReason DuplicateTransaction)
    90. 08-11 12:27:49.092 15558 15578 I Unity   : UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
    91. 08-11 12:27:49.092 15558 15578 I Unity   : UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    92. 08-11 12:27:49.092 15558 15578 I Unity   : UnityEngine.Logger:Log(LogType, Object)
    93. 08-11 12:27:49.092 15558 15578 I Unity   : UnityEngine.Debug:Log(Object)
    94. 08-11 12:27:49.092 15558 15578 I Unity   : UnityEngine.Purchasing.IAPButton:OnPurchaseFailed(Product, PurchaseFailureReason) (at D:\Unity Projects\Jump Hero\Jump Hero\Assets\Plugins\UnityPurchasing\script\IAPButton.cs:179)
    95. 08-11 12:27:49.092 15558 15578 I Unity   : UnityEngine.Purchasing.CodelessIAPStoreListener:OnPurchaseFailed(Product, PurchaseFailureReason) (at D:\Unity Projects\Jump Hero\Jump Hero\Assets\Plugins\UnityPurchasing\script\CodelessIAPStoreListener.cs:222)
    96. 08-11 12:27:49.092 15558 15578 I Unity   : UnityEngine.Purchasing.StoreListenerProxy:OnPurchaseFailed(Product, PurchaseFailureReason) (at /Users/stevenb/unity-src3/Extensions/UnityPurchasing/Runtime/Purchasing/StoreListenerProxy.cs:40)
    97. 08-11 12:27:49.092 15558 15578 I Unity   : UnityEngine.Purchasing.PurchasingManager:OnPurchaseFailed(PurchaseFailureDescription) (at /Users/stevenb/unity-src3/Exte
    98. 08-11 12:29:16.046 15558 15558 I Unity   : onPause
    99. 08-11 12:29:16.095 15558 15578 D Unity   : Sensor :        Accelerometer ( 1) ; 0.009577 / 0.00s ; accelerometer-kx023 / KIONIX
    100. 08-11 12:29:16.114 15558 15558 V ActivityThread: Finishing stop of ActivityRecord{5ba164b token=android.os.BinderProxy@7b7c5 {dado.jumphero/com.unity3d.player.UnityPlayerActivity}}
    101. 08-11 12:29:16.137 15558 15578 D Unity   : SetWindow 0 0x0
    102. 08-11 12:29:40.620   625   625 D SurfaceFlinger: duplicate layer name: changing SurfaceView - dado.jumphero/com.unity3d.player.UnityPlayerActivity to SurfaceView - dado.jumphero/com.unity3d.player.UnityPlayerActivity#1
    103. 08-11 12:29:40.621   625   625 D SurfaceFlinger: duplicate layer name: changing Background for - SurfaceView - dado.jumphero/com.unity3d.player.UnityPlayerActivity to Background for - SurfaceView - dado.jumphero/com.unity3d.player.UnityPlayerActivity#1
    104. 08-11 12:29:40.625 15558 15578 D Unity   : SetWindow 0 0xc71ae808
    105. 08-11 12:29:40.627   625  1753 E SurfaceFlinger: Failed to find layer (Background for - SurfaceView - dado.jumphero/com.unity3d.player.UnityPlayerActivity#0) in layer parent (no-parent).
    106. 08-11 12:29:40.627 15558 15578 D Unity   : SetWindow 0 0xc71ae808
    107. 08-11 12:29:40.628   625  2578 E SurfaceFlinger: Failed to find layer (SurfaceView - dado.jumphero/com.unity3d.player.UnityPlayerActivity#0) in layer parent (no-parent).
    108. 08-11 12:29:40.679 15558 15558 I Unity   : onResume
    109. 08-11 12:29:40.679 15558 15578 D Unity   : [EGL] Attaching window :0xc71ae808
    110. 08-11 12:29:40.714 15558 15578 D Unity   : ANativeWindow: (1080/2160) RequestedResolution: (0/0) RenderingResolution: (0/0) EGLSurface: (1080/2160)
    111. 08-11 12:29:40.748 15558 15578 D Unity   : Sensor :        Accelerometer ( 1) ; 0.009577 / 0.00s ; accelerometer-kx023 / KIONIX
    112. 08-11 12:29:40.765 15558 15578 D Unity   : Choreographer available: Enabling VSYNC timing
    113. 08-11 12:29:52.552 15558 15558 I Unity   : onPause
    114. 08-11 12:29:52.554  1246  1256 V WindowManager: findFocusedWindow: AppWindowToken{50e2c21 token=Token{f6a5a88 ActivityRecord{ed0362b u0 dado.jumphero/com.unity3d.player.UnityPlayerActivity t17}}} below Reached focused app=AppWindowToken{2492801 token=Token{1c659e8 ActivityRecord{ce9170b u0 com.android.systemui/.recents.RecentsActivity t4}}}
    115. 08-11 12:29:52.603 15558 15578 D Unity   : Sensor :        Accelerometer ( 1) ; 0.009577 / 0.00s ; accelerometer-kx023 / KIONIX
    116. 08-11 12:29:52.628 15558 15558 I Unity   : windowFocusChanged: false
    117. 08-11 12:29:52.634 15558 15578 D Unity   : SetWindow 0 0x0
    118. 08-11 12:29:52.658  1246  2944 V WindowManager: notifyAppStopped: AppWindowToken{50e2c21 token=Token{f6a5a88 ActivityRecord{ed0362b u0 dado.jumphero/com.unity3d.player.UnityPlayerActivity t17}}}
    119. 08-11 12:29:52.838  1246  1354 V WindowManager: Exit animation finished in Window{420ef6 u0 dado.jumphero/com.unity3d.player.UnityPlayerActivity EXITING}: remove=false
    120. 08-11 12:29:52.838  1246  1354 E WindowManager: win=Window{420ef6 u0 com.didado.jumphero/com.unity3d.player.UnityPlayerActivity EXITING} destroySurfaces: appStopped=true win.mWindowRemovalAllowed=false win.mRemoveOnExit=false
    121. 08-11 12:29:52.839  1246  1354 I WindowManager: Destroying surface Surface(name=dado.jumphero/com.unity3d.player.UnityPlayerActivity) called by com.android.server.wm.WindowStateAnimator.destroySurface:2060 com.android.server.wm.WindowStateAnimator.destroySurfaceLocked:873 com.android.server.wm.HwWindowStateAnimator.destroySurfaceLocked:1006 com.android.server.wm.WindowState.destroyOrSaveSurfaceUnchecked:2990 com.android.server.wm.WindowState.destroySurface:2951 com.android.server.wm.AppWindowToken.destroySurfaces:654 com.android.server.wm.AppWindowToken.destroySurfaces:638 com.android.server.wm.WindowState.onExitAnimationDone:4410
    122. 08-11 12:29:54.749 15558 15558 I Unity   : onDestroy
    123. 08-11 12:29:55.014  1246  3383 I WindowManager: WIN DEATH: Window{420ef6 u0 dado.jumphero/com.unity3d.player.UnityPlayerActivity}
    124. 08-11 12:29:55.014  1246  3383 V WindowManager: removeIfPossible: Window{420ef6 u0 dado.jumphero/com.unity3d.player.UnityPlayerActivity} callers=com.android.server.wm.WindowState.-wrap1:0 com.android.server.wm.WindowState$DeathRecipient.binderDied:2481 android.os.BinderProxy.sendDeathNotice:840 <bottom of call stack> <bottom of call stack>
    125. 08-11 12:29:55.016  1246  3383 V WindowManager: postWindowRemoveCleanupLocked: Window{420ef6 u0 com.didado.jumphero/com.unity3d.player.UnityPlayerActivity}
    126. 08-11 12:29:55.016  1246  3383 V WindowManager: Removing Window{420ef6 u0 dado.jumphero/com.unity3d.player.UnityPlayerActivity} from AppWindowToken{50e2c21 token=Token{f6a5a88 ActivityRecord{ed0362b u0 com.didado.jumphero/com.unity3d.player.UnityPlayerActivity t17}}}
    127. 08-11 12:29:55.079  1246  5859 V WindowManager: removeAppToken: AppWindowToken{50e2c21 token=Token{f6a5a88 ActivityRecord{ed0362b u0 com.didado.jumphero/com.unity3d.player.UnityPlayerActivity t17}}} delayed=false Callers=com.android.server.wm.DisplayContent.removeAppToken:985 com.android.server.wm.AppWindowContainerController.removeContainer:348 com.android.server.am.ActivityRecord.removeWindowContainer:1039 com.android.server.am.ActivityStack.removeActivityFromHistoryLocked:4493
    128.  
     
  20. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please describe the logs that you provided. It looks like there are purchase button clicks? I am looking for the initialization only, perhaps that is what you have provided. I see the adsremoved purchase, was this a manual purchase or the callback during initialization? Item Already Owned would be expected if you are trying to purchase again. Please post your log as an attachment for easier reading, use the Upload a File button at the bottom.
     
  21. Jojoba007

    Jojoba007

    Joined:
    Feb 11, 2017
    Posts:
    148
    The following log file is the part where the game starts. It has all kind of stuff for the Ads in it.
    My IAP button is in the main level scene. I had bought a non-consumable product (ad remover) for this specific Play Store account.

    These are parts of the startup log:

    com.unity3d.ads.device.Storage.sendEvent() (line:82) :: Couldn't send storage event to WebApp
    (line:105) :: Wrote file: /storage/emulated/0/Android/data/dado.jumphero/cache/UnityAdsCache/UnityAdsStorage-public-data.json

    and

    (line:160) :: Unity Ads environment check OK
    Initializing UnityPurchasing via Codeless IAP

    com.unity3d.ads.configuration.InitializeThread$InitializeStateLoadCache.execute() (line:267) :: Unity Ads init: webapp loaded from local cache

    Subscriptions AVAILABLE.
    Subscription upgrade and downgrade are AVAILABLE.
    Package name: dado.jumphero
    Sku is owned: dado.adsremoved
    Owned items response: 0
    Purchase history response: 0

    The number of owned skus is0
    The number of purchased skus is1

    Purchase not correctly processed for product "comdidado.adsremoved". Add an active IAPButton to process this purchase, or add an IAPListener to receive any unhandled purchase events.


    What does all of this mean. Sorry still new and trying hard to find out.
    In the Unity Editor I get the following message, see screenshot: http://prntscr.com/kikzpp
     

    Attached Files:

    Last edited: Aug 14, 2018
  22. mahmoud93p

    mahmoud93p

    Joined:
    Feb 11, 2015
    Posts:
    66
    if someone has already bought the non-consumable product in google play ! you can't show again price or dialog from google play because this is non-consumable can't bought again if you test anther device does't bought you will see your iap is work .
     
  23. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    A user can only purchase a non-consumable once, and therefore its name. To test again, you need to configure several non-consumable products, or use a separate/another test account.