123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- #if UNITY_PURCHASING
- using UnityEngine.Events;
- using UnityEngine.UI;
- using System.IO;
- using System.Collections.Generic;
- namespace UnityEngine.Purchasing
- {
- [RequireComponent(typeof(Button))]
- [AddComponentMenu("Unity IAP/IAP Button")]
- [HelpURL("https://docs.unity3d.com/Manual/UnityIAP.html")]
- public class IAPButton : MonoBehaviour
- {
- public enum ButtonType
- {
- Purchase,
- Restore
- }
- [System.Serializable]
- public class OnPurchaseCompletedEvent : UnityEvent<Product>
- {
- };
- [System.Serializable]
- public class OnPurchaseFailedEvent : UnityEvent<Product, PurchaseFailureReason>
- {
- };
- [HideInInspector]
- public string productId;
- [Tooltip("The type of this button, can be either a purchase or a restore button")]
- public ButtonType buttonType = ButtonType.Purchase;
- [Tooltip("Consume the product immediately after a successful purchase")]
- public bool consumePurchase = true;
- [Tooltip("Event fired after a successful purchase of this product")]
- public OnPurchaseCompletedEvent onPurchaseComplete;
- [Tooltip("Event fired after a failed purchase of this product")]
- public OnPurchaseFailedEvent onPurchaseFailed;
- [Tooltip("[Optional] Displays the localized title from the app store")]
- public Text titleText;
- [Tooltip("[Optional] Displays the localized description from the app store")]
- public Text descriptionText;
- [Tooltip("[Optional] Displays the localized price from the app store")]
- public Text priceText;
- void Start()
- {
- Button button = GetComponent<Button>();
- if (buttonType == ButtonType.Purchase)
- {
- if (button)
- {
- button.onClick.AddListener(PurchaseProduct);
- }
- if (string.IsNullOrEmpty(productId))
- {
- Debug.LogError("IAPButton productId is empty");
- }
- if (!IAPButtonStoreManager.Instance.HasProductInCatalog(productId))
- {
- Debug.LogWarning("The product catalog has no product with the ID \"" + productId + "\"");
- }
- }
- else if (buttonType == ButtonType.Restore)
- {
- if (button)
- {
- button.onClick.AddListener(Restore);
- }
- }
- }
- void OnEnable()
- {
- if (buttonType == ButtonType.Purchase)
- {
- IAPButtonStoreManager.Instance.AddButton(this);
- UpdateText();
- }
- }
- void OnDisable()
- {
- if (buttonType == ButtonType.Purchase)
- {
- IAPButtonStoreManager.Instance.RemoveButton(this);
- }
- }
- void PurchaseProduct()
- {
- if (buttonType == ButtonType.Purchase)
- {
- Debug.Log("IAPButton.PurchaseProduct() with product ID: " + productId);
- IAPButtonStoreManager.Instance.InitiatePurchase(productId);
- }
- }
- void Restore()
- {
- if (buttonType == ButtonType.Restore)
- {
- if (Application.platform == RuntimePlatform.WSAPlayerX86 ||
- Application.platform == RuntimePlatform.WSAPlayerX64 ||
- Application.platform == RuntimePlatform.WSAPlayerARM)
- {
- IAPButtonStoreManager.Instance.ExtensionProvider.GetExtension<IMicrosoftExtensions>()
- .RestoreTransactions();
- }
- else if (Application.platform == RuntimePlatform.IPhonePlayer ||
- Application.platform == RuntimePlatform.OSXPlayer ||
- Application.platform == RuntimePlatform.tvOS)
- {
- IAPButtonStoreManager.Instance.ExtensionProvider.GetExtension<IAppleExtensions>()
- .RestoreTransactions(OnTransactionsRestored);
- }
- else if (Application.platform == RuntimePlatform.Android &&
- StandardPurchasingModule.Instance().appStore == AppStore.SamsungApps)
- {
- IAPButtonStoreManager.Instance.ExtensionProvider.GetExtension<ISamsungAppsExtensions>()
- .RestoreTransactions(OnTransactionsRestored);
- }
- else if (Application.platform == RuntimePlatform.Android &&
- StandardPurchasingModule.Instance().appStore == AppStore.CloudMoolah)
- {
- IAPButtonStoreManager.Instance.ExtensionProvider.GetExtension<IMoolahExtension>()
- .RestoreTransactionID((restoreTransactionIDState) =>
- {
- OnTransactionsRestored(
- restoreTransactionIDState != RestoreTransactionIDState.RestoreFailed &&
- restoreTransactionIDState != RestoreTransactionIDState.NotKnown);
- });
- }
- else
- {
- Debug.LogWarning(Application.platform.ToString() +
- " is not a supported platform for the Codeless IAP restore button");
- }
- }
- }
- void OnTransactionsRestored(bool success)
- {
- Debug.Log("Transactions restored: " + success);
- }
- /**
- * Invoked to process a purchase of the product associated with this button
- */
- public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
- {
- Debug.Log(string.Format("IAPButton.ProcessPurchase(PurchaseEventArgs {0} - {1})", e,
- e.purchasedProduct.definition.id));
- onPurchaseComplete.Invoke(e.purchasedProduct);
- return (consumePurchase) ? PurchaseProcessingResult.Complete : PurchaseProcessingResult.Pending;
- }
- /**
- * Invoked on a failed purchase of the product associated with this button
- */
- public void OnPurchaseFailed(Product product, PurchaseFailureReason reason)
- {
- Debug.Log(string.Format("IAPButton.OnPurchaseFailed(Product {0}, PurchaseFailureReason {1})", product,
- reason));
- onPurchaseFailed.Invoke(product, reason);
- }
- private void UpdateText()
- {
- var product = IAPButtonStoreManager.Instance.GetProduct(productId);
- if (product != null)
- {
- if (titleText != null)
- {
- titleText.text = product.metadata.localizedTitle;
- }
- if (descriptionText != null)
- {
- descriptionText.text = product.metadata.localizedDescription;
- }
- if (priceText != null)
- {
- priceText.text = product.metadata.localizedPriceString;
- }
- }
- }
- public class IAPButtonStoreManager : IStoreListener
- {
- private static IAPButtonStoreManager instance = new IAPButtonStoreManager();
- private ProductCatalog catalog;
- private List<IAPButton> activeButtons = new List<IAPButton>();
- private List<IAPListener> activeListeners = new List<IAPListener> ();
- protected IStoreController controller;
- protected IExtensionProvider extensions;
- private IAPButtonStoreManager()
- {
- catalog = ProductCatalog.LoadDefaultCatalog();
- StandardPurchasingModule module = StandardPurchasingModule.Instance();
- module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser;
- ConfigurationBuilder builder = ConfigurationBuilder.Instance(module);
- IAPConfigurationHelper.PopulateConfigurationBuilder(ref builder, catalog);
- UnityPurchasing.Initialize(this, builder);
- }
- public static IAPButtonStoreManager Instance
- {
- get { return instance; }
- }
- public IStoreController StoreController
- {
- get { return controller; }
- }
- public IExtensionProvider ExtensionProvider
- {
- get { return extensions; }
- }
- public bool HasProductInCatalog(string productID)
- {
- foreach (var product in catalog.allProducts)
- {
- if (product.id == productID)
- {
- return true;
- }
- }
- return false;
- }
- public Product GetProduct(string productID)
- {
- if (controller != null && controller.products != null && !string.IsNullOrEmpty(productID))
- {
- return controller.products.WithID(productID);
- }
- return null;
- }
- public void AddButton(IAPButton button)
- {
- activeButtons.Add(button);
- }
- public void RemoveButton(IAPButton button)
- {
- activeButtons.Remove(button);
- }
- public void AddListener(IAPListener listener)
- {
- activeListeners.Add (listener);
- }
- public void RemoveListener(IAPListener listener)
- {
- activeListeners.Remove (listener);
- }
- public void InitiatePurchase(string productID)
- {
- if (controller == null)
- {
- Debug.LogError("Purchase failed because Purchasing was not initialized correctly");
- foreach (var button in activeButtons)
- {
- if (button.productId == productID)
- {
- button.OnPurchaseFailed(null, Purchasing.PurchaseFailureReason.PurchasingUnavailable);
- }
- }
- return;
- }
- controller.InitiatePurchase(productID);
- }
- public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
- {
- this.controller = controller;
- this.extensions = extensions;
- foreach (var button in activeButtons)
- {
- button.UpdateText();
- }
- }
- public void OnInitializeFailed(InitializationFailureReason error)
- {
- Debug.LogError(string.Format("Purchasing failed to initialize. Reason: {0}", error.ToString()));
- }
- public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
- {
- PurchaseProcessingResult result;
- // if any receiver consumed this purchase we return the status
- bool consumePurchase = false;
- bool resultProcessed = false;
- foreach (IAPButton button in activeButtons)
- {
- if (button.productId == e.purchasedProduct.definition.id)
- {
- result = button.ProcessPurchase(e);
- if (result == PurchaseProcessingResult.Complete) {
- consumePurchase = true;
- }
-
- resultProcessed = true;
- }
- }
- foreach (IAPListener listener in activeListeners)
- {
- result = listener.ProcessPurchase(e);
- if (result == PurchaseProcessingResult.Complete) {
- consumePurchase = true;
- }
- resultProcessed = true;
- }
- // we expect at least one receiver to get this message
- if (!resultProcessed) {
- Debug.LogWarning("Purchase not correctly processed for product \"" +
- e.purchasedProduct.definition.id +
- "\". Add an active IAPButton to process this purchase, or add an IAPListener to receive any unhandled purchase events.");
-
- }
- return (consumePurchase) ? PurchaseProcessingResult.Complete : PurchaseProcessingResult.Pending;
- }
- public void OnPurchaseFailed(Product product, PurchaseFailureReason reason)
- {
- bool resultProcessed = false;
- foreach (IAPButton button in activeButtons)
- {
- if (button.productId == product.definition.id)
- {
- button.OnPurchaseFailed(product, reason);
- resultProcessed = true;
- }
- }
- foreach (IAPListener listener in activeListeners)
- {
- listener.OnPurchaseFailed(product, reason);
- resultProcessed = true;
- }
- // we expect at least one receiver to get this message
- if (resultProcessed) {
-
- Debug.LogWarning ("Failed purchase not correctly handled for product \"" + product.definition.id +
- "\". Add an active IAPButton to handle this failure, or add an IAPListener to receive any unhandled purchase failures.");
- }
-
- return;
- }
- }
- }
- }
- #endif
|