I follow this thread that works perfectly:
Set discount based on number of orders in WooCommerce.
But in my case I need to apply the discount not to the order total, but to the shipping cost and I would like to do this only for a specific country, specifically UK.
For example:
- ONLY First order: 6€ (flat rate shipping cost)
- From the second order onwards, always 25€ (flat rate shipping cost)
I already set the flat rate at 6€ for Uk, but I need to understand how to apply the 25€ surcharge only from the second order onwards.
This is my code attempt:
add_filter( 'woocommerce_package_rates', 'free_first_order_shipping', 20, 2 ); function free_first_order_shipping( $rates, $package ) { if(is_user_logged_in()) { $user_id = get_current_user_id(); //We want to know how many completed orders customer have or remove status if you dont care. $args = array( 'customer_id' => 1, 'status' => array('wc-completed'), ); $orders = wc_get_orders($args); //If there are no orders returned apply free shipping if($orders == 0) { unset( $rates['flat_rate:15'] ); // Shipping 25 euro } else{ unset( $rates['betrs_shipping:10-2'] ); // Shipping 6 euro } } return $rates; }
However, this does not adjust the costs, but removes the shipping method. Any advice?
Advertisement
Answer
Some notes on your code attempt/question:
- The answer you refer to is about adding a (negative) fee, the
woocommerce_package_rates
hook is indeed better suited than thewoocommerce_cart_calculate_fees
hook for your question - You can use
$package['destination']['country']
to determine the country unset( $rates['flat_rate:15'] )
will not adjust the cost but remove the method- To get the total orders by a customer you can use the
wc_get_customer_order_count()
function
So you get:
function filter_woocommerce_package_rates( $rates, $package ) { // ONLY for specific countries $specific_countries = array( 'UK', 'BE' ); // Checks if a value (country) exists in an array, if not return if ( ! in_array( $package['destination']['country'], $specific_countries ) ) return $rates; // Only for logged in users if ( is_user_logged_in() ) { // Get user ID $user_id = get_current_user_id(); // Get the total orders by a customer. $count = wc_get_customer_order_count( $user_id ); // Loop through foreach ( $rates as $rate_key => $rate ) { // Initialize $has_taxes = false; // Targeting "Flat Rate" shipping method if ( $rate->method_id == 'flat_rate' ) { // Get the initial cost $initial_cost = $new_cost = $rates[$rate_key]->cost; // Based on order count if ( $count == 0 ) { // Set the new rate cost $new_cost = 6; } else { // Set the new rate cost $new_cost = 25; } // Set the new cost $rates[$rate_key]->cost = $new_cost; // Taxes rate cost (if enabled) $taxes = []; // Loop through the shipping taxes array (as they can be many) foreach ($rates[$rate_key]->taxes as $key => $tax ) { if ( $rates[$rate_key]->taxes[$key] > 0 ) { // Get the initial tax cost $initial_tax_cost = $new_tax_cost = $rates[$rate_key]->taxes[$key]; // Get the tax rate conversion $tax_rate = $initial_tax_cost / $initial_cost; // Set the new tax cost $taxes[$key] = $new_cost * $tax_rate; // Enabling tax $has_taxes = true; } } // When true if ( $has_taxes ) { $rates[$rate_key]->taxes = $taxes; } } } } return $rates; } add_filter( 'woocommerce_package_rates','filter_woocommerce_package_rates', 10, 2 );
Don’t forget to empty your cart to refresh shipping cached data!