Unity SDK

Store Catalog

Pull a live storefront of items and bundles with translations, prices and images. Log soft-currency purchases for analytics, with on-device history that survives offline launches and a retry path for failed network logs.

Overview

KalmForge.StoreCatalog is a static class. Items and bundles are authored on the dashboard with prices, currencies, translations and images; the SDK fetches them in one call and exposes typed Item / Bundle records.

Note
Store Catalog is a Studio tier capability. Plan-gated server-side; the SDK returns an empty catalog if the project is not eligible.

Fetching the catalog

exampleC#
1var catalog = await StoreCatalog.GetAsync(lang: Localization.CurrentLanguage);
2foreach (var item in catalog.items)
3 Debug.Log($"{item.resolved.name} {item.price} {item.currency}");
4foreach (var b in catalog.bundles)
5 Debug.Log($"{b.resolved.name} contains {b.items.Count} items");

Loading images

exampleC#
1if (item.HasImage) {
2 var tex = await StoreCatalog.LoadTextureAsync(item);
3 var sprite = await StoreCatalog.LoadSpriteAsync(item);
4}

image is an opaque token, not a URL - always call the helpers; they sign the download via the SDK's HTTP layer.

Recording purchases

Use MakePurchaseAsync for the full flow - it appends to local history first (so HasPurchased / GetPurchaseCount reflect it immediately), then logs to the backend. Failed logs stay in history marked synced = false.

exampleC#
1var result = await StoreCatalog.MakePurchaseAsync(item, pricePaid: item.price);
2if (result.Synced) Debug.Log("Backend confirmed");
3
4// Bundles use the same overload:
5var b = await StoreCatalog.MakePurchaseAsync(bundle, pricePaid: bundle.price);
6
7// If you only want to log, without local history:
8await StoreCatalog.LogPurchaseAsync(item.id, null, item.price, item.currency);

Local history

exampleC#
1bool owns = StoreCatalog.HasPurchased(item);
2int copies = StoreCatalog.GetPurchaseCount(bundle);
3float totalUsd = StoreCatalog.GetTotalSpent("USD");
4var records = StoreCatalog.GetHistory(); // newest last
5
6StoreCatalog.ClearHistory(); // local only

Retrying failed logs

exampleC#
1int synced = await StoreCatalog.RetryUnsyncedAsync();
2Debug.Log($"resynced {synced} pending purchases");

API reference

StoreCatalog - static API
NameTypeDescription
GetAsync(lang?)Task<Catalog>Items + bundles localised to lang (or default).
LoadTextureAsync(item / bundle / token)Task<Texture2D>Download & decode an image to RGBA32.
LoadSpriteAsync(item / bundle / token)Task<Sprite>Same, wrapped as a Sprite (full-texture rect, pivot 0.5).
LogPurchaseAsync(itemId, bundleId, pricePaid, currency)Task<bool>Pure backend log. No local history side effects.
MakePurchaseAsync(item, pricePaid, currency?)Task<PurchaseResult>Append to local history + log to backend.
MakePurchaseAsync(bundle, pricePaid, currency?)Task<PurchaseResult>Same, for a bundle.
GetHistory()IReadOnlyList<PurchaseRecord>Snapshot of all locally recorded purchases.
HasPurchased(item / bundle)boolLocal-only check, no network.
GetPurchaseCount(item / bundle)intHow many times locally recorded.
GetTotalSpent(currency)floatSum of price_paid across history in the given currency.
ClearHistory()voidWipe local history. Backend records are untouched.
RetryUnsyncedAsync()Task<int>Re-log any records whose previous backend write failed.
HistoryFileNamestring (const)"kalmforge_purchases.json".

REST endpoint

examplebash
1# Fetch the catalog
2GET /api/public/sdk/catalog?lang=en
3Headers: X-API-Key: kf_xxx_yyy
4
5# Download an image (token comes from item.image / bundle.image)
6GET /api/public/sdk/catalog-image?path=<token>
7
8# Log a soft-currency purchase
9POST /api/public/sdk/catalog
10{ "item_id": "...", "bundle_id": null, "player_id": "...", "install_id": "...",
11 "price_paid": 4.99, "currency": "USD" }
Back to DocsKalmForge SDK · v1.0.1