Development of an integration module with the 1C-Bitrix external API

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
    1173
  • 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
    745
  • 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

External API Integration Module Development for 1C-Bitrix

Integration built from "five lines of cURL in some random file" is a classic technical debt in Bitrix projects. Such code produces no logs, handles no errors, supports no retries, and falls apart the moment an API key changes. A proper integration module solves these problems systematically.

Integration Module Architecture Principles

A well-designed integration module consists of several layers:

  1. HTTP client — abstraction over the transport layer (cURL/Guzzle), authentication management, timeouts, retries
  2. API Gateway — methods corresponding to specific external API endpoints
  3. Mapper/DTO — data transformation between the API format and the Bitrix format
  4. Queue/Retry — queue for asynchronous requests and retry logic on errors
  5. Logger — log of all requests and responses for diagnostics
  6. Admin UI — connection settings, monitoring, manual sync trigger

HTTP Client with Retry Logic

namespace Vendor\Integration\Http;

use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\HttpHeaders;

class ApiClient
{
    private HttpClient $http;
    private string $baseUrl;
    private string $apiKey;
    private int $maxRetries = 3;

    public function request(string $method, string $endpoint, array $data = []): array
    {
        $attempt = 0;
        $lastException = null;

        while ($attempt < $this->maxRetries) {
            try {
                $response = $this->doRequest($method, $endpoint, $data);
                $this->logRequest($method, $endpoint, $data, $response);
                return $response;
            } catch (RateLimitException $e) {
                sleep(pow(2, $attempt)); // Exponential backoff
                $attempt++;
                $lastException = $e;
            } catch (ApiException $e) {
                $this->logError($method, $endpoint, $e);
                throw $e; // Do not retry business errors
            }
        }

        throw $lastException;
    }
}

Request Logging

A request log is a mandatory part of a production module. Without it, support becomes guesswork. ORM table for logs:

// lib/Orm/ApiLogTable.php
class ApiLogTable extends DataManager
{
    public static function getTableName(): string { return 'vendor_integration_log'; }

    public static function getMap(): array
    {
        return [
            new IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            new StringField('METHOD'),      // GET/POST/PUT
            new StringField('ENDPOINT'),
            new TextField('REQUEST_BODY'),
            new IntegerField('STATUS_CODE'),
            new TextField('RESPONSE_BODY'),
            new FloatField('DURATION_MS'),  // execution time
            new StringField('ERROR'),
            new DatetimeField('CREATED_AT'),
        ];
    }
}

The admin section provides a filterable list of requests by status, date, and endpoint. This is the first place a developer looks when diagnosing an issue.

Queue for Asynchronous Synchronization

Synchronous external API calls during a user request is an anti-pattern: the external service may be slow or unavailable. Heavy operations (catalog updates from ERP, order synchronization) are offloaded to a queue.

Implementation via Bitrix agents:

// Agent runs via cron every N minutes
public static function processSyncQueue(): string
{
    $items = SyncQueueTable::getList([
        'filter' => ['STATUS' => 'pending', '<ATTEMPTS' => 3],
        'limit'  => 50,
        'order'  => ['CREATED_AT' => 'ASC'],
    ]);

    foreach ($items as $item) {
        try {
            static::processItem($item);
            SyncQueueTable::update($item['ID'], ['STATUS' => 'done']);
        } catch (\Exception $e) {
            SyncQueueTable::update($item['ID'], [
                'STATUS'       => $item['ATTEMPTS'] >= 2 ? 'failed' : 'pending',
                'ATTEMPTS'     => $item['ATTEMPTS'] + 1,
                'LAST_ERROR'   => $e->getMessage(),
                'NEXT_ATTEMPT' => (new \Bitrix\Main\Type\DateTime())->add('PT' . pow(2, $item['ATTEMPTS']) . 'M'),
            ]);
        }
    }

    return '\Vendor\Integration\SyncAgent::processSyncQueue();'; // Return for re-scheduling
}

Webhook Handler

If the external system sends events (webhooks), the module registers a public URL to receive them:

// Public handler: /local/api/integration/webhook.php
use Bitrix\Main\Application;

$request = Application::getInstance()->getContext()->getRequest();
$payload = json_decode($request->getInput(), true);

// Signature verification
$signature = $request->getHeader('X-Signature');
if (!WebhookSecurity::verify($payload, $signature)) {
    http_response_code(401);
    exit;
}

// Enqueue for processing
SyncQueueTable::add([
    'TYPE'    => 'webhook_' . ($payload['event'] ?? 'unknown'),
    'PAYLOAD' => json_encode($payload),
    'STATUS'  => 'pending',
]);

http_response_code(200);
echo json_encode(['ok' => true]);

Module Settings

Settings (API URL, keys, operating mode) are stored via \Bitrix\Main\Config\Option:

// Write a setting
Option::set('vendor.integration', 'api_key', $encryptedKey);
Option::set('vendor.integration', 'api_url', 'https://api.service.com/v2');

// Read
$apiKey = Option::get('vendor.integration', 'api_key');

Sensitive data (API keys, passwords) are encrypted before saving via \Bitrix\Main\Security\Sign\Signer or the standard \Bitrix\Main\Crypt function.

Typical Development Timelines

Configuration Timeline
Simple integration: 3–5 methods, no queue 1–2 weeks
Bidirectional sync, queue, logging 3–5 weeks
Complex integration: webhooks, mapping, UI 6–10 weeks
Integration with ERP via CommerceML/REST 4–8 weeks

The module is documented at the architecture level (data flow diagram) and at the operational level (administrator guide describing settings and error interpretation).