1C-Bitrix Integration with EGAIS
EGAIS (Unified State Automated Information System) is the federal system for tracking alcohol production and circulation. Since 2021, an online store selling alcohol remotely is required to register every sale in EGAIS. This means: when an order is created — deducting the item from EGAIS inventory; on a return — crediting it back. 1C-Bitrix must interact with EGAIS through the UTM (Universal Transport Module) — locally installed software that encrypts and signs requests to EGAIS.
Integration Architecture
EGAIS does not provide a cloud REST API. Communication is exclusively through the UTM installed on the company's local server. The UTM accepts XML requests on port 8080 (inbound) and returns responses on port 8080 (outbound via a queue).
1C-Bitrix → XML request → UTM (localhost:8080)
↓
EGAIS (Rosalkogolregulirovaniye)
↓
UTM forms response → Bitrix polling the response queue
The scheme is asynchronous: a request is submitted → the response appears in the queue within seconds or minutes.
XML Structure for a Write-Off Request
<!-- TTNQuery — write-off request for a sale -->
<?xml version="1.0" encoding="utf-8"?>
<ns:Documents xmlns:ns="urn:TNInformF2Reg:Documents"
xmlns:oref="urn:TNInformF2:OrgInfo"
version="2">
<ns:Document>
<ns:TTNInformF2Reg>
<ns:Header>
<ns:IsSSMark>0</ns:IsSSMark>
</ns:Header>
<ns:Content>
<ns:Position>
<ns:Identity>1</ns:Identity>
<ns:ProductCode>0366700000002375890</ns:ProductCode>
<ns:Quantity>1.000</ns:Quantity>
<ns:InformF1RegId>TEST-TTN123456</ns:InformF1RegId>
<ns:InformF2RegId>TEST-F2-123456</ns:InformF2RegId>
</ns:Position>
</ns:Content>
</ns:TTNInformF2Reg>
</ns:Document>
</ns:Documents>
PHP Client for UTM Communication
class EgaisUtmClient
{
private string $utmUrl;
private string $orgRarId; // organization identifier in EGAIS
public function __construct(string $utmUrl, string $orgRarId)
{
$this->utmUrl = $utmUrl; // http://localhost:8080
$this->orgRarId = $orgRarId;
}
public function sendDocument(string $xmlDocument): string
{
$response = file_get_contents(
$this->utmUrl . '/opt/in/TTNInformF2Reg',
false,
stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/xml',
'content' => $xmlDocument,
]
])
);
// UTM returns ReplyId — identifier for tracking the response
$replyXml = simplexml_load_string($response);
return (string)$replyXml->ReplyId;
}
public function getReplyQueue(): array
{
$response = file_get_contents($this->utmUrl . '/opt/out');
// Parse the response queue
return $this->parseQueue($response);
}
public function getReply(string $replyId): ?array
{
$response = file_get_contents(
$this->utmUrl . "/opt/out/TTNInformF2Reg/{$replyId}"
);
if (!$response) return null;
$xml = simplexml_load_string($response);
return [
'result' => (string)$xml->Result->Conclusion,
'comment' => (string)$xml->Result->ConclusionDate,
'egais_id' => (string)$xml->Result->AccisesHeader->EGAISQuntId,
];
}
}
Order Handling in Bitrix
// Handler for order status change events
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'sale', 'OnSaleStatusOrderChange',
function (\Bitrix\Main\Event $event) {
$order = $event->getParameter('ENTITY');
$statusId = $event->getParameter('VALUE');
if ($statusId !== 'shipped') return; // only send on "Shipped" status
$egaisItems = $this->getAlcoholItemsFromOrder($order);
if (empty($egaisItems)) return;
$client = new EgaisUtmClient(EGAIS_UTM_URL, EGAIS_ORG_RAR_ID);
$xml = $this->buildActWriteOff($order, $egaisItems);
$replyId = $client->sendDocument($xml);
// Save replyId for tracking
EgaisDocumentTable::add([
'ORDER_ID' => $order->getId(),
'REPLY_ID' => $replyId,
'STATUS' => 'pending',
'SENT_AT' => new \Bitrix\Main\Type\DateTime(),
]);
}
);
Case Study: Alcohol Online Store
An online wine and spirits retailer, ~300 orders/day. Daily task: deduct every shipped alcohol unit from EGAIS inventory. A failed write-off means the order cannot be considered legally closed.
Project challenges:
-
The UTM was installed on an office Windows machine while the website ran on shared hosting. No direct network access.
-
The UTM occasionally became unresponsive (reboots, updates), causing documents to be lost.
-
EGAIS returns an AlcoCode — a unique code for each bottle (for marked alcohol) — which must be mapped to the corresponding order line item.
Solutions:
-
VPN tunnel between the hosting and the office server + Middleware on the office server that accepts requests from Bitrix and forwards them to the UTM. Middleware runs on Node.js as a Windows service.
-
A task queue on the Bitrix side: unacknowledged documents are retried after 10 minutes (up to 5 attempts). After exhausting retries — an administrator notification is sent.
-
When EGAIS confirmation is received — the EGAISQuntId is saved in the
local_egais_alcocodestable, linked to the Bitrix order line item.
| Metric | Before | After |
|---|---|---|
| Manual EGAIS operations | ~2 hours/day | 0 (monitoring only) |
| Write-off delay from shipment | 1–3 hours | < 15 minutes |
| Missed write-offs | 3–5%/month | < 0.1% |
Returns in EGAIS
On an alcohol return — the reverse operation: crediting stock back via a WayBillAct document. Triggered by the Bitrix return event (OnSaleRefund).
EGAIS Inventory in Bitrix
For synchronizing warehouse stock with EGAIS data — a periodic query to the UTM (RestBal) and comparison with Bitrix catalog inventory. Discrepancies are logged for audit review.
Scope of Work
- UTM setup, obtaining EGAIS keys (via Rosalkogolregulirovaniye)
- Network connectivity: VPN or Middleware service
- PHP client for UTM: document submission, response queue polling
- XML generation for write-off acts and returns
- Bitrix event handlers: shipment, return
- Retry queue, error monitoring
- EGAIS document history table in Bitrix
Timeline: with an already-configured UTM and network access — 4–6 weeks. If infrastructure setup is required — 8–12 weeks.







