# PC SDK Native Integrate Guide

# Introduction

The STOVE platform for games provides integrated services. All processes of game release, including game distribution and sales, community, and indicator analysis, can be handled in one-stop. With the PC SDK (Native), you can easily integrate the services provided by the Stove platform into your game.

This section describes how to integrate the PC SDK(Native).

confirm If this is the first time you are trying to integrate PC SDK(Native), please read the PC SDK Native Follow Through Through first.

# Preparations

  • Check that you have issued the stove subscription account and the App key, App secret, and Game Id for the released game from STOVE Studio (opens new window).
  • Download the newest Native(C/C++) distributed files(stated as StovePCSDK from here on) from the PC SDK Download page.

# StovePCSDK Distributed File Configuration

# 1) include Folder

The files below can be found in the include folder when you download and unzip StovePCSDK.

  • StovePCCallback.h
    Header file for callback definitions to receive callbacks after calling the NativeSDK API with the integrated game.

  • StovePCEnum.h
    This is a header file that defines enumerations for errors, API types, and asynchronous state values in the NativeSDK.

  • StovePCDefine.h
    API call result (StovePCResult), error result structure (StovePCError), callback function, API structure parameter, etc. used for communication between game project and PC SDK are declared.

  • StovePCSDK.h
    Declare API function prototypes used for communication between the game and the PC SDK.

# 2) bin Folder

Binaries required for each platforms(Win32/x64) and configurations(Debug/Release) are included in the bin folder.

  • concrt140.dll
  • msvcp100.dll
  • msvcp140.dll
  • msvcr100.dll
  • sgup_api(64).dll
  • StovePCSDK.dll
  • vcruntime140.dll

confirm Except for StovePCSDK.lib, you need to include the DLL files listed above when distributing the game client to end-users.

# 3) sample folder

The sample folder includes the StovePCSDKTestMfc.exe GUI application to check the operation of StovePCSDK as a Release build for each platform (Win32/x64). First, enter the App key and App secret in the StovePCConfig.MFC.ini file, and then run StovePCSDKTestMfc.exe. In addition, by directly executing StovePCSDKTestMfc, you can directly input AppKey, SecretKey, etc. in the Setting UI.

# Configuring StovePCSDK Build Settings

Refer to the Configuring Project Settings in the PC SDK Native Follow Through for configuring build settings.

# Integration

# 1) Config, Callback Settings

To initialize PC SDK, start with filling in the values for the StovePCConfig and StovePCCallback structures, and calling the StovePC_Init function.
Refer to the code below to fill in each field values within the StovePCConfig structure.

StovePCConfig config{"live",
                    "YOUR_APP_KEY",
                    "YOUR_SECRET_KEY",
                    "YOUR_GAME_ID",
                    StovePCLogLevel::STOVE_PC_LOG_LEVEL_DEBUG,
                    ""};
1
2
3
4
5
6

Refer to the StovePCDefine.h file for details regarding the StovePCConfig structure.

Communication between the game and the PC SDK uses callback functions connected to the StovePCCallback structure. In the game code, you need to define the function pointer to connect to the callback pointer of the StovePCCallback structure below in advance. The pointer of the specified function should be connected.

struct StovePCCallback
{

    /// Callback for StovePCSDK errors
    void(*OnError)(const StovePCError error);
    
    /// Callback for completing PC SDK initialization 
    void(*OnInitComplete)(); 
    
    /// Callback for completing GetToken process 
    void(*OnToken)(const StovePCToken token); 
    
    /// Callback for completing GetUser process 
    void(*OnUser)(const StovePCUser user); 
    
    /// Callback for completing GetOwnership process 
    void(*OnOwnership)(int size, StovePCOwnership* ownership);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

NULL initialization is required before using the StovePCCallback structure’s instance.

/* Create StovePCCallback structure instance*/
StovePCCallback callback;
/* Initialize all function pointers to NULL*/
memset(&callback, 0, sizeof(StovePCCallback));
/* Connect configured function pointers*/
callback.OnError = OnMyErrorCallback;
callback.OnInitComplete = OnMyInitCompleteCallback;
callback.OnToken = OnMyTokenCallback;
callback.OnUser = OnMyUserInfoCallback;
callback.OnOwnership = OnMyOwnershipCallback;
1
2
3
4
5
6
7
8
9
10

The OnError, OnInitComplete and OnOwnership callback functions must work together. You can integrate the rest of the callback functions only when necessary. For example, suppose you only use the Ownership function. In that case, you can implement it as shown below.

/*When only the ownership feature is being used, 
only the OnOwnership callback is essential 
On top of the essential callbacks, OnError and OnInitcomplte.*/
callback.OnError = OnMyErrorCallback;
callback.OnInitComplete = OnMyInitCompleteCallback;
callback.OnOwnership = OnMyOwnershipCallback;
1
2
3
4
5
6

# 2) SDK Initialization

When you complete StovePCConfig and StovePCCallback structure initialization and callback function connection, call the StovePC_Init function to initialize PC SDK.

StovePCResult result = StovePC_Init(config, callback);
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*StovePCSDK init success.    
    Call StovePC_RunCallback at regular intervals using timers, etc.*/

}
1
2
3
4
5
6
7

After the StovePC_Init function checks only the config and callback validity, it immediately returns the type value of the StovePCResult enum.
In case of success, it returns a value of STOVE_PC_NO_ERROR. In case of failure, it returns the corresponding error code, and you need to quit the game. Check the StovePCResult enum in the StovePCDefine.h file for a complete list of error codes.

If the returned value is STOVE_PC_NO_ERROR, therefore, a 'success', regularly call the StovePC_RunCallback function.
StovePC_RunCallback function must be regularly called to normally call the connected callback.
The callback response speed slows down if the call cycle is long, so it is better to maintain an appropriate call cycle. The example code in this guide sets the call period to 0.5 seconds.

confirm It only calls the callback function connected to the PC SDK from the thread that called the StovePC_RunCallback function.

The StovePC_Init function processes unsynchronized procedures excluding the config and callback validity check.
The OnInitComplete callback is called if the unsynchronized procedures are successful, and the OnError callback is called if an error occurs.
In case of an error, the error code and message can be checked through the delivered StovePCError structure.

void OnInitComplete()
{
    printf("pc sdk init success");
}

void OnError(const StovePCError error)
{
	switch (Error.functionType)
	{
	case STOVE_PC_INIT:
	case STOVE_PC_GET_USER:
	case STOVE_PC_GET_OWNERSHIP:
		QuitApplicationDueToError();
		break;
	}
}

void QuitApplicationDueToError()
{
        // After showing the user a message about app outage rather than stopping it immediately
        // Depending on user action (e.g. clicking the exit button), you may want to terminate the app.
        // If so, implement your own logic.
        // Recommended messages for required pre-task errors are as follows.
        // Korean: The required pre-task failed to operate and the game has been terminated.
        // Other Languages: The required pre-task fails and exits the game.
	OnStoveLog("QuitApplicationDueToError");
	OnStoveLog("QuitApplicationDueToError");
	exit(0)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

You can use the StovePC_GetInitState function if there is a need to check the initialized status value of PC SDK before the OnInitComplete callback is received.

/*After calling the StovePC_Init...*/
while(StovePC_GetInitState()
        == StovePCInitState::STOVE_PC_INIT_PENDING)
{
    sleep(500ms);
    StovePC_RunCallback();
}

if (StovePC_GetInitState()
            == StovePCInitState::STOVE_PC_INIT_COMPLETE)
{
    /* Initialization Complete
    OnInitComplete callback is called*/
}
else
{
    /* Initialization failed
    OnError callback is called*/
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 3) Cautions when synchronizing the SDK

confirm When setting the log level of the StovePCConfig structure, set it as StovePCLogLevel::STOVE_PC_LOG_LEVEL_DEBUG value when testing, and set it as StovePCLogLevel::STOVE_PC_LOG_LEVEL_ERROR value at the time of official release.

confirm Call the GetToken, GetUser, or GetOwnership functions before PC SDK initialization is complete. You may not receive the results usually. In other words, after the OnInitComplete callback is normally received, the GetToken, GetUser, and GetOwnership functions must be called to receive the result normally.

# 4) SDK Termination

After using PC SDK, call the StovePC_UnInit function to clean up resources in use.

StovePCResult result = StovePC_UnInit();
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*Processed as a success*/
}
...
1
2
3
4
5
6

# 5) Acquiring User Information

Use the StovePC_GetUser function to retrieve the logged-in user information in STOVE Launcher.

StovePCResult result = StovePC_GetUser();
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*Processed as a success*/
}
1
2
3
4
5

If the StovePC_GetUser function is normally processed, the OnUser callback is called.
The member no, nickname, Game User ID information can be viewed through the StovePCUser structure delivered by the callback.
We describe the StovePCUser structure in the StovePCDefine.h file.

void OnUser(const StovePCUser user)
{
    /*Display User Information*/
    printf("User Info(memberNo = %I64d, nickname = %S, gameUserId = %s)",
                      user.memberNo, user.nickname, user.gameUserId);
}
1
2
3
4
5
6

# 6) Acquiring Token Information

With the StovePC_GetToken function, you can check the token information of the user who has logged into the STOVE launcher.

StovePCResult result = StovePC_GetToken();
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*Processed as a success*/
}
1
2
3
4
5

If the StovePC_GetToken function is normally processed, the OnToken callback is called.
The StovePCToken structure delivered by the callback includes the token string.

void OnToken(const StovePCToken token)
{
    /*Display Token Information*/
    printf("Token : %s", token.accessToken);
}
1
2
3
4
5

confirm What is a token? It is the access token of the logged-in user in STOVE Launcher, and the game server passes this access token to the stove authentication server to validate the logged-in user.
For a detailed explanation of Access Token, please get in touch with store.support@smilegate.com for technical support.

# 7) Acquiring Ownership Information

The StovePC_GetOwnership function lets you check whether the user has purchased and owns the game.


StovePCResult result = StovePC_GetOwnership();
if (result == STOVE_PC_NO_ERROR)
{
    /*Processed as a success*/ 
    /*Ownership information is delivered as the OnOwnership callback.*/
}
1
2
3
4
5
6
7

If the StovePC_GetOwnership function is normally processed, the OnOwnership callback is called.
For details on the StovePCOwnership structure, which is a parameter of the OnOwnership callback, refer to the StovePCDefine.h file.

The sample below is a code that checks if the game has been purchased through the OnOwnership callback. If the game is without DLC, the confirmation code for lines 20 to 23 is unnecessary.

void OnOwnership(int size, StovePCOwnership* ownership)
{
    bool owned = false;
 
    StovePCOwnership* data = ownership;
    for (int i = 0; i < size; i++, data++)
    {
        if ((data->memberNo != LOGIN_USER_MEMBER_NO /*StovePCUser structure's memberNo*/)
            || (data->ownershipCode != 1 /*1:Ownership acquired, 2:Ownership disabled(in case the purchase has been canceled)*/))
        {
            continue;
        }

        if (0 == wcscmp(L"YOUR_GAME_ID", data->gameId) && data->gameCode == 3 /* 3: BASIC, 4: DEMO*/)
        {
            owned = true; // Set ownership verification variable to true
        }

        /*Necessary only if it is a game that has DLCs*/
        if (0 == wcscmp(L"YOUR_DLC_ID", data->gameId) && data->gameCode == 5 /* 5: DLC*/)
        {
            /*Process for users who have purchased YOUR_DLC_ID(DLC)*/
        }
    }

     if(owned)
    {
        // Write game entry logic after ownership verification is usually completed
    }
    else
    {
        // After ownership verification fails, end the game and write an error message display logic
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  • After running the game exe, users who own the game can play.
  • Users who don't own the game cannot play, and please show the following message.
    • "Please log in to STOVE Client with the account that has purchased the game."

# 8) Language Settings

Set the language with StovePC_SetLanguage function.
When initializing the PC SDK, the language is set as default using the system language (operating system language).
To explicitly set the system language (operating system language), enter "system" as a parameter.
To set a specific language, call the StovePC_SetLanguage function after successful initialization (e.g. OnInitComplete).

StovePCResult result = StovePC_SetLanguage("LANGUAGE_CODE");
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /* handle success */
}
1
2
3
4
5

# 9) Language translation

Translate languages with StovePC_TranslateLanguage function.
PC SDK provides a translation for a specific string based on the set language information.
A specific string is managed as a String ID managed by the PC SDK.
If the game directly implements the PC SDK popup UI, the string displayed in the UI must display the translated string through the StovePC_TranslateLanguage function.

wchar_t* translated = StovePC_TranslateLanguage("STRING_ID");
1

Precautions

Returns an English translation if there is no translation of a specific string for the language set in the PC SDK.
For exceptions or unsupported string IDs, the input parameter (string ID) is returned as it is.

# Checking Errors

Errors occurring during PC SDK use can be divided into two big categories.

# StovePCResult enum value returned after calling the function

All PC SDK’s functions will return a StovePCResult enum value immediately after calling, to mark whether the call was successful.
The entire value can be checked in the PC SDK Error Code page.

# StovePCError Structure Delivered Through OnError callbacks

If an error occurs in an unsynchronized function among the PC SDK functions, the OnError callback is called, and a StovePCError structure including the description of the error is delivered.

/*Delivered when the OnError callback is called.*/
struct StovePCError
{
    /*Enum value showing the called function*/
    StovePCFunctionType functionType;


    /*Enum value showing the error type*/ 
    StovePCResult result; 
    
    /*Error message*/ 
    char* message; 
    
    /*Error codes for external errors(http error, external module error)*/ 
    int externalError;

};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Integrate Game support service

PC SDK provides API to integrate the Stove platform’s game support service into the game. The game support service supported by the PC SDK includes stats, achievements, and leaderboards. Each service is defined as follows:

  • Stats: A service that records the user’s various game play data in numerical terms
  • Achievements: A service that sets gameplay challenges and provides user-specific achievement information
  • Leaderboard: A service that provides user ranking information of specific game play data

In order to use the PC SDK game support service API, metadata registration for game support services must be conducted first through the studio.

For information on metadata management, refer to the Simple Console User Manual.

# 1) Callback Settings

To communicate with the PC SDK using the game support service API, the game should define a callback function to connect to the callback pointer of the StovePCCallbak structure below.

struct StovePCCallback
{
    void(*OnError)(const StovePCError error);
    void(*OnInitComplete)();
    void(*OnToken)(const StovePCToken token);
    void(*OnUser)(const StovePCUser user);
    void(*OnOwnership)(int size, StovePCOwnership* ownership);

    // Callback that is called when GetStat has been completed
    void(*OnStat)(const StovePCStat stat);

    // Callback that is called when SetStat has been completed
    void(*OnSetStat)(const StovePCStatValue statValue);

    // Callback that is called when GetAchievement has been completed
    void(*OnAchievement)(StovePCAchievement achievement);

    // Callback that is called when GetAllAchievement has been completed
    void(*OnAllAchievement)(int size, StovePCAchievement* achievement);

    // Callback function pointer received when calling GetRank API
    void(*OnRank)(int size, StovePCRank* rank, unsigned int rankTotalCount);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Connect the callback function to the callback of the StovePCCallback structure as in Integration 1) Config, Callback Settings.

// Create StovePCCallback structure instance
StovePCCallback callback;

// Initialize every function pointer with NULL
memset(&callback, 0, sizeof(StovePCCallback));

// Connect the implemented function pointer
callback.OnError = OnMyErrorCallback; /*Globally defined callback function*/
callback.OnInitComplete = OnMyInitCompleteCallback; /*Globally defined callback function*/
callback.OnToken = OnMyTokenCallback; /*Globally defined callback function*/
callback.OnUser = OnMyUserInfoCallback; /*Globally defined callback function*/
callback.OnOwnership = OnMyOwnershipCallback; /*Globally defined callback function*/
 
 // Game support service 
callback.OnStat = OnMyStat; /*Globally defined callback function*/ 
callback.OnSetStat = OnMySetStat; /*Globally defined callback function*/
callback.OnAchievement = OnMyAchievement; /*Globally defined callback function*/
callback.OnAllAchievement = OnMyAllAchievement; /*Globally defined callback function*/
callback.OnRank = OnMyRank; /*Globally defined callback function*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

You do not need to implement the callbacks other than OnStat, OnSetStat, OnAchievement, OnAllAchievement, and OnRank.

You only need to implement and connect callback functions necessary for the game support service used in the game.

# 2) Update User Stats

Update specific stats in the game for a logged in user with the StovePC_SetStat function.

// Input parameters
// const char* statId : Stat identifier registered in the studio
// const int statValue : Stat value to be updated
StovePCResult result = StovePC_SetStat("STAT_ID", STAT_VALUE);
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*Processed as a success*/ 
}
1
2
3
4
5
6
7
8

The OnSetStat callback is called when the StovePC_SetStat function is processed properly.
The StovePCStatValue structure delivered to the callback contains a flag indicating the current stat value, update status and error messages.

If the stat value is fully reflected and updated, the Updated field will contain ‘true’ and the ErrorMessage field will contain an empty string. If the stat value is partially updated, the Updated field will contain ‘true’ and the ErrorMessage field will contain a string such as “integer overflow”.

For example, assuming that the current stat value of the INCREMENT type is 2,147,483,000 and you try to add 1,000 through the StovePC_SetStat API, it will become out of range of the values that the Int32 type can have, and when it is updated to 2,147,483,647 which is the maximum value of the Int32 type, reflecting only part of the value (1,000), the ErrorMessage field will contain a string such as “integer overflow”.

The table below lists the results that can be obtained through the StovePCStatValue structure.

Stat Type Updated ErrorMessage Result
All Types True “”(Empty string) Requested value is fully updated to current value
INCREMENT True "integer overflow" Storage space exceeded, partial update
INCREMENT False "integer overflow" Storage space exceeded, no update
MIN False “”(Empty string) Requested value larger than current value
MAX False “”(Empty string) Requested value smaller than current value
REPLACE Fasle “”(Empty string) Requested value same as current value
void OnSetStat(const StovePCStatValue statValue)
{
    // Display stat update result information
    printf("OnSetStat");
    printf(" - statValue.currentValue : %d", statValue.currentValue);
    printf(" - statValue.updated : %s", statValue.updated ? "true" : "false");
    printf(" - statValue.errorMessage : %s", statValue.errorMessage);
}
1
2
3
4
5
6
7
8

confirm Caution) The valid range of the callback parameter StovePCStatValue structure is limited to the scope of the callback function. The PC SDK releases internally allocated memory as soon as execution of the callback function is completed. Therefore, if storage is required to use information of the StovePCStatValue structure outside of the scope of the callback function, a copy must be created through Deep Copy, and the memory must be released when use of the copy is completed.

If an error occurs while the StovePC_SetStat function is running, the ‘OnError’ callback is called.

You can check for external errors through the ExternalError field of the StovePCError structure.

ExternalError Description
2000 Invalid Access
3000 Wrong API Usage
4000 Stats ID Not Found
9000 Service Error

# 3) Get User Stat Information

Use the StovePC_GetStat function to retrieve specific game stat information for a logged in user.

// Input parameters
// const char* statId : Stat identifier registered in the studio
StovePCResult result = StovePC_GetStat("STAT_ID");
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /*Processed as a success*/
}
1
2
3
4
5
6
7

The OnStat callback is called when the StovePC_GetStat function is processed properly.

The StovePCStat structure delivered to the callback contains the current stat value.

void OnStat(const StovePCStat stat)
{
    // Display stat info
    printf("OnStat");
    wprintf(L" - stat.statFullId.gameId : %s", stat.statFullId.gameId);
    printf(" - stat.statFullId.statId : %s", stat.statFullId.statId);
    printf(" - stat.memberNo : %llu", stat.memberNo);
    printf(" - stat.currentValue : %d", stat.currentValue);
    printf(" - stat.updatedAt : %llu", stat.updatedAt);
}
1
2
3
4
5
6
7
8
9
10

confirm Caution) The valid range of the callback parameter StovePCStat structure is limited to the scope of the callback. The PC SDK releases internally allocated memory as soon as execution of the callback is completed. Therefore, if storage is required to use information of the StovePCStat structure outside of the scope of the callback, a copy must be created through Deep Copy, and the memory must be released when use of the copy is completed.

If an error occurs while the StovePC_GetStat function is running, the OnError callback is called.

You can check for external errors through the ExternalError field of the StovePCError structure.

ExternalError Description
2000 Invalid Access
3000 Wrong API Usage
4000 Stats ID Not Found
9000 Service Error

# 4) Get User Single Achievement Information

Use the StovePC_GetAchievement function to retrieve specific game single achievement information for a logged in user.

// Input parameters
// const char* achievementId : Achievement identifier created in the studio
StovePCResult result = StovePC_GetAchievement("ACHIEVEMENT_ID");
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /*Processed as a success*/
}
1
2
3
4
5
6
7

The OnAchievement callback is called when the StovePC_GetAchievement function is processed properly.

The StovePCAchievement structure delivered to the callback contains the current achievement value, achievement status, and achievement metadata.

void OnAchievement(const StovePCAchievement achievement)
{
    // Display single achievement information
    printf("OnAchievement");

    printf(" - achievement.achievementId : %s", achievement.achievementId);
    wprintf(L" - achievement.name : %s", achievement.name);
    wprintf(L" - achievement.description : %s", achievement.description);
    wprintf(L" - achievement.defaultImage : %s", achievement.defaultImage);
    wprintf(L" - achievement.achievedImage : %s", achievement.achievedImage);
    printf(" - achievement.condition.goalValue : %d", achievement.condition.goalValue);
    printf(" - achievement.condition.valueOperation : %s", achievement.condition.valueOperation);
    printf(" - achievement.condition.type : %s", achievement.condition.type);
    printf(" - achievement.value : %d", achievement.value);
    printf(" - achievement.status : %s", achievement.status);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

confirm Caution) The valid range of the callback parameter StovePCAchievement structure is limited to the scope of the callback. The PC SDK releases internally allocated memory as soon as execution of the callback is completed. Therefore, if storage is required to use information of the StovePCAchievement structure outside of the scope of the callback, a copy must be created through Deep Copy, and the memory must be released when use of the copy is completed.

If an error occurs while the StovePC_GetAchievement function is running, the OnError callback is called.

You can check for external errors through the ExternalError field of the StovePCError structure.

ExternalError Description
1200 Not found achievement
9000 Service Error

# 5) Get All User Achievement Information

Use the StovePC_GetAllAchievement function to retrieve specific game single achievement information for a logged in user.

StovePCResult result = StovePC_GetAllAchievement();
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /*Processed as a success*/
}
1
2
3
4
5

The OnAllAchievement callback is called when the StovePC_GetAllAchievement function is processed properly.

The StovePCAchievement structure delivered to the callback contains the current achievement value, achievement status, and achievement metadata.

void OnAllAchievement(int size, StovePCAchievement* achievements)
{
    // Display all achievement information
    printf("OnAllAchievement");
    printf(" - achievements size : %d", size);

    for (int i = 0; i < size; i++, achievements++)
    {
        printf(" - achievements[%d].achievementId : %s", i, achievements->achievementId);
        wprintf(L" - achievements[%d].name : %s", i, achievements->name);
        wprintf(L" - achievements[%d].description : %s", i, achievements->description);
        wprintf(L" - achievements[%d].defaultImage : %s", i, achievements->defaultImage);
        wprintf(L" - achievements[%d].achievedImage : %s", i, achievements->achievedImage);
        printf(" - achievements[%d].condition.goalValue : %d", i, achievements->condition.goalValue);
        printf(" - achievements[%d].condition.valueOperation : %s", i, achievements->condition.valueOperation);
        printf(" - achievements[%d].condition.type : %s", i, achievements->condition.type);
        printf(" - achievements[%d].value : %d", i, achievements->value);
        printf(" - achievements[%d].status : %s", i, achievements->status);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

confirm Caution) The valid range of the callback parameter StovePCAchievement structure array is limited to the scope of the callback function. The PC SDK releases internally allocated memory as soon as execution of the callback function is completed. Therefore, if storage is required to use information of the StovePCAchievement structure array outside of the scope of the callback function, a copy must be created through Deep Copy, and the memory must be released when use of the copy is completed.

If an error occurs while the StovePC_GetAllAchievement function is running, the OnError callback is called.

You can check for external errors through the ExternalError field of the StovePCError structure.

ExternalError Description
9000 Service Error

# 6) Get Leaderboard Ranking Information

Use the StovePC_GetRank function to retrieve the ranking information of a specific game leaderboard.

// Input parameters
// const char* leaderboardId : Leaderboard identifier created in the studio
// const unsigned int pageIndex : Page number to search (1 <= pageIndex)
// const unsigned int pageSize : Number of ranks to search (1 <= pageSize <= 50)
// const bool includeMyRank : Include rank of logged-in users in search results
StovePCResult result = StovePC_GetRank("LEADERBOARD_ID", PAGE_INDEX, PAGE_SIZE, INCLUDE_MY_RANK);
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /*Processed as a success*/
}
1
2
3
4
5
6
7
8
9
10

The OnRank callback is called when the StovePC_GetRank function is processed properly.

The StovePCRank structure delivered to the callback contains score and rank information for a specific user.

// 콜백 파라미터
// unsigned int rankTotalCount : Total number of rankings aggregated in the searched leaderboard
void OnRank(int size, StovePCRank* ranks, unsigned int rankTotalCount)
{
    // Display Ranking Information
    printf("OnRank");
    printf(" - ranks.Length : %d", size);

    for (int i = 0; i < size; i++, ranks++)
    {
        printf(" - ranks[%d].memberNo : %llu", i, ranks->memberNo);
        printf(" - ranks[%d].score : %d", i, ranks->score);
        printf(" - ranks[%d].rank : %u", i, ranks->rank);
        wprintf(L" - ranks[%d].nickname : %s", i, ranks->nickname);
        wprintf(L" - ranks[%d].profileImage : %s", i, ranks->profileImage);
    }

    printf(" - rankTotalCount : %u", rankTotalCount);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

confirm Caution) The valid range of the callback parameter StovePCRank structure array is limited to the scope of the callback function. The PC SDK releases internally allocated memory as soon as execution of the callback function is completed. Therefore, if storage is required to use information of the StovePCRank structure array outside of the scope of the callback function, a copy must be created through Deep Copy, and the memory must be released when use of the copy is completed.

If an error occurs while the StovePC_GetRank function is running, the OnError callback is called.

You can check for external errors through the ExternalError field of the StovePCError structure.

ExternalError Description
1251 Invalid Parameter
1252 CannotFindData
3603 ErrorLeaderBoardNotFound
3631 ErrorMembershipAPI
500 External Server Error

# Integrating pop-ups

The PC SDK provides APIs to integrate popups into your game. Pop-ups supported by PC SDK include automatic, manual, news, coupon, and community.
The PC SDK provides data for popups to the game. The game creates a pop-up view using the provided data.
Each popup is defined as follows.

  • Automatic pop-up: Pop-up that is most exposed on the game lobby screen and shows advertisements and events
  • Manual pop-up: Pop-up showing registered events corresponding to the resource key -News pop-up: A pop-up that collects and shows announcement posts at once
  • Coupon pop-up: Pop-up showing the coupon registration page
  • Community popup: Popup showing the game community page

In order to use the PC SDK popup API, the metadata registration of the popup integrated with Partners must be preceded.

# 1) Callback setting

To communicate with the PC SDK using the pop-up API, the game must define a callback function to connect to the callback pointer of the StovePCCallback structure below.

struct StovePCCallback
{
     void(*OnError)(const StovePCError error);
     void(*OnInitComplete)();
     void(*OnToken)(const StovePCToken token);
     void(*OnUser)(const StovePCUser user);
     void(*OnOwnership)(int size, StovePCOwnership* ownership);
 
     /// Callback called when GetAutoPopup processing is complete
     void(*OnAutoPopup)(int size, StovePCAutoPopup* autoPopup, int headerSize, StovePCPopupRequestHeader* header);
 
     /// Callback called when GetManualPopup processing is complete
     void(*OnManualPopup)(int size, StovePCManualPopup* manualPopup, int headerSize, StovePCPopupRequestHeader* header);
 
     /// Callback called when GetNewsPopup processing is complete
     void(*OnNewsPopup)(StovePCNewsPopup newsPopup, int headerSize, StovePCPopupRequestHeader* header);
 
     /// Callback called when GetCouponPopup processing is complete
     void(*OnCouponPopup)(StovePCCouponPopup couponPopup, int headerSize, StovePCPopupRequestHeader* header);
 
     /// Callback called when GetCommunityPopup processing is complete
     void(*OnCommunityPopup)(StovePCCommunityPopup communityPopup, int cookieSize, StovePCPopupRequestCookie* cookie);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Connect the callback function to the callback pointer of the StovePCCallback structure as in Config, Callbak setting.

// Create StovePCCallback structure instance
StovePCCallback callback;
 
// Initialize all function pointers to NULL
memset(&callback, 0, sizeof(StovePCCallback));
 
// Link implemented function pointers
callback.OnError = OnMyErrorCallback; /* Callback function defined globally */
callback.OnInitComplete = OnMyInitCompleteCallback; /* Callback function defined globally */
callback.OnToken = OnMyTokenCallback; /* Callback function defined globally */
callback.OnUser = OnMyUserInfoCallback; /* Callback function defined globally */
callback.OnOwnership = OnMyOwnershipCallback; /* Callback function defined globally */
  
  // pop-up
callback.OnAutoPopup = OnMyAutoPopup; /* Callback function defined globally */
callback.OnManualPopup = OnMyManualPopup; /* Callback function defined globally */
callback.OnNewsPopup = OnMyNewsPopup; /* Callback function defined globally */
callback.OnCouponPopup = OnMyCouponPopup; /* Callback function defined globally */
callback.OnCommunityPopup = OnMyCommunityPopup; /*Callback function defined globally*
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

You are not required to implement the OnAutoPopup, OnManualPopup, OnNewsPopup, OnCouponPopup, OnCommunityPopup callbacks.
All you need to do is implement and connect only the callback function that is necessary for the popup used in the game.

# 2) Game profile settings

Set game world and character information with StovePC_SetGameProfile function.
Set information is used in pop-ups, so it must be set before using pop-ups.
The validity of the game profile is not checked separately. Therefore, you must enter the correct value by proceeding with validation (null) when entering.
The entered game profile is only valid for the life cycle of PCSDK.
That is, whenever PCSDK is initialized, the StovePC_SetGameProfile function must be called to set the game world and character information.

// input parameters
// const char* worldId: the world identifier of the game
// const long characterNo: character identifier
StovePCResult result = StovePC_SetGameProfile("WORLD_ID", CHARACTER_NO);
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /* handle success */
}
1
2
3
4
5
6
7
8

# 3) Get automatic pop-up information

Search information about auto popup with StovePC_GetAutoPopup function.

StovePCResult result = StovePC_GetAutoPopup();
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /* handle success */
}
1
2
3
4
5

When the StovePC_GetAutoPopup function is successfully processed, the OnAutoPopup callback is called.
The StovePCAutoPopup structure passed to the callback contains the URL to the auto-popup.
The StovePCPopupRequestHeader structure passed to the callback contains name/value pairs of headers to be set when requesting URLs.

void OnAutoPopup(int size, StovePCAutoPopup* autoPopup, int headerSize, StovePCPopupRequestHeader* header)
{

     printf("OnAutoPopup");
     printf(" - autoPopup size = %d", size);
    
     for (int i = 0; i < size; i++, autoPopup++)
     {
         printf("- autoPopup[%d].origin : %s", i, autoPopup->origin);
         printf("- autoPopup[%d].id : %d", i, autoPopup->id);
         printf("- autoPopup[%d].url : %s", i, autoPopup->url);
        
         // ADD 2.6.0 Start
         printf("- autoPopup[%d].control.ui.visible.closeButton : %s", i, autoPopup->control.ui.visible.closeButton ? "true" : "false");
         printf("- autoPopup[%d].control.ui.visible.navigationBar : %s", i, autoPopup->control.ui.visible.navigationBar ? "true" : "false");
         printf("- autoPopup[%d].control.ui.visible.backButton : %s", i, autoPopup->control.ui.visible.backButton ? "true" : "false");
         printf("- autoPopup[%d].control.ui.visible.forwardButton : %s", i, autoPopup->control.ui.visible.forwardButton ? "true" : "false");
         printf("- autoPopup[%d].control.ui.visible.refreshButton : %s", i, autoPopup->control.ui.visible.refreshButton ? "true" : "false");
         printf("- autoPopup[%d].control.ui.visible.homeButton : %s", i, autoPopup->control.ui.visible.homeButton ? "true" : "false");
         printf("- autoPopup[%d].control.ui.visible.disallowedButton : %s", i, autoPopup->control.ui.visible.disallowedButton ? "true" : "false");
         printf("- autoPopup[%d].control.ui.disallowedDay : %d", i, autoPopup->control.ui.disallowedDay);
         printf("- autoPopup[%d].control.ui.closeButtonImage.normal.fileUrl : %s", i, autoPopup->control.ui.closeButtonImage.normal.fileUrl);
         printf("- autoPopup[%d].control.ui.closeButtonImage.normal.fileId : %s", i, autoPopup->control.ui.closeButtonImage.normal.fileId);
         printf("- autoPopup[%d].control.ui.closeButtonImage.pressed.fileUrl : %s", i, autoPopup->control.ui.closeButtonImage.pressed.fileUrl);
         printf("- autoPopup[%d].control.ui.closeButtonImage.pressed.fileId : %s", i, autoPopup->control.ui.closeButtonImage.pressed.fileId);
         printf("- autoPopup[%d].control.ui.closeButtonImage.type : %d", i, autoPopup->control.ui.closeButtonImage.type);
         printf("---------------------------------------------- --");
         // 2.6.0 End
     }

     printf("header size = %d", headerSize);

     for (int i = 0; i < headerSize; i++, header++)
     {
         printf(" -> index: %d", i);
         printf("name : %s", header->name);
         printf("value : %s", header->value);
         printf("---------------------------------------------- --");
     }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

Precautions

The valid scope of the callback parameter StovePCAutoPopup/StovePCPopupRequestHeader structure is limited to the scope of the callback function.
PC SDK frees internally allocated memory as soon as callback function execution is completed.
Therefore, if you need to save the information of StovePCAutoPopup/StovePCPopupRequestHeader structure outside the scope of the callback function, make sure to create a copy through deep copy,
When the use of the copy is complete, the memory must be freed.

Even if the success callback (OnAutoPopup) is executed, the size callback parameter may be 0.
At this time, null is passed to the autoPopup callback parameter. Before using the autoPopup callback parameter, you should check the size callback parameter before deciding whether or not to open a popup.
In this case, check the automatic pop-up settings of Partners.

The display order of auto popup must be the same as the order of autoPopup array elements. For example, if your autoPopup array contains three elements [A,B,C], you should expose popups in A, B, C order.

If an error occurs while running the StovePC_GetAutoPopup function, the OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.

ExternalError Description
403000 Invalid Access Error
400000 Wrong API usage Error
400001 Not Found Error
400002 Not Match Error
400003 Already exist
500001 Internal Interaction Error
900000 Unknown Service Error

# 4) Obtain manual pop-up information

Search information about manual popup with StovePC_GetManualPopup function.

// input parameters
// string resourceKey: Manual pop-up identifier registered by Partners
StovePCResult result = StovePC_GetManualPopup("RESOURCE_KEY");
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /* handle success */
}
1
2
3
4
5
6
7

When the StovePC_GetManualPopup function is successfully processed, the OnManualPopup callback is called.
The StovePCManualPopup structure passed to the callback contains the URL to the manual popup.
The StovePCPopupRequestHeader structure passed to the callback contains name/value pairs of headers to be set when requesting URLs.

void OnManualPopup(int size, StovePCManualPopup* manualPopup, int headerSize, StovePCPopupRequestHeader* header)
{

     printf("OnManualPopup");
     printf(" - manualPopup size = %d", size);
    
     for (int i = 0; i < size; i++, manualPopup++)
     {
         printf("- manualPopup[%d].origin : %s", i, autoPopup->origin);
         printf("- manualPopup[%d].id : %d", i, autoPopup->id);
         printf("- manualPopup[%d].url : %s", i, autoPopup->url);
         // ADD 2.6.0 Start
         printf("- manualPopup[%d].control.ui.visible.closeButton : %s", i, manualPopup->control.ui.visible.closeButton ? "true" : "false");
         printf("- manualPopup[%d].control.ui.visible.navigationBar : %s", i, manualPopup->control.ui.visible.navigationBar ? "true" : "false");
         printf("- manualPopup[%d].control.ui.visible.backButton : %s", i, manualPopup->control.ui.visible.backButton ? "true" : "false");
         printf("- manualPopup[%d].control.ui.visible.forwardButton : %s", i, manualPopup->control.ui.visible.forwardButton ? "true" : "false");
         printf("- manualPopup[%d].control.ui.visible.refreshButton : %s", i, manualPopup->control.ui.visible.refreshButton ? "true" : "false");
         printf("- manualPopup[%d].control.ui.visible.homeButton : %s", i, manualPopup->control.ui.visible.homeButton ? "true" : "false");
         printf("- manualPopup[%d].control.ui.visible.disallowedButton : %s", i, manualPopup->control.ui.visible.disallowedButton ? "true" : "false");
         printf("- manualPopup[%d].control.ui.disallowedDay : %d", i, manualPopup->control.ui.disallowedDay);
         printf("- manualPopup[%d].control.ui.closeButtonImage.normal.fileUrl : %s", i, manualPopup->control.ui.closeButtonImage.normal.fileUrl);
         printf("- manualPopup[%d].control.ui.closeButtonImage.normal.fileId : %s", i, manualPopup->control.ui.closeButtonImage.normal.fileId);
         printf("- manualPopup[%d].control.ui.closeButtonImage.pressed.fileUrl : %s", i, manualPopup->control.ui.closeButtonImage.pressed.fileUrl);
         printf("- manualPopup[%d].control.ui.closeButtonImage.pressed.fileId : %s", i, manualPopup->control.ui.closeButtonImage.pressed.fileId);
         printf("- manualPopup[%d].control.ui.closeButtonImage.type : %d", i, manualPopup->control.ui.closeButtonImage.type);
         printf("---------------------------------------------- --");
         // 2.6.0 End
     }

     printf("header size = %d", headerSize);

     for (int i = 0; i < headerSize; i++, header++)
     {
         printf(" -> index: %d", i);
         printf("name : %s", header->name);
         printf("value : %s", header->value);
         printf("---------------------------------------------- --");
     }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

Precautions

The valid scope of the callback parameter StovePCManualPopup/StovePCPopupRequestHeader structure is limited to the scope of the callback function.
PC SDK frees internally allocated memory as soon as callback function execution is completed.
Therefore, if you need to save the information of StovePCManualPopup/StovePCPopupRequestHeader structure outside the scope of the callback function, make sure to create a copy through deep copy,
When the use of the copy is complete, the memory must be freed.

Even if the success callback (OnManualPopup) is executed, the size callback parameter may be 0. At this time, null is passed to the manualPopup callback parameter.
Before using the manualPopup callback parameter, you should check the size callback parameter first and decide whether or not to open a popup. In this case, check the manual pop-up settings of Partners.

The display order of manual popup must be the same as the order of manualPopup array elements. For example, if the manualPopup array contains three elements [A,B,C], then we need to expose popups in A, B, C order.

If an error occurs while executing StovePC_GetManualPopup function, OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.

ExternalError Description
403000 Invalid Access Error
400000 Wrong API usage Error
400001 Not Found Error
400002 Not Match Error
400003 Already exist
500001 Internal Interaction Error
900000 Unknown Service Error

# 5) Get news pop-up information

Search information about news popup with StovePC_GetNewsPopup function.

StovePCResult result = StovePC_GetNewsPopup();
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /* handle success */
}
1
2
3
4
5

When the StovePC_GetNewsPopup function is successfully processed, the OnNewsPopup callback is called.
The StovePCNewsPopup structure passed to the callback contains the URL to the newspopup.
The StovePCPopupRequestHeader structure passed to the callback contains name/value pairs of headers to be set when requesting URLs.

void OnNewsPopup(StovePCNewsPopup newsPopup, int headerSize, StovePCPopupRequestHeader* header)
{
     printf("OnNewsPopup");
   
     printf("- newsPopup.origin : %s", i, autoPopup->origin);
     printf("- newsPopup.id : %d", i, autoPopup->id);
     printf("- newsPopup.url : %s", i, autoPopup->url);
     // ADD 2.6.0 Start
     printf("- newsPopup.control.ui.visible.closeButton : %s", newsPopup.control.ui.visible.closeButton ? "true" : "false");
     printf("- newsPopup.control.ui.visible.navigationBar : %s", newsPopup.control.ui.visible.navigationBar ? "true" : "false");
     printf("- newsPopup.control.ui.visible.backButton : %s", newsPopup.control.ui.visible.backButton ? "true" : "false");
     printf("- newsPopup.control.ui.visible.forwardButton : %s", newsPopup.control.ui.visible.forwardButton ? "true" : "false");
     printf("- newsPopup.control.ui.visible.refreshButton : %s", newsPopup.control.ui.visible.refreshButton ? "true" : "false");
     printf("- newsPopup.control.ui.visible.homeButton : %s", newsPopup.control.ui.visible.homeButton ? "true" : "false");
     printf("- newsPopup.control.ui.visible.disallowedButton : %s", newsPopup.control.ui.visible.disallowedButton ? "true" : "false");
     printf("- newsPopup.control.ui.disallowedDay : %d", newsPopup.control.ui.disallowedDay);
     printf("- newsPopup.control.ui.closeButtonImage.normal.fileUrl : %s", newsPopup.control.ui.closeButtonImage.normal.fileUrl);
     printf("- newsPopup.control.ui.closeButtonImage.normal.fileId : %s", newsPopup.control.ui.closeButtonImage.normal.fileId);
     printf("- newsPopup.control.ui.closeButtonImage.pressed.fileUrl : %s", newsPopup.control.ui.closeButtonImage.pressed.fileUrl);
     printf("- newsPopup.control.ui.closeButtonImage.pressed.fileId : %s", newsPopup.control.ui.closeButtonImage.pressed.fileId);
     printf("- newsPopup.control.ui.closeButtonImage.type : %d", newsPopup.control.ui.closeButtonImage.type);
     printf("header size = %d", headerSize);
     // 2.6.0 End

     for (int i = 0; i < headerSize; i++, header++)
     {
         printf(" -> index: %d", i);
         printf("name : %s", header->name);
         printf("value : %s", header->value);
         printf("---------------------------------------------- --");
     }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Precautions

The valid scope of the callback parameter StovePCNewsPopup/StovePCPopupRequestHeader structure is limited to the scope of the callback function.
PC SDK frees internally allocated memory as soon as callback function execution is completed.
Therefore, if you need to save the information of StovePCNewsPopup/StovePCPopupRequestHeader structure outside the scope of the callback function, you must create a copy through deep copy.
When the use of the copy is complete, the memory must be freed.

Even if the success callback (OnNewsPopup) is executed, newsPopup callback parameter properties may be default values (empty string or 0).
After checking the url property of the newsPopup callback parameter, you should decide whether to open a popup or not. In this case, check the news pop-up settings of Partners.

If an error occurs while running the StovePC_GetNewsPopup function, the OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.

ExternalError Description
403000 Invalid Access Error
400000 Wrong API usage Error
400001 Not Found Error
400002 Not Match Error
400003 Already exist
500001 Internal Interaction Error
900000 Unknown Service Error

# 6) Get coupon pop-up information

Search coupon popup information with StovePC_GetCouponPopup function.

StovePCResult result = StovePC_GetCouponPopup();
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /* handle success */
}
1
2
3
4
5

When the StovePC_GetCouponPopup function is successfully processed, the OnCouponPopup callback is called.
The StovePCCouponPopup structure passed to the callback contains the URL to the coupon popup.
The StovePCPopupRequestHeader structure passed to the callback contains name/value pairs of headers to be set when requesting URLs.

void OnCouponPopup(StovePCCouponPopup couponPopup, int headerSize, StovePCPopupRequestHeader* header)
{
     printf("OnCouponPopup");

     printf("- couponPopup.origin: %s", i, couponPopup.origin);
     printf("- couponPopup.id : %d", i, couponPopup.id);
     printf("- couponPopup.url : %s", i, couponPopup.url);
     // ADD 2.6.0 Start
     printf("- couponPopup.control.ui.visible.closeButton : %s", couponPopup.control.ui.visible.closeButton ? "true" : "false");
     printf("- couponPopup.control.ui.visible.navigationBar : %s", couponPopup.control.ui.visible.navigationBar ? "true" : "false");
     printf("- couponPopup.control.ui.visible.backButton : %s", couponPopup.control.ui.visible.backButton ? "true" : "false");
     printf("- couponPopup.control.ui.visible.forwardButton : %s", couponPopup.control.ui.visible.forwardButton ? "true" : "false");
     printf("- couponPopup.control.ui.visible.refreshButton : %s", couponPopup.control.ui.visible.refreshButton ? "true" : "false");
     printf("- couponPopup.control.ui.visible.homeButton : %s", couponPopup.control.ui.visible.homeButton ? "true" : "false");
     printf("- couponPopup.control.ui.visible.disallowedButton : %s", couponPopup.control.ui.visible.disallowedButton ? "true" : "false");
     printf("- couponPopup.control.ui.disallowedDay : %d", couponPopup.control.ui.disallowedDay);
     printf("- couponPopup.control.ui.closeButtonImage.normal.fileUrl : %s", couponPopup.control.ui.closeButtonImage.normal.fileUrl);
     printf("- couponPopup.control.ui.closeButtonImage.normal.fileId : %s", couponPopup.control.ui.closeButtonImage.normal.fileId);
     printf("- couponPopup.control.ui.closeButtonImage.pressed.fileUrl : %s", couponPopup.control.ui.closeButtonImage.pressed.fileUrl);
     printf("- couponPopup.control.ui.closeButtonImage.pressed.fileId : %s", couponPopup.control.ui.closeButtonImage.pressed.fileId);
     printf("- couponPopup.control.ui.closeButtonImage.type : %d", couponPopup.control.ui.closeButtonImage.type);
     printf("header size = %d", headerSize);
     // 2.6.0 End

     for (int i = 0; i < headerSize; i++, header++)
     {
         printf(" -> index: %d", i);
         printf("name : %s", header->name);
         printf("value : %s", header->value);
         printf("---------------------------------------------- --");
     }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Precautions

The valid scope of the callback parameter StovePCCouponPopup/StovePCPopupRequestHeader structure is limited to the scope of the callback function.
PC SDK frees internally allocated memory as soon as callback function execution is completed.
Therefore, if you need to save the information of StovePCCouponPopup/StovePCPopupRequestHeader structure outside the scope of the callback function, you must create a copy through deep copy, and
When the use of the copy is complete, the memory must be freed.

If an error occurs while running the StovePC_GetCouponPopup function, the OnError callback is called.

# 7) Get community pop-up information

Use the StovePC_GetCommunityPopup function to retrieve community popup information.

StovePCResult result = StovePC_GetCommunityPopup();
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /* handle success */
}
1
2
3
4
5

When the StovePC_GetCommunityPopup function is successfully processed, the OnCommunityPopup callback is called.
The StovePCCommunityPopup structure passed to the callback contains the URL to the community popup.
The StovePCPopupRequestCookie structure passed to the callback contains the cookie name/value pair to be set when requesting the URL.

void OnCommunityPopup(StovePCCommunityPopup communityPopup, int cookieSize, StovePCPopupRequestCookie* cookie)
{
     printf("OnCommunityPopup");

     printf("- communityPopup.url : %s", i, couponPopup.url);
     // ADD 2.6.0 Start
     printf("- communityPopup.control.ui.visible.closeButton : %s", communityPopup.control.ui.visible.navigationBar ? "true" : "false");
     printf("- communityPopup.control.ui.visible.navigationBar : %s", communityPopup.control.ui.visible.navigationBar ? "true" : "false");
     printf("- communityPopup.control.ui.visible.backButton : %s", communityPopup.control.ui.visible.backButton ? "true" : "false");
     printf("- communityPopup.control.ui.visible.forwardButton : %s", communityPopup.control.ui.visible.forwardButton ? "true" : "false");
     printf("- communityPopup.control.ui.visible.refreshButton : %s", communityPopup.control.ui.visible.refreshButton ? "true" : "false");
     printf("- communityPopup.control.ui.visible.homeButton : %s", communityPopup.control.ui.visible.homeButton ? "true" : "false");
     printf("- communityPopup.control.ui.visible.disallowedButton : %s", communityPopup.control.ui.visible.disallowedButton ? "true" : "false");
     printf("- communityPopup.control.ui.disallowedDay : %d", communityPopup.control.ui.disallowedDay);
     printf("- communityPopup.control.ui.closeButtonImage.normal.fileUrl : %s", communityPopup.control.ui.closeButtonImage.normal.fileUrl);
     printf("- communityPopup.control.ui.closeButtonImage.normal.fileId : %s", communityPopup.control.ui.closeButtonImage.normal.fileId);
     printf("- communityPopup.control.ui.closeButtonImage.pressed.fileUrl : %s", communityPopup.control.ui.closeButtonImage.pressed.fileUrl);
     printf("- communityPopup.control.ui.closeButtonImage.pressed.fileId : %s", communityPopup.control.ui.closeButtonImage.pressed.fileId);
     printf("- communityPopup.control.ui.closeButtonImage.type : %d", communityPopup.control.ui.closeButtonImage.type);
     printf("cookie size = %d", cookieSize);
     // 2.6.0 End

     for (int i = 0; i < headerSize; i++, cookies++)
     {
         printf(" -> index: %d", i);
         printf("name : %s", header->name);
         printf("value : %s", header->value);
         printf("---------------------------------------------- --");
     }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

Precautions

The valid scope of the callback parameter StovePCCommunityPopup/StovePCPopupRequestCookie structure is limited to the scope of the callback function.
PC SDK frees internally allocated memory as soon as callback function execution is completed.
Therefore, if you need to save the information of StovePCcommunityPopup/StovePCPopupRequestCookie structure outside the scope of the callback function, make sure to create a copy through deep copy,
When the use of the copy is complete, the memory must be freed.

If an error occurs while running the StovePC_GetCommunityPopup function, the OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.

ExternalError Description
13008 Mandatory Parameter missing
90001 AccessToken invalid
40101 Invalid token

# 8) Disable pop-ups 2.6.0

Use the StovePC_SetPopupDisallowed function to disable certain pop-ups from being displayed for a certain period of time.
If the game directly implements the PC SDK pop-up UI, configure the UI by referring to the control.ui.visible.disallowedButton value of the pop-up UI information.
Call StovePC_SetPopupDisallowed function from button click handler.
When calling the StevePC_SetPopupDisallowed method, the days parameter uses the value of control.UI.disallowedDay from the popup information.
If pop-up disallow is set, the relevant pop-up information will not be searched during the disallow period.

// input parameters
// int popupId : Popup identifier issued by Partners
// int days : the number of days of disallowance registered by Partners (once) or -1 (don't look again)
// int days : Unacceptable period registered by Partners (in days)
StovePCResult result = StovePC_SetPopupDisallowed(POPUP_ID, DAYS);
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
     // handle success
}
1
2
3
4
5
6
7
8
9

# Integrate billing 2.6.0

The PC SDK provides APIs to integrate Stove Platform's billing service into games. There is a store as a billing service. A typical scenario for a store is below. This may vary slightly depending on the game situation (e.g. whether or not there is a game server).

  • Information for store configuration is acquired through store category search and product search APIs.
  • The game organizes the store through the acquired category and product information and displays the UI.
  • To purchase each product, call the purchase start API.
    • In the case of a product with a selling price of 0
      • The purchase is completed when the purchase start API response is received.
    • For products with a selling price greater than 0
      • Obtain the one-time payment URL from the response of the purchase start API.
      • The game browses the one-time payment URL with an external browser. Supported browsers: Chrome (75+), Edge (42+)
      • Subsequent payment process will be completed through the web page.
  • When the payment is complete, the game calls the Purchase Status Check API to check the purchase status.
  • If the payment is confirmed to have been completed normally, the game will provide the product.
  • You can check the product purchase history (whether purchased more than once) through the purchase verification API.
  • It can be used to restore items through the library inquiry API.

In order to use the PC SDK billing service API, you must register the metadata of the billing service through Partners in advance.
Also, if you use the store through the PC SDK, you must call the StovePC_IAPInit function and pass the ShopKey issued from the partners.
An error will be returned if the billing service API is called without ShopKey settings.

The game must check whether you agree to the terms of service every time you open the store.
If the game user does not agree to the service terms and conditions, open the browser using the terms and conditions agreement page URL provided by PCSDK so that the game user can agree to the service terms and conditions.
When a game user agrees to the terms of service and opens the store, he or she enters the store.

PC SDK operates an internal cache for store support.

Through the isRefresh parameter of the StovePC_FetchProducts function, you can determine whether product information is retrieved from the cache or via Web API.
The product information retrieved through the Web API is updated in whole or in part (by category) in the cache, and then the product information is passed to the game as a callback.
(However, if the cache is empty, the product information is retrieved through the Web API and updated to the cache regardless of the value of the isRefresh parameter.)
In addition, the PC SDK updates the purchase/sale quantity and purchase status of each product in the cache through the Web API response at the time of calling the StovePC_ConfirmPurchase function.

# (Example) Flow chart of billing integration

confirm confirm

  1. Initialize PC_SDK when starting the game
    • Initialize IAP through StovePC_IAPInit function.
    • When IAP is initialized, the entire item list is retrieved and stored in the built-in cache.
  2. Handling non-payment inquiries when entering the in-game shop page (optional)
    • If there are unpaid items after completing payment through StovePC_FetchInventory storage box inquiry, re-shipment will be processed.
  3. After entering the store, search the category list for store composition.
    • Search categories in the store through StovePC_FetchShopCategories function.
  4. Search the item information through the category information in the store inquired in number 3.
    • Search product information included in the category through StovePC_FetchProducts function.
  5. Select an item to purchase from the store.
    • Purchase product information must be composed directly in an array. (ProductId/SalePrice/Quantity)
    • Quantity must be specified as 1.
  6. Search for one-time payment URL information to start product purchase.
    • Search the URL information of the one-time payment window through the StovePC_StartPurchase function.
  7. Process the product payment information pop-up within the game. (It must be processed to check the payment result in an external browser.)
  8. Pop up an external browser with the one-time payment URL information obtained through step 6.
  9. Proceed with product payment through the payment window of Stove billing.
    • Close the browser after payment is completed in the payment window.
  10. When you click the "Payment Complete" button on the product payment information pop-up created in step 7 in-game, the purchase status information is searched.
  • Search information on the payment status through the StovePC_ConfirmPurchase function.
  • After checking the payment completion status, close the pop-up and return to the store page.
  1. The purchase flow is complete.

reference

If the Stove payment is not in progress through an external browser and the payment result is not known through StovePC_StartPurchase
When entering the store page (2 times), the item is reissued through the StovePC_FetchProducts storage box inquiry.


The sequence diagram below shows a hypothetical store operation scenario.
This is an example of a general case and may differ slightly depending on the game situation (e.g. store category structure, store UI creation time, etc.).

  • PCSDK IAP initialization
  • Check to accept the Terms of Service
  • Open shop
  • Purchase goods
  • Check product purchase status
  • Verification of product purchase history
  • Handle item restoration

# 1) Callback setting

To communicate with the PC SDK using the billing service API, the game must define a callback function to connect to the callback of the StovePCCallback class below.

struct StovePCCallback
{
     void(*OnError)(const StovePCError error);
     void(*OnInitComplete)();
     void(*OnToken)(const StovePCToken token);
     void(*OnUser)(const StovePCUser user);
     void(*OnOwnership)(int size, StovePCOwnership* ownership);

     // callback to be called when FetchTermsAgreement processing is complete
    void(*OnFetchTermsAgreement ) OnFetchTermsAgreement;

     // Callback called when FetchShopCategories processing is complete
     void(*OnFetchShopCategories) OnFetchShopCategories;

     // Callback called when FetchProducts processing is complete
     void(*OnFetchProducts) OnFetchProducts;

     // Callback called when StartPurchase processing is complete
     void(*OnStartPurchase) OnStartPurchase;

     // Callback called when ConfirmPurchase processing is complete
     void(*OnConfirmPurchase) OnConfirmPurchase;
    
     // Callback called when FetchInventory processing is complete
     void(*OnFetchInventory) OnFetchInventory;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

Connect the callback pointer callback function of the StovePCCallback structure as in Connection 2) Config, Callback setting.

// Create StovePCCallback structure instance
StovePCCallback callback;
  
// Initialize all function pointers to NULL
memset(&callback, 0, sizeof(StovePCCallback));
  
// Link implemented function pointers
callback.OnError = OnMyErrorCallback; /* Callback function defined globally */
callback.OnInitComplete = OnMyInitCompleteCallback; /* Callback function defined globally */
callback.OnToken = OnMyTokenCallback; /* Callback function defined globally */
callback.OnUser = OnMyUserInfoCallback; /* Callback function defined globally */
callback.OnOwnership = OnMyOwnershipCallback; /* Callback function defined globally */
   
// Terms of Service
callback.OnFetchTermsAgreement = OnMyFetchTermsAgreement; /*Callback function defined globally*/
// billing service
OnFetchShopCategories = OnMyFetchShopCategories; /* Callback function defined globally */
OnFetchProducts = OnMyFetchProducts; /* Callback function defined globally */
OnStartPurchase = OnMyStartPurchase; /* Callback function defined globally */
OnConfirmPurchase = OnMyConfirmPurchase; /* Callback function defined globally */
OnFetchInventory = OnMyFetchInventory; /* Callback function defined globally */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

You are not required to implement the OnFetchTermsAgreement, OnFetchShopCategories, OnFetchProducts, OnStartPurchase, OnConfirmPurchase, OnFetchInventory callbacks.
You only need to connect the store when the game needs it. However, for the store function, all 5 callbacks must be implemented and connected.

# 2) Initialize IAP

If the game decides to use PCSDK to provide billing service, try initializing billing with the StovePC_IAPInit function with the ShopKey factor value of the store key issued by the stove.
When billing initialization is attempted, the product list registered on the Stove platform is automatically retrieved and stored in the Stove PCSDK internal cache.
Call StovePC_IAPInit and if it fails, send the error details to StovePCResult and OnError callbacks.

// input parameters
// char* shopKey: shopKey issued by the stove

StovePCResult result = StovePC_IAPInit(YOUR_SHOP_KEY);
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     // handle success
}
1
2
3
4
5
6
7
8
ExternalError Description
500 Internal Server Error
50001 Store does not exist, or is under maintenance
50002 Product does not exist or is unavailable for sale
999999 undefined error

# 4) Get store category information

Use the StovePC_FetchShopCategories function to retrieve store category information for the game.
Category information includes the ID of the parent category, so you can organize your store in a hierarchical structure.

StovePCResult result = StovePC_FetchShopCategories();
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     // Success processing
}
1
2
3
4
5

If the StovePC_FetchShopCategories function is processed normally, the OnFetchShopCategories callback is called.
The StovePCShopCategory structure passed to the callback contains meta information about the store category.

  • StovePCShopCategory.categoryId: Category ID
  • StovePCShopCategory.parentCategoryId: Parent category ID
  • StovePCShopCategory.displayNo: Category order
  • StovePCShopCategory.name: Category name
  • StovePCShopCategory.depth: Category depth (1 for top category)
void OnFetchShopCategories(const int size, StovePCShopCategory* categories)
{
     printf("OnFetchShopCategories");
     printf("shopCategory size = %d", size);
    
     for (int i = 0; i < size; i++, categories++)
     {
         printf(" - categories[%d].categoryId : %s", i, categories->categoryId);
         printf(" - categories[%d].parentCategoryId : %s", i, categories->parentCategoryId);
         printf(" - categories[%d].displayNo: %d", i, categories->displayNo);
         wprintf(L" - categories[%d].name: %s", i, categories->name);
         printf(" - categories[%d].depth : %d", i, categories->depth);
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

If an error occurs during execution of the StovePC_FetchShopProducts function, the OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.

ExternalError Description
500 Internal Server Error
999999 undefined error

# 5) Get store category information

The StovePC_FetchShopCategories function retrieves store category information for the game.
Category information includes the ID of the parent category, so you can organize your store in a hierarchical structure.

StovePCResult result = StovePC_FetchShopCategories();
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     // handle success
}
1
2
3
4
5

When the StovePC_FetchShopCategories function is successfully processed, the OnFetchShopCategories callback is called.
The StovePCShopCategory structure passed to the callback contains meta information about the store category.

  • StovePCShopCategory.categoryId : Category ID
  • StovePCShopCategory.parentCategoryId: Parent Category ID
  • StovePCShopCategory.displayNo: Category order
  • StovePCShopCategory.name: Category name
  • StovePCShopCategory.depth : category depth (1 for top category)
void OnFetchShopCategories(const int size, StovePCShopCategory* categories)
{
     printf("OnFetchShopCategories");
     printf("shopCategory size = %d", size);
    
     for (int i = 0; i < size; i++, categories++)
     {
         printf(" - categories[%d].categoryId : %s", i, categories->categoryId);
         printf(" - categories[%d].parentCategoryId : %s", i, categories->parentCategoryId);
         printf(" - categories[%d].displayNo: %d", i, categories->displayNo);
         wprintf(L" - categories[%d].name: %s", i, categories->name);
         printf(" - categories[%d].depth : %d", i, categories->depth);
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

If an error occurs while running the StovePC_FetchShopProducts function, the OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.

ExternalError Description
500 Internal Server Error
999999 undefined error

# 6) Get product information

Retrieve product information for the game with StovePC_FetchProducts function.

// input parameters
// char* categoryId : Category identifier registered by Partners (when passing an empty string, search all categories)
// bool isRefresh : If true, search Web API, if false, search PC SDK Cache
StovePCResult result = StovePC_FetchProducts("CATEGORY_ID", IS_REFRESH);
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     // handle success
}
1
2
3
4
5
6
7
8

When the StovePC_FetchProducts function is successfully processed, the OnFetchProducts callback is called.
The StovePCProduct structure passed to the callback contains meta information about the product.

  • StovePCProduct.productId : Product ID
  • StovePCProduct.gameItemId : In-game item ID mapped to product ID
  • StovePCProduct.name : Product name
  • StovePCProduct.description : Product description
  • StovePCProduct.quantity: Quantity of individual product
  • StovePCProduct.productTypeCode : Product type code (1: game product, 2: in-game product, 3: package item)
  • StovePCProduct.categoryId : Category ID
  • StovePCProduct.currencyCode : Currency code
  • StovePCProduct.price: List price of the product (when displaying, if currencyCode is equal to "KRW", the decimal point is omitted; otherwise, it is indicated to two decimal places)
  • StovePCProduct.salePrice: Product sales price (when displaying, if currencyCode is equal to "KRW", the decimal point is omitted; otherwise, it is indicated to two decimal places)
  • StovePCProduct.isDiscount: Whether or not there is a discount
  • StovePCProduct.discountType : Discount type (1: flat rate, 2: flat rate)
  • StovePCProduct.discountTypeValue: Discount value
  • StovePCProduct.discountBeginDate : Discount start date (UTC+0)
  • StovePCProduct.discountEndDate : Discount end date (UTC+0)
  • StovePCProduct.totalQuantity : Total product sales quantity
  • StovePCProduct.memberQuantity : Member purchase quantity
  • StovePCProduct.guidQuantity: Guid purchase quantity (purchase quantity of product purchase subject [CharacterNo/Guid/MemberNo])
  • StovePCProduct.thumbnailUrl : Representative product image
void OnFetchProducts(const int size, StovePCProduct* products)
{
     printf("OnFetchProducts");
     printf("product size = %d", size);
    
     for (int i = 0; i < size; i++, products++)
     {
        printf(" - products[%d].productId: %lld", i, products->productId);
         printf(" - products[%d].gameItemId: %s", i, products->gameItemId);
         wprintf(L" - products[%d].name: %s", i, products->name);
         wprintf(L" - products[%d].description: %s", i, products->description);
         printf(" - products[%d].quantity: %d", i, products->quantity);
         printf(" - products[%d].productTypeCode: %hd", i, products->productTypeCode);
         printf(" - products[%d].categoryId: %s", i, products->categoryId);
         printf(" - products[%d].currencyCode: %s", i, products->currencyCode);
        
         if( strcmp(products->currencyCode, "KRW") == 0)
         {
             printf(" - products[%d].price: %.0lf", i, products->price);
             printf(" - products[%d].salePrice: %.0lf", i, products->salePrice);
         }
         else
         {
              printf(" - products[%d].price: %.2lf", i, products->price);
              printf(" - products[%d].salePrice: %.2lf", i, products->salePrice);
         }
            
         printf(" - products[%d].isDiscount: %s", i, products->isDiscount ? "true" : "false");
         printf(" - products[%d].discountType: %hd", i, products->discountType);
         printf(" - products[%d].discountTypeValue: %d", i, products->discountTypeValue);
         printf(" - products[%d].discountBeginDate: %llu", i, products->discountBeginDate);
         printf(" - products[%d].discountEndDate: %llu", i, products->discountEndDate);
         printf(" - products[%d].totalQuantity: %d", i, products->totalQuantity);
         printf(" - products[%d].memberQuantity: %d", i, products->memberQuantity);
         printf(" - products[%d].thumbnailUrl: %s", i, products->thumbnailUrl);
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

If an error occurs while running the StovePC_FetchProducts function, the OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.

ExternalError Description
500 Internal Server Error
50001 Store does not exist, or is under maintenance
50002 Product does not exist or is unavailable for sale
999999 undefined error

# 7) Start purchasing products

Start purchasing a product with the StovePC_StartPurchase function.

// input parameters
// StovePCOrderProduct* products: Order product information
// Size: number of ordered products


StovePCResult result = StovePC_StartPurchase(products, size);
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     // handle success
}
1
2
3
4
5
6
7
8
9
10

When the StovePC_StartPurchase function is successfully processed, the OnStartPurchase callback is called.
The StovePCPurchase structure passed to the callback contains meta information about product purchases.

  • StovePCPurchase.transactionMasterNo: transaction unique master number
  • StovePCPurchase.tempPaymentUrl : One-time payment URL
  • StovePCPurchase.purchaseProgress : Purchase progress status
    • 1: Payment in progress (page displayed in external browser)
    • 2: Purchase completed (Payment is completed due to the purchase of a product with a selling price of 0, so it is not necessary to display the page in an external browser using TempPaymentUrl)

When necessary, the game browses the one-time payment URL through an external browser. Supported browsers: Chrome (75+), Edge (42+)

void OnStartPurchase(StovePCPurchase purchase)
{
     printf("OnStartPurchase");
     printf(" - transactionMasterNo : %lld", purchase.transactionMasterNo);
     printf(" - tempPaymentUrl : %s", purchase.tempPaymentUrl);
     printf(" - purchaseProgress : %d", purchase.purchaseProgress);
    
     if(purchase.purchaseProgress == 1)
     {
         // open external browser
         ShellExecute( NULL, "open", purchase. tempPaymentUrl, NULL, NULL, SW_SHOWNORMAL);
     }
     else if(purchase.purchaseProgress == 2)
     {
         // Processing purchase completion (e.g. purchase completion message box)
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

If an error occurs while running the StovePC_StartPurchase function, the OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.
Normally, when the OnError callback is called for the StovePC_StartPurchase function call, the game exposes a message about the failure to the game user.
The table below provides a guide on what messages to display to game users.

| ExternalError | Description | Check the exposure message for game users | |:-------------|:-----------------------------|:- ------------------------------------| | 500 | Internal Server Error | This is a temporary phenomenon or the service is not smooth due to network reasons. | | 50001 | Store does not exist, or is under maintenance | The service is under maintenance, or the service does not exist. | | 50002 | Product does not exist or is unavailable for sale | This product cannot be purchased due to its condition. | | 50003 | non-exhibition products | This product is not currently on sale. | | 50004 | Products outside the sale period | This is not a product sale period. | | 50005 | Product price inconsistency (if product price is changed) | Product price information has been changed. | | 50009 | Exceeds the number of sales per member that can be purchased | The number of purchases per person has been exceeded. | | 50010 | Exceeds the total number of sales available for purchase | All prepared quantities have been sold. | | 50031 | Purchase quantity is '0' | Please enter at least one quantity to purchase. | | 999999 | undefined error | The service is not smooth due to other errors. |

# 8) Check product purchase status

Check the product purchase status with the StovePC_ConfirmPurchase function.

// input parameters
// int64 transactionMasterNo : Transaction unique master number (obtained through the OnStartPurchase callback parameter StovePCPurchase.transactionMasterNo)
StovePCResult result = StovePC_ConfirmPurchase(TRANSACTION_MASTER_NO);
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     // handle success
}
1
2
3
4
5
6
7

When the StovePC_ConfirmPurchase function is successfully processed, the OnConfirmPurchase callback is called.
The StovePCPurchaseProduct structure passed to the callback contains meta information about the purchased product, and the status callback parameter delivers the product purchase status.

  • StovePCPurchaseProduct.totalQuantity : Total product sales quantity
  • StovePCPurchaseProduct.memberQuantity : Member purchase quantity
  • StovePCPurchaseProduct.guidQuantity : Guid purchase quantity (purchase quantity of product purchase subject [CharacterNo/Guid/MemberNo])

In the case of a game without a separate game server, if the purchase result is successful, the game may provide an item.
In the case of a game with a game server, the game server can receive a notification about the purchase and can provide the item at this time.

void OnConfirmPurchase(const int size, StovePCPurchaseProduct* purchaseProducts, bool status, char* shopKey)
{
     printf("OnConfirmPurchase");
     printf(" - status : %s", status ? "true":"false");
     printf(" - shopKey: %s", shopKey);
    
     printf("-puchaseProduct size = %d", size);
     for (int i = 0; i < size; i++, purchaseProducts++)
   {
         printf(" - purchaseProducts[%d].productId: %lld", i, purchaseProducts->productId);
         printf(" - purchaseProducts[%d].categoryId: %s", i, purchaseProducts->categoryId);
         printf(" - purchaseProducts[%d].totalQuantity: %d", i, purchaseProducts->totalQuantity);
         printf(" - purchaseProducts[%d].memberQuantity: %d", i, purchaseProducts->memberQuantity);
         printf(" - purchaseProducts[%d].guidQuantity: %d", i, purchaseProducts->guidQuantity);
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

TIP

In the above sample code, string shopKey in the function is the same value as YOUR_SHOP_KEY called by StovePC_IAPInit function.

You need to send YOUR_SHOP_KEY with shopKey as an input parameter.

If an error occurs while running the StovePC_ConfirmPurchase function, the OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.

ExternalError Description
500 Internal Server Error
999999 undefined error

# 9) Verification of product purchase history

Verify product purchase history with StovePC_VerifyPurchase function. The value of the IsPurchased field is true for products that have been purchased more than once.
Product purchase history verification is performed targeting the cache within the PC SDK. At this time, if you explicitly enter the value of the categoryId parameter, only that category will be searched.
If you enter an empty string ("") in the value of the categoryId parameter, the search will be conducted for all categories.
Therefore, it may be advantageous in terms of search speed to accurately enter the category ID to search.

// input parameters
// char* categoryId: Category ID to search for products
// int64 productId: Product ID
StovePCPurchaseVerification purchaseVerification = StovePC_VerifyPurchase("CATEGORY_ID", PRODUCT_ID);
if (purchaseVerification.result == StovePCResult::STOVE_PC_NO_ERROR)
{
     printf("VerifyPurchase Success");
     printf(" - purchaseVerification.isPurchased : %s", purchaseVerification.isPurchased ? "true" : "false");
}
else
{
     // handle failure
}
1
2
3
4
5
6
7
8
9
10
11
12
13

The StovePC_VerifyPurchase function returns a StovePCPurchaseVerification structure.
The returned StovePCPurchaseVerification structure contains the product purchase history.
Also, error codes for function calls are included.

# 10) Search archives

Retrieve the inventory with the StovePC_FetchInventory function. Items that have been purchased are stored in the storage box.
You can process product payment by using the list of purchased products in the storage box.
Normally, games call the StovePC_ConfirmPurchase function to check the product purchase status and immediately deliver the product.
If the product information provided is lost due to an error, game reinstallation, etc., it can be used for recovery work using the storage box information.

StovePCResult result = StovePC_FetchInventory();
if(result == StovePCResult.NoError)
{
     // handle success
}
1
2
3
4
5

When the StovePC_FetchInventory function is successfully processed, the OnFetchInventory callback is called.
The StovePCInventoryItem structure passed to the callback contains meta information about the purchased product.

  • StovePCInventoryItem.transactionMasterNo: transaction unique master number
  • StovePCInventoryItem.transactionDetailNo: transaction specific detail number
  • StovePCInventoryItem.productId: Product ID
  • StovePCInventoryItem.gameItemId: In-game item ID mapped to product ID
  • StovePCInventoryItem.productName : product name
  • StovePCInventoryItem.quantity: Quantity of individual product
  • StovePCInventoryItem.thumbnailUrl : Representative product image
void OnFetchInventory(const int size, StovePCInventoryItem* inventoryItems)
{
     printf("OnFetchInventory");
     printf(" - inventoryItem size = %d", size);
     for (int i = 0; i < size; i++, inventoryItems++)
     {
         printf(" - inventoryItems[%d].transactionMasterNo: %lld", i, inventoryItems->transactionMasterNo);
         printf(" - inventoryItems[%d].transactionDetailNo: %lld", i, inventoryItems->transactionDetailNo);
         printf(" - inventoryItems[%d].productId: %lld", i, inventoryItems->productId);
         printf(" - inventoryItems[%d].gameItemId: %s", i, inventoryItems->gameItemId);
         wprintf(" - inventoryItems[%d].productName: %s", i, inventoryItems->productName);
         printf(" - inventoryItems[%d].quantity: %d", i, inventoryItems->quantity);
         printf(" - inventoryItems[%d].thumbnailUrl: %s", i, inventoryItems->thumbnailUrl);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

If an error occurs while running the StovePC_FetchInventory function, the OnError callback is called.
External errors can be checked through the ExternalError field of the StovePCError structure.

ExternalError Description
500 Internal Server Error
999999 undefined error

# Integrating additional services

PC SDK provides API to integrate additional services into games.
Additional services supported by PC SDK include custom event log, PC SDK version inquiry, over-immersion prevention notification, shutdown notification, tracking clue inquiry.
Games can send custom in-game events (game logs) to the Stove platform. Also, the game can query the semantic version of the PC SDK currently in use.
PC SDK semantic version inquiry can be obtained as a return value, not a callback.
The Over Immersion Prevention Alert delivers a warning phrase about over immersion in the game through a callback every hour.
Shutdown notification is a system that restricts children under the age of 18 from using the game at a specific time per day of the week by parents. When the requirements are met, notifications are delivered through callbacks up to 4 times.

# 1) Callback setting

In order to communicate with the PC SDK using the additional service API, the game must define a callback function to connect to the callback pointer of the StovePCCallback structure below.

struct StovePCCallback
{
     void(*OnError)(const StovePCError error);
     void(*OnInitComplete)();
     void(*OnToken)(const StovePCToken token);
     void(*OnUser)(const StovePCUser user);
     void(*OnOwnership)(int size, StovePCOwnership* ownership);
  
     void(*OnAutoPopup)(int size, StovePCAutoPopup* autoPopup, int headerSize, StovePCPopupRequestHeader* header);
     void(*OnManualPopup)(int size, StovePCManualPopup* manualPopup, int headerSize, StovePCPopupRequestHeader* header);
     void(*OnNewsPopup)(StovePCNewsPopup newsPopup, int headerSize, StovePCPopupRequestHeader* header);
     void(*OnCouponPopup)(StovePCCouponPopup couponPopup, int headerSize, StovePCPopupRequestHeader* header);
     void(*OnCommunityPopup)(StovePCCommunityPopup communityPopup, int cookieSize, StovePCPopupRequestCookie* cookie);
 
     // Callback called when StashCustomEvent processing is complete
     void(*OnStashCustomEvent)(const StovePCCustomEvent customEvent, int parameterSize, StovePCCustomEventParameter* parameter);

     // ADD 2.6.0 Start
     // Callback that is called every hour to prevent over-immersion
     void(*OnOverImmersion)(const StovePCOverImmersion overImmersion);

     // Callback to be called on shutdown limit
     void(*OnShutdown)(const StovePCShutdown shutdown);
     // 2.6.0 End

};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

Connect the callback function to the callback pointer of the StovePCCallback structure as in Connection 2) Config, Callback Settings.

// Create StovePCCallback structure instance
StovePCCallback callback;
 
// Initialize all function pointers to NULL
memset(&callback, 0, sizeof(StovePCCallback));
 
// Link implemented function pointers
callback.OnError = OnMyErrorCallback; /* Callback function defined globally */
callback.OnInitComplete = OnMyInitCompleteCallback; /* Callback function defined globally */
callback.OnToken = OnMyTokenCallback; /* Callback function defined globally */
callback.OnUser = OnMyUserInfoCallback; /* Callback function defined globally */
callback.OnOwnership = OnMyOwnershipCallback; /* Callback function defined globally */
  
// pop-up
callback.OnAutoPopup = OnMyAutoPopup; /* Callback function defined globally */
callback.OnManualPopup = OnMyManualPopup; /* Callback function defined globally */
callback.OnNewsPopup = OnMyNewsPopup; /* Callback function defined globally */
callback.OnCouponPopup = OnMyCouponPopup; /* Callback function defined globally */
callback.OnCommunityPopup = OnMyCommunityPopup; /* Callback function defined globally */
 
// Extra service
callback.OnStashCustomEvent = OnMyStashCustomEvent; /* Callback function defined globally */
// ADD 2.6.0 Start
callback.OnOverImmersion = OnMyOverImmersion; /* Callback function defined globally */
callback.OnShutdown = OnMyShutdown; /* Callback function defined globally */
// 2.6.0 End
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

You don't have to implement the OnStashCustomEvent callback. You only need to hook it up if your game uses the custom event logging feature.

warning

The OnOverImmersion callback must be implemented if legally required to prevent overimmersion/addiction to games.
The OnShutdown callback must be implemented if a selective shutdown is required by law.

# 2) Logging custom events

Log custom events (game logs) with StovePC_StashCustomEvent function.

// input parameters
// const char* name: event name
// const char* category1 : primary category name
// const char* category2: 2nd category name
// const float simpleValue : simple value
// const StovePCCustomEventParameter* params: Detailed parameter information
// const int paramsSize: Number of detailed parameter information
StovePCResult result = StovePC_StashCustomEvent("EVENT_NAME", "CATEGORY1", "CATEGORY2", 1.0f, params, PARAMS_SIZE);
if(result == StovePCResult::STOVE_PC_NO_ERROR)
{
     /* handle success */
}
1
2
3
4
5
6
7
8
9
10
11
12

When the StovePC_StashCustomEvent function is successfully processed, the OnStashCustomEvent callback is called.
The StovePCCustomEvent structure passed to the callback contains the event name, primary category name, secondary category name, and simple values passed when calling the API.
The StovePCCustomEventParameter structure passed to the callback contains the parameter information passed when calling the API.

void OnStashCustomEvent(const StovePCCustomEvent customEvent, int parameterSize, StovePCCustomEventParameter* parameter)
{
     // Print all user-defined event information
     printf("OnStashCustomEvent");
     printf(" - customEvent.name : %s", customEvent.name);
     printf(" - customEvent.category1 : %s", customEvent.category1);
     printf(" - customEvent.category2: %s", customEvent.category2);
     printf(" - customEvent.simpleValue: %f", customEvent.simpleValue);
 
     printf(" - parameter size : %d", parameterSize);
 
     for (int i = 0; i < parameterSize; i++, parameter++)
     {
         printf(" - parameter[%d].name : %s", i, parameter->name);
         printf(" - parameter[%d].value : %s", i, parameter->value);
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Precautions

Callback Parameter The valid scope of the StovePCCustomEvent/StovePCCustomEventParameter structure is limited to the scope of the callback function.
PC SDK frees internally allocated memory as soon as callback function execution is completed.
Therefore, if saving is necessary to use the information of StovePCCustomEvent/StovePCCustomEventParameter structure outside the scope of the callback function, a copy must be created through deep copy, and
When the use of the copy is complete, the memory must be freed.

If an error occurs while running the StovePC_StashCustomEvent function, the OnError callback is called.

# 3) Get PC SDK semantic version

Use the StovePC_GetSDKVersion function to retrieve the version information of the currently interlocking PC SDK.

char* version = StovePC_GetSDKVersion();
if(0 != strcmp(version, ""))
{
     /* handle success */
}
1
2
3
4
5

# 4) Prevention of excessive immersion in games 2.6.0

The OnOverImmersion callback is called every hour after starting the game.
The StovePCOverImmersion structure passed to the callback contains the message, the elapsed time of using the game, and the minimum exposure time (in seconds) of the message.

  • StovePCOverImmersion.message : Overimmersion message
  • StovePCOverImmersion.elapsedTimeInHours : Elapsed time
  • StovePCOverImmersion.minExposureTimeInSeconds : Minimum exposure time of message (in seconds)

The message is translated based on the language set in the PC SDK.

void OnOverImmersion(const StovePCOverImmersion overImmersion)
{
     // output excessive immersion prevention information
     printf("OnOverImmersion");
     wprintf(L" - overImmersion.message : %s", overImmersion.message);
     printf(" - overImmersion.elapsedTimeInHours: %d", overImmersion.elapsedTimeInHours);
     printf(" - overImmersion.minExposureTimeInSeconds: %d", overImmersion.minExposureTimeInSeconds);
}
1
2
3
4
5
6
7
8

Precautions

The valid scope of the callback parameter StovePCOverImmersion structure is limited to the scope of the callback function.
PC SDK frees internally allocated memory as soon as callback function execution is completed.
Therefore, if you need to save information in the StovePCOverImmersion structure outside the scope of the callback function
You must create a copy through deep copy, and release the memory when the use of the copy is complete.

Guide to over-immersion messages

과몰입 메시지 : 게임을 플레이한 지 1 시간이 지났습니다. 과도한 게임이용은 정상적인 일상생활에 지장을 줄 수 있습니다.

# 5) Shut down 2.6.0

After starting the game, the OnShutdown callback is called based on the timetable registered in the shutdown system only for those subject to selective shutdown.
The OnShutdown callback can be called up to 4 times, and the time it is called and the actions to be taken in the game are as follows.

  • Shutdown event after successful PCSDK initialization
    • Shutdown notification 10 minutes ago: Shows only notification that you will be logged out after 10 minutes
    • Notification of shutdown 5 minutes ago: Shows only notification that you will be logged out after 5 minutes
    • Shutdown notification 1 minute ago: Displays only notification that you will be logged out after 1 minute
    • Shutdown Notification: Displays a notification that you will be logged out and ends the game immediately upon user confirmation

The StovePCShutdown structure passed to the callback contains the remaining time until shutdown, the message, and the message exposure time (seconds).

  • StovePCShutdown.inadvanceTimeInMinutes: The remaining time (minutes) until the user shuts down. If 0, the game ends immediately.
  • StovePCShutdown.message : Shutdown notification message
  • StovePCShutdown.exposureTimeInSeconds: message exposure time (seconds)
void OnShutdown(const StovePCShutdown shutdown)
{
     // print shutdown information
     printf("OnShutdown");
     printf(" - shutdown.inadvanceTimeInMinutes: %d", shutdown.inadvanceTimeInMinutes);
     wprintf(L" - shutdown.message : %s", shutdown.message);
     printf(" - shutdown.exposureTimeInSeconds: %d", shutdown.exposureTimeInSeconds);
}
1
2
3
4
5
6
7
8

Precautions

The valid scope of the callback parameter StovePCShutdown structure is limited to the scope of the callback function.
PC SDK frees internally allocated memory as soon as callback function execution is completed.
Therefore, if you need to store the information in the StovePCShutdown structure outside the scope of the callback function
You must create a copy through deep copy, and release the memory when the use of the copy is complete.

Shutdown Message Information

10 minutes : 회원님은 게임 시간 선택제 적용 대상으로 10 분 후 게임 이용이 제한됩니다.
5 minutes : 회원님은 게임 시간 선택제 적용 대상으로 5 분 후 게임 이용이 제한됩니다.
1 minutes : 회원님은 게임 시간 선택제 적용 대상으로 1 분 후 게임 이용이 제한됩니다.
0 minutes : 회원님은 게임 시간 선택제 적용 대상으로 게임 이용이 제한되어 게임을 종료합니다.

Retrieve a set of clues for tracing stove platform logs with StovePC.GetTraceHint function.

StovePCTraceHint traceHint = StovePC_GetTraceHint();
if (traceHint.result == StovePCResult::STOVE_PC_NO_ERROR)
{
     printf("GetTraceHint");
     printf(" - traceHint.sessionId : %s", traceHint.sessionId);
     printf(" - traceHint.refSessionId : %s", traceHint.refSessionId);
     printf(" - traceHint.uuid : %s", traceHint.uuid);
     printf(" - traceHint.serviceProtocol : %s", traceHint.serviceProtocol);
     printf(" - traceHint.refResourceType : %s", traceHint.refResourceType);
}
else
{
     /* handle failure */
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

The StovePC_GetTraceHint function returns a StovePCTraceHint structure.
The returned StovePCTraceHint structure includes the session ID and reference session ID.
Also, error codes for function calls are included.

Last Updated: 7/10/2024, 2:07:53 AM