SDKs for Unity / How to use Pay Station in combination with PlayFab authentication
  Back to Docs

SDKs for Unity

How to use Pay Station in combination with PlayFab authentication

If you have already implemented user authentication in your application using PlayFab, you can generate a payment token on PlayFab side and then pass it to the client side of the application to open the payment UI.

Using this integration option, you need to independently implement the logic for determining the user’s country and currency to pay for the purchase.

Integration flow:

  1. Create a project.
  1. Sign up to Publisher Account and create a new project. You will need the ID of the created project in further steps.

  1. Set up a catalog:
    • Create an item catalog on Xsolla side. You can add items manually or import them from Google Play or PlayFab.
    • Implement getting and displaying the catalog on the client side of the application using the SDK.

  1. Set up an item purchase:
    • Create an order with user and item data on the client side of the application using the PlayFab cloud script.
    • Implement the opening of the payment UI on the client side of your application using the SDK.

  1. Set up an order status tracking.

Notice

To complete the integration and start accepting real payments, you need to sign a licensing agreement with Xsolla.

You can sign the licensing agreement at any integration step, but keep in mind that the review process can take up to 3 business days.

Create project

Sign up to Publisher Account

Publisher Account is the main tool to configure Xsolla features, as well as to work with analytics and transactions.

The data about the company and your application specified during registration will be used to create a draft licensing agreement with Xsolla and to generate recommendations on solutions that are suitable for you. You can change the data later, but providing the correct data when you sign up will speed up the process of signing the licensing agreement.

To sign up, go to Publisher Account and create an account.

Note

The password from Publisher Account can consist of Latin letters, numerals, and special characters and must contain at least:

  • 8 characters
  • one digit
  • one capital letter
  • one lowercase letter

To ensure password security, we recommend:

  • changing your password at least once every 90 days
  • using a new password that does not match the last 4 passwords on your account
  • using a unique password that does not match passwords used anywhere else
  • not storing your password where it is easily accessible
  • using password managers to store your password

Publisher account uses two-factor authentication and sends a confirmation code with each authentication attempt.

Create project in Publisher Account

If you have multiple applications, we recommend creating a separate project for each application. Based on the data specified during project creation, Xsolla generates recommendations on solutions that are suitable for you.

To create a new project:

  1. Open Publisher Account.
  2. In the side menu, click Create project.

  1. Enter your project name in English (required).

Note
After you’ve created the project, you can add additional languages and localized project names in the Project settings section.

  1. Select one or several release platforms of your game (required).
  2. Add a link to your game. If your game doesn’t have a website yet, add a link to the source that includes information about the game (required).
  3. Select the game engine.
  4. Select the monetization options you use or plan to use.
  5. Specify if the game is already released. If the game hasn’t been released yet, specify the planned release date.
  6. Click Create project. You will see a page with the Xsolla products recommended for you.

During the integration process, you need to provide the project ID that can be found in your Publisher Account next to the project name.

Set up catalog

Create items in Publisher Account

Notice

You need to create a catalog on Xsolla side. You can add items manually or import them from Google Play or PlayFab. When importing from Google Play, you can import a maximum of 100 items at a time.

These instructions provide steps for basic setup of a virtual item. Later, you can add other items to your catalog (virtual currency, bundles, game keys), create item groups, set up promotional campaigns, regional prices, etc.

To add a virtual item with basic settings to the catalog:

  1. Open your project in Publisher Account.
  2. Click Store in the side menu.
  3. In the Virtual Items pane, click Connect.
  4. In the drop-down menu, select Create item.

  1. Set the basic settings of the item in the following fields:
    • Image (optional)
    • SKU (item unique ID)
    • Item name
    • Description (optional)

  1. Specify item price:
    1. Set the Price in real currency toggle to On.
    2. In the Default currency field, change the currency (optional) and specify the item price.
    3. If you changed the currency in the Default currency field, select the same currency in the Price in real currency field.

Note
To ensure that the API calls for getting the catalog work correctly, make sure that the default currency and the list of currencies in which prices are specified match for all items.

  1. Change the item status to Available.

  1. Click Create item.

Display catalog on client side of application

  1. Download the SDK from CDN or GitHub.
  2. Unzip the package.
  3. In the main menu, go to Assets > Import Package > Custom Package and select the downloaded SDK.
  4. In the main menu, go to Window > Xsolla > Edit Settings.
  5. Go to Inspector panel. In the Project ID field, specify the project ID that can be found in Publisher Account next to the name of your project.

  1. On the client side of the application, add a UI to display the product catalog.
  2. Implement requesting for an item catalog from Xsolla servers.

Note

To get a list of virtual items, use the GetCatalog SDK method. You can also get information about catalog items using other SDK methods.

For a step-by-step tutorial on creating a catalog page, refer to Display of item catalog.

Set up item purchase

To create an order with user and item data on Xsolla side, add a Cloud Function to the project that uses the Create payment token for purchase API call. This call will return a payment token, which is required to open the payment UI and make a purchase.

Limitations:

  • You need to pass either the user country or the user’s IP address when requesting the payment token.
  • If you don’t pass the currency in the token, it is determined by the country.
  • If you pass the currency in the token, the user pays in this currency.

Note

PlayFab project should be created and PlayFab SDK should already be integrated into your Unity project.

PlayFab Cloud Scripts do not directly support functions with HTTP triggers, so Azure functions are used to implement the receiving of webhooks.

To get started with Azure functions, create an Azure account and prepare your development environment. This instruction describes the steps in the development environment with the following settings:

Add cloud script to your project

  1. Open Visual Studio Code and go to the Azure tab.
  2. In the Workspace section, click the + icon and select Create Function.

  1. Select the new project directory. A menu for creating a new project will appear with a choice of settings.

  1. Specify the new project settings:
    1. Select a language for your function project — C#.
    2. Select a .NET runtime — .NET 8.0 Isolated (LTS).
    3. Select a template for your project’s first function — HTTP trigger.
    4. Enter a function name — GetXsollaPaymentToken.
    5. Enter a namespace — My.Functions.
    6. Select the authorization level — Anonymous.
    7. Select how you would like to open your project — Open in current window.

  1. As a result, Visual Studio Code will generate a C# project and open the generated GetXsollaPaymentToken.cs file.

  1. Modify the GetXsollaPaymentToken.cs file:

Copy
Full screen
Small screen
using System.Text;
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace My.Function
{
    public class GetXsollaPaymentToken
    {
        private readonly ILogger<GetXsollaPaymentToken> _logger;

        private const int PROJECT_ID = ""; // Your Xsolla project ID
        private const string API_KEY = ""; // Your Xsolla API key

        public GetXsollaPaymentToken(ILogger<GetXsollaPaymentToken> logger)
        {
            _logger = logger;
        }

        [Function("GetXsollaPaymentToken")]
        public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
        {
            _logger.LogInformation("GetXsollaPaymentToken function processed a request.");

            // Reading the request body
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            _logger.LogInformation("Request body: " + requestBody);

            // Deserializing request body JSON
            dynamic data = JsonConvert.DeserializeObject(requestBody);

            // Extracting necessary data from JSON
            string uid = data.FunctionArgument.uid;
            string sku = data.FunctionArgument.sku;
            string returnUrl = data.FunctionArgument.returnUrl;

            // Creating payload for Xsolla API
            var payload = new
            {
                user = new
                {
                    id = new { value = uid },
                    country = new { value = "US", allow_modify = false }
                },
                purchase = new
                {
                    items = new[]
                    {
                        new { sku = sku, quantity = 1 }
                    }
                },
                sandbox = true,
                settings = new
                {
                    language = "en",
                    currency = "USD",
                    return_url = returnUrl,
                    ui = new { theme = "63295aab2e47fab76f7708e3" }
                }
            };

            // Constructing Xsolla API URL
            string url = $"https://store.xsolla.com/api/v3/project/{PROJECT_ID}/admin/payment/token";

            // Sending request to Xsolla API
            using (HttpClient client = new HttpClient())
            {
                // Adding authorization header
                string headerValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{PROJECT_ID}:{API_KEY}"));
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", headerValue);

                // Serializing payload to JSON
                var jsonPayload = JsonConvert.SerializeObject(payload);
                var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");

                // Making POST request to Xsolla API
                var xsollaRes = await client.PostAsync(url, content);

                // Checking response from Xsolla API
                if (xsollaRes.IsSuccessStatusCode)
                {
                    // Reading successful response content
                    string responseContent = await xsollaRes.Content.ReadAsStringAsync();
                    return new OkObjectResult(responseContent);
                }
                else
                {
                    // Returning status code in case of failure
                    return new StatusCodeResult((int)xsollaRes.StatusCode);
                }
            }
        }
    }
}

  1. In the script, specify the values of the constants:

    • PROJECT_ID — project ID that you can find in your Publisher Account next to the project name.

    • API_KEY — API key. It is shown in Publisher Account only once when it is created and must be stored on your side. You can create a new key in the following section:
      • Company settings > API keys
      • Project settings > API keys

After adding the cloud script, you can test the call of the GetXsollaPaymentToken function locally.

Deploy cloud script

  1. In Visual Studio Code go to Azure > Resources section and click the + icon.
  2. Select Create Function App in Azure as a resource. A menu for creating a new application will appear with a choice of settings.
  3. Set application settings:

    1. Enter the name for the new function app — XsollaFunctions.
    2. Select a runtime stack — .NET 8 Isolated.
    3. Select a location for new resources (you can choose any option).

  1. Wait until the resource group is created.

  1. In the list of resources, select the XsollaFunctions, call the context menu and select Deply to Function App.

After adding the cloud script, you can test the call of the GetXsollaPaymentToken function remotely.

Test cloud script

To test the cloud script (locally or remotely), call the GetXsollaPaymentToken function using Postman or another tool. To do this:

  1. In Visual Studio Code, go to the Azure > Workspace > Local Project > Functions section and click Start debugging to update this list.
  2. Call the context menu for the function and select Copy Function Url. When testing locally, the URL will look like this — http://localhost:7071/api/getXsollaPaymentToken. When testing remotely — https://xsollafunctions.azurewebsites.net/api/GetXsollaPaymentToken.

  1. Use the copied URL to call the function with the specified parameters. To call a function from Postman:
    1. Create a new GET request.
    2. Provide the URL you copied in step 2.
    3. Go to the Body tab and specify the request parameters.

Example request body:

Copy
Full screen
Small screen
    {
    
     "FunctionArgument": {
    
       "uid": "1D384D9EF12EAB8B",
    
       "sku": "booster_max_1",
    
       "returnUrl": "https://login.xsolla.com/api/blank"
    
     }
    
    }
    
    Note
    You can specify any value for the user ID (uid). As the item SKU (sku), specify the SKU of the virtual item that you previously added in Publisher Account.

    1. Click Send. In the response you should receive JSON with the following parameters:
      • token — payment token. Required to open the payment UI.
      • order_id — ID of the created order. Required to track order status.

    Example response body:

    Copy
    Full screen
    Small screen
      {"token":"xsnpCF8tS4ox7quoibgTgPFVFxG9gTvS_lc_en_bg_2C2640_tb_6E7BF7","order_id":90288613}
      

      Register function for getting payment token in PlayFab

      1. Open your project in PlayFab.
      2. In the side menu, click Automation.
      3. In the Register New Cloud Script Function. section, click Register Function.
      4. Enter the name of the function — GetXsollaPaymentToken.
      5. Enter the function URL that you copied into Visual Code Studio (see steps 1-2 of Test cloud script).

      Create order and open the payment UI in Unity project

      1. Open your Unity project.
      2. Create the XsollaPlayfabSample.cs script with the following content:

      Copy
      Full screen
      Small screen
      using System;
      using PlayFab;
      using PlayFab.ClientModels;
      using PlayFab.CloudScriptModels;
      using UnityEngine;
      using Xsolla.Core;
      
      public class XsollaPlayfabSample : MonoBehaviour
      {
          private void Start()
          {
              // Logging in anonymously
              LoginAnonymous(
                  // Callback function invoked after successful login
                  userId => {
                      // Requesting Xsolla payment token
                      GetXsollaPaymentToken(
                          userId, // PlayFab user ID received after login
                          "booster_max_1", // SKU of the product
                          orderData => {
                              // Creating Xsolla token and opening purchase UI
                              XsollaToken.Create(orderData.token);
                              XsollaWebBrowser.OpenPurchaseUI(orderData.token);
      
                              // Adding order for tracking
                              OrderTrackingService.AddOrderForTracking(
                                  orderData.order_id,
                                  true,
                                  () => Debug.Log("Payment completed"),
                                  onError => Debug.LogError(onError.errorMessage));
                          });
                  });
          }
      
          private static void LoginAnonymous(Action<string> onSuccess)
          {
              // Logging in with custom ID
              PlayFabClientAPI.LoginWithCustomID(
                  new LoginWithCustomIDRequest {
                      CustomId = SystemInfo.deviceUniqueIdentifier, // Unique ID generated based on the device
                      CreateAccount = true
                  },
                  result => {
                      // Logging the result
                      Debug.Log("Logged with playfab id: " + result.PlayFabId);
      
                      // Invoking onSuccess callback with PlayFab ID
                      onSuccess?.Invoke(result.PlayFabId);
                  },
                  error => { Debug.LogError(error.GenerateErrorReport()); }); // Handling login error
          }
      
          private static void GetXsollaPaymentToken(string userId, string sku, Action<OrderData> onSuccess)
          {
              // Creating request data for Xsolla payment token
              var tokenRequestData = new PaymentTokenRequestData {
                  uid = userId, // User ID
                  sku = sku, // Product SKU
                  returnUrl = $"app://xpayment.{Application.identifier}" // Return URL
              };
      
              // Executing a function in the PlayFab cloud to get payment token
              PlayFabCloudScriptAPI.ExecuteFunction(
                  new ExecuteFunctionRequest {
                      FunctionName = "GetXsollaPaymentToken", // Name of Azure function
                      FunctionParameter = tokenRequestData, // Data passed to the function
                      GeneratePlayStreamEvent = false // Setting true if call should show up in PlayStream
                  },
                  result => {
                      // Logging the result
                      Debug.Log($"GetXsollaPaymentToken result: {result.FunctionResult}");
      
                      // Parsing JSON result to OrderData object
                      OrderData orderData = JsonUtility.FromJson<OrderData>(result.FunctionResult.ToString());
      
                      // Invoking onSuccess callback with order data
                      onSuccess?.Invoke(orderData);
                  },
                  error => Debug.LogError($"Error: {error.GenerateErrorReport()}")); // Handling error
          }
      
          // Class for payment token request data
          public class PaymentTokenRequestData
          {
              public string uid; // User ID
              public string sku; // Product SKU
              public string returnUrl; // Return URL
          }
      }
      

      1. Create a new scene.
      2. Create an empty game object. To do this, go to the main menu and select GameObject > Create Empty.

      1. Add a script to the game object:
        1. In the Hierarchy panel, select the object.
        2. In the Inspector panel, click Add Component and select the XsollaPlayfabSample script.

      1. In the Hierarchy panel, call the context menu and select UI > EventSystem.

      To test order creation, run the scene by clicking Play. As a result, the payment UI with order information should appear.

      The source code for the Unity project is available on GitHub.

      Set up order status tracking

      Tracking the order status is required to ensure that the payment was successful and to grant items to the user.

      Get order status on client side

      The order tracking logic is included in the GetXsollaPaymentToken method. To process a successful purchase, you need to pass a function that is called when order status changes to done.

      The AddOrderForTracking SDK method is used for tracking. For detailed information about how the method works, refer to Track order status.

      Get order status on server side

      Notice

      The SDK allows you to track the order status on the client side of your application. However, we recommend setting up the Payment webhook handler to receive order information in the back end of your application. This allows you to implement additional validation of completed purchases.

      For the full list of webhooks and general information about working with them, refer to the webhooks documentation.

      To configure webhooks on Xsolla side:

      1. Open your project in Publisher Account.
      2. Click Project settings in the side menu and go to the Webhooks section.
      3. In the Webhook server field, enter the URL to which Xsolla will send webhooks.

      Note

      To test webhooks, you can also choose any dedicated site, such as webhook.site, or a platform, such as ngrok.

      For testing purposes, you can also add a cloud script that simulates successful webhook processing. The script code is available on GitHub.

      For a real project, you need to add purchase validation logic.

      1. Copy and save the value from the Secret key field. This key is generated by default and is used to sign webhooks. If you want to change it, click the update icon.
      2. Click Enable webhooks.

      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.
      Rate this page
      Rate this page
      Is there anything we can improve?

      Don’t want to answer

      Thank you for your feedback!
      Last updated: April 5, 2024

      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!