You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改WooCommerce代码实现单个商品运费单独计算

修改WooCommerce运费计算函数以单独计算单个商品运费

Great question! Your approach of backing up the current cart, temporarily clearing it to calculate shipping for just the target product, then restoring the original cart is spot-on. Here's the modified get_shipping_text function that implements this logic, with key steps commented for clarity:

/* function for calculate shipping */
public function get_shipping_text($shipping_method, $country) {
    global $woocommerce, $post;
    $returnResponse = array();

    // 1. 备份原购物车状态及用户地址信息
    $original_cart = WC()->cart->get_cart();
    $original_shipping_address = WC()->customer->get_shipping();
    $original_billing_address = WC()->customer->get_billing();

    try {
        // 2. 临时清空购物车,确保仅计算目标商品的运费
        WC()->cart->empty_cart();

        // 3. 设置指定国家,保证运费计算基于正确的区域规则
        WC()->customer->set_shipping_country($country);
        WC()->customer->set_billing_country($country);
        WC()->customer->save();

        // 4. 将目标商品添加到临时购物车
        $product_id = sanitize_text_field($_POST["product_id"]);
        $qty = (isset($_POST['current_qty']) && $_POST['current_qty'] > 0) ? $_POST['current_qty'] : 1;
        $variation_id = isset($_POST['variation_id']) ? sanitize_text_field($_POST['variation_id']) : 0;

        if ($variation_id > 0) {
            WC()->cart->add_to_cart($product_id, $qty, $variation_id);
        } else {
            WC()->cart->add_to_cart($product_id, $qty);
        }

        // 5. 计算临时购物车的运费
        WC_Shortcode_Cart::calculate_shipping();
        $packages = WC()->cart->get_shipping_packages();
        $packages = WC()->shipping->calculate_shipping($packages);
        $packages = WC()->shipping->get_packages();

        // 6. 处理运费计算结果
        wc_clear_notices();
        if (isset($packages[0]["rates"][$shipping_method])) {
            $selectedShipping = $packages[0]["rates"][$shipping_method];
            $returnResponse = array(
                "label" => $selectedShipping->label,
                "cost" => wc_price(($selectedShipping->cost)*1.24)
            );
        } else {
            $AllMethod = WC()->shipping->load_shipping_methods();
            if (isset($AllMethod[$shipping_method])) {
                $selectedMethod = $AllMethod[$shipping_method];
                $flag = 0;
                if ($selectedMethod->availability == "including") {
                    foreach ($selectedMethod->countries as $methodcountry) {
                        if ($country == $methodcountry) {
                            $flag = 1;
                            break;
                        }
                    }
                    if ($flag == 0) {
                        $message = $selectedMethod->method_title . " is not available in selected country.";
                        $returnResponse = array("code" => "error", "message" => $message);
                    }
                }
            } else {
                $returnResponse = array("code" => "error", "message" => "Shipping method not found.");
            }
        }
    } catch (Exception $e) {
        // 捕获异常,避免计算出错时破坏原购物车状态
        $returnResponse = array("code" => "error", "message" => "Failed to calculate shipping: " . $e->getMessage());
    } finally {
        // 7. 恢复原购物车及用户地址信息
        WC()->cart->set_cart($original_cart);
        WC()->customer->set_shipping($original_shipping_address);
        WC()->customer->set_billing($original_billing_address);
        WC()->customer->save();

        // 重新计算原购物车运费,确保前端显示正确
        WC_Shortcode_Cart::calculate_shipping();
    }

    return $returnResponse;
}

关键修改说明:

  • 购物车与地址备份恢复:提前保存原购物车内容和用户地址,最终通过finally块确保无论计算成功或失败,都能恢复用户的原始购物状态,不影响正常购物流程。
  • 临时购物车隔离:清空原购物车后仅添加目标商品,彻底避免原购物车中其他商品对运费计算的干扰。
  • 异常处理:通过try...catch捕获计算过程中的错误,返回友好提示的同时保证原购物车状态不受破坏。
  • 区域规则锁定:明确设置用户的配送/账单国家,确保运费计算使用指定区域的物流规则。
  • 恢复后重新计算:恢复原购物车后重新计算运费,保证用户前端看到的运费信息与实际购物车状态一致。

内容的提问来源于stack exchange,提问作者user4697086

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:44:59