Диагностика проблемы несинхронизации статусов заказов WooCommerce
При работе с несколькими сайтами WooCommerce, часто возникает ситуация, когда статусы заказов не обновляются синхронно. Например, на основном сайте заказ отмечен как "Выполнен", а на зеркальном — всё ещё "В обработке". Это ведёт к рассинхронизации данных и усложняет обработку заказов.
Основные признаки проблемы:
- Заказы создаются на всех сайтах, но статусы обновляются только на одном.
- Обновления статуса заказа не триггерят событие синхронизации.
- В логах синхронизации отсутствует информация по изменениям статусов заказов.
Для начала проверьте, как происходит синхронизация заказов и какие хуки она использует.
Почему статусы заказов WooCommerce не синхронизируются автоматически
Чаще всего синхронизация основывается на сохранении поста (заказа) с помощью хука save_post_shop_order или на пользовательских хуках WooCommerce, например, woocommerce_order_status_changed. Если в цепочке синхронизации не предусмотрена обработка смены статуса, обновления не передаются на другие сайты.
Кроме того, некоторые плагины или кастомный код могут прерывать выполнение хуков или вмешиваться в логику изменения статуса заказа, что блокирует синхронизацию.
Пошаговое решение: синхронизация статусов заказов WooCommerce через webhook и WP-CLI
1. Добавляем webhook для отслеживания изменений статуса заказа
Создайте webhook, который будет реагировать на событие смены статуса заказа и отправлять данные на другой сайт.
add_action('woocommerce_order_status_changed', 'wpsync_send_order_status_update', 10, 4);
function wpsync_send_order_status_update($order_id, $old_status, $new_status, $order) {
$data = [
'order_id' => $order_id,
'old_status' => $old_status,
'new_status' => $new_status,
'timestamp' => current_time('mysql'),
];
$url = 'https://target-site.ru/wp-json/wpsync/v1/order-status-update';
wp_remote_post($url, [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode($data),
'timeout' => 10,
]);
}2. Принимаем и обрабатываем обновления на целевом сайте
Регистрируем REST API endpoint для получения данных и изменения статуса заказа:
add_action('rest_api_init', function () {
register_rest_route('wpsync/v1', '/order-status-update', [
'methods' => 'POST',
'callback' => 'wpsync_receive_order_status_update',
'permission_callback' => '__return_true',
]);
});
function wpsync_receive_order_status_update(WP_REST_Request $request) {
$params = $request->get_json_params();
if (empty($params['order_id']) || empty($params['new_status'])) {
return new WP_Error('invalid_data', 'Missing order_id or new_status', ['status' => 400]);
}
$order = wc_get_order($params['order_id']);
if (!$order) {
return new WP_Error('order_not_found', 'Order not found', ['status' => 404]);
}
$order->update_status($params['new_status'], 'Синхронизировано со стороннего сайта');
return ['success' => true];
}3. Используем WP-CLI для массовой синхронизации
Если есть необходимость обновить статусы заказов в большом объёме, можно создать WP-CLI команду:
if (defined('WP_CLI') && WP_CLI) {
WP_CLI::add_command('wpsync sync-orders-status', function() {
$args = [
'post_type' => 'shop_order',
'post_status' => 'any',
'numberposts' => -1,
];
$orders = get_posts($args);
foreach ($orders as $post) {
$order = wc_get_order($post->ID);
// Логика синхронизации, например, вызов API
WP_CLI::log("Синхронизирован заказ #{$post->ID} со статусом {$order->get_status()}");
}
});
}Проверка результата после внедрения синхронизации
- Создайте тестовый заказ и измените его статус на основном сайте.
- Проверьте, что webhook отправлен (логи серверов или плагин Debug Bar).
- Убедитесь, что заказ с обновлённым статусом появился на целевом сайте.
- Используйте WP-CLI команду для массовой проверки и синхронизации.
Частые ошибки и пути их исправления
- Ошибка: REST API endpoint возвращает 401 или 403.
Решение: Проверьте разрешения вpermission_callback, добавьте аутентификацию или временно установите__return_true. - Ошибка: Статус заказа не меняется после получения webhook.
Решение: Убедитесь, что передаваемый статус допустим для WooCommerce. Используйтеwc_get_order_statuses()для проверки. - Ошибка: WP-CLI команда не видит заказов.
Решение: Проверьте, что команда запускается в нужной среде и с правами администратора.
Практические советы по безопасности и производительности
- Добавьте проверку аутентичности запросов REST API с помощью ключей API или OAuth.
- Логируйте ошибки синхронизации в отдельный файл для быстрого анализа.
- Ограничьте частоту вызовов webhook, чтобы избежать перегрузки сервера.
- Используйте асинхронные запросы (wp_remote_post с non-blocking) для минимизации влияния на производительность.
Сравнение вариантов синхронизации статусов заказов WooCommerce
| Метод | Плюсы | Минусы |
|---|---|---|
Webhook на woocommerce_order_status_changed | Реальное время, автоматизация | Требует настройки API и безопасности |
| WP-CLI команда | Массовая синхронизация, простота отладки | Не автоматическая, ручной запуск |
| Плагины (например, WPShop продукты) | Готовые решения, поддержка | Иногда дорогие, не всегда гибкие |