Setting up multi-supplier order logic in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Configuring Multi-Supplier Order Logic in 1C-Bitrix

In dropshipping, a single customer order can contain products from different suppliers. Each supplier needs to receive only their portion. Bitrix does not split orders by suppliers automatically — the logic is implemented through event handlers and custom tables.

Implementation Options

Option 1 — unified order, separate notifications to suppliers. The order in Bitrix remains unified in b_sale_order. When the order is placed, the OnSaleOrderSaved handler determines which basket items belong to which suppliers and sends each supplier a notification containing only their products. Simpler, but does not allow tracking shipment per supplier separately.

Option 2 — splitting into child shipments. One order, but the \Bitrix\Sale\Shipment object is created separately for each supplier. This is a native Bitrix mechanism — one order can have multiple shipments with different parameters.

Option 3 — splitting into separate orders (sub-orders). When the order is placed, a parent order and multiple child orders are created based on the number of suppliers. More complex, but provides full independence of statuses.

Implementation via Separate Shipments (Option 2)

When saving an order, determine suppliers and create shipments:

AddEventHandler('sale', 'OnSaleOrderSaved', function(\Bitrix\Main\Event $event) {
    $order   = $event->getParameter('ENTITY');
    $isNew   = $event->getParameter('IS_NEW');

    if (!$isNew) return;

    $basket = $order->getBasket();
    $supplierItems = [];

    // Group basket items by supplier
    foreach ($basket->getOrderableItems() as $item) {
        $supplierId = getSupplierByProductId($item->getProductId());
        if ($supplierId) {
            $supplierItems[$supplierId][] = $item;
        }
    }

    $shipmentCollection = $order->getShipmentCollection();

    foreach ($supplierItems as $supplierId => $items) {
        $shipment = $shipmentCollection->createItem();
        $shipment->setField('DELIVERY_ID', getSupplierDeliveryId($supplierId));
        $shipment->setField('CUSTOM_PRICE_DELIVERY', 'N');

        $shipmentItemCollection = $shipment->getShipmentItemCollection();
        foreach ($items as $basketItem) {
            $shipmentItem = $shipmentItemCollection->createItem($basketItem);
            $shipmentItem->setQuantity($basketItem->getQuantity());
        }
    }

    $order->save();
});

The getSupplierByProductId() function reads the SUPPLIER_ID property from b_iblock_element_property.

Notifications to Suppliers

Each supplier receives an email or message containing only their products. Sending through \Bitrix\Main\Mail\Event::send() with a custom template:

foreach ($supplierItems as $supplierId => $items) {
    $supplierEmail = getUserEmail($supplierId);

    \Bitrix\Main\Mail\Event::send([
        'EVENT_NAME' => 'SUPPLIER_ORDER_NOTIFY',
        'LID'        => SITE_ID,
        'C_FIELDS'   => [
            'SUPPLIER_EMAIL' => $supplierEmail,
            'ORDER_ID'       => $order->getId(),
            'ORDER_ITEMS'    => formatItemsForEmail($items),
            'BUYER_ADDRESS'  => getOrderDeliveryAddress($order),
        ],
    ]);
}

The SUPPLIER_ORDER_NOTIFY template is created in "Email Events" in the administrative interface.

Status Tracking by Suppliers

The HL-block SupplierOrderStatus records the status of each order portion:

  • UF_ORDER_ID — Bitrix order ID
  • UF_SUPPLIER_ID — supplier
  • UF_STATUSnew / confirmed / shipped
  • UF_TRACKING_NUMBER — tracking number

An agent verifies whether all suppliers have set shipped and changes the main order status:

function checkAllSuppliersShippedAgent(): string
{
    // Find orders where all suppliers have shipped
    $connection = \Bitrix\Main\Application::getConnection();
    $orders = $connection->query("
        SELECT UF_ORDER_ID
        FROM b_hl_supplier_order_status
        GROUP BY UF_ORDER_ID
        HAVING COUNT(*) = SUM(CASE WHEN UF_STATUS = 'shipped' THEN 1 ELSE 0 END)
           AND UF_ORDER_ID IN (
               SELECT ID FROM b_sale_order WHERE STATUS_ID NOT IN ('F','C')
           )
    ");

    while ($row = $orders->fetch()) {
        $order = \Bitrix\Sale\Order::load($row['UF_ORDER_ID']);
        if ($order) {
            $order->setField('STATUS_ID', 'S'); // status "Shipped"
            $order->save();
        }
    }

    return __FUNCTION__ . '();';
}

Setup takes 2–5 days depending on the chosen splitting variant and notification complexity.