Migrate to Unity SDK 2.0.0
Version 2.0.0 reshapes the error model and makes Initialize, SetPlayerId and ResetPlayerId asynchronous, where they used to be fire-and-forget.
This guide takes 1.13.2 as the starting point. On an older version, upgrade to 1.13.2 first, using the changelog for the breaking changes in between.
Install
Install 2.0.0 from the scoped registry as described in Integrate → Unity, then work through the sections below in order.
ApiError
Every onError callback receives an ApiError instead of a string.
// 1.13.2
void OnError(string error) => Debug.LogError(error);
// 2.0.0
void OnError(ApiError error) => Debug.LogError(error.DebugMessage);
You can branch on the failure:
void OnError(ApiError error)
{
switch (error)
{
case ApiError.Cancelled:
return;
case ApiError.Network:
case ApiError.Timeout:
case ApiError.ServerUnavailable:
ShowRetryPrompt();
break;
case ApiError.NotAuthenticated:
case ApiError.NotAuthorized:
ReAuthenticate();
break;
case ApiError.Server server:
Debug.LogError($"HTTP {server.Code}: {server.DebugMessage}");
break;
case ApiError.InvalidArgument argument:
Debug.LogError($"{argument.ArgumentName} is {argument.Reason}");
break;
default:
Debug.LogError(error.DebugMessage);
break;
}
}
Later versions can add cases, so keep a default branch; without one a new failure goes unreported.
DebugMessage is a non-localized diagnostic string. Never show it to players.
ApiError is in AghanimSdk.Runtime.Api.Result. For every case and what produces it, see Error reference.
Initialize
Initialize is now asynchronous, reporting through onSuccess and onError. The Initialize(AghanimLogLevel, IAghanimLogger) overload is removed, and log level and logger move onto AghanimConfig.
// 1.13.2
Aghanim.Initialize(AghanimLogLevel.DEBUG, new MyLogger());
// 2.0.0
var config = new AghanimConfig(apiKey)
{
MinLogLevel = AghanimLogLevel.DEBUG,
Logger = new MyLogger()
};
Aghanim.Initialize(
config,
onSuccess: () =>
{
// The SDK is ready. Make your first call from here.
},
onError: error => Debug.LogError($"Failed to initialize: {error.DebugMessage}")
);
Aghanim.Initialize(config) with no callbacks still compiles, and onError is now the only report of a failed initialization.
A second Initialize reports ApiError.AlreadyInitialized and never invokes onSuccess. The first configuration stays in effect.
AghanimConfigSO
AghanimConfigSO and the Aghanim Settings asset it created are removed. An existing asset in your project becomes a missing script after the upgrade. Delete it, and pass the API key to AghanimConfig from wherever you keep it.
Constructor validation
AghanimConfig, CheckoutParams and CheckoutItem constructors no longer throw on invalid input. They accept the value, and the failure surfaces as ApiError.InvalidArgument through the onError of whichever call consumes it.
// 1.13.2
try
{
var config = new AghanimConfig(apiKey);
}
catch (ArgumentNullException)
{
// blank key
}
// 2.0.0
Aghanim.Initialize(
config,
onSuccess: OnReady,
onError: error =>
{
if (error is ApiError.InvalidArgument { ArgumentName: InvalidArgumentName.ApiKey })
{
// blank key
}
}
);
Any catch around those constructors is now dead code. InvalidArgument carries ArgumentName and Reason.
SetPlayerId
SetPlayerId is now asynchronous, reporting through onSuccess and onError.
// 1.13.2
Aghanim.SetPlayerId(playerId);
Aghanim.GetUnconsumedOrders(onSuccess: OnOrders, onError: OnError);
// 2.0.0
Aghanim.SetPlayerId(
playerId,
onSuccess: () => Aghanim.GetUnconsumedOrders(onSuccess: OnOrders, onError: OnError),
onError: OnError
);
The 1.13.2 shape still compiles, so a call made straight after it can run before the ID is set.
ClearPlayerId
ClearPlayerId is now asynchronous, reporting through onSuccess and onError. It was called ResetPlayerId in 1.13.2.
// 1.13.2
Aghanim.ResetPlayerId();
// 2.0.0
Aghanim.ClearPlayerId(
onSuccess: () => ReturnToLoginScreen(),
onError: OnError
);
The 1.13.2 shape still compiles, so a sign-out that clears the ID and immediately fetches orders can still return the previous player's.
CheckoutParams
PriceTemplateId and CustomMessage are removed. Price comes from the item catalog.
// 1.13.2
CheckoutParams(
List<CheckoutItem> items,
Dictionary<string, string> metadata = null,
string priceTemplateId = null,
string locale = null,
string customMessage = null,
string backToGameUrl = null,
RedirectSettings redirectSettings = null,
UiSettings uiSettings = null)
// 2.0.0
CheckoutParams(
IReadOnlyList<CheckoutItem> items,
IReadOnlyDictionary<string, string> metadata = null,
string locale = null,
string backToGameUrl = null,
RedirectSettings redirectSettings = null,
UiSettings uiSettings = null)
A positional call such as new CheckoutParams(items, metadata, "tpl_123", "en") still compiles. "tpl_123" now binds to locale and "en" to backToGameUrl. Switch to named arguments before you upgrade, then upgrade.
CheckoutItem
CheckoutItem lost its quantity parameter. Unit count comes from the item catalog.
// 1.13.2
var item = new CheckoutItem(sku: "your-item-sku", quantity: 3);
// 2.0.0
var item = new CheckoutItem(sku: "your-item-sku");
StartCheckout
onError receives an ApiError instead of a string. If you use the onSuccess / onError pair, that is the only change, covered in ApiError.
The overload taking a single Action<CheckoutLaunchResult>, obsolete since before 1.13.2, is removed, along with the CheckoutLaunchResult and CheckoutLaunchResultType types.
// 1.13.2
Aghanim.StartCheckout(checkoutParams, LaunchMode.DefaultBrowser, result =>
{
if (result.Type == CheckoutLaunchResultType.Success) Save(result.OrderId);
});
// 2.0.0
Aghanim.StartCheckout(
checkoutParams,
LaunchMode.DefaultBrowser,
onSuccess: orderId => Save(orderId),
onError: OnError
);
ItemType
Unknown is new, and it sits first. An item type this SDK version does not recognize now arrives as ItemType.Unknown instead of failing the whole response, so give every switch (item.Type) a default branch.
A persisted (int)ItemType reads back as the next member along: Item was 0 and is now 1. Map the old number to the member name on load, and store names from then on.
Locale
OrderRead.Locale changed from string to Locale?, and is Unknown for a locale this SDK version does not recognize.
// 1.13.2
string locale = order.Locale;
// 2.0.0
Locale? locale = order.Locale;
Six members are new: Unknown, FrCa, Ms, Nl, No and Sv. They sit in alphabetical order, so every existing member's numeric value changed.
A persisted (int)Locale reads back as a different member: a saved Th of 14 now reads as Pl, and no single offset corrects every member. Map the old number to the member name on load, and store names from then on.
Editor, Standalone and WebGL
In 1.13.2 the SDK refused every call outside Android and iOS. In 2.0.0 the API works in the Editor, Standalone players and WebGL; for development, not for production use.
Only LaunchMode.DefaultBrowser is supported there.
Need help?
Contact our integration team at [email protected]