我应该使用CreditCardAttribute来验证信用卡号吗?

Jer*_*ook 10 c# validation credit-card payment-gateway

我应该使用Microsoft的CreditCardAttribute来验证信用卡号码吗?

[Required, CreditCard]
public string CreditCardNumber { get; set; }
Run Code Online (Sandbox Code Playgroud)

或者我应该让支付网关处理它,还是做其他事情?我发现一些客户无法使用他们的信用卡信息提交付款后我问这个问题.幸运的是,我能够与其中一个客户合作,并发现他们的Visa卡在删除后没有任何问题CreditCardAttribute.

在某种程度上,这个问题是修辞性的,但我希望从其他开发人员的想法和经验中受益,并让其他开发人员意识到使用CreditCardAttribute提问的风险.

Jev*_*sen 5

我认为找到这个问题的最好方法就是简单地测试它:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

IsValid 方法来自原始 C# CreditCardAttribute类。12 个号码中有 1 个失败:

        True
        True
        True
        True
        False //"76009244561", // Dankort (PBS)
        True
        True
        True
        True
        True
        True
        True
Run Code Online (Sandbox Code Playgroud)

那么,你应该使用它吗?不,显然它不能检测所有数字。尽管您可以获取他们的代码并改进它!


Pau*_*ulG 5

在credit card属性背后的代码中,它只是执行Luhn检查。

所有支付卡 (*) 目前都遵循ISO/IEC/7812标准,该标准将 luhn 校验位作为最后一位。

不过,此 luhn 检查仅用于防止换位错误。在将卡号提交到支付网关之前,它作为健全性检查很有用,但不适合绝对验证一个号码是否是有效的卡号。

有效卡号范围每月更改一次,绝对验证号码的唯一方法是通过支付网关对其进行验证。如果仅尝试验证卡(而不是对其收费),则应使用零值“仅授权”样式检查来完成。

(*)唯一的例外是在中国称为中国银联的卡类型
(历史上也有一个大莱卡“enRoute”品牌,于 1992 年被撤销)