// // /*===============================================================================
// // Copyright (C) 2024 PhantomsXR Ltd. All Rights Reserved.
// //
// // This file is part of the Nin1.Runtime.
// //
// // The Nin1 cannot be copied, distributed, or made available to
// // third-parties for commercial purposes without written permission of PhantomsXR Ltd.
// //
// // Contact nswell@phantomsxr.com for licensing requests.
// // ===============================================================================*/
#if UNITY_IN_APP_PURCHASE
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Phantom.XRMOD.InAppPurchase.Runtime
{
///
/// Manages In-App Purchases (IAP).
/// Handles product initialization, purchase flow, and restoration.
///
public class InAppPurchaseManager
{
public Action OnPurchaseStateChange;
public Action OnPurchaseFailedHandler;
public Action OnRestoreHandler;
private IPurchaseAPI purchaseAPI;
private static InAppPurchaseManager _INSTANCE;
public static InAppPurchaseManager GetInstance => _INSTANCE ??= new();
private InAppPurchaseManager()
{
}
///
/// Initialize in-app purchase products
///
/// The products for in-app purchase
public async Task Initialization(ProductData[] _productDatas)
{
try
{
#if QUEST_INSTALL && !UNITY_EDITOR && META_PLATFORM_PLUGIN_INSTALL
purchaseAPI = new OculusInAppPurchase(new PurchaseCallback
{
OnPurchaseStateChange = this.OnPurchaseStateChange,
OnPurchaseFailedHandler = this.OnPurchaseFailedHandler,
OnRestoreHandler = this.OnRestoreHandler
});
#elif (UNITY_IOS || UNITY_ANDROID || UNITY_TVOS || UNITY_VISIONOS) && !UNITY_EDITOR
purchaseAPI = new AppleAppPurchase(new PurchaseCallback
{
OnPurchaseStateChange = this.OnPurchaseStateChange,
OnPurchaseFailedHandler = this.OnPurchaseFailedHandler,
OnRestoreHandler = this.OnRestoreHandler
});
#else
purchaseAPI = new UnityEditorPurchase(new PurchaseCallback
{
OnPurchaseStateChange = this.OnPurchaseStateChange,
OnPurchaseFailedHandler = this.OnPurchaseFailedHandler,
OnRestoreHandler = this.OnRestoreHandler
});
#endif
await purchaseAPI.FetchProduct(_productDatas);
}
catch (Exception e)
{
throw; // TODO handle exception
}
}
///
/// But the product via product id
///
/// Will be but product id
public Task BuyProduct(string _productId) => purchaseAPI.BuyProduct(_productId);
///
/// Restore your product
///
public async Task Restore() => await purchaseAPI.RestoreProduct();
///
/// Check the product is purchased
///
/// Provide the product id to check purchase state
/// If the return value is True,
/// it means that the current product has been purchased and vice versa.
///
public async Task IsPurchased(string _productId) => await purchaseAPI.IsPurchased(_productId);
///
/// Get a list of products that can be purchased in-app.
///
/// List of products
public async Task> GetProducts() => await purchaseAPI.GetProducts();
}
}
#endif