Format Credit Card with X’s and Dashes using PHP (credit card masking)

by Brett on March 22, 2010

I recently had a project where I needed to accomplish the following two tasks:

  1. Replace all but the last four digits of a credit card with X’s
  2. 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.

Previous post:

Next post: