Setting up 1C-Bitrix order statuses

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 Order Statuses in 1C-Bitrix

Every order moves through a chain of statuses: "Received" → "Processing" → "Dispatched" → "Delivered". The standard 1C-Bitrix installation provides a basic set that rarely matches the real operational process. "Pending Approval" for corporate orders, "Awaiting Prepayment", "Reservation Confirmed", "Return Initiated" — all of this requires configuration.

Status Structure

Statuses are stored in the b_sale_status table. Key attributes:

  • ID — code (Latin characters + digits), used in code and integrations
  • TypeO (order) or D (delivery/shipment)
  • Color — for visual highlighting in the order list
  • "Is cancellation status" — automatically releases product reservations
  • "Order completed" — marks the order as finished, blocks certain operations

Shipment statuses (D) are a separate entity for the multi-shipment model.

Adding a Status via API

use Bitrix\Sale\OrderStatus;

$result = OrderStatus::add([
    'ID'           => 'WAIT_PREPAY',
    'TYPE'         => 'O',
    'NOTIFY_BUYER' => 'Y',
    'COLOR'        => '#f0a500',
    'SORT'         => 25,
]);

\Bitrix\Sale\Internals\StatusLangTable::add([
    'STATUS_ID'   => 'WAIT_PREPAY',
    'LID'         => 'en',
    'NAME'        => 'Awaiting Prepayment',
    'DESCRIPTION' => 'Order confirmed, awaiting payment receipt',
]);

Changing Status in Code

$order = \Bitrix\Sale\Order::load($orderId);

if ($order) {
    $order->setField('STATUS_ID', 'WAIT_PREPAY');
    $saveResult = $order->save();

    if (!$saveResult->isSuccess()) {
        $errors = $saveResult->getErrorMessages();
    }
}

When the status changes, the events OnSaleStatusOrderChange and OnSaleOrderSaved are triggered automatically. If the status is flagged "Notify buyer" — an email is sent using mail event templates.

Allowed Transition Matrix

Restricting transitions between statuses via an event handler:

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

    $oldStatus = $order->getField('STATUS_ID');
    // Get the new status via changedFields
    $changedFields = $order->getFields()->getChangedValues();
    $newStatus = $changedFields['STATUS_ID'] ?? $oldStatus;

    $allowedTransitions = [
        'N'           => ['F', 'WAIT_PREPAY', 'CANCEL'],
        'F'           => ['PROCESSING', 'CANCEL'],
        'WAIT_PREPAY' => ['F', 'CANCEL'],
        'PROCESSING'  => ['DELIVERING', 'CANCEL'],
        'DELIVERING'  => ['D', 'RETURN_INIT'],
    ];

    if (isset($allowedTransitions[$oldStatus]) &&
        $newStatus !== $oldStatus &&
        !in_array($newStatus, $allowedTransitions[$oldStatus])) {
        return new \Bitrix\Main\EventResult(
            \Bitrix\Main\EventResult::ERROR,
            new \Bitrix\Sale\ResultError("Transition from {$oldStatus} to {$newStatus} is not allowed"),
            'sale'
        );
    }
});

Typical Status Sets

Standard B2C: New → Confirmed → Being Picked → Dispatched → Delivered / Cancelled

B2B with Approval: New → Pending Approval → Awaiting Prepayment → Confirmed → In Production → Ready for Shipment → Shipped → Closed

With Returns: Added to the main chain: Return Initiated → Item Received → Return Completed

Changing Shipment Status

$shipmentCollection = $order->getShipmentCollection();
foreach ($shipmentCollection as $shipment) {
    if (!$shipment->isSystem()) {
        $shipment->setField('STATUS_ID', 'DELIVERING');
    }
}
$order->save();

Timeline

Configuring 5–8 statuses with names and colors — 2–4 hours. Configuration with a transition matrix, 1C integration, and custom notifications — 1–2 business days.