/// <summary>
        /// Does the express checkout.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="authorizeOnly">if set to <c>true</c> [authorize only].</param>
        /// <param name="userName">Name of the user.</param>
        /// <returns></returns>
        public static Transaction DoExpressCheckout(Order order, bool authorizeOnly, string userName)
        {
            PaymentService paymentService = new PaymentService();
              Transaction transaction = paymentService.DoExpressCheckout(order, authorizeOnly);
              order.OrderStatusDescriptorId = (int)OrderStatus.ReceivedPaymentProcessingOrder;
              order.Save(userName);

              try {
            //Adjust the Inventory
            Sku sku;
            foreach (OrderItem orderItem in order.OrderItemCollection) {
              sku = new Sku(SKU, orderItem.Sku);
              sku.Inventory = sku.Inventory - orderItem.Quantity;
              sku.Save(SYSTEM);
              ProductCache.RemoveSKUFromCache(orderItem.Sku);
            }
            //Send out the messages
            MessageService messageService = new MessageService();
            messageService.SendOrderReceivedNotificationToCustomer(order);
            messageService.SendOrderReceivedNotificationToMerchant(order);
              }
              catch (Exception ex) {
            //swallow the exception here because the transaction is saved
            //and, while this is an inconvenience, it's not critical
            Logger.Error(typeof(OrderController).Name + ".DoExpressCheckout", ex);
              }
              return transaction;
        }
        /// <summary>
        /// Charges the specified order.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="userName">Name of the user.</param>
        /// <returns></returns>
        public static Transaction Charge(Order order, string userName)
        {
            //update the order with IP
              order.IPAddress = HttpContext.Current.Request.UserHostAddress;
              PaymentService paymentService = new PaymentService();
              Transaction transaction = paymentService.Charge(order);
              order.OrderStatusDescriptorId = (int)OrderStatus.ReceivedPaymentProcessingOrder;
              order.OrderTypeId = (int)OrderType.Purchase;
              order.Save(userName);
              Guid userGuid = new Guid(Membership.GetUser(userName).ProviderUserKey.ToString());
              try {
            //Add an OrderNote
            OrderNote orderNote = new OrderNote();
            orderNote.OrderId = order.OrderId;
            orderNote.Note = Strings.ResourceManager.GetString(ORDER_CHARGED);
            orderNote.Save(userName);
            Sku sku;
            DownloadCollection downloadCollection;
            DownloadAccessControlCollection downloadAccessControlCollection;
            DownloadAccessControl downloadAccessControl;
            foreach (OrderItem orderItem in order.OrderItemCollection) {
              //Adjust the Inventory
              sku = new Sku(SKU, orderItem.Sku);
              sku.Inventory = sku.Inventory - orderItem.Quantity;
              sku.Save(SYSTEM);
              ProductCache.RemoveSKUFromCache(orderItem.Sku);
              //Add access control for orderitems
              downloadCollection = new ProductController().FetchAssociatedDownloadsByProductIdAndForPurchase(orderItem.ProductId);
              if (downloadCollection.Count > 0) {
            foreach (Download download in downloadCollection) {
              Query query = new Query(DownloadAccessControl.Schema).
                AddWhere(DownloadAccessControl.Columns.UserId, Comparison.Equals, userGuid).
                AddWhere(DownloadAccessControl.Columns.DownloadId, Comparison.Equals, download.DownloadId);
              downloadAccessControlCollection = new DownloadAccessControlController().FetchByQuery(query);
              if (downloadAccessControlCollection.Count == 0) {
                downloadAccessControl = new DownloadAccessControl();
                downloadAccessControl.DownloadId = download.DownloadId;
                downloadAccessControl.UserId = userGuid;
                downloadAccessControl.Save(SYSTEM);
              }
            }
              }
            }

            //Send out the messages
            //Send these last in case something happens with the email
            MessageService messageService = new MessageService();
            messageService.SendOrderReceivedNotificationToCustomer(order);
            messageService.SendOrderReceivedNotificationToMerchant(order);
              }
              catch (Exception ex) {
            //swallow the exception here because the transaction is saved
            //and, while this is an inconvenience, it's not critical
            Logger.Error(typeof(OrderController).Name + ".Charge", ex);
              }
              return transaction;
        }
        /// <summary>
        /// Commits the standard transaction.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="transactionId">The transaction id.</param>
        /// <param name="grossAmount">The gross amount.</param>
        /// <returns></returns>
        public static Transaction CommitStandardTransaction(Order order, string transactionId, decimal grossAmount)
        {
            order.OrderStatusDescriptorId = (int)OrderStatus.ReceivedPaymentProcessingOrder;
              order.Save(SYSTEM);
              Transaction transaction = new Transaction();
              transaction.OrderId = order.OrderId;
              transaction.TransactionTypeDescriptorId = (int)TransactionType.Charge;
              transaction.PaymentMethod = PAYPAL;
              transaction.GatewayName = PAYPAL_STANDARD;
              transaction.GatewayResponse = SUCCESS;
              transaction.GatewayTransactionId = transactionId;
              transaction.GrossAmount = grossAmount;
              transaction.TransactionDate = DateTime.UtcNow;
              transaction.Save(SYSTEM);

              try {
            //Adjust the Inventory
            Sku sku;
            foreach (OrderItem orderItem in order.OrderItemCollection) {
              sku = new Sku("Sku", orderItem.Sku);
              sku.Inventory = sku.Inventory - orderItem.Quantity;
              sku.Save("System");
              ProductCache.RemoveSKUFromCache(orderItem.Sku);
            }
            //Send out the messages
            MessageService messageService = new MessageService();
            messageService.SendOrderReceivedNotificationToCustomer(order);
            messageService.SendOrderReceivedNotificationToMerchant(order);
              }
              catch (Exception ex) {
            //swallow the exception here because the transaction is saved
            //and, while this is an inconvenience, it's not critical
            Logger.Error(typeof(OrderController).Name + ".CommitStandardTransaction", ex);
              }
              return transaction;
        }