199 lines
6.3 KiB
C#
199 lines
6.3 KiB
C#
#if USE_IAP
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.Purchasing;
|
||
|
||
public class IAPTool : NormalSingleton<IAPTool>, IStoreListener
|
||
{
|
||
public event Action<string, bool> OnPurchaseDone;
|
||
public event Action<bool> OnRestoreDone;
|
||
|
||
public bool IsRestoring => mIsRestoring;
|
||
private bool mIsRestoring = false;
|
||
|
||
private static IStoreController m_StoreController; // 存储商品信息;
|
||
private static IExtensionProvider m_StoreExtensionProvider; // IAP扩展工具;
|
||
private bool m_PurchaseInProgress = false; // 是否处于付费中;
|
||
|
||
public void Initialize()
|
||
{
|
||
if (m_StoreController == null && m_StoreExtensionProvider == null)
|
||
InitUnityPurchase();
|
||
}
|
||
|
||
private bool IsInitialized()
|
||
{
|
||
return m_StoreController != null && m_StoreExtensionProvider != null;
|
||
}
|
||
|
||
// 初始化IAP;
|
||
private void InitUnityPurchase()
|
||
{
|
||
if (IsInitialized()) return;
|
||
|
||
// 标准采购模块;
|
||
StandardPurchasingModule module = StandardPurchasingModule.Instance();
|
||
|
||
// 配置模式;
|
||
ConfigurationBuilder builder = ConfigurationBuilder.Instance(module);
|
||
|
||
// 注意ProductType的类型,Consumable是可以无限购买(比如水晶),NonConsumable是只能购买一次(比如关卡),Subscription是每月订阅(比如VIP);
|
||
// 这里初始化没有添加平台信息,因为平台信息有的时候还存在bug,如果必须添加,也可以添加,没有问题,确保平台信息添加正确就行了。
|
||
|
||
foreach (string tID in IAPProducts.ProductDic.Keys)
|
||
{
|
||
builder.AddProduct(tID, IAPProducts.ProductDic[tID]);
|
||
}
|
||
|
||
//初始化;
|
||
UnityPurchasing.Initialize(this, builder);
|
||
}
|
||
|
||
#region Public Func
|
||
// 根据ID给购买商品;
|
||
public void BuyProductByID(string productId)
|
||
{
|
||
if (IsInitialized())
|
||
{
|
||
if (m_PurchaseInProgress == true) return;
|
||
|
||
Product product = m_StoreController.products.WithID(productId);
|
||
if (product != null && product.availableToPurchase)
|
||
{
|
||
m_PurchaseInProgress = true;
|
||
Debug.Log(string.Format("Purchasing product asychronously: '{0}'", product.definition.id));
|
||
m_StoreController.InitiatePurchase(product);
|
||
}
|
||
else
|
||
{
|
||
Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.Log("BuyProductID FAIL. Not initialized.");
|
||
}
|
||
}
|
||
|
||
// 确认购买产品成功;
|
||
public void DoConfirmPendingPurchaseByID(string productId)
|
||
{
|
||
Product product = m_StoreController.products.WithID(productId);
|
||
if (product != null && product.availableToPurchase)
|
||
{
|
||
if (m_PurchaseInProgress)
|
||
{
|
||
m_StoreController.ConfirmPendingPurchase(product);
|
||
m_PurchaseInProgress = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 恢复购买;
|
||
public void RestorePurchases()
|
||
{
|
||
if (!IsInitialized())
|
||
{
|
||
OnRestoreDone?.Invoke(false);
|
||
Debug.Log("RestorePurchases FAIL. Not initialized.");
|
||
return;
|
||
}
|
||
if (Application.platform == RuntimePlatform.IPhonePlayer ||
|
||
Application.platform == RuntimePlatform.OSXPlayer)
|
||
{
|
||
Debug.Log("RestorePurchases started ...");
|
||
mIsRestoring = true;
|
||
var apple = m_StoreExtensionProvider.GetExtension<IAppleExtensions>();
|
||
apple.RestoreTransactions((result) => {
|
||
mIsRestoring = false;
|
||
OnRestoreDone?.Invoke(result);
|
||
// 返回一个bool值,如果成功,则会多次调用支付回调,然后根据支付回调中的参数得到商品id,最后做处理(ProcessPurchase);
|
||
Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore.");
|
||
});
|
||
}
|
||
else
|
||
{
|
||
Debug.Log("RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region IStoreListener Callback
|
||
// IAP初始化成功回掉函数;
|
||
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
|
||
{
|
||
Debug.Log("IAP initialize Succeed!");
|
||
|
||
m_StoreController = controller;
|
||
m_StoreExtensionProvider = extensions;
|
||
|
||
// 这里可以获取您在AppStore和Google Play 上配置的商品;
|
||
ProductCollection products = m_StoreController.products;
|
||
Product[] all = products.all;
|
||
for (int i = 0; i < all.Length; i++)
|
||
{
|
||
Debug.Log(all[i].metadata.localizedTitle + "|" + all[i].metadata.localizedPriceString + "|" + all[i].metadata.localizedDescription + "|" + all[i].metadata.isoCurrencyCode);
|
||
}
|
||
|
||
#if UNITY_IOS
|
||
m_StoreExtensionProvider.GetExtension<IAppleExtensions>().RegisterPurchaseDeferredListener(OnDeferred);
|
||
#endif
|
||
}
|
||
|
||
// IAP初始化失败回掉函数(没有网络的情况下并不会调起,而是一直等到有网络连接再尝试初始化);
|
||
public void OnInitializeFailed(InitializationFailureReason error)
|
||
{
|
||
switch (error)
|
||
{
|
||
case InitializationFailureReason.AppNotKnown:
|
||
Debug.LogError("Is your App correctly uploaded on the relevant publisher console?");
|
||
break;
|
||
case InitializationFailureReason.PurchasingUnavailable:
|
||
Debug.Log("Billing disabled! Ask the user if billing is disabled in device settings.");
|
||
break;
|
||
case InitializationFailureReason.NoProductsAvailable:
|
||
Debug.Log("No products available for purchase! Developer configuration error; check product metadata!");
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 支付成功处理函数;
|
||
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
|
||
{
|
||
m_PurchaseInProgress = false;
|
||
|
||
Debug.Log("Purchase OK: " + e.purchasedProduct.definition.id);
|
||
|
||
// 消息结构 : Receipt: {"Store":"fake","TransactionID":"9c5c16a5-1ae4-468f-806d-bc709440448a","Payload":"{ \"this\" : \"is a fake receipt\" }"};
|
||
Debug.Log("Receipt: " + e.purchasedProduct.receipt);
|
||
|
||
OnPurchaseDone?.Invoke(e.purchasedProduct.definition.id, true);
|
||
|
||
// 我们自己后台完毕的话,通过代码设置成功(如果是不需要后台设置直接设置完毕,不要设置Pending);
|
||
return PurchaseProcessingResult.Complete;
|
||
}
|
||
|
||
// 支付失败回掉函数;
|
||
public void OnPurchaseFailed(Product item, PurchaseFailureReason r)
|
||
{
|
||
Debug.Log("Purchase OK: " + item.definition.id);
|
||
m_PurchaseInProgress = false;
|
||
OnPurchaseDone?.Invoke(item.definition.id, false);
|
||
}
|
||
|
||
// 购买延迟提示(这个看自己项目情况是否处理);
|
||
public void OnDeferred(Product item)
|
||
{
|
||
Debug.Log("Purchase deferred: " + item.definition.id);
|
||
OnPurchaseDone?.Invoke(item.definition.id, false);
|
||
}
|
||
|
||
// 恢复购买功能执行回掉函数;
|
||
public void OnTransactionsRestored(bool success)
|
||
{
|
||
Debug.Log("Transactions restored : " + success);
|
||
}
|
||
#endregion
|
||
}
|
||
#endif |