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:
- Sign up to Publisher Account and create a new project. You will need the ID of the created project in further steps.
- 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.
- 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.
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.
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:
- Open Publisher Account.
- In the side menu, click Create project.
- Enter your project name in English (required).
- Select one or several release platforms of your game (required).
- 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).
- Select the game engine.
- Select the monetization options you use or plan to use.
- Specify if the game is already released. If the game hasn’t been released yet, specify the planned release date.
- 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
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:
- Open your project in Publisher Account.
- Click Store in the side menu.
- In the Virtual Items pane, click Connect.
- In the drop-down menu, select Create item.
- Set the basic settings of the item in the following fields:
- Image (optional)
- SKU (item unique ID)
- Item name
- Description (optional)
- Specify item price:
- Set the Price in real currency toggle to On.
- In the Default currency field, change the currency (optional) and specify the item price.
- If you changed the currency in the Default currency field, select the same currency in the Price in real currency field.
- Change the item status to Available.
- Click Create item.
Display catalog on client side of application
- Download the SDK from CDN or GitHub.
- Unzip the package.
- In the main menu, go to
Assets > Import Package > Custom Package and select the downloaded SDK. - In the main menu, go to
Window > Xsolla > Edit Settings . - Go to
Inspector panel. In theProject ID field, specify the project ID that can be found in Publisher Account next to the name of your project.
- On the client side of the application, add a UI to display the product catalog.
- Implement requesting for an item catalog from Xsolla servers.
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.
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:
- Visual Studio Code is installed.
- .NET 8.0 SDK is installed.
- The extension for working with C# is installed.
- The extension for working with Azure functions has been installed.
Add cloud script to your project
- Open Visual Studio Code and go to the
Azure tab. - In the
Workspace section, click the + icon and selectCreate Function .
- Select the new project directory. A menu for creating a new project will appear with a choice of settings.
- Specify the new project settings:
- Select a language for your function project —
C# . - Select a .NET runtime —
.NET 8.0 Isolated (LTS) . - Select a template for your project’s first function —
HTTP trigger . - Enter a function name —
GetXsollaPaymentToken
. - Enter a namespace —
My.Functions
. - Select the authorization level —
Anonymous . - Select how you would like to open your project —
Open in current window .
- Select a language for your function project —
- As a result, Visual Studio Code will generate a C# project and open the generated
GetXsollaPaymentToken.cs
file.
- Modify the
GetXsollaPaymentToken.cs
file:
- C#
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);
}
}
}
}
}
- 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
- In Visual Studio Code go to
Azure > Resources section and click the + icon. - Select
Create Function App in Azure as a resource. A menu for creating a new application will appear with a choice of settings. - Set application settings:
- Enter the name for the new function app —
XsollaFunctions
. - Select a runtime stack —
.NET 8 Isolated . - Select a location for new resources (you can choose any option).
- Enter the name for the new function app —
- Wait until the resource group is created.
- In the list of resources, select the
XsollaFunctions
, call the context menu and selectDeply 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:
- In Visual Studio Code, go to the
Azure > Workspace > Local Project > Functions section and clickStart debugging to update this list . - 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
.
- Use the copied URL to call the function with the specified parameters. To call a function from Postman:
- Create a new
GET
request. - Provide the URL you copied in step 2.
- Go to the
Body tab and specify the request parameters.
- Create a new
Example request body:
- json
{
"FunctionArgument": {
"uid": "1D384D9EF12EAB8B",
"sku": "booster_max_1",
"returnUrl": "https://login.xsolla.com/api/blank"
}
}
uid
). As the item SKU (sku
), specify the SKU of the virtual item that you previously added in Publisher Account.- 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:
- json
{"token":"xsnpCF8tS4ox7quoibgTgPFVFxG9gTvS_lc_en_bg_2C2640_tb_6E7BF7","order_id":90288613}
Register function for getting payment token in PlayFab
- Open your project in PlayFab.
- In the side menu, click
Automation . - In the
Register New Cloud Script Function . section, clickRegister Function . - Enter the name of the function —
GetXsollaPaymentToken
. - 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
- Open your Unity project.
- Create the
XsollaPlayfabSample.cs
script with the following content:
- C#
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
}
}
- Create a new scene.
- Create an empty game object. To do this, go to the main menu and select
GameObject > Create Empty .
- Add a script to the game object:
- In the
Hierarchy panel, select the object. - In the
Inspector panel, clickAdd Component and select theXsollaPlayfabSample
script.
- In the
- In the
Hierarchy panel, call the context menu and selectUI > EventSystem .
To test order creation, run the scene by clicking
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
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:
- Open your project in Publisher Account.
- Click Project settings in the side menu and go to the Webhooks section.
- In the Webhook server field, enter the URL to which Xsolla will send webhooks.
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.
- 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.
- Click Enable webhooks.
Found a typo or other text error? Select the text and press Ctrl+Enter.