Hive SDK v1.19.1부터 IAP v1의 지원을 종료합니다. Hive SDK v1.19.1 이상의 환경에서는 Hive IAP v4를 적용하시기 바랍니다.
본 가이드는 Hive IAP v1에 대해 안내하며, Hive SDK v1.19.0 이하 환경에서 적용하실 수 있습니다.
플랫폼 구매 개요
- 13개 마켓 공통 API로 지원한다.
- 마켓에서 받은 영수증에 대해 아이템이 지급될 때까지 트랜젝션을 보장한다.
- 게임 서버가 없는 경우 모듈에서 영수증 검증을 지원한다.
- CS 문의 시 실시간 백오피스 조회가 가능하다.
플랫폼 구매 도식도
C2SModuleInapp_Restore
- 상품 구매 과정에서 여러가지 상황으로 인하여 아이템 지급을 실패하거나 취소되는 경우가 발생할 수 있다. 이런 상황을 대비하기 위해서는 미 지급된 아이템의 영수증 정보를 요청해야 한다.
- 이전에 완료(finish)되지 않은 구매를 복구하여 사용자에게 전달한다. 이전 구매 상태에 따라 통지가 없을 수 있다.
- 플레이스토어에서 프로모션 코드를 넣을 수 있는데, 게임이 종료된 상태에서도 과금이 가능하다. 이를 체크하기 위해서는 게임 초기화 후 필요한 특정 시점에
restore()
메서드를 호출해주면 된다. restore()
메서드를 호출한 결과 값이 SUCCESS가 아닌 경우 게임에서 처리하지 않아도 된다.
Request
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
argument 없음 | all |
Response
복구한 아이템에 대한 정보를 받는다.
Api.Inapp_Purchase와 같은 형식으로 데이터가 내려온다.
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
pid | string | product id | all | |
quantity | int | 수량 | all | |
receipt | map | 영수증 데이터 | all |
key-value for receipt
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
APPLE_RECEIPT | string | apple | ios | |
TSTORE_TRANSACTION | string | T-store | android | |
OLLEHMARKET_TRANSACTIONID | string | olleh market | android | |
OLLEHMARKET_DATELOCAL | string | oz store | android | |
OZSTORE_DATELOCAL | string | oz store | android | |
THIRDPARTY_ORDERKEY | string | third party (google checkout) | android | |
QIIP_DATELOCAL | string | qiip | android | |
HAMI_DATELOCAL | string | hami | android | |
LEBI_BILLINGNUM | string | lebi | android | |
PLASMA_PAYMENTID | string | samsung apps plasma | android | |
PLASMA_PURCHASEID | string | samsung apps plasma | android | |
PLASMA_ITEMID | string | samsung apps plasma | android | |
PLASMA_VERIFYURL | string | samsung apps plasma | android | |
PLASMA_PARAM1 | string | samsung apps plasma | android | |
PLASMA_PARAM2 | string | samsung apps plasma | android | |
PLASMA_PARAM3 | string | samsung apps plasma | android | |
PLASMA_PURCHASEDATE | string | samsung apps plasma | android | |
AMAZON_PRODUCTID | string | amazon | android | |
AMAZON_USERID | string | amazon | android | |
AMAZON_RECEIPTID | string | amazon | android | |
AMAZON_REQUESTID | string | amazon | android | |
AMAZON_MARKETPLACE | string | amazon | android | |
KDDI_TRANSACTION | string | kddi | android | |
KDDI_SIGNATURE | string | kddi | android | |
MM_ORDERID | string | mm | android | |
MM_PURCHASEDATE | string | mm | android | |
MBIZ_EMONEY | string | mbiz | android | |
MBIZ_PURCHASEDATE | string | mbiz | android | |
GOOGLEPLAY_RECEIPT | string | android | ||
GOOGLEPLAY_SIGNATURE | string | android |
샘플 코드
API Reference: C2SModule.Inapp.Restore
- public static bool C2SModule.Inapp.Restore(C2SModule.Parameter arg, out C2SModule.Error error);
- public static bool C2SModule.Inapp.Restore(C2SModule.Parameter arg, out C2SModule.Error error,
C2SModule.CompletionHandler completionHandler);
1 2 3 4 5 |
C2SModule.Error error; if(!C2SModule.Inapp.Restore(null, out error)) { // Error 시 처리 } |
API Reference: HiveSDKUEInapp_Restore
- void HiveSDKUEInapp_Restore(FString fstrJson);
1 2 |
FString empty; FHiveSDKModule::Get().HiveSDKUEInapp_Restore(empty); |
API Reference: C2SModuleInapp_Restore
- bool C2SModuleInapp_Restore(const char* pstrJson, C2SModule_Cocos2dx::C2SModuleError* pkError,
C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
1 2 3 4 5 6 |
C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleInapp_Restore( (char*)NULL, &error) == false ) { CCLog( "====>>>> Restore error (%s)", error.get()->GetMessage() ); } |
API Reference: C2SModuleSns Restore
- +(BOOL)Restore:(id)arg error:(NSError**)error;
- +(BOOL)Restore:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
1 2 3 4 5 6 7 8 |
NSError* error; //이전에 완료되지 않은 상품 구매를 복구한다. [C2SModuleInapp Restore:nil error:&error completionHandler:^(NSDictionary* resultArg, NSError* resultError) { if (resultError == nil) { //succeed } }]; |
C2SModuleInapp_Purchase
상품을 구매 한다.
purchase()
메서드를 호출하는 도중 마켓 오류로 RESPONSE_FAIL, CANCELED 에러가 발생하면 사용자에게 구매 과정에 문제가 있음을 알린다.
- 구매 과정에 문제가 있다는 알림을 사용자가 확인했다면
restore()
메서드를 호출하여 구매 복구를 진행한다.
Request
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
pid | string | 구매 할 product id | all | |
quantity | int | (option) 구매할 아이템 수량 구글 : managed = 0, 소모성 아이템 = 1 (구글과 IOS는 1로 값을 세팅하여야 한다.) 아마존, 러비, 원스토어, … : 구매 요청 시 넣어준 quantity의 값 |
all | |
additionalInfo | string | (option) 게임서버가 여러 개일 경우 구매로그에 추가적인 정보가 필요할 경우 사용한다. 서버 구분의 경우 server_id라는 키로 jsonstring 형식으로 넣는다. 예){“server_id”:”some info”} – (참고) IOS에서는 Restore 시 해당 정보가 포함되지 않음. 서버 지역 코드값은 ‘ISO 3166 alpha-2’ 코드를 기준으로 하며 Hive 연동 가이드라인 게임서버 ID 항목을 참고한다. |
all |
Response
- 구매한 아이템에 대한 정보를 받는다.
- Api.Inapp_Restore와 같은 형식으로 데이터가 내려온다.
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
pid | string | product id | all | |
quantity | int | 수량 구글 : managed = 0, 소모성 아이템 = 1 (현재는 managed로 등록한 아이템을 소모성 아이템으로 사용하고 있으므로 큰 의미가 없는 값) 아마존, 러비, 원스토어, … : 구매 요청 시 넣어준 quantity의 값 (현재 사용하지 않는 기능) |
all | |
receipt | map | 영수증 데이터 | all |
key-value for receipt
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
APPLE_RECEIPT | string | apple | ios | |
TSTORE_TRANSACTION | string | T-store | android | |
OLLEHMARKET_TRANSACTIONID | string | olleh market | android | |
OLLEHMARKET_DATELOCAL | string | oz store | android | |
OZSTORE_DATELOCAL | string | oz store | android | |
THIRDPARTY_ORDERKEY | string | third party (google checkout) | android | |
QIIP_DATELOCAL | string | qiip | android | |
HAMI_DATELOCAL | string | hami | android | |
LEBI_BILLINGNUM | string | lebi | android | |
PLASMA_PAYMENTID | string | samsung apps plasma | android | |
PLASMA_PURCHASEID | string | samsung apps plasma | android | |
PLASMA_ITEMID | string | samsung apps plasma | android | |
PLASMA_VERIFYURL | string | samsung apps plasma | android | |
PLASMA_PARAM1 | string | samsung apps plasma | android | |
PLASMA_PARAM2 | string | samsung apps plasma | android | |
PLASMA_PARAM3 | string | samsung apps plasma | android | |
PLASMA_PURCHASEDATE | string | samsung apps plasma | android | |
AMAZON_PRODUCTID | string | amazon | android | |
AMAZON_USERID | string | amazon | android | |
AMAZON_RECEIPTID | string | amazon | android | |
AMAZON_REQUESTID | string | amazon | android | |
AMAZON_MARKETPLACE | string | amazon | android | |
KDDI_TRANSACTION | string | kddi | android | |
KDDI_SIGNATURE | string | kddi | android | |
MM_ORDERID | string | mm | android | |
MM_PURCHASEDATE | string | mm | android | |
MBIZ_EMONEY | string | mbiz | android | |
MBIZ_PURCHASEDATE | string | mbiz | android | |
GOOGLEPLAY_RECEIPT | string | android | ||
GOOGLEPLAY_SIGNATURE | string | android |
샘플 코드
API Reference: C2SModule.Inapp.Purchase
- public static bool C2SModule.Inapp.Purchase(C2SModule.Parameter arg, out C2SModule.Error error);
- public static bool C2SModule.Inapp.Purchase(C2SModule.Parameter arg, out C2SModule.Error error,
C2SModule.CompletionHandler completionHandler);
1 2 3 4 5 6 7 |
C2SModule.Parameter arg = new C2SModule.Parameter(); arg["pid"] = "m1"; C2SModule.Error error; if(!C2SModule.Inapp.Purchase(arg, out error)) { // Error 시 처리 } |
API Reference: HiveSDKUEInapp_Purchase
- void HiveSDKUEInapp_Purchase(FString fstrJson);
1 2 3 4 5 6 7 8 9 10 |
TSharedPtr arg = MakeShareable(new FJsonObject); arg->SetStringField(TEXT("pid"), TEXT("com.com2us.platformsample.normal.freefull.apple.global.ios.universal.item01")); //iOS Test Product ID FString OutputString; TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(arg.ToSharedRef(), Writer); UE_LOG(LogTemp, Warning, TEXT( " PurchaseTest :.. %s"), *OutputString); FHiveSDKModule::Get().HiveSDKUEInapp_Purchase(OutputString); |
API Reference: C2SModuleInapp_Purchase
- bool C2SModuleInapp_Purchase(const char* pstrJson, C2SModule_Cocos2dx::C2SModuleError* pkError,
C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
1 2 3 4 5 6 7 8 9 10 |
C2SModule_Cocos2dx::C2SModuleError error; Json::Value arg; arg["pid"] = "com.com2us.platformsample.normal.freefull.google.global.android.common.item01"; Json::StyledWriter writer; std::string strJSON = writer.write(arg); C2SModule_Cocos2dx::C2SModuleError error; if( C2SModuleInapp_Purchase( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Purcahse error (%s)", error.get()->GetMessage() ); } |
API Reference: C2SModuleInapp Purchase
- +(BOOL)Purchase:(id)arg error:(NSError**)error;
- +(BOOL)Purchase:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
1 2 3 4 5 6 7 8 |
//상품을 구매합니다. NSString* purchasePid = @"testpid"; [C2SModuleInapp Purchase:@{@"pid":purchasePid} error:&error completionHandler:^(NSDictionary* resultArg, NSError* resultError) { if (resultError == nil) { //succeed } }]; |
C2SModuleInapp_Finish
- 구매한 상품의 완료를 알린다.
- 과금 이벤트 트래킹을 위해 과금 성공 후 다음과 같이 Inapp Finish에 Argument를 추가하여야 한다.
Request
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
isPurchaseSuccess | bool | isPurchaseSuccess는 마케팅 트래킹 로그(PartyTrack, Adjust) 전송 여부를 나타낸다. 따라서 과금이 실제로 성공한 Finish일 경우에만 true로 설정한다. default : false. |
all | 1.7.1+ |
Response
- 구매 상품 완료 처리가 완료되면 오는 콜백
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
argument 없음 | all |
샘플 코드
API Reference: C2SModule.Inapp.Finish
- public static bool C2SModule.Inapp.Finish(C2SModule.Parameter arg, out C2SModule.Error error);
- public static bool C2SModule.Inapp.Finish(C2SModule.Parameter arg, out C2SModule.Error error,
C2SModule.CompletionHandler completionHandler);
1 2 3 4 5 6 7 |
C2SModule.Parameter arg = new C2SModule.Parameter(); C2SModule.Error error; arg["isPurchaseSuccess"] = isPurchaseSuccess; //true or false if(!C2SModule.Inapp.Finish(arg, out error)) { // Error 시 처리 } |
API Reference: HiveSDKUEInapp_Finish
- void HiveSDKUEInapp_Finish(FString fstrJson);
1 2 3 4 5 6 7 8 9 |
TSharedPtr arg = MakeShareable(new FJsonObject); arg->SetBoolField(TEXT("isPurchaseSuccess"), true); // or false FString OutputString; TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(arg.ToSharedRef(), Writer); FHiveSDKModule::Get().HiveSDKUEInapp_Finish(OutputString); |
API Reference: C2SModuleInapp_Finish
- bool C2SModuleInapp_Finish(const char* pstrJson, C2SModule_Cocos2dx::C2SModuleError* pkError,
C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
1 2 3 4 5 6 7 8 9 10 11 12 |
Json::Value arg; arg["isPurchaseSuccess"] = true; //or false Json::StyledWriter writer; std::string strJson = writer.witre(arg); C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleInapp_Finish( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Finish error (%s)", error.get()->GetMessage() ); } |
API Reference: C2SModuleInapp Finish
- +(BOOL)Finish:(id)arg error:(NSError**)error;
- +(BOOL)Finish:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
1 2 3 4 5 6 7 8 9 |
//상품 지급 완료 후 Finish 호출로 통합 모듈에 구매 완료 전달. NSDictionary *arg = @{@"isPurchaseSuccess" : isPurchaseSuccess}; //true or false [C2SModuleInapp Finish:arg error:&error completionHandler:^(NSDictionary* finishArg, NSError* finishError) { if(finishError == nil) { //succeed } }]; |
C2SModuleInapp_CheckPromotePurchase
- 앱스토어에서 구매 요청이 들어온 pid 값을 요청한다.(1회성)
-
앱스토어로부터 delegate로 pid를 전달받았을 때 state = “enable” 값을 전역콜백으로 준다.
- 해당 콜백 이후에 API를 호출해야 정상적으로 pid를 전달받을 수 있다.
- 저장된 pid가 없을 땐 NotOwned(-306) error를 전달한다.
- 한번 전달된 pid는 메모리에서 삭제되어 재전달되지 않기 때문에 콜백 이후엔 따로 pid 관리가 필요하다.
Request
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
argument 없음 | iOS |
Response
- 앱스토어로부터 구매 요청이 들어온 상품의 pid를 받는다.
argument name | type | desc | platform | 비고 |
---|---|---|---|---|
state | string | “enable” 앱스토어로부터 pid를 전달받았을 때 전역콜백으로 전달 |
iOS | |
API 호출 시 | ||||
pid | string | product id | iOS |
샘플 코드
API Reference: C2SModule.Inapp.CheckPromotePurchase
- public static bool C2SModule.Inapp.CheckPromotePurchase(C2SModule.Parameter arg, out C2SModule.Error error);
- public static bool C2SModule.Inapp.CheckPromotePurchase(C2SModule.Parameter arg, out C2SModule.Error error,
C2SModule.CompletionHandler completionHandler);
1 2 3 4 5 6 7 8 |
C2SModule.Parameter arg = new C2SModule.Parameter(); C2SModule.Error error; if(!C2SModule.Inapp.CheckPromotePurchase(arg, out error)) { // Error 시 처리 } |
API Reference: HiveSDKUEInapp_CheckPromotePurchase
- void HiveSDKUEInapp_CheckPromotePurchase(FString fstrJson);
1 2 3 4 5 6 7 8 |
TSharedPtr arg = MakeShareable(new FJsonObject); FString OutputString; TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(arg.ToSharedRef(), Writer); FHiveSDKModule::Get().HiveSDKUEInapp_CheckPromotePurchase(OutputString); |
API Reference: C2SModuleInapp_CheckPromotePurchase
- bool C2SModuleInapp_CheckPromotePurchase(const char* pstrJson, C2SModule_Cocos2dx::C2SModuleError* pkError,
C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
1 2 3 4 5 6 7 |
JC2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleInapp_CheckPromotePurchase( (char*)NULL, &error ) == false ) { CCLog( "====>>>> Finish error (%s)", error.get()->GetMessage() ); } |
API Reference: C2SModuleInapp CheckPromotePurchase
- +(BOOL)CheckPromotePurchase:(id)arg error:(NSError**)error;
- +(BOOL)CheckPromotePurchase:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
1 2 3 4 5 6 7 |
NSDictionary *arg; NSError *error; [C2SModuleInapp CheckPromotePurchase:arg error:&error completionHandler:^(NSDictionary* finishArg, NSError* finishError) { if(finishError == nil) { //succeed } }]; |