Unreal Engine 빌링
Unreal Engine에서 Hybe Game Platform Service(이하, Platform)의 결제 서비스 연동을 위한 SDK 사용법에 대해서 설명합니다.
요구사항
빌링 플랫폼 SDK를 사용하기 위한 요구 사항은 다음과 같습니다.
OS : Windows, Android, iOS
Enreal Engine : 5.2.1, 5.4.4
Visual Studio 2019 이상
연동 준비
SDK 설치
언리얼 엔진에서 Platform SDK를 사용하기 위해서는 배포된 플러그인을 프로젝트의 Plugins 복사합니다.
SDK 설치 가이드를 참고하세요.
스팀 결제 환경 설정
플랫폼에 제공하는 별도의 설정은 필요하지 않습니다. 스팀앱에 로그인 상태이어야 합니다.
스팀에서 게임을 실행하거나, 언리얼 에디터에서 실행하는 경우 스팀 오버레이 결제 팝업을 통해서 결제를 진행합니다.
스팀 결제 연동
스팀 결제는 게임 클라이언트에서 스팀 서버에 결제를 요청하지 않고 게임 서버를 통해 구매를 진행해야 합니다.
API Flow
1 -2 빌링 Agent 등록
3 - 6 스팀 빌링 초기화
3 - 4 빌링 플랫폼에 구매 요청 시 호출되는 스팀결제 핸들러 등록
5 -6 스팀 결제 환경 초기화
7 - 10 판매할 상품 SKU 조회
11 - 26 상품 구매
11 빌링 백엔드에 구매할 상품 예약
12 상품 구매 요청
13 (3 -4) 단계에서 등록한 스팀결제 핸들러 호출
14 게임 서버에 상품 구매 요청
게임 서버 -> 빌링 백엔드 -> 스팀 결제 서버 를 통해 클라이언트에 결제창 팝업
19 결제 취소 이벤트 수신
20 - 26 결제 완료 이벤트 수신
결제 완료 프로세스 진행
27 - 28 미처리 상품 복구
28 구매 완료 이벤트 수신
21 단계 이후 결제 완료와 동일한 프로세스 진행
스팀 결제
BillingAgent 인터페이스 구현
HybeBillingAgent 인터페이스를 상속받은 Billing Agent 클래스를 구현합니다.
class StarterBillingAgent : public HybeBillingAgent
{
public:
void OnPrepared(BillingResultCode result) override;
void OnPurchasesUpdated(const FString& boid, const FString& resultJson) override;
void OnPurchasesCanceled() override;
void OnPurchasesError(BillingErrorCode code, const FString& message) override;
void OnUnconsumedPurchasesUpdated(const FString& boid, const FString& resultJson) override;
void OnRestoreFinished(const TArray<UnconsumedPurchaseDetails>& details) override;
void OnContinueSteamPurchase(const FString& boid) override;
};
BillingAgent 등록
①에서 구현한 BillingAgent 를 빌링 플랫폼에 등록합니다.
HybePlatformAgent::Instance().SetPlatformBillingAgent(new StarterBillingAgent());
스팀 결제 핸들러 등록
스팀 결제 요청 프로세스 과정에서 게임 클라이언트의 구현이 필요한 단계에서 클라이언트 커스텀 결제 핸들러가 호출됩니다. 스팀 결제의 경우 게임 서버로 스팀 결제 팝업을 요청하는 기능을 구현해야 합니다.
HybeBillingPlatform::Instance().RegisterSteamPurchaseHandler([](std::string boid, std::string productId, std::function<void(bool)> callback)
{
std::thread([boid, productId, callback]()
{
// 게임 서버에게 스팀 결제 시작 즉, 결제 팝업을 요청한다.
bool result = VirtualGameServer::Instance().InitTx(FString(productId.c_str()), FString(boid.c_str()));
callback(true);
}).detach();
});
등록된 결제 핸들러는 빌링 플랫폼으로 구매 요청(StartPurchase) 이후 진행되는 결제 프로세스 에서 호출됩니다.
빌링 플랫폼 연결
게임 서버 연동 후에 빌링 플랫폼에 연동합니다. 게임 서버로 부터 수신한 플레이어 정보(imid)를 빌링 플랫폼에 전달합니다.
GetBillingPlatform().PreInit(imid);
초기화 결과 이벤트 핸들러 추가
빌링 플랫폼 초기화 결과는 OnPrepared 로 전달됩니다.
void StarterBillingAgent::OnPrepared(BillingResultCode result)
{
if(result == BillingResultCode::OK)
{
// 빌링 플랫폼 연동 완료 이후 프로세스 진행
// ex) 소비 처리되지 않은 구매 복구
}
else // 빌링 플랫폼 연동 실패
{
}
}
판매할 상품 정보 조회
스토어에 등록된 상품의 상품명, 가격 정보 등 세부 정보를 조회합니다.
TArray<FString> products = { TEXT("item_01"), TEXT("item_02") };
GetBillingPlatform().QueryProductDetails(products, [](bool result)
{
if (result) //조회 성공
{
}
});
조회된 상품은 ProductManager에 캐싱됩니다. QueryProductDetails() 으로 빌링 플랫폼에 요청하기 전에 ProductManager에 조회한 후 상품 정보가 없는 경우 사용하면 서버 요청을 줄 일 수 있습니다.
TArray<FString> products = { TEXT("item_01"), TEXT("item_02") };
GetBillingPlatform().QueryProductDetails(products, [](bool result)
{
if (result)
{
ProductDetail productDetail = HybeProductManager::GetProduct(TEXT("item_01"));
if(productDetail.IsPurchasable())
{
// 상점 UI 에 상품 등
}
}
});
구매할 상품 예약
상품을 구매하기 전에 게임 서버를 통해 구매할 상품 예약을 요청합니다. 게임 서버는 플랫폼 빌링 서버에 구매할 상품을 예약한 후 예약ID (boid)를 클라이언트에 전달합니다. 게임 클라이언트는 수신한 boid를 사용해서 이후 진행되는 결제 프로세스에 사용합니다.
상품 구매 요청
예약한 상품의 구매를 게임 서버에게 요청합니다. 스팀 결제는 서버 요청으로 시작됩니다. 게임 서버에서 제공하는 결제 요청 기능을 사용하세요
스팀 결제 핸들러 호출
스팀 결제는 다른 스토어와 달리 결제 팝업을 스팀 결제 서버 요청으로 구현됩니다.
게임 서버에 상품 구매를 요청하면 게임 클라이언트에 스팀 결제 오버레이 창이 팝업 됩니다.
결제 완료 요청하기
결제를 완료하면 OnPurchasesUpdated 이벤트가 전달됩니다.
void StarterBillingAgent::OnPurchasesUpdated(std::shared_ptr<Purchase> purchase)
{
// 게임서버에 스팀 구매 프로세스 완료을 요청한다.
}
구매 정보(예약ID, 상품ID, 구매상품정보 등)이 Purchase로 전달된다.
PlayStore 결제 연동
API Flow
1 -2 빌링 Agent 등록
3 - 4 스팀 빌링 초기화
5 - 7 판매할 상품 SKU 조회
8 - 16 상품 구매
8 빌링 백엔드에 구매할 상품 예약
9 빌링 플랫폼에 상품 구매 요청
PlayStore 결제 팝업 후 결제를 완료한다.
10 [결제완료] 결제 정보를 BillingAgent 에 전달한다.
11 [결제 취소] 결제 취소 이벤트를 BillingAgent 에전달한다.
12 - 14 게임서버에 구매 완료를 요청한다.
15 결제 완료 결과 빌링 플랫폼에 전달
17 - 19 미처리 상품 복구
17 미처리 상품 복구 요청
18 복구할 구매 정보 전달
19 구매 완료 요청. 12 - 14 프로세스와 동일
PlayStore 결제
BillingAgent 인터페이스 구현
HybeBillingAgent 인터페이스를 상속받은 Billing Agent 클래스를 구현합니다.
BillingAgent 등록
①에서 구현한 BillingAgent 를 빌링 플랫폼에 등록합니다.
빌링 플랫폼 연결
게임 서버 연동 후에 빌링 플랫폼에 연동합니다. 게임 서버로 부터 수신한 플레이어 정보(imid)를 빌링 플랫폼에 전달합니다.
GetBillingPlatform().PreInit(imid);
판매할 상품 정보 조회
스토어에 등록된 상품의 상품명, 가격 정보 등 세부 정보를 조회합니다.
TArray<FString> products = { TEXT("item_01"), TEXT("item_02") };
GetBillingPlatform().QueryProductDetails(products, [](bool result)
{
if (result) //조회 성공
{
}
});
조회된 상품은 ProductManager에 캐싱됩니다. QueryProductDetails() 으로 빌링 플랫폼에 요청하기 전에 ProductManager에 조회한 후 상품 정보가 없는 경우 사용하면 서버 요청을 줄 일 수 있습니다.
TArray<FString> products = { TEXT("item_01"), TEXT("item_02") };
GetBillingPlatform().QueryProductDetails(products, [](bool result)
{
if (result)
{
ProductDetail productDetail = HybeProductManager::GetProduct(TEXT("item_01"));
if(productDetail.IsPurchasable())
{
// 상점 UI 에 상품 등
}
}
});
구매할 상품 예약
상품을 구매하기 전에 게임 서버를 통해 구매할 상품 예약을 요청합니다. 게임 서버는 플랫폼빌링 서버에 구매할 상품을 예약한 후 예약ID (boid)를 클라이언트에 전달합니다. 게임 클라이언트는 수신한 boid를 사용해서 이후 진행되는 결제 프로세스에 사용합니다.
상품 구매 요청
예약한 상품의 구매를 빌링 플랫폼에 요청한다.
결제 완료 요청하기
결제를 완료하면 OnPurchasesUpdated 이벤트가 전달됩니다.
void StarterBillingAgent::OnPurchasesUpdated(std::shared_ptr<Purchase> purchase)
{
// 게임서버에 스팀 구매 프로세스 완료을 요청한다.
}
구매 정보(예약ID, 상품ID, 구매 상품 정보 등)이 Purchase로 전달된다.
AppStore 결제 연동
PlayStore 결제 프로세스 와 동일합니다.
구매 정보 Purchase 가 AppStore 결제 항목으로 전달됩니다.
Google Play PC 결제 연동
API Flow
1 -2 빌링 Agent 등록
3 - 4 Google Play PC 결제 핸들러 등록
5 - 6 빌링 초기화
7 -10 판매할 상품 SKU 조회
11 - 21 상품 결제
11 게임 서버를 통해 빌링 백엔드에 구매할 상품 예약
12 빌링 플랫폼에 상품 구매 요청
13 웹브라우저에서 결제 페이지를 팝업한다.
14 클라이언트에서 등록한 Google Play PC 결제 핸들러를 호출한다.
15 브라우저에서 결제 완료 후에 결제 프로세스 계속 진행 여부를 BillingPlatform 에 전달한다.
16 - 22 결제 완료/취소
16 [결제 프로세스 계속]을 요청한 경우 구매 정보를 BillingAgent에 전달한다.
웹 브라우저에서 결제한 영수증 정보가 전달된다.
17 [결제 프로세스 취소]를 요청한 경우 BillingAgent 에전달한다.
18 - 20 게임서버에 구매 완료를 요청한다.
21 결제 완료 결과를 빌링 플랫폼에 전달한다.
23 - 25 미처리 상품 복구
23 미처리 상품 복구 요청한다.
24 복구할 구매 정보를 수신한다.
25 구매 완료를 요청한다.
16 - 22 프로세스와 동일한 과정을 수행한다.
Google Play PC 결제
BillingAgent 인터페이스 구현
HybeBillingAgent 인터페이스를 상속받은 Billing Agent 클래스를 구현합니다.
class StarterBillingAgent : public HybeBillingAgent
{
public:
void OnPrepared(BillingResultCode result) override;
void OnPurchasesUpdated(const FString& boid, const FString& resultJson) override;
void OnPurchasesCanceled() override;
void OnPurchasesError(BillingErrorCode code, const FString& message) override;
void OnUnconsumedPurchasesUpdated(const FString& boid, const FString& resultJson) override;
void OnRestoreFinished(const TArray<UnconsumedPurchaseDetails>& details) override;
void OnContinueSteamPurchase(const FString& boid) override;
};
결제 플랫폼 등록
PC 게임의 경우 다양한 결제 방식을 제공합니다.
지원하는 결제 스토어와 결제 수단을 직접 지정해야 합니다.
HybeBillingPlatform::SetAvailableStore(HybePlatform::StoreType::GOOGLE_PLAY_PC)
HybeBillingPlatform::SetAvailablePayment(HybePlatform::PaymentType::GOOGLE_PLAY)
BillingAgent 등록
①에서 구현한 BillingAgent 를 빌링 플랫폼에 등록합니다.
HybePlatformAgent::Instance().SetPlatformBillingAgent(new StarterBillingAgent());
Google Play PC 결제 핸들러 등록
Google Play PC 결제는 결제 요청 프로세스 과정에서 게임 클라이언트의 응답이 필요합니다. 클라이언트 응답이 필요한 단계에서 클라이언트 커스텀 결제 핸들러가 호출됩니다. Google Play PC 결제의 경우 외부 브라우저에서 진행한 결제 후 결제 완료/취소 결과를 빌링 플랫폼에 알리는 기능을 구현해야 합니다.
HybeBillingPlatform::Instance().RegisterGooglePlayPcPurchaseHandler([](std::string boid, std::string productId, std::function<void(bool)> callback)
{
// 웹브라우저에서결제 완료 대기 후 처리
// 결제 완료시 callback()을 호출해야 한다.
AsyncTask(ENamedThreads::GameThread, [callback]()
{
// 웹브라우저에서 결제를 완료할 때 까지 팝업을 띄운다.
FString msg = TEXT("브라우저에서 결제를 완료하세요.");
UAlertWidget* alertWidget = UAlertWidget::Alert(AlertBoxType::AT_YESNO, msg, [callback](AlertBoxType alertType)
{
// 웹브라우저에서 진행한결제 결과(완료, 취소)를 빌딩플랫폼에 전달한다.
callback(alertType == AlertBoxType::AT_YES);
}, TEXT("결제 완료"), TEXT("결제 취소"));
});
});
등록된 결제 핸들러는 빌링 플랫폼으로 구매 요청(StartPurchase) 이후 진행되는 결제 프로세스 에서 호출됩니다.
웹 브라우저에서 진행하는 결제 결과를 게임에서 수신하는 방법이 Google Play PC에서 제공되지 않습니다. 이러한 이유로 결제 요청 후 결제 핸들러에서 유저에게 결제 여부를 입력받는 UX가 제공되어야 합니다.
Google Play PC 결제 핸들러는 웹 브라우저에서 결제 페이지가 팝업 된 후에 호출됩니다.
빌링 플랫폼 연결
게임 서버 연동 후에 빌링 플랫폼에 연동합니다. 게임 서버로 부터 수신한 플레이어 정보(imid)를 빌링 플랫폼에 전달합니다.
GetBillingPlatform().PreInit(imid);
판매할 상품 정보 조회
스토어에 등록된 상품의 상품명, 가격 정보 등 세부 정보를 조회합니다.
TArray<FString> products = { TEXT("item_01"), TEXT("item_02") };
GetBillingPlatform().QueryProductDetails(products, [](bool result)
{
if (result) //조회 성공
{
}
});
조회된 상품은 ProductManager에 캐싱됩니다. QueryProductDetails() 으로 빌링 플랫폼에 요청하기 전에 ProductManager에 조회한 후 상품 정보가 없는 경우 사용하면 서버 요청을 줄 일 수 있습니다.
TArray<FString> products = { TEXT("item_01"), TEXT("item_02") };
GetBillingPlatform().QueryProductDetails(products, [](bool result)
{
if (result)
{
ProductDetail productDetail = HybeProductManager::GetProduct(TEXT("item_01"));
if(productDetail.IsPurchasable())
{
// 상점 UI 에 상품 등
}
}
});
QueryProductDetails()로 조회하는 상품 정보를 Google 결제 서버에 상품 정보를 조회하는 과정입니다. 게임 서버 접속 후에 필요한 상품 정보를 미리 조회하여 ProductManager에 캐싱하는 것을 구현해야합니다.
구매할 상품 예약
상품을 구매하기 전에 게임 서버를 통해 구매할 상품 예약을 요청합니다. 게임 서버는 플랫폼 빌링 서버에 구매할 상품을 예약한 후 예약ID (boid)를 클라이언트에 전달합니다. 게임 클라이언트는 수신한 boid를 사용해서 이후 진행되는 결제 프로세스에 이용합니다.
상품 구매 요청
예약한 상품의 구매를 빌링 플랫폼에 요청한다.
// boid : 7단계에서 게임서버를 통해 수신한 상품 구매 예약ID
GetBillingPlatform().StartPurchase(TEXT("item_01"), boid);
외부 브라우저에서 결제 창 팝업
StartPurchase로 결제를 요청하면 외부 브라우저에서 결제 페이지가 팝업 됩니다.
Google Play PC 결제 핸들러 호출
4) 단계에서 등록한 결제 핸들러가 호출됩니다.
입력 파라미터로 전달되는 callback으로 결제 결과를 결제 플랫폼에 반드시 전달해야 합니다.
HybeBillingPlatform::Instance().RegisterGooglePlayPcPurchaseHandler([](std::string boid, std::string productId, std::string paymentUrl, std::function<void(bool)> callback)
{
// 웹브라우저에서결제 완료 대기 후 처리
// 웹브라우저에서 진행한결제 결과(완료, 취소)를 빌딩플랫폼에 전달한다.
callback(true); //true, false
});
결제 완료 이벤트 수신
결제를 완료하면 OnPurchasesUpdated 이벤트가 전달됩니다.
void StarterBillingAgent::OnPurchasesUpdated(std::shared_ptr<Purchase> purchase)
{
// 게임서버에 구매 프로세스 완료을 요청한다.
}
구매 정보(예약ID, 상품ID, 구매 상품 정보 등)이 Purchase로 전달된다.
게임 서버에 결제 완료 요청
게임 서버에 결제 결과를 전달하여 구매 완료 프로세스를 진행합니다.
구매 프로세스 완료
게임 서버로부터 수신한 구매 프로세스 결과를 빌링 플랫폼에 전달합니다.
// boid : 예약 ID
// productId : 구매한 상품 ID
// result : 구매 프로세스 성공 여부
bool result = true;
GetBillingPlatform().OnCompletedPurchase(boid, productId, result);
미 처리 구매 복구
다음과 같은 경우 미처리 구매가 발생합니다.
브라우저에서 결제하기 전에 결제 완료 callback(true) 호출한 경우
브라우저에 결제 진행한 후 결제 완료 callback( false) 호출한 경우
결제 완료 callback(...) 호출 후에 브라우저에서 결제 진행한 경우
결제 플랫폼 초기화 후에 Restore를 호출하여 소비 처리 되지 않은 구매를 복구할 수 있습니다. 자세한 구매 복구는 미처리 구매 상품 복구를 참고하세요.
PG 결제 연동
API Flow
1 -2 빌링 Agent 등록
3 - 4 PG 결제 핸들러 등록
5 - 6 빌링 초기화
7 -10 판매할 상품 SKU 조회
11 - 20 상품 결제
11 게임 서버를 통해 빌링 백엔드에 구매할 상품 예약
예약ID와 결제URL이 전달된다.
12 빌링 플랫폼에 상품 구매 요청
13 웹브라우저에서 결제 페이지를 팝업한다.
14 - 15 유저가 브라우저에서 결제한 정보를 빌링 백엔드에 전달된다.
16 클라이언트에서 등록한 PG 결제 핸들러를 호출한다.
17 [게임으로 돌아가기] 이벤트 수신 핸들러를 등록한다.
18 - 19 브라우저로부터 [게임으로 돌아가기] 이벤트를 수신한 한다.
20 브라우저에서 결제 완료 후에 결제 프로세스 계속 진행 여부를 BillingPlatform 에 전달한다.
21 결제 완료
결제 완료 구매 정보를 BillingAgent에 전달한다.
[결제 프로세스 취소] 이벤트는 별도로 전달하지는 않는다.
PG 결제
BillingAgent 인터페이스 구현
HybeBillingAgent 인터페이스를 상속받은 Billing Agent 클래스를 구현합니다.
class StarterBillingAgent : public HybeBillingAgent
{
public:
void OnPrepared(BillingResultCode result) override;
void OnPurchasesUpdated(const FString& boid, const FString& resultJson) override;
void OnPurchasesCanceled() override;
void OnPurchasesError(BillingErrorCode code, const FString& message) override;
void OnUnconsumedPurchasesUpdated(const FString& boid, const FString& resultJson) override;
void OnRestoreFinished(const TArray<UnconsumedPurchaseDetails>& details) override;
void OnContinueSteamPurchase(const FString& boid) override;
};
결제 플랫폼 등록
PC 게임의 경우 다양한 결제 방식을 제공합니다.
지원하는 결제 스토어와 결제 수단을 직접 지정해야 합니다.
HybeBillingPlatform::SetAvailablePayment(HybePlatform::PaymentType::PG)
BillingAgent 등록
①에서 구현한 BillingAgent 를 빌링 플랫폼에 등록합니다.
HybePlatformAgent::Instance().SetPlatformBillingAgent(new StarterBillingAgent());
PG 결제 핸들러 등록
PG 결제는 결제 요청 프로세스 과정에서 게임 클라이언트의 응답이 필요합니다. 클라이언트 응답이 필요한 단계에서 클라이언트 커스텀 결제 핸들러가 호출됩니다. PG 결제의 경우 외부 브라우저에서 진행한 결제 후 [게임으로 돌아가기] 이벤트를 수신하여 결제 프로세스를 완료하도록 해야 합니다.
HybeBillingPlatform::Instance().RegisterPgPurchaseHandler([](std::string boid, std::string productId, std::string paymentUrl, std::function<void(bool)> callback)
{
// 웹브라우저에서결제 완료 대기 후 처리
// 결제 완료시 callback()을 호출해야 한다.
AsyncTask(ENamedThreads::GameThread, [callback]()
{
// 브라우저에서 결제를 완료 후, [게임으로 돌아가기]를 선택한 경우 수신할 이벤트를 처리한다.
HybePlatformAgent::Instance().ListenReturnToGame([](const FString& Message)
{
// 게임으로 돌아가기 이벤트 수신
});
// TODO : 웹브라우저에서 결제를 완료할 때 까지 팝업을 띄운다.
// 결제 완료 프로세스를 처리합니다.
// [게임으로 돌아가기] 이벤트 리스너 완료
HybePlatformAgent::Instance().CompleteReturnToGame();
// 클라이언트에서 결제 프로세스가 완료되었음을 SDK에 통지한다.
callback(true);
});
});
등록된 결제 핸들러는 빌링 플랫폼으로 구매 요청(StartPurchase) 이후 진행되는 결제 프로세스 에서 호출됩니다.
웹 브라우저에서 결제 후 [게임으로 돌아가기] 를 선택한 경우 등록한 핸들러로 전달됩니다.
PG 결제 핸들러는 웹 브라우저에서 결제 페이지가 팝업 된 후에 호출됩니다.
빌링 플랫폼 연결
게임 서버 연동 후에 빌링 플랫폼에 연동합니다. 게임 서버로 부터 수신한 플레이어 정보(imid)를 빌링 플랫폼에 전달합니다.
GetBillingPlatform().PreInit(imid);
판매할 상품 정보 조회
스토어에 등록된 상품의 상품명, 가격 정보 등 세부 정보를 조회합니다.
TArray<FString> products = { TEXT("item_01"), TEXT("item_02") };
GetBillingPlatform().QueryProductDetails(products, [](bool result)
{
if (result) //조회 성공
{
}
});
조회된 상품은 ProductManager에 캐싱됩니다. QueryProductDetails() 으로 빌링 플랫폼에 요청하기 전에 ProductManager에 조회한 후 상품 정보가 없는 경우 사용하면 서버 요청을 줄 일 수 있습니다.
TArray<FString> products = { TEXT("item_01"), TEXT("item_02") };
GetBillingPlatform().QueryProductDetails(products, [](bool result)
{
if (result)
{
ProductDetail productDetail = HybeProductManager::GetProduct(TEXT("item_01"));
if(productDetail.IsPurchasable())
{
// 상점 UI 에 상품 등
}
}
});
QueryProductDetails()로 조회하는 상품 정보를 Google 결제 서버에 상품 정보를 조회하는 과정입니다. 게임 서버 접속 후에 필요한 상품 정보를 미리 조회하여 ProductManager에 캐싱하는 것을 구현해야합니다.
구매할 상품 예약
상품을 구매하기 전에 게임 서버를 통해 구매할 상품 예약을 요청합니다. 게임 서버는 플랫폼 빌링 서버에 구매할 상품을 예약한 후 예약ID (boid)와 PG 결제 URL이 클라이언트에 전달합니다. 게임 클라이언트는 수신한 boid와 PG 결제 URL을 사용해서 이후 진행되는 결제 프로세스에 이용합니다.
상품 구매 요청
예약한 상품의 구매를 빌링 플랫폼에 요청한다.
// boid : 7단계에서 게임서버를 통해 수신한 상품 구매 예약ID
// paymentUrl : 7단계에서 게임서버를 통해 수신한 결제URL
GetBillingPlatform().StartPurchase(TEXT("item_01"), boid, paymentUrl);
외부 브라우저에서 결제 창 팝업
StartPurchase로 결제를 요청하면 외부 브라우저에서 결제 페이지가 팝업 됩니다.
PG 결제 핸들러 호출
4) 단계에서 등록한 결제 핸들러가 호출됩니다.
브라우저의 [게임으로 돌아가기] 이벤트를 수신하는 핸들러등록합니다.
입력 파라미터로 전달되는 callback으로 결제 결과를 결제 플랫폼에 반드시 전달해야 합니다.
[게임으로 돌아가기] 이벤트를 수신 완료 후 CompleteReturnToGame 을 호출하여 이벤트 수신 대기 상태를 해제해야합니다.
HybeBillingPlatform::Instance().RegisterGooglePlayPcPurchaseHandler([](std::string boid, std::string productId, std::string paymentUrl, std::function<void(bool)> callback)
{
// 브라우저에서 결제를 완료 후, [게임으로 돌아가기]를 선택한 경우 수신할 이벤트를 처리한다.
HybePlatformAgent::Instance().ListenReturnToGame([](const FString& Message)
{
}
// [게임으로 돌아가기] 수신 완료 처리
CompleteReturnToGame();
// 웹브라우저에서결제 완료 대기 후 처리
// 웹브라우저에서 진행한결제 결과(완료, 취소)를 빌딩플랫폼에 전달한다.
callback(true); //true, false
});
결제 완료 이벤트 수신
결제를 완료하면 OnPurchasesUpdated 이벤트가 전달됩니다.
void StarterBillingAgent::OnPurchasesUpdated(std::shared_ptr<Purchase> purchase)
{
// PG결제는 다른결제와 호환을 위해 제공합니다.
// 추가 작업이 필요하지 않습니다.
}
구매 정보(예약ID, 상품ID, 구매 상품 정보 등)이 Purchase로 전달된다.
PG 결제는 웹 브라우저에서 결제 후에 빌링 백엔드와 게임 서버 연동으로 모든 결제 프로세스가 완료되기 때문에 게임 클라이언트에서 결제 완료를 빌링 플랫폼에 명시적으로 전달하지 않습니다.
PG 결제는 웹 브라우저에서 결제 후에 빌링 백엔드와 게임 서버 연동으로 모든 결제 프로세스가 완료되기 때문에 미처리 결제가 발생하지 않습니다.
소비처리되지 않은 구매 복구
상품 결제 후 즉, 플랫폼 빌링 백엔드 통하여 결제 프로세스 완료되지 않은 경우 소비 처리되지 않은 구매가 발생할 수 있습니다. 이러한 경우에 유저는 결제 대금은 청구 받았으나 구매한 상품을 지급 받지 못하는 발생할 수 있습니다.
결제 플랫폼 초기화(PreInit) 후에 Restore()를 호출하여 미처리 구매 상품을 복구할 수 있습니다.
Restore를 호출하면 미처리 구매 정보를 OnRestore를 통해 전달합니다.
OnRestore 전달되는 구매 정보(Purchase) 상품 구매시 OnPurchaseUpdate로 전달되는 데이터와 동일한 구매 정보(Purchase)가 전달됩니다. OnPurchaseUpdate 동일한 프로세스로 결제 완료를 진행해야 합니다.
API Reference
클라이언트 커스텀 결제 핸들러
결제 플래폼에서 모든 결제 프로세스 구현을 제공하는 안드로이드 PlayStore, iOS AppStore 결제와 달리 스팀, PG 결제와 같은 일부 빌링 플랫폼은 결제 프로세스 과정에서 게임 클라이언트의 추가 구현이 필요합니다. 이러한 경우 게임 플랫폼에서 게임 클라이언트의 구현을 요청하기 위해 클라이언트가 등록한 결제 핸들러를 호출한다.
클라이언트 결제 핸들러를 제공해야 하는 스토어는 다음과 같습니다.
Billing 클래스
HybeBillingPlatform
SDK
빌링 플랫폼 결제 기능을 제공하는 메인 클래스
HybeBillingAgent
SDK
결제 과정에서 발생하는 이벤트를 정의한 인터페이스
HybeProductManager
SDK
상품 상세정보 관리 기능 제공
ProductDetail
SDK
상품 상세 정보 (상품명, 가격, 통화 등)
Purchase
SDK
구매 정보 (예약ID, 상품ID, PlayerID)
PurchaseDetails
SDK
구매 상품 상세 정보(가격, 통화, 결제인증 등)
StarterBillingAgent
개발사
게임 클라이언트에서 결제 이벤트 수신을 위해 구현해야 하는 클래스.
HybeBillingPlatform
빌링 플랫폼 결제 기능을 제공하는 메인 클래스.
빌링 플랫폼 연결, 상품 조회 및 구매 기능을 제공한다.
PreInit
빌링 플랫폼 초기화 . 플랫폼 결제 환경에 연결합니다.
void PreInit(const FString& imid)
파라미터
imid Player ID (IMID)
접속한 Player ID 정보를 알 수 있는 시점에 호출해야 합니다. 주로 게임 서버 접속 후 호출합니다.
결과는 Billing Agent의 OnPrepared() 이벤트로 전달됩니다.
QueryProductDetails
스토어에 등록된 구매상품 정보를 요청합니다.
수신된 상품 정보는 HybeProductManager를 통해 조회할 수 있습니다.
void QueryProductDetails(
const TArray<FString>& products, const std::function<void(bool)>& callback)
파라미터
products 조회할 상품 ID 배열
callback 결과를 수신할 콜백
products 는 1개 이상의 조회할 상품을 배열로 전달할 수 있습니다.
한번에 조회 가능한 상품은 20개 이상인 경우 일부 상품 정보가 조회 되지 않을 수 있습니다.
TArray<FString> products = { TEXT("item_01"), TEXT("item_02") };
GetBillingPlatform().QueryProductDetails(products, [](bool result)
{
if (result)
{
ProductDetail pd = HybeProductManager::GetProduct(TEXT("item_01"));
}
});
StartPurchase
상품 구매를 요청합니다.
bool StartPurchase(const FString& productId, const FString& boid);
파라미터
productId 구매할상품ID
boid 예약 ID
상품 구매 Entry Point. 스토어에 관계없이 상품 구매 프로세스는 StartPurchase 호출로 시작됩니다.
상품 구매를 위한 결제창을 팝업하고 결제 결과를 OnPurchasesUpdated 이벤트로 전달합니다.
결제를 취소한 경우 OnPurchasesCanceled 이벤트를 전달합니다.
Restore
소비 처리되지 않은 구매 복구를 요청합니다.
void Restore()
구매 과정에서 상품 결제 완료 후에 여러가지 이유로 결제 프로세스가 완료되지 못해서 결제는 완료 했지만아이템 지급이 되지 않는 상황이 발생할 수 있습니다.
결제 완료 이벤트를 클라이언트 수신하지 못한 경우
네트워크 장애로 클라이언트가 게임 서버에 결제 정보 전달에 실패한 경우
게임 서버로부터 결제 결과를 수신하지 못한 경우
결제 완료 후 비정상 종료된 경우
기타, 결제 완료 이벤트 OnCompletedPurchase를 호출하지 않는 경우
클라이언트에서 빌링 플랫폼으로 결제 완료 이벤트 OnCompletedPurchase를 전달하지 않은 구매 건은 미처리 상품으로 남게 됩니다.
소비 처리되지 않은 구매 건이 있는 경우 OnRestore에 결제 정보(Purchase) 가 전달됩니다.
결제 정보(Purchase)는 결제 완료 시 수신한 결제 정보와 동일한 데이터로 결제 완료 프로세스를 동일하게 진행해야 하며, 결제 완료와 마찬가지로 복구 프로세스를 완료한 경우 OnCompletedPurchase를 호출해야 합니다.
OnCompletedPurchase
구매 완료 상태를 빌링 플랫폼에 전달합니다.
void OnCompletedPurchase(const FString& boid, const FString& productId, bool purchased)
파라미터
boid 예약 ID
productId 구매 상품 ID
purchased 결제 프로세스가 성공한 경우 true, 실패하면 false
클라이언트는 상품 구매 후 게임 서버와 아이템 지급 등의 결제 프로세스를 진행한 후 결과를 반드시 빌링 플랫폼에 알려줘야 합니다. 모든 결제 프로세스가 정상적으로 완료된 경우 purchased를 true로 전달하고, 실패한 경우 false를 전달해야 합니다.
RegisterSteamPurchaseHandler
스팀 커스텀 결제 핸들러를 등록 한다.
void RegisterSteamPurchaseHandler(SteamInitTxnDelegate handler);
파라미터
handler 스팀 결제 핸들러
typedef std::function<bool(std::string, std::string, std::function<void(bool)>)> SteamInitTxnDelegate;
파라미터
- std::string boid 예약ID
- std::string productId 상품ID
- std::function<void(bool)> 콜백
결제 핸들러 수행 결과를 전달해야 합니다.
false를 전달하는 경우 OnPurchasesCanceled() 이벤트가 전달된다.
리턴
- 성공한 경우 true, 그렇지 않으면 false
스팀 결제는 결제 프로세스 과정에서 클라이언트가 게임 서버로 결제창 팝업을 요청하는 과정이 필요하다. 이러한 프로세스를 위해 빌링 플랫폼이 클라이언트가 등록한 스팀 결제 핸들러(SteamInitTxnDelegate)를 호출한다.
HybeBillingPlatform::Instance().RegisterSteamPurchaseHandler([](std::string boid, std::string productId, std::function<void(bool)> callback)
{
std::thread([boid, productId, callback]()
{
// 게임 서버에게 스팀 결제 시작 즉, 결제 팝업을 요청한다.
bool result = VirtualGameServer::Instance().InitTx(FString(productId.c_str()), FString(boid.c_str()));
callback(true);
}).detach();
});
RegisterPgPurchaseHandler
PG 커스텀 결제 핸들러 를 등록 한다.
void RegisterPgPurchaseHandler(PgPurchaseDelegate handler)
파라미터
handler 결제 핸들러
typedef std::function<bool(std::string, std::string, std::function<void(bool)>)> PgPurchaseDelegate ;
파라미터
- std::string boid 예약ID
- std::string productId 상품ID
- std::function<void(bool)> 콜백
결제 핸들러 수행 결과를 전달해야 합니다.
리턴
- 성공한 경우 true, 그렇지 않으면 false
PG 결제는 외부 브라우저에서 결제 진행 후 결과를 처리해야 한다.
결제 완료 후 [게임으로 돌아가기] 이벤트 처리
유저에게 외부 브라우저에서 결제 완료를 대기하도록 식별하는UX 제공
[게임으로 돌아가기] 이벤트 수신 후 결제 완료 콜백 호출
HybeBillingPlatform::Instance().RegisterSteamPurchaseHandler([](std::string boid, std::string productId, std::function<void(bool)> callback)
{
// 브라우저에서 결제 완료 후, [게임으로 돌아가기]를 선택한 경우 수신할 이벤트 핸들러
HybePlatformAgent::Instance().ListenReturnToGame([isResolved](const FString& Message)
{
});
// [게임으로 돌아가기] 이벤트 수신후 완료 처리
HybePlatformAgent::Instance().CompleteReturnToGame();
// 클라이언트에서 결제 프로세스가 완료되었음을 SDK에 알림
callback(true);
});
[게임으로 돌아가기] 이벤트를 수신하면 게임이 화면 최상단으로 자동으로 팝업됩니다.
RegisterGooglePlayPcPurchaseHandler
PG 커스텀 결제 핸들러를 등록 한다.
void RegisterGooglePlayPcPurchaseHandler(GooglePlayPcPurchaseDelegate handler)
파라미터
handler 결제 핸들러
typedef std::function<bool(std::string, std::string, std::function<void(bool)>)> GooglePlayPcPurchaseDelegate;
파라미터
- std::string boid 예약ID
- std::string productId 상품ID
- std::function<void(bool)> 콜백
결제 핸들러 수행 결과를 전달해야 합니다.
리턴
- 성공한 경우 true, 그렇지 않으면 false
Google Play PC 결제는 외부 브라우저에서 결제 진행 후 결과를 처리해야 한다.
결제 완료 후 결제 프로세스 계속 진행 여부를 빌링 플랫폼에 전달합니다.
HybeBillingPlatform::Instance().RegisterGooglePlayPcPurchaseHandler([](std::string boid, std::string productId, std::function<void(bool)> callback)
{
// TODO 유저에게 결제 완료 여부를 입력하는 UX 제공
// 클라이언트에서 결제 프로세스가 완료되었음을 SDK에 알림
callback(true);// false : 결제 취소
});
미처리 구매 발생하는 경우
브라우저에서 결제하기 전에 결제 완료 callback(true) 호출한 경우
브라우저에 결제 진행한 후 결제 완료 callback( false) 호출한 경우
결제 완료 callback(...) 호출 후에 브라우저에서 결제 진행한 경우
SetAvailableStore
빌링 스토어를 설정합니다.
void SetAvailableStore(HybePlatform::StoreType storeType)
파라미터
storeType 스토어 종류, GetStore 참고
모바일, 스팀 결제의 경우 자동으로 설정되어 별도 설정이 필요하지 않습니다.
PC 결제의 경우 플랫폼 초기화 단계에서 설정해야 합니다.
지원하는 스토어가 다음과 같은 경우 명시적으로 SetAvailableStore를 호출해야 합니다.
PG 결제
Google Play PC 결제
SetAvailablePayment
빌링 결제 타입을 설정합니다.
void SetAvailablePayment(HybePlatform::PaymentType paymentType)
파라미터
paymentType 결제 종류, GetPayment 참고
모바일, 스팀 결제의 경우 자동으로 설정되어 별도 설정이 필요하지 않습니다.
PC 결제의 경우 플랫폼 초기화 단계에서 설정해야 합니다.
지원하는 스토어가 다음과 같은 경우 명시적으로 SetAvailablePayment를 호출해야 합니다.
PG 결제
Google Play PC 결제
IsReady
빌링 플랫폼 연동 상태를 조회합니다.
bool IsReady();
리턴
빌링 플랫폼 연동 완료 상태로 결제 가능한 경우 true를 리턴 합니다. PreInit() 호출 후 빌링 플랫폼을 사용할 수 있는 경우 true, 빌링 플랫폼 연동이 실패한 경우 false
GetStore
결제 스토어 종류를 조회합니다.
StoreType GetStore() const
리턴
StoreType
enum class StoreType
{
GOOGLE_PLAY,
APPLE_APP_STORE,
STEAM,
GOOGLE_PLAY_PC,
IM_LAUNCHER, //PC 런처 플레이 게임
GALAXY_STORE,
ONE_STORE,
DMM
};
GetPlayment
연동된 결제 수단 종류를 조회합니다.
PaymentType GetPlayment() const
리턴
PaymentType
enum class PaymentType
{
GOOGLE_PLAY,
APPLE_APP_STORE,
STEAM,
DMM,
XSOLLA,
MYCARD
};
GetStoreName
결제 스토어 종류를 조회합니다.
FString GetStoreName() const
리턴
StoreType 문자열
GetPlaymentName
연동된 결제 수단 종류를 조회합니다.
FString GetPlaymentName() const
리턴
PaymentType 문자열
HybeBillingAgent
결제 프로세스에서 발생하는 이벤트를 정의한 인터페이스입니다.
게임 클라이언트는 HybeBillingAgent 를 구현한 클래스를 반드시 제공해야 합니다.
OnPrepared
결제 환경 초기화, PreInit() 호출 결과를 수신하는 이벤트 핸들러
void OnPrepared(BillingResultCode result)
파라미터
result 초기화 결과 코드
enum class BillingResultCode
{
OK = 0,
UNSUPPORTED_STORE = 1, // 지원하지 않는 스토어
UNREGISTERED_AGENT = 2, // BillingAgent 미등록
FAIL = 3, // 기타 오류
};
OnPurchasesUpdated
결제 완료 시 호출되는 이벤트 핸들러
void OnPurchasesUpdated(std::shared_ptr<Purchase> purchase)
파라미터
purchase 상품 구매 정보
상품 구매 정보 Purchase 가 전달된다. Purchase에 포함된 정보를 게임 서버에 전달하여 상품 구매 프로세스를 완료해야 합니다.
OnPurchasesCanceled
결제 취소 시 호출되는 이벤트 핸들러
void OnPurchasesCanceled()
파라미터
없음
OnRestore
미 처리 결제 건 복구(Restore) 요청 시 호출되는 이벤트 핸들러
void OnRestore(const TArray< std::shared_ptr<Purchase>>& details)
파라미터
details 상품 구매 정보
상품 구매 정보 Purchase 가 전달된다. 전달되는 Purchase 결제 완료 시 호출되는 OnPurchasesUpdated에 전달되는 Purchase 동일한 데이터로 OnPurchasesUpdated 이벤트에서 진행한 결제 완료 프로세스를 동일하게 구현해야 하며, 복구 프로세스를 완료한 경우 OnCompletedPurchase를 호출해야 합니다.
OnPurchasesError
결제 과정에서 에러 발생 시 호출되는 이벤트 핸들러
void OnPurchasesError(BillingStatus code, const FString& message)
파라미터
code 결제 상태 코드 (BillingStatus)
message 에러 메시지
BillingStatus
결제 상태 코드
enum class BillingStatus
{
OK = 0,
// 기타 에러
UNKNOWN_ERROR = 1,
// 사용자 취소
USER_CANCELED = 2,
// 구매할 수 없는 아이템
ITEM_UNAVAILABLE = 3,
// 결제 에러 (미지원 국가/스토어, 결제권한 없음 등)
BILLING_UNAVAILABLE = 4,
// 지원되지 않는 기능
FEATURE_NOT_SUPPORTED = 5,
// 결제 서비스 이용 불가 (스토어 결제 서버 연결 오류 등)
SERVICE_UNAVAILABLE = 6,
// 네트워크 오류
NETWORK_ERROR = 7,
// 가격 정보 오류
INVALID_PRICE = 8,
// 빌링 플랫폼 연결 안됨
BILLING_SERVICE_DISCONNECTED = 9,
// 스팀 오버레이 비활성
STEAM_OVERLAY_DISABLED = 10
};
HybeProductManager
판매할 상품의 상세 정보( SKU)를 관리하는 기능을 제공합니다
QueryProductDetails 을 호출하여 결제 모듈을 통해 스토어의 상품을 조회하면 ProductManager에 조회한 상품 정보가 등록됩니다. 등록된 상품은 상점 배치 및 구매 단계에서 사용합니다.
GetProduct
QueryProductDetails 을 호출하여 저장한 조회한 스토어 상품 정보를 조회합니다.
static ProductDetail GetProduct(const FString& prodectId)
파라미터
prodectId 상품ID
조회한 상품이 없는 경우, QueryProductDetails 을 호출하여 상품 정보를 캐시해야 합니다.
Purchase
상품 구매 정보
class Purchase
{
public:
FString boid;
FString productId;
FString playerId;
std::shared_ptr<PurchaseDetails> details;
};
상품 구매 시 사용한 구매 기본 정보와 상세 정보를 담고 있습니다.
boid
예약 ID
productId
상품 ID
playerId
플레이어 ID
플레이어 식별하는 ID. 게임 서버 결제 스펙에서 결정 필요
PurchaseDetails
결제 상세 정보
class PurchaseDetails
{
public:
uint64_t microPrice = 0;
FString currency;
FString signature;
FString transactionId;
FString originalJson;
TArray<std::shared_ptr<ProductDetail>> productDetails;
uint64_t purchaseTime = 0;
FString purchaseToken;
int purchaseState = 0;
bool isAcknowledged = false;
bool isAutoRenewing = false;
};
결제 모듈로 부터 수신한 결제 상제 데이터를 저장하는 구조체.
일부 데이터는 특정 스토어에서만 유효합니다.
microPrice
상품 가격, Micro price
1200000000
currency
통화 정보
KRW, USD
signature
영수증 정보
transactionId
iOS 결제 트랜젝션 ID
originalJson
PlayStore 결제 데이터
productDetails
결제 상품 상세 정보
purchaseTime
구매 시간
purchaseToken
PlayStore PurchaseToken
purchaseState
PlayStore PurchaseState
isAcknowledged
isAutoRenewing
ProductDetail
상품 정보
class ProductDetail
{
public:
FString productId;
uint32_t productIdNo; // Product Id Number : Steam Only
FString inappType;
FString name;
FString description;
int64_t priceAmountMicros;
FString priceCurrencyCode;
FString formattedPrice;
FString skuDetailsToken;
FString deepLink; // 웹 결제 딥링크(웹 결제시 사용)
};
productId
스토어에 등록된 아이템 ID(문자열)
item.bag.blue
productIdNo
등록 아이템 번호
스팀 전용
inappType
상품 종류
inapp
name
스토어에 등록한 상품명
가방(블루)
description
스토어에 등록한 상품 설명
파란색 10칸가방
priceAmountMicros
micro 상품 가격
1200000000
priceCurrencyCode
통화
KRW, USD
formattedPrice
스토어에 출력 될 가격 문구
₩1,200
skuDetailsToken
안드로이드 sku details (서버 로그용)
deepLink
웹 결제 딥링크 (Xsolla 결제 링크)
Troubleshooting
안드로이드 결제 창이 나오지 않습니다.
Play Store에 업로드한 최신 빌드의 버전이 테스트 중인 버전과 동일한지 확인하세요.
실행 버전이 Play Store에 등록된 버전과 다를 경우 결제 창이 나오지 않습니다.
PlayStore에서 테스트 카드 결제가 되지 않습니다.
라이선스 테스트에 테스트하는 계정이 등록되어 있는지 확인하세요.
Google Play Console > 설정 > 라이선스 테스트
PlayStore 구입 상품 정보를 조회할 수 없습니다
해당 계정이 테스터 참여 수락이 안 된 상황입니다. 테스터 페이지에 있는 링크에서 수락참여를 해야합니다.
Google Play Console > 홈 > (테스트할 앱) > 테스트 > 내부 테스트 > 테스터 > 테스트 참여방법 항목의 “링크 복사”
스팀 결제 창이 나오지 않습니다.
스팀 결제는 오버레이 기능으로 스팀 결제 창이 팝업 됩니다. 스팀 앱에서 오버레이 기능이 비활성화 되어 있는 경우 스팀 결제 창이 나오지 않습니다.
스팀 결제를 진행하기 전에 반드시 오버레이가 활성화 되어있는지 조회 후 진행 해야 합니다.
Last updated