Search Unity

Codeless IAP is restoring consumable, and it should not.

Discussion in 'Unity IAP' started by tonOnWu, Nov 6, 2018.

  1. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Hi guys.

    I've been working the whole morning in something that I'm pretty sure should not be complicated. I'd appreciate your suggestions. Now, please, bear with me.

    I'm using Codeless IAP. I created a catalog with only Consumable products. For every product, I created an IAP Button where each one is Purchase (in Button Type) and set Checked on Consume Purchase. Finally, in Apple Connect I created a tester user to make the purchases.

    Now, when I go to my iPhone and make a purchase, everything goes well (usually). But if I make some update to the code, compile to xCode, load the game again and then try to make the same purchase, the iPhone tells me that that was a previous purchase and it has been restored.

    First, I don't understand why you can Restore a product if it is a Consumable. I think this makes no sense, but if someone can explain it to me, I'll appreciate. And, if this is an option, how can I inform Apple that the Consumable has been consumed and the user has been enabled to purchase other consumable (not to restore a previous purchase).

    Thank you.
     
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,906
    Make sure you check Consume Purchase in the IAP Button properties. Are you testing on TestFlight?
     
  3. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Yes it's Checked. And I'm using testing.
     
  4. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    This is a picture of my current setting.
    Screen Shot 2018-11-06 at 12.19.57 PM.png
     
  5. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,906
    Understood, does this only happen when you create/install a new build?
     
  6. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Well, I'm still understanding its behavior. If I remove the IAP button and create a new one with the same properties, the thing works the first two times without inconvenience. But them, it starts to tell me that it's going to restore the purchases. So, responding to your question, this happens if I start the app several times and try again, or even if I compile the whole xCode file and try to make the purchase.

    Now, one very curious thing is that if I remove both Runtime Only Actions when On Purchase Complete is done, then everything starts working again. And as soon as I insert them again and try to make purchase more than once, then the error pops up again. As you can see, one of them just SetActive an element to false, and the other just present a Debug Message (although you don't see the code here). It's pretty simple but always at the end, it presents this message:

    IMG_2060.PNG
     
  7. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,906
    We would need to see your full code to understand fully what is going on. Specifically the code that is run in the Runtime Only Actions that is apparently causing this behavior. I wouldn't expect a method that simply outputs a Debug message to cause the issue, but is something we can certainly test. Also, please show how your product is configured in the IAP Catalog and perhaps a screenshot of the product settings in the store. It could even be behavior in the Sandbox environment, based on your description, which is out of our control. But we should rule out other possibilities first.
     
  8. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Sure. This is the code I'm calling:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Purchasing;
    3. using UnityEngine.Events;
    4.  
    5. // This class is call at the end of an IAP Transaction:
    6. public class IAPTransactionResultMngr : SingletonWulum<IAPTransactionResultMngr>
    7. {
    8.     [SerializeField] UnityEvent OnTransactionSuccess;
    9.     [SerializeField] UnityEvent OnTransactionFailed;
    10.  
    11.  
    12.     public void Fulfill(Product product)
    13.     {
    14.         Debug.Log("WULUM - Getting into Fulfill -----");
    15.         int coins = 0;
    16.  
    17.         if (product != null)
    18.         {
    19.             switch (product.definition.id)
    20.             {
    21.                 case "10000coins":
    22.                     coins = 10000;
    23.                     TransactionSucceded(coins);
    24.                     break;
    25.                 case "30000coins":
    26.                     coins = 30000;
    27.                     TransactionSucceded(coins);
    28.                     break;
    29.                 case "100000coins":
    30.                     coins = 100000;
    31.                     TransactionSucceded(coins);
    32.                     break;
    33.                 case "200000coins":
    34.                     coins = 200000;
    35.                     TransactionSucceded(coins);
    36.                     break;
    37.                 default:
    38.                     break;
    39.             }
    40.  
    41.         }
    42.     }
    43.  
    44.     private void TransactionFailed()
    45.     {
    46.         ConfirmIAPTransactionMngr.Instance.PresentPurchased (0);
    47.         OnTransactionFailed.Invoke();
    48.  
    49.         Debug.Log("WULUM - You Tried But Couln't purchase Coins");
    50.     }
    51.  
    52.     private void TransactionSucceded(int coins)
    53.     {
    54.         Debug.Log("WULUM - IAP Transacctions Successful");
    55.         ConfirmIAPTransactionMngr.Instance.PresentPurchased(coins);
    56.         AddCoinsToPlayFab(coins);
    57.  
    58.         OnTransactionSuccess.Invoke();
    59.     }
    60.  
    61.     private void AddCoinsToPlayFab(int coins)
    62.     {
    63.         Debug.Log("WULUM - You Purchased " + coins + " coins");
    64.         //PlayFabMngr.Instance.AddCoinsToUser (coins);
    65.     }
    66.  
    67.     public void TestingToDeleteOnRelease()
    68.     {
    69.         Debug.Log("WULUM -------------- TESTING");
    70.     }
    71.  
    72. }
     
  9. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    This is the Catalog Setting:
    Screen Shot 2018-11-06 at 4.47.54 PM.png



    An this is the Product setting on the AppStore:

    Screen Shot 2018-11-06 at 4.52.09 PM.png
     
  10. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Still NOT working. Now I tried to create a new clean Scene with just IAP Menu Button and I cleaned the whole IAP Catalog. Then I set a new Consumable in the App Store Connect (double checked it) and linked just one Unity IAP Button to that only consumable in the App Store. Sadly, the problem persists. The first purchase goes well, but if I tried to purchase again (immediately), it says: "This In-App Purchase has already been bought. It will be restored for free"

    Here you find the Consumable Set Up in the App Store, the IAP Catalog and the IAP Button Setting.

    Screen Shot 2018-11-07 at 5.02.43 AM.png Screen Shot 2018-11-07 at 5.03.06 AM.png Screen Shot 2018-11-07 at 5.03.19 AM.png
     
  11. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Ok. Making other tests.

    Now I removed all the On Purchase Complete Unity Events from the IAP Button. Retry the IAP on the iPhone and everything went perfect.

    Then I added the IAPTransactionResultMngr to the On Purchase Complete. As you can see in previous post, I just called a function that only display a Debug.Log. So far, everything was perfect.

    Then I decided to add a Unity Event inside TestingToDeleteOnRelease() inside IAPTransactionResultMngr. It end up looking like this:

    Code (CSharp):
    1.     public void TestingToDeleteOnRelease()
    2.     {
    3.         Debug.Log("WULUM -------------- TESTING");
    4.         OnTransactionSuccess.Invoke();
    5.     }
    Then, on the Unity Event On Transaction Success, I SetActive to false for the CanvasIAPWindow (the one that presents the menu for the IAP). Then the error POPS UP again. Here how I set the Unity Event inside IAPTransactionResultMngr:

    Screen Shot 2018-11-07 at 5.55.41 AM.png

    I'm starting to believe that the problem has relation with the Unity Events.
     
  12. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    It seems I found the problem: as you can see, as soon as the On Transaction Success is Invoke, I always call the SetActive(false) for the same GameObject that presents the menu for the IAP (CanvasIAPWindow). It looks like the Transaction and the SetActive(false) action are having some kind of conflict. I really don't know why, but I created a Coroutine that runs the SetActive(false) with a delay of a couple of seconds and everything works perfectly.

    You might be thinking that it must have been some extra code in the CanvasIAPWindow that it's breaking everything, but it's not. It is just a simple Canvas with some UI Images and UI Buttons. The only different thing is that the buttons are IAP Button.

    So, if you have any idea of how to solve this issue without having to call the SetActive(false) after a few seconds with a Coroutine, I would appreciate the inspiration.
     
    Rock-Soft and Gmora7 like this.
  13. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,906
  14. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Hi @JeffDUnity3D . I don't get when you say that "I'm using IAP scripting". Where am I using it?. In fact, I think that Codeless IAP is awesome and I don't want to use IAP scripting.
    In any case, I solved the issue for the moment. But I want to understand your suggestion.
     
  15. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,906
    In the code that you provided, you have "using UnityEngine.Purchasing;" and subsequent method calls. This is IAP scripting. Glad you got it working. If it is, then don't change it!
     
    tonOnWu likes this.
  16. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Thank you for your support.
     
  17. Taninty

    Taninty

    Joined:
    Dec 22, 2013
    Posts:
    2
    My IAP button is enabled and it’s active ( including parent object . But still I get an dialog states that Inapp already bought and on purchase success is not getting triggered.
     
  18. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,906
    I trust that you made the changes that I suggested previously, you were/are mixing scripting and codeless. Also, please try with a different user account. Also, please review the sample project code for the correct implementation and compare to yours.