Skip to main content

QUICK START

Extended Example (IAP)

Xsolla SDK for Unity seamlessly integrates with Unity InAppPurchasing by providing an extension module for it.

This integration works seamlessly across both iOS and Android platforms, allowing you to implement in-app purchases effortlessly.

All you need to do is configure and initialize the module anywhere in your code before attempting to make a purchase.

Configuration & Initialization

PREREQUISITE

Make sure Unity In-App Purchasing 4.15+ is installed.

See the official Unity IAP setup guide ↗ (https://docs.unity3d.com/Packages/com.unity.purchasing@4.15/manual/GettingStarted.html).

⚠️ Unity In-App Purchasing 5.x is NOT supported at this moment.

public class MyIAPManager
{

// ...

public MyIAPManager()
{
var settings = XsollaStoreClientSettings.Builder.Create()
.SetProjectId(301871)
.SetLoginId("dfcb133b-6d0b-4937-b8d2-c4f4d58fb53a")
.SetSandbox(true)
.Build();

var configuration = XsollaStoreClientConfiguration.Builder.Create()
.SetSettings(settings)
.Build();

var module = XsollaPurchasingModule.Builder.Create()
.SetConfiguration(configuration)
.Build();

var builder = ConfigurationBuilder.Instance(module);

builder.AddProduct("money.100", ProductType.Consumable, new IDs
{
{ "money.100", XsollaPurchasingModule.StoreName },
{ "money_100_google", GooglePlay.Name },
{ "money_100_mac", MacAppStore.Name }
});

UnityPurchasing.Initialize(this, builder);
}

// ...

}
important

If you are using your own Project/Login IDs, make sure to enable Device ID login in your Project. Learn how to enable it here: https://developers.xsolla.com/sdk/publisher-account/login#enable-device-id-login-in-publisher-account

A fully-fledged implementation

We'll base our code on the existing official Unity IAP sample called "01 Buying Consumables":

publisher account 6

The code:

using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Extension;
using UnityEngine.UI;
using Xsolla.SDK.Common;
using Xsolla.SDK.Store;
using Xsolla.SDK.UnityPurchasing;

namespace Samples.Purchasing.Core.BuyingConsumables
{
public class BuyingConsumables : MonoBehaviour, IDetailedStoreListener
{
IStoreController m_StoreController; // The Unity Purchasing system.

//Your products IDs. They should match the ids of your products in your store.
public string moneyProductId = "money.100";
public string ticketProductId = "ticket.10";

public Text MoneyCountText;
public Text TicketCountText;

int m_MoneyCount;
int m_TicketCount;

void Start()
{
InitializePurchasing();
UpdateUI();
}

void InitializePurchasing()
{
//Remove this line from the original code.
//var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());

//Add these lines here..
var settings = XsollaStoreClientSettings.Builder.Create()
.SetProjectId(301871)
.SetLoginId("dfcb133b-6d0b-4937-b8d2-c4f4d58fb53a")
.SetSandbox(true)
.Build();

var configuration = XsollaStoreClientConfiguration.Builder.Create()
.SetSettings(settings)
.Build();

var module = XsollaPurchasingModule.Builder.Create()
.SetConfiguration(configuration)
.Build();

var builder = ConfigurationBuilder.Instance(module);

//Add products that will be purchasable and indicate its type.
builder.AddProduct(moneyProductId, ProductType.Consumable);
builder.AddProduct(ticketProductId, ProductType.Consumable);

UnityPurchasing.Initialize(this, builder);
}

public void BuyMoney()
{
m_StoreController.InitiatePurchase(moneyProductId);
}

public void BuyTicket()
{
m_StoreController.InitiatePurchase(ticketProductId);
}

public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
Debug.Log("In-App Purchasing successfully initialized");
m_StoreController = controller;
}

public void OnInitializeFailed(InitializationFailureReason error)
{
OnInitializeFailed(error, null);
}

public void OnInitializeFailed(InitializationFailureReason error, string message)
{
var errorMessage = $"Purchasing failed to initialize. Reason: {error}.";

if (message != null)
{
errorMessage += $" More details: {message}";
}

Debug.Log(errorMessage);
}

public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
{
//Retrieve the purchased product
var product = args.purchasedProduct;

//Add the purchased product to the players inventory
if (product.definition.id == moneyProductId)
{
AddMoney();
}
else if (product.definition.id == ticketProductId)
{
AddTicket();
}

Debug.Log($"Purchase Complete - Product: {product.definition.id}");

//We return Complete, informing IAP that the processing on our side is done and the transaction can be closed.
return PurchaseProcessingResult.Complete;
}

public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
{
Debug.Log($"Purchase failed - Product: '{product.definition.id}', PurchaseFailureReason: {failureReason}");
}

public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)
{
Debug.Log($"Purchase failed - Product: '{product.definition.id}'," +
$" Purchase failure reason: {failureDescription.reason}," +
$" Purchase failure details: {failureDescription.message}");
}

void AddMoney()
{
m_MoneyCount++;
UpdateUI();
}

void AddTicket()
{
m_TicketCount++;
UpdateUI();
}

void UpdateUI()
{
MoneyCountText.text = $"Your Money: {m_MoneyCount}";
TicketCountText.text = $"Your Tickets: {m_TicketCount}";
}
}
}