private ViewResult PaymentResponseSuccess(DoExpressCheckoutPaymentResponseType response, Checkout checkout, List<CartItem> cart)
 {
     var failure = new List<string>();
     var paymentStatus = response.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0].PaymentStatus;
     if (paymentStatus == PaymentStatusCodeType.DENIED)
     {
         //change
         failure.Add("Unsuccessful.");
         return PaymentFailed(failure);
     }
     if (paymentStatus == PaymentStatusCodeType.VOIDED || paymentStatus == PaymentStatusCodeType.EXPIRED)
     {
         //changes
         failure.Add("Expired");
         return PaymentFailed(failure);
     }
     if (paymentStatus == PaymentStatusCodeType.COMPLETED || paymentStatus == PaymentStatusCodeType.PENDING ||
         paymentStatus == PaymentStatusCodeType.COMPLETEDFUNDSHELD)
     {
         return PaymentSuccess(response, checkout, cart);
     }
     if (paymentStatus == PaymentStatusCodeType.FAILED)
     {
         failure.Add("Failed");
         return PaymentFailed(failure);
     }
     throw new InvalidOperationException("Invalid payment operation.");
 }
        /// <summary>
        /// Checkout Validation
        /// </summary>
        /// <param name="checkout"></param>
        /// <returns></returns>
        private IEnumerable<string> Validate(Checkout checkout)
        {
            var validationMessage = new List<string>();

            if (string.IsNullOrEmpty(checkout.BillingInfo.FirstName))
            {
                validationMessage.Add("Firstname cannot be emptied.");
            }

            if (string.IsNullOrEmpty(checkout.BillingInfo.SurName))
            {
                validationMessage.Add("Surname cannot be emptied.");
            }

            if (string.IsNullOrEmpty(checkout.BillingInfo.FirmName))
            {
                validationMessage.Add("First Name cannot be emptied.");
            }

            if (string.IsNullOrEmpty(checkout.BillingInfo.BuildingName))
            {
                validationMessage.Add("Building No and Name cannot be emptied.");
            }

            if (string.IsNullOrEmpty(checkout.BillingInfo.StreetName))
            {
                validationMessage.Add("Street Name cannot be emptied.");
            }
            if (string.IsNullOrEmpty(checkout.BillingInfo.City))
            {
                validationMessage.Add("City cannot be emptied.");
            }
            if (string.IsNullOrEmpty(checkout.BillingInfo.County))
            {
                validationMessage.Add("County cannot be emptied.");
            }
            if (string.IsNullOrEmpty(checkout.BillingInfo.PostCode))
            {
                validationMessage.Add("Postcode cannot be emptied.");
            }
            else
            {
                var regex =
                   new Regex(
                       @"(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY])))) [0-9][A-Z-[CIKMOV]]{2})");
                var match = regex.Match(checkout.BillingInfo.PostCode);
                if (!match.Success)
                {
                    validationMessage.Add("The UK postcode entered is not valid.");
                }
            }

            if (string.IsNullOrEmpty(checkout.BillingInfo.TelephoneNo))
            {
                validationMessage.Add("Street Name cannot be emptied.");
            }
            else
            {
                var regex = new Regex(@"^(?:(?:\(?(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?(?:\(?0\)?[\s-]?)?)|(?:\(?0))(?:(?:\d{5}\)?[\s-]?\d{4,5})|(?:\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3}))|(?:\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4})|(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}))(?:[\s-]?(?:x|ext\.?|\#)\d{3,4})?$
            ");
                var match = regex.Match(checkout.BillingInfo.TelephoneNo);
                if (!match.Success)
                {
                    validationMessage.Add("");
                }
            }

            if (string.IsNullOrEmpty(checkout.BillingInfo.Email))
            {
                validationMessage.Add("Email cannot be emptied.");
            }
            else
            {

                var regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
                var match = regex.Match(checkout.BillingInfo.Email);
                if (!match.Success)
                    validationMessage.Add("Invalid email format.");
            }

            if (!checkout.PaymentInfo.IsDirectDebit && !checkout.PaymentInfo.IsPayPal)
            {
                validationMessage.Add("Payment method must be set.");
            }

            return validationMessage;
        }
        /// <summary>
        /// Get the system to send email once Direct Debit has been placed.
        /// This configuration is using the local hosting machine
        /// Therefore you will need to install a software called 'smtp4dev'
        /// </summary>
        /// <param name="checkout"></param>
        /// <param name="cart"></param>
        /// <param name="orderNumber"></param>
        private void SendEmail(Checkout checkout, List<CartItem> cart, int orderNumber)
        {
            var id = orderNumber.ToString().PadLeft(6, '0');
            var mail = new MailMessage("*****@*****.**", checkout.BillingInfo.Email);
            var bodyText = "<html>" +
                           "<head>" +
                               "<style> " +
                                "table{border-collapse:collapse;} " +
                                "table, td, th{border:1px solid black;} " +
                               "</style>" +
                           "</head>" +
                           "<body>" +
                           "<h2>Your order has been confirmed. The order number is : " + id + "</h2>" +
                           "<p>Below are a list of items that you have purchased:</p></br></br>" +
                           "<table>" +
                               "<thead>" +
                                   "<tr>" +
                                       "<td>Product Code</td>" +
                                       "<td>Product Name</td>" +
                                       "<td>Quantity</td>" +
                                   "</tr>" +
                               "</thead>" +
                               "<tbody>" +
                               GenerateInnerOrderItem(cart) +
                               "</tbody>" +
                           "</table>" +
                           "</body>" +
                           "</html>";
            var smtp = new SmtpClient
            {
                Host = "smtp.gmail.com",
                Port = 587,
                EnableSsl = true,
                DeliveryMethod = SmtpDeliveryMethod.Network,
                UseDefaultCredentials = false,
                Credentials = new NetworkCredential("*****@*****.**", "p19o08m1991me")
            };

            mail.Subject = "Order Confirmation: " + id;
            mail.IsBodyHtml = true;
            mail.Body = bodyText;
            smtp.Send(mail);
            smtp.Dispose();
        }
 private ViewResult PaymentSuccess(DoExpressCheckoutPaymentResponseType response, Checkout checkout, List<CartItem> cart)
 {
     var details = response.DoExpressCheckoutPaymentResponseDetails;
     var transaction = new TransacDetails
     {
         TransId = details.PaymentInfo[0].TransactionID
     };
     var user = Session["User"] as UserLoginDto;
     OrderManagement.RecordPayPalTransaction(checkout, cart, details.PaymentInfo[0].TransactionID, user.Id);
     return View("PaymentSuccess", transaction);
 }
        /// <summary>
        ///Record PayPal transaction to the database
        /// </summary>
        /// <param name="checkout"></param>
        /// <param name="cart"></param>
        /// <param name="paypalid"></param>
        /// <param name="userid"></param>
        public static void RecordPayPalTransaction(Checkout checkout, List<CartItem> cart, string paypalid, int userid)
        {
            SqlTransaction transaction = null;
            try
            {
                var con = new SqlConnection(GetConnection());
                con.Open();
                transaction = con.BeginTransaction();
                var cmd = new SqlCommand
                {
                    Transaction = transaction,
                    Connection = con,
                    CommandType = CommandType.Text,
                    CommandText =
                        "INSERT INTO [dbo].[orders](userID, firstName, lastName, payerEmail, paymentDate, paymentStatus, paymentType, mcGross, mcCurrency, dateCreated, paypalID) " +
                        " OUTPUT INSERTED.orderID " +
                        "VALUES (@uID, @Firstname, @Surname, @email, @date, @status, @type, @gross, @net, @dateCreated, @pID)"
                };
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@uID", userid);
                cmd.Parameters.AddWithValue("@Firstname", checkout.BillingInfo.FirstName);
                cmd.Parameters.AddWithValue("@Surname", checkout.BillingInfo.SurName);
                cmd.Parameters.AddWithValue("@email", checkout.BillingInfo.Email);
                cmd.Parameters.AddWithValue("@date", DateTime.Now);
                cmd.Parameters.AddWithValue("@status", "Success");
                cmd.Parameters.AddWithValue("@type", checkout.PaymentInfo.IsDirectDebit ? "Direct Debit" : "Paypal");
                cmd.Parameters.AddWithValue("@gross", CalculateGross(cart));
                cmd.Parameters.AddWithValue("@net", CalculateNet(cart));
                cmd.Parameters.AddWithValue("@dateCreated", DateTime.Now);
                cmd.Parameters.AddWithValue("@pID", paypalid);
                var orderId = (Int32)cmd.ExecuteScalar();

                foreach (var item in cart)
                {
                    var insertOrderItemCmd = new SqlCommand
                    {
                        Transaction = transaction,
                        Connection = con,
                        CommandType = CommandType.Text,
                        CommandText =
                            "INSERT INTO [dbo].[orderItems](ProductID, qty, orderID) " +
                            "VALUES (@pID, @q, @oID)"
                    };
                    insertOrderItemCmd.Parameters.Clear();
                    insertOrderItemCmd.Parameters.AddWithValue("@pID", item.Id);
                    insertOrderItemCmd.Parameters.AddWithValue("@q", item.Quantity);
                    insertOrderItemCmd.Parameters.AddWithValue("@oID", orderId);
                    insertOrderItemCmd.ExecuteNonQuery();
                }

                transaction.Commit();

                if (con.State != ConnectionState.Closed) return;
                con.Close();
            }
            catch (SqlException ex)
            {
                transaction.Rollback();
                var msg = "Insert errors";
                msg += ex.Message;
                throw new Exception(msg);
            }
        }