From package-guide
This skill should be used when the user asks to "add IAP", "implement in-app purchase", "add gem purchase", "create shop system", "integrate Unity Purchasing", "add consumable products", or needs to implement any in-app purchase system in a Unity project. Provides a complete implementation workflow for Unity IAP with clean architecture patterns.
npx claudepluginhub flashwade03/unity-dev-vibecoding-with-awesome-assets --plugin package-guideThis skill uses the workspace's default tool permissions.
Implement a Unity IAP (In-App Purchase) system for consumable products using Unity Purchasing package.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Implement a Unity IAP (In-App Purchase) system for consumable products using Unity Purchasing package. The architecture follows a clean separation pattern: a thin wrapper service handles platform communication, a ScriptableObject catalog defines products, and decoupled events handle UI communication.
UI (ShopPopup)
|
|-- [Purchase button click] --> Event: PurchaseRequested(productId)
|
IAPService (MonoBehaviour + IDetailedStoreListener)
|
|-- [Platform purchase flow]
|-- [Receipt validation]
|-- [Grant reward] --> CurrencyVariable += amount
|-- [Broadcast result] --> Event: PurchaseCompleted / PurchaseFailed
|
UI (ShopPopup)
|-- [Result event received] --> Update UI
Key Principles:
Add com.unity.purchasing via Package Manager or manifest.json.
IAPProductEntry - Serializable data class per product:
[Serializable]
public class IAPProductEntry
{
public string ProductId; // Must match store console ID
public int RewardAmount; // Currency amount to grant
public Sprite Icon; // Optional: for shop UI
}
IAPProductCatalog - ScriptableObject holding all products:
[CreateAssetMenu(menuName = "IAP/Product Catalog")]
public class IAPProductCatalog : ScriptableObject
{
public List<IAPProductEntry> Products = new();
public int GetRewardAmount(string productId)
{
return Products.Find(p => p.ProductId == productId)?.RewardAmount ?? 0;
}
}
Implement IDetailedStoreListener with this lifecycle:
Awake() - DontDestroyOnLoad(gameObject)Start() - InitializePurchasing() using ConfigurationBuilderOnEnable() - Subscribe to purchase request eventOnDisable() - Unsubscribe from purchase request eventCritical methods:
InitializePurchasing() - Register products from catalog, call UnityPurchasing.Initialize(this, builder)HandlePurchaseRequest(string productId) - Validate state, call _storeController.InitiatePurchase(product)ProcessPurchase(PurchaseEventArgs) - Validate receipt, grant reward, broadcast successOnPurchaseFailed(Product, PurchaseFailureDescription) - Broadcast failureprivate bool ValidateReceipt(string receipt)
{
#if UNITY_ANDROID && !UNITY_EDITOR
try
{
var validator = new CrossPlatformValidator(
GooglePlayTangle.Data(), null, Application.identifier);
validator.Validate(receipt);
return true;
}
catch (IAPSecurityException) { return false; }
#else
return true;
#endif
}
Pre-release requirement: Generate GooglePlayTangle.cs via:
Window > Unity IAP > IAP Receipt Validation Obfuscator
The shop UI should:
purchaseRequestEvent.Raise(productId) on button clickIAPService.GetLocalizedPrice(productId) for price displayAdd Unity.Purchasing.SecurityStub reference to the main asmdef for Editor compatibility
with Obfuscator/CrossPlatformValidator classes.
After implementation, generate a setup guide documenting:
Create ScriptableEvent<string> subclasses for purchase events. See references/implementation-patterns.md.
Use C# events or UnityEvent:
public static event Action<string> OnPurchaseRequested;
public static event Action<string> OnPurchaseCompleted;
public static event Action<string> OnPurchaseFailed;
| Pitfall | Solution |
|---|---|
Obfuscator not found in Editor | Add Unity.Purchasing.SecurityStub asmdef reference |
AppleTangle missing | Pass null to CrossPlatformValidator if Apple not targeted |
| Sirenix errors in test asmdef | Add Sirenix DLLs to precompiledReferences when overrideReferences: true |
| Pending purchases lost | Return PurchaseProcessingResult.Complete only AFTER granting reward |
| Price shows empty | GetLocalizedPrice() only works after OnInitialized callback |
references/implementation-patterns.md - Complete code templates with SOAP and non-SOAP variants