Работа с заказами на D7: руководство

Внимание! Все сообщения на форуме проходят модерацию. Ваше сообщение появится после проверки.
Работа с заказами на D7: руководство

Задача: изучить работу с заказами в новом API Битрикс D7, получение данных заказа, работа со свойствами, оплатами и отгрузками
Создание заказа в D7 пошагово: сначала создаём заказ, затем корзину с товарами, устанавливаем свойства и добавляем службы доставки и оплаты.
Код
use Bitrix\Main\Loader;
use Bitrix\Sale;
use Bitrix\Catalog;

// Подключаем модули
Loader::includeModule('sale');
Loader::includeModule('catalog');

// Данные для создания заказа
$siteId = 's1';
$userId = 1; // ID пользователя
$currency = 'RUB';

// Создаём новый заказ
$order = Sale\Order::create($siteId, $userId);
$order->setPersonTypeId(1); // ID типа плательщика (физ/юр лицо)

// Создаём корзину для заказа
$basket = Sale\Basket::create($siteId);

// Добавляем товары в корзину
$productsData = [
    [
        'PRODUCT_ID' => 123,
        'QUANTITY' => 2,
        'PRICE' => 1500,
        'NAME' => 'Товар 1',
        'CURRENCY' => $currency
    ],
    [
        'PRODUCT_ID' => 124,
        'QUANTITY' => 1,
        'PRICE' => 2500,
        'NAME' => 'Товар 2',
        'CURRENCY' => $currency
    ]
];

foreach ($productsData as $productData) {
    $basketItem = $basket->createItem('catalog', $productData['PRODUCT_ID']);
    $basketItem->setFields([
        'QUANTITY' => $productData['QUANTITY'],
        'CURRENCY' => $productData['CURRENCY'],
        'PRICE' => $productData['PRICE'],
        'NAME' => $productData['NAME'],
        'DETAIL_PAGE_URL' => '/catalog/product_' . $productData['PRODUCT_ID'] . '/',
        'MODULE' => 'catalog',
        'PRODUCT_PROVIDER_CLASS' => 'CCatalogProductProvider',
    ]);
}

// Привязываем корзину к заказу
$order->setBasket($basket);

После создания заказа необходимо заполнить свойства покупателя.
Код
// Получаем коллекцию свойств заказа
$propertyCollection = $order->getPropertyCollection();

// Данные покупателя
$buyerData = [
    'NAME' => 'Иван Иванов',
    'EMAIL' => 'ivan@example.com',
    'PHONE' => '+7 (999) 123-45-67',
    'ADDRESS' => 'г. Москва, ул. Тестовая, д. 1',
    'ZIP' => '123456',
    'LOCATION' => '0000073738' // ID местоположения в системе
];

// Устанавливаем значения свойств
foreach ($propertyCollection as $property) {
    $propertyCode = $property->getField('CODE');

    switch ($propertyCode) {
        case 'FIO':
            $property->setValue($buyerData['NAME']);
            break;
        case 'EMAIL':
            $property->setValue($buyerData['EMAIL']);
            break;
        case 'PHONE':
            $property->setValue($buyerData['PHONE']);
            break;
        case 'ADDRESS':
            $property->setValue($buyerData['ADDRESS']);
            break;
        case 'ZIP':
            $property->setValue($buyerData['ZIP']);
            break;
        case 'LOCATION':
            $property->setValue($buyerData['LOCATION']);
            break;
    }
}

// Или можно искать по типу свойства
$emailProperty = $propertyCollection->getUserEmail();
if ($emailProperty) {
    $emailProperty->setValue($buyerData['EMAIL']);
}

$phoneProperty = $propertyCollection->getPhone();
if ($phoneProperty) {
    $phoneProperty->setValue($buyerData['PHONE']);
}

Заказ должен содержать информацию о способе доставки и оплаты. Создаём отгрузку и платёж для заказа
Код
// Создаём отгрузку (доставку)
$shipmentCollection = $order->getShipmentCollection();
$shipment = $shipmentCollection->createItem();

// Устанавливаем службу доставки
$deliveryId = 1; // ID службы доставки
$shipment->setFields([
    'DELIVERY_ID' => $deliveryId,
    'DELIVERY_NAME' => 'Курьерская доставка',
    'PRICE_DELIVERY' => 500, // Стоимость доставки
    'CURRENCY' => $currency,
    'ALLOW_DELIVERY' => 'Y'
]);

// Добавляем товары в отгрузку
$shipmentItemCollection = $shipment->getShipmentItemCollection();
foreach ($basket as $basketItem) {
    $shipmentItem = $shipmentItemCollection->createItem($basketItem);
    $shipmentItem->setQuantity($basketItem->getQuantity());
}

// Создаём платёж (оплату)
$paymentCollection = $order->getPaymentCollection();
$payment = $paymentCollection->createItem();

// Устанавливаем систему оплаты
$paySystemId = 1; // ID платёжной системы
$payment->setFields([
    'PAY_SYSTEM_ID' => $paySystemId,
    'PAY_SYSTEM_NAME' => 'Наличные',
    'SUM' => $order->getPrice(), // Сумма к оплате = сумме заказа
    'CURRENCY' => $currency
]);

// Сохраняем заказ
$result = $order->save();

if ($result->isSuccess()) {
    echo "Заказ успешно создан! ID: " . $order->getId();
    echo "Номер заказа: " . $order->getField('ACCOUNT_NUMBER');
} else {
    echo "Ошибки при создании заказа:";
    foreach ($result->getErrors() as $error) {
        echo $error->getMessage();
    }
}
Для корректной работы заказа необходимо произвести расчёты скидок, налогов и итоговых сумм
Код
// Функция для полного создания заказа с расчётами
function createOrderWithCalculations($userId, $productsData, $buyerData, $deliveryId = 1, $paySystemId = 1) {
    $siteId = 's1';
    $currency = 'RUB';

    try {
        // Создаём заказ и корзину
        $order = Sale\Order::create($siteId, $userId);
        $order->setPersonTypeId(1);

        $basket = Sale\Basket::create($siteId);

        // Добавляем товары
        foreach ($productsData as $productData) {
            $basketItem = $basket->createItem('catalog', $productData['PRODUCT_ID']);
            $basketItem->setFields([
                'QUANTITY' => $productData['QUANTITY'],
                'CURRENCY' => $currency,
                'PRICE' => $productData['PRICE'],
                'NAME' => $productData['NAME'],
                'MODULE' => 'catalog',
                'PRODUCT_PROVIDER_CLASS' => 'CCatalogProductProvider',
            ]);
        }

        $order->setBasket($basket);

        // Заполняем свойства заказа
        $propertyCollection = $order->getPropertyCollection();
        $emailProperty = $propertyCollection->getUserEmail();
        if ($emailProperty) $emailProperty->setValue($buyerData['EMAIL']);

        $phoneProperty = $propertyCollection->getPhone();
        if ($phoneProperty) $phoneProperty->setValue($buyerData['PHONE']);

        // Создаём отгрузку
        $shipmentCollection = $order->getShipmentCollection();
        $shipment = $shipmentCollection->createItem();
        $shipment->setField('DELIVERY_ID', $deliveryId);
        $shipment->setField('CURRENCY', $currency);

        // Добавляем товары в отгрузку
        $shipmentItemCollection = $shipment->getShipmentItemCollection();
        foreach ($basket as $basketItem) {
            $shipmentItem = $shipmentItemCollection->createItem($basketItem);
            $shipmentItem->setQuantity($basketItem->getQuantity());
        }

        // Создаём платёж
        $paymentCollection = $order->getPaymentCollection();
        $payment = $paymentCollection->createItem();
        $payment->setField('PAY_SYSTEM_ID', $paySystemId);
        $payment->setField('CURRENCY', $currency);

        // ВАЖНО: производим расчёты перед сохранением
        $order->doFinalAction(true); // Финализируем заказ с расчётами

        // Устанавливаем сумму платежа после расчётов
        $payment->setField('SUM', $order->getPrice());

        // Сохраняем заказ
        $result = $order->save();

        if ($result->isSuccess()) {
            return [
                'success' => true,
                'order_id' => $order->getId(),
                'order_number' => $order->getField('ACCOUNT_NUMBER'),
                'total_price' => $order->getPrice()
            ];
        } else {
            return [
                'success' => false,
                'errors' => array_map(function($error) { return $error->getMessage(); }, $result->getErrors())
            ];
        }

    } catch (Exception $e) {
        return [
            'success' => false,
            'errors' => [$e->getMessage()]
        ];
    }
}

// Пример использования
$result = createOrderWithCalculations(
    1, // ID пользователя
    [
        [
            'PRODUCT_ID' => 123,
            'QUANTITY' => 2,
            'PRICE' => 1500,
            'NAME' => 'Тестовый товар 1'
        ]
    ],
    [
        'EMAIL' => 'test@example.com',
        'PHONE' => '+7 (999) 123-45-67'
    ]
);

if ($result['success']) {
    echo "Заказ #{$result['order_number']} создан успешно!";
    echo "Сумма: {$result['total_price']} руб.";
} else {
    echo "Ошибки: " . implode(', ', $result['errors']);
}
Форма ответов
 
Текст сообщения*
Перетащите файлы
Ничего не найдено
Файл
Загрузить файлы
 

Стоимость разработки на 1С-Битрикс:

Индивидуальная разработка магазина

от 350 000 руб. от 5-ти недель

Разработка магазина на 1С-Битрикс с нуля. Дизайн, сборка и оптимизация производительности под конкретный проект и требования. Реализация любого функционала без ограничений готовых решений.

Запуск сайта на готовом решении

от 150 000 руб. от 7-ми дней

Вариант для тех, кто не хочет тратить много средств на индивидуальный проект, и не имеет серьезных требований к сайту. Магазин, быстро запускается на базе одного из 200-та готовых решений.

Мобильное приложение

от 400 000 руб. от 5-ти недель

Разработка кроссплатформенного мобильного приложения, которое не уступает нативным решениям как в производительности, так и пользовательском опыте. Публикуется в AppStore, GooglePlay и RuStore

Сайт компании

от 300 000 руб. от 2-х недель

Корпоративный сайт с информационными разделами, каталогом товаров или услуг. Включает формы обратной связи карточек каталога, любое количество статичных и динамичных разделов.

Инфоресурс

от 300 000 руб. от 4-х недель

Информационный ресурс любой сложности. Сайт для СМИ, городской портал или многопользовательская доска объявлений. Внутренние форумы, блоги- по необходимости.

3D‑моделирование, визуализация

от 25 000 руб. от 3-х дней

По вашим фото, чертежам или описанию создадим 3D‑модели и отрендерим набор изображений для каталога товаров: общий вид, крупные планы и технические ракурсы или 360°‑обзор товара.