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

349 lines
10 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 PhxhSDK.AOT.Bilibili;
using Gameplay;
public class IAPManager : Singlenton<IAPManager>
{
public enum PayChannel
{
None = 0,
Alipay = 1,
WeChat = 2,
Huabei = 3,
Apple = 4,
}
public Dictionary<string, int> ProductDic;
public Dictionary<int, DataCurrencyShopCfg> IapDataDic;
private bool _isInitialized;
private IAPHandle _helper;
private CurrencyShopCfg _currencyShopCfg;
private Dictionary<int, string> _consumableGoods;
private Dictionary<int, string> _nonConsumableGoods;
public PayChannel CurrentPayChannel { get; private set; }
private const string PayChannelKey = "PayChannel";
private bool _clientVerify;
public bool ClientVerify
{
set
{
if (_isInitialized)
{
Debug.Log("当前验证为客户端:" + value);
SetClientVerify(value);
}
_clientVerify = value;
}
get { return _clientVerify; }
}
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;
_helper = new IAPHandle();
ProductDic = 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 table = TableManager.Instance.Tables;
_currencyShopCfg = table.CurrencyShopCfg;
_consumableGoods = new Dictionary<int, string>();
_nonConsumableGoods = new Dictionary<int, string>();
IapDataDic = new Dictionary<int, DataCurrencyShopCfg>();
foreach (var currencyShop in _currencyShopCfg.DataMap)
{
IapDataDic.TryAdd(currencyShop.Key, currencyShop.Value);
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;
}
ProductDic.TryAdd(currencyShop.Value.AppleProductID, currencyShop.Key);
}
foreach (var good in ProductDic)
{
var count = Actor.Instance.Purchase.GetPurchaseCount((uint)good.Value);
Debug.Log($"商品{good.Key},购买了{count}次");
}
}
/// <summary>
/// 添加商品并初始化IAP
/// </summary>
private void AddGoods(List<string> consumableGoods, List<string> nonConsumableGoods,
Action<string> onBreakPurchase = null)
{
_helper.ConsumableGoods = consumableGoods;
_helper.NonConsumableGoods = nonConsumableGoods;
_helper.OnBreakPurchase = onBreakPurchase;
try
{
_helper.InitIap();
}
catch (Exception e)
{
DebugUtil.LogError("Add Goods Failed, Error: {0}", e.Message);
}
}
/// <summary>
/// 设置购买成功后的回调验证
/// </summary>
private void OnReceiveReceipt(Action<string, string> onResult)
{
_helper.SendReceiptAction = onResult;
}
#endregion
#region 购买
/// <summary>
/// IAP购买商品 通过商品ID
/// </summary>
public void IAPBuyGoods(int id)
{
if (!_consumableGoods.TryGetValue(id, out var good))
{
if (!_nonConsumableGoods.TryGetValue(id, out good))
{
DebugUtil.LogError("检查 IAPProducts 中配置ID为 {0} 的商品", id);
return;
}
}
#if SDK_TAPTAP
SdkHelper sdkHelper = SDKManager.Instance.GetSdkHelper(SDKManager.SdkName.TapTap);
if (sdkHelper is IPayLimitService payLimitService)
{
payLimitService.CheckPayLimit(5000,
() => { BuyGoods(id, good, Actor.Instance.Base.AccountID, PurchaseSuccess, PurchaseFail); },
() => { DebugUtil.LogError("充值上限 无法充值"); });
}
else
BuyGoods(id, good, Actor.Instance.Base.AccountID, PurchaseSuccess, PurchaseFail);
#elif SDK_BILIBILI
SdkHelper sdkHelper = SDKManager.Instance.GetSdkHelper(SDKManager.SdkName.Bilibili);
if (sdkHelper is BilibiliSdkHelper biliSdk)
{
if (!IapDataDic.TryGetValue(id, out DataCurrencyShopCfg cfg))
return;
if (TableManager.Instance.Tables.GlobalConfig.DiamondItemId == cfg.ItemID)
biliSdk.Pay(Actor.Instance.Base.Nickname, cfg.NowPriceRMB * 100, cfg.ItemCount,
CommonUtils.GetLocalizeText(cfg.NameLocal), "111", string.Empty);
}
else
BuyGoods(id, good, Actor.Instance.Base.AccountID, PurchaseSuccess, PurchaseFail);
#else
BuyGoods(id, good, Actor.Instance.Base.AccountID, PurchaseSuccess, PurchaseFail);
#endif
}
/// <summary>
/// 购买商品
/// </summary>
private void BuyGoods(int currencyID, string goodsName, string actorId, Action<string> onPurchaseSuccess, Action onPurchaseFail)
{
if (!IapDataDic.TryGetValue(currencyID, out var goodData))
return;
switch (CurrentPayChannel)
{
case PayChannel.WeChat:
{
if (WXPayHandle.Instance.CheckWxInit())
WXPayHandle.Instance.BuyGoods(goodData.PhxhProductID, 1);
else
UITipsManager.ShowTips("未安装微信应用");
}
break;
case PayChannel.Alipay:
AliPayHandle.Instance.BuyGoods(goodsName);
break;
case PayChannel.Apple:
_helper.BuyGoods(goodsName, actorId, onPurchaseSuccess, onPurchaseFail);
break;
default:
UITipsManager.ShowTips($"没有{CurrentPayChannel}支付方式");
break;
}
}
/// <summary>
/// 恢复购买 TODO待测试
/// </summary>
public void RestorePurchase(Action<List<string>> restorePurchase)
{
_helper.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 (ProductDic.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)
{
_helper.RemovePendingOrder(receipt);
}
#endregion
#region 释放
public void Release()
{
_isInitialized = false;
ProductDic = 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)
{
_helper.ClientVerify = clientVerify;
}
public void ConfirmPending()
{
_helper.ConfirmPending();
}
#endregion
}