• Resolved Rune Rasmussen

    (@syntaxerrorno)


    You’re overriding the phone number field, and adds t.ex. +47 automatically into it for Norway.

    This causes a lot of customers to skip the field as it’s already filled, and have no further validation on the phone number length / formatting – so they can checkout without filling it.

    Better remove your override, or add a proper phone number validation, else it’s worse as is than you not getting the country prefix (something carriers should be able to handle elsewhere anyway ;)).

    Just an example for a simple validation, needs something more solid for all the world:

    add_action('woocommerce_checkout_process', 'wc_validate_nordic_phone');

    function wc_validate_nordic_phone() {

    if (empty($_POST['billing_phone'])) {
    return;
    }

    $raw = trim(wp_unslash($_POST['billing_phone']));

    // Normalize: keep leading + if present, remove everything but digits
    $has_plus = (strpos($raw, '+') === 0);
    $digits = preg_replace('/\D/', '', $raw);

    // Convert 00 prefix to "international" (same treatment as +)
    $is_international = false;
    if ($has_plus) {
    $is_international = true;
    // the digits are already without +
    } elseif (strpos($digits, '00') === 0) {
    $is_international = true;
    $digits = substr($digits, 2); // remove 00
    }

    // Country rules: national length (without country code) for mobile
    // [country code => [min, max]]
    $rules = [
    '47' => [8, 8], // Norway
    '46' => [9, 9], // Sweden (mobile, without leading 0)
    '45' => [8, 8], // Denmark
    '358' => [9, 10], // Finland (mobile varies)
    '354' => [7, 7], // Iceland
    '298' => [6, 6], // Faroe Islands
    '299' => [6, 6], // Greenland
    ];

    $country_code = null;
    $national = $digits;

    if ($is_international) {
    // Find matching country code (longest first to hit 358/354/298/299 before 3/5/2/9)
    $codes = array_keys($rules);
    usort($codes, function ($a, $b) { return strlen($b) - strlen($a); });

    foreach ($codes as $code) {
    if (strpos($digits, $code) === 0) {
    $country_code = $code;
    $national = substr($digits, strlen($code));
    break;
    }
    }

    if ($country_code === null) {
    wc_add_notice(__('Invalid country code. Use +47, +46, +45, +358, +354, +298 eller +299.', 'posten-bring-checkout'), 'error');
    return;
    }
    } else {
    // National format – assume the store's country, fall back to Norway
    $store_country = WC()->customer ? WC()->customer->get_billing_country() : 'NO';
    $country_map = [
    'NO' => '47', 'SE' => '46', 'DK' => '45',
    'FI' => '358', 'IS' => '354', 'FO' => '298', 'GL' => '299',
    ];
    $country_code = $country_map[$store_country] ?? '47';

    // Remove any leading 0 (common in national notation for SE/FI)
    $national = ltrim($national, '0');
    }

    [$min, $max] = $rules[$country_code];
    $len = strlen($national);

    if ($len < $min || $len > $max) {
    wc_add_notice(
    sprintf(
    /* translators: 1: country code, 2: min, 3: max */
    __('Invalid mobile number for +%1$s. Expected %2$d–%3$d digits after the country code.', 'posten-bring-checkout'),
    $country_code, $min, $max
    ),
    'error'
    );
    }
    }
Viewing 3 replies - 16 through 18 (of 18 total)
Viewing 3 replies - 16 through 18 (of 18 total)

You must be logged in to reply to this topic.