在Woocommerce中设置购物车商品价格后重新计算总计

How i can change subtotal price after i changed the price of product by the set_price() method? Now it is calculate the total cost at old prices in review-order.php.

cart.php

foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
  ...
  $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
  $product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
  ...
  $_product->set_price( $price );
  ...
}

This need to be done in a specific dedicated hooked function instead of cart.php template:

add_action( 'woocommerce_before_calculate_totals', 'changing_cart_item_prices', 20, 1 );
function changing_cart_item_prices( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // The instance of the WC_Product Object
        $product = $cart_item['data'];
        $product_id = $product->get_id(); // The product ID

        $price = $product->get_price(); // The product price

        $new_price = 50;

        // Set the new cart item price
        $product->set_price( $new_price );
    }
}

Code goes in function.php file of your active child theme (or active theme). Tested and work.

Everything will be updated correctly as the hook is ajax powered

Ran into this issue where the cart_item's line_total and the cart totals were not updating after programmatically updating existing items in the cart. The woocommerce_before_calculate_totals was not running so that does not fully solve the question in these cases.

In my case, because this was updated on the server side and not through a WooCommerce form my assumption is woocommerce_before_calculate_totals hook was not ran automatically.

Easy enough, you can explicitly tell WooCommerce to recalculate with:

WC()->cart->calculate_totals();

So if you have a woocommerce_before_calculate_totals hook it should be called after this, or WooCommerce should handle it as is just fine.