Проблема: неавтоматическое обновление статуса заказа после 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, сложности с безопасностью и обновлениями |
| Использование плагина платёжной системы | Готовое решение, поддержка разработчика | Может не подходить под кастомные требования, зависимость от стороннего кода |