What is the best way to validate a credit card in PHP?
There are three parts to the validation of the card number:
- PATTERN - does it match an issuers pattern (e.g. VISA/Mastercard/etc.)
- CHECKSUM - does it actually check-sum (e.g. not just 13 random numbers after "34" to make it an AMEX card number)
- REALLY EXISTS - does it actually have an associated account (you are unlikely to get this without a merchant account)
Pattern
- MASTERCARD Prefix=51-55, Length=16 (Mod10 checksummed)
- VISA Prefix=4, Length=13 or 16 (Mod10)
- AMEX Prefix=34 or 37, Length=15 (Mod10)
- Diners Club/Carte Prefix=300-305, 36 or 38, Length=14 (Mod10)
- Discover Prefix=6011,622126-622925,644-649,65, Length=16, (Mod10)
- etc. (detailed list of prefixes)
Checksum
Most cards use the Luhn algorithm for checksums:
Luhn Algorithm described on Wikipedia
There are links to many implementations on the Wikipedia link, including PHP:
<?
/* Luhn algorithm number checker - (c) 2005-2008 shaman - www.planzero.org *
* This code has been released into the public domain, however please *
* give credit to the original author where possible. */
function luhn_check($number) {
// Strip any non-digits (useful for credit card numbers with spaces and hyphens)
$number=preg_replace('/\D/', '', $number);
// Set the string length and parity
$number_length=strlen($number);
$parity=$number_length % 2;
// Loop through each digit and do the maths
$total=0;
for ($i=0; $i<$number_length; $i++) {
$digit=$number[$i];
// Multiply alternate digits by two
if ($i % 2 == $parity) {
$digit*=2;
// If the sum is two digits, add them together (in effect)
if ($digit > 9) {
$digit-=9;
}
}
// Total up the digits
$total+=$digit;
}
// If the total mod 10 equals 0, the number is valid
return ($total % 10 == 0) ? TRUE : FALSE;
}
?>
Validate credit card number
Don't change the user's entered text, it will just cause confusion. Don't cause the user to think: WTF. The user entered the number in the way he understood, honor that as much as possible.
Just sanitize what the user has entered. Generally just remove all leading, training and interspersed space characters, possibly any non-numeric characters. Then ensure the entered text is all numeric and of the correct length.
Keep in mind that the number can have a length of 13 to 19 digits, American Express is 15 digits. See: Bank card number
Consider the code:
if ([temp.text length]>19) {
txtCard.text= [temp.text substringToIndex:[temp.text length] - 1];
}
If the user entered an extra space character between groups the last digit will be deleted. It is all to easy to come up with such a scheme will avoid all possible pitfalls.
Example: "1234 4567 9012 3456" would be truncated to "1234 4567 9012 345".
Extra, Method to verify the check digit:
+ (BOOL)isValidCheckDigitForCardNumberString:(NSString *)cardNumberString {
int checkSum = 0;
uint8_t *cardDigitArray = (uint8_t *)[cardNumberString dataUsingEncoding:NSUTF8StringEncoding].bytes;
int digitsCount = (int)cardNumberString.length;
BOOL odd = cardNumberString.length % 2;
for (int digitIndex=0; digitIndex<digitsCount; digitIndex++) {
uint8_t cardDigit = cardDigitArray[digitIndex] - '0';
if (digitIndex % 2 == odd) {
cardDigit = cardDigit * 2;
cardDigit = cardDigit / 10 + cardDigit % 10;
}
checkSum += cardDigit;
}
return (checkSum % 10 == 0);
}
BOOL checkDigitValid = [TestClass isValidCheckDigitForCardNumberString:@"371238839571772"];
NSLog(@"check digit valid: %@", checkDigitMatch ? @"yes" : @"no");
Output:
check digit valid: yes
validate the credit card in authorize.net without specifying the amount
You can't validate a credit card is legitimate without processing a transaction. You can validate the format of the card number is valid and the card is not expired, but not if it is real or active.
To validate a credit card is valid without charging it you need to do an AUTH_ONLY for either $0.00 or $0.01 depending on your processor's requirements. If it is approved, and the amount is $0.01, you should then void that transaction.
how to validate credit card info(billing, card number etc) through authorize.net?
No. The only way to know a credit card is valid is to process a transaction. Only then is the bank contacted to validate the credit card.
FYI, I am the author of the article you linked to.
Credit card validation check in C programming
I solved this problem 2 years ago from now. But I forgot to post the answer of this the question. So, I am putting my answer below. Hope this will be useful to beginner programmers.
#include<cs50.h>
#include<stdio.h>
#include<stdbool.h>
// Function prototype slot
bool validity_checker(long long ccnum) ;
int find_length_cc(long long ccnum) ;
bool checksum(long long ccnum) ;
void print_credit_card_name(long long ccnum) ;
//Driver function to execute all those user-defined function
int main()
{
long long ccnum;
do
{
ccnum = get_long("Enter your credit card number: \n") ;
}
while (ccnum <= 0) ;
if (validity_checker(ccnum))
{
print_credit_card_name(ccnum) ;
}
else
{
printf("INVALID\n") ;
}
}
//Creating function body which will be called in the main function
bool validity_checker(long long ccnum)
{
int len = find_length_cc(ccnum) ;
return ((len == 13 || len == 15 || len == 16) && checksum(ccnum)) ; // this will return if true
}
int find_length_cc(long long ccnum)
{
int len = 0 ;
while (ccnum != 0)
{
ccnum = ccnum / 10 ;
len++ ;
}
return len ;
}
bool checksum(long long ccnum)
{
int sum = 0 ;
long long tempccnum = ccnum ;
//Case-01(Weren't multiplied by 2): will start it's work from the last
while (tempccnum > 0)
{
int lastdigit = tempccnum % 10 ; // accessing the last digit
sum = sum + lastdigit ;
tempccnum = tempccnum / 100 ;
}
// Case-02(Multiplication every other digit by 2):
tempccnum = ccnum / 10 ; //removing the last digit
while (tempccnum > 0)
{
int secondlastdigit = (tempccnum % 10) ;
int tempmultiply = secondlastdigit * 2 ;
// for multiple digits, this expression gives us their individual sum and adds with the total sum of cc
sum = sum + (tempmultiply % 10) + (tempmultiply / 10) ;
//This will allow us to move and access two digits over
tempccnum = tempccnum / 100 ;
}
return (sum % 10) == 0 ;
}
void print_credit_card_name(long long ccnum) // First two digits checking
{
// 34e13 is first two digits and followed by 13 zeros as AMEX is 15 digits long
if ((ccnum >= 34e13 && ccnum < 35e13) || (ccnum >= 37e13 && ccnum < 38e13))
{
printf("AMEX\n") ;
}
else if (ccnum >= 51e14 && ccnum < 56e14)
{
printf("MASTERCARD\n") ;
}
else if ((ccnum >= 4e12 && ccnum < 5e12) || (ccnum >= 4e15 && ccnum < 5e15))
{
printf("VISA\n") ;
}
else
{
printf("INVALID\n") ;
}
}
Credit Card Number Validation
Instead of
if(x.length != 13 || x.length != 18)
you should use
if(x.length != 13 && x.length != 18)
in fact, with your original condition, 18 is different from 13, and that would have returned true
!
Also, that accepts only exact length of 13 or 18, if you want to reject anything shorter than 13 or longer than 18, then you need
if(x.length < 13 || x.length > 18)
Related Topics
If Check Box Checked Disable Other, If Unchecked Enable All in React
To Check If a String Is Alphanumeric in JavaScript
Get Count of True Values in Json With JavaScript
Electron - How to Add External Files
Why Does Prettier Not Format Code in VS Code
How to I Retrieve Last Part of Url and Use It in HTML
How to Change the State Correctly (Read-Only Error)
How to Change Background Color of a Row on Checkbox Selection
Prevent Particular Child Element from Firing Parent'S Mouseover Event in Jquery
Javascript Function (Input Date Bigger Than Today Date)
Connection Refused! Is Selenium Server Started
Removing Currency Symbol and Replacing Comma With Point Using Pure JavaScript
Why Isnt Window.Location.Href= Not Forwarding to Page Using Safari
How to Access a Model Attribute With JavaScript Variable
Edit Table Row Inline on Click of Edit in Angular