예제 #1
0
        /// <summary>
        /// restore already purchased user's transactions for non consumable iaps.
        /// For Android/WP8 we use the received list for detecting previous purchases
        /// </summary>
        public static void RestoreTransactions()
        {
                        #if UNITY_IPHONE
            OpenIAB.restoreTransactions();
                        #elif UNITY_ANDROID || UNITY_WP8
            if (inventory == null)
            {
                RestoreFailed("Restoring transactions failed. Please try again.");
                return;
            }

            List <string> prods = inventory.GetAllOwnedSkus();
            for (int i = 0; i < prods.Count; i++)
            {
                string id = GetIAPIdentifier(prods[i]);
                if (!DBManager.isPurchased(id))
                {
                    DBManager.SetToPurchased(id);
                }
            }
            RestoreSucceeded();
                        #endif

            //update ShopManager GUI items
            if (ShopManager.GetInstance())
            {
                ShopManager.SetItemState();
            }
        }
예제 #2
0
 //just shows a message via our ShopManager component,
 //but checks for an instance of it first
 public void ShowMessage(string text)
 {
     if (ShopManager.GetInstance())
     {
         ShopManager.ShowMessage(text);
     }
 }
예제 #3
0
 //called when an purchaseFailedEvent happens, here we forward
 //the error message to ShopManager's error window (if present)
 void HandleFailedInventory(string error)
 {
     if (ShopManager.GetInstance())
     {
         ShopManager.ShowMessage(error);
     }
 }
예제 #4
0
 //called when an purchaseFailedEvent happens,
 //we do the same here
 void HandleFailedPurchase(string error)
 {
     if (ShopManager.GetInstance())
     {
         ShopManager.ShowMessage(error);
     }
 }
예제 #5
0
        /// <summary>
        /// restore already purchased user's transactions for non consumable iaps.
        /// For Android we use the received list for detecting previous purchases
        /// </summary>
        public static void RestoreTransactions()
        {
            #if UNITY_IPHONE
            StoreKitBinding.restoreCompletedTransactions();
            #elif UNITY_ANDROID
            if (prods == null)
            {
                RestoreFailed("Restoring transactions failed. Please try again.");
                return;
            }

            for (int i = 0; i < prods.Count; i++)
            {
                string id = GetIAPIdentifier(prods[i].productId);
                if (!DBManager.isPurchased(id))
                {
                    DBManager.SetToPurchased(id);
                }
            }
            RestoreSucceeded();
            #endif

            //update ShopManager GUI items
            if (ShopManager.GetInstance())
            {
                ShopManager.SetItemState();
            }
        }
예제 #6
0
        /// <summary>
        /// Restore already purchased user's transactions for non consumable IAPs.
        /// For Android we use the received list for detecting previous purchases.
        /// </summary>
        public static void RestoreTransactions()
        {
                        #if UNITY_IOS
            extensions.GetExtension <IAppleExtensions>().RestoreTransactions(OnTransactionsRestored);
                        #else
            Product[] purchasedProducts = controller.products.all;
            foreach (Product product in purchasedProducts)
            {
                string id = product.definition.id;
                if (DBManager.isPurchased(id) || product.definition.type == ProductType.Consumable ||
                    !product.hasReceipt || String.IsNullOrEmpty(product.receipt))
                {
                    continue;
                }

                DBManager.SetToPurchased(id);
            }

            OnTransactionsRestored(true);
            #endif

            //update ShopManager GUI items
            if (ShopManager.GetInstance())
            {
                ShopManager.SetItemState();
            }
        }
예제 #7
0
        // check for purchases on online servers at billing initialization.
        // If a purchase is not registered, set local purchase state back to false
        private void VerifyReceipts()
        {
            //get list of old purchases: on iOS the saved transactions,
            //on Android we use the old purchases list received from Google
            if (inventory == null || inventory.GetAllPurchases().Count == 0)
            {
                return;
            }

            //loop over all IAP items to check if a valid receipt exists
            for (int i = 0; i < ids.Length; i++)
            {
                //cache IAP id,
                //only verify purchased items
                string localId  = ids[i];
                string globalId = GetIAPIdentifier(localId);
                if (DBManager.isPurchased(globalId))
                {
                    //initialize item as faked and loop over receipts
                    bool     faked   = true;
                    Purchase receipt = inventory.GetPurchase(localId);

                    if (receipt != null)
                    {
                        //we found a receipt for this product on the device,
                        //unset fake purchase and let our external
                        //server decide what happens with this transaction
                        faked = false;
                        MakeRequest(receipt);
                        break;
                    }

                    //we haven't found a receipt for this item, yet it is
                    //set to purchased. This can't be, maybe our external server
                    //response or the database has been hacked with fake data
                    if (faked)
                    {
                        IAPItem item = null;
                        if (ShopManager.GetInstance())
                        {
                            item = ShopManager.GetIAPItem(globalId);
                        }
                        if (item)
                        {
                            item.Purchased(false);
                        }
                        DBManager.RemovePurchased(globalId);
                    }
                }
            }
        }
예제 #8
0
        // Optionally: verify old purchases online.
        // Once we've received the product list, we overwrite
        // the existing shop item values with this online data
        public void OnInitialized(IStoreController ctrl, IExtensionProvider ext)
        {
            controller = ctrl;
            extensions = ext;

            if (validator && validator.shouldValidate(VerificationType.onStart))
            {
                validator.Validate();
            }

            if (ShopManager.GetInstance())
            {
                ShopManager.OverwriteWithFetch(controller.products.all);
            }
        }
예제 #9
0
        /// <summary>
        /// Increases player level by 1 which unlocks new shop items.
        /// <summary>
        public void LevelUp()
        {
            if (DBManager.GetInstance())
            {
                int level = DBManager.IncreasePlayerData("level", 1);

                if (ShopManager.GetInstance())
                {
                    ShopManager.RefreshAll();
                }

                Debug.Log("Leveled up to level: " + level +
                          "! Shop Manager tried to unlock new items.");
            }
        }
예제 #10
0
        //when the buy button has been clicked, here we try to purchase this item
        //maps to the corresponding purchase methods of IAPManager
        //only works on an actual mobile device
        public void Purchase()
        {
            #if UNITY_EDITOR
            if (type == IAPType.consumable || type == IAPType.nonConsumable ||
                type == IAPType.subscription)
            {
                string editorText = "Calling purchase ID: " + this.productId + ".\nYou are not on a mobile device, nothing will happen.";
                if (ShopManager.GetInstance())
                {
                    ShopManager.ShowMessage(editorText);
                }
                Debug.Log(editorText);
                return;
            }
            #endif

            //differ between IAP type
            switch (type)
            {
            case IAPType.consumable:
                IAPManager.PurchaseConsumableProduct(this.productId);
                break;

            case IAPType.nonConsumable:
                IAPManager.PurchaseNonconsumableProduct(this.productId);
                break;

            case IAPType.subscription:
                IAPManager.PurchaseSubscription(this.productId);
                break;

            case IAPType.consumableVirtual:
                IAPManager.PurchaseConsumableVirtualProduct(this.productId);
                break;

            case IAPType.nonConsumableVirtual:
                IAPManager.PurchaseNonconsumableVirtualProduct(this.productId);
                break;
            }

            //hide buy button once a purchase was made
            //only when an additional buy trigger was set
            if (buyTrigger)
            {
                ConfirmPurchase(false);
            }
        }
예제 #11
0
        // iOS version: receive StoreKitProducts.
        // Optionally: verify old purchases online.
        // Once we've received the productList, we create a
        // cross-platform version of it and overwrite
        // the existing shop item values with this online data
        private void ProductDataReceived(List <StoreKitProduct> list)
        {
            if ((verificationType == VerificationType.onStart || verificationType == VerificationType.both) &&
                !string.IsNullOrEmpty(serverUrl))
            {
                VerifyReceipts();
            }

            productCache = new List <IAPArticle>();
            for (int i = 0; i < list.Count; i++)
            {
                productCache.Add(new IAPArticle(list[i]));
            }

            if (ShopManager.GetInstance())
            {
                ShopManager.OverwriteWithFetch(productCache);
            }
        }
예제 #12
0
        /*
         * public void CloudMoolahButton()
         * {
         *  extensions.GetExtension<IMoolahExtension>().FastRegister(DBManager.GetDeviceId(), (string moolahName) =>
         *  {
         *      //register succeeded
         *      extensions.GetExtension<IMoolahExtension>().Login(moolahName, DBManager.GetDeviceId(), (LoginResultState loginResult, string error) =>
         *      {
         *          //login succeeded?
         *          Debug.Log("Moolah Login State: " + loginResult + ", " + error);
         *      });
         *  }, (FastRegisterError registerResult, string error) =>
         *  {
         *      //register failed
         *      Debug.Log("Moolah Register Error: " + registerResult + ", " + error);
         *  });
         * }
         */


        /// <summary>
        /// Purchase product based on its product id. If the productId matches "restore", we restore transactions instead.
        /// Our delegates then fire the appropriate succeeded/fail/restore event.
        /// </summary>
        public static void PurchaseProduct(string productId)
        {
            #if UNITY_PURCHASING
            if (productId == "restore")
            {
                RestoreTransactions();
                return;
            }
            #endif

            IAPObject obj = GetIAPObject(productId);
            if (obj == null)
            {
                if (isDebug)
                {
                    Debug.LogError("Product " + productId + " not found in IAP Settings.");
                }
                return;
            }

            //distinguish between virtual and real products
            if (obj.editorType == IAPType.Virtual)
            {
                PurchaseProduct(obj);
                return;
            }

            #if UNITY_PURCHASING
            if (controller == null)
            {
                if (ShopManager.GetInstance())
                {
                    ShopManager.ShowMessage("Billing is not available.");
                }
                Debug.LogError("Unity IAP is not initialized correctly! Please check your billing settings.");
                return;
            }

            controller.InitiatePurchase(controller.products.WithID(productId));
            #endif
        }
예제 #13
0
        // Once we've received the productList, we create a
        // cross-platform version of it and overwrite
        // the existing shop item values with this online data
        // Optional: verify old purchases online.
        private void ProductDataReceived(Inventory inv)
        {
            //store fetched inventory for later access
            inventory = inv;

            //check for non-consumed consumables
            List <Purchase> prods = inv.GetAllPurchases();

            for (int i = 0; i < prods.Count; i++)
            {
                IAPObject obj = GetIAPObject(prods[i].Sku);
                if (obj != null && obj.type == IAPType.consumable)
                {
                    OpenIAB.consumeProduct(prods[i]);
                }
            }

                        #if UNITY_ANDROID
            if ((verificationType == VerificationType.onStart || verificationType == VerificationType.both) &&
                !string.IsNullOrEmpty(serverUrl))
            {
                VerifyReceipts();
            }
                        #endif

            //build live cache
            productCache = new List <IAPArticle>();
            for (int i = 0; i < ids.Length; i++)
            {
                if (inv.GetSkuDetails(ids[i]) != null)
                {
                    productCache.Add(new IAPArticle(inv.GetSkuDetails(ids[i])));
                }
            }

            if (ShopManager.GetInstance())
            {
                ShopManager.OverwriteWithFetch(productCache);
            }
        }
예제 #14
0
        // Android version: receive GoogleSkuInfos.
        // Optionally: verify old purchases online.
        // Once we've received the productList, we create a
        // cross-platform version of it and overwrite
        // the existing shop item values with this online data
        void ProductDataReceived(List <GooglePurchase> purchases, List <GoogleSkuInfo> list)
        {
            //store old purchases for verification purposes
            prods = purchases;

            if ((verificationType == VerificationType.onStart || verificationType == VerificationType.both) &&
                !string.IsNullOrEmpty(serverUrl))
            {
                VerifyReceipts();
            }

            productCache = new List <IAPArticle>();
            for (int i = 0; i < list.Count; i++)
            {
                productCache.Add(new IAPArticle(list[i]));
            }

            if (ShopManager.GetInstance())
            {
                ShopManager.OverwriteWithFetch(productCache);
            }
        }
예제 #15
0
        /// <summary>
        /// Manually triggering purchase confirmation after a PayPal payment has been made.
        /// This is so that the transaction gets finished and PayPal actually substracts funds.
        /// </summary>
        public void ConfirmPurchase()
        {
            if (string.IsNullOrEmpty(orderId))
            {
                return;
            }

            ConfirmPurchaseRequest request = new ConfirmPurchaseRequest()
            {
                OrderId = orderId
            };

            PlayFabClientAPI.ConfirmPurchase(request, (result) =>
            {
                if (ShopManager.GetInstance() != null && ShopManager.GetInstance().confirmWindow != null)
                {
                    ShopManager.GetInstance().confirmWindow.SetActive(false);
                }

                OnPurchaseSucceeded(result);
            }, OnPurchaseFailed);
        }
예제 #16
0
        /// <summary>
        /// handle purchases, for real money or ingame currency
        /// </summary>
        public void HandleSuccessfulPurchase(string id)
        {
            //differ between ids set in the IAP Settings editor
            if (IAPManager.isDebug)
            {
                Debug.Log("HandleSuccessfulPurchase: " + id);
            }
            IAPObject obj = IAPManager.GetIAPObject(id);

            //get instantiated shop item based on the IAP id
            IAPItem item = null;

            if (ShopManager.GetInstance())
            {
                item = ShopManager.GetIAPItem(id);
            }

            //if the purchased item was non-consumable,
            //additionally block further purchase of the shop item
            if (item != null && obj != null && obj.type != ProductType.Consumable)
            {
                item.Purchased(true);
            }

            switch (id)
            {
            //section for in app purchases
            case "coins":
                //the user bought the item "coins",
                //increase coins by 1000 and show appropriate feedback
                DBManager.IncreaseFunds("coins", 1000);
                ShowMessage("1000 coins were added to your balance!");
                break;

            case "coin_pack":
                DBManager.IncreaseFunds("coins", 2500);
                ShowMessage("2500 coins were added to your balance!");
                break;

            case "big_coin_pack":
                DBManager.IncreaseFunds("coins", 6000);
                ShowMessage("6000 coins were added to your balance!");
                break;

            case "huge_coin_pack":
                DBManager.IncreaseFunds("coins", 12000);
                ShowMessage("12000 coins were added to your balance!");
                break;

            case "no_ads":
                //no_ads purchased. You can now check DBManager.isPurchased("no_ads")
                //before showing ads and block them
                ShowMessage("Ads disabled!");
                break;

            case "abo_monthly":
                //same here - your code to unlock subscription content
                ShowMessage("Subscribed to monthly abo!");
                break;

            case "restore":
                //nothing else to call here,
                //the actual restore is handled by IAPManager
                ShowMessage("Restored transactions!");
                break;

            //section for in game content
            case "bullets":
                //for virtual items, you could use DBManager's custom data option in order
                //to save amounts of virtual products. E.g. increasing bullets by 100:
                //int bullets = DBManager.GetPlayerData("bullets").AsInt;
                //DBManager.SetPlayerData("bullets", new SimpleJSON.JSONData(bullets + 100));
                ShowMessage("Bullets were added to your inventory!");
                break;

            case "health":
                ShowMessage("Medikits were added to your inventory!");
                break;

            case "energy":
                ShowMessage("Energy was added to your inventory!");
                break;

            case "speed":
                ShowMessage("Speed boost unlocked!");
                break;

            case "speed_1":
            case "speed_2":
            case "speed_3":
                ShowMessage("Speed boost upgraded!");
                break;

            case "bonus":
                ShowMessage("Bonus level unlocked!");
                break;

            case "uzi":
                ShowMessage("Uzi unlocked!");
                break;

            case "ak47":
                ShowMessage("AK47 unlocked!");
                break;

            case "m4":
                ShowMessage("M4 unlocked!");
                break;

            case "hat":
                ShowMessage("Hat unlocked!");
                break;

            case "backpack":
                ShowMessage("Backpack unlocked!");
                break;

            case "belt":
                ShowMessage("Ammo belt unlocked!");
                break;

            case "jetpack":
                ShowMessage("Jetpack unlocked!");
                break;

            case "booster":
                ShowMessage("Double XP unlocked!");
                break;
            }
        }
예제 #17
0
        // check for purchases on online servers at billing initialization.
        // If a purchase is not registered, set local purchase state back to false
        private void VerifyReceipts()
        {
            //get list of old purchases: on iOS the saved and filtered transactions (avoiding duplicates),
            //on Android we use the old purchases list received from Google
            #if UNITY_IPHONE
            List <StoreKitTransaction> prods = FilterTransactions(StoreKitBinding.getAllSavedTransactions());
            #endif
            if (prods == null || prods.Count == 0)
            {
                return;
            }

            //loop over all IAP items to check if a valid receipt exists
            for (int i = 0; i < ids.Length; i++)
            {
                //cache IAP id,
                //only verify purchased items
                string localId  = ids[i];
                string globalId = GetIAPIdentifier(localId);
                if (DBManager.isPurchased(globalId))
                {
                    //initialize item as faked and loop over receipts
                    bool faked = true;
                    for (int j = 0; j < prods.Count; j++)
                    {
                        //find corresponding transaction class
                        string identifier = "";
                        #if UNITY_IPHONE
                        StoreKitTransaction purchase = prods[j];
                        identifier = purchase.productIdentifier;
                        #elif UNITY_ANDROID
                        GooglePurchase purchase = prods[j];
                        identifier = purchase.productId;
                        #endif
                        if (identifier == localId)
                        {
                            //we found a receipt for this product on the device,
                            //unset fake purchase and let our external
                            //server decide what happens with this transaction
                            faked = false;
                            MakeRequest(purchase);
                            break;
                        }
                    }
                    //we haven't found a receipt for this item, yet it is
                    //set to purchased. This can't be, maybe our external server
                    //response or the database has been hacked with fake data
                    if (faked)
                    {
                        IAPItem item = null;
                        if (ShopManager.GetInstance())
                        {
                            item = ShopManager.GetIAPItem(globalId);
                        }
                        if (item)
                        {
                            item.Purchased(false);
                        }
                        DBManager.RemovePurchased(globalId);
                    }
                }
            }
        }
예제 #18
0
        /// <summary>
        /// handle purchases, for real money or ingame currency
        /// </summary>
        public void HandleSuccessfulPurchase(string id)
        {
            //differ between ids set in the IAP Settings editor
            if (debug)
            {
                Debug.Log("HandleSuccessfulPurchase: " + id);
            }
            //get instantiated shop item based on the IAP id
            IAPItem item = null;

            if (ShopManager.GetInstance())
            {
                item = ShopManager.GetIAPItem(id);
            }

            //if the purchased item was non-consumable,
            //additionally block further purchase of the shop item
            if (item != null &&
                (item.type == IAPType.nonConsumable ||
                 item.type == IAPType.nonConsumableVirtual ||
                 item.type == IAPType.subscription))
            {
                item.Purchased(true);
            }

            switch (id)
            {
            //section for in app purchases

            case "bann_coins":
                gameParameters.currentCharacter = "Bann";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Bann!");
                break;

            case "bella_coins":
                gameParameters.currentCharacter = "Bella";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Bella!");
                break;

            case "blane_coins":
                gameParameters.currentCharacter = "Blane";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Blane!");
                break;

            case "damien_coins":
                gameParameters.currentCharacter = "Damien";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Damien!");
                break;

            case "finnikin_coins":
                gameParameters.currentCharacter = "Finnikin";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Finnikin!");
                break;

            case "gwyn_coins":
                gameParameters.currentCharacter = "Gwyn";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Gwyn!");
                break;

            case "hector_coins":
                gameParameters.currentCharacter = "Hector";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Hector!");
                break;

            case "katsa_coins":
                gameParameters.currentCharacter = "Katsa";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Katsa!");
                break;

            case "mather_coins":
                gameParameters.currentCharacter = "Mather";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Mather!");
                break;

            case "pifoo_coins":
                gameParameters.currentCharacter = "Pifoo";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Pifoo!");
                break;

            case "rylan_coins":
                gameParameters.currentCharacter = "Rylan";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Rylan!");
                break;

            case "sothe_coins":
                gameParameters.currentCharacter = "Sothe";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Sothe!");
                break;

            case "wesker_coins":
                gameParameters.currentCharacter = "Wesker";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Wesker!");
                break;

            case "yuki_coins":
                gameParameters.currentCharacter = "Yuki";
                PlayerPrefs.SetString("currentCharacter", gameParameters.currentCharacter);
                ShowMessage("You can now play with Yuki!");
                break;
            }
        }
예제 #19
0
        // handles an online verification request and response from
        // our external server. www.text can returns true or false.
        // true: purchase verified, false: not verified (fake?) purchase
        IEnumerator WaitForRequest(Dictionary <string, string> dic)
        {
            //cache requested product id
            string id = dic["pid"];

            //build POST request with transaction data
            WWWForm form = new WWWForm();

            foreach (string key in dic.Keys)
            {
                form.AddField(key, dic[key]);
            }
            //create URL and execute until we have a respone
            WWW www = new WWW(serverUrl + verificationFileName, form);

            yield return(www);

            //check for URL errors
            if (www.error == null)
            {
                //we have a successful response from our server,
                //but it returned false (fake purchase)
                if (!bool.Parse(www.text))
                {
                    inventory.ErasePurchase(id);
                    if (debug)
                    {
                        Debug.Log("The receipt for '" + id + "' could not be verified: " + www.text);
                    }
                    //PurchaseFailed("The receipt for '" + id + "' could not be verified.");

                    id = GetIAPIdentifier(id);
                    //remove purchase from the database and update item state
                    if (DBManager.isPurchased(id))
                    {
                        IAPItem item = null;
                        if (ShopManager.GetInstance())
                        {
                            item = ShopManager.GetIAPItem(id);
                        }
                        if (item)
                        {
                            item.Purchased(false);
                        }
                        DBManager.RemovePurchased(id);
                    }
                    yield break;
                }
                else
                {
                    //successful response, verified transaction
                    if (debug)
                    {
                        Debug.Log(dic["pid"] + " verification success.");
                    }
                }
            }
            else
            {
                //we can't reach our external server, do nothing:
                //in this case we handle the purchase as without verification
                if (debug)
                {
                    Debug.Log("Verification URL error: " + www.text);
                }
            }

            id = GetIAPIdentifier(id);
            PurchaseVerified(id);
        }