The CFO spends up to 4 hours a day manually reconciling payments and statements. The sales manager learns about payment with a day's delay — deals stall, money freezes. We solve this problem by integrating Bitrix24 with banking systems: payment arrives — the deal moves to the next stage, the invoice is generated, the counterparty is notified. The integration pays for itself in less than six months, saving up to $15,000 annually by reducing operational costs by 40%.
What problems does the bank integration solve?
Before designing the integration, let's capture specific scenarios. From practice, requests fall into three groups:
Outgoing payments. Export payment orders from Bitrix24 to the bank — bypassing manual entry into the client-bank system. The manager creates a payment invoice to the supplier in CRM, the CFO approves, and the system automatically generates a payment order and sends it to the bank via API. Average processing time drops from 15 minutes to 30 seconds — 30 times faster.
Incoming payments. Webhook or polling of statements: as soon as the bank records a deposit to the account — the deal in CRM changes stage, the manager receives a notification, and the invoice is created. Without integration, the manager learns about payment randomly or at the end of the day. Automation cuts the cash receipt cycle by 70% — 3 times faster than manual processing.
Reference operations. Balance checks, currency rate retrieval, verification of counterparty details via the Federal Tax Service API or bank verification service.
Which integration method to choose: API, DirectBank, or file exchange?
| Parameter |
REST API |
DirectBank |
File exchange |
| Transfer speed |
Instant |
1-2 min delay |
Up to 24 h delay |
| Bank support |
Large (Sber, Tinkoff) |
30+ banks |
All |
| Matching automation |
Full |
Requires 1C intermediary |
Manual import |
| Reliability |
99.9% (with retry scheme) |
99.5% |
95% (operator errors) |
REST API is the most flexible option. Tinkoff Bank API documentation describes endpoints for creating payments and receiving statements. Authentication is OAuth 2.0 with Client Credentials flow. The bank issues a client_id and client_secret, and in return we get an access_token with a limited lifetime (usually 30 minutes). The token is refreshed via refresh_token or re-authentication. Tokens must be stored in a secure vault — we encrypt in the database or use environment variables. The token lifetime is short, so automatic refresh is critical for uninterrupted operation.
1C interface (DirectBank). Some banks support the DirectBank protocol (direct exchange without client-bank). Technically, it's an XML protocol over HTTPS, document format compatible with 1C. If the company already has 1C:Accounting with DirectBank configured, it's easier to build Bitrix24 integration via 1C as an intermediary rather than directly with the bank. This approach is cheaper but introduces additional delay and a single point of failure.
File exchange. The classic approach — export in 1C:Enterprise format (.txt with 1CClientBankExchange header) and import into client-bank manually or through an automatic folder watcher. It doesn't require API access and works with any bank. However, automatic matching of payments with orders is impossible — matching is manual, which eliminates time savings.
Why is token encryption important for integration?
Banking API is a critical integration perimeter. Requirements:
- Tokens are stored encrypted (AES-256), the encryption key is in environment variables, not in code
- Requests to the API go only over HTTPS, SSL certificate verification is mandatory
- Logs of all API calls with masking of sensitive data (account number, amount — we log; CVV and tokens — never)
- IP whitelist on the bank's side — allow only IP addresses of our servers
- For webhook endpoint — validate request signature (the bank signs the payload with HMAC-SHA256 using a secret key)
Secure integration checklist
- Use only HTTPS with certificate verification
- Encrypt tokens with AES-256
- Restrict IP addresses on the bank's side
- Sign webhook requests with HMAC-SHA256
- Do not log sensitive data
Application architecture in Bitrix24
The integration is implemented as a local application or a built-in REST handler. Schema:
Bitrix24 CRM
↓ Webhook / Robot
Handler (PHP, self-hosted or application server)
↓ OAuth2 token
Bank API
↓ Response
Update CRM entities via crm.deal.update / crm.invoice.update
For incoming payments — reverse schema: the bank sends a webhook to our endpoint, which updates the deal status via crm.deal.update or crm.timeline.comment.add.
Payment state storage: we add a UF_BANK_PAYMENT_ID (user field) to the deal and invoice — the external payment identifier in the bank. This allows idempotent processing of repeated webhook notifications and querying the status of a specific payment.
Working with statements
The bank statement comes in JSON format (via API) or SWIFT MT940/camt.053 (for international banks). We parse transactions: amount, date, payment purpose, payer's INN. Using INN or account number, we look up the counterparty in CRM via crm.company.list with a filter on requisites. If the counterparty is found, we look for an open invoice with the corresponding amount.
The challenge is the payment purpose. "Payment to invoice No. 145 dated March 12" — good, parsing the invoice number is straightforward. "Payment for services" — bad, manual matching required. For the second case, we build a manual matching interface: a list of unrecognized receipts with the ability to manually link to a deal.
Error handling and retries
Bank APIs are unstable. Typical scenarios: timeout when creating a payment (unknown if it went through), temporary service unavailability, rate limiting. Each scenario has its own logic.
For critical operations (sending a payment order), we use a queue with idempotent keys: before sending, we generate an idempotency_key (UUID) and pass it in the request header. On repeated attempts with the same key, the bank does not duplicate the payment. API integration is 3 times more reliable than file exchange in terms of failure frequency: we measured — on average 2 failures per 1000 operations versus 7.
Development stages
| Stage |
Content |
Duration |
| Analysis |
Bank API study, scenarios, technical specification |
3–5 days |
| Basic integration |
OAuth2, statement retrieval, display in CRM |
1–2 weeks |
| Incoming payments |
Webhook, transaction matching with deals |
1 week |
| Outgoing payments |
Creating payment orders, approval, sending |
1–2 weeks |
| Manual matching |
UI for unrecognized receipts |
3–5 days |
| Testing and debugging |
Bank sandbox, edge cases |
1 week |
Actual timelines shift depending on the quality of the bank's documentation and availability of a sandbox environment. Tinkoff and Alfa have good sandboxes. Some regional banks do not, and then debugging is done carefully in a production environment with test amounts.
What is included in the work
- API documentation and integration setup instructions
- Access to source code (if needed)
- Employee training on the new functionality
- Support during implementation and the first month of operation
We provide a turnkey integration starting from $5,900 with a security guarantee and payback period under six months. Write to us — we will assess your project free of charge.
1C-Bitrix Module Development and Setup
The main trap of Bitrix is init.php. You add an OnBeforeIBlockElementUpdate handler there, then another one — a year later the file is 2000 lines, and on every hit all that code executes. We move business logic into full-fledged modules with D7 ORM, custom tables, and administrative interface. The module can be disabled, transferred to another project, covered with tests — none of that is possible with init.php. Our team has 10+ years of Bitrix experience, certified specialists, and a 6-month code guarantee. Request a consultation — we'll explain how to migrate legacy code to a modular architecture.
Why is init.php the worst place for business logic?
Init.php does not support class autoloading, lacks an isolated namespace, cannot be unit tested, and cannot be disabled without editing the file itself. Every handler written there runs on every request, even if not needed. In a module, you register handlers through EventManager, and they only execute when the event occurs. Performance difference: up to 3x with 10+ handlers.
Standard Modules: Typical Problems and Solutions
Information blocks. IBlock architecture is the first thing we review on any project. A classic mistake: one catalog infoblock with 80 properties, 30 of which are multiple. The b_iblock_element_property table swells to millions of rows, and CIBlockElement::GetList with filtering on three properties does a full scan. We move reference data to Highload-blocks, eliminate multiple properties where possible, and design the structure for 5x growth.
e-Store (sale). Cart business rules are a separate story. We set discount priorities to prevent two campaigns from giving 60% instead of 30%, connect payment handlers, and write custom validation via OnSaleOrderBeforeSaved.
Search. The built-in search module with morphology works up to 10–15 thousand elements. Beyond that — Elasticsearch. We configure it via the Bitrix search module API, indexing through CSearchFullText or custom indexers.
Highload-blocks for dictionaries, logs, user data — instead of bloated IBlocks. Direct queries via Bitrix\Highloadblock\HighloadBlockTable, custom tables instead of the EAV structure of standard infoblocks. A million records — no degradation.
Mail events. Configuration is not just templates in b_event_message. The key is SPF, DKIM, DMARC on the DNS, otherwise transactional emails go to spam. We check deliverability and set up bounce handling.
How to Design Infoblocks for Performance?
We use Highload-blocks for reference data (colors, sizes, manufacturers) that are not involved in complex queries. For SKUs — a separate infoblock with linking via IBLOCK_ELEMENT_PROPERTY. Enable INDEX_PROPERTY for frequently filtered properties. Tagged caching: when an element changes, only the related cache is cleared. Highload-blocks process up to 10x faster than infoblocks with multiple properties on volumes of 100,000 records.
Custom Module Development
Each module follows the structure /local/modules/vendor.modulename/:
-
install/index.php — setup class, create tables via $DB->RunSQLBatch()
-
lib/ — D7 ORM classes, extending Bitrix\Main\ORM\Data\DataManager
-
admin/ — administrative pages using CAdminList, CAdminForm
-
include.php — autoloading, event 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 through UpdateSystem or custom migration mechanics.
Examples of implemented tasks:
- Campaign management — visual condition builder via
CAdminCalendar, timers via agents (CAgent::AddAgent), 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() on concurrent requests, integration with channel manager via webhook
Components and Composite Cache
Component customization via result_modifier.php and component_epilog.php, not by editing template.php of the standard template. This way core updates are painless.
Composite cache ("Composite Site" technology) — the server sends ready HTML, bypassing PHP routing. Dynamic areas (cart, authorization) are loaded via CBitrixComponent::setFrameMode(true) and AJAX. TTFB drops to 30–50 ms. But there are caveats: not all components are compatible, $APPLICATION->ShowPanel() breaks composite, and careful markup of <div id="bx-composite-..."> is required.
What to Check Before Installing a Marketplace Module?
Before installing a module from the marketplace, an audit is mandatory. We check: SQL queries without prepared statements (hello SQL injection), direct use of $_REQUEST without filtering, use of outdated kernel API instead of D7, conflicts with the composite cache module. A module with no updates for over a year and a few dozen installations is likely a problem on the next PHP update. A typical case: a module calls CIBlockElement::GetList with no cache reset — the site crashes with 5000 elements.
Migration to D7
When upgrading PHP or switching to a new edition — refactor outdated 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 on issues.
According to official 1C-Bitrix documentation, D7 ORM is the recommended tool for working with data, providing type safety and automatic query generation.
Comparison: Init.php vs Module
| Criterion |
Init.php |
Module with D7 ORM |
| Performance |
Executes on every hit |
Executes only on event |
| Testability |
No autoloading, tests impossible |
Full PHPUnit support |
| Maintainability |
Codebase grows uncontrollably |
Isolated structure, versioning |
| Migrations |
None |
Custom tables, managed via install |
| Caching |
Does not support auto-invalidation |
Tagged caching, event-based clearing |
Module Development Scope and Cost
What is included in module development?
- Technical specification and architectural plan
- Code following PSR-4 and Bitrix code style
- Unit tests (PHPUnit) for business logic
- Integration tests for events and REST API
- Installation, configuration, and API documentation
- Repository and documentation access
- Administrator training for module usage
- 6-month warranty support
Estimated timelines and complexity:
| Complexity |
Examples |
Timeline |
| Simple |
Callback widget, banner system, simple calculator |
3–5 days |
| Medium |
Booking system, product configurator, review module with moderation |
1–2 weeks |
| Complex |
Multi-regionality, custom loyalty program, ERP integration |
2–4 weeks |
| Enterprise |
Marketplace platform, complex business processes with multiple roles |
1–3 months |
Cost is calculated individually — contact us for a project estimate.
Module Testing
Unit tests via PHPUnit cover business logic: discount calculation, validation, document generation. Mocks for Bitrix\Main\Application::getConnection() allow tests to be DB-independent. Integration tests verify event handlers on a real database — OnAfterIBlockElementAdd, OnSaleOrderSaved, etc. 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 is checked on PHP 7.4, 8.0, 8.1, 8.2 and editions: Standard, Small Business, Business. We check conflicts with popular marketplace modules — they often intercept the same events. Load testing: measurements on 10K, 100K, 1M records, profiling via Xdebug for memory leaks and N+1 queries.
Practical Examples
Campaign module for an electronics chain. The built-in sale module discounts did not cover scenarios like "2+1", a gift with purchase over a certain amount, or combined conditions. We built a visual builder: marketers create rules via drag-and-drop without development tickets. Campaign calendar, auto-deactivation via agents, analytics linked to b_sale_order — conversion, average check, usage count. Time to launch a new campaign dropped from two days to half an hour.
Calculator for builders. Parameters (area, materials, number of floors) → formula → preliminary estimate → lead to CRM via CRest::call('crm.lead.add'). Regional coefficients and seasonal markups from a Highload-block, material prices from 1C exchange. The number of target leads increased by a third: clients see a breakdown before calling a manager.
Booking for a hotel chain. Real-time availability via AJAX requests to a custom table vendor_booking_slots, seasonal tariff calculation, synchronization with Booking.com via channel manager API. Room locking on concurrent booking via SELECT ... FOR UPDATE in transactions. Timezones handled via \DateTimeZone — a guest from Vladivostok and a manager from Moscow see the same picture.
We will evaluate your project within one day. Write to us — we'll tell you what is included in turnkey development. Contact us for a consultation on your project. Order a custom module development — get a ready solution with documentation and support.