Skip to content

New SDK Preview

This section is a preview of the new SDK. The new SDK is still in development, and we are actively working on improving it. We value your feedback, so if you have any questions or suggestions, please reach out to us. If you are not using the new SDK, please refer to another documentation section.

Shop

Balancy provides a comprehensive Game Shops system that allows developers to configure and manage in-game stores dynamically. The system supports multiple shop configurations, each containing pages and slots for various store items. This enables the creation of sophisticated store interfaces with tabbed navigation and grid-based item displays.

Shop Structure

The shop system is organized in a hierarchical structure:

  • Game Shops: Top-level containers that represent different stores (e.g., Main Shop, Event Shop, VIP Shop)
  • Shop Pages: Categories within a shop (e.g., Items, Weapons, Consumables)
  • Shop Slots: Individual items available for purchase within a page
  • Store Items: The actual purchasable items with pricing and rewards

Accessing Available Shops

To retrieve the list of available Game Shops, use the following method:

var shopsInfo = Balancy.Profiles.System.ShopsInfo;
var gameShops = shopsInfo.GameShops;
const shopsInfo = Balancy.Profiles.system.shopsInfo;
const gameShops = shopsInfo.gameShops;

This returns a collection of GameShop objects, each representing a unique shop configuration.

Working with Active Shop

You can access the currently active shop directly:

var activeShop = shopsInfo.ActiveShopInfo;
var shopName = activeShop?.Shop?.Name;
const activeShop = shopsInfo.activeShopInfo;
const shopName = activeShop?.shop?.name?.value;

The active shop is automatically determined by Balancy based on your dashboard configuration and user segmentation.

Accessing Shop Pages

Each Game Shop can have multiple pages for organizing items into categories. To retrieve and work with shop pages:

var shopPages = activeShop?.ActivePages;
var firstPage = shopPages?.FirstOrDefault();

// Iterate through all pages
foreach (var page in shopPages)
{
    Debug.Log($"Page: {page.Page?.Name}");
}
const shopPages = activeShop?.activePages?.toArray() || [];
const firstPage = shopPages.length > 0 ? shopPages[0] : null;

// Iterate through all pages
shopPages.forEach(page => {
    console.log(`Page: ${page.page?.name?.value}`);
});

Displaying Shop Slots and Store Items

Each Shop Page contains multiple Shop Slots, which reference store items available for purchase:

var shopSlots = selectedPage?.ActiveSlots;

foreach (var shopSlot in shopSlots)
{
    var storeItem = shopSlot.Slot?.StoreItem;
    var itemName = storeItem?.Name;
    var price = storeItem?.Price?.Product?.Price;
    var priceType = storeItem?.Price?.Type;

    Debug.Log($"Item: {itemName}, Price: {price}, Type: {priceType}");
}
const shopSlots = selectedPage?.activeSlots?.toArray() || [];

shopSlots.forEach(shopSlot => {
    const storeItem = shopSlot.slot?.storeItem;
    const itemName = storeItem?.name?.value;
    const price = storeItem?.price?.product?.price;
    const priceType = storeItem?.price?.type;

    console.log(`Item: ${itemName}, Price: ${price}, Type: ${priceType}`);
});

Shop Slot Availability and Limits

Shop slots can have various availability restrictions and purchase limits. Use these methods to check slot status:

// Check if slot is currently available for purchase
bool isAvailable = shopSlot.IsAvailable();

// Get seconds until slot becomes available
int secondsUntilAvailable = shopSlot.GetSecondsLeftUntilAvailable();

// Check if slot has purchase limits
bool hasLimits = shopSlot.HasLimits();

// Get purchase limit information
int purchaseLimit = shopSlot.GetPurchasesLimitForCycle();
int purchasesDone = shopSlot.GetPurchasesDoneDuringTheLastCycle();

Debug.Log($"Available: {isAvailable}");
Debug.Log($"Limit: {purchasesDone}/{purchaseLimit}");
// Check if slot is currently available for purchase
const isAvailable = shopSlot.isAvailable();

// Get seconds until slot becomes available
const secondsUntilAvailable = shopSlot.getSecondsLeftUntilAvailable();

// Check if slot has purchase limits
const hasLimits = shopSlot.hasLimits();

// Get purchase limit information
const purchaseLimit = shopSlot.getPurchasesLimitForCycle();
const purchasesDone = shopSlot.getPurchasesDoneDuringTheLastCycle();

console.log(`Available: ${isAvailable}`);
console.log(`Limit: ${purchasesDone}/${purchaseLimit}`);

Purchasing Shop Items

High-Level Purchase Methods

For most use cases, use the high-level purchase methods that handle all the complexity automatically:

// Purchase from shop slot (recommended)
Balancy.API.InitPurchaseShop(shopSlot, (success, errorMessage) => {
    if (success) {
        Debug.Log("Purchase successful!");
    } else {
        Debug.Log($"Purchase failed: {errorMessage}");
    }
});

// Direct store item purchase (use only when necessary)
Balancy.API.InitPurchase(storeItem, (success, errorMessage) => {
    Debug.Log($"Purchase result: {success}, Error: {errorMessage}");
});
// Purchase from shop slot (recommended)
Balancy.API.initPurchaseShop(shopSlot, (success, errorMessage) => {
    if (success) {
        console.log("Purchase successful!");
    } else {
        console.log(`Purchase failed: ${errorMessage}`);
    }
});

// Direct store item purchase (use only when necessary)
Balancy.API.initPurchase(storeItem, (success, errorMessage) => {
    console.log(`Purchase result: ${success}, Error: ${errorMessage}`);
});

Low-Level Purchase Methods

For advanced scenarios, you can use low-level purchase methods:

// Soft currency purchase
bool success = Balancy.API.SoftPurchaseShopSlot(shopSlot);

// Hard currency purchase (requires payment processing)
var paymentInfo = new Balancy.Core.PaymentInfo
{
    Receipt = receipt,
    Price = price,
    Currency = currency,
    ProductId = productId,
    OrderId = orderId
};

Balancy.API.HardPurchaseShopSlot(shopSlot, paymentInfo, (response) => {
    Debug.Log($"Purchase result: {response.Success}");
}, requireValidation: true);
// Soft currency purchase
const success = Balancy.API.softPurchaseShopSlot(shopSlot);

// Hard currency purchase (requires payment processing)
const paymentInfo = new BalancyPaymentInfo(
    price, receipt, productId, currency, orderId
);

Balancy.API.hardPurchaseShopSlot(shopSlot, paymentInfo, (response) => {
    console.log(`Purchase result: ${response.success}`);
}, true);

For detailed information about purchase methods and payment processing, refer to the API Documentation.

Listening for Shop Updates

Since shop contents may change dynamically based on events, segmentation, or time-based conditions, subscribe to onShopUpdated to refresh the shop interface:

Balancy.Callbacks.OnShopUpdated += () =>
{
    Debug.Log("Shop data updated - refreshing UI");
    RefreshShopDisplay();
};
const shopUpdatedId = Balancy.Callbacks.onShopUpdated.subscribe(() => {
    console.log("Shop data updated - refreshing UI");
    refreshShopDisplay();
});

// Unsubscribe when component is destroyed
Balancy.Callbacks.onShopUpdated.unsubscribe(shopUpdatedId);

Finding Shop Slots

You can search for specific shop slots using various methods:

var shopsInfo = Balancy.Profiles.System.ShopsInfo;

// Find slot by ID
var shopSlot = shopsInfo.FindShopSlotById("slot_123");

// Find slot by store slot reference
var shopSlotByReference = shopsInfo.FindShopSlot(storeSlot);

// Find slot within specific shop
var shopSlotInShop = activeShop.FindShopSlotById("slot_123");
const shopsInfo = Balancy.Profiles.system.shopsInfo;

// Find slot by ID
const shopSlot = shopsInfo.findShopSlotById("slot_123");

// Find slot by store slot reference
const shopSlotByReference = shopsInfo.findShopSlot(storeSlot);

// Find slot within specific shop
const shopSlotInShop = activeShop.findShopSlotById("slot_123");

Best Practices

  1. Always check availability before allowing purchases using shopSlot.IsAvailable()
  2. Display purchase limits to inform users about remaining purchases
  3. Subscribe to shop updates to keep the UI synchronized with server changes
  4. Use high-level purchase methods (InitPurchaseShop) for most scenarios
  5. Handle purchase callbacks to update UI and provide user feedback
  6. Implement proper error handling for failed purchases
  7. Cache shop data temporarily but refresh on updates to avoid stale information

Using these methods, you can create a fully dynamic in-game shop system where items, pages, pricing, and purchase logic are seamlessly managed by Balancy, providing a flexible and powerful e-commerce solution for your game.