Интеграция с АТОЛ Онлайн для 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Интеграция с АТОЛ Онлайн для 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Интеграция с АТОЛ Онлайн для 1С-Битрикс

АТОЛ Онлайн — один из крупнейших операторов фискальных данных (ОФД) в России, предоставляющий облачную кассу для интернет-магазинов. Если сайт работает на 1С-Битрикс и принимает онлайн-платежи от физических лиц, закон 54-ФЗ обязывает применять ККТ и передавать чеки в ОФД. АТОЛ Онлайн закрывает эту задачу без покупки физической кассы.

Как АТОЛ Онлайн вписывается в цепочку

Стандартная цепочка при оплате с фискализацией через АТОЛ:

  1. Покупатель оплачивает заказ — платёжный агрегатор (ЮКасса, Тинькофф и др.) проводит транзакцию
  2. Платёжный агрегатор отправляет уведомление в Битрикс об успешной оплате
  3. Битрикс (или модуль АТОЛ) отправляет запрос в АТОЛ Онлайн на фискализацию чека
  4. АТОЛ Онлайн регистрирует чек на облачной кассе и передаёт его в ОФД
  5. Покупатель получает электронный чек на email или по SMS
  6. АТОЛ возвращает фискальные данные (номер чека, ФН, ФП) в Битрикс

Ключевой момент: АТОЛ работает асинхронно. Запрос на создание чека отправляется, но ответ о результате приходит через webhook или при повторном запросе статуса.

Официальный модуль АТОЛ для Битрикс

АТОЛ предоставляет официальный модуль atol.kkt54 для 1С-Битрикс. Устанавливается через Маркетплейс или вручную.

После установки настраивается в Магазин → Настройки → АТОЛ Онлайн:

Параметр Откуда взять
Login Личный кабинет АТОЛ Онлайн
Password Там же
Group Code Идентификатор группы касс
INN ИНН организации
Payment Address URL сайта (как зарегистрирован в АТОЛ)
Callback URL https://shop.ru/local/api/atol-callback.php

Структура запроса на создание чека

// Отправка чека прихода в АТОЛ
class AtolClient
{
    private string $token;
    private const API = 'https://online.atol.ru/possystem/v4/';

    public function getToken(): void
    {
        $resp = $this->post('getToken', [
            'login'    => ATOL_LOGIN,
            'pass'     => ATOL_PASSWORD,
        ]);
        $this->token = $resp['token'];
    }

    public function sendReceipt(array $order): array
    {
        $items = [];
        foreach ($order['basket'] as $item) {
            $items[] = [
                'name'          => mb_substr($item['name'], 0, 128), // ограничение АТОЛ
                'price'         => (float)$item['price'],
                'quantity'      => (float)$item['quantity'],
                'sum'           => round($item['price'] * $item['quantity'], 2),
                'payment_method'=> 'full_payment',
                'payment_object'=> 'commodity',
                'vat'           => ['type' => 'none'], // или 'vat20', 'vat10'
            ];
        }

        if ($order['delivery_price'] > 0) {
            $items[] = [
                'name'           => 'Доставка',
                'price'          => (float)$order['delivery_price'],
                'quantity'       => 1.0,
                'sum'            => (float)$order['delivery_price'],
                'payment_method' => 'full_payment',
                'payment_object' => 'service',
                'vat'            => ['type' => 'none'],
            ];
        }

        $payload = [
            'external_id' => 'BX-' . $order['id'] . '-' . time(),
            'receipt'     => [
                'client'   => [
                    'email' => $order['buyer_email'],
                    'phone' => $order['buyer_phone'] ?? null,
                ],
                'company'  => [
                    'email'           => ATOL_COMPANY_EMAIL,
                    'sno'             => 'osn', // система налогообложения: osn|usn_income|usn_income_outcome|envd|esn|patent
                    'inn'             => ATOL_INN,
                    'payment_address' => ATOL_PAYMENT_ADDRESS,
                ],
                'items'    => $items,
                'payments' => [
                    [
                        'type' => 1,  // 1=электронный, 0=наличные
                        'sum'  => (float)$order['total'],
                    ],
                ],
                'total'    => (float)$order['total'],
            ],
            'service'     => [
                'callback_url' => ATOL_CALLBACK_URL,
            ],
            'timestamp'   => date('d.m.Y H:i:s'),
        ];

        return $this->post(ATOL_GROUP_CODE . '/sell', $payload);
    }

    private function post(string $endpoint, array $data): array
    {
        $ch = curl_init(self::API . $endpoint);
        curl_setopt_array($ch, [
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode($data),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => [
                'Content-Type: application/json; charset=utf-8',
                'Token: ' . $this->token,
            ],
        ]);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true) ?? [];
    }
}

Критичные тонкости при реализации

Сумма позиций должна точно совпадать с total — АТОЛ проверяет это на своей стороне. Расхождение в 1 копейку вызывает ошибку. Типичная проблема при округлении: сумма трёх позиций по 33.33 руб. = 99.99, а total = 100.00. Решение — последней позиции присваивать сумму по остатку.

Наименование позиции — максимум 128 символов. Длинные названия нужно обрезать, но так, чтобы сохранился смысл.

Номенклатурный код (поле nomenclature_code) — с 2024 года обязателен для маркированных товаров (одежда, обувь, парфюмерия, молочная продукция и другие категории). Код берётся из системы «Честный ЗНАК».

Асинхронность — ответ POST /sell содержит только uuid задачи. Фактический результат фискализации приходит в callback. Необходимо хранить uuid и обрабатывать callback.

Обработчик callback от АТОЛ

// local/api/atol-callback.php
$body = json_decode(file_get_contents('php://input'), true);

$uuid   = $body['uuid']   ?? '';
$status = $body['status'] ?? '';  // 'done' | 'fail'

if ($status === 'done') {
    $fiscalData = $body['payload']['fiscal_receipt_number'] ?? '';
    $fnNumber   = $body['payload']['fn_number'] ?? '';
    $fnDocument = $body['payload']['fiscal_document_number'] ?? '';

    // Сохраняем фискальные данные в заказ
    saveAtolReceiptData($uuid, [
        'fiscal_number' => $fiscalData,
        'fn'            => $fnNumber,
        'fd'            => $fnDocument,
        'status'        => 'done',
    ]);
} elseif ($status === 'fail') {
    $error = $body['payload']['message'] ?? 'Unknown error';
    logAtolError($uuid, $error);
    // Ставим задачу в очередь на повтор
    scheduleAtolRetry($uuid);
}

http_response_code(200);
echo 'OK';

Чек возврата

При возврате средств в АТОЛ нужно отправить чек возврата через метод /sell_refund (полный) или /sell_correction (корректировка). Структура идентична исходному чеку, но endpoint другой:

// Чек полного возврата
$atol->post(ATOL_GROUP_CODE . '/sell_refund', $payload);

// Чек частичного возврата — только возвращаемые позиции
// total и items содержат только возвращаемую часть

Кейс: магазин с 50+ SKU маркированного товара

Магазин одежды подключил АТОЛ Онлайн в 2023 году. Первоначально интеграция работала корректно, но после расширения ассортимента начались ошибки: часть позиций не имела номенклатурного кода из «Честного ЗНАКА».

Решение: при добавлении товара в каталог добавили обязательное поле «Код маркировки» (UF_MARKING_CODE). В момент отправки чека в АТОЛ — валидация наличия кода для маркированных категорий. Если код отсутствует — заказ переходит в статус «Требует проверки» и менеджер вводит код вручную перед фискализацией.

Это задержало автоматическую фискализацию для части заказов, но исключило штрафы за нарушение требований маркировки.

Сроки

Задача Срок
Установка и настройка официального модуля 1–2 дня
Кастомная интеграция через API АТОЛ 3–5 дней
Обработчик callback + очередь повторов 1–2 дня
Чеки возврата 1–2 дня
Тестирование в тестовой среде АТОЛ 1–2 дня