Example #1
0
        public override void RetrieveProducts(ReadOnlyCollection <ProductDefinition> products)
        {
#if HIGH_PERMISSION_DATA
            if ((isManagedStoreEnabled || Application.isEditor) &&
                m_managedStore != null &&
                (isRefreshing || isFirstTimeRetrievingProducts))
            {
                m_BuilderProducts = new HashSet <ProductDefinition>(products);
                m_managedStore.FetchProducts(ProcessManagedStoreResponse);
            }
            else // Fetch Additional Products triggered by developer with IStoreController or managedStore is unavailable
            {
#endif
            store.RetrieveProducts(JSONSerializer.SerializeProductDefs(products));
#if HIGH_PERMISSION_DATA
        }

        isFirstTimeRetrievingProducts = false;
#endif
        }
Example #2
0
        public override void Purchase(UnityEngine.Purchasing.ProductDefinition product, string developerPayload)
        {
            if (!string.IsNullOrEmpty(developerPayload))
            {
                Dictionary <string, object> dic = null;

                // try and get dev payload dictionary from the the developerPayload string, this may fail if the
                // developer payload is not a json string, so we catch the exception silently.
                try
                {
                    dic = (Dictionary <string, object>)MiniJSON.Json.Deserialize(developerPayload);
                }

                catch { }

                if ((dic != null) && (dic.ContainsKey("iapPromo")) && (dic.TryGetValue("productId", out var prodId)))
                {
                    m_Logger.Log("UnityIAP: Promo Purchase(" + prodId + ")");
                    promoPayload = dic;

                    // Add more fields to promoPayload
                    //
                    promoPayload.Add("type", "iap.purchase");
                    promoPayload.Add("iap_service", true);

                    var thisProduct = unity.products.WithID(prodId as string);
                    if (thisProduct != null)
                    {
                        promoPayload.Add("amount", thisProduct.metadata.localizedPrice);
                        promoPayload.Add("currency", thisProduct.metadata.isoCurrencyCode);
                    }

                    // For promotions we want to delete the promo JSON
                    // before sending upstream to stores
                    developerPayload = "iapPromo";
                }
            }
            store.Purchase(JSONSerializer.SerializeProductDef(product), developerPayload);
        }
Example #3
0
        internal void ProcessManagedStoreResponse(List <ProductDefinition> storeProducts)
        {
            m_storeCatalog = storeProducts;
            if (isRefreshing)
            {
                isRefreshing = false;
                // Skip native store layer during refresh if catalog contains no information
                if (storeCatalog.Length == 0 && refreshCallback != null)
                {
                    refreshCallback();
                    refreshCallback = null;
                    return;
                }
            }
            var products = new HashSet <ProductDefinition>(m_BuilderProducts);

            if (storeProducts != null)
            {
                products.UnionWith(storeProducts);
            }
            store.RetrieveProducts(JSONSerializer.SerializeProductDefs(products));
        }
Example #4
0
 public void OnPurchaseFailed(string json)
 {
     OnPurchaseFailed(JSONSerializer.DeserializeFailureReason(json), json);
 }
Example #5
0
 /// <summary>
 /// To use for Amazon’s local Sandbox testing app, generate a JSON description of your product catalog on the device’s SD card.
 /// </summary>
 /// <param name="products">Products to add to the testing app JSON.</param>
 public void WriteSandboxJSON(HashSet <ProductDefinition> products)
 {
     android.Call("writeSandboxJSON", JSONSerializer.SerializeProductDefs(products));
 }
 public override void Purchase(UnityEngine.Purchasing.ProductDefinition product, string developerPayload)
 {
     m_Store.Purchase(JSONSerializer.SerializeProductDef(product), developerPayload);
 }
 public virtual void OnProductsRetrieved(string json)
 {
     // NB: AppleStoreImpl overrides this completely and does not call the base.
     unity.OnProductsRetrieved(JSONSerializer.DeserializeProductDescriptions(json));
 }
 public override void RetrieveProducts(ReadOnlyCollection <ProductDefinition> products)
 {
     m_Store.RetrieveProducts(JSONSerializer.SerializeProductDefs(products));
 }
 public Dictionary <string, string> GetProductDetails()
 {
     return(JSONSerializer.DeserializeProductDetails(this.products_json));
 }
 public Dictionary <string, string> GetIntroductoryPriceDictionary()
 {
     return(JSONSerializer.DeserializeSubscriptionDescriptions(this.products_json));
 }
        public override void OnProductsRetrieved(string json)
        {
            // base.OnProductsRetrieved (json); // Don't call this, because we want to enrich the products first

            // get product list
            var productDescriptions = JSONSerializer.DeserializeProductDescriptions(json);
            List <ProductDescription> finalProductDescriptions = null;

            this.products_json = json;

            // parse app receipt
            if (m_Native != null)
            {
                var base64AppReceipt = m_Native.appReceipt;
                if (!string.IsNullOrEmpty(base64AppReceipt))
                {
                    AppleReceipt appleReceipt = getAppleReceiptFromBase64String(base64AppReceipt);
                    if (appleReceipt != null &&
                        appleReceipt.inAppPurchaseReceipts != null &&
                        appleReceipt.inAppPurchaseReceipts.Length > 0)
                    {
                        // Enrich the product descriptions with parsed receipt data
                        finalProductDescriptions = new List <ProductDescription> ();
                        foreach (var productDescription in productDescriptions)
                        {
                            // JDRjr this Find may not be sufficient for subsciptions (or even multiple non-consumables?)
                            var foundReceipts = Array.FindAll(appleReceipt.inAppPurchaseReceipts, (r) => r.productID == productDescription.storeSpecificId);
                            if (foundReceipts == null || foundReceipts.Length == 0)
                            {
                                finalProductDescriptions.Add(productDescription);
                            }
                            else
                            {
                                Array.Sort(foundReceipts, (b, a) => (a.purchaseDate.CompareTo(b.purchaseDate)));
                                var mostRecentReceipt = foundReceipts[0];
                                var productType       = (AppleStoreProductType)Enum.Parse(typeof(AppleStoreProductType), mostRecentReceipt.productType.ToString());
                                if (productType == AppleStoreProductType.AutoRenewingSubscription)
                                {
                                    // if the product is auto-renewing subscription, filter the expired products
                                    if (new SubscriptionInfo(mostRecentReceipt, null).isExpired() == Result.True)
                                    {
                                        finalProductDescriptions.Add(productDescription);
                                    }
                                    else
                                    {
                                        finalProductDescriptions.Add(
                                            new ProductDescription(
                                                productDescription.storeSpecificId,
                                                productDescription.metadata,
                                                base64AppReceipt,
                                                mostRecentReceipt.transactionID));
                                    }
                                }
                                else if (productType == AppleStoreProductType.Consumable)
                                {
                                    finalProductDescriptions.Add(productDescription);
                                }
                                else
                                {
                                    finalProductDescriptions.Add(
                                        new ProductDescription(
                                            productDescription.storeSpecificId,
                                            productDescription.metadata,
                                            base64AppReceipt,
                                            mostRecentReceipt.transactionID));
                                }
                            }
                        }
                    }
                }
            }

            // Pass along the enriched product descriptions
            unity.OnProductsRetrieved(finalProductDescriptions ?? productDescriptions);

            // Set up IAP promo product list (since we bypassed the JSON store here)
            Promo.ProvideProductsToAds(this, unity, shouldLogPromoInitialization);
            shouldLogPromoInitialization = false;

            // If there is a promotional purchase callback, tell the store to intercept those purchases.
            if (m_PromotionalPurchaseCallback != null)
            {
                m_Native.InterceptPromotionalPurchases();
            }

            // Indicate we are ready to start receiving payments.
            m_Native.AddTransactionObserver();
        }
        private void OnInventoryQueried(bool success, object payload)
        {
            bool   actualSuccess = success;
            string parsedPayload;
            Type   inventoryType = InventoryInterface.GetClassType();

            if (success)
            {
                if (inventoryType != null)
                {
                    object inventory = payload;
                    if (inventory != null && inventory.GetType() == inventoryType)
                    {
                        HashSet <ProductDescription> fetchedProducts = new HashSet <ProductDescription>();

                        var getProductList = InventoryInterface.GetProductListMethod();
                        var products       = (IEnumerable)getProductList.Invoke(inventory, null);
                        var productList    = products.Cast <object>().ToList();

                        foreach (var productInfo in productList)
                        {
                            var priceProp    = ProductInfoInterface.GetPriceProp();
                            var titleProp    = ProductInfoInterface.GetTitleProp();
                            var descProp     = ProductInfoInterface.GetDescriptionProp();
                            var currencyProp = ProductInfoInterface.GetCurrencyProp();
                            var microsProp   = ProductInfoInterface.GetPriceAmountMicrosProp();

                            ProductMetadata metadata = new ProductMetadata(
                                (string)priceProp.GetValue(productInfo, null),
                                (string)titleProp.GetValue(productInfo, null),
                                (string)descProp.GetValue(productInfo, null),
                                (string)currencyProp.GetValue(productInfo, null),
                                Convert.ToDecimal((long)microsProp.GetValue(productInfo, null)) / 1000000);


                            var idProp    = ProductInfoInterface.GetProductIdProp();
                            var productId = (string)idProp.GetValue(productInfo, null);

                            ProductDescription desc = new ProductDescription(productId, metadata);

                            var hasPurchase = InventoryInterface.HasPurchaseMethod();
                            if ((bool)hasPurchase.Invoke(inventory, new object[] { productId }))
                            {
                                var    getPurchaseInfo = InventoryInterface.GetPurchaseInfoMethod();
                                object purchase        = getPurchaseInfo.Invoke(inventory, new object[] { productId });

                                var    dic             = StringPropertyToDictionary(purchase);
                                string transactionId   = dic["GameOrderId"];
                                var    storeSpecificId = dic["ProductId"];

                                if (!string.IsNullOrEmpty(transactionId))
                                {
                                    dic["transactionId"] = transactionId;
                                }

                                if (!string.IsNullOrEmpty(storeSpecificId))
                                {
                                    dic["storeSpecificId"] = storeSpecificId;
                                }

                                desc = new ProductDescription(productId, metadata, dic.toJson(), transactionId);
                            }

                            fetchedProducts.Add(desc);
                        }

                        parsedPayload = JSONSerializer.SerializeProductDescs(fetchedProducts);
                    }
                    else
                    {
                        actualSuccess = false;
                        parsedPayload = "{ \"error\" : \"Cannot load inventory from UDP. Please make sure your UDP package is installed and up-to-date\" }";
                    }
                }
                else
                {
                    actualSuccess = false;
                    parsedPayload = "{ \"error\" : \"Cannot parse inventory type for UDP. Please make sure your UDP package is installed and up-to-date\" }";
                }
            }
            else
            {
                parsedPayload = (string)payload;
            }

            m_RetrieveProductsCallbackCache(actualSuccess, parsedPayload);
            m_RetrieveProductsCallbackCache = null;
        }