1C-Bitrix Module Development Services

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.
FAQ
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

Development and Configuration of 1C-Bitrix Modules

The main trap in Bitrix is init.php. You put an OnBeforeIBlockElementUpdate handler there, then another one, and a year later the file is 2000 lines long, all executing on every hit. We move business logic into proper modules with D7 ORM, custom tables, and an administrative interface. A module can be disabled, transferred to another project, covered with tests — none of that is possible with init.php.

Standard Modules: Where the Pitfalls Are

Information blocks. IB architecture is the first thing we review on any project. Classic mistake: a single catalog infoblock with 80 properties, 30 of which are multiple-value. The b_iblock_element_property table bloats to millions of rows, and CIBlockElement::GetList filtering on three properties goes into a full table scan. We move reference data to Highload blocks, eliminate multiple-value properties where possible, and design the structure with the expectation that the catalog will grow 5x.

Online store (sale). A powerful module, but cart business rules are a story of their own. We configure discount priorities so two promotions don't stack to 60% instead of 30%, connect payment handlers, and set up OnSaleOrderBeforeSaved handlers for custom validation.

Search. The built-in search module with morphology works up to 10-15 thousand items. Beyond that — Elasticsearch. We configure it through the Bitrix search module API and index via CSearchFullText or custom indexers.

Highload blocks. For reference data, logs, user data — instead of bloated IBs. Direct queries via Bitrix\Highloadblock\HighloadBlockTable, custom tables instead of the EAV structure of standard infoblock. A million records — without degradation.

Mail events. Configuration isn't just about templates in b_event_message. The key is SPF, DKIM, DMARC on DNS — otherwise transactional emails land in spam. We verify deliverability and set up bounce handling.

Custom Module Development

Each module follows the structure /local/modules/vendor.modulename/:

  • install/index.php — installation class, table creation via $DB->RunSQLBatch()
  • lib/ — D7 ORM classes, inheriting from Bitrix\Main\ORM\Data\DataManager
  • admin/ — admin pages via CAdminList, CAdminForm
  • include.php — autoloading, handler registration via EventManager::getInstance()->registerEventHandler()
  • REST API endpoints via \Bitrix\Rest\RestManager

The module registers in the system, appears in the "Installed Solutions" list, and has its own settings at /bitrix/admin/settings.php?mid=vendor.modulename. It can be enabled, disabled, and updated via UpdateSystem or a custom migration mechanism.

What we've built:

  • Promotions management — a visual condition builder via CAdminCalendar, timers via agents (CAgent::AddAgent), effectiveness analytics linked to the sale module
  • Cost calculator — React widget on the frontend, REST API in the module, formulas stored in a Highload block
  • Booking system — real-time calendar, locking via $DB->StartTransaction() / $DB->Commit() for concurrent requests, synchronization with channel managers via webhook

Components and Composite Cache

Component customization — via result_modifier.php and component_epilog.php, not by editing the standard template's template.php. This way the core updates painlessly.

Composite cache ("Composite Site" technology) — the server delivers ready-made HTML, bypassing PHP routing. Dynamic zones (cart, authentication) are loaded via CBitrixComponent::setFrameMode(true) and AJAX. TTFB drops to 30-50 ms. But there are nuances: not all components are compatible, $APPLICATION->ShowPanel() breaks the composite, and careful <div id="bx-composite-..."> markup is required.

Marketplace: Audit Before Installation

Before installing a marketplace module — a mandatory audit. We check for: SQL queries without prepared statements (hello, SQL injection), direct access to $_REQUEST without filtering, use of the deprecated old core API instead of D7, conflicts with the composite cache module. A module with no updates for over a year and a couple dozen installations is most likely a headache at the next PHP update.

Migration to D7

When upgrading PHP to 8.x or transitioning to a new edition — refactoring of deprecated calls:

  • CIBlockElement::GetList()Bitrix\Iblock\Elements\ElementTable::getList()
  • CSaleOrder::GetList()Bitrix\Sale\Order::getList()
  • CModule::IncludeModule()Bitrix\Main\Loader::includeModule()
  • Testing on staging, rollback via git if issues arise

Module Development Costs

Complexity Examples Timeline Approximate Cost
Simple Callback widget, banner system, simple calculator 3-5 days from 30,000 RUB
Medium Booking system, product configurator, review module with moderation 1-2 weeks from 80,000 RUB
Complex Multi-regionality, custom loyalty program, ERP integration 2-4 weeks from 150,000 RUB
Enterprise Marketplace platform, complex business processes with multiple roles 1-3 months from 350,000 RUB

The cost includes design, development, testing, documentation, and deployment.

Module Testing

Unit tests via PHPUnit. We cover business logic: discount calculations, validation, document generation. Mocks for Bitrix\Main\Application::getConnection() — so tests don't depend on the database.

Integration tests. We verify event handlers on a real database — OnAfterIBlockElementAdd, OnSaleOrderSaved, and others. REST API endpoints are tested via curl or PHPUnit HTTP client. Critical for modules working with b_sale_order, b_catalog_price — where errors cost money.

Compatibility. PHP 7.4, 8.0, 8.1, 8.2. Editions: Standard, Small Business, Business. We check for conflicts with popular marketplace modules — they love intercepting the same events.

Load testing. For modules with large data volumes: benchmarks at 10K, 100K, 1M records. Profiling via Xdebug for memory leaks and N+1 queries.

Case Studies

Promotions module for an electronics chain. The standard sale module discounts didn't cover "buy 2 get 1 free," gift with purchase over a certain amount, or combined conditions. We built a visual constructor: the marketer creates rules via drag-and-drop, without filing development tickets. Promotion calendar, auto-deactivation via agents, analytics linked to b_sale_order — conversion, average order value, usage count. Time to launch a new promotion dropped from two days to half an hour.

Calculator for a construction company. Parameters (area, materials, number of floors) → formula → preliminary estimate → CRM lead via CRest::call('crm.lead.add'). Regional coefficients and seasonal surcharges from a Highload block, material prices from 1C data exchange. Qualified leads increased by a third: clients see a breakdown by line items before calling the sales manager.

Booking system for a hotel chain. Real-time availability via AJAX requests to a custom vendor_booking_slots table, seasonal rate calculations, synchronization with Booking.com via channel manager API. Room locking during concurrent bookings — via SELECT ... FOR UPDATE in a transaction. Timezones handled via \DateTimeZone — a guest from Vladivostok and a manager from Moscow see the same picture.