WooCommerce如何实现24小时后自动将Failed订单转为Canceled状态
问题根因
- 钩子选择错误:
woocommerce_cancel_unpaid_submitted是WooCommerce内置用于自动取消「待付款」「保留中」状态未支付订单的钩子,执行逻辑和后台「未支付订单保留时长」设置绑定,不会主动扫描failed状态的订单,因此函数几乎不会被触发。 - 时间计算存在误差:使用
strtotime( date('Y-m-d') )取当天零点再减1天,实际匹配的是「创建时间早于昨天零点」的订单,最大会产生接近24小时的延迟,无法实现满24小时立即触发的需求。 - 查询参数兼容性不足:不同WooCommerce版本对
date_created直接传入时间戳的支持度不同,容易出现查询失效的情况。
修正后完整代码
<?php // 注册自定义定时任务 add_action('wp', 'register_failed_order_cancel_cron'); function register_failed_order_cancel_cron() { if (!wp_next_scheduled('cancel_failed_orders_daily')) { wp_schedule_event(time(), 'hourly', 'cancel_failed_orders_daily'); } } // 定时执行失败订单取消逻辑 add_action('cancel_failed_orders_daily', 'cancel_failed_orders_after_24h'); function cancel_failed_orders_after_24h() { $hours_delay = 24; // 可自定义延迟时长 $delay_seconds = $hours_delay * 60 * 60; $failed_orders = wc_get_orders(array( 'limit' => -1, 'status' => 'failed', 'date_created' => '<' . (time() - $delay_seconds), 'return' => 'objects', )); if (!empty($failed_orders)) { $cancelled_text = __("No successful payment", "woocommerce"); foreach ($failed_orders as $order) { $order->update_status('cancelled', $cancelled_text); } } } // 插件禁用时清理定时任务 register_deactivation_hook(__FILE__, 'remove_failed_order_cancel_cron'); function remove_failed_order_cancel_cron() { $timestamp = wp_next_scheduled('cancel_failed_orders_daily'); if ($timestamp) { wp_unschedule_event($timestamp, 'cancel_failed_orders_daily'); } }
额外注意事项
- 确保站点WP Cron功能正常运行,如果站点访问量较低,建议配置服务器系统定时任务触发WP Cron,避免执行延迟。
- 测试时可安装WP Crontrol插件,查看定时任务是否正常注册,也可以手动触发任务验证效果。
- 可自行调整
$hours_delay参数的值,修改需要的触发时长。
内容的提问来源于stack exchange,提问作者Antoine
相关产品推荐
相关产品推荐

