Разработка кастомного плагина WooCommerce
WooCommerce построен на хуках WordPress и предоставляет собственный слой хуков поверх — action и filter для каждого этапа жизненного цикла заказа, товара, платежа. Кастомный плагин WooCommerce — это бизнес-логика, которая не покрывается ни стандартным WooCommerce, ни готовыми аддонами: специфическое ценообразование, интеграция с внутренней ERP, нестандартные типы скидок, кастомные статусы заказов. Разработка плагина средней сложности — 5–10 рабочих дней.
Базовая структура и проверка зависимостей
<?php
/**
* Plugin Name: My WooCommerce Extension
* WC requires at least: 8.0
* WC tested up to: 9.0
*/
defined('ABSPATH') || exit;
// Проверяем наличие WooCommerce перед активацией
register_activation_hook(__FILE__, function () {
if (!class_exists('WooCommerce')) {
deactivate_plugins(plugin_basename(__FILE__));
wp_die('Для работы плагина необходим WooCommerce 8.0+');
}
});
// Безопасная инициализация после загрузки WooCommerce
add_action('woocommerce_loaded', function () {
require_once plugin_dir_path(__FILE__) . 'includes/class-main.php';
My_WC_Plugin::instance();
});
// Декларируем совместимость с HPOS (High-Performance Order Storage)
add_action('before_woocommerce_init', function () {
if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
'custom_order_tables',
__FILE__,
true
);
}
});
Кастомные статусы заказов
// Регистрация статуса
add_action('init', function () {
register_post_status('wc-awaiting-delivery', [
'label' => 'Ожидает отправки',
'public' => true,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => true,
'exclude_from_search' => false,
'label_count' => _n_noop(
'Ожидает отправки <span class="count">(%s)</span>',
'Ожидает отправки <span class="count">(%s)</span>'
),
]);
});
// Добавление в список WooCommerce
add_filter('wc_order_statuses', function (array $statuses): array {
$statuses['wc-awaiting-delivery'] = 'Ожидает отправки';
return $statuses;
});
// Цвет в списке заказов
add_filter('woocommerce_admin_order_statuses_list_badge', function (array $badges): array {
$badges['awaiting-delivery'] = '#f59e0b'; // amber
return $badges;
});
// Email при переходе в новый статус
add_action('woocommerce_order_status_awaiting-delivery', function (int $order_id): void {
$order = wc_get_order($order_id);
// отправка письма клиенту
WC()->mailer()->customer_new_account($order->get_billing_email());
});
Кастомная система скидок
Пример: скидка на основе накопленных заказов клиента:
add_filter('woocommerce_cart_totals_coupon_label', '__return_false'); // скрываем стандартный купон
add_action('woocommerce_cart_calculate_fees', function (WC_Cart $cart): void {
if (is_admin() && !defined('DOING_AJAX')) return;
$user_id = get_current_user_id();
if (!$user_id) return;
$total_spent = wc_get_customer_total_spent($user_id);
$discount_pct = 0;
if ($total_spent >= 100000) {
$discount_pct = 10;
} elseif ($total_spent >= 50000) {
$discount_pct = 7;
} elseif ($total_spent >= 20000) {
$discount_pct = 5;
}
if ($discount_pct > 0) {
$cart_subtotal = $cart->get_subtotal();
$discount = -($cart_subtotal * $discount_pct / 100);
$cart->add_fee(
sprintf('Накопительная скидка %d%%', $discount_pct),
$discount,
true // облагается налогом
);
}
});
Кастомные поля товара
Добавление вкладки с полями в редакторе товара:
// Добавляем вкладку
add_filter('woocommerce_product_data_tabs', function (array $tabs): array {
$tabs['production_info'] = [
'label' => 'Производство',
'target' => 'production_info_data',
'class' => ['show_if_simple', 'show_if_variable'],
'priority' => 80,
];
return $tabs;
});
// Содержимое вкладки
add_action('woocommerce_product_data_panels', function (): void {
global $thepostid;
?>
<div id="production_info_data" class="panel woocommerce_options_panel">
<?php
woocommerce_wp_text_input([
'id' => '_manufacturer',
'label' => 'Производитель',
'placeholder' => 'Название компании',
'value' => get_post_meta($thepostid, '_manufacturer', true),
]);
woocommerce_wp_text_input([
'id' => '_country_of_origin',
'label' => 'Страна происхождения',
'value' => get_post_meta($thepostid, '_country_of_origin', true),
]);
woocommerce_wp_select([
'id' => '_certification',
'label' => 'Сертификация',
'options' => [
'' => 'Не указано',
'gost' => 'ГОСТ',
'iso' => 'ISO 9001',
'ce' => 'CE',
],
'value' => get_post_meta($thepostid, '_certification', true),
]);
?>
</div>
<?php
});
// Сохранение
add_action('woocommerce_process_product_meta', function (int $post_id): void {
update_post_meta($post_id, '_manufacturer', sanitize_text_field($_POST['_manufacturer'] ?? ''));
update_post_meta($post_id, '_country_of_origin', sanitize_text_field($_POST['_country_of_origin'] ?? ''));
update_post_meta($post_id, '_certification', sanitize_key($_POST['_certification'] ?? ''));
});
Кастомный отчёт в /wp-admin
add_filter('woocommerce_admin_reports', function (array $reports): array {
$reports['my_plugin'] = [
'title' => 'Поставщики',
'reports' => [
'suppliers_summary' => [
'title' => 'Сводка по поставщикам',
'description' => '',
'hide_title' => false,
'callback' => ['WC_Report_Suppliers', 'get_report'],
],
],
];
return $reports;
});
Интеграция с HPOS (High-Performance Order Storage)
WordPress WooCommerce с версии 7.1 переходит на хранение заказов в кастомных таблицах (wc_orders) вместо wp_posts. При работе с заказами в плагине нужно использовать только WC_Order API, не прямые SQL-запросы:
// Правильно — через WC API (работает и с HPOS, и без)
$orders = wc_get_orders([
'status' => ['processing', 'awaiting-delivery'],
'customer' => $customer_id,
'limit' => 20,
'orderby' => 'date',
'order' => 'DESC',
]);
foreach ($orders as $order) {
$total = $order->get_total();
$items = $order->get_items();
}
// Неправильно — прямой SQL ломается при HPOS
$orders = $wpdb->get_results(
"SELECT * FROM wp_posts WHERE post_type='shop_order' AND post_status='wc-processing'"
);
Очереди и фоновые задачи
Для тяжёлых операций (синхронизация остатков, массовое обновление цен) используем WooCommerce Action Scheduler:
// Планируем задачу
as_schedule_single_action(
time() + 60,
'my_plugin_sync_stock',
['supplier_id' => 42],
'my-plugin'
);
// Обработчик
add_action('my_plugin_sync_stock', function (int $supplier_id): void {
$items = fetch_supplier_stock($supplier_id);
foreach ($items as $sku => $qty) {
$product_id = wc_get_product_id_by_sku($sku);
if ($product_id) {
$product = wc_get_product($product_id);
$product->set_stock_quantity($qty);
$product->save();
}
}
});
Action Scheduler — production-ready очередь задач, встроенная в WooCommerce. Хранит задачи в БД, повторяет при ошибках, имеет UI в /wp-admin → Инструменты → Запланированные действия.
Типовые сроки: плагин с кастомными полями товара и статусами — 3–4 дня. Плагин с кастомной логикой скидок, интеграцией с внешним API и фоновыми задачами — 8–12 дней.







