diff --git a/Assets/Scripts/Buy/IAPManager.cs b/Assets/Scripts/Buy/IAPManager.cs index f09190a..2d4e8af 100644 --- a/Assets/Scripts/Buy/IAPManager.cs +++ b/Assets/Scripts/Buy/IAPManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Unity.Services.Core; using UnityEngine; using UnityEngine.Purchasing; @@ -76,17 +77,54 @@ public class IAPManager : MonoBehaviour, IDetailedStoreListener public bool IsSubscribed() { - if (controller == null) return false; + if (controller == null) + return false; Product product = controller.products.WithID(subscriptionId); if (product != null && product.hasReceipt) { - // 对于订阅商品,hasReceipt 通常意味着用户已经订阅 - Debug.Log("用户已订阅!"); - return true; + string receipt = product.receipt; + + // 解析 JSON(第一层是 Unity 封装的 JSON) + var receiptDict = (Dictionary)UnityEngine.Purchasing.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 = UnityEngine.Purchasing.MiniJSON.Json.Deserialize(base64Receipt) as Dictionary; + if (appleReceipt != null && appleReceipt.TryGetValue("latest_receipt_info", out object latestInfoObj)) + { + var latestList = latestInfoObj as List; + if (latestList != null && latestList.Count > 0) + { + var latest = latestList[latestList.Count - 1] as Dictionary; + 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("用户未订阅。"); + Debug.Log("未订阅或订阅已过期"); return false; }