在插入数据库之前使用钩子从 Woocommerce 订单中删除费用

Remove fee from Woocommerce order using hook before inserting to database

在将 Woocommerce 订单保存到数据库之前,有什么方法可以取消费用吗?

我尝试了以下钩子,但没有成功

  1. woocommerce_before_save_order_items
  2. woocommerce_calculate_totals
  3. wp_insert_post_data

我也试过如下编辑费用总额,但费用仍然保存到数据库中

add_action( 'woocommerce_review_order_before_payment', 'cst_my_hook_1', 10, 3);
function cst_my_hook_1() {
    WC()->cart->set_fee_total(0);
}

我正在分享一个屏幕截图,以使我的要求更清楚。 Woocommerce 购物车 class (class-wc-cart.php) 包含一个 public 功能来添加费用,所以我认为应该有办法删除它。

我使用挂钩“woocommerce_cart_calculate_fees”添加了屏幕截图中显示的费用。现在我想在保存到数据库之前将其删除。

我正在使用 Wordpress 5.7.1Woocommerce 5.2.1

要在结帐后禁用订单费用,请使用以下这个简单的挂钩函数,它将清除订单和电子邮件通知中的所有费用:

add_action( 'woocommerce_checkout_order_created', 'order_created_disable_fees' );
function order_created_disable_fees( $order ) {
    $targeted_item_name = __( "Total Tax Payment", "woocommerce" );

    foreach( $order->get_items( 'fee' ) as $item_id => $item ) {
        if( $targeted_item_name === $item['name'] ) {
            $order->remove_item($item_id);
        }       
    }
    $order->calculate_totals();
}

代码进入活动子主题(或活动主题)的 functions.php 文件。已测试并有效。


现在,如果您想取消费用,但保留原始总订单金额,请使用以下方法:

add_action( 'woocommerce_checkout_order_created', 'order_created_disable_fees' );
function order_created_disable_fees( $order ) {
    $targeted_item_name = __( "Total Tax Payment", "woocommerce" );

    foreach( $order->get_items( 'fee' ) as $item_id => $item ) {
        if( $targeted_item_name === $item['name'] ) {
            $order->remove_item($item_id);
        }
    }
    $order->save();
}

代码进入活动子主题(或活动主题)的 functions.php 文件。已测试并有效。

如果您希望在将订单保存到数据库之前从订单中删除费用,您可以使用在订单创建之前触发的woocommerce_create_order挂钩create_order WC_Checkout 方法 class.

基于这个答案:

您将能够从购物车中删除费用。

However, you will also have to recalculate the totals and taxes (it works whether the fee is taxable or not, and even with multiple tax classes).

从购物车中删除费用并重新计算总额

// removes a specific fee by name before creating the order and recalculates the totals
add_filter( 'woocommerce_create_order', 'remove_specific_fee_from_cart_before_creating_order', 10, 2 );
function remove_specific_fee_from_cart_before_creating_order( $order_id = null, $order ) {

    // get the fees added to the cart
    $fees = WC()->cart->get_fees();

    // initialize taxes (if the fee is not taxable)
    $fee_tax = 0;
    $fee_tax_data = array();

    foreach ( $fees as $key => $fee ) {
        // replace "Total Tax Payment" with the name of the fee you added to the cart
        if ( $fee->name == 'Total Tax Payment' ) {
            // gets the data to recalculate the cart total
            $fee_amount = $fee->amount;
            if ( $fee->taxable ) {
                $fee_tax      = $fee->tax;
                $fee_tax_data = $fee->tax_data;
            }
            // removes the fee
            unset( $fees[$key] );
            break;
        }
    }

    // updates the cart fees
    WC()->cart->fees_api()->set_fees( $fees );

    // gets the current values of the cart to be recalculated
    $cart_total     = WC()->cart->get_total(''); // returns the float value instead of HTML code
    $cart_total_tax = WC()->cart->get_total_tax();
    $cart_fee_taxes = WC()->cart->get_fee_taxes();

    // if the fee is taxable
    // recalculates the taxes by removing the taxes of the removed fee
    if ( ! empty( $fee_tax_data ) ) {
        foreach ( $cart_fee_taxes as $fee_tax_key => $fee_tax ) {
            if ( array_key_exists( $fee_tax_key, $fee_tax_data ) ) {
                $cart_fee_taxes[$fee_tax_key] = $fee_tax - $fee_tax_data[$fee_tax_key];
            }
        }
    }

    // updates the cart totals
    WC()->cart->set_total( $cart_total - $fee_amount - $fee_tax );
    WC()->cart->set_total_tax( $cart_total_tax - $fee_tax );
    WC()->cart->set_fee_taxes( $cart_fee_taxes );

    return $order_id;
}

在不重新计算总数的情况下从购物车中删除费用

// removes a specific fee by name before creating the order
add_filter( 'woocommerce_create_order', 'remove_specific_fee_from_cart_before_creating_order', 10, 2 );
function remove_specific_fee_from_cart_before_creating_order( $order_id = null, $order ) {

    // get the fees added to the cart
    $fees = WC()->cart->get_fees();

    foreach ( $fees as $key => $fee ) {
        // replace "Total Tax Payment" with the name of the fee you added to the cart
        if ( $fee->name == 'Total Tax Payment' ) {
            // removes the fee
            unset( $fees[$key] );
            break;
        }
    }

    // updates the cart fees
    WC()->cart->fees_api()->set_fees( $fees );

    return $order_id;
}

代码已经过测试并且可以工作。将它添加到您的活动主题 functions.php.