WooCommerce REST API: как автоматизировать обновление статуса заказа после callback от платёжной системы

Проблема: неавтоматическое обновление статуса заказа после callback от платёжной системы

При интеграции платёжных шлюзов с WooCommerce часто возникает задача автоматического обновления статуса заказа после получения callback (webhook) от платёжной системы. Без автоматизации приходится менять статус вручную, что неудобно и чревато ошибками. Рассмотрим, как реализовать корректную обработку callback и обновление заказа через WooCommerce REST API.

Диагностика проблемы

Чтобы понять, почему статус заказа не обновляется, проверьте следующие моменты:

  • Получаете ли вы callback от платёжной системы на сервер (проверьте логи веб-сервера или плагина)
  • Обрабатывается ли callback корректно и вызывается ли код, обновляющий заказ
  • Есть ли ошибки при запросах к WooCommerce REST API (например, 401 Unauthorized, 403 Forbidden)
  • Правильно ли настроены права пользователя API для изменения заказов

Как проверить callback

Добавьте простой лог в обработчик webhook, чтобы убедиться, что ваш сервер получает запросы:

add_action('init', function() {
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && strpos($_SERVER['REQUEST_URI'], '/payment-callback') !== false) {
        $input = file_get_contents('php://input');
        error_log('Callback data: ' . $input);
        // Здесь вызвать функцию обработки
        wp_send_json_success();
        exit;
    }
});

Проверьте error_log сервера, чтобы увидеть, что данные действительно приходят.

Пошаговое решение: автоматизация обновления статуса заказа

1. Создаём endpoint для обработки callback

Добавьте endpoint в WordPress для приёма webhook от платёжной системы. Используем rest_api_init:

add_action('rest_api_init', function() {
    register_rest_route('custom/v1', '/payment-callback', [
        'methods' => 'POST',
        'callback' => 'handle_payment_callback',
        'permission_callback' => '__return_true',
    ]);
});

2. Реализуем обработчик callback

В функции handle_payment_callback распарсим входные данные, проверим их и обновим статус заказа через WooCommerce REST API:

function handle_payment_callback(WP_REST_Request $request) {
    $data = $request->get_json_params();

    if (empty($data['order_id']) || empty($data['payment_status'])) {
        return new WP_REST_Response(['error' => 'Invalid data'], 400);
    }

    $order_id = intval($data['order_id']);
    $payment_status = sanitize_text_field($data['payment_status']);

    $order = wc_get_order($order_id);
    if (!$order) {
        return new WP_REST_Response(['error' => 'Order not found'], 404);
    }

    // Преобразуем статус платежа в статус WooCommerce
    $status_map = [
        'paid' => 'processing',
        'failed' => 'failed',
        'refunded' => 'refunded',
    ];

    if (!isset($status_map[$payment_status])) {
        return new WP_REST_Response(['error' => 'Unknown payment status'], 400);
    }

    $new_status = $status_map[$payment_status];
    $order->update_status($new_status, 'Status updated via payment callback');

    return new WP_REST_Response(['success' => true], 200);
}

3. Проверка авторизации для REST API

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

'permission_callback' => function(WP_REST_Request $request) {
    $secret = $request->get_header('X-Secret-Key');
    return $secret === 'ваш_секретный_ключ';
},

Проверка результата после внедрения

Чтобы убедиться, что обновление статуса работает:

  • Отправьте тестовый POST-запрос на ваш endpoint c JSON: {"order_id":123,"payment_status":"paid"}
  • Проверьте, что заказ с ID 123 получил статус «processing» в админке WooCommerce
  • Просмотрите логи сервера на предмет ошибок
  • Проверьте ответ API: должен быть {"success":true} с HTTP статусом 200

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

  • Ошибка 401/403: Проверьте ключи API и права пользователя, под которым выполняется запрос
  • Не обновляется статус: Убедитесь, что функция update_status вызывается на объекте WC_Order, а не на ID
  • Callback не приходит: Проверьте URL webhook в платёжной системе, доступность сервера и firewall
  • Неверные данные в callback: Добавьте логирование входящих данных и проверяйте JSON формат

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

  • Обязательно проверяйте и валидируйте входные данные callback
  • Используйте секретные ключи или IP-ограничения для защиты endpoint
  • Логируйте ошибки и успешные обновления для аудита
  • Обрабатывайте callback асинхронно, если возможно, чтобы не задерживать ответ платёжной системе
  • Регулярно обновляйте WooCommerce и плагины безопасности

Сравнение вариантов реализации

ВариантПлюсыМинусы
Обработка через REST API endpointСтандартный способ, легко масштабируется, интеграция с WP REST APIНужно обеспечить безопасность, немного сложнее в настройке
Обработка через отдельный скрипт (например, PHP файл)Простота, прямой контрольМеньшая интеграция с WP, сложности с безопасностью и обновлениями
Использование плагина платёжной системыГотовое решение, поддержка разработчикаМожет не подходить под кастомные требования, зависимость от стороннего кода

Шаблоны для WP Плагины для WP