NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/IAP/IAPManager.cs

402 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using PhxhSDK;
using Framework;
using System.Linq;
using UnityEngine;
using Gameplay.Net;
using cfg.ChargeCfg;
using System.Collections.Generic;
using Gameplay;
#if SDK_BILIBILI
using PhxhSDK.AOT.Bilibili;
#endif
public class IAPManager : Singlenton<IAPManager>
{
public enum PayChannel
{
None = 0,
Alipay = 1,
WeChat = 2,
Huabei = 3,
Apple = 4,
Bilibili = 5,
}
public Dictionary<int, DataCurrencyShopCfg> IapShopItem => iapShopItem;
public Dictionary<string, int> AppleProductDic => appleProductDic;
public bool ClientVerify
{
set
{
if (_isInitialized)
{
Debug.Log("当前验证为客户端:" + value);
SetClientVerify(value);
}
_clientVerify = value;
}
get => _clientVerify;
}
public PayChannel CurrentPayChannel { get; private set; }
/// <summary>
/// 跳过真实支付
/// </summary>
public bool SkipRealPay = false;
private const string PayChannelKey = "PayChannel";
/// <summary>
/// 苹果商品ID, 商品配置表ID
/// </summary>
private Dictionary<string, int> appleProductDic;
/// <summary>
/// 现金商店商品
/// </summary>
private Dictionary<int, DataCurrencyShopCfg> iapShopItem;
/// <summary>
/// 所有内购商品
/// </summary>
private Dictionary<int, DataCurrencyShopCfg> allItemDic;
/// <summary>
/// 可消耗商品列表
/// </summary>
private Dictionary<int, string> _consumableGoods;
/// <summary>
/// 不可消耗商品列表
/// </summary>
private Dictionary<int, string> _nonConsumableGoods;
/// <summary>
/// 客户端验证 测试使用
/// </summary>
private bool _clientVerify;
private bool _isInitialized;
private IAPHandle iapHelper;
public void SetCurrentPayChannel(PayChannel payChannel)
{
CurrentPayChannel = payChannel;
PlayerPrefs.SetInt("PayChannel", (int)payChannel);
}
#region 初始化
public void Init()
{
EventManager.Instance.Register<string>(EventManager.EventName.IAPServerVerifySuccessful, SeverVerifySuccess);
// 缓存支付方法
var payChannelValue = PlayerPrefs.GetInt(PayChannelKey, (int)PayChannel.Alipay);
CurrentPayChannel = Enum.IsDefined(typeof(PayChannel), payChannelValue)
? (PayChannel)payChannelValue
: PayChannel.Alipay;
iapHelper = new IAPHandle();
appleProductDic = new Dictionary<string, int>();
// 创建支付宝的监听器
var aliListener = new GameObject("AliPayHandle");
aliListener.AddComponent<AliPayHandle>();
// 创建微信回调监听
var wxPayHandle = new GameObject("WXPayHandle");
wxPayHandle.AddComponent<WXPayHandle>();
InitIAP();
}
private void InitIAP()
{
if (_isInitialized) return;
InitProducts();
OnReceiveReceipt(SendReceipt);
SetClientVerify(_clientVerify);
AddGoods(_consumableGoods.Values.ToList(), _nonConsumableGoods.Values.ToList());
_isInitialized = true;
}
/// <summary>
/// 初始化商品
/// </summary>
private void InitProducts()
{
var currencyShopCfg = TableManager.Instance.Tables.CurrencyShopCfg;
_consumableGoods = new Dictionary<int, string>();
_nonConsumableGoods = new Dictionary<int, string>();
allItemDic = new Dictionary<int, DataCurrencyShopCfg>();
iapShopItem = new Dictionary<int, DataCurrencyShopCfg>();
foreach (var currencyShop in currencyShopCfg.DataMap)
{
// 所有商品
allItemDic.TryAdd(currencyShop.Key, currencyShop.Value);
// 现金商店展示商品
if (currencyShop.Value.ShowInShop)
iapShopItem.TryAdd(currencyShop.Key, currencyShop.Value);
// 苹果内购
if (!string.IsNullOrEmpty(currencyShop.Value.AppleProductID))
{
appleProductDic.TryAdd(currencyShop.Value.AppleProductID, currencyShop.Key);
switch (currencyShop.Value.AppleBuyType)
{
case AppleBuyType.Consumable:
_consumableGoods.Add(currencyShop.Key, currencyShop.Value.AppleProductID);
break;
case AppleBuyType.NonConsumable:
_nonConsumableGoods.Add(currencyShop.Key, currencyShop.Value.AppleProductID);
break;
}
}
/*var count = Actor.Instance.Purchase.GetPurchaseCount((uint)currencyShop.Key);
Debug.Log($"商品{(uint)currencyShop.Key},购买了{count}次");*/
}
}
/// <summary>
/// 添加商品并初始化IAP
/// </summary>
private void AddGoods(List<string> consumableGoods, List<string> nonConsumableGoods,
Action<string> onBreakPurchase = null)
{
iapHelper.ConsumableGoods = consumableGoods;
iapHelper.NonConsumableGoods = nonConsumableGoods;
iapHelper.OnBreakPurchase = onBreakPurchase;
try
{
#if UNITY_IOS
iapHelper.InitIap();
#endif
}
catch (Exception e)
{
DebugUtil.LogError("Add Goods Failed, Error: {0}", e.Message);
}
}
/// <summary>
/// 设置购买成功后的回调验证
/// </summary>
private void OnReceiveReceipt(Action<string, string> onResult)
{
iapHelper.SendReceiptAction = onResult;
}
#endregion
#region 购买
/// <summary>
/// 通过商品 ID购买商品
/// </summary>
public void CheckAndBuyGoods(int id, int param = 0)
{
if (!allItemDic.TryGetValue(id, out var good))
{
DebugUtil.LogError("检查 CurrencyShop 中配置ID为 {0} 的商品", id);
return;
}
#if SDK_TAPTAP
SdkHelper sdkHelper = SDKManager.Instance.GetSdkHelper(SDKManager.SdkName.TapTap);
if (sdkHelper is IPayLimitService payLimitService)
{
payLimitService.CheckPayLimit(5000,
() => { BuyGoods(good, Actor.Instance.Base.AccountID, PurchaseSuccess, PurchaseFail); },
() => { DebugUtil.LogError("充值上限 无法充值"); });
}
else
BuyGoods(good, Actor.Instance.Base.AccountID, PurchaseSuccess, PurchaseFail);
#else
BuyGoods(good, Actor.Instance.Base.AccountID, PurchaseSuccess, PurchaseFail, param);
#endif
}
/// <summary>
/// 购买商品
/// </summary>
private void BuyGoods(DataCurrencyShopCfg data, string actorId, Action<string> onPurchaseSuccess,
Action onPurchaseFail, int param = 0)
{
if (SkipRealPay)
{
NetHelper.InAppPurchaseTest((uint)data.Id);
return;
}
switch (CurrentPayChannel)
{
case PayChannel.WeChat:
{
if (WXPayHandle.Instance.CheckWxInit())
{
if (!WXPayHandle.Instance.starPay)
WXPayHandle.Instance.BuyGoods(data.PhxhProductID, 1, param);
}
else
UITipsManager.ShowTips("未安装微信应用");
}
break;
case PayChannel.Alipay:
AliPayHandle.Instance.BuyGoods(data.AppleProductID);
break;
case PayChannel.Apple:
iapHelper.BuyGoods(data.AppleProductID, actorId, onPurchaseSuccess, onPurchaseFail);
break;
case PayChannel.Bilibili:
{
#if SDK_BILIBILI
SdkHelper sdkHelper = SDKManager.Instance.GetSdkHelper(SDKManager.SdkName.Bilibili);
if (sdkHelper is BilibiliSdkHelper biliSdk)
{
int diamondCount = 0;
if (11 == data.ItemID) // 付费钻石
diamondCount = data.ItemCount;
biliSdk.BiliListerner.RegistPayCallback(BilibiliPayHandle.Instance.BiliPaySuccess);
BilibiliPayHandle.Instance.BuyGoods(data.PhxhProductID, 1, diamondCount, biliSdk.UID,
(string order, string sign, int money) =>
{
biliSdk.Pay(Actor.Instance.Base.Nickname, money, diamondCount,
CommonUtils.GetLocalizeText(data.NameLocal), order, string.Empty, sign);
});
}
#endif
}
break;
default:
UITipsManager.ShowTips($"没有{CurrentPayChannel}支付方式");
break;
}
}
/// <summary>
/// 恢复购买 TODO待测试
/// </summary>
public void RestorePurchase(Action<List<string>> restorePurchase)
{
iapHelper.RestorePurchase(restorePurchase);
}
/// <summary>
/// 购买成功服务器验证
/// </summary>
private void SendReceipt(string receipt, string product)
{
if (string.IsNullOrEmpty(receipt) || string.IsNullOrEmpty(product))
{
DebugUtil.LogError("IAP交易错误 检查商品id");
return;
}
Debug.Log($"发送商品:{product},交易ID:{receipt}到服务器验证");
NetHelper.InAppPurchase(receipt, product);
}
private void PurchaseSuccess(string goodsID)
{
#if SDK_TAPTAP
SdkHelper sdkHelper = SDKManager.Instance.GetSdkHelper(SDKManager.SdkName.TapTap);
if (sdkHelper is IPayLimitService payLimitService)
payLimitService.SubmitPayResult(5000);
#endif
WaitingForServer.Instance.EventDone(WaitingForServer.EventName.Pay);
Debug.Log($"{goodsID}商品购买成功");
}
private void PurchaseFail()
{
WaitingForServer.Instance.EventDone(WaitingForServer.EventName.Pay);
Debug.Log("!! Unsuccessful purchase !!");
}
/// <summary>
/// 是否为不可消耗产品
/// </summary>
public bool OwnedNonConsumableGood(string productID)
{
if (appleProductDic.TryGetValue(productID, out var id) &&
_nonConsumableGoods.TryGetValue(id, out var nonConsumableGood))
{
return Actor.Instance.Purchase.GetPurchaseCount((uint)id) > 0;
}
return false;
}
#endregion
#region 服务器验证
/// <summary>
/// 服务器验证成功消息事件
/// </summary>
private void SeverVerifySuccess(string receipt)
{
Debug.Log("服务器验证成功");
ReceiveServerReceipt(receipt);
}
/// <summary>
/// 服务器验证成功后操作
/// </summary>
private void ReceiveServerReceipt(string receipt)
{
iapHelper.RemovePendingOrder(receipt);
}
#endregion
#region 释放
public void Release()
{
_isInitialized = false;
appleProductDic = null;
EventManager.Instance.Unregister<string>(EventManager.EventName.IAPServerVerifySuccessful, SeverVerifySuccess);
}
#endregion
#region Debug
public void ReLoad()
{
InitProducts();
SetClientVerify(_clientVerify);
AddGoods(_consumableGoods.Values.ToList(), _nonConsumableGoods.Values.ToList());
}
/// <summary>
/// 设为客户端验证凭证
/// </summary>
private void SetClientVerify(bool clientVerify = false)
{
iapHelper.ClientVerify = clientVerify;
}
public void ConfirmPending()
{
iapHelper.ConfirmPending();
}
#endregion
}