I recently had a project where I needed to accomplish the following two tasks:
- Replace all but the last four digits of a credit card with X’s
- Format the credit card with dashes in the appropriate places
There are many different approaches that can be taken to accomplish the above two tasks. The simplest approach would be to do something like the following:
<?php echo 'XXXX-XXXX-XXXX-'.substr($cc,-4); ?>
I have often seen credit cards masked with the above approach. For the most case this solution will work fairly well. However, I am not a huge fan of this approach as it displays the credit card at a fixed length of 16 digits. This can be a bit confusing since credit cards can very in length from 13 to 16 digits.
To better address this issue I put together two functions. One function is to apply a mask to a credit card and the other is to format the credit card with dashes. These functions will keep the original length of each credit card.
<?php /** * Replaces all but the last for digits with x's in the given credit card number * @param int|string $cc The credit card number to mask * @return string The masked credit card number */ function MaskCreditCard($cc){ // Get the cc Length $cc_length = strlen($cc); // Replace all characters of credit card except the last four and dashes for($i=0; $i<$cc_length-4; $i++){ if($cc[$i] == '-'){continue;} $cc[$i] = 'X'; } // Return the masked Credit Card # return $cc; } /** * Add dashes to a credit card number. * @param int|string $cc The credit card number to format with dashes. * @return string The credit card with dashes. */ function FormatCreditCard($cc) { // Clean out extra data that might be in the cc $cc = str_replace(array('-',' '),'',$cc); // Get the CC Length $cc_length = strlen($cc); // Initialize the new credit card to contian the last four digits $newCreditCard = substr($cc,-4); // Walk backwards through the credit card number and add a dash after every fourth digit for($i=$cc_length-5;$i>=0;$i--){ // If on the fourth character add a dash if((($i+1)-$cc_length)%4 == 0){ $newCreditCard = '-'.$newCreditCard; } // Add the current character to the new credit card $newCreditCard = $cc[$i].$newCreditCard; } // Return the formatted credit card number return $newCreditCard; } ?>
Below are a couple examples of how to use these functions and the results they create.
<?php echo maskCreditCard('5362267121053405').'<br>'; // Prints XXXXXXXXXXXX3405 echo formatCreditCard('5362267121053405').'<br>'; // Prints 5362-2671-2105-3405 echo formatCreditCard(maskCreditCard('5362267121053405')).'<br>'; // Prints XXXX-XXXX-XXXX-3405 ?>
<?php $creditCard[] = '5362267121053405'; // Mastercard $creditCard[] = '4556189015881361'; // Visa 16 $creditCard[] = '4716904617062'; // Visa 13 $creditCard[] = '372348371455844'; // American Express $creditCard[] = '6011757892594291'; // Discover $creditCard[] = '30329445722959'; // Diners Club $creditCard[] = '214927124363421'; // enRoute $creditCard[] = '180012855304868'; // JCB 15 $creditCard[] = '3528066275370961'; // JCB 16 $creditCard[] = '8699775919'; // Voyager for($i=0;$i<count($creditCard);$i++) { echo FormatCreditCard(MaskCreditCard(($creditCard[$i])))."\n"; } ?>
Output:
XXXX-XXXX-XXXX-3405 XXXX-XXXX-XXXX-1361 X-XXXX-XXXX-7062 XXX-XXXX-XXXX-5844 XXXX-XXXX-XXXX-4291 XX-XXXX-XXXX-2959 XXX-XXXX-XXXX-3421 XXX-XXXX-XXXX-4868 XXXX-XXXX-XXXX-0961 XX-XXXX-5919
Let me know if you find these functions useful or have any suggestions on how to tweak them.