Monetization Module¶
The Monetization module provides unified interfaces for in-app purchases (IAP), advertising (multiple networks), and offerwalls.
Overview¶
| Namespace | IntelliVerseX.Monetization |
| Assembly | IntelliVerseX.Monetization |
| Dependencies | Platform SDKs (LevelPlay, Appodeal, AdMob), Unity Purchasing |
Components¶
IAP (In-App Purchases)¶
- Product catalog management
- Purchase flow handling
- Receipt validation
- Subscription management
Ads (Advertising)¶
- Rewarded video ads
- Interstitial ads
- Banner ads
- Ad network waterfall
Offerwalls¶
- Third-party offer integration
- Virtual currency rewards
IAP System¶
IVXIAPManager¶
public static class IVXIAPManager
{
// Events
public static event Action<IVXPurchaseResult> OnPurchaseComplete;
public static event Action<string> OnPurchaseFailed;
public static event Action OnRestoreComplete;
// State
public static bool IsInitialized { get; }
// Initialize
public static void Initialize(string[] productIds);
public static void Initialize(IVXIAPConfig config);
// Products
public static IVXProduct GetProduct(string productId);
public static List<IVXProduct> GetAllProducts();
// Purchase
public static void PurchaseProduct(string productId, Action<IVXPurchaseResult> callback = null);
// Restore
public static void RestorePurchases(Action<bool> callback = null);
}
Usage:
using IntelliVerseX.Monetization;
public class StoreController : MonoBehaviour
{
void Start()
{
// Subscribe to events
IVXIAPManager.OnPurchaseComplete += HandlePurchaseComplete;
IVXIAPManager.OnPurchaseFailed += HandlePurchaseFailed;
// Initialize with product IDs
IVXIAPManager.Initialize(new[]
{
"com.mygame.coins_100",
"com.mygame.coins_500",
"com.mygame.premium",
"com.mygame.subscription"
});
}
void BuyCoins(string productId)
{
IVXIAPManager.PurchaseProduct(productId, result =>
{
if (result.success)
{
// Grant coins
AddCoins(GetCoinsForProduct(productId));
ShowPurchaseSuccessUI();
}
});
}
void HandlePurchaseComplete(IVXPurchaseResult result)
{
Debug.Log($"Purchase complete: {result.productId}");
Debug.Log($"Transaction: {result.transactionId}");
}
void HandlePurchaseFailed(string error)
{
ShowErrorDialog(error);
}
void RestorePurchases()
{
IVXIAPManager.RestorePurchases(success =>
{
if (success)
ShowToast("Purchases restored!");
else
ShowToast("Restore failed");
});
}
}
IVXProduct¶
public class IVXProduct
{
public string productId;
public string title;
public string description;
public string price; // Formatted: "$4.99"
public decimal priceDecimal; // Raw: 4.99
public string currencyCode; // "USD"
public IVXProductType type;
public bool isAvailable;
}
public enum IVXProductType
{
Consumable,
NonConsumable,
Subscription
}
IVXSubscriptionManager¶
public class IVXSubscriptionManager
{
public static bool IsSubscribed(string productId);
public static DateTime? GetExpirationDate(string productId);
public static SubscriptionStatus GetStatus(string productId);
}
Advertising System¶
IVXAdsBootstrap¶
Automatic ad initialization component.
public class IVXAdsBootstrap : MonoBehaviour
{
[Header("Configuration")]
[SerializeField] private bool initializeOnStart = true;
[SerializeField] private IVXAdsConfig adsConfig;
// Initialize manually
public void Initialize();
}
Setup: 1. Add IVXAdsBootstrap prefab to your first scene 2. Configure ad unit IDs in the inspector 3. Ads will initialize automatically
Ad Network Waterfall¶
The SDK supports multiple ad networks with automatic fallback:
graph TD
A[Ad Request] --> B{LevelPlay Available?}
B -->|Yes| C[Show LevelPlay Ad]
B -->|No| D{Appodeal Available?}
D -->|Yes| E[Show Appodeal Ad]
D -->|No| F{AdMob Available?}
F -->|Yes| G[Show AdMob Ad]
F -->|No| H[No Ad Available] Rewarded Ads¶
// Check if ad is available
if (IVXAdsManager.IsRewardedAdReady())
{
// Show rewarded ad
IVXAdsManager.ShowRewardedAd(
onRewarded: () =>
{
// User earned reward
walletManager.AddCoins(100);
},
onClosed: () =>
{
// Ad closed (may or may not have earned)
},
onFailed: (error) =>
{
Debug.LogError($"Ad failed: {error}");
}
);
}
else
{
ShowNoAdAvailableUI();
}
Interstitial Ads¶
// Show at natural break points
public void OnLevelComplete()
{
// Show interstitial (non-blocking)
if (IVXAdsManager.IsInterstitialReady())
{
IVXAdsManager.ShowInterstitial(
onClosed: () => LoadNextLevel()
);
}
else
{
LoadNextLevel();
}
}
Banner Ads¶
// Show banner
IVXAdsManager.ShowBanner(BannerPosition.Bottom);
// Hide banner
IVXAdsManager.HideBanner();
// Destroy banner
IVXAdsManager.DestroyBanner();
WebGL Monetization¶
WebGL has a separate monetization system:
IVXWebGLAdsManager¶
public class IVXWebGLAdsManager
{
public static void ShowVideoAd(Action onComplete);
public static void ShowDisplayAd(Vector2 position, Vector2 size);
public static void HideDisplayAd();
}
IVXWebGLMonetizationManager¶
public class IVXWebGLMonetizationManager
{
public static void Initialize(IVXWebGLMonetizationSettings settings);
public static bool IsAdReady();
}
Offerwall¶
public class IVXOfferwallManager
{
public static bool IsAvailable { get; }
public static void ShowOfferwall();
public static event Action<int> OnOfferwallReward;
public static event Action OnOfferwallClosed;
}
Usage:
// Subscribe to rewards
IVXOfferwallManager.OnOfferwallReward += (coins) =>
{
walletManager.AddCoins(coins);
ShowToast($"Earned {coins} coins!");
};
// Show offerwall
if (IVXOfferwallManager.IsAvailable)
{
IVXOfferwallManager.ShowOfferwall();
}
Configuration¶
IVXAdsConfig¶
[Serializable]
public class IVXAdsConfig
{
[Header("Enable/Disable")]
public bool enableAds = true;
[Header("LevelPlay (IronSource)")]
public string levelPlayAndroidAppKey;
public string levelPlayIosAppKey;
[Header("Appodeal")]
public string appodealAndroidAppKey;
public string appodealIosAppKey;
[Header("AdMob")]
public string admobAndroidAppId;
public string admobIosAppId;
[Header("Ad Units")]
public string rewardedAdUnitId;
public string interstitialAdUnitId;
public string bannerAdUnitId;
}
IVXIAPConfig¶
[CreateAssetMenu(fileName = "IAPConfig", menuName = "IntelliVerse-X/IAP Configuration")]
public class IVXIAPConfig : ScriptableObject
{
public List<IVXProductDefinition> products;
public bool validateReceipts = true;
public bool restoreOnInit = true;
}
[Serializable]
public class IVXProductDefinition
{
public string productId;
public string productName;
public IVXProductType productType;
public int virtualCurrencyAmount;
}
Platform Notes¶
| Feature | Android | iOS | WebGL | Standalone |
|---|---|---|---|---|
| IAP | ✅ | ✅ | ❌ | ❌ |
| Rewarded Ads | ✅ | ✅ | ⚠️ | ❌ |
| Interstitials | ✅ | ✅ | ⚠️ | ❌ |
| Banners | ✅ | ✅ | ⚠️ | ❌ |
| Offerwalls | ✅ | ✅ | ❌ | ❌ |
⚠️ WebGL uses platform-specific implementation
Best Practices¶
Ad Frequency¶
// Don't show ads too frequently
private float _lastInterstitialTime;
private const float INTERSTITIAL_COOLDOWN = 60f; // 60 seconds
void TryShowInterstitial()
{
if (Time.time - _lastInterstitialTime < INTERSTITIAL_COOLDOWN)
return;
if (IVXAdsManager.IsInterstitialReady())
{
IVXAdsManager.ShowInterstitial();
_lastInterstitialTime = Time.time;
}
}
Purchase Validation¶
// Always validate purchases server-side
void HandlePurchaseComplete(IVXPurchaseResult result)
{
if (!result.success) return;
// Send receipt to server for validation
_ = ValidatePurchaseOnServer(result.receipt);
}
Error Handling¶
IVXIAPManager.OnPurchaseFailed += (error) =>
{
switch (error)
{
case "PurchaseCancelled":
// User cancelled - no error message needed
break;
case "NetworkError":
ShowErrorDialog("Please check your internet connection");
break;
default:
ShowErrorDialog($"Purchase failed: {error}");
break;
}
};
Testing¶
Test Mode¶
For development, use test ad unit IDs:
#if UNITY_EDITOR || DEVELOPMENT_BUILD
// Use test IDs
adsConfig.rewardedAdUnitId = "test_rewarded_ad";
#endif
IAP Testing¶
- Android: Use test accounts or license testing
- iOS: Use sandbox tester accounts
Related Documentation¶
- Ads Demo - Sample ad integration
- Ad Integration Guide - Step-by-step guide