如何在WooCommerce订单保存及发通知前将订单ID添加至订单项元数据
解决方案
你遇到的核心问题是 woocommerce_checkout_create_order_line_item 钩子触发时,订单还未被写入数据库,此时调用$order->get_id()无法获取到有效订单ID,因此无法生成正确的带参数访问链接。
你可以通过「拆分元数据写入逻辑」的方式实现需求,整个流程完全可以在订单保存后、客户通知邮件发送前完成:
第一步:修改原有钩子逻辑,仅写入无需订单ID的元数据
保留原有钩子,只写入固定的测试ID和生成的密码,暂时不生成访问链接:
add_action( 'woocommerce_checkout_create_order_line_item', 'custom_checkout_create_order_line_item', 20, 4 ); function custom_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) { if( ! isset( $values['test_title'] ) || empty( $values['test_title'] ) ) { return; } $test_pw = wp_generate_password(); $item->update_meta_data( '_test_id', $values['test_id'] ); $item->update_meta_data( '_test_password', $test_pw ); }
第二步:新增钩子补全访问链接
使用 woocommerce_checkout_order_created 钩子,该钩子触发时订单已完成数据库写入(已存在有效订单ID),且还未发送任何客户通知邮件,刚好满足你的需求:
add_action( 'woocommerce_checkout_order_created', 'add_access_link_to_order_items', 10, 1 ); function add_access_link_to_order_items( $order ) { // 遍历订单所有商品项 foreach ( $order->get_items() as $item ) { $test_id = $item->get_meta( '_test_id', true ); $test_pw = $item->get_meta( '_test_password', true ); // 仅给包含测试信息的商品项补加访问链接 if ( $test_id && $test_pw ) { $access_link = get_permalink( $test_id ) . '?order=' . $order->get_id() . '&pw=' . $test_pw; $item->update_meta_data( 'Access link', $access_link ); $item->save(); } } // 保存订单修改 $order->save(); }
说明
- 你之前用下划线开头命名的
_test_id和_test_password属于隐藏元数据,不会在前端订单页、邮件中展示给客户,仅用于后台逻辑判断 - 该方案兼容WooCommerce 3.0及以上所有版本,不会影响原有结账流程,生成的访问链接会正常展示在客户订单详情和通知邮件中
内容的提问来源于stack exchange,提问作者Iurie
相关产品推荐
相关产品推荐

