You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WooCommerce中通过代码创建已完成订单且不向客户发送邮件

Hey there! I get what you're trying to do—create a completed WooCommerce order without triggering that automatic email to the customer, and you don't want to disable emails globally in the admin. Let's walk through a couple of reliable ways to handle this:

方法1:临时移除邮件通知钩子(简单直接)

This approach temporarily disables the specific hook that triggers the completed order email, runs your order creation code, then re-enables the hook so future orders work normally.

Here's your modified code:

// Temporarily remove the completed order email hook
remove_action('woocommerce_order_status_completed_notification', array(WC()->mailer(), 'send_transactional_email'), 10);

// Your original order creation logic
$order = wc_create_order();
$order->set_customer_id($userId);
foreach($_POST['basket'] as $prod){
    $order->add_product(wc_get_product($prod['id']), $prod['count']); // Note: get_product() is deprecated, use wc_get_product() instead
}
$order->set_address($address, 'billing');
$order->calculate_totals();
$order->update_status("completed", 'TEST', TRUE);

// Restore the email hook for future orders
add_action('woocommerce_order_status_completed_notification', array(WC()->mailer(), 'send_transactional_email'), 10);

Quick note: I swapped get_product() for wc_get_product()—the former is an outdated WooCommerce function, so using the new one keeps your code compatible with recent versions.

方法2:Use a filter to disable email for specific orders (more flexible)

If you need granular control (like only blocking emails for your test orders), use the woocommerce_email_enabled filter to target specific orders.

First, add this filter to your theme's functions.php file or a custom plugin:

add_filter('woocommerce_email_enabled_completed_order', 'disable_completed_email_for_test_orders', 10, 2);
function disable_completed_email_for_test_orders($enabled, $order) {
    // Check if the order has our test note
    if ($order->get_status_notes() && str_contains($order->get_status_notes(), 'TEST')) {
        return false;
    }
    // Alternatively, use a custom meta field for clearer targeting:
    // if ($order->get_meta('_is_test_order') === 'yes') {
    //     return false;
    // }
    return $enabled;
}

Then update your order creation code to mark the test order (if using the custom meta field approach):

$order = wc_create_order();
$order->set_customer_id($userId);
foreach($_POST['basket'] as $prod){
    $order->add_product(wc_get_product($prod['id']), $prod['count']);
}
$order->set_address($address, 'billing');
$order->calculate_totals();
// Add custom meta to mark as test order (if using the meta field filter)
$order->update_meta_data('_is_test_order', 'yes');
$order->save_meta_data();
$order->update_status("completed", 'TEST', TRUE);

This method ensures only your test orders skip the email, leaving normal order notifications fully functional.

One extra tip: You might notice the third parameter in update_status() is set to TRUE—that's the "notify" flag. Setting it to FALSE can sometimes prevent emails, but third-party plugins or custom code might override this. The two methods above are more reliable for consistent results.

内容的提问来源于stack exchange,提问作者Parsa Nikoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 11:27:41