Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

IAP is restoring consumable items

Discussion in 'Unity IAP' started by martman100, May 11, 2020.

Thread Status:
Not open for further replies.
  1. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Using IAP and for some reason, the restore purchases on the google play is restoring consumable items. That is not good since it will basically allow people to uninstall and install and get all of their in game gold again. I have noticed it is actually restoring on every load it appears but I have

    Anyone experienced this problem?

    I wouldn't expect the processpurchase callback to be executed on consumable items. I have google play game services installed as well since I backup players data to playfab but at this time I am not loading data from playfab. Additionally with LogCat I can see it restoring the purchase of a consumable item.
     
  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please provide the logcat logs as an attachment here. Also show how you are defining the product in your code and please provide a screenshot of how the product is defined on your Google Play Developer dashboard. Are you using Codeless IAP? If so, make sure the Consume Product checkbox is checked under the button properties.
     
  3. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Not using codeless. I am doing some additional testing. I don't recall having this problem until after I added Google Play Services. Added that in for Playfab authentication rather than Facebook. Just did a quick test with GPGS commented out and didn't see the restore process take the same path. I am now doing a test using the social api but not the GPGS plugins and will see if I get the same issue.
     
  4. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Here is the IAP and Google play scripts I am using. Did a test where I commented out the GPGS initialization and only used the Unity Social API and did not have an IAP restore problem. The main reason I was using GPGS is to get a server auth code for Playfab Authentication. However, it seems there is a problem with GPGS and Unity IAP on the same device with restore or I am doing it wrong.
     

    Attached Files:

  5. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I would expect your REMOVEADS product to be restored each time. IAP depends on the user who made the purchase, be logged into the Google Play app on the device as this user. Do any of those other libraries log the user off? Restore only happens for subscriptions and non-consumables on Android and there is no separate "Restore" button or functionality like on iOS. On Android it happens automatically, and you would expect ProcessPurchase to be called at IAP initialization for a new install for this product. Also, we need the logcat logs, can you attach them? IAP automatically writes debug information to the logs https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/
     
  6. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Let me restore the code to how it was breaking and I will run a new adb log. Give me a few. And yes even when it was restoring incorrectly it was restoring the removeads as expected. But I was also getting the restoration of the others that had been purchased as well. So a wipe and new install would result in it restoring a 250, 50, and 500 gold that I had previously purchased. I did just happen to stumble on this link that I have never come across before.

    https://developer.android.com/google/play/billing/unity
     
    Last edited: May 12, 2020
  7. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Make sure the same user stays logged into the Play Store app on the device.
     
  8. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Is there a way I can email or send this logcat without posting on the public forum? I have recreated the issue.

    Basically I have a startup scene that initializes my playerprefs and Unity Ads. And that async loads the mainentry scene. At that point I have the google play script that I have attached on scene level gameobject. The attached IAP script is basically initialized when someone clicks a "BuyGold" button. Based on the link I posted above it almost appears I should be using the GooglePlay billing instead of the standard store controller but I am not certain on that.
     

    Attached Files:

  9. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
  10. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Sorry, please provide only the relevant logs as an attachment here. Please attach a screenshot of where you say the "Restore" is occurring. It would be in ProcessPurchase, so make sure to put clear Debug logs there.
     
  11. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    I am doing more debugging and different approaches. I did find a situation where I have a null reference during the purchase callback because I was initializing the IAP and the callback has a reference to a UI item that was not available at that time. Could that have been causing the purchase to be left in pending and then the next time I opened the app it completed the purchase?
     
  12. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    No, not likely. Please debug as suggested.
     
  13. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    I have revamped my process and I am still not 100% certain what the scenario is. I know that I created a new build and installed that APK and then it did some crazy restoring. But it stopped after like the second load. I uninstalled and installed the same apk and have done that several times without issue. If I can identify what when the problem is recreated I will post back here.
     
  14. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please debug as suggested. Is ProcessPurchase being called? It is not a Restore that is occurring, that only applies to Subscriptions and Non-Consumables. You may have a stuck transaction, debugging will show the issue. No need to share the full logs, go through them first and pull out all your debug statements. You can search for UnityIAP ( case insensitive) for the IAP system debug output in the logcat logs, please provide those lines too.
     
  15. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    I have done that and it has been inconsistent on what it is doing. I will continue to research. Seems like it is something I am doing with it being inconsistent.
     
  16. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please provide your updated code with the additional debug.log statements. One key question, is ProcessPurchase being fired? Let me know if you have any questions around that statement, it is very important. Place your debug statements there, and provide the results between each of your tests (just the debug output). ProcessPurchase is fired when you make a new purchase, and when products are restored. https://forum.unity.com/threads/tips-for-new-unity-users.701864/#post-5057741
     
  17. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Okay I have spent a tremendous amount of time on this and of all things for some reason can't get the ADB to pipe to a file with the filter of unityiap. However, I have recreated. So here is what the process was for this. And this is all testing with a test google account

    Was within the game buying items via gold. Had a balance of 740 gold, made a purchase of 100 gold. Closed the app, not just suspend. Re-opened and it restored the last purchase I made of 100 gold and gave me a balance of 940 gold. In the app. This was the second occurence and the first time I recreated it also restored the last purchase I made. Not all purchases just the last purchase.

    I have no idea why this won't pipe to a file with unityiap as the filter. Done this 1000 times. It does fine with other items.
    using the command
    adb logcat | findstr -i unityIAP c:\temp\iaplog.txt

    upload_2020-5-12_18-41-55.png
     

    Attached Files:

  18. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Here is the earlier transactions of the log. You can see where the actual purchase took place for the 100 gold.

    upload_2020-5-12_18-51-9.png
     
  19. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    As requested, only copy your Debug.Log statements here, specifically the ones in ProcessPurchase. What was the result of your debugging? I'm not seeing any of your debug statements in the log? You are calling ReportPurchaseResult all the time, and it in turn calls OnIAPPurchaseCompleted. That could be causing your issue. Don't do any of that, get the basics working first.Please use the Sample IAP Project, and get it working first. And PLEASE log from ProcessPurchase, you have the string already in purchaseResult. Use Debug.Log to track the flow of your code. The correct syntax for adb logcat is mentioned here https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/ The Sample IAP Project is here https://forum.unity.com/threads/sample-iap-project.529555/
     
  20. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, I see the purchase. This would occur when you click the Purchase button.
     
  21. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Everything in there that has a UnityIAP - IAPManager - are my debug statements that I created in Unity. The report purchase result is just an event delegate so I can update appropriate UI items. IAPManager that I attached is basically a singleton of which you can see all of the debug statements. In the snippet at the very end where it says it is consuming sku is the areas that were done at time of app start. Which 100gold is the last purchase I performed before closing the app and re-opening where it applied the 100gold. What is interesting is it says "Finish transaction:GPA...." And above that you can see where the processpurchase callback occurred for the 100 gold that I have already purchased, received a success, and processed. Processpurchase callback should not be happening on a consumable item and that is in the UnityIAP modules. As far as I know there is no way to know in the processpurchase callback that you can determine if it is a restore or purchase.

    More importantly I cannot get this to pipe to a file through adb if I have the findstr -i unityiap


    upload_2020-5-12_19-15-43.png
     
  22. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Here is a dump of the log. That has the issue. In app I had 540 gold. Made a purchase of 750 which showed in the app as 1290 as a balance. If you go to line 30 in the attached log you can see where I have a debug statement showing where I initiate that purchase. Looks like line 55 is where all is complete on the actual purchase. I then closed the game and re-opened which is why you see the 26 second delay between lines 55 and 56. It performed the 750 purchase again and I can see in game the amount go from 1290 to 2570. Basically everything from line 56 down is the initializing and restoration process of unity iap.

    Seems that it is restoring the last consumable purchase that is made. I will also test a longer delay between the time I make my last purchase and a restart to see if something is hanging.
     

    Attached Files:

  23. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I believe you are missing the > character for logcat as described in the article. I'm having trouble reading your verbose logs, you mention "It performed the 750 purchase again and I can see in game the amount go from 1290 to 2570". Can you share just that log entry? And this second purchase occurs on IAP initialization after you quit the app the first time (swipe the app up on the Android task list to close it). Please compare to the Sample IAP Project. Tip, don't use Application.Quit if you are using this method to exit your game. Also, you can see the purchases on your Google Play account for this user, are you actually seeing duplicate purchases in your Google account reports?
     
  24. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    So when I say the amount go from 1290 to 2570 I am saying in the game UI and I can see it saved to playfab and when I reopen the app it is pulling from playerprefs as well. I get emails to the account and only have one purchase anytime this happens including the 750. Not using application.quit. Just doing the swipe. The IAP is not supposed to be calling processpurchase for consumables on restore correct?

    But more importantly the reason it is adding the 750 again is due to the last callback on the re-open of the app. Basically the restore or whatever it is doing is saying "complete purchase for 750" which it had already completed.

    I have reviewed the sample IAP project. This is a pretty simple process in comparison to other stuff I have had to do in the game.
     
  25. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    Look on line 79 of the log I attached. Why is it reporting a sku being owned that is a consumable item. I have made many purchases of consumable items but the 750 was the last one I made.
     
  26. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    If you are truly seeing duplicate purchases, you will see two ProcessPurchase calls, one you can't explain, and your Google account will show the duplicate purchases. Please compare to the logs from the Sample IAP Project, and post your results here. If you find a bug in IAP using the Sample IAP project, then I will let the engineering team know and we can look into addressing it. First we need to reproduce here, and the Sample project will allow both of us to do just that.
     
  27. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    I am not saying that duplicate purchases are hitting the account. What I am saying is Unity IAP is telling the game there is another purchase. The customer basically is paying for 750 gold but getting 1500 because they are getting another 750 when they open the app again. Another call is not being made to google to make a purchase. It almost appears that the unityiap is checking for items that are owned and didn't flag the last purchase as consumable. Hence why it is showing as a sku that is owned along with the remove ads which is a non consumable.
     
  28. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    You should only award products in ProcessPurchase. Where are you adding the extra points? Unfortunately we are not able to debug your app. Please compare to the Sample IAP project, and if you see the same thing, we can go from there.
     
  29. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44

    So the flow is as such at a high level.

    player clicks to buy 750 gold
    unityiap storecontroller.InitiatePurchase is called.
    unityiap fires processpurchase callback
    developer handles successful purchase and gives player consumable item (gold)
    player closes game (with swipe)
    player opens game
    developer initializes unityiap
    unityiap checks for non cosumables that are owned

    THIS IS WHERE IT IS BREAKING
    UnityIAP is seeing a consumable as a sku that is owned.
    it is then doing a foreach on each owned sku which is causing the consumable item to be purchased (in the game not on the store) again.
    developer is handling the processpurchase and applying the purchases which in this instance is including a consumable item that the player may have already spent in the game before they closed it.

    What should be happening:
    UnityIAP gets all owned non consumables.
    foreach non consumable call processpurchase callback
    developer makes sure that the player is rewarded those items. Since they are non consumable the developer basically makes sure the player is credited.

    The code is pretty simple that I sent and each button is just calling the BuyProductID function.
     
  30. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44

    Is it in anyway possible that google play game services are causing this? I don't recall having this problem until I added google play game services to get the server auth code.

    This is this class for the android side where I intialize the google play services. I am just curious if the GPGS are triggering the unity iap to make a call back for some reason.
     

    Attached Files:

  31. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Got it, we have not heard of this behavior. I'm still not clear, but it sounds like you mentioned that ProcessPurchase is indeed being called twice? You are seeing a ProcessPurchase trigger right at app launch, after you reinstall? That is unusual. Please compare to the Sample Project and see if you see the same thing, and we can then try to reproduce and troubleshoot.
     
  32. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    And this line in the IAPManager I attached is where the gold purchase is getting granted to the player which is in the processpurchase callback.

    PlayerInfo.Instance.RecordGoldPurchase(purchaseAmount);
     
  33. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    It's possible but I have not heard of this, you would want to contact Google. Unity IAP is just a pass through service for the existing Google Billing Library. And as I previously mentioned but didn't hear back, make sure this same user is properly logged into the Google Play Store on device. If you can reproduce on the the Sample project, we could take a look.
     
  34. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44

    That is why I am wondering if the google play services are doing some billing operations and causing this?
     
  35. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    I will do further testing and let you know if I find anything. It is definitely the same sure logged into the device.

    Did you see this link I posted above? https://developer.android.com/google/play/billing/unity

    Seems like google says you need to use their purchasingmodule versus the unity standard. Maybe I will try that and see what happens.
     
  36. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    626
    Is the consumable product in the pending state? If the consumable product is in the pending state, then ProcessPurchase will still be called after the next initialization. Maybe you can try to call ConfirmPendingPurchase. https://docs.unity3d.com/Manual/UnityIAPProcessingPurchases.html
     
    JeffDUnity3D likes this.
  37. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    It has to be something like that. I have recreated this multiple times. I have reviewed the sample project again and as I watch the logs run in the console when I restart the game it appears as though the purchase has not been completed and UnityIAP thinks it needs to finish the transaction. I did some reading and I am also wondering if the when this happens the first attempt the purchase was successful but the product was not consumed immediately. Apparently if you don't consume immediately it will be in the queue and still be available for consumption but not in a pending state. Snippet below is from a restart of the app with nothing else being done. I notice that the 4th line from the bottom that states "Successfully consumed sku: com.crookedfinger.toughtruck.100gold" was not present on the initial purchase output before I restarted the app.


    upload_2020-5-13_7-50-46.png
     
  38. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44
    At what point would we need to call the confirmpendingpurchase? If the process purchase goes smoothly and we return a complete status then to me that transaction should be considered complete and no pending purchases exist.
     
  39. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    The transaction may not be complete, is the point. On next app launch after reinstall, you are claiming that another ProcessPurchase is automatically called. You would call ConfirmPendingPurchase at this point. You mentioned you are using the Sample IAP project? Great! How would we go through the same steps here (I wrote that sample)
     
  40. martman100

    martman100

    Joined:
    Sep 4, 2013
    Posts:
    44

    Its not on app reinstall. It is when they start the app next time. I have reviewed the sample project and done a ton of research on this. Seems like there are similar issues reported last year with purchases hanging but most are related to non consumable.

    Since I am not using the codeless approach please confirm the steps below.

    User clicks a button or something to initiate a purchase.
    Developer fires store controller .intiatepurchase(product)
    callback happens on processingpurchaseresult ProcessPurchase(PurchaseEventArgs args)
    Developer does the appropriate code to handle the purchase and give player goods (both consumable or non consumable)
    If everything is successuful developer returns ProcessingPurchaseResult.Complete


    Are you saying that on each start of the app the first thing that needs to happen is confirm purcahse? Since we have to initialize the IAP how can we ensure that is executed prior to the UnityIAP restore operations firing?
     
  41. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Typically you would not need to confirm a purchase during initialization, so something else is going on. Keep in mind that the title of this thread is "Restoring consumables". Restore only happen during reinstall. So it's not restore occurring. I believe you would agree that we have been quite responsive to your questions. To assist you further, we would require that you provide specific steps to reproduce. You haven't answered some key questions, like if you are using Application.Quit (which leaves components in memory) You have admitted yourself that it works as expected "until you add Google Play services". Please provide steps to reproduce with the Sample IAP project so we are all on the same page. It's preferred to start with a working project (the Sample IAP project) and customize as necessary, instead of trying to debug a non-working project. Thank you for understanding. I will lock this thread. Once you have the Sample IAP project working and you see the same issue, please open a new thread at that time and we can start fresh and investigate further.
     
    Last edited: May 15, 2020
Thread Status:
Not open for further replies.