Ẩn phí Shipping khi đơn hàng Free Shipping trên WooCommerce

Woocommerce An phi Shipping khi don hang da duoc Free Shipping

Bạn đang chạy shop WooCommerce và gặp tình trạng khó chịu: khách hàng đã đủ điều kiện nhận freeship nhưng trang thanh toán vẫn hiển thị tất cả các phương thức vận chuyển khác. Điều này không chỉ gây rối mắt mà còn khiến khách hàng bối rối, thậm chí chọn nhầm phương thức tính phí mặc dù họ được miễn phí. Trong bài viết này, mình sẽ hướng dẫn bạn cách ẩn hoàn toàn các phương thức shipping tính phí khi đơn hàng đã được áp dụng Free Shipping trên WooCommerce, chỉ bằng một đoạn code đơn giản.

Vấn đề: Tại sao phí Shipping vẫn hiển thị khi đã có Free Shipping?

Mặc định WooCommerce không tự động ẩn các phương thức vận chuyển tính phí khi điều kiện Free Shipping được đáp ứng. Nghĩa là nếu bạn cấu hình miễn phí vận chuyển cho đơn hàng từ 500.000đ trở lên, thì khi khách đạt mốc đó, WooCommerce vẫn hiển thị cả Free Shipping lẫn các phương thức khác như Giao hàng tiêu chuẩn, Giao hàng nhanh, v.v. Đây là một trong những nhiều nghịch lý với WooCommerce mà anh em thường gặp phải.

Phí Shipping vẫn hiển thị dù đơn hàng đã đủ điều kiện Free Shipping

Đơn hàng đã được Free Shipping rồi mà vẫn hiển thị thêm phí vận chuyển khác, thật là phiền toái.

Giải pháp: Ẩn phí Shipping khi Free Shipping sẵn sàng

Cách tốt nhất và an toàn nhất là sử dụng filter woocommerce_package_rates của WooCommerce. Đoạn code dưới đây sẽ kiểm tra danh sách các phương thức shipping hiện có, nếu phát hiện phương thức free_shipping thì chỉ giữ lại nó và loại bỏ tất cả các phương thức khác.

Cách 1: Dùng code thêm vào file functions.php

Anh em tìm đến file functions.php trong theme (hoặc child theme) đang sử dụng và thêm đoạn code sau vào:

/**
 * Ẩn tất cả phương thức shipping tính phí
 * khi phương thức Free Shipping sẵn sàng
 */
function my_hide_shipping_when_free_is_available( $rates ) {
    // Tạo mảng rỗng để chứa phương thức free shipping
    $free = array();
    
    // Lặp qua tất cả các phương thức shipping hiện có
    foreach ( $rates as $rate_id => $rate ) {
        // Nếu tìm thấy free_shipping, lưu lại và thoát vòng lặp
        if ( 'free_shipping' === $rate->method_id ) {
            $free[ $rate_id ] = $rate;
            break;
        }
    }
    
    // Nếu có free shipping thì chỉ trả về free shipping
    // Ngược lại trả về danh sách gốc (các phương thức bình thường)
    return ! empty( $free ) ? $free : $rates;
}
// Thêm filter với priority 100 để đảm bảo chạy sau các filter khác
add_filter( 'woocommerce_package_rates', 'my_hide_shipping_when_free_is_available', 100 );

Giải thích code chi tiết:

Hàm my_hide_shipping_when_free_is_available nhận tham số $rates là mảng chứa tất cả các phương thức vận chuyển khả dụng cho gói hàng hiện tại. Nó lặp qua mảng này để tìm phương thức có method_idfree_shipping. Nếu tìm thấy, hàm chỉ trả về mảng chứa duy nhất phương thức miễn phí đó. Nếu không tìm thấy free shipping nào (ví dụ khách chưa đủ điều kiện), hàm trả về toàn bộ danh sách phương thức gốc.

Tham số 100 trong add_filter là priority, cho phép filter này chạy sau các filter khác của plugin hoặc theme, đảm bảo logic ẩn shipping luôn được ưu tiên.

Cách 2: Dùng plugin (cho người không rành code)

Nếu bạn không muốn chỉnh sửa code, có thể cài đặt plugin WooCommerce Free Shipping Coupons từ thư mục plugin WordPress. Plugin này cho phép bạn cấu hình miễn phí vận chuyển theo mã coupon hoặc theo giá trị đơn hàng mà không cần viết code. Tuy nhiên cách này chỉ phù hợp nếu bạn muốn kiểm soát freeship qua coupon, còn nếu bạn cần logic ẩn tự động thì code ở Cách 1 vẫn là lựa chọn linh hoạt nhất.

Cách xóa cache shipping (Bước bắt buộc)

Đây là bước quan trọng nhất mà nhiều người bỏ quên. WooCommerce cache các phương thức shipping vào database (transients). Sau khi thêm hoặc thay đổi code liên quan đến shipping, bạn bắt buộc phải xóa cache để code mới có hiệu lực. Nếu không xóa, bạn sẽ không thấy thay đổi nào.

Cách xóa cache shipping trong WooCommerce:

1. Vào menu WooCommerce > Status > Tools

2. Tìm đến mục WooCommerce Transients

3. Bấm nút Clear transients

Sau khi xóa xong, hãy load lại trang checkout và thêm sản phẩm vào giỏ hàng để kiểm tra kết quả.

Kết quả sau khi ẩn phí Shipping khi có Free Shipping

Chỉ còn hiển thị Free Shipping, tất cả các phương thức tính phí đã bị ẩn hoàn toàn.

Troubleshooting: Code không hoạt động?

Nếu sau khi thêm code mà phí shipping vẫn hiển thị, hãy kiểm tra các nguyên nhân phổ biến sau:

1. Chưa xóa WooCommerce Transients: Đây là nguyên nhân phổ biến nhất. WooCommerce cache shipping rates, nên bạn phải xóa cache sau mỗi lần thay đổi code. Vào WooCommerce > Status > Tools > Clear transients.

2. Sai vị trí thêm code: Đảm bảo bạn thêm code vào file functions.php của child theme, không phải parent theme. Nếu bạn thêm vào parent theme thì khi theme update, code sẽ bị mất. Nếu bạn dùng theme Flatsome, file functions.php của child theme nằm ở /wp-content/themes/flatsome-child/functions.php.

3. Có plugin nào đó đang override filter: Một số plugin shipping như Table Rate Shipping, FedEx Shipping, UPS Shipping có thể thêm các phương thức shipping riêng không sử dụng method_idfree_shipping. Trong trường hợp đó, bạn cần kiểm tra method_id thực tế bằng cách thêm error_log( print_r( $rates, true ) ); vào đầu hàm để xem danh sách phương thức hiện có.

4. Sai tên phương thức free shipping: Đoạn code trên kiểm tra method_idfree_shipping. Nếu bạn tạo nhiều phương thức free shipping khác nhau, tất cả đều dùng chung method_idfree_shipping, nên code sẽ hoạt động đúng cho tất cả.

Best practices khi làm việc với WooCommerce Shipping

Luôn dùng child theme: Mọi code custom nên được thêm vào child theme để không bị mất khi update parent theme. Nếu chưa có child theme, hãy tạo một bằng plugin Child Theme Configurator hoặc tạo thủ công.

Sử dụng plugin Code Snippets: Nếu bạn không muốn chỉnh sửa file functions.php trực tiếp, hãy cài plugin Code Snippets (miễn phí trên WordPress.org). Plugin này cho phép bạn thêm các đoạn code PHP một cách an toàn, quản lý dễ dàng và không sợ lỗi trắng trang.

Backup trước khi thay đổi: Luôn backup website trước khi thêm code custom. Bạn có thể dùng plugin Duplicator, UpdraftPlus hoặc backup qua hosting control panel.

Kiểm tra kỹ trước khi đưa lên production: Thử code trên môi trường staging trước để đảm bảo không gây lỗi trang thanh toán. Lỗi ở trang checkout có thể ảnh hưởng trực tiếp đến doanh thu của bạn.

Mở rộng: Ẩn shipping theo điều kiện cụ thể

Nếu bạn muốn ẩn shipping chỉ khi tổng đơn hàng lớn hơn một giá trị cụ thể (thay vì phụ thuộc vào phương thức free shipping), bạn có thể sử dụng đoạn code mở rộng sau:

/**
 * Ẩn shipping khi tổng đơn hàng lớn hơn ngưỡng
 */
function my_hide_shipping_above_threshold( $rates, $package ) {
    $threshold = 500000; // Ngưỡng: 500.000đ
    $cart_total = WC()->cart->get_cart_contents_total();
    
    if ( $cart_total >= $threshold ) {
        $free = array();
        foreach ( $rates as $rate_id => $rate ) {
            if ( 'free_shipping' === $rate->method_id ) {
                $free[ $rate_id ] = $rate;
            }
        }
        if ( ! empty( $free ) ) {
            return $free;
        }
    }
    return $rates;
}
add_filter( 'woocommerce_package_rates', 'my_hide_shipping_above_threshold', 100, 2 );

Đoạn code này thêm tham số $package và kiểm tra tổng giá trị giỏ hàng. Chỉ khi tổng đơn hàng đạt ngưỡng 500.000đ, nó mới thực hiện logic ẩn shipping. Bạn có thể thay đổi giá trị $threshold theo nhu cầu của shop.

Tổng kết

Ẩn phí shipping khi đơn hàng đã đủ điều kiện Free Shipping là một cải thiện UX nhỏ nhưng mang lại hiệu quả lớn cho trải nghiệm mua sắm của khách hàng. Chỉ với một đoạn code ngắn gọn thêm vào functions.php hoặc plugin Code Snippets, bạn đã giải quyết được vấn đề này. Đừng quên xóa WooCommerce Transients sau khi thêm code để thay đổi có hiệu lực ngay lập tức.

Chúc anh em thành công! Xem thêm: Hidden Field on WooCommerce Checkout Page.

Nhiều Lượt xem

Giới thiệuLiên hệChính sách Biên tập