wpload.ru wordpress WPLoad.ru

Как показывать разные способы доставки в WooCommerce только для определённых зон

В WooCommerce часто всплывает одна и та же задача: для Москвы нужны курьер и самовывоз, для регионов — только СДЭК или Почта России, а для отдельной зоны вообще должен быть доступен один способ доставки. Если оставить все методы сразу, покупатель видит лишние варианты, а менеджер потом вручную исправляет заказы. Это неудобно и для корзины, и для аналитики.

Решается задача двумя рабочими путями: через настройки зон доставки и через код, если нужна логика сложнее стандартной. Ниже — как понять, что именно у вас ломается, как настроить фильтрацию способов доставки и как проверить результат без догадок.

Когда проблема действительно в зонах доставки

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

Типичные симптомы

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

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

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

Настройка через интерфейс: когда кода не нужно

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

Пошагово

  1. Откройте WooCommerce → Настройки → Доставка → Зоны доставки.
  2. Создайте зону, например Москва, и укажите регион: город, область или индекс.
  3. Добавьте в неё только нужные методы: курьер, самовывоз, экспресс-доставка.
  4. Создайте отдельную зону для регионов и добавьте туда СДЭК, Почту России или другой метод.
  5. Проверьте, что зона Остальной мир не перехватывает адрес раньше нужной зоны.

Если вам нужно просто скрыть метод доставки для части адресов, этого обычно достаточно. Но если логика зависит не только от региона, а ещё от суммы корзины, категории товаров или наличия конкретного товара, без кода уже не обойтись.

Как скрыть способы доставки по условиям через код

Ниже — рабочий пример для functions.php дочерней темы или для собственного мини-плагина. Он оставляет только нужные методы в зависимости от зоны доставки и суммы корзины. Это удобнее, чем пытаться собрать всё через десяток отдельных правил в интерфейсе.

add_filter( 'woocommerce_package_rates', 'wpload_filter_shipping_methods_by_zone', 100, 2 );
function wpload_filter_shipping_methods_by_zone( $rates, $package ) {
	if ( empty( $rates ) ) {
		return $rates;
	}

	$chosen_zone = WC_Shipping_Zones::get_zone_matching_package( $package );
	$zone_name    = $chosen_zone ? $chosen_zone->get_zone_name() : '';
	$cart_total   = WC()->cart ? (float) WC()->cart->get_cart_contents_total() : 0;

	// Пример: для зоны "Москва" оставляем только курьер и самовывоз.
	if ( 'Москва' === $zone_name ) {
		foreach ( $rates as $rate_id => $rate ) {
			if ( false === strpos( $rate_id, 'flat_rate' ) && false === strpos( $rate_id, 'local_pickup' ) ) {
				unset( $rates[ $rate_id ] );
			}
		}
	}

	// Пример: бесплатную доставку показываем только от 5000 руб. и только в зоне "Москва".
	if ( 'Москва' === $zone_name && $cart_total < 5000 ) {
		foreach ( $rates as $rate_id => $rate ) {
			if ( false !== strpos( $rate_id, 'free_shipping' ) ) {
				unset( $rates[ $rate_id ] );
			}
		}
	}

	return $rates;
}

Этот код не создаёт новые методы доставки и не подменяет расчёт WooCommerce. Он только фильтрует уже рассчитанные варианты. Это важно: если метод не настроен в зоне, код его не вернёт.

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

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

add_filter( 'woocommerce_package_rates', 'wpload_hide_shipping_for_specific_category', 100, 2 );
function wpload_hide_shipping_for_specific_category( $rates, $package ) {
	$has_fragile = false;

	foreach ( $package['contents'] as $item ) {
		$product_id = $item['product_id'];
		if ( has_term( 'fragile', 'product_cat', $product_id ) ) {
			$has_fragile = true;
			break;
		}
	}

	if ( $has_fragile ) {
		foreach ( $rates as $rate_id => $rate ) {
			if ( false !== strpos( $rate_id, 'local_pickup' ) ) {
				unset( $rates[ $rate_id ] );
			}
		}
	}

	return $rates;
}

Здесь важно использовать реальный slug категории, а не её название. Если slug другой, фильтр просто не сработает.

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

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

Как проверить, что всё работает

После внедрения не ограничивайтесь визуальной проверкой на одной странице. Доставка в WooCommerce пересчитывается по адресу, составу корзины и сессии пользователя, поэтому тестировать нужно несколько сценариев.

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

Если используете отладку, можно временно посмотреть, какие зоны и методы возвращает WooCommerce. Для этого удобно включить логирование в собственном коде через error_log() или WC_Logger, но не оставляйте такие записи на продакшене надолго.

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

Неправильный порядок зон доставки

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

Проверка по названию метода вместо ID

У методов доставки есть внутренние ID, и они не всегда совпадают с тем, как метод называется в админке. Если вы фильтруете по строке, а не по реальному ID, код может работать нестабильно. Лучше сначала посмотреть, какие ключи приходят в $rates, и уже потом писать условие.

Кэш на checkout или в корзине

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

Слишком жёсткая логика в одном фильтре

Когда в одном callback смешаны зона, сумма, категория и пользовательская роль, сопровождать код становится трудно. Разбейте условия на отдельные блоки и оставьте комментарии рядом с каждым правилом.

Практические советы по безопасности и производительности

  • Не вставляйте такой код в родительскую тему: после обновления он потеряется.
  • Если правил становится много, вынесите их в отдельный мини-плагин.
  • Не делайте тяжёлые запросы к базе внутри woocommerce_package_rates: этот фильтр вызывается часто.
  • Проверяйте наличие WC()->cart, если код может сработать вне фронтенда.
  • После обновления WooCommerce перепроверяйте логику на тестовом заказе, особенно если используете сторонний плагин доставки.

Если вам нужно не только скрывать способы доставки, но и убирать лишние элементы интерфейса в магазине, полезно держать под рукой инструменты для чистки шаблонов и дублей. Например, Clearfy Pro уместен там, где нужно убрать лишний технический шум и не плодить конфликтующие настройки: https://wpshop.ru/plugins/clearfy.

Когда лучше не писать код

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

Код оправдан, когда правило однотипное и повторяется в нескольких зонах: например, в одном регионе показывать только курьера, в другом — только пункт выдачи, а бесплатную доставку скрывать до определённой суммы. Тогда фильтр в теме или мини-плагине проще поддерживать, чем набор разрозненных настроек в админке.

×

Время действовать!

Суперцены на
WordPress!

-20%
на премиум темы

Не упусти шанс ⋙