Future Webs
Future Webs

Reputation: 239

WooCommerce dynamic minimum order amount based fee

I need to set a minimum order fee in the shopping cart so if products in the cart don't total more than £10 then an extra fee is applied to bring the price up to £10.

Here is the code I have at the moment which works well in the cart phase however when you reach the checkout the pricing section doesn't stop loading for some reason and you can't checkout, can anyone help?

Code from functions.php:

function woocommerce_custom_surcharge() {
  global $woocommerce;
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    $minimumprice = 10;
    $currentprice = $woocommerce->cart->cart_contents_total;
    $additionalfee = $minimumprice - $currentprice;
    if ( $additionalfee >= 0 ) {
        wc_print_notice(
            sprintf( 'We have a minimum %s per order. As your current order is only %s, an additional fee will be applied at checkout.' ,
                wc_price( $minimumprice ),
                wc_price( $currentprice )
            ), 'error'
        );
        $woocommerce->cart->add_fee( 'Minimum Order Adjustment', $additionalfee, true, '' );
    }
}
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );

Upvotes: 2

Views: 720

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253804

Enhanced and updated on May 2019.

The infinite loading spin issue that you are facing is due to wc_print_notice() when it's used in woocommerce_cart_calculate_fees hook. It's seems like a bug.

If you use instead wc_add_notice(), the problem is gone but the notice is displayed 2 times.

Additionally I have revisited your code.The only solution is to split it in 2 separated functions (and a third one for the message):

// Add a custom fee (displaying a notice in cart page)
add_action( 'woocommerce_cart_calculate_fees', 'add_custom_surcharge', 10, 1 );
function add_custom_surcharge( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

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

    $min_price     = 100; // The minimal cart amount

    $current_price = $cart->cart_contents_total;
    $custom_fee    = $min_price - $current_price;

    if ( $custom_fee > 0 ) {
        $cart->add_fee( __('Minimum Order Adjustment'), $custom_fee, true );

        // NOTICE ONLY IN CART PAGE
        if( is_cart() ){
            wc_print_notice( get_custom_fee_message( $min_price, $current_price ), 'error' );
        }
    }
}

// Displaying the notice on checkout page
add_action( 'woocommerce_before_checkout_form', 'custom_surcharge_message', 10 );
function custom_surcharge_message(  ) {
    $min_price     = 100; // The minimal cart amount

    $cart          = WC()->cart;
    $current_price = $cart->cart_contents_total;
    $custom_fee    = $min_price - $current_price;

    // NOTICE ONLY IN CHECKOUT PAGE
    if ( $custom_fee > 0 ) {
        wc_print_notice( get_custom_fee_message( $min_price, $current_price ), 'error' );
    }
}

// The fee notice message
function get_custom_fee_message( $min_price, $current_price ) {
    return sprintf(
        __('We have a minimum %s per order. As your current order is only %s, an additional fee will be applied.', 'woocommerce'),
        wc_price( $min_price ),
        wc_price( $current_price )
    );
}

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

Upvotes: 1

Related Questions