# PC SDK Unity 연동 가이드
# 소개
STOVE 플랫폼은 게임 배포 및 판매, 커뮤니티, 지표분석 등을 포함한, 게임 출시의 모든 과정을 원스탑으로 처리할 수 있는 통합 서비스를 제공합니다. PC SDK(Unity, 이하 PC SDK)를 사용하면 Stove 플랫폼이 제공하는 서비스를 게임에 쉽게 통합할 수 있습니다.
여기서는 PC SDK를 연동하는 방법에 대해 설명합니다.
PC SDK 연동이 처음이라면, PC SDK Unity 따라하기를 먼저 읽어보기 바랍니다.
# 사전준비
- 스토브 가입 계정과 출시 게임용 App key, App secret, Game Id를 STOVE Studio (opens new window)에서 발급받았는지 확인합니다.
- Unity 2017 이상 버전과 Visual Studio 2017 이상 버전의 설치를 권장합니다.
- PC SDK 다운로드 페이지에서 최신 버전의
Unity(C#)
배포 파일(이하StovePCSDK_NET
로 표기)을 다운로드 합니다.
# StovePCSDK_NET 배포 파일 구성
# 1) StovePCSDK 폴더
StovePCSDK_NET를 다운로드하고 압축을 풀면 StovePCSDK
폴더에 아래와 같은 폴더들이 포함되어 있습니다.
Plugins
Unity Project 플러그인 폴더입니다.Plugins\x86
x86용 빌드에 필요한 바이너리가 포함되어 있습니다.Plugins\x86_64
x64용 빌드에 필요한 바이너리가 포함되어 있습니다.
# StovePCSDK_NET 빌드 환경 구성
# 1) Assets 추가하기
통합 할 유니티 프로젝트를 열고 앞서 설명한 StovePCSDK
폴더에서 x86 폴더와 x86_64 폴더 중 하나만 남기고 다른 하나는 삭제한 후 StovePCSDK
폴더를 복사하여 Assets 폴더 하위에 붙여넣기를 합니다.
# 2) x86 폴더의 파일 확인하기
x86 폴더 하위에 있는 파일을 선택하고 인스펙터(Inspector)에서 Platform settings 섹션에 Windows x86 항목이 체크되어 있는지 확인합니다. 만약 체크되어 있지 않다면 체크박스를 선택합니다.
# 3) x86_64 폴더의 파일 확인하기
x86_64 폴더 하위에 있는 파일을 선택하고 인스펙터에서 Platform settings 섹션에 Windows x86_x64 항목이 선택되어 있는지 확인합니다. 선택되어 있지 않다면 선택해 줍니다.
# 4) Build Settings
File > Build Settings... 메뉴를 눌러 Build Settings 대화상자를 열고 Player Settings... 버튼을 클릭하여 Inspector 또는 Project Settings 창을 엽니다.
Other Settings 그룹 > Configuration 섹션 > Api Compatibility Level 항목을 아래와 같이 설정합니다.
Unity 2018 이전 버전 : .NET 2.0 (.NET 2.0 Subset 아님)
Unity 2018 이후 버전 : .NET 4.x (.NET Standard 2.0 아님)
# 5) 빈 게임오브젝트 생성하기
적당한 씬에 게임오브젝트(GameObject -> Create Empty)를 생성합니다. 빈 게임오브젝트의 이름을 편의상 StovePCSDKManager로 설정합니다.
# 6) 스크립트 컴포넌트 추가하기
StovePCSDKManager 오브젝트에 Script 컴포넌트를 추가합니다.
편의상 스크립트의 이름을 StovePCSDKManager
로 설정합니다.
# 7) 스크립트 작성하기
StovePCSDKManager 오브젝트가 씬 전환등에 의해 해제되지 않도록 Awake 메서드에 아래와 같이 처리를 해 줍니다.
private void Awake()
{
DontDestroyOnLoad(transform.gameObject);
}
2
3
4
# PC SDK 연동하기
# 1) RunCallback
PC SDK의 API는 게임엔진 및 게임로직에 방해가 되지 않도록 대부분 비동기로 수행됩니다. API 호출에 대한 결과는 PC SDK 내부의 큐에 적재되며 게임이 API 호출에 대한 결과를 처리하려 할 때 RunCallback 메서드를 호출함으로써 등록한 콜백이 실행됩니다. 보통 RunCallback 메서드의 호출은 코루틴을 이용하여 작성하며 호출 주기는 설정이 가능 합니다.
private IEnumerator RunCallback(float intervalSeconds)
{
WaitForSeconds wfs = new WaitForSeconds(intervalSeconds);
while (true)
{
StovePC.RunCallback();
yield return wfs;
}
}
2
3
4
5
6
7
8
9
코루틴은 MonoBehaviour.StartCoroutine
메서드를 통해 시작하며 일반적으로 PC SDK 초기화가
성공하면 시작하고 PC SDK 종료가 성공하면 중지합니다.
PC SDK 종료 성공 후 RunCallback 코루틴의 중지를 위해 멤버 변수를 이용하는 방법이 있습니다.
private Coroutine runcallbackCoroutine;
게임프로젝트에 멤버변수로 선언된 runcallbackCoroutine
을 아래 코드와 같이 StartCoroutine
함수와 StopCoroutine
함수를 사용해 타이머처럼 동작시킬 수 있습니다.
public void ToggleRunCallback_ValueChanged(bool isOn)
{
if (isOn)
{
float intervalSeconds = 1f;
runcallbackCoroutine = StartCoroutine(RunCallback(intervalSeconds));
WriteLog("RunCallback Start");
}
else
{
if (runcallbackCoroutine != null)
{
StopCoroutine(runcallbackCoroutine);
runcallbackCoroutine = null;
WriteLog("RunCallback Stop");
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2) Config, Callback 설정
PC SDK를 초기화하기 위해서는, 먼저 StovePCConfig
와 StovePCCallback
구조체에 값을 채운 뒤, StovePC.Initialize
메서드를 호출합니다.
아래 코드를 참고하여 멤버변수를 이용하여 StovePCConfig
구조체의 각 필드 값을 채웁니다.
해당 멤버변수는 유니티 에디터의 인스펙터를 통해 값을 설정합니다.
[SerializeField]
private string env;
[SerializeField]
private string appKey;
[SerializeField]
private string appSecret;
[SerializeField]
private string gameId;
[SerializeField]
private StovePCLogLevel logLevel;
[SerializeField]
string logPath;
StovePCConfig config = new StovePCConfig
{
Env = env,
AppKey = appKey,
AppSecret = appSecret,
GameId = gameId,
LogLevel = logLevel,
LogPath = logPath
};
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
"YOUR_APP_KEY", "YOUR_SECRET_KEY", "YOUR_GAME_ID"는STOVE Studio
에서 발급 받은 키값으로 데이터로 변경해야 됩니다.
스토브 런처에 로그인 하지 않은 상태로StovePC.Initialize
메서드를 호출하면 에러가 발생하니 사전에 스토브 런처를 실행하고 로그인합니다.
주의사항
PC SDK 로그경로는 절대적경로로 설정해야 합니다. ex) C:\Program Files\{Your Game Folder}\Logs
마지막에 "\"는 추가하지 않습니다. PCSDK 에서 "StovePCSDK.log" 파일명을 자동으로 추가합니다.
만약 "" 빈문자열로 경로를 설정하게 되면 PC SDK는 자동적으로 게임실행파일 폴더 또는 PC SDK DLL 이 위치한 폴더의 경로로 로그가 생성됩니다.
게임과 PC SDK간의 연동은 C# 델리게이트(Delegate)을 사용합니다.
게임에서는 아래 StovePCCallback
클래스의 콜백에 연결할 델리게이트 메서드를 정의해야 합니다.
public class StovePCCallback
{
// StovePCSDK 에서 에러발생시 호출되는 콜백
public StovePCErrorDelegate OnError;
// PC SDK 초기화가 완료됐을 때 호출되는 콜백
public StovePCInitializationCompleteDelegate OnInitializationComplete;
// GetToken 처리가 완료됐을 때 호출되는 콜백
public StovePCTokenDelegate OnToken;
// GetUser 처리가 완료됐을 때 호출되는 콜백
public StovePCUserDelegate OnUser;
// GetOwnership 처리가 완료됐을 때 호출되는 콜백
public StovePCOwnershipDelegate OnOwnership;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
여기서 주의할 점이 있는데 StovePCCallback
객체는 PC SDK가 종료될 때까지 보존되어야 합니다. 그 이유는 StovePCCallback
객체가 가비지 컬렉팅이 되면 PC SDK 내부에서는 콜백을 호출 할 수 없기 때문입니다.
이 점을 충족시키기 위해 StovePCCallback
클래스를 게임프로젝트 클래스의 멤버변수로 선언해서 가비지 컬렉팅이 되지 않도록 하여 해결할 수 있습니다.
private StovePCCallback callback;
// StovePCCallback 클래스 instance 생성
this.callback = new StovePCCallback
{
OnError = new StovePCErrorDelegate(this.OnError),
OnInitializationComplete = new StovePCInitializationCompleteDelegate(this.OnInitializationComplete),
OnToken = new StovePCTokenDelegate(this.OnToken),
OnUser = new StovePCUserDelegate(this.OnUser),
OnOwnership = new StovePCOwnershipDelegate(this.OnOwnership)
};
2
3
4
5
6
7
8
9
필수적으로 연동해야 하는 OnError
, OnInitializationComplete
, OnOwnership
콜백함수 외의 나머지 콜백함수는 필요 시에만 연동을 하면 됩니다. 예를 들어, 소유권(Ownership) 기능만 사용하는 경우, 아래와 같이 델리게이트 메소드로 연결하면 됩니다.
/*
소유권(Ownership) 기능만 사용하는 경우는,
필수 구현 콜백인 OnError, OnInitializationComplete 외에
OnOwnership 콜백만 추가로 구현해서 연결합니다.
*/
this.callback = new StovePCCallback
{
OnError = new StovePCErrorDelegate(this.OnError),
OnInitializationComplete = new StovePCInitializationCompleteDelegate(this.OnInitializationComplete),
OnOwnership = new StovePCOwnershipDelegate(this.OnOwnership)
};
2
3
4
5
6
7
8
9
10
11
# 3) SDK 초기화
PC SDK를 초기화하기 위해 StovePC.Initialize
메서드를 호출합니다.
StovePCResult sdkResult = StovePC.Initialize(config, this.callback);
if (StovePCResult.NoError == sdkResult)
{
this.runCallbackCoroutine = StartCoroutine(RunCallback(0.5f));
// 초기화 오류가 없어 RunCallback 주기적 호출
}
else
{
// 초기화 실패로 게임 종료
}
2
3
4
5
6
7
8
9
10
StovePC.Initialize
메서드는 config와 callback의 유효성 여부만 확인한 후, 즉시 StovePCResult
enum 타입 값을 반환합니다.
성공한 경우, StovePCResult.NoError
값이 반환됩니다. 실패한 경우는 해당 에러 코드를 반환하며 게임 종료를 처리해야 합니다.
반환값이 StovePCResult.NoError
, 즉 '성공'인 경우, StovePC.RunCallback
메서드를 주기적으로 호출해 줍니다.
StovePC.RunCallback
메서드를 주기적으로 호출해야만, 연결된 콜백이 정상적으로 호출됩니다.
호출 주기가 길면 콜백의 응답 속도도 느려지게 되므로, 적당한 호출 주기를 유지하는 것이 좋습니다. 예제코드에서는 1초에 한번 콜백함수가 호출되는 것으로 설정했습니다.
주의사항
StovePC_RunCallback
함수를 비롯하여 PCSDK와 연동되는 Callback함수들은 반드시 메인스레드
에서 호출하도록 코드를 작성해주시기 바랍니다.
StovePC.Initialize
메서드는 config와 callback 유효성 확인을 제외한, 그 외의 작업을 비동기로 처리합니다.
비동기 작업이 성공적으로 완료된 경우, OnInitializationComplete
콜백이 호출되며, 에러가 발생한 경우는 OnError
콜백이 호출됩니다.
에러가 발생한 경우, 전달된 StovePCError
구조체를 통해 에러 코드, 메시지 등을 확인할 수 있습니다.
private void OnInitializationComplete()
{
Debug.Log("PC SDK initialization success");
}
private void OnError(StovePCError error)
{
#region Log
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnError");
sb.AppendFormat(" - error.FunctionType : {0}" + Environment.NewLine, error.FunctionType.ToString());
sb.AppendFormat(" - error.Result : {0}" + Environment.NewLine, (int)error.Result);
sb.AppendFormat(" - error.Message : {0}" + Environment.NewLine, error.Message);
sb.AppendFormat(" - error.ExternalError : {0}", error.ExternalError.ToString());
WriteLog(sb.ToString());
#endregion
switch (error.FunctionType)
{
case StovePCFunctionType.Initialize:
case StovePCFunctionType.GetUser:
case StovePCFunctionType.GetOwnership:
BeginQuitAppDueToError();
break;
}
}
private void BeginQuitAppDueToError()
{
#region Log
StringBuilder sb = new StringBuilder();
sb.AppendLine("BeginQuitAppDueToError");
sb.AppendFormat(" - nothing");
WriteLog(sb.ToString());
#endregion
// 어쩌면 당신은 즉시 앱을 중단하기보다는 사용자에게 앱 중단에 대한 메시지를 보여준 후
// 사용자 액션(e.g. 종료 버튼 클릭)에 따라 앱을 중단하고 싶어 할지도 모릅니다.
// 그렇다면 여기에 QuitApplication을 지우고 당신만의 로직을 구현하십시오.
// 권장하는 필수 사전 작업 오류에 대한 메시지는 아래와 같습니다.
// 한국어 : 필수 사전 작업이 실패하여 게임을 종료합니다.
// 그 외 언어 : The required pre-task fails and exits the game.
QuitApplication();
}
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
42
43
44
OnInitializationComplete
콜백이 오기 전, PC SDK의 초기화 상태 값을 조회할 필요가 있는 경우, StovePC.GetInitializationState
함수를 사용할 수 있습니다.`
// StovePC.Initialize 호출 후...
while (StovePC.GetInitializationState() == StovePCInitializationState.Pending)
{
Thread.Sleep(500);
StovePC.RunCallback();
}
if (StovePC.GetInitializationState() == StovePCInitializationState.Complete)
{
// 초기화 완료 OnInitializationComplete 콜백이 호출됨
}
else
{
// 초기화 실패 OnError 콜백이 호출됨
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 4) SDK 연동시 주의사항
초기화가 완료되기 전에
GetToken
,GetUser
,GetOwnership
메서드를 호출하면 정상적으로 결과를 받지 못할 수 있습니다. 즉,OnInitializationComplete
콜백이 정상적으로 수신된 이후에GetToken
,GetUser
,GetOwnership
메서드를 호출해야 정상적으로 결과를 받을 수 있습니다.
StovePCConfig 구조체의 로그레벨 설정시 PC SDK 테스트 시에는
StovePCLogLevel.Debug
값을 입력하고, 정식 빌드에는StovePCLogLevel.Error
값으로 설정하여 불필요한 로그가 생성되는 것을 방지해 주시기 바랍니다.
# 5) SDK 종료
PC SDK 사용이 끝난 뒤에 호출하여 사용중인 리소스를 정리합니다. StovePC.Uninitialize
메서드가 호출된 후에는 PC SDK의 API가 동작하지 않습니다. StovePC.Uninitialize
메서드 호출 전 또는 후에 반드시 StopCoroutine
함수로 runcallbackCoroutine
코루틴 실행을 중지시켜야 합니다.
StovePCResult result = StovePC.Uninitialize();
if (result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
# 6) 사용자 정보 얻기
StovePC.GetUser
메서드로 스토브 런처에 로그인한 사용자 정보를 확인 할 수 있습니다.
StovePCResult result = StovePC.GetUser();
if (result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.GetUser
메서드가 정상적으로 처리되면 OnUser
콜백이 호출됩니다.
콜백에 전달되는 StovePCUser
구조체를 통해 사용자의 멤버넘버, 닉네임, 게임사용자아이디 정보들를 알 수 있습니다.
private void OnUser(StovePCUser user)
{
// 사용자 정보 출력
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnUser");
sb.AppendFormat(" - user.MemberNo : {0}" + Environment.NewLine, user.MemberNo.ToString());
sb.AppendFormat(" - user.Nickname : {0}" + Environment.NewLine, user.Nickname);
sb.AppendFormat(" - user.GameUserId : {0}", user.GameUserId);
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
11
# 7) 토큰 정보 얻기
StovePC.GetToken
메서드로 스토브 런처에 로그인한 사용자의 토큰 정보를 얻어 옵니다.
StovePCResult result = StovePC.GetToken();
if (result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.GetToken
메서드가 정상적으로 처리되면 OnToken
콜백이 호출됩니다.
콜백에 전달되는 StovePCToken
구조체에는 토큰 문자열이 포함되어 있습니다.
private void OnToken(StovePCToken token)
{
// 토큰 정보 출력
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnToken");
sb.AppendFormat(" - token.AccessToken : {0}", token.AccessToken);
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
토큰이란? STOVE 런처에 로그인된 사용자의 엑세스토큰(Access Token)으로 게임서버가 이 엑세스토큰을 스토브 인증서버로 전달해서 로그인한 사용자의 유효성 검증을 수행할 수 있습니다. 엑세스토큰에 대한 상세한 설명은 store.support@smilegate.com 로 기술지원을 받으시길 바랍니다
# 8) 소유권 정보 얻기
StovePC.GetOwnership
메서드로 스토브 런처 사용자가 해당 게임을 구매해서 소유하고 있는지 여부를 조회합니다.
StovePCResult result = StovePC.GetOwnership();
if (result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.GetOwnership
메서드가 정상적으로 처리되면 OnOwnership
콜백이 호출됩니다.
아래는 OnOwnership
콜백에서 게임 구매 여부를 판단하는 예시 코드입니다.
DLC가 없는 게임인 경우, 22~27 line의 확인 코드는 불필요합니다.
private void OnOwnership(StovePCOwnership[] ownerships)
{
bool owned = false;
foreach(var ownership in ownerships)
{
// [LOGIN_USER_MEMBER_NO] StovePCUser 구조체의 MemberNo
// [OwnershipCode] 1: 소유권 획득, 2: 소유권 해제(구매 취소한 경우)
if (ownership.MemberNo != LOGIN_USER_MEMBER_NO ||
ownership.OwnershipCode != 1)
{
continue;
}
// [GameCode] 3: BASIC 게임, 4: DEMO
if (ownership.GameId == "YOUR_GAME_ID" &&
ownership.GameCode == 3)
{
owned = true; // 소유권 확인 변수 true로 설정
}
// DLC를 판매하는 게임일 때만 필요
if (ownership.GameId == "YOUR_DLC_ID" &&
ownership.GameCode == 5)
{
// YOUR_DLC_ID(DLC) 소유권이 있기에 DLC 플레이 허용
}
}
if(owned)
{
// 소유권 검증이 정상적으로 완료 된 이후 게임진입 로직 작성
}
else
{
// 소유권 검증실패 후 게임을 종료하고 에러메세지 표출 로직 작성
}
}
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
- 게임을 구매한 계정(소유권 보유)으로 STOVE 런처에 로그인한 후 게임을 플레이를 할 수 있습니다.
- 게임 소유권이 없는 계정으로 STOVE 런처에 로그인한 후 exe 실행 시 아래 안내 메시지(예시)를 출력한 후 게임을 종료합니다.
- 한국어 외의 OS : Please log in to STOVE Client with the account that has purchased the game
- 한국어 : 게임을 구매한 계정으로 STOVE 클라이언트에 로그인하시기 바랍니다
게임 소유권이 있는 계정이 없어도 소유권 기능을 테스트할 수 있으며, 자세한 방법은 FAQ를 확인하시기 바랍니다.
- 또한 소유권( Ownership) 호출 <GetOwnership Success> 후에 output_log.txt 혹은 Player.log에 아래와 같은 로그 추가 부탁 드립니다.
예시 :
성공: 소유권이 있는 유저입니다.
실패: 소유권이 없는 유저입니다.
2
3
4
# 9) 언어 설정 2.6.0
StovePC.SetLanguage
함수로 언어를 설정합니다.
PC SDK는 초기화시 시스템 언어(운영체제 언어)를 이용하여 언어를 기본으로 설정합니다.
명시적으로 시스템 언어(운영체제 언어)를 설정하려면 파라미터로 system
을 입력합니다.
특정언어를 설정하기 위해서는 초기화 성공 이후(e.g. OnInitializationComplete) StovePC.SetLanguage
함수를 호출합니다.
StovePCResult result = StovePC.SetLanguage("LANGUAGE_CODE");
if (result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
# 10) 언어 번역 2.6.0
StovePC.TranslateLanguage
함수로 언어를 번역합니다.
PC SDK는 설정된 언어 정보를 기반으로 특정 문자열에 대한 번역본을 제공합니다.
특정 문자열은 PC SDK 에서 관리하는 문자열 아이디(String Id)로 관리됩니다.
게임에서 PC SDK 팝업 UI 를 직접 구현하는 경우 UI에 표시되는 문자열은 StovePC.TranslateLanguage
함수를 통해 번역된 문자열을 표시해야 합니다.
string translated = StovePC.TranslateLanguage("STRING_ID");
주의사항
PC SDK에 설정된 언어에 대해 특정 문자열의 번역본이 없는 경우 영어 번역본을 리턴하며,
예외 발생 또는 지원하지 않는 문자열 아이디에 대해서는 입력 파라미터(문자열 아이디)를 그대로 리턴합니다.
# 에러 확인
PC SDK 사용 중 발생하는 에러는 크게 두 가지 경우로 구분해서 확인할 수 있습니다.
# 메서드 호출 후 반환되는 StovePCResult enum 값
PC SDK의 모든 메서드는 호출 직후, 호출이 성공했는지 여부를 나타내는 StovePCResult
enum 값을 반환합니다.
반환되는 오류코드는 PC SDK 오류 코드 페이지에서 확인 할 수 있습니다.
# OnError 콜백을 통해 전달되는 StovePCError 구조체
PC SDK API에서 에러가 발생한 경우는 OnError
콜백이 호출되며, 에러에 대한 자세한 정보가 포함된 StovePCError
구조체가 전달됩니다.
// OnError 콜백이 호출될 때 전달 됩니다.
public struct StovePCError
{
// 호출된 함수를 나타내는 enum 값
public StovePCFunctionType FunctionType;
// 발생한 에러 유형을 나타내는 enum 값
public StovePCResult Result;
// 발생한 에러 메시지
public string Message;
// 외부 에러(http 에러, 외부 모듈 에러)가 발생한 경우, 해당하는 에러 코드
public int ExternalError;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 게임지원서비스 연동하기
PC SDK는 스토브 플랫폼의 게임지원서비스를 게임에 통합할 수 있도록 API를 제공합니다. PC SDK가 지원하는 게임지원서비스로는 스탯, 업적, 리더보드가 있습니다. 각각의 서비스는 아래와 같이 정의합니다.
- 스탯 : 유저의 다양한 게임 Play Data를 수치로 기록해 주는 서비스
- 업적 : 게임 Play 도전 과제를 설정하고, 유저 별 달성 정보를 제공해 주는 서비스
- 리더보드 : 특정 게임 Play Data의 유저 랭킹 정보를 제공해 주는 서비스
PC SDK 게임지원서비스 API를 사용하기 위해서는 스튜디오를 통한 게임지원서비스의 메타데이터 등록이 선행되어야 합니다.
메타데이터 관리에 대한 내용은 게임지원서비스 스튜디오 가이드을 참고하시기 바랍니다.
# 1) Callback 설정
게임지원서비스 API를 사용하여 PC SDK와 커뮤니케이션 하기 위하여, 게임에서는 아래 StovePCCallbak
클래스의 콜백에 연결할 델리게이트 메서드를 정의해야 합니다.
public class StovePCCallback
{
public StovePCErrorDelegate OnError;
public StovePCInitializationCompleteDelegate OnInitializationComplete;
public StovePCTokenDelegate OnToken;
public StovePCUserDelegate OnUser;
public StovePCOwnershipDelegate OnOwnership;
// GetStat 처리가 완료됐을 때 호출되는 콜백
public StovePCStatDelegate OnStat;
// SetStat 처리가 완료됐을 때 호출되는 콜백
public StovePCSetStatDelegate OnSetStat;
// GetAchievement 처리가 완료됐을 때 호출되는 콜백
public StovePCAchievementDelegate OnAchievement;
// GetAllAchievement 처리가 완료됐을 때 호출되는 콜백
public StovePCAllAchievementDelegate OnAllAchievement;
// GetRank 처리가 완료됐을 때 호출되는 콜백
public StovePCRankDelegate OnRank;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
연동하기 2) Config, Callbak 설정
에서와 같이 StovePCCallback
클래스의 콜백에 델리게이드를 연결합니다.
// StovePCCallback 클래스 instance 생성
this.callback = new StovePCCallback
{
OnError = new StovePCErrorDelegate(this.OnError),
OnInitializationComplete = new StovePCInitializationCompleteDelegate(this.OnInitializationComplete),
OnToken = new StovePCTokenDelegate(this.OnToken),
OnUser = new StovePCUserDelegate(this.OnUser),
OnOwnership = new StovePCOwnershipDelegate(this.OnOwnership),
// 게임지원서비스
OnStat = new StovePCStatDelegate(this.OnStat),
OnSetStat = new StovePCSetStatDelegate(this.OnSetStat),
OnAchievement = new StovePCAchievementDelegate(this.OnAchievement),
OnAllAchievement = new StovePCAllAchievementDelegate(this.OnAllAchievement),
OnRank = new StovePCRankDelegate(this.OnRank)
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
OnStat
, OnSetStat
, OnAchievement
, OnAllAchievement
, OnRank
콜백을 반드시 구현할 필요는 없습니다.
게임에서 사용하는 게임지원서비스에 맞게 필요한 콜백 메서드만 구현하여 연결하면 됩니다.
# 2) 사용자 스탯 업데이트 하기
StovePC.SetStat
메서드로 로그인한 사용자의 해당 게임에 대한 특정 스탯을 업데이트 합니다.
// 입력 파라미터
// string statId : 스튜디오에서 등록한 스탯 식별자
// int statValue : 업데이트할 스탯값
StovePCResult result = StovePC.SetStat("STAT_ID", STAT_VALUE);
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
8
StovePC.SetStat
메서드가 정상적으로 처리되면 OnSetStat
콜백이 호출됩니다.
콜백에 전달되는 StovePCStatValue
구조체에는 현재 스탯값과 업데이트 상태를 나타내는 플래그 및 에러메세지가 포함되어 있습니다.
스탯값이 완전하게 반영되어 업데이트 되었다면 Updated 필드는 true, ErrorMessage 필드는 빈문자열이 포함되며, 스탯값이 부분적으로 업데이트 되었다면 Updated 필드는 true, ErrorMessage 필드는 "integer overflow" 와 같은 문자열이 포함됩니다.
예를들어 INCREMENT 유형 스탯의 현재값이 2,147,483,000라고 가정하고 StovePC.SetStat
API를 통해 1,000을 합산하려 한다면 Int32 타입이 가질 수 있는 값의 범위를 벗어나게 되므로 업데이트를 요청한 값(1,000)의 일부만 반영되어 현재값이 Int32 타입의 최대값인 2,147,483,647로 업데이트 되는 경우 ErrorMessage 필드에 "integer overflow" 와 같은 문자열이 포함됩니다.
아래 표는 StovePCStatValue
구조체를 통해 얻을 수 있는 결과의 목록입니다.
스탯유형 | Updated | ErrorMessage | 결과 |
---|---|---|---|
모든유형 | True | ""(빈문자열) | 요청값이 현재값에 완전히 업데이트 됨 |
INCREMENT | True | "integer overflow" | 저장 공간 초과로 부분(partial) 업데이트 됨 |
INCREMENT | False | "integer overflow" | 저장 공간 초과로 업데이트 안됨 |
MIN | False | ""(빈문자열) | 요청값이 현재값보다 큼 |
MAX | False | ""(빈문자열) | 요청값이 현재값보다 작음 |
REPLACE | False | ""(빈문자열) | 요청값이 현재값과 동일함 |
private void OnSetStat(StovePCStatValue statValue)
{
// 스탯 업데이트 결과 정보 출력
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnSetStat");
sb.AppendFormat(" - statValue.CurrentValue : {0}" + Environment.NewLine, statValue.CurrentValue.ToString());
sb.AppendFormat(" - statValue.Updated : {0}" + Environment.NewLine, statValue.Updated.ToString());
sb.AppendFormat(" - statValue.ErrorMessage : {0}", statValue.ErrorMessage);
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
11
주의사항) 콜백파라미터
StovePCStatValue
구조체의 유효한 범위는 콜백함수 스코프로 한정됩니다. PC SDK는 콜백함수 실행이 완료되는 즉시 내부에서 할당한 메모리를 해제합니다. 따라서 콜백함수 스코프 밖에서StovePCStatValue
구조체의 정보를 사용하기 위해 저장이 필요한 경우 반드시 깊은복사(Deep Copy)를 통해 사본을 생성하고, 사본에 대한 사용이 완료되면 메모리를 해제하여야 합니다.
StovePC.SetStat
메서드가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
2000 | Invalid Access |
3000 | Wrong API Usage |
4000 | Stats ID Not Found |
9000 | Service Error |
# 3) 사용자 스탯 정보 얻기
StovePC.GetStat
메서드로 로그인한 사용자의 해당 게임에 대한 특정 스탯 정보를 조회합니다.
// 입력 파라미터
// string statId : 스튜디오에서 등록한 스탯 식별자
StovePCResult result = StovePC.GetStat("STAT_ID");
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
StovePC.GetStat
메서드가 정상적으로 처리되면 OnStat
콜백이 호출됩니다.
콜백에 전달되는 StovePCStat
구조체에는 현재 스탯값이 포함되어 있습니다.
private void OnStat(StovePCStat stat)
{
// 스탯 정보 출력
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnStat");
sb.AppendFormat(" - stat.StatFullId.GameId : {0}" + Environment.NewLine, stat.StatFullId.GameId);
sb.AppendFormat(" - stat.StatFullId.StatId : {0}" + Environment.NewLine, stat.StatFullId.StatId);
sb.AppendFormat(" - stat.MemberNo : {0}" + Environment.NewLine, stat.MemberNo.ToString());
sb.AppendFormat(" - stat.CurrentValue : {0}" + Environment.NewLine, stat.CurrentValue.ToString());
sb.AppendFormat(" - stat.UpdatedAt : {0}", stat.UpdatedAt.ToString());
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
11
12
13
주의사항) 콜백파라미터
StovePCStat
구조체의 유효한 범위는 콜백 스코프로 한정됩니다. PC SDK는 콜백 실행이 완료되는 즉시 내부에서 할당한 메모리를 해제합니다. 따라서 콜백 스코프 밖에서StovePCStat
구조체의 정보를 사용하기 위해 저장이 필요한 경우 반드시 깊은복사(Deep Copy)를 통해 사본을 생성하고, 사본에 대한 사용이 완료되면 메모리를 해제하여야 합니다.
StovePC.GetStat
메서드가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
2000 | Invalid Access |
3000 | Wrong API Usage |
4000 | Stats ID Not Found |
9000 | Service Error |
# 4) 사용자 단일 업적 정보 얻기
StovePC.GetAchievement
메서드로 로그인한 사용자의 해당 게임에 대한 특정 단일 업적 정보를 조회합니다.
// 입력 파라미터
// string achievementId : 스튜디오에서 생성한 업적 식별자
StovePCResult result = StovePC.GetAchievement("ACHIEVEMENT_ID");
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
StovePC.GetAchievement
메서드가 정상적으로 처리되면 OnAchievement
콜백이 호출됩니다.
콜백에 전달되는 StovePCAchievement
구조체에는 현재 업적값과 업적 달성 상태 및 업적의 메타정보가 포함되어 있습니다.
private void OnAchievement(StovePCAchievement achievement)
{
// 단일 업적 정보 출력
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnAchievement");
sb.AppendFormat(" - achievement.AchievementId : {0}" + Environment.NewLine, achievement.AchievementId);
sb.AppendFormat(" - achievement.Name : {0}" + Environment.NewLine, achievement.Name);
sb.AppendFormat(" - achievement.Description : {0}" + Environment.NewLine, achievement.Description);
sb.AppendFormat(" - achievement.DefaultImage : {0}" + Environment.NewLine, achievement.DefaultImage);
sb.AppendFormat(" - achievement.AchievedImage : {0}" + Environment.NewLine, achievement.AchievedImage);
sb.AppendFormat(" - achievement.Condition.GoalValue : {0}" + Environment.NewLine, achievement.Condition.GoalValue.ToString());
sb.AppendFormat(" - achievement.Condition.ValueOperation : {0}" + Environment.NewLine, achievement.Condition.ValueOperation);
sb.AppendFormat(" - achievement.Condition.Type : {0}" + Environment.NewLine, achievement.Condition.Type);
sb.AppendFormat(" - achievement.Value : {0}" + Environment.NewLine, achievement.Value.ToString());
sb.AppendFormat(" - achievement.Status : {0}", achievement.Status);
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
주의사항) 콜백파라미터
StovePCAchievement
구조체의 유효한 범위는 콜백 스코프로 한정됩니다. PC SDK는 콜백 실행이 완료되는 즉시 내부에서 할당한 메모리를 해제합니다. 따라서 콜백 스코프 밖에서StovePCAchievement
구조체의 정보를 사용하기 위해 저장이 필요한 경우 반드시 깊은복사(Deep Copy)를 통해 사본을 생성하고, 사본에 대한 사용이 완료되면 메모리를 해제하여야 합니다.
StovePC.GetAchievement
메서드가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
1200 | Not found achievement |
9000 | Service error |
# 5) 사용자 전체 업적 정보 얻기
StovePC.GetAllAchievement
메서드로 로그인한 사용자의 해당 게임에 대한 모든 업적 정보를 조회합니다.
StovePCResult result = StovePC.GetAllAchievement();
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.GetAllAchievement
메서드가 정상적으로 처리되면 OnAllAchievement
콜백이 호출됩니다.
콜백에 전달되는 StovePCAchievement
구조체에는 현재 업적값과 업적 달성 상태 및 업적의 메타정보가 포함되어 있습니다.
private void OnAchievement(StovePCAchievement[] achievements)
{
// 모든 업적 정보 출력
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnAllAchievement");
sb.AppendFormat(" - achievements.Length : {0}" + Environment.NewLine, achievements.Length);
for (int i = 0; i < achievements.Length; i++)
{
sb.AppendFormat(" - achievements[{0}].AchievementId : {1}" + Environment.NewLine, i, achievements[i].AchievementId);
sb.AppendFormat(" - achievements[{0}].Name : {1}" + Environment.NewLine, i, achievements[i].Name);
sb.AppendFormat(" - achievements[{0}].Description : {1}" + Environment.NewLine, i, achievements[i].Description);
sb.AppendFormat(" - achievements[{0}].DefaultImage : {1}" + Environment.NewLine, i, achievements[i].DefaultImage);
sb.AppendFormat(" - achievements[{0}].AchievedImage : {1}" + Environment.NewLine, i, achievements[i].AchievedImage);
sb.AppendFormat(" - achievements[{0}].Condition.GoalValue : {1}" + Environment.NewLine, i, achievements[i].Condition.GoalValue.ToString());
sb.AppendFormat(" - achievements[{0}].Condition.ValueOperation : {1}" + Environment.NewLine, i, achievements[i].Condition.ValueOperation);
sb.AppendFormat(" - achievements[{0}].Condition.Type : {1}" + Environment.NewLine, i, achievements[i].Condition.Type);
sb.AppendFormat(" - achievements[{0}].Value : {1}" + Environment.NewLine, i, achievements[i].Value.ToString());
sb.AppendFormat(" - achievements[{0}].Status : {1}", i, achievements[i].Status);
if (i < achievements.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
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
StovePC.GetAllAchievement
메서드가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
9000 | Service error |
# 6) 리더보드 랭킹 정보 얻기
StovePC.GetRank
메서드로 해당 게임에 대한 특정 리더보드의 순위 정보를 조회합니다.
// 입력 파라미터
// string leaderboardId : 스튜디오에서 생성한 리더보드 식별자
// uint pageIndex : 조회할 페이지 번호 (1 <= pageIndex)
// uint pageSize : 조회할 순위의 개수 (1 <= pageSize <= 50)
// bool includeMyRank : 조회결과에 로그인한 사용자의 순위를 포함할지 여부
StovePCResult result = StovePC.GetRank("LEADERBOARD_ID", PAGE_INDEX, PAGE_SIZE, INCLUDE_MY_RANK);
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
8
9
10
INCLUDE_MY_RANK:true
로 요청하면 응답 데이터 리스트의 첫번째 데이터에 로그인한 유저의 랭킹 정보를 반환하고 이후 페이지 랭킹 데이터를 반환합니다.
StovePC.GetRank
메서드가 정상적으로 처리되면 OnRank
콜백이 호출됩니다.
콜백에 전달되는 StovePCRank
구조체에는 특정 사용자에 대한 점수 및 순위 정보가 포함됩니다.
// 콜백 파라미터
// uint rankTotalCount : 조회한 리더보드에 집계된 전체 순위 개수
private void OnRank(StovePCRank[] ranks, uint rankTotalCount)
{
// 순위 정보 출력
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnRank");
sb.AppendFormat(" - ranks.Length : {0}" + Environment.NewLine, ranks.Length);
for (int i = 0; i < ranks.Length; i++)
{
sb.AppendFormat(" - ranks[{0}].MemberNo : {1}" + Environment.NewLine, i, ranks[i].MemberNo.ToString());
sb.AppendFormat(" - ranks[{0}].Score : {1}" + Environment.NewLine, i, ranks[i].Score.ToString());
sb.AppendFormat(" - ranks[{0}].Rank : {1}" + Environment.NewLine, i, ranks[i].Rank.ToString());
sb.AppendFormat(" - ranks[{0}].Nickname : {1}" + Environment.NewLine, i, ranks[i].Nickname);
sb.AppendFormat(" - ranks[{0}].ProfileImage : {1}" + Environment.NewLine, i, ranks[i].ProfileImage);
}
sb.AppendFormat(" - rankTotalCount : {0}", rankTotalCount);
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
StovePC.GetRank
메서드가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
1251 | Invalid Parameter |
1252 | CannotFindData |
3603 | ErrorLeaderBoardNotFound |
3631 | ErrorMembershipAPI |
500 | External Server Error |
# 팝업 연동하기
PC SDK는 팝업을 게임에 통합할 수 있도록 API를 제공합니다.
PC SDK가 지원하는 팝업으로는 자동, 수동, 뉴스, 쿠폰, 커뮤니티가 있습니다.
PC SDK는 팝업을 위한 데이터를 게임에 제공합니다. 게임은 제공받은 데이터를 이용해 팝업뷰를 생성합니다.
각각의 팝업은 아래와 같이 정의합니다.
- 자동 팝업 : 게임 로비화면에 가장 많이 노출하며 광고와 이벤트 등을 보여주는 팝업
- 수동 팝업 : 리소스키에 해당하는 등록된 이벤트를 보여주는 팝업
- 뉴스 팝업 : 공지성 게시글을 한 번에 모아서 보여주는 팝업
- 쿠폰 팝업 : 쿠폰 등록 페이지를 보여주는 팝업
- 커뮤니티 팝업 : 게임 커뮤니티 페이지를 보여주는 팝업
PC SDK 팝업 API를 사용하기 위해서는 파트너스를 통합 팝업의 메타데이터 등록이 선행되어야 합니다.
# 1) Callback 설정
팝업 API를 사용하여 PC SDK와 커뮤니케이션 하기 위하여, 게임에서는 아래 StovePCCallback
클래스의 콜백에 연결할 델리게이트 함수를 정의해야 합니다.
public class StovePCCallback
{
public StovePCErrorDelegate OnError;
public StovePCInitializationCompleteDelegate OnInitializationComplete;
public StovePCTokenDelegate OnToken;
public StovePCUserDelegate OnUser;
public StovePCOwnershipDelegate OnOwnership;
// GetAutopopup 처리가 완료됐을 때 호출되는 콜백
public StovePCAutoPopupDelegate OnAutoPopup;
// GetManualPopup 처리가 완료됐을 때 호출되는 콜백
public StovePCManualPopupDelegate OnManualPopup;
// GetNewsPopup 처리가 완료됐을 때 호출되는 콜백
public StovePCNewsPopupDelegate OnNewsPopup;
// GetCouponPopup 처리가 완료됐을 때 호출되는 콜백
public StovePCCouponPopupDelegate OnCouponPopup;
// GetCommunityPopup 처리가 완료됐을 때 호출되는 콜백
public StovePCcommunityPopupDelegate OnCommunityPopup;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
연동하기 2) Config, Callbak 설정
에서와 같이 StovePCCallback
클래스의 콜백에 델리게이드를 연결합니다.
// StovePCCallback 클래스 instance 생성
this.callback = new StovePCCallback
{
OnError = new StovePCErrorDelegate(this.OnError),
OnInitializationComplete = new StovePCInitializationCompleteDelegate(this.OnInitializationComplete),
OnToken = new StovePCTokenDelegate(this.OnToken),
OnUser = new StovePCUserDelegate(this.OnUser),
OnOwnership = new StovePCOwnershipDelegate(this.OnOwnership),
// 팝업
OnAutoPopup = new StovePCAutoPopupDelegate(this.OnAutoPopup),
OnManualPopup = new StovePCManualPopupDelegate(this.OnManualPopup),
OnNewsPopup = new StovePCNewsPopupDelegate(this.OnNewsPopup),
OnCouponPopup = new StovePCCouponPopupDelegate(this.OnCouponPopup),
OnCommunityPopup = new StovePCCommunityPopupDelegate(this.OnCommunityPopup)
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
OnAutoPopup
, OnManualPopup
, OnNewsPopup
, OnCouponPopup
, OnCommunityPopup
콜백을 반드시 구현할 필요는 없습니다.
게임에서 사용하는 팝업에 맞게 필요한 콜백 함수만 구현하여 연결하면 됩니다.
# 2) 게임프로필 설정
StovePC.SetGameProfile
함수로 게임의 월드와 캐릭터 정보를 설정합니다.
설정된 정보는 팝업에서 활용되므로 팝업을 사용하기 전에 반드시 설정되어야 합니다.
게임프로필의 유효성은 별도로 검사하고 있지 않습니다. 때문에 입력시 유효성 체크(null)를 진행하여 값을 정확히 입력해야 합니다.
입력한 게임프로필은 PCSDK 수명주기 동안만 유효합니다. 즉, PCSDK 를 초기화 할 때 마다 StovePC.SetGameProfile
함수를 호출하여
게임의 월드와 캐릭터 정보를 설정해야 합니다.
// 입력 파라미터
// string worldId: 게임의 월드 식별자
// long characterNo: 캐릭터 식별자
StovePCResult result = StovePC.SetGameProfile("WORLD_ID", CHARACTER_NO);
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
8
# 3) 자동팝업 정보 얻기
StovePC.GetAutoPopup
함수로 자동팝업에 대한 정보를 조회합니다.
StovePCResult result = StovePC.GetAutoPopup();
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.GetAutoPopup
함수가 정상적으로 처리되면 OnAutoPopup
콜백이 호출됩니다.
콜백에 전달되는 StovePCAutoPopup
구조체에는 자동팝업에 대한 URL이 포함되어 있습니다.
콜백에 전달되는 StovePCPopupRequestHeader
구조체에는 URL 요청시 셋팅할 헤더의 이름/값 쌍이 포함되어 있습니다.
private void OnAutoPopup(StovePCAutoPopup[] autoPopups, StovePCPopupRequestHeader[] headers)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnAutoPopup");
sb.AppendFormat(" - autoPopups.Length : {0}" + Environment.NewLine, autoPopups.Length);
for (int i = 0; i < autoPopups.Length; i++)
{
sb.AppendFormat(" - autoPopups[{0}].Origin : {1}" + Environment.NewLine, i, autoPopups[i].Origin);
sb.AppendFormat(" - autoPopups[{0}].Id : {1}" + Environment.NewLine, i, autoPopups[i].Id.ToString());
sb.AppendFormat(" - autoPopups[{0}].Url : {1}" + Environment.NewLine, i, autoPopups[i].Url);
// ADD 2.6.0 start
sb.AppendFormat(" - autoPopups[{0}].Control.UI.Visible.CloseButton : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.Visible.CloseButton.ToString());
sb.AppendFormat(" - autoPopups[{0}].Control.UI.Visible.NavigationBar : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.Visible.NavigationBar.ToString());
sb.AppendFormat(" - autoPopups[{0}].Control.UI.Visible.BackButton : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.Visible.BackButton.ToString());
sb.AppendFormat(" - autoPopups[{0}].Control.UI.Visible.ForwardButton : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.Visible.ForwardButton.ToString());
sb.AppendFormat(" - autoPopups[{0}].Control.UI.Visible.RefreshButton : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.Visible.RefreshButton.ToString());
sb.AppendFormat(" - autoPopups[{0}].Control.UI.Visible.HomeButton : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.Visible.HomeButton.ToString());
sb.AppendFormat(" - autoPopups[{0}].Control.UI.Visible.DisallowedButton : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.Visible.DisallowedButton.ToString());
sb.AppendFormat(" - autoPopups[{0}].Control.UI.DisallowedDay : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.DisallowedDay.ToString());
sb.AppendFormat(" - autoPopups[{0}].Control.UI.CloseButtonImage.Normal.FileUrl : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.CloseButtonImage.Normal.FileUrl);
sb.AppendFormat(" - autoPopups[{0}].Control.UI.CloseButtonImage.Normal.FileId : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.CloseButtonImage.Normal.FileId);
sb.AppendFormat(" - autoPopups[{0}].Control.UI.CloseButtonImage.Pressed.FileUrl : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.CloseButtonImage.Pressed.FileUrl);
sb.AppendFormat(" - autoPopups[{0}].Control.UI.CloseButtonImage.Pressed.FileId : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.CloseButtonImage.Pressed.FileId);
sb.AppendFormat(" - autoPopups[{0}].Control.UI.CloseButtonImage.Type : {1}" + Environment.NewLine, i, autoPopups[i].Control.UI.CloseButtonImage.Type.ToString());
// 2.6.0 End
}
sb.AppendFormat(" - headers.Length : {0}" + Environment.NewLine, headers.Length);
for (int i = 0; i < headers.Length; i++)
{
sb.AppendFormat(" - headers[{0}].Name : {1}" + Environment.NewLine, i, headers[i].Name);
sb.AppendFormat(" - headers[{0}].Value : {1}", i, headers[i].Value);
if (i < headers.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
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
42
43
44
주의사항
성공 콜백(OnAutoPopup)이 실행 되었다고 해도 autoPopups
콜백파라미터가 빈 배열인 경우가 있습니다.
autoPopups
콜백파라미터를 사용하기 전에 배열의 길이를 먼저 확인 후 팝업을 띄울지 말지를 결정해야 합니다.
이런 경우 파트너스의 자동팝업 설정을 확인합니다.
자동팝업의 노출 순서는 autoPopups
배열요소의 순서와 동일해야 합니다.
예를 들면 autoPopups
배열이 [A,B,C] 세개의 요소를 포함한다면 A, B, C 순서로 팝업을 노출해야 합니다.
StovePC.GetAutoPopup
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
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) 수동팝업 정보 얻기
StovePC.GetManualPopup
함수로 수동팝업에 대한 정보를 조회합니다.
// 입력 파라미터
// string resourceKey: 파트너스에서 등록한 수동팝업 식별자
StovePCResult result = StovePC.GetManualPopup("RESOURCE_KEY");
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
StovePC.GetManualPopup
함수가 정상적으로 처리되면 OnManualPopup
콜백이 호출됩니다.
콜백에 전달되는 StovePCManualPopup
구조체에는 수동팝업에 대한 URL이 포함되어 있습니다.
콜백에 전달되는 StovePCPopupRequestHeader
구조체에는 URL 요청시 셋팅할 헤더의 이름/값 쌍이 포함되어 있습니다.
private void OnManualPopup(StovePCManualPopup[] manualPopups, StovePCPopupRequestHeader[] headers)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnManualPopup");
for (int i = 0; i < manualPopups.Length; i++)
{
sb.AppendFormat(" - manualPopups[{0}].Origin : {1}" + Environment.NewLine, i, manualPopups[i].Origin);
sb.AppendFormat(" - manualPopups[{0}].ResourceKey : {1}" + Environment.NewLine, i, manualPopups[i].ResourceKey);
sb.AppendFormat(" - manualPopups[{0}].Id : {1}" + Environment.NewLine, i, manualPopups[i].Id.ToString());
sb.AppendFormat(" - manualPopups[{0}].Url : {1}" + Environment.NewLine, i, manualPopups[i].Url);
// ADD 2.6.0 Start
sb.AppendFormat(" - manualPopups[{0}].Control.UI.Visible.CloseButton : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.Visible.CloseButton.ToString());
sb.AppendFormat(" - manualPopups[{0}].Control.UI.Visible.NavigationBar : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.Visible.NavigationBar.ToString());
sb.AppendFormat(" - manualPopups[{0}].Control.UI.Visible.BackButton : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.Visible.BackButton.ToString());
sb.AppendFormat(" - manualPopups[{0}].Control.UI.Visible.ForwardButton : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.Visible.ForwardButton.ToString());
sb.AppendFormat(" - manualPopups[{0}].Control.UI.Visible.RefreshButton : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.Visible.RefreshButton.ToString());
sb.AppendFormat(" - manualPopups[{0}].Control.UI.Visible.HomeButton : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.Visible.HomeButton.ToString());
sb.AppendFormat(" - manualPopups[{0}].Control.UI.Visible.DisallowedButton : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.Visible.DisallowedButton.ToString());
sb.AppendFormat(" - manualPopups[{0}].Control.UI.DisallowedDay : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.DisallowedDay.ToString());
sb.AppendFormat(" - manualPopups[{0}].Control.UI.CloseButtonImage.Normal.FileUrl : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.CloseButtonImage.Normal.FileUrl);
sb.AppendFormat(" - manualPopups[{0}].Control.UI.CloseButtonImage.Normal.FileId : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.CloseButtonImage.Normal.FileId);
sb.AppendFormat(" - manualPopups[{0}].Control.UI.CloseButtonImage.Pressed.FileUrl : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.CloseButtonImage.Pressed.FileUrl);
sb.AppendFormat(" - manualPopups[{0}].Control.UI.CloseButtonImage.Pressed.FileId : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.CloseButtonImage.Pressed.FileId);
sb.AppendFormat(" - manualPopups[{0}].Control.UI.CloseButtonImage.Type : {1}" + Environment.NewLine, i, manualPopups[i].Control.UI.CloseButtonImage.Type.ToString());
// 2.6.0 End
}
sb.AppendFormat(" - headers.Length : {0}" + Environment.NewLine, headers.Length);
for (int i = 0; i < headers.Length; i++)
{
sb.AppendFormat(" - headers[{0}].Name : {1}" + Environment.NewLine, i, headers[i].Name);
sb.AppendFormat(" - headers[{0}].Value : {1}", i, headers[i].Value);
if (i < headers.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
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
42
43
44
주의사항
성공 콜백(OnManualPopup)이 실행 되었다고 해도 manualPopups
콜백파라미터가 빈 배열인 경우가 있습니다.
manualPopups
콜백파라미터를 사용하기 전에 배열의 길이를 먼저 확인 후 팝업을 띄울지 말지를 결정해야 합니다.
이런 경우 파트너스의 수동팝업 설정을 확인합니다.
수동팝업의 노출 순서는 manualPopups
배열요소의 순서와 동일해야 합니다.
예를 들면 manualPopups
배열이 [A,B,C] 세개의 요소를 포함한다면 A, B, C 순서로 팝업을 노출해야 합니다.
StovePC.GetManualPopup
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
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) 뉴스팝업 정보 얻기
StovePC.GetNewsPopup
함수로 뉴스팝업에 대한 정보를 조회합니다.
StovePCResult result = StovePC.GetNewsPopup();
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.GetNewsPopup
함수가 정상적으로 처리되면 OnNewsPopup
콜백이 호출됩니다.
콜백에 전달되는 StovePCNewsPopup
구조체에는 뉴스팝업에 대한 URL이 포함되어 있습니다.
콜백에 전달되는 StovePCPopupRequestHeader
구조체에는 URL 요청시 셋팅할 헤더의 이름/값 쌍이 포함되어 있습니다.
private void OnNewsPopup(StovePCNewsPopup newsPopup, StovePCPopupRequestHeader[] headers)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnNewsPopup");
sb.AppendFormat(" - newsPopup.Origin : {0}" + Environment.NewLine, newsPopup.Origin);
sb.AppendFormat(" - newsPopup.Id : {0}" + Environment.NewLine, newsPopup.Id.ToString());
sb.AppendFormat(" - newsPopup.Url : {0}" + Environment.NewLine, newsPopup.Url);
// ADD 2.6.0 Start
sb.AppendFormat(" - newsPopup.Control.UI.Visible.CloseButton : {0}" + Environment.NewLine, newsPopup.Control.UI.Visible.CloseButton.ToString());
sb.AppendFormat(" - newsPopup.Control.UI.Visible.NavigationBar : {0}" + Environment.NewLine, newsPopup.Control.UI.Visible.NavigationBar.ToString());
sb.AppendFormat(" - newsPopup.Control.UI.Visible.BackButton : {0}" + Environment.NewLine, newsPopup.Control.UI.Visible.BackButton.ToString());
sb.AppendFormat(" - newsPopup.Control.UI.Visible.ForwardButton : {0}" + Environment.NewLine, newsPopup.Control.UI.Visible.ForwardButton.ToString());
sb.AppendFormat(" - newsPopup.Control.UI.Visible.RefreshButton : {0}" + Environment.NewLine, newsPopup.Control.UI.Visible.RefreshButton.ToString());
sb.AppendFormat(" - newsPopup.Control.UI.Visible.HomeButton : {0}" + Environment.NewLine, newsPopup.Control.UI.Visible.HomeButton.ToString());
sb.AppendFormat(" - newsPopup.Control.UI.Visible.DisallowedButton : {0}" + Environment.NewLine, newsPopup.Control.UI.Visible.DisallowedButton.ToString());
sb.AppendFormat(" - newsPopup.Control.UI.DisallowedDay : {0}" + Environment.NewLine, newsPopup.Control.UI.DisallowedDay.ToString());
sb.AppendFormat(" - newsPopup.Control.UI.CloseButtonImage.Normal.FileUrl : {0}" + Environment.NewLine, newsPopup.Control.UI.CloseButtonImage.Normal.FileUrl);
sb.AppendFormat(" - newsPopup.Control.UI.CloseButtonImage.Normal.FileId : {0}" + Environment.NewLine, newsPopup.Control.UI.CloseButtonImage.Normal.FileId);
sb.AppendFormat(" - newsPopup.Control.UI.CloseButtonImage.Pressed.FileUrl : {0}" + Environment.NewLine, newsPopup.Control.UI.CloseButtonImage.Pressed.FileUrl);
sb.AppendFormat(" - newsPopup.Control.UI.CloseButtonImage.Pressed.FileId : {0}" + Environment.NewLine, newsPopup.Control.UI.CloseButtonImage.Pressed.FileId);
sb.AppendFormat(" - newsPopup.Control.UI.CloseButtonImage.Type : {0}" + Environment.NewLine, newsPopup.Control.UI.CloseButtonImage.Type.ToString());
// 2.6.0 End
sb.AppendFormat(" - headers.Length : {0}" + Environment.NewLine, headers.Length);
for (int i = 0; i < headers.Length; i++)
{
sb.AppendFormat(" - headers[{0}].Name : {1}" + Environment.NewLine, i, headers[i].Name);
sb.AppendFormat(" - headers[{0}].Value : {1}", i, headers[i].Value);
if (i < headers.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
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
주의사항
성공 콜백(OnNewsPopup)이 실행 되었다고 해도 newsPopup
콜백파라미터의 속성들이 기본값(빈 문자열 또는 0)인 경우가 있습니다.
newsPopup
콜백파라미터의 Url 속성을 먼저 확인 후 팝업을 띄울지 말지를 결정해야 합니다. 이런 경우 파트너스의 뉴스팝업 설정을 확인합니다.
StovePC.GetNewsPopup
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
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) 쿠폰팝업 정보 얻기
StovePC.GetCouponPopup
함수로 쿠폰팝업에 대한 정보를 조회합니다.
StovePCResult result = StovePC.GetCouponPopup();
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.GetCouponPopup
함수가 정상적으로 처리되면 OnCouponPopup
콜백이 호출됩니다.
콜백에 전달되는 StovePCCouponPopup
구조체에는 쿠폰팝업에 대한 URL이 포함되어 있습니다.
콜백에 전달되는 StovePCPopupRequestHeader
구조체에는 URL 요청시 셋팅할 헤더의 이름/값 쌍이 포함되어 있습니다.
private void OnCouponPopup(StovePCCouponPopup couponPopup, StovePCPopupRequestHeader[] headers)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnCouponPopup");
sb.AppendFormat(" - couponPopup.Url : {0}" + Environment.NewLine, couponPopup.Url);
// ADD 2.6.0 Start
sb.AppendFormat(" - couponPopup.Control.UI.Visible.CloseButton : {0}" + Environment.NewLine, couponPopup.Control.UI.Visible.CloseButton.ToString());
sb.AppendFormat(" - couponPopup.Control.UI.Visible.NavigationBar : {0}" + Environment.NewLine, couponPopup.Control.UI.Visible.NavigationBar.ToString());
sb.AppendFormat(" - couponPopup.Control.UI.Visible.BackButton : {0}" + Environment.NewLine, couponPopup.Control.UI.Visible.BackButton.ToString());
sb.AppendFormat(" - couponPopup.Control.UI.Visible.ForwardButton : {0}" + Environment.NewLine, couponPopup.Control.UI.Visible.ForwardButton.ToString());
sb.AppendFormat(" - couponPopup.Control.UI.Visible.RefreshButton : {0}" + Environment.NewLine, couponPopup.Control.UI.Visible.RefreshButton.ToString());
sb.AppendFormat(" - couponPopup.Control.UI.Visible.HomeButton : {0}" + Environment.NewLine, couponPopup.Control.UI.Visible.HomeButton.ToString());
sb.AppendFormat(" - couponPopup.Control.UI.Visible.DisallowedButton : {0}" + Environment.NewLine, couponPopup.Control.UI.Visible.DisallowedButton.ToString());
sb.AppendFormat(" - couponPopup.Control.UI.DisallowedDay : {0}" + Environment.NewLine, couponPopup.Control.UI.DisallowedDay.ToString());
sb.AppendFormat(" - couponPopup.Control.UI.CloseButtonImage.Normal.FileUrl : {0}" + Environment.NewLine, couponPopup.Control.UI.CloseButtonImage.Normal.FileUrl);
sb.AppendFormat(" - couponPopup.Control.UI.CloseButtonImage.Normal.FileId : {0}" + Environment.NewLine, couponPopup.Control.UI.CloseButtonImage.Normal.FileId);
sb.AppendFormat(" - couponPopup.Control.UI.CloseButtonImage.Pressed.FileUrl : {0}" + Environment.NewLine, couponPopup.Control.UI.CloseButtonImage.Pressed.FileUrl);
sb.AppendFormat(" - couponPopup.Control.UI.CloseButtonImage.Pressed.FileId : {0}" + Environment.NewLine, couponPopup.Control.UI.CloseButtonImage.Pressed.FileId);
sb.AppendFormat(" - couponPopup.Control.UI.CloseButtonImage.Type : {0}" + Environment.NewLine, couponPopup.Control.UI.CloseButtonImage.Type.ToString());
// 2.6.0 End
sb.AppendFormat(" - headers.Length : {0}" + Environment.NewLine, headers.Length);
for (int i = 0; i < headers.Length; i++)
{
sb.AppendFormat(" - headers[{0}].Name : {1}" + Environment.NewLine, i, headers[i].Name);
sb.AppendFormat(" - headers[{0}].Value : {1}", i, headers[i].Value);
if (i < headers.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
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
StovePC.GetCouponPopup
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
# 7) 커뮤니티팝업 정보 얻기
StovePC.GetCommunityPopup
함수로 커뮤니티팝업에 대한 정보를 조회합니다.
StovePCResult result = StovePC.GetCommunityPopup();
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.GetCommunityPopup
함수가 정상적으로 처리되면 OnCommunityPopup
콜백이 호출됩니다.
콜백에 전달되는 StovePCCommunityPopup
구조체에는 커뮤니티팝업에 대한 URL이 포함되어 있습니다.
콜백에 전달되는 StovePCPopupRequestCookie
구조체에는 URL 요청시 셋팅할 쿠키의 이름/값 쌍이 포함되어 있습니다.
private void OnCommunityPopup(StovePCCommunityPopup communityPopup, StovePCPopupRequestCookie[] cookies)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnCommunityPopup");
sb.AppendFormat(" - communityPopup.Url : {0}" + Environment.NewLine, communityPopup.Url);
// ADD 2.6.0 Start
sb.AppendFormat(" - communityPopup.Control.UI.Visible.CloseButton : {0}" + Environment.NewLine, communityPopup.Control.UI.Visible.CloseButton.ToString());
sb.AppendFormat(" - communityPopup.Control.UI.Visible.NavigationBar : {0}" + Environment.NewLine, communityPopup.Control.UI.Visible.NavigationBar.ToString());
sb.AppendFormat(" - communityPopup.Control.UI.Visible.BackButton : {0}" + Environment.NewLine, communityPopup.Control.UI.Visible.BackButton.ToString());
sb.AppendFormat(" - communityPopup.Control.UI.Visible.ForwardButton : {0}" + Environment.NewLine, communityPopup.Control.UI.Visible.ForwardButton.ToString());
sb.AppendFormat(" - communityPopup.Control.UI.Visible.RefreshButton : {0}" + Environment.NewLine, communityPopup.Control.UI.Visible.RefreshButton.ToString());
sb.AppendFormat(" - communityPopup.Control.UI.Visible.HomeButton : {0}" + Environment.NewLine, communityPopup.Control.UI.Visible.HomeButton.ToString());
sb.AppendFormat(" - communityPopup.Control.UI.Visible.DisallowedButton : {0}" + Environment.NewLine, communityPopup.Control.UI.Visible.DisallowedButton.ToString());
sb.AppendFormat(" - communityPopup.Control.UI.DisallowedDay : {0}" + Environment.NewLine, communityPopup.Control.UI.DisallowedDay.ToString());
sb.AppendFormat(" - communityPopup.Control.UI.CloseButtonImage.Normal.FileUrl : {0}" + Environment.NewLine, communityPopup.Control.UI.CloseButtonImage.Normal.FileUrl);
sb.AppendFormat(" - communityPopup.Control.UI.CloseButtonImage.Normal.FileId : {0}" + Environment.NewLine, communityPopup.Control.UI.CloseButtonImage.Normal.FileId);
sb.AppendFormat(" - communityPopup.Control.UI.CloseButtonImage.Pressed.FileUrl : {0}" + Environment.NewLine, communityPopup.Control.UI.CloseButtonImage.Pressed.FileUrl);
sb.AppendFormat(" - communityPopup.Control.UI.CloseButtonImage.Pressed.FileId : {0}" + Environment.NewLine, communityPopup.Control.UI.CloseButtonImage.Pressed.FileId);
sb.AppendFormat(" - communityPopup.Control.UI.CloseButtonImage.Type : {0}" + Environment.NewLine, communityPopup.Control.UI.CloseButtonImage.Type.ToString());
// 2.6.0 End
sb.AppendFormat(" - cookies.Length : {0}" + Environment.NewLine, cookies.Length);
for (int i = 0; i < cookies.Length; i++)
{
sb.AppendFormat(" - cookies[{0}].Name : {1}" + Environment.NewLine, i, cookies[i].Name);
sb.AppendFormat(" - cookies[{0}].Value : {1}", i, cookies[i].Value);
if (i < cookies.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
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
StovePC.GetCommunityPopup
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
13008 | Mandatory Parameter missing |
90001 | AccessToken invalid |
40101 | Invalid token |
# 8) 팝업 불허 설정 2.6.0
StovePC.SetPopupDisallowed
함수로 일정기간 동안 특정 팝업이 표시되지 않도록 설정합니다.
게임에서 PC SDK 팝업 UI 를 직접 구현하는 경우 팝업 UI 정보의 Control.UI.Visible.DisallowedButton
값을 참고하여 UI 를 구성하고
버튼 클릭 핸들러에서 StovePC.SetPopupDisallowed
함수를 호출합니다.
StovePC.SetPopupDisallowed
메서드를 호출시 days 파라미터는 팝업 정보의 Control.UI.DisallowedDay 값을 사용합니다.
팝업 불허가 설정되면 불허기간 동안 해당 팝업 정보는 조회되지 않습니다.
// 입력 파라미터
// int popupId : 파트너스에서 발급된 팝업 식별자
// int days : 파트너스에서 등록한 불허 기간(일단위) 또는 -1(다시 보지 않기)
// int days : 파트너스에서 등록한 불허 기간(일단위)
StovePCResult result = StovePC.SetPopupDisallowed(POPUP_ID, DAYS);
if (result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
8
9
# 빌링 연동하기 2.6.0
PC SDK는 스토브 플랫폼의 빌링서비스를 게임에 통합할 수 있도록 API를 제공합니다. 빌링서비스로는 상점이 있습니다.
상점에 대한 일반적인 시나리오는 아래와 같습니다. 이는 게임의 상황(e.g. 게임서버 유무)에 따라 조금씩 달라질 수 있습니다.
- 상점 구성을 위한 정보는 상점 카테고리 조회 및 상품 조회 API를 통해 획득합니다.
- 게임은 획득한 카테고리 및 상품 정보를 통해 상점을 구성하여 UI를 표시합니다.
- 각 상품에 대한 구매는 구매 시작 API를 호출합니다.
- 판매가격이 0 인 상품의 경우
- 구매 시작 API 응답을 받는 시점에 구매가 완료되어 있습니다.
- 판매가격이 0 보다 큰 상품의 경우
- 구매 시작 API의 응답에서 1회용 결제 URL을 획득합니다.
- 게임은 1회성 결제 URL을 외부브라우저로 탐색합니다. 지원브라우저 : Chrome(75이상), Edge(42이상)
- 이후 결제 진행은 웹페이지를 통해 완료됩니다.
- 판매가격이 0 인 상품의 경우
- 결제가 완료되면 게임은 구매 상태 확인 API를 호출하여 구매 상태를 확인합니다.
- 결제가 정상적으로 완료된 것으로 확인되면 게임은 상품을 지급합니다.
- 구매 검증 API를 통해 상품 구매 이력(1회 이상 구매 여부)을 확인 할 수 있습니다.
- 보관함 조회 API를 통해 아이템 복원등에 활용할 수 있습니다.
PC SDK 빌링서비스 API를 사용하기 위해서는 파트너스를 통한 빌링서비스의 메타데이터 등록이 선행되어야 합니다.
또한 PC SDK를 통해 상점을 이용하는 경우 StovePC.IAPInitialize
함수를 호출하여 파트너스로부터 발급 받는 ShopKey를 전달해야 합니다.
ShopKey 설정 없이 빌링서비스 API를 호출할 경우 에러가 반환됩니다.
게임은 상점 열기를 할 때마다 서비스 이용 약관 동의 여부를 체크하여야 합니다.
게임 이용자의 서비스 이용 약관 동의 여부가 미동의인 경우 PCSDK 가 제공하는 약관동의 페이지 Url을 이용하여 브라우저를 열어
게임 이용자가 서비스 이용 약관 동의를 할 수 있도록 합니다.
게임 이용자가 서비스 이용 약관을 동의 이후 상점 열기를 하면 상점으로 진입합니다.
PC SDK는 상점 지원을 위해 내부에 캐시를 운영합니다.
StovePC.FetchProducts
함수의 isRefresh 파라미터를 통해 상품 정보를 캐시에서 가져올지 Web API를 통해 가져올지 결정할 수 있습니다.
Web API를 통해 가져온 상품 정보는 캐시에 전체 또는 부분(카테고리별)적으로 업데이트 된 후 게임에 상품 정보를 콜백으로 전달합니다.
(다만, 캐시가 비어 있으면 isRefresh 파라미터 값과 관계없이 Web API를 통해 상품 정보를 조회하여 캐시에 업데이트 합니다.)
또한 PC SDK는 StovePC.ConfirmPurchase
함수 호출 시점에 Web API 응답을 통해 각 상품의 구매/판매수량 및 구매여부를 캐시에 업데이트 합니다.
# (예시)빌링 연동 흐름도
- 게임 시작 시 PC_SDK 초기화
StovePC.IAPInitialize
함수를 통하여 IAP를 초기화 합니다.- IAP 초기화 시 전체 아이템 리스트를 조회 후 내장 캐시에 저장합니다.
- 인게임 내 상점 페이지 진입 시 미지급 조회 처리(선택사항)
StovePC.FetchInventory
보관함 조회를 통하여 결재 완료 후 미지급된 아이템이 있는 경우 재지급 처리 합니다.
- 상점 진입 후 상점구성을 위해 카테고리 리스트를 조회 합니다.
StovePC.FetchShopCategories
함수를 통하여 상점내 카테고리를 조회 합니다.
- 3번에서 조회 된 상점 내 카테고리 정보를 통해 아이템 정보를 조회 합니다.
StovePC.FetchProducts
함수를 통하여 카테고리에 포함된 상품 정보를 조회 합니다.
- 상점에서 구매상품을 선택합니다.
- 구매 상품 정보는 배열로 직접 구성 하여야 합니다.(PruductId/SalePrice/Quantity)
- Quantity는 반드시 1로 지정 필요 합니다.
- 상품구매 시작을 위해 1회용 결제 URL 정보를 조회 합니다.
StovePC.StartPurchase
함수를 통해서 1회용 결재창 URL 정보를 조회 합니다.
- 인게임 내에서 상품결제안내 팝업을 처리합니다.(외부 브라우져 결재 결과 체크를 위해 반드시 처리해야 합니다.)
- 6번을 통해 얻은 1회용 결제 URL 정보로 외부 브라우져를 팝업합니다.
- Stove 빌링의 결제창을 통해 제품 결제를 진행합니다.
- 결제창에서 결재가 완료 된 후 브라우저를 종료 합니다.
- 인 게임내 7번에서 생성한 상품결제안내 팝업에서 "결재완료" 버튼을 클릭 시 구매상태 정보를 조회 합니다.
StovePC.ConfirmPurchase
함수를 통해서 결재 상태에 대한 정보를 조회 합니다.- 결재완료 상태 확인 후 팝업 종료 후 상점페이지로 돌아갑니다.
- 구매동선이 완료 됩니다.
참고
외부 브라우저를 통해 Stove 결재 미진행 및 StovePC.StartPurchase
를 통해서 결재 결과를 알수 없는 경우
상점 페이지 진입(2번) 시 StovePC.FetchInventory
보관함 조회를 통하여 아이템을 재지급 처리 합니다.
아래 시퀀스 다이어그램은 가상의 상점 운용 시나리오를 보여줍니다.
이는 일반적인 케이스에 대한 일례로써 게임의 상황(e.g. 상점 카테고리 구조, 상점 UI 생성 시점 etc)에 따라 다소 차이가 있을 수 있습니다.
- PCSDK IAP 초기화
- 서비스 이용 약관 동의 여부 체크
- 상점 열기
- 상품 구매
- 상품 구매 상태 확인
- 상품 구매 이력 검증
- 아이템 복원 처리
# 1) Callback 설정
빌링서비스 API를 사용하여 PC SDK와 커뮤니케이션 하기 위하여, 게임에서는 아래 StovePCCallback
클래스의 콜백에 연결할 델리게이트 함수를 정의해야 합니다.
public class StovePCCallback
{
public StovePCErrorDelegate OnError;
public StovePCInitializationCompleteDelegate OnInitializationComplete;
public StovePCTokenDelegate OnToken;
public StovePCUserDelegate OnUser;
public StovePCOwnershipDelegate OnOwnership;
// FetchShopCategories 처리가 완료됐을 때 호출되는 콜백
public StovePCFetchShopCategoriesDelegate OnFetchShopCategories;
// FetchProducts 처리가 완료됐을 때 호출되는 콜백
public StovePCFetchProductsDelegate OnFetchProducts;
// StartPurchase 처리가 완료됐을 때 호출되는 콜백
public StovePCStartPurchaseDelegate OnStartPurchase;
// ConfirmPurchase 처리가 완료됐을 때 호출되는 콜백
public StovePCConfirmPurchaseDelegate OnConfirmPurchase;
// FetchInventory 처리가 완료됐을 때 호출되는 콜백
public StovePCFetchInventoryDelegate OnFetchInventory;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
연동하기 2) Config, Callback 설정
에서와 같이 StovePCCallback
클래스의 콜백에 델리게이트를 연결합니다.
// StovePCCallback 클래스 instance 생성
this.callback = new StovePCCallback
{
OnError = new StovePCErrorDelegate(this.OnError),
OnInitializationComplete = new StovePCInitializationCompleteDelegate(this.OnInitializationComplete),
OnToken = new StovePCTokenDelegate(this.OnToken),
OnUser = new StovePCUserDelegate(this.OnUser),
OnOwnership = new StovePCOwnershipDelegate(this.OnOwnership),
// 서비스 이용 약관
OnFetchTermsAgreement = new StovePCFetchTermsAgreementDelegate(this.OnFetchTermsAgreement),
// 빌링서비스
OnFetchShopCategories = new StovePCFetchShopCategoriesDelegate(this.OnFetchShopCategories),
OnFetchProducts = new StovePCFetchProductsDelegate(this.OnFetchProducts),
OnStartPurchase = new StovePCStartPurchaseDelegate(this.OnStartPurchase),
OnConfirmPurchase = new StovePCConfirmPurchaseDelegate(this.OnConfirmPurchase),
OnFetchInventory = new StovePCFetchInventoryDelegate(this.OnFetchInventory)
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
OnFetchTermsAgreement
, OnFetchShopCategories
, OnFetchProducts
, OnStartPurchase
, OnConfirmPurchase
, OnFetchInventory
콜백을 반드시 구현할 필요는 없습니다.
게임에서 상점이 필요한 경우만 연결하면 됩니다.
단, 상점 기능을 위해서는 5개의 콜백을 모두 구현하여 연결하여야 합니다.
# 2) IAP 초기화
게임에서 PCSDK 를 사용해서 빌링서비스를 제공하기로 결정하였다면, 스토브에서 발급된 상점키 ShopKey
인자값으로 StovePC.IAPInitialize
함수로 빌링 초기화를 시도합니다.
빌링초기화 시도시 스토브 플랫폼에 등록된 상품리스트를 자동으로 조회한 후 스토브 PCSDK 내부 캐시에 저장을 합니다.
StovePC.IAPInitialize
함수를 호출하고 실패하였다면 StovePCResult
와 OnError
콜백으로 에러내용을 전달합니다.
// 입력 파라미터
// string shopKey : 스토브에서 발급받은 shopKey
StovePCResult result = StovePC.IAPInitialize(YOUR_SHOP_KEY);
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
ExternalError | 설명 |
---|---|
500 | Internal Server Error |
50001 | 상점이 존재하지 않거나, 점검 중 |
50002 | 상품이 존재 하지 않거나 판매 불가능 상품 |
999999 | 정의되지 않은 오류 |
# 3) 게임프로필 설정
StovePC.SetGameProfile
함수로 게임의 월드와 캐릭터 정보를 설정합니다.
이는 상품 구매 주체의 수준을 결정하기 위함입니다. PC SDK는 상품 구매 주체의 우선순위를 아래와 같이 매깁니다.
- Character No. > Guid > Member No.
StovePC.SetGameProfile
함수를 통해 캐릭터 정보가 설정되면 PC SDK는 상품 구매시 Character No.를 기준으로 구매를 진행합니다.
반면에 StovePC.SetGameProfile
함수를 통해 캐릭터 정보가 설정되지 않은 경우, PC SDK는 Guid 또는 Member No.를 기준으로 구매를 진행합니다.
따라서 상품 구매시 상품 구매 주체가 잘 적용되도록 하려면 PC SDK의 빌링서비스 API를 호출하기 전에 StovePC.SetGameProfile
API 호출 여부를 고려해야 합니다.
일반적으로 StovePC.SetGameProfile
함수는 월드/캐릭터 변경시마다 1회만 호출하면 됩니다.
# 4) 서비스 이용 약관 동의 여부 조회
StovePC.FetchTermsAgreement
메서드로 해당 게임에 대한 사용자의 서비스 이용 약관 동의 정보를 조회합니다.
StovePCResult result = StovePC.FetchTermsAgreement();
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.FetchTermsAgreement
메서드가 정상적으로 처리되면 OnFetchTermsAgreement
콜백이 호출됩니다.
콜백에 전달되는 StovePCTermsAgreement
구조체에는 약관 동의에 대한 메타정보가 포함되어 있습니다.
- StovePCShopCategory.GameId: 게임 아이디
- StovePCShopCategory.Result : 서비스 이용 약관 동의 여부
- StovePCShopCategory.Region: 권역 코드
- StovePCShopCategory.AgreementUrl : 서비스 약관 동의 동의 페이지 Url
private void OnFetchTermsAgreement(StovePCTermsAgreement termsAgreement)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnFetchTermsAgreement");
sb.AppendFormat(" - termsAgreement.GameId : {0}" + Environment.NewLine, termsAgreement.GameId);
sb.AppendFormat(" - termsAgreement.Result : {0}" + Environment.NewLine, termsAgreement.Result.ToString());
sb.AppendFormat(" - termsAgreement.Region : {0}", termsAgreement.Region);
sb.AppendFormat(" - termsAgreement.AgreementUrl : {0}", termsAgreement.AgreementUrl);
Debug.Log(sb.ToString());
if(termsAgreement.Result == false)
{
// 외부 브라우저 열기
Application.OpenURL(termsAgreement.AgreementUrl);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
StovePC.FetchTermsAgreement
메서드가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError 설명
400 잘못된 요청 정보
500 시스템 에러
70898 유효하지 않은 데이터
70899 파라미터에 유효하지 않은 값이 존재
70800 해당 조건으로 존재하는 약관 없음
70804 GS API 호출에러
70805 GUID API 호출 에러
70806 서비스를 찾을 수 없음
70807 GUID API 에서 정의되지 않은 오류 발생
40103 토큰 만료
# 5) 상점 카테고리 정보 얻기
StovePC.FetchShopCategories
함수로 해당 게임에 대한 상점 카테고리 정보를 조회합니다.
카테고리 정보에는 부모 카테고리에 대한 아이디를 포함하고 있어 계층적 구조로 상점을 구성할 수 있습니다.
StovePCResult result = StovePC.FetchShopCategories();
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.FetchShopCategories
함수가 정상적으로 처리되면 OnFetchShopCategories
콜백이 호출됩니다.
콜백에 전달되는 StovePCShopCategory
구조체에는 상점 카테고리에 대한 메타정보가 포함되어 있습니다.
- StovePCShopCategory.CategoryId : 카테고리 아이디
- StovePCShopCategory.ParentCategoryId : 부모 카테고리 아이디
- StovePCShopCategory.DisplayNo : 카테고리 순서
- StovePCShopCategory.Name : 카테고리명
- StovePCShopCategory.Depth : 카테고리 깊이 (최상위 카테고리의 경우 1)
private void OnFetchShopCategories(StovePCShopCategory[] categories)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnFetchShopCategories");
sb.AppendFormat(" - categories.Length : {0}" + Environment.NewLine, categories.Length);
for (int i = 0; i < categories.Length; i++)
{
sb.AppendFormat(" - categories[{0}].CategoryId : {1}" + Environment.NewLine, i, categories[i].CategoryId);
sb.AppendFormat(" - categories[{0}].ParentCategoryId : {1}" + Environment.NewLine, i, categories[i].ParentCategoryId);
sb.AppendFormat(" - categories[{0}].DisplayNo : {1}" + Environment.NewLine, i, categories[i].DisplayNo.ToString());
sb.AppendFormat(" - categories[{0}].Name : {1}" + Environment.NewLine, i, categories[i].Name);
sb.AppendFormat(" - categories[{0}].Depth : {1}", i, categories[i].Depth.ToString());
if (i < categories.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
StovePC.FetchShopProducts
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
500 | Internal Server Error |
999999 | 정의되지 않은 오류 |
# 6) 상품 정보 얻기
StovePC.FetchProducts
함수로 해당 게임에 대한 상품 정보를 조회합니다.
// 입력 파라미터
// string categoryId : 파트너스에서 등록한 카테고리 식별자(빈문자열 전달시 전체 카테고리 조회)
// bool isRefresh : true 인 경우 Web API 조회, false 인 경우 PC SDK 의 Cache 조회
StovePCResult result = StovePC.FetchProducts("CATEGORY_ID", IS_REFRESH);
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
8
StovePC.FetchProducts
함수가 정상적으로 처리되면 OnFetchProducts
콜백이 호출됩니다.
콜백에 전달되는 StovePCProduct
구조체에는 상품에 대한 메타정보가 포함되어 있습니다.
- StovePCProduct.ProductId : 상품 아이디
- StovePCProduct.GameItemId : 상품 아이디에 매핑되는 게임 내 아이템 아이디
- StovePCProduct.Name : 상품명
- StovePCProduct.Description : 상품 설명
- StovePCProduct.Quantity : 개별 상품 수량
- StovePCProduct.ProductTypeCode : 상품 유형 코드 (1: 패키지 게임 상품, 2: 인 게임 상품, 3: 패키지 아이템)
- StovePCProduct.CategoryId : 카테고리 아이디
- StovePCProduct.CurrencyCode : 통화 코드
- StovePCProduct.Price : 상품 정가 (표기시에는 CurrencyCode 가 "KRW" 와 같으면 소수점 이하 생략 표기, 다르면 소수점 둘째자리까지 표기)
- StovePCProduct.SalePrice : 상품 판매가 (표기시에는 CurrencyCode 가 "KRW" 와 같으면 소수점 이하 생략 표기, 다르면 소수점 둘째자리까지 표기)
- StovePCProduct.IsDiscount : 할인 여부
- StovePCProduct.DiscountType : 할인 유형(1: 정률, 2: 정액)
- StovePCProduct.DiscountTypeValue : 할인값
- StovePCProduct.DiscountBeginDate : 할인 시작 일자(UTC+0)
- StovePCProduct.DiscountEndDate : 할인 종료 일자(UTC+0)
- StovePCProduct.TotalQuantity : 상품 총 판매 수량
- StovePCProduct.MemberQuantity : 회원 구매 수량
- StovePCProduct.GuidQuantity : Guid 구매 수량(상품 구매 주체[CharacterNo/Guid/MemberNo]의 구매 수량)
- StovePCProduct.ThumbnailUrl : 대표 상품 이미지
private void OnFetchProducts(StovePCProduct[] products)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnFetchProducts");
sb.AppendFormat(" - products.Length : {0}" + Environment.NewLine, products.Length);
for (int i = 0; i < products.Length; i++)
{
sb.AppendFormat(" - products[{0}].ProductId : {1}" + Environment.NewLine, i, products[i].ProductId.ToString());
sb.AppendFormat(" - products[{0}].GameItemId : {1}" + Environment.NewLine, i, products[i].GameItemId);
sb.AppendFormat(" - products[{0}].Name : {1}" + Environment.NewLine, i, products[i].Name);
sb.AppendFormat(" - products[{0}].Discription : {1}" + Environment.NewLine, i, products[i].Discription);
sb.AppendFormat(" - products[{0}].Quantity : {1}" + Environment.NewLine, i, products[i].Quantity.ToString());
sb.AppendFormat(" - products[{0}].ProductTypeCode : {1}" + Environment.NewLine, i, products[i].ProductTypeCode.ToString());
sb.AppendFormat(" - products[{0}].CategoryId : {1}" + Environment.NewLine, i, products[i].CategoryId);
sb.AppendFormat(" - products[{0}].CurrencyCode : {1}" + Environment.NewLine, i, products[i].CurrencyCode);
sb.AppendFormat(" - products[{0}].Price : {1}" + Environment.NewLine, i, products[i].CurrencyCode == "KRW" ? products[i].Price.ToString("F0") : products[i].Price.ToString("F2"));
sb.AppendFormat(" - products[{0}].SalePrice : {1}" + Environment.NewLine, i, products[i].CurrencyCode == "KRW" ? products[i].SalePrice.ToString("F0") : products[i].SalePrice.ToString("F2"));
sb.AppendFormat(" - products[{0}].IsDiscount : {1}" + Environment.NewLine, i, products[i].IsDiscount.ToString());
sb.AppendFormat(" - products[{0}].DiscountType : {1}" + Environment.NewLine, i, products[i].DiscountType.ToString());
sb.AppendFormat(" - products[{0}].DiscountTypeValue : {1}" + Environment.NewLine, i, products[i].DiscountTypeValue.ToString());
sb.AppendFormat(" - products[{0}].DiscountBeginDate : {1}" + Environment.NewLine, i, products[i].DiscountBeginDate.ToString());
sb.AppendFormat(" - products[{0}].DiscountEndDate : {1}" + Environment.NewLine, i, products[i].DiscountEndDate.ToString());
sb.AppendFormat(" - products[{0}].TotalQuantity : {1}" + Environment.NewLine, i, products[i].TotalQuantity.ToString());
sb.AppendFormat(" - products[{0}].MemberQuantity : {1}" + Environment.NewLine, i, products[i].MemberQuantity.ToString());
sb.AppendFormat(" - products[{0}].GuidQuantity : {1}" + Environment.NewLine, i, products[i].GuidQuantity.ToString());
sb.AppendFormat(" - products[{0}].ThumbnailUrl : {1}", i, products[i].ThumbnailUrl);
if (i < products.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
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
StovePC.FetchProducts
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
500 | Internal Server Error |
50001 | 상점이 존재하지 않거나, 점검 중 |
50002 | 상품이 존재 하지 않거나 판매 불가능 상품 |
999999 | 정의되지 않은 오류 |
# 7) 상품 구매 시작
StovePC.StartPurchase
함수로 상품 구매를 시작합니다.
// 입력 파라미터
// StovePCOrderProduct[] products : 주문 상품 정보
StovePCResult result = StovePC.StartPurchase(products);
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
StovePC.StartPurchase
함수가 정상적으로 처리되면 OnStartPurchase
콜백이 호출됩니다.
콜백에 전달되는 StovePCPurchase
구조체에는 상품 구매에 대한 메타정보가 포함되어 있습니다.
- StovePCPurchase.TransactionMasterNo : 거래 고유 마스터 번호
- StovePCPurchase.TempPaymentUrl : 1회용 결제 URL
- StovePCPurchase.PurchaseProgress : 구매 진행 상태
- 1 : 결제중 (TempPaymentUrl 을 이용하여 외부브라우저 표시 필요)
- 2 : 구매 완료 (판매가격이 0 인 상품의 구매 진행으로 결제가 완료 상태로써 TempPaymentUrl 을 이용하여 외부브라우저 페이지 표시 불필요)
필요시 게임은 외부브라우저를 통해 1회용 결제 URL을 탐색합니다. 지원브라우저 : Chrome(75이상), Edge(42이상)
private void OnStartPurchase(StovePCPurchase purchase)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnStartPurchase");
sb.AppendFormat(" - purchase.TransactionMasterNo : {0}" + Environment.NewLine, purchase.TransactionMasterNo.ToString());
sb.AppendFormat(" - purchase.TempPaymentUrl : {0}" + Environment.NewLine, purchase.TempPaymentUrl);
sb.AppendFormat(" - purchase.PurchaseProgress : {0}", purchase.PurchaseProgress);
Debug.Log(sb.ToString());
if(purchase.PurchaseProgress == 1)
{
// 외부 브라우저 열기
Application.OpenURL(purchase.TempPaymentUrl);
}
else if(purchase.PurchaseProgress == 2)
{
// 구매 완료 처리(e.g. 구매 완료 메세지 박스)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
StovePC.StartPurchase
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
일반적으로 StovePC.StartPurchase
함수 호출에 대해 OnError
콜백이 호출되면 게임은 실패에 대한 메세지를 게임 사용자에게 노출합니다.
아래 표는 게임 사용자에게 표시 할 메세지에 대한 가이드를 함께 제시합니다.
ExternalError | 설명 | 게임 사용자 대상 노출 메시지 확인 |
---|---|---|
500 | Internal Server Error | 일시적인 현상이거나 네트워크 원인으로 서비스가 원활하지 않습니다. |
50001 | 상점이 존재하지 않거나, 점검 중 | 서비스 점검 중이거나, 존재하지 않는 서비스 입니다. |
50002 | 상품이 존재 하지 않거나 판매 불가능 상품 | 상품 상태로 인하여 구매하실 수 없는 상품입니다. |
50003 | 비 전시 상품 | 현재 판매하고 있지 않은 상품입니다. |
50004 | 판매 기간이 아닌 상품 | 상품 판매 기간이 아닙니다. |
50005 | 상품 가격이 불일치(상품 가격이 변경 되었을 경우) | 상품 가격 정보가 변경되었습니다. |
50009 | 구매 가능 한 회원 별 판매 개수를 초과 | 1인 당 구매 가능 개수를 초과 하였습니다. |
50010 | 구매 가능 한 총 판매 개수를 초과 | 준비 된 수량이 모두 판매 완료 되었습니다. |
50031 | 구매 수량이 '0' | 구매하실 수량을 1개 이상 입력해 주세요. |
999999 | 정의되지 않은 오류 | 기타 오류로 서비스가 원활하지 않습니다. |
# 8) 상품 구매 상태 확인
StovePC.ConfirmPurchase
함수로 상품 구매 상태를 확인합니다.
// 입력 파라미터
// Int64 transactionMasterNo : 거래 고유 마스터 번호(OnStartPurchase 콜백 파라미터 StovePCPurchase.TransactionMasterNo를 통해 취득)
StovePCResult result = StovePC.ConfirmPurchase(TRANSACTION_MASTER_NO);
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
'StovePC.ConfirmPurchase' 함수가 정상적으로 처리되면 OnConfirmPurchase
콜백이 호출됩니다.
콜백에 전달되는 StovePCPurchaseProduct
구조체에는 구매된 상품에 대한 메타정보가 포함되어 있고, status 콜백 파라미터는 상품 구매 상태를 전달합니다.
- StovePCPurchaseProduct.TotalQuantity : 상품 총 판매 수량
- StovePCPurchaseProduct.MemberQuantity : 회원 구매 수량
- StovePCPurchaseProduct.GuidQuantity : Guid 구매 수량(상품 구매 주체[CharacterNo/Guid/MemberNo]의 구매 수량)
별도의 게임서버가 없는 게임의 경우 구매 결과가 성공이라면 게임은 아이템을 지급할 수도 있습니다.
게임서버가 있는 게임의 경우 게임서버가 구매에 대한 알림을 받을 수 있고 이때 아이템을 지급할 수도 있습니다.
private void OnConfirmPurchase(StovePCPurchaseProduct[] products, bool status, string shopKey)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnConfirmPurchase");
sb.AppendFormat(" - products.Length : {0}" + Environment.NewLine, products.Length);
for (int i = 0; i < products.Length; i++)
{
sb.AppendFormat(" - products[{0}].ProductId : {1}" + Environment.NewLine, i, products[i].ProductId.ToString());
sb.AppendFormat(" - products[{0}].CategoryId : {1}" + Environment.NewLine, i, products[i].CategoryId);
sb.AppendFormat(" - products[{0}].TotalQuantity : {1}" + Environment.NewLine, i, products[i].TotalQuantity.ToString());
sb.AppendFormat(" - products[{0}].MemberQuantity : {1}" + Environment.NewLine, i, products[i].MemberQuantity.ToString());
sb.AppendFormat(" - products[{0}].GuidQuantity : {1}" + Environment.NewLine, i, products[i].GuidQuantity.ToString());
}
sb.AppendFormat(" - status : {0}" + Environment.NewLine, status.ToString());
sb.AppendFormat(" - shopKey : {0}", shopKey);
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
참고
위 샘플코드에서 함수에서 string shopKey
는StovePC_IAPInit
함수로 호출하는 YOUR_SHOP_KEY
와 동일한 값입니다.
shopKey
를 입력 파라메터로 YOUR_SHOP_KEY
를 보내야 합니다.
StovePC.ConfirmPurchase
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
500 | Internal Server Error |
999999 | 정의되지 않은 오류 |
# 9) 상품 구매 이력 검증
StovePC.VerifyPurchase
함수로 상품 구매 이력를 검증합니다. 1회 이상 구매 이력이 있는 상품의 경우 IsPurchased 필드 값은 true 입니다.
상품 구매 이력 검증은 PC SDK 내의 캐시를 대상으로 수행됩니다.
이때 categoryId 파라미터의 값을 명시적으로 입력하면 해당 카테고리만을 대상으로 검색하고 categoryId 파라미터의 값에 빈문자열("")을 입력하면 전체 카테고리를 대상으로 검색을 진행합니다.
따라서 검색할 카테고리 아이디를 정확히 입력하는 편이 검색 속도면에서 유리할 수 있습니다.
// 입력 파라미터
// string categoryId : 상품을 검색할 카테고리 아이디
// long productId : 상품 아이디
StovePCPurchaseVerification purchaseVerification = StovePC.VerifyPurchase("CATEGORY_ID", PRODUCT_ID);
if (purchaseVerification.Result == StovePCResult.NoError)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("VerifyPurchase Success");
sb.AppendFormat(" - purchaseVerification.IsPurchased : {0}", purchaseVerification.IsPurchased);
Debug.Log(sb.ToString());
}
else
{
// 실패 처리
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
StovePC.VerifyPurchase
함수는 StovePCPurchaseVerification
구조체를 리턴합니다.
리턴되는 StovePCPurchaseVerification
구조체에는 상품 구매 이력 여부가 포함되어 있습니다.
또한, 함수 호출에 대한 에러코드도 포함되어 있습니다.
# 10) 보관함 조회
StovePC.FetchInventory
함수로 보관함을 조회합니다. 보관함에는 구매가 완료된 상품들이 보관되어 있습니다.
보관함의 구매 완료 상품 리스트를 이용하여 상품 지급 처리를 할 수 있습니다.
보통 게임은 StovePC.ConfirmPurchase
함수를 호출하여 상품 구매 상태를 확인 후 즉시 상품을 지급하지만
오류, 게임 재설치 등의 사유로 지급된 상품 정보가 소실 되었을 경우 보관함 정보를 이용하여 복구 작업에 활용이 가능합니다.
StovePCResult result = StovePC.FetchInventory();
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
StovePC.FetchInventory
함수가 정상적으로 처리되면 OnFetchInventory
콜백이 호출됩니다.
콜백에 전달되는 StovePCInventoryItem
구조체에는 구매된 상품에 대한 메타정보가 포함되어 있습니다.
- StovePCInventoryItem.TransactionMasterNo : 거래 고유 마스터 번호
- StovePCInventoryItem.TransactionDetailNo : 거래 고유 상세 번호
- StovePCInventoryItem.ProductId : 상품 아이디
- StovePCInventoryItem.GameItemId : 상품 아이디에 매핑되는 게임 내 아이템 아이디
- StovePCInventoryItem.ProductName : 상품명
- StovePCInventoryItem.Quantity : 개별 상품 수량
- StovePCInventoryItem.ThumbnailUrl : 대표 상품 이미지
private void OnFetchInventory(StovePCInventoryItem[] inventoryItems)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnFetchInventory");
sb.AppendFormat(" - inventoryItems.Length : {0}" + Environment.NewLine, inventoryItems.Length);
for (int i = 0; i < inventoryItems.Length; i++)
{
sb.AppendFormat(" - inventoryItems[{0}].TransactionMasterNo : {1}" + Environment.NewLine, i, inventoryItems[i].TransactionMasterNo.ToString());
sb.AppendFormat(" - inventoryItems[{0}].TransactionDetailNo : {1}" + Environment.NewLine, i, inventoryItems[i].TransactionDetailNo.ToString());
sb.AppendFormat(" - inventoryItems[{0}].ProductId : {1}" + Environment.NewLine, i, inventoryItems[i].ProductId.ToString());
sb.AppendFormat(" - inventoryItems[{0}].GameItemId : {1}" + Environment.NewLine, i, inventoryItems[i].GameItemId);
sb.AppendFormat(" - inventoryItems[{0}].ProductName : {1}" + Environment.NewLine, i, inventoryItems[i].ProductName);
sb.AppendFormat(" - inventoryItems[{0}].Quantity : {1}" + Environment.NewLine, i, inventoryItems[i].Quantity.ToString());
sb.AppendFormat(" - inventoryItems[{0}].ThumbnailUrl : {1}", i, inventoryItems[i].ThumbnailUrl);
if (i < inventoryItems.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
StovePC.FetchInventory
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
StovePCError
구조체의 ExternalError 필드를 통해 외부 오류를 확인할 수 있습니다.
ExternalError | 설명 |
---|---|
500 | Internal Server Error |
999999 | 정의되지 않은 오류 |
# 부가서비스 연동하기
PC SDK는 부가서비스를 게임에 통합할 수 있도록 API를 제공합니다.
PC SDK가 지원하는 부가서비스로는 사용자정의 이벤트 로그, PC SDK 버전 조회, 과몰입방지 알림, 셧다운 알림, 추적 단서 조회가 있습니다.
게임은 게임내 사용자정의 이벤트(게임 로그)를 스토브 플랫폼으로 전송할 수 있습니다. 또한 게임은 현재 사용중인 PC SDK의 유의적 버전을 조회할 수 있습니다.
PC SDK의 유의적 버전 조회는 콜백이 아닌 리턴값으로 획득이 가능합니다.
과몰입방지 알림은 매시간 게임 과몰입에 대한 경고 문구를 콜백을 통해 전달합니다.
셧다운 알림은 만 18세 미만의 청소년이 부모에 의해 요일별 특정시간에 게임을 이용 할 수 없도록 제한을 하는 시스템으로써 요건이 충족되면 최대 4회에 걸쳐 알림을 콜백을 통해 전달합니다.
# 1) Callback 설정
부가서비스 API를 사용하여 PC SDK와 커뮤니케이션 하기 위하여, 게임에서는 아래 StovePCCallback
구조체의 콜백 포인터에 연결할 델리게이트 함수를 정의해야 합니다.
public class StovePCCallback
{
public StovePCErrorDelegate OnError;
public StovePCInitializationCompleteDelegate OnInitializationComplete;
public StovePCTokenDelegate OnToken;
public StovePCUserDelegate OnUser;
public StovePCOwnershipDelegate OnOwnership;
// FetchTermsAgreement 처리가 완료됐을 때 호출되는 콜백
public StovePCFetchTermsAgreementDelegate OnFetchTermsAgreement;
public StovePCStatDelegate OnStat;
public StovePCSetStatDelegate OnSetStat;
public StovePCAchievementDelegate OnAchievement;
public StovePCAllAchievementDelegate OnAllAchievement;
public StovePCRankDelegate OnRank;
// StashCustomEvent 처리가 완료됐을 때 호출되는 콜백
public StovePCStashCustomEventDelegate OnStashCustomEvent;
// ADD 2.6.0 Start
// 과몰입방지를 위해 매시간 호출되는 콜백
public StovePCOverImmersionDelegate OnOverImmersion;
// 셧다운 제한시 호출되는 콜백
public StovePCShutdownDelegate OnShutdown;
// 2.6.0 End
}
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
연동하기 2) Config, Callback 설정
에서와 같이 StovePCCallback
클래스의 콜백에 델리게이트를 연결합니다.
// StovePCCallback 클래스 instance 생성
this.callback = new StovePCCallback
{
OnError = new StovePCErrorDelegate(this.OnError),
OnInitializationComplete = new StovePCInitializationCompleteDelegate(this.OnInitializationComplete),
OnToken = new StovePCTokenDelegate(this.OnToken),
OnUser = new StovePCUserDelegate(this.OnUser),
OnOwnership = new StovePCOwnershipDelegate(this.OnOwnership),
// 게임지원서비스
OnStat = new StovePCStatDelegate(this.OnStat),
OnSetStat = new StovePCSetStatDelegate(this.OnSetStat),
OnAchievement = new StovePCAchievementDelegate(this.OnAchievement),
OnAllAchievement = new StovePCAllAchievementDelegate(this.OnAllAchievement),
OnRank = new StovePCRankDelegate(this.OnRank),
//부가서비스
OnStashCustomEvent = new StovePCStashCustomEventDelegate(this.OnStashCustomEvent)
// ADD 2.6.0 Start
OnOverImmersion = new StovePCOverImmersionDelegate(this.OnOverImmersion);
OnShutdown = new StovePCShutdownDelegate(this.OnShutdown);
// 2.6.0 End
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
OnStashCustomEvent
콜백을 반드시 구현할 필요는 없습니다. 게임에서 사용자정의 이벤트 로그 기능을 사용할 경우만 연결하면 됩니다.
경고
OnOverImmersion
콜백은 법률에 의거 게임과몰입/중독 예방조치가 필요한 경우 반드시 구현하여야 합니다.
OnShutdown
콜백은 법률에 의거 선택적 셧다운이 필요한 경우 반드시 구현하여야 합니다.
# 2) 사용자정의 이벤트 로깅
StovePC.StashCustomEvent
함수로 사용자정의 이벤트(게임 로그)를 로깅합니다.
// 입력 파라미터
// string name: 이벤트명
// string category1 : 1차 카테고리명
// string category2 : 2차 카테고리명
// float simpleValue : 간단한 값
// StovePCCustomEventParameter[] parameters : 세부적인 파라미터 정보
StovePCResult result = StovePC.StashCusomEvent("EVENT_NAME", "CATEGORY1", "CATEGORY2", 1.0f, parameters);
if(result == StovePCResult.NoError)
{
// 성공 처리
}
2
3
4
5
6
7
8
9
10
11
StovePC.StashCustomEvent
함수가 정상적으로 처리되면 OnStashCustomEvent
콜백이 호출됩니다.
콜백에 전달되는 StovePCCustomEvent
구조체에는 API 호출시 전달한 이벤트명, 1차 카테고리명, 2차 카테고리명, 간단한 값이 포함되어 있습니다.
콜백에 전달되는 StovePCCustomEventParameter
구조체에는 API 호출시 전달한 파라미터 정보가 포함되어 있습니다.
void OnStashCustomEvent(StovePCCustomEvent customEvent, StovePCCustomEventParameter[] parameters)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnStashCustomEvent");
sb.AppendFormat(" - customEvent.Name : {0}" + Environment.NewLine, customEvent.Name);
sb.AppendFormat(" - customEvent.Category1 : {0}" + Environment.NewLine, customEvent.Category1);
sb.AppendFormat(" - customEvent.Category2 : {0}" + Environment.NewLine, customEvent.Category2);
sb.AppendFormat(" - customEvent.SimpleValue : {0}" + Environment.NewLine, customEvent.SimpleValue.ToString());
sb.AppendFormat(" - parameters.Length : {0}" + Environment.NewLine, parameters.Length);
for (int i = 0; i < parameters.Length; i++)
{
sb.AppendFormat(" - parameters[{0}].Name : {1}" + Environment.NewLine, i, parameters[i].Name);
sb.AppendFormat(" - parameters[{0}].Value : {1}", i, parameters[i].Value);
if (i < parameters.Length - 1)
sb.AppendFormat(Environment.NewLine);
}
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
StovePC_StashCustomEvent
함수가 실행중에 오류가 발생하면 OnError
콜백이 호출됩니다.
# 3) PC SDK 유의적 버전 얻기
StovePC.GetSDKVersion
함수로 현재 연동중인 PC SDK의 버전 정보를 조회합니다.
string version = StovePC.GetSDKVersion();
if(version != "")
{
// 성공 처리
}
2
3
4
5
# 4) 게임 과몰입방지 2.6.0
게임을 시작한 후 매시간마다 OnOverImmersion
콜백이 호출됩니다.
콜백에 전달되는 StovePCOverImmersion
구조체에는 메세지, 게임이용 경과시간, 메세지 최소 노출시간(초)이 포함되어 있습니다.
- StovePCOverImmersion.Message : 과몰입 메세지
- StovePCOverImmersion.ElapsedTimeInHours : 경과 시간
- StovePCOverImmersion.MinExposureTimeInSeconds : 메세지 최소 노출 시간(초단위)
메세지는 PC SDK에 설정된 언어를 기반으로 번역된 메세지가 전달 됩니다.
private void OnOverImmersion(StovePCOverImmersion overImmersion)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnOverImmersion");
sb.AppendFormat(" - overImmersion.Message : {0}" + Environment.NewLine, overImmersion.Message);
sb.AppendFormat(" - overImmersion.ElapsedTimeInHours : {0}" + Environment.NewLine, overImmersion.ElapsedTimeInHours.ToString());
sb.AppendFormat(" - overImmersion.MinExposureTimeInSeconds : {0}", overImmersion.MinExposureTimeInSeconds.ToString());
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
과몰입 메시지 안내
과몰입 메시지 : 게임을 플레이한 지 1 시간이 지났습니다. 과도한 게임이용은 정상적인 일상생활에 지장을 줄 수 있습니다.
# 5) 셧다운 2.6.0
게임을 시작한 후 선택적 셧다운 대상자에 한해 셧다운 시스템에 등록된 타임테이블에 의거하여 OnShutdown
콜백이 호출됩니다.
OnShutdown
콜백은 최대 4회 호출 될 수 있으며 호출되는 시점 및 게임에서 조치해야 하는 사항은 아래와 같습니다.
- PCSDK 초기화 성공 후 셧다운 이벤트
- 10분전 셧다운 알림 : 10분뒤 로그아웃 된다는 알림만 표시
- 5분전 셧다운 알림 : 5분뒤 로그아웃 된다는 알림만 표시
- 1분전 셧다운 알림 : 1분뒤 로그아웃 된다는 알림만 표시
- 셧다운 알림 : 로그아웃 된다는 알림을 표시하고 사용자 확인시 즉시 게임 종료
콜백에 전달되는 StovePCShutdown
구조체에는 셧다운까지 남은 시간, 메세지, 메세지 노출시간(초)이 포함되어 있습니다.
- StovePCShutdown.InadvanceTimeInMinutes : 사용자의 셧다운까지 남은 시간(분)으로써 0 인 경우 즉시 게임 종료
- StovePCShutdown.Message : 셧다운 알림 메세지
- StovePCShutdown.ExposureTimeInSeconds : 메세지 노출 시간(초)
private void OnShutdown(StovePCShutdown shutdown)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("OnShutdown");
sb.AppendFormat(" - shutdown.InadvanceTimeInMinutes : {0}" + Environment.NewLine, shutdown.InadvanceTimeInMinutes.ToString());
sb.AppendFormat(" - shutdown.Message : {0}" + Environment.NewLine, shutdown.Message);
sb.AppendFormat(" - shutdown.ExposureTimeInSeconds : {0}", shutdown.ExposureTimeInSeconds.ToString());
Debug.Log(sb.ToString());
}
2
3
4
5
6
7
8
9
10
셧다운 메시지 안내
10분 : 회원님은 게임 시간 선택제 적용 대상으로 10 분 후 게임 이용이 제한됩니다.
5분 : 회원님은 게임 시간 선택제 적용 대상으로 5 분 후 게임 이용이 제한됩니다.
1분 : 회원님은 게임 시간 선택제 적용 대상으로 1 분 후 게임 이용이 제한됩니다.
0분 : 회원님은 게임 시간 선택제 적용 대상으로 게임 이용이 제한되어 게임을 종료합니다.
# 6) 추적 단서 조회 2.6.0
StovePC.GetTraceHint
함수로 스토브 플랫폼 로그를 추적 하기 위한 일련의 단서를 조회합니다.
StovePCTraceHint traceHint = StovePC.GetTraceHint();
if (traceHint.Result == StovePCResult.NoError)
{
sb.AppendLine("GetTraceHint Success");
sb.AppendFormat(" - traceHint.SessionId : {0}" + Environment.NewLine, traceHint.SessionId);
sb.AppendFormat(" - traceHint.RefSessionId : {0}" + Environment.NewLine, traceHint.RefSessionId);
sb.AppendFormat(" - traceHint.Uuid : {0}" + Environment.NewLine, traceHint.Uuid);
sb.AppendFormat(" - traceHint.ServiceProtocol : {0}" + Environment.NewLine, traceHint.ServiceProtocol);
sb.AppendFormat(" - traceHint.RefSourceType : {0}", traceHint.RefSourceType);
Debug.Log(sb.ToString());
}
else
{
// 실패 처리
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
StovePC.GetTraceHint
함수는 StovePCTraceHint
구조체를 리턴합니다.
리턴되는 StovePCTraceHint
구조체에는 세션 아이디 및 레퍼런스 세션 아이디 등이 포함되어 있습니다.
또한, 함수 호출에 대한 에러코드도 포함되어 있습니다.