Probably you already found a better way to do this since this question is quite old, but so far I could only make it work by getting the price difference manually and then using the method set_total from the order object:
$order = new \WC_Order(2051);
$diff = 0;
foreach ($order->get_items('shipping') as $key => $item) {
wc_update_order_item_meta($key,'cost',0);
wc_update_order_item_meta($key,'total_tax',0);
wc_update_order_item_meta($key,'taxes',[]);
$diff += $item->get_total();
}
$newTotal = $order->calculate_totals() - $diff;
$order->set_total($newTotal);
$order->save();
I will post this here because maybe it could be useful for someone. If you see this and you found a better / cleaner way to solve this I would like to see it :-).