EmailVerify LogoEmailVerify

WooCommerce

Email checker for WooCommerce. Verify emails at checkout and in WordPress forms.

将电子邮件验证添加到您的 WooCommerce 商店,以减少投递失败、防止欺诈并改善客户沟通。

集成方式

方式最佳用途复杂度
插件快速设置
结账钩子实时验证中等
订单处理后台验证中等
REST API自定义解决方案

方式 1:WordPress 插件

如果您已经设置了 EmailVerify WordPress 插件,WooCommerce 集成是自动的。

启用 WooCommerce 支持

  1. 转到 设置EmailVerify
  2. 检查 启用 WooCommerce 集成
  3. 配置选项:
    • ✓ 在结账时验证
    • ✓ 阻止一次性电子邮件
    • ✓ 在订单中显示验证状态

方式 2:结账验证

将电子邮件验证添加到 WooCommerce 结账流程。

服务器端验证

<?php
// functions.php 或自定义插件

/**
 * 在 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']) {
        // API 错误 - 允许结账继续进行
        return;
    }

    $data = $result['data'];

    // 阻止无效的电子邮件
    if ($data['status'] === 'invalid') {
        wc_add_notice(
            __('请输入有效的电子邮件地址以完成您的订单。', 'your-theme'),
            'error'
        );
    }

    // 阻止一次性电子邮件(可选)
    if (get_option('emailverify_block_disposable', true)) {
        if ($data['result']['disposable'] ?? false) {
            wc_add_notice(
                __('不接受临时电子邮件地址。请使用永久电子邮件。', 'your-theme'),
                'error'
            );
        }
    }
}

/**
 * EmailVerify API 调用帮助函数
 */
function emailverify_verify_email($email) {
    $api_key = get_option('emailverify_api_key');

    // 先检查缓存
    $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];

    // 缓存 24 小时
    set_transient($cache_key, $result, DAY_IN_SECONDS);

    return $result;
}

实时 AJAX 验证

当客户输入电子邮件时提供即时反馈。

<?php
// 入队脚本
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'),
    ]);
}

// 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' => '电子邮件是必需的']);
    }

    $result = emailverify_verify_email($email);

    if ($result['success']) {
        wp_send_json_success($result['data']);
    } else {
        wp_send_json_error(['message' => '验证失败']);
    }
}
// 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> 验证中...').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> 电子邮件已验证')
                            .addClass('valid')
                            .removeClass('invalid');
                    } else if (data.status === 'invalid') {
                        $status
                            .html('<span class="dashicons dashicons-no"></span> 请输入有效的电子邮件')
                            .addClass('invalid')
                            .removeClass('valid');
                    } else if (data.result && data.result.disposable) {
                        $status
                            .html('<span class="dashicons dashicons-warning"></span> 请使用永久电子邮件')
                            .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); }
}

方式 3:订单处理

在订单放置后验证电子邮件并存储结果。

保存验证数据

<?php
/**
 * 在创建订单后验证电子邮件
 */
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'];

        // 将验证数据存储为订单元数据
        $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();

        // 添加订单备注
        if ($data['status'] === 'invalid') {
            $order->add_order_note(
                sprintf(
                    __('警告:客户电子邮件 %s 验证失败(状态:%s)', 'your-theme'),
                    $email,
                    $data['status']
                )
            );
        }
    }
}

/**
 * 在订单详情中显示验证状态
 */
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>' . __('电子邮件验证', 'your-theme') . '</h3>';
    echo '<p><strong>' . __('状态:', 'your-theme') . '</strong> ';
    echo '<mark class="order-status ' . esc_attr($status_class) . '">' . esc_html(ucfirst($status)) . '</mark></p>';

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

    if ($disposable === 'yes') {
        echo '<p><span class="dashicons dashicons-warning" style="color: #d63638;"></span> ';
        echo __('检测到一次性电子邮件', 'your-theme') . '</p>';
    }

    echo '</div>';
}

添加订单列表列

<?php
/**
 * 将电子邮件状态列添加到订单列表
 */
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'] = __('电子邮件', '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="未验证"></span>';
        return;
    }

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

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

方式 4:REST API 集成

用于无头 WooCommerce 或自定义结账流程。

自定义 REST 端点

<?php
/**
 * 注册用于电子邮件验证的 REST API 端点
 */
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');

    // 速率限制
    $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',
            '验证请求过多',
            ['status' => 429]
        );
    }

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

    // 验证电子邮件
    $result = emailverify_verify_email($email);

    if (!$result['success']) {
        return new WP_Error(
            'verification_failed',
            '电子邮件验证失败',
            ['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);
}

前端使用

// 无头结账验证
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('请求过多。请稍候。');
        }
        throw new Error('验证失败');
    }

    return response.json();
}

// 使用方法
try {
    const result = await verifyCheckoutEmail('customer@example.com');

    if (!result.valid) {
        showError('请输入有效的电子邮件地址');
    } else if (result.disposable) {
        showError('请使用永久电子邮件地址');
    } else {
        proceedToPayment();
    }
} catch (error) {
    // 出错时允许结账
    proceedToPayment();
}

批量客户验证

验证数据库中现有的客户。

WP-CLI 命令

<?php
/**
 * 用于批量客户验证的 WP-CLI 命令
 */
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;

        // 获取没有验证状态的客户
        $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('所有客户都已验证!');
            return;
        }

        WP_CLI::log(sprintf('发现 %d 个客户待验证', count($customers)));

        $progress = \WP_CLI\Utils\make_progress_bar('验证中', 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();

            // 速率限制
            usleep(100000); // 100ms 延迟
        }

        $progress->finish();

        WP_CLI::success(sprintf(
            '验证完成:%d 个有效,%d 个无效,%d 个错误',
            $stats['valid'],
            $stats['invalid'],
            $stats['error']
        ));
    });
}

使用方法

# 验证 100 个客户(默认)
wp emailverify verify-customers

# 验证 500 个客户
wp emailverify verify-customers --batch=500

# 演练运行(无数据库更改)
wp emailverify verify-customers --dry-run

欺诈防预

将电子邮件验证用作欺诈检测的一部分。

<?php
/**
 * 根据电子邮件验证标记高风险订单
 */
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'];

        // 无效的电子邮件 = 高风险
        if ($data['status'] === 'invalid') {
            $risk_score += 50;
            $risk_reasons[] = '无效的电子邮件地址';
        }

        // 一次性电子邮件 = 高风险
        if ($data['result']['disposable'] ?? false) {
            $risk_score += 40;
            $risk_reasons[] = '检测到一次性电子邮件';
        }

        // 低分数 = 中等风险
        if (($data['score'] ?? 1) < 0.5) {
            $risk_score += 20;
            $risk_reasons[] = '低电子邮件分数';
        }

        // 基于角色的电子邮件 = 轻微风险
        if ($data['result']['role'] ?? false) {
            $risk_score += 10;
            $risk_reasons[] = '基于角色的电子邮件地址';
        }
    }

    // 存储风险评估
    $order->update_meta_data('_fraud_risk_score', $risk_score);
    $order->update_meta_data('_fraud_risk_reasons', $risk_reasons);

    // 标记高风险订单以供手动审查
    if ($risk_score >= 50) {
        $order->set_status('on-hold', __('高欺诈风险 - 需要手动审查', 'your-theme'));

        // 通知管理员
        $admin_email = get_option('admin_email');
        wp_mail(
            $admin_email,
            sprintf(__('高风险订单 #%s 需要审查', 'your-theme'), $order_id),
            sprintf(
                __("订单 #%s 已被标记为高风险。\n\n风险分数:%d\n原因:\n- %s\n\n请审查该订单。", 'your-theme'),
                $order_id,
                $risk_score,
                implode("\n- ", $risk_reasons)
            )
        );
    }

    $order->save();
}

最佳实践

1. 优雅降级

// 如果 API 失败,始终允许结账
$result = emailverify_verify_email($email);

if (!$result['success']) {
    error_log('EmailVerify API 错误:' . ($result['error'] ?? '未知'));
    return; // 不要阻止结账
}

2. 缓存结果

// 缓存验证结果以减少 API 调用
$cache_key = 'bv_email_' . md5($email);
$cached = get_transient($cache_key);

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

// ... 进行 API 调用 ...

set_transient($cache_key, $result, DAY_IN_SECONDS);

3. 清晰的错误消息

// 提供有帮助的、非技术性的错误消息
$messages = [
    'invalid' => __('此电子邮件地址似乎无效。请检查并重试。', 'your-theme'),
    'disposable' => __('临时电子邮件地址不能用于订单。请使用您的常规电子邮件。', 'your-theme'),
];

相关资源

On this page