1C-Bitrix Integration with Diadoc EDI (Kontur)

Manual document exchange with counterparties slows down operations and leads to errors in details. We set up integration of 1C-Bitrix with Diadoc, automating the sending of UPD, invoices, and acts with electronic signature. Our team delivers a turnkey project—from API configuration to support—ensuring reliable and transparent document flow.

Our competencies:

Frequently Asked Questions

We automate the exchange of legally significant documents between 1C-Bitrix and the Diadoc EDI system (SKB Kontur). With extensive experience, we configure integrations for online stores and B2B platforms: invoices, waybills, acts, and UPD are signed with a qualified electronic signature (CES) and transmitted without manual work. When every minute counts, automation pays for itself within 2–3 months.

A typical pain point: managers spend up to 30 minutes daily manually creating documents in Diadoc. Errors in requisites lead to returns and payment delays. We solve these problems: we configure automatic XML generation according to Federal Tax Service standards, server-side CES signing, and status monitoring. The client gets transparent document flow without unnecessary steps.

Through integration, EDI processing time is reduced to 2 minutes per day, and error rates drop from 5% to 0.5%. In this article, we cover the architecture, code, and a real implementation case.

What is required for integration - Diadoc account with API rights - Cryptographic provider (CryptoPro CSP) - CES certificate installed on the server - HTTPS access to Diadoc API

Integrating 1C-Bitrix with Diadoc

Diadoc provides a REST API (https://diadoc-api.kontur.ru/). Authentication is via a token issued using Diadoc account login/password or through a CES certificate. For server integration, token-based authentication is used.

Integration schema:

Bitrix (event: order paid) → PHP handler → XML document generation (UPD/Act) → POST /v1/organizations/{orgId}/messages (Diadoc API) → Diadoc delivers to counterparty → Webhook from Diadoc: signing status → Status update in Bitrix 

Implementing automation saves up to $2.7k–3.9k per year on manual document filling. The average cost of one requisites error is $14–20, and automation eliminates up to 90% of such errors.

Configuring Authentication to Diadoc API

class DiadokClient {
    private string $apiKey;
    private string $token;
    private string $baseUrl = 'https://diadoc-api.kontur.ru';

    public function __construct(string $apiKey, string $login, string $password) {
        $this->apiKey = $apiKey;
        $this->token = $this->authenticate($login, $password);
    }

    private function authenticate(string $login, string $password): string {
        $response = $this->request('POST', '/V3/Authenticate', [
            'login' => $login,
            'password' => $password,
        ], false);
        return $response; // returns token string
    }

    public function request(string $method, string $path, array $data = [], bool $auth = true): mixed {
        $headers = ['DiadocAuth ddauth_api_client_id=' . $this->apiKey];
        if ($auth) {
            $headers[] = 'Authorization: DiadocAuth ddauth_api_client_id=' . $this->apiKey . ', ddauth_token=' . $this->token;
        }
        // ... curl/Guzzle request
    }
}

Automatable Documents

With the integration, you can send UPD, acts, invoices, and waybills. All documents are generated according to Federal Tax Service standards, in particular the Universal Transfer Document as per FTS Order MMV-7-15/820. Custom XML forms are also supported if they conform to Diadoc's XSD schemas.

XSD Validation Reduces Error Rates Tenfold

Diadoc accepts documents in XML format per FTS standards. For UPD, the format is according to FTS Order MMV-7-15/820. XSD schema validation is mandatory: if the structure does not match, Diadoc returns a 400 error. We use DOMDocument::schemaValidate() before sending.

class UPDGenerator {
    public function generateFromOrder(\Bitrix\Sale\Order $order): string {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $root = $dom->createElement('Файл');
        $root->setAttribute('ИдФайл', $this->generateFileId($order));
        $root->setAttribute('ВерсПрог', 'BitrixIntegration 1.0');
        $root->setAttribute('ВерсФорм', '5.02');

        // Participant details
        $svUch = $dom->createElement('СвУчДокОбор');
        $svSender = $dom->createElement('СвОЭДОтпр');
        $svSender->setAttribute('НаимОрг', $this->senderName);
        $svSender->setAttribute('ИННЮЛ', $this->senderInn);
        $svSender->setAttribute('ИдЭДО', $this->senderEdoId);
        $svUch->appendChild($svSender);
        $root->appendChild($svUch);

        // Document
        $doc = $dom->createElement('Документ');
        $doc->setAttribute('КНД', '1115125');
        $doc->setAttribute('ФункцДок', 'ДОП'); // DOP = transfer of work/services results
        $doc->setAttribute('НомерДок', $order->getId());
        $doc->setAttribute('ДатаДок', date('d.m.Y'));
        $doc->setAttribute('Сумма', number_format($order->getPrice(), 2, '.', ''));
        $doc->setAttribute('СумНал', $this->calculateVat($order));

        // Table rows (order items)
        $this->appendOrderItems($dom, $doc, $order);
        $root->appendChild($doc);
        $dom->appendChild($root);

        $schemaPath = __DIR__ . '/schemas/utd820_05_01_02_hyphen.xsd';
        if (!$dom->schemaValidate($schemaPath)) {
            throw new \RuntimeException('XML did not pass XSD validation');
        }

        return $dom->saveXML();
    }
}

Sending a Document via API

public function sendUPD(\Bitrix\Sale\Order $order, string $recipientOrgId): string {
    $xml = (new UPDGenerator())->generateFromOrder($order);

    // Upload document
    $uploadResult = $this->client->request('POST', "/V3/PostMessagePatchDraft?boxId={$this->boxId}", [
        'FromBoxId' => $this->boxId,
        'ToBoxId' => $recipientOrgId,
        'DocumentAttachments' => [[
            'SignedContent' => [
                'Content' => base64_encode($xml),
                'Signature' => $this->sign($xml), // CES signature
            ],
            'TypeNamedId' => 'UniversalTransferDocument',
            'Function' => 'ДОП',
            'Version' => 'utd820_05_01_02_hyphen',
        ]],
    ]);

    return $uploadResult['MessageId'];
}

To sign a document with a CES on the server, a cryptographic provider is required — CryptoPro CSP or ViPNet CSP. Integration uses openssl_pkcs7_sign() with a certificate installed on the server.

Webhooks Instead of Polling

Diadoc notifies about document status changes via two methods: polling (GET /V3/GetNewEvents) and webhooks (push notifications). We recommend webhooks — they are more efficient and reduce server load.

Criteria Polling Webhooks
Latency Up to 5 minutes (poll interval) Real-time (seconds)
Server load High (frequent requests) Low (only on events)
Implementation complexity Simple (single cron) Medium (endpoint setup)
Scalability Poor (linear request growth) Good (event-driven)

Polling for a small volume of documents runs via cron every 5 minutes. Webhooks, on the other hand, provide instant status updates without server load.

Case Study: Automated EDI for a Wholesale Supplier

A cosmetics distributor with ~800 B2B orders per month. Each order required a UPD. An employee manually created the document in Diadoc, taking 20–30 minutes per day cumulatively.

Automated operations:

  1. When the order status changes to "Shipped" (OnSaleStatusOrder) — automatic generation and sending of UPD to Diadoc. Counterparty details (INN, KPP, Diadoc BoxId) are taken from Bitrix order properties.

  2. Counterparty directory: on the first order from a new legal entity — automatic search for the counterparty's BoxId via GET /V3/GetOrganizationsByInnKpp. If found, it is saved in the Bitrix buyer's custom field.

  3. When the counterparty signs the UPD — a webhook from Diadoc changes the order status to "Documents signed". The manager sees the change in Bitrix without opening Diadoc.

  4. Notification: if the counterparty rejects a document with a comment — the manager receives a notification in Bitrix (CEventLog::Add()) with the rejection reason text.

Metric Before After
Time for EDI processing 20–30 min/day < 2 min/day (exceptions only)
Errors in requisites ~5% of documents < 0.5%
Signing time by counterparties Not tracked Monitored, avg 1.8 days

Request a consultation — we will analyze your document flow and propose an optimal solution.

Storing Document History

To track all documents, we create a table via D7 ORM:

class DiadokDocumentTable extends \Bitrix\Main\ORM\Data\DataManager
{
    public static function getTableName(): string
    {
        return 'local_diadok_documents';
    }

    public static function getMap(): array
    {
        return [
            new \Bitrix\Main\ORM\Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            new \Bitrix\Main\ORM\Fields\IntegerField('ORDER_ID'),
            new \Bitrix\Main\ORM\Fields\StringField('DIADOK_MESSAGE_ID'),
            new \Bitrix\Main\ORM\Fields\StringField('DOCUMENT_TYPE'), // UPD, ACT, INVOICE
            new \Bitrix\Main\ORM\Fields\StringField('STATUS'), // sent, signed, rejected
            new \Bitrix\Main\ORM\Fields\DatetimeField('CREATED_AT'),
            new \Bitrix\Main\ORM\Fields\DatetimeField('SIGNED_AT'),
        ];
    }
}

What Is Included

  • Setting up Diadoc account, obtaining API keys
  • Installing cryptographic provider on server, uploading CES certificate
  • Developing PHP client for Diadoc API
  • XML document generator (UPD, Acts) with XSD validation
  • Bitrix event handlers (order status change)
  • Status synchronization: polling or webhooks
  • Storing document history, displaying in Bitrix order
  • Staff training, documentation, 3-month support

Timelines: basic integration (UPD sending, statuses) — 3–5 weeks. Full integration with multiple document types, counterparty directory, and notifications — 6–10 weeks.

Contact us — we will configure integration for your business. Get in touch for a project assessment — we will analyze your document flow and propose the optimal solution.