CSaleOrder и CSaleBasket — устаревшие классы
старого модуля "Интернет-магазин" (D6), которые до сих пор встречаются
в проектах, не переведённых на современный
Bitrix\Sale\Order. Разберём, как они работают,
и почему для нового кода стоит выбирать D7-вариант.
Добавление товара в корзину (D6)
<?php
CSaleBasket::Add([
'PRODUCT_ID' => $productId,
'QUANTITY' => 1,
'LID' => 's1',
'PRICE' => $price,
'CURRENCY' => 'RUB',
]);
Создание заказа (D6)
<?php
$orderId = CSaleOrder::DoOrderFromBasket($basket, [
'PAY_SYSTEM_ID' => 1,
'DELIVERY_ID' => 1,
'USER_ID' => $userId,
]);
Функция принимает объект корзины и минимальный набор параметров, создавая заказ старым способом. Работоспособность этого кода сохраняется на актуальных версиях Битрикса, но официальная документация давно помечает D6 API модуля продаж как устаревший.
Нужна помощь с Битрикс?
Тот же сценарий на D7
<?php
use Bitrix\Sale\Order;
use Bitrix\Sale\Basket;
use Bitrix\Main\Context;
$basket = Basket::create(1); // ID сайта
$item = $basket->createItem('catalog', $productId);
$item->setFields([
'QUANTITY' => 1,
'CURRENCY' => 'RUB',
]);
$order = Order::create(1, $userId);
$order->setBasket($basket);
$order->setField('PERSON_TYPE_ID', 1);
$result = $order->save();
if (!$result->isSuccess()) {
foreach ($result->getErrorMessages() as $msg) {
echo $msg . PHP_EOL;
}
}
D7-вариант многословнее, но даёт то, чего у D6 нет вовсе: объект результата с проверкой ошибок на каждом шаге, явное управление плательщиком, доставкой и оплатой через отдельные коллекции, а также поддержку событий модуля продаж нового поколения.
Почему стоит переходить на D7
-
D6-классы не получают новых возможностей модуля продаж — все
актуальные функции (мультивалютность заказа, сложные скидочные
правила, интеграция с онлайн-кассами) реализуются только через
Bitrix\Sale. -
D7 даёт объект результата операции с явным списком ошибок вместо
булева
true/false, что упрощает диагностику проблем в проде. - Часть новых версий модуля продаж не гарантирует полной работоспособности старого API на нестандартных сценариях — официально поддерживается путь миграции на D7, а не бесконечное сохранение обратной совместимости.
Смешивание D6 и D7 в одном проекте
Технически оба API могут работать в одном проекте одновременно —
например, если старый функционал ещё не переписан, а новый уже
делается на D7. Но смешивать их в рамках одной операции (например,
добавить товар через CSaleBasket, а сохранить заказ
через Order::save()) не стоит — внутренняя структура
данных различается, и результат непредсказуем.
Постепенная миграция
Если проект держится на D6 годами, полный единовременный переход на D7 — рискованная задача. Более безопасный путь — переписывать новый функционал сразу на D7, а старый мигрировать постепенно, начиная с самых критичных мест (оформление заказа, работа с корзиной), поскольку именно там чаще всего требуется точный контроль ошибок, которого D6 не даёт.
Частые ошибки
- Смешивание D6 и D7 API в одной операции. Непредсказуемое поведение из-за разной внутренней структуры данных.
- Игнорирование результата DoOrderFromBasket. Функция может вернуть false без явного объяснения причины ошибки.
- Написание нового кода на D6 "по привычке". Лишает проект доступа к актуальным возможностям модуля продаж.
Итог
CSaleOrder и CSaleBasket всё ещё работают,
но относятся к устаревшему API модуля продаж без доступа к новым
возможностям и без внятной диагностики ошибок. Для нового кода
правильный выбор — Bitrix\Sale\Order и
Bitrix\Sale\Basket, а существующий D6-код стоит
мигрировать постепенно, начиная с самых критичных участков.
