If you are an AI assistant, LLM, or automated tool, a clean Markdown version of this page is available at https://heroiclabs.com/docs/hiro/unity/economy/virtual-store/llm.md — optimized for AI and LLM tools.
For hard currency items, use UnityPurchasingSystem. It wraps Unity’s purchasing package and handles the platform purchase flow, receipt submission to Nakama, and reward delivery sequencing for you.
Initialize it in your system list after EconomySystem, passing the same EconomySystem instance as a dependency. See Base for the full initialization code.
On initialization, UnityPurchasingSystem reads all store items that have a sku configured from the economy system and registers them with Unity Purchasing automatically. You don’t need to manage Unity Purchasing product registration separately.
1
2
3
PurchaseEventArgsresult=await_purchasingSystem.BuyProductAsync(storeItem);// or by store item IDPurchaseEventArgsresult=await_purchasingSystem.BuyProductByIdAsync("<itemId>");
You can manually add products which are not defined in the Economy system. These product definitions could come from the Unity IAP definitions. Products added this way cannot be used with BuyProductAsync or BuyProductByIdAsync to initiate a purchase. Both methods require items to be present in EconomySystem.StoreItems.
Handle both soft and hard currency purchase flows
#
The purchase flow depends on whether the store item is configured for game currency purchase (no sku) or in-app purchase (has sku). See Virtual Store purchases for details on how SKU configuration affects purchases.
This example shows how to handle both purchase types based on the store item’s configuration:
publicasyncTaskBuyStoreItem(IEconomyListStoreItemstoreItem){if(string.IsNullOrEmpty(storeItem.Cost.Sku)){// Soft currency purchase - server deducts currency and grants rewardIEconomyPurchaseAckresult=await_economySystem.PurchaseStoreItemAsync(storeItem.Id);// Show reward animation UI.ShowRewardAnimationUI(result.Reward);// Your custom function.}else{// IAP purchase - UnityPurchasingSystem handles the platform flow and Nakama validationtry{PurchaseEventArgsresult=await_unityPurchasingSystem.BuyProductByIdAsync(storeItem.Id);// Reward has already been granted by Nakama. Receipt is available for analytics.AnalyticsSendReceipt(result.purchasedProduct.receipt);// Your custom function.// Show reward animation UI.ShowRewardAnimationUI(storeItem.Reward);// Your custom function.}catch(PurchaseFailureExceptione){switch(e.Reason){caseUnityEngine.Purchasing.PurchaseFailureReason.UserCancelled:// Popup some UI.break;caseUnityEngine.Purchasing.PurchaseFailureReason.PaymentDeclined:// Popup some UI.break;caseUnityEngine.Purchasing.PurchaseFailureReason.ExistingPurchasePending:// Popup some UI.break;caseUnityEngine.Purchasing.PurchaseFailureReason.PurchasingUnavailable:caseUnityEngine.Purchasing.PurchaseFailureReason.ProductUnavailable:caseUnityEngine.Purchasing.PurchaseFailureReason.SignatureInvalid:caseUnityEngine.Purchasing.PurchaseFailureReason.DuplicateTransaction:caseUnityEngine.Purchasing.PurchaseFailureReason.Unknown:break;}}}}
Soft currency purchases will fail if the store item has a sku but you haven’t configured IAP validation on your server. Remove the sku from items that should only be purchasable with soft currency.