D7: Изменить статус заказа и сохранить
Изменение статуса заказа через setField() и сохранение через save() с обработкой результата и ошибок.
Как использовать
- Подключите модуль sale, загрузите заказ через Order::load($orderId), установите статус setField('STATUS_ID', $newStatusId) и вызовите save().
- Проверяйте результат через isSuccess() и getErrorMessages(); проверьте существование статуса через CSaleStatus::GetByID().
- Используйте в обработчиках платежей, агентах или админ-действиях после проверки оплаты/доставки.
В 1С-Битрикс заказы в D7 меняют через объект Order: без вызова save() изменения в БД не попадают. При автоматизации (оплата, доставка, интеграции) нужно единообразно ставить новый статус, обрабатывать ошибки и не полагаться на то, что статус «сам сохранится». Проблема возникает в обработчиках платежей, агентах и админке: вызвали setField('STATUS_ID', 'P'), но забыли save() или не проверили результат — статус в интерфейсе не меняется или скрипт падает без понятной ошибки. Симптомы: заказ остаётся в старом статусе после оплаты, либо в логах пустая ошибка. Ниже — функция с проверкой существования статуса, вызовом save() и возвратом результата с прежним/новым статусом и текстом ошибки; плюс как проверить изменение в БД.
Решение
Изменение статуса заказа через D7 API с сохранением и обработкой результата. Используйте в обработчиках платежей, агентах, админ-панели для автоматического изменения статусов заказов.
use Bitrix\Main\Loader;
use Bitrix\Sale\Order;
use Bitrix\Main\Error;
/**
* Изменить статус заказа
* @param int $orderId ID заказа
* @param string $newStatusId Новый статус (например, 'F', 'P', 'N')
* @return array ['success' => bool, 'error' => string]
*/
function changeOrderStatus($orderId, $newStatusId) {
if (!Loader::includeModule('sale')) {
return ['success' => false, 'error' => 'Модуль sale не подключен'];
}
// Проверяем существование статуса
$status = \CSaleStatus::GetByID($newStatusId);
if (!$status) {
return ['success' => false, 'error' => 'Статус не найден'];
}
$order = Order::load($orderId);
if (!$order) {
return ['success' => false, 'error' => 'Заказ не найден'];
}
// Получаем текущий статус
$currentStatus = $order->getField('STATUS_ID');
// Устанавливаем новый статус
$result = $order->setField('STATUS_ID', $newStatusId);
if (!$result->isSuccess()) {
$errors = $result->getErrorMessages();
return ['success' => false, 'error' => implode(', ', $errors)];
}
// Сохраняем заказ
$saveResult = $order->save();
if (!$saveResult->isSuccess()) {
$errors = $saveResult->getErrorMessages();
return ['success' => false, 'error' => implode(', ', $errors)];
}
return [
'success' => true,
'error' => '',
'old_status' => $currentStatus,
'new_status' => $newStatusId
];
}
Пример использования:
// В обработчике платежа или агенте
$result = changeOrderStatus(12345, 'P'); // P - оплачен
if ($result['success']) {
echo 'Статус изменён с ' . $result['old_status'] . ' на ' . $result['new_status'];
} else {
echo 'Ошибка: ' . $result['error'];
}
// Изменить на статус "Выполнен"
changeOrderStatus(12345, 'F');
После setField() обязательно вызывайте save() для применения изменений. Метод save() возвращает Result с isSuccess() и getErrorMessages(). Статусы должны существовать в системе (N — новый, P — оплачен, F — выполнен, C — отменён и т.д.). Изменение статуса может вызвать события OnSaleOrderSaved.
Проверка
- Проверить, что статус сохранился в БД — после вызова функции загрузите заказ снова и прочитайте поле:
$order = \Bitrix\Sale\Order::load(12345);
echo $order->getField('STATUS_ID'); // ожидаем новый статус, например P
- Диагностика списка статусов — убедиться, что используемый код статуса есть в системе:
$status = \CSaleStatus::GetByID('P');
var_dump($status); // массив с ID, NAME и т.д. или false
- Проверка в админке — заказ → карточка заказа → поле «Статус». Должен отображаться новый статус после выполнения скрипта (обработчик или агент).
Типичные ошибки
- Статус в коде не меняется — не вызван
save()послеsetField(). В D7 все изменения применяются только после$order->save(). - Ошибка «Статус не найден» — передан несуществующий ID статуса. Проверьте коды в настройках продаж (Настройки → Настройки продукта → Статусы заказов) или через
CSaleStatus::GetList(). - Заказ не найден (Order::load возвращает null) — неверный ID заказа или заказ удалён. Проверьте наличие заказа в БД (таблица заказов модуля sale).
- События при смене статуса — если подписаны обработчики на
OnSaleOrderSaved, они выполнятся при save(); учитывайте рекурсию или тяжёлую логику в обработчиках. См. Клонирование заказа со статусом при необходимости копирования заказа.
Где применять
- Prod / dev: обработчики оплаты (внутренние платёжные системы, webhook от платёжного шлюза), агенты (автосмена статуса по времени), админ-действия, интеграции с 1С/CRM.
- Локально: вызовите функцию из скрипта в корне сайта с подключённым прологом Bitrix или из тестовой страницы в админке.
Связанные сниппеты: Получение платежей и отгрузок заказа, Сопоставление статуса заказа и режим запроса, PHP 8.5: клонирование заказа со статусом.