Заказ покупателя, оформленный через sale.order.ajax, — не единственный
способ создать заказ в 1С-Битрикс. Часто нужно собрать его программно: при импорте
из внешней системы, при оформлении по звонку менеджером, при переносе заказов
со старого сайта.
Разберём, как создать заказ через объектную модель Bitrix\Sale\Order
из кода D7 — без обращения к устаревшим функциям старого модуля продаж.
Основные объекты
Модуль продаж в D7 построен на нескольких связанных сущностях:
| Класс | Назначение |
|---|---|
Order | Сам заказ: сумма, статус, свойства |
Basket | Корзина товаров внутри заказа |
BasketItem | Одна позиция корзины |
PropertyValueCollection | Значения свойств заказа — имя, телефон, адрес |
PaymentCollection | Платежи по заказу |
ShipmentCollection | Доставки по заказу |
Создание заказа
<?php
use Bitrix\Main\Loader;
use Bitrix\Sale\Order;
use Bitrix\Sale\Basket;
use Bitrix\Sale\Fuser;
Loader::includeModule('sale');
Loader::includeModule('catalog');
$siteId = 's1';
$order = Order::create($siteId, 0); // 0 — заказ от гостя
$order->setPersonTypeId(1); // физическое лицо
$basket = Basket::create($siteId);
$item = $basket->createItem('catalog', 1024); // ID товара
$item->setFields([
'QUANTITY' => 2,
'CURRENCY' => 'RUB',
'LID' => $siteId,
]);
$order->setBasket($basket);
Метод createItem принимает модуль-источник товара
(catalog для обычного инфоблока каталога) и идентификатор
элемента. Цена и название подтягиваются из каталога автоматически —
указывать их вручную не нужно и не стоит: это откроет возможность создать
заказ по произвольной, а не реальной цене.
Нужна помощь с Битрикс?
Свойства заказа
Имя, телефон и остальные поля оформления заполняются через коллекцию свойств:
<?php
$propertyCollection = $order->getPropertyCollection();
foreach ($propertyCollection as $property) {
$code = $property->getField('CODE');
if ($code === 'PHONE') {
$property->setValue('+79001234567');
}
if ($code === 'NAME') {
$property->setValue('Иван Петров');
}
}
Свойства заказа настраиваются в административной части так же, как обычные поля формы оформления — подробный разбор их настройки есть в отдельной статье. Здесь важно, что код каждого свойства должен совпадать с тем, что задано в настройках, иначе значение просто не найдёт, куда записаться.
Доставка и оплата
<?php
use Bitrix\Sale\Delivery\Services\Manager as DeliveryManager;
use Bitrix\Sale\PaySystem\Manager as PaySystemManager;
$shipmentCollection = $order->getShipmentCollection();
$shipment = $shipmentCollection->createItem();
$shipment->setFields([
'DELIVERY_ID' => 3, // ID службы доставки
'DELIVERY_NAME' => 'Курьером',
'CURRENCY' => 'RUB',
]);
$shipmentItemCollection = $shipment->getShipmentItemCollection();
foreach ($basket as $basketItem) {
$shipmentItem = $shipmentItemCollection->createItem($basketItem);
$shipmentItem->setQuantity($basketItem->getQuantity());
}
$paymentCollection = $order->getPaymentCollection();
$payment = $paymentCollection->createItem();
$payment->setFields([
'PAY_SYSTEM_ID' => 2, // ID платёжной системы
'PAY_SYSTEM_NAME' => 'Оплата картой',
'SUM' => $order->getPrice(),
'CURRENCY' => 'RUB',
]);
У каждой позиции доставки должна быть заполнена коллекция товаров — без неё заказ сохранится, но в доставке будет числиться ноль позиций, что видно как ошибка при попытке передать заказ в службу доставки или в 1С.
Сохранение
<?php
$result = $order->save();
if ($result->isSuccess()) {
$orderId = $order->getId();
} else {
$errors = $result->getErrorMessages();
}
Проверка isSuccess() обязательна: неполные данные — например,
отсутствующий обязательный тип плательщика или пустая корзина — не вызовут
исключения, а просто вернутся ошибкой в результате.
События после создания
После сохранения заказа отрабатывают события модуля продаж —
OnSaleOrderSaved и другие, которые удобно использовать
для собственной логики: отправки уведомления, передачи во внешнюю систему,
постановки задачи менеджеру. Вешать такую логику стоит через обработчики
событий, а не встраивать в сам скрипт создания заказа — тогда она сработает
одинаково независимо от того, откуда заказ был создан: из формы на сайте
или из вашего собственного скрипта импорта.
Частые ошибки
- Цена товара указывается вручную. Открывает возможность создать заказ с произвольной суммой вместо реальной цены каталога.
- Не заполнена коллекция позиций у доставки. Заказ создаётся, но доставка формально пуста.
- Код свойства не совпадает с настройками. Значение заполняется в никуда, а форма при следующем открытии заказа окажется пустой.
-
Не проверяется
isSuccess(). Заказ, который не сохранился, считается успешным в логике скрипта. - Собственная логика в скрипте создания вместо события. Не срабатывает, если заказ создаётся другим путём.
Итог
Программное создание заказа в D7 строится вокруг объекта Order,
к которому последовательно добавляются корзина, свойства, доставка и оплата,
а затем всё сохраняется одним вызовом save() с обязательной
проверкой результата.
Ключевое правило безопасности — цена товара берётся из каталога автоматически, а не передаётся вручную. А для любой логики, которая должна сработать после оформления, правильное место — обработчик события, а не сам скрипт создания заказа.
