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éthode | Idéal pour | Complexité |
|---|---|---|
| Plugin | Configuration rapide | Faible |
| Hook de paiement | Vérification en temps réel | Moyenne |
| Traitement des commandes | Vérification en arrière-plan | Moyenne |
| REST API | Solutions 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
- Allez dans Réglages → EmailVerify
- Cochez Activer l'intégration WooCommerce
- 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-runPré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'),
];