Example #1
0
        public OrderDto CreateNewOrder(string email, OrderInputModel order)
        {
            // Retrieve information for the user with the email passed in
            var user = _dbContext.Users.FirstOrDefault(u => u.Email == email);

            if (user == null)
            {
                throw new Exception("User not found");
            }

            // Retrieve information for the address with the address id passed in
            var address = _dbContext.Addresses.FirstOrDefault(a => a.Id == order.AddressId);
            // Retrieve information for the payment card with the payment card id passed in
            var card         = _dbContext.PaymentCards.FirstOrDefault(c => c.Id == order.PaymentCardId);
            var cardNumber   = card.CardNumber;
            var shoppingCart = _dbContext.ShoppingCarts.FirstOrDefault(s => s.UserId == user.Id);
            var fullName     = user.FullName;

            float totalPrice = 0;

            for (int i = 0; i < shoppingCart.ShoppingCartItems.Count(); i++)
            {
                totalPrice += shoppingCart.ShoppingCartItems[i].UnitPrice * shoppingCart.ShoppingCartItems[i].Quantity;
            }

            // Create a new order where the credit card number has been masked, e.g. ************5555
            var entity = new OrderEntity
            {
                Email            = user.Email,
                FullName         = fullName,
                StreetName       = address.StreetName,
                HouseNumber      = address.HouseNumber,
                ZipCode          = address.ZipCode,
                Country          = address.Country,
                City             = address.City,
                CardHolderName   = card.CardHolderName,
                MaskedCreditCard = PaymentCardHelper.MaskPaymentCard(card.CardNumber),
                OrderDate        = DateTime.Now,
                TotalPrice       = totalPrice
            };

            _dbContext.Orders.Add(entity);
            _dbContext.SaveChanges();

            // Return the order but here the credit card number should not be masked
            return(new OrderDto
            {
                Id = entity.Id,
                FullName = entity.FullName,
                Email = entity.Email,
                StreetName = entity.StreetName,
                HouseNumber = entity.HouseNumber,
                ZipCode = entity.ZipCode,
                Country = entity.Country,
                CardholderName = entity.CardHolderName,
                CreditCard = cardNumber,
                OrderDate = entity.OrderDate.ToString("dd.MM.yyyy"),
                TotalPrice = entity.TotalPrice
            });
        }
Example #2
0
        public bool ValidatePaymentInfo(Dictionary <string, string> parameters, out string error)
        {
            var stripeSettings = DependencyResolver.Resolve <StripeSettings>();

            error = null;
            if (stripeSettings.UseRedirectionFlow)
            {
                return(true); //we don't collect anything on our site in case of redirection flow
            }
            parameters.TryGetValue("cardNumber", out var cardNumber);
            parameters.TryGetValue("cardName", out var cardName);
            parameters.TryGetValue("expireMonth", out var expireMonthStr);
            parameters.TryGetValue("expireYear", out var expireYearStr);
            parameters.TryGetValue("cvv", out var cvv);

            if (!PaymentCardHelper.IsCardNumberValid(cardNumber))
            {
                error = LocalizationHelper.Localize("The card number is incorrect");
                return(false);
            }
            if (cardName.IsNullEmptyOrWhiteSpace())
            {
                error = LocalizationHelper.Localize("The card name can not be empty");
                return(false);
            }
            if (cvv.IsNullEmptyOrWhiteSpace())
            {
                error = LocalizationHelper.Localize("The card security code can not be empty");
                return(false);
            }

            try
            {
                if (ExpiryCheck(expireMonthStr, expireYearStr))
                {
                    error = LocalizationHelper.Localize("The card expiry is incorrect or card has expired");
                    return(false);
                }
            }
            catch
            {
                error = LocalizationHelper.Localize("The card expiry is incorrect or card has expired");
                return(false);
            }

            return(true);
        }
Example #3
0
        private Order CreateOrder(User user, Address address, PaymentCard paymentCard)
        {
            var newOrder = new Order
            {
                User             = user,
                FullName         = user.FullName,
                Email            = user.Email,
                Country          = address.Country,
                City             = address.City,
                StreetName       = address.StreetName,
                HouseNumber      = address.HouseNumber,
                ZipCode          = address.ZipCode,
                CardHolderName   = paymentCard.CardholderName,
                MaskedCreditCard = PaymentCardHelper.MaskPaymentCard(paymentCard.CardNumber),
                OrderDate        = DateTime.Now
            };

            _dbContext.Add(newOrder);
            _dbContext.SaveChanges();
            return(newOrder);
        }
Example #4
0
 public MappingProfile()
 {
     CreateMap <Address, AddressDto>()
     .ForSourceMember(x => x.UserId, opt => opt.DoNotValidate());
     CreateMap <Order, OrderDto>()
     .ForMember(o => o.CreditCard, opt => opt.MapFrom(src => src.MaskedCreditCard))
     .ForMember(o => o.OrderDate, opt => opt.MapFrom(src => src.OrderDate.ToString("MM.dd.yyyy")))
     .ForSourceMember(p => p.UserId, opt => opt.DoNotValidate());
     CreateMap <OrderItem, OrderItemDto>()
     .ForSourceMember(o => o.OrderId, y => y.DoNotValidate())
     .ForSourceMember(o => o.Order, y => y.DoNotValidate());
     CreateMap <PaymentCard, PaymentCardDto>()
     .ForSourceMember(p => p.UserId, opt => opt.DoNotValidate())
     .ForMember(o => o.CardNumber, opt => opt.MapFrom(src => PaymentCardHelper.MaskPaymentCard(src.CardNumber)));
     CreateMap <ShoppingCartItem, ShoppingCartItemDto>()
     .ForMember(c => c.TotalPrice, src => src.MapFrom(src => src.UnitPrice * src.Quantity))
     .ForSourceMember(c => c.ShoppingCartId, opt => opt.DoNotValidate());
     CreateMap <User, UserDto>()
     .ForSourceMember(u => u.Addresses, opt => opt.DoNotValidate())
     .ForSourceMember(u => u.PaymentCards, opt => opt.DoNotValidate())
     .ForSourceMember(u => u.Orders, opt => opt.DoNotValidate())
     .ForSourceMember(u => u.ShoppingCart, opt => opt.DoNotValidate());
 }
        public IHttpActionResult ProcessPayment(FormCollection parameters)
        {
            //first get the payment processor
            var paymentMethodName = parameters.Get(PaymentParameterNames.PaymentMethodTypeName);

            if (string.IsNullOrEmpty(paymentMethodName))
            {
                VerboseReporter.ReportError("Invalid payment method", "process_payment");
                return(RespondFailure());
            }

            //the transaction amount
            decimal amount;
            var     amountString = parameters.Get(PaymentParameterNames.Amount) ?? "0";

            decimal.TryParse(amountString, out amount);

            PaymentMethodType methodType;

            if (System.Enum.TryParse(paymentMethodName, out methodType))
            {
                methodType = PaymentMethodType.CreditCard;
            }

            //get the payment processor now
            var paymentProcessor = _paymentProcessingService.GetPaymentProcessorPlugin(amount, methodType);

            if (paymentProcessor == null)
            {
                VerboseReporter.ReportError("Invalid payment method", "process_payment");
                return(RespondFailure());
            }

            //convert form collection to dictionary to check if parameters are valid
            var formCollectionDictionary = parameters.ToDictionary(pair => pair.Key, pair => (object)pair.Value);

            var isValid = paymentProcessor.AreParametersValid(formCollectionDictionary);

            UserPaymentMethod paymentMethod = null;

            if (!isValid)
            {
                //the parameters are not valid. but that may also mean that the user is selecting an already saved payment method
                //and so he wouldn't have sent that data again
                var savedPaymentMethodIdString = parameters.Get(PaymentParameterNames.UserSavedPaymentMethodId);
                int savedPaymentMethodId;
                if (int.TryParse(savedPaymentMethodIdString, out savedPaymentMethodId))
                {
                    var userPaymentMethods =
                        _paymentMethodService.Get(x => x.UserId == ApplicationContext.Current.CurrentUser.Id && x.Id == savedPaymentMethodId, null);

                    if (userPaymentMethods.Any())
                    {
                        paymentMethod = userPaymentMethods.First();
                        isValid       = true;
                    }
                }
                //still invalid? something is not right then.
                if (!isValid)
                {
                    VerboseReporter.ReportError("Invalid parameters to process payment", "process_payment");
                    return(RespondFailure());
                }
            }

            //we save the payment method in our database if it's CreditCard
            if (paymentProcessor.Supports(PaymentMethodType.CreditCard))
            {
                if (paymentMethod == null)
                {
                    #region saving payment method to database
                    var creditCardNumber = parameters.Get(PaymentParameterNames.CardNumber);
                    //let's validate the card for level 1 check (luhn's test) first before storing
                    var isCardValid = PaymentCardHelper.IsCardNumberValid(creditCardNumber);
                    //card number
                    if (!isCardValid)
                    {
                        VerboseReporter.ReportError("Invalid card number", "process_payment");
                        return(RespondFailure());
                    }
                    //expiration date
                    var expireMonth = parameters.Get(PaymentParameterNames.ExpireMonth);
                    var expireYear  = parameters.Get(PaymentParameterNames.ExpireYear);
                    if (!expireYear.IsInteger() || !expireMonth.IsInteger())
                    {
                        VerboseReporter.ReportError("Invalid expiration month or year", "process_payment");
                        return(RespondFailure());
                    }
                    //card issuer
                    var cardIssuer = PaymentCardHelper.GetCardTypeFromNumber(creditCardNumber);
                    if (!cardIssuer.HasValue)
                    {
                        VerboseReporter.ReportError("Unsupported card provider", "process_payment");
                        return(RespondFailure());
                    }


                    var nameOnCard = parameters.Get(PaymentParameterNames.NameOnCard);
                    //encrypt credit card info to store in db
                    var key  = ConfigurationManager.AppSettings.Get("EncryptionKey");
                    var salt = ConfigurationManager.AppSettings.Get("Salt");

                    var cardNumber = _cryptographyService.Encrypt(creditCardNumber, key, salt); //encrypt the card info
                    //fine if the card is valid, but is the card number already in our record, then not possible to save the same again
                    if (_paymentMethodService.DoesCardNumberExist(cardNumber))
                    {
                        VerboseReporter.ReportError("The card number is already saved in records", "process_payment");
                        return(RespondFailure());
                    }

                    paymentMethod = new UserPaymentMethod()
                    {
                        UserId            = ApplicationContext.Current.CurrentUser.Id,
                        IsVerified        = false,
                        PaymentMethodType = PaymentMethodType.CreditCard,
                        CardIssuerType    = cardIssuer.ToString().ToLowerInvariant(),
                        CardNumber        = creditCardNumber,
                        CardNumberMasked  = PaymentCardHelper.MaskCardNumber(creditCardNumber),
                        NameOnCard        = nameOnCard,
                    };
                    //save this payment method
                    _paymentMethodService.Insert(paymentMethod);
                    #endregion
                }
            }


            //we need to see if we should only authorize or capture as well
            //the idea is if it's a sponsorship context, it's better to authorize the payment transaction and capture later when
            //the sponsorship is accepted //we thought of initially only authorizing sponsorship transactions and capture when it's accepted.
            //but that flow doesn't seem to work quite well, thoughts?
            var authorizeOnly = false; // (parameters.Get(PaymentParameterNames.PaymentContext) ?? string.Empty) == "sponsor";

            //so we are ready for payment processing, let's create a paymenttrasaction for storing in our db
            var paymentTransaction = new PaymentTransaction()
            {
                IsLocalTransaction = true,
                PaymentStatus      = PaymentStatus.Pending,
                TransactionAmount  = amount,
                TransactionGuid    = Guid.NewGuid(),
                CreatedOn          = DateTime.UtcNow,
                UserIpAddress      = WebHelper.GetClientIpAddress()
            };
            _paymentTransactionService.Insert(paymentTransaction);

            //now proceed further with the payment
            //create the transaction request
            var transactionRequest = new TransactionRequest()
            {
                Amount                     = amount,
                CurrencyIsoCode            = "USD",//TODO: SET CURRENCY AS SELECTED BY USER
                PaymentProcessorSystemName = paymentProcessor.PluginInfo.SystemName,
                UserId                     = ApplicationContext.Current.CurrentUser.Id,
                Parameters                 = formCollectionDictionary,
                TransactionUniqueId        = paymentTransaction.TransactionGuid.ToString()
            };


            var response = paymentProcessor.Process(transactionRequest, authorizeOnly);
            //update values of transaction parameters for future reference
            paymentTransaction.TransactionCodes = response.ResponseParameters;
            //update payment transaction
            _paymentTransactionService.Update(paymentTransaction);

            if (response.Success)
            {
                //let's verify the payment method first if it's not
                if (paymentMethod != null && !paymentMethod.IsVerified)
                {
                    paymentMethod.IsVerified = true;
                    _paymentMethodService.Update(paymentMethod);
                }

                //now since the response was success, we can actually assign some credits to the user
                var creditCount = amount * (1 / _paymentSettings.CreditExchangeRate);
                var credit      = new Credit()
                {
                    PaymentTransactionId = paymentTransaction.Id,
                    CreatedOnUtc         = DateTime.UtcNow,
                    CreditCount          = creditCount,
                    CreditExchangeRate   = _paymentSettings.CreditExchangeRate,
                    //if it's authorize only transaction, we assign the credits, but they won't be usable before they are approved by capture
                    CreditTransactionType = CreditTransactionType.Issued,
                    CreditType            = CreditType.Transactional,
                    IsExpired             = false
                };

                //save credit
                _creditService.Insert(credit);

                //get total available credits of user
                var usableCreditCount = _creditService.GetUsableCreditsCount(ApplicationContext.Current.CurrentUser.Id);
                return(RespondSuccess(new {
                    UsableCreditCount = usableCreditCount
                }));
            }
            VerboseReporter.ReportError("An error occured while processing payment", "process_payment");
            return(RespondFailure());
        }
Example #6
0
        public OrderDto CreateNewOrder(string email, OrderInputModel order)
        {
            // Get user information
            var user = _dbContext.Users.FirstOrDefault(u => u.Email == email);

            if (user == null)
            {
                throw new ResourceMissingException("No user was found with this email.");
            }

            // Get user address, throw exception if none is found
            Address address;

            if (order.AddressId != 0)
            {
                // Find given address
                address = _dbContext.Addresses.FirstOrDefault(a => a.Id == order.AddressId);
            }
            else
            {
                // Find a address if none is given
                address = _dbContext.Addresses.FirstOrDefault(a => a.UserId == user.Id);
            }
            if (address == null)
            {
                throw new ResourceNotFoundException($"No address with id {order.AddressId} was found.");
            }

            // Get user card information, throw exception if none is found
            PaymentCard paymentCard;

            if (order.PaymentCardId != 0)
            {
                // Find given payment card
                paymentCard = _dbContext.PaymentCards.FirstOrDefault(c => c.Id == order.PaymentCardId);
            }
            else
            {
                // Find a payment if none is given
                paymentCard = _dbContext.PaymentCards.FirstOrDefault(c => c.UserId == user.Id);
            }
            if (paymentCard == null)
            {
                throw new ResourceNotFoundException($"No payment card with id {order.PaymentCardId} was found.");
            }


            // Get user shoppingcart or create new cart if none exists
            var cart = _dbContext.ShoppingCarts.FirstOrDefault(c => c.UserId == user.Id);

            if (cart == null)
            {
                throw new ResourceMissingException("Shopping cart is empty.");
            }

            // Create order items from cart items
            var orderItems = _dbContext.ShoppingCartItems
                             .Where(i => i.ShoppingCartId == cart.Id)
                             .Select(i => new OrderItem
            {
                Id = i.Id,
                ProductIdentifier = i.ProductIdentifier,
                Quantity          = i.Quantity,
                UnitPrice         = i.UnitPrice,
                TotalPrice        = i.Quantity * i.UnitPrice
            })
                             .ToList();

            if (!orderItems.Any())
            {
                throw new ResourceMissingException("Shopping cart is empty.");
            }

            // Calculate total order price
            var totalPrice = 0F;

            foreach (var item in orderItems)
            {
                totalPrice += item.TotalPrice;
            }

            var maskedCardNumber = PaymentCardHelper.MaskPaymentCard(paymentCard.CardNumber);

            // Create and save order
            var entity = new Order
            {
                Email            = user.Email,
                FullName         = user.FullName,
                StreetName       = address.StreetName,
                HouseNumber      = address.HouseNumber,
                ZipCode          = address.ZipCode,
                Country          = address.Country,
                City             = address.City,
                CardholderName   = paymentCard.CardholderName,
                MaskedCreditCard = maskedCardNumber,
                OrderDate        = DateTime.Now,
                TotalPrice       = totalPrice
            };

            _dbContext.Orders.Add(entity);
            _dbContext.SaveChanges();

            // Save order items
            AddOrderItems(entity.Id, orderItems);

            // Create and return order DTO
            var dto = ToOrderDto(entity);

            dto.CreditCard = paymentCard.CardNumber;
            dto.OrderItems = GetOrderItems(dto.Id);
            return(dto);
        }
Example #7
0
        public OrderDto CreateNewOrder(string email, OrderInputModel order)
        {
            // Find user
            var user = _dbContext.Users.FirstOrDefault(u => u.Email == email);

            // Find address
            var address = _dbContext.Addresses.FirstOrDefault(a => a.UserId == user.Id && a.Id == order.AddressId);

            if (address == null)
            {
                throw new ResourceNotFoundException($"Address with id {order.AddressId} not found.");
            }

            // Find payment card
            var paymentCard = _dbContext.PaymentCards.FirstOrDefault(p => p.UserId == user.Id && p.Id == order.PaymentCardId);

            if (paymentCard == null)
            {
                throw new ResourceNotFoundException($"Payment card with id {order.PaymentCardId} not found.");
            }

            var cart = _dbContext.ShoppingCarts.FirstOrDefault(s => s.UserId == user.Id);

            if (cart == null)
            {
                throw new Exception("Shopping cart is empty.");
            }

            var cartItems = _dbContext.ShoppingCartItems.Where(s => s.ShoppingCartId == cart.Id);

            if (!cartItems.Any())
            {
                throw new Exception("Shopping cart is empty.");
            }

            // Find the total price
            var totalPrice = 0.0;

            foreach (var cartItem in cartItems)
            {
                totalPrice += cartItem.Quantity * cartItem.UnitPrice;
            }

            // Mask the credit card with helper function
            var maskedCreditCard = PaymentCardHelper.MaskPaymentCard(paymentCard.CardNumber);

            // Add the order to the database
            var newOrder = new Order
            {
                UserId           = user.Id,
                Email            = user.Email,
                FullName         = user.FullName,
                StreetName       = address.StreetName,
                HouseNumber      = address.HouseNumber,
                ZipCode          = address.ZipCode,
                Country          = address.Country,
                City             = address.City,
                CardholderName   = paymentCard.CardholderName,
                MaskedCreditCard = maskedCreditCard,
                OrderDate        = DateTime.Now,
                TotalPrice       = (float)totalPrice,
            };

            _dbContext.Orders.Add(newOrder);
            _dbContext.SaveChanges();

            // Map cart items to order items
            foreach (var cartItem in cartItems)
            {
                var newOrderItem = new OrderItem
                {
                    ProductIdentifier = cartItem.ProductIdentifier,
                    Quantity          = cartItem.Quantity,
                    UnitPrice         = cartItem.UnitPrice,
                    TotalPrice        = cartItem.Quantity * cartItem.UnitPrice,
                    OrderId           = newOrder.Id
                };

                _dbContext.OrderItems.Add(newOrderItem);
            }
            _dbContext.SaveChanges();

            var orderItems = _dbContext.OrderItems.Where(o => o.OrderId == newOrder.Id).ToList();

            // Map order items to dto
            var orderItemsDtoList = _mapper.Map <List <OrderItemDto> >(orderItems);

            // Map order to dto and return
            var newOrderDto = new OrderDto
            {
                Id             = newOrder.Id,
                Email          = user.Email,
                FullName       = user.FullName,
                StreetName     = address.StreetName,
                HouseNumber    = address.HouseNumber,
                ZipCode        = address.ZipCode,
                Country        = address.Country,
                City           = address.City,
                CardholderName = paymentCard.CardholderName,
                CreditCard     = paymentCard.CardNumber,
                OrderDate      = newOrder.OrderDate.ToString("MM.dd.yyyy"),
                TotalPrice     = (float)totalPrice,
                OrderItems     = orderItemsDtoList
            };

            return(newOrderDto);
        }