In-app Purchase Integration
Overview
AccelByte Gaming Services (AGS) Starter In-app Purchase Integration enables you to track player purchases and sync entitlements from third-party platforms such as PlayStation or Xbox. This way, any In-app items that are sold and granted to players from third-party platforms will also be transferred to our AccelByte Gaming Services (AGS) Starter platform, so long as our platform has the proper item IDs set up. Items that can be sold include coins, bundles, loot boxes, and in-game items (consumable and durable).
Supported Platforms
Here's a table showing the platforms we support and the features each platform offers:
Platform | 3rd-party> Login | In-app Purchases | Entitlements |
Apple | N | Y | Y |
Google Play | N | Y | Y |
Epic Online Services | Y | Y | Y |
PlayStation 4 + 5 | Y | Y | Y |
Steam | Y | Y | Y |
Xbox Live | Y | Y | Y |
Twitch | Y | Y | Y |
Manage In-app Purchase Integration in the Admin Portal
Add a New Configuration
Before continuing on to the following steps, make sure you have registered the PS4 Client to our IAM.
In the desired game title, expand the E-Commerce section, click In-app Purchase, and select Third-party Store Integrations.
Select the platform you wish to configure from the tabs at the top and click Add Configuration.
NOTEEach game title can have only one configuration per third-party platform.
The Add Configuration form will appear. This will be different for each platform.
PSN
- Select the Environment, e.g. sp-int for Development, prod-qa for QA, or np for Live Environment.
Make sure you have also created a service in PlayStation Store Delivered Content inside your AppServer.
Xbox
- Input the Relying Party Private Key in Base64 format.
- Upload your Business Partner Certificate in .pfx format.
- Input your Certificate Password. This field is optional. If your certificate requires a password, you must input the password to continue.
Steam
Make sure you’ve created an item with the same SKU in both the Steam Store and your AccelByte Gaming Services (AGS) Starter Platform namespace. Once you've done this, input the Publisher Authentication Key.
Epic
Input the Sandbox ID of your Epic Developers account.
Google Play
Make sure you’ve created your android app and set the Product ID to Publish your app in the Google Play store.
- Input the Application Name you set in the Play Console.
- Input your Service Account ID.
- Upload your Business Certificate in .p12 format.
Apple
Make sure you’ve created an item in App Store Connect. Use the SKU/Item ID of this item as a Product ID to sync with your App in your namespace’s store.
- Input the Bundle ID.
- Input the Password with the App-Specific Shared Secret found in your item’s details in App Store Connect.
Once your configuration is complete, the information you have entered will be visible under the Configuration Details section of the relevant platform. You can also edit or remove configurations on this page.
Change Your Business Partner Certificate
In your desired game title, expand the E-Commerce section, click In-app Purchase, and select Third-party Store Integrations. Click the Xbox tab.
In the Configuration Details window, click Edit next to Business Partner Certificate.
The Change Business Partner Certificate form will appear. Fill in the required fields:
- Upload your Business Partner Certificate in .pkf format.
- Input your Certificate Password.
Integrate In-app Purchase using SDK
Sync Durable Entitlement
Epic Games
- Unreal Engine
- Unity
FString EpicGameJwtToken = TEXT("Some-token-value");
FRegistry::Entitlement.SyncEpicGameDurableItems(EpicGameJwtToken,
FVoidHandler::CreateLambda([&]()
{
UE_LOG(LogAccelByte, Log, TEXT("Success"));
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
UE_LOG(LogAccelByte, Error, TEXT("Error. Code: %d, Reason: %s"), ErrorCode, *ErrorMessage);
});
string epicGamesJwtToken = "token from epic games";
Result syncEpicGamesDurableItemsResult = null;
entitlement.SyncEpicGamesDurableItems(epicGamesJwtToken, result => syncEpicGamesDurableItemsResult = result);
yield return TestHelper.WaitForValue(() => syncEpicGamesDurableItemsResult);
TestHelper.Assert.IsTrue(syncEpicGamesDurableItemsResult.IsError, "sync epic games durable items failed.");
Xbox
- Unreal Engine
- Unity
FAccelByteModelsXBoxDLCSync XBoxDLCSyncToken;
XBoxDLCSyncToken.XstsToken = "XBox Xsts token from XBox One Manager sample apps";
FRegistry::Entitlement.SyncXBoxDLC(XBoxDLCSyncToken, FVoidHandler::CreateLambda([&bSyncDone]()
{
UE_LOG(LogAccelByte, Log, TEXT(" Success"));
}), FErrorHandler::CreateLambda([&bSyncDone](int32 ErrorCode, const FString& ErrorMessage)
{
bSyncDone = true;
UE_LOG(LogAccelByte, Error, TEXT("Error. Code: %d, Reason: %s"), ErrorCode, *ErrorMessage);
}));
XBoxDLCSync xBoxDLCSync = new XBoxDLCSync
{
xstsToken = "token from XBox One Manager"
};
Result syncXBoxDLCResult = null;
Entitlement entitlement = AccelBytePlugin.GetEntitlement();
entitlement.SyncXBoxDLC(xBoxDLCSync, result => {
syncXBoxDLCResult = result;
});
Third-Party Entitlement Consumption
- Unreal Engine
- Unity
void Entitlement::ConsumeUserEntitlement(FString const& EntitlementId, int32 const& UseCount, THandler<FAccelByteModelsEntitlementInfo> const& OnSuccess, FErrorHandler const& OnError,
TArray<FString> Options, FString const& RequestId )
{
FReport::Log(FString(__FUNCTION__));
FAccelByteModelsConsumeUserEntitlementRequest ConsumeUserEntitlementRequest;
ConsumeUserEntitlementRequest.UseCount = UseCount;
ConsumeUserEntitlementRequest.Options = Options;
ConsumeUserEntitlementRequest.RequestId = RequestId;
FString Url = FString::Printf(TEXT("%s/public/namespaces/%s/users/%s/entitlements/%s/decrement"), *SettingsRef.PlatformServerUrl, *CredentialsRef.GetNamespace(), *CredentialsRef.GetUserId(), *EntitlementId);
FString Content;
TSharedPtr<FJsonObject> Json = FJsonObjectConverter::UStructToJsonObject(ConsumeUserEntitlementRequest);
FAccelByteUtilities::RemoveEmptyStrings(Json);
TSharedRef<TJsonWriter<>> const Writer = TJsonWriterFactory<>::Create(&Content);
FJsonSerializer::Serialize(Json.ToSharedRef(), Writer);
HttpClient.ApiRequest("PUT", Url, {}, Content, OnSuccess, OnError);
}
public IEnumerator ConsumeUserEntitlement(string userId
, string entitlementId
, int useCount
, ResultCallback<EntitlementInfo> callback
, string[] options )
, string[] options
, string requestId)
{
Report.GetFunctionLog(GetType().Name);
Assert.IsNotNull(Namespace_, "Can't consume user entitlement! Namespace_ from parent is null!");
Assert.IsNotNull(AuthToken, "Can't consume user entitlement! AccessToken from parent is null!");
Assert.IsNotNull(userId, "Can't consume user entitlement! userId parameter is null!");
Assert.IsNotNull(entitlementId, "Can't consume user entitlement! entitlementId parameter is null!");
ConsumeUserEntitlementRequest consumeUserEntitlement = new ConsumeUserEntitlementRequest
{
useCount = useCount,
options = options
options = options,
requestId = requestId
};
var request = HttpRequestBuilder
.CreatePut(BaseUrl + "/public/namespaces/{namespace}/users/{userId}/entitlements/{entitlementId}/decrement")
.WithPathParam("namespace", Namespace_)
.WithPathParam("userId", userId)
.WithPathParam("entitlementId", entitlementId)
.WithBearerAuth(AuthToken)
.WithContentType(MediaType.ApplicationJson)
.WithBody(consumeUserEntitlement.ToUtf8Json())
.Accepts(MediaType.ApplicationJson)
.GetResult();
IHttpResponse response = null;
yield return HttpClient.SendRequest(request,
rsp => response = rsp);
var result = response.TryParseJson<EntitlementInfo>();
callback.Try(result);
}