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

为何WooCommerce钩子在COD订单中返回数据库结果为Null?

问题描述

我们在订单流程中收集客户的非商品相关信息并存储在数据库表中,随后将这些数据提取并添加到管理员新订单邮件中,正常情况下邮件会显示:

Location: Hospital
County:   Los Angeles
Delivery: Pickup

使用的钩子代码如下:

add_action( 'woocommerce_email_order_meta', 'add_email_order_meta', 10, 3 );

function add_email_order_meta( $order_obj, $sent_to_admin, $plain_text ){
    global $wpdb;
    $order_id = $order_obj->get_order_number();

    $result = $wpdb->get_row( "SELECT * FROM cl_order_meta 
              WHERE order_id = " . $order_id, OBJECT );

    if ($sent_to_admin) {
        echo '
        <ul>
        <li><strong>Location:</strong> ' . $result->location. '</li>
        <li><strong>County:</strong> ' . $result->county. '</li>
        <li><strong>Delivery:</strong> ' . $result->delivery. '</li>
        </ul>';
    } 
}

该功能在信用卡订单中运行正常,但货到付款(COD)订单中无数据显示,邮件中仅显示:

Location:
County:  
Delivery:

已确认数据已存在于数据库中,邮件可正常接收但无元数据。在邮件中输出的Order ID正确,输出json_encode($result)显示为Null,说明查询未返回结果。尝试在查询前添加sleep(5),推测可能是数据库写入延迟,但无效果。

已确认钩子已触发,因为邮件中有标签和正确的Order ID,但查询数据未显示。

Apache错误日志信息:

AH01071: Got error 'PHP message: The WC_Product::get_parent function is deprecated 
since version 3.0. Replace with WC_Product::get_parent_id.PHP message: The 
WC_Product::get_post_data function is deprecated since version 3.0. Replace with 
get_post.

PHP message: The WC_Product::get_post_data function is deprecated since version 3.0. 
Replace with get_post.

PHP message: The WC_Product::get_parent function is deprecated since version 3.0. 
Replace with WC_Product::get_parent_id.

PHP message: The WC_Product::get_post_data function is deprecated since version 3.0. 
Replace with get_post.

PHP message: The WC_Product::get_parent function is deprecated since version 3.0. 
Replace with WC_Product::get_parent_id.

PHP message: The WC_Product::get_post_data function is deprecated since version 3.0. 
Replace with get_post.

PHP message: woocommerce_add_order_item_meta is deprecated since version 3.0.0! Use 
woocommerce_new_order_item instead.

PHP message: woocommerce_add_order_item_meta is deprecated since version 3.0.0! Use 
woocommerce_new_order_item instead.

PHP message: woocommerce_add_order_item_meta is deprecated since version 3.0.0! Use 
woocommerce_new_order_item instead.

PHP message: woocommerce_add_order_item_meta is deprecated since version 3.0.0! Use 
woocommerce_new_order_item instead.

PHP message: woocommerce_add_order_item_meta is deprecated since version 3.0.0! Use 
woocommerce_new_order_item instead.', referer: https://example.com/checkout/

数据库插入代码:

add_action('wp_ajax_cl_add_session_vars_to_db', 
'add_session_vars_to_db');

function add_session_vars_to_db() {
    global $wpdb;

    $order_id = $_POST['order_id'];
    $wpdb->insert('cl_order_meta', 
        array(
          'order_id' => $order_id,
          'location' => isset($_SESSION['location']) ? $_SESSION['location'] : 'N/A',
          'county' => isset($_SESSION['county']) ? $_SESSION['county'] : 'N/A',
          'delivery' => isset($_SESSION['delivery']) ? $_SESSION['delivery'] : 'Pickup',
          'create_date' => time()
    )); 
}
问题原因及解决方案

核心原因

  1. 订单ID类型不匹配:
    信用卡订单中,$order_obj->get_order_number()返回的是订单的纯数字原始ID,和数据库中存储的order_id一致;但COD订单里,WooCommerce可能会生成带前缀的格式化订单号(比如WC-123),此时get_order_number()返回的是带前缀的字符串,而非数据库中存储的纯数字ID,导致查询无法匹配到数据。

  2. (次要排查点)插入时机问题:
    虽然你确认数据已写入数据库,但需确认COD订单的邮件触发时机是否早于wp_ajax_cl_add_session_vars_to_db的执行时机,不过这条可能性较低。

验证方式

在邮件钩子中添加调试代码,对比两种订单类型的ID差异:

function add_email_order_meta( $order_obj, $sent_to_admin, $plain_text ){
    global $wpdb;
    $order_number = $order_obj->get_order_number();
    $order_raw_id = $order_obj->get_id(); // 获取原始数字ID

    // 调试输出,可在邮件中查看
    echo "格式化订单号: {$order_number}<br>";
    echo "原始数字ID: {$order_raw_id}<br>";

    $result = $wpdb->get_row( "SELECT * FROM cl_order_meta WHERE order_id = " . $order_raw_id, OBJECT );
    // ... 其余代码不变
}

解决办法

将查询时使用的订单ID替换为$order_obj->get_id()(WooCommerce订单的原始数字ID),同时优化代码安全性:
修改后的钩子代码:

add_action( 'woocommerce_email_order_meta', 'add_email_order_meta', 10, 3 );

function add_email_order_meta( $order_obj, $sent_to_admin, $plain_text ){
    global $wpdb;
    $order_id = $order_obj->get_id(); // 使用原始数字ID

    // 使用prepare防止SQL注入
    $result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM cl_order_meta WHERE order_id = %d", $order_id ), OBJECT );

    // 增加非空判断,避免查询失败时邮件报错
    if ($sent_to_admin && $result) { 
        echo '
        <ul>
        <li><strong>Location:</strong> ' . esc_html($result->location) . '</li>
        <li><strong>County:</strong> ' . esc_html($result->county) . '</li>
        <li><strong>Delivery:</strong> ' . esc_html($result->delivery) . '</li>
        </ul>';
    } 
}

额外检查:确认数据库插入代码中$_POST['order_id']传入的是原始数字ID,确保插入和查询使用的ID类型完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:32:14