This forum is no longer open and is for reading/searching only.

Please use our new MachForm Community Forum instead.

MachForm Community Forums » MachForm 3

HOW TO: Add Mod-10 Credit Card validation to your form.


  1. tmparisi
    Member

    For those of you that take credit card numbers in your forms, here is a simple way to set up CC validation in your form that ultimately checks for several factors including, length, prefix, and mod-10 algorithm. The following code is adapted from: http://www.braemoor.co.uk/software/creditcard.php

    Open up your post_functions.php file in your include folder and find the following lines of code:

    if(!empty($row['form_redirect_enable'])){
     $form_redirect = $row['form_redirect'];
     }

    Right below this code, add the following verification script:

    //custom code
     //====================START CC Validation=======================
     if ($form_id == 15 || $form_id == 3 || $form_id == 4 || $form_id == 10 || $form_id == 11) {  //form numbers that have text fields that you want to perform CC validation
     if($form_id == 15)  //if form #15, set the credit card type dropdown and the credit card number fields according to the element numbers for that form
     {
     $cc_validate_id = 1;  //set credit card number field
     $cc_validate_type = 2;  //set credit card type field
     }
     if($form_id == 3)
     {
     $cc_validate_id = 28;
     $cc_validate_type = 17;
     }
     if($form_id == 4)
     {
     $cc_validate_id = 29;
     $cc_validate_type = 17;
     }
     if($form_id == 10)
     {
     $cc_validate_id = 28;
     $cc_validate_type = 17;
     }
     if($form_id == 11)
     {
     $cc_validate_id = 29;
     $cc_validate_type = 17;
     }
    
     $failcheck = 0;
     if (!empty($table_data['element_' . $cc_validate_id])) {
    
     if($table_data['element_' . $cc_validate_type] == 1) //check if credit card dropdown type is 1
     {
     $cardname = 'american express'; //if so, set $cardname equal to american express
     }
     else if($table_data['element_' . $cc_validate_type] == 2)
     {
     $cardname = 'visa';
     }
     else if($table_data['element_' . $cc_validate_type] == 3)
     {
     $cardname = 'mastercard';
     }
     else if($table_data['element_' . $cc_validate_type] == 4)
     {
     $cardname = 'discover';
     }
     else
     {
     $cardname = '';
     }
    
     $cardnumber = $table_data['element_' . $cc_validate_id]; //set $cardnumber equal to the credit card number entered by user
    
     $cards = array ( array ('name' => 'American Express',
    'length' => '15',
    'prefixes' => '34,37',
     'checkdigit' => true
     ),
     array ('name' => 'Discover',
    'length' => '16',
    'prefixes' => '6011,622,64,65',
     'checkdigit' => true
     ),
     array ('name' => 'MasterCard',
    'length' => '16',
    'prefixes' => '51,52,53,54,55',
     'checkdigit' => true
     ),
     array ('name' => 'VISA',
    'length' => '16',
    'prefixes' => '4',
     'checkdigit' => true
     ),
     array ('name' => 'VISA Electron',
    'length' => '16',
    'prefixes' => '417500,4917,4913,4508,4844',
     'checkdigit' => true
     )
     );
    
     $ccErrorNo = 0;
    
     $ccErrors [0] = "Unknown card type";
     $ccErrors [1] = "No card number provided";
     $ccErrors [2] = "Credit card number has invalid format";
     $ccErrors [3] = "Credit card number is invalid";
     $ccErrors [4] = "Credit card number is wrong length";
    
     // Establish card type
     $cardType = -1;
     for ($i=0; $i<sizeof($cards); $i++) {
    
     // See if it is this card (ignoring the case of the string)
     if (strtolower($cardname) == strtolower($cards[$i]['name'])) {
     $cardType = $i;
     break;
     }
     }
    
     // If card type not found, report an error
     if ($cardType == -1 && $failcheck == 0) {
     $errornumber = 0;
    $errortext = $ccErrors [$errornumber];
     $error_elements[$cc_validate_id] = $ccErrors [$errornumber];
     $failcheck = 1;
     }
    
     // Ensure that the user has provided a credit card number
     if (strlen($cardnumber) == 0 && $failcheck == 0) {
     $errornumber = 1;
    $errortext = $ccErrors [$errornumber];
     $error_elements[$cc_validate_id] = $ccErrors [$errornumber];
     $failcheck = 1;
     }
    
     // Remove any spaces from the credit card number
     $cardNo = str_replace (' ', '', $cardnumber); 
    
    // Check that the number is numeric and of the right sort of length.
     if (!preg_match("/^[0-9]{13,19}$/",$cardNo) && $failcheck == 0) {
     $errornumber = 2;
    $errortext = $ccErrors [$errornumber];
     $error_elements[$cc_validate_id] = $ccErrors [$errornumber];
     $failcheck = 2;
     }
    
     // Now check the modulus 10 check digit - if required
     if ($cards[$cardType]['checkdigit'] && $failcheck == 0) {
     $checksum = 0; // running checksum total
     $mychar = ""; // next char to process
     $j = 1; // takes value of 1 or 2
    
     // Process each digit one by one starting at the right
     for ($i = strlen($cardNo) - 1; $i >= 0; $i--) {
    
     // Extract the next digit and multiply by 1 or 2 on alternative digits.
    $calc = $cardNo{$i} * $j;
    
     // If the result is in two digits add 1 to the checksum total
     if ($calc > 9) {
     $checksum = $checksum + 1;
     $calc = $calc - 10;
     }
    
     // Add the units element to the checksum total
     $checksum = $checksum + $calc;
    
     // Switch the value of j
     if ($j ==1) {$j = 2;} else {$j = 1;};
     } 
    
    // All done - if checksum is divisible by 10, it is a valid modulus 10.
     // If not, report an error.
     if ($checksum % 10 != 0 && $failcheck == 0) {
     $errornumber = 3;
    $errortext = $ccErrors [$errornumber];
     $error_elements[$cc_validate_id] = $ccErrors [$errornumber];
     $failcheck = 3;
     }
     } 
    
    // The following are the card-specific checks we undertake.
    
     // Load an array with the valid prefixes for this card
     $prefix = explode(',',$cards[$cardType]['prefixes']);
    
     // Now see if any of them match what we have in the card number
    $PrefixValid = false;
    for ($i=0; $i<sizeof($prefix); $i++) {
     $exp = '/^' . $prefix[$i] . '/';
     if (preg_match($exp,$cardNo)) {
     $PrefixValid = true;
     break;
     }
     }
    
     // If it isn't a valid prefix there's no point at looking at the length
     if (!$PrefixValid && $failcheck == 0) {
     $errornumber = 3;
    $errortext = $ccErrors [$errornumber];
     $error_elements[$cc_validate_id] = $ccErrors [$errornumber];
     $failcheck = 3;
     }
    
     // See if the length is valid for this card
     $LengthValid = false;
     $lengths = explode(',',$cards[$cardType]['length']);
     for ($j=0; $j<sizeof($lengths); $j++) {
     if (strlen($cardNo) == $lengths[$j]) {
     $LengthValid = true;
     break;
     }
     }
    
     // See if all is OK by seeing if the length was valid.
    if (!$LengthValid && $failcheck == 0) {
     $errornumber = 4;
    $errortext = $ccErrors [$errornumber];
     $error_elements[$cc_validate_id] = $ccErrors [$errornumber];
     $failcheck = 4;
     }; 
    
     }
     }
     //====================END CC Validation=======================

    This is probably not perfect nor is it most likely the most efficient method, but it is tested and does work. I hope it can be of some use for others out there!

    Posted 11 years ago #
  2. yuniar

    Thank you for sharing this!


    MachForm Founder

    Posted 11 years ago #
  3. aolmos
    Member

    How can I include this code in machform 2? We have customized our machform and we can't switch to machform 3

    Posted 11 years ago #
  4. tmparisi
    Member

    Hi aolmos, unfortunately I cannot help you with this. I have never used v2. Best of luck!

    Posted 11 years ago #
  5. aolmos
    Member

    What about version 4?

    Posted 9 years ago #

RSS feed for this topic

Reply