You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Woocommerce优惠券页面添加JS邮件按钮遇400错误请求求助

WooCommerce优惠券邮件发送按钮400错误修复方案

核心问题与修正点

  • 缺少AJAX动作注册:WordPress的AJAX请求必须通过add_action绑定处理函数,原代码未注册send_coupon_email,导致系统无法识别该动作,返回400错误。
  • AJAX场景下错误提示无效:add_settings_error仅适用于WordPress设置页面的同步提示,在异步AJAX请求中无法生效,需改用JSON返回结果。
  • 未处理空值场景:未判断优惠券是否绑定customer_id元数据,若为空会直接触发后续邮箱验证失败逻辑。

修正后的完整代码

// 添加 metabox
function add_coupon_email_meta_box() {
  add_meta_box( 'coupon-email', __( 'Send Email', 'woocommerce' ), 'coupon_email_meta_box_callback', 'shop_coupon', 'side' );
}
add_action( 'add_meta_boxes', 'add_coupon_email_meta_box' );

// Metabox 回调函数
function coupon_email_meta_box_callback( $post ) {
  ?>
  <form>
      <input type="hidden" name="coupon-id" value="<?= $post->ID ?>" />
      <input type="hidden" name="security" value="<?= wp_create_nonce( 'coupon_email_nonce' ); ?>" />
      <input type="button" id="send-coupon-email" class="button button-primary" value="<?= __( 'Send Email', 'woocommerce' ); ?>" />
  </form>

  <script>
    jQuery(document).ready(function($) {
        $('#send-coupon-email').on('click', function(e) {
            e.preventDefault();
            var couponId = $('input[name="coupon-id"]').val();
            var security = $('input[name="security"]').val();
            $.ajax({
                type: 'POST',
                url: ajaxurl,
                data: {
                    action: 'send_coupon_email',
                    coupon_id: couponId,
                    security: security
                },
                success: function(response) {
                    if (response.success) {
                        alert(response.data.message);
                    } else {
                        alert('Error: ' + response.data.message);
                    }
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    console.log(XMLHttpRequest);
                    console.log(textStatus);
                    console.log(errorThrown);
                    alert('请求失败,请检查控制台信息');
                }
            });
        });
    });
  </script>
  <?php
}

// 注册AJAX动作(后台专用)
add_action('wp_ajax_send_coupon_email', 'send_coupon_email');

// 发送优惠券邮件逻辑
function send_coupon_email() {
    // 验证nonce
    check_ajax_referer( 'coupon_email_nonce', 'security' );
    
    // 获取优惠券ID
    $coupon_id = intval( $_POST['coupon_id'] );
    
    // 验证优惠券是否存在
    $coupon = new WC_Coupon( $coupon_id );
    if ( ! $coupon->get_id() ) {
        wp_send_json_error( array('message' => __( '优惠券不存在。', 'woocommerce' )) );
    }
    
    // 获取绑定的用户ID
    $customer_id = $coupon->get_meta( 'customer_id' );
    
    // 检查用户ID是否为空
    if ( empty($customer_id) ) {
        wp_send_json_error( array('message' => __( '该优惠券未绑定任何用户。', 'woocommerce' )) );
    }
    
    // 获取用户邮箱
    $customer = get_user_by( 'id', $customer_id );
    $customer_email = $customer ? $customer->user_email : '';
    
    // 验证邮箱有效性
    if ( ! is_email( $customer_email ) ) {
        wp_send_json_error( array('message' => __( '无效的邮箱地址。', 'woocommerce' )) );
    }
    
    // 准备邮件内容
    $to = $customer_email;
    $subject = __( '您的优惠券信息', 'woocommerce' );
    $message = $coupon->get_description();
    $headers = array( 'Content-Type: text/html; charset=UTF-8' );
    
    // 发送邮件并返回结果
    if ( wp_mail( $to, $subject, $message, $headers ) ) {
        wp_send_json_success( array('message' => __( '邮件发送成功。', 'woocommerce' )) );
    } else {
        wp_send_json_error( array('message' => __( '邮件发送失败。', 'woocommerce' )) );
    }
}

关键修改说明

  1. 注册AJAX动作:新增add_action('wp_ajax_send_coupon_email', 'send_coupon_email');,让WordPress识别该AJAX请求的处理函数。
  2. 优化错误反馈:用wp_send_json_success和wp_send_json_error返回带提示信息的JSON数据,前端通过弹窗展示结果。
  3. 增加空值校验:在获取customer_id后立即检查是否为空,提前终止无效流程。
  4. 强化安全验证:移除check_ajax_referer的第三个参数,默认验证失败时直接返回403错误,符合WordPress安全规范。

内容的提问来源于stack exchange,提问作者Zealot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 01:24:29