|
|
Validating Credit Card Numbers Without Bank Involvement
The best way to validate a credit card is to authorize the transaction with
your merchant bank. The authorization not only verifies that the account number is
indeed valid, but that the account is still active. When the bank provides you with an
authorization code or number, it is your assurance that you will be paid for
the transaction. If you proceed with the sale without bank authorization, you
assume the risk of loss should the credit card transaction be declined by the bank.
Instead of a credit to your account, the bank will notify you that the
transaction was denied.
Your agreement with your merchant bank may require you to always obtain
authorization for all transactions, at least transactions over a certain dollar amount. If
you don't have such an agreement, or if circumstances reasonably preclude you from
obtaining immediate authorization, you may wish to validate the credit card transactions
using some simplified verification techniques, detailed below. The account numbers
for all major credit cards can be validated by applying a relatively simple
mathematical formula to the number. This algorithm merely verifies the credit card number; it DOES
NOT verify the account itself. Someone can give you the number for an outdated or canceled
account. The number will appear valid, but the transaction will still be declined by
your bank when you attempt to collect.
Note: The "blind" verification method discussed here is best suited for pre-validating
credit card numbers prior to obtaining proper authorization from the bank. You can save
time and reduce unnecessary server load by making sure the customer has given you a
valid credit card number. If the number is not valid, you can immediately ask the
customer to correct it, without first having to contact the bank for final authorization.
Basic Number Validation
Each major credit card has its own unique account number pattern. This pattern
is shown in the table below
Card Prefix Digits Length
Mastercard 51-55 16
Visa 4 13 or 16
AmEx 34, 37 15
Discover 6011 16
You can use these patterns to quickly analyze the credit card number. If the
number is not valid, you can ask the customer to correct it. An easy way to perform
rudimentary credit card number validation based on the prefix and length is with a
JavaScript program. The following example asks the user to specify the card type, either
MasterCard, Visa, or American Express. A text box allows the customer to enter the credit
card number. A special feature of the following JavaScript example is that any non-digit
characters are stripped from the entry provided in the text box. In this way, customers
can use any of the following formats, and each will be accepted:
0123456789012
0123 45678 9012
0123-45678-9012
<HTML>
<HEAD><TITLE>Simple credit card validation</TITLE></HEAD>
<BODY>
<SCRIPT LANGUAGE="JavaScript">
function validatecard () {
if (validatecardfunc() == true)
alert ("Credit card validated!")
else
alert ("Credit card not valid!")
}
function validatecardfunc () {
validcard = false;
ret = stripNonNumbers (document.validate.accountnumber.value);
item = document.validate.cardtypelist.selectedIndex;
result = document.validate.cardtypelist.options[item].text;
if (result == "Mastercard") {
if (ret.length == 16)
validcard = true;
if ((ret.substring (0, 2) >= "51") &&
(ret.substring (0, 2) <= "55"))
validcard = true;
else
validcard = false;
}
if (result == "Visa") {
if ((ret.length == 16) || (ret.length ==13))
validcard = true;
if (ret.substring (0, 1) != "4")
validcard = false;
}
if (result == "American Express") {
if (ret.length == 15)
validcard = true;
if ((ret.substring (0, 2) != "34") &&
(ret.substring (0, 2) != "37"))
validcard = false;
}
if (result == "Discover") {
if (ret.length == 16)
validcard = true;
if (ret.substring (0, 4) != "6011")
validcard = false;
}
return (validcard);
}
function stripNonNumbers (InString) {
OutString="";
for (Count=0; Count < InString.length; Count++) {
TempChar=InString.substring (Count, Count+1);
Strip = false;
CharString="0123456789";
for (Countx = 0; Countx < CharString.length; Countx++) {
StripThis = CharString.substring(Countx, Countx+1)
if (TempChar == StripThis) {
Strip = true;
break;
}
}
if (Strip)
OutString=OutString+TempChar;
}
return (OutString);
}
</SCRIPT>
<P>
<FORM NAME="validate">
Select card type:<BR>
<SELECT NAME="cardtypelist" SIZE=1>
<OPTION SELECTED VALUE=1>Mastercard
<OPTION VALUE=2>Visa
<OPTION VALUE=3>American Express
<OPTION VALUE=4>Discover
</SELECT>
<P>
Enter account number:<BR> <INPUT TYPE="text" VALUE=""
NAME="accountnumber"> <P>
<INPUT TYPE="button" VALUE="Submit" onClick="validatecard()">
<INPUT TYPE="Reset" VALUE="Reset">
</FORM>
</BODY>
</HTML>
The script works by validating one of four possible card types with a series of
if tests. For example, if the card is a Visa, then the script first checks that
the length of the credit card number is either 13 or 16 digits (note that
previously to this test, the script has stripped out all non-digit characters). The script
then verifies that the number begins with the proper prefix. In the case of
Visa cards, this prefix is the number 4. As long as the length of the number and its
prefix checks out, the card is assumed "valid."
Checksum Validation
You can further test the validity of a credit card by processing its checksum
digits. All account numbers used in major credit cards follow a "mod 10" check digit
algorithm, whereby a simple mathematical equation can be applied to the digits to verify
that the number is good. The general process is as follows. For example purposes, the
account number is 1234567890123456 (an obvious fictitious number, because it doesn't
begin with a known prefix):
1. Double the value of alternate digits of the account number, beginning with
the second digit from the right. Example:
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
x2 x2 x2 x2 x2 x2 x2 x2
-------------------------------------------------------------
4 8 12 16 0 4 8 12
2. Add the individual digits comprising The products obtained in Step 1 to each
of the skipped digits of the original number. Example:
1+(4)+3+(8)+5+(1+2)+7+(1+6)+9+(0)+1+(4)+3+(8)+5+(1+2) = 71
3. Verify that the sum obtained in Step 2 is evenly divisible by 10. Example:
71/10 = 7.1 (not evenly divisible)
Try out this checksum algorithm with your own credit card numbers. The sum in
Step 2 should be evenly divisible by 10, such as 60, 70, 80, etc.
As with basic credit card validation, you can readily use a programming
language like JavaScript to perform the checksum calculation. Following is an example
JavaScript program that accepts credit card numbers for the four major credit cards, Visa,
Mastercard,Discover, and American Express. The numbers are validated for length and
prefix, as well as for checksum.
<HTML>
<HEAD><TITLE>Less simple credit card validation</TITLE></HEAD>
<BODY>
<SCRIPT LANGUAGE="JavaScript">
function validatecard () {
result = validatecardfunc();
if (result == true) {
Num = stripNonNumbers
(document.validate.accountnumber.value);
ret = cardcheck (Num)
if (ret == "VALID")
alert ("Credit card validated!")
else
alert ("Credit card not valid!")
} else {
alert ("Credit card not valid!")
}
}
function validatecardfunc () {
validcard = false;
ret = stripNonNumbers (document.validate.accountnumber.value);
item = document.validate.cardtypelist.selectedIndex;
result = document.validate.cardtypelist.options[item].text;
if (result == "Mastercard") {
if (ret.length == 16)
validcard = true;
if ((ret.substring (0, 2) >= "51") &&
(ret.substring (0, 2) <= "55"))
validcard = true;
else
validcard = false;
}
if (result == "Visa") {
if ((ret.length == 16) || (ret.length ==13))
validcard = true;
if (ret.substring (0, 1) != "4")
validcard = false;
}
if (result == "American Express") {
if (ret.length == 15)
validcard = true;
if ((ret.substring (0, 2) != "34") &&
(ret.substring (0, 2) != "37"))
validcard = false;
}
if (result == "Discover") {
if (ret.length == 16)
validcard = true;
if (ret.substring (0, 4) != "6011")
validcard = false;
}
return (validcard);
}
function cardcheck (Num) {
CardType=""
mask = "2121212121212121"
if (Num=="") {
CardType="BLANK"
return (CardType)
}
if ( Num.length == 13 )
Num = "000" + Num;
else if ( Num.length == 14 )
Num = "00" + Num;
else if (Num.length == 15 )
Num = "0" + Num;
if (Num.length == 16)
Num = Num;
else
CardType="INVALID" ;
CheckSum = 0;
for (count = 1; count<= 16; count++) {
ProdVal = Num.charAt(count-1) * mask.charAt(count-1)
if (ProdVal > 9)
ProdVal = ProdVal - 9
CheckSum = CheckSum + ProdVal
}
CheckSum = CheckSum % 10
if (CheckSum != 0)
CardType="INVALID"
else
CardType="VALID"
return (CardType)
}
function stripNonNumbers (InString) {
OutString="";
for (Count=0; Count < InString.length; Count++) {
TempChar=InString.substring (Count, Count+1);
Strip = false;
CharString="0123456789";
for (Countx = 0; Countx < CharString.length; Countx++) {
StripThis = CharString.substring(Countx, Countx+1)
if (TempChar == StripThis) {
Strip = true;
break;
}
}
if (Strip)
OutString=OutString+TempChar;
}
return (OutString);
}
</SCRIPT>
<P>
<FORM NAME="validate">
Select card type:<BR>
<SELECT NAME="cardtypelist" SIZE=1>
<OPTION SELECTED VALUE=1>Mastercard
<OPTION VALUE=2>Visa
<OPTION VALUE=3>American Express
<OPTION VALUE=4>Discover
</SELECT>
<P>
Enter account number:<BR>
<INPUT TYPE="text" VALUE="" NAME="accountnumber"> <P>
<INPUT TYPE="button" VALUE="Submit" onClick="validatecard()">
<INPUT TYPE="Reset" VALUE="Reset">
</FORM>
</BODY>
</HTML>
Note: If you are processing credit cards, you should also ask for the
expiration date. The expiration date is not used in any validation routines,
so it is not shown in the above examples. However, the bank will want the expiration
date when authorization the card. The date will be in four digit format, beginning
with the last two digits of the year, followed by the the month, always
expressed as two digits. For example, 9902 is February, 1999; 0112 is December, 2001.
Notice that both JavaScript programs display a generic message saying the card
was valid or not valid. In place of this message you can place additional code, to
perform any extra steps you like. For example, you can add a statement to submit the
form to a CGI program on your Web site. This can be done with the following (you must NOT
use a TYPE=submit button in your form).
document.validate.submit();
Add the above statement in place of (or in addition to) to alert that says the
card is valid.
Also note that the <FORM> tag in both examples is not complete. You need to add
a parameter specifying the name of the CGI program you wish to run, should this
be desired. Example:
<FORM NAME="validate" ACTION="/cgibin/submit.cgi">
Should the card be invalid, it's probably a good idea not to tell the user what
precisely is wrong. For example, don't say that the account number has too many
or too few digits. If someone is trying to scam you, this kind of information
could make it easier for them to circumvent your validation efforts.
(Abridged from Web Commerce Cookbook, published by Wiley Computer Publishing
and written by Gordon McComb. Copyright 1997, Gordon McComb. All Rights
Reserved. Please see http://gmccomb.com/commerce/ for more details on this
book.) |
|
| an example of the cyberlib payment class Categories : PHP, PHP Classes, Ecommerce, Credit Cards | | | Credit Card Numbers for testing Categories : Credit Cards, Ecommerce, Debugging | | | After discovering some credit card validation routines didnt work - here is one that I found works with all the numbers I have tried so far Categories : Credit Cards, Ecommerce, PHP | | | credit card security code Categories : PHP, Credit Cards, PHP Classes, Credit Cards | | | gpg encryption. 99% of it will apply to PGP.
Categories : Credit Cards, Authentication, Ecommerce, Misc | | | Validation function for LUHNMod10 and variant. Can discriminate credit card numbers of varying lengths. Uses [Double >> Sum-of-Digits] transform. Categories : Credit Cards, Authentication, Ecommerce, PHP | | | Real-Time Transaction Processing PHP Class. Credit Cards & Checks. Supports system check, address verification, authorization and deposit, deposit, credit, commercial card, electronic check debit, and more. Categories : PHP Classes, OpenSSL, Credit Cards, Ecommerce, Verisign Payflow Pro | | | Credit Card Identification and Validation Class - The credit_card class provides methods for cleaning, validating and identifying the type of credit card numbers. Categories : PHP, PHP Classes, Credit Cards, Ecommerce, Algorithms | | | Credit Card validation routine. Uses MOD 10 to check if credit card number is valid. Categories : Ecommerce, Credit Cards, PHP, Complete Programs | | | ECHO-Perl Module Credit Card, Check and ACH Transaction Processor Categories : Perl, Cybercash, Classes and Objects, Ecommerce, Credit Cards | | | A set of functions to check the validity of a credit card number. Categories : Ecommerce, Credit Cards, PHP | | | ECHOcart - Open Source Shopping Cart Categories : PHP, Credit Cards, Ecommerce | | | This is a redirection program which is as good as the come.to v3 url
redirection, complete with admin interface all clients stored in mysql
Categories : PHP, MySQL, Ecommerce, HTML and PHP, Complete Programs | | | Install Flash player plug-in Categories : Flash, Java Script | | | A ball is attached to your mouse cursor with an elastic cord! Categories : Java Script, DHTML, Graphics | |
| |
| | | | | Stuart Cayzer wrote : 123
There appears to be a flaw in the logic of this example:
if (result == "Mastercard") {
if (ret.length == 16)
validcard = true;
if ((ret.substring (0, 2) >= "51") &&
(ret.substring (0, 2) <= "55"))
validcard = true;
else
validcard = false;
}
The first Mastercard sub-condition:
if (ret.length == 16)
validcard = true;
is rendered ineffective as "validcard" will be reset by the next statement:
if ((ret.substring (0, 2) >= "51") && (ret.substring (0, 2) <= "55"))
regardless of whether the length is 16. I suspect that the intent was:
if (result == "Mastercard") {
if (ret.length == 16) {
if ((ret.substring (0, 2) >= "51") &&
(ret.substring (0, 2) <= "55"))
validcard = true;
else
validcard = false; }
}
Cheers,
Stuart at www.netcentricservices.com
| | | | Scott Taylor wrote :364
I`ve tried the algorithm on a few cards and none of them
appear to be divisible by 10. Maybe I`m just bad at maths....
| |
|
|