The creator-centric platform for building live games in Unity

Easily add social, commerce, and content management features to your live game with low-code, drag-and-drop prefabs fully integrated with your Unity workflow.

Adding Custom Store


The purpose of this guide is for game makers to setup a complete custom store experience using Beamable.

Here is everything needed to use the CommerceService in the "Beamable SDK for Unity".

Game Maker User Experience

During development, the game maker's user experience is as follows. There are 3 major parts to StoreStore - A collection of Beamable store listings setup process.


Follow these steps to get started.


Related Guides

A common use case for the feature is covered in the guides.



Step 1. Setup Unity IAP

ā€¢ See Using Store Flow Ā» Step 1. Setup Unity IAP

Step 2. Setup Platform

ā€¢ See Using Store Flow Ā» Step 2. Setup Platform

Step 3. Setup Beamable Content

ā€¢ See Using Store Flow Ā» Step 3. Setup Beamable Content

Step 4b. Setup Custom UI



  1. Create the custom store with C#

ā€¢ See the Example below

A highlight of the functionality is the Purchase method.


await _beamableAPI.CommerceService.Purchase(storeSymbol, listingSymbol);


Here are examples which cover common programming needs.


Beamable SDK Examples

ā€¢ This and all examples are available for download at

The CommerceServiceExample.cs demonstrates the custom store experience.

using System.Collections.Generic;
using Beamable.Examples.Shared;
using UnityEngine;
using UnityEngine.Events;
using Beamable.Api.Payments;
using Beamable.Common.Api.Inventory;
using Beamable.Common.Inventory;
using Beamable.Common.Shop;

namespace Beamable.Examples.Services.CommerceService
    public class RefreshedUnityEvent : UnityEvent<CommerceServiceExampleData> { }
    /// <summary>
    /// Demonstrates <see cref="CommerceService"/>.
    /// </summary>
    public class CommerceServiceExample : MonoBehaviour
        //  Events  ---------------------------------------
        public RefreshedUnityEvent OnRefreshed = new RefreshedUnityEvent();
        //  Fields  ---------------------------------------
        private const string ItemContentType = "items";
        private const string CurrencyContentType = "currency";
        private const string CurrencyType = "currency.Coin";
        private const string EmptyDisplayName = "[Empty]";
        private const string CurrencyDisplayName = "Coin";
        private StoreRef _storeRef = null;
        private StoreContent _storeContent = null;
        private IBeamableAPI _beamableAPI = null;
        private CommerceServiceExampleData _data = new CommerceServiceExampleData();
        //  Unity Methods  --------------------------------
        protected void Start()
            Debug.Log($"Start() Instructions...\n" +
                      " * Ensure Computer's Internet Is Active\n" +
                      " * Run The Scene\n" +
                      " * See Onscreen UI Show HasInternet = true\n" +
                      " * Ensure Computer's Internet Is NOT Active\n" +
                      " * See Onscreen UI Show HasInternet = false\n");

        //  Methods  --------------------------------------
        private async void SetupBeamable()
            _beamableAPI = await Beamable.API.Instance;

            Debug.Log($" = {}");

            _storeContent = await _storeRef.Resolve();

            // Observe Changes
            _beamableAPI.InventoryService.Subscribe(ItemContentType, Inventory_OnChanged);
            _beamableAPI.InventoryService.Subscribe(CurrencyContentType, Currency_OnChanged);
            _beamableAPI.CommerceService.Subscribe(_storeContent.Id, CommerceService_OnChanged);
            // Update UI Immediately
        public async void Buy()
            if (_data.SelectedItemData == null)
                Debug.LogError($"BuySelectedStoreItem() failed because _selectedItemData = {_data.SelectedItemData}.");

            if (!_data.CanAffordSelectedStoreItemData)
                Debug.LogError($"BuySelectedStoreItem() failed because CanAffordSelectedStoreItemData = {_data.CanAffordSelectedStoreItemData}.");

            // Buy!
            string storeSymbol = _storeContent.Id;
            string listingSymbol = _data.SelectedItemData.PlayerListingView.symbol;
            await _beamableAPI.CommerceService.Purchase(storeSymbol, listingSymbol);

        public void ResetPlayer()

        public void Refresh()
            string refreshLog = $"Refresh() ..." +
                                $"\n * StoreItemDatas.Count = {_data.StoreItemDatas.Count}\n\n" +
                                $"\n * InventoryItemDatas.Count = {_data.InventoryItemDatas.Count}\n\n" +
                                $"\n * CurrencyAmount.Count = {_data.CurrencyAmount}\n\n";
            _data.InstructionLogs.Add("Click `Buy` to add 1 item to Inventory");
            _data.InstructionLogs.Add("or Click `Reset` to delete and create a new player");
            // Send relevant data to the UI for rendering
        //  Event Handlers  -------------------------------
        private async void Inventory_OnChanged(InventoryView inventoryView)
            foreach (KeyValuePair<string, List<ItemView>> kvp in inventoryView.items)
                string itemName = ExampleProjectHelper.GetDisplayNameFromContentId(kvp.Key);
                ItemContent itemContent = await CommerceServiceHelper.GetItemContentById(_beamableAPI, kvp.Key);

                string title = $"{itemName} x {kvp.Value.Count}";
                ItemData itemData = new ItemData(title, itemContent, null);

            if (_data.InventoryItemDatas.Count == 0)
                // Show "Empty"
                _data.InventoryItemDatas.Add(new ItemData(EmptyDisplayName, null, null));


        private async void Currency_OnChanged(InventoryView inventoryViewForCurrencies)
            _data.CurrencyAmount = 0;
            foreach (KeyValuePair<string, long> kvp in inventoryViewForCurrencies.currencies)
                if (kvp.Key == CurrencyType)
                    _data.CurrencyAmount = (int)kvp.Value;
                string itemName = ExampleProjectHelper.GetDisplayNameFromContentId(kvp.Key);
                CurrencyContent currencyContent = await CommerceServiceHelper.GetCurrencyContentById(_beamableAPI, kvp.Key);
                _data.CurrencyContent = currencyContent;
                _data.CurrencyLogs.Add($"{itemName} x {kvp.Value}");
            if (_data.CurrencyLogs.Count == 0)

        private async void CommerceService_OnChanged(PlayerStoreView playerStoreView)

            foreach (PlayerListingView playerListingView in playerStoreView.listings)
                int price = playerListingView.offer.price.amount;   
                string contentId = playerListingView.offer.obtainItems[0].contentId;
                string itemName = ExampleProjectHelper.GetDisplayNameFromContentId(contentId);
                ItemContent itemContent = await CommerceServiceHelper.GetItemContentById(_beamableAPI, contentId);

                string title = $"{itemName} ({price} {CurrencyDisplayName})";
                ItemData itemData = new ItemData(title, itemContent, playerListingView);
            if (_data.StoreItemDatas.Count == 0)
                // Show "Empty"
                _data.StoreItemDatas.Add(new ItemData(EmptyDisplayName, null, null));


This section contains any advanced configuration options and workflows.

ā€¢ See Using Store Flow Ā» Advanced

Updated about a month ago

Adding Custom Store

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.