| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | #if USE_IAP | 
					
						
							|  |  |  |  | using System; | 
					
						
							|  |  |  |  | using System.Collections.Generic; | 
					
						
							|  |  |  |  | using UnityEngine; | 
					
						
							|  |  |  |  | using UnityEngine.Purchasing; | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | using Touka; | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | public class IAPTool : NormalSingleton<IAPTool>, IStoreListener | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 	public event Action OnPurchaseBegin; | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 	public event Action<string, bool> OnPurchaseDone; | 
					
						
							|  |  |  |  | 	public event Action<bool> OnRestoreDone; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	public bool IsRestoring => mIsRestoring; | 
					
						
							|  |  |  |  | 	private bool mIsRestoring = false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	private static IStoreController m_StoreController; // 存储商品信息; | 
					
						
							|  |  |  |  | 	private static IExtensionProvider m_StoreExtensionProvider; // IAP扩展工具; | 
					
						
							|  |  |  |  | 	private bool m_PurchaseInProgress = false; // 是否处于付费中; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 	private Dictionary<string, ProductType> mInitProductDic; | 
					
						
							|  |  |  |  | 	private SubscriptionInfo mSubsInfo = null; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 	public void Initialize() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (m_StoreController == null && m_StoreExtensionProvider == null) | 
					
						
							|  |  |  |  | 			InitUnityPurchase(); | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	private bool IsInitialized() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return m_StoreController != null && m_StoreExtensionProvider != null; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 	public void AddProducts(Dictionary<string, ProductType> pInitProductDic) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		mInitProductDic = pInitProductDic; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 	// 初始化IAP; | 
					
						
							|  |  |  |  | 	private void InitUnityPurchase() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (IsInitialized()) return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// 标准采购模块; | 
					
						
							|  |  |  |  | 		StandardPurchasingModule module = StandardPurchasingModule.Instance(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// 配置模式; | 
					
						
							|  |  |  |  | 		ConfigurationBuilder builder = ConfigurationBuilder.Instance(module); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// 注意ProductType的类型,Consumable是可以无限购买(比如水晶),NonConsumable是只能购买一次(比如关卡),Subscription是每月订阅(比如VIP); | 
					
						
							|  |  |  |  | 		// 这里初始化没有添加平台信息,因为平台信息有的时候还存在bug,如果必须添加,也可以添加,没有问题,确保平台信息添加正确就行了。 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		foreach (string tID in IAPProducts.ProductDic.Keys) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			builder.AddProduct(tID, IAPProducts.ProductDic[tID]); | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (mInitProductDic != null && mInitProductDic.Count > 0) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			foreach (string tID in mInitProductDic.Keys) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				builder.AddProduct(tID, mInitProductDic[tID]); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 		 | 
					
						
							|  |  |  |  | 		//初始化; | 
					
						
							|  |  |  |  | 		UnityPurchasing.Initialize(this, builder); | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #region Public Func | 
					
						
							|  |  |  |  | 	// 根据ID给购买商品; | 
					
						
							|  |  |  |  | 	public void BuyProductByID(string productId) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (IsInitialized()) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (m_PurchaseInProgress == true) return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			Product product = m_StoreController.products.WithID(productId); | 
					
						
							|  |  |  |  | 			if (product != null && product.availableToPurchase) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 				OnPurchaseBegin?.Invoke(); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 				m_PurchaseInProgress = true; | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 				TKGDebugger.LogDebug(string.Format("Purchasing product asychronously: '{0}'", product.definition.id)); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 				m_StoreController.InitiatePurchase(product); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			else | 
					
						
							|  |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 				TKGDebugger.LogDebug("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase"); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		else | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 			TKGDebugger.LogDebug("BuyProductID FAIL. Not initialized."); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 确认购买产品成功; | 
					
						
							|  |  |  |  | 	public void DoConfirmPendingPurchaseByID(string productId) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		Product product = m_StoreController.products.WithID(productId); | 
					
						
							|  |  |  |  | 		if (product != null && product.availableToPurchase) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (m_PurchaseInProgress) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				m_StoreController.ConfirmPendingPurchase(product); | 
					
						
							|  |  |  |  | 				m_PurchaseInProgress = false; | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 恢复购买; | 
					
						
							|  |  |  |  | 	public void RestorePurchases() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (!IsInitialized()) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			OnRestoreDone?.Invoke(false); | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 			TKGDebugger.LogDebug("RestorePurchases FAIL. Not initialized."); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 			return; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		if (Application.platform == RuntimePlatform.IPhonePlayer || | 
					
						
							|  |  |  |  | 			Application.platform == RuntimePlatform.OSXPlayer) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 			TKGDebugger.LogDebug("RestorePurchases started ..."); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 			mIsRestoring = true; | 
					
						
							|  |  |  |  | 			var apple = m_StoreExtensionProvider.GetExtension<IAppleExtensions>(); | 
					
						
							|  |  |  |  | 			apple.RestoreTransactions((result) => { | 
					
						
							|  |  |  |  | 				mIsRestoring = false; | 
					
						
							|  |  |  |  | 				OnRestoreDone?.Invoke(result); | 
					
						
							|  |  |  |  | 				// 返回一个bool值,如果成功,则会多次调用支付回调,然后根据支付回调中的参数得到商品id,最后做处理(ProcessPurchase);  | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 				TKGDebugger.LogDebug("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore."); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 			}); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		else | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 			TKGDebugger.LogDebug("RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | #endregion | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #region IStoreListener Callback | 
					
						
							|  |  |  |  | 	// IAP初始化成功回掉函数; | 
					
						
							|  |  |  |  | 	public void OnInitialized(IStoreController controller, IExtensionProvider extensions) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 		TKGDebugger.LogDebug("IAP initialize Succeed!"); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 		m_StoreController = controller; | 
					
						
							|  |  |  |  | 		m_StoreExtensionProvider = extensions; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// 这里可以获取您在AppStore和Google Play 上配置的商品; | 
					
						
							|  |  |  |  | 		ProductCollection products = m_StoreController.products; | 
					
						
							|  |  |  |  | 		Product[] all = products.all; | 
					
						
							|  |  |  |  | 		for (int i = 0; i < all.Length; i++) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 			TKGDebugger.LogDebug(all[i].metadata.localizedTitle + "|" + all[i].metadata.localizedPriceString + "|" + all[i].metadata.localizedDescription + "|" + all[i].metadata.isoCurrencyCode); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #if UNITY_IOS | 
					
						
							|  |  |  |  | 		m_StoreExtensionProvider.GetExtension<IAppleExtensions>().RegisterPurchaseDeferredListener(OnDeferred); | 
					
						
							|  |  |  |  | #endif | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | /* | 
					
						
							|  |  |  |  | 		Dictionary<string, string> introductory_info_dict = null; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #if UNITY_IOS | 
					
						
							|  |  |  |  | 		introductory_info_dict = m_StoreExtensionProvider.GetExtension<IAppleExtensions>().GetIntroductoryPriceDictionary(); | 
					
						
							|  |  |  |  | #endif | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		TKGDebugger.LogDebug("IAP - Available items:"); | 
					
						
							|  |  |  |  | 		foreach (var item in controller.products.all) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (item.availableToPurchase) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				TKGDebugger.LogDebug("IAP - " + string.Join(" - ", | 
					
						
							|  |  |  |  | 					new[] | 
					
						
							|  |  |  |  | 					{ | 
					
						
							|  |  |  |  | 						item.metadata.localizedTitle, | 
					
						
							|  |  |  |  | 						item.metadata.localizedDescription, | 
					
						
							|  |  |  |  | 						item.metadata.isoCurrencyCode, | 
					
						
							|  |  |  |  | 						item.metadata.localizedPrice.ToString(), | 
					
						
							|  |  |  |  | 						item.metadata.localizedPriceString, | 
					
						
							|  |  |  |  | 						item.transactionID, | 
					
						
							|  |  |  |  | 						item.receipt | 
					
						
							|  |  |  |  | 					})); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 // this is the usage of SubscriptionManager class | 
					
						
							|  |  |  |  |                 if (item.receipt != null) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  |                     if (item.definition.type == ProductType.Subscription) | 
					
						
							|  |  |  |  | 					{ | 
					
						
							|  |  |  |  |                         if (CheckIfProductIsAvailableForSubscriptionManagerC(item.receipt)) | 
					
						
							|  |  |  |  | 						{ | 
					
						
							|  |  |  |  |                             string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId]; | 
					
						
							|  |  |  |  |                             SubscriptionManager p = new SubscriptionManager(item, intro_json); | 
					
						
							|  |  |  |  |                             SubscriptionInfo info = p.getSubscriptionInfo(); | 
					
						
							|  |  |  |  | 							mSubsInfo = info; | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("product id is: " + info.getProductId()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("purchase date is: " + info.getPurchaseDate()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("subscription next billing date is: " + info.getExpireDate()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("is subscribed? " + info.isSubscribed().ToString()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("is expired? " + info.isExpired().ToString()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("is cancelled? " + info.isCancelled()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("product is in free trial peroid? " + info.isFreeTrial()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("product is auto renewing? " + info.isAutoRenewing()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("subscription remaining valid time until next billing date is: " + info.getRemainingTime()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("is this product in introductory price period? " + info.isIntroductoryPricePeriod()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("the product introductory localized price is: " + info.getIntroductoryPrice()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("the product introductory price period is: " + info.getIntroductoryPricePeriod()); | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("the number of product introductory price period cycles is: " + info.getIntroductoryPricePeriodCycles()); | 
					
						
							|  |  |  |  |                         } | 
					
						
							|  |  |  |  | 						else | 
					
						
							|  |  |  |  | 						{ | 
					
						
							|  |  |  |  |                             TKGDebugger.LogDebug("This product is not available for SubscriptionManager class, only products that are purchase by 1.19+ SDK can use this class."); | 
					
						
							|  |  |  |  |                         } | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  | 					else | 
					
						
							|  |  |  |  | 					{ | 
					
						
							|  |  |  |  |                         TKGDebugger.LogDebug("the product is not a subscription product"); | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  | 				else | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  |                     TKGDebugger.LogDebug("the product should have a valid receipt"); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | */ | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// IAP初始化失败回掉函数(没有网络的情况下并不会调起,而是一直等到有网络连接再尝试初始化); | 
					
						
							|  |  |  |  | 	public void OnInitializeFailed(InitializationFailureReason error) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		switch (error) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			case InitializationFailureReason.AppNotKnown: | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 				TKGDebugger.LogError("Is your App correctly uploaded on the relevant publisher console?"); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 				break; | 
					
						
							|  |  |  |  | 			case InitializationFailureReason.PurchasingUnavailable: | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 				TKGDebugger.LogDebug("Billing disabled! Ask the user if billing is disabled in device settings."); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 				break; | 
					
						
							|  |  |  |  | 			case InitializationFailureReason.NoProductsAvailable: | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 				TKGDebugger.LogDebug("No products available for purchase! Developer configuration error; check product metadata!"); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 				break; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  |     private bool CheckIfProductIsAvailableForSubscriptionManagerC(string receipt) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  |         var receipt_wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(receipt); | 
					
						
							|  |  |  |  |         if (!receipt_wrapper.ContainsKey("Store") || !receipt_wrapper.ContainsKey("Payload")) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  |             TKGDebugger.LogDebug("The product receipt does not contain enough information"); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         var store = (string)receipt_wrapper ["Store"]; | 
					
						
							|  |  |  |  |         var payload = (string)receipt_wrapper ["Payload"]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (payload != null ) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  |             switch (store) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  |             case GooglePlay.Name: | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     var payload_wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(payload); | 
					
						
							|  |  |  |  |                     if (!payload_wrapper.ContainsKey("json")) { | 
					
						
							|  |  |  |  |                         TKGDebugger.LogDebug("The product receipt does not contain enough information, the 'json' field is missing"); | 
					
						
							|  |  |  |  |                         return false; | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                     var original_json_payload_wrapper = (Dictionary<string, object>)MiniJson.JsonDecode((string)payload_wrapper["json"]); | 
					
						
							|  |  |  |  |                     if (original_json_payload_wrapper == null || !original_json_payload_wrapper.ContainsKey("developerPayload")) { | 
					
						
							|  |  |  |  |                         TKGDebugger.LogDebug("The product receipt does not contain enough information, the 'developerPayload' field is missing"); | 
					
						
							|  |  |  |  |                         return false; | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                     var developerPayloadJSON = (string)original_json_payload_wrapper["developerPayload"]; | 
					
						
							|  |  |  |  |                     var developerPayload_wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(developerPayloadJSON); | 
					
						
							|  |  |  |  |                     if (developerPayload_wrapper == null || !developerPayload_wrapper.ContainsKey("is_free_trial") || !developerPayload_wrapper.ContainsKey("has_introductory_price_trial")) { | 
					
						
							|  |  |  |  |                         TKGDebugger.LogDebug("The product receipt does not contain enough information, the product is not purchased using 1.19 or later"); | 
					
						
							|  |  |  |  |                         return false; | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                     return true; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             case AppleAppStore.Name: | 
					
						
							|  |  |  |  |             case AmazonApps.Name: | 
					
						
							|  |  |  |  |             case MacAppStore.Name: | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     return true; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             default: | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     return false; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return false; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 	// 支付成功处理函数; | 
					
						
							|  |  |  |  | 	public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		m_PurchaseInProgress = false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 		TKGDebugger.LogDebug("Purchase OK: " + e.purchasedProduct.definition.id); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// 消息结构 : Receipt: {"Store":"fake","TransactionID":"9c5c16a5-1ae4-468f-806d-bc709440448a","Payload":"{ \"this\" : \"is a fake receipt\" }"}; | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 		TKGDebugger.LogDebug("Receipt: " + e.purchasedProduct.receipt); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 		OnPurchaseDone?.Invoke(e.purchasedProduct.definition.id, true); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// 我们自己后台完毕的话,通过代码设置成功(如果是不需要后台设置直接设置完毕,不要设置Pending); | 
					
						
							|  |  |  |  | 		return PurchaseProcessingResult.Complete; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 支付失败回掉函数; | 
					
						
							|  |  |  |  | 	public void OnPurchaseFailed(Product item, PurchaseFailureReason r) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 		TKGDebugger.LogDebug("Purchase OK: " + item.definition.id); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 		m_PurchaseInProgress = false; | 
					
						
							|  |  |  |  | 		OnPurchaseDone?.Invoke(item.definition.id, false); | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 购买延迟提示(这个看自己项目情况是否处理); | 
					
						
							|  |  |  |  | 	public void OnDeferred(Product item) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 		TKGDebugger.LogDebug("Purchase deferred: " + item.definition.id); | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 		OnPurchaseDone?.Invoke(item.definition.id, false); | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 恢复购买功能执行回掉函数; | 
					
						
							|  |  |  |  | 	public void OnTransactionsRestored(bool success) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-30 02:21:29 +00:00
										 |  |  |  | 		TKGDebugger.LogDebug("Transactions restored : " + success); | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | #endregion | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #region custom functions | 
					
						
							|  |  |  |  | 	public string GetPriceByID(string pID) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (m_StoreController == null && m_StoreExtensionProvider == null) | 
					
						
							|  |  |  |  | 			return ""; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		Product[] tProducts = m_StoreController.products.all; | 
					
						
							|  |  |  |  | 		for (int i = 0; i < tProducts.Length; i++) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			TKGDebugger.LogDebug(tProducts[i].metadata.localizedTitle + "|" + tProducts[i].metadata.localizedPriceString + "|" + tProducts[i].metadata.localizedDescription + "|" + tProducts[i].metadata.isoCurrencyCode); | 
					
						
							|  |  |  |  | 			Product tItem = tProducts[i]; | 
					
						
							|  |  |  |  | 			if (tItem.definition.id.Equals(pID)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | #if UNITY_ANDROID | 
					
						
							|  |  |  |  | 				return tItem.metadata.GetGoogleProductMetadata().localizedPriceString; | 
					
						
							|  |  |  |  | #else | 
					
						
							|  |  |  |  | 				return tItem.metadata.localizedPriceString; | 
					
						
							|  |  |  |  | #endif | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		return ""; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	public SubscriptionInfo GetSubscriptionInfo() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		return mSubsInfo; | 
					
						
							| 
									
										
										
										
											2022-05-23 13:39:59 +00:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | #endregion | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | #endif |