Setting up automatic order status changes 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

Automatic Order Status Change Configuration for 1C-Bitrix

Manual status changes by a manager are a bottleneck. At volumes of 100+ orders per day, this consumes significant time and increases the risk of forgotten orders. Automation covers typical scenarios: "move to Confirmed after payment", "cancel if prepayment has not been received within 24 hours", "move to Delivered after confirmation from the shipping company".

Auto Status Change on Payment

The OnSalePaymentPaid event fires when the payment module marks a payment as processed — both on manual confirmation by the manager and on an automatic IPN from the payment gateway:

AddEventHandler('sale', 'OnSalePaymentPaid', function(\Bitrix\Main\Event $event) {
    $payment = $event->getParameter('ENTITY');
    $order = $payment->getOrder();

    if ($payment->isPaid() && $order->getField('STATUS_ID') === 'WAIT_PREPAY') {
        $order->setField('STATUS_ID', 'F');
        $order->save();
    }
});

Auto-Cancellation on Timeout

Implemented via a Bitrix agent — it runs on a schedule and checks for unpaid orders:

// Agent registration (one-time)
\CAgent::AddAgent(
    'Local\Sale\OrderAgents::cancelUnpaidOrders();',
    'local',
    'N',
    3600, // every hour
    '',
    'Y',
    \ConvertTimeStamp(time() + 3600, 'FULL'),
);

class OrderAgents
{
    public static function cancelUnpaidOrders(): string
    {
        $deadline = new \Bitrix\Main\Type\DateTime();
        $deadline->add('-24 hours');

        $result = \Bitrix\Sale\Internals\OrderTable::getList([
            'filter' => [
                'STATUS_ID'    => 'WAIT_PREPAY',
                '<DATE_INSERT' => $deadline,
            ],
            'select' => ['ID'],
            'limit'  => 50,
        ]);

        while ($row = $result->fetch()) {
            $order = \Bitrix\Sale\Order::load($row['ID']);
            if ($order) {
                $order->setField('STATUS_ID', 'CANCEL');
                $order->save();
            }
        }

        return 'Local\Sale\OrderAgents::cancelUnpaidOrders();';
    }
}

The limit of 50 orders per iteration protects against timeouts when a large backlog has accumulated.

Automation via Business Processes

For complex chains with conditions and delays — Sale business processes (E-Commerce → Order Business Processes). Available triggers:

  • By status — launch when transitioning to a specific status
  • By payment — on payment confirmation or refund
  • By time — after N hours/days from creation or status change

Example: "2 hours after transitioning to Handed to Courier — send an SMS requesting a rating." Implemented without code through the BP builder.

Integration with Shipping Company Statuses

// Webhook from shipping company — POST /bitrix/tools/delivery_webhook.php
$trackNumber    = $_POST['track'];
$deliveryStatus = $_POST['status'];

$shipmentResult = \Bitrix\Sale\Internals\ShipmentTable::getList([
    'filter' => ['TRACKING_NUMBER' => $trackNumber],
    'select' => ['ORDER_ID'],
]);

if ($shipment = $shipmentResult->fetch()) {
    $order = \Bitrix\Sale\Order::load($shipment['ORDER_ID']);
    $statusMap = ['delivered' => 'D', 'returned' => 'RETURN_INIT', 'lost' => 'PROBLEM'];
    $newStatus = $statusMap[$deliveryStatus] ?? null;

    if ($newStatus && $order) {
        $order->setField('STATUS_ID', $newStatus);
        $order->save();
    }
}

Auto-Completion of Delivered Orders

Transitioning to "Closed" 14 days after delivery with no complaints:

public static function completeDeliveredOrders(): string
{
    $deadline = new \Bitrix\Main\Type\DateTime();
    $deadline->add('-14 days');

    $result = \Bitrix\Sale\Internals\OrderTable::getList([
        'filter' => ['STATUS_ID' => 'D', '<DATE_STATUS' => $deadline],
        'select' => ['ID'],
        'limit'  => 100,
    ]);

    while ($row = $result->fetch()) {
        $order = \Bitrix\Sale\Order::load($row['ID']);
        if ($order) {
            $order->setField('STATUS_ID', 'CLOSED');
            $order->save();
        }
    }

    return 'Local\Sale\OrderAgents::completeDeliveredOrders();';
}

Timeline

Auto status change on payment and a single auto-cancellation agent — 3–5 hours. Full automation with shipping company integration, business processes, and multiple agents — 1–3 business days.