public void onPurchaseSucceeded(string data, string receipt)
        {
            Dictionary <string, object> response = (Dictionary <string, object>)Unibill.Impl.MiniJSON.jsonDecode(data);

            var productId     = (string)response ["productId"];
            var transactionId = response.getString("transactionIdentifier");

            // If we're restoring, make sure it isn't a consumable.
            if (restoreInProgress)
            {
                if (remapper.canMapProductSpecificId(productId))
                {
                    if (remapper.getPurchasableItemFromPlatformSpecificId(productId).PurchaseType == PurchaseType.Consumable)
                    {
                        // Silently ignore this consumable.
                        logger.Log("Ignoring restore of consumable: " + productId);
                        // We must close the transaction or storekit will keep sending it to us.
                        storekit.finishTransaction(transactionId);
                        return;
                    }
                }
            }

            biller.onPurchaseSucceeded(productId, receipt, transactionId);
        }
        public void onPurchaseSucceeded(string json)
        {
            Dictionary <string, object> response = (Dictionary <string, object>)Unibill.Impl.MiniJSON.jsonDecode(json);
            var signature     = (string)response ["signature"];
            var productId     = (string)response ["productId"];
            var transactionId = (string)response ["transactionId"];

            if (!verifyReceipt(signature))
            {
                logger.Log("Signature is invalid!");
                callback.onPurchaseFailedEvent(new PurchaseFailureDescription(productId, PurchaseFailureReason.SIGNATURE_INVALID, "mono"));
                return;
            }
            callback.onPurchaseSucceeded(productId, signature, transactionId);
        }
 public RemoteConfigManager(IResourceLoader loader, IStorage storage, Uniject.ILogger logger, RuntimePlatform platform, List <ProductDefinition> runtimeProducts = null)
 {
     this.storage  = storage;
     logger.prefix = "Unibill.RemoteConfigManager";
     this.XML      = loader.openTextFile("unibillInventory.json").ReadToEnd();
     Config        = new UnibillConfiguration(XML, platform, logger, runtimeProducts);
     if (Config.UseHostedConfig)
     {
         string val = storage.GetString(CACHED_CONFIG_PATH, string.Empty);
         if (string.IsNullOrEmpty(val))
         {
             logger.Log("No cached config available. Using bundled");
         }
         else
         {
             logger.Log("Cached config found, attempting to parse");
             try {
                 Config = new UnibillConfiguration(val, platform, logger, runtimeProducts);
                 if (Config.inventory.Count == 0)
                 {
                     logger.LogError("No purchasable items in cached config, ignoring.");
                     Config = new UnibillConfiguration(XML, platform, logger, runtimeProducts);
                 }
                 else
                 {
                     logger.Log(string.Format("Using cached config with {0} purchasable items", Config.inventory.Count));
                     XML = val;
                 }
             } catch (Exception e) {
                 logger.LogError("Error parsing inventory: {0}", e.Message);
                 Config = new UnibillConfiguration(XML, platform, logger, runtimeProducts);
             }
         }
         refreshCachedConfig(Config.HostedConfigUrl, logger);
     }
     else
     {
         logger.Log("Not using cached inventory, using bundled.");
         Config = new UnibillConfiguration(XML, platform, logger, runtimeProducts);
     }
 }
        public void purchase(PurchasableItem item, string developerPayload = "")
        {
            if (State == BillerState.INITIALISING)
            {
                logError(UnibillError.BILLER_NOT_READY);
                onPurchaseFailedEvent(item, PurchaseFailureReason.BILLER_NOT_READY);
                return;
            }
            else if (State == BillerState.INITIALISED_WITH_CRITICAL_ERROR)
            {
                logError(UnibillError.UNIBILL_INITIALISE_FAILED_WITH_CRITICAL_ERROR);
                onPurchaseFailedEvent(item, PurchaseFailureReason.BILLING_UNAVAILABLE);
                return;
            }

            if (null == item)
            {
                logger.LogError("Trying to purchase null PurchasableItem");
                return;
            }

            if (!item.AvailableToPurchase)
            {
                logError(UnibillError.UNIBILL_MISSING_PRODUCT, item.Id);
                return;
            }

            if (item.PurchaseType == PurchaseType.NonConsumable && transactionDatabase.getPurchaseHistory(item) > 0)
            {
                logError(UnibillError.UNIBILL_ATTEMPTING_TO_PURCHASE_ALREADY_OWNED_NON_CONSUMABLE);
                onPurchaseFailedEvent(item, PurchaseFailureReason.CANNOT_REPURCHASE_NON_CONSUMABLE);
                return;
            }

            billingSubsystem.purchase(remapper.mapItemIdToPlatformSpecificId(item), developerPayload);
            logger.Log("purchase({0})", item.Id);
        }
 private void refreshCachedConfig(string url, Uniject.ILogger logger)
 {
     logger.Log("Trying to fetch remote config...");
     new GameObject().AddComponent <RemoteConfigFetcher> ().Fetch(storage, Config.HostedConfigUrl, CACHED_CONFIG_PATH);
 }