原因解释:
woocommerce_checkout_create_order 是在 WooCommerce 的结账流程中触发的,它的触发位置是:
php复制编辑// 文件:woocommerce/includes/class-wc-checkout.php
do_action( 'woocommerce_checkout_create_order', $order, $data );
这个钩子只在 WC_Checkout::create_order() 方法中触发,也就是用户从前端结账提交的时候触发。
🚫 而 wc_create_order() 是你自己手动在代码里创建订单用的,它只是基础的订单创建函数,不走完整的结账流程,也不会触发 checkout 的钩子们。
✅ 如何解决?
如果你是用 wc_create_order() 自定义下单,那么你应该:
✅ 自己手动调用设置订单号的逻辑,例如:
php复制编辑$order = wc_create_order([
'customer_id' => 123, // 可选
// 其他订单数据
]);
// 自定义订单号
$custom_order_number = 'ORD-' . date('YmdHis') . '-' . wp_rand(1000, 9999);
$order->update_meta_data('_custom_order_number', $custom_order_number);
$order->save(); // 别忘了保存
✅ 或者你可以挂在 save_post_shop_order 钩子上
如果你想更通用地拦截所有新创建订单(不管是不是走结账流程),可以这样:
php复制编辑add_action('save_post_shop_order', 'set_custom_order_number_for_manual_order', 10, 3);
function set_custom_order_number_for_manual_order($post_id, $post, $update) {
if ($update) return; // 只对新订单
$order = wc_get_order($post_id);
if (!$order || $order->get_meta('_custom_order_number')) return; // 避免重复设置
$custom_order_number = 'ORD-' . date('YmdHis') . '-' . wp_rand(1000, 9999);
$order->update_meta_data('_custom_order_number', $custom_order_number);
$order->save();
}
这个方式能确保你所有订单(无论前台结账还是后台代码创建)都能自动获得自定义订单号。
✅ 总结
| 创建方式 | 是否触发 woocommerce_checkout_create_order |
|---|---|
| 前端正常结账流程 | ✅ 会触发 |
代码调用 wc_create_order() | ❌ 不会触发 |
使用 save_post_shop_order 钩子 | ✅ 可以拦截所有订单保存 |