Unity专用SDK(PC、网页端) / 如何结合PlayFab身份认证使用支付中心
  返回文档

Unity专用SDK(PC、网页端)

如何结合PlayFab身份认证使用支付中心

如已使用PlayFab在应用程序中实现用户身份认证,可在PlayFab侧生成一个支付令牌,然后将其传入应用程序的客户端侧来打开支付UI。

如使用此集成方案,需独立实现决定用户国家/地区和支付所使用的货币的逻辑。

集成过程:

  1. 创建项目
  1. 注册发布商帐户并新建一个项目。后续步骤需要用到所创建项目的ID。

  1. 设置目录
    • 在艾克索拉侧创建一个商品目录。您可以手动添加商品或从Google Play或PlayFab导入。
    • 使用SDK实现在应用程序客户端侧获取和显示目录。

  1. 设置商品购买
    • 通过PlayFab云脚本使用用户和商品数据在应用程序客户端侧创建一个订单。
    • 使用SDK实现在应用程序客户端侧打开支付UI。

  1. 设置订单状态跟踪

注意

要完成集成并开始接收真实付款,您需要签署与艾克索拉的许可协议

您可以在集成的任意阶段签署许可协议,但请知晓审核过程最长可能需要3个工作日。

创建项目

注册发布商帐户

发布商帐户是配置艾克索拉功能以及对分析和交易进行操作的主要工具。

注册时指定的公司及应用程序信息将用于创建与艾克索拉许可协议的草稿以及生成合适解决方案的推荐。后续您可以更改这些数据,但在注册时提供正确的信息可以加快签署许可协议的速度。

要注册,请前往发布商帐户,然后创建一个帐户。

注:

发布商帐户的密码可以由英文字母、数字和特殊字符组成,必须包含至少:

  • 8个字符
  • 一个数字
  • 一个大写字母
  • 一个小写字母

为确保密码安全性,建议您:

  • 每90天至少更改一次密码
  • 使用与帐户中过去4个密码不同的新密码
  • 使用与其他地方的密码不同的特殊密码
  • 勿将密码保存在可以轻易访问的地方
  • 使用密码管理器来保存您的密码

发布商帐户使用双因素认证,每次尝试认证时会向您发送一个验证码。

在发布商帐户中创建项目

如有多个应用程序,建议您为每个应用程序创建单独的项目。艾克索拉会根据项目创建过程中指定的数据为您推荐适合的解决方案。

要创建新项目:

  1. 打开发布商帐户
  2. 在侧边栏中,单击创建项目

  1. 用英文输入您的项目名称(必需)。

注:
创建项目后,可在项目设置部分中添加其他语言和本地化项目名称。

  1. 选择游戏的一个或多个发布平台(必需)。
  2. 添加游戏的链接。如游戏没有网站,请添加一个包含游戏信息的资源链接(必需)。
  3. 选择游戏引擎。
  4. 选择使用或打算使用的盈利方式。
  5. 指定游戏是否已发布。如游戏尚未发布,则指定计划发布日期。
  6. 单击创建项目。您将看到一个包含推荐艾克索拉推荐产品的页面。

集成过程中需提供项目ID,可在发布商帐户中项目名称的旁边找到。

设置目录

在发布商帐户中创建商品

注意

您需要在艾克索拉侧创建一个目录。您可以手动添加商品从Google Play或PlayFab导入商品。从Google Play导入时,一次最多可以导入100个商品。

以下说明提供的是设置虚拟物品的基本步骤。您可以在后来向目录添加其他商品(虚拟货币、捆绑包、游戏密钥等)、创建商品组、设置促销活动和区域价格等。

要向目录添加具有基本设置的虚拟物品:

  1. 发布商帐户中打开您的项目。
  2. 在侧边栏中单击商店
  3. 虚拟物品窗格中,单击连接
  4. 在下拉列表中,选择创建物品

  1. 在以下字段中完成物品的基本设置:
    • 图片(可选)
    • SKU(物品唯一ID)
    • 物品名称
    • 描述(可选)

  1. 指定物品价格:
    1. 真实货币定价开关设置为
    2. 默认货币字段,更改货币(可选)并指定物品价格。
    3. 如更改了默认货币字段中的货币,请在真实货币定价字段中选择同样的货币。

注:
为确保获取目录的API调用正常工作,请确保所有物品的默认货币和指定价格的货币列表一致。

  1. 将物品状态更改为可用

  1. 单击创建物品

在应用程序客户端侧显示目录

  1. CDNGitHub下载SDK。
  2. 解压缩包。
  3. 在主菜单中,前往Assets > Import Package > Custom Package,然后选择下载的SDK。
  4. 在主菜单中,前往Window > Xsolla > Edit Settings
  5. 前往Inspector面板。在Project ID字段中指定可在发布商帐户项目名称旁边找到的项目ID。

  1. 在应用程序的客户端侧,添加显示产品目录的UI。
  2. 实现向艾克索拉服务器请求商品目录。

注:

要获取虚拟物品列表,请使用GetCatalog SDK方法。您也可以使用其他SDK方法获取目录商品的信息。

关于创建目录页的分步教程,请参阅显示商品目录

设置商品购买

要使用用户和商品数据在艾克索拉侧创建订单,请添加使用为购买创建支付令牌API调用的云函数至项目。该调用将返回一个支付令牌,用于打开支付UI并进行购买。

限制:

  • 需在请求支付令牌时传入用户国家/地区或用户IP地址。
  • 如未在令牌中传入货币,则货币由国家/地区决定。
  • 如在令牌中传入了货币,则用户用该货币进行支付。

注:

您应已创建PlayFab项目并已在您的Unity项目中集成了PlayFab SDK。

PlayFab云脚本不直接支持使用HTTP触发器的函数,因此这里使用Azure函数来实现Webhook的接收。

要开始使用Azure函数,请创建Azure帐户准备您的开发环境。本说明描述的步骤适用于具有以下设置的开发环境:

向项目添加云脚本

  1. 打开Visual Studio Code,前往Azure选项卡。
  2. Workspace部分中,单击+图标,然后选择Create Function

  1. 选择新项目目录。随后将显示包含设置选项的新建项目菜单。

  1. 指定新项目的设置:
    1. 选择函数项目的语言 — C#
    2. 选择.NET运行引擎 — .NET 8.0 Isolated (LTS)
    3. 选择项目首个函数的模板 — HTTP trigger
    4. 输入函数名称 — GetXsollaPaymentToken
    5. 输入命名空间 — My.Functions
    6. 选择授权等级 — Anonymous
    7. 选择项目打开方式 — Open in current window

  1. 作为结果,Visual Studio Code将生成一个C#项目并打开生成的GetXsollaPaymentToken.cs文件。

  1. 修改GetXsollaPaymentToken.cs文件:

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. 在脚本中,指定常量的值:

    • PROJECT_ID — 可在发布商帐户中项目名称旁边找到的项目ID。

    • API_KEY — API密钥。密钥仅在创建它时在发布商帐户中显示一次,必须存储在己侧。您可以在以下部分中创建新的密钥:
      • 公司设置 > API密钥
      • 项目设置 > API密钥

添加云脚本后,您可以在本地测试调用GetXsollaPaymentToken函数。

部署云脚本

  1. 在Visual Studio Code中,前往Azure > Resources部分,然后单击+图标。
  2. 选择Create Function App in Azure作为资源。随后将显示包含设置选项的新建应用程序菜单。
  3. 设置应用程序的设置:

    1. 输入新函数应用程序的名称 — XsollaFunctions
    2. 选择运行时栈 — .NET 8 Isolated
    3. 选择新资源的位置(可选择任意方案)。

  1. 等待资源组创建完成。

  1. 在资源列表中,选择XsollaFunctions,调用快捷菜单并选择Deply to Function App

添加云脚本后,您可以在远程测试调用GetXsollaPaymentToken函数。

测试云脚本

要测试云脚本(本地或远程),请使用Postman或其他工具调用GetXsollaPaymentToken函数。具体方法是:

  1. 在Visual Studio Code中,前往Azure > Workspace > Local Project > Functions部分,然后单击Start debugging to update this list
  2. 调用函数的快捷菜单并选择Copy Function Url。进行本地测试时,URL类似于 — http://localhost:7071/api/getXsollaPaymentToken;进行远程测试时则类似于 — https://xsollafunctions.azurewebsites.net/api/GetXsollaPaymentToken

  1. 使用复制的URL通过指定参数调用该函数。要从Postman调用函数:
    1. 新建一个GET请求。
    2. 提供在步骤2中复制的URL。
    3. 前往Body选项卡并指定请求参数。

示例请求正文:

Copy
Full screen
Small screen
{

 "FunctionArgument": {

   "uid": "1D384D9EF12EAB8B",

   "sku": "booster_max_1",

   "returnUrl": "https://login.xsolla.com/api/blank"

 }

}
注:
您可以对用户ID (uid)指定任何值。对于商品SKU (sku),请指定之前在发布商帐户中添加的虚拟物品的SKU。

  1. 单击Send。响应中应会收到包含以下参数的JSON:
    • token — 支付令牌。打开支付UI所必需。
    • order_id — 所创建订单的ID。跟踪订单状态所必需。

示例响应正文:

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

在PlayFab中注册用于获取支付令牌的函数

  1. 在PlayFab中打开您的项目。
  2. 在侧边栏中,单击Automation
  3. Register New Cloud Script Function部分中,单击Register Function
  4. 输入函数名称 — GetXsollaPaymentToken
  5. 输入复制到Visual Studio Code中的函数URL(见测试云脚本中的步骤1-2)。

在Unity项目中创建订单并打开支付UI

  1. 打开您的Unity项目。
  2. 使用以下内容创建XsollaPlayfabSample.cs脚本:

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. 创建一个新场景。
  2. 创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty

  1. 将脚本添加到游戏对象:
    1. Hierarchy面板中选择对象。
    2. Inspector面板中,单击Add Component,然后选择XsollaPlayfabSample脚本。

  1. Hierarchy面板中,调用快捷菜单,然后选择UI > EventSystem

要测试订单的创建,请点击Play运行场景。运行结果应显示包含订单信息的支付UI。

该Unity项目的源代码在GitHub上提供。

设置订单状态跟踪

您需要跟踪项目状态,以确保支付成功并向用户发放商品。

获取客户端侧订单状态

订单跟踪逻辑包含在GetXsollaPaymentToken方法中。要处理成功的购买,需传递一个在订单状态变为done时调用的函数。

AddOrderForTracking SDK方法用于跟踪。关于该方法的详细使用信息,请参阅跟踪订单状态

在服务器侧获取订单状态

注意

通过本SDK,您可以在应用程序的客户端侧跟踪订单状态。但是,我们建议您设置支付Webhook处理程序在应用程序后端接收订单信息。这样您可以实现对完成的购买的额外验证。

关于Webhook的完整列表及常规使用信息,请参阅Webhook文档

要在艾克索拉侧配置Webhook:

  1. 发布商帐户中打开您的项目。
  2. 在侧边栏中单击项目设置,然后前往Webhooks部分。
  3. Webhook服务器字段中,输入艾克索拉要向其发送Webhook的URL。

注:

要测试Webhook,您还可以选择任意专门网站(如webhook.site)或平台(如ngrok)。

对于测试,您还可以添加一个模拟成功Webhook处理的云脚本。该脚本的代码在GitHub上提供。

对于真实项目,需添加购买验证逻辑。

  1. 复制并保存密钥字段的值。该密钥默认生成,并用于Webhook签名。如要更改该密钥,请单击更新图标。
  2. 单击启用Webhook

本文对您的有帮助吗?
谢谢!
我们还有其他可改进之处吗? 留言
非常抱歉
请说明为何本文没有帮助到您。 留言
感谢您的反馈!
我们会查看您的留言并运用它改进用户体验。
上次更新时间: 2024年10月3日

发现了错别字或其他内容错误? 请选择文本,然后按Ctrl+Enter。

报告问题
我们非常重视内容质量。您的反馈将帮助我们做得更好。
请留下邮箱以便我们后续跟进
感谢您的反馈!