Skip to main content

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.

warning

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}")
);
warning

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
);
warning

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
);
warning

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)
warning

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.

warning

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.

warning

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 integration@aghanim.com