Как правильно удалить заказ в Битриксе на D7

26.09.20253 мин чтения
Никита Рунов
Разработчик, NBM-ITНикита Рунов

Работая с интернет-магазином на 1С-Битрикс, разработчики часто сталкиваются с необходимостью не просто отменить, а полностью удалить заказ. На первый взгляд задача кажется простой, но на практике всё упирается в связанные сущности: оплаты и отгрузки. В этой статье разберём, как корректно удалить заказ через D7, чтобы не оставлять "висячих" данных в базе.


Почему нельзя удалить заказ напрямую

В Битриксе заказ связан с множеством объектов:

  • оплатами;
  • отгрузками;
  • корзиной и её элементами;
  • историями изменений.

Если попытаться удалить заказ без подготовки, система выдаст ошибку. Поэтому алгоритм всегда одинаковый:

  1. Проверить наличие оплат и вернуть их.
  2. Проверить наличие отгрузок и снять признак отгрузки.
  3. Только после этого выполнить удаление заказа.

Подключаем модуль sale

Для работы с заказами в D7 нужно подключить модуль:

\Bitrix\Main\Loader::includeModule('sale');
use Bitrix\Sale;

Получаем список заказов для удаления

Можно выбрать один конкретный заказ или список по фильтру. Например, удалим заказ с ID = 1000:

$filter = ["ID" => 1000]; // ID заказа
$orderList = [];
$logFile = $_SERVER["DOCUMENT_ROOT"]."/orders.log";

if (file_exists($logFile)) unlink($logFile);

$dbSales = CSaleOrder::GetList(["DATE_INSERT" => "ASC"], $filter);
while ($arSales = $dbSales->Fetch()) {
    $orderList[] = $arSales["ID"];
}

Обрабатываем каждый заказ

Теперь нужно пройтись по списку и удалить заказы:

foreach ($orderList as $orderId) {
    $order = Sale\Order::load($orderId);

    if ($order) {
        // Проверяем оплаты
        foreach ($order->getPaymentCollection() as $payment) {
            if ($payment->isPaid()) {
                $payment->setReturn("Y");
            }
        }

        // Проверяем отгрузки
        foreach ($order->getShipmentCollection() as $shipment) {
            if ($shipment->isShipped()) {
                $shipment->setField("DEDUCTED", "N");
            }
        }

        $order->save();

        // Удаляем заказ
        $deleteResult = Sale\Order::delete($orderId);

        file_put_contents(
            $logFile,
            "Удаление заказа #$orderId: " .
            ($deleteResult->isSuccess() ? "успех" : implode(", ", $deleteResult->getErrorMessages())) .
            PHP_EOL,
            FILE_APPEND
        );
    }
}

Итог

Таким образом, корректное удаление заказа в D7 выглядит так:

  1. Подключаем модуль sale.
  2. Находим нужные заказы.
  3. Отменяем оплаты и отгрузки.
  4. Сохраняем изменения.
  5. Удаляем заказ через Sale\Order::delete().

Такой подход гарантирует, что система не сохранит "битые" данные, а логи помогут убедиться, что всё прошло успешно.