I’m working on a WooCommerce store where we offer free shipping for orders over €100. However, when a partial refund is processed from an order with multiple products and for example 1 product is returned and the total order value drops below €100, the shipping method is not recalculated. The "Free Shipping" option remains, but it should revert to a flat rate of €9 for orders under €100.
EXAMPLE:
Product 1 costs 33€
Product 2 costs 44€
Product 3 costs 55€
Total order price: 132€ = Freeshipping
Client requests to return product 2 so the total value changes under the 100€ on the order.
Total order price: 88€ + 9€ standard shippingcosts.
But now it keeps saying freeshipping when I return 1 product what is incorrect.
add_action('woocommerce_order_refunded', 'adjust_shipping_after_refund', 10, 2);
function adjust_shipping_after_refund($order_id, $refund_id) {
$order = wc_get_order($order_id);
$total_sale_price = 0;
// Calculate new total after refund
foreach ($order->get_items() as $item_id => $item) {
$product = $item->get_product();
$quantity = $item->get_quantity();
$sale_price = $product->get_sale_price();
if ($sale_price) {
$total_sale_price += $sale_price * $quantity;
} else {
$total_sale_price += $product->get_regular_price() * $quantity;
}
}
// If the total is under €100, apply flat rate shipping
if ($total_sale_price < 100) {
foreach ($order->get_shipping_methods() as $shipping_item_id => $shipping_item) {
if ($shipping_item->get_method_id() === 'free_shipping') {
$order->remove_item($shipping_item_id); // Remove free shipping
}
}
// Add flat rate shipping of €9
if (empty($order->get_shipping_methods())) {
$rate = new WC_Shipping_Rate('flat_rate', 'Verzendkosten', 9, array(), 'flat_rate');
$shipping_item = new WC_Order_Item_Shipping();
$shipping_item->set_props(array(
'method_title' => $rate->get_label(),
'method_id' => $rate->get_method_id(),
'total' => wc_format_decimal($rate->get_cost())
));
$order->add_item($shipping_item);
}
// Recalculate totals
$order->calculate_totals();
$order->save();
}
}
Here’s what I’ve tried so far:
- Hooked into the woocommerce_order_refunded action to recalculate shipping costs.
- Removed the free shipping method when the total is less than €100.
- Added a new shipping method with a flat rate of €9.
What am I missing or doing wrong? How can I force WooCommerce to properly update the shipping method dynamically after a refund?
2
Answers
The issue is that WooCommerce isn’t automatically recalculating the shipping after a partial refund, leading to
Free Shipping
being incorrectly applied when the total falls below €100. The solution involves adjusting the total and shipping methods dynamically after a refund.Here’s the updated code:
There are some mistakes, complications, unnecessary and missing things in your code.
Try the following instead:
It should work.
Related: Add update or remove WooCommerce shipping order items