|
- using System;
- using System.Collections.Generic;
- using Unity.Services.Core;
- using UnityEngine;
- using UnityEngine.Purchasing;
- using UnityEngine.Purchasing.Extension;
-
- public class IAPManager : MonoBehaviour, IDetailedStoreListener
- {
- public static IAPManager Instance { get; private set; } // 单例
-
- private IStoreController controller;
- private IExtensionProvider extensions;
-
- private string subscriptionId = "quewenYueKa";
-
-
- void Awake()
- {
- // 单例初始化
- if (Instance == null)
- {
- Instance = this;
- DontDestroyOnLoad(gameObject); // 可选:防止切换场景被销毁
- }
- else
- {
- Destroy(gameObject); // 避免重复创建
- }
- }
-
- async void Start()
- {
- await UnityServices.InitializeAsync(); // 初始化 UGS
- var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
- builder.AddProduct(subscriptionId, ProductType.Subscription);
-
- UnityPurchasing.Initialize(this, builder); // 使用新版接口
- }
-
- public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
- {
- this.controller = controller;
- this.extensions = extensions;
- Debug.Log("IAP 初始化成功");
- }
-
- public void OnInitializeFailed(InitializationFailureReason error)
- {
- Debug.LogError("IAP 初始化失败: " + error);
- }
-
- public void OnInitializeFailed(InitializationFailureReason error, string message)
- {
- Debug.LogError($"详细失败信息: {error} - {message}");
- }
-
- public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
- {
- if (args.purchasedProduct.definition.id == subscriptionId)
- {
- Debug.Log("订阅成功!");
- // 解锁功能
- }
- return PurchaseProcessingResult.Complete;
- }
-
- public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)
- {
- Debug.LogError($"购买失败: {failureDescription.message}");
- }
-
- public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
- {
- Debug.LogError($"购买失败: {failureReason}");
- }
-
- public bool IsSubscribed()
- {
- if (controller == null)
- return false;
-
- Product product = controller.products.WithID(subscriptionId);
- if (product != null && product.hasReceipt)
- {
- string receipt = product.receipt;
-
- // 解析 JSON(第一层是 Unity 封装的 JSON)
- var receiptDict = (Dictionary<string, object>)MiniJSON.Json.Deserialize(receipt);
- if (receiptDict.TryGetValue("Payload", out object payloadObj))
- {
- #if UNITY_IOS
- // iOS 平台下,Payload 是 Apple 的 base64 收据字符串
- string base64Receipt = payloadObj.ToString();
-
- // 解码 base64,得到 Apple 的 JSON 收据(PKCS7 → JSON)
- // 没有服务端,这一步只能依赖 Unity IAP 自动提供的结构
- var appleReceipt = MiniJSON.Json.Deserialize(base64Receipt) as Dictionary<string, object>;
- if (appleReceipt != null && appleReceipt.TryGetValue("latest_receipt_info", out object latestInfoObj))
- {
- var latestList = latestInfoObj as List<object>;
- if (latestList != null && latestList.Count > 0)
- {
- var latest = latestList[latestList.Count - 1] as Dictionary<string, object>;
- if (latest != null && latest.TryGetValue("expires_date_ms", out object expiresMsObj))
- {
- long expiresMs = long.Parse(expiresMsObj.ToString());
- DateTimeOffset expiresTime = DateTimeOffset.FromUnixTimeMilliseconds(expiresMs);
- if (expiresTime > DateTimeOffset.UtcNow)
- {
- Debug.Log("订阅有效,过期时间:" + expiresTime);
- return true;
- }
- else
- {
- Debug.Log("订阅已过期:" + expiresTime);
- }
- }
- }
- }
- #else
- Debug.LogWarning("非 iOS 平台,无法解析 iOS 订阅");
- #endif
- }
- }
-
- Debug.Log("未订阅或订阅已过期");
- return false;
- }
-
- public void BuySubscription()
- {
- if (controller == null) return;
-
- Product product = controller.products.WithID(subscriptionId);
- if (product != null && product.availableToPurchase)
- {
- controller.InitiatePurchase(product);
- }
- else
- {
- Debug.LogWarning("订阅商品未准备好");
- }
- }
-
- }
|