WooCommerce后台修改订单为完成后执行PHP代码的钩子咨询
问题解答:WooCommerce手动改订单为已完成时触发自定义代码
首先,你用的woocommerce_payment_complete钩子不正确。这个钩子是用户完成在线支付(比如支付宝、信用卡付款成功)时自动触发的,和管理员手动修改订单状态为“已完成”的场景完全不匹配,所以你的代码不会执行。
正确的钩子选择
要在订单状态被修改为“已完成”(不管是自动还是手动操作)时触发代码,应该用woocommerce_order_status_completed钩子。如果需要仅在管理员手动修改时触发,可以额外添加判断当前操作用户权限的逻辑。
修正后的代码示例
基础版(所有已完成状态变更都触发)
add_action( 'woocommerce_order_status_completed', 'wenn_order_completed', 10, 1 ); function wenn_order_completed( $order_id ){ // 获取订单对象,先验证有效性 $order = wc_get_order( $order_id ); if ( ! $order ) return; $customer_id = $order->get_customer_id(); // 验证用户ID是否有效 if ( empty( $customer_id ) ) return; global $wpdb; // 正确使用prepare占位符,避免SQL注入,同时兼容不同前缀的数据库表 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}users SET new = %s WHERE ID = %d", '1', $customer_id ) ); }
进阶版(仅管理员手动修改时触发)
如果需要限定只有管理员手动操作才执行代码,加个用户权限判断:
add_action( 'woocommerce_order_status_completed', 'wenn_admin_completes_order', 10, 1 ); function wenn_admin_completes_order( $order_id ){ // 检查当前用户是否有WooCommerce管理权限 if ( ! current_user_can( 'manage_woocommerce' ) ) return; $order = wc_get_order( $order_id ); if ( ! $order ) return; $customer_id = $order->get_customer_id(); if ( empty( $customer_id ) ) return; global $wpdb; $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}users SET new = %s WHERE ID = %d", '1', $customer_id ) ); }
额外注意点
- 用
{$wpdb->prefix}代替硬编码的lpd7_,这样代码在不同数据库前缀的WordPress站点都能正常运行,避免迁移或换环境出问题。 wpdb->prepare的占位符要对应正确类型:%s用于字符串,%d用于数字,不要直接把变量拼进SQL语句,防止注入风险。- 排查问题时可以加日志,比如在函数里加
error_log( '已完成订单触发,用户ID:' . $customer_id );,然后去WordPress的debug.log里查看是否执行。
内容的提问来源于stack exchange,提问作者Bartek Pesz
相关产品推荐
相关产品推荐

