WordPress WooCommerce自动完成订单代码重复执行问题咨询
解决WooCommerce订单自动完成代码重复执行的问题
一、修复代码避免重复执行
你当前的代码每次触发woocommerce_payment_complete_order_status钩子都会强制返回completed,完全不判断订单当前状态,所以钩子被调用两次就会重复修改订单状态。可以给函数加上状态校验,只在订单处于processing状态时才修改:
add_filter( 'woocommerce_payment_complete_order_status', 'bbloomer_autocomplete_processing_orders', 9999, 2 ); function bbloomer_autocomplete_processing_orders( $status, $order_id ) { // 获取订单对象 $order = wc_get_order( $order_id ); // 仅当订单当前状态为processing时,才将其改为completed if ( $order && $order->get_status() === 'processing' ) { return 'completed'; } // 其他状态保持原状态不变 return $status; }
注意:原函数没有接收钩子传递的$status和$order_id参数,需要在add_filter里加上第四个参数2(表示接收2个参数),才能实现状态判断逻辑。
二、关于PHP中类似JS setTimeout的函数
PHP里有sleep()函数,能让脚本暂停指定秒数,但完全不适合你的场景:
sleep()是同步阻塞的,会让整个请求等待,严重影响性能和用户体验- 它无法解决钩子被重复触发的问题,只是延迟了执行时间,两次触发依然会执行两次
三、排查钩子重复触发的根源
代码重复执行大多是因为支付回调被重复调用(比如支付网关重复发送通知),或者主题/其他插件也触发了这个钩子:
- 检查支付网关设置,开启回调签名验证,拦截非法重复通知
- 可以添加日志记录,定位重复触发的来源:
add_filter( 'woocommerce_payment_complete_order_status', 'bbloomer_autocomplete_processing_orders', 9999, 2 ); function bbloomer_autocomplete_processing_orders( $status, $order_id ) { // 将调用信息写入WordPress错误日志 error_log( "钩子触发,订单ID:{$order_id},调用栈:" . print_r( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), true ) ); $order = wc_get_order( $order_id ); if ( $order && $order->get_status() === 'processing' ) { return 'completed'; } return $status; }
你可以在WordPress根目录的wp-content/debug.log文件中查看日志,找到重复触发的具体原因。
内容的提问来源于stack exchange,提问作者Nicholas Lee
相关产品推荐
相关产品推荐

