Integrating 1C-Bitrix with counterparty verification 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.
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

Integration of 1C-Bitrix with Counterparty Verification Services

A B2B store or corporate portal on Bitrix receives a request from a company — and the manager spends 15 minutes manually verifying the TIN through third-party websites. Automatic counterparty verification is embedded at the moment of organization registration, order placement, or CRM deal creation, and data from the Unified State Register of Legal Entities / disqualified persons registry appears directly in the card.

Data Sources and API

Main services integrated with Bitrix:

Service Provides Request Type
FNS Unified Register (API) Company status, address, director REST by TIN/OGRN
Kontur.Focus Bankruptcy registries, arbitration, financial statements REST + OAuth
SPARK Reliability scoring, affiliations REST + API key
Dadata.ru Property enrichment by TIN, auto-completion REST, simple key
Transparent Business (FNS) Disqualified persons, tax debts Public API

Dadata is the most common choice for auto-completion when entering properties: by TIN it returns full name, KPP, OGRN, legal address, status. Kontur.Focus or SPARK are connected when deep financial analysis is needed.

Integration Architecture

The integration works in two modes:

Mode 1 — online verification when entering TIN. A client enters the TIN into the organization registration or profile form. An AJAX request goes to an intermediate PHP controller, which queries the Dadata API and returns the properties to the front. The user sees the form filled automatically.

Mode 2 — background verification of existing counterparties. A Bitrix agent (CAgent) runs at night, iterates through companies from b_highload_block_entity (HL-block "Organizations") or from the users table, sends the TIN to the API, saves the result.

Storage of Counterparty Data

For storing organization properties — HL-block CompanyRequisites:

  • UF_INN — TIN (string, unique index)
  • UF_OGRN — OGRN
  • UF_KPP — KPP
  • UF_FULL_NAME — full name
  • UF_ADDRESS_LEGAL — legal address
  • UF_DIRECTOR — director
  • UF_STATUS — status (active, liquidated, reorganizing)
  • UF_RISK_SCORE — risk score (if SPARK/Focus is used)
  • UF_LAST_CHECK — date of last verification
  • UF_RAW_DATA — raw API response JSON

Binding to Bitrix user — the UF_USER_ID field on the user or connection through the COMPANY_ID property in the profile.

Dadata Request: Implementation

class DadataContragentChecker
{
    private string $apiKey;
    private string $secretKey;

    public function __construct(string $apiKey, string $secretKey)
    {
        $this->apiKey    = $apiKey;
        $this->secretKey = $secretKey;
    }

    public function getByInn(string $inn): ?array
    {
        $cacheKey = 'dadata_inn_' . md5($inn);
        $cache    = \Bitrix\Main\Data\Cache::createInstance();

        if ($cache->initCache(86400, $cacheKey, '/dadata/inn/')) {
            return $cache->getVars();
        }

        $response = (new \Bitrix\Main\Web\HttpClient())->post(
            'https://suggestions.dadata.ru/suggestions/api/4_1/rs/findById/party',
            json_encode(['query' => $inn, 'count' => 1]),
            [
                'Content-Type'  => 'application/json',
                'Authorization' => 'Token ' . $this->apiKey,
                'X-Secret'      => $this->secretKey,
            ]
        );

        $data = json_decode($response, true);
        if (empty($data['suggestions'][0])) {
            return null;
        }

        $result = $this->normalizeResponse($data['suggestions'][0]);

        $cache->startDataCache(86400, $cacheKey, '/dadata/inn/');
        $cache->endDataCache($result);

        return $result;
    }

    private function normalizeResponse(array $suggestion): array
    {
        $data = $suggestion['data'];
        return [
            'full_name' => $data['name']['full_with_opf'] ?? '',
            'inn'       => $data['inn'] ?? '',
            'kpp'       => $data['kpp'] ?? '',
            'ogrn'      => $data['ogrn'] ?? '',
            'address'   => $suggestion['unrestricted_value'] ?? '',
            'director'  => $data['management']['name'] ?? '',
            'status'    => strtolower($data['state']['status'] ?? 'unknown'),
        ];
    }
}

24-hour caching is mandatory. Without it, when checking in bulk, API limits are quickly reached (Dadata: 10,000 requests per day on the free plan).

Integration into Registration Form

The bitrix:system.auth.registration component is redefined in the template. A TIN field with JavaScript auto-completion is added to the form:

document.getElementById('inn-field').addEventListener('blur', async function() {
    const inn = this.value.replace(/\D/g, '');
    if (inn.length !== 10 && inn.length !== 12) return;

    const resp = await fetch('/local/ajax/check-inn.php?inn=' + inn);
    const data = await resp.json();

    if (data.success) {
        document.getElementById('company-name').value  = data.full_name;
        document.getElementById('kpp-field').value     = data.kpp;
        document.getElementById('ogrn-field').value    = data.ogrn;
        document.getElementById('address-field').value = data.address;

        if (data.status !== 'active') {
            showWarning('Company is not active');
        }
    }
});

The /local/ajax/check-inn.php endpoint is a thin controller that calls DadataContragentChecker and returns JSON.

Integration with Bitrix24 CRM

If CRM is used, verification is embedded when creating a contact or company through events:

  • OnAfterCrmContactAdd / OnAfterCrmCompanyAdd — triggers background verification through a handler
  • Result is written to a UF field of the CRM company
  • For low scoring or "liquidated" status — a task for manual verification is automatically created for the manager
AddEventHandler('crm', 'OnAfterCrmCompanyAdd', function(&$fields) {
    $inn = $fields['fields']['UF_INN'] ?? '';
    if (!$inn) return;

    // Run asynchronously through agent
    \CAgent::AddAgent(
        "checkContragentAgent({$fields['id']}, '{$inn}');",
        'my_module',
        'N',
        60
    );
});

Periodic Re-verification

Companies change status — they liquidate, reorganize. The agent re-checks records older than 30 days:

function reCheckContragentsAgent(): string
{
    $connection = \Bitrix\Main\Application::getConnection();
    $rows = $connection->query(
        "SELECT ID, UF_INN FROM b_hl17_company_requisites
         WHERE UF_LAST_CHECK < DATE_SUB(NOW(), INTERVAL 30 DAY)
         LIMIT 50"
    );

    $checker = new DadataContragentChecker(DADATA_API_KEY, DADATA_SECRET);

    while ($row = $rows->fetch()) {
        $data = $checker->getByInn($row['UF_INN']);
        if ($data) {
            updateHlBlockRecord($row['ID'], $data);
        }
    }

    return __FUNCTION__ . '();';
}

The 50 record limit per run ensures the agent doesn't exceed PHP execution time.

Implementation Timeline

Task Scope Composition Timeline
Property auto-completion by TIN (Dadata) AJAX + cache + registration form 2–4 days
HL-block of counterparties + background agent Storage + periodic verification 1 week
Full integration (CRM + scoring + notifications) Kontur.Focus or SPARK + CRM integration 2–3 weeks