WooCommerce延迟交易邮件后收不到订单邮件,如何修复format()错误?
解决WooCommerce延迟邮件导致订单日期为空的错误并保持结账速度
问题根源
启用woocommerce_defer_transactional_emails钩子后,邮件会延迟到结账流程的shutdown阶段发送,但此时订单对象可能还未完全写入数据库,导致$order->get_date_created()返回null,调用format()方法时触发致命错误,最终邮件发送失败。
方案一:修复订单日期为空的错误(保留官方延迟逻辑)
方法1:用钩子修改(推荐,不影响核心更新)
在主题的functions.php中添加以下代码,通过过滤器拦截日期格式化逻辑,提前判断日期是否存在:
add_filter( 'woocommerce_email_order_date_created', 'fix_deferred_email_date_null_error', 10, 2 ); function fix_deferred_email_date_null_error( $formatted_date, $order ) { $date_created = $order->get_date_created(); // 如果日期为空,用当前时间替代,保证邮件正常发送 return $date_created ? $date_created->format( 'c' ) : current_time( 'c' ); }
方法2:临时修改核心文件(不推荐,更新会覆盖)
找到/woocommerce/emails/email-order-details.php第34行,将原代码:
$order->get_date_created()->format( 'c' )
替换为:
$date_created = $order->get_date_created(); echo $date_created ? $date_created->format( 'c' ) : current_time( 'c' );
方案二:替换为更可靠的异步邮件发送逻辑(彻底避免核心错误)
放弃官方的延迟钩子,改用WP Cron实现异步邮件发送,确保订单完全写入数据库后再处理邮件:
// 先禁用官方的延迟邮件钩子 remove_filter( 'woocommerce_defer_transactional_emails', '__return_true' ); // 订单完成后,安排Cron任务异步发送邮件 add_action( 'woocommerce_checkout_order_processed', 'schedule_async_woocommerce_emails', 20, 1 ); function schedule_async_woocommerce_emails( $order_id ) { // 设置1分钟后发送(可根据需求调整时间,比如30秒:time() + 30) if ( ! wp_next_scheduled( 'send_async_woocommerce_order_emails', array( $order_id ) ) ) { wp_schedule_single_event( time() + 60, 'send_async_woocommerce_order_emails', array( $order_id ) ); } } // 定义Cron任务的回调函数,执行邮件发送 add_action( 'send_async_woocommerce_order_emails', 'send_async_woocommerce_order_emails_callback' ); function send_async_woocommerce_order_emails_callback( $order_id ) { $order = wc_get_order( $order_id ); if ( ! $order ) return; $mailer = WC()->mailer(); // 发送管理员新订单邮件 $mailer->get_emails()['WC_Email_New_Order']->trigger( $order_id ); // 发送客户处理中订单邮件(如果需要) $mailer->get_emails()['WC_Email_Customer_Processing_Order']->trigger( $order_id ); // 可根据需求添加其他邮件类型,比如完成订单邮件等 }
注意事项
- 如果主机禁用了WP Cron,需要在服务器的定时任务中添加触发命令,示例:
*/5 * * * * wget -q -O - https://你的域名/wp-cron.php?doing_wp_cron >/dev/null 2>&1 - 该方案既保证了结账流程不被邮件发送阻塞,又避免了订单未完全保存导致的错误,稳定性更高。
内容的提问来源于stack exchange,提问作者Phan Vũ
相关产品推荐
相关产品推荐

