在 WooCommerce 结帐页面中,更改付款类型时运费不会更新,但更新地址字段时运费会发生变化。
要求:
如果付款方式为COD,则运费为100; 如果付款类型是UPI,则运费为70;
以下是我们用来满足要求的两个文件
// Adjust shipping cost based on the selected payment method
add_filter('woocommerce_package_rates', 'adjust_shipping_based_on_payment_method', 10, 2);
function adjust_shipping_based_on_payment_method($rates, $package) {
$chosen_payment_method = WC()->session->get('chosen_payment_method');
if ($chosen_payment_method) {
foreach ($rates as $rate_key => $rate) {
if ($chosen_payment_method === 'cod') {
$rates[$rate_key]->cost = 100;
} elseif ($chosen_payment_method === 'wc-upi') {
$rates[$rate_key]->cost = 70;
}
}
}
return $rates;
}
// Enqueue custom JavaScript
function enqueue_custom_shipping_scripts() {
if (is_checkout()) {
wp_enqueue_script('custom-shipping-js', plugin_dir_url(__FILE__) . 'custom-shipping.js', array('jquery', 'wc-checkout'), '1.0', true);
wp_localize_script('custom-shipping-js', 'customShippingParams', array(
'ajax_url' => admin_url('admin-ajax.php'),
));
}
}
add_action('wp_enqueue_scripts', 'enqueue_custom_shipping_scripts');
// Handle AJAX request to update shipping cost
add_action('wp_ajax_update_shipping_cost', 'update_shipping_cost');
add_action('wp_ajax_nopriv_update_shipping_cost', 'update_shipping_cost');
function update_shipping_cost() {
if (isset($_POST['payment_method'])) {
WC()->session->set('chosen_payment_method', sanitize_text_field($_POST['payment_method']));
}
WC()->cart->calculate_totals();
WC()->cart->maybe_set_cart_cookies();
wp_send_json_success();
}
jQuery(document).ready(function($) {
// Detect changes in payment method selection
$('form.checkout').on('change', 'input[name="payment_method"]', function() {
var paymentMethod = $(this).val();
console.log("Selected Payment Method: " + paymentMethod); // Log selected payment method
// Update session and trigger checkout update via AJAX
$.ajax({
type: 'POST',
url: customShippingParams.ajax_url,
data: {
action: 'update_shipping_cost',
payment_method: paymentMethod,
},
success: function(response) {
console.log("AJAX Response: ", response); // Log the response
if (response.success) {
console.log('Success');
// Trigger WooCommerce update checkout event
$(document.body).trigger('update_checkout');
// location.reload(true);
}
},
error: function(error) {
console.error('AJAX error:', error); // Debugging
}
});
});
// Prevent the 'update_checkout' event from being triggered infinitely
var isUpdating = false;
$(document.body).on('update_checkout', function() {
if (!isUpdating) {
isUpdating = true;
$('body').trigger('update_checkout');
isUpdating = false;
}
});
});
我做错了什么?
以下代码仅适用于经典结帐(但不适用于新的结帐块)。 有关信息,请参阅以下方法切换回旧版经典结账(简码)。
您的代码比需要的复杂得多,不需要自定义 Ajax,并且缺少重要的东西。
在下面的第一个功能(设置)中,我们通过付款方式 ID 定义运费。
尝试以下方法:
// Utility function (settings: payment ID / cost pairs)
function get_shipping_cost_for_chosen_payment_method() {
$payment_id = WC()->session->get('chosen_payment_method');
$data_costs = array(
'cod' => 100,
'wc-upi' => 70,
);
return isset($data_costs[$payment_id]) ? floatval($data_costs[$payment_id]) : false;
}
// Change shipping cost based on the chosen payment method
add_filter('woocommerce_package_rates', 'adjust_shipping_based_on_payment_method', 10, 2);
function adjust_shipping_based_on_payment_method($rates, $package) {
if ( $new_cost = get_shipping_cost_for_chosen_payment_method() ) {
foreach ($rates as $rate_key => $rate) {
if ( $rate->cost > 0 && $new_cost > 0 ) {
$rates[$rate_key]->cost = $new_cost;
}
}
}
return $rates;
}
// Update checkout on payment method change (jQuery)
add_action( 'woocommerce_checkout_init', 'trigger_update_checkout_on_payment_method_change' );
function trigger_update_checkout_on_payment_method_change(){
wc_enqueue_js("$('form.checkout').on( 'change', 'input[name=payment_method]', function(){
$(document.body).trigger('update_checkout');
});");
}
// Refresh shipping methods on payment method change (Mandatory)
add_action('woocommerce_checkout_update_order_review', 'payment_method_change_refresh_shipping_methods' );
function payment_method_change_refresh_shipping_methods() {
if ( WC()->session->get('chosen_payment_method') ) {
$packages = WC()->cart->get_shipping_packages();
foreach ($packages as $package_key => $package ) {
WC()->session->set( 'shipping_for_package_' . $package_key, false );
}
}
}
代码位于子主题的 function.php 文件中(或插件中)。已测试并有效。