Проблема: заказ в WooCommerce не обновляется после callback платёжной системы
При интеграции сторонних платёжных систем часто возникает задача: после успешного завершения оплаты платёжная система отправляет callback (уведомление) на ваш сайт. Нужно автоматически обновить статус соответствующего заказа в WooCommerce, чтобы избежать ручного вмешательства и ошибок.
Однако, многие сталкиваются с тем, что статус не меняется, заказ остаётся в статусе "Ожидает оплаты" или "В обработке". Это приводит к путанице и дополнительной работе.
Диагностика проблемы: почему статус заказа не меняется
- Неправильный endpoint — callback не достигает нужного обработчика в WordPress.
- Отсутствие или неправильная аутентификация — запросы к REST API отклоняются.
- Ошибки в коде обновления заказа — неверный ID заказа, отсутствие вызова нужных методов WooCommerce.
- Кэширование — старые данные возвращаются из кэша, и изменения не видны.
- Отсутствие проверки nonce или прав — WordPress блокирует запрос.
Пошаговое решение: как реализовать обновление заказа через REST API
1. Создайте кастомный endpoint для приёма callback
Добавьте в functions.php или в плагин следующий код, который регистрирует REST API маршрут для callback:
add_action('rest_api_init', function () {
register_rest_route('custom/v1', '/payment-callback', [
'methods' => 'POST',
'callback' => 'handle_payment_callback',
'permission_callback' => '__return_true', // временно, лучше добавить проверку
]);
});
function handle_payment_callback(WP_REST_Request $request) {
$params = $request->get_json_params();
if (empty($params['order_id']) || empty($params['payment_status'])) {
return new WP_REST_Response(['error' => 'Invalid parameters'], 400);
}
$order_id = intval($params['order_id']);
$payment_status = sanitize_text_field($params['payment_status']);
$order = wc_get_order($order_id);
if (!$order) {
return new WP_REST_Response(['error' => 'Order not found'], 404);
}
// Обновляем статус заказа в зависимости от статуса оплаты
switch (strtolower($payment_status)) {
case 'paid':
$order->update_status('processing', 'Оплата подтверждена через callback');
break;
case 'failed':
$order->update_status('failed', 'Оплата не прошла');
break;
default:
return new WP_REST_Response(['error' => 'Unknown payment status'], 400);
}
return new WP_REST_Response(['success' => true], 200);
}2. Настройте платёжную систему для вызова вашего callback URL
URL будет выглядеть так:
https://yourdomain.com/wp-json/custom/v1/payment-callbackПроверьте, что платёжная система отправляет POST запрос с JSON телом, например:
{
"order_id": 1234,
"payment_status": "paid"
}3. Добавьте базовую защиту и аутентификацию
Для безопасности не стоит разрешать открытый вызов. Например, используйте параметр секретного ключа:
function handle_payment_callback(WP_REST_Request $request) {
$secret = $request->get_header('X-Callback-Secret');
if ($secret !== 'ваш_секретный_ключ') {
return new WP_REST_Response(['error' => 'Unauthorized'], 401);
}
// остальной код...Как проверить, что решение работает
- Отправьте тестовый POST запрос через Postman или curl на ваш endpoint с корректными параметрами.
- Убедитесь, что в админке WooCommerce статус заказа изменился.
- Проверьте логи сервера и WordPress на наличие ошибок.
curl -X POST https://yourdomain.com/wp-json/custom/v1/payment-callback \
-H 'Content-Type: application/json' \
-H 'X-Callback-Secret: ваш_секретный_ключ' \
-d '{"order_id":1234,"payment_status":"paid"}'Частые ошибки и способы исправления
- Ошибка 404 при вызове callback — проверьте, что пермалинки включены, и маршрут зарегистрирован.
- Ошибка 401 Unauthorized — неверный или отсутствующий секретный ключ, настройте заголовки запроса.
- Статус заказа не меняется — проверьте, что ID заказа правильный и что $order не null.
- Callback не срабатывает из-за кэширования — отключите кэширование для REST API или используйте хуки очистки кэша.
Практические советы по безопасности и производительности
- Используйте HTTPS для callback URL, чтобы защитить данные.
- Добавьте IP-фильтрацию, если платёжная система имеет фиксированные IP адреса.
- Ограничьте количество запросов с помощью rate limiting, чтобы избежать DDoS.
- Логируйте события callback в отдельный файл, чтобы быстро отследить проблемы.
- Обрабатывайте callback асинхронно, если обновление заказа требует дополнительных действий, чтобы не блокировать ответ.
Сравнение способов реализации
| Метод | Плюсы | Минусы |
|---|---|---|
| Кастомный REST API endpoint | Гибкость, можно реализовать логику под себя | Требуется код, безопасность на ответственности разработчика |
| Плагины интеграции платёжных систем | Готовые решения, поддержка | Может не подходить под специфические задачи, ограниченная кастомизация |
| Использование webhooks платёжной системы напрямую с WooCommerce | Простота, часто встроено | Меньший контроль, зависит от возможностей плагина или темы |