Files

257 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// IAPDemoUsage.cs
// IAP 接入使用示例(MonoBehaviour
//
// 将此脚本挂到场景中的任意 GameObject 即可运行示例。
// 请将商品 ID 替换为你在 App Store Connect / Google Play Console 中配置的真实 ID。
// ============================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Purchasing;
namespace SDK_IAP
{
public class IAPDemoUsage : MonoBehaviour
{
// ──────────────────────────────────────────────────────────
// 商品 ID 常量(请替换为真实 ID)
// ──────────────────────────────────────────────────────────
private const string PRODUCT_GOLD_100 = "mediumpack_01"; // 消耗品
private const string PRODUCT_REMOVE_ADS = "non_ads"; // 非消耗品
private const string PRODUCT_VIP_MONTH = "subcra"; // 订阅
// ──────────────────────────────────────────────────────────
// 生命周期
// ──────────────────────────────────────────────────────────
private void Awake()
{
// 订阅发货事件(持续监听,全局处理发货逻辑)
IAPManager.OnDeliver += HandleDeliver;
IAPManager.OnInitialized += HandleInitialized;
}
private void Start()
{
InitIAP();
//StartCoroutine(Test());
}
//private IEnumerator Test()
//{
// int index = 0;
// while (true)
// {
// yield return new WaitForSeconds(1f);
// Analytics.OnTrackEvent?.Invoke($"test{index}", new Dictionary<string, string>());
// index++;
// }
//}
private void OnDestroy()
{
IAPManager.OnDeliver -= HandleDeliver;
IAPManager.OnInitialized -= HandleInitialized;
IAPManager.Dispose();
}
// ──────────────────────────────────────────────────────────
// 初始化
// ──────────────────────────────────────────────────────────
private void InitIAP()
{
var products = new List<ProductDefine>
{
// 消耗品 — 金币
ProductDefine.Simple(PRODUCT_GOLD_100, ProductType.Consumable),
// 非消耗品 — 去广告(带平台特定 ID 示例)
ProductDefine.Simple(
PRODUCT_REMOVE_ADS,
ProductType.NonConsumable),
// 订阅 — VIP 月卡
ProductDefine.Simple(PRODUCT_VIP_MONTH, ProductType.Subscription),
};
Debug.Log("[IAP Demo] 开始初始化...");
IAPManager.Init(products, OnInitCallback);
}
// Init 完成回调(与 OnInitialized 事件等价,二选一即可)
private void OnInitCallback(bool success)
{
if (success)
{
Debug.Log("[IAP Demo] 初始化成功!");
ShowProductPrices();
}
else
{
Debug.LogError("[IAP Demo] 初始化失败,请检查网络或 App Store / Google Play 配置。");
}
}
// 也可以通过静态事件监听(适合多个 Manager 分散处理)
private void HandleInitialized(bool success)
{
// 此处可做更新 UI 等操作
}
// ──────────────────────────────────────────────────────────
// 显示商品价格(初始化成功后调用)
// ──────────────────────────────────────────────────────────
private void ShowProductPrices()
{
var products = IAPManager.GetProducts();
foreach (var p in products)
{
Debug.Log($"[IAP Demo] 商品: {p.definition.id} | 价格: {p.metadata.localizedPriceString}");
}
}
// ──────────────────────────────────────────────────────────
// 购买示例
// ──────────────────────────────────────────────────────────
/// <summary>购买 100 金币(消耗品)</summary>
public void BuyGold100()
{
IAPManager.Buy(PRODUCT_GOLD_100, result =>
{
if (result.success)
{
Debug.Log($"[IAP Demo] 购买成功: {result.productId} | tid={result.transactionId}");
// ⚠️ 消耗品奖励建议存服务器,防止本地数据丢失
// GoldManager.Add(100);
}
else
{
Debug.LogWarning($"[IAP Demo] 购买失败: {result.error}");
}
});
}
/// <summary>购买去广告(非消耗品)</summary>
public void BuyRemoveAds()
{
IAPManager.Buy(PRODUCT_REMOVE_ADS, result =>
{
if (result.success)
{
Debug.Log("[IAP Demo] 去广告购买成功");
// AdsManager.Disable();
}
else
{
Debug.LogWarning($"[IAP Demo] 购买失败: {result.error}");
}
});
}
/// <summary>购买 VIP 月卡(订阅)</summary>
public void BuyVipMonth()
{
IAPManager.Buy(PRODUCT_VIP_MONTH, result =>
{
if (result.success)
{
Debug.Log("[IAP Demo] VIP 订阅成功");
ShowSubscriptionInfo();
}
else
{
Debug.LogWarning($"[IAP Demo] 订阅失败: {result.error}");
}
});
}
// ──────────────────────────────────────────────────────────
// 恢复购买(iOS 界面上必须提供此按钮)
// ──────────────────────────────────────────────────────────
public void OnRestoreButtonClicked()
{
// UI 控制:仅在需要时显示此按钮
if (!IAPManager.NeedShowRestoreButton()) return;
IAPManager.Restore(result =>
{
if (result.success)
Debug.Log("[IAP Demo] 恢复购买流程完成(实际恢复内容通过 OnDeliver 发放)");
else
Debug.LogWarning($"[IAP Demo] 恢复购买失败: {result.error}");
});
}
// ──────────────────────────────────────────────────────────
// 权益检查
// ──────────────────────────────────────────────────────────
public void CheckRemoveAdsEntitlement()
{
IAPManager.CheckEntitlement(PRODUCT_REMOVE_ADS, status =>
{
Debug.Log($"[IAP Demo] 去广告权益状态: {status}");
// EntitlementStatus.FullyEntitled = 已购买且有效
});
}
// ──────────────────────────────────────────────────────────
// 订阅信息查询
// ──────────────────────────────────────────────────────────
public void ShowSubscriptionInfo()
{
var info = IAPManager.GetSubscriptionInfo(PRODUCT_VIP_MONTH);
Debug.Log($"[IAP Demo] VIP 订阅状态:");
Debug.Log($" isSubscribed = {info.isSubscribed}");
Debug.Log($" isExpired = {info.isExpired}");
Debug.Log($" expireDate = {info.expireDate:yyyy-MM-dd HH:mm:ss}");
Debug.Log($" isAutoRenewing= {info.isAutoRenewing}");
}
// ──────────────────────────────────────────────────────────
// 全局发货处理(OnDeliver 事件接收)
// ──────────────────────────────────────────────────────────
/// <summary>
/// 统一发货处理入口。
/// 无论是新购买、补单、还是恢复购买,都会触发此方法。
/// ⚠️ 幂等保护已由 DeliverGuardLite 处理,此处无需再判重。
/// </summary>
private void HandleDeliver(string productId)
{
Debug.Log($"[IAP Demo] 发货通知: {productId}");
switch (productId)
{
case PRODUCT_GOLD_100:
Debug.Log("[IAP Demo] 发放 100 金币");
// GoldManager.Add(100);
break;
case PRODUCT_REMOVE_ADS:
Debug.Log("[IAP Demo] 开启去广告");
// AdsManager.Disable();
break;
case PRODUCT_VIP_MONTH:
Debug.Log("[IAP Demo] 激活 VIP");
// VipManager.Activate();
break;
default:
Debug.LogWarning($"[IAP Demo] 未知商品 ID: {productId}");
break;
}
}
}
}