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

Woocommerce后台订单页自定义表单邮件发送失败求助

Hey there! Let's fix your WooCommerce admin order form issue step by step. The main problems with your current code are incorrect hook usage, missing security checks, and not integrating properly with WooCommerce's admin page flow. Here's the revised solution that will make your form show only on order detail pages and send emails correctly:

What Was Wrong With Your Original Code?

  • Incorrect Hook: dbx_post_sidebar is designed for regular posts/pages, not WooCommerce order (custom post type shop_order) admin pages. This means your form wasn't targeting the right location.
  • No Security Validation: Missing nonce fields left your form open to CSRF attacks, and WordPress might have blocked the submission silently.
  • Submission Conflict: Using the current order page URI as the form action triggered WooCommerce's order update process instead of your email-sending logic.
  • Unattached Logic: Your deliver_mail() function wasn't hooked to any admin action, so it never ran when the form was submitted.

Fixed Complete Code

// Add custom form to WooCommerce admin order detail page
add_action( 'woocommerce_admin_order_data_after_order_details', 'display_custom_order_form' );
function display_custom_order_form( $order ) {
    // Only show form to users with order editing permissions
    if ( ! current_user_can( 'edit_shop_orders' ) ) {
        return;
    }

    echo '<div class="custom-order-form" style="margin-top:20px;padding:15px;border:1px solid #eee;">';
    echo '<h3>' . __( 'Send Custom Email', 'text-domain' ) . '</h3>';
    // Use WordPress admin_post endpoint for secure submission
    echo '<form action="' . esc_url( admin_url( 'admin-post.php' ) ) . '" method="post">';

    // Security nonce to validate legitimate requests
    wp_nonce_field( 'custom_order_email_nonce', 'custom_order_email_nonce_field' );
    // Action parameter to trigger our submission handler
    echo '<input type="hidden" name="action" value="send_custom_order_email">';
    // Pass order ID to include order context in email (optional)
    echo '<input type="hidden" name="order_id" value="' . esc_attr( $order->get_id() ) . '">';

    // Name field
    echo '<p>';
    echo __( 'Your Name (required)', 'text-domain' ) . '<br>';
    echo '<input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="' . ( isset( $_POST["cf-name"] ) ? esc_attr( $_POST["cf-name"] ) : '' ) . '" size="40" required>';
    echo '</p>';

    // Email field
    echo '<p>';
    echo __( 'Your Email (required)', 'text-domain' ) . '<br>';
    echo '<input type="email" name="cf-email" value="' . ( isset( $_POST["cf-email"] ) ? esc_attr( $_POST["cf-email"] ) : '' ) . '" size="40" required>';
    echo '</p>';

    // Subject field
    echo '<p>';
    echo __( 'Subject (required)', 'text-domain' ) . '<br>';
    echo '<input type="text" name="cf-subject" pattern="[a-zA-Z ]+" value="' . ( isset( $_POST["cf-subject"] ) ? esc_attr( $_POST["cf-subject"] ) : '' ) . '" size="40" required>';
    echo '</p>';

    // Message field
    echo '<p>';
    echo __( 'Your Message (required)', 'text-domain' ) . '<br>';
    echo '<textarea rows="10" cols="35" name="cf-message" required>' . ( isset( $_POST["cf-message"] ) ? esc_textarea( $_POST["cf-message"] ) : '' ) . '</textarea>';
    echo '</p>';

    echo '<p><input type="submit" name="cf-submitted" value="' . __( 'Send', 'text-domain' ) . '" class="button button-primary"></p>';
    echo '</form>';
    echo '</div>';
}

// Handle form submission and send email
add_action( 'admin_post_send_custom_order_email', 'handle_custom_order_email_submission' );
function handle_custom_order_email_submission() {
    // Block unauthorized users
    if ( ! current_user_can( 'edit_shop_orders' ) ) {
        wp_die( __( 'You do not have permission to perform this action.', 'text-domain' ) );
    }

    // Validate security nonce
    if ( ! isset( $_POST['custom_order_email_nonce_field'] ) || ! wp_verify_nonce( $_POST['custom_order_email_nonce_field'], 'custom_order_email_nonce' ) ) {
        wp_die( __( 'Invalid security token. Please try again.', 'text-domain' ) );
    }

    // Sanitize and validate form data
    $name = isset( $_POST['cf-name'] ) ? sanitize_text_field( $_POST['cf-name'] ) : '';
    $email = isset( $_POST['cf-email'] ) ? sanitize_email( $_POST['cf-email'] ) : '';
    $subject = isset( $_POST['cf-subject'] ) ? sanitize_text_field( $_POST['cf-subject'] ) : '';
    $message = isset( $_POST['cf-message'] ) ? esc_textarea( $_POST['cf-message'] ) : '';
    $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;

    // Check for required fields and valid email
    if ( empty( $name ) || empty( $email ) || empty( $subject ) || empty( $message ) || ! is_email( $email ) ) {
        wp_redirect( add_query_arg( 'custom_email_error', 'invalid_fields', wp_get_referer() ) );
        exit;
    }

    // Get target email (default to admin, change to your desired address if needed)
    $to = get_option( 'admin_email' );
    // Optional: Add order details to the email for context
    $order = wc_get_order( $order_id );
    if ( $order ) {
        $message .= "\n\n--- Order Details ---\n";
        $message .= "Order ID: " . $order->get_id() . "\n";
        $message .= "Order Status: " . wc_get_order_status_name( $order->get_status() ) . "\n";
        $message .= "Customer: " . $order->get_billing_first_name() . " " . $order->get_billing_last_name() . "\n";
    }

    // Set proper email headers
    $headers = array(
        'From: ' . $name . ' <' . $email . '>',
        'Content-Type: text/plain; charset=UTF-8'
    );

    // Send email and redirect with status
    if ( wp_mail( $to, $subject, $message, $headers ) ) {
        wp_redirect( add_query_arg( 'custom_email_success', '1', wp_get_referer() ) );
    } else {
        wp_redirect( add_query_arg( 'custom_email_error', 'send_failed', wp_get_referer() ) );
    }
    exit;
}

// Show admin notices for submission status
add_action( 'admin_notices', 'custom_order_email_notices' );
function custom_order_email_notices() {
    // Success notice
    if ( isset( $_GET['custom_email_success'] ) && $_GET['custom_email_success'] == '1' ) {
        echo '<div class="notice notice-success is-dismissible">';
        echo '<p>' . __( 'Email sent successfully!', 'text-domain' ) . '</p>';
        echo '</div>';
    }

    // Error notices
    if ( isset( $_GET['custom_email_error'] ) ) {
        $error_code = $_GET['custom_email_error'];
        switch ( $error_code ) {
            case 'invalid_fields':
                $message = __( 'Please fill in all required fields correctly.', 'text-domain' );
                break;
            case 'send_failed':
                $message = __( 'Failed to send email. Please check your WordPress email settings (try using an SMTP plugin if needed).', 'text-domain' );
                break;
            default:
                $message = __( 'An unexpected error occurred. Please try again.', 'text-domain' );
        }
        echo '<div class="notice notice-error is-dismissible">';
        echo '<p>' . $message . '</p>';
        echo '</div>';
    }
}

Key Improvements Explained:

  • Targeted Hook: Uses woocommerce_admin_order_data_after_order_details to ensure the form only appears on WooCommerce admin order detail pages.
  • Secure Submission: Integrates WordPress's admin_post system with nonce validation to prevent malicious requests.
  • Permission Checks: Restricts form access to users who can edit orders, keeping your admin area secure.
  • Seamless UI Feedback: Uses WordPress admin notices instead of raw echo statements, matching WooCommerce's native admin experience.
  • Order Context: Includes the order ID in the form, so you can add relevant order details to the email (optional but highly useful).
  • Robust Validation: Combines HTML5 required attributes and server-side checks to ensure all form data is valid before sending.

Troubleshooting Tips:

  1. If emails still don't arrive, test your WordPress email setup with a plugin like WP Mail SMTP (many hosts block default PHP mail).
  2. Verify the form appears: Navigate to any order detail page in WooCommerce admin—you'll see it below the core order details section.
  3. Check admin notices: Any submission issues will show a clear, actionable error message at the top of the page.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:53:35