SDKs for Unity / Integrate SDK on application side
 Back to Docs

SDKs for Unity

  • Integration guide

  • Demo project

  • Authentication

  • Catalog

  • Subscriptions

  • Promotions

  • Item purchase

  • Player inventory

  • User account and attributes

  • Application build guides

  • Troubleshooting


  • Integrate SDK on application side

    1. Design an interface for the login system, in-game store, and other pages for your application.
    2. Set up event handling according to your application logic using SDK methods. To get started with the basic SDK features, follow the step-by-step tutorials below.

    Note
    You can create your own solution by following Unity instructions, or use the demo scene as a template. To adapt the demo scene UI to your application, use the UI builder.
    Follow the step-by-step tutorials below to get going with the basic SDK features.

    User login via username/email and password

    This instruction shows how to use SDK methods to implement:

    • user sign-up
    • resend request for a sign-up confirmation email
    • user login
    • user password reset

    You can authenticate users with their username or email address. In the following examples we authenticate users with their username, whereas the email address is used to confirm sign-up and to reset the password.

    Note
    If you use the Login widget on your site (in a web store, for example), make sure that you implemented the same user authentication methods on your site and in your application. The widget uses the email address for authentication by default. To set up user login via username, contact your Account Manager.

    The logics and interface in the examples are less complicated than they will be in your application. A possible authentication system implementation option is described in the demo project.

    Implement user sign-up

    This tutorial describes the implementation of the following logic:

    Create page interface

    Create a scene for a sign-up page and add the following elements on it:

    • username field
    • user email address field
    • user password field
    • sign-up button

    The following picture shows the example of a page structure.

    Create page controller

    1. Create a script RegistrationPage inherited from the MonoBehaviour base class.
    2. Declare variables for the page interface elements and set values for them in the Inspector panel.
    3. Add logics to process clicking on the sign-up button:

      1. In the Start method, subscribe to a clicking event.
      2. Add an anonymous method that is called after clicking the button.
      3. In this method, declare the username, email, and password variables and initialize them by the values from the fields on the page.
      4. Call the XsollaAuth.Instance.Register SDK method and pass the username, email, and password variables and the following methods to it:

        • OnSuccess — called if sign-up is successful
        • OnError — called if an error occurs

    Note

    In the script’s examples, the OnSuccess and OnError methods call the standard Debug.Log method. The error code and description are passed in the error parameter.

    You can add other actions like opening a page with a resend request for a sign-up email or opening a login page if sign-up is successful.

    Example of a script for a sign-up page:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    using Xsolla.Auth;
    using Xsolla.Core;
    
    namespace Recipes
    {
        public class RegistrationPage : MonoBehaviour
        {
            // Declaration of variables for UI elements on the page
    
            [SerializeField] private InputField UsernameInput;
    
            [SerializeField] private InputField EmailInputField;
    
            [SerializeField] private InputField PasswordInputField;
    
            [SerializeField] private Button RegisterButton;
    
            private void Start()
            {
                // Handling the button click
             RegisterButton.onClick.AddListener(() =>
                {
                    var username = UsernameInput.text;
                    var email = EmailInputField.text;
                    var password = PasswordInputField.text;
    
                    XsollaAuth.Instance.Register(username, email, password, onSuccess: OnSuccess, onError: OnError);
                });
            }
    
            private void OnSuccess()
            {
                UnityEngine.Debug.Log("Registration successful");
                // Some actions
         }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.Log($"Registration failed. Description: {error.errorMessage}");
                // Some actions
         }
        }
    }
    

    Set up sign-up confirmation email

    After successful sign-up, a user receives a sign-up confirmation email to a specified address. You can customize emails sent to users in Publisher Account.

    If you are developing an Android application, set up deep links to return a user to an application after they confirm sign-up.

    Note
    You can disable sign-up confirmation via an email address if your security standards allow you to do this. Contact your Account Manager to disable it or contact us at am@xsolla.com.

    Implement sign-up confirmation email resend request

    This tutorial describes the implementation of the following logic:

    Create page interface

    Create a scene for a page with a request to resend a confirmation email and add the following elements to it:

    • username/email field
    • resend email button

    The following picture shows an example of the page structure.

    Create page controller

    1. Create a script ResendConfirmationEmail inherited from the MonoBehaviour base class.
    2. Declare variables for page interface elements and set values for them in the Inspector panel.
    3. Add logics to process clicking on the resend email button:

      1. In the Start method, subscribe to a clicking event.
      2. Add an anonymous method that is called after clicking the button.
      3. In this method, declare the username variable and initialize it by the values from the fields on the page.
      4. Call the XsollaAuth.Instance.ResendConfirmationLink SDK method and pass the username variable and OnSuccess and OnError methods to it.

    Example of a script for an email resend page:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    using Xsolla.Auth;
    using Xsolla.Core;
    
    namespace Recipes
    {
        public class ResendConfirmationEmail : MonoBehaviour
        {
            // Declaration of variables for UI elements on the page
    
            [SerializeField] private InputField UsernameInput;
    
            [SerializeField] private Button ResendEmailButton;
    
            private void Start()
            {
                // Handling the button click
             ResendEmailButton.onClick.AddListener(() =>
                {
                    var username = UsernameInput.text;
    
                    XsollaAuth.Instance.ResendConfirmationLink(username, onSuccess: OnSuccess, onError: OnError);
                });
            }
    
            private void OnSuccess()
            {
                UnityEngine.Debug.Log("Resend confirmation email successful");
                // Some actions
         }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.Log($"Resend confirmation email failed. Description: {error.errorMessage}");
                // Some actions
         }
        }
    }
    

    If the request is successful, the user receives a sign-up confirmation email to the email address specified during sign-up.

    Implement user login

    This tutorial describes the implementation of the following logic:

    Create page interface

    Create a scene for a login page and add the following elements to it:

    • username field
    • password field
    • remember me checkbox
    • login button

    The following picture shows an example of the page structure.

    Create page controller

    1. Create a script AutorizationPage inherited from the MonoBehaviour base class.
    2. Declare variables for page interface elements and set values for them in the Inspector panel.
    3. Add logics to process clicking on the login button:

      1. In the Start method, subscribe to a clicking event.
      2. Add an anonymous method that is called after clicking the button.
      3. In this method, declare the username and password variables and initialize them by the values from the fields on the page. Create a rememberMe variable and initialize it with a checkbox state to remember an account.
      4. Call the XsollaAuth.Instance.SignIn SDK method and pass the username, password, and rememberMe variables and OnSuccess and OnError methods to it.

    Note
    After successful user login, the authorization token is passed in the token parameter. The authorization token is used in requests to Xsolla servers.

    Example of a script for a login page:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    using Xsolla.Auth;
    using Xsolla.Core;
    
    namespace Recipes
    {
        public class AuthorizationPage : MonoBehaviour
        {
            // Declaration of variables for UI elements on the page
    
            [SerializeField] private InputField UsernameInput;
    
            [SerializeField] private InputField PasswordInputField;
    
            [SerializeField] private Toggle RememberMeToggle;
    
            [SerializeField] private Button AuthorizationButton;
    
            private void Start()
            {
                // Handling the button click
    
                AuthorizationButton.onClick.AddListener(() =>
                {
                    var username = UsernameInput.text;
                    var password = PasswordInputField.text;
                    var rememberMe = RememberMeToggle.isOn;
    
                    XsollaAuth.Instance.SignIn(username, password, rememberMe, null, onSuccess: OnSuccess, onError: OnError);
                });
            }
    
            private void OnSuccess(string token)
            {
                UnityEngine.Debug.Log($"Authorization successful. Token: {token}");
                // Some actions
         }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.Log($"Authorization failed. Description: {error.errorMessage}");
                // Some actions
         }
        }
    }
    

    Implement password reset

    This tutorial describes the implementation of the following logic:

    Create page interface

    Create a scene for a password reset page and add the following elements to a page:

    • username/email field
    • password reset button

    The following picture shows an example of the page structure.

    Create page controller

    1. Create a script ResetPasswordPage inherited from the MonoBehaviour base class.
    2. Declare variables for page interface elements and set values for them in the Inspector panel.
    3. Add logics to process clicking on the password reset button:

      1. In the Start method, subscribe to a clicking event.
      2. Add an anonymous method that is called after the button is clicked.
      3. In this method, declare the username variable and initialize it by the values from the fields on the page.
      4. Call the XsollaAuth.Instance.ResetPassword SDK method and pass the username variables and OnSuccess and OnError methods to it.

    Example of a script for a password reset page:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    using Xsolla.Auth;
    using Xsolla.Core;
    
    namespace Recipes
    {
        public class ResetPasswordPage : MonoBehaviour
        {
            // Declaration of variables for UI elements on the page
    
            [SerializeField] private InputField UsernameInput;
    
            [SerializeField] private Button ResetPasswordButton;
    
            private void Start()
            {
                // Handling the button click
    
                ResetPasswordButton.onClick.AddListener(() =>
                {
                    var username = UsernameInput.text;
    
                    XsollaAuth.Instance.ResetPassword(username, null, null, OnSuccess, OnError);
                });
            }
    
            private void OnSuccess()
            {
                UnityEngine.Debug.Log("Password reset successful");
                // Some actions
         }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.Log($"Password reset failed. Description: {error.errorMessage}");
                // Some actions
         }
        }
    }
    

    After successful password reset request, the user receives an email with a password reset link. In Publisher Account > your Login project > Security > OAuth 2.0 > OAuth 2.0 redirect URIs, you can configure a URL address or a path a user is redirected to after successful authentication, email confirmation, or password reset.

    Was this article helpful?
    Thank you!
    Is there anything we can improve? Message
    We’re sorry to hear that
    Please explain why this article wasn’t helpful to you. Message
    Thank you for your feedback!
    We’ll review your message and use it to help us improve your experience.
    Hide

    Social login

    This guide shows how you can use SDK methods to implement user sign-up and login via their social network account.

    Unlike for user authentication via username/user email address and password, you don’t have to implement separate logics for user sign-up. If the user’s first login is via a social network, a new account is created automatically.

    If you have implemented social login in your application as an alternative authentication method, the social network account automatically links to an existing user account if the following conditions are met:

    • A user who signed up with username/email address and password logged into your application via a social network account.
    • A social network returns an email address.
    • User email address in a social network is the same as the email address used for sign-up in your application.

    Note
    You can implement manual linking of a social network account. Add the page to your application where users can link a social network account to their account. In the page controller, use the LinkSocialProvider SDK method.

    This tutorial describes the implementation of the following logic:

    The examples show how to set up user login via a Twitter account. You can set up all social networks in the same way.

    The logics and interface in the examples are less complicated than they will be in your application. A possible authentication system implementation option is described in the demo project.

    Create page interface

    Create a scene for a login page and add the social login button to it. The following picture shows an example of the page structure.

    Create page controller

    1. Create a script SocialAuthorizationPage inherited from the MonoBehaviour base class.
    2. Declare variables for the application login page interface elements and set values for them in the Inspector panel.
    3. Add logics to process clicking on the login button:

      1. In the Start method, subscribe to a clicking event.
      2. Add an anonymous method that is called after clicking the button.
      3. To pass a login page URL, declare the url variable in an anonymous method. Initialize this variable by the GetSocialNetworkAuthUrl SDK method by passing a Facebook value in the SocialProvider parameter.
      4. To open a browser, call the BrowserHelper.Instance.Open method. To use a built-in browser, pass the url variable and a true value to the method.

    Note
    Social login isn’t available for external browsers. SDK contains a built-in browser developed by Xsolla. You can use either an Xsolla built-in browser or a different built-in browsing solution.

      1. To get a token and close the browser, track the changes of the page URL after successful user sign-up:
        1. Declare a singlePageBrowser variable and initialize it via the BrowserHelper.Instance.GetLastBrowser SDK method.
        2. Subscribe to an active page URL changing event and set the OnUrlChanged method as a handler.

    1. Implement getting of the token:
      1. Use a ParseUtils.TryGetValueFromUrl utility method to parse a URL of an active page passed in the OnUrlChanged method.
      2. Add a check for an authentication code in an active page URL. The ParseUtils.TryGetValueFromUrl method passes an authentication code in the code variable.
      3. To exchange an authentication code for a token, call the ExchangeCodeToToken SDK method and pass a code variable and the following methods to it:
        • OnSuccess — called if sign-up is successful
        • OnError — called if an error occurs

    Note

    In the script’s examples, the OnSuccess and OnError methods call the standard Debug.Log method. You can add other actions.

    If a user successfully logs in, the authorization token is passed in the token parameter. This token is used in requests to Xsolla servers. If an error occurs, its code and description are passed in the error parameter.

      1. After you get the token, delete a game object with a browser.

    Example of a script for a login page:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    using Xsolla.Auth;
    using Xsolla.Core;
    
    namespace Recipes
    {
        public class SocialAuthorizationPage : MonoBehaviour
        {
            // Declaration of variables for UI elements on the page
    
            [SerializeField] private Button FacebookButton;
    
            private void Start()
            {
                // Handling the button click
    
                FacebookButton.onClick.AddListener(() =>
                {
                    // Opening browser
    
                    var url = XsollaAuth.Instance.GetSocialNetworkAuthUrl(SocialProvider.Facebook);
                    BrowserHelper.Instance.Open(url, true);
    
                    // Determining the end of authentication
                 BrowserHelper.Instance.InAppBrowser.AddUrlChangeHandler(OnUrlChanged);
                });
            }
    
            // Getting token
         private void OnUrlChanged(string url)
            {
                if (ParseUtils.TryGetValueFromUrl(url, ParseParameter.code, out var code))
                {
                    XsollaAuth.Instance.ExchangeCodeToToken(code, OnSuccess, OnError);
                    Destroy(BrowserHelper.Instance.gameObject);
                }
            }
    
            private void OnSuccess(string token)
            {
                UnityEngine.Debug.Log($"Authorization successful. Token: {token}");
                // Some actions
         }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.Log($"Authorization failed. Description: {error.errorMessage}");
                // Some actions
         }
        }
    }
    

    Was this article helpful?
    Thank you!
    Is there anything we can improve? Message
    We’re sorry to hear that
    Please explain why this article wasn’t helpful to you. Message
    Thank you for your feedback!
    We’ll review your message and use it to help us improve your experience.
    Hide

    Display of item catalog

    This tutorial shows how to use the SDK methods to display the following items in an in-game store:

    • virtual items
    • groups of virtual items
    • bundles
    • packages of virtual currency

    Before you start, configure items in Publisher Account:

    1. Configure virtual items and groups of virtual items.
    2. Configure packages of virtual currencies.
    3. Configure bundles.

    This tutorial describes the implementation of the following logic:

    The logics and interface in the examples are less complicated than they will be in your application. A possible item catalog in an in-game store implementation option is described in the demo project.

    Note

    The example of every item in a catalog shows:

    • item name
    • item description
    • item price
    • image

    You can also show other information about the item if this information is stored in an in-game store.

    Implement display of virtual items

    Create item widget

    1. Create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Convert the created game object in a prefab by dragging a game object from a Hierarchy panel to a Project panel.
    3. Select a created prefab and click Open Prefab in the Inspector panel.
    4. Add the following UI elements as prefab child objects and configure their visuals:
      • item background image
      • item name
      • item description
      • item price
      • item image

    The following picture shows an example of the widget structure.

    Create item widget script

    1. Create a script VirtualItemWidget inherited from the MonoBehaviour base class.
    2. Declare variables for the item widget interface elements and set values for them in the Inspector panel.

    Example of the widget script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Recipes
    {
        public class VirtualItemWidget : MonoBehaviour
        {
            // Declaration of variables for UI elements
    
            public Text NameText;
    
            public Text DescriptionText;
    
            public Text PriceText;
    
            public Image IconImage;
        }
    }
    

    Create page to show list of items

    1. On the scene, create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Add the following UI elements as prefab child objects and configure their visuals:
      • page background image
      • item widgets display area

    The following picture shows an example of the page structure.

    Create page controller

    1. Create a script VirtualItemsPage inherited from the MonoBehaviour base class.
    2. Declare the following variables:
      • WidgetsContainer — container for widgets
      • WidgetPrefab — item widget prefab

    1. Attach a script to a page game object:
      1. Select an object in a Hierarchy panel.
      2. In the Inspector panel, click Add Component and select a VirtualItemsPage script.
    2. Set values for variables in the Inspector panel.

    1. Add login logics by calling an XsollaAuth.Instance.SignIn SDK method in the Start method and pass to it:
      • a username or email address in the username parameter
      • a user password in the password parameter

    Note
    In the script example to login we use the credentials of a demo account (username: xsolla, password: xsolla).

      • a flag in the rememberUser parameter for remembering an account
      • the OnAuthenticationSuccess callback method for successful user login
      • the OnError callback method for an error

    1. Add logics for getting the list of items. In the OnAuthenticationSuccess method call the XsollaCatalog.Instance.GetCatalog SDK method and pass to it:
      • a Project ID in the projectId parameter

    Note
    You can find the Project ID in Project settings in Publisher Account. In the script example, we passed the value from the SDK settings to a parameter.

      • the OnItemsRequestSuccess for successful operation of getting a list of items
      • the OnError callback method for an error
      • an offset based on the first item in the list in the offset parameter
      • the number of loaded items in the limit parameter

    Note
    The offset and limit parameters are not required. Use them to implement pagination — a page-by-page display of items in the catalog. The maximum number of items on the page is 50. If the catalog has more than 50 items, pagination is necessary.

    1. In the OnItemsRequestSuccess method, add logics for creating a widget for every received item:
      1. Instantiate a prefab of item widget as a container child object.
      2. Attach the received VirtualItemWidget component to a widget variable.

    1. Pass the following data to the item widget:
      1. Pass the storeItem.name variable value to the element with the item name.
      2. Pass the storeItem.description variable value to the element with the item description.
      3. Implement the following logics to display the item price:
        • If the value of the storeItem.price variable doesn’t equal null, the item is sold for real currency. Specify the price in the {amount} {currency} format and pass it to the widget element.
        • If the value of the storeItem.virtual_prices variable doesn’t equal null, the item is sold for virtual currency. Specify the price in the {name}: {amount} format and pass it to the widget element.

    Note
    The storeItem.virtual_prices variable is an array of prices for the same item in different currencies. The example shows a price specified by default in the item settings in Store > Virtual items in Publisher Account.

      1. To display an item image, use the ImageLoader.Instance.GetImageAsync utility method and pass to it:
        • Image URL.
        • An anonymous function as a callback. In this function, add a received sprite as an item image.

    Example of a page controller script:

    Copy
    Full screen
    Small screen
    using System.Linq;
    using UnityEngine;
    using Xsolla.Auth;
    using Xsolla.Catalog;
    using Xsolla.Core;
    
    namespace Recipes
    {
        public class VirtualItemsPage : MonoBehaviour
        {
            // Declaration of variables for containers and widget prefabs
    
            public Transform WidgetsContainer;
    
            public GameObject WidgetPrefab;
    
            private void Start()
            {
                // Starting the authentication process
    
                XsollaAuth.Instance.SignIn("xsolla", "xsolla", true, null, null, OnAuthenticationSuccess, OnError);
            }
    
            private void OnAuthenticationSuccess(string token)
            {
                // After successful authentication starting the request for catalog from store
    
                XsollaCatalog.Instance.GetCatalog(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError, offset: 0, limit: 50);
            }
    
            private void OnItemsRequestSuccess(StoreItems storeItems)
            {
                // Iterating the items collection and assign values for appropriate ui elements
    
                foreach (var storeItem in storeItems.items)
                {
                    var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
                    var widget = widgetGo.GetComponent<VirtualItemWidget>();
    
                    widget.NameText.text = storeItem.name;
                    widget.DescriptionText.text = storeItem.description;
    
                    if (storeItem.price != null)
                    {
                        var realMoneyPrice = storeItem.price;
                        widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
                    }
                    else if (storeItem.virtual_prices != null)
                    {
                        var virtualCurrencyPrice = storeItem.virtual_prices.First(x => x.is_default);
                        widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}";
                    }
    
                    ImageLoader.Instance.GetImageAsync(storeItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
                }
            }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
            }
        }
    }
    

    The following picture shows the result of the script’s work.

    Implement display of virtual item groups

    Create item widget

    1. Create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Convert the created game object in a prefab by dragging a game object from a Hierarchy panel to a Project panel.
    3. Select a created prefab and click Open Prefab in the Inspector panel.
    4. Add the following UI elements as prefab child objects and configure their visuals:
      • item background image
      • item name
      • item description
      • item price
      • item image

    The following picture shows an example of the widget structure.

    Create item widget script

    1. Create a script VirtualItemWidget inherited from the MonoBehaviour base class.
    2. Declare variables for the item widget interface elements and set values for them in the Inspector panel.

    Example of the widget script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Recipes
    {
        public class VirtualItemWidget : MonoBehaviour
        {
            // Declaration of variables for UI elements
    
            public Text NameText;
    
            public Text DescriptionText;
    
            public Text PriceText;
    
            public Image IconImage;
        }
    }
    

    Create widget for button that opens groups of items

    1. Create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Convert the created game object in a prefab by dragging a game object from a Hierarchy panel to a Project panel.
    3. Select a created prefab and click Open Prefab in the Inspector panel.
    4. Add the button that allows displaying of the group of items as a child object for a prefab and configure its visuals.

    The following picture shows an example of the widget structure.

    Create script for button that opens groups of items

    1. Create the VirtualItemGroupButton script inherited from the MonoBehaviour base class.
    2. Declare variables for the button that opens the group of items and set values for the variables in the Inspector panel.
    3. Add a script to the root object of a prefab:
      1. Select an object in the Hierarchy panel.
      2. In the Inspector panel, click Add Component and select a VirtualItemGroupButton script.

    Example of the widget script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Recipes
    {
        public class VirtualItemGroupButton : MonoBehaviour
        {
            // Declaration of variables for UI elements
         public Text NameText;
    
            public Button Button;
        }
    }
    

    Create page to show list of items

    1. On the scene, create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Add the following UI elements as prefab child objects and configure their visuals:
      • page background image
      • item groups buttons display area
      • item widgets display area

    The following picture shows an example of the page structure.

    Create page controller

    1. Create the VirtualItemsByGroupsPage script inherited from the MonoBehaviour base class.
    2. Declare variables:
      • GroupButtonsContainer — container for group buttons
      • GroupButtonPrefab — button prefab
      • ItemWidgetsContainer — container for item widgets
      • WidgetPrefab — item widget prefab

    1. Attach a script to a page game object:
      1. Select an object in a Hierarchy panel.
      2. In the Inspector panel, click Add Component and select a VirtualItemsByGroupsPage script.
    2. Set values for variables in the Inspector panel.
    3. Add login logics by calling an XsollaAuth.Instance.SignIn SDK method in the Start method and pass to it:
      • a username or email address in the username parameter
      • a user password in the password parameter

    Note
    In the script example to login we use the credentials of a demo account (username: xsolla, password: xsolla).

      • a flag in the rememberUser parameter for remembering an account
      • the OnAuthenticationSuccess callback method for successful user login
      • the OnError callback method for an error

    1. Add logics for getting the list of items. In the OnAuthenticationSuccess method call the XsollaCatalog.Instance.GetCatalog SDK method and pass to it:
      • a Project ID in the projectId parameter

    Note
    You can find the Project ID in Project settings in Publisher Account. In the script example, we passed the value from the SDK settings to a parameter.

      • the OnItemsRequestSuccess for successful operation of getting a list of items
      • the OnError callback method for an error
      • an offset based on the first item in the list in the offset parameter
      • the number of loaded items in the limit parameter

    Note
    The offset and limit parameters are not required. Use them to implement pagination — a page-by-page display of items in the catalog. The maximum number of items on the page is 50. If the catalog has more than 50 items, pagination is necessary.

    1. In the OnItemsRequestSuccess method, add logics for forming a list of item groups:
      1. Get the list of unique groups from a received item list. Add to it the All element that will show all items not dependent on their category.
      2. Clear the buttons container by deleting all child objects. To do this, call the DeleteAllChildren method and pass a container object to it.
      3. For every item group:

        1. Instantiate a prefab of item widget as a container child object.
        2. Set the received VirtualItemGroupButton component to the groupButton variable.
        3. Pass the groupName variable value to the element with a group name.
        4. Add an anonymous method to the action of clicking the button. In this method, call the OnGroupSelected method and pass the name of the item group and the list of items as parameters.

      1. To display all items call the OnGroupSelected method and pass All as a group name.

    1. In the OnGroupSelected method, add logics for initial display of items:
      1. Create the itemsForDisplay variable and assign all received items to it if the name of the item group has All. Otherwise, link items that the group name matches with the groupName variable to the itemsForDisplay variable.
      2. Clear the buttons container by deleting all child objects. To do this, call the DeleteAllChildren method and pass a container object to it.

    1. Add logics for creating a widget for every received item:
      1. Instantiate a prefab of item widget as a container child object.
      2. Attach the received VirtualItemWidget component to a widget variable.

    1. Pass the following data to the item widget:
      1. Pass the storeItem.name variable value to the element with the item name.
      2. Pass the storeItem.description variable value to the element with the item description.
      3. Implement the following logics to display item price:

        • If the value of the storeItem.price variable doesn’t equal null, the item is sold for real currency. Specify the price in the {amount} {currency} format and pass it to the widget element.
        • If the value of the storeItem.virtual_prices variable doesn’t equal null, the item is sold for virtual currency. Specify the price in the {name}: {amount} format and pass it to the widget element.

    Note
    The storeItem.virtual_prices variable is an array of prices for the same item in different currencies. The example shows a price specified by default in the item settings in Store > Virtual items in Publisher Account.

      1. To display an item image, use the ImageLoader.Instance.GetImageAsync utility method and pass to it:
        • Image URL.
        • An anonymous function as a callback. In this function, add a received sprite as an item image.

    Copy
    Full screen
    Small screen
    using System.Collections.Generic;
    using System.Linq;
    using UnityEngine;
    using Xsolla.Auth;
    using Xsolla.Catalog;
    using Xsolla.Core;
    
    namespace Recipes
    {
        public class VirtualItemsByGroupsPage : MonoBehaviour
        {
            // Declaration of variables for containers and widget prefabs
         public Transform GroupButtonsContainer;
    
            public GameObject GroupButtonPrefab;
    
            public Transform ItemWidgetsContainer;
    
            public GameObject ItemWidgetPrefab;
    
            private void Start()
            {
                // Starting the authentication process
             XsollaAuth.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess,
                    onError: OnError);
            }
    
            private void OnAuthenticationSuccess(string token)
            {
                // After successful authentication starting the request for catalog from store
             XsollaCatalog.Instance.GetCatalog(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError, offset: 0,
                    limit: 50);
            }
    
            private void OnItemsRequestSuccess(StoreItems storeItems)
            {
                // Selecting the group’s name from items and order them alphabetical
             var groupNames = storeItems.items
                    .SelectMany(x => x.groups)
                    .GroupBy(x => x.name)
                    .Select(x => x.First())
                    .OrderBy(x => x.name)
                    .Select(x => x.name)
                    .ToList();
    
                // Add group name for “all groups”, which will mean show all items regardless of group affiliation
             groupNames.Insert(0, "All");
    
                // Clear container
             DeleteAllChildren(GroupButtonsContainer);
    
                // Iterating the group names and creating ui-button for each
             foreach (var groupName in groupNames)
                {
                    var buttonObj = Instantiate(GroupButtonPrefab, GroupButtonsContainer, false);
                    var groupButton = buttonObj.GetComponent<VirtualItemGroupButton>();
    
                    groupButton.NameText.text = groupName;
                    groupButton.Button.onClick.AddListener(() => OnGroupSelected(groupName, storeItems));
                }
    
                // Calling method for redraw page
             OnGroupSelected("All", storeItems);
            }
    
            private void OnGroupSelected(string groupName, StoreItems storeItems)
            {
                // Declaring variable for items which will display on page
             IEnumerable<StoreItem> itemsForDisplay;
                if (groupName == "All")
                {
                    itemsForDisplay = storeItems.items;
                }
                else
                {
                    itemsForDisplay = storeItems.items.Where(item => item.groups.Any(group => group.name == groupName));
                }
    
                // Clear container
             DeleteAllChildren(ItemWidgetsContainer);
    
                // Iterating the items collection and assign values for appropriate ui elements
             foreach (var storeItem in itemsForDisplay)
                {
                    var widgetGo = Instantiate(ItemWidgetPrefab, ItemWidgetsContainer, false);
                    var widget = widgetGo.GetComponent<VirtualItemWidget>();
    
                    widget.NameText.text = storeItem.name;
                    widget.DescriptionText.text = storeItem.description;
    
                    if (storeItem.price != null)
                    {
                        var realMoneyPrice = storeItem.price;
                        widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
                    }
                    else if (storeItem.virtual_prices != null)
                    {
                        var virtualCurrencyPrice = storeItem.virtual_prices.First(x => x.is_default);
                        widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}";
                    }
    
                    ImageLoader.Instance.GetImageAsync(storeItem.image_url,
                        (url, sprite) => widget.IconImage.sprite = sprite);
                }
            }
    
            // Utility method for delete all children of container
         private static void DeleteAllChildren(Transform parent)
            {
                var childList = parent.Cast<Transform>().ToList();
                foreach (var childTransform in childList)
                {
                    Destroy(childTransform.gameObject);
                }
            }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
            }
        }
    }
    

    Example of a page controller script:

    Implement display of bundles

    Create bundle widget

    1. Create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Convert the created game object in a prefab by dragging a game object from a Hierarchy panel to a Project panel.
    3. Select a created prefab and click Open Prefab in the Inspector panel.
    4. Add the following UI elements as prefab child objects and configure their visuals:

      • widget background image
      • bundle name
      • bundle description
      • bundle price
      • bundle content description (items and their quantity)
      • bundle image

    The following picture shows an example of the widget structure.

    Create widget script

    1. Create a script BundleWidget inherited from the MonoBehaviour base class.
    2. Declare variables for the item widget interface elements and set values for them in the Inspector panel.

    Example of the widget script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Recipes
    {
        public class BundleWidget : MonoBehaviour
        {
            // Declaration of variables for UI elements
         public Text NameText;
    
            public Text DescriptionText;
    
            public Text PriceText;
    
            public Text ContentText;
    
            public Image IconImage;
        }
    }
    

    Create page to show bundles

    1. On the scene, create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Add the following UI elements as prefab child objects and configure their visuals:
      • page background image
      • bundle widgets display area

    The following picture shows an example of the page structure.

    Create page controller

    1. Create the BundlesPage script inherited from the MonoBehaviour base class.
    2. Declare variables:
      • WidgetsContainer — container for widgets
      • WidgetPrefab — bundle widget prefab

    1. Attach a script to a page game object:
      1. Select an object in a Hierarchy panel.
      2. In the Inspector panel, click Add Component and select a BundlesPage script.

    1. Set values for variables in the Inspector panel.
    2. Add login logics by calling an XsollaAuth.Instance.SignIn SDK method in the Start method and pass to it:
      • a username or email address in the username parameter
      • a user password in the password parameter

    Note
    In the script example to login we use the credentials of a demo account (username: xsolla, password: xsolla).

      • a flag in the rememberUser parameter for remembering an account
      • the OnAuthenticationSuccess callback method for successful user login
      • the OnError callback method for an error

    1. Add logics for getting the list of bundles. In the OnAuthenticationSuccess method call the XsollaCatalog.Instance.GetBundles SDK method and pass to it:
      • a Project ID in the projectId parameter

    Note
    You can find the Project ID in Project settings in Publisher Account. In the script example, we passed the value from the SDK settings to a parameter.

      • the OnItemsRequestSuccess callback method for successful operation of getting a list of bundles
      • the OnError callback method for an error

    1. In the OnBundlesRequestSuccess method, add logics for creating a widget for every received bundles:
      1. Instantiate a prefab of item widget as a container child object.
      2. Attach the received BundleWidget component to a widget variable.

    1. Pass the following data to the bundle widget:
      1. Pass the bundleItem.name variable value to the element with the item name.
      2. Pass the bundleItem.description variable value to the element with the item description.
      3. Implement the following logics to display bundle content:
        1. Use every item in a bundle to form a line that contains the item name and its quantity. The line should have a {name} x {quantity} format.
        2. Group these lines into one line by using a new line character as a separator.
        3. Pass the new line to the widget element.

      1. Implement the following logics to display bundle price:
        • If the value of the bundleItem.price variable doesn’t equal null, the bundle is sold for real currency. Specify the price in the {amount} {currency} format and pass it to the widget element.
        • If the value of the bundleItem.virtual_prices variable doesn’t equal null, the bundle is sold for virtual currency. Specify the price in the {name}: {amount} format and pass it to the widget element.

    Note
    The bundleItem.virtual_prices variable is an array of prices for the same bundle in different currencies. The example shows a price specified by default in the item settings in Store > Bundles in Publisher Account.

      1. To display an item image, use the ImageLoader.Instance.GetImageAsync utility method and pass to it:
        • Image URL.
        • An anonymous function as a callback. In this function, add a received sprite as a bundle image.

    Example of a page controller script:

    Copy
    Full screen
    Small screen
    using System.Linq;
    using UnityEngine;
    using Xsolla.Auth;
    using Xsolla.Catalog;
    using Xsolla.Core;
    
    namespace Recipes
    {
        public class BundlesPage : MonoBehaviour
        {
            // Declaration of variables for containers and widget prefabs
         public Transform WidgetsContainer;
    
            public GameObject WidgetPrefab;
    
            private void Start()
            {
                // Starting the authentication process
             XsollaAuth.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess, onError: OnError);
            }
    
            private void OnAuthenticationSuccess(string token)
            {
                // After successful authentication starting the request for bundles from store
             XsollaCatalog.Instance.GetBundles(XsollaSettings.StoreProjectId, OnBundlesRequestSuccess, OnError);
            }
    
            private void OnBundlesRequestSuccess(BundleItems bundleItems)
            {
                // Iterating the bundles collection and assign values for appropriate ui elements
             foreach (var bundleItem in bundleItems.items)
                {
                    var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
                    var widget = widgetGo.GetComponent<BundleWidget>();
    
                    widget.NameText.text = bundleItem.name;
                    widget.DescriptionText.text = bundleItem.description;
    
                    var bundleContent = bundleItem.content.Select(x => $"{x.name} x {x.quantity}");
                    widget.ContentText.text = string.Join("\n", bundleContent);
    
                    if (bundleItem.price != null)
                    {
                        var realMoneyPrice = bundleItem.price;
                        widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
                    }
                    else if (bundleItem.virtual_prices != null)
                    {
                        var virtualCurrencyPrice = bundleItem.virtual_prices.First(x => x.is_default);
                        widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}";
                    }
    
                    ImageLoader.Instance.GetImageAsync(bundleItem.image_url,
                        (url, sprite) => widget.IconImage.sprite = sprite);
                }
            }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
            }
        }
    }
    

    The following picture shows the result of the script’s work.

    Implement display of virtual currency packages

    Create widget for virtual currency package

    1. Create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Convert the created game object in a prefab by dragging a game object from a Hierarchy panel to a Project panel.
    3. Select a created prefab and click Open Prefab in the Inspector panel.
    4. Add the following UI elements as prefab child objects and configure their visuals:

      • widget background image
      • package name
      • package description
      • package price
      • package image

    The following picture shows an example of the widget structure.

    Create widget script

    1. Create a script VirtualCurrencyPackageWidget inherited from the MonoBehaviour base class.
    2. Declare variables for the item widget interface elements and set values for them in the Inspector panel.

    Example of the widget script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Recipes
    {
        public class VirtualCurrencyPackageWidget : MonoBehaviour
        {
            // Declaration of variables for UI elements
    
            public Text NameText;
    
            public Text DescriptionText;
    
            public Text PriceText;
    
            public Image IconImage;
        }
    }
    

    Create page to show list of virtual currency packages

    1. On the scene, create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Add the following UI elements as prefab child objects and configure their visuals:
      • page background image
      • virtual currency package widgets display area

    The following picture shows an example of the page structure.

    Create page controller

    1. Create the VirtualCurrencyPackagesPage script inherited from the MonoBehaviour base class.
    2. Declare variables:
      • WidgetsContainer — container for widgets
      • WidgetPrefab — virtual currency package prefab

    1. Attach a script to a page game object:
      1. Select an object in a Hierarchy panel.
      2. In the Inspector panel, click Add Component and select a VirtualCurrencyPackagesPage script.
    2. Set values for variables in the Inspector panel.
    3. Add login logics by calling an XsollaAuth.Instance.SignIn SDK method in the Start method and pass to it:

      • username or email address in the username parameter
      • user password in the password parameter

    Note
    In the script example to login we use the credentials of a demo account (username: xsolla, password: xsolla).

      • a flag in the rememberUser parameter for remembering an account
      • the OnAuthenticationSuccess callback method for successful user login
      • the OnError callback method for an error

    1. Add logics for getting the list of items. In the OnAuthenticationSuccess method call the XsollaCatalog.Instance.GetVirtualCurrencyPackagesList SDK method and pass to it:
      • Project ID in the projectId parameter

    Note
    You can find the Project ID in Project settings in Publisher Account. In the script example, we passed the value from the SDK settings to a parameter.

      • the OnItemsRequestSuccess for successful operation of getting a list of items
      • the OnError callback method for an error

    1. In the OnPackagesRequestSuccess method, add logics for creating a widget for every received package:
      1. Instantiate a prefab of item widget as a container child object.
      2. Attach the received VirtualCurrencyPackageWidget component to a widget variable.

    1. Pass the following data to the package widget:
      1. Pass the packageItem.name variable value to the element with the package name.
      2. Pass the packageItem.description variable value to the element with the package description.
      3. Implement the following logics to display package price:

        • If the value of the packageItem.price variable doesn’t equal null, the package is sold for real currency. Specify the price in the {amount} {currency} format and pass it to the widget element.
        • If the value of the packageItem.virtual_prices variable doesn’t equal null, the package is sold for virtual currency. Specify the price in the {name}: {amount} format and pass it to the widget element.

    Note
    The packageItem.virtual_prices variable is an array of prices for the same package in different currencies. The example shows a price specified by default in the package settings in Store > Virtual currency > Packages in Publisher Account.

      1. To display an item image, use the ImageLoader.Instance.GetImageAsync utility method and pass to it:
        • Image URL.
        • An anonymous function as a callback. In this function, add a received sprite as an item image.

    Example of a page controller script:

    Copy
    Full screen
    Small screen
    using System.Linq;
    using UnityEngine;
    using Xsolla.Auth;
    using Xsolla.Catalog;
    using Xsolla.Core;
    
    namespace Recipes
    {
        public class VirtualCurrencyPackagesPage : MonoBehaviour
        {
            // Declaration of variables for containers and widget prefabs
         public Transform WidgetsContainer;
    
            public GameObject WidgetPrefab;
    
            private void Start()
            {
                // Starting the authentication process
             XsollaAuth.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess, onError: OnError);
            }
    
            private void OnAuthenticationSuccess(string token)
            {
                // After successful authentication starting the request for packages from store
             XsollaCatalog.Instance.GetVirtualCurrencyPackagesList(XsollaSettings.StoreProjectId, OnPackagesRequestSuccess, OnError);
            }
    
            private void OnPackagesRequestSuccess(VirtualCurrencyPackages packageItems)
            {
                // Iterating the packages collection and assign values for appropriate ui elements
             foreach (var packageItem in packageItems.items)
                {
                    var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
                    var widget = widgetGo.GetComponent<VirtualCurrencyPackageWidget>();
    
                    widget.NameText.text = packageItem.name;
                    widget.DescriptionText.text = packageItem.description;
    
                    if (packageItem.price != null)
                    {
                        var realMoneyPrice = packageItem.price;
                        widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
                    }
                    else if (packageItem.virtual_prices != null)
                    {
                        var virtualCurrencyPrice = packageItem.virtual_prices.First(x => x.is_default);
                        widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}";
                    }
    
                    ImageLoader.Instance.GetImageAsync(packageItem.image_url,
                        (url, sprite) => widget.IconImage.sprite = sprite);
                }
            }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
            }
        }
    }
    

    The following picture shows the result of the script’s work.

    Was this article helpful?
    Thank you!
    Is there anything we can improve? Message
    We’re sorry to hear that
    Please explain why this article wasn’t helpful to you. Message
    Thank you for your feedback!
    We’ll review your message and use it to help us improve your experience.
    Hide

    Sell virtual items for real currency

    This instruction shows how to use the SDK methods to implement selling of virtual items for real currency.

    Before you start, implement a display of virtual items in a catalog. In the following example, we describe how to implement purchasing of virtual items. Configuration for other item types is similar.

    This tutorial describes the implementation of the following logic:

    The logic and interface in the examples are less complicated than they will be in your application. A possible implementation option for selling items for real currency and displaying a catalog of items is described in the demo project.

    Complete item widget

    Add a purchase button to the item widget and configure its visuals.

    The following picture shows an example of the widget structure.

    Complete item widget script

    1. Open the VirtualItemWidget script.
    2. Declare variables for the purchase button and set values for them in the Inspector panel.

    Example of the widget script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Recipes
    {
        public class VirtualItemWidget : MonoBehaviour
        {
            // Declaration of variables for UI elements
    
            public Text NameText;
    
            public Text DescriptionText;
    
            public Text PriceText;
    
            public Image IconImage;
    
            public Button BuyButton;
        }
    }
    

    Complete page controller to show list of items

    1. Open the VirtualItemsPage script.
    2. In the OnAuthenticationSuccess method, pass the authorization token to the Token.Instance variable.

    Note
    You can use one of the following tokens:

    1. Add logic for processing clicking on the virtual item purchase button:
      1. In the OnItemsRequestSuccess method, subscribe to the button-clicking event.
      2. Add an anonymous method that is called after the button is clicked.
      3. In this method, call the XsollaCatalog.Instance.PurchaseItem SDK method to form an order and pass to it:

        • a Project ID in the projectId parameter
        • an item identifier in the itemSku parameter
        • the OnOrderCreateSuccess method to process a successful forming of the item purchase order
        • the OnError callback method for an error

    1. Implement opening of a payment page. To do this, add the OnOrderCreateSuccess method and call in it:
      • the XsollaOrders.Instance.OpenPurchaseUi SDK method, to open a payment page
      • the TrackOrderStatus coroutine, to track changes in the order status

    Note
    By default, the payment page opens in a built-in browser. To open it in an external browser, go to Window > Xsolla > Edit Settings in the Unity editor main menu and uncheck the Enable in-app browser? box in the Inspector panel. If you use the external browser for Android apps, we recommend setting up the deep links to redirect the user to the app after they make a payment.

    1. In the TrackOrderStatus coroutine, implement getting the info about the order status one time per second. To do this, use the XsollaOrders.Instance.CheckOrderStatus SDK method and pass to it:
      • a Project ID in the projectId parameter
      • an order number from payment details in the orderId parameter
      • an anonymous method for processing successful receiving of order status info
      • an anonymous method for error processing

    1. In the method for processing successful receiving of order status info, implement the callback of an OnPurchaseSuccess method during the payment for the order (payment status done or paid).
    2. In the OnPurchaseSuccess method, implement the processing of a successful virtual item purchase.

    Note

    In the script example, we call the Debug.Log base method if the item purchase is successful. You can add other actions like inventory display, etc.

    Implementation of logic for adding purchased items to the inventory isn’t required — it’s done automatically.

    1. If you use a built-in browser for opening a payment page, close this browser.

    Example of a script for a page:

    Copy
    Full screen
    Small screen
    using System.Collections;
    using UnityEngine;
    using Xsolla.Auth;
    using Xsolla.Catalog;
    using Xsolla.Core;
    using Xsolla.Orders;
    
    namespace Recipes
    {
        public class VirtualItemsPage : MonoBehaviour
        {
            // Declaration of variables for containers and widget prefabs
    
            public Transform WidgetsContainer;
    
            public GameObject WidgetPrefab;
    
            private void Start()
            {
                // Starting the authentication process
    
                XsollaAuth.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess, onError: OnError);
            }
    
            private void OnAuthenticationSuccess(string token)
            {
                // After successful authentication starting the request for catalog from store
             Token.Instance = Token.Create(token);
                XsollaCatalog.Instance.GetCatalog(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError, offset: 0, limit: 50);
            }
    
            private void OnItemsRequestSuccess(StoreItems storeItems)
            {
                // Iterating the items collection and assign values for appropriate ui elements
    
                foreach (var storeItem in storeItems.items)
                {
                    if (storeItem.price == null)
                        continue;
    
                    var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
                    var widget = widgetGo.GetComponent<VirtualItemWidget>();
    
                    widget.NameText.text = storeItem.name;
                    widget.DescriptionText.text = storeItem.description;
    
                    var realMoneyPrice = storeItem.price;
                    widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
    
                    ImageLoader.Instance.GetImageAsync(storeItem.image_url,
                        (url, sprite) => widget.IconImage.sprite = sprite);
    
                    widget.BuyButton.onClick.AddListener(() =>
                    {
                        XsollaCatalog.Instance.PurchaseItem(XsollaSettings.StoreProjectId, storeItem.sku, OnOrderCreateSuccess, OnError);
                    });
                }
            }
    
            private void OnOrderCreateSuccess(PurchaseData purchaseData)
            {
                XsollaOrders.Instance.OpenPurchaseUi(purchaseData);
                StartCoroutine(TrackOrderStatus(purchaseData));
            }
    
            private IEnumerator TrackOrderStatus(PurchaseData purchaseData)
            {
                var isDone = false;
                while (!isDone)
                {
                    XsollaOrders.Instance.CheckOrderStatus
                    (
                        XsollaSettings.StoreProjectId,
                        purchaseData.order_id,
                        status =>
                        {
                            if (status.status == "paid" || status.status == "done")
                            {
                                isDone = true;
                                OnPurchaseSuccess();
                            }
                        },
                        error => { OnError(error); }
                    );
    
                    yield return new WaitForSeconds(1f);
                }
            }
    
            private void OnPurchaseSuccess()
            {
                UnityEngine.Debug.Log($"Purchase successful");
                BrowserHelper.Instance.Close();
            }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
            }
        }
    }
    

    Was this article helpful?
    Thank you!
    Is there anything we can improve? Message
    We’re sorry to hear that
    Please explain why this article wasn’t helpful to you. Message
    Thank you for your feedback!
    We’ll review your message and use it to help us improve your experience.
    Hide

    Sell virtual items for virtual currency

    This instruction shows how to use the SDK methods to implement selling of virtual items for virtual currency.

    Before you start, implement a display of virtual items in a catalog. In the following example, we describe how to implement purchasing of virtual items. Configuration for other item types is similar.

    This tutorial describes the implementation of the following logic:

    The logic and interface in the examples are less complicated than they will be in your application. A possible implementation option for selling items for real currency and displaying a catalog of items is described in the demo project.

    Complete item widget

    Add a purchase button to the item widget and configure its visuals.

    The following picture shows an example of the widget structure.

    Complete item widget script

    1. Open the VirtualItemWidget script.
    2. Declare variables for the purchase button and set values for them in the Inspector panel.

    Example of the widget script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Recipes
    {
        public class VirtualItemWidget : MonoBehaviour
        {
            // Declaration of variables for UI elements
    
            public Text NameText;
    
            public Text DescriptionText;
    
            public Text PriceText;
    
            public Image IconImage;
    
            public Button BuyButton;
        }
    }
    

    Complete page controller to show list of items

    1. Open the VirtualItemsPage script.
    2. In the OnAuthenticationSuccess method, pass the authorization token to the Token.Instance variable.

    Note
    You can use one of the following tokens:

    1. Add logic for processing clicking on the virtual item purchase button:
      1. In the OnItemsRequestSuccess method, subscribe to the button-clicking event.
      2. Add an anonymous method that is called after the button is clicked.
      3. In this method, call the XsollaCatalog.Instance.PurchaseItem SDK method to form an order and pass to it:

        • a Project ID in the projectId parameter
        • an item identifier in the itemSku parameter
        • the OnOrderCreateSuccess method to process a successful forming of the item purchase order
        • the OnError callback method for an error

    1. In the OnOrderCreateSuccess method, implement the order status check process. To do this, use the XsollaOrders.Instance.CheckOrderStatus SDK method and pass to it:
      • a Project ID in the projectId parameter
      • an order number from payment details in the orderId parameter
      • an anonymous method for processing successful receiving of order status info
      • an anonymous method for error processing

    1. In the method for processing successful receiving of order status info, implement the callback of an OnPurchaseSuccess method during the payment for the order (payment status done or paid).
    2. In the OnPurchaseSuccess method, implement the processing of a successful virtual item purchase.

    Note

    In the script example, we call the Debug.Log base method if the item purchase is successful. You can add other actions like inventory display, virtual currency balance change, etc.

    Implementation of logic for adding purchased items to the inventory isn’t required — it’s done automatically.

    Example of a script for a page:

    Copy
    Full screen
    Small screen
    using System.Linq;
    using UnityEngine;
    using Xsolla.Auth;
    using Xsolla.Catalog;
    using Xsolla.Core;
    using Xsolla.Orders;
    
    namespace Recipes
    {
        public class VirtualItemsPage : MonoBehaviour
        {
            // Declaration of variables for containers and widget prefabs
    
            public Transform WidgetsContainer;
    
            public GameObject WidgetPrefab;
    
            private void Start()
            {
                // Starting the authentication process
    
                XsollaAuth.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess, onError: OnError);
            }
    
            private void OnAuthenticationSuccess(string token)
            {
                // After successful authentication starting the request for catalog from store
             Token.Instance = Token.Create(token);
                XsollaCatalog.Instance.GetCatalog(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError, offset: 0, limit: 50);
            }
    
            private void OnItemsRequestSuccess(StoreItems storeItems)
            {
                // Iterating the items collection and assign values for appropriate ui elements
             foreach (var storeItem in storeItems.items)
                {
                    if (storeItem.virtual_prices.Length == 0)
                        continue;
    
                    var widget = Instantiate(WidgetPrefab, WidgetsContainer, false).GetComponent<VirtualItemWidget>();
    
                    widget.NameText.text = storeItem.name;
                    widget.DescriptionText.text = storeItem.description;
    
                    var defaultPrice = storeItem.virtual_prices.First(x => x.is_default);
                    widget.PriceText.text = $"{defaultPrice.name}: {defaultPrice.amount}";
    
                    ImageLoader.Instance.GetImageAsync(storeItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
    
                    widget.BuyButton.onClick.AddListener(() =>
                    {
                        var price = storeItem.virtual_prices.First(x => x.is_default);
                        XsollaCatalog.Instance.PurchaseItemForVirtualCurrency(XsollaSettings.StoreProjectId, storeItem.sku, price.sku, OnOrderCreateSuccess, OnError);
                    });
                }
            }
    
            private void OnOrderCreateSuccess(PurchaseData purchaseData)
            {
                XsollaOrders.Instance.CheckOrderStatus
                (
                    XsollaSettings.StoreProjectId,
                    purchaseData.order_id,
                    status =>
                    {
                        if (status.status == "paid" || status.status == "done")
                        {
                            OnPurchaseSuccess();
                        }
                    },
                    error =>
                    {
                        OnError(error);
                    }
                );
            }
    
    
            private void OnPurchaseSuccess()
            {
                UnityEngine.Debug.Log($"Purchase successful");
            }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
            }
        }
    }
    

    Was this article helpful?
    Thank you!
    Is there anything we can improve? Message
    We’re sorry to hear that
    Please explain why this article wasn’t helpful to you. Message
    Thank you for your feedback!
    We’ll review your message and use it to help us improve your experience.
    Hide

    Display of virtual currency balance

    This tutorial shows how to use the SDK methods to display the balance of virtual currency in your app.

    The logics and interface in the examples are less complicated than they will be in your application. A possible item catalog in an in-game store implementation option is described in the demo project.

    Create widget for display of balance

    1. Create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Convert the created game object in a prefab by dragging a game object from a Hierarchy panel to a Project panel.
    3. Select a created prefab and click Open Prefab in the Inspector panel.
    4. Add the following UI elements as prefab child objects and configure their visuals:
      • widget background image
      • virtual currency name
      • virtual currency quantity
      • virtual currency image

    The following picture shows an example of the widget structure.

    Create widget script to show balance

    1. Create a script VirtualCurrencyWidget inherited from the MonoBehaviour base class.
    2. Declare variables for the item widget interface elements and set values for them in the Inspector panel.

    Example of the widget script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Recipes
    {
        public class VirtualCurrencyWidget : MonoBehaviour
        {
            // Declaration of variables for UI elements
    
            public Text NameText;
    
            public Text AmountText;
    
            public Image IconImage;
        }
    }
    

    Create page with list of virtual currencies

    1. On the scene, create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Add the following UI elements as prefab child objects and configure their visuals:
      • page background image
      • widgets display area

    The following picture shows an example of the page structure.

    Create controller for page with list of virtual currencies

    1. Create a script VirtualCurrenciesPage inherited from the MonoBehaviour base class.
    2. Declare the following variables:
      • WidgetsContainer — container for widgets
      • WidgetPrefab — balance display widget prefab

    1. Attach a script to a page game object:
      1. Select an object in a Hierarchy panel.
      2. In the Inspector panel, click Add Component and select a VirtualCurrenciesPage script.

    1. Set values for variables in the Inspector panel.
    2. Add login logics by calling an XsollaAuth.Instance.SignIn SDK method in the Start method and pass to it:
      • a username or email address in the username parameter
      • a user password in the password parameter

    Note
    In the script example, to login we use the credentials of a demo account (username: xsolla, password: xsolla).

      • a flag in the rememberUser parameter for remembering an account
      • the OnAuthenticationSuccess callback method for successful user login
      • the OnError callback method for an error

    1. Add logics of getting a list of virtual currencies. To do this, in the OnAuthenticationSuccess method:
      1. Pass the authorization token to the Token.Instance variable.

    Note
    You can use one of the following tokens:

      1. Call the XsollaInventory.Instance.GetVirtualCurrencyBalance SDK method and pass to it:
        • the Project ID in the projectId parameter

    Note
    You can find the Project ID in Project settings in Publisher Account. In the script example, we passed the value from the SDK settings to a parameter.

        • the OnBalanceRequestSuccess method for successful operation of getting a list of items
        • the OnError callback method for an error

    1. In the OnBalanceRequestSuccess method, add logics for creating a widget for every received virtual currency:
      1. Instantiate a prefab of item widget as a container child object.
      2. Attach the received VirtualCurrencyWidget component to a widget variable.

    1. Pass the following data to the balance widget:
      1. Pass the balanceItem.name variable value to the element with the virtual currency name.
      2. Pass the balanceItem.amount.ToString() variable value to the element with the quantity of the virtual currency.
      3. Implement the following logics to display the item price. To show a virtual currency image, use the ImageLoader.Instance.GetImageAsync utility method, and pass to it:
        • The image URL.
        • An anonymous callback function. In this function, set the received sprite as a virtual currency image.

    Example of the page controller script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using Xsolla.Auth;
    using Xsolla.Core;
    using Xsolla.Inventory;
    
    namespace Recipes
    {
        public class VirtualCurrenciesPage : MonoBehaviour
        {
            // Declaration of variables for containers and widget prefabs
    
            public Transform WidgetsContainer;
    
            public GameObject WidgetPrefab;
    
            private void Start()
            {
                // Starting the authentication process
    
                XsollaAuth.Instance.SignIn("xsolla", "xsolla", true, null, null, OnAuthenticationSuccess, OnError);
            }
    
            private void OnAuthenticationSuccess(string token)
            {
                // After successful authentication starting the request for virtual currencies
    
                Token.Instance = Token.Create(token);
                XsollaInventory.Instance.GetVirtualCurrencyBalance(XsollaSettings.StoreProjectId, OnBalanceRequestSuccess, OnError);
            }
    
            private void OnBalanceRequestSuccess(VirtualCurrencyBalances balance)
            {
                // Iterating the virtual currencies list and assign values for appropriate ui elements
    
                foreach (var balanceItem in balance.items)
                {
                    var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
                    var widget = widgetGo.GetComponent<VirtualCurrencyWidget>();
    
                    widget.NameText.text = balanceItem.name;
                    widget.AmountText.text = balanceItem.amount.ToString();
    
                    ImageLoader.Instance.GetImageAsync(balanceItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
                }
            }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
            }
        }
    }
    

    The following picture shows the result of the script’s work.

    Was this article helpful?
    Thank you!
    Is there anything we can improve? Message
    We’re sorry to hear that
    Please explain why this article wasn’t helpful to you. Message
    Thank you for your feedback!
    We’ll review your message and use it to help us improve your experience.
    Hide

    Display of items in inventory

    This tutorial shows how to use the SDK methods to display items in the user inventory.

    The logics and interface in the examples are less complicated than they will be in your application. A possible inventory implementation option is described in the demo project.

    Create item widget

    1. Create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Convert the created game object in a prefab by dragging a game object from a Hierarchy panel to a Project panel.
    3. Select a created prefab and click Open Prefab in the Inspector panel.
    4. Add the following UI elements as prefab child objects and configure their visuals:
      • item background image
      • item name
      • item description
      • item quantity
      • item image

    The following picture shows an example of the widget structure.

    Create item widget script

    1. Create a script InventoryItemWidget inherited from the MonoBehaviour base class.
    2. Declare variables for the item widget interface elements and set values for them in the Inspector panel.

    Example of the widget script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Recipes
    {
        public class InventoryItemWidget : MonoBehaviour
        {
            // Declaration of variables for UI elements
    
            public Text NameText;
    
            public Text DescriptionText;
    
            public Text QuantityText;
    
            public Image IconImage;
        }
    }
    

    Create page to show inventory

    1. On the scene, create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.
    2. Add the following UI elements as prefab child objects and configure their visuals:
      • page background image
      • item widgets display area

    The following picture shows an example of the page structure.

    Create page controller

    1. Create a script InventoryItemsPage inherited from the MonoBehaviour base class.
    2. Declare the following variables:
      • WidgetsContainer — container for item widgets
      • WidgetPrefab — item widget prefab

    1. Attach a script to a page game object:
      1. Select an object in a Hierarchy panel.
      2. In the Inspector panel, click Add Component and select an InventoryItemsPage script.

    1. Set values for variables in the Inspector panel.
    2. Add login logics by calling an XsollaAuth.Instance.SignIn SDK method in the Start method and pass to it:
      • a username or email address in the username parameter
      • a user password in the password parameter

    Note
    In the script example, to login we use the credentials of a demo account (username: xsolla, password: xsolla).

      • a flag in the rememberUser parameter for remembering an account
      • the OnAuthenticationSuccess callback method for successful user login
      • the OnError callback method for an error

    1. Add logic for getting the list of items in the inventory. To do this, in the OnAuthenticationSuccess method:
      1. Pass an authorization token to the Token.Instance variable.

    Note
    You can use one of the following tokens:

      1. Call the XsollaInventory.Instance.GetInventoryItems SDK method and pass to it:
        • a Project ID in the projectId parameter

    Note
    You can find the project ID in Project settings in Publisher Account. In the script example, we passed the value from the SDK settings to a parameter.

        • the OnItemsRequestSuccess for successful operation of getting a list of items
        • the OnError callback method for an error

    1. For every received item in the OnItemsRequestSuccess method, add logic for creating a widget:
      1. Use the InventoryItem.IsVirtualCurrency method, to add a check to make sure a received item isn’t a virtual currency.

    Note
    In this example, we demonstrate only virtual items, bundles, and subscriptions in the inventory. Implement display of virtual currency balance on a separate page.

      1. Instantiate a prefab of an item widget as a container child object.
      2. Attach the received InventoryItemWidget component to a widget variable.

    1. Pass the following data to the item widget:
      1. Pass the inventoryItem.name variable value to the element with the item name.
      2. Pass the inventoryItem.description variable value to the element with the item description.
      3. Pass the inventoryItem.amount.ToString() to the element with the item quantity.
      4. To display an item image, use the ImageLoader.Instance.GetImageAsync utility method and pass to it:
        • Image URL
        • An anonymous function as a callback. In this function, add a received sprite as an item image.

    Example of the page controller script:

    Copy
    Full screen
    Small screen
    using UnityEngine;
    using Xsolla.Auth;
    using Xsolla.Core;
    using Xsolla.Inventory;
    
    namespace Recipes
    {
        public class InventoryItemsPage : MonoBehaviour
        {
            // Declaration of variables for containers and widget prefabs
         public Transform WidgetsContainer;
    
            public GameObject WidgetPrefab;
    
            private void Start()
            {
                // Starting the authentication process
             XsollaAuth.Instance.SignIn("xsolla", "xsolla", true, null, null, OnAuthenticationSuccess, OnError);
            }
    
            private void OnAuthenticationSuccess(string token)
            {
                // After successful authentication starting the request for virtual currencies
             Token.Instance = Token.Create(token);
                XsollaInventory.Instance.GetInventoryItems(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError);
            }
    
            private void OnItemsRequestSuccess(InventoryItems inventoryItems)
            {
                // Iterating the item list and assign values for appropriate ui elements
    
                foreach (var inventoryItem in inventoryItems.items)
                {
                    if (inventoryItem.IsVirtualCurrency())
                        continue;
    
                    var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
                    var widget = widgetGo.GetComponent<InventoryItemWidget>();
    
                    widget.NameText.text = inventoryItem.name;
                    widget.DescriptionText.text = inventoryItem.description;
                    widget.QuantityText.text = inventoryItem.quantity.ToString();
    
                    ImageLoader.Instance.GetImageAsync(inventoryItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
                }
            }
    
            private void OnError(Error error)
            {
                UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
            }
        }
    }
    

    The following picture shows the result of the script’s work.

    Was this article helpful?
    Thank you!
    Is there anything we can improve? Message
    We’re sorry to hear that
    Please explain why this article wasn’t helpful to you. Message
    Thank you for your feedback!
    We’ll review your message and use it to help us improve your experience.
    Hide
    Your progress
    Thank you for your feedback!

    Useful links

    Last updated: August 8, 2022

    Found a typo or other text error? Select the text and press Ctrl+Enter.

    Report a problem
    We always review our content. Your feedback helps us improve it.
    Provide an email so we can follow up
    Thank you for your feedback!