WooCommerce订单邮件发送后如何追加特殊Product ID
WooCommerce 订单邮件插入异步获取的特殊Product ID实现方案
问题根源
默认WooCommerce的客户订单类邮件(如付款成功后的处理中订单邮件)默认在woocommerce_payment_complete钩子优先级10的位置触发,执行时机早于跳转支付成功页后调用外部REST API的逻辑,因此邮件发送时还未拿到后续生成的特殊Product ID。
推荐实现方案
通过调整钩子优先级,先完成外部API请求、存储特殊ID,再触发邮件发送,全程无需修改WooCommerce核心文件。
步骤1:移除默认的邮件自动触发逻辑
将以下代码加入子主题functions.php或自定义功能插件,先解绑默认的邮件触发动作:
// 移除默认支付完成后的订单邮件自动触发 remove_action( 'woocommerce_payment_complete', array( 'WC_Emails', 'maybe_queue_transactional_email' ), 10 );
步骤2:先执行API请求存储特殊ID,再手动触发邮件
将原有的外部API请求逻辑挂载到更高优先级的支付完成钩子上,拿到特殊ID存入订单元数据后,再手动触发订单邮件发送:
add_action( 'woocommerce_payment_complete', 'custom_process_special_id_and_send_mail', 5 ); function custom_process_special_id_and_send_mail( $order_id ) { $order = wc_get_order( $order_id ); if ( !$order ) return; // 替换为实际调用外部REST API获取特殊Product ID的逻辑 $api_response = wp_remote_get( '你的外部API请求地址', [ 'timeout' => 10, 'headers' => [ // 按接口要求填写鉴权信息 ] ] ); // 根据实际接口返回结构解析特殊Product ID $special_product_id = wp_remote_retrieve_body( $api_response ); // 将获取到的特殊ID存入订单元数据 if ( !is_wp_error( $api_response ) && !empty( $special_product_id ) ) { $order->update_meta_data( '_special_product_id', sanitize_text_field( $special_product_id ) ); $order->save(); } // 数据存储完成后,手动触发客户处理中订单邮件,可根据实际使用的邮件模板替换对应类名 WC()->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger( $order_id ); }
步骤3:将特殊Product ID插入邮件内容
通过WooCommerce官方提供的邮件内容钩子,把存储的特殊ID输出到邮件指定位置,以下示例为插入到订单明细表格上方:
add_action( 'woocommerce_email_before_order_table', 'custom_insert_special_id_to_email', 20, 4 ); function custom_insert_special_id_to_email( $order, $sent_to_admin, $plain_text, $email ) { // 仅在发给客户的处理中订单邮件中显示,可按需调整邮件ID匹配规则 if ( $email->id !== 'customer_processing_order' ) return; $special_id = $order->get_meta( '_special_product_id', true ); if ( !empty( $special_id ) ) { // 适配纯文本邮件格式 if ( $plain_text ) { echo "特殊商品ID: " . esc_html( $special_id ) . "\n\n"; } else { echo '<p style="margin-bottom: 15px;"><strong>特殊商品ID:</strong>' . esc_html( $special_id ) . '</p>'; } } }
备选方案
如果不想调整默认邮件的触发时机,可以保留原有邮件发送逻辑,等拿到特殊Product ID后,通过WC()->mailer()手动发送一封补充通知邮件,单独告知用户特殊Product ID,缺点是用户会收到两封订单相关邮件,体验稍差。
注意事项
- 不要将代码直接放入父主题
functions.php或WooCommerce核心文件,否则主题/插件更新时代码会被覆盖 - 如果使用的支付网关为异步回调模式(即支付成功后不是同步跳转就更新订单状态,而是通过网关异步推送通知标记支付完成),建议将API请求、邮件触发逻辑挂载到对应支付网关的专属回调钩子上,避免用户跳转中断导致漏存ID、漏发邮件
- 外部API请求建议增加失败重试、错误日志记录逻辑,避免接口异常导致邮件发送流程中断
内容的提问来源于stack exchange,提问作者stefan007
相关产品推荐
相关产品推荐

