Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Issues with TestFlight IAP restores (non-consumable)

Discussion in 'iOS and tvOS' started by BCStudios, Mar 11, 2019.

  1. BCStudios

    BCStudios

    Joined:
    Sep 25, 2016
    Posts:
    5
    Hi all, hoping that someone can shed some light on an issue we've been having while trying to test IAP on TestFlight.

    Bottom line: We're having issues when trying to restore purchases, and I'm unsure if it's an issue with the testflight accounts or an issue with our code.

    We're using a modified version of the example code, adjusted for our own product ID's and having added some functionality to inform UI etc. New users can make purchases as expected, no issues. If the same user signs in on a new device, or if the user deletes/reinstalls the app, "RestorePurchases" seems to work as intended on that device - but only the first time it's used on that device. After that, however, things break down. ProcessPurchase does not seem to be called again thereafter, either for restorations or direct purchases.
    If the user deletes/reinstalls again, restore does not work. Apple.RestoreTransactions((result) => {//dostuff} never executes the callback (//dostuff). Furthermore, attempting to buy a product that was purchased on a previous install only half works. The apple dialogue pops up, user inputs password, and then apple says that "This in-app purchase has already been bought. It will be restored for free." - however ProcessPurchase is not called, nor is RestorePurchases()

    Has anyone seen this before? I suspect it's an issue with the testflight accounts themselves, but I'm really not sure - it could be something in our unity side c#, but that code consistently works until we try the restore purchases edge case - and even then, it works the first time.

    This is on iOS12.1.4, latest version of TestFlight, and Unity 2017.3.1f1

    Thoughts or ideas appreciated!
     
    krisventure likes this.
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
  3. BCStudios

    BCStudios

    Joined:
    Sep 25, 2016
    Posts:
    5
    Jeff,

    Thanks for the response - I put it here because it's specific to iOS (and probably TestFlight) rather than IAP in general. I'll move this over to IAP for future posts, but for the benefit of those finding this thread here:

    It's understood that non-consumables should only be purchased once per user. We also do have multiple products and multiple testers. We're testing edge cases, and one of those is a delete/reinstall and attempted re-purchase before the player finds the "restore purchases" button (which is also not working in this case). I believe IAP's OnPurchaseFailed() should call when the player repurchases with a PurchaseFailureReason.DuplicateTransaction.
    On iOS, once the phone is in this state, OnPurchaseFailed is not called, nor is ProcessPurchase() when the native modal states that the item "will be restored for free"

    Looking at the log files, it does seem like a failure because of a "method called without a valid ACAccountStore", and that account type <private> "does not support multiples"
    -This seems more and more like crossed wires between the TestFlight accounts and the actual user accounts, but if anyone has further insight I'd really appreciate it!
     
  4. oguz1ak

    oguz1ak

    Joined:
    Jul 10, 2015
    Posts:
    5
    Hi @BCStudios , did you find a solution to this? I am having almost the same problem. I tried to find some error in my code for a long time, but it seems it is in Apples side.

    I find a related post (not the same case but similar here). It says, it would be related some confusion about using live Apple Id in test flight. As far as I understand, live apple id and sandbox account id in the test flight is the same and because of that "restore purchases" is failing. But if you have a different solution please share.
     
    krisventure likes this.
  5. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please describe your current issue.
     
  6. oguz1ak

    oguz1ak

    Joined:
    Jul 10, 2015
    Posts:
    5
    I am testing "restore purchases" funcionality for IOS. I used always "Test Flight" in my ipad with my live apple id. But "restore purchases" did not bring previously bought non-consumable products. I though there was a problem in my code, I search for the code implementation. But finally I found that it is related with using Test Flight with live apple id.

    Today I used sandbox account with a different email and "restore purchases button" worked correctly. It seems my problem is solved. Thanks!
     
    JeffDUnity3D likes this.
  7. Robert_Hildebrand

    Robert_Hildebrand

    Joined:
    Sep 19, 2018
    Posts:
    15
    Hello Everyone,

    I'm having the exact same problem with Test Flight right now. I'm using Simple IAP that sits on top of Unity IAP but I can confirm that the process to restore transactions is not working with Test Flight for me using 2019.4 LTS.

    However, If I try to purchase the non-consumable again, the purchase detects that I've already purchased the item and everything works as normal.

    The restore purchases mechanism should call ProcessPurchase and it's not in test flight. If you deploy to your device using Xcode and run it from there, it will work properly. Don't go through testflight and see if this works.
     
    krisventure likes this.
  8. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Can you share the Restore code that Simple IAP is using?
     
  9. Robert_Hildebrand

    Robert_Hildebrand

    Joined:
    Sep 19, 2018
    Posts:
    15
    On restore they call RestoreTransactions as follows...
    extensions.GetExtension<IAppleExtensions>().RestoreTransactions(OnTransactionsRestored);

    The OnTransactionsRestore is a callback that just checks for success or fail. In my case I get success but prior to that I should be seeing calls to ProcessPurchase and I'm not.

    === Apologies... this is another problem I am having
    I'm trying to debug this on my iPhone 7 using VS2019 for Mac (latest) and I'm not able to get any of my break points to get set. Works fine in the Unity Editor. I'm attach to attach the debugger to the device running the debug build, just never able to get the breakpoints active and it appears that the debugger is connected.
     
  10. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
  11. Robert_Hildebrand

    Robert_Hildebrand

    Joined:
    Sep 19, 2018
    Posts:
    15
    I wanted to add that I'm noticing that in my case, it doesn't execute correctly on the first time through, you need to execute once, then exit the game. Then on the second execution, it will work. Not sure why but that's what is working. I tried to work around this by simply executing it twice in a row but no dice, you need to exit the game completely and then it will work on the second try.
     
  12. Robert_Hildebrand

    Robert_Hildebrand

    Joined:
    Sep 19, 2018
    Posts:
    15
    Also, I've observed where on initialization it appears that SIAP or UIAP are confirming my Store Items as I have a number of items in my local store that are not yet available on the Apple Store ... example as follows:

    iPhonePlayer(Darlenes-iPhone):56000 Unavailable product sc_levels15_21 -sc_levels15_21
    etc... I have several levels yet to be built but defined in the game and not in the Apple Store

    At the very end... I get the following... this is a legit purchase through testflight...
    iPhonePlayer(Darlenes-iPhone):56000 IAPListener reports: HandleSuccessfulPurchase: sc_levels8_14

    Right after that i get the following...

    iPhonePlayer(Darlenes-iPhone):56000 Local Receipt Validation failed for: sc_levels8_14. Exception: System.NullReferenceException: Object reference not set to an instance of an object.
    at SIS.IAPListener.HandleSuccessfulPurchase (System.String id) [0x00000] in <00000000000000000000000000000000>:0
    at SIS.IAPManager.PurchaseVerified (System.String id) [0x00000] in <00000000000000000000000000000000>:0
    at SIS.ReceiptValidatorClient.Validate (UnityEngine.Purchasing.Product p) [0x00000] in <00000000000000000000000000000000>:0
    at SIS.IAPManager.ProcessPurchase (UnityEngine.Purchasing.PurchaseEventArgs e) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Purchasing.StoreListenerProxy.ProcessPurchase (UnityEngine.Purchasing.PurchaseEventArgs e) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Purchasing.PurchasingManager.ProcessPurchaseIfNew (UnityEngine.Purchasing.Product product) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Purchasing.PurchasingManager.OnPurchaseSucceeded (System.String id, System.String receipt, System.String transactionId) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Purchasing.JSONStore.OnPurchaseSucceeded (System.String id, System.String receipt, System.String transactionID) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Purchasing.AppleStoreImpl.OnPurchaseSucceeded (System.String id, System.String receipt, System.String transactionId) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Purchasing.AppleStoreImpl.ProcessMessage (System.String subject, System.String payload, System.String receipt, System.String transactionId) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Purchasing.AppleStoreImpl+<>c__DisplayClass37_0.<MessageCallback>b__0 () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Purchasing.Extension.UnityUtil.Update () [0x00000] in <00000000000000000000000000000000>:0 , Object reference not set to an instance of an object.

    Does this make any sense or offer any clues?
     
  13. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    This looks to be separate from the discussion of TestFlight in this thread. You have a NRE in SIS.IAPListener.HandleSuccessfulPurchase. Can you share your code? You are using a listener? Is this Codeless IAP or Scripted?
     
  14. Robert_Hildebrand

    Robert_Hildebrand

    Joined:
    Sep 19, 2018
    Posts:
    15
    What is an NRE ?? It's scripted... I can share code but would need some time to build a project that just has this in it.
     
  15. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    NRE is Null Reference Exception as shown in your logs. I'm trying to determine if it's your code or IAP. You don't need to build a project, just share the code here (with Code Tags). And you're using a Listener? I'm not familiar with that approach when using Scripted, comparing to the Sample IAP Project here https://forum.unity.com/threads/sample-iap-project.529555/
     
  16. Robert_Hildebrand

    Robert_Hildebrand

    Joined:
    Sep 19, 2018
    Posts:
    15
    Yes, this is correct. I'm using a listener with scripted... actually, I'm using Simple IAP which is an asset within the Unity Store. I've already reached out to them on this as well. Let me do some more debugging tomorrow.
     
  17. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    You should not be using a listener. Was IAP working previously without a listener, did you add this customization? Please show your code including the listener
     
  18. Robert_Hildebrand

    Robert_Hildebrand

    Joined:
    Sep 19, 2018
    Posts:
    15
    I'm not able to share the SIP code as it's straight from the Simple IAP implementation. I'm not sure what you mean by ... I should not be using a listener. I've been doing some research on this and I'm going to try this with a new user with the idea that this might be a bad transaction within TestFlight. I will let you know. If you have time I can setup a Skype session to show you what is happening.
     
  19. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    @Robert_Hildebrand Why are you adding a Listener? Unity IAP already handles all the listeners. And I'm not sure what you mean by "not able to share the SIP code", is it in a DLL or otherwise not available? Did you compare to the implementation in the Sample IAP Project? If you're concerned about security, you can send the relevant code in a private message
     
    Last edited: Oct 15, 2020
  20. Robert_Hildebrand

    Robert_Hildebrand

    Joined:
    Sep 19, 2018
    Posts:
    15
    Hi Jeff,

    I just pushed another build to TestFlight and the restore process worked perfectly!

    I found that I had some scene related code that should not have been in HandleSuccessfulPurchase and I rearchitected that process. I also updated my Unity IAP services on the Mac as I found an update that I was not aware of. The package manager component was fine but I had and update to apply where the services were concerned. Either one of those two modifications could have resolved the issue.

    Thanks!
    Robert
     
    JeffDUnity3D likes this.