Введение
API для работы с заказами в 1С-Битрикс — это мощный инструмент для автоматизации бизнес-процессов интернет-магазина. В этой статье мы рассмотрим не только основы, но и продвинутые техники работы с заказами, уделяя особое внимание безопасности, производительности и практическому применению. Материал ориентирован на разработчиков, уже знакомых с платформой.
1. Настройка среды и проверка прав доступа
Важность: Безопасность должна быть на первом месте при работе с финансовыми данными и персональной информацией пользователей.
<?
// Строгая проверка контекста выполнения и прав администратора
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
die(); // Прямой доступ к файлу запрещен
}
use Bitrix\Main\Loader;
use Bitrix\Main\Context;
global $USER;
// Проверка авторизации и прав
if (!$USER->IsAuthorized() || !$USER->IsAdmin()) {
ShowError("Доступ разрешен только авторизованным администраторам.");
return;
}
// Подключение модуля с обработкой ошибок через try-catch
try {
if (!Loader::includeModule('sale')) {
throw new \Exception("Не удалось подключить модуль Интернет-магазина (sale)");
}
if (!Loader::includeModule('catalog')) {
throw new \Exception("Не удалось подключить модуль Торгового каталога (catalog)");
}
} catch (\Exception $e) {
ShowError($e->getMessage());
return;
}Что изменено/добавлено:
-
Проверка
B_PROLOG_INCLUDEDдля защиты от прямого вызова. -
Использование
Loader::includeModule— современный стандарт. -
Проверка
$USER->IsAuthorized()перед проверкой прав. -
Подключение модуля
catalog, так как он часто нужен для работы с товарами в заказах.
2. Получение списка заказов: от устаревшего API к современному D7
2.1. Классический подход (устаревший, но всё ещё работает)
Важно: Этот метод считается устаревшим и не рекомендуется для новых проектов из-за низкой производительности и сложности поддержки.
$orders = CSaleOrder::GetList(
["ID" => "DESC"], // Сортировка
[], // Фильтр (пустой - все заказы)
false, // Группировка
false, // Постраничная навигация (false - без ограничений, ОПАСНО!)
["ID", "DATE_INSERT", "PRICE", "CURRENCY", "USER_ID"]
);
while ($order = $orders->Fetch()) {
// Обработка каждого заказа
}2.2. Современный подход (D7 API)
Начиная с версии ядра 14.0.0, рекомендуется использовать D7.
<?
use Bitrix\Sale\Order;
use Bitrix\Main\Loader;
use Bitrix\Main\SystemException;
use Bitrix\Main\Type\DateTime;
try {
if (!Loader::includeModule('sale')) {
throw new SystemException('Модуль sale не доступен');
}
// Формируем дату для фильтра (заказы за последние 30 дней)
$filterDate = new DateTime();
$filterDate->add('-30 days');
$orders = Order::getList([
'select' => [
'ID',
'DATE_INSERT',
'PRICE',
'CURRENCY',
'USER_ID',
'STATUS_ID',
'LID' // Сайт
],
'filter' => [
'>DATE_INSERT' => $filterDate
],
'order' => ['ID' => 'DESC'],
'limit' => 50 // ОБЯЗАТЕЛЬНО ограничиваем выборку
]);
$ordersList = $orders->fetchAll(); // Получить все сразу как массив
// или
while ($orderData = $orders->fetch()) {
// Работа с одним заказом
}
} catch (SystemException $e) {
ShowError($e->getMessage());
}Преимущества D7:
-
Объектно-ориентированный подход.
-
Поддержка современных PHP-стандартов (PSR).
-
Лучшая производительность за счет гидратации только запрошенных полей.
-
Четкое разделение
select,filter,order.
Эволюция API заказов в Битрикс
CSaleOrder::GetList()
["ID"=>"DESC"],
["PRICE">=1000],
false, false, []
);
Bitrix\Sale\Order::getList()
'filter' => ['>PRICE' => 1000],
'order' => ['ID' => 'DESC']
]);
Ключевые отличия:
- Старое API: Порядок параметров фиксирован, легко ошибиться
- Новое API: Именованные параметры, понятно с первого взгляда
- Старое API: Возвращает массив, типы данных не определены
- Новое API: Объекты с методами, автоподстановка в IDE
3. Расширенная выборка данных (D7)
3.1. Получение свойств заказа (свойства заказа — это не поля заказа)
В примере ниже исправлена ключевая ошибка: нельзя просто так добавить SELECT_PROPS в GetList старого API. В D7 это делается через отдельные запросы или join.
use Bitrix\Sale\Order;
use Bitrix\Sale\PropertyValue;
$order = Order::load($orderId);
if ($order) {
$propertyCollection = $order->getPropertyCollection();
$phoneProp = $propertyCollection->getPhone();
$emailProp = $propertyCollection->getUserEmail();
$phone = $phoneProp ? $phoneProp->getValue() : '';
$email = $emailProp ? $emailProp->getValue() : '';
echo "Телефон из свойства: " . $phone;
}3.2. Получение состава заказа (товары)
$order = Order::load($orderId);
if (!$order) {
return;
}
$basket = $order->getBasket();
$basketItems = $basket->getBasketItems();
foreach ($basketItems as $basketItem) {
$itemData = [
'NAME' => $basketItem->getField('NAME'),
'QUANTITY' => $basketItem->getQuantity(),
'PRICE' => $basketItem->getPrice(),
'PRODUCT_ID' => $basketItem->getProductId(),
];
// Обработка товаров
}
[Иллюстрация 3: Структура данных заказа в D7]
Содержание: Диаграмма классов, показывающая связи Order -> Basket -> BasketItem, а также PropertyCollection.
4. Практические примеры
4.1. Экспорт заказов в CSV с корректной кодировкой
<?
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="orders_export_'.date('Y-m-d').'.csv"');
$output = fopen('php://output', 'w');
// Добавляем BOM для корректного отображения UTF-8 в Excel
fputs($output, "\xEF\xBB\xBF");
fputcsv($output, ['ID', 'Дата', 'Сумма', 'Валюта', 'Статус']);
$orders = Order::getList([
'select' => ['ID', 'DATE_INSERT', 'PRICE', 'CURRENCY', 'STATUS_ID'],
'limit' => 1000
]);
while ($order = $orders->fetch()) {
fputcsv($output, [
$order['ID'],
$order['DATE_INSERT']->toString(), // Объект DateTime преобразуем в строку
$order['PRICE'],
$order['CURRENCY'],
$order['STATUS_ID']
]);
}
fclose($output);
die();4.2. Массовое обновление статусов (с использованием событий)
<?
use Bitrix\Sale\Order;
use Bitrix\Main\Loader;
Loader::includeModule('sale');
$orders = Order::getList([
'filter' => ['STATUS_ID' => 'N'], // Только новые заказы
'select' => ['ID']
]);
foreach ($orders as $orderData) {
$order = Order::load($orderData['ID']);
if ($order) {
$result = $order->setField('STATUS_ID', 'P'); // Меняем статус
if ($result->isSuccess()) {
$order->save();
// Отправка почтового события происходит автоматически, если настроено в Торговом соглашении
}
}
}5. Оптимизация производительности
Проблема: При большом количестве заказов (50k+) выборка без ограничений может привести к падению памяти и таймаутам.
Решения:
-
Постраничная навигация (пагинация):
use Bitrix\Main\UI\PageNavigation; $nav = new PageNavigation("orders-page"); $nav->setPageSize(50)->initFromUri(); $orders = Order::getList([ 'offset' => $nav->getOffset(), 'limit' => $nav->getLimit(), 'count_total' => true, // Важно для корректной работы навигации // ... остальные параметры ]); $nav->setRecordCount($orders->getCount());
-
Кэширование результатов (для статистики/отчетов):
use Bitrix\Main\Data\Cache; use Bitrix\Main\Application; $cache = Cache::createInstance(); $cacheTime = 3600; // 1 час $cacheId = 'orders_list_aggregated_' . date('YmdH'); // Кэш по часам $cachePath = '/orders'; if ($cache->initCache($cacheTime, $cacheId, $cachePath)) { $ordersData = $cache->getVars(); } else { $cache->startDataCache(); $ordersData = Order::getList([ 'select' => ['ID', 'PRICE', 'DATE_INSERT'], 'filter' => ['>=DATE_INSERT' => (new DateTime())->add('-1 day')] ])->fetchAll(); $cache->endDataCache($ordersData); }
6. Интеграция с другими системами
6.1. Отправка данных в CRM (Битрикс24)
<?
use Bitrix\Crm\DealTable; // Только для примера, лучше использовать CCrmDeal
if (!Loader::includeModule('crm')) {
return;
}
$orders = Order::getList(['limit' => 10]);
foreach ($orders as $orderData) {
$deal = new CCrmDeal();
$fields = [
'TITLE' => 'Заказ с сайта #' . $orderData['ID'],
'OPPORTUNITY' => $orderData['PRICE'],
'CURRENCY_ID' => $orderData['CURRENCY'],
'CONTACT_ID' => findContactByUserId($orderData['USER_ID']), // Ваша логика поиска контакта
'SOURCE_ID' => 'WEB',
'COMMENTS' => 'Импортировано из заказа',
];
$dealId = $deal->Add($fields, true, ['DISABLE_USER_FIELD_CHECK' => true]);
}6.2. Синхронизация с 1С (пример генерации XML для CommerceML)
<?
header('Content-type: text/xml; charset=utf-8');
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><КоммерческаяИнформация ВерсияСхемы="2.09" ДатаФормирования="' . date('Y-m-d H:i:s') . '"></КоммерческаяИнформация>');
$documents = $xml->addChild('Документы');
$orders = Order::getList(['limit' => 5]);
foreach ($orders as $orderData) {
$orderNode = $documents->addChild('Документ');
$orderNode->addChild('Ид', $orderData['ID']);
$orderNode->addChild('Номер', $orderData['ACCOUNT_NUMBER']); // Используем публичный номер
$orderNode->addChild('Дата', $orderData['DATE_INSERT']->format('Y-m-d'));
$orderNode->addChild('ХозОперация', 'Заказ товара');
$orderNode->addChild('Сумма', $orderData['PRICE']);
$orderNode->addChild('Валюта', $orderData['CURRENCY']);
// ... остальные поля
}
echo $xml->asXML();Заключение
Работа с API заказов в Битрикс требует понимания не только технических аспектов, но и бизнес-логики вашего магазина. Современные подходы (D7 API) обеспечивают лучшую производительность и безопасность, а грамотная оптимизация запросов позволяет работать с большими объемами данных без потери скорости.