App development¶
This guide outlines the steps to develop an app using the Hive SDK. The Hive SDK provides various features such as authentication, payment, push notifications, ad banners, and customer data analysis. In this guide, we will focus on implementing the most basic features: authentication and payment.
Note
The Hive SDK supports various development engines (Android Native, iOS Native, Unity, Unreal Engine, etc.). This guide assumes that you are already familiar with developing, building, and releasing apps with each development engine and will focus on how to use the Hive SDK. For details on developing, building, and releasing apps for each development engine, refer to their respective developer centers and documentation.
The overall process of using the Hive SDK in app development can be summarized as follows:
- Implement Hive SDK initialization
- Implement authentication
- Implement payment
Implementing authentication includes:
- Implementing login
- Implementing login token verification
Implementing payment includes:
- Implementing payment initialization
- Implementing product list retrieval
- Implementing product purchase
- Implementing purchase receipt verification
Hive SDK implementation flow¶
The overview of general implementation flow of Hive SDK to develop your app features is as follows.
Implement Hive SDK initialization¶
To operate the Hive SDK, you first need to initialize it. Initializing the Hive SDK involves assigning pre-entered Hive SDK settings and performing various preparatory tasks. To initialize the Hive SDK, call AuthV4.setup
. If the call is successful, you will receive the following information, which can be stored and used at an appropriate time in your app.
Hive Initialization Result Information
Field Name | Description | Example |
---|---|---|
isAutoSignIn | Whether auto sign-in is possible | true |
did | Identifier generated when the app is installed | 123456789 |
providerTypeList | List of IdP authentications available in the current app | ProviderType.HIVEProviderType.GOOGLE |
The following is the implementation example of setup
method.
API Reference: hive.AuthV4.setup
// Request to initialize Hive SDK
AuthV4.setup ((ResultAPI result, Boolean isAutoSignIn, String did, List providerTypeList) => {
if (result.isSuccess()) {
// Initialization succeeded. Handle login based on the auto-login availability.
} else if (result.needExit()) {
// TODO: Implement app exit functionality
// e.g., Application.Quit();
} else {
// Initialization failed
}
});
API Reference: AuthV4::setup
// Request to initialize Hive SDK
AuthV4::setup([=](ResultAPI const & result, bool isAutoSignIn, std::string did, std::vector<ProviderType> const & providerTypeList) {
if (result.isSuccess()) {
// Initialization succeeded. Handle login based on the auto-login availability.
} else if (result.needExit()) {
// TODO: Implement app exit functionality
// Cocos2d-x engine users
// e.g., exit(0);
// Unreal engine users
// e.g., UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
} else {
// Initialization failed
}
});
API Reference: com.hive.AuthV4.setup
// Request to initialize Hive SDK
AuthV4.setup(object: AuthV4.AuthV4SetupListener{
override fun onAuthV4Setup(result: ResultAPI, isAutoSignIn: Boolean, did: String?, providerTypeList: ArrayList<AuthV4.ProviderType>?) {
if (result.isSuccess) {
// Initialization succeeded. Handle login based on the auto-login availability.
} else if (result.needExit()) {
// TODO: Implement app exit functionality
// e.g., exitProcess(0)
} else {
// Initialization failed
}
}
})
API Reference: com.hive.AuthV4.setup
// Request to initialize Hive SDK
AuthV4.setup(new AuthV4.AuthV4SetupListener() {
@Override
public void onAuthV4Setup(ResultAPI result, boolean isAutoSignIn, String did, ArrayList<AuthV4.ProviderType> providerTypeList) {
if (result.isSuccess()) {
// Initialization succeeded. Handle login based on the auto-login availability.
} else if (result.needExit()) {
// TODO: Implement app exit functionality
// e.g., System.exit(0);
} else {
// Initialization failed
}
}
});
API Reference: HIVEAuthV4:setup
AuthV4Interface.setup { (result, isAutoSignIn, did, providerTypeList) in
if result.isSuccess() {
// Initialization succeeded. Handle login based on the auto-login availability.
} else if result.needExit() {
// TODO: Implement app exit functionality
// e.g., exit(0)
} else {
// Initialization failed
}
}
API Reference: HIVEAuthV4:setup
// Request to initialize Hive SDK
[HIVEAuthV4 setup:^(HIVEResultAPI *result, BOOL isAutoSignIn, NSString *did, NSArray<NSNumber *> *providerTypeList) {
if (result.isSuccess) {
// Initialization succeeded. Handle login based on the auto-login availability.
} else if (result.needExit) {
// TODO: Implement app exit functionality
// e.g., exit(0);
} else {
// Initialization failed
}
}];
Info
For more details, refer to the Hive Initialization Guide.
Authentication implementation¶
App users can log into the app not only with their Hive membership account but also with various ID provider (IdP) accounts such as Google and Facebook. When implementing login, users can select their preferred IdP account to log into the app and link their app account with the IdP account. The types of IdP offered can be configured differently depending on the app, and the Hive platform exposes the appropriate IdP to users based on their country information.
First, configure the IdP settings in the Hive console.
- Save the key values provided by the IdP
- Enable IdP usage in App Center > Manage AppID > Search and click the app > Click the AppID tab > Click the app AppID > Login
Info
For more details, refer to the Hive Console Authentication Guide.
Login implementation¶
Once the console settings are complete, implement the login UI using the Hive SDK. Below is an example using the UI provided by the SDK.
API Reference: hive.AuthV4.showSignIn
// Hive SDK AuthV4 authentication UI request
AuthV4.showSignIn((ResultAPI result, AuthV4.PlayerInfo playerInfo)=>{
if (result.isSuccess()) {
// Authentication successful
// playerInfo: authenticated user information
// Example of retrieving email information
foreach (KeyValuePair<AuthV4.ProviderType, AuthV4.ProviderInfo> entry in playerInfo.providerInfoData) {
AuthV4.ProviderInfo providerInfo = entry.Value;
if(providerInfo.providerEmail != null && providerInfo.providerEmail != "") {
string email = providerInfo.providerEmail;
break;
}
}
}
else if (result.needExit()) {
// TODO: Implement the app exit function
// e.g., Application.Quit();
}
});
API Reference: AuthV4::showSignIn
// Hive SDK AuthV4 authentication UI request
AuthV4::showSignIn([=](ResultAPI const & result, PlayerInfo const & playerInfo) {
if (result.isSuccess()) {
// Authentication successful
// playerInfo: authenticated user information
// Example of retrieving email information
for(auto it = playerInfo.providerInfoData.begin(); it != playerInfo.providerInfoData.end(); ++it) {
hive::ProviderInfo providerInfo = it->second;
if(!providerInfo.providerEmail.empty()) {
std::string email = providerInfo.providerEmail;
break;
}
}
}
else if (result.needExit()) {
// TODO: Implement the app exit function
// Cocos2d-x engine users
// e.g., exit(0);
// Unreal engine users
// e.g., UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
}
});
API Reference: com.hive.AuthV4.showSignIn
// Hive SDK AuthV4 authentication UI request
AuthV4.showSignIn(object : AuthV4.AuthV4SignInListener {
override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
if (result.isSuccess) {
// Authentication successful
// playerInfo: authenticated user information
// Example of retrieving email information
playerInfo?.let {
for ((key, value) in it.providerInfoData) {
var providerInfo: AuthV4.ProviderInfo = value
if(providerInfo.providerEmail.isNotEmpty()) {
val email = providerInfo.providerEmail
break
}
}
}
} else if (result.needExit()) {
// TODO: Implement the app exit function
// e.g., exitProcess(0)
}
}
})
API Reference: com.hive.AuthV4.showSignIn
// Hive SDK AuthV4 authentication UI request
AuthV4.showSignIn(new AuthV4.AuthV4SignInListener() {
@Override
public void onAuthV4SignIn(ResultAPI result, AuthV4.PlayerInfo playerInfo) {
if (result.isSuccess()) {
// Authentication successful
// playerInfo: authenticated user information
// Example of retrieving email information
if(playerInfo != null) {
for (Map.Entry<AuthV4.ProviderType, AuthV4.ProviderInfo> entry : playerInfo.getProviderInfoData().entrySet()) {
AuthV4.ProviderInfo providerInfo = entry.getValue();
if (providerInfo.getProviderEmail() != "") {
String email = providerInfo.getProviderEmail();
break;
}
}
}
}
else if (result.needExit()) {
// TODO: Implement the app exit function
// e.g., System.exit(0);
}
}
});
API Reference: HIVEAuthV4:showSignIn
var email = String()
// Request Hive SDK AuthV4 authentication UI
AuthV4Interface.showSignIn { (result, playerInfo) in
if result.isSuccess() {
// Authentication successful
// playerInfo: authenticated user information
// Example of retrieving email information
if let playerInfo = playerInfo {
// Search for providerInfo with providerEmail (currently logged-in provider)
for key in playerInfo.providerInfoData.keys {
if let providerInfo = playerInfo.providerInfoData[key],
providerInfo.providerEmail.count > 0 {
// providerEmail != ""
email = providerInfo.providerEmail
break
}
}
}
} else if result.needExit() {
// TODO: Implement app exit functionality
// e.g., exit(0)
}
}
API Reference: HIVEAuthV4:showSignIn
__block NSString* email = @"";
// Request Hive SDK AuthV4 authentication UI
[HIVEAuthV4 showSignIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
if([result isSuccess]){
// Authentication successful
// playerInfo: authenticated user information
// Example of retrieving email information
if(playerInfo != nil) {
// Search for providerInfo with providerEmail (currently logged-in provider)
for (NSString* key in playerInfo.providerInfoData.allKeys) {
HIVEProviderInfo* providerInfo = playerInfo.providerInfoData[key];
if (providerInfo != nil && providerInfo.providerEmail.length > 0) {
// providerEmail != ""
email = providerInfo.providerEmail;
break;
}
}
}
} else if ([result needExit]) {
// TODO: Implement app exit functionality
// e.g., exit(0);
}
}];
If there is an existing authentication token key, the user can be automatically logged into the app. If the isAutoSignIn
received from the Hive SDK initialization response is true
, the user can be logged in automatically without using the login UI as shown above. Below is an example of calling the automatic login.
API Reference: hive.AuthV4.Helper.signIn
// Attempting Hive SDK signIn
AuthV4.Helper.signIn (delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) {
if (result.isSuccess()) {
// Login successful
} else if (result.needExit()) {
// TODO: Implement app exit functionality
// e.g., Application.Quit();
} else {
switch (result.code) {
case ResultAPI.Code.AuthV4ConflictPlayer:
// Account conflict
break;
case ResultAPI.Code.AuthV4HelperImplifiedLoginFail:
// Implicit login failed
// ex) AuthV4.showSignIn(...);
break;
default:
// Other exceptional situations
break;
}
}
});
API Reference: Auth4::signIn
// Attempting Hive SDK signIn
AuthV4::Helper::signIn([=](ResultAPI const & result, std::shared_ptr playerInfo) {
if (result.isSuccess()) {
// Login successful
} else if (result.needExit()) {
// TODO: Implement app exit functionality
// Cocos2d-x engine users
// e.g., exit(0);
// Unreal engine users
// e.g., UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
} else {
switch (result.code) {
case ResultAPI::AuthV4ConflictPlayer:
// Account conflict
break;
case ResultAPI::AuthV4HelperImplifiedLoginFail:
// Implicit login failed
// ex) AuthV4.showSignIn(...);
break;
default:
break;
}
}
});
API Reference: com.hive.Auth4.Helper.signIn
// Attempting Hive SDK signIn
AuthV4.Helper.signIn(object : AuthV4.Helper.AuthV4HelperListener {
override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
if (result.isSuccess) {
// Login successful
} else if (result.needExit()) {
// TODO: Implement app exit functionality
// e.g., exitProcess(0)
} else {
when (result.code) {
ResultAPI.Code.AuthV4ConflictPlayer -> {
// Account conflict
}
ResultAPI.Code.AuthV4HelperImplifiedLoginFail -> {
// Implicit login failed
// ex) AuthV4.showSignIn(...);
}
else -> {
// Other exceptional situations
}
}
}
}
})
API Reference: Auth4::signIn
// Attempt to sign in with Hive SDK
AuthV4.Helper.signIn(new AuthV4.Helper.AuthV4HelperListener() {
@Override
public void onAuthV4Helper(ResultAPI result, AuthV4.PlayerInfo playerInfo) {
if (result.isSuccess()) {
// Successful login
} else if (result.needExit()) {
// TODO: Implement app exit functionality
// e.g., System.exit(0);
} else {
switch (result.code) {
case AuthV4ConflictPlayer:
// Account conflict
break;
case AuthV4HelperImplifiedLoginFail:
// Implicit login failed
// e.g., AuthV4.showSignIn(...);
break;
default:
// Other exceptional situations
break;
}
}
}
});
API Reference: HIVEAuth4:signIn
// Attempt to sign in with Hive SDK
AuthV4Interface.helper().signIn() { (result, playerInfo) in
if result.isSuccess() {
// Successful login
}
else if result.needExit() {
// TODO: Implement app exit functionality
// e.g., exit(0)
}
else {
switch result.getCode() {
case .authV4ConflictPlayer:
// Account conflict
case .authV4HelperImplifiedLoginFail:
// Implicit login failed
// e.g., AuthV4Interface.showSignIn() { (result, playerInfo)
// // do something...
// }
default:
// Other exceptional situations
break
}
}
}
API Reference: HIVEAuth4:signIn
// Attempt to sign in with Hive SDK
[[HIVEAuthV4 helper] signIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
if (result.isSuccess) {
// Successful login
}
else if (result.needExit) {
// TODO: Implement app exit functionality
// e.g., exit(0);
}
else {
switch (result.code) {
case kAuthV4ConflictPlayer:
// Account conflict
break;
case kAuthV4HelperImplifiedLoginFail:
// Implicit login failed
// e.g., [HIVEAuthV4 showSignIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
// // do something...
// }];
break;
default:
// Other exceptional situations
break;
}
}
}];
In addition, we support customization features that allow users to implement their own login UI in their app without using Hive UI, and guest login features that allow users to use the app as a guest without selecting an IdP.
Info
For more details, refer to Login/Logout.
Verify login token¶
To prevent security incidents such as account theft or hacking, you must perform login token verification after the user logs in. Using the token, PlayerID, and DID returned after a successful login, your app server can verify whether the token key of the logged-in user is valid. Verify Login Token is performed by calling the Hive Server API > Auth v4 Verify Token API.
The Hive SDK by default allows duplicate logins for app accounts. Therefore, if you log in with one account on multiple devices, the session key generated at login is maintained on all devices. If you do not want to allow duplicate logins in your app, you must implement it so that only one session key is matched to one PlayerId (i.e., only one device is connected to the app server).
Info
For more details, refer to Verify Sign-In Token Key.
Implementing payments¶
The in-app item sales and payment features in the Hive SDK are implemented using the Hive SDK billing module, Hive IAP v4. Hive IAP v4 provides payment features that reduce development time and quickly respond to market changes, such as item purchase receipt verification, duplicate item payment checks, and payment log transmission.
Info
For more details, refer to this.
To use the payment features of the Hive SDK, you must first register the item product information for sale in the app market (Google Play) console and the Hive console.
Info
For detailed information, refer to the respective app market documentation and Hive console guide billing.
Initialize billing¶
After registering the product information in the app market console and the Hive console, you must execute the Hive IAP v4 initialization code when the app is launched to use Hive IAP v4. When you request Hive IAP v4 initialization, it returns the available market information from the app client as a result. Below is an example code for initializing Hive IAP v4.
API Reference: hive.IAPV4.marketConnect
API Reference: IAPV4::marketConnect
API Reference: IAPV4.marketConnect
API Reference: com.hive.IAPV4.marketConnect
API Reference: IAPV4Interface.marketConnect
API Reference: HIVEIAPV4::marketConnect
Info
For more details, please refer to IAP Initialization.
Get product list implementation¶
When users enter the in-app item store, you need to display the list of items for sale. To do this, implement the product list query. Below is an example code to request the product list.
API Reference: hive.IAPV4.getProductInfo
API Reference: IAPV4::getProductInfo
API Reference: IAPV4.getProductInfo
API Reference: com.hive.IAPV4.getProductInfo
API Reference: IAPV4Interface.getProductInfo
API Reference: HIVEIAPV4::getProductInfo
When performing a product list query, the result will return the product list information in the IAPV4Product
class. The product information includes marketPid
, which is used for item purchase requests, and displayPrice
, which is a combination of currency symbol and price (e.g., $0.99).
Info
For more details, please refer to Get Product List.
Implement product purchase¶
When users enter the app store and check the list of items for sale, they can select a specific item to purchase. To do this, you must call the purchase
method of the IAPV4 class with the marketPid
corresponding to the product ID as a parameter, requesting the app market to complete the item purchase. Below is an example code to request a product purchase.
API Reference: hive.IAPV4.purchase
API Reference: IAPV4::purchase
#include <HIVE_SDK_Plugin/HIVE_CPP.h>
using namespace std;
using namespace hive;
string marketPid = "{YOUR_PRODUCT_MARKET_PID}";
string iapPayload = "{YOUR_CUSTOM_PAYLOAD}";
IAPV4::purchase(marketPid, iapPayload, [=](ResultAPI const & result, IAPV4Receipt const & receipt) {
if (result.isSuccess()) {
// TODO: Request receipt verification with the received receipt
}
});
API Reference: com.hive.IAPV4.purchase
import com.hive.IAPV4
import com.hive.ResultAPI
val marketPid = "{YOUR_PRODUCT_MARKET_PID}"
val iapPayload = "{YOUR_CUSTOM_PAYLOAD}"
IAPV4.purchase(marketPid, iapPayload, object : IAPV4.IAPV4PurchaseListener {
override fun onIAPV4Purchase(result: ResultAPI, iapV4Receipt: IAPV4.IAPV4Receipt?) {
if (result.isSuccess) {
// Call successful
}
}
})
API Reference: com.hive.IAPV4.purchase
API Reference: HIVEIAPV4::purchase:additionalInfo:handler:
API Reference: HIVEIAPV4::purchase:additionalInfo:handler:
#import <HIVEService/HIVEService-Swift.h>
NSString *marketPid = @"{YOUR_PRODUCT_MARKET_PID}";
NSString *iapPayload = @"{YOUR_CUSTOM_PAYLOAD}";
[HIVEIAPV4 purchase: marketPid iapPayload: iapPayload handler: ^(HIVEResultAPI *result, HIVEIAPV4Receipt *receipt) {
if ([result isSuccess]) {
// TODO: Request receipt verification with the received receipt
}
}];
Before implementing the product purchase feature, you can predefine purchase metadata (iapPayload). iapPayload
is information defined in a format desired by the app developer. Using this, you can analyze user information that exploits the payment system or resolve situations where payment was made but the item was not delivered due to an error during purchase.
Info
For more details on product purchases, check here. For more details on purchasing subscription items, refer to here.
Verify receipt implementation¶
After executing the code that requests a product purchase, once the user completes the payment in the app market, the Hive SDK delivers the purchase receipt to the app client. Your app server should receive this receipt from the app client and verify its validity using Hive server API to verify the receipt. After verifying the receipt, the app server should directly provide the item to the user.
The Receipt Verification API verifies the receipt of the in-app purchased product and returns the result of the receipt's validity. The hiveiap_transaction_id
in the response is a unique ID issued for each receipt, so you should store this value in your app server and check for duplicate receipts before providing the item.
Info
For more details, refer to Verify Receipt.