Step 1: Understand WooCommerce Shipping Basics
Identify Default Shipping Zones
WooCommerce organizes shipping around “zones.” A shipping zone is a geographical region where a certain set of shipping methods and rates apply. By default, WooCommerce creates a “Rest of the World” zone, and you can add specific zones for countries, states, or even postal codes. To see your zones, navigate to WooCommerce > Settings > Shipping in your WordPress admin dashboard. Each zone can have multiple shipping methods configured within it.
Recognize Shipping Method Types (Flat Rate, Free Shipping, Local Pickup)
WooCommerce offers several built-in shipping method types, each serving a different purpose:
- Flat Rate: A fixed price for shipping, regardless of the number of items or order value. You can set up advanced flat rates based on calculations like percentage of cart total or per item.
- Free Shipping: Allows you to offer free shipping based on conditions such as a minimum order amount, a valid coupon, or a specific product.
- Local Pickup: Enables customers to pick up their order directly from your location, often without a shipping cost.
- Table Rate Shipping (via extensions): While not built-in, many popular extensions allow for highly complex shipping rules based on weight, dimensions, cart total, and more.
Understanding these types is crucial when trying to retrieve or display shipping information, as their data structures can vary slightly.
Step 2: Access Shipping Information Programmatically
Utilize WooCommerce Core Functions for Shipping Data
WooCommerce provides a robust API for accessing shipping data. To get the active shipping methods available for a given cart or order, you’ll primarily interact with the WC_Shipping
class and related functions. For example, to get all enabled shipping methods globally, you might use WC()->shipping->get_shipping_methods()
, though this returns the method objects themselves, not necessarily what’s available for a specific cart.
Query Order Details for Applied Shipping Methods
When an order has been placed, the chosen shipping method is stored as part of the order’s data. To retrieve it, you’ll need the order ID. Here’s a common approach using the WC_Order
object:
$order_id = 123; // Replace with your order ID
$order = wc_get_order( $order_id );
if ( $order ) {
foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) {
$method_title = $shipping_item->get_method_title(); // e.g., "Flat Rate"
$method_id = $shipping_item->get_method_id(); // e.g., "flat_rate"
$instance_id = $shipping_item->get_instance_id(); // e.g., "1" (for specific zone/method)
$cost = $shipping_item->get_total(); // Shipping cost for this item
echo "<p>Shipping Method: " . esc_html( $method_title ) . " (ID: " . esc_html( $method_id ) . ", Cost: " . wc_price( $cost ) . ")</p>";
}
}
This code iterates through all shipping line items attached to an order, providing details like the method title, ID, instance ID, and the calculated cost.
Step 3: Display Shipping Methods on the Frontend
Retrieve Active Shipping Methods for a Cart/Order
To display shipping methods dynamically, especially on the cart or checkout page, you need to get the methods available for the current cart. WooCommerce handles this automatically on these pages. However, if you need to display them elsewhere or for a specific scenario, you can leverage the WC_Session_Handler
and WC_Shipping
classes. The key is to ensure the cart’s shipping address is set, as this determines the applicable zone.
For the current cart, on a page where WC()->cart
is available:
if ( WC()->cart ) {
WC()->cart->calculate_shipping(); // Ensure shipping is calculated based on current cart state
$packages = WC()->shipping->get_packages();
foreach ( $packages as $i => $package ) {
if ( ! empty( $package['rates'] ) ) {
echo "<h3>Available Shipping Methods for Package " . ( $i + 1 ) . "</h3>";
echo "<ul>";
foreach ( $package['rates'] as $rate_id => $rate ) {
echo "<li>" . esc_html( $rate->label ) . " - " . wc_price( $rate->cost ) . "</li>";
}
echo "</ul>";
} else {
echo "<p>No shipping methods available for this package.</p>";
}
}
}
This code snippet will list the available shipping methods and their costs for the current cart, as determined by WooCommerce’s shipping calculations.
Format and Present Shipping Method Details to Users
When presenting shipping methods, clarity is key. Use descriptive labels ($rate->label
from the example above) and clearly display the cost (wc_price($rate->cost)
). If a method is free, explicitly state “Free.” Consider using radio buttons or a dropdown for selection on checkout pages, ensuring the selected option’s ID is correctly passed to the order processing. For order summaries, simply list the chosen method and its final cost.
Example of outputting a single selected method (e.g., on an order confirmation page):
$order = wc_get_order( $order_id );
if ( $order ) {
foreach ( $order->get_shipping_methods() as $method ) {
echo "<p><strong>Shipping Method:</strong> " . esc_html( $method->get_method_title() ) . "<br>";
echo "<strong>Shipping Cost:</strong> " . wc_price( $method->get_total() ) . "</p>";
}
}
Step 4: Customize Shipping Method Behavior
Implement Conditional Logic for Shipping Method Availability
You can programmatically control when certain shipping methods are available using WooCommerce hooks. The woocommerce_package_rates
filter is powerful for this. It allows you to modify the array of shipping rates before they are displayed to the customer.
add_filter( 'woocommerce_package_rates', 'filter_shipping_methods_conditionally', 10, 2 );
function filter_shipping_methods_conditionally( $rates, $package ) {
// Example: Disable 'Local Pickup' if cart total is less than $50
$cart_total = WC()->cart->get_subtotal();
if ( $cart_total < 50 ) {
foreach ( $rates as $rate_id => $rate ) {
if ( 'local_pickup' === $rate->method_id ) {
unset( $rates[ $rate_id ] ); // Remove the local pickup rate
}
}
}
// Example: Add a custom message to Free Shipping if available
foreach ( $rates as $rate_id => $rate ) {
if ( 'free_shipping' === $rate->method_id ) {
$rates[ $rate_id ]->label .= ' (Orders over $100)';
}
}
return $rates;
}
This filter gives you granular control to remove, modify, or even add new rates based on cart contents, user roles, shipping address, or any other custom logic you require.
Integrate with Third-Party Shipping APIs for Real-time Rates
For complex shipping needs (e.g., live rates from UPS, FedEx, DHL, or advanced freight calculations), you’ll typically use a dedicated WooCommerce extension. These extensions hook into the shipping calculation process and make API calls to external services. While the specifics depend on the extension, the general principle is that the extension will register itself as a shipping method, and when WooCommerce requests rates for a package, the extension queries the third-party API and returns the real-time rates. You generally won’t write custom code for these integrations unless developing your own API connector.
If you were to develop a custom integration, you would typically create a custom shipping method class that extends WC_Shipping_Method
and implements a calculate_shipping()
method. Inside this method, you would make your API calls and add the returned rates using $this->add_rate()
.
FAQs
Q: Why are no shipping methods showing up on my cart/checkout page?
A: This is a common issue. First, check your WooCommerce shipping zone settings (WooCommerce > Settings > Shipping). Ensure you have a shipping zone that matches the customer’s shipping address (or the default location if no address is entered). Within that zone, make sure you have at least one shipping method enabled (e.g., Flat Rate, Free Shipping). Also, verify that the products in the cart are shippable and have weight/dimensions if your methods rely on them.
Q: How can I get the shipping method chosen by the customer after they complete an order?
A: After an order is placed, the chosen shipping method is stored with the order. You can retrieve it programmatically using the WC_Order
object. If you have the order ID, use $order = wc_get_order( $order_id );
. Then, iterate through the shipping items associated with the order: foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) { ... }
. Inside the loop, $shipping_item->get_method_title()
will give you the displayed name, and $shipping_item->get_total()
will give you the cost.
Q: Can I set different shipping costs for different product categories?
A: WooCommerce’s built-in Flat Rate method has some basic cost options, but for category-specific rates, you’ll typically need a more advanced solution. The most common way is to use a “Table Rate Shipping” plugin (e.g., WooCommerce Table Rate Shipping by WooCommerce, or Flexible Shipping). These plugins allow you to define complex rules based on product categories, weight, dimensions, cart totals, and more.
Q: What’s the difference between method_id
and instance_id
for a shipping method?
A: The method_id
refers to the core type of shipping method (e.g., ‘flat_rate’, ‘free_shipping’, ‘local_pickup’). The instance_id
is a unique identifier for a specific instance of that method within a shipping zone. For example, if you have two “Flat Rate” methods in the same zone (perhaps one for standard shipping and one for express), they would both have a method_id
of ‘flat_rate’ but distinct instance_id
s.