If it hasn’t happened yet, the day will soon come when you will need, or a customer will ask you, to offer several shipping methods, free and paid at checkout, depending on the products added to the cart.
Let’s get started, it’s just a few steps…
Table of Contents
Create shipping classes for each method
In your online store administration go to WooCommerce menu → Settings → Shipping → Shipping classes and add the shipping classes you need, as in the following example.

Write down the slugs of the new shipping classes (we will need them later) and save the shipping classes.
Assign the new shipping classes
Now edit the products with different shipping costs to the standard ones you have configured and assign the shipping class you have created to each of the affected products and save the changes in the editor.

Assign amounts to the new shipment types
Now that we have the new shipping classes and products they will affect, we need to assign an amount or rate to these shipping classes.
To do this go to WooCommerce → Settings → Shipping → Shipping Zones, click on the shipping zone to which we will add the rates, and then click the “Add shipping method” button.

Name the new sending method and then edit it to configure it as follows:

The most important thing is the following:
- The calculation type must be “Per class”.
- Specify a zero cost for the free shipping type, if applicable.
- Specify a cost for each additional shipping type.
Save the changes.
Separate shipments according to cost
The next step is very important, because you will want to have the different shipping costs displayed separately depending on the shipping method. To achieve this you need to create a function with some custom code, like this:
/* Shipping cost by class */
add_filter( 'cw_woocommerce_package_cart', 'wphelp_sort_shipping_cost' );
function wphelp_sort_shipping_cost( $packages ) {
$bulk_products = array();
$packages = array();
$regular_products = array();
// Sort by class
foreach ( WC()->cart->get_cart() as $item ) {
if ( $item['data']->needs_shipping() ) {
if ( $item['data']->get_shipping_class() == 'free' ) {
$bulk_products[] = $item;
} else {
$regular_products[] = $item;
}
}
}
if ( $bulk_products ) {
$packages[] = array(
'ship_via' => array( 'flat_rate' ),
'contents' => $bulk_products,
'contents_cost' => array_sum( wp_list_pluck( $bulk_products, 'line_total' ) ),
'applied_coupons' => WC()->cart->applied_coupons,
'destination' => array(
'country' => WC()->customer->get_shipping_country(),
'state' => WC()->customer->get_shipping_state(),
'postcode' => WC()->customer->get_shipping_postcode()
)
);
}
if ( $regular_products ) {
$packages[] = array(
'contents' => $regular_products,
'contents_cost' => array_sum( wp_list_pluck( $regular_products, 'line_total' ) ),
'applied_coupons' => WC()->cart->applied_coupons,
'destination' => array(
'country' => WC()->customer->get_shipping_country(),
'state' => WC()->customer->get_shipping_state(),
'postcode' => WC()->customer->get_shipping_postcode()
)
);
}
return $packages;
}
Code language: PHP (php)
In the previous code you must change the slugs of the example array for the ones that you created, remember that I told you that later we would need them.
Save the changes.
Where do I put this code?
You can add the code in several places, choose yourself how to do it following this simple guide…
How and where to paste PHP, JS, CSS codes and functions you find around in WordPress