EmailVerify LogoEmailVerify

WooCommerce

Email checker for WooCommerce. Verify at checkout and in order processing.

Ajoutez la vérification d'e-mails à votre boutique WooCommerce pour réduire les échecs de livraison, prévenir la fraude et améliorer la communication avec les clients.

Méthodes d'intégration

MéthodeIdéal pourComplexité
PluginConfiguration rapideFaible
Hook de paiementVérification en temps réelMoyenne
Traitement des commandesVérification en arrière-planMoyenne
REST APISolutions personnaliséesÉlevée

Méthode 1 : Plugin WordPress

Si vous avez déjà configuré le plugin WordPress EmailVerify, l'intégration WooCommerce est automatique.

Activer le support WooCommerce

  1. Allez dans RéglagesEmailVerify
  2. Cochez Activer l'intégration WooCommerce
  3. Configurez les options :
    • ✓ Vérifier lors du paiement
    • ✓ Bloquer les e-mails jetables
    • ✓ Afficher le statut de vérification dans les commandes

Méthode 2 : Validation au paiement

Ajoutez la vérification d'e-mails au processus de paiement WooCommerce.

Validation côté serveur

<?php
// functions.php ou plugin personnalisé

/**
 * Vérifier l'e-mail lors du paiement WooCommerce
 */
add_action('woocommerce_checkout_process', 'emailverify_checkout_validation');

function emailverify_checkout_validation() {
    $email = sanitize_email($_POST['billing_email']);

    if (empty($email)) {
        return;
    }

    $result = emailverify_verify_email($email);

    if (!$result['success']) {
        // Erreur API - autoriser le paiement à continuer
        return;
    }

    $data = $result['data'];

    // Bloquer les e-mails invalides
    if ($data['status'] === 'invalid') {
        wc_add_notice(
            __('Veuillez entrer une adresse e-mail valide pour finaliser votre commande.', 'your-theme'),
            'error'
        );
    }

    // Bloquer les e-mails jetables (optionnel)
    if (get_option('emailverify_block_disposable', true)) {
        if ($data['result']['disposable'] ?? false) {
            wc_add_notice(
                __('Les adresses e-mail temporaires ne sont pas acceptées. Veuillez utiliser un e-mail permanent.', 'your-theme'),
                'error'
            );
        }
    }
}

/**
 * Fonction d'aide pour l'appel API EmailVerify
 */
function emailverify_verify_email($email) {
    $api_key = get_option('emailverify_api_key');

    // Vérifier le cache d'abord
    $cache_key = 'bv_email_' . md5($email);
    $cached = get_transient($cache_key);

    if ($cached !== false) {
        return $cached;
    }

    $response = wp_remote_post('https://api.emailverify.ai/v1/verify', [
        'headers' => [
            'Authorization' => 'Bearer ' . $api_key,
            'Content-Type' => 'application/json',
        ],
        'body' => json_encode(['email' => $email]),
        'timeout' => 10,
    ]);

    if (is_wp_error($response)) {
        return ['success' => false, 'error' => $response->get_error_message()];
    }

    $body = json_decode(wp_remote_retrieve_body($response), true);
    $result = ['success' => true, 'data' => $body];

    // Mettre en cache pendant 24 heures
    set_transient($cache_key, $result, DAY_IN_SECONDS);

    return $result;
}

Validation AJAX en temps réel

Ajoutez un retour instantané pendant que les clients saisissent leur e-mail.

<?php
// Mettre en file d'attente les scripts
add_action('wp_enqueue_scripts', 'emailverify_wc_scripts');

function emailverify_wc_scripts() {
    if (!is_checkout()) {
        return;
    }

    wp_enqueue_script(
        'emailverify-checkout',
        get_template_directory_uri() . '/js/emailverify-checkout.js',
        ['jquery'],
        '1.0.0',
        true
    );

    wp_localize_script('emailverify-checkout', 'bv_checkout', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('emailverify_checkout'),
    ]);
}

// Gestionnaire AJAX
add_action('wp_ajax_verify_checkout_email', 'emailverify_ajax_checkout_verify');
add_action('wp_ajax_nopriv_verify_checkout_email', 'emailverify_ajax_checkout_verify');

function emailverify_ajax_checkout_verify() {
    check_ajax_referer('emailverify_checkout', 'nonce');

    $email = sanitize_email($_POST['email'] ?? '');

    if (empty($email)) {
        wp_send_json_error(['message' => 'L\'e-mail est requis']);
    }

    $result = emailverify_verify_email($email);

    if ($result['success']) {
        wp_send_json_success($result['data']);
    } else {
        wp_send_json_error(['message' => 'La vérification a échoué']);
    }
}
// js/emailverify-checkout.js
jQuery(function($) {
    var $billingEmail = $('#billing_email');
    var verifyTimeout;
    var $status = $('<span class="bv-status"></span>');

    $billingEmail.after($status);

    $billingEmail.on('blur change', function() {
        var email = $(this).val();

        if (!email || !isValidEmailFormat(email)) {
            $status.html('').removeClass('valid invalid verifying');
            return;
        }

        clearTimeout(verifyTimeout);

        verifyTimeout = setTimeout(function() {
            verifyEmail(email);
        }, 500);
    });

    function verifyEmail(email) {
        $status.html('<span class="spinner"></span> Vérification...').addClass('verifying');

        $.ajax({
            url: bv_checkout.ajax_url,
            method: 'POST',
            data: {
                action: 'verify_checkout_email',
                nonce: bv_checkout.nonce,
                email: email
            },
            success: function(response) {
                $status.removeClass('verifying');

                if (response.success) {
                    var data = response.data;

                    if (data.status === 'valid') {
                        $status
                            .html('<span class="dashicons dashicons-yes"></span> E-mail vérifié')
                            .addClass('valid')
                            .removeClass('invalid');
                    } else if (data.status === 'invalid') {
                        $status
                            .html('<span class="dashicons dashicons-no"></span> Veuillez entrer un e-mail valide')
                            .addClass('invalid')
                            .removeClass('valid');
                    } else if (data.result && data.result.disposable) {
                        $status
                            .html('<span class="dashicons dashicons-warning"></span> Veuillez utiliser un e-mail permanent')
                            .addClass('invalid')
                            .removeClass('valid');
                    }
                }
            },
            error: function() {
                $status.html('').removeClass('verifying valid invalid');
            }
        });
    }

    function isValidEmailFormat(email) {
        return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    }
});
/* style.css */
.bv-status {
    display: block;
    margin-top: 5px;
    font-size: 13px;
}

.bv-status.verifying {
    color: #666;
}

.bv-status.valid {
    color: #28a745;
}

.bv-status.invalid {
    color: #dc3545;
}

.bv-status .spinner {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 2px solid #ccc;
    border-top-color: #333;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

Méthode 3 : Traitement des commandes

Vérifiez les e-mails après la création de la commande et stockez les résultats.

Enregistrer les données de vérification

<?php
/**
 * Vérifier l'e-mail après la création de la commande
 */
add_action('woocommerce_checkout_order_created', 'emailverify_verify_order_email');

function emailverify_verify_order_email($order) {
    $email = $order->get_billing_email();

    if (empty($email)) {
        return;
    }

    $result = emailverify_verify_email($email);

    if ($result['success']) {
        $data = $result['data'];

        // Stocker les données de vérification en tant que métadonnées de commande
        $order->update_meta_data('_email_verification_status', $data['status']);
        $order->update_meta_data('_email_verification_score', $data['score'] ?? '');
        $order->update_meta_data('_email_is_disposable', $data['result']['disposable'] ? 'yes' : 'no');
        $order->update_meta_data('_email_verified_at', current_time('mysql'));
        $order->save();

        // Ajouter une note de commande
        if ($data['status'] === 'invalid') {
            $order->add_order_note(
                sprintf(
                    __('Attention : L\'e-mail client %s a échoué à la vérification (Statut : %s)', 'your-theme'),
                    $email,
                    $data['status']
                )
            );
        }
    }
}

/**
 * Afficher le statut de vérification dans les détails de la commande
 */
add_action('woocommerce_admin_order_data_after_billing_address', 'emailverify_show_order_email_status');

function emailverify_show_order_email_status($order) {
    $status = $order->get_meta('_email_verification_status');

    if (empty($status)) {
        return;
    }

    $score = $order->get_meta('_email_verification_score');
    $disposable = $order->get_meta('_email_is_disposable');

    $status_class = $status === 'valid' ? 'status-completed' : 'status-on-hold';

    echo '<div class="email-verification-status">';
    echo '<h3>' . __('Vérification d\'e-mail', 'your-theme') . '</h3>';
    echo '<p><strong>' . __('Statut :', 'your-theme') . '</strong> ';
    echo '<mark class="order-status ' . esc_attr($status_class) . '">' . esc_html(ucfirst($status)) . '</mark></p>';

    if ($score) {
        echo '<p><strong>' . __('Score :', 'your-theme') . '</strong> ' . esc_html($score) . '</p>';
    }

    if ($disposable === 'yes') {
        echo '<p><span class="dashicons dashicons-warning" style="color: #d63638;"></span> ';
        echo __('E-mail jetable détecté', 'your-theme') . '</p>';
    }

    echo '</div>';
}

Ajouter une colonne à la liste des commandes

<?php
/**
 * Ajouter une colonne de statut d'e-mail à la liste des commandes
 */
add_filter('manage_edit-shop_order_columns', 'emailverify_orders_column');

function emailverify_orders_column($columns) {
    $new_columns = [];

    foreach ($columns as $key => $value) {
        $new_columns[$key] = $value;

        if ($key === 'order_status') {
            $new_columns['email_status'] = __('E-mail', 'your-theme');
        }
    }

    return $new_columns;
}

add_action('manage_shop_order_posts_custom_column', 'emailverify_orders_column_content', 10, 2);

function emailverify_orders_column_content($column, $post_id) {
    if ($column !== 'email_status') {
        return;
    }

    $order = wc_get_order($post_id);
    $status = $order->get_meta('_email_verification_status');

    if (empty($status)) {
        echo '<span class="dashicons dashicons-minus" title="Non vérifié"></span>';
        return;
    }

    if ($status === 'valid') {
        echo '<span class="dashicons dashicons-yes-alt" style="color: #28a745;" title="Valide"></span>';
    } else {
        echo '<span class="dashicons dashicons-dismiss" style="color: #dc3545;" title="Invalide"></span>';
    }

    $disposable = $order->get_meta('_email_is_disposable');
    if ($disposable === 'yes') {
        echo '<span class="dashicons dashicons-warning" style="color: #d63638;" title="Jetable"></span>';
    }
}

Méthode 4 : Intégration REST API

Pour WooCommerce headless ou des flux de paiement personnalisés.

Point de terminaison REST personnalisé

<?php
/**
 * Enregistrer un point de terminaison REST API pour la vérification d'e-mail
 */
add_action('rest_api_init', 'emailverify_register_wc_endpoint');

function emailverify_register_wc_endpoint() {
    register_rest_route('emailverify/v1', '/verify-checkout', [
        'methods' => 'POST',
        'callback' => 'emailverify_rest_verify_checkout',
        'permission_callback' => '__return_true',
        'args' => [
            'email' => [
                'required' => true,
                'type' => 'string',
                'format' => 'email',
                'sanitize_callback' => 'sanitize_email',
            ],
        ],
    ]);
}

function emailverify_rest_verify_checkout($request) {
    $email = $request->get_param('email');

    // Limitation du débit
    $ip = $_SERVER['REMOTE_ADDR'];
    $rate_key = 'bv_rate_' . md5($ip);
    $rate_count = get_transient($rate_key) ?: 0;

    if ($rate_count >= 20) {
        return new WP_Error(
            'rate_limited',
            'Trop de demandes de vérification',
            ['status' => 429]
        );
    }

    set_transient($rate_key, $rate_count + 1, MINUTE_IN_SECONDS);

    // Vérifier l'e-mail
    $result = emailverify_verify_email($email);

    if (!$result['success']) {
        return new WP_Error(
            'verification_failed',
            'La vérification d\'e-mail a échoué',
            ['status' => 503]
        );
    }

    $data = $result['data'];

    return new WP_REST_Response([
        'valid' => $data['status'] === 'valid',
        'status' => $data['status'],
        'disposable' => $data['result']['disposable'] ?? false,
        'score' => $data['score'] ?? null,
    ], 200);
}

Utilisation côté frontend

// Vérification de paiement headless
async function verifyCheckoutEmail(email) {
    const response = await fetch('/wp-json/emailverify/v1/verify-checkout', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email }),
    });

    if (!response.ok) {
        if (response.status === 429) {
            throw new Error('Trop de requêtes. Veuillez patienter.');
        }
        throw new Error('La vérification a échoué');
    }

    return response.json();
}

// Utilisation
try {
    const result = await verifyCheckoutEmail('customer@example.com');

    if (!result.valid) {
        showError('Veuillez entrer une adresse e-mail valide');
    } else if (result.disposable) {
        showError('Veuillez utiliser une adresse e-mail permanente');
    } else {
        proceedToPayment();
    }
} catch (error) {
    // Autoriser le paiement en cas d'erreur
    proceedToPayment();
}

Vérification groupée des clients

Vérifiez les clients existants dans votre base de données.

Commande WP-CLI

<?php
/**
 * Commande WP-CLI pour la vérification groupée des clients
 */
if (defined('WP_CLI') && WP_CLI) {
    WP_CLI::add_command('emailverify verify-customers', function($args, $assoc_args) {
        $batch_size = $assoc_args['batch'] ?? 100;
        $dry_run = isset($assoc_args['dry-run']);

        global $wpdb;

        // Obtenir les clients sans statut de vérification
        $customers = $wpdb->get_results("
            SELECT DISTINCT pm.meta_value as email, pm.post_id as order_id
            FROM {$wpdb->postmeta} pm
            LEFT JOIN {$wpdb->postmeta} pm2 ON pm.post_id = pm2.post_id
                AND pm2.meta_key = '_email_verification_status'
            WHERE pm.meta_key = '_billing_email'
            AND pm.meta_value != ''
            AND pm2.meta_id IS NULL
            LIMIT {$batch_size}
        ");

        if (empty($customers)) {
            WP_CLI::success('Tous les clients sont vérifiés !');
            return;
        }

        WP_CLI::log(sprintf('%d clients trouvés à vérifier', count($customers)));

        $progress = \WP_CLI\Utils\make_progress_bar('Vérification', count($customers));

        $stats = ['valid' => 0, 'invalid' => 0, 'error' => 0];

        foreach ($customers as $customer) {
            $result = emailverify_verify_email($customer->email);

            if ($result['success']) {
                $status = $result['data']['status'];
                $stats[$status === 'valid' ? 'valid' : 'invalid']++;

                if (!$dry_run) {
                    update_post_meta($customer->order_id, '_email_verification_status', $result['data']['status']);
                    update_post_meta($customer->order_id, '_email_verification_score', $result['data']['score'] ?? '');
                }
            } else {
                $stats['error']++;
            }

            $progress->tick();

            // Limitation du débit
            usleep(100000); // délai de 100ms
        }

        $progress->finish();

        WP_CLI::success(sprintf(
            'Vérification terminée : %d valides, %d invalides, %d erreurs',
            $stats['valid'],
            $stats['invalid'],
            $stats['error']
        ));
    });
}

Utilisation

# Vérifier 100 clients (par défaut)
wp emailverify verify-customers

# Vérifier 500 clients
wp emailverify verify-customers --batch=500

# Exécution à blanc (aucune modification de la base de données)
wp emailverify verify-customers --dry-run

Prévention de la fraude

Utilisez la vérification d'e-mails dans le cadre de la détection de fraude.

<?php
/**
 * Marquer les commandes à haut risque en fonction de la vérification d'e-mail
 */
add_action('woocommerce_checkout_order_processed', 'emailverify_fraud_check', 10, 3);

function emailverify_fraud_check($order_id, $posted_data, $order) {
    $risk_score = 0;
    $risk_reasons = [];

    $email = $order->get_billing_email();
    $result = emailverify_verify_email($email);

    if ($result['success']) {
        $data = $result['data'];

        // E-mail invalide = risque élevé
        if ($data['status'] === 'invalid') {
            $risk_score += 50;
            $risk_reasons[] = 'Adresse e-mail invalide';
        }

        // E-mail jetable = risque élevé
        if ($data['result']['disposable'] ?? false) {
            $risk_score += 40;
            $risk_reasons[] = 'E-mail jetable détecté';
        }

        // Score faible = risque moyen
        if (($data['score'] ?? 1) < 0.5) {
            $risk_score += 20;
            $risk_reasons[] = 'Score d\'e-mail faible';
        }

        // E-mail de rôle = risque léger
        if ($data['result']['role'] ?? false) {
            $risk_score += 10;
            $risk_reasons[] = 'Adresse e-mail de rôle';
        }
    }

    // Stocker l'évaluation du risque
    $order->update_meta_data('_fraud_risk_score', $risk_score);
    $order->update_meta_data('_fraud_risk_reasons', $risk_reasons);

    // Marquer les commandes à haut risque pour examen manuel
    if ($risk_score >= 50) {
        $order->set_status('on-hold', __('Risque de fraude élevé - examen manuel requis', 'your-theme'));

        // Notifier l'administrateur
        $admin_email = get_option('admin_email');
        wp_mail(
            $admin_email,
            sprintf(__('La commande à haut risque #%s nécessite un examen', 'your-theme'), $order_id),
            sprintf(
                __("La commande #%s a été marquée comme à haut risque.\n\nScore de risque : %d\nRaisons :\n- %s\n\nVeuillez examiner la commande.", 'your-theme'),
                $order_id,
                $risk_score,
                implode("\n- ", $risk_reasons)
            )
        );
    }

    $order->save();
}

Bonnes pratiques

1. Dégradation gracieuse

// Toujours autoriser le paiement si l'API échoue
$result = emailverify_verify_email($email);

if (!$result['success']) {
    error_log('Erreur API EmailVerify : ' . ($result['error'] ?? 'Inconnue'));
    return; // Ne pas bloquer le paiement
}

2. Mise en cache des résultats

// Mettre en cache les résultats de vérification pour réduire les appels API
$cache_key = 'bv_email_' . md5($email);
$cached = get_transient($cache_key);

if ($cached !== false) {
    return $cached;
}

// ... effectuer l'appel API ...

set_transient($cache_key, $result, DAY_IN_SECONDS);

3. Messages d'erreur clairs

// Fournir des messages d'erreur utiles et non techniques
$messages = [
    'invalid' => __('Cette adresse e-mail semble être invalide. Veuillez vérifier et réessayer.', 'your-theme'),
    'disposable' => __('Les adresses e-mail temporaires ne peuvent pas être utilisées pour les commandes. Veuillez utiliser votre e-mail habituel.', 'your-theme'),
];

Ressources connexes

On this page