// INativeStore public void Purchase(string productJSON, string developerPayload) { var dic = (Dictionary <string, object>)MiniJson.JsonDecode(productJSON); object obj; string id, storeId, type; ProductType itemType; dic.TryGetValue("id", out obj); id = obj.ToString(); dic.TryGetValue("storeSpecificId", out obj); storeId = obj.ToString(); dic.TryGetValue("type", out obj); type = obj.ToString(); if (Enum.IsDefined(typeof(ProductType), type)) { itemType = (ProductType)Enum.Parse(typeof(ProductType), type); } else { itemType = ProductType.Consumable; } // This doesn't currently deal with "enabled" and "payouts" that could be included in the JSON var product = new ProductDefinition(id, storeId, itemType); FakePurchase(product, developerPayload); }
// INativeStore public void RetrieveProducts(string json) { var jsonList = (List <object>)MiniJson.JsonDecode(json); var productDefinitions = jsonList.DecodeJSON(Name); StoreRetrieveProducts(new ReadOnlyCollection <ProductDefinition>(productDefinitions.ToList())); }
/// <summary> /// Parse product definitions from JSON, selecting store specific identifiers /// for the specified store name. /// </summary> internal static List <ProductDefinition> ParseProductsFromJSON(string json, string storeName, ILogger logger) { if (String.IsNullOrEmpty(json)) { return(null); } var result = new HashSet <ProductDefinition>(); try { var container = (Dictionary <string, object>)MiniJson.JsonDecode(json); object storeCatalog; object abGroupObject; container.TryGetValue("catalog", out storeCatalog); if (container.TryGetValue("abGroup", out abGroupObject)) { if (profile != null) { profile.SetStoreABGroup(Convert.ToInt32(abGroupObject)); } } var cat = storeCatalog as Dictionary <string, object>; object catid; if (cat.TryGetValue("id", out catid)) { if (profile != null) { var id = catid as string; if (id == "") { id = "empty-catalog-id"; } profile.SetCatalogId(id); } } else { // Tracking the case when store catalog returns without an "id" field // May need to be an errr at some point if (profile != null) { profile.SetCatalogId("no-catalog-id-present"); } } object products; cat.TryGetValue("products", out products); var jsonList = (List <object>)products; return(jsonList.DecodeJSON(storeName)); } catch (Exception e) { if (logger != null) { logger.LogWarning("UnityIAP", "Error parsing catalog, exception " + e); } return(null); } }
private double computeExtraTime(string metadata, double new_sku_period_in_seconds) { var wrapper = (Dictionary <string, object>)MiniJson.JsonDecode(metadata); long old_sku_remaining_seconds = (long)wrapper["old_sku_remaining_seconds"]; long old_sku_price_in_micros = (long)wrapper["old_sku_price_in_micros"]; double old_sku_period_in_seconds = (parseTimeSpan((string)wrapper["old_sku_period_string"])).TotalSeconds; long new_sku_price_in_micros = (long)wrapper["new_sku_price_in_micros"]; double result = ((((double)old_sku_remaining_seconds / (double)old_sku_period_in_seconds) * (double)old_sku_price_in_micros) / (double)new_sku_price_in_micros) * new_sku_period_in_seconds; return(result); }
public static Dictionary <string, string> DeserializeProductDetails(string json) { var objects = (List <object>)MiniJson.JsonDecode(json); var result = new Dictionary <string, string>(); foreach (Dictionary <string, object> obj in objects) { var details = new Dictionary <string, string>(); if (obj.TryGetValue("metadata", out var metadata)) { var metadataStr = (Dictionary <string, object>)metadata; details["subscriptionNumberOfUnits"] = metadataStr.TryGetString("subscriptionNumberOfUnits"); details["subscriptionPeriodUnit"] = metadataStr.TryGetString("subscriptionPeriodUnit"); details["localizedPrice"] = metadataStr.TryGetString("localizedPrice"); details["isoCurrencyCode"] = metadataStr.TryGetString("isoCurrencyCode"); details["localizedPriceString"] = metadataStr.TryGetString("localizedPriceString"); details["localizedTitle"] = metadataStr.TryGetString("localizedTitle"); details["localizedDescription"] = metadataStr.TryGetString("localizedDescription"); details["introductoryPrice"] = metadataStr.TryGetString("introductoryPrice"); details["introductoryPriceLocale"] = metadataStr.TryGetString("introductoryPriceLocale"); details["introductoryPriceNumberOfPeriods"] = metadataStr.TryGetString("introductoryPriceNumberOfPeriods"); details["numberOfUnits"] = metadataStr.TryGetString("numberOfUnits"); details["unit"] = metadataStr.TryGetString("unit"); // this is a double check for Apple side's bug if (!string.IsNullOrEmpty(details["subscriptionNumberOfUnits"]) && string.IsNullOrEmpty(details["subscriptionPeriodUnit"])) { details["subscriptionPeriodUnit"] = "0"; } // this is a double check for Apple side's bug if (!string.IsNullOrEmpty(details["numberOfUnits"]) && string.IsNullOrEmpty(details["unit"])) { details["unit"] = "0"; } } else { Debug.LogWarning("metadata key not found in product details json"); } if (obj.TryGetValue("storeSpecificId", out var id)) { var idStr = (string)id; result.Add(idStr, MiniJson.JsonEncode(details)); } else { Debug.LogWarning("storeSpecificId key not found in product details json"); } } return(result); }
public static void UpdateSubscription(Product newProduct, Product oldProduct, string developerPayload, Action <Product, string> appleStore, Action <string, string> googleStore) { if (oldProduct.receipt == null) { Debug.Log("The product has not been purchased, a subscription can only be upgrade/downgrade when has already been purchased"); return; } var receipt_wrapper = (Dictionary <string, object>)MiniJson.JsonDecode(oldProduct.receipt); if (receipt_wrapper == null || !receipt_wrapper.ContainsKey("Store") || !receipt_wrapper.ContainsKey("Payload")) { Debug.Log("The product receipt does not contain enough information"); return; } var store = (string)receipt_wrapper ["Store"]; var payload = (string)receipt_wrapper ["Payload"]; if (payload != null) { switch (store) { case "GooglePlay": { SubscriptionManager oldSubscriptionManager = new SubscriptionManager(oldProduct, null); SubscriptionInfo oldSubscriptionInfo = null; try { oldSubscriptionInfo = oldSubscriptionManager.getSubscriptionInfo(); } catch (Exception e) { Debug.unityLogger.Log("Error: the product that will be updated does not have a valid receipt", e); return; } string newSubscriptionId = newProduct.definition.storeSpecificId; googleStore(oldSubscriptionInfo.getSubscriptionInfoJsonString(), newSubscriptionId); return; } case "AppleAppStore": case "MacAppStore": { appleStore(newProduct, developerPayload); return; } default: { Debug.Log("This store does not support update subscriptions"); return; } } } }
// parse the "payload" part to get the subscription // info from the platform based native receipt public SubscriptionInfo getSubscriptionInfo() { if (this.receipt != null) { var receipt_wrapper = (Dictionary <string, object>)MiniJson.JsonDecode(receipt); var validPayload = receipt_wrapper.TryGetValue("Payload", out var payloadAsObject); var validStore = receipt_wrapper.TryGetValue("Store", out var storeAsObject); if (validPayload && validStore) { var payload = payloadAsObject as string; var store = storeAsObject as string; switch (store) { case GooglePlay.Name: { return(getGooglePlayStoreSubInfo(payload)); } case AppleAppStore.Name: case MacAppStore.Name: { if (this.productId == null) { throw new NullProductIdException(); } return(getAppleAppStoreSubInfo(payload, this.productId)); } case AmazonApps.Name: { return(getAmazonAppStoreSubInfo(this.productId)); } default: { throw new StoreSubscriptionInfoNotSupportedException("Store not supported: " + store); } } } } throw new NullReceiptException(); }
/// <exception cref="System.ArgumentException">Thrown when parsing fails</exception> public static StoreConfiguration Deserialize(string json) { var dic = (Dictionary <string, object>)MiniJson.JsonDecode(json); AppStore store; var key = (string)dic ["androidStore"]; if (!Enum.IsDefined(typeof(AppStore), key)) { store = AppStore.GooglePlay; } else { store = (AppStore)Enum.Parse(typeof(AppStore), (string)dic["androidStore"], true); } return(new StoreConfiguration(store)); }
public static List <ProductDescription> DeserializeProductDescriptions(string json) { var objects = (List <object>)MiniJson.JsonDecode(json); var result = new List <ProductDescription>(); foreach (Dictionary <string, object> obj in objects) { var metadata = DeserializeMetadata((Dictionary <string, object>)obj["metadata"]); var product = new ProductDescription( (string)obj["storeSpecificId"], metadata, obj.TryGetString("receipt"), obj.TryGetString("transactionId"), ProductType.NonConsumable); result.Add(product); } return(result); }
private StoreSpecificPurchaseErrorCode ParseStoreSpecificPurchaseErrorCode(string json) { // If we didn't get any JSON just return Unknown. if (json == null) { return(StoreSpecificPurchaseErrorCode.Unknown); } // If the dictionary contains a storeSpecificErrorCode, return it, otherwise return Unknown. var purchaseFailureDictionary = MiniJson.JsonDecode(json) as Dictionary <string, object>; if (purchaseFailureDictionary != null && purchaseFailureDictionary.ContainsKey(kStoreSpecificErrorCodeKey) && Enum.IsDefined(typeof(StoreSpecificPurchaseErrorCode), (string)purchaseFailureDictionary[kStoreSpecificErrorCodeKey])) { string storeSpecificErrorCodeString = (string)purchaseFailureDictionary[kStoreSpecificErrorCodeKey]; return((StoreSpecificPurchaseErrorCode)Enum.Parse(typeof(StoreSpecificPurchaseErrorCode), storeSpecificErrorCodeString)); } return(StoreSpecificPurchaseErrorCode.Unknown); }
public static Dictionary <string, string> DeserializeSubscriptionDescriptions(string json) { var objects = (List <object>)MiniJson.JsonDecode(json); var result = new Dictionary <string, string>(); foreach (Dictionary <string, object> obj in objects) { var subscription = new Dictionary <string, string>(); if (obj.TryGetValue("metadata", out var metadata)) { var metadataDict = (Dictionary <string, object>)metadata; subscription["introductoryPrice"] = metadataDict.TryGetString("introductoryPrice"); subscription["introductoryPriceLocale"] = metadataDict.TryGetString("introductoryPriceLocale"); subscription["introductoryPriceNumberOfPeriods"] = metadataDict.TryGetString("introductoryPriceNumberOfPeriods"); subscription["numberOfUnits"] = metadataDict.TryGetString("numberOfUnits"); subscription["unit"] = metadataDict.TryGetString("unit"); // this is a double check for Apple side's bug if (!string.IsNullOrEmpty(subscription["numberOfUnits"]) && string.IsNullOrEmpty(subscription["unit"])) { subscription["unit"] = "0"; } } else { Debug.LogWarning("metadata key not found in subscription description json"); } if (obj.TryGetValue("storeSpecificId", out var id)) { var idStr = (string)id; result.Add(idStr, MiniJson.JsonEncode(subscription)); } else { Debug.LogWarning("storeSpecificId key not found in subscription description json"); } } return(result); }
public bool IsPurchasedProductDeferred(Product product) { try { var unifiedReceipt = MiniJson.JsonDecode(product.receipt) as Dictionary <string, object>; var payloadStr = unifiedReceipt["Payload"] as string; var payload = MiniJson.JsonDecode(payloadStr) as Dictionary <string, object>; var jsonStr = payload["json"] as string; var jsonDic = MiniJson.JsonDecode(jsonStr) as Dictionary <string, object>; var purchaseState = (long)jsonDic["purchaseState"]; //PurchaseState codes: https://developer.android.com/reference/com/android/billingclient/api/Purchase.PurchaseState#pending return(purchaseState == 2 || purchaseState == 4); } catch { Debug.LogWarning("Cannot parse Google receipt for transaction " + product.transactionID); return(false); } }
public static PurchaseFailureDescription DeserializeFailureReason(string json) { var dic = (Dictionary <string, object>)MiniJson.JsonDecode(json); var reason = PurchaseFailureReason.Unknown; if (dic.TryGetValue("reason", out var reasonStr)) { if (Enum.IsDefined(typeof(PurchaseFailureReason), (string)reasonStr)) { reason = (PurchaseFailureReason)Enum.Parse(typeof(PurchaseFailureReason), (string)reasonStr); } if (dic.TryGetValue("productId", out var productId)) { return(new PurchaseFailureDescription((string)productId, reason, dic.TryGetString("message"))); } } else { Debug.LogWarning("Reason key not found in purchase failure json: " + json); } return(new PurchaseFailureDescription("Unknown ProductID", reason, dic.TryGetString("message"))); }
private SubscriptionInfo getGooglePlayStoreSubInfo(string payload) { var payload_wrapper = (Dictionary <string, object>)MiniJson.JsonDecode(payload); var validSkuDetailsKey = payload_wrapper.TryGetValue("skuDetails", out var skuDetailsObject); string skuDetails = null; if (validSkuDetailsKey) { skuDetails = skuDetailsObject as string; } var purchaseHistorySupported = false; var original_json_payload_wrapper = (Dictionary <string, object>)MiniJson.JsonDecode((string)payload_wrapper["json"]); var validIsAutoRenewingKey = original_json_payload_wrapper.TryGetValue("autoRenewing", out var autoRenewingObject); var isAutoRenewing = false; if (validIsAutoRenewingKey) { isAutoRenewing = (bool)autoRenewingObject; } // Google specifies times in milliseconds since 1970. DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var validPurchaseTimeKey = original_json_payload_wrapper.TryGetValue("purchaseTime", out var purchaseTimeObject); long purchaseTime = 0; if (validPurchaseTimeKey) { purchaseTime = (long)purchaseTimeObject; } var purchaseDate = epoch.AddMilliseconds(purchaseTime); var validDeveloperPayloadKey = original_json_payload_wrapper.TryGetValue("developerPayload", out var developerPayloadObject); var isFreeTrial = false; var hasIntroductoryPrice = false; string updateMetadata = null; if (validDeveloperPayloadKey) { var developerPayloadJSON = (string)developerPayloadObject; var developerPayload_wrapper = (Dictionary <string, object>)MiniJson.JsonDecode(developerPayloadJSON); var validIsFreeTrialKey = developerPayload_wrapper.TryGetValue("is_free_trial", out var isFreeTrialObject); if (validIsFreeTrialKey) { isFreeTrial = (bool)isFreeTrialObject; } var validHasIntroductoryPriceKey = developerPayload_wrapper.TryGetValue("has_introductory_price_trial", out var hasIntroductoryPriceObject); if (validHasIntroductoryPriceKey) { hasIntroductoryPrice = (bool)hasIntroductoryPriceObject; } var validIsUpdatedKey = developerPayload_wrapper.TryGetValue("is_updated", out var isUpdatedObject); var isUpdated = false; if (validIsUpdatedKey) { isUpdated = (bool)isUpdatedObject; } if (isUpdated) { var isValidUpdateMetaKey = developerPayload_wrapper.TryGetValue("update_subscription_metadata", out var updateMetadataObject); if (isValidUpdateMetaKey) { updateMetadata = (string)updateMetadataObject; } } } return(new SubscriptionInfo(skuDetails, isAutoRenewing, purchaseDate, isFreeTrial, hasIntroductoryPrice, purchaseHistorySupported, updateMetadata)); }
public SubscriptionInfo(AppleInAppPurchaseReceipt r, string intro_json) { var productType = (AppleStoreProductType)Enum.Parse(typeof(AppleStoreProductType), r.productType.ToString()); if (productType == AppleStoreProductType.Consumable || productType == AppleStoreProductType.NonConsumable) { throw new InvalidProductTypeException(); } if (!string.IsNullOrEmpty(intro_json)) { var intro_wrapper = (Dictionary <string, object>)MiniJson.JsonDecode(intro_json); var nunit = -1; var unit = SubscriptionPeriodUnit.NotAvailable; this.introductory_price = intro_wrapper.TryGetString("introductoryPrice") + intro_wrapper.TryGetString("introductoryPriceLocale"); if (string.IsNullOrEmpty(this.introductory_price)) { this.introductory_price = "not available"; } else { try { this.introductory_price_cycles = Convert.ToInt64(intro_wrapper.TryGetString("introductoryPriceNumberOfPeriods")); nunit = Convert.ToInt32(intro_wrapper.TryGetString("numberOfUnits")); unit = (SubscriptionPeriodUnit)Convert.ToInt32(intro_wrapper.TryGetString("unit")); } catch (Exception e) { Debug.unityLogger.Log("Unable to parse introductory period cycles and duration, this product does not have configuration of introductory price period", e); unit = SubscriptionPeriodUnit.NotAvailable; } } DateTime now = DateTime.Now; switch (unit) { case SubscriptionPeriodUnit.Day: this.introductory_price_period = TimeSpan.FromTicks(TimeSpan.FromDays(1).Ticks *nunit); break; case SubscriptionPeriodUnit.Month: TimeSpan month_span = now.AddMonths(1) - now; this.introductory_price_period = TimeSpan.FromTicks(month_span.Ticks * nunit); break; case SubscriptionPeriodUnit.Week: this.introductory_price_period = TimeSpan.FromTicks(TimeSpan.FromDays(7).Ticks *nunit); break; case SubscriptionPeriodUnit.Year: TimeSpan year_span = now.AddYears(1) - now; this.introductory_price_period = TimeSpan.FromTicks(year_span.Ticks * nunit); break; case SubscriptionPeriodUnit.NotAvailable: this.introductory_price_period = TimeSpan.Zero; this.introductory_price_cycles = 0; break; } } else { this.introductory_price = "not available"; this.introductory_price_period = TimeSpan.Zero; this.introductory_price_cycles = 0; } DateTime current_date = DateTime.UtcNow; this.purchaseDate = r.purchaseDate; this.productId = r.productID; this.subscriptionExpireDate = r.subscriptionExpirationDate; this.subscriptionCancelDate = r.cancellationDate; // if the product is non-renewing subscription, apple store will not return expiration date for this product if (productType == AppleStoreProductType.NonRenewingSubscription) { this.is_subscribed = Result.Unsupported; this.is_expired = Result.Unsupported; this.is_cancelled = Result.Unsupported; this.is_free_trial = Result.Unsupported; this.is_auto_renewing = Result.Unsupported; this.is_introductory_price_period = Result.Unsupported; } else { this.is_cancelled = (r.cancellationDate.Ticks > 0) && (r.cancellationDate.Ticks < current_date.Ticks) ? Result.True : Result.False; this.is_subscribed = r.subscriptionExpirationDate.Ticks >= current_date.Ticks ? Result.True : Result.False; this.is_expired = (r.subscriptionExpirationDate.Ticks > 0 && r.subscriptionExpirationDate.Ticks < current_date.Ticks) ? Result.True : Result.False; this.is_free_trial = (r.isFreeTrial == 1) ? Result.True : Result.False; this.is_auto_renewing = ((productType == AppleStoreProductType.AutoRenewingSubscription) && this.is_cancelled == Result.False && this.is_expired == Result.False) ? Result.True : Result.False; this.is_introductory_price_period = r.isIntroductoryPricePeriod == 1 ? Result.True : Result.False; } if (this.is_subscribed == Result.True) { this.remainedTime = r.subscriptionExpirationDate.Subtract(current_date); } else { this.remainedTime = TimeSpan.Zero; } }
public SubscriptionInfo(string skuDetails, bool isAutoRenewing, DateTime purchaseDate, bool isFreeTrial, bool hasIntroductoryPriceTrial, bool purchaseHistorySupported, string updateMetadata) { var skuDetails_wrapper = (Dictionary <string, object>)MiniJson.JsonDecode(skuDetails); var validTypeKey = skuDetails_wrapper.TryGetValue("type", out var typeObject); if (!validTypeKey || (string)typeObject == "inapp") { throw new InvalidProductTypeException(); } var validProductIdKey = skuDetails_wrapper.TryGetValue("productId", out var productIdObject); productId = null; if (validProductIdKey) { productId = productIdObject as string; } this.purchaseDate = purchaseDate; this.is_subscribed = Result.True; this.is_auto_renewing = isAutoRenewing ? Result.True : Result.False; this.is_expired = Result.False; this.is_cancelled = isAutoRenewing ? Result.False : Result.True; this.is_free_trial = Result.False; string sub_period = null; if (skuDetails_wrapper.ContainsKey("subscriptionPeriod")) { sub_period = (string)skuDetails_wrapper["subscriptionPeriod"]; } string free_trial_period = null; if (skuDetails_wrapper.ContainsKey("freeTrialPeriod")) { free_trial_period = (string)skuDetails_wrapper["freeTrialPeriod"]; } string introductory_price = null; if (skuDetails_wrapper.ContainsKey("introductoryPrice")) { introductory_price = (string)skuDetails_wrapper["introductoryPrice"]; } string introductory_price_period_string = null; if (skuDetails_wrapper.ContainsKey("introductoryPricePeriod")) { introductory_price_period_string = (string)skuDetails_wrapper["introductoryPricePeriod"]; } long introductory_price_cycles = 0; if (skuDetails_wrapper.ContainsKey("introductoryPriceCycles")) { introductory_price_cycles = (long)skuDetails_wrapper["introductoryPriceCycles"]; } // for test free_trial_period_string = free_trial_period; this.subscriptionPeriod = computePeriodTimeSpan(parsePeriodTimeSpanUnits(sub_period)); this.freeTrialPeriod = TimeSpan.Zero; if (isFreeTrial) { this.freeTrialPeriod = parseTimeSpan(free_trial_period); } this.introductory_price = introductory_price; this.introductory_price_cycles = introductory_price_cycles; this.introductory_price_period = TimeSpan.Zero; this.is_introductory_price_period = Result.False; TimeSpan total_introductory_duration = TimeSpan.Zero; if (hasIntroductoryPriceTrial) { if (introductory_price_period_string != null && introductory_price_period_string.Equals(sub_period)) { this.introductory_price_period = this.subscriptionPeriod; } else { this.introductory_price_period = parseTimeSpan(introductory_price_period_string); } // compute the total introductory duration according to the introductory price period and period cycles total_introductory_duration = accumulateIntroductoryDuration(parsePeriodTimeSpanUnits(introductory_price_period_string), this.introductory_price_cycles); } // if this subscription is updated from other subscription, the remaining time will be applied to this subscription TimeSpan extra_time = TimeSpan.FromSeconds(updateMetadata == null ? 0.0 : computeExtraTime(updateMetadata, this.subscriptionPeriod.TotalSeconds)); TimeSpan time_since_purchased = DateTime.UtcNow.Subtract(purchaseDate); // this subscription is still in the extra time (the time left by the previous subscription when updated to the current one) if (time_since_purchased <= extra_time) { // this subscription is in the remaining credits from the previous updated one this.subscriptionExpireDate = purchaseDate.Add(extra_time); } else if (time_since_purchased <= this.freeTrialPeriod.Add(extra_time)) { // this subscription is in the free trial period // this product will be valid until free trial ends, the beginning of next billing date this.is_free_trial = Result.True; this.subscriptionExpireDate = purchaseDate.Add(this.freeTrialPeriod.Add(extra_time)); } else if (time_since_purchased < this.freeTrialPeriod.Add(extra_time).Add(total_introductory_duration)) { // this subscription is in the introductory price period this.is_introductory_price_period = Result.True; DateTime introductory_price_begin_date = this.purchaseDate.Add(this.freeTrialPeriod.Add(extra_time)); this.subscriptionExpireDate = nextBillingDate(introductory_price_begin_date, parsePeriodTimeSpanUnits(introductory_price_period_string)); } else { // no matter sub is cancelled or not, the expire date will be next billing date DateTime billing_begin_date = this.purchaseDate.Add(this.freeTrialPeriod.Add(extra_time).Add(total_introductory_duration)); this.subscriptionExpireDate = nextBillingDate(billing_begin_date, parsePeriodTimeSpanUnits(sub_period)); } this.remainedTime = this.subscriptionExpireDate.Subtract(DateTime.UtcNow); this.sku_details = skuDetails; }
/// <summary> /// Parse product definitions from JSON, selecting store specific identifiers /// for the specified store name. /// </summary> internal static HashSet <ProductDefinition> ParseProductsFromJSON(string json, string storeName) { var result = new HashSet <ProductDefinition>(); try { var container = (Dictionary <string, object>)MiniJson.JsonDecode(json); object products; container.TryGetValue("products", out products); var productsList = products as List <object>; var snakeCaseStoreName = CamelCaseToSnakeCase(storeName); foreach (object product in productsList) { var productDict = (Dictionary <string, object>)product; object id, storeIDs, typeString; // Remove payouts and enabled references for 1.13.0. //object enabled, payoutsJson; productDict.TryGetValue("id", out id); productDict.TryGetValue("store_ids", out storeIDs); productDict.TryGetValue("type", out typeString); // Remove payouts and enabled references for 1.13.0. //productDict.TryGetValue("enabled", out enabled); //productDict.TryGetValue("payouts", out payoutsJson); var idHash = storeIDs as Dictionary <string, object>; string storeSpecificId = (string)id; if (null != idHash && idHash.ContainsKey(snakeCaseStoreName)) { object storeId = null; idHash.TryGetValue(snakeCaseStoreName, out storeId); if (null != storeId) { storeSpecificId = (string)storeId; } } var type = (ProductType)Enum.Parse(typeof(ProductType), (string)typeString); // Remove payouts and enabled references for 1.13.0. //bool enabledBool = true; //if (enabled != null && (enabled is bool || enabled is Boolean)) { // enabledBool = (bool)enabled; //} //var definition = new ProductDefinition((string)id, storeSpecificId, type, enabledBool); var definition = new ProductDefinition((string)id, storeSpecificId, type); // Remove payouts and enabled references for 1.13.0. //List<object> payoutsJsonArray = payoutsJson as List<object>; //if (payoutsJsonArray != null) { // var payouts = new List<PayoutDefinition>(); // foreach (object payoutJson in payoutsJsonArray) { // Dictionary<string, object> payoutJsonDict = payoutJson as Dictionary<string, object>; // object payoutTypeString, subtype, quantity, data; // payoutJsonDict.TryGetValue("t", out payoutTypeString); // payoutJsonDict.TryGetValue("st", out subtype); // payoutJsonDict.TryGetValue("q", out quantity); // payoutJsonDict.TryGetValue("d", out data); // // double q = quantity == null ? 0 : Convert.ToDouble (quantity); // // payouts.Add(new PayoutDefinition((string)payoutTypeString, (string)subtype, q, (string)data)); // } // definition.SetPayouts(payouts); //} result.Add(definition); } return(result); } catch (Exception e) { throw new SerializationException("Error parsing JSON", e); } }