using OneStore.Auth; using OneStore.Common; // 지우면 안됨 using OneStore.Purchasing; using System; using System.Collections.Generic; using System.Collections.ObjectModel; // 지우면 안됨 using System.Text; using UnityEngine; using UnityEngine.Events; using UnityEngine.Purchasing; using UnityEngine.Purchasing.Extension; public class IAPManager : MonoBehaviour, IDetailedStoreListener { private IStoreController storeController; //구매 과정을 제어하는 함수 제공자 private IExtensionProvider storeExtensionProvider; //여러 플랫폼을 위한 확장 처리 제공자 private StringBuilder sb = new StringBuilder(); public UnityAction OnProcessPurchase; public UnityAction OnProcessPurchaseFailed; private bool isInitialize = false; private static readonly string TAG = "IAPManager"; string[] all_products = { "com.fgb.cash500", "com.fgb.cash2000", "com.fgb.cash7500", "com.fgb.heart20", "com.fgb.heart150", "com.fgb.heart500" }; private Dictionary signatureMap = new Dictionary(); string onstore_publickey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCCkywe50yx7BpLXxrkothbVVY5hyHNq/L4u0ExhMxIY7lj6yX4TZjQtWGr+gPakI28RNO8QEVMBtDxtWb1/JyMPIcqzwLqqwYhFdtUxNSkIOpZHDx8+spXotwcKG6zm5w7c8iXcHg8hnlrUArLYdNcRh/cMu+bHIAsx1BKS5rDSwIDAQAB"; PurchaseClientImpl m_PurchaseClientImpl; OneStoreIapCallBack m_OneStoreIapCallBack = new OneStoreIapCallBack(); void Start() { Init_IAP(); //if (GameManager.Network != null) //{ // if (GameManager.Network.IsOnline) // { // Init_IAP(); //Start 문에서 초기화 필수 // } // GameManager.Network.OnNetworkOnline += OnNetworkOnline; //} } private void Init_IAP() { #if UNITY_EDITOR Init_Google(); #else Debug.Log("StoreEnvironment.GetStoreType() " + StoreEnvironment.GetStoreType()); if (StoreEnvironment.GetStoreType() == StoreType.ONESTORE) { m_PurchaseClientImpl = new PurchaseClientImpl(onstore_publickey); m_PurchaseClientImpl.Initialize(m_OneStoreIapCallBack); m_OneStoreIapCallBack.m_PurchaseClientImpl = m_PurchaseClientImpl; m_PurchaseClientImpl.QueryProductDetails(new ReadOnlyCollection(all_products), OneStore.Purchasing.ProductType.ALL); // 상품 정보 받아오기 m_PurchaseClientImpl.QueryPurchases(OneStore.Purchasing.ProductType.INAPP); // 미지급된 상품이 있는 지 체크 } else Init_Google(); #endif isInitialize = true; } void Init_Google() { ConfigurationBuilder builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); /* 구글 플레이 상품들 추가 */ //builder.AddProduct("com.fgb.adsremove", ProductType.Consumable); builder.AddProduct("com.fgb.cash500", UnityEngine.Purchasing.ProductType.Consumable); builder.AddProduct("com.fgb.cash2000", UnityEngine.Purchasing.ProductType.Consumable); builder.AddProduct("com.fgb.cash7500", UnityEngine.Purchasing.ProductType.Consumable); builder.AddProduct("com.fgb.heart20", UnityEngine.Purchasing.ProductType.Consumable); builder.AddProduct("com.fgb.heart150", UnityEngine.Purchasing.ProductType.Consumable); builder.AddProduct("com.fgb.heart500", UnityEngine.Purchasing.ProductType.Consumable); UnityPurchasing.Initialize(this, builder); } /* 구매하는 함수 */ public void Purchase(string productId) { //// 게등위 테스트용 //AddProductItem(productId); //OnProcessPurchase?.Invoke(productId); //return; #if UNITY_EDITOR BuyItem(productId); #else if (StoreEnvironment.GetStoreType() == StoreType.ONESTORE) { ProductDetail productDetail = m_OneStoreIapCallBack.Get_ProductDetail(productId); if (productDetail != null) { OneStore.Purchasing.ProductType productType = OneStore.Purchasing.ProductType.Get(productDetail.type); var purchaseFlowParams = new PurchaseFlowParams.Builder() .SetProductId(productId) // mandatory .SetProductType(productType) // mandatory .Build(); m_PurchaseClientImpl.Purchase(purchaseFlowParams); } else { // 초기화가 안됐으니 다시 시도 Init_IAP(); } } else BuyItem(productId); #endif } void BuyItem(string productId) { if (storeController != null) { Product product = storeController.products.WithID(productId); //상품 정의 if (product != null && product.availableToPurchase) //상품이 존재하면서 구매 가능하면 { storeController.InitiatePurchase(product); //구매가 가능하면 진행 } else //상품이 존재하지 않거나 구매 불가능하면 { Debug.Log("상품이 없거나 현재 구매가 불가능합니다"); } } else Debug.Log("인앱 초기화가 되지 않았습니다."); } /* 초기화 성공 시 실행되는 함수 */ public void OnInitialized(IStoreController controller, IExtensionProvider extension) { Debug.Log("초기화에 성공했습니다"); storeController = controller; storeExtensionProvider = extension; } /* 초기화 실패 시 실행되는 함수 */ public void OnInitializeFailed(InitializationFailureReason error) { sb.Clear(); sb.Append("IAPManager: OnInitializeFailed: ").Append(error.ToString()); Debug.LogError(sb.ToString()); } public void OnInitializeFailed(InitializationFailureReason error, string message) { sb.Clear(); sb.Append("IAPManager: OnInitializeFailed: ").Append(error.ToString()).Append(": ").Append(message); Debug.LogError(sb.ToString()); } /* 구매에 실패했을 때 실행되는 함수 */ public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription) { OnProcessPurchase?.Invoke("FailPurchase"); } public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) { sb.Clear(); sb.Append("IAPManager: OnPurchaseFailed: ").Append(product.ToString()).Append(failureReason.ToString()); Debug.LogError(sb.ToString()); OnProcessPurchase?.Invoke("FailPurchase"); } /* 구매를 처리하는 함수 */ public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) { Debug.Log("IAPManager: SuccessPurchase"); AddProductItem(args.purchasedProduct.definition.id); OnProcessPurchase?.Invoke(args.purchasedProduct.definition.id); return PurchaseProcessingResult.Complete; } private void OnNetworkOnline(bool isOnline) { if(isOnline == true && isInitialize == false) { Init_IAP(); } } int Get_Price(string id) { //// 게등위 테스트용 //var data = StorePanel.list_item.Find(f=>f.productID == id); //return data.price; #if UNITY_EDITOR return (int)storeController.products.WithID(id).metadata.localizedPrice; #else if (StoreEnvironment.GetStoreType() == StoreType.ONESTORE) return int.Parse(m_OneStoreIapCallBack.Get_Price(id)); else return (int)storeController.products.WithID(id).metadata.localizedPrice; #endif } public void AddProductItem(string id) { switch (id) { case "com.fgb.adsremove": GameManager.DB.RemoveADS(); GameManager.ADS.HideBanner(); GameManager.UI.ShowNStackPopup(EPopupType.ADSRemovePopup); FireBaseMgr.Ins.LogPurchase(id, Get_Price(id), "KRW"); break; case "com.fgb.heart20": GameManager.DB.AddHeart(20, this.name); GameManager.DB.AddTotalCashPerMonth(Get_Price(id)); FireBaseMgr.Ins.LogPurchase(id, Get_Price(id), "KRW"); break; case "com.fgb.heart150": GameManager.DB.AddHeart(150, this.name); GameManager.DB.AddTotalCashPerMonth(Get_Price(id)); FireBaseMgr.Ins.LogPurchase(id, Get_Price(id), "KRW"); break; case "com.fgb.heart500": GameManager.DB.AddHeart(500, this.name); GameManager.DB.AddTotalCashPerMonth(Get_Price(id)); FireBaseMgr.Ins.LogPurchase(id, Get_Price(id), "KRW"); break; case "com.fgb.cash500": GameManager.DB.AddKey(500, this.name); GameManager.DB.AddTotalCashPerMonth(Get_Price(id)); FireBaseMgr.Ins.LogPurchase(id, Get_Price(id), "KRW"); break; case "com.fgb.cash1800": GameManager.DB.AddKey(1800, this.name); GameManager.DB.AddTotalCashPerMonth(Get_Price(id)); FireBaseMgr.Ins.LogPurchase(id, Get_Price(id), "KRW"); break; case "com.fgb.cash7500": GameManager.DB.AddKey(7500, this.name); GameManager.DB.AddTotalCashPerMonth(Get_Price(id)); FireBaseMgr.Ins.LogPurchase(id, Get_Price(id), "KRW"); break; } } class OneStoreIapCallBack : IPurchaseCallback { public Action Action_Init; public PurchaseClientImpl m_PurchaseClientImpl; List m_productDetails; public string Get_Price(string id) { var detail = Get_ProductDetail(id); return detail != null ? detail.price : ""; } public ProductDetail Get_ProductDetail(string id) { if (m_productDetails != null) { for (int i = 0; i < m_productDetails.Count; ++i) { if (m_productDetails[i].productId.Equals(id)) return m_productDetails[i]; } } return null; } public void OnAcknowledgeFailed(IapResult iapResult) { Debug.Log("OnAcknowledgeFailed : " + iapResult.Message); } public void OnAcknowledgeSucceeded(PurchaseData purchase, OneStore.Purchasing.ProductType type) { Debug.Log("OnAcknowledgeSucceeded : " + purchase.ProductId); } public void OnConsumeFailed(IapResult iapResult) { Debug.Log("OnConsumeFailed : " + iapResult.Message); } public void OnConsumeSucceeded(PurchaseData purchase) { Debug.Log("OnConsumeSucceeded " + purchase.ProductId); GameManager.IAP.AddProductItem(purchase.ProductId); GameManager.UI.ShowNStackPopup(EPopupType.SuccessIAPPopup); } public void OnManageRecurringProduct(IapResult iapResult, PurchaseData purchase, RecurringAction action) { Debug.Log("OnManageRecurringProduct : " + iapResult.Message); } public void OnNeedLogin() { new OneStoreAuthClientImpl().LaunchSignInFlow(signInResult => { if (signInResult.IsSuccessful()) { } }); } public void OnNeedUpdate() { m_PurchaseClientImpl.LaunchUpdateOrInstallFlow(null); } public void OnProductDetailsFailed(IapResult iapResult) { Debug.Log(iapResult.ToString()); } public void OnProductDetailsSucceeded(List productDetails) { m_productDetails = productDetails; //for (int i = 0; i < productDetails.Count; i++) // DevTool.Ins.m_MyLog.Add(productDetails[i].productId + " " + productDetails[i].price); } public void OnPurchaseFailed(IapResult iapResult) { Debug.Log("OnPurchaseFailed : " + iapResult.Message); //GameManager.UI.ShowNStackPopup(EPopupType.FailIAPPopup); } public void OnPurchaseSucceeded(List purchases) { // 결제 성공 or 미지급된 아이템 지급 for (int i = 0; i < purchases.Count; i++) { var purchaseData = purchases[i]; m_PurchaseClientImpl.ConsumePurchase(purchaseData); } } public void OnSetupFailed(IapResult iapResult) { Debug.Log("OnSetupFailed : " + iapResult.Message); } } }