2015-04-27 3 views
8

Должен ли я использовать Microsoft CreditCardAttribute для подтверждения номеров кредитных карт?Должен ли я использовать CreditCardAttribute для проверки номеров кредитных карт?

[Required, CreditCard] 
public string CreditCardNumber { get; set; } 

Должен ли я позволить шлюзу оплаты обрабатывать его или делать что-то еще? Я спрашиваю об этом после того, как некоторые клиенты не смогли отправить платеж с информацией о своей кредитной карте. К счастью, я смог работать с одним из этих клиентов и обнаружил, что их карточка Visa была обработана без проблем после удаления CreditCardAttribute.

В частности, этот вопрос носит риторический характер, но я хотел бы извлечь пользу из соображений и опытов других разработчиков и сообщить другим разработчикам о рисках использования CreditCardAttribute, задав вопрос.

+0

Ссылка на документация соответствующего атрибута будет очень полезна. –

+0

@OndrejTucny [Здесь вы идете] (https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.creditcardattribute%28v=vs.110%29.aspx). Быстрый поиск в Google проходит долгий путь. –

+1

[Этот вопрос] (http://stackoverflow.com/q/12580450/3199927) дает некоторое представление о том, как проверяет ввод данных «CreditCardAttribute». – Tom

ответ

3

Я думаю, что лучший способ узнать это, чтобы просто проверить:

using System; 
using System.Linq; 
using System.Text; 
using System.IO; 

namespace SO 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string[] cards = new string[] { 
       //http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm 
       "378282246310005", // American Express 
       "4012888888881881", // Visa 
       "6011111111111117", // Discover 
       "4222222222222", // Visa 
       "76009244561", // Dankort (PBS) 
       "5019717010103742", // Dakort (PBS) 
       "6331101999990016", // Switch/Solo (Paymentech) 
       "30569309025904", // Diners Club 
       //http://www.getcreditcardnumbers.com/ 
       "5147004213414803", // Mastercard 
       "6011491706918120", // Discover 
       "379616680189541", // American Express 
       "4916111026621797", // Visa 
      }; 

      foreach (string card in cards) 
      { 
       Console.WriteLine(IsValid(card)); 
      } 

      Console.ReadLine(); 
     } 

     public static bool IsValid(object value) 
     { 
      if (value == null) 
      { 
       return true; 
      } 

      string ccValue = value as string; 
      if (ccValue == null) 
      { 
       return false; 
      } 
      ccValue = ccValue.Replace("-", ""); 
      ccValue = ccValue.Replace(" ", ""); 

      int checksum = 0; 
      bool evenDigit = false; 

      // http://www.beachnet.com/~hstiles/cardtype.html 
      foreach (char digit in ccValue.Reverse()) 
      { 
       if (digit < '0' || digit > '9') 
       { 
        return false; 
       } 

       int digitValue = (digit - '0') * (evenDigit ? 2 : 1); 
       evenDigit = !evenDigit; 

       while (digitValue > 0) 
       { 
        checksum += digitValue % 10; 
        digitValue /= 10; 
       } 
      } 

      return (checksum % 10) == 0; 
     } 
    } 
} 

Метод IsValid от оригинального C# CreditCardAttribute класса. 1 из 12 чисел не удалось:

 True 
     True 
     True 
     True 
     False //"76009244561", // Dankort (PBS) 
     True 
     True 
     True 
     True 
     True 
     True 
     True 

Таким образом, вы должны использовать его? Нет, очевидно, он не обнаруживает всех чисел. Хотя вы можете взять их код и улучшить его!

+0

Очень приятно взять на себя эту проблему! Мне жаль, что это не дало мне уверенности в использовании «улучшенной» проверки. К сожалению, это похоже на то, что я боюсь. Список номеров кредитных карт кажется неполным, потому что мне сказали, что это карта Visa. Я ожидал, что одна из них не будет визой. Возможно, клиент ошибся, но я сомневаюсь в этом. Мне все еще кажется, что использование валидации кредитной карты таким образом является рискованным, даже если у вас есть много поддельных номеров кредитных карт для тестирования. В конце концов, Visa может завтра выпустить новые номера, так как моя обычная, полностью обновленная проверка может потерпеть неудачу. –

+0

Действительно, это уже много раз обсуждалось в Интернете, использование алгоритма Луна не охватывает все существующие кредитные карты. Я предполагаю, что единственный способ быть на 100% уверенным - это проверить его, выполнив транзакцию. –

+0

Сказав это, если я по какой-то причине был вынужден проверять в своем коде, то, как правило, это единичный тест, подобный этому. В дополнение к этому я бы хотел, чтобы журнал (а не номера используемых кредитных карт!), Но число проверки не удалось, так что я мог бы рассмотреть вопрос о том, создает ли мой валидатор ложные негативы. –

1

В code за кредитной картой attribute он просто выполняет проверку Luhn.

Все платежные карточки (*) в настоящее время соответствуют стандарту ISO/IEC/7812, который имеет цифру проверки luhn в качестве окончательной цифры.

Эта проверка luhn просто используется для предотвращения ошибок в транспозиции. Он полезен как проверка работоспособности перед отправкой номеров карт на платежный шлюз, но не подходит для полной проверки того, является ли номер действительным номером карты.

Диапазон действительных номеров карт изменяется ежемесячно, и единственный способ абсолютно подтвердить номер - проверить его через платежный шлюз. Если вы только пытаетесь проверить карту (а не заряжать ее), это должно быть выполнено с помощью проверки стиля только «авторизация».

(*) Единственным исключением является тип карты в Китае известный как China UnionPay
(Исторически также заклеймить Diners Club «EnRoute», который был снят в 1992 году)

+0

Не могли бы вы предоставить некоторые доказательства, подтверждающие ваше утверждение о том, что «все платежные карты в настоящее время следуют алгоритму Луна»? Казалось бы, либо Microsoft неправильно реализовала простой и известный алгоритм, либо ваше утверждение неверно. –

+1

В реализации Microsoft нет ничего плохого. Это действительный алгоритм проверки luhn. Если, однако, вы подаете недействительные тестовые данные, вы получите недействительный результат теста .. как и ожидалось :) Последний оставшийся тест, который у вас есть, не проходит, это 11-значное число. Это короткий путь для действительного номера карты, который обычно равен * 16 цифрам. (Формат обычно представляет собой 6-значный индекс IIN, последнюю цифру в качестве контрольной цифры, остаток - как уникальный номер счета). Это означало бы, что карта Dankort имеет только 10 000 действительных номеров счетов? Кажется маловероятным :) – PaulG

+0

Возможно, я вас не понимаю, но кажется, что вы верите, что проблема, с которой я столкнулась, не существует. Мне посчастливилось уловить эту проблему раньше :) Около 20 клиентов, которые попали на страницу оплаты, по крайней мере один из них с 16-значным номером карты Visa застрял в проверке CreditCardAttribute. Как только я удалил этот атрибут, клиент смог отправить платеж без проблем. Я понимаю, что Лун является стандартом, и также считаю, что реализация MS прекрасна, но выяснение того, что один из первых 20 клиентов имел «нестандартный» номер кредитной карты, удивляет. –

Смежные вопросы