如何挂钩WooCommerce的checkout-draft订单状态并记录时长?
如何挂钩WooCommerce的checkout-draft订单状态
客户将商品加入购物车并进入购物车/结账页面时,订单会进入checkout-draft状态,直到完成下单操作,状态才会切换为pending payment(待付款)或processing(处理中)。
我此前通过以下代码成功实现了对其他订单状态的监听:
function track_order_draft_duration($orderID, $old_status, $new_status) { // 获取订单详情 $order = new WC_Order($orderID); if ($new_status == 'processing') { $msg = "something"; } } add_action('woocommerce_order_status_changed', "track_order_draft_duration", 10, 3);
但在处理checkout-draft状态时遇到了问题,希望实现记录该状态持续时长的功能。
问题核心:checkout-draft状态的特殊性
checkout-draft是WooCommerce 4.6版本新增的临时订单状态,它不会触发常规的woocommerce_order_status_changed钩子——因为它通常是订单的初始状态,或是直接从购物车生成的临时状态,而非从其他状态转换而来。因此需要用专门的钩子来处理。
解决方案代码实现
1. 记录checkout-draft订单的创建时间
当checkout-draft订单生成时,用woocommerce_checkout_draft_created钩子记录其创建时间,存储到订单元数据中:
function save_checkout_draft_created_time($order) { // 仅针对checkout-draft状态的订单 if ($order->get_status() === 'checkout-draft') { // 记录当前时间(UTC时区,避免时区偏差) $order->update_meta_data('_checkout_draft_created_at', current_time('timestamp', 1)); $order->save(); } } add_action('woocommerce_checkout_draft_created', 'save_checkout_draft_created_time', 10, 1);
2. 计算并记录checkout-draft状态的持续时长
当订单离开checkout-draft状态时,通过woocommerce_order_status_changed钩子,结合之前存储的创建时间计算持续时长:
function track_checkout_draft_duration($order_id, $old_status, $new_status) { $order = wc_get_order($order_id); // 替代new WC_Order,更符合WooCommerce规范 // 仅当订单从checkout-draft切换到其他状态时触发 if ($old_status === 'checkout-draft') { $created_at = $order->get_meta('_checkout_draft_created_at'); if ($created_at) { // 计算持续时长(秒) $duration = current_time('timestamp', 1) - $created_at; // 将时长转换为更易读的格式(比如分钟) $duration_minutes = round($duration / 60, 2); // 保存时长到订单元数据 $order->update_meta_data('_checkout_draft_duration_minutes', $duration_minutes); $order->save(); // 这里可以添加其他逻辑,比如记录到日志或发送通知 error_log("订单 {$order_id} 的checkout-draft状态持续了 {$duration_minutes} 分钟"); } } } add_action('woocommerce_order_status_changed', 'track_checkout_draft_duration', 10, 3);
代码优化建议
- 避免使用
global $woocommerce,改用wc_get_order($order_id)获取订单对象,这是WooCommerce官方推荐的方式,兼容性更好。 - 时间处理使用UTC时区(
current_time('timestamp', 1)),避免因站点时区设置导致的时间计算误差。 - 钩子的优先级设置为10(默认值),确保在其他插件之前执行,若需要调整执行顺序可修改该数值。
内容的提问来源于stack exchange,提问作者Wylly Jeremy
相关产品推荐
相关产品推荐

