Did you ever wanted to add an Eleven Test validation to your CF7 form? Yes? Then read on quickly!

First, let me explain what the Eleven Test is.

The Eleven Test (11 Test) is a test conducted in the Dutch electronic payment system to validate nine and ten digit Dutch bank account numbers before the introduction of IBAN, to ensure that a number could be a valid account number. Variants of eleven test that use a check digit are applied to other important numbers such as the BSN number (Dutch Social Security Number) and the payment reference on a giro collection form.

BSN numbers have a format of 11 digits. The last digit is the check digit. With the Eleven Test, the last digit for BSN numbers is multiplied by -1 instead of multiplied by 1. Based on a number that complies the Eleven test, no new valid number can be generated by changing one digit or by changing two digits.

One of the most frustrating things in Contact Form 7 is when you want to display a validation message based on custom conditions that cannot be added yet.
I had just this issue recently for a client when I was trying to display a “BSN nummer niet geldig” (BSN number not valid!) message. The website visitor should see an error message when entering an invalid number.

Since I couldn’t find a plugin for this or any other solution, I decided to write the code myself.
I would like to share this code with you. Who knows what it will do for you!

Step 1: Create your CF7 form

Create your CF7 form as you normally would you. For the Eleven Test validation, you’ll have to use a text field which is required. Give the field a recognizable name. We’ll need it later. You can add multiple fields with Eleven Test validation but must give each field its own unique name, e.g. bsn-number, extra-bsn-number2, extra-bsn-number3, etc. They cannot have the same name or you will get errors on all fields if one is incorrect or different from the other.

Step 2: Add a filter

Now it’s time to start coding! Open your favorite coding editor (like Atom or Brackets) and let’s begin by adding a filter:

add_filter( 'wpcf7_validate_text*', 'bsn_field_validation', 20, 2 );
function bsn_field_validation($result, $tag ) {

Step 3: Add fields

Now it’s time to add a field (or fields). In my case I needed multiple fields in one form. You can add as much fields as you need, as long as you add the field names into this code, like this:

$fields_to_validate = [
	'bsn-number',
	'extra-bsn-number2',
	'extra-bsn-number3',
];

Step 4: Character count validation

The Eleven Test works only on numbers with 9 digits. So let’s add a check for that first:

if ( in_array($tag->name, $fields_to_validate) ) {

    $bsn_number = isset( $_POST[$tag->name] ) ? trim( $_POST[$tag->name] ) : '';

	if (strlen($bsn_number) != 9 ) {
		$result->invalidate( $tag, "YOUR ERROR MESSAGE!" );
		return $result;
	}

Step 5: Add the magic!

The Eleven Test is actually a simple formula.

In the Eleven Test, the individual numbers are “weighted” together, that is, depending on the position of the number, it is multiplied by an agreed number (weight). For valid numbers, the sum of the results must be a multiple of 11.

For account numbers, the weights are the numbers 1, 2, 3, … The last digit of the account number is multiplied by 1, the penultimate by 2, the third-to-last by 3, and so on. All results are then added together and then the sum is divided by 11. For a valid number the result of this division must be a whole number and greater than zero. Requiring the result to be greater than 0 prevents a number consisting of all zeros from being considered valid.

Let’s add it to the code:

$number = str_split($bsn_number);

	$bsn_counter = 0;
	$sum = 0;
	for ( $i = 9; $i >= 1 ; $i--) {
		if ($i == 1) {
			$sum = $sum - ($number[$bsn_counter] * $i);
		} else {
			$sum = $sum + ($number[$bsn_counter] * $i);
		}
		
		$bsn_counter++;
}

	if ($sum % 11 != 0) {
		$result->invalidate( $tag, "YOUR ERROR MESSAGE" );
		return $result;
	}
	return $result;
	}
return $result;
}

Step 6: Add the action!

We’re almost done, but first we need to add an action that calls a script with the error message that appears on the front-end if the input is incorrect.

add_action( 'wp_footer', 'validate_cf7_bsn_field' );
function validate_cf7_bsn_field() {
	?>

Then we need to add the jQuery script that displays the actual error message below the input fields:

<script>
	
	jQuery(document).ready(function($) {

	const fieldsToValidate = [
		'bsn-number',
		'extra-bsn-number2',
		'extra-bsn-number3'
	];

	fieldsToValidate.forEach(function(v, i) {
		$('input[name="' + v + '"]').on('blur', function() {
			const bsnNumber = $(this).val().trim();
			$(this).removeClass('wpcf7-not-valid');
			$(this).parent().find('.wpcf7-not-valid-tip').remove();
			if (bsnNumber.length != 9) {
				$(this).addClass('wpcf7-not-valid');
				$(this).parent().append('<span class="wpcf7-not-valid-tip" aria-hidden="true">YOUR ERROR MESSAGE!</span>');
				return false;
			} else if (Number(bsnNumber) == NaN) {
				$(this).addClass('wpcf7-not-valid');
				$(this).parent().append('<span class="wpcf7-not-valid-tip" aria-hidden="true">YOUR ERROR MESSAGE!</span>');
				return false;
			}

			bsnCounter = 0;
			sum = 0;
			for ( i = 9; i >= 1 ; i--) {
				if (i == 1) {
					sum = sum - (bsnNumber[bsnCounter] * i);
				} else {
					sum = sum + (bsnNumber[bsnCounter] * i);
				}
					
				bsnCounter++;
			}

			if (sum % 11 != 0) {
				$(this).addClass('wpcf7-not-valid');
				$(this).parent().append('<span class="wpcf7-not-valid-tip" aria-hidden="true">YOUR ERROR MESSAGE!</span>');
			} else {
				$(this).removeClass('wpcf7-not-valid');
				$(this).parent().find('.wpcf7-not-valid-tip').remove();
			}
		});
	});
		
});
</script>
	

Step 7: Wrapping up!

Close your code correctly by adding this at the end:

<?php
}

All this code goes in functions.php or can be added to a snippets plugin.
Don’t forget to customize all error messages in the code above and change the field name(s) if you use other names for your field(s).

Last but certainly very important: always create a full site backup before modifying WordPress core files like functions.php!
I do not accept any liability in case your website breaks down.

I hope you find this code useful. Feel free to comment what you think about it and how it helped you!