73 votes

Quel est le meilleur moyen de valider une carte de crédit en PHP?

Étant donné le numéro de carte de crédit et aucune information supplémentaire, quel est le meilleur moyen en PHP de déterminer s’il s’agit ou non d’un numéro valide?

Pour le moment, j'ai besoin de quelque chose qui fonctionne avec American Express, Discover, MasterCard et Visa, mais il serait peut-être utile que cela fonctionne également avec d'autres types.

155voto

Ray Hayes Points 9819

Il ya trois parties à la validation du numéro de la carte:

  1. MODÈLE - t-elle correspondre à une émetteurs modèle (ex: VISA/Mastercard/etc.)
  2. Somme de contrôle - t-il fait le check-sum (pas seulement, par exemple 13 nombres aléatoires après "34" pour en faire un AMEX numéro de la carte)
  3. EXISTE - t-il en fait un compte associé (vous êtes peu probable d'obtenir ce sans un compte marchand)

Modèle

Il y a une description ici qui décrit de nombreux types de cartes:

  • MASTERCARD Prefix=51-55, Longueur=16 (Mod10 somme)
  • VISA Prefix=4, Longueur=13 ou 16 (Mod10)
  • AMEX Prefix=34 ou 37, Longueur=15 (Mod10)
  • Diners Club/Carte Prefix=300-305, 36 ou 38, Longueur=14 (Mod10)
  • Découvrez Prefix=6011, Longueur=16, (Mod10)
  • etc. (liste détaillée des préfixes)

Somme de contrôle

La plupart des cartes de l'utilisation de l'algorithme de Luhn pour les sommes de contrôle:

L'Algorithme de Luhn décrit sur Wikipedia

Il y a des liens à de nombreuses implémentations sur le lien Wikipédia, y compris 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;

}
?>

30voto

ConroyP Points 24021

À partir de 10 expressions régulières sans PHP, vous ne pourrez plus vous en passer :

 function check_cc($cc, $extra_check = false){
    $cards = array(
        "visa" => "(4\d{12}(?:\d{3})?)",
        "amex" => "(3[47]\d{13})",
        "jcb" => "(35[2-8][89]\d\d\d{10})",
        "maestro" => "((?:5020|5038|6304|6579|6761)\d{12}(?:\d\d)?)",
        "solo" => "((?:6334|6767)\d{12}(?:\d\d)?\d?)",
        "mastercard" => "(5[1-5]\d{14})",
        "switch" => "(?:(?:(?:4903|4905|4911|4936|6333|6759)\d{12})|(?:(?:564182|633110)\d{10})(\d\d)?\d?)",
    );
    $names = array("Visa", "American Express", "JCB", "Maestro", "Solo", "Mastercard", "Switch");
    $matches = array();
    $pattern = "#^(?:".implode("|", $cards).")$#";
    $result = preg_match($pattern, str_replace(" ", "", $cc), $matches);
    if($extra_check && $result > 0){
        $result = (validatecard($cc))?1:0;
    }
    return ($result>0)?$names[sizeof($matches)-2]:false;
}
 

Exemple de saisie:

 $cards = array(
    "4111 1111 1111 1111",
);

foreach($cards as $c){
    $check = check_cc($c, true);
    if($check!==false)
        echo $c." - ".$check;
    else
        echo "$c - Not a match";
    echo "<br/>";
}
 

Cela nous donne

 4111 1111 1111 1111 - Visa
 

14voto

Thelonious Points 1038

Il est probablement préférable de ne pas valider le code de votre côté. Envoyez les informations de la carte directement à votre passerelle de paiement, puis traitez leur réponse. Cela les aide à détecter les fraudes si vous ne faites rien comme Luhn en premier - laissez-les voir les tentatives qui ont échoué.

6voto

Patrick Desjardins Points 51478

Code PHP

 function validateCC($cc_num, $type) {

	if($type == "American") {
	$denum = "American Express";
	} elseif($type == "Dinners") {
	$denum = "Diner's Club";
	} elseif($type == "Discover") {
	$denum = "Discover";
	} elseif($type == "Master") {
	$denum = "Master Card";
	} elseif($type == "Visa") {
	$denum = "Visa";
	}

	if($type == "American") {
	$pattern = "/^([34|37]{2})([0-9]{13})$/";//American Express
	if (preg_match($pattern,$cc_num)) {
	$verified = true;
	} else {
	$verified = false;
	}


	} elseif($type == "Dinners") {
	$pattern = "/^([30|36|38]{2})([0-9]{12})$/";//Diner's Club
	if (preg_match($pattern,$cc_num)) {
	$verified = true;
	} else {
	$verified = false;
	}


	} elseif($type == "Discover") {
	$pattern = "/^([6011]{4})([0-9]{12})$/";//Discover Card
	if (preg_match($pattern,$cc_num)) {
	$verified = true;
	} else {
	$verified = false;
	}


	} elseif($type == "Master") {
	$pattern = "/^([51|52|53|54|55]{2})([0-9]{14})$/";//Mastercard
	if (preg_match($pattern,$cc_num)) {
	$verified = true;
	} else {
	$verified = false;
	}


	} elseif($type == "Visa") {
	$pattern = "/^([4]{1})([0-9]{12,15})$/";//Visa
	if (preg_match($pattern,$cc_num)) {
	$verified = true;
	} else {
	$verified = false;
	}

	}

	if($verified == false) {
	//Do something here in case the validation fails
	echo "Credit card invalid. Please make sure that you entered a valid <em>" . $denum . "</em> credit card ";

	} else { //if it will pass...do something
	echo "Your <em>" . $denum . "</em> credit card is valid";
	}


}
 

Usage

 echo validateCC("1738292928284637", "Dinners");
 

Plus d'informations théoriques peuvent être trouvés ici:

Validation de la carte de crédit - Vérifier les chiffres

Somme de contrôle

3voto

Dana Points 9876

L' algorithme luhn est une somme de contrôle qui permet de valider le format de nombreux formats de cartes de crédit (ainsi que les numéros d'assurance sociale canadiens ...).

L'article de Wikipédia est également lié à de nombreuses implémentations différentes; en voici un en PHP:

http://planzero.org/code/bits/viewcode.php?src=luhn_check.phps

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X