Как отключить платную доставку в WooCommerce при самовывозе

Типичный сценарий: в магазине есть самовывоз, но одновременно подключены платные способы доставки — курьер, СДЭК, Boxberry, фиксированная ставка. Проблема появляется, когда покупатель выбирает самовывоз, а WooCommerce всё равно показывает лишние варианты или считает их в итоговой сумме. Ниже — рабочие способы, как убрать платную доставку при самовывозе без лишней магии и с проверкой результата.

Когда это действительно ломает оформление заказа

Чаще всего ошибка выглядит не как «доставка не работает», а как несоответствие логики. Пользователь выбирает самовывоз, но:

  • видит одновременно самовывоз и платные методы;
  • сумма доставки не обнуляется;
  • на странице оформления заказа остаются старые расчёты после смены адреса;
  • платный метод становится выбранным по умолчанию, хотя нужен только самовывоз.

Если у вас включены зоны доставки, это особенно заметно: WooCommerce честно отдаёт все методы, которые подходят под зону, а бизнес-логика «при самовывозе платную доставку не показывать» уже не входит в стандартное поведение.

Что проверить до правки кода

Перед изменениями посмотрите на базовую конфигурацию. Иногда проблема не в коде, а в настройках зоны доставки.

  • В WooCommerce → Настройки → Доставка проверьте, что самовывоз добавлен как отдельный метод в нужной зоне.
  • Убедитесь, что платные методы не продублированы в нескольких зонах с пересечением адресов.
  • Проверьте, не включён ли плагин, который переопределяет расчёт доставки или кэширует checkout-данные.
  • Если используется кастомная тема, временно переключитесь на стандартную и проверьте поведение.

Как решить задачу через фильтр WooCommerce

Самый надёжный путь — отфильтровать список доступных методов доставки и оставить только local_pickup, когда он выбран или когда нужно принудительно скрыть платные варианты в этой зоне. Для этого подходит фильтр woocommerce_package_rates.

Ниже пример, который оставляет только самовывоз, если он доступен в посылке. Код лучше добавить в мини-плагин или в functions.php дочерней темы.

add_filter('woocommerce_package_rates', function ($rates, $package) {
    $pickup_rates = [];

    foreach ($rates as $rate_id => $rate) {
        if (strpos($rate_id, 'local_pickup') === 0) {
            $pickup_rates[$rate_id] = $rate;
        }
    }

    if (!empty($pickup_rates)) {
        return $pickup_rates;
    }

    return $rates;
}, 100, 2);

Что делает этот код: если в доступных методах есть самовывоз, он оставляет только его. Если самовывоза нет, список не трогается. Это безопаснее, чем жёстко удалять все платные методы в любой ситуации.

Если нужно скрывать платную доставку только при выборе самовывоза

Иногда самовывоз и платные методы должны быть видны сначала, а после выбора самовывоза платные варианты нужно убрать. Тогда удобнее ориентироваться на выбранный метод из сессии WooCommerce.

add_filter('woocommerce_package_rates', function ($rates, $package) {
    if (!function_exists('WC') || !WC()->session) {
        return $rates;
    }

    $chosen_methods = WC()->session->get('chosen_shipping_methods');
    $chosen_method = isset($chosen_methods[0]) ? $chosen_methods[0] : '';

    if (strpos($chosen_method, 'local_pickup') !== 0) {
        return $rates;
    }

    $filtered = [];
    foreach ($rates as $rate_id => $rate) {
        if (strpos($rate_id, 'local_pickup') === 0) {
            $filtered[$rate_id] = $rate;
        }
    }

    return !empty($filtered) ? $filtered : $rates;
}, 100, 2);

Этот вариант полезен, если у вас несколько способов доставки и самовывоз должен работать как переключатель, а не как постоянное ограничение.

Диагностика: почему код может не сработать

Если после вставки кода ничего не изменилось, не спешите искать конфликт в WooCommerce. Сначала проверьте, какой именно ID у метода доставки. У самовывоза он обычно начинается с local_pickup, но в конкретной зоне может быть несколько экземпляров с разными ID.

Для быстрой диагностики можно временно вывести список rate ID в лог:

add_filter('woocommerce_package_rates', function ($rates, $package) {
    if (defined('WP_DEBUG') && WP_DEBUG) {
        error_log('Shipping rates: ' . implode(', ', array_keys($rates)));
    }

    return $rates;
}, 1, 2);

После этого откройте страницу оформления заказа и посмотрите wp-content/debug.log. Если там нет local_pickup, значит проблема в настройках зоны доставки, а не в фильтре.

Пошаговая схема внедрения

  1. Проверьте, что самовывоз добавлен в нужную зону доставки.
  2. Определите, нужно ли скрывать платные методы всегда или только после выбора самовывоза.
  3. Добавьте код в дочернюю тему или мини-плагин, а не в основную тему.
  4. Очистите кэш сайта и кэш браузера, если на checkout есть оптимизация или отложенная загрузка.
  5. Протестируйте оформление заказа в режиме инкогнито.

Мини-плагин вместо functions.php

Если не хотите зависеть от темы, проще оформить решение как маленький плагин. Это удобно для переноса между проектами.

<?php
/**
 * Plugin Name: WooCommerce Local Pickup Shipping Filter
 */

add_filter('woocommerce_package_rates', function ($rates, $package) {
    $pickup_rates = [];

    foreach ($rates as $rate_id => $rate) {
        if (strpos($rate_id, 'local_pickup') === 0) {
            $pickup_rates[$rate_id] = $rate;
        }
    }

    return !empty($pickup_rates) ? $pickup_rates : $rates;
}, 100, 2);

Как проверить, что решение сработало

Проверка должна быть не визуальной, а функциональной. Иначе легко пропустить ситуацию, когда на одном адресе всё работает, а на другом — нет.

  • Откройте checkout в режиме инкогнито.
  • Выберите адрес, который попадает в зону доставки с самовывозом.
  • Убедитесь, что при наличии самовывоза платные методы не отображаются.
  • Смените адрес на другой, где самовывоз не предусмотрен, и проверьте, что доставка снова считается по обычным правилам.
  • Проверьте итоговую сумму заказа до и после смены метода доставки.

Если у вас включён AJAX на checkout, важно сделать ещё один тест: сменить метод доставки без перезагрузки страницы и убедиться, что WooCommerce пересчитывает корзину корректно.

Сравнение подходов: плагин, код, компромисс

ПодходКогда подходитПлюсыМинусы
Код через фильтрНужна точная логика без лишних зависимостейКонтроль, предсказуемость, нет лишнего интерфейсаНужно аккуратно тестировать зоны и ID методов
Плагин доставкиНужны сложные правила по весу, городу, складуБольше готовой логики, меньше ручного кодаМожет добавлять лишнюю сложность и конфликтовать с темой
Компромисс через настройки зоныСамовывоз нужен только в отдельных регионахПросто и без кодаНе решает сценарий, когда логика зависит от выбранного метода

Частые ошибки и как их исправить

Скрывают не тот метод доставки

Ошибка возникает, когда разработчик сравнивает не ID метода, а его название в админке. В WooCommerce нужно ориентироваться на технический ID, например local_pickup, а не на человекочитаемую подпись.

Код добавили в родительскую тему

После обновления темы правка исчезает. Для такого кода лучше использовать дочернюю тему или мини-плагин.

Не учитывают кэш checkout-страницы

Если на сайте есть агрессивный кэш или оптимизация JS, WooCommerce может показывать старые расчёты. В этом случае нужно исключить страницу оформления заказа из кэширования и проверить, не ломает ли оптимизатор AJAX-запросы.

Оставили несколько пересекающихся зон доставки

Тогда самовывоз может появляться в неожиданной зоне, а фильтр будет работать не так, как ожидается. Проверьте порядок зон и адреса, которые в них попадают.

Безопасность и производительность

Сам фильтр лёгкий, но проблема обычно не в нём, а в окружении. Не добавляйте тяжёлую логику в woocommerce_package_rates: там не стоит делать запросы к внешним API или сложные вычисления по каждому AJAX-обновлению checkout.

Если нужно более сложное правило — например, скрывать платную доставку только для определённых категорий товаров или складов — лучше вынести расчёт в отдельную функцию и кешировать результат на уровне транзиентов или сессии WooCommerce, если это оправдано логикой магазина.

Для проектов, где часто приходится чистить дубли, оптимизировать WooCommerce и убирать лишние сущности из админки, полезно держать под рукой инструменты вроде Clearfy Pro: он не решает задачу доставки напрямую, но помогает убрать часть технического шума на сайте и быстрее отлавливать конфликты. Если нужен такой инструмент, смотрите Clearfy Pro.

Если после внедрения логики самовывоза у вас всё ещё остаются нестабильные расчёты доставки, проверьте не только код, но и плагины кэширования, оптимизации checkout и сторонние модули доставки. В WooCommerce именно они чаще всего создают ощущение, что фильтр «не работает», хотя на самом деле проблема в пересчёте корзины.

Как удалить или скрыть свойства товара WooCommerce в админке WordPress
29.04.2026
Как отключить платную доставку в WooCommerce при самовывозе
09.08.2026
Как создать динамические таблицы в WordPress с помощью WPDataTables
04.04.2026
Удаление и оптимизация базы данных WordPress без плагинов: пошаговое руководство
18.02.2026
Как добавить автоматическое удаление старых записей через PHP в WordPress
17.03.2026