Copyright (c) 2025 AccelByte Inc. All Rights Reserved. This is licensed software from AccelByte Inc, for limitations and restrictions contact your company contract manager.
Unity SDK Google is an extension package to enable Accelbyte SDK support for Android Google Authentication and Authorization.
-
AccelByte Unity SDK minimum version: 17.6.0. For more information about configuring AccelByte Unity SDK, see Install and configure the SDK.
-
Android minimum API level 30.
Unity SDK Google requires following additional configuration:
- Android Credentials Manager library.
Android Credentials Manager provides unified access to a user's credentials to provide seamless and secure sign-in experiences. Required configuration will be included in
Assets\Plugins\Android\gradleTemplate.propertiesand you could import it fromAccelByteUnitySdkGoogle.unitypackage. - Customized Unity Activity.
AccelByteUnitySdkGoogle.unitypackagewill provideAccelBytePlayerActivity.javaextendingUnityPlayerActivityto interact with the Google login activity result and customizedAndroidManifest.xmlto set theAccelBytePlayerActivity.javaas the application entry point.
-
In your Unity project, go to
Window > Package Manager. -
Click the + icon on the Package Manager window and click
Add package from git URL... -
Paste the following link into the URL field and click Add:
https://github.com/AccelByte/accelbyte-unity-sdk-google.git. -
Install
_Install/AccelByteUnitySdkGoogle.unitypackageto your game directory. Import all of the item if there's no conflict with your Android build configuration files. -
If there is any conflict with your current Android build configuration, please follow these guide how to merge them:
-
If you're using custom main activity extending
UnityPlayerActivity, ignoreAndroidManifest.xmlfrom the package, and add the following code toYourCustomUnityPlayerActivityto allow AccelByte SDK get the login activity result when requesting additional scopes:import com.accelbyte.googlesigninlib.AccelByteGoogleSignIn; import static com.accelbyte.googlesigninlib.AccelByteConst.REQUEST_AUTHORIZE; public class YourCustomUnityPlayerActivity extends UnityPlayerActivity { protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_AUTHORIZE) { AccelByteGoogleSignIn.getInstance().onActivityResult(resultCode, data, this); } } }
-
If your'e enabling custom main gradle template, ignore
mainTemplate.gradlefrom the package, and add the following configuration to yourAssets\Plugins\Android\mainTemplate.gradleto enable androidX library.**ADDITIONAL_PROPERTIES** android.useAndroidX=true android.enableJetifier=true
-
If you're enabling Custom Gradle Properties Template, ignore
gradleTemplate.propertiesfrom the package, and add the following configuration to yourAssets\Plugins\Android\gradleTemplate.propertiesto add required libraries into your project.apply plugin: 'com.android.library' **APPLY_PLUGINS** dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.credentials:credentials:1.3.0' implementation 'androidx.credentials:credentials-play-services-auth:1.3.0' implementation 'com.google.android.libraries.identity.googleid:googleid:1.1.1' implementation 'com.google.android.gms:play-services-auth:16.0.1' **DEPS**}
-
If you're using
Unity 6, ignoreAndroidManifest.xmlandAccelBytePlayerActivity.javafrom the package. Requesting additional scopes is still under development onUnity 6.
-
-
Add assembly reference of
com.AccelByte.GoogleExtensionto your project.
- Requesting additional scopes on
Unity 6is still under development.
We provide easier way to let player perform Sign in With Google platform. Therefore player doesn't need to register a new account to AGS to utilize the AGS features.
To get the client ID for your game from Google Cloud, follow this documentation.
- Open AccelByte Client Configuration on
AccelByte > Edit Client Settings. - Find
Google Configssection and fillGoogle Web Client Idfield using generated Google Client Id.
- Header Initialization
using AccelByte.Core;
using AccelByte.Models;- Get Google Id Token and Server Auth Code
private string googleIdToken;
private string googleAuthCode;
private AccelByte.ThirdParties.Google.AccelByteGoogle accelByteGoogle;
void Start()
{
AGSInitialize();
}
void AGSInitialize()
{
accelByteGoogle = new AccelByte.ThirdParties.Google.AccelByteGoogle();
}
void GetSignInWithGoogle()
{
var optionalParams = new AccelByte.ThirdParties.Google.GetSignInWithGoogleOptionalParameters()
{
RequestServerAuthCode = true,
Scopes = new string[]
{
"profile",
"email"
}
};
accelByteGoogle.GetSignInWithGoogle(optionalParams)
.OnSuccess((result) =>
{
googleIdToken = result.IdToken;
googleAuthCode = result.ServerAuthCode;
UnityEngine.Debug.Log("Sign in with Google succeeded");
})
.OnFailed((error) =>
{
UnityEngine.Debug.LogWarning($"Sign in with Google failed: {error.Message}");
});
}- Login to AGS
private void AGSLogin()
{
if (!string.IsNullOrEmpty(googleIdToken))
{
var optionalParams = new LoginWithOtherPlatformV4OptionalParameters()
{
CreateHeadless = false
};
AccelByteSDK.GetClientRegistry().GetApi().GetUser().LoginWithOtherPlatformV4(
new Models.LoginPlatformType(AccelByte.Models.PlatformType.Google)
, googleIdToken
, optionalParams
, result =>
{
if (result.IsError)
{
UnityEngine.Debug.LogWarning($"Login with AGS failed [{result.Error.error}]: {result.Error.error_description}");
return;
}
UnityEngine.Debug.Log("Login with AGS succeeded");
});
}
}The full script on the package sample named Sign in with Google.
There are three kinds of ProductType based on Unity Documentation. Previously we supported synchronizing consumable, non-consumable entitlements with the AccelByte server. And now also supports subscriptions as well.
Please contact AccelByte support for guideline document
- Import package UnityPurchasing library to the project.
- Please refers to official Unity documentation on how to install it.
- Open
File > Build Settings > Player Settings. OnPlayercategories, navigate toAndroid Settingsbuild section. Please checkCustom main gradle templateandCustom Gradle Properties Templateto avoid duplicated class exception.
Important : Ensure that the player is already Logged in using AGS service before using this feature. You may check player's login status by using this snippet
bool isLoggedIn = AccelByteSDK.GetClientRegistry().GetApi().GetUser().Session.IsValid();and isLoggedIn should returntrue.
- Sign in With Google, please refer to previous part
- Please create
MonoBehaviorclass implementingIDetailedStoreListener. Unity IAP will handle the purchase and trigger callbacks using this interface. Then prepare the following variables.
IStoreController storeController;
public Button BuyGoldButton;
public Button BuyWeaponButton;
public Button BuySeasonPassButton;
private string goldProductId = "item_gold"; // assume that the registered consumable product id is named Item_gold
private ProductType goldProductType = ProductType.Consumable;
private string weaponProductId = "item_weapon"; // assume that the registered non-consumable product id is named item_weapon
private ProductType weaponProductType = ProductType.NonConsumable;
private string seasonPassProductId = "item_season_pass"; // assume that the registered subscription product id is named item_season_pass
private ProductType seasonPassProductType = ProductType.Subscription;- Prepare three Buttons to login and trigger the purchasing event. Using Unity Editor's inspector, attach those buttons into
public Button BuyGoldButton;,public Button BuyWeaponButton;, andpublic Button BuySeasonPassButton;. - Initialize Purchasing.
void Start()
{
InitializePurchasing();
}
void InitializePurchasing()
{
var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
if (!string.IsNullOrEmpty(user.Session.UserId))
{
var uid = System.Guid.Parse(user.Session.UserId);
builder.Configure<IGooglePlayConfiguration>().SetObfuscatedAccountId(uid.ToString().Replace("-",""));
}
//Add products that will be purchasable and indicate its type.
builder.AddProduct(GoldProductId, GoldProductType);
builder.AddProduct(WeaponProductId, WeaponProductType);
builder.AddProduct(SeasonPassProductId, SeasonPassProductType);
UnityPurchasing.Initialize(this, builder);
}
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
Debug.Log("In-App Purchasing successfully initialized");
storeController = controller;
}- Prepare several functions that will be trigger the purchasing event
private void BuyGold()
{
storeController.InitiatePurchase(productId);
}
private void BuyWeapon()
{
storeController.InitiatePurchase(weaponProductId);
}
private void BuySeasonPass()
{
storeController.InitiatePurchase(seasonPassProductId);
}- Assign each buttons
void Start()
{
ButtonAssigning();
}
void ButtonAssigning()
{
BuyGoldButton.onClick.AddListener(BuyGold);
BuyWeaponButton.onClick.AddListener(BuyWeapon);
BuySeasonPassButton.onClick.AddListener(BuySeasonPass);
}- Handle Process Purchase. Please note that it must return
PurchaseProcessingResult.Pendingbecause purchased item will be synchronized with AccelByte's Backend. reference. If client successfully purchase item from Google Play Store,ProcessPurchasewill be triggered, elseOnPurchaseFailedwill be triggered.
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
{
var product = purchaseEvent.purchasedProduct;
Debug.Log($"Purchase Complete - Product: {product.definition.id}");
if (product.definition.type == ProductType.Subscription)
{
AGSSubscriptionEntitlementSync(product);
}
else
{
AGSEntitlementSync(product);
}
return PurchaseProcessingResult.Pending;
}
public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
{
Debug.LogError($"Purchase failed - Product: '{product.definition.id}', PurchaseFailureReason: {failureReason}");
}- Sync Purchased Product with AGS
private void AGSEntitlementSync(Product product)
{
// Please note that Sync will work after the player is logged in using AB service
// Please refer to https://github.com/AccelByte/accelbyte-unity-sdk-google-play?tab=readme-ov-file#sign-in-with-google-play-games for implementation
try
{
string receiptPayload = JObject.Parse(product.receipt)["Payload"].ToString();
var receiptJson = JObject.Parse(receiptPayload)["json"].ToString();
var receiptObject = JObject.Parse(receiptJson);
var orderId = ((string)receiptObject["orderId"]);
var packageName = ((string)receiptObject["packageName"]);
var productId = ((string)receiptObject["productId"]);
var purchaseTime = ((long)receiptObject["purchaseTime"]);
var purchaseToken = ((string)receiptObject["purchaseToken"]);
var autoAck = product.definition.type == ProductType.NonConsumable;
entitlement.SyncMobilePlatformPurchaseGoogle(
orderId
, packageName
, productId
, purchaseTime
, purchaseToken
, autoAck
, syncResult =>
{
if (syncResult.IsError)
{
UnityEngine.Debug.LogWarning(syncResult.Error.Message);
return;
}
if (syncResult.Value.NeedConsume)
{
FinalizePurchase(product);
}
});
}
}
catch (Exception e)
{
UnityEngine.Debug.LogWarning($"Failed to sync with AB {e.Message}");
}
}
private void AGSSubscriptionEntitlementSync(Product purchasedSubscription)
{
// Please note that Sync will work after the player is logged in using AB service
try
{
string receiptPayload = JObject.Parse(product.receipt)["Payload"].ToString();
var receiptJson = JObject.Parse(receiptPayload)["json"].ToString();
var receiptObject = JObject.Parse(receiptJson);
var orderId = ((string)receiptObject["orderId"]);
var packageName = ((string)receiptObject["packageName"]);
var productId = ((string)receiptObject["productId"]);
var purchaseTime = ((long)receiptObject["purchaseTime"]);
var purchaseToken = ((string)receiptObject["purchaseToken"]);
var autoAck = true;
entitlement.SyncMobilePlatformSubscriptionGoogle(
orderId
, packageName
, productId
, purchaseTime
, purchaseToken
, autoAck
, syncResult =>
{
if (syncResult.IsError)
{
UnityEngine.Debug.LogWarning(syncResult.Error.Message);
return;
}
if (syncResult.Value.NeedConsume)
{
FinalizePurchase(product);
}
});
}
}Please note that when syncing subscription product, if
autoAckset tofalse, Game client need to manual ack it, otherwise this transaction will be expired. Iftrue, game client don’t need to do anything.
- Finalize Pending Purchase
private void FinalizePurchase(Product purchasedProduct)
{
Debug.Log($"Confirm Pending Purchase for: {purchasedProduct.definition.id}");
storeController.ConfirmPendingPurchase(purchasedProduct);
}The full script on the package sample named In App Purchase.