How to Validate Romanian CNP in WooCommerce and Laravel Using an External API

How to Validate Romanian CNP in WooCommerce and Laravel Using an External API

Validating personal identification numbers, such as the Romanian Cod Numeric Personal (CNP), is essential for e-commerce platforms and Web applications operating in Romania. Accurate CNP validation ensures data integrity for invoicing, identity verification, legal compliance, and fraud prevention.

In this guide, we will explore how to integrate automated CNP validation into Laravel applications and WooCommerce checkout fields using the official VerificareCNP API.


Why Use an API for CNP Validation?

While simple regex or client-side JavaScript functions can check basic 13-digit lengths, a complete CNP validation requires:

  1. Verifying the first digit (cifra S for gender and century).
  2. Validating the birth date structure (including leap years).
  3. Checking valid county codes (cod județ).
  4. Running the official control digit calculation algorithm (cifra de control).

By leveraging the CNP Validation API, you ensure that your platform relies on a reliable and always up-to-date validation service without adding heavy custom algorithms to your codebase.


1. Integrating CNP Validation into Laravel

To validate a CNP in a Laravel application, you can easily create a custom Validation Rule using Laravel's Http facade.

Step 1: Create a Custom Rule

Run the Artisan command in your terminal:

php artisan make:rule ValidCnp

Step 2: Implement the API Request

Update the generated ValidCnp.php file to send a POST request to the VerificareCNP API Endpoint:

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Http;

class ValidCnp implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $response = Http::asJson()->post('https://verificarecnp.ro/api/v1/cnp/validate', [
            'cnp' => $value,
        ]);

        if ($response->failed() || ! $response->json('valid')) {
            $fail('The provided :attribute is not a valid Romanian CNP.');
        }
    }
}

Step 3: Use the Rule in Your Controller

You can now apply ValidCnp directly inside your form request or controller:

use App\Rules\ValidCnp;

$request->validate([
    'cnp' => ['required', 'string', new ValidCnp()],
]);

2. Adding CNP Validation to WooCommerce Checkout

In WooCommerce, invoicing laws in Romania often require storing customer identification numbers. Here is how you can add a CNP field to the WooCommerce checkout and validate it server-side before an order is placed.

Add the following snippet to your theme's functions.php or inside a custom plugin:

// 1. Add CNP Field to Checkout
add_filter('woocommerce_checkout_fields', 'add_cnp_checkout_field');
function add_cnp_checkout_field($fields) {
    $fields['billing']['billing_cnp'] = array(
        'type'        => 'text',
        'label'       => __('CNP (Cod Numeric Personal)', 'woocommerce'),
        'placeholder' => __('1960527400195', 'woocommerce'),
        'required'    => true,
        'class'       => array('form-row-wide'),
        'priority'    => 25,
    );
    return $fields;
}

// 2. Validate CNP via VerificareCNP API
add_action('woocommerce_checkout_process', 'validate_cnp_checkout_field');
function validate_cnp_checkout_field() {
    if (isset($_POST['billing_cnp']) && !empty($_POST['billing_cnp'])) {
        $cnp = sanitize_text_field($_POST['billing_cnp']);

        $response = wp_remote_post('https://verificarecnp.ro/api/v1/cnp/validate', array(
            'headers' => array('Content-Type' => 'application/json'),
            'body'    => wp_json_encode(array('cnp' => $cnp)),
            'timeout' => 5,
        ));

        if (is_wp_error($response)) {
            wc_add_notice(__('Validation service is temporarily unavailable. Please try again.', 'woocommerce'), 'error');
            return;
        }

        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);

        if (empty($data['valid'])) {
            wc_add_notice(__('Codul CNP introdus nu este valid.', 'woocommerce'), 'error');
        }
    }
}

Need Dummy CNP Data for Automated Testing?

During staging and testing phases, developers should avoid using real personal identification data to comply with GDPR requirements. You can use the CNP Generator API to automatically generate synthetic, mathematically correct CNPs for your unit and integration tests.