여기에서는 Unity에서 인앱 결제 기능을 사용하기 위해 필요한 설정 방법을 알아보겠습니다. Gamebase는 하나의 통합된 결제 API를 제공해 게임에서 손쉽게 많은 스토어의 인앱 결제를 연동할 수 있도록 돕습니다.
Android나 iOS에서 인앱 결제 기능을 설정하는 방법은 다음 문서를 참고하시기 바랍니다.
Unity Standalone에서 결제하려면 IapAdapter와 WebViewAdapter를 반드시 추가해야 합니다.
아이템 구매는 크게 결제 Flow 와 Consume Flow, 재처리 Flow 로 나누어 볼 수 있습니다. 결제 Flow는 다음과 같은 순서로 구현하시기 바랍니다.
미소비 결제 내역 목록에 값이 있으면 다음과 같은 순서로 Consume Flow 를 진행하시기 바랍니다.
[주의]
아이템이 중복 지급되는 일이 발생하지 않도록, 게임 서버에서 반드시 중복 지급 여부를 체크하시기 바랍니다.
구매하고자 하는 아이템의 gamebaseProductId를 이용해 다음의 API를 호출하여 구매를 요청합니다. 게임 유저가 구매를 취소하는 경우 PURCHASE_USER_CANCELED 오류가 반환됩니다.
API
Supported Platforms ■ UNITY_IOS ■ UNITY_ANDROID
static void RequestPurchase(string gamebaseProductId, GamebaseCallback.GamebaseDelegate<GamebaseResponse.Purchase.PurchasableReceipt> callback)
static void RequestPurchase(string gamebaseProductId, string payload, GamebaseCallback.GamebaseDelegate<GamebaseResponse.Purchase.PurchasableReceipt> callback)
// Legacy API
static void RequestPurchase(long itemSeq, GamebaseCallback.GamebaseDelegate<GamebaseResponse.Purchase.PurchasableReceipt> callback)
Example
public void RequestPurchase(string gamebaseProductId)
{
Gamebase.Purchase.RequestPurchase(gamebaseProductId, (purchasableReceipt, error) =>
{
if (Gamebase.IsSuccess(error))
{
Debug.Log("Purchase succeeded.");
}
else
{
if (error.code == (int)GamebaseErrorCode.PURCHASE_USER_CANCELED)
{
Debug.Log("User canceled purchase.");
}
else
{
Debug.Log(string.Format("Purchase failed. error is {0}", error));
}
}
});
}
public void RequestPurchase(string gamebaseProductId)
{
string userPayload = "{\"description\":\"This is example\",\"channelId\":\"delta\",\"characterId\":\"abc\"}";
Gamebase.Purchase.RequestPurchase(gamebaseProductId, userPayload, (purchasableReceipt, error) =>
{
if (Gamebase.IsSuccess(error))
{
Debug.Log("Purchase succeeded.");
// userPayload value entered when calling API
string payload = purchasableReceipt.payload
}
else
{
if (error.code == (int)GamebaseErrorCode.PURCHASE_USER_CANCELED)
{
Debug.Log("User canceled purchase.");
}
else
{
Debug.Log(string.Format("Purchase failed. error is {0}", error));
}
}
});
}
아이템 목록을 조회하려면 다음 API를 호출합니다. 콜백으로 반환되는 목록 안에는 각 아이템들에 대한 정보가 담겨 있습니다.
API
Supported Platforms ■ UNITY_IOS ■ UNITY_ANDROID
static void RequestItemListPurchasable(GamebaseCallback.GamebaseDelegate<List<GamebaseResponse.Purchase.PurchasableItem>> callback)
Example
public void RequestItemListPurchasable()
{
Gamebase.Purchase.RequestItemListPurchasable((purchasableItemList, error) =>
{
if (Gamebase.IsSuccess(error))
{
Debug.Log("Get list succeeded.");
}
else
{
Debug.Log(string.Format("Get list failed. error is {0}", error));
}
});
}
아이템을 구매했지만, 정상적으로 아이템이 소비(배송, 지급)되지 않은 미소비 결제 내역을 요청합니다. 미결제 내역이 있는 경우에는 게임 서버(아이템 서버)에 요청하여, 아이템을 배송(지급)하도록 처리해야 합니다. 정상적으로 결제가 완료되지 못한 경우 재처리의 역할도 하므로 다음 상황에서 호출해 주세요. * 게임 유저에게 지급되지 못한 아이템이 남아 있는지 확인 * 로그인 완료 후 * 게임 내 상점(또는 로비) 진입시 * 유저 프로필 또는 우편함 확인시 * 재처리가 필요한 아이템이 있는지 확인 * 결제 전 * 결제 실패 후
API
Supported Platforms ■ UNITY_IOS ■ UNITY_ANDROID
static void RequestItemListOfNotConsumed(GamebaseCallback.GamebaseDelegate<List<GamebaseResponse.Purchase.PurchasableReceipt>> callback)
Example
public void RequestItemListOfNotConsumed()
{
Gamebase.Purchase.RequestItemListOfNotConsumed((purchasableReceiptList, error) =>
{
if (Gamebase.IsSuccess(error))
{
Debug.Log("Get list succeeded.");
// Should Deal With This non-consumed Items.
// Send this item list to the game(item) server for consuming item.
}
else
{
Debug.Log(string.Format("Get list failed. error is {0}", error));
}
});
}
현재 사용자 ID 기준으로 활성화된 구독 목록을 조회합니다. 결제가 완료된 구독 상품(자동 갱신형 구독, 자동 갱신형 소비성 구독 상품)은 만료되기 전까지 계속 조회할 수 있습니다. 사용자 ID가 같다면 Android와 iOS에서 구매한 구독 상품이 모두 조회됩니다.
[주의]
현재 구독 상품은 Android의 경우 Google Play 스토어만 지원합니다.
API
Supported Platforms ■ UNITY_IOS ■ UNITY_ANDROID
static void RequestActivatedPurchases(GamebaseCallback.GamebaseDelegate<List<GamebaseResponse.Purchase.PurchasableReceipt>> callback)
Example
public void RequestActivatedPurchasesSample()
{
Gamebase.Purchase.RequestActivatedPurchases((purchasableReceiptList, error) =>
{
if (Gamebase.IsSuccess(error) == true)
{
Debug.Log("RequestItemListPurchasable succeeded");
foreach (GamebaseResponse.Purchase.PurchasableReceipt purchasableReceipt in purchasableReceiptList)
{
var message = new StringBuilder();
message.AppendLine(string.Format("gamebaseProductId:{0}", purchasableReceipt.gamebaseProductId));
message.AppendLine(string.Format("price:{0}", purchasableReceipt.price));
message.AppendLine(string.Format("currency:{0}", purchasableReceipt.currency));
// You will need paymentSeq and purchaseToken when calling the Consume API.
// Refer to the following document for the Consume API.
// https://docs.toast.com/en/Game/Gamebase/en/api-guide/#purchaseiap
message.AppendLine(string.Format("paymentSeq:{0}", purchasableReceipt.paymentSeq));
message.AppendLine(string.Format("purchaseToken:{0}", purchasableReceipt.purchaseToken));
message.AppendLine(string.Format("marketItemId:{0}", purchasableReceipt.marketItemId));
Debug.Log(message);
}
}
else
{
// Check the error code and handle the error appropriately.
Debug.Log(string.Format("RequestItemListPurchasable failed. error is {0}", error));
}
});
}
프로모션 결제가 완료되었을때 GamebaseEventHandler 를 통해 이벤트를 받아 처리할 수 있습니다. GamebaseEventHandler 로 프로모션 결제 이벤트를 처리하는 방법은 아래 가이드를 확인하세요. Game > Gamebase > Unity SDK 사용 가이드 > ETC > Gamebase Event Handler
Supported Platforms ■ UNITY_IOS ■ UNITY_ANDROID
[주의]
iOS 프로모션 결제를 위해서는 반드시 아래 가이드를 따라 설정하세요. Game > Gamebase > iOS SDK 사용 가이드 > 결제 > Event by Promotion
Error | Error Code | Description |
---|---|---|
PURCHASE_NOT_INITIALIZED | 4001 | Purchase 모듈이 초기화되지 않았습니다. gamebase-adapter-purchase-IAP 모듈을 프로젝트에 추가했는지 확인해 주세요. |
PURCHASE_USER_CANCELED | 4002 | 게임 유저가 아이템 구매를 취소하였습니다. |
PURCHASE_NOT_FINISHED_PREVIOUS_PURCHASING | 4003 | 구매 로직이 아직 완료되지 않은 상태에서 API가 호출되었습니다. |
PURCHASE_NOT_ENOUGH_CASH | 4004 | 해당 스토어의 캐시가 부족해 결제할 수 없습니다. |
PURCHASE_INACTIVE_PRODUCT_ID | 4005 | 해당 상품이 활성화 상태가 아닙니다. |
PURCHASE_NOT_EXIST_PRODUCT_ID | 4006 | 존재하지 않는 GamebaseProductID 로 결제를 요청하였습니다. |
PURCHASE_NOT_SUPPORTED_MARKET | 4010 | 지원하지 않는 스토어입니다. 선택 가능한 스토어는 AS(App Store), GG(Google), ONESTORE, GALAXY 입니다. |
PURCHASE_EXTERNAL_LIBRARY_ERROR | 4201 | IAP 라이브러리 오류입니다. DetailCode를 확인하세요. |
PURCHASE_UNKNOWN_ERROR | 4999 | 정의되지 않은 구매 오류입니다. 전체 로그를 고객 센터에 올려 주시면 가능한 한 빠르게 답변 드리겠습니다. |
PURCHASE_EXTERNAL_LIBRARY_ERROR
GamebaseError gamebaseError = error; // GamebaseError object via callback
if (Gamebase.IsSuccess(gamebaseError))
{
// succeeded
}
else
{
Debug.Log(string.Format("code:{0}, message:{1}", gamebaseError.code, gamebaseError.message));
GamebaseError moduleError = gamebaseError.error; // GamebaseError.error object from external module
if (null != moduleError)
{
int moduleErrorCode = moduleError.code;
string moduleErrorMessage = moduleError.message;
Debug.Log(string.Format("moduleErrorCode:{0}, moduleErrorMessage:{1}", moduleErrorCode, moduleErrorMessage));
}
}