IEnumerable <KeyValuePair <CreditCardValidationField, string> > ValidateFields(CreditCardValidationConfiguration configuration, CreditCardValidationContext context)
        {
            var acceptedCardType = CreditCardTypeProvider
                                   .GetAcceptedCreditCardTypes()
                                   .Contains(context.CardType, StringComparer.OrdinalIgnoreCase);

            if (!acceptedCardType)
            {
                yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.CardType, AppLogic.GetString("creditCardDetails.cardType.invalid")));
            }

            var missingRequiredIssueNumber =
                CreditCardTypeProvider
                .GetCardTypesRequiringIssueNumber()
                .Contains(context.CardType, StringComparer.OrdinalIgnoreCase) &&
                string.IsNullOrEmpty(context.IssueNumber);

            if (missingRequiredIssueNumber)
            {
                yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.IssueNumber, AppLogic.GetString("creditCardDetails.cardIssueNumber.required")));
            }

            if (configuration.ValidateCreditCardNumber)
            {
                var cardType = CardType.Parse(context.CardType);
                if (cardType != null)                // Only validate known card types
                {
                    var creditCardValidator = new CreditCardValidator(context.Number, cardType);
                    if (!creditCardValidator.Validate())
                    {
                        yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.Number, AppLogic.GetString("creditCardDetails.cardNumber.format")));
                    }
                }
            }

            var missingExpirationDate = context.ExpirationDate == null;

            if (missingExpirationDate)
            {
                yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.ExpirationDate, AppLogic.GetString("creditCardDetails.cardExpirationDate.required")));
            }

            var missingRequiredCardExtraCode =
                !configuration.CardExtraCodeIsOptional &&
                string.IsNullOrEmpty(context.Cvv);

            if (missingRequiredCardExtraCode)
            {
                yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.Cvv, AppLogic.GetString("address.cs.29")));
            }
        }
        IEnumerable <KeyValuePair <CreditCardValidationField, string> > ValidateFields(CreditCardValidationConfiguration configuration, CreditCardValidationContext context)
        {
            var acceptedCardType = CreditCardTypeProvider
                                   .GetAcceptedCreditCardTypes()
                                   .Contains(context.CardType, StringComparer.OrdinalIgnoreCase);

            if (!acceptedCardType)
            {
                yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.CardType, "Invalid card type"));
            }

            var missingRequiredIssueNumber =
                CreditCardTypeProvider
                .GetCardTypesRequiringIssueNumber()
                .Contains(context.CardType, StringComparer.OrdinalIgnoreCase) &&
                string.IsNullOrEmpty(context.IssueNumber);

            if (missingRequiredIssueNumber)
            {
                yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.IssueNumber, "Please enter a card issue number"));
            }

            if (configuration.ValidateCreditCardNumber)
            {
                var cardType = CardType.Parse(context.CardType);
                if (cardType != null)                // Only validate known card types
                {
                    var creditCardValidator = new CreditCardValidator(context.Number, cardType);
                    if (!creditCardValidator.Validate())
                    {
                        yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.Number, "Please enter a valid credit card number"));
                    }
                }
            }

            var missingExpirationDate = context.ExpirationDate == null;

            if (missingExpirationDate)
            {
                yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.ExpirationDate, "Card expiration date is missing or invalid"));
            }

            var missingRequiredCardExtraCode =
                !configuration.CardExtraCodeIsOptional &&
                string.IsNullOrEmpty(context.Cvv);

            if (missingRequiredCardExtraCode)
            {
                yield return(new KeyValuePair <CreditCardValidationField, string>(CreditCardValidationField.Cvv, "Please enter the credit card verification code with no spaces. This number can be found printed on the back side of your card"));
            }
        }
        CheckoutCreditCardViewModel BuildCheckoutCreditCardViewModel(Customer customer)
        {
            var walletsAreEnabled  = customer.IsRegistered && WalletProvider.WalletsAreEnabled();
            var displayWalletCards = walletsAreEnabled && WalletProvider.GetPaymentProfiles(customer).Any();

            var creditCardTypeListItems = CreditCardTypeProvider
                                          .GetAcceptedCreditCardTypes()
                                          .Select(creditCardType => new SelectListItem
            {
                Text  = creditCardType,
                Value = creditCardType.ToUpper(),
            });

            var showIssueNumber = CreditCardTypeProvider
                                  .GetAcceptedCreditCardTypes()
                                  .Intersect(
                CreditCardTypeProvider.GetCardTypesRequiringIssueNumber(),
                StringComparer.OrdinalIgnoreCase)
                                  .Any();


            string name           = customer.FullName(),
                   number         = null,
                   cardType       = null,
                   issueNumber    = null,
                   expirationDate = null,
                   startDate      = null,
                   cvv            = null;

            var checkoutContext = PersistedCheckoutContextProvider.LoadCheckoutContext(customer);

            if (checkoutContext.CreditCard != null)
            {
                name = checkoutContext.CreditCard.Name ?? customer.FullName();

                number = GetCreditCardNumberForDisplay(checkoutContext.CreditCard.Number);

                cardType = checkoutContext.CreditCard.CardType;

                issueNumber = !string.IsNullOrEmpty(checkoutContext.CreditCard.IssueNumber)
                                        ? "••••"
                                        : null;

                expirationDate = GetCreditCardDateForDisplay(checkoutContext.CreditCard.ExpirationDate);

                startDate = GetCreditCardDateForDisplay(checkoutContext.CreditCard.StartDate);

                cvv = !string.IsNullOrEmpty(checkoutContext.CreditCard.Cvv)
                                        ? "•••"
                                        : null;
            }

            return(new CheckoutCreditCardViewModel
            {
                Name = name,
                Number = number,
                CardType = cardType,
                IssueNumber = issueNumber,
                ExpirationDate = expirationDate,
                StartDate = startDate,
                Cvv = cvv,
                CardTypes = creditCardTypeListItems,
                ShowStartDate = AppLogic.AppConfigBool("ShowCardStartDateFields"),
                ShowIssueNumber = showIssueNumber,
                ShowSaveCreditCardNumber = AppLogic.AppConfigBool("StoreCCInDB"),
                SaveCreditCardNumber = customer.StoreCCInDB,
                ValidateCreditCardNumber = AppLogic.AppConfigBool("ValidateCreditCardNumbers"),
                WalletsAreEnabled = walletsAreEnabled,
                DisplayWalletCards = displayWalletCards,
            });
        }