WooCommerce: Cart price override with text

10,526

Solution 1

expanding on Helga's answer, here's the full code that changes the prices to 'to be determined' on cart pages, checkout pages and order confirmation emails too. Text kept different so people can spot where each filter goes.

    add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 3 );
function filter_cart_item_price( $price, $cart_item, $cart_item_key ) {
    if ( $cart_item[ 'data' ]->price == 0 ) {
        $price = __( 'Special Order', 'yourtheme' );
    }
    return $price;
}

add_filter( 'woocommerce_cart_item_subtotal', 'filter_cart_item_subtotal', 10, 3 );
function filter_cart_item_subtotal( $subtotal, $cart_item, $cart_item_key ) {
    if ( $cart_item[ 'data' ]->price == 0 ) {
        $subtotal = __( 'To be determined', 'yourtheme' );
    }
    return $subtotal;
}

add_filter( 'woocommerce_cart_subtotal', 'filter_woocommerce_cart_subtotal', 10, 3 ); 
function filter_woocommerce_cart_subtotal( $cart_subtotal, $compound, $instance ) { 
    $cart_subtotal = __( 'To be determined 4', 'yourtheme' ); 
    return $cart_subtotal; 
}; 


add_filter( 'woocommerce_order_formatted_line_subtotal', 'filter_order_item_subtotal', 10, 3 );
function filter_order_item_subtotal( $subtotal, $item, $order ) {
    if ( isset( $item[ 'line_subtotal' ] ) && $item[ 'line_subtotal' ] == 0 ) {
        $subtotal = __( 'To be determined 2', 'yourtheme' );
    }
    return $subtotal;
}

add_filter( 'woocommerce_order_subtotal_to_display', 'filter_woocommerce_order_subtotal_to_display', 10, 3 ); 
function filter_woocommerce_order_subtotal_to_display( $subtotal, $compound, $instance ) { 
        $subtotal = __( 'To be determined 6', 'yourtheme' );
    return $subtotal; 
};

add_filter( 'woocommerce_get_formatted_order_total', 'filter_woocommerce_get_formatted_order_total', 10, 2 ); 
function filter_woocommerce_get_formatted_order_total( $formatted_total, $instance ) { 
        $formatted_total = __( 'To be determined 8', 'yourtheme' );
    return $formatted_total; 
}; 

Solution 2

You need to filter the strings that display the price and subtotal in the cart. The link you mentioned discussed changing the actual price. In your case the price is $0 until you set an actual price later on. There are probably filters for the cart totals too, but this should be a start:

add_filter( 'woocommerce_cart_item_price', 'so_38057349_cart_item_price', 10, 3 );
function so_38057349_cart_item_price( $price, $cart_item, $cart_item_key ) {

    if ( $cart_item[ 'data' ]->price == 0 ) {
        $price = __( 'Special Order', 'yourtheme' );
    }

    return $price;
}


add_filter( 'woocommerce_cart_item_subtotal', 'so_38057349_cart_item_subtotal', 10, 3 );
function so_38057349_cart_item_subtotal( $subtotal, $cart_item, $cart_item_key ) {

    if ( $cart_item[ 'data' ]->price == 0 ) {
        $subtotal = __( 'To be determined', 'yourtheme' );
    }

    return $subtotal;
}


add_filter( 'woocommerce_order_formatted_line_subtotal', 'so_38057349_order_item_subtotal', 10, 3 );
function so_38057349_order_item_subtotal( $subtotal, $item, $order ) {

    if ( isset( $item[ 'line_subtotal' ] ) && $item[ 'line_subtotal' ] == 0 ) {
        $subtotal = __( 'To be determined', 'yourtheme' );
    }

    return $subtotal;
}

Of course, this will also apply to any product with a 0 price and maybe not only the ones you have configured to be custom built, so you may need more conditional logic than I've supplied here.

To follow up on your comment.... woocommerce_order_amount_total is the numerical total and not the displayed html. You can see the functions being called in the cart-totals.php template.

function so_38057349_woocommerce_cart_subtotal( $cart_subtotal, $compound, $cart ) { 
    if( $cart->subtotal == 0 ){
        $cart_subtotal = __( 'Order subtotal to be determined', 'yourtheme' ); 
    }
    return $cart_subtotal; 
}; 
add_filter( 'woocommerce_cart_subtotal', 'so_38057349_woocommerce_cart_subtotal', 10, 3 ); 


// define the woocommerce_order_amount_total callback 
function so_38057349_woocommerce_order_amount_total( $order_total ) { 
    if( WC()->cart->get_total() == 0 ){
        $order_total = __( 'Order total to be determined', 'yourtheme' ); 
    }
    return $order_total; 
}; 
add_filter( 'woocommerce_cart_totals_order_total_html', 'so_38057349_woocommerce_order_amount_total' ); 

Updated screenshot: cart

Share:
10,526
Admin
Author by

Admin

Updated on August 04, 2022

Comments

  • Admin
    Admin over 1 year

    We have a bunch of products with either:

    • No price
    • Zero price

    We made them purchasable with the built-in hook but the cart still displays them as having a 0 price during checkout.

    We'd like the cart & checkout summary to display "Special order" or any other text, but it seems WooCommerce invalidates text-based prices.

    Tried this : WooCommerce: Add product to cart with price override?

    The above works fine with a number override, but when tried with a text override it defaults back to displaying a 0 price.

    Why? These products are built-to-order and the shop admin will update price after talking to customer/supplier.

  • Admin
    Admin almost 8 years
    Thank you so much Helga, it's exactly what was needed. Expanded on your example to cover cart & checkout pages too !
  • helgatheviking
    helgatheviking almost 8 years
    Check out my edit. Similar to the error in your question woocommerce_order_amount_total is not meant to be an html string.