P粉7181655402023-08-14 11:18:03
This code is untested and may need some tweaking, but it can be the correct path to make your external API calls work.
We can try to use the WC_Session variable to set the shipping fee we want to pass:
function handle_api_response( $rates ) { // 在这里编写API调用代码..... if ($response_code === 200){ $response_data = json_decode($response, true); $cost = $response_data['shipments']; if ( $cost > 0 ) { // 将费用设置为WC Session变量 WC()->session->set('shipment_cost', floatval($cost)); // 尝试触发“更新结账”Ajax事件 ?><script>jQuery('body').trigger('update_checkout');</script><?php } } }
Then we can call the WC_Session variable in your hook function:
add_filter('woocommerce_package_rates', 'update_shipping_costs', 10, 2); function update_shipping_costs( $rates, $package ) { foreach ( $rates as $rate_id => $rate ) { // 从Session变量中获取新的费用 $new_cost = WC()->session->get('shipment_cost'); if( isset($rate->cost) && $rate->cost > 0 && $new_cost > 0 ) { $rates[ $rate_id ]->cost = $new_cost; // 设置新的费用 } } return $rates; }
However, we need something else to refresh the cached shipping method in order for it to take effect:
add_action('woocommerce_checkout_update_order_review', 'refresh_shipping_methods'); function refresh_shipping_methods( $post_data ){ $bool = true; // 我们检查Session变量 if ( WC()->session->get('shipment_cost') > 0 ) { $bool = false; } // 与运输方法一起使用时是必需的 foreach ( WC()->cart->get_shipping_packages() as $package_key => $package ){ WC()->session->set( 'shipping_for_package_' . $package_key, $bool ); } WC()->cart->calculate_shipping(); }
Finally, we unset the WC Session variable (on checkout first load and thank you page) :
add_action('wp_footer', 'reset_wc_session_variable'); function reset_wc_session_variable() { if (is_checkout() && WC()->session->get('shipment_cost') > 0) { WC()->session->__unset('shipment_cost'); } }
Put the code into your child theme's functions.php file (or into a plugin). It may work.
Related: Remove shipping costs after checking custom checkbox in WooCommerce checkout