Main class to handle order creation and submittion to Riskified Servers
        public static void SendOrdersToRiskifiedExample()
        {
            #region preprocessing and loading config
            
            string domain = ConfigurationManager.AppSettings["MerchantDomain"];
            string authToken = ConfigurationManager.AppSettings["MerchantAuthenticationToken"];
            RiskifiedEnvironment riskifiedEnv = (RiskifiedEnvironment) Enum.Parse(typeof (RiskifiedEnvironment),ConfigurationManager.AppSettings["RiskifiedEnvironment"]);

            // Generating a random starting order number
            // we need to send the order with a new order number in order to create it on riskified
            var rand = new Random();
            int orderNum = rand.Next(1000, 200000);

            #endregion

            #region order object creation

            // generate a new order - the sample generates a fixed order with same details but different order number each time
            // see GenerateOrder for more info on how to create the Order objects
            var order = GenerateOrder(orderNum);

            #endregion

            #region sending data to riskified

            // read action from console
            const string menu = "Commands:\n" +
                                "'p' for checkout\n" +
                                "'e' for checkout denied\n" +
                                "'c' for create\n" +
                                "'u' for update\n" +
                                "'s' for submit\n" +
                                "'d' for cancel\n" +
                                "'r' for partial refund\n" +
                                "'f' for fulfill\n" +
                                "'x' for decision\n" +
                                "'h' for historical sending\n" +
                                "'q' to quit";
            Console.WriteLine(menu);
            string commandStr = Console.ReadLine();

            
            // loop on console actions 
            while (commandStr != null && (!commandStr.Equals("q")))
            {
                
                

                // the OrdersGateway is responsible for sending orders to Riskified servers
                OrdersGateway gateway = new OrdersGateway(riskifiedEnv, authToken, domain);
                try
                {
                    OrderNotification res=null;
                    switch (commandStr)
                    {
                        case "p":
                            Console.WriteLine("Order checkout Generated with merchant order number: " + orderNum);
                            var orderCheckout = GenerateOrderCheckout(orderNum.ToString());
                            orderCheckout.Id = orderNum.ToString();
                            
                            // sending order checkout for creation (if new orderNum) or update (if existing orderNum)
                            res = gateway.Checkout(orderCheckout);
                            break;
                        case "e":
                            Console.WriteLine("Order checkout Generated.");
                            var orderCheckoutDenied = GenerateOrderCheckoutDenied(orderNum);
                            
                            Console.Write("checkout to deny id: ");
                            string orderCheckoutDeniedId = Console.ReadLine();

                            orderCheckoutDenied.Id = orderCheckoutDeniedId;
                            



                            // sending order checkout for creation (if new orderNum) or update (if existing orderNum)
                            res = gateway.CheckoutDenied(orderCheckoutDenied);
                            break;
                        case "c":
                            Console.WriteLine("Order Generated with merchant order number: " + orderNum);
                            order.Id = orderNum.ToString();
                            orderNum++;
                            // sending order for creation (if new orderNum) or update (if existing orderNum)
                            res = gateway.Create(order);
                            break;
                        case "s":
                            Console.WriteLine("Order Generated with merchant order number: " + orderNum);
                            order.Id = orderNum.ToString();
                            orderNum++;
                            // sending order for submitting and analysis 
                            // it will generate a callback to the notification webhook (if defined) with a decision regarding the order
                            res = gateway.Submit(order);
                            break;
                        case "u":
                            Console.Write("Updated order id: ");
                            string upOrderId = Console.ReadLine();
                            order.Id = int.Parse(upOrderId).ToString();
                            res = gateway.Update(order);
                            break;
                        case "d":
                            Console.Write("Cancelled order id: ");
                            string canOrderId = Console.ReadLine();
                            res = gateway.Cancel(
                                new OrderCancellation(
                                    merchantOrderId: int.Parse(canOrderId),
                                    cancelledAt: DateTime.Now,
                                    cancelReason: "Customer cancelled before shipping"));
                            break;
                        case "r":
                            Console.Write("Refunded order id: ");
                            string refOrderId = Console.ReadLine();
                            res = gateway.PartlyRefund(
                                new OrderPartialRefund(
                                    merchantOrderId: int.Parse(refOrderId),
                                    partialRefunds: new[]
                                    {
                                        new PartialRefundDetails(
                                            refundId: "12345",
                                            refundedAt: DateTime.Now,  // make sure to initialize DateTime with the correct timezone
                                            amount: 5.3,
                                            currency: "USD",
                                            reason: "Customer partly refunded on shipping fees")
                                    }));
                            break;
                        case "f":
                            Console.Write("Fulfill order id: ");
                            string fulfillOrderId = Console.ReadLine();
                            OrderFulfillment orderFulfillment = GenerateFulfillment(int.Parse(fulfillOrderId));
                            res = gateway.Fulfill(orderFulfillment);

                            break;
                        case "x":
                            Console.Write("Decision order id: ");
                            string decisionOrderId = Console.ReadLine();
                            OrderDecision orderDecision = GenerateDecision(int.Parse(decisionOrderId));
                            res = gateway.Decision(orderDecision);

                            break;
                        case "h":
                            int startOrderNum = orderNum;
                            var orders = new List<Order>();
                            var financialStatuses = new[] { "paid", "cancelled", "chargeback" };
                            for (int i = 0; i < 22; i++)
                            {
                                Order o = GenerateOrder(orderNum++);
                                o.FinancialStatus = financialStatuses[i%3];
                                orders.Add(o);
                            }
                            Console.WriteLine("Orders Generated with merchant order numbers: {0} to {1}",startOrderNum,orderNum-1);
                            // sending 3 historical orders with different processing state
                            Dictionary<string,string> errors;
                            bool success = gateway.SendHistoricalOrders(orders,out errors);
                            if(success)
                            {
                                Console.WriteLine("All historical orders sent successfully");
                            }
                            else
                            {
                                Console.WriteLine("Some historical orders failed to send:");
                                Console.WriteLine(String.Join("\n", errors.Select(p => p.Key + ":" + p.Value).ToArray()));
                            }
                            break;

                    }


                    if (res != null)
                    {
                        Console.WriteLine("\n\nOrder sent successfully:" + 
                                              "\nStatus at Riskified: " + res.Status +
                                              "\nOrder ID received:" + res.Id +
                                              "\nDescription: " + res.Description + 
                                              "\nWarnings: " + (res.Warnings==null ? "---" : string.Join("        \n",res.Warnings)) + "\n\n");
                    }
                }
                catch (OrderFieldBadFormatException e)
                {
                    // catching 
                    Console.WriteLine("Exception thrown on order field validation: " + e.Message);
                }
                catch (RiskifiedTransactionException e)
                {
                    Console.WriteLine("Exception thrown on transaction: " + e.Message);
                }

                // ask for next action to perform
                Console.WriteLine();
                Console.WriteLine(menu);
                commandStr = Console.ReadLine();
            }

            #endregion

        }
        public static int runAll()
        {
            try
            {
                string domain = ConfigurationManager.AppSettings["MerchantDomain"];
                string authToken = ConfigurationManager.AppSettings["MerchantAuthenticationToken"];
                RiskifiedEnvironment riskifiedEnv = (RiskifiedEnvironment)Enum.Parse(typeof(RiskifiedEnvironment), ConfigurationManager.AppSettings["RiskifiedEnvironment"]);

                OrderNotification res = null;
                var rand = new Random();
                int orderNum = rand.Next(1000, 200000);
                var order = GenerateOrder(orderNum);

                OrdersGateway gateway = new OrdersGateway(riskifiedEnv, authToken, domain);

                var orderCheckout = GenerateOrderCheckout(orderNum.ToString());
                orderCheckout.Id = orderNum.ToString();
                res = gateway.Checkout(orderCheckout);

                var orderCheckoutDenied = GenerateOrderCheckoutDenied(orderNum);
                orderNum++;
                orderCheckoutDenied.Id = orderNum.ToString();
                res = gateway.CheckoutDenied(orderCheckoutDenied);

                orderNum++;
                order.Id = orderNum.ToString();
                res = gateway.Create(order);

                order.Id = orderNum.ToString();
                orderNum++;
                res = gateway.Submit(order);

                res = gateway.Update(order);
                res = gateway.Cancel(
                                new OrderCancellation(
                                    merchantOrderId: order.Id,
                                    cancelledAt: DateTime.Now,
                                    cancelReason: "Customer cancelled before shipping"));

                order.Id = orderNum.ToString();
                orderNum++;
                // sending order for creation (if new orderNum) or update (if existing orderNum)
                res = gateway.Create(order);

                order.Id = orderNum.ToString();
                orderNum++;
                // sending order for submitting and analysis
                // it will generate a callback to the notification webhook (if defined) with a decision regarding the order
                res = gateway.Submit(order);

                order.Id = order.Id;
                res = gateway.Update(order);

                res = gateway.Cancel(
                    new OrderCancellation(
                        merchantOrderId: int.Parse(order.Id),
                        cancelledAt: DateTime.Now,
                        cancelReason: "Customer cancelled before shipping"));

                res = gateway.PartlyRefund(
                    new OrderPartialRefund(
                        merchantOrderId: int.Parse(order.Id),
                        partialRefunds: new[]
                                    {
                                        new PartialRefundDetails(
                                            refundId: "12345",
                                            refundedAt: DateTime.Now,  // make sure to initialize DateTime with the correct timezone
                                            amount: 5.3,
                                            currency: "USD",
                                            reason: "Customer partly refunded on shipping fees")
                                    }));

                OrderFulfillment orderFulfillment = GenerateFulfillment(int.Parse(order.Id));
                res = gateway.Fulfill(orderFulfillment);

                OrderDecision orderDecision = GenerateDecision(int.Parse(order.Id));
                res = gateway.Decision(orderDecision);

            }
            catch (Exception ex)
            {
                Console.WriteLine("[failed] " + ex.ToString());
                return -1;
            }

            return 0;
        }