public static FluentValidation.Results.ValidationResult AsInvalidPayment(Braintree.Result <Transaction> transactionResult) { // generate an 'invalid ' fluent error var baseValidationResult = new ValidationResult(); var modelValidationResult = new Obsequy.Model.ResponseFormValidator.ResponseFormValidationResult(baseValidationResult); // get braintree validation errors var validationErrors = transactionResult.Errors.DeepAll(); if (validationErrors.Any()) { modelValidationResult.Payment = new ModelValidationResult(); foreach (var attribute in Attributes) { // no real reason why I'm using last instead of first, just initial testing showed these messages make more sense to the user? var validationError = validationErrors.LastOrDefault(item => item.Attribute == attribute.Key); if (validationError != null) { // only set the general message if the property errors are not set modelValidationResult.Payment.Errors.Add(new PropertyValidationFailure(attribute.Value, validationError.Message) { Status = FormatHelper.ToCamlCase("Invalid"), Severity = FormatHelper.ToCamlCase("Error") }); } } } if (!string.IsNullOrEmpty(transactionResult.Message)) { // only set the general message if the property errors are not set modelValidationResult.Errors.Add(new PropertyValidationFailure("Id", transactionResult.Message) { Status = FormatHelper.ToCamlCase("Invalid"), Severity = FormatHelper.ToCamlCase("Error") }); } return(modelValidationResult); }
public async Task <IActionResult> Index(CheckoutViewModel model) { if (ModelState.IsValid) { // load cart if (Request.Cookies.ContainsKey("cartId")) { if (Guid.TryParse(Request.Cookies["cartId"], out var cartId)) { model.Cart = await _oContext.Carts .Include(carts => carts.CartItems) .ThenInclude(cartitems => cartitems.Yacht) .FirstOrDefaultAsync(x => x.CookieIdentifier == cartId); } } Order order = new Order { TrackingNumber = Guid.NewGuid().ToString(), OrderDate = DateTime.Now, OrderItems = model.Cart.CartItems.Select(x => new OrderItem { Yacht = x.Yacht, DatesFrom = x.DatesFrom, DatesTo = x.DatesTo }).ToArray(), FirstName = model.FirstName, LastName = model.LastName, Email = model.Email, Address = model.Address, Country = model.Country, Zip = model.Zip, PhoneNumber = model.PhoneNumber }; Braintree.Customer customer = null; Braintree.CustomerSearchRequest search = new Braintree.CustomerSearchRequest(); search.Email.Is(model.Email); var searchResult = await _braintreeGateway.Customer.SearchAsync(search); if (searchResult.Ids.Count == 0) { //Create a new Braintree Customer Braintree.Result <Customer> creationResult = await _braintreeGateway.Customer.CreateAsync(new Braintree.CustomerRequest { Email = model.Email, Phone = model.PhoneNumber }); customer = creationResult.Target; } else { customer = searchResult.FirstItem; } //More on card testing: https://developers.braintreepayments.com/reference/general/testing/dotnet var transaction = new TransactionRequest { Amount = model.Cart.CartItems.Sum(x => (x.Yacht.PriceHighSeason ?? 0)), CreditCard = new TransactionCreditCardRequest { Number = model.CCnumber, CardholderName = model.NameOnCard, CVV = model.CVV, ExpirationMonth = model.ExpirationMonth?.PadLeft(2, '0'), ExpirationYear = model.ExpirationYear }, CustomerId = customer.Id, LineItems = model.Cart.CartItems.Select(x => new TransactionLineItemRequest { Name = x.Yacht.Name, // Description = x.Yacht.Description, ProductCode = x.Yacht.ID.ToString(), Quantity = '1', LineItemKind = TransactionLineItemKind.DEBIT, UnitAmount = x.Yacht.PriceHighSeason, //* x.Quantity, TotalAmount = x.Yacht.PriceHighSeason // * x.Quantity }).ToArray() }; var transactionResult = await _braintreeGateway.Transaction.SaleAsync(transaction); if (transactionResult.IsSuccess()) { _oContext.Orders.Add(order); _oContext.CartItems.RemoveRange(model.Cart.CartItems); _oContext.Carts.Remove(model.Cart); await _oContext.SaveChangesAsync(); Response.Cookies.Delete("cartId"); return(RedirectToAction("Receipt", new { id = order.ID })); } } return(View(model)); }
public async Task <IActionResult> Index(CheckOutViewModel model) { await GetCurrentCart(model); if (ModelState.IsValid) { if (!string.IsNullOrEmpty(model.SavedAddressId) || (!string.IsNullOrEmpty(model.ShippingAddressLine1) && !string.IsNullOrEmpty(model.ShippingCity) && !string.IsNullOrEmpty(model.ShippingState) && !string.IsNullOrEmpty(model.ShippingZipcode) && !string.IsNullOrEmpty(model.ShippingCountry))) { Order newOrder = new Order { TrackingNumber = Guid.NewGuid().ToString(), OrderDate = DateTime.Now, OrderItems = model.Cart.CartItems.Select(x => new OrderItem { ProductID = x.Product.ID, ProductName = x.Product.Name, ProductPrice = (x.Product.Price ?? 0), Quantity = x.Quantity }).ToArray(), AddressLine1 = model.ShippingAddressLine1, AddressLine2 = model.ShippingAddressLine2, State = model.ShippingState, Country = model.ShippingCountry, Email = model.email, phoneNumber = model.phoneNumber, Locale = model.ShippingCity, PostalCode = model.ShippingZipcode, }; Braintree.Customer customer = null; Braintree.CustomerSearchRequest search = new Braintree.CustomerSearchRequest(); search.Email.Is(model.email); var searchResult = await _brainTreeGateway.Customer.SearchAsync(search); if (searchResult.Ids.Count == 0) { //Create a new Braintree Customer Braintree.Result <Customer> creationResult = await _brainTreeGateway.Customer.CreateAsync(new Braintree.CustomerRequest { Email = model.email, Phone = model.phoneNumber }); customer = creationResult.Target; } else { customer = searchResult.FirstItem; } CreditCard creditCard = null; if (model.SaveBillingCard) { var newCardRequest = new CreditCardRequest { CardholderName = model.NameOnCard, CustomerId = customer.Id, ExpirationMonth = model.BillingCardExpirationMonth.ToString().PadLeft(2, '0'), ExpirationYear = model.BillingCardExpirationYear.ToString(), Number = model.CardNumber, CVV = model.CVV }; var newCardResult = await _brainTreeGateway.CreditCard.CreateAsync(newCardRequest); if (newCardResult.IsSuccess()) { creditCard = newCardResult.Target; } } Address savedAddress = null; if (model.SaveShippingAddress) { var newAddressRequest = new AddressRequest { StreetAddress = model.ShippingAddressLine1, ExtendedAddress = model.ShippingAddressLine2, CountryName = model.ShippingCountry, PostalCode = model.ShippingZipcode, Locality = model.ShippingCity, Region = model.ShippingState }; var newAddressResult = await _brainTreeGateway.Address.CreateAsync(customer.Id, newAddressRequest); if (newAddressResult.IsSuccess()) { savedAddress = newAddressResult.Target; } } TransactionRequest transaction = new TransactionRequest { //Amount = 1, Amount = model.Cart.CartItems.Sum(x => x.Quantity * (x.Product.Price ?? 0)), CustomerId = customer.Id, LineItems = model.Cart.CartItems.Select(x => new TransactionLineItemRequest { Name = x.Product.Name, Description = x.Product.Description, ProductCode = x.Product.ID.ToString(), Quantity = x.Quantity, LineItemKind = TransactionLineItemKind.DEBIT, UnitAmount = x.Product.Price * x.Quantity, TotalAmount = x.Product.Price * x.Quantity }).ToArray() }; if (creditCard == null) { transaction.CreditCard = new TransactionCreditCardRequest { Number = model.CardNumber, CardholderName = model.NameOnCard, CVV = model.CVV, ExpirationMonth = model.BillingCardExpirationMonth.ToString().PadLeft(2, '0'), ExpirationYear = model.BillingCardExpirationYear.ToString() }; } else { transaction.PaymentMethodToken = creditCard.Token; } if (savedAddress != null) { transaction.ShippingAddressId = savedAddress.Id; } var transactionResult = await _brainTreeGateway.Transaction.SaleAsync(transaction); if (transactionResult.IsSuccess()) { _context.Orders.Add(newOrder); _context.CartItems.RemoveRange(model.Cart.CartItems); _context.Carts.Remove(model.Cart); await _context.SaveChangesAsync(); //Try to checkout Response.Cookies.Delete("cartId"); return(RedirectToAction("Index", "Receipt", new { id = newOrder.TrackingNumber })); } for (int i = 0; i < transactionResult.Errors.Count; i++) { ModelState.AddModelError("BillingCardNumber" + i, transactionResult.Errors.All()[i].Message); } //Try to checkout Response.Cookies.Delete("cartId"); return(RedirectToAction("Index", "Receipt", new { id = newOrder.TrackingNumber })); } } return(View(model)); }
public async Task <IActionResult> Index(Checkout model) { await GetCurrentCart(model); model.Addresses = new Address[0]; if (ModelState.IsValid) { if (!string.IsNullOrEmpty(model.SavedAddressId) || (!string.IsNullOrEmpty(model.ShippingAddressLine1) && !string.IsNullOrEmpty(model.ShippingLocale) && !string.IsNullOrEmpty(model.ShippingRegion) && !string.IsNullOrEmpty(model.ShippingPostalCode) && !string.IsNullOrEmpty(model.ShippingCountry))) { Order neworder = new Order { TrackingNumber = Guid.NewGuid().ToString(), OrderDate = DateTime.Now, OrderItems = model.Cart.CartItems.Select(x => new OrderItem { ProductID = x.Product.ID, ProductName = x.Product.Name, ProductPrice = (x.Product.Price ?? 0), Quantity = x.Quantity }).ToArray(), AddressLine1 = model.ShippingAddressLine1, AddressLine2 = model.ShippingAddressLine2, Country = model.ShippingCountry, Email = model.ContactEmail, PhoneNumber = model.ContactPhoneNumber, Locale = model.ShippingLocale, PostalCode = model.ShippingPostalCode, Region = model.ShippingRegion }; Braintree.Customer customer = null; Braintree.CustomerSearchRequest search = new Braintree.CustomerSearchRequest(); search.Email.Is(model.ContactEmail); var searchResult = await _brainTreeGateway.Customer.SearchAsync(search); if (searchResult.Ids.Count == 0) { //Create a new Braintree Customer Braintree.Result <Customer> creationResult = await _brainTreeGateway.Customer.CreateAsync(new Braintree.CustomerRequest { Email = model.ContactEmail, Phone = model.ContactPhoneNumber }); customer = creationResult.Target; } else { customer = searchResult.FirstItem; } CreditCard creditCard = null; if (model.SaveBillingCard) { var newCardRequest = new CreditCardRequest { CardholderName = model.BillingNameOnCard, CustomerId = customer.Id, ExpirationMonth = model.BillingCardExpirationMonth.ToString().PadLeft(2, '0'), ExpirationYear = model.BillingCardExpirationYear.ToString(), Number = model.BillingCardNumber, CVV = model.BillingCardVerificationValue }; var newCardResult = await _brainTreeGateway.CreditCard.CreateAsync(newCardRequest); if (newCardResult.IsSuccess()) { creditCard = newCardResult.Target; } } Address savedAddress = null; if (model.SaveShippingAddress) { var newAddressRequest = new AddressRequest { StreetAddress = model.ShippingAddressLine1, ExtendedAddress = model.ShippingAddressLine2, CountryName = model.ShippingCountry, PostalCode = model.ShippingPostalCode, Locality = model.ShippingLocale, Region = model.ShippingRegion }; var newAddressResult = await _brainTreeGateway.Address.CreateAsync(customer.Id, newAddressRequest); if (newAddressResult.IsSuccess()) { savedAddress = newAddressResult.Target; } } TransactionRequest transaction = new TransactionRequest { Amount = model.Cart.CartItems.Sum(x => x.Quantity * (x.Product.Price ?? 0)), CustomerId = customer.Id, LineItems = model.Cart.CartItems.Select(x => new TransactionLineItemRequest { Name = x.Product.Name, Description = x.Product.Description, ProductCode = x.Product.ID.ToString(), Quantity = x.Quantity, LineItemKind = TransactionLineItemKind.DEBIT, UnitAmount = x.Product.Price * x.Quantity, TotalAmount = x.Product.Price * x.Quantity }).ToArray() }; if (creditCard == null) { transaction.CreditCard = new TransactionCreditCardRequest { Number = model.BillingCardNumber, CardholderName = model.BillingNameOnCard, CVV = model.BillingCardVerificationValue, ExpirationMonth = model.BillingCardExpirationMonth.ToString().PadLeft(2, '0'), ExpirationYear = model.BillingCardExpirationYear.ToString() }; } else { transaction.PaymentMethodToken = creditCard.Token; } if (savedAddress != null) { transaction.ShippingAddressId = savedAddress.Id; } var transactionResult = await _brainTreeGateway.Transaction.SaleAsync(transaction); if (transactionResult.IsSuccess()) { _context.Orders.Add(neworder); _context.CartItems.RemoveRange(model.Cart.CartItems); _context.Carts.Remove(model.Cart); await _context.SaveChangesAsync(); Response.Cookies.Delete("cartId"); RegisterViewModel regModel = new RegisterViewModel(); var plainText = "Thanks for signing up, " + regModel.FirstName + "!"; var htmlText = "<p> Thanks for Shopping with us, " + regModel.FirstName + "!</p>"; await _emailService.SendEmailAsync(model.ContactEmail, "Your Receipt", htmlText, plainText); return(RedirectToAction("Confirmation", "Checkout", new { id = neworder.TrackingNumber })); } for (int i = 0; i < transactionResult.Errors.Count; i++) { ModelState.AddModelError("BillingCardNumber" + i, transactionResult.Errors.All()[i].Message); } } //#region use the SendGrid client to send a welcome email //var client = new SendGrid.SendGridClient(_sendGridKey); //var senderAddress = new SendGrid.Helpers.Mail.EmailAddress("*****@*****.**", "Organic-Farm Store"); //var subject = "Your Receipt"; //var to = new SendGrid.Helpers.Mail.EmailAddress(emailReceipt.Email, emailReceipt.Email); //var plainText = "Thanks for signing up, " + emailReceipt.FirstName + "!"; //var htmlText = "<p> Thanks for Shopping with us, " + emailReceipt.FirstName + "!</p>"; //var message = SendGrid.Helpers.Mail.MailHelper.CreateSingleEmail(senderAddress, to, subject, plainText, htmlText); //var mailResult = await client.SendEmailAsync(message); //if ((mailResult.StatusCode == System.Net.HttpStatusCode.OK) || (mailResult.StatusCode == System.Net.HttpStatusCode.Accepted)) //{ // return RedirectToAction("Confirmation"); //} //else //{ // return BadRequest(await mailResult.Body.ReadAsStringAsync()); //} //#endregion } return(View(model)); }
public async Task <IActionResult> Index(CheckoutViewModel model) { await GetCurrentCart(model); if (ModelState.IsValid) { if (!string.IsNullOrEmpty(model.SavedAddressId) || (!string.IsNullOrEmpty(model.ShippingAddressLine1) && !string.IsNullOrEmpty(model.ShippingLocale) && !string.IsNullOrEmpty(model.ShippingRegion) && !string.IsNullOrEmpty(model.ShippingPostalCode) && !string.IsNullOrEmpty(model.ShippingCountry))) { Order newOrder = new Order { TrackingNumber = Guid.NewGuid().ToString(), OrderDate = DateTime.Now, OrderItems = model.Cart.CartItems.Select(x => new OrderItem { ProductID = x.Product.ID, ProductName = x.Product.Name, ProductPrice = (x.Product.Price ?? 0), Quantity = x.Quantity }).ToArray(), AddressLine1 = model.ShippingAddressLine1, AddressLine2 = model.ShippingAddressLine2, Country = model.ShippingCountry, Email = model.ContactEmail, PhoneNumber = model.ContactPhoneNumber, Locale = model.ShippingLocale, PostalCode = model.ShippingPostalCode, Region = model.ShippingRegion }; Braintree.Customer customer = null; Braintree.CustomerSearchRequest search = new Braintree.CustomerSearchRequest(); search.Email.Is(model.ContactEmail); var searchResult = await _brainTreeGateway.Customer.SearchAsync(search); if (searchResult.Ids.Count == 0) { //Create a new Braintree Customer Braintree.Result <Customer> creationResult = await _brainTreeGateway.Customer.CreateAsync(new Braintree.CustomerRequest { Email = model.ContactEmail, Phone = model.ContactPhoneNumber }); customer = creationResult.Target; } else { customer = searchResult.FirstItem; } CreditCard creditCard = null; if (model.SaveBillingCard) { var newCardRequest = new CreditCardRequest { CardholderName = model.BillingNameOnCard, CustomerId = customer.Id, ExpirationMonth = model.BillingCardExpirationMonth.ToString().PadLeft(2, '0'), ExpirationYear = model.BillingCardExpirationYear.ToString(), Number = model.BillingCardNumber, CVV = model.BillingCardVerificationValue }; var newCardResult = await _brainTreeGateway.CreditCard.CreateAsync(newCardRequest); if (newCardResult.IsSuccess()) { creditCard = newCardResult.Target; } } Address savedAddress = null; if (model.SaveShippingAddress) { var newAddressRequest = new AddressRequest { StreetAddress = model.ShippingAddressLine1, ExtendedAddress = model.ShippingAddressLine2, CountryName = model.ShippingCountry, PostalCode = model.ShippingPostalCode, Locality = model.ShippingLocale, Region = model.ShippingRegion }; var newAddressResult = await _brainTreeGateway.Address.CreateAsync(customer.Id, newAddressRequest); if (newAddressResult.IsSuccess()) { savedAddress = newAddressResult.Target; } } else { } TransactionRequest transaction = new TransactionRequest { Amount = model.Cart.CartItems.Sum(x => x.Quantity * (x.Product.Price ?? 0)), CustomerId = customer.Id, LineItems = model.Cart.CartItems.Select(x => new TransactionLineItemRequest { Name = x.Product.Name, Description = x.Product.Description, ProductCode = x.Product.ID.ToString(), Quantity = x.Quantity, LineItemKind = TransactionLineItemKind.DEBIT, UnitAmount = x.Product.Price * x.Quantity, TotalAmount = x.Product.Price * x.Quantity }).ToArray() }; if (creditCard == null) { transaction.CreditCard = new TransactionCreditCardRequest { Number = model.BillingCardNumber, CardholderName = model.BillingNameOnCard, CVV = model.BillingCardVerificationValue, ExpirationMonth = model.BillingCardExpirationMonth.ToString().PadLeft(2, '0'), ExpirationYear = model.BillingCardExpirationYear.ToString() }; } else { transaction.PaymentMethodToken = creditCard.Token; } if (savedAddress != null) { transaction.ShippingAddressId = savedAddress.Id; } var transactionResult = await _brainTreeGateway.Transaction.SaleAsync(transaction); if (transactionResult.IsSuccess()) { _thisSiteDbContext.Orders.Add(newOrder); _thisSiteDbContext.CartItems.RemoveRange(model.Cart.CartItems); _thisSiteDbContext.Carts.Remove(model.Cart); await _thisSiteDbContext.SaveChangesAsync(); //Try to checkout //Confirmation Email //TODO: var serOrder serializes user order. I want to parse this JSON and send to SendGrid template for custom receipt /*var serOrder = JsonConvert.SerializeObject(newOrder, Formatting.Indented, * new JsonSerializerSettings * { * ReferenceLoopHandling = ReferenceLoopHandling.Ignore * }); */ var user = model.ContactEmail; var orderCompleteSubject = "Order #" + newOrder.TrackingNumber + " Completed"; var htmlContent = "Thanks for placing your order with us! Please reference your order number above."; var plainTextContent = "Thanks for placing your order with us! Please reference your order number above."; var emailResult = await _emailService.SendEmailAsync(user, orderCompleteSubject, htmlContent, plainTextContent); //await _emailService.SendEmailAsync(user, orderCompleteSubject, htmlContent, plainTextContent); if (!emailResult.Success) { throw new Exception(string.Join(',', emailResult.Errors.Select(x => x.Message))); } Response.Cookies.Delete("cartId"); return(RedirectToAction("Index", "Receipt", new { id = newOrder.TrackingNumber })); } for (int i = 0; i < transactionResult.Errors.Count; i++) { ModelState.AddModelError("BillingCardNumber" + i, transactionResult.Errors.All()[i].Message); } } } return(View(model)); }