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

[Closed] How to Integrate the new IAP System [TUTORIAL]

Discussion in 'Unity IAP' started by Alzan, Dec 17, 2015.

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

    Alzan

    Joined:
    Sep 2, 2012
    Posts:
    81
    I've hit a lot of road blocks trying to get the new IAP system working for Android. In the past we just used a reasonably priced plugin with well documented functions. From start to finish it would take less than two hours to do. With the release of the Unity In-App Purchase system (IAP), we've switched to a set of docs which are still being written; therefor, we've been lacking a bit of necessary information. Now that everything is up and running I would like to share a quick tutorial on how to write it into your project. I don't have a lot of time to gather code samples for everything, but we will import the examples during the process. It is worth noting that there are a few differences between Android and other platforms; however, I will do my best to include code that will work on both Apple and Android. Okay, let's get started!
    First we need to open the Services Panel inside Unity. This screen can be enabled under the Windows tab.
    Ref_0.jpg

    Once here you will be given an array of services to work with. By default everything should be disabled. Click on the IAP option to move on to the following screen.

    Ref_1.jpg

    Here we are going to do two things. First, enable the IAP system by toggling the button in the top right (blue is enabled). Once it's enabled, Unity Analytics may turn itself on as well, this is because the two systems work together. Next, click the Import button to load some rather useful files into the project. You may want to take a moment and explore the example code that is imported with the IAP system.

    Now we will modify the example logic just a bit. Make a new C# script to store our logic (mine is called IAP). The entire script I use is below.
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Purchasing;
    5.  
    6.     // Deriving the Purchaser class from IStoreListener enables it to receive messages from Unity Purchasing.
    7.     public class IAP : MonoBehaviour, IStoreListener
    8.     {
    9.         private static IStoreController m_StoreController; // Reference to the Purchasing system.
    10.         private static IExtensionProvider m_StoreExtensionProvider; // Reference to store-specific Purchasing
    11.  
    12.         private static string kItem = "items_all"; // General handle for the consumable product.
    13.  
    14.         private static string kGooglePlayItems = "com.Comp.Proj.shop.items_all"; // Google Play Store identifier for the consumable product.
    15.         public MonoBehaviour _Main;
    16.         void Start()
    17.         {
    18.             //ZPlayerPrefs.Initialize("----------------", SystemInfo.deviceUniqueIdentifier);
    19.             // If we haven't set up the Unity Purchasing reference
    20.             if (m_StoreController == null)
    21.             {
    22.                 // Begin to configure our connection to Purchasing
    23.                 InitializePurchasing();
    24.             }
    25.         }
    26.    
    27.         public void InitializePurchasing()
    28.         {
    29.             // If we have already connected to Purchasing ...
    30.             if (IsInitialized())
    31.             {
    32.                 // ... we are done here.
    33.                 return;
    34.             }
    35.        
    36.             // Create a builder, first passing in a suite of Unity provided stores.
    37.             var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
    38.        
    39.             // Add a product to sell / restore by way of its identifier, associating the general identifier with its store-specific identifiers.
    40.             builder.AddProduct(kItems, ProductType.NonConsumable, new IDs(){ {kGooglePlayItems,  GooglePlay.Name} });// Continue adding the non-consumable product.
    41.        
    42.             UnityPurchasing.Initialize(this, builder);
    43.         }
    44.    
    45.    
    46.         private bool IsInitialized()
    47.         {
    48.             // Only say we are initialized if both the Purchasing references are set.
    49.             return m_StoreController != null && m_StoreExtensionProvider != null;
    50.         }
    51.    
    52.         public void BuyNonConsumable()
    53.         {
    54.             // Buy the non-consumable product using its general identifier. Expect a response either through ProcessPurchase or OnPurchaseFailed asynchronously.
    55.             BuyProductID(kItems);
    56.         }
    57.    
    58.    
    59.         void BuyProductID(string productId)
    60.         {
    61.             // If the stores throw an unexpected exception, use try..catch to protect my logic here.
    62.             try
    63.             {
    64.                 // If Purchasing has been initialized ...
    65.                 if (IsInitialized())
    66.                 {
    67.                     // ... look up the Product reference with the general product identifier and the Purchasing system's products collection.
    68.                     Product product = m_StoreController.products.WithID(productId);
    69.                
    70.                     // If the look up found a product for this device's store and that product is ready to be sold ...
    71.                     if (product != null && product.availableToPurchase)
    72.                     {
    73.                         Debug.Log (string.Format("Purchasing product asychronously: '{0}'", product.definition.id));// ... buy the product. Expect a response either through ProcessPurchase or OnPurchaseFailed asynchronously.
    74.                         m_StoreController.InitiatePurchase(product);
    75.                     }
    76.                     // Otherwise ...
    77.                     else
    78.                     {
    79.                         // ... report the product look-up failure situation
    80.                         Debug.Log ("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
    81.                     }
    82.                 }
    83.                 // Otherwise ...
    84.                 else
    85.                 {
    86.                     // ... report the fact Purchasing has not succeeded initializing yet. Consider waiting longer or retrying initiailization.
    87.                     Debug.Log("BuyProductID FAIL. Not initialized.");
    88.                 }
    89.             }
    90.             // Complete the unexpected exception handling ...
    91.             catch (Exception e)
    92.             {
    93.                 // ... by reporting any unexpected exception for later diagnosis.
    94.                 Debug.Log ("BuyProductID: FAIL. Exception during purchase. " + e);
    95.             }
    96.         }
    97.    
    98.    
    99.         // Restore purchases previously made by this customer. Some platforms automatically restore purchases. Apple currently requires explicit purchase restoration for IAP.
    100.         public void RestorePurchases()
    101.         {
    102.             // If Purchasing has not yet been set up ...
    103.             if (!IsInitialized())
    104.             {
    105.                 // ... report the situation and stop restoring. Consider either waiting longer, or retrying initialization.
    106.                 Debug.Log("RestorePurchases FAIL. Not initialized.");
    107.                 return;
    108.             }
    109.        
    110.             // If we are running on an Apple device ...
    111.             if (Application.platform == RuntimePlatform.IPhonePlayer ||
    112.                 Application.platform == RuntimePlatform.OSXPlayer)
    113.             {
    114.                 // ... begin restoring purchases
    115.                 Debug.Log("RestorePurchases started ...");
    116.            
    117.                 // Fetch the Apple store-specific subsystem.
    118.                 var apple = m_StoreExtensionProvider.GetExtension<IAppleExtensions>();
    119.                 // Begin the asynchronous process of restoring purchases. Expect a confirmation response in the Action<bool> below, and ProcessPurchase if there are previously purchased products to restore.
    120.                 apple.RestoreTransactions((result) => {
    121.                     // The first phase of restoration. If no more responses are received on ProcessPurchase then no purchases are available to be restored.
    122.                     Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore.");
    123.                 });
    124.             }
    125.             // Otherwise ...
    126.             else
    127.             {
    128.                 // We are not running on an Apple device. No work is necessary to restore purchases.
    129.                 Debug.Log("RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform);
    130.             }
    131.         }
    132.    
    133.    
    134.         //
    135.         // --- IStoreListener
    136.         //
    137.    
    138.         public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    139.         {
    140.             // Purchasing has succeeded initializing. Collect our Purchasing references.
    141.             Debug.Log("OnInitialized: PASS");
    142.        
    143.             // Overall Purchasing system, configured with products for this application.
    144.             m_StoreController = controller;
    145.             // Store specific subsystem, for accessing device-specific store features.
    146.             m_StoreExtensionProvider = extensions;
    147.         }
    148.    
    149.    
    150.         public void OnInitializeFailed(InitializationFailureReason error)
    151.         {
    152.             // Purchasing set-up has not succeeded. Check error for reason. Consider sharing this reason with the user.
    153.             Debug.Log("OnInitializeFailed InitializationFailureReason:" + error);
    154.         }
    155.    
    156.    
    157.         public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    158.         {
    159.             // A consumable product has been purchased by this user.
    160.             if (String.Equals(args.purchasedProduct.definition.id, kItems, StringComparison.Ordinal))
    161.             {
    162.                 Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    163.                 //If the item has been successfully purchased, store the item for later use!
    164.                 PlayerPrefs.SetInt("Items_All", 1);
    165.                 _Main.Invoke("Got_Items", 0); //Call a function in another script to play some effects.
    166.             }
    167.             else
    168.             {
    169.                 Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
    170.                 PlayerPrefs.SetInt("Itemss_All", 0);
    171.             }
    172.             // Return a flag indicating wither this product has completely been received, or if the application needs to be reminded of this purchase at next app launch. Is useful when saving purchased products to the cloud, and when that save is delayed.
    173.             return PurchaseProcessingResult.Complete;
    174.         }
    175.    
    176.    
    177.         public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
    178.         {
    179.             // A product purchase attempt did not succeed. Check failureReason for more detail. Consider sharing this reason with the user.
    180.             Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}",product.definition.storeSpecificId, failureReason));}
    181.     }
    182.  

    There are a few security problems with the above code, but before we get to that I want to explain how we retrieve purchases from the store. The PurchaseProcessingResult function is called when a purchase has been processed at runtime. That means it will go off every time someone uses your store. We use some simple logic here to figure out if the item was bought or not. Then we have to save that information somehow. For now, the above code drops the state of our item into the PlayerPrefs as soon as possible. DO NOT LEAVE IT THAT WAY. The PlayerPrefs are written in everyday text and can be "hacked" really easily - That's not the way to store purchases. We will get back to that issue in a second. The PlayerPrefs allow us to see if the player has purchased an item so long as the app remains on the device. In order to restore our save file after the game has been removed and reinstalled, we actually use the same exact function. While Android is automated to process every purchase on the FIRST run after installation and call PurchaseProcessingResult for each item, Apple requires us to ask for that using the RestorePurchases function. Either way, the app should process the purchases like they were just made at runtime by a user during the first run after installation.

    What do we have left to do? There's that issue with the security of PlayerPrefs, and we still haven't setup our products on the Play Store end!
    To fix the security issue, I used the free Secured PlayerPrefs (Link below). This free package encrypts our player prefs using a salt.
    https://www.assetstore.unity3d.com/en/#!/content/32357
    Simply add the letter Z before all our PlayerPrefs so that they read ZPlayerPrefs, and initialize the system with
    Code (CSharp):
    1. //BASE
    2. ZPlayerPrefs.Initialize("PASSWORD", "SALT");
    3. //EXAMPLE
    4. ZPlayerPrefs.Initialize("789so9isdead", SystemInfo.deviceUniqueIdentifier);
    Now we just have to setup the items in the Play Store. Open the Google Play Developer Console and navigate to your project. Make sure everything is setup so you can publish an apk file to Alpha or Beta (prices set, store info written, screen shots provided, etc.) Next select the In-app Products tab and add a new product. The id you make should be formatted something like so
    and copied into our script for the value of kGooglePlayItems near line 14. The name of the item will be displayed on the screen when the store is called. Make sure to publish the item on Google Play along with a new apk file. All testers must be signed up for your app's testing under Google Play in-order to use the store before official release of the app.

    For examples using the Apple store, read over the example code imported with the IAP system.

    Debug the Play Store:
    If the items does not exist on Google Play (For Android Builds) then your shop will return an error along the lines of "item not found", when you try to purchase said item. If the item was found but your client doesn't have permission to buy it (if the apk is under Alpha or Beta and the user's Google Account isn't signed up for testing) you'll get something along the lines of "Item can not be purchased at the moment".
     
    Last edited: Dec 17, 2015
    SshockwaveGames, MrDasix and georetro like this.
  2. rxmarccall

    rxmarccall

    Joined:
    Oct 13, 2011
    Posts:
    353
    Thanks for posting this tutorial, really helpful. I am stuck on something though....
    In your code, what in the world is "kItems"? I see "kItem" that is being used as a general identifier.

    It also doesn't make sense to me that ProcessPurchase is comparing args.purchasedProduct.definition.id to kProductIDConsumable as the first string is the products store identifier... so it never matches for me....

    Also what is up with the BuyConsumable, BuyNonConsumable and BuySubscription methods, are those only for testing?
     
  3. iamau5

    iamau5

    Joined:
    Oct 19, 2015
    Posts:
    13
    If I'm not wrong, kItems is the default productId whether you set that on AppleStore, or GooglePlay , that must have the same Id

    The args.purchasedProduct.definition.id is use to compare that which productId that you sent to buy with BuyProductID(); function. In this case, there is only kItems as 1 product. so when you call BuyProductID(kItems); it will send callback to PurchaseProcessingResult and send the productId for you to compare which package the user buy, and just add that package to the user pref or anything you want to add.

    Don't concern much about BuyConsumable, BuyNonConsumable and BuySubscription methods. It's just an example of 3 kinds of package which refer to three type of packages it can be sell. It can be BuyConsumable1, BuyConsumable2 and BuyConsumable3 with specific Id you want to be on the store.
     
  4. iamau5

    iamau5

    Joined:
    Oct 19, 2015
    Posts:
    13
    Anyway, I also have a question here about the Implementing test. (Android)

    When I test the APK on the android phone. The application isn't Initialize the controller and extension for me. So that when I call BuyConsumable, it errors that "BuyConsumable FAIL Not Initialized". (When Testing on UnityEditor , the Initializing part works fine.)

    I dont know that do I have to upload a new APK to the GooglePlay store first, In order to test the IAP on testing APK? It doesn't make sense that uploading a new APK with implemented IAP to the GooglePlay should have something to do with OnInitialze. Or I'm missing something?
     
  5. iamau5

    iamau5

    Joined:
    Oct 19, 2015
    Posts:
    13
    Ok, now the error just show that the package on Google Play are not available because I skip the setup to alpha or beta part. I think If I do the setup to alpha, this might solve the problem
     
  6. rxmarccall

    rxmarccall

    Joined:
    Oct 13, 2011
    Posts:
    353
    @iamau5
    I was having those same problems, YES you do need to have an APK uploaded to either Alpha or Beta in the google player developer console AND make sure that you PUBLISH IT. I uploaded mine but didn't publish it, I found the publish button after you click the "Advanced Setup" button. Then you'll still have to wait up to 24 hours for testing after you publish it. Also make sure that the APK you upload has the same bundle version as the one you are going to test with locally on your device.

    In regards to my previous question, I think what you said makes sense, but I wish someone would share an example that works with multiple product IDs rather than just 1 "master product" like in the above code. I'm still struggling with the right way to add a product to the builder and then purchase it. I keep getting errors about the product not existing, etc.
     
  7. TimBorquez

    TimBorquez

    Joined:
    Mar 18, 2013
    Posts:
    81
    Thanks man! I struggle figuring out stuff that doesn't have ridiculous amounts of documentation, so this should help a lot :)
     
  8. gifer81

    gifer81

    Joined:
    Nov 16, 2015
    Posts:
    9
    How would this script work with multiple consumables? Any idea?
     
  9. jc-drile77

    jc-drile77

    Joined:
    Jul 1, 2014
    Posts:
    230
    I did everything as it is stated here (or so I believe), but when I run it on my Android device nothing happens.
    I click the buy button on my virtual shop and nothing happens :C
    Help?
     
  10. jc-drile77

    jc-drile77

    Joined:
    Jul 1, 2014
    Posts:
    230
  11. mpinol

    mpinol

    Joined:
    Jul 29, 2015
    Posts:
    317
  12. gifer81

    gifer81

    Joined:
    Nov 16, 2015
    Posts:
    9
    Thanks mpinol,

    I have a different question:

    I'm using a sandbox test user to test my iap and everything works as expected. However when I switch back to my main Apple account I get the login dialog that asks for the sandbox user password every time the game is started or restored from the background. Any idea of why this happens?

    Thanks in advance
     
  13. mpinol

    mpinol

    Joined:
    Jul 29, 2015
    Posts:
    317
    Hi @gifer81

    It sounds like there is still a connection from your device to the Sandbox store. Can you please try to, uninstall the app, restart the device, and then reinstall the app and try again?
     
  14. gifer81

    gifer81

    Joined:
    Nov 16, 2015
    Posts:
    9
    Thanks for the response.

    I have tried the steps you suggested but the problem persists. I'm currently using TestFlight to test my game. On a different device everything works great, but on my device (the one where I logged in with my sandbox user and tested iap during development) it keeps prompting the itunes store login dialog as something is still pending. This happens on my device also when I create a new development build from unity and run it with xcode.
     
  15. Banderous

    Banderous

    Joined:
    Dec 25, 2011
    Posts:
    669
    Storekit will prompt the user for their credentials if it thinks there are pending transactions the user is owed and needs to log in. Unity IAP has no control over the login prompt. Once you login, does it stop prompting?
     
  16. gifer81

    gifer81

    Joined:
    Nov 16, 2015
    Posts:
    9
    The login dialog pops up during these events:

    1. When I launch the game
    2. When I resume the game
    3. Randomly even when the game is closed

    If I type the password and log in the game still keeps prompting the dialog during the events above. The only way not to have the login dialog to show is to delete the game from the device.
     
  17. basavaraj_guled

    basavaraj_guled

    Joined:
    Nov 1, 2014
    Posts:
    4
    please find the below function. this function is written for restoring the previously purchased items in Apple store.

    can anyone rewrite the below function for google play store
    please find the below function. this function is written for restoring the previously purchased items in Apple store.

    can anyone rewrite the below function for google play store

    // Restore purchases previously made by this customer. Some platforms automatically restore purchases. Apple currently requires explicit purchase restoration for IAP.
    public void RestorePurchases()
    {
    // If Purchasing has not yet been set up ...
    if (!IsInitialized())
    {
    // ... report the situation and stop restoring. Consider either waiting longer, or retrying initialization.
    Debug.Log("RestorePurchases FAIL. Not initialized.");
    return;
    }

    // If we are running on an Apple device ...
    if (Application.platform == RuntimePlatform.IPhonePlayer ||
    Application.platform == RuntimePlatform.OSXPlayer)
    {
    // ... begin restoring purchases
    Debug.Log("RestorePurchases started ...");

    // Fetch the Apple store-specific subsystem.
    var apple = m_StoreExtensionProvider.GetExtension<IAppleExtensions>();
    // Begin the asynchronous process of restoring purchases. Expect a confirmation response in the Action<bool> below, and ProcessPurchase if there are previously purchased products to restore.
    apple.RestoreTransactions((result) => {
    // The first phase of restoration. If no more responses are received on ProcessPurchase then no purchases are available to be restored.
    Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore.");
    });
    }
    // Otherwise ...
    else
    {
    // We are not running on an Apple device. No work is necessary to restore purchases.
    Debug.Log("RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform);
    }
    }
     
  18. erika_d

    erika_d

    Joined:
    Jan 20, 2016
    Posts:
    413
    Hi @basavaraj_guled,

    I believe that this code should work for both iOS and Android because in the final else statement it says that no work is necessary to restore purchases on non-Apple devices. I'm not 100% sure though, so I want to confirm for you that this is the case. I am checking with someone working on the service and once I hear back, I will post an additional update to this forum.
     
  19. basavaraj_guled

    basavaraj_guled

    Joined:
    Nov 1, 2014
    Posts:
    4
    hi @erika_d

    ya its working 100% for an android devices
    there is no function written to call for restore in android it will automatically call the function "PurchaseProcessingResult" if u r logged in
     
  20. erika_d

    erika_d

    Joined:
    Jan 20, 2016
    Posts:
    413
  21. Entwicklerpages

    Entwicklerpages

    Joined:
    Aug 31, 2013
    Posts:
    14
    I'm not sure but normally you provide a public RSA shared secret for Google Play IAPs. This secret is different for every app. Until now I don't find any explanation how to provide it for Unity IAP. In Soomla you put this secret in the Settings.
     
  22. erika_d

    erika_d

    Joined:
    Jan 20, 2016
    Posts:
    413
    Hi @Entwicklerpages,

    I believe what you're referring to we call the Google API key. You can enter it in the settings of the analytics dashboard for your project.

    This is a quote from the receipt verification page on the Unity manual, found here: http://docs.unity3d.com/Manual/UnityAnalyticsReceiptVerification.html
    You can find the Analytics dashboard by going to https://analytics.cloud.unity3d.com/
    From there you can get to settings by clicking on the cog icon in the row of your relevant project.

    Does that sound like what you are looking for?

    Screen Shot 2016-02-19 at 10.49.44 AM.png Screen Shot 2016-02-19 at 10.53.20 AM.png
     

    Attached Files:

  23. Entwicklerpages

    Entwicklerpages

    Joined:
    Aug 31, 2013
    Posts:
    14
    @erika_d Thanks! That's exactly what I wanted! I only searched in the Unity IAP manual, not the Analytics' one. I'm realy new to Unity Analytics... yeah ok Unity Analytics itself is realy new but... You know what I mean.
     
    erika_d likes this.
  24. waqasbuttms

    waqasbuttms

    Joined:
    Sep 29, 2015
    Posts:
    1
    Hey,

    my game is getting crashed on pause since i implement unity in-apps

    Here is the crash log

    AndroidJavaException: java.lang.IllegalArgumentException: Receiver not registered: com.unity.purchasing.googleplay.GooglePlayPurchasing$3@885d4d7
    java.lang.IllegalArgumentException: Receiver not registered: com.unity.purchasing.googleplay.GooglePlayPurchasing$3@885d4d7
    at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:780)
    at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1195)
    at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:576)
    at com.unity.purchasing.googleplay.GooglePlayPurchasing.OnApplicationPause(GooglePlayPurchasing.java:102)
    at com.unity3d.player.UnityPlayer.nativePause(Native Method)
    at com.unity3d.player.UnityPlayer.i(Unknown Source)
    at com.unity3d.player.UnityPlayer$18.run(Unknown Source)
    at com.unity3d.player.UnityPlayer.executeGLThreadJobs(Unknown Source)
    at com.unity3d.player.UnityPlayer$b.run(Unknown Source)
    at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <filename unknown>:0
    at UnityEngine.AndroidJNISafe.CallVoid
    07-15 16:35:43.308 12333 12348 D CppWrapper: onActivityPaused: -1
     
  25. erika_d

    erika_d

    Joined:
    Jan 20, 2016
    Posts:
    413
  26. manny003

    manny003

    Joined:
    Mar 18, 2014
    Posts:
    69
    Can we get a definitive answer about whether Unity 5.4.1p1 supports IAP for Apple TVOS? My project fails to build and need to know if I'm spinning my wheels trying to fix something that is not supported.

    I recall reading on a Road Map once that is was supposed to be support in version 5.4.x but have heard nothing since. My questions about this to Unity Answer and other forums remains unanswered.

    Thanks,
    Manny
     
  27. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
  28. manny003

    manny003

    Joined:
    Mar 18, 2014
    Posts:
    69
    Thanks for reply. I was getting Xcode errors but now I am getting errors during Unity Builds. Also, this is the same app that I have successfully build and deployed for iOS using Unity IAP. I'm trying to release a tvOS version using Unity IAP and have reimported the IAP Package several times:

    (PS: I realize the project path as "android" in its name - just ignore that, it's a left over naming convention I haven't gotten around to changing yet. Rest assured, it's a tvOS app)

    Unhandled Exception: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
    at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (bool)
    at System.Reflection.Assembly.GetTypes () [0x00000] in <filename unknown>:0
    at Mono.CSharp.RootNamespace.ComputeNamespaces (System.Reflection.Assembly assembly, System.Type extensionType) [0x00000] in <filename unknown>:0
    at Mono.CSharp.RootNamespace.ComputeNamespace (Mono.CSharp.CompilerContext ctx, System.Type extensionType) [0x00000] in <filename unknown>:0
    at Mono.CSharp.GlobalRootNamespace.ComputeNamespaces (Mono.CSharp.CompilerContext ctx) [0x00000] in <filename unknown>:0
    at Mono.CSharp.Driver.LoadReferences () [0x00000] in <filename unknown>:0
    at Mono.CSharp.Driver.Compile () [0x00000] in <filename unknown>:0
    at Mono.CSharp.Driver.Main (System.String[] args) [0x00000] in <filename unknown>:0

    The following assembly referenced from /Users/mtran/Documents/UniyProjects5.4/XtremeBreakerInfinite_android/Assets/Plugins/UnityPurchasing/Bin/Stores.dll could not be loaded:
    Assembly: Tizen (assemblyref_index=7)
    Version: 0.0.0.0
    Public Key: (none)
    The assembly was not found in the Global Assembly Cache, a path listed in the MONO_PATH environment variable, or in the location of the executing assembly (/Users/mtran/Documents/UniyProjects5.4/XtremeBreakerInfinite_android/Assets/Plugins/UnityPurchasing/Bin/).

    Could not load file or assembly 'Tizen, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
     
    Last edited: Sep 21, 2016
  29. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
    Hi @manny003,

    It looks like we missed a setting when 1.8.1 was created, so iOS / OS X rules aren't being applied to tvOS. We'll make sure this is fixed. But in the mean time, you can change that setting in your project to create your tvOS build.

    In the Editor, go to Plugins/UnityPurchasing/Bin/Tizen and click on the Tizen.dll. In the Inspector, you'll see a list of platforms with a checkbox by each. Just make sure tvOS is checked. Then make sure you apply the changes.

    tvos.PNG

    You should be able to build for tvOS after that. Sorry about the inconvenience.
     
  30. manny003

    manny003

    Joined:
    Mar 18, 2014
    Posts:
    69

    Thanks ap-unity. Changing the Platform associations definitely got me over the hump with being able to generate a Build from Unity.

    Now, however, I'm getting the errors I had encountered in the past within Xcode when trying to compile a tvOS deployable:

    Screen Shot 2016-09-22 at 1.38.35 PM.png
     
  31. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
  32. manny003

    manny003

    Joined:
    Mar 18, 2014
    Posts:
    69
    ap-unity, yes I have been cleaning my projects. However, the other links you provided lead me to the correct solution:

    Apparently, the Unity Build Xcode Project does NOT include the tvOS StoreKit Framework by default. It had not occurred to me to double check this as it was not an issue with iOS. It would seem that tvOS has it's own StoreKit framework that is separate from iOS. Once I manually added it, I was able to successfully build. (Although I've not had the chance to actually test IAP on a deployed device yet.)

    Thanks,
    Manny
     
    ap-unity likes this.
  33. KristianBalaj

    KristianBalaj

    Joined:
    Mar 12, 2015
    Posts:
    1
    Hi, I am just wondering, where I am getting earned money/revenue from unity IAPs. (When we are talking about android platform)

    Thanks,
    Kristián
     
  34. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
    Hi @manny003,

    I'm glad to hear you were able to get your app built for Apple TV. I will let the engineers know about the tvOS StoreKit Framework.

    Hi @ScHeIsSeR,

    The Analytics dashboard receives IAP data via transaction events that are sent for every purchase made. These transactions go through a Verification process (for Google Play and iOS) that marks them as Verified or Unverified if we are able to verify them with the platform. This happens automatically for iOS and you need to enter your Google API key on your Configure page to get this working for Google Play.

    You can learn more about Verified and Unverified revenue on the IAP FAQ (#8):
    http://forum.unity3d.com/threads/unity-iap-faqs.388069/

    If you want to know how to get paid from Unity IAP, you would need to contact Google Play. We simply track transactions, we don't handle payment from users or to developers.

    If you would like to know what items are generating the most revenue for you, this is also something that is available in the Google Play Developer Console.

    If you would like to know what region your paying customers are coming from, you can do this by using the default geographic segments in the Data Explorer:

    segments-geo.PNG
     
  35. tresreisgames

    tresreisgames

    Joined:
    Sep 21, 2016
    Posts:
    1
    Hi,
    Am having confusion with consuming a purchase.There is no code for ConsumePurchase in Unity IAP.
    How to do that??
    Or Does Unity automatically consumes consumable products?
     
    Last edited: Nov 6, 2016
  36. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
    Hi @tresreisgames

    Yes, Unity IAP automatically consumes product after the ProcessPurchase phase, as long as your return PurchaseProcessingResult.Complete.

    If you return PurchaseProcessingResult.Pending (which is only necessary when you are saving your purchases to the cloud) then the product won't be consumed until you call ConfirmPendingPurchase.
     
    Last edited: Nov 16, 2016
    tresreisgames likes this.
  37. imrankhanswati

    imrankhanswati

    Joined:
    Jul 14, 2016
    Posts:
    5
    Hi:
    I feel dump because i am not able to figure out restore purchases for "IOS" currently i am using unity "code less iap" which is working for purchases but i want to restore purchases after reinstalling game so my steps are:
    1.
    extensions.GetExtension<IAppleExtensions>().RestoreTransactions(result =>
    {
    if (result)
    {
    OnTransactionsRestored();
    }
    else
    {
    //nothing to restore.
    }
    });

    2.
    public void OnTransactionsRestored()
    {
    Product product2 = controller.products.WithID("key1");
    Product product3 = controller.products.WithID("key2");
    Product product4 = controller.products.WithID("key3");
    Product product5 = controller.products.WithID("key4");


    if (product2 != null && product2.hasReceipt && product2.receipt != null)
    {
    //unlock product 2
    }

    //level 3

    if (product3 != null && product3.hasReceipt && product3.receipt != null)
    {
    //unlock product 3
    }

    //level 4

    if (product4 != null && product4.hasReceipt && product4.receipt != null)
    {
    //unlock product 4
    }

    //level 5

    if (product5 != null && product5.hasReceipt && product5.receipt != null)
    {
    //unlock product 5
    }
    }


    this code is working and recover all of the products that i already bought but problem is its take too much time approximately 30 sec or even more.and also there only 4 products if i increase it 20 so it will even more and more time.

    so i want an easy and less time consuming way to do that work.
    Thanks!!!!!
     
  38. Zaphod-Beeblebrox

    Zaphod-Beeblebrox

    Joined:
    Nov 7, 2015
    Posts:
    3
    Hey guys!

    Can I use it for iaps on tvOS (Apple TV)?

    Thank you!
     
  39. Zaphod-Beeblebrox

    Zaphod-Beeblebrox

    Joined:
    Nov 7, 2015
    Posts:
    3
    Sorry guys. Now I see it:
    "Unity IAP supports tvOS as of version 1.2.0::
     
  40. rogaroga

    rogaroga

    Joined:
    Oct 30, 2016
    Posts:
    10
    I have a quick question about product ids when using a Purchaser script as shown in the Unity Tutorial (here):

    In this section of the code:

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Purchasing;
    5.  
    6. // Placing the Purchaser class in the CompleteProject namespace allows it to interact with ScoreManager,
    7. // one of the existing Survival Shooter scripts.
    8. namespace CompleteProject
    9. {
    10.     // Deriving the Purchaser class from IStoreListener enables it to receive messages from Unity Purchasing.
    11.     public class Purchaser : MonoBehaviour, IStoreListener
    12.     {
    13.         private static IStoreController m_StoreController;          // The Unity Purchasing system.
    14.         private static IExtensionProvider m_StoreExtensionProvider; // The store-specific Purchasing subsystems.
    15.  
    16.         // Product identifiers for all products capable of being purchased:
    17.         // "convenience" general identifiers for use with Purchasing, and their store-specific identifier
    18.         // counterparts for use with and outside of Unity Purchasing. Define store-specific identifiers
    19.         // also on each platform's publisher dashboard (iTunes Connect, Google Play Developer Console, etc.)
    20.  
    21.         // General product identifiers for the consumable, non-consumable, and subscription products.
    22.         // Use these handles in the code to reference which product to purchase. Also use these values
    23.         // when defining the Product Identifiers on the store. Except, for illustration purposes, the
    24.         // kProductIDSubscription - it has custom Apple and Google identifiers. We declare their store-
    25.         // specific mapping to Unity Purchasing's AddProduct, below.
    26.         public static string kProductIDConsumable =    "consumable";
    27.         public static string kProductIDNonConsumable = "nonconsumable";
    28.         public static string kProductIDSubscription =  "subscription";
    29.  
    Are the example product ids completely arbitrary? If my particular game has the following, for example:

    150 Coins for $0.99
    1000 Coins for $4.99
    5000 Coins for $9.99

    All of these would be consumables, so would my list of public static strings look more like this:

    Code (CSharp):
    1. public static string 150Coins = "150Coins";
    2. public static string 1000Coins= "1000Coins";
    3. public static string 5000Coins=  "5000Coins";
    ...and then later in builder:

    Code (CSharp):
    1. builder.AddProduct(150Coins, ProductType.Consumable);
    2. builder.AddProduct(1000Coins, ProductType.Consumable);
    3. builder.AddProduct(5000Coins, ProductType.Consumable);
    Am I understanding the implementation correctly?
     
    andreini likes this.
  41. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
    @rogaroga

    The product ids must match exactly what you have configured in your Google Play Developer Console:
    https://docs.unity3d.com/Manual/UnityIAPGoogleConfiguration.html

    (You can also create your product ids in your scripts and then copy them to the Google Play Developer Console).

    They are arbitrary in the sense that they can be whatever string you choose, but they must match in the script and what you set up in the store.
     
    rogaroga likes this.
  42. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
    @imrankhanswati

    Could you provide a copy of your purchase script (or wherever you implement your IAP code). This is not an issue I've heard before (at least not for that few products), so any additional information you provide will be helpful.
     
  43. rogaroga

    rogaroga

    Joined:
    Oct 30, 2016
    Posts:
    10
    Is this method "BuyNonConsumable()" called by onclick of the regular button component of the IAP button gameobject, or is it called by the IAP Button component of the gameobject? Or somewhere else entirely that I'm not understanding?

    @ap-unity
    Thanks in advance for any clues here... I feel like I'm missing something obvious about implementation of IAP buttons.

    EDIT: I called it using onclick of regular button component, and that worked. I'm still confused on how to use the IAP button component correctly though. I guess I'll have to read a bit more about that, as even with my now working code and button, it never comes back and calls the functions under Completed or Failed purchase of the IAP button component:

     
    Last edited: Jan 29, 2017
  44. dappledore

    dappledore

    Joined:
    Feb 16, 2015
    Posts:
    12
  45. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
  46. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
    @rogaroga

    That is likely called via an OnClick of a regular button. I mentioned this in another thread, but if you read this one first, you can find the code for the Codeless IAP in:
    Plugins/UnityPurchasing/script/IAPButton.cs

    I'm not able to reproduce this issue. Could you send a support ticket with a sample project:
    https://analytics.cloud.unity3d.com/support/
     
Thread Status:
Not open for further replies.