Integration of 1C-Bitrix with RetailCRM

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

1C-Bitrix Integration with RetailCRM

RetailCRM is a CRM system built specifically for ecommerce: inventory management, order picking, delivery, and cohort analytics. Bitrix24 is a general-purpose CRM; RetailCRM is designed for the day-to-day operational work of an online store. Integration is preferred when order volume exceeds 50–100 per day.

Off-the-shelf Module vs. Custom Integration

RetailCRM provides an official module for 1C-Bitrix through the marketplace. The module covers standard scenarios. A custom integration is required when:

  • Non-standard order statuses or properties are not supported by the module.
  • Complex mapping logic is needed (multiple stores, different warehouses).
  • Integration with other systems via RetailCRM is required (telephony, delivery services).

RetailCRM REST API v5

Base URL: https://yourdomain.retailcrm.ru/api/v5/. Authentication uses the X-API-KEY header.

class RetailCRMClient {
    private string $apiKey;
    private string $siteKey; // store code in RetailCRM
    private string $baseUrl;

    public function createOrder(\Bitrix\Sale\Order $order): ?string {
        $basket = $order->getBasket();
        $props  = $order->getPropertyCollection();

        $items = [];
        foreach ($basket as $item) {
            $items[] = [
                'offer'    => ['xmlId' => (string)$item->getProductId()],
                'quantity' => $item->getQuantity(),
                'initialPrice' => $item->getBasePrice(),
                'discountPercent' => 0,
            ];
        }

        $orderData = [
            'number'      => 'BX-' . $order->getId(),
            'externalId'  => (string)$order->getId(),
            'site'        => $this->siteKey,
            'status'      => $this->mapStatus($order->getField('STATUS_ID')),
            'customer'    => [
                'externalId' => (string)$order->getUserId(),
                'email'      => $props->getUserEmail(),
                'phone'      => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
            ],
            'items'       => $items,
            'delivery'    => [
                'code'    => $this->mapDelivery($order->getDeliveryId()),
                'address' => ['text' => $this->getOrderAddress($props)],
            ],
            'paymentType' => $this->mapPayment($order->getPaymentSystemId()),
        ];

        $http = new \Bitrix\Main\Web\HttpClient();
        $http->setHeader('X-API-KEY', $this->apiKey);
        $http->setHeader('Content-Type', 'application/x-www-form-urlencoded');

        $response = json_decode($http->post(
            $this->baseUrl . 'orders/create',
            'order=' . urlencode(json_encode($orderData)) . '&site=' . $this->siteKey
        ), true);

        return $response['id'] ?? null; // Order ID in RetailCRM
    }
}

Two-way Status Synchronisation

RetailCRM updates the order status (manager processed it, set it to picking, handed it to delivery) — the website must reflect the updated status.

RetailCRM supports outgoing webhooks. Configure them under Administration → Webhooks:

// RetailCRM webhook handler
$payload = json_decode(file_get_contents('php://input'), true);

foreach ($payload['orders'] as $orderData) {
    $externalId = $orderData['externalId']; // Order ID in 1C-Bitrix
    $newStatus  = $statusMap[$orderData['status']] ?? null;

    if ($newStatus) {
        $order = \Bitrix\Sale\Order::load($externalId);
        $order->setField('STATUS_ID', $newStatus);
        $order->save();
    }
}

Reference Data Mapping

RetailCRM stores reference data: statuses, delivery types, payment methods — each with a code. Those codes must be mapped to 1C-Bitrix codes:

1C-Bitrix Status RetailCRM Status
N (new) new
P (paid) complete-payment
D (in delivery) delivery
F (completed) complete
C (cancelled) cancel-other

The mapping is stored in the module settings or in a custom table.

Case Study: Sync Breakdown Under Peak Load

A clothing store during a sale: 800 orders in 2 hours. Synchronous transmission to RetailCRM on every OnSaleOrderSaved event caused timeouts — the RetailCRM API responded with 3–5 second delays, blocking order processing on the website.

Solution: a queue based on 1C-Bitrix agents. Orders are written to a queue table (b_retailcrm_queue); an agent runs every 10 seconds and sends batches of 10 orders. Peak load is smoothed out and orders are processed within 1–5 minutes.

Task Effort
Basic order transfer (site → RetailCRM) 6–8 h
Two-way status synchronisation 6–10 h
Reference data and delivery mapping 4–6 h
Queue and error handling 6–8 h
Product catalogue synchronisation 8–12 h