using System; using Unity.Services.Core; using Unity.Services.Core.Environments; using UnityEngine; using UnityEngine.Purchasing; using UnityEngine.Purchasing.Extension; // using UnityEngine.Purchasing.Security; public class IAPController : MonoBehaviour, IDetailedStoreListener { public static IAPController Instance { get; private set; } private event Action OnInitializeComplete; private event Action OnPurchaseSuccessful; private event Action OnPurchaseFailure; [SerializeField] private string environment = "production"; [SerializeField] private string removeAdsId; private bool _isInitialized; private IStoreController _storeController; // private CrossPlatformValidator _validator; private void Awake() { if (Instance != null) return; Instance = this; // _validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), Application.identifier); } public void Initialize(Action onComplete) { OnInitializeComplete += onComplete; InitializeUnityServices(InitializePurchasing); } private async void InitializeUnityServices(Action onSuccess) { try { var options = new InitializationOptions().SetEnvironmentName(environment); await UnityServices.InitializeAsync(options); Debug.Log("Congratulations!\nUnity Gaming Services has been successfully initialized."); onSuccess?.Invoke(); } catch (Exception exception) { Debug.LogError($"Unity Gaming Services failed to initialize with error: {exception.Message}."); OnInitializeComplete?.Invoke(); OnInitializeComplete = null; } } private void InitializePurchasing() { var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); builder.AddProduct(removeAdsId, ProductType.NonConsumable); UnityPurchasing.Initialize(this, builder); } public void OnInitialized(IStoreController controller, IExtensionProvider extensions) { Debug.Log("In-App Purchasing successfully initialized"); _isInitialized = true; _storeController = controller; CheckForAdRemoval(); } public void OnInitializeFailed(InitializationFailureReason error) { Debug.LogError($"In-App Purchasing initialize failed: {error.ToString()}"); OnInitializeComplete?.Invoke(); OnInitializeComplete = null; } public void OnInitializeFailed(InitializationFailureReason error, string message) { Debug.LogError($"In-App Purchasing initialize failed: {error.ToString()} - {message}"); OnInitializeComplete?.Invoke(); OnInitializeComplete = null; } public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) { var product = args.purchasedProduct.definition.id; if (product.Equals(removeAdsId, StringComparison.Ordinal)) { OnPurchaseSuccessful?.Invoke(); OnPurchaseSuccessful = null; } Debug.Log($"Purchase Complete - Product: {product}"); return PurchaseProcessingResult.Complete; } /*private bool IsPurchaseValid(Product inProduct) { try { _validator.Validate(inProduct.receipt); } catch (IAPSecurityException reason) { Debug.Log($"Invalid receipt: {reason}"); return false; } return true; }*/ public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription) { OnPurchaseFailure?.Invoke(); OnPurchaseFailure = null; Debug.LogError($"Purchase failed - Product: '{product.definition.id}', PurchaseFailureReason: {failureDescription.message}"); } public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) { OnPurchaseFailure?.Invoke(); OnPurchaseFailure = null; Debug.LogError($"Purchase failed - Product: '{product.definition.id}', PurchaseFailureReason: {failureReason.ToString()}"); } public static void PurchaseAdRemoval(Action onComplete, Action onFail) { if (!Instance._isInitialized) { onFail?.Invoke(); return; } Instance.OnPurchaseSuccessful += onComplete; Instance.OnPurchaseFailure += onFail; Instance._storeController.InitiatePurchase(Instance.removeAdsId); } private void CheckForAdRemoval() { var disableAdsProduct = _storeController.products.WithID(removeAdsId); var areAdsAvailable = disableAdsProduct == null || !disableAdsProduct.hasReceipt; if (!areAdsAvailable) UnityAdController.DisableAds(); OnInitializeComplete?.Invoke(); OnInitializeComplete = null; } }