using OneStore.Auth; using OneStore.Common; using OneStore.Purchasing; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using UnityEngine; using UnityEngine.Purchasing; public class InappInfo : MonoBehaviourSingletonTemplate { // 구글 StoreController m_StoreController; // 원스토어 string onstore_publickey = ""; PurchaseClientImpl m_PurchaseClientImpl; OneStoreIapCallBack m_OneStoreIapCallBack = new OneStoreIapCallBack(); Action act_success, act_fail; IEnumerator Start() { while (true) { if (table_shop.Ins && table_shop.Ins.Get_LoadComplete()) break; yield return null; } #if UNITY_EDITOR Init_Google(); #else Debug.Log("StoreEnvironment.GetStoreType() " + StoreEnvironment.GetStoreType()); if (StoreEnvironment.GetStoreType() == StoreType.ONESTORE) Init_OneStore(); else Init_Google(); #endif } async void Init_Google() { // StoreController 인스턴스 가져오기 m_StoreController = UnityIAPServices.StoreController(); // Pending 상태 구매 처리 시점 제어 (생략 가능) // m_StoreController.ProcessPendingOrdersOnPurchasesFetched(false); // 이벤트 핸들러 등록 m_StoreController.OnPurchasePending += OnPurchasePending; m_StoreController.OnProductsFetched += OnProductsFetched; m_StoreController.OnPurchasesFetched += OnPurchasesFetched; m_StoreController.OnPurchaseConfirmed += OnPurchaseConfirmed; m_StoreController.OnPurchaseFailed += OnPurchaseFailed; // 스토어 연결 await m_StoreController.Connect(); var products = new List(); var iaplst = table_shop.Ins.Get_DataList().FindAll(f => f.e_BuyType == eShopBuyType.IAP); for (int i = 0; i < iaplst.Count; i++) products.Add(new ProductDefinition(iaplst[i].s_ID, UnityEngine.Purchasing.ProductType.Consumable)); // 상품 가져오기 시작 m_StoreController.FetchProducts(products); } void Init_OneStore() { var iaplst = table_shop.Ins.Get_DataList().FindAll(f => f.e_BuyType == eShopBuyType.IAP); var products = new List(); for (int i = 0; i < iaplst.Count; i++) products.Add(iaplst[i].s_ID); m_PurchaseClientImpl = new PurchaseClientImpl(onstore_publickey); m_PurchaseClientImpl.Initialize(m_OneStoreIapCallBack); m_OneStoreIapCallBack.m_PurchaseClientImpl = m_PurchaseClientImpl; m_PurchaseClientImpl.QueryProductDetails(new ReadOnlyCollection(products), OneStore.Purchasing.ProductType.ALL); // 상품 정보 받아오기 m_PurchaseClientImpl.QueryPurchases(OneStore.Purchasing.ProductType.INAPP); // 미지급된 상품이 있는 지 체크 } #region 구글 void OnProductsFetched(List products) { Debug.Log("상품 불러오기 완료"); //Debug.Log(products[0].definition.id); //Debug.Log(products[0].metadata.localizedPriceString); } void OnPurchasesFetched(Orders orders) { Debug.Log("복원 처리 필요"); Debug.Log($"orders.ConfirmedOrders.Count : {orders.ConfirmedOrders.Count}"); Debug.Log($"orders.PendingOrders.Count : {orders.PendingOrders.Count}"); Debug.Log($"orders.DeferredOrders.Count : {orders.DeferredOrders.Count}"); // 복원 처리 로직 (예: 보상 지급) } // 2 보류로 들어옴 void OnPurchasePending(PendingOrder order) { Debug.Log($"보류 중인 주문: {order.CartOrdered.Items().First().Product.definition.id}"); m_StoreController.ConfirmPurchase(order); } // 3 구매 완료 private void OnPurchaseConfirmed(Order order) { //NetWait.Ins.Set(false); Debug.Log($"Purchase confirmed: {order.CartOrdered.Items().First().Product.definition.id}"); act_success?.Invoke(); } private void OnPurchaseFailed(FailedOrder order) { //NetWait.Ins.Set(false); Debug.Log($"구매 실패 {order.FailureReason}"); act_fail?.Invoke(); } #endregion #region 원스토어 class OneStoreIapCallBack : IPurchaseCallback { public Action Action_Init; public PurchaseClientImpl m_PurchaseClientImpl; public Action act_success, act_fail; List m_productDetails; public string Get_Price(string id) { var detail = Get_ProductDetail(id); return detail != null ? detail.price : "0"; } 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); act_fail?.Invoke(); } public void OnConsumeSucceeded(PurchaseData purchase) { Debug.Log("OnConsumeSucceeded " + purchase.ProductId); act_success?.Invoke(); //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); } } #endregion // 구매 시도 public void BuyProduct(string productId, Action success, Action fail = null) { //// 게등위 테스트 //success?.Invoke(); //return; m_OneStoreIapCallBack.act_success = act_success = success; m_OneStoreIapCallBack.act_fail = act_fail = fail; //NetWait.Ins.Set(true); #if UNITY_EDITOR m_StoreController.PurchaseProduct(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_OneStore(); } } else m_StoreController.PurchaseProduct(productId); #endif } public string Get_Price_orNull(string _id) { #if UNITY_EDITOR return m_StoreController.GetProductById(_id).metadata.localizedPriceString; #else if (StoreEnvironment.GetStoreType() == StoreType.ONESTORE) return m_OneStoreIapCallBack.Get_Price(_id); else return m_StoreController.GetProductById(_id).metadata.localizedPriceString; #endif return null; } } public class JsonData { // JSON Fields, ! Case-sensitive public string orderId; public string packageName; public string productId; public long purchaseTime; public int purchaseState; public string purchaseToken; } public class PayloadData { public JsonData JsonData; // JSON Fields, ! Case-sensitive public string signature; public string json; public static PayloadData FromJson(string json) { var payload = JsonUtility.FromJson(json); payload.JsonData = JsonUtility.FromJson(payload.json); return payload; } } public class GooglePurchase { public PayloadData PayloadData; // JSON Fields, ! Case-sensitive public string Store; public string TransactionID; public string Payload; public static GooglePurchase FromJson(string json) { var purchase = JsonUtility.FromJson(json); purchase.PayloadData = PayloadData.FromJson(purchase.Payload); return purchase; } } [SerializeField] class IOSTEST { public string Payload, Store, TransactionID; }