驱蚊app
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 

152 Zeilen
5.1 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using Unity.Services.Core;
  4. using UnityEngine;
  5. using UnityEngine.Purchasing;
  6. using UnityEngine.Purchasing.Extension;
  7. public class IAPManager : MonoBehaviour, IDetailedStoreListener
  8. {
  9. public static IAPManager Instance { get; private set; } // 单例
  10. private IStoreController controller;
  11. private IExtensionProvider extensions;
  12. private string subscriptionId = "quewenYueKa";
  13. void Awake()
  14. {
  15. // 单例初始化
  16. if (Instance == null)
  17. {
  18. Instance = this;
  19. DontDestroyOnLoad(gameObject); // 可选:防止切换场景被销毁
  20. }
  21. else
  22. {
  23. Destroy(gameObject); // 避免重复创建
  24. }
  25. }
  26. async void Start()
  27. {
  28. if (GameConfig.platform!= RuntimePlatform.IPhonePlayer)
  29. {
  30. Debug.LogWarning("非 iOS 平台,无法初始化 IAP");
  31. return;
  32. }
  33. await UnityServices.InitializeAsync(); // 初始化 UGS
  34. var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
  35. builder.AddProduct(subscriptionId, ProductType.Subscription);
  36. UnityPurchasing.Initialize(this, builder); // 使用新版接口
  37. }
  38. public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
  39. {
  40. this.controller = controller;
  41. this.extensions = extensions;
  42. Debug.Log("IAP 初始化成功");
  43. }
  44. public void OnInitializeFailed(InitializationFailureReason error)
  45. {
  46. Debug.LogError("IAP 初始化失败: " + error);
  47. }
  48. public void OnInitializeFailed(InitializationFailureReason error, string message)
  49. {
  50. Debug.LogError($"详细失败信息: {error} - {message}");
  51. }
  52. public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
  53. {
  54. if (args.purchasedProduct.definition.id == subscriptionId)
  55. {
  56. Debug.Log("订阅成功!");
  57. // 解锁功能
  58. }
  59. return PurchaseProcessingResult.Complete;
  60. }
  61. public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)
  62. {
  63. Debug.LogError($"购买失败: {failureDescription.message}");
  64. }
  65. public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
  66. {
  67. Debug.LogError($"购买失败: {failureReason}");
  68. }
  69. public bool IsSubscribed()
  70. {
  71. if (controller == null)
  72. return false;
  73. Product product = controller.products.WithID(subscriptionId);
  74. if (product != null && product.hasReceipt)
  75. {
  76. string receipt = product.receipt;
  77. // 解析 JSON(第一层是 Unity 封装的 JSON)
  78. var receiptDict = (Dictionary<string, object>)MiniJSON.Json.Deserialize(receipt);
  79. if (receiptDict.TryGetValue("Payload", out object payloadObj))
  80. {
  81. #if UNITY_IOS
  82. // iOS 平台下,Payload 是 Apple 的 base64 收据字符串
  83. string base64Receipt = payloadObj.ToString();
  84. // 解码 base64,得到 Apple 的 JSON 收据(PKCS7 → JSON)
  85. // 没有服务端,这一步只能依赖 Unity IAP 自动提供的结构
  86. var appleReceipt = MiniJSON.Json.Deserialize(base64Receipt) as Dictionary<string, object>;
  87. if (appleReceipt != null && appleReceipt.TryGetValue("latest_receipt_info", out object latestInfoObj))
  88. {
  89. var latestList = latestInfoObj as List<object>;
  90. if (latestList != null && latestList.Count > 0)
  91. {
  92. var latest = latestList[latestList.Count - 1] as Dictionary<string, object>;
  93. if (latest != null && latest.TryGetValue("expires_date_ms", out object expiresMsObj))
  94. {
  95. long expiresMs = long.Parse(expiresMsObj.ToString());
  96. DateTimeOffset expiresTime = DateTimeOffset.FromUnixTimeMilliseconds(expiresMs);
  97. if (expiresTime > DateTimeOffset.UtcNow)
  98. {
  99. Debug.Log("订阅有效,过期时间:" + expiresTime);
  100. return true;
  101. }
  102. else
  103. {
  104. Debug.Log("订阅已过期:" + expiresTime);
  105. }
  106. }
  107. }
  108. }
  109. #else
  110. Debug.LogWarning("非 iOS 平台,无法解析 iOS 订阅");
  111. #endif
  112. }
  113. }
  114. Debug.Log("未订阅或订阅已过期");
  115. return false;
  116. }
  117. public void BuySubscription()
  118. {
  119. if (controller == null) return;
  120. Product product = controller.products.WithID(subscriptionId);
  121. if (product != null && product.availableToPurchase)
  122. {
  123. controller.InitiatePurchase(product);
  124. }
  125. else
  126. {
  127. Debug.LogWarning("订阅商品未准备好");
  128. }
  129. }
  130. }