[Caution]
If you use 3rd party payment plugins or modules such as those for Unreal or Unity, it might affect the Gamebase purchase functionality.
This page describes how to set In-App Purchase (IAP).
Gamebase provides an integrated purchase API to easily link IAP of many stores in a game.
See the following for the setup on Gamebase Console.
Import the following header to ViewController to implement purchase API.
#import <Gamebase/Gamebase.h>
Purchase of an item can be divided into Purchase Flow, Consume Flow, and Reprocess Flow. It is recommended to implement the Purchase Flow in the following order:
If there's a value on the list of unconsumed purchases, proceed with the Consume Flow in the following order:
[Caution]
To prevent duplicate provision of an item, always check whether the item is being provided in duplicate in the game server.
With gamebaseProductId of an item to purchase, call the following API to request for purchase.
The gamebaseProductId is generally same as the ID of item registered at store, but it could be changed on Gamebase console.
When a game user cancels purchase, the TCGB_ERROR_PURCHASE_USER_CANCELED is returned. Please process cancellation.
API
+ (void)requestPurchaseWithGamebaseProductId:(NSString *)gamebaseProductId
viewController:(UIViewController *)viewController
completion:(void(^)(TCGBPurchasableReceipt *purchasableReceipt, TCGBError *error))completion;
+ (void)requestPurchaseWithGamebaseProductId:(NSString *)gamebaseProductId
payload:(NSString *)payload
viewController:(UIViewController *)viewController
completion:(void(^)(TCGBPurchasableReceipt *purchasableReceipt, TCGBError *error))completion;
Example
- (void)purchasingItem:(NSString *)gamebaseProductId {
NSString *userPayload = @"USER_PAYLOAD";
[TCGBPurchase requestPurchaseWithGamebaseProductId:gamebaseProductId payload:userPayload viewController:self completion:^(TCGBPurchasableReceipt *purchasableReceipt, TCGBError *error) {
NSString *receivedPayload = purchasableReceipt.payload;
if ([TCGBGamebase isSuccessWithError:error] == YES) {
// To Purchase Item Succeeded
} else if (error.code == TCGB_ERROR_PURCHASE_USER_CANCELED) {
// User Canceled Purchasing Item
} else if (error) {
// To Purchase Item Failed cause of the error
}
}];
}
VO
@interface TCGBPurchasableReceipt : NSObject
// The product ID of a purchased item.
@property (nonatomic, strong) NSString *gamebaseProductId;
// Price of purchased product
@property (assign) float price;
// Currency code
@property (nonatomic, strong) NSString *currency;
// Payment identifier
// This is an important piece of information used to call 'Consume' server API with purchaseToken
// Consume API : https://docs.toast.com/en/Game/Gamebase/en/api-guide/#purchase-iap
// Caution : Call Consume API from game server!
@property (nonatomic, strong) NSString *paymentSeq;
// Payment identifier
// Used to call 'Consume' server API with paymentSeq
// Consume API : https://docs.toast.com/en/Game/Gamebase/en/api-guide/#purchase-iap
// Caution : Call Consume API from game server!
@property (nonatomic, strong) NSString *purchaseToken;
// The product ID registered with Apple Store console
@property (nonatomic, strong) NSString *marketItemId;
// Product type
// UNKNOWN : An unknown type. Either update Gamebase SDK or contact Gamebase Customer Center.
// CONSUMABLE : A consumable product.
// AUTO_RENEWABLE : A subscription product
// CONSUMABLE_AUTO_RENEWABLE : This 'consumable subscription product' is used when providing a subscribed user a subscription product that can be consumed periodically.
@property (nonatomic, strong) NSString *productType;
// This is a user ID with which a product is purchased
// If a user logs in with a user ID that is not used to purchase a product, the user cannot obtain the product they purchased.
@property (nonatomic, strong) NSString *userId;
// The payment identifier of a store
@property (nonatomic, strong, nullable) NSString *paymentId;
// The time when the subscription expires (epoch time)
@property (nonatomic, assign) long expiryTime;
// The time when the product was purchased (epoch time)
@property (nonatomic, assign) long purchaseTime;
// It is the value passed to payload when calling the requestPurchase API
// This field can be used to hold a variety of additional information. For example, this field can be used to separately handle purchase
// of the products purchased using the same user ID and sort them by game channel or character.
@property (nonatomic, strong, nullable) NSString *payload;
// paymentId is changed whenever product subscription is renewed.
// This field shows the paymentId that was used when a subscription product was first purchased.
// This value does not guarantee to be always valid, as it can have no value depending on the store the user made a purchase and the status of the payment server.
@property (nonatomic, strong, nullable) NSString *originalPaymentId;
// An identifier for Legacy API that purchases products with itemSeq
@property (assign) long itemSeq;
// Whether it is sandbox payment
@property (nonatomic, assign) BOOL sandboxPayment;
// Whether it is promotion payment
@property (nonatomic, assign) BOOL promotionPayment;
// Store code (ex. "AS")
@property (nonatomic, strong) NSString *storeCode;
@end
To retrieve the list of items, call the following API. Information of each item is included in the array of callback return.
- (void)viewDidLoad {
[TCGBPurchase requestItemListPurchasableWithCompletion:^(NSArray *purchasableItemArray, TCGBError *error) {
if (error != nil) {
// To Request Item List Failed cause of the error
return;
}
NSMutableArray *itemArrayMutable = [[NSMutableArray alloc] init];
[purchasableItemArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
TCGBPurchasableItem *item = (TCGBPurchasableItem *)obj;
[itemArrayMutable addObject:item];
}];
}];
}
VO
@interface TCGBPurchasableItem : NSObject
// The product ID that is registered with the Gamebase console
// Used when purchasing a product with requestPurchase API
@property (nonatomic, strong) NSString *gamebaseProductId;
// Product price
@property (assign) float price;
// Currency code
@property (nonatomic, strong) NSString *currency;
// The product name registered with the Gamebase console
@property (nonatomic, strong) NSString *itemName;
// Store code ("AS")
@property (nonatomic, strong) NSString *marketId;
// The product ID registered with Apple Store console
@property (nonatomic, strong) NSString *marketItemId;
// Product type
// UNKNOWN: An unknown type. Either update Gamebase SDK or contact Gamebase Customer Center.
// CONSUMABLE: A consumable product.
// AUTO_RENEWABLE: A subscription product
// CONSUMABLE_AUTO_RENEWABLE: This 'consumable subscription product' is used when providing a subscribed user a subscription product that can be consumed periodically.
// Localized price information with currency symbol
@property (nonatomic, strong) NSString *localizedPrice;
// The name of a localized product registered with the store console
@property (nonatomic, strong) NSString *localizedTitle;
// The description of a localized product registered with the store console
@property (nonatomic, strong) NSString *localizedDescription;
// Determines whether the product is used in the Gamebase console or not
@property (nonatomic, assign, getter=isActive) BOOL active;
// An item identifier for Legacy API that purchases products with itemSeq
@property (assign) long itemSeq;
@end
Request a list of non-consumed items, which have not been normally consumed (delivered, or provided) after purchase.
* In case there is any non-purchased item, request the game server (item server) to proceed with item delivery (provision).
API
+ (void)requestItemListOfNotConsumedWithConfiguration:(TCGBPurchasableConfiguration *)configuration
completion:(void(^)(NSArray<TCGBPurchasableReceipt *> * _Nullable purchasableReceiptArray, TCGBError * _Nullable error))completion;
Example
- (void)viewDidLoad {
TCGBPurchasableConfiguration *configuration = [[TCGBPurchasableConfiguration alloc] init];
[TCGBPurchase requestItemListOfNotConsumedWithConfiguration:configuration completion:^(NSArray<TCGBPurchasableReceipt *> *purchasableReceiptArray, TCGBError *error) {
if (error != nil) {
// To Requesting Non-consumed Item List Failed cause of the error
return;
}
// Should Deal With This Non-consumed Items.
// Send this item list to the game(item) server for consuming item
}];
}
List activated subscriptions based on the current user ID. Subscriptions that are paid up (e.g. auto-renewable subscription, auto-renewed consumable subscription) can be listed before they are expired.
API
+ (void)requestActivatedPurchasesWithConfiguration:(TCGBPurchasableConfiguration *)configuration
completion:(void(^)(NSArray<TCGBPurchasableReceipt *> * _Nullable purchasableReceiptArray, TCGBError * _Nullable error))completion;
Example
- (void)viewDidLoad {
TCGBPurchasableConfiguration *configuration = [[TCGBPurchasableConfiguration alloc] init];
[TCGBPurchase requestActivatedPurchasesWithConfiguration:configuration completion:^(NSArray<TCGBPurchasableReceipt *> *purchasableReceiptArray, TCGBError *error) {
if (error != nil) {
// To Requesting Activated Item List Failed cause of the error
return;
}
// Should Deal With This Activated Items.
}];
}
List of purchases made by user's App Store account can be restored and applied to console. This feature is useful when a purchased subscription cannot be queried nor activated. Restored payment, including expired payment, is returned as result. In the case of auto-renewed consumable subscriptions, any missing purchases can be queried from the unconsumed purchase history after restoration is done.
API
+ (void)requestRestoreWithCompletion:(void(^)(NSArray<TCGBPurchasableReceipt *> * _Nullable purchasableReceiptArray, TCGBError * _Nullable error))completion;
Example
- (void)viewDidLoad {
[TCGBPurchase requestRestoreWithCompletion:^(NSArray<TCGBPurchasableReceipt *> *purchasableReceiptArray, TCGBError *error) {
if (error != nil) {
// To Requesting Restore Failed cause of the error
return;
}
// Should Deal With This Restored Items.
}];
}
Caution
It is available for iOS version 11 or later. Supported in Gamebase 1.13.0 or later. (NHN Cloud IAP SDK 1.6.0 or later applied)
The promotion payment can be processed through GamebaseEventHandler. Please refer to the guide below for how to process the promotion payment with GamebaseEventHandler. Game > Gamebase > iOS SDK user guide > ETC > Gamebase Event Handler
If In-App Purchase (for App Store) is included to SDK, like Facebook SDK or Google AdMob SDK, and advance payment begins even before login to Gamebase, a payment popup may not show up.
It provides a function to purchase in-app items from App Store apps. After a successful purchase of items, the items can be delivered using the handler listed below.
The promotion IAP is displayed only when an additional setting is done in App Store Connect.
Caution
You can test your app after uploading it to the App Store Connect and installing the app with TestFlight.
URL Components | keyname | value |
---|---|---|
scheme | itms-services | Fixed value |
host & path | None | None |
queries | action | purchaseIntent |
bundleId | bundled identifier of the app | |
productIdentifier | product identifier of the purchased item |
E.g.) itms-services://?action=purchaseIntent&bundleId=com.bundleid.testest&productIdentifier=productid.001
Parameter | Values | Description |
---|---|---|
allStores | Bool | Set to make sure the API works for the current or all stores based on the same UserID - All Stores: YES - Current Store: NO default: NO |
Error | Error Code | Description |
---|---|---|
TCGB_ERROR_NOT_SUPPORTED | 10 | GamebaseAdapter is not included. If domain of the error object is "TCGB.Gamebase.TCGBPurchase", see if PurchaseAdapter exists. |
TCGB_ERROR_PURCHASE_NOT_INITIALIZED | 4001 | Gamebase PurchaseAdapter has not been initialized. |
TCGB_ERROR_PURCHASE_USER_CANCELED | 4002 | Purchase has been cancelled. |
TCGB_ERROR_PURCHASE_NOT_FINISHED_PREVIOUS_PURCHASING | 4003 | Previous purchase has not been completed. |
TCGB_ERROR_PURCHASE_NOT_ENOUGH_CASH | 4004 | Unable to purchase due to shortage of cash for the store. |
TCGB_ERROR_PURCHASE_INACTIVE_PRODUCT_ID | 4005 | Product is not activated. |
TCGB_ERROR_PURCHASE_NOT_EXIST_PRODUCT_ID | 4006 | Requested for purchase with invalid GamebaseProductID. |
TCGB_ERROR_PURCHASE_LIMIT_EXCEEDED | 4007 | You have exceeded your monthly purchase limit. |
TCGB_ERROR_PURCHASE_NOT_SUPPORTED_MARKET | 4010 | The store is not supported. iOS supports "AS". |
TCGB_ERROR_PURCHASE_EXTERNAL_LIBRARY_ERROR | 4201 | Error in NHN Cloud IAP library. Please check the error details. |
TCGB_ERROR_PURCHASE_UNKNOWN_ERROR | 4999 | Unknown error in purchase. Please upload the entire logs to the Customer Center and we'll return at the earliest possible moment. |
TCGB_ERROR_PURCHASE_EXTERNAL_LIBRARY_ERROR
TCGBError *tcgbError = error; // TCGBError object via callback
NSInteger detailErrorCode = [error detailErrorCode];
NSString *detailErrorMessage = [error detailErrorMessage];
// If you use **description** method, you can get entire information of this object by JSON Format
NSLog(@"TCGBError: %@", [tcgbError description]);