321 lines
10 KiB
C#
321 lines
10 KiB
C#
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<InappInfo>
|
|
{
|
|
// 구글
|
|
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<ProductDefinition>();
|
|
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<string>();
|
|
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<string>(products), OneStore.Purchasing.ProductType.ALL); // 상품 정보 받아오기
|
|
m_PurchaseClientImpl.QueryPurchases(OneStore.Purchasing.ProductType.INAPP); // 미지급된 상품이 있는 지 체크
|
|
}
|
|
|
|
#region 구글
|
|
void OnProductsFetched(List<Product> 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<PurchaseClientImpl> Action_Init;
|
|
public PurchaseClientImpl m_PurchaseClientImpl;
|
|
public Action act_success, act_fail;
|
|
|
|
List<ProductDetail> 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<ProductDetail> 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<PurchaseData> 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<PayloadData>(json);
|
|
payload.JsonData = JsonUtility.FromJson<JsonData>(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<GooglePurchase>(json);
|
|
purchase.PayloadData = PayloadData.FromJson(purchase.Payload);
|
|
return purchase;
|
|
}
|
|
}
|
|
|
|
[SerializeField]
|
|
class IOSTEST { public string Payload, Store, TransactionID; } |