Third-party Platform Purchase
1. 概述
第三方平台购买集成允许开发者将玩家从平台(如Steam、EpicGames)购买的物品同步到PGOS。为了实现这一点,准确地将第三方平台上销售的物品映射到PGOS中对应的物品非常重要。在第三方平台完成购买后,开发者必须主动调用PGOS同步接口以确保物品同步。
通过阅读本教程,开发者将了解以下信息:
- 使用PGOS和第三方平台购买的一般流程。
- 如何将第三方平台购买的物品同步到PGOS。
2. 基本流程
开发者在进行实际开发前,需要先在PGOS门户网站完成以下配置:
开发者需要理解不同第三方平台上道具的概念。在PGOS中,item_id
是道具ID,item_inst_id
是道具实例ID。但在第三方平台上可能会有不同的命名。例如在Steam平台上,ItemDef
是道具ID,ItemInstanceID
或ItemID
是道具实例ID。
在下文中,platform_item_id
表示第三方平台上的道具ID,platform_item_inst_id
表示第三方平台上的道具实例ID。
The ID of the item | The ID of the item instance | |
---|---|---|
PGOS | item_id | item_inst_id |
Definition of 3rd-party platform on PGOS | platform_item_id | platform_item_inst_id |
Steam | ItemDef | ItemInstanceID/ItemID |
Xbox | store_id/product_id |
流程如下所示:
3. 在网页端配置道具映射
3.1 安装插件
以下以 Steam 平台为例。
- Game ID:Steam 上的目标游戏 ID。
- Web API Key:Steam 上的 Server Key。点击此处获取更多信息。
- Use Sandbox For Economy:此开关用于开发者在开发和测试区域调试"同步购买道具"功能。启用开关表示仅同步沙盒中购买的道具。禁用表示仅同步非沙盒购买的道具。
3.2 配置物品映射
可以在经济界面中添加、编辑和删除物品映射。
4. 使用第三方平台购买相关的API
4.1 获取商店与商品映射
获取在门户网站上定义的指定商店。此接口可获取在PGOS Portal上配置的指定平台的platform_item_mapping
值。
接口原型:
/**
* Get the specified store defined on the portal. This interface can get the value of 'platform_item_mapping'.
*
* @param Params Request params.
*/
void GetStoreWithPlatform(
const FClientGetStoreWithPlatformParams& Params,
TFunction<void(const FPgosResult& Ret, const FClientStore* Data)> Callback) const;
struct FClientGetStoreWithPlatformParams
{
/** The specified store id. */
FString store_id;
/** Pay platform name, such as: 'Steam', 'EpicGames', etc. You can use macros starting with 'PAY_PLATFORM' in `pgos_common_define.h` */
FString pay_platform;
};
struct FClientStore
{
/** The id of the store. */
FString store_id;
/** The name of the store. */
FString display_name;
/** The description of the store. */
FString description;
/** The custom tags of the store. */
TMap<FString, FString> tags;
/** The category list of the the store, each category has a store item list. */
TArray<FClientStoreCategory> categories;
/** In-game item defines that may be referenced in the 'item_content', and you can use 'ItemDict::FindItem' to search. */
FItemDict item_dict;
/** The mapping relationship between PGOS in-game items and 3rd-party platform items configured on the PGOS portal. key: PGOS in-game item id, value: 3rd-party platform item id. */
TMap<FString, FString> platform_item_mapping;
};
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Economy = IPgosSDKCpp::Get().GetClientEconomyAPI();
if (Economy)
{
FClientGetStoreWithPlatformParams Params;
Params.store_id = TEXT("store123456");
Params.pay_platform = TEXT("Steam");
Economy->GetStoreWithPlatform(Params, [](const FPgosResult& Ret, const FClientStore* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetStoreWithPlatform Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetStoreWithPlatform Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2 在第三方平台购买物品前的检查
在第三方平台购买物品前进行检查。用于检查由于独特物品、映射配置等原因而无法购买物品的情况。
接口原型:
/**
* Check before purchasing items on 3rd-party platforms. It is used to check situations where items cannot be purchased due to unique items, mapping configuration, etc.
*
* @param Params Request params.
*/
void CheckBeforePlatformPurchase(
const FClientCheckBeforePlatformPurchaseParams& Params,
TFunction<void(const FPgosResult& Ret)> Callback) const;
struct FClientCheckBeforePlatformPurchaseParams
{
/** The PGOS in-game item id corresponding to the item id of the 3rd-party platform to be purchased. */
FString item_id;
/** The amount of item will be purchased. */
int32 amount = 0;
/** Pay platform name, such as: 'Steam', 'EpicGames', etc. You can use macros starting with 'PAY_PLATFORM' in `pgos_common_define.h` */
FString pay_platform;
};
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Economy = IPgosSDKCpp::Get().GetClientEconomyAPI();
if (Economy)
{
FClientCheckBeforePlatformPurchaseParams Params;
// Fill params
Economy->CheckBeforePlatformPurchase(Params, [](const FPgosResult& Ret) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("CheckBeforePlatformPurchase Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("CheckBeforePlatformPurchase Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
CheckBeforePlatformPurchase Key Error Codes
4.3 Steam
4.3.1 将Steam背包同步至PGOS
将Steam背包同步至PGOS。建议在登录PGOS后调用一次。
接口原型:
/**
* Synchronize the Steam's inventory to PGOS.
* It is recommended to call it once after logging in to PGOS.
*
* The PGOS backend events `event_item_granted`/`event_currency_changed` will be triggered.
*
* @param Params Request params.
* @param ResultCallback The result callback after the API execution ends, and it will be called in the GAME THREAD. For lifetime safety, it is recommended to use the CreateWeakCallback provided in PgosSDKCpp.h to create a lambda bound to a UObject.
*/
void SyncSteamPlayerInventory(
const FClientSyncSteamPlayerInventoryParams& Params,
TFunction<void(const FPgosResult& Ret, const FClientSyncSteamPlayerInventoryResult* Data)> ResultCallback) const;
struct FClientSyncSteamPlayerInventoryParams : public FBaseBackendEventParams
{
};
struct FClientSyncSteamPlayerInventoryResult
{
/** The item instances obtained after synchronized. */
FItemInstPack item_insts;
/** The currencies obtained after synchronized. */
TArray<FCurrency> currencies;
/** Unique items that already in inventory cause failed to be synchronized. */
TArray<FClientConflictUniqueItem> conflict_unique_items;
};
struct FBaseBackendEventParams
{
/**
* [Optional] A game-defined custom value pass to PGOS backend event.
* If you need to get a custom value in the event, pass it in, otherwise, ignore this field.
* The size is limited to 4096 bytes (after converting the string to utf8 format).
* Detail for PGOS backend event: https://pgos.intlgame.com/pgosdoc/manual/service_manual/extensions/event.html.
* Detail for how to reference the 'event_custom_data':https://pgos.intlgame.com/pgosdoc/manual/service_manual/extensions/virtual_server_v2.html#43-the-request-and-response-protocol.
*/
FString event_custom_data;
};
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Economy = IPgosSDKCpp::Get().GetClientEconomyAPI();
if (Economy)
{
FClientSyncSteamPlayerInventoryParams Params;
// Fill params
Economy->SyncSteamPlayerInventory(Params, [](const FPgosResult& Ret, const FClientSyncSteamPlayerInventoryResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SyncSteamPlayerInventory Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SyncSteamPlayerInventory Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
SyncSteamPlayerInventory Key Error Codes
4.3.2 将从Steam购买的物品实例同步至PGOS
将玩家从Steam购买的物品实例同步至PGOS。
接口原型:
/**
* Synchronize item instances purchased by players from Steam to PGOS.
*
* The PGOS backend events `event_item_granted`/`event_currency_changed` will be triggered.
*
* @param Params Request params.
* @param ResultCallback The result callback after the API execution ends, and it will be called in the GAME THREAD. For lifetime safety, it is recommended to use the CreateWeakCallback provided in PgosSDKCpp.h to create a lambda bound to an UObject.
*/
void SyncSteamPurchase(
const FClientSyncSteamPurchaseParams& Params,
TFunction<void(const FPgosResult& Ret, const FClientSyncSteamPurchaseResult* Data)> ResultCallback) const;
struct FClientSyncSteamPurchaseParams : public FBaseBackendEventParams
{
/** Steam item instance id. */
uint64 steam_item_inst_id = 0;
};
struct FClientSyncSteamPurchaseResult : public FClientSyncSteamPlayerInventoryResult
{
};
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Economy = IPgosSDKCpp::Get().GetClientEconomyAPI();
if (Economy)
{
FClientSyncSteamPurchaseParams Params;
// Fill params
Economy->SyncSteamPurchase(Params, [](const FPgosResult& Ret, const FClientSyncSteamPurchaseResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SyncSteamPurchase Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SyncSteamPurchase Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
SyncSteamPurchase Key Error Codes
4.4 Xbox
4.4.1 安装 Xbox 插件
这是一个 Xbox 平台的示例。
- Upload Relying Party Certificate (.pfx file format)
- Upload Business Partner Certificate (.pfx file format)
我们建议在创建中继组队时将 Xbox 用户 ID 声明添加到 xsts 令牌中。
4.4.2 将 Xbox 背包同步至 PGOS
将 Xbox 背包同步至 PGOS。建议在登录 PGOS 后调用一次。
接口原型:
/**
* Synchronize the Xbox platform's inventory to PGOS.
* It is recommended to call it once after logging in to PGOS.
*
* The PGOS virtual server events `event_item_granted`/`event_currency_changed` will be triggered.
*
* @param Params Request params.
*/
void SyncXboxPlayerInventory(
const FClientSyncXboxPlayerInventoryParams& Params,
TFunction<void(const FPgosResult& Ret, const FClientSyncXboxPurchaseResult* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Economy = IPgosSDKCpp::Get().GetClientEconomyAPI();
if (Economy)
{
FClientSyncXboxPlayerInventoryParams Params;
// Fill Params
Economy->SyncXboxPlayerInventory(Params, [](const FPgosResult& Ret, const FClientSyncXboxPurchaseResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SyncXboxPlayerInventory Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SyncXboxPlayerInventory Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
SyncSteamPlayerInventory Key Error Codes
4.4.3 将从 Xbox 购买的物品实例同步至 PGOS
将玩家从 Xbox 购买的物品实例同步至 PGOS。
接口原型:
/**
* Synchronize item instances purchased by players from Xbox to PGOS.
*
* The PGOS virtual server events `event_item_granted`/`event_currency_changed` will be triggered.
*
* @param Params Request params.
*/
void SyncXboxPurchase(
const FClientSyncXboxPurchaseParams& Params,
TFunction<void(const FPgosResult& Ret, const FClientSyncXboxPurchaseResult* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Economy = IPgosSDKCpp::Get().GetClientEconomyAPI();
if (Economy)
{
FClientSyncXboxPurchaseParams Params;
// Fill Params
Economy->SyncXboxPurchase(Params, [](const FPgosResult& Ret, const FClientSyncXboxPurchaseResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SyncXboxPurchase Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SyncXboxPurchase Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
SyncSteamPurchase Key Error Codes
5. 关键错误处理
错误代码 | 相关 API | 处理建议 |
---|---|---|
kBackendSyncInventory | SyncSteamPlayerInventory SyncSteamPurchase | 这表示同步操作失败。 |
kBackendUniqueItemDuplicated | CheckBeforePlatformPurchase | 这表示背包中已存在相同的物品 |
kBackendMultipleUniqueItemToGrant | CheckBeforePlatformPurchase | 这表示多个唯一项目同时进行同步,这是不允许的。 |