public ActionResult Review(ReviewViewModel model) { CheckoutViewModel checkoutModel; if (CacheHelpers.GetCheckoutInstanceFromCache(model.CheckoutInstance, this.ControllerContext, out checkoutModel) != CacheHelpers.CheckoutCacheStatus.Success) { return(RedirectToAction("Index", "ShoppingCart")); } //Check to see where the user was trying to go if (ConfirmButtonWasClicked()) { //Clear the checkoutmodel from cache to prevent reprocessing CacheHelpers.RemoveCheckoutInstanceFromCache(this.ControllerContext); Order toCreate = checkoutModel.GetOrder(IdentityHelpers.GetUserId(this.User.Identity)); Boolean orderCreated = false; Int32 attempts = 3; Order newOrder = null; using (TransactionScope orderProcessingScope = new TransactionScope()) { do { try { using (TransactionScope createOrderScope = new TransactionScope()) { _shoppingCartService.EmptyCart(ShoppingCartHelpers.GetShoppingCartID(this.ControllerContext)); if (!_productService.DecrementInventory(toCreate.OrderDetails)) { return(RedirectToAction("StockUnavailable", "Checkout")); } newOrder = _orderService.CreateOrder(toCreate); _uow.Save(); orderCreated = true; createOrderScope.Complete(); } } catch (DbUpdateConcurrencyException ex) { //Reload any entry that changed with new values before we retry foreach (var item in ex.Entries) { item.Reload(); } attempts--; } } while (!orderCreated && attempts > 0); if (orderCreated) { using (TransactionScope scope = new TransactionScope()) { var payment = new CreditCardPayment() { Amount = newOrder.SubTotal + newOrder.Tax + newOrder.ShippingCost, CreditCardNumber = checkoutModel.CreditCardPayment.CreditCardNumber, CVV = checkoutModel.CreditCardPayment.CVV, Expiration = new DateTime(checkoutModel.CreditCardPayment.ExpirationYear, checkoutModel.CreditCardPayment.ExpirationMonth, DateTime.DaysInMonth(checkoutModel.CreditCardPayment.ExpirationYear, checkoutModel.CreditCardPayment.ExpirationMonth), 0, 0, 0) }; //Authorize the payment var paymentAuthResult = _creditCardService .Authorize(payment, "Payment for order " + newOrder.OrderID, newOrder.BillingAddress); //If successful authorization if (paymentAuthResult.Success) { _transactionService.Create(paymentAuthResult.Transaction); newOrder.OrderStatus = OrderStatus.Processing; _orderService.Update(newOrder); _uow.Save(); _emailService.SendMessage(EmailHelpers.GetOrderReceivedEmail(this, newOrder.Email, newOrder.OrderID)); scope.Complete(); orderProcessingScope.Complete(); TempData.Add("OrderID", newOrder.OrderID); return(RedirectToAction("Confirmation")); } else { paymentAuthResult.Errors.ForEach(e => ModelState.AddModelError("", e)); } } } else { ModelState.AddModelError("", "We're sorry, there was a problem creating your order. " + "Please try again and if the problem persists, please try again later."); } } CacheHelpers.InsertCheckoutInstanceIntoCache(checkoutModel, this.ControllerContext); var reModel = checkoutModel.GetReviewViewModel(); return(View("Review", reModel)); } else if (PreviousButtonWasClicked()) { var previousModel = checkoutModel.GetBillingViewModel(); ModelState.Clear(); return(View("BillingInformation", previousModel)); } throw new HttpException(500, "Invalid destination."); }