public ActionResult Receipt(EmailOrderReceiptModel model)
 {
     return(Json(mailer.Receipt(model)));
 }
Beispiel #2
0
        public Status <Order> ProcessOrder(
            string username, int orderId, UserCreditCard card, bool saveCard)
        {
            bool isNewCard = card.UserCreditCardId == 0;

            if (isNewCard)
            {
                // we're adding the new card regardless but we don't know if its valid
                // if the user requested to save it we will make it active after the payment
                // is successful, otherwise it will remain inactive
                card.IsDeleted = true;

                var cardResult = AddUserCreditCard(username, card);

                if (cardResult.StatusCode != 200)
                {
                    var orderStatus = GetOrderForCheckout(username, orderId);

                    orderStatus.StatusCode = 500;
                    orderStatus.Errors     = new ValidationResult[] {
                        new ValidationResult("An unexpected failure occurred: payment was not processed", new string[] { "Order" })
                    };

                    return(orderStatus);
                }
            }
            else
            {
                //get the card
                var storedCard = GetUserCreditCard(username, card.UserCreditCardId);

                if (storedCard == null)
                {
                    var orderStatus = GetOrderForCheckout(username, orderId);

                    orderStatus.StatusCode = 500;
                    orderStatus.Errors     = new ValidationResult[] {
                        new ValidationResult("Failed to locate credit card on file: payment was not processed", new string[] { "Order" })
                    };

                    return(orderStatus);
                }

                //update the billing address if anything changed
                if (storedCard.Address1 != card.Address1 ||
                    storedCard.Address2 != card.Address2 ||
                    storedCard.City != card.City ||
                    storedCard.FirstName != card.FirstName ||
                    storedCard.LastName != card.LastName ||
                    storedCard.State != card.State ||
                    storedCard.Zip != card.Zip)
                {
                    storedCard.Address1  = card.Address1;
                    storedCard.Address2  = card.Address2;
                    storedCard.City      = card.City;
                    storedCard.FirstName = card.FirstName;
                    storedCard.LastName  = card.LastName;
                    storedCard.State     = card.State;
                    storedCard.Zip       = card.Zip;

                    var updateStatus = UpdateUserCreditCard(username, storedCard);

                    if (updateStatus.StatusCode != 200)
                    {
                        var orderStatus = GetOrderForCheckout(username, orderId);

                        orderStatus.StatusCode = 500;
                        orderStatus.Errors     = new ValidationResult[] {
                            new ValidationResult("Failed to update card address: payment was not processed", new string[] { "Order" })
                        };

                        return(orderStatus);
                    }
                }

                card = storedCard;
            }

            //grab the order
            var order = GetOrderForCheckout(username, orderId);

            //attach the credit card to the order for our records
            order.Result.UserCreditCardId = card.UserCreditCardId;

            if (order.StatusCode != 200)
            {
                return(order);
            }

            //let's pay for stuff!

            CardPaymentResult result;

            if (App.StorePricing == "Penny")
            {
                result = manager.AuthorizeCreditCardPayment(card, 0.01m);
            }
            else
            {
                result = manager.AuthorizeCreditCardPayment(card, order.Result.OrderTotal);
            }

            //did it work?
            if (result.Approved)
            {
                order.Result.OrderStatus = OrderStatus.Succeeded;
            }
            else
            {
                order.StatusCode = 500;

                // the payment method used is not valid so it should not be attached to
                // the order. Clear it here and the change will be persisted later
                order.Result.UserCreditCardId = null;

                //gateway might be down
                if (result.ServiceUnavailable)
                {
                    order.Result.OrderStatus = OrderStatus.ServiceUnavailable;
                    order.Errors             = new ValidationResult[] {
                        new ValidationResult("Payment service is unavailable. Please try again later.", new string[] { "Order" })
                    };
                }
                //or it was declined
                else
                {
                    order.Result.OrderStatus = OrderStatus.CardDeclined;
                    order.Errors             = new ValidationResult[] {
                        new ValidationResult("Credit Card was declined", new string[] { "Order" })
                    };
                }
            }

            //update the order status
            using (var context = new RentlerContext())
            {
                var toUpdate = (from o in context.Orders
                                .Include("Building")
                                where o.OrderId == order.Result.OrderId
                                select o).SingleOrDefault();

                toUpdate.OrderStatus      = order.Result.OrderStatus;
                toUpdate.UserCreditCardId = order.Result.UserCreditCardId;

                //remove temporary order if we're good
                if (order.Result.OrderStatus == OrderStatus.Succeeded)
                {
                    toUpdate.Building.TemporaryOrderId = null;

                    // allow credit card to be used again if requested
                    if (isNewCard && saveCard)
                    {
                        context.Entry(toUpdate).Reference(o => o.UserCreditCard).Load();
                        toUpdate.UserCreditCard.IsDeleted = false;
                    }
                }

                context.SaveChanges();
            }

            // send receipt only if order was successful
            if (order.Result.OrderStatus == OrderStatus.Succeeded)
            {
                //send a receipt
                EmailOrderReceiptModel model = new EmailOrderReceiptModel()
                {
                    To         = order.Result.User.Email,
                    Name       = string.Format("{0} {1}", order.Result.User.FirstName, order.Result.User.LastName),
                    BuildingId = (order.Result.BuildingId.HasValue) ? order.Result.BuildingId.Value : 0,
                    OrderItems = order.Result.OrderItems.ToList(),
                    OrderTotal = order.Result.OrderTotal
                };
                mailer.Receipt(model);
            }

            return(order);
        }